From e8a15d396a652069350b07d78920f31735dfb2ff Mon Sep 17 00:00:00 2001 From: Vasilito Date: Thu, 30 Apr 2026 01:32:25 +0100 Subject: [PATCH] fix: KF6Attica recipe, kf6-knewstuff Attica dep, topo-sort cycle error MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Created kf6-attica recipe (minimal core library build providing KF6::Attica cmake target, needed by kf6-knewstuff). v6.10.0, QML/tests/examples disabled. - Added kf6-attica to redbear-full.toml config, integrate-redbear.sh symlink, and recipes/kde/ symlink. - Fixed kf6-knewstuff: removed stale find_package(KF6Attica) suppression; added kf6-attica as dependency. Now publishes to repo (core-only build produces empty package — upstream code structure yields no libs with QtQuick/widgets/tools off). - Cookbook topo-sort: changed cycle fallback from silent Ok(recipes) to Err(Recursion) — surfaces dependency graph bugs instead of hiding them. - Fixed stale QtNetwork comment: QtNetwork IS enabled in qtbase since 2026-04-29 (relibc DNS resolver hardened). - Verified: kf6-attica builds, kf6-knewstuff publishes to repo --- config/redbear-full.toml | 7 +- local/recipes/kde/kf6-attica/recipe.toml | 55 + .../kf6-attica/source/.git-blame-ignore-revs | 4 + .../recipes/kde/kf6-attica/source/.gitignore | 29 + .../kde/kf6-attica/source/.gitlab-ci.yml | 11 + .../recipes/kde/kf6-attica/source/.kde-ci.yml | 8 + local/recipes/kde/kf6-attica/source/AUTHORS | 4 + .../kde/kf6-attica/source/CMakeLists.txt | 102 + local/recipes/kde/kf6-attica/source/ChangeLog | 56 + .../source/KF6AtticaConfig.cmake.in | 9 + .../kf6-attica/source/LICENSES/CC0-1.0.txt | 121 ++ .../source/LICENSES/LGPL-2.0-or-later.txt | 446 ++++ .../source/LICENSES/LGPL-2.1-only.txt | 467 +++++ .../source/LICENSES/LGPL-3.0-only.txt | 163 ++ .../LICENSES/LicenseRef-KDE-Accepted-LGPL.txt | 12 + local/recipes/kde/kf6-attica/source/README.md | 15 + .../source/autotests/CMakeLists.txt | 11 + .../source/autotests/configtest.cpp | 44 + .../source/autotests/persontest.cpp | 50 + .../source/autotests/privatedatatest.cpp | 47 + .../source/autotests/providertest.cpp | 193 ++ .../kde/kf6-attica/source/docs/Doxyfile.local | 7 + .../kde/kf6-attica/source/metainfo.yaml | 21 + .../kde/kf6-attica/source/src/CMakeLists.txt | 236 +++ .../kf6-attica/source/src/accountbalance.cpp | 56 + .../kf6-attica/source/src/accountbalance.h | 82 + .../source/src/accountbalanceparser.cpp | 35 + .../source/src/accountbalanceparser.h | 26 + .../kde/kf6-attica/source/src/achievement.cpp | 272 +++ .../kde/kf6-attica/source/src/achievement.h | 107 + .../source/src/achievementparser.cpp | 136 ++ .../kf6-attica/source/src/achievementparser.h | 29 + .../kde/kf6-attica/source/src/activity.cpp | 98 + .../kde/kf6-attica/source/src/activity.h | 131 ++ .../kf6-attica/source/src/activityparser.cpp | 57 + .../kf6-attica/source/src/activityparser.h | 26 + .../kf6-attica/source/src/atticabasejob.cpp | 185 ++ .../kde/kf6-attica/source/src/atticabasejob.h | 88 + .../kde/kf6-attica/source/src/atticautils.cpp | 83 + .../kde/kf6-attica/source/src/atticautils.h | 29 + .../kf6-attica/source/src/buildservice.cpp | 90 + .../kde/kf6-attica/source/src/buildservice.h | 70 + .../kf6-attica/source/src/buildservicejob.cpp | 154 ++ .../kf6-attica/source/src/buildservicejob.h | 77 + .../source/src/buildservicejoboutput.cpp | 56 + .../source/src/buildservicejoboutput.h | 52 + .../src/buildservicejoboutputparser.cpp | 36 + .../source/src/buildservicejoboutputparser.h | 26 + .../source/src/buildservicejobparser.cpp | 56 + .../source/src/buildservicejobparser.h | 26 + .../source/src/buildserviceparser.cpp | 69 + .../source/src/buildserviceparser.h | 26 + .../kde/kf6-attica/source/src/category.cpp | 77 + .../kde/kf6-attica/source/src/category.h | 109 + .../kf6-attica/source/src/categoryparser.cpp | 39 + .../kf6-attica/source/src/categoryparser.h | 26 + .../kde/kf6-attica/source/src/cloud.cpp | 124 ++ .../recipes/kde/kf6-attica/source/src/cloud.h | 194 ++ .../kde/kf6-attica/source/src/cloudparser.cpp | 51 + .../kde/kf6-attica/source/src/cloudparser.h | 26 + .../kde/kf6-attica/source/src/comment.cpp | 155 ++ .../kde/kf6-attica/source/src/comment.h | 88 + .../kf6-attica/source/src/commentparser.cpp | 77 + .../kde/kf6-attica/source/src/commentparser.h | 28 + .../kde/kf6-attica/source/src/config.cpp | 101 + .../kde/kf6-attica/source/src/config.h | 77 + .../kf6-attica/source/src/configparser.cpp | 45 + .../kde/kf6-attica/source/src/configparser.h | 29 + .../kde/kf6-attica/source/src/content.cpp | 328 +++ .../kde/kf6-attica/source/src/content.h | 268 +++ .../kf6-attica/source/src/contentparser.cpp | 93 + .../kde/kf6-attica/source/src/contentparser.h | 26 + .../kde/kf6-attica/source/src/deletejob.cpp | 33 + .../kde/kf6-attica/source/src/deletejob.h | 39 + .../kf6-attica/source/src/distribution.cpp | 64 + .../kde/kf6-attica/source/src/distribution.h | 73 + .../source/src/distributionparser.cpp | 37 + .../source/src/distributionparser.h | 27 + .../source/src/downloaddescription.cpp | 217 ++ .../source/src/downloaddescription.h | 103 + .../kf6-attica/source/src/downloaditem.cpp | 118 ++ .../kde/kf6-attica/source/src/downloaditem.h | 77 + .../source/src/downloaditemparser.cpp | 45 + .../source/src/downloaditemparser.h | 26 + .../kde/kf6-attica/source/src/event.cpp | 184 ++ .../recipes/kde/kf6-attica/source/src/event.h | 224 ++ .../kde/kf6-attica/source/src/eventparser.cpp | 61 + .../kde/kf6-attica/source/src/eventparser.h | 26 + .../kde/kf6-attica/source/src/folder.cpp | 90 + .../kde/kf6-attica/source/src/folder.h | 116 + .../kf6-attica/source/src/folderparser.cpp | 41 + .../kde/kf6-attica/source/src/folderparser.h | 26 + .../kde/kf6-attica/source/src/forum.cpp | 135 ++ .../recipes/kde/kf6-attica/source/src/forum.h | 72 + .../kde/kf6-attica/source/src/forumparser.cpp | 71 + .../kde/kf6-attica/source/src/forumparser.h | 27 + .../kde/kf6-attica/source/src/getjob.cpp | 29 + .../kde/kf6-attica/source/src/getjob.h | 39 + .../kf6-attica/source/src/homepageentry.cpp | 63 + .../kde/kf6-attica/source/src/homepageentry.h | 67 + .../kf6-attica/source/src/homepagetype.cpp | 64 + .../kde/kf6-attica/source/src/homepagetype.h | 73 + .../source/src/homepagetypeparser.cpp | 37 + .../source/src/homepagetypeparser.h | 27 + .../kde/kf6-attica/source/src/icon.cpp | 76 + .../recipes/kde/kf6-attica/source/src/icon.h | 70 + .../kde/kf6-attica/source/src/itemjob.cpp | 104 + .../kde/kf6-attica/source/src/itemjob.h | 101 + .../source/src/knowledgebaseentry.cpp | 174 ++ .../source/src/knowledgebaseentry.h | 83 + .../source/src/knowledgebaseentryparser.cpp | 58 + .../source/src/knowledgebaseentryparser.h | 27 + .../kde/kf6-attica/source/src/license.cpp | 72 + .../kde/kf6-attica/source/src/license.h | 74 + .../kf6-attica/source/src/licenseparser.cpp | 36 + .../kde/kf6-attica/source/src/licenseparser.h | 24 + .../kde/kf6-attica/source/src/listjob.cpp | 36 + .../kde/kf6-attica/source/src/listjob.h | 43 + .../kf6-attica/source/src/listjob_inst.cpp | 151 ++ .../kde/kf6-attica/source/src/message.cpp | 123 ++ .../kde/kf6-attica/source/src/message.h | 73 + .../kf6-attica/source/src/messageparser.cpp | 49 + .../kde/kf6-attica/source/src/messageparser.h | 28 + .../kde/kf6-attica/source/src/metadata.cpp | 147 ++ .../kde/kf6-attica/source/src/metadata.h | 105 + .../kde/kf6-attica/source/src/parser.cpp | 166 ++ .../kde/kf6-attica/source/src/parser.h | 39 + .../kde/kf6-attica/source/src/person.cpp | 173 ++ .../kde/kf6-attica/source/src/person.h | 83 + .../kf6-attica/source/src/personparser.cpp | 65 + .../kde/kf6-attica/source/src/personparser.h | 29 + .../kf6-attica/source/src/platformdependent.h | 82 + .../source/src/platformdependent_v2.cpp | 15 + .../source/src/platformdependent_v2.h | 41 + .../source/src/platformdependent_v3.cpp | 6 + .../source/src/platformdependent_v3.h | 45 + .../kf6-attica/source/src/postfiledata.cpp | 129 ++ .../kde/kf6-attica/source/src/postfiledata.h | 49 + .../kde/kf6-attica/source/src/postjob.cpp | 109 + .../kde/kf6-attica/source/src/postjob.h | 56 + .../kde/kf6-attica/source/src/privatedata.cpp | 73 + .../kde/kf6-attica/source/src/privatedata.h | 73 + .../source/src/privatedataparser.cpp | 41 + .../kf6-attica/source/src/privatedataparser.h | 26 + .../kde/kf6-attica/source/src/project.cpp | 172 ++ .../kde/kf6-attica/source/src/project.h | 84 + .../kf6-attica/source/src/projectparser.cpp | 62 + .../kde/kf6-attica/source/src/projectparser.h | 26 + .../kde/kf6-attica/source/src/provider.cpp | 1858 +++++++++++++++++ .../kde/kf6-attica/source/src/provider.h | 783 +++++++ .../kf6-attica/source/src/providermanager.cpp | 329 +++ .../kf6-attica/source/src/providermanager.h | 181 ++ .../kde/kf6-attica/source/src/publisher.cpp | 100 + .../kde/kf6-attica/source/src/publisher.h | 78 + .../kf6-attica/source/src/publisherfield.cpp | 78 + .../kf6-attica/source/src/publisherfield.h | 52 + .../source/src/publisherfieldparser.cpp | 37 + .../source/src/publisherfieldparser.h | 26 + .../kf6-attica/source/src/publisherparser.cpp | 101 + .../kf6-attica/source/src/publisherparser.h | 26 + .../kde/kf6-attica/source/src/putjob.cpp | 114 + .../kde/kf6-attica/source/src/putjob.h | 56 + .../source/src/qtplatformdependent.cpp | 172 ++ .../source/src/qtplatformdependent_p.h | 60 + .../kf6-attica/source/src/remoteaccount.cpp | 111 + .../kde/kf6-attica/source/src/remoteaccount.h | 67 + .../source/src/remoteaccountparser.cpp | 48 + .../source/src/remoteaccountparser.h | 26 + .../kde/kf6-attica/source/src/topic.cpp | 123 ++ .../recipes/kde/kf6-attica/source/src/topic.h | 66 + .../kde/kf6-attica/source/src/topicparser.cpp | 48 + .../kde/kf6-attica/source/src/topicparser.h | 26 + .../kde/kf6-attica/source/src/version.h.cmake | 93 + .../kf6-attica/source/tests/CMakeLists.txt | 1 + .../source/tests/projecttest/CMakeLists.txt | 18 + .../source/tests/projecttest/editproject.ui | 381 ++++ .../source/tests/projecttest/main.cpp | 18 + .../source/tests/projecttest/projecttest.cpp | 476 +++++ .../source/tests/projecttest/projecttest.h | 86 + local/recipes/kde/kf6-knewstuff/recipe.toml | 13 +- local/scripts/integrate-redbear.sh | 1 + recipes/kde/kf6-attica | 1 + src/recipe.rs | 2 +- 183 files changed, 17533 insertions(+), 9 deletions(-) create mode 100644 local/recipes/kde/kf6-attica/recipe.toml create mode 100644 local/recipes/kde/kf6-attica/source/.git-blame-ignore-revs create mode 100644 local/recipes/kde/kf6-attica/source/.gitignore create mode 100644 local/recipes/kde/kf6-attica/source/.gitlab-ci.yml create mode 100644 local/recipes/kde/kf6-attica/source/.kde-ci.yml create mode 100644 local/recipes/kde/kf6-attica/source/AUTHORS create mode 100644 local/recipes/kde/kf6-attica/source/CMakeLists.txt create mode 100644 local/recipes/kde/kf6-attica/source/ChangeLog create mode 100644 local/recipes/kde/kf6-attica/source/KF6AtticaConfig.cmake.in create mode 100644 local/recipes/kde/kf6-attica/source/LICENSES/CC0-1.0.txt create mode 100644 local/recipes/kde/kf6-attica/source/LICENSES/LGPL-2.0-or-later.txt create mode 100644 local/recipes/kde/kf6-attica/source/LICENSES/LGPL-2.1-only.txt create mode 100644 local/recipes/kde/kf6-attica/source/LICENSES/LGPL-3.0-only.txt create mode 100644 local/recipes/kde/kf6-attica/source/LICENSES/LicenseRef-KDE-Accepted-LGPL.txt create mode 100644 local/recipes/kde/kf6-attica/source/README.md create mode 100644 local/recipes/kde/kf6-attica/source/autotests/CMakeLists.txt create mode 100644 local/recipes/kde/kf6-attica/source/autotests/configtest.cpp create mode 100644 local/recipes/kde/kf6-attica/source/autotests/persontest.cpp create mode 100644 local/recipes/kde/kf6-attica/source/autotests/privatedatatest.cpp create mode 100644 local/recipes/kde/kf6-attica/source/autotests/providertest.cpp create mode 100644 local/recipes/kde/kf6-attica/source/docs/Doxyfile.local create mode 100644 local/recipes/kde/kf6-attica/source/metainfo.yaml create mode 100644 local/recipes/kde/kf6-attica/source/src/CMakeLists.txt create mode 100644 local/recipes/kde/kf6-attica/source/src/accountbalance.cpp create mode 100644 local/recipes/kde/kf6-attica/source/src/accountbalance.h create mode 100644 local/recipes/kde/kf6-attica/source/src/accountbalanceparser.cpp create mode 100644 local/recipes/kde/kf6-attica/source/src/accountbalanceparser.h create mode 100644 local/recipes/kde/kf6-attica/source/src/achievement.cpp create mode 100644 local/recipes/kde/kf6-attica/source/src/achievement.h create mode 100644 local/recipes/kde/kf6-attica/source/src/achievementparser.cpp create mode 100644 local/recipes/kde/kf6-attica/source/src/achievementparser.h create mode 100644 local/recipes/kde/kf6-attica/source/src/activity.cpp create mode 100644 local/recipes/kde/kf6-attica/source/src/activity.h create mode 100644 local/recipes/kde/kf6-attica/source/src/activityparser.cpp create mode 100644 local/recipes/kde/kf6-attica/source/src/activityparser.h create mode 100644 local/recipes/kde/kf6-attica/source/src/atticabasejob.cpp create mode 100644 local/recipes/kde/kf6-attica/source/src/atticabasejob.h create mode 100644 local/recipes/kde/kf6-attica/source/src/atticautils.cpp create mode 100644 local/recipes/kde/kf6-attica/source/src/atticautils.h create mode 100644 local/recipes/kde/kf6-attica/source/src/buildservice.cpp create mode 100644 local/recipes/kde/kf6-attica/source/src/buildservice.h create mode 100644 local/recipes/kde/kf6-attica/source/src/buildservicejob.cpp create mode 100644 local/recipes/kde/kf6-attica/source/src/buildservicejob.h create mode 100644 local/recipes/kde/kf6-attica/source/src/buildservicejoboutput.cpp create mode 100644 local/recipes/kde/kf6-attica/source/src/buildservicejoboutput.h create mode 100644 local/recipes/kde/kf6-attica/source/src/buildservicejoboutputparser.cpp create mode 100644 local/recipes/kde/kf6-attica/source/src/buildservicejoboutputparser.h create mode 100644 local/recipes/kde/kf6-attica/source/src/buildservicejobparser.cpp create mode 100644 local/recipes/kde/kf6-attica/source/src/buildservicejobparser.h create mode 100644 local/recipes/kde/kf6-attica/source/src/buildserviceparser.cpp create mode 100644 local/recipes/kde/kf6-attica/source/src/buildserviceparser.h create mode 100644 local/recipes/kde/kf6-attica/source/src/category.cpp create mode 100644 local/recipes/kde/kf6-attica/source/src/category.h create mode 100644 local/recipes/kde/kf6-attica/source/src/categoryparser.cpp create mode 100644 local/recipes/kde/kf6-attica/source/src/categoryparser.h create mode 100644 local/recipes/kde/kf6-attica/source/src/cloud.cpp create mode 100644 local/recipes/kde/kf6-attica/source/src/cloud.h create mode 100644 local/recipes/kde/kf6-attica/source/src/cloudparser.cpp create mode 100644 local/recipes/kde/kf6-attica/source/src/cloudparser.h create mode 100644 local/recipes/kde/kf6-attica/source/src/comment.cpp create mode 100644 local/recipes/kde/kf6-attica/source/src/comment.h create mode 100644 local/recipes/kde/kf6-attica/source/src/commentparser.cpp create mode 100644 local/recipes/kde/kf6-attica/source/src/commentparser.h create mode 100644 local/recipes/kde/kf6-attica/source/src/config.cpp create mode 100644 local/recipes/kde/kf6-attica/source/src/config.h create mode 100644 local/recipes/kde/kf6-attica/source/src/configparser.cpp create mode 100644 local/recipes/kde/kf6-attica/source/src/configparser.h create mode 100644 local/recipes/kde/kf6-attica/source/src/content.cpp create mode 100644 local/recipes/kde/kf6-attica/source/src/content.h create mode 100644 local/recipes/kde/kf6-attica/source/src/contentparser.cpp create mode 100644 local/recipes/kde/kf6-attica/source/src/contentparser.h create mode 100644 local/recipes/kde/kf6-attica/source/src/deletejob.cpp create mode 100644 local/recipes/kde/kf6-attica/source/src/deletejob.h create mode 100644 local/recipes/kde/kf6-attica/source/src/distribution.cpp create mode 100644 local/recipes/kde/kf6-attica/source/src/distribution.h create mode 100644 local/recipes/kde/kf6-attica/source/src/distributionparser.cpp create mode 100644 local/recipes/kde/kf6-attica/source/src/distributionparser.h create mode 100644 local/recipes/kde/kf6-attica/source/src/downloaddescription.cpp create mode 100644 local/recipes/kde/kf6-attica/source/src/downloaddescription.h create mode 100644 local/recipes/kde/kf6-attica/source/src/downloaditem.cpp create mode 100644 local/recipes/kde/kf6-attica/source/src/downloaditem.h create mode 100644 local/recipes/kde/kf6-attica/source/src/downloaditemparser.cpp create mode 100644 local/recipes/kde/kf6-attica/source/src/downloaditemparser.h create mode 100644 local/recipes/kde/kf6-attica/source/src/event.cpp create mode 100644 local/recipes/kde/kf6-attica/source/src/event.h create mode 100644 local/recipes/kde/kf6-attica/source/src/eventparser.cpp create mode 100644 local/recipes/kde/kf6-attica/source/src/eventparser.h create mode 100644 local/recipes/kde/kf6-attica/source/src/folder.cpp create mode 100644 local/recipes/kde/kf6-attica/source/src/folder.h create mode 100644 local/recipes/kde/kf6-attica/source/src/folderparser.cpp create mode 100644 local/recipes/kde/kf6-attica/source/src/folderparser.h create mode 100644 local/recipes/kde/kf6-attica/source/src/forum.cpp create mode 100644 local/recipes/kde/kf6-attica/source/src/forum.h create mode 100644 local/recipes/kde/kf6-attica/source/src/forumparser.cpp create mode 100644 local/recipes/kde/kf6-attica/source/src/forumparser.h create mode 100644 local/recipes/kde/kf6-attica/source/src/getjob.cpp create mode 100644 local/recipes/kde/kf6-attica/source/src/getjob.h create mode 100644 local/recipes/kde/kf6-attica/source/src/homepageentry.cpp create mode 100644 local/recipes/kde/kf6-attica/source/src/homepageentry.h create mode 100644 local/recipes/kde/kf6-attica/source/src/homepagetype.cpp create mode 100644 local/recipes/kde/kf6-attica/source/src/homepagetype.h create mode 100644 local/recipes/kde/kf6-attica/source/src/homepagetypeparser.cpp create mode 100644 local/recipes/kde/kf6-attica/source/src/homepagetypeparser.h create mode 100644 local/recipes/kde/kf6-attica/source/src/icon.cpp create mode 100644 local/recipes/kde/kf6-attica/source/src/icon.h create mode 100644 local/recipes/kde/kf6-attica/source/src/itemjob.cpp create mode 100644 local/recipes/kde/kf6-attica/source/src/itemjob.h create mode 100644 local/recipes/kde/kf6-attica/source/src/knowledgebaseentry.cpp create mode 100644 local/recipes/kde/kf6-attica/source/src/knowledgebaseentry.h create mode 100644 local/recipes/kde/kf6-attica/source/src/knowledgebaseentryparser.cpp create mode 100644 local/recipes/kde/kf6-attica/source/src/knowledgebaseentryparser.h create mode 100644 local/recipes/kde/kf6-attica/source/src/license.cpp create mode 100644 local/recipes/kde/kf6-attica/source/src/license.h create mode 100644 local/recipes/kde/kf6-attica/source/src/licenseparser.cpp create mode 100644 local/recipes/kde/kf6-attica/source/src/licenseparser.h create mode 100644 local/recipes/kde/kf6-attica/source/src/listjob.cpp create mode 100644 local/recipes/kde/kf6-attica/source/src/listjob.h create mode 100644 local/recipes/kde/kf6-attica/source/src/listjob_inst.cpp create mode 100644 local/recipes/kde/kf6-attica/source/src/message.cpp create mode 100644 local/recipes/kde/kf6-attica/source/src/message.h create mode 100644 local/recipes/kde/kf6-attica/source/src/messageparser.cpp create mode 100644 local/recipes/kde/kf6-attica/source/src/messageparser.h create mode 100644 local/recipes/kde/kf6-attica/source/src/metadata.cpp create mode 100644 local/recipes/kde/kf6-attica/source/src/metadata.h create mode 100644 local/recipes/kde/kf6-attica/source/src/parser.cpp create mode 100644 local/recipes/kde/kf6-attica/source/src/parser.h create mode 100644 local/recipes/kde/kf6-attica/source/src/person.cpp create mode 100644 local/recipes/kde/kf6-attica/source/src/person.h create mode 100644 local/recipes/kde/kf6-attica/source/src/personparser.cpp create mode 100644 local/recipes/kde/kf6-attica/source/src/personparser.h create mode 100644 local/recipes/kde/kf6-attica/source/src/platformdependent.h create mode 100644 local/recipes/kde/kf6-attica/source/src/platformdependent_v2.cpp create mode 100644 local/recipes/kde/kf6-attica/source/src/platformdependent_v2.h create mode 100644 local/recipes/kde/kf6-attica/source/src/platformdependent_v3.cpp create mode 100644 local/recipes/kde/kf6-attica/source/src/platformdependent_v3.h create mode 100644 local/recipes/kde/kf6-attica/source/src/postfiledata.cpp create mode 100644 local/recipes/kde/kf6-attica/source/src/postfiledata.h create mode 100644 local/recipes/kde/kf6-attica/source/src/postjob.cpp create mode 100644 local/recipes/kde/kf6-attica/source/src/postjob.h create mode 100644 local/recipes/kde/kf6-attica/source/src/privatedata.cpp create mode 100644 local/recipes/kde/kf6-attica/source/src/privatedata.h create mode 100644 local/recipes/kde/kf6-attica/source/src/privatedataparser.cpp create mode 100644 local/recipes/kde/kf6-attica/source/src/privatedataparser.h create mode 100644 local/recipes/kde/kf6-attica/source/src/project.cpp create mode 100644 local/recipes/kde/kf6-attica/source/src/project.h create mode 100644 local/recipes/kde/kf6-attica/source/src/projectparser.cpp create mode 100644 local/recipes/kde/kf6-attica/source/src/projectparser.h create mode 100644 local/recipes/kde/kf6-attica/source/src/provider.cpp create mode 100644 local/recipes/kde/kf6-attica/source/src/provider.h create mode 100644 local/recipes/kde/kf6-attica/source/src/providermanager.cpp create mode 100644 local/recipes/kde/kf6-attica/source/src/providermanager.h create mode 100644 local/recipes/kde/kf6-attica/source/src/publisher.cpp create mode 100644 local/recipes/kde/kf6-attica/source/src/publisher.h create mode 100644 local/recipes/kde/kf6-attica/source/src/publisherfield.cpp create mode 100644 local/recipes/kde/kf6-attica/source/src/publisherfield.h create mode 100644 local/recipes/kde/kf6-attica/source/src/publisherfieldparser.cpp create mode 100644 local/recipes/kde/kf6-attica/source/src/publisherfieldparser.h create mode 100644 local/recipes/kde/kf6-attica/source/src/publisherparser.cpp create mode 100644 local/recipes/kde/kf6-attica/source/src/publisherparser.h create mode 100644 local/recipes/kde/kf6-attica/source/src/putjob.cpp create mode 100644 local/recipes/kde/kf6-attica/source/src/putjob.h create mode 100644 local/recipes/kde/kf6-attica/source/src/qtplatformdependent.cpp create mode 100644 local/recipes/kde/kf6-attica/source/src/qtplatformdependent_p.h create mode 100644 local/recipes/kde/kf6-attica/source/src/remoteaccount.cpp create mode 100644 local/recipes/kde/kf6-attica/source/src/remoteaccount.h create mode 100644 local/recipes/kde/kf6-attica/source/src/remoteaccountparser.cpp create mode 100644 local/recipes/kde/kf6-attica/source/src/remoteaccountparser.h create mode 100644 local/recipes/kde/kf6-attica/source/src/topic.cpp create mode 100644 local/recipes/kde/kf6-attica/source/src/topic.h create mode 100644 local/recipes/kde/kf6-attica/source/src/topicparser.cpp create mode 100644 local/recipes/kde/kf6-attica/source/src/topicparser.h create mode 100644 local/recipes/kde/kf6-attica/source/src/version.h.cmake create mode 100644 local/recipes/kde/kf6-attica/source/tests/CMakeLists.txt create mode 100644 local/recipes/kde/kf6-attica/source/tests/projecttest/CMakeLists.txt create mode 100644 local/recipes/kde/kf6-attica/source/tests/projecttest/editproject.ui create mode 100644 local/recipes/kde/kf6-attica/source/tests/projecttest/main.cpp create mode 100644 local/recipes/kde/kf6-attica/source/tests/projecttest/projecttest.cpp create mode 100644 local/recipes/kde/kf6-attica/source/tests/projecttest/projecttest.h create mode 120000 recipes/kde/kf6-attica diff --git a/config/redbear-full.toml b/config/redbear-full.toml index 72cd6ccc..691c276a 100644 --- a/config/redbear-full.toml +++ b/config/redbear-full.toml @@ -53,11 +53,14 @@ qt6-wayland-smoke = {} # KF6 Frameworks — explicit real-build surface in alphabetical order # kirigami: core-only build (QML disabled), needed as build-dep for plasma-framework -# kf6-kio: honest KIOCORE_ONLY build (source-local QtNetwork compat headers) -kirigami = {} +# kf6-kio: honest KIOCORE_ONLY build (QtNetwork now available in qtbase) +kirigami = "ignore" kf6-kio = {} +kf6-knewstuff = {} +kf6-kwallet = {} kdecoration = {} +kf6-attica = {} kf6-karchive = {} kf6-kauth = {} kf6-kbookmarks = {} diff --git a/local/recipes/kde/kf6-attica/recipe.toml b/local/recipes/kde/kf6-attica/recipe.toml new file mode 100644 index 00000000..10a0a60f --- /dev/null +++ b/local/recipes/kde/kf6-attica/recipe.toml @@ -0,0 +1,55 @@ +#TODO: KF6Attica — minimal core library build for Red Bear OS. +# Provides KF6::Attica cmake target needed by kf6-knewstuff. +# QML, tests, and examples disabled. +[source] +tar = "https://invent.kde.org/frameworks/attica/-/archive/v6.10.0/attica-v6.10.0.tar.gz" + +[build] +template = "custom" +dependencies = [ + "qtbase", + "kf6-extra-cmake-modules", + "kf6-kcoreaddons", + "kf6-ki18n", + "kf6-kconfig", +] +script = """ +DYNAMIC_INIT + +HOST_BUILD="${COOKBOOK_ROOT}/build/qt-host-build" + +for qtdir in plugins mkspecs metatypes modules; do + if [ -d "${COOKBOOK_SYSROOT}/usr/${qtdir}" ] && [ ! -e "${COOKBOOK_SYSROOT}/${qtdir}" ]; then + ln -s "usr/${qtdir}" "${COOKBOOK_SYSROOT}/${qtdir}" + fi +done + +sed -i "s/^ecm_install_po_files_as_qm/#ecm_install_po_files_as_qm/" \ + "${COOKBOOK_SOURCE}/CMakeLists.txt" 2>/dev/null || true +sed -i 's/^ki18n_install(po)/#ki18n_install(po)/' \ + "${COOKBOOK_SOURCE}/CMakeLists.txt" 2>/dev/null || true +sed -i '/include(ECMQmlModule)/s/^/#/' "${COOKBOOK_SOURCE}/CMakeLists.txt" 2>/dev/null || true +sed -i '/add_subdirectory(autotests)/s/^/#/' "${COOKBOOK_SOURCE}/CMakeLists.txt" 2>/dev/null || true +sed -i '/add_subdirectory(examples)/s/^/#/' "${COOKBOOK_SOURCE}/CMakeLists.txt" 2>/dev/null || true + +rm -f CMakeCache.txt +rm -rf CMakeFiles + +cmake "${COOKBOOK_SOURCE}" \ + -DCMAKE_TOOLCHAIN_FILE="${COOKBOOK_ROOT}/local/recipes/qt/redox-toolchain.cmake" \ + -DQT_HOST_PATH="${HOST_BUILD}" \ + -DCMAKE_INSTALL_PREFIX=/usr \ + -DCMAKE_BUILD_TYPE=Release \ + -DCMAKE_PREFIX_PATH="${COOKBOOK_SYSROOT}" \ + -DBUILD_TESTING=OFF \ + -DBUILD_QCH=OFF \ + -Wno-dev + +cmake --build . -j${COOKBOOK_MAKE_JOBS} +cmake --install . --prefix "${COOKBOOK_STAGE}/usr" + +for lib in "${COOKBOOK_STAGE}/usr/lib/"libKF6Attica*.so.*; do + [ -f "${lib}" ] || continue + patchelf --remove-rpath "${lib}" 2>/dev/null || true +done +""" diff --git a/local/recipes/kde/kf6-attica/source/.git-blame-ignore-revs b/local/recipes/kde/kf6-attica/source/.git-blame-ignore-revs new file mode 100644 index 00000000..1d867f68 --- /dev/null +++ b/local/recipes/kde/kf6-attica/source/.git-blame-ignore-revs @@ -0,0 +1,4 @@ +#clang-format/tidy +1a83c332f5f67e9b2720cf60a8fe2b917be216f6 +03e3238586140114e64bd5d60e76f91112f542f7 +ad4035e86c84cbd74f0a4f88b14016cc906e1ade diff --git a/local/recipes/kde/kf6-attica/source/.gitignore b/local/recipes/kde/kf6-attica/source/.gitignore new file mode 100644 index 00000000..6aada616 --- /dev/null +++ b/local/recipes/kde/kf6-attica/source/.gitignore @@ -0,0 +1,29 @@ +# Ignore the following files +*~ +*.[oa] +*.diff +*.kate-swp +*.kdev4 +.kdev_include_paths +*.kdevelop.pcs +*.moc +*.moc.cpp +*.orig +*.user +.*.swp +.swp.* +Doxyfile +Makefile +avail +random_seed +/build*/ +CMakeLists.txt.user* +*.unc-backup* +.cmake/ +/.clang-format +/compile_commands.json +.clangd +.idea +.vscode +/cmake-build* +.cache diff --git a/local/recipes/kde/kf6-attica/source/.gitlab-ci.yml b/local/recipes/kde/kf6-attica/source/.gitlab-ci.yml new file mode 100644 index 00000000..0f1b5a84 --- /dev/null +++ b/local/recipes/kde/kf6-attica/source/.gitlab-ci.yml @@ -0,0 +1,11 @@ +# SPDX-FileCopyrightText: 2020 Volker Krause +# SPDX-License-Identifier: CC0-1.0 + +include: + - project: sysadmin/ci-utilities + file: + - /gitlab-templates/linux-qt6.yml + - /gitlab-templates/android-qt6.yml + - /gitlab-templates/freebsd-qt6.yml + - /gitlab-templates/windows-qt6.yml + - /gitlab-templates/alpine-qt6.yml diff --git a/local/recipes/kde/kf6-attica/source/.kde-ci.yml b/local/recipes/kde/kf6-attica/source/.kde-ci.yml new file mode 100644 index 00000000..e52bc323 --- /dev/null +++ b/local/recipes/kde/kf6-attica/source/.kde-ci.yml @@ -0,0 +1,8 @@ +Dependencies: +- 'on': ['@all'] + 'require': + 'frameworks/extra-cmake-modules': '@same' + +Options: + test-before-installing: True + require-passing-tests-on: [ 'Linux', 'FreeBSD', 'Windows' ] diff --git a/local/recipes/kde/kf6-attica/source/AUTHORS b/local/recipes/kde/kf6-attica/source/AUTHORS new file mode 100644 index 00000000..c13851ab --- /dev/null +++ b/local/recipes/kde/kf6-attica/source/AUTHORS @@ -0,0 +1,4 @@ +Sebastian Kügler +Eckhart Wörner +Frederik Gladhorn +Cornelius Schumacher diff --git a/local/recipes/kde/kf6-attica/source/CMakeLists.txt b/local/recipes/kde/kf6-attica/source/CMakeLists.txt new file mode 100644 index 00000000..eba96fae --- /dev/null +++ b/local/recipes/kde/kf6-attica/source/CMakeLists.txt @@ -0,0 +1,102 @@ +cmake_minimum_required(VERSION 3.16) + +set(KF_VERSION "6.10.0") # handled by release scripts +project(Attica VERSION ${KF_VERSION}) + +# ECM setup +include(FeatureSummary) +find_package(ECM 6.10.0 NO_MODULE) +set_package_properties(ECM PROPERTIES TYPE REQUIRED DESCRIPTION "Extra CMake Modules." URL "https://commits.kde.org/extra-cmake-modules") +feature_summary(WHAT REQUIRED_PACKAGES_NOT_FOUND FATAL_ON_MISSING_REQUIRED_PACKAGES) + +set(CMAKE_MODULE_PATH ${ECM_MODULE_PATH}) + +include(KDEInstallDirs) +include(KDECMakeSettings) +include(KDEFrameworkCompilerSettings NO_POLICY_SCOPE) +include(KDEGitCommitHooks) + +include(ECMGenerateExportHeader) +include(ECMGeneratePkgConfigFile) +include(ECMCheckOutboundLicense) +include(ECMSetupVersion) +include(ECMGenerateHeaders) +include(CMakePackageConfigHelpers) # Used to create CMake config files +include(ECMQtDeclareLoggingCategory) +include(ECMDeprecationSettings) +include(ECMAddQch) + +set(EXCLUDE_DEPRECATED_BEFORE_AND_AT 0 CACHE STRING "Control the range of deprecated API excluded from the build [default=0].") + +option(BUILD_QCH "Build API documentation in QCH format (for e.g. Qt Assistant, Qt Creator & KDevelop)" OFF) +add_feature_info(QCH ${BUILD_QCH} "API documentation in QCH format (for e.g. Qt Assistant, Qt Creator & KDevelop)") + +set(attica_version_header "${CMAKE_CURRENT_BINARY_DIR}/src/attica_version.h") +ecm_setup_version(PROJECT + VARIABLE_PREFIX ATTICA + VERSION_HEADER "${attica_version_header}" + PACKAGE_VERSION_FILE "${CMAKE_CURRENT_BINARY_DIR}/KF6AtticaConfigVersion.cmake" + SOVERSION 6) + +# Dependencies +set(REQUIRED_QT_VERSION 6.6.0) + +# Required Qt components to build this framework +find_package(Qt6 ${REQUIRED_QT_VERSION} NO_MODULE REQUIRED Core Network) + +set(ATTICA_LIB_SONAME KF6Attica) + +# Enable static build +option(ATTICA_STATIC_BUILD "Build a static library" Off) + +ecm_set_disabled_deprecation_versions( + QT 6.8 +) + +add_subdirectory(src) + +# Enable unit testing +if (BUILD_TESTING) +# add_subdirectory(autotests) + add_subdirectory(tests) +endif () + +# Create a Config.cmake and a ConfigVersion.cmake file and install them +set(CMAKECONFIG_INSTALL_DIR "${KDE_INSTALL_CMAKEPACKAGEDIR}/KF6Attica") + +# Create the CMake Config files +if (BUILD_QCH) + ecm_install_qch_export( + TARGETS KF6Attica_QCH + FILE KF6AtticaQchTargets.cmake + DESTINATION "${CMAKECONFIG_INSTALL_DIR}" + COMPONENT Devel + ) + set(PACKAGE_INCLUDE_QCHTARGETS "include(\"\${CMAKE_CURRENT_LIST_DIR}/KF6AtticaQchTargets.cmake\")") +endif() + +configure_package_config_file( + "${CMAKE_CURRENT_SOURCE_DIR}/KF6AtticaConfig.cmake.in" + "${CMAKE_CURRENT_BINARY_DIR}/KF6AtticaConfig.cmake" + INSTALL_DESTINATION "${CMAKECONFIG_INSTALL_DIR}" +) + +install(FILES + "${CMAKE_CURRENT_BINARY_DIR}/KF6AtticaConfig.cmake" + "${CMAKE_CURRENT_BINARY_DIR}/KF6AtticaConfigVersion.cmake" + DESTINATION "${CMAKECONFIG_INSTALL_DIR}" + COMPONENT Devel) + +install(EXPORT KF6AtticaTargets + DESTINATION "${CMAKECONFIG_INSTALL_DIR}" + FILE KF6AtticaTargets.cmake + NAMESPACE KF6::) + +install(FILES "${attica_version_header}" + DESTINATION "${KDE_INSTALL_INCLUDEDIR_KF}/Attica" + COMPONENT Devel) + +include(ECMFeatureSummary) +ecm_feature_summary(WHAT ALL FATAL_ON_MISSING_REQUIRED_PACKAGES) + +kde_configure_git_pre_commit_hook(CHECKS CLANG_FORMAT) diff --git a/local/recipes/kde/kf6-attica/source/ChangeLog b/local/recipes/kde/kf6-attica/source/ChangeLog new file mode 100644 index 00000000..f8412127 --- /dev/null +++ b/local/recipes/kde/kf6-attica/source/ChangeLog @@ -0,0 +1,56 @@ +0.4.1 + - Add some Qt5 support in tests. + - Comment out some qDebug calls. + - Fix various Qt5 issues. + +0.4.0 + - Bump soname from 0.3.0 to 0.4.0 for BIC change. + - Don't export non-public header files. + - Fix build of tests. + - Fix compile with Qt5. + - Don't output xml by default. + +0.3.0 + - Bump soname from .0 to .0.3 since we have a BIC change. + +0.2.9 + - Fix upload errors resulting from content-id not being set. + - Add Forum, Achievement, services and related dependencies. + - Make it build against Qt 4.8. + - Add static build option. + +0.2.0 + - Update voting function (add overload) to take uint 0..100 according to ocs 1.6 spec + - Add comments interface to request comments, add new comments and vote for comments + - Add distribution interface to request distributions available in the server + - Add homepagetype interface to request home page types from the server + - Add methods to access home page entries in content + - Add support of icons to content (OCS 1.6) + - Add support of videos to content (OCS 1.6) + - Add summary description to content (OCS 1.6) + - Add size to download description (OCS 1.6) + - Add fields to download item for package name, package repository, gpg fingerprint, mimetype (OCS 1.6) + +0.1.4 + - Remove function decls without body introduced in 0.1.3 + - Add functions to check for provider services (parts of the api they implement) + - Make adding, disabling and removing default providers possible (so we can have other + providers than openDesktop.org) + +0.1.3 + - Add possibility to get Licenses from server + - Add search for contents by username + - Add convenience function to get list of download links and fix some related strings + - Fix qt-only hasCredentials + - Win and Mac compile/link fixes + - Fix crash when multiple apps would use attica simultaneously: do not delete root component of qtplugins + +0.1.2 + - Don't define qHash for QUrl in Qt 4.7 + - fix memlead for aborted requests + - qt platform plugin implements basic password/user name handling + - copying file: lesser gpl 2.1 + - don't link qtgui without reason + - make hasCredentials const (new function) + + diff --git a/local/recipes/kde/kf6-attica/source/KF6AtticaConfig.cmake.in b/local/recipes/kde/kf6-attica/source/KF6AtticaConfig.cmake.in new file mode 100644 index 00000000..ea629250 --- /dev/null +++ b/local/recipes/kde/kf6-attica/source/KF6AtticaConfig.cmake.in @@ -0,0 +1,9 @@ +@PACKAGE_INIT@ + +# Required components to use this framework +include(CMakeFindDependencyMacro) +find_dependency(Qt6Core @REQUIRED_QT_VERSION@) +find_dependency(Qt6Network @REQUIRED_QT_VERSION@) + +include("${CMAKE_CURRENT_LIST_DIR}/KF6AtticaTargets.cmake") +@PACKAGE_INCLUDE_QCHTARGETS@ diff --git a/local/recipes/kde/kf6-attica/source/LICENSES/CC0-1.0.txt b/local/recipes/kde/kf6-attica/source/LICENSES/CC0-1.0.txt new file mode 100644 index 00000000..0e259d42 --- /dev/null +++ b/local/recipes/kde/kf6-attica/source/LICENSES/CC0-1.0.txt @@ -0,0 +1,121 @@ +Creative Commons Legal Code + +CC0 1.0 Universal + + CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE + LEGAL SERVICES. DISTRIBUTION OF THIS DOCUMENT DOES NOT CREATE AN + ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS + INFORMATION ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES + REGARDING THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS + PROVIDED HEREUNDER, AND DISCLAIMS LIABILITY FOR DAMAGES RESULTING FROM + THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS PROVIDED + HEREUNDER. + +Statement of Purpose + +The laws of most jurisdictions throughout the world automatically confer +exclusive Copyright and Related Rights (defined below) upon the creator +and subsequent owner(s) (each and all, an "owner") of an original work of +authorship and/or a database (each, a "Work"). + +Certain owners wish to permanently relinquish those rights to a Work for +the purpose of contributing to a commons of creative, cultural and +scientific works ("Commons") that the public can reliably and without fear +of later claims of infringement build upon, modify, incorporate in other +works, reuse and redistribute as freely as possible in any form whatsoever +and for any purposes, including without limitation commercial purposes. +These owners may contribute to the Commons to promote the ideal of a free +culture and the further production of creative, cultural and scientific +works, or to gain reputation or greater distribution for their Work in +part through the use and efforts of others. + +For these and/or other purposes and motivations, and without any +expectation of additional consideration or compensation, the person +associating CC0 with a Work (the "Affirmer"), to the extent that he or she +is an owner of Copyright and Related Rights in the Work, voluntarily +elects to apply CC0 to the Work and publicly distribute the Work under its +terms, with knowledge of his or her Copyright and Related Rights in the +Work and the meaning and intended legal effect of CC0 on those rights. + +1. Copyright and Related Rights. A Work made available under CC0 may be +protected by copyright and related or neighboring rights ("Copyright and +Related Rights"). Copyright and Related Rights include, but are not +limited to, the following: + + i. the right to reproduce, adapt, distribute, perform, display, + communicate, and translate a Work; + ii. moral rights retained by the original author(s) and/or performer(s); +iii. publicity and privacy rights pertaining to a person's image or + likeness depicted in a Work; + iv. rights protecting against unfair competition in regards to a Work, + subject to the limitations in paragraph 4(a), below; + v. rights protecting the extraction, dissemination, use and reuse of data + in a Work; + vi. database rights (such as those arising under Directive 96/9/EC of the + European Parliament and of the Council of 11 March 1996 on the legal + protection of databases, and under any national implementation + thereof, including any amended or successor version of such + directive); and +vii. other similar, equivalent or corresponding rights throughout the + world based on applicable law or treaty, and any national + implementations thereof. + +2. Waiver. To the greatest extent permitted by, but not in contravention +of, applicable law, Affirmer hereby overtly, fully, permanently, +irrevocably and unconditionally waives, abandons, and surrenders all of +Affirmer's Copyright and Related Rights and associated claims and causes +of action, whether now known or unknown (including existing as well as +future claims and causes of action), in the Work (i) in all territories +worldwide, (ii) for the maximum duration provided by applicable law or +treaty (including future time extensions), (iii) in any current or future +medium and for any number of copies, and (iv) for any purpose whatsoever, +including without limitation commercial, advertising or promotional +purposes (the "Waiver"). Affirmer makes the Waiver for the benefit of each +member of the public at large and to the detriment of Affirmer's heirs and +successors, fully intending that such Waiver shall not be subject to +revocation, rescission, cancellation, termination, or any other legal or +equitable action to disrupt the quiet enjoyment of the Work by the public +as contemplated by Affirmer's express Statement of Purpose. + +3. Public License Fallback. Should any part of the Waiver for any reason +be judged legally invalid or ineffective under applicable law, then the +Waiver shall be preserved to the maximum extent permitted taking into +account Affirmer's express Statement of Purpose. In addition, to the +extent the Waiver is so judged Affirmer hereby grants to each affected +person a royalty-free, non transferable, non sublicensable, non exclusive, +irrevocable and unconditional license to exercise Affirmer's Copyright and +Related Rights in the Work (i) in all territories worldwide, (ii) for the +maximum duration provided by applicable law or treaty (including future +time extensions), (iii) in any current or future medium and for any number +of copies, and (iv) for any purpose whatsoever, including without +limitation commercial, advertising or promotional purposes (the +"License"). The License shall be deemed effective as of the date CC0 was +applied by Affirmer to the Work. Should any part of the License for any +reason be judged legally invalid or ineffective under applicable law, such +partial invalidity or ineffectiveness shall not invalidate the remainder +of the License, and in such case Affirmer hereby affirms that he or she +will not (i) exercise any of his or her remaining Copyright and Related +Rights in the Work or (ii) assert any associated claims and causes of +action with respect to the Work, in either case contrary to Affirmer's +express Statement of Purpose. + +4. Limitations and Disclaimers. + + a. No trademark or patent rights held by Affirmer are waived, abandoned, + surrendered, licensed or otherwise affected by this document. + b. Affirmer offers the Work as-is and makes no representations or + warranties of any kind concerning the Work, express, implied, + statutory or otherwise, including without limitation warranties of + title, merchantability, fitness for a particular purpose, non + infringement, or the absence of latent or other defects, accuracy, or + the present or absence of errors, whether or not discoverable, all to + the greatest extent permissible under applicable law. + c. Affirmer disclaims responsibility for clearing rights of other persons + that may apply to the Work or any use thereof, including without + limitation any person's Copyright and Related Rights in the Work. + Further, Affirmer disclaims responsibility for obtaining any necessary + consents, permissions or other rights required for any use of the + Work. + d. Affirmer understands and acknowledges that Creative Commons is not a + party to this document and has no duty or obligation with respect to + this CC0 or use of the Work. diff --git a/local/recipes/kde/kf6-attica/source/LICENSES/LGPL-2.0-or-later.txt b/local/recipes/kde/kf6-attica/source/LICENSES/LGPL-2.0-or-later.txt new file mode 100644 index 00000000..5c96471a --- /dev/null +++ b/local/recipes/kde/kf6-attica/source/LICENSES/LGPL-2.0-or-later.txt @@ -0,0 +1,446 @@ +GNU LIBRARY GENERAL PUBLIC LICENSE + +Version 2, June 1991 Copyright (C) 1991 Free Software Foundation, Inc. + +51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + +Everyone is permitted to copy and distribute verbatim copies of this license +document, but changing it is not allowed. + +[This is the first released version of the library GPL. It is numbered 2 because +it goes with version 2 of the ordinary GPL.] + +Preamble + +The licenses for most software are designed to take away your freedom to share +and change it. By contrast, the GNU General Public Licenses are intended to +guarantee your freedom to share and change free software--to make sure the +software is free for all its users. + +This license, the Library General Public License, applies to some specially +designated Free Software Foundation software, and to any other libraries whose +authors decide to use it. You can use it for your libraries, too. + +When we speak of free software, we are referring to freedom, not price. Our +General Public Licenses are designed to make sure that you have the freedom +to distribute copies of free software (and charge for this service if you +wish), that you receive source code or can get it if you want it, that you +can change the software or use pieces of it in new free programs; and that +you know you can do these things. + +To protect your rights, we need to make restrictions that forbid anyone to +deny you these rights or to ask you to surrender the rights. These restrictions +translate to certain responsibilities for you if you distribute copies of +the library, or if you modify it. + +For example, if you distribute copies of the library, whether gratis or for +a fee, you must give the recipients all the rights that we gave you. You must +make sure that they, too, receive or can get the source code. If you link +a program with the library, you must provide complete object files to the +recipients so that they can relink them with the library, after making changes +to the library and recompiling it. And you must show them these terms so they +know their rights. + +Our method of protecting your rights has two steps: (1) copyright the library, +and (2) offer you this license which gives you legal permission to copy, distribute +and/or modify the library. + +Also, for each distributor's protection, we want to make certain that everyone +understands that there is no warranty for this free library. If the library +is modified by someone else and passed on, we want its recipients to know +that what they have is not the original version, so that any problems introduced +by others will not reflect on the original authors' reputations. + +Finally, any free program is threatened constantly by software patents. We +wish to avoid the danger that companies distributing free software will individually +obtain patent licenses, thus in effect transforming the program into proprietary +software. To prevent this, we have made it clear that any patent must be licensed +for everyone's free use or not licensed at all. + +Most GNU software, including some libraries, is covered by the ordinary GNU +General Public License, which was designed for utility programs. This license, +the GNU Library General Public License, applies to certain designated libraries. +This license is quite different from the ordinary one; be sure to read it +in full, and don't assume that anything in it is the same as in the ordinary +license. + +The reason we have a separate public license for some libraries is that they +blur the distinction we usually make between modifying or adding to a program +and simply using it. Linking a program with a library, without changing the +library, is in some sense simply using the library, and is analogous to running +a utility program or application program. However, in a textual and legal +sense, the linked executable is a combined work, a derivative of the original +library, and the ordinary General Public License treats it as such. + +Because of this blurred distinction, using the ordinary General Public License +for libraries did not effectively promote software sharing, because most developers +did not use the libraries. We concluded that weaker conditions might promote +sharing better. + +However, unrestricted linking of non-free programs would deprive the users +of those programs of all benefit from the free status of the libraries themselves. +This Library General Public License is intended to permit developers of non-free +programs to use free libraries, while preserving your freedom as a user of +such programs to change the free libraries that are incorporated in them. +(We have not seen how to achieve this as regards changes in header files, +but we have achieved it as regards changes in the actual functions of the +Library.) The hope is that this will lead to faster development of free libraries. + +The precise terms and conditions for copying, distribution and modification +follow. Pay close attention to the difference between a "work based on the +library" and a "work that uses the library". The former contains code derived +from the library, while the latter only works together with the library. + +Note that it is possible for a library to be covered by the ordinary General +Public License rather than by this special one. + +TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + +0. This License Agreement applies to any software library which contains a +notice placed by the copyright holder or other authorized party saying it +may be distributed under the terms of this Library General Public License +(also called "this License"). Each licensee is addressed as "you". + +A "library" means a collection of software functions and/or data prepared +so as to be conveniently linked with application programs (which use some +of those functions and data) to form executables. + +The "Library", below, refers to any such software library or work which has +been distributed under these terms. A "work based on the Library" means either +the Library or any derivative work under copyright law: that is to say, a +work containing the Library or a portion of it, either verbatim or with modifications +and/or translated straightforwardly into another language. (Hereinafter, translation +is included without limitation in the term "modification".) + +"Source code" for a work means the preferred form of the work for making modifications +to it. For a library, complete source code means all the source code for all +modules it contains, plus any associated interface definition files, plus +the scripts used to control compilation and installation of the library. + +Activities other than copying, distribution and modification are not covered +by this License; they are outside its scope. The act of running a program +using the Library is not restricted, and output from such a program is covered +only if its contents constitute a work based on the Library (independent of +the use of the Library in a tool for writing it). Whether that is true depends +on what the Library does and what the program that uses the Library does. + +1. You may copy and distribute verbatim copies of the Library's complete source +code as you receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice and disclaimer +of warranty; keep intact all the notices that refer to this License and to +the absence of any warranty; and distribute a copy of this License along with +the Library. + +You may charge a fee for the physical act of transferring a copy, and you +may at your option offer warranty protection in exchange for a fee. + +2. You may modify your copy or copies of the Library or any portion of it, +thus forming a work based on the Library, and copy and distribute such modifications +or work under the terms of Section 1 above, provided that you also meet all +of these conditions: + + a) The modified work must itself be a software library. + +b) You must cause the files modified to carry prominent notices stating that +you changed the files and the date of any change. + +c) You must cause the whole of the work to be licensed at no charge to all +third parties under the terms of this License. + +d) If a facility in the modified Library refers to a function or a table of +data to be supplied by an application program that uses the facility, other +than as an argument passed when the facility is invoked, then you must make +a good faith effort to ensure that, in the event an application does not supply +such function or table, the facility still operates, and performs whatever +part of its purpose remains meaningful. + +(For example, a function in a library to compute square roots has a purpose +that is entirely well-defined independent of the application. Therefore, Subsection +2d requires that any application-supplied function or table used by this function +must be optional: if the application does not supply it, the square root function +must still compute square roots.) + +These requirements apply to the modified work as a whole. If identifiable +sections of that work are not derived from the Library, and can be reasonably +considered independent and separate works in themselves, then this License, +and its terms, do not apply to those sections when you distribute them as +separate works. But when you distribute the same sections as part of a whole +which is a work based on the Library, the distribution of the whole must be +on the terms of this License, whose permissions for other licensees extend +to the entire whole, and thus to each and every part regardless of who wrote +it. + +Thus, it is not the intent of this section to claim rights or contest your +rights to work written entirely by you; rather, the intent is to exercise +the right to control the distribution of derivative or collective works based +on the Library. + +In addition, mere aggregation of another work not based on the Library with +the Library (or with a work based on the Library) on a volume of a storage +or distribution medium does not bring the other work under the scope of this +License. + +3. You may opt to apply the terms of the ordinary GNU General Public License +instead of this License to a given copy of the Library. To do this, you must +alter all the notices that refer to this License, so that they refer to the +ordinary GNU General Public License, version 2, instead of to this License. +(If a newer version than version 2 of the ordinary GNU General Public License +has appeared, then you can specify that version instead if you wish.) Do not +make any other change in these notices. + +Once this change is made in a given copy, it is irreversible for that copy, +so the ordinary GNU General Public License applies to all subsequent copies +and derivative works made from that copy. + +This option is useful when you wish to copy part of the code of the Library +into a program that is not a library. + +4. You may copy and distribute the Library (or a portion or derivative of +it, under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you accompany it with the complete corresponding +machine-readable source code, which must be distributed under the terms of +Sections 1 and 2 above on a medium customarily used for software interchange. + +If distribution of object code is made by offering access to copy from a designated +place, then offering equivalent access to copy the source code from the same +place satisfies the requirement to distribute the source code, even though +third parties are not compelled to copy the source along with the object code. + +5. A program that contains no derivative of any portion of the Library, but +is designed to work with the Library by being compiled or linked with it, +is called a "work that uses the Library". Such a work, in isolation, is not +a derivative work of the Library, and therefore falls outside the scope of +this License. + +However, linking a "work that uses the Library" with the Library creates an +executable that is a derivative of the Library (because it contains portions +of the Library), rather than a "work that uses the library". The executable +is therefore covered by this License. Section 6 states terms for distribution +of such executables. + +When a "work that uses the Library" uses material from a header file that +is part of the Library, the object code for the work may be a derivative work +of the Library even though the source code is not. Whether this is true is +especially significant if the work can be linked without the Library, or if +the work is itself a library. The threshold for this to be true is not precisely +defined by law. + +If such an object file uses only numerical parameters, data structure layouts +and accessors, and small macros and small inline functions (ten lines or less +in length), then the use of the object file is unrestricted, regardless of +whether it is legally a derivative work. (Executables containing this object +code plus portions of the Library will still fall under Section 6.) + +Otherwise, if the work is a derivative of the Library, you may distribute +the object code for the work under the terms of Section 6. Any executables +containing that work also fall under Section 6, whether or not they are linked +directly with the Library itself. + +6. As an exception to the Sections above, you may also compile or link a "work +that uses the Library" with the Library to produce a work containing portions +of the Library, and distribute that work under terms of your choice, provided +that the terms permit modification of the work for the customer's own use +and reverse engineering for debugging such modifications. + +You must give prominent notice with each copy of the work that the Library +is used in it and that the Library and its use are covered by this License. +You must supply a copy of this License. If the work during execution displays +copyright notices, you must include the copyright notice for the Library among +them, as well as a reference directing the user to the copy of this License. +Also, you must do one of these things: + +a) Accompany the work with the complete corresponding machine-readable source +code for the Library including whatever changes were used in the work (which +must be distributed under Sections 1 and 2 above); and, if the work is an +executable linked with the Library, with the complete machine-readable "work +that uses the Library", as object code and/or source code, so that the user +can modify the Library and then relink to produce a modified executable containing +the modified Library. (It is understood that the user who changes the contents +of definitions files in the Library will not necessarily be able to recompile +the application to use the modified definitions.) + +b) Accompany the work with a written offer, valid for at least three years, +to give the same user the materials specified in Subsection 6a, above, for +a charge no more than the cost of performing this distribution. + +c) If distribution of the work is made by offering access to copy from a designated +place, offer equivalent access to copy the above specified materials from +the same place. + +d) Verify that the user has already received a copy of these materials or +that you have already sent this user a copy. + +For an executable, the required form of the "work that uses the Library" must +include any data and utility programs needed for reproducing the executable +from it. However, as a special exception, the source code distributed need +not include anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the operating +system on which the executable runs, unless that component itself accompanies +the executable. + +It may happen that this requirement contradicts the license restrictions of +other proprietary libraries that do not normally accompany the operating system. +Such a contradiction means you cannot use both them and the Library together +in an executable that you distribute. + +7. You may place library facilities that are a work based on the Library side-by-side +in a single library together with other library facilities not covered by +this License, and distribute such a combined library, provided that the separate +distribution of the work based on the Library and of the other library facilities +is otherwise permitted, and provided that you do these two things: + +a) Accompany the combined library with a copy of the same work based on the +Library, uncombined with any other library facilities. This must be distributed +under the terms of the Sections above. + +b) Give prominent notice with the combined library of the fact that part of +it is a work based on the Library, and explaining where to find the accompanying +uncombined form of the same work. + +8. You may not copy, modify, sublicense, link with, or distribute the Library +except as expressly provided under this License. Any attempt otherwise to +copy, modify, sublicense, link with, or distribute the Library is void, and +will automatically terminate your rights under this License. However, parties +who have received copies, or rights, from you under this License will not +have their licenses terminated so long as such parties remain in full compliance. + +9. You are not required to accept this License, since you have not signed +it. However, nothing else grants you permission to modify or distribute the +Library or its derivative works. These actions are prohibited by law if you +do not accept this License. Therefore, by modifying or distributing the Library +(or any work based on the Library), you indicate your acceptance of this License +to do so, and all its terms and conditions for copying, distributing or modifying +the Library or works based on it. + +10. Each time you redistribute the Library (or any work based on the Library), +the recipient automatically receives a license from the original licensor +to copy, distribute, link with or modify the Library subject to these terms +and conditions. You may not impose any further restrictions on the recipients' +exercise of the rights granted herein. You are not responsible for enforcing +compliance by third parties to this License. + +11. If, as a consequence of a court judgment or allegation of patent infringement +or for any other reason (not limited to patent issues), conditions are imposed +on you (whether by court order, agreement or otherwise) that contradict the +conditions of this License, they do not excuse you from the conditions of +this License. If you cannot distribute so as to satisfy simultaneously your +obligations under this License and any other pertinent obligations, then as +a consequence you may not distribute the Library at all. For example, if a +patent license would not permit royalty-free redistribution of the Library +by all those who receive copies directly or indirectly through you, then the +only way you could satisfy both it and this License would be to refrain entirely +from distribution of the Library. + +If any portion of this section is held invalid or unenforceable under any +particular circumstance, the balance of the section is intended to apply, +and the section as a whole is intended to apply in other circumstances. + +It is not the purpose of this section to induce you to infringe any patents +or other property right claims or to contest validity of any such claims; +this section has the sole purpose of protecting the integrity of the free +software distribution system which is implemented by public license practices. +Many people have made generous contributions to the wide range of software +distributed through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing to +distribute software through any other system and a licensee cannot impose +that choice. + +This section is intended to make thoroughly clear what is believed to be a +consequence of the rest of this License. + +12. If the distribution and/or use of the Library is restricted in certain +countries either by patents or by copyrighted interfaces, the original copyright +holder who places the Library under this License may add an explicit geographical +distribution limitation excluding those countries, so that distribution is +permitted only in or among countries not thus excluded. In such case, this +License incorporates the limitation as if written in the body of this License. + +13. The Free Software Foundation may publish revised and/or new versions of +the Library General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to address +new problems or concerns. + +Each version is given a distinguishing version number. If the Library specifies +a version number of this License which applies to it and "any later version", +you have the option of following the terms and conditions either of that version +or of any later version published by the Free Software Foundation. If the +Library does not specify a license version number, you may choose any version +ever published by the Free Software Foundation. + +14. If you wish to incorporate parts of the Library into other free programs +whose distribution conditions are incompatible with these, write to the author +to ask for permission. For software which is copyrighted by the Free Software +Foundation, write to the Free Software Foundation; we sometimes make exceptions +for this. Our decision will be guided by the two goals of preserving the free +status of all derivatives of our free software and of promoting the sharing +and reuse of software generally. + + NO WARRANTY + +15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR +THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE +STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE LIBRARY +"AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, +BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE +OF THE LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + +16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE +THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE +OR INABILITY TO USE THE LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA +OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES +OR A FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF SUCH +HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. +END OF TERMS AND CONDITIONS + +How to Apply These Terms to Your New Libraries + +If you develop a new library, and you want it to be of the greatest possible +use to the public, we recommend making it free software that everyone can +redistribute and change. You can do so by permitting redistribution under +these terms (or, alternatively, under the terms of the ordinary General Public +License). + +To apply these terms, attach the following notices to the library. It is safest +to attach them to the start of each source file to most effectively convey +the exclusion of warranty; and each file should have at least the "copyright" +line and a pointer to where the full notice is found. + +one line to give the library's name and an idea of what it does. + +Copyright (C) year name of author + +This library is free software; you can redistribute it and/or modify it under +the terms of the GNU Library General Public License as published by the Free +Software Foundation; either version 2 of the License, or (at your option) +any later version. + +This library is distributed in the hope that it will be useful, but WITHOUT +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more +details. + +You should have received a copy of the GNU Library General Public License +along with this library; if not, write to the Free Software Foundation, Inc., +51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. + +Also add information on how to contact you by electronic and paper mail. + +You should also get your employer (if you work as a programmer) or your school, +if any, to sign a "copyright disclaimer" for the library, if necessary. Here +is a sample; alter the names: + +Yoyodyne, Inc., hereby disclaims all copyright interest in + +the library `Frob' (a library for tweaking knobs) written + +by James Random Hacker. + +signature of Ty Coon, 1 April 1990 + +Ty Coon, President of Vice + +That's all there is to it! diff --git a/local/recipes/kde/kf6-attica/source/LICENSES/LGPL-2.1-only.txt b/local/recipes/kde/kf6-attica/source/LICENSES/LGPL-2.1-only.txt new file mode 100644 index 00000000..130dffb3 --- /dev/null +++ b/local/recipes/kde/kf6-attica/source/LICENSES/LGPL-2.1-only.txt @@ -0,0 +1,467 @@ +GNU LESSER GENERAL PUBLIC LICENSE + +Version 2.1, February 1999 + +Copyright (C) 1991, 1999 Free Software Foundation, Inc. + +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +Everyone is permitted to copy and distribute verbatim copies of this license +document, but changing it is not allowed. + +[This is the first released version of the Lesser GPL. It also counts as the +successor of the GNU Library Public License, version 2, hence the version +number 2.1.] + +Preamble + +The licenses for most software are designed to take away your freedom to share +and change it. By contrast, the GNU General Public Licenses are intended to +guarantee your freedom to share and change free software--to make sure the +software is free for all its users. + +This license, the Lesser General Public License, applies to some specially +designated software packages--typically libraries--of the Free Software Foundation +and other authors who decide to use it. You can use it too, but we suggest +you first think carefully about whether this license or the ordinary General +Public License is the better strategy to use in any particular case, based +on the explanations below. + +When we speak of free software, we are referring to freedom of use, not price. +Our General Public Licenses are designed to make sure that you have the freedom +to distribute copies of free software (and charge for this service if you +wish); that you receive source code or can get it if you want it; that you +can change the software and use pieces of it in new free programs; and that +you are informed that you can do these things. + +To protect your rights, we need to make restrictions that forbid distributors +to deny you these rights or to ask you to surrender these rights. These restrictions +translate to certain responsibilities for you if you distribute copies of +the library or if you modify it. + +For example, if you distribute copies of the library, whether gratis or for +a fee, you must give the recipients all the rights that we gave you. You must +make sure that they, too, receive or can get the source code. If you link +other code with the library, you must provide complete object files to the +recipients, so that they can relink them with the library after making changes +to the library and recompiling it. And you must show them these terms so they +know their rights. + +We protect your rights with a two-step method: (1) we copyright the library, +and (2) we offer you this license, which gives you legal permission to copy, +distribute and/or modify the library. + +To protect each distributor, we want to make it very clear that there is no +warranty for the free library. Also, if the library is modified by someone +else and passed on, the recipients should know that what they have is not +the original version, so that the original author's reputation will not be +affected by problems that might be introduced by others. + +Finally, software patents pose a constant threat to the existence of any free +program. We wish to make sure that a company cannot effectively restrict the +users of a free program by obtaining a restrictive license from a patent holder. +Therefore, we insist that any patent license obtained for a version of the +library must be consistent with the full freedom of use specified in this +license. + +Most GNU software, including some libraries, is covered by the ordinary GNU +General Public License. This license, the GNU Lesser General Public License, +applies to certain designated libraries, and is quite different from the ordinary +General Public License. We use this license for certain libraries in order +to permit linking those libraries into non-free programs. + +When a program is linked with a library, whether statically or using a shared +library, the combination of the two is legally speaking a combined work, a +derivative of the original library. The ordinary General Public License therefore +permits such linking only if the entire combination fits its criteria of freedom. +The Lesser General Public License permits more lax criteria for linking other +code with the library. + +We call this license the "Lesser" General Public License because it does Less +to protect the user's freedom than the ordinary General Public License. It +also provides other free software developers Less of an advantage over competing +non-free programs. These disadvantages are the reason we use the ordinary +General Public License for many libraries. However, the Lesser license provides +advantages in certain special circumstances. + +For example, on rare occasions, there may be a special need to encourage the +widest possible use of a certain library, so that it becomes a de-facto standard. +To achieve this, non-free programs must be allowed to use the library. A more +frequent case is that a free library does the same job as widely used non-free +libraries. In this case, there is little to gain by limiting the free library +to free software only, so we use the Lesser General Public License. + +In other cases, permission to use a particular library in non-free programs +enables a greater number of people to use a large body of free software. For +example, permission to use the GNU C Library in non-free programs enables +many more people to use the whole GNU operating system, as well as its variant, +the GNU/Linux operating system. + +Although the Lesser General Public License is Less protective of the users' +freedom, it does ensure that the user of a program that is linked with the +Library has the freedom and the wherewithal to run that program using a modified +version of the Library. + +The precise terms and conditions for copying, distribution and modification +follow. Pay close attention to the difference between a "work based on the +library" and a "work that uses the library". The former contains code derived +from the library, whereas the latter must be combined with the library in +order to run. + +TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + +0. This License Agreement applies to any software library or other program +which contains a notice placed by the copyright holder or other authorized +party saying it may be distributed under the terms of this Lesser General +Public License (also called "this License"). Each licensee is addressed as +"you". + +A "library" means a collection of software functions and/or data prepared +so as to be conveniently linked with application programs (which use some +of those functions and data) to form executables. + +The "Library", below, refers to any such software library or work which has +been distributed under these terms. A "work based on the Library" means either +the Library or any derivative work under copyright law: that is to say, a +work containing the Library or a portion of it, either verbatim or with modifications +and/or translated straightforwardly into another language. (Hereinafter, translation +is included without limitation in the term "modification".) + +"Source code" for a work means the preferred form of the work for making modifications +to it. For a library, complete source code means all the source code for all +modules it contains, plus any associated interface definition files, plus +the scripts used to control compilation and installation of the library. + +Activities other than copying, distribution and modification are not covered +by this License; they are outside its scope. The act of running a program +using the Library is not restricted, and output from such a program is covered +only if its contents constitute a work based on the Library (independent of +the use of the Library in a tool for writing it). Whether that is true depends +on what the Library does and what the program that uses the Library does. + +1. You may copy and distribute verbatim copies of the Library's complete source +code as you receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice and disclaimer +of warranty; keep intact all the notices that refer to this License and to +the absence of any warranty; and distribute a copy of this License along with +the Library. + +You may charge a fee for the physical act of transferring a copy, and you +may at your option offer warranty protection in exchange for a fee. + +2. You may modify your copy or copies of the Library or any portion of it, +thus forming a work based on the Library, and copy and distribute such modifications +or work under the terms of Section 1 above, provided that you also meet all +of these conditions: + + a) The modified work must itself be a software library. + +b) You must cause the files modified to carry prominent notices stating that +you changed the files and the date of any change. + +c) You must cause the whole of the work to be licensed at no charge to all +third parties under the terms of this License. + +d) If a facility in the modified Library refers to a function or a table of +data to be supplied by an application program that uses the facility, other +than as an argument passed when the facility is invoked, then you must make +a good faith effort to ensure that, in the event an application does not supply +such function or table, the facility still operates, and performs whatever +part of its purpose remains meaningful. + +(For example, a function in a library to compute square roots has a purpose +that is entirely well-defined independent of the application. Therefore, Subsection +2d requires that any application-supplied function or table used by this function +must be optional: if the application does not supply it, the square root function +must still compute square roots.) + +These requirements apply to the modified work as a whole. If identifiable +sections of that work are not derived from the Library, and can be reasonably +considered independent and separate works in themselves, then this License, +and its terms, do not apply to those sections when you distribute them as +separate works. But when you distribute the same sections as part of a whole +which is a work based on the Library, the distribution of the whole must be +on the terms of this License, whose permissions for other licensees extend +to the entire whole, and thus to each and every part regardless of who wrote +it. + +Thus, it is not the intent of this section to claim rights or contest your +rights to work written entirely by you; rather, the intent is to exercise +the right to control the distribution of derivative or collective works based +on the Library. + +In addition, mere aggregation of another work not based on the Library with +the Library (or with a work based on the Library) on a volume of a storage +or distribution medium does not bring the other work under the scope of this +License. + +3. You may opt to apply the terms of the ordinary GNU General Public License +instead of this License to a given copy of the Library. To do this, you must +alter all the notices that refer to this License, so that they refer to the +ordinary GNU General Public License, version 2, instead of to this License. +(If a newer version than version 2 of the ordinary GNU General Public License +has appeared, then you can specify that version instead if you wish.) Do not +make any other change in these notices. + +Once this change is made in a given copy, it is irreversible for that copy, +so the ordinary GNU General Public License applies to all subsequent copies +and derivative works made from that copy. + +This option is useful when you wish to copy part of the code of the Library +into a program that is not a library. + +4. You may copy and distribute the Library (or a portion or derivative of +it, under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you accompany it with the complete corresponding +machine-readable source code, which must be distributed under the terms of +Sections 1 and 2 above on a medium customarily used for software interchange. + +If distribution of object code is made by offering access to copy from a designated +place, then offering equivalent access to copy the source code from the same +place satisfies the requirement to distribute the source code, even though +third parties are not compelled to copy the source along with the object code. + +5. A program that contains no derivative of any portion of the Library, but +is designed to work with the Library by being compiled or linked with it, +is called a "work that uses the Library". Such a work, in isolation, is not +a derivative work of the Library, and therefore falls outside the scope of +this License. + +However, linking a "work that uses the Library" with the Library creates an +executable that is a derivative of the Library (because it contains portions +of the Library), rather than a "work that uses the library". The executable +is therefore covered by this License. Section 6 states terms for distribution +of such executables. + +When a "work that uses the Library" uses material from a header file that +is part of the Library, the object code for the work may be a derivative work +of the Library even though the source code is not. Whether this is true is +especially significant if the work can be linked without the Library, or if +the work is itself a library. The threshold for this to be true is not precisely +defined by law. + +If such an object file uses only numerical parameters, data structure layouts +and accessors, and small macros and small inline functions (ten lines or less +in length), then the use of the object file is unrestricted, regardless of +whether it is legally a derivative work. (Executables containing this object +code plus portions of the Library will still fall under Section 6.) + +Otherwise, if the work is a derivative of the Library, you may distribute +the object code for the work under the terms of Section 6. Any executables +containing that work also fall under Section 6, whether or not they are linked +directly with the Library itself. + +6. As an exception to the Sections above, you may also combine or link a "work +that uses the Library" with the Library to produce a work containing portions +of the Library, and distribute that work under terms of your choice, provided +that the terms permit modification of the work for the customer's own use +and reverse engineering for debugging such modifications. + +You must give prominent notice with each copy of the work that the Library +is used in it and that the Library and its use are covered by this License. +You must supply a copy of this License. If the work during execution displays +copyright notices, you must include the copyright notice for the Library among +them, as well as a reference directing the user to the copy of this License. +Also, you must do one of these things: + +a) Accompany the work with the complete corresponding machine-readable source +code for the Library including whatever changes were used in the work (which +must be distributed under Sections 1 and 2 above); and, if the work is an +executable linked with the Library, with the complete machine-readable "work +that uses the Library", as object code and/or source code, so that the user +can modify the Library and then relink to produce a modified executable containing +the modified Library. (It is understood that the user who changes the contents +of definitions files in the Library will not necessarily be able to recompile +the application to use the modified definitions.) + +b) Use a suitable shared library mechanism for linking with the Library. A +suitable mechanism is one that (1) uses at run time a copy of the library +already present on the user's computer system, rather than copying library +functions into the executable, and (2) will operate properly with a modified +version of the library, if the user installs one, as long as the modified +version is interface-compatible with the version that the work was made with. + +c) Accompany the work with a written offer, valid for at least three years, +to give the same user the materials specified in Subsection 6a, above, for +a charge no more than the cost of performing this distribution. + +d) If distribution of the work is made by offering access to copy from a designated +place, offer equivalent access to copy the above specified materials from +the same place. + +e) Verify that the user has already received a copy of these materials or +that you have already sent this user a copy. + +For an executable, the required form of the "work that uses the Library" must +include any data and utility programs needed for reproducing the executable +from it. However, as a special exception, the materials to be distributed +need not include anything that is normally distributed (in either source or +binary form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component itself +accompanies the executable. + +It may happen that this requirement contradicts the license restrictions of +other proprietary libraries that do not normally accompany the operating system. +Such a contradiction means you cannot use both them and the Library together +in an executable that you distribute. + +7. You may place library facilities that are a work based on the Library side-by-side +in a single library together with other library facilities not covered by +this License, and distribute such a combined library, provided that the separate +distribution of the work based on the Library and of the other library facilities +is otherwise permitted, and provided that you do these two things: + +a) Accompany the combined library with a copy of the same work based on the +Library, uncombined with any other library facilities. This must be distributed +under the terms of the Sections above. + +b) Give prominent notice with the combined library of the fact that part of +it is a work based on the Library, and explaining where to find the accompanying +uncombined form of the same work. + +8. You may not copy, modify, sublicense, link with, or distribute the Library +except as expressly provided under this License. Any attempt otherwise to +copy, modify, sublicense, link with, or distribute the Library is void, and +will automatically terminate your rights under this License. However, parties +who have received copies, or rights, from you under this License will not +have their licenses terminated so long as such parties remain in full compliance. + +9. You are not required to accept this License, since you have not signed +it. However, nothing else grants you permission to modify or distribute the +Library or its derivative works. These actions are prohibited by law if you +do not accept this License. Therefore, by modifying or distributing the Library +(or any work based on the Library), you indicate your acceptance of this License +to do so, and all its terms and conditions for copying, distributing or modifying +the Library or works based on it. + +10. Each time you redistribute the Library (or any work based on the Library), +the recipient automatically receives a license from the original licensor +to copy, distribute, link with or modify the Library subject to these terms +and conditions. You may not impose any further restrictions on the recipients' +exercise of the rights granted herein. You are not responsible for enforcing +compliance by third parties with this License. + +11. If, as a consequence of a court judgment or allegation of patent infringement +or for any other reason (not limited to patent issues), conditions are imposed +on you (whether by court order, agreement or otherwise) that contradict the +conditions of this License, they do not excuse you from the conditions of +this License. If you cannot distribute so as to satisfy simultaneously your +obligations under this License and any other pertinent obligations, then as +a consequence you may not distribute the Library at all. For example, if a +patent license would not permit royalty-free redistribution of the Library +by all those who receive copies directly or indirectly through you, then the +only way you could satisfy both it and this License would be to refrain entirely +from distribution of the Library. + +If any portion of this section is held invalid or unenforceable under any +particular circumstance, the balance of the section is intended to apply, +and the section as a whole is intended to apply in other circumstances. + +It is not the purpose of this section to induce you to infringe any patents +or other property right claims or to contest validity of any such claims; +this section has the sole purpose of protecting the integrity of the free +software distribution system which is implemented by public license practices. +Many people have made generous contributions to the wide range of software +distributed through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing to +distribute software through any other system and a licensee cannot impose +that choice. + +This section is intended to make thoroughly clear what is believed to be a +consequence of the rest of this License. + +12. If the distribution and/or use of the Library is restricted in certain +countries either by patents or by copyrighted interfaces, the original copyright +holder who places the Library under this License may add an explicit geographical +distribution limitation excluding those countries, so that distribution is +permitted only in or among countries not thus excluded. In such case, this +License incorporates the limitation as if written in the body of this License. + +13. The Free Software Foundation may publish revised and/or new versions of +the Lesser General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to address +new problems or concerns. + +Each version is given a distinguishing version number. If the Library specifies +a version number of this License which applies to it and "any later version", +you have the option of following the terms and conditions either of that version +or of any later version published by the Free Software Foundation. If the +Library does not specify a license version number, you may choose any version +ever published by the Free Software Foundation. + +14. If you wish to incorporate parts of the Library into other free programs +whose distribution conditions are incompatible with these, write to the author +to ask for permission. For software which is copyrighted by the Free Software +Foundation, write to the Free Software Foundation; we sometimes make exceptions +for this. Our decision will be guided by the two goals of preserving the free +status of all derivatives of our free software and of promoting the sharing +and reuse of software generally. + + NO WARRANTY + +15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR +THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE +STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE LIBRARY +"AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, +BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE +OF THE LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + +16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE +THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE +OR INABILITY TO USE THE LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA +OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES +OR A FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF SUCH +HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. +END OF TERMS AND CONDITIONS + +How to Apply These Terms to Your New Libraries + +If you develop a new library, and you want it to be of the greatest possible +use to the public, we recommend making it free software that everyone can +redistribute and change. You can do so by permitting redistribution under +these terms (or, alternatively, under the terms of the ordinary General Public +License). + +To apply these terms, attach the following notices to the library. It is safest +to attach them to the start of each source file to most effectively convey +the exclusion of warranty; and each file should have at least the "copyright" +line and a pointer to where the full notice is found. + +< one line to give the library's name and an idea of what it does. > + +Copyright (C) < year > < name of author > + +This library is free software; you can redistribute it and/or modify it under +the terms of the GNU Lesser General Public License as published by the Free +Software Foundation; either version 2.1 of the License, or (at your option) +any later version. + +This library is distributed in the hope that it will be useful, but WITHOUT +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more +details. + +You should have received a copy of the GNU Lesser General Public License along +with this library; if not, write to the Free Software Foundation, Inc., 51 +Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Also add information +on how to contact you by electronic and paper mail. + +You should also get your employer (if you work as a programmer) or your school, +if any, to sign a "copyright disclaimer" for the library, if necessary. Here +is a sample; alter the names: + +Yoyodyne, Inc., hereby disclaims all copyright interest in + +the library `Frob' (a library for tweaking knobs) written + +by James Random Hacker. + +< signature of Ty Coon > , 1 April 1990 + +Ty Coon, President of Vice + +That's all there is to it! diff --git a/local/recipes/kde/kf6-attica/source/LICENSES/LGPL-3.0-only.txt b/local/recipes/kde/kf6-attica/source/LICENSES/LGPL-3.0-only.txt new file mode 100644 index 00000000..bd405afb --- /dev/null +++ b/local/recipes/kde/kf6-attica/source/LICENSES/LGPL-3.0-only.txt @@ -0,0 +1,163 @@ +GNU LESSER GENERAL PUBLIC LICENSE + +Version 3, 29 June 2007 + +Copyright (C) 2007 Free Software Foundation, Inc. + +Everyone is permitted to copy and distribute verbatim copies of this license +document, but changing it is not allowed. + +This version of the GNU Lesser General Public License incorporates the terms +and conditions of version 3 of the GNU General Public License, supplemented +by the additional permissions listed below. + + 0. Additional Definitions. + + + +As used herein, "this License" refers to version 3 of the GNU Lesser General +Public License, and the "GNU GPL" refers to version 3 of the GNU General Public +License. + + + +"The Library" refers to a covered work governed by this License, other than +an Application or a Combined Work as defined below. + + + +An "Application" is any work that makes use of an interface provided by the +Library, but which is not otherwise based on the Library. Defining a subclass +of a class defined by the Library is deemed a mode of using an interface provided +by the Library. + + + +A "Combined Work" is a work produced by combining or linking an Application +with the Library. The particular version of the Library with which the Combined +Work was made is also called the "Linked Version". + + + +The "Minimal Corresponding Source" for a Combined Work means the Corresponding +Source for the Combined Work, excluding any source code for portions of the +Combined Work that, considered in isolation, are based on the Application, +and not on the Linked Version. + + + +The "Corresponding Application Code" for a Combined Work means the object +code and/or source code for the Application, including any data and utility +programs needed for reproducing the Combined Work from the Application, but +excluding the System Libraries of the Combined Work. + + 1. Exception to Section 3 of the GNU GPL. + +You may convey a covered work under sections 3 and 4 of this License without +being bound by section 3 of the GNU GPL. + + 2. Conveying Modified Versions. + +If you modify a copy of the Library, and, in your modifications, a facility +refers to a function or data to be supplied by an Application that uses the +facility (other than as an argument passed when the facility is invoked), +then you may convey a copy of the modified version: + +a) under this License, provided that you make a good faith effort to ensure +that, in the event an Application does not supply the function or data, the +facility still operates, and performs whatever part of its purpose remains +meaningful, or + +b) under the GNU GPL, with none of the additional permissions of this License +applicable to that copy. + + 3. Object Code Incorporating Material from Library Header Files. + +The object code form of an Application may incorporate material from a header +file that is part of the Library. You may convey such object code under terms +of your choice, provided that, if the incorporated material is not limited +to numerical parameters, data structure layouts and accessors, or small macros, +inline functions and templates (ten or fewer lines in length), you do both +of the following: + +a) Give prominent notice with each copy of the object code that the Library +is used in it and that the Library and its use are covered by this License. + +b) Accompany the object code with a copy of the GNU GPL and this license document. + + 4. Combined Works. + +You may convey a Combined Work under terms of your choice that, taken together, +effectively do not restrict modification of the portions of the Library contained +in the Combined Work and reverse engineering for debugging such modifications, +if you also do each of the following: + +a) Give prominent notice with each copy of the Combined Work that the Library +is used in it and that the Library and its use are covered by this License. + +b) Accompany the Combined Work with a copy of the GNU GPL and this license +document. + +c) For a Combined Work that displays copyright notices during execution, include +the copyright notice for the Library among these notices, as well as a reference +directing the user to the copies of the GNU GPL and this license document. + + d) Do one of the following: + +0) Convey the Minimal Corresponding Source under the terms of this License, +and the Corresponding Application Code in a form suitable for, and under terms +that permit, the user to recombine or relink the Application with a modified +version of the Linked Version to produce a modified Combined Work, in the +manner specified by section 6 of the GNU GPL for conveying Corresponding Source. + +1) Use a suitable shared library mechanism for linking with the Library. A +suitable mechanism is one that (a) uses at run time a copy of the Library +already present on the user's computer system, and (b) will operate properly +with a modified version of the Library that is interface-compatible with the +Linked Version. + +e) Provide Installation Information, but only if you would otherwise be required +to provide such information under section 6 of the GNU GPL, and only to the +extent that such information is necessary to install and execute a modified +version of the Combined Work produced by recombining or relinking the Application +with a modified version of the Linked Version. (If you use option 4d0, the +Installation Information must accompany the Minimal Corresponding Source and +Corresponding Application Code. If you use option 4d1, you must provide the +Installation Information in the manner specified by section 6 of the GNU GPL +for conveying Corresponding Source.) + + 5. Combined Libraries. + +You may place library facilities that are a work based on the Library side +by side in a single library together with other library facilities that are +not Applications and are not covered by this License, and convey such a combined +library under terms of your choice, if you do both of the following: + +a) Accompany the combined library with a copy of the same work based on the +Library, uncombined with any other library facilities, conveyed under the +terms of this License. + +b) Give prominent notice with the combined library that part of it is a work +based on the Library, and explaining where to find the accompanying uncombined +form of the same work. + + 6. Revised Versions of the GNU Lesser General Public License. + +The Free Software Foundation may publish revised and/or new versions of the +GNU Lesser General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to address +new problems or concerns. + +Each version is given a distinguishing version number. If the Library as you +received it specifies that a certain numbered version of the GNU Lesser General +Public License "or any later version" applies to it, you have the option of +following the terms and conditions either of that published version or of +any later version published by the Free Software Foundation. If the Library +as you received it does not specify a version number of the GNU Lesser General +Public License, you may choose any version of the GNU Lesser General Public +License ever published by the Free Software Foundation. + +If the Library as you received it specifies that a proxy can decide whether +future versions of the GNU Lesser General Public License shall apply, that +proxy's public statement of acceptance of any version is permanent authorization +for you to choose that version for the Library. diff --git a/local/recipes/kde/kf6-attica/source/LICENSES/LicenseRef-KDE-Accepted-LGPL.txt b/local/recipes/kde/kf6-attica/source/LICENSES/LicenseRef-KDE-Accepted-LGPL.txt new file mode 100644 index 00000000..232b3c5d --- /dev/null +++ b/local/recipes/kde/kf6-attica/source/LICENSES/LicenseRef-KDE-Accepted-LGPL.txt @@ -0,0 +1,12 @@ +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 3 of the license or (at your option) any later version +that is accepted by the membership of KDE e.V. (or its successor +approved by the membership of KDE e.V.), which shall act as a +proxy as defined in Section 6 of version 3 of the license. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. diff --git a/local/recipes/kde/kf6-attica/source/README.md b/local/recipes/kde/kf6-attica/source/README.md new file mode 100644 index 00000000..d0d4a707 --- /dev/null +++ b/local/recipes/kde/kf6-attica/source/README.md @@ -0,0 +1,15 @@ +# Attica + +Open Collaboration Service client library + +## Introduction + +Attica is a Qt library that implements the Open Collaboration Services API version 1.6. +The REST API is defined here: +https://www.freedesktop.org/wiki/Specifications/open-collaboration-services/ + +It grants easy access to the services such as querying information about persons and contents. +The library is used in KNewStuff3 as content provider. +In order to integrate with KDE's Plasma Desktop, a platform plugin exists in [plasma-desktop](https://commits.kde.org/plasma-desktop?path=attica-kde). + +Your basic entrypoint for using Attica's functionality is the Attica::ProviderManager class. diff --git a/local/recipes/kde/kf6-attica/source/autotests/CMakeLists.txt b/local/recipes/kde/kf6-attica/source/autotests/CMakeLists.txt new file mode 100644 index 00000000..2bfba3a6 --- /dev/null +++ b/local/recipes/kde/kf6-attica/source/autotests/CMakeLists.txt @@ -0,0 +1,11 @@ +include(ECMAddTests) + +find_package(Qt6 ${REQUIRED_QT_VERSION} NO_MODULE REQUIRED Test) +set_package_properties(Qt6Test PROPERTIES PURPOSE "Required for autotests") + +ecm_add_tests( + configtest.cpp + persontest.cpp + providertest.cpp + LINK_LIBRARIES Qt6::Test KF6::Attica +) diff --git a/local/recipes/kde/kf6-attica/source/autotests/configtest.cpp b/local/recipes/kde/kf6-attica/source/autotests/configtest.cpp new file mode 100644 index 00000000..f13eefea --- /dev/null +++ b/local/recipes/kde/kf6-attica/source/autotests/configtest.cpp @@ -0,0 +1,44 @@ +/* + This file is part of KDE. + + SPDX-FileCopyrightText: 2018 Ralf Habacker + + SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL +*/ + +#include +#include + +using namespace Attica; + +class ConfigTest : public QObject +{ + Q_OBJECT + +private Q_SLOTS: + void testParsing(); +}; + +void ConfigTest::testParsing() +{ + Config::Parser parser; + QString validData( + QLatin1String("" + "" + "1.7" + "store.kde.org" + "api.kde-look.org" + "contact@opendesktop.org" + "true" + "")); + Config config = parser.parse(validData); + QVERIFY(config.isValid()); + + QString invalidData = QLatin1String(""); + config = parser.parse(invalidData); + QVERIFY(!config.isValid()); +} + +QTEST_GUILESS_MAIN(ConfigTest) + +#include "configtest.moc" diff --git a/local/recipes/kde/kf6-attica/source/autotests/persontest.cpp b/local/recipes/kde/kf6-attica/source/autotests/persontest.cpp new file mode 100644 index 00000000..b0de1d58 --- /dev/null +++ b/local/recipes/kde/kf6-attica/source/autotests/persontest.cpp @@ -0,0 +1,50 @@ +/* + This file is part of KDE. + + SPDX-FileCopyrightText: 2010 Martin Sandsmark + + SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL +*/ + +#include +#include + +using namespace Attica; + +class PersonTest : public QObject +{ + Q_OBJECT + +private Q_SLOTS: + void testParsing(); +}; + +void PersonTest::testParsing() +{ + Person::Parser parser; + QString validData( + QLatin1String("" + "" + "10" + "Ola" + "Nordmann" + "http://kde.org/" + "http://techbase.kde.org/skins/oxygen/top-kde.png" + "1" + "2010-06-21" + "Oslo" + "Norway" + "59.56" + "10.41" + "")); + Person person = parser.parse(validData); + QVERIFY(person.isValid()); + + QString invalidData = QLatin1String(""); + person = parser.parse(invalidData); + QVERIFY(!person.isValid()); +} + +QTEST_MAIN(PersonTest) + +#include "persontest.moc" diff --git a/local/recipes/kde/kf6-attica/source/autotests/privatedatatest.cpp b/local/recipes/kde/kf6-attica/source/autotests/privatedatatest.cpp new file mode 100644 index 00000000..537bb71c --- /dev/null +++ b/local/recipes/kde/kf6-attica/source/autotests/privatedatatest.cpp @@ -0,0 +1,47 @@ +/* + This file is part of KDE. + + SPDX-FileCopyrightText: 2010 Martin Sandsmark + + SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL +*/ + +#include "../privatedata.h" +#include "../privatedataparser.h" +#include + +using namespace Attica; + +class PersonTest : public QObject +{ + Q_OBJECT + +private slots: + void testParsing(); + void testMergeType(); +}; + +void PersonTest::testParsing() +{ + PrivateData::Parser parser; + QString validData( + "" + "keyfoo" + "valuebar" + "01.01.1998" + ""); + PrivateData attributes = parser.parse(validData); + QVERIFY(attributes.attributeChanged("keyfoo").isValid()); + QVERIFY(!attributes.attribute("keyfoo").isNull()); +} + +void PersonTest::testMergeType() +{ + PrivateData a; + a.setMergeType(PrivateData::OverwriteLocal); + QVERIFY(a.mergeType() == PrivateData::OverwriteLocal); +} + +QTEST_MAIN(PersonTest); + +#include "moc_persontest.cxx" diff --git a/local/recipes/kde/kf6-attica/source/autotests/providertest.cpp b/local/recipes/kde/kf6-attica/source/autotests/providertest.cpp new file mode 100644 index 00000000..3b260a57 --- /dev/null +++ b/local/recipes/kde/kf6-attica/source/autotests/providertest.cpp @@ -0,0 +1,193 @@ +/* + This file is part of KDE. + + SPDX-FileCopyrightText: 2018 Ralf Habacker + + SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL +*/ + +#include +#include +#include + +#include + +#include "config.h" +#include "content.h" +#include "providermanager.h" + +using namespace Attica; + +class ProviderTest : public QObject +{ + Q_OBJECT +public: + ProviderTest(); + ~ProviderTest() override; + +private: + void initProvider(const QUrl &url); + +private Q_SLOTS: + void testFetchValidProvider(); + void testFetchInvalidProvider(); + void testSwitchSortOrder(); + +protected Q_SLOTS: + void providerAdded(Attica::Provider p); + void slotDefaultProvidersLoaded(); + void slotConfigResult(Attica::BaseJob *j); + void slotListResult(Attica::BaseJob *j); + void slotList2Result(Attica::BaseJob *j); + void slotTimeout(); + +private: + Attica::ProviderManager *m_manager; + QEventLoop *m_eventloop; + QTimer m_timer; + bool m_errorReceived = false; +}; + +ProviderTest::ProviderTest() + : m_manager(nullptr) + , m_eventloop(new QEventLoop) +{ + QLoggingCategory::setFilterRules(QStringLiteral("kf.attica.debug=true")); +} + +ProviderTest::~ProviderTest() +{ + delete m_manager; + delete m_eventloop; +} + +void ProviderTest::slotDefaultProvidersLoaded() +{ + qDebug() << "default providers loaded"; + m_eventloop->exit(); +} + +void ProviderTest::providerAdded(Attica::Provider p) +{ + qDebug() << "got provider" << p.name(); + m_eventloop->exit(); +} + +void ProviderTest::initProvider(const QUrl &url) +{ + m_errorReceived = false; + delete m_manager; + m_manager = new Attica::ProviderManager; + m_manager->setAuthenticationSuppressed(true); + connect(m_manager, &ProviderManager::defaultProvidersLoaded, this, &ProviderTest::slotDefaultProvidersLoaded); + connect(m_manager, &ProviderManager::providerAdded, this, &ProviderTest::providerAdded); + m_manager->addProviderFile(url); + connect(m_manager, &Attica::ProviderManager::failedToLoad, this, [this]() { + m_errorReceived = true; + m_eventloop->quit(); + }); + m_timer.singleShot(30000, this, &ProviderTest::slotTimeout); + + m_eventloop->exec(); +} + +void ProviderTest::testFetchValidProvider() +{ + initProvider(QUrl(QLatin1String("https://autoconfig.kde.org/ocs/providers.xml"))); + Attica::Provider provider = m_manager->providers().at(0); + ItemJob *job = provider.requestConfig(); + QVERIFY(job); + connect(job, &BaseJob::finished, this, &ProviderTest::slotConfigResult); + job->start(); + m_eventloop->exec(); +} + +void ProviderTest::slotConfigResult(Attica::BaseJob *j) +{ + if (j->metadata().error() == Metadata::NoError) { + Attica::ItemJob *itemJob = static_cast *>(j); + Attica::Config p = itemJob->result(); + qDebug() << QLatin1String("Config loaded - Server has version") << p.version(); + } else if (j->metadata().error() == Metadata::OcsError) { + qDebug() << QString(QLatin1String("OCS Error: %1")).arg(j->metadata().message()); + } else if (j->metadata().error() == Metadata::NetworkError) { + qDebug() << QString(QLatin1String("Network Error: %1")).arg(j->metadata().message()); + } else { + qDebug() << QString(QLatin1String("Unknown Error: %1")).arg(j->metadata().message()); + } + m_eventloop->exit(); + m_timer.stop(); + QVERIFY(j->metadata().error() == Metadata::NoError); +} + +void ProviderTest::testSwitchSortOrder() +{ + initProvider(QUrl(QLatin1String("https://autoconfig.kde.org/ocs/providers.xml"))); + Attica::Provider provider = m_manager->providers().at(0); + ListJob *job = provider.searchContents({}, {}); + QVERIFY(job); + connect(job, &BaseJob::finished, this, &ProviderTest::slotListResult); + job->start(); + m_eventloop->exec(); +} + +void ProviderTest::slotListResult(Attica::BaseJob *j) +{ + if (j->metadata().error() == Metadata::NoError) { + Attica::ListJob *contentJob = static_cast *>(j); + Content::List items = contentJob->itemList(); + qDebug() << QLatin1String("First list of items loaded, we have the following amount:") << items.count(); + } else if (j->metadata().error() == Metadata::OcsError) { + qDebug() << QString(QLatin1String("OCS Error: %1")).arg(j->metadata().message()); + } else if (j->metadata().error() == Metadata::NetworkError) { + qDebug() << QString(QLatin1String("Network Error: %1")).arg(j->metadata().message()); + } else { + qDebug() << QString(QLatin1String("Unknown Error: %1")).arg(j->metadata().message()); + } + m_timer.stop(); + QVERIFY(j->metadata().error() == Metadata::NoError); + + // Now do the actual switch + Attica::Provider provider = m_manager->providers().at(0); + ListJob *job = provider.searchContents({}, {}, Provider::Downloads); + QVERIFY(job); + connect(job, &BaseJob::finished, this, &ProviderTest::slotList2Result); + m_timer.singleShot(30000, this, &ProviderTest::slotTimeout); + job->start(); +} + +void ProviderTest::slotList2Result(Attica::BaseJob *j) +{ + if (j->metadata().error() == Metadata::NoError) { + Attica::ListJob *contentJob = static_cast *>(j); + Content::List items = contentJob->itemList(); + qDebug() << QLatin1String("Second list of items loaded, we have the following amount:") << items.count(); + } else if (j->metadata().error() == Metadata::OcsError) { + qDebug() << QString(QLatin1String("OCS Error: %1")).arg(j->metadata().message()); + } else if (j->metadata().error() == Metadata::NetworkError) { + qDebug() << QString(QLatin1String("Network Error: %1")).arg(j->metadata().message()); + } else { + qDebug() << QString(QLatin1String("Unknown Error: %1")).arg(j->metadata().message()); + } + m_eventloop->exit(); + m_timer.stop(); + QVERIFY(j->metadata().error() == Metadata::NoError); +} + +void ProviderTest::slotTimeout() +{ + QVERIFY(m_eventloop->isRunning()); + m_eventloop->exit(); + QFAIL("Timeout fetching provider"); +} + +void ProviderTest::testFetchInvalidProvider() +{ + initProvider(QUrl(QLatin1String("https://invalid-url.org/ocs/providers.xml"))); + QVERIFY(m_manager->providers().size() == 0); + QVERIFY(m_errorReceived); +} + +QTEST_GUILESS_MAIN(ProviderTest) + +#include "providertest.moc" diff --git a/local/recipes/kde/kf6-attica/source/docs/Doxyfile.local b/local/recipes/kde/kf6-attica/source/docs/Doxyfile.local new file mode 100644 index 00000000..c01bc193 --- /dev/null +++ b/local/recipes/kde/kf6-attica/source/docs/Doxyfile.local @@ -0,0 +1,7 @@ +### KApiDox Project-specific Overrides file + +# define so that deprecated API is not skipped +PREDEFINED += \ + "ATTICA_ENABLE_DEPRECATED_SINCE(x, y)=1" \ + "ATTICA_BUILD_DEPRECATED_SINCE(x, y)=1" \ + "ATTICA_DEPRECATED_VERSION(x, y, t)=" diff --git a/local/recipes/kde/kf6-attica/source/metainfo.yaml b/local/recipes/kde/kf6-attica/source/metainfo.yaml new file mode 100644 index 00000000..788c4747 --- /dev/null +++ b/local/recipes/kde/kf6-attica/source/metainfo.yaml @@ -0,0 +1,21 @@ +maintainer: +description: Open Collaboration Services API +tier: 1 +type: functional +platforms: + - name: Linux + - name: FreeBSD + - name: Windows + - name: macOS + - name: Android +portingAid: false +deprecated: false +release: true +libraries: + - cmake: "KF6::Attica" + license: LGPL-2.1-only OR LGPL-3.0-only +cmakename: KF6Attica + +public_lib: true +group: Frameworks +subgroup: Tier 1 diff --git a/local/recipes/kde/kf6-attica/source/src/CMakeLists.txt b/local/recipes/kde/kf6-attica/source/src/CMakeLists.txt new file mode 100644 index 00000000..3e74b3f6 --- /dev/null +++ b/local/recipes/kde/kf6-attica/source/src/CMakeLists.txt @@ -0,0 +1,236 @@ +# mingw can't handle exported explicit template instantiations in a DLL +if (MINGW) + set(CMAKE_SHARED_LINKER_FLAGS "-Wl,--export-all-symbols ${CMAKE_SHARED_LINKER_FLAGS}") +endif (MINGW) + +configure_file(version.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/version.h) + +add_library(KF6Attica) +add_library(KF6::Attica ALIAS KF6Attica) + +set_target_properties(KF6Attica PROPERTIES + VERSION ${ATTICA_VERSION} + SOVERSION ${ATTICA_SOVERSION} + EXPORT_NAME "Attica" +) + +target_sources(KF6Attica PRIVATE + accountbalance.cpp + accountbalanceparser.cpp + achievement.cpp + achievementparser.cpp + buildservice.cpp + buildserviceparser.cpp + buildservicejob.cpp + buildservicejobparser.cpp + buildservicejoboutput.cpp + buildservicejoboutputparser.cpp + activity.cpp + activityparser.cpp + atticabasejob.cpp + atticautils.cpp + privatedata.cpp + privatedataparser.cpp + category.cpp + categoryparser.cpp + comment.cpp + commentparser.cpp + config.cpp + configparser.cpp + content.cpp + contentparser.cpp + deletejob.cpp + distribution.cpp + distributionparser.cpp + downloaddescription.cpp + downloaditem.cpp + downloaditemparser.cpp + event.cpp + eventparser.cpp + folder.cpp + folderparser.cpp + forum.cpp + forumparser.cpp + getjob.cpp + homepageentry.cpp + homepagetype.cpp + homepagetypeparser.cpp + icon.cpp + itemjob.cpp + knowledgebaseentry.cpp + knowledgebaseentryparser.cpp + license.cpp + licenseparser.cpp + listjob_inst.cpp + message.cpp + messageparser.cpp + metadata.cpp + parser.cpp + person.cpp + personparser.cpp + platformdependent_v2.cpp + postfiledata.cpp + postjob.cpp + project.cpp + projectparser.cpp + putjob.cpp + remoteaccount.cpp + remoteaccountparser.cpp + provider.cpp + providermanager.cpp + publisher.cpp + publisherparser.cpp + publisherfield.cpp + publisherfieldparser.cpp + qtplatformdependent.cpp + topic.cpp + topicparser.cpp + platformdependent_v3.cpp +) + +ecm_qt_declare_logging_category(KF6Attica + HEADER attica_debug.h + IDENTIFIER ATTICA + CATEGORY_NAME kf.attica + OLD_CATEGORY_NAMES org.kde.attica + DESCRIPTION "Attica" + EXPORT ATTICA +) + +file(GLOB TEST_FILES "*.cpp" "*.h") +ecm_check_outbound_license( + LICENSES LGPL-2.1-only LGPL-3.0-only + TEST_NAME KF6Attica + FILES ${TEST_FILES} +) + +ecm_generate_export_header(KF6Attica + BASE_NAME Attica + GROUP_BASE_NAME KF + VERSION ${KF_VERSION} + USE_VERSION_HEADER + DEPRECATED_BASE_VERSION 0 + DEPRECATION_VERSIONS + EXCLUDE_DEPRECATED_BEFORE_AND_AT ${EXCLUDE_DEPRECATED_BEFORE_AND_AT} +) + +target_link_libraries(KF6Attica +PUBLIC + Qt6::Core + Qt6::Network +) +target_include_directories(KF6Attica INTERFACE "$") + + +ecm_generate_headers(Attica_CamelCase_HEADERS + HEADER_NAMES + Activity + AccountBalance + Achievement + Comment + Config + Content + Category + DeleteJob + Distribution + DownloadDescription + DownloadItem + Event + Folder + Forum + GetJob + HomePageEntry + HomePageType + Icon + ItemJob + KnowledgeBaseEntry + ListJob + License + Message + Metadata + Person + PrivateData + PostJob + Project + PutJob + RemoteAccount + BuildService + BuildServiceJob + BuildServiceJobOutput + ProviderManager + Provider + Publisher + PublisherField + Topic + + PREFIX Attica + REQUIRED_HEADERS Attica_HEADERS +) + +set(Attica_HEADERS + ${Attica_HEADERS} + atticabasejob.h # TODO: rename to basejob.h, add atticabasejob.h forwarding to basejob.h for compat + atticautils.h # TODO: not exported, this should probably NOT be installed at all? + #interface for external platform plugins + platformdependent.h + platformdependent_v2.h + platformdependent_v3.h +) + +install(FILES ${Attica_CamelCase_HEADERS} DESTINATION ${KDE_INSTALL_INCLUDEDIR_KF}/Attica/Attica COMPONENT Devel) + +install(TARGETS KF6Attica + EXPORT KF6AtticaTargets + ${KF_INSTALL_TARGETS_DEFAULT_ARGS}) + +install(FILES + ${Attica_HEADERS} + ${CMAKE_CURRENT_BINARY_DIR}/version.h + ${CMAKE_CURRENT_BINARY_DIR}/attica_export.h + DESTINATION ${KDE_INSTALL_INCLUDEDIR_KF}/Attica/attica + COMPONENT Devel +) + +ecm_qt_install_logging_categories( + EXPORT ATTICA + FILE attica.categories + DESTINATION ${KDE_INSTALL_LOGGINGCATEGORIESDIR} +) + +if(BUILD_QCH) + ecm_add_qch( + KF6Attica_QCH + NAME Attica + BASE_NAME KF6Attica + VERSION ${KF_VERSION} + ORG_DOMAIN org.kde + SOURCES # using only public headers, to cover only public API + ${Attica_HEADERS} + MD_MAINPAGE "${CMAKE_SOURCE_DIR}/README.md" + LINK_QCHS + Qt6Core_QCH + Qt6Network_QCH + INCLUDE_DIRS + ${CMAKE_CURRENT_BINARY_DIR} + BLANK_MACROS + ATTICA_EXPORT + ATTICA_DEPRECATED + ATTICA_DEPRECATED_EXPORT + "ATTICA_DEPRECATED_VERSION(x, y, t)" + TAGFILE_INSTALL_DESTINATION ${KDE_INSTALL_QTQCHDIR} + QCH_INSTALL_DESTINATION ${KDE_INSTALL_QTQCHDIR} + COMPONENT Devel + ) +endif() + +# Install package config file +if(NOT WIN32) + ecm_generate_pkgconfig_file(BASE_NAME KF6Attica + LIB_NAME KF6Attica + INCLUDE_INSTALL_DIR ${KDE_INSTALL_INCLUDEDIR_KF}/Attica + DEPS Qt6Core Qt6Network + DESCRIPTION "Qt library to access Open Collaboration Services" + INSTALL + ) +endif(NOT WIN32) + diff --git a/local/recipes/kde/kf6-attica/source/src/accountbalance.cpp b/local/recipes/kde/kf6-attica/source/src/accountbalance.cpp new file mode 100644 index 00000000..a0b12b60 --- /dev/null +++ b/local/recipes/kde/kf6-attica/source/src/accountbalance.cpp @@ -0,0 +1,56 @@ +/* + SPDX-FileCopyrightText: 2009 Frederik Gladhorn + + SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL +*/ + +#include "accountbalance.h" + +using namespace Attica; + +class Q_DECL_HIDDEN AccountBalance::Private : public QSharedData +{ +public: + QString balance; + QString currency; +}; + +AccountBalance::AccountBalance() + : d(new Private) +{ +} + +AccountBalance::AccountBalance(const Attica::AccountBalance &other) + : d(other.d) +{ +} + +AccountBalance &AccountBalance::operator=(const Attica::AccountBalance &other) +{ + d = other.d; + return *this; +} + +AccountBalance::~AccountBalance() +{ +} + +void AccountBalance::setBalance(const QString &balance) +{ + d->balance = balance; +} + +QString AccountBalance::balance() const +{ + return d->balance; +} + +void AccountBalance::setCurrency(const QString ¤cy) +{ + d->currency = currency; +} + +QString AccountBalance::currency() const +{ + return d->currency; +} diff --git a/local/recipes/kde/kf6-attica/source/src/accountbalance.h b/local/recipes/kde/kf6-attica/source/src/accountbalance.h new file mode 100644 index 00000000..c41f51f4 --- /dev/null +++ b/local/recipes/kde/kf6-attica/source/src/accountbalance.h @@ -0,0 +1,82 @@ +/* + SPDX-FileCopyrightText: 2009 Frederik Gladhorn + + SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL +*/ + +#ifndef ATTICA_ACCOUNTBALANCE_H +#define ATTICA_ACCOUNTBALANCE_H + +#include +#include + +#include "attica_export.h" + +namespace Attica +{ +/** + * @class AccountBalance accountbalance.h + * + * Represents the money in the account of the user + */ +class ATTICA_EXPORT AccountBalance +{ +public: + typedef QList List; + class Parser; + + /** + * Creates an empty AccountBalance + */ + AccountBalance(); + + /** + * Copy constructor. + * @param other the AccountBalance to copy from + */ + AccountBalance(const AccountBalance &other); + + /** + * Assignment operator. + * @param other the AccountBalance to assign from + * @return pointer to this AccountBalance + */ + AccountBalance &operator=(const AccountBalance &other); + + /** + * Destructor. + */ + ~AccountBalance(); + + /** + * Sets the currency in use. + * @param currency the new currency (Euro, US Dollar) + */ + void setCurrency(const QString ¤cy); + + /** + * Gets the currency. + * @return the currency + */ + QString currency() const; + + /** + * Sets the balance. + * @param balance + */ + void setBalance(const QString &name); + + /** + * Gets the balance. + * @return the amount of money in the account + */ + QString balance() const; + +private: + class Private; + QSharedDataPointer d; +}; + +} + +#endif // ACCOUNTBALANCE_H diff --git a/local/recipes/kde/kf6-attica/source/src/accountbalanceparser.cpp b/local/recipes/kde/kf6-attica/source/src/accountbalanceparser.cpp new file mode 100644 index 00000000..16d8ad6f --- /dev/null +++ b/local/recipes/kde/kf6-attica/source/src/accountbalanceparser.cpp @@ -0,0 +1,35 @@ +/* + This file is part of KDE. + + SPDX-FileCopyrightText: 2009 Frederik Gladhorn + + SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL +*/ + +#include "accountbalanceparser.h" + +#include + +using namespace Attica; + +QStringList AccountBalance::Parser::xmlElement() const +{ + return QStringList(QStringLiteral("person")); +} + +AccountBalance AccountBalance::Parser::parseXml(QXmlStreamReader &xml) +{ + AccountBalance item; + + while (!xml.atEnd()) { + xml.readNext(); + if (xml.isStartElement()) { + if (xml.name() == QLatin1String("balance")) { + item.setBalance(xml.readElementText()); + } else if (xml.name() == QLatin1String("currency")) { + item.setCurrency(xml.readElementText()); + } + } + } + return item; +} diff --git a/local/recipes/kde/kf6-attica/source/src/accountbalanceparser.h b/local/recipes/kde/kf6-attica/source/src/accountbalanceparser.h new file mode 100644 index 00000000..daf4024b --- /dev/null +++ b/local/recipes/kde/kf6-attica/source/src/accountbalanceparser.h @@ -0,0 +1,26 @@ +/* + This file is part of KDE. + + SPDX-FileCopyrightText: 2009 Frederik Gladhorn + + SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL +*/ + +#ifndef ATTICA_ACCOUNTBALANCEPARSER_H +#define ATTICA_ACCOUNTBALANCEPARSER_H + +#include "accountbalance.h" +#include "parser.h" + +namespace Attica +{ +class Q_DECL_HIDDEN AccountBalance::Parser : public Attica::Parser +{ +private: + AccountBalance parseXml(QXmlStreamReader &xml) override; + QStringList xmlElement() const override; +}; + +} + +#endif diff --git a/local/recipes/kde/kf6-attica/source/src/achievement.cpp b/local/recipes/kde/kf6-attica/source/src/achievement.cpp new file mode 100644 index 00000000..4da2429d --- /dev/null +++ b/local/recipes/kde/kf6-attica/source/src/achievement.cpp @@ -0,0 +1,272 @@ +/* + This file is part of KDE. + + SPDX-FileCopyrightText: 2011 Laszlo Papp + + SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL +*/ + +#include "achievement.h" + +using namespace Attica; + +Achievement::Type Achievement::stringToAchievementType(const QString &achievementTypeString) +{ + if (achievementTypeString == QLatin1String("flowing")) { + return Achievement::FlowingAchievement; + } else if (achievementTypeString == QLatin1String("stepped")) { + return Achievement::SteppedAchievement; + } else if (achievementTypeString == QLatin1String("namedsteps")) { + return Achievement::NamedstepsAchievement; + } else if (achievementTypeString == QLatin1String("set")) { + return Achievement::SetAchievement; + } + + Q_ASSERT(false); + return Achievement::FlowingAchievement; +} + +QString Achievement::achievementTypeToString(const Achievement::Type type) +{ + switch (type) { + case Achievement::FlowingAchievement: + return QStringLiteral("flowing"); + case Achievement::SteppedAchievement: + return QStringLiteral("stepped"); + case Achievement::NamedstepsAchievement: + return QStringLiteral("namedsteps"); + case Achievement::SetAchievement: + return QStringLiteral("set"); + } + + Q_ASSERT(false); + return QString(); +} + +Achievement::Visibility Achievement::stringToAchievementVisibility(const QString &achievementVisibilityString) +{ + if (achievementVisibilityString == QLatin1String("visible")) { + return Achievement::VisibleAchievement; + } else if (achievementVisibilityString == QLatin1String("dependents")) { + return Achievement::DependentsAchievement; + } else if (achievementVisibilityString == QLatin1String("secret")) { + return Achievement::SecretAchievement; + } + + Q_ASSERT(false); + return Achievement::VisibleAchievement; +} + +QString Achievement::achievementVisibilityToString(const Achievement::Visibility visibility) +{ + switch (visibility) { + case Achievement::VisibleAchievement: + return QStringLiteral("visible"); + case Achievement::DependentsAchievement: + return QStringLiteral("dependents"); + case Achievement::SecretAchievement: + return QStringLiteral("secret"); + } + + Q_ASSERT(false); + return QString(); +} + +class Q_DECL_HIDDEN Achievement::Private : public QSharedData +{ +public: + QString m_id; + QString m_contentId; + QString m_name; + QString m_description; + QString m_explanation; + int m_points; + QUrl m_image; + QStringList m_dependencies; + Achievement::Visibility m_visibility; + Achievement::Type m_type; + QStringList m_options; + int m_steps; + QVariant m_progress; + + Private() + : m_points(0) + , m_steps(0) + { + } +}; + +Achievement::Achievement() + : d(new Private) +{ +} + +Achievement::Achievement(const Achievement &other) + : d(other.d) +{ +} + +Achievement &Achievement::operator=(const Attica::Achievement &other) +{ + d = other.d; + return *this; +} + +Achievement::~Achievement() +{ +} + +void Achievement::setId(const QString &id) +{ + d->m_id = id; +} + +QString Achievement::id() const +{ + return d->m_id; +} + +void Achievement::setContentId(const QString &contentId) +{ + d->m_contentId = contentId; +} + +QString Achievement::contentId() const +{ + return d->m_contentId; +} + +void Achievement::setName(const QString &name) +{ + d->m_name = name; +} + +QString Achievement::name() const +{ + return d->m_name; +} + +void Achievement::setDescription(const QString &description) +{ + d->m_description = description; +} + +QString Achievement::description() const +{ + return d->m_description; +} + +void Achievement::setExplanation(const QString &explanation) +{ + d->m_explanation = explanation; +} + +QString Achievement::explanation() const +{ + return d->m_explanation; +} + +void Achievement::setPoints(const int points) +{ + d->m_points = points; +} + +int Achievement::points() const +{ + return d->m_points; +} + +void Achievement::setImage(const QUrl &image) +{ + d->m_image = image; +} + +QUrl Achievement::image() const +{ + return d->m_image; +} + +void Achievement::setDependencies(const QStringList &dependencies) +{ + d->m_dependencies = dependencies; +} + +void Achievement::addDependency(const QString &dependency) +{ + d->m_dependencies.append(dependency); +} + +void Achievement::removeDependency(const QString &dependency) +{ + d->m_dependencies.removeOne(dependency); +} + +QStringList Achievement::dependencies() const +{ + return d->m_dependencies; +} + +void Achievement::setVisibility(Achievement::Visibility visibility) +{ + d->m_visibility = visibility; +} + +Achievement::Visibility Achievement::visibility() const +{ + return d->m_visibility; +} + +void Achievement::setType(Achievement::Type type) +{ + d->m_type = type; +} + +Achievement::Type Achievement::type() const +{ + return d->m_type; +} + +void Achievement::setOptions(const QStringList &options) +{ + d->m_options = options; +} + +void Achievement::addOption(const QString &option) +{ + d->m_options.append(option); +} + +void Achievement::removeOption(const QString &option) +{ + d->m_options.removeOne(option); +} + +QStringList Achievement::options() const +{ + return d->m_options; +} + +void Achievement::setSteps(const int steps) +{ + d->m_steps = steps; +} + +int Achievement::steps() const +{ + return d->m_steps; +} + +void Achievement::setProgress(const QVariant &progress) +{ + d->m_progress = progress; +} + +QVariant Achievement::progress() const +{ + return d->m_progress; +} + +bool Achievement::isValid() const +{ + return !(d->m_id.isEmpty()); +} diff --git a/local/recipes/kde/kf6-attica/source/src/achievement.h b/local/recipes/kde/kf6-attica/source/src/achievement.h new file mode 100644 index 00000000..e053b8ca --- /dev/null +++ b/local/recipes/kde/kf6-attica/source/src/achievement.h @@ -0,0 +1,107 @@ +/* + This file is part of KDE. + + SPDX-FileCopyrightText: 2011 Laszlo Papp + + SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL +*/ + +#ifndef ATTICA_ACHIEVEMENT_H +#define ATTICA_ACHIEVEMENT_H + +#include "attica_export.h" + +#include +#include +#include +#include + +namespace Attica +{ + +/** + * @class Achievement achievement.h + * + * Represents an achievement. + */ +class ATTICA_EXPORT Achievement +{ +public: + typedef QList List; + class Parser; + + enum Type { + FlowingAchievement, + SteppedAchievement, + NamedstepsAchievement, + SetAchievement, + }; + static Achievement::Type stringToAchievementType(const QString &achievementTypeString); + static QString achievementTypeToString(const Achievement::Type type); + + enum Visibility { + VisibleAchievement, + DependentsAchievement, + SecretAchievement, + }; + static Achievement::Visibility stringToAchievementVisibility(const QString &achievementVisibilityString); + static QString achievementVisibilityToString(const Achievement::Visibility visibility); + + Achievement(); + Achievement(const Achievement &other); + Achievement &operator=(const Achievement &other); + ~Achievement(); + + void setId(const QString &id); + QString id() const; + + void setContentId(const QString &contentId); + QString contentId() const; + + void setName(const QString &name); + QString name() const; + + void setDescription(const QString &description); + QString description() const; + + void setExplanation(const QString &explanation); + QString explanation() const; + + void setPoints(const int points); + int points() const; + + void setImage(const QUrl &image); + QUrl image() const; + + void setDependencies(const QStringList &dependencies); + void addDependency(const QString &dependency); + void removeDependency(const QString &dependency); + QStringList dependencies() const; + + void setVisibility(Achievement::Visibility visibility); + Achievement::Visibility visibility() const; + + void setType(Achievement::Type type); + Achievement::Type type() const; + + void setOptions(const QStringList &options); + void addOption(const QString &option); + void removeOption(const QString &option); + QStringList options() const; + + void setSteps(const int steps); + int steps() const; + + void setProgress(const QVariant &progress); + QVariant progress() const; + + bool isValid() const; + +private: + class Private; + QSharedDataPointer d; +}; + +} + +#endif diff --git a/local/recipes/kde/kf6-attica/source/src/achievementparser.cpp b/local/recipes/kde/kf6-attica/source/src/achievementparser.cpp new file mode 100644 index 00000000..cabe60ea --- /dev/null +++ b/local/recipes/kde/kf6-attica/source/src/achievementparser.cpp @@ -0,0 +1,136 @@ +/* + This file is part of KDE. + + SPDX-FileCopyrightText: 2011 Laszlo Papp + + SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL +*/ + +#include "achievementparser.h" +#include "atticautils.h" + +using namespace Attica; + +Achievement Achievement::Parser::parseXml(QXmlStreamReader &xml) +{ + Achievement achievement; + + while (!xml.atEnd()) { + xml.readNext(); + + if (xml.isStartElement()) { + if (xml.name() == QLatin1String("id")) { + achievement.setId(xml.readElementText()); + } else if (xml.name() == QLatin1String("content_id")) { + achievement.setContentId(xml.readElementText()); + } else if (xml.name() == QLatin1String("name")) { + achievement.setName(xml.readElementText()); + } else if (xml.name() == QLatin1String("description")) { + achievement.setDescription(xml.readElementText()); + } else if (xml.name() == QLatin1String("explanation")) { + achievement.setExplanation(xml.readElementText()); + } else if (xml.name() == QLatin1String("points")) { + achievement.setPoints(xml.readElementText().toInt()); + } else if (xml.name() == QLatin1String("image")) { + achievement.setImage(QUrl(xml.readElementText())); + } else if (xml.name() == QLatin1String("dependencies")) { + QStringList dependencies = parseXmlDependencies(xml); + achievement.setDependencies(dependencies); + } else if (xml.name() == QLatin1String("visibility")) { + achievement.setVisibility(Achievement::stringToAchievementVisibility(xml.readElementText())); + } else if (xml.name() == QLatin1String("type")) { + achievement.setType(Achievement::stringToAchievementType(xml.readElementText())); + } else if (xml.name() == QLatin1String("options")) { + QStringList options = parseXmlOptions(xml); + achievement.setOptions(options); + } else if (xml.name() == QLatin1String("steps")) { + achievement.setSteps(xml.readElementText().toInt()); + } else if (xml.name() == QLatin1String("progress")) { + switch (achievement.type()) { + case Achievement::FlowingAchievement: + achievement.setProgress(QVariant(xml.readElementText().toFloat())); + break; + case Achievement::SteppedAchievement: + achievement.setProgress(QVariant(xml.readElementText().toInt())); + break; + case Achievement::NamedstepsAchievement: + achievement.setProgress(QVariant(xml.readElementText())); + break; + case Achievement::SetAchievement: { + QVariant progress = parseXmlProgress(xml); + achievement.setProgress(progress); + break; + } + default: + break; + } + } + } else if (xml.isEndElement() && xml.name() == QLatin1String("achievement")) { + break; + } + } + + return achievement; +} + +QStringList Achievement::Parser::parseXmlDependencies(QXmlStreamReader &xml) +{ + QStringList dependencies; + + while (!xml.atEnd()) { + xml.readNext(); + + if (xml.isStartElement()) { + if (xml.name() == QLatin1String("achievement_id")) { + dependencies.append(xml.readElementText()); + } + } else if (xml.isEndElement() && xml.name() == QLatin1String("dependencies")) { + break; + } + } + + return dependencies; +} + +QStringList Achievement::Parser::parseXmlOptions(QXmlStreamReader &xml) +{ + QStringList options; + + while (!xml.atEnd()) { + xml.readNext(); + + if (xml.isStartElement()) { + if (xml.name() == QLatin1String("option")) { + options.append(xml.readElementText()); + } + } else if (xml.isEndElement() && xml.name() == QLatin1String("options")) { + break; + } + } + + return options; +} + +QVariant Achievement::Parser::parseXmlProgress(QXmlStreamReader &xml) +{ + QStringList progress; + + while (!xml.atEnd()) { + xml.readNext(); + + if (xml.isStartElement()) { + if (xml.name() == QLatin1String("reached")) { + progress.append(xml.readElementText()); + } + } else if (xml.isEndElement() && xml.name() == QLatin1String("progress")) { + break; + } + } + + return progress; +} + +QStringList Achievement::Parser::xmlElement() const +{ + return QStringList(QStringLiteral("achievement")); +} diff --git a/local/recipes/kde/kf6-attica/source/src/achievementparser.h b/local/recipes/kde/kf6-attica/source/src/achievementparser.h new file mode 100644 index 00000000..16333a55 --- /dev/null +++ b/local/recipes/kde/kf6-attica/source/src/achievementparser.h @@ -0,0 +1,29 @@ +/* + This file is part of KDE. + + SPDX-FileCopyrightText: 2011 Laszlo Papp + + SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL +*/ + +#ifndef ATTICA_ACHIEVEMENTPARSER_H +#define ATTICA_ACHIEVEMENTPARSER_H + +#include "achievement.h" +#include "parser.h" + +namespace Attica +{ +class Q_DECL_HIDDEN Achievement::Parser : public Attica::Parser +{ +private: + Achievement parseXml(QXmlStreamReader &xml) override; + QStringList parseXmlOptions(QXmlStreamReader &xml); + QStringList parseXmlDependencies(QXmlStreamReader &xml); + QVariant parseXmlProgress(QXmlStreamReader &xml); + QStringList xmlElement() const override; +}; + +} + +#endif diff --git a/local/recipes/kde/kf6-attica/source/src/activity.cpp b/local/recipes/kde/kf6-attica/source/src/activity.cpp new file mode 100644 index 00000000..fdf1ec66 --- /dev/null +++ b/local/recipes/kde/kf6-attica/source/src/activity.cpp @@ -0,0 +1,98 @@ +/* + This file is part of KDE. + + SPDX-FileCopyrightText: 2008 Cornelius Schumacher + + SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL +*/ + +#include "activity.h" + +#include + +using namespace Attica; + +class Q_DECL_HIDDEN Activity::Private : public QSharedData +{ +public: + QString m_id; + Person m_associatedPerson; + QDateTime m_timestamp; + QString m_message; + QUrl m_link; +}; + +Activity::Activity() + : d(new Private) +{ +} + +Activity::Activity(const Attica::Activity &other) + : d(other.d) +{ +} + +Activity &Activity::operator=(const Attica::Activity &other) +{ + d = other.d; + return *this; +} + +Activity::~Activity() +{ +} + +void Activity::setId(const QString &id) +{ + d->m_id = id; +} + +QString Activity::id() const +{ + return d->m_id; +} + +void Activity::setAssociatedPerson(const Person &associatedPerson) +{ + d->m_associatedPerson = associatedPerson; +} + +Person Activity::associatedPerson() const +{ + return d->m_associatedPerson; +} + +void Activity::setTimestamp(const QDateTime &date) +{ + d->m_timestamp = date; +} + +QDateTime Activity::timestamp() const +{ + return d->m_timestamp; +} + +void Activity::setMessage(const QString &c) +{ + d->m_message = c; +} + +QString Activity::message() const +{ + return d->m_message; +} + +void Activity::setLink(const QUrl &v) +{ + d->m_link = v; +} + +QUrl Activity::link() const +{ + return d->m_link; +} + +bool Activity::isValid() const +{ + return !(d->m_id.isEmpty()); +} diff --git a/local/recipes/kde/kf6-attica/source/src/activity.h b/local/recipes/kde/kf6-attica/source/src/activity.h new file mode 100644 index 00000000..8a1ed386 --- /dev/null +++ b/local/recipes/kde/kf6-attica/source/src/activity.h @@ -0,0 +1,131 @@ +/* + This file is part of KDE. + + SPDX-FileCopyrightText: 2008 Cornelius Schumacher + + SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL +*/ +#ifndef ATTICA_ACTIVITY_H +#define ATTICA_ACTIVITY_H + +#include +#include +#include + +#include "attica_export.h" +#include "person.h" + +class QDateTime; + +namespace Attica +{ +/** + * @class Activity activity.h + * + * Represents a single news item (also known as activity) + */ +class ATTICA_EXPORT Activity +{ +public: + typedef QList List; + class Parser; + + /** + * Creates an empty Activity + */ + Activity(); + + /** + * Copy constructor. + * @param other the Activity to copy from + */ + Activity(const Activity &other); + + /** + * Assignment operator. + * @param other the Activity to assign from + * @return pointer to this Activity + */ + Activity &operator=(const Activity &other); + + /** + * Destructor. + */ + ~Activity(); + + /** + * Sets the id of the Activity. + * The id uniquely identifies an Activity with the OCS API. + * @param id the new id + */ + void setId(const QString &id); + + /** + * Gets the id of the Activity. + * The id uniquely identifies an Activity with the OCS API. + * @return the id + */ + QString id() const; + + /** + * Sets the user bound to the Activity. + * @param id the new user + */ + void setAssociatedPerson(const Person &associatedPerson); + + /** + * Gets the user bound to the Activity. + * @return the user + */ + Person associatedPerson() const; + + /** + * Sets the timestamp the Activity has been published. + * @param timestamp the new timestamp + */ + void setTimestamp(const QDateTime ×tamp); + + /** + * Gets the timestamp the Activity has been published. + * @return the timestamp + */ + QDateTime timestamp() const; + + /** + * Sets the message of the Activity. + * @param message the new message + */ + void setMessage(const QString &message); + + /** + * Gets the message of the Activity. + * @return the message + */ + QString message() const; + + /** + * Sets the link to further information about this Activity. + * @param link the new link + */ + void setLink(const QUrl &link); + + /** + * Gets the link to further information about this Activity. + * @return the link + */ + QUrl link() const; + + /** + * Checks whether this Activity has an id + * @return @c true if an id has been set, @c false otherwise + */ + bool isValid() const; + +private: + class Private; + QSharedDataPointer d; +}; + +} + +#endif diff --git a/local/recipes/kde/kf6-attica/source/src/activityparser.cpp b/local/recipes/kde/kf6-attica/source/src/activityparser.cpp new file mode 100644 index 00000000..9b5b2647 --- /dev/null +++ b/local/recipes/kde/kf6-attica/source/src/activityparser.cpp @@ -0,0 +1,57 @@ +/* + This file is part of KDE. + + SPDX-FileCopyrightText: 2008 Cornelius Schumacher + + SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL +*/ + +#include "activityparser.h" + +#include +#include + +using namespace Attica; + +Activity Activity::Parser::parseXml(QXmlStreamReader &xml) +{ + Activity activity; + Person person; + + while (!xml.atEnd()) { + xml.readNext(); + + if (xml.isStartElement()) { + if (xml.name() == QLatin1String("id")) { + activity.setId(xml.readElementText()); + } else if (xml.name() == QLatin1String("personid")) { + person.setId(xml.readElementText()); + } else if (xml.name() == QLatin1String("avatarpic")) { + person.setAvatarUrl(QUrl(xml.readElementText())); + } else if (xml.name() == QLatin1String("firstname")) { + person.setFirstName(xml.readElementText()); + } else if (xml.name() == QLatin1String("lastname")) { + person.setLastName(xml.readElementText()); + } else if (xml.name() == QLatin1String("timestamp")) { + QString timestampString = xml.readElementText(); + timestampString.remove(QRegularExpression(QStringLiteral("\\+.*$"))); + QDateTime timestamp = QDateTime::fromString(timestampString, Qt::ISODate); + activity.setTimestamp(timestamp); + } else if (xml.name() == QLatin1String("message")) { + activity.setMessage(xml.readElementText()); + } else if (xml.name() == QLatin1String("link")) { + activity.setLink(QUrl(xml.readElementText())); + } + } else if (xml.isEndElement() && xml.name() == QLatin1String("activity")) { + break; + } + } + + activity.setAssociatedPerson(person); + return activity; +} + +QStringList Activity::Parser::xmlElement() const +{ + return QStringList(QStringLiteral("activity")); +} diff --git a/local/recipes/kde/kf6-attica/source/src/activityparser.h b/local/recipes/kde/kf6-attica/source/src/activityparser.h new file mode 100644 index 00000000..b5818f70 --- /dev/null +++ b/local/recipes/kde/kf6-attica/source/src/activityparser.h @@ -0,0 +1,26 @@ +/* + This file is part of KDE. + + SPDX-FileCopyrightText: 2008 Cornelius Schumacher + + SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL +*/ + +#ifndef ATTICA_ACTIVITYPARSER_H +#define ATTICA_ACTIVITYPARSER_H + +#include "activity.h" +#include "parser.h" + +namespace Attica +{ +class Q_DECL_HIDDEN Activity::Parser : public Attica::Parser +{ +private: + Activity parseXml(QXmlStreamReader &xml) override; + QStringList xmlElement() const override; +}; + +} + +#endif diff --git a/local/recipes/kde/kf6-attica/source/src/atticabasejob.cpp b/local/recipes/kde/kf6-attica/source/src/atticabasejob.cpp new file mode 100644 index 00000000..8be7f327 --- /dev/null +++ b/local/recipes/kde/kf6-attica/source/src/atticabasejob.cpp @@ -0,0 +1,185 @@ +/* + This file is part of KDE. + + SPDX-FileCopyrightText: 2008 Cornelius Schumacher + + SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL +*/ + +#include "atticabasejob.h" + +#include +#include +#include +#include + +#include "platformdependent.h" +#include "platformdependent_v3.h" +#include +#include + +using namespace Attica; + +class Q_DECL_HIDDEN BaseJob::Private +{ +public: + Metadata m_metadata; + PlatformDependent *m_internals; + QPointer m_reply; + bool aborted{false}; + bool started = false; + + Private(PlatformDependent *internals) + : m_internals(internals) + { + } + + bool redirection(QUrl &newUrl) const + { + if (m_reply == nullptr || m_reply->error() != QNetworkReply::NoError) { + return false; + } + + const int httpStatusCode = m_reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(); + if (httpStatusCode == 301 // Moved Permanently + || httpStatusCode == 302 // Found + || httpStatusCode == 303 // See Other + || httpStatusCode == 307) { // Temporary Redirect + QNetworkRequest request = m_reply->request(); + QUrl redirectUrl(m_reply->attribute(QNetworkRequest::RedirectionTargetAttribute).toUrl()); + if (redirectUrl.isRelative()) { + QUrl baseUrl(request.url()); + newUrl = baseUrl.resolved(redirectUrl); + qCDebug(ATTICA) << "resolving relative URL redirection to" << newUrl.toString(); + } else { + newUrl = redirectUrl; + qCDebug(ATTICA) << "resolving absolute URL redirection to" << newUrl.toString(); + } + return true; + } + + return false; + } +}; + +BaseJob::BaseJob(PlatformDependent *internals) + : d(std::make_unique(internals)) +{ +} + +BaseJob::~BaseJob() = default; + +void BaseJob::dataFinished() +{ + if (!d->m_reply) { + return; + } + + bool error = d->m_reply->error() != QNetworkReply::NoError && d->m_reply->error() != QNetworkReply::OperationCanceledError; + + // handle redirections automatically + QUrl newUrl; + if (d->redirection(newUrl)) { + // qCDebug(ATTICA) << "BaseJob::dataFinished" << newUrl; + QNetworkRequest request = d->m_reply->request(); + QNetworkAccessManager::Operation operation = d->m_reply->operation(); + if (newUrl.isValid() && operation == QNetworkAccessManager::GetOperation) { + d->m_reply->deleteLater(); + // reissue same request with different Url + request.setUrl(newUrl); + d->m_reply = internals()->get(request); + connect(d->m_reply, &QNetworkReply::finished, this, &BaseJob::dataFinished); + return; + } + error = true; + } + + if (error) { + d->m_metadata.setError(Metadata::NetworkError); + d->m_metadata.setStatusCode(d->m_reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt()); + d->m_metadata.setStatusString(d->m_reply->errorString()); + d->m_metadata.setHeaders(d->m_reply->rawHeaderPairs()); + } else if (d->m_reply->error() == QNetworkReply::OperationCanceledError) { + d->m_metadata.setError(Metadata::NoError); + } else { + QByteArray data = d->m_reply->readAll(); + // qCDebug(ATTICA) << "XML Returned:\n" << data; + parse(QString::fromUtf8(data.constData())); + if (d->m_metadata.statusCode() >= 100 && d->m_metadata.statusCode() < 200) { + d->m_metadata.setError(Metadata::NoError); + } else { + d->m_metadata.setError(Metadata::OcsError); + } + } + Q_EMIT finished(this); + + d->m_reply->deleteLater(); + deleteLater(); +} + +void BaseJob::start() +{ + if (!d->started) { + d->started = true; + QTimer::singleShot(0, this, &BaseJob::doWork); + } +} + +void BaseJob::doWork() +{ + if (d->aborted) { + return; + } + + auto platformDependentV3 = dynamic_cast(d->m_internals); + if (platformDependentV3 && !platformDependentV3->isReady()) { + connect(platformDependentV3, &Attica::PlatformDependentV3::readyChanged, this, &BaseJob::doWork); + return; + } + + d->m_reply = executeRequest(); + qCDebug(ATTICA) << "executing" << Utils::toString(d->m_reply->operation()) << "request for" << d->m_reply->url(); + connect(d->m_reply, &QNetworkReply::finished, this, &BaseJob::dataFinished); + connect(d->m_reply->manager(), &QNetworkAccessManager::authenticationRequired, this, &BaseJob::authenticationRequired); + connect(d->m_reply, &QNetworkReply::errorOccurred, [](QNetworkReply::NetworkError code) { + qCDebug(ATTICA) << "error found" << code; + }); +} + +void BaseJob::authenticationRequired(QNetworkReply *reply, QAuthenticator *auth) +{ + auth->setUser(reply->request().attribute((QNetworkRequest::Attribute)BaseJob::UserAttribute).toString()); + auth->setPassword(reply->request().attribute((QNetworkRequest::Attribute)BaseJob::PasswordAttribute).toString()); +} + +void BaseJob::abort() +{ + d->aborted = true; + if (d->m_reply) { + d->m_reply->abort(); + d->m_reply->deleteLater(); + } + deleteLater(); +} + +bool BaseJob::isAborted() const +{ + return d->aborted; +} + +PlatformDependent *BaseJob::internals() +{ + return d->m_internals; +} + +Metadata BaseJob::metadata() const +{ + return d->m_metadata; +} + +void BaseJob::setMetadata(const Attica::Metadata &data) const +{ + d->m_metadata = data; +} + +#include "moc_atticabasejob.cpp" diff --git a/local/recipes/kde/kf6-attica/source/src/atticabasejob.h b/local/recipes/kde/kf6-attica/source/src/atticabasejob.h new file mode 100644 index 00000000..3f0e91d0 --- /dev/null +++ b/local/recipes/kde/kf6-attica/source/src/atticabasejob.h @@ -0,0 +1,88 @@ +/* + This file is part of KDE. + + SPDX-FileCopyrightText: 2008 Cornelius Schumacher + + SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL + */ +#ifndef ATTICA_ATTICABASEJOB_H +#define ATTICA_ATTICABASEJOB_H + +#include + +#include +#include +#include +#include +#include + +#include "attica_export.h" +#include "metadata.h" + +class QNetworkReply; + +namespace Attica +{ +class PlatformDependent; + +/** + * @class BaseJob atticabasejob.h + * + * The baseclass for all job classes. + */ +class ATTICA_EXPORT BaseJob : public QObject +{ + Q_OBJECT + +public: + ~BaseJob() override; + + Metadata metadata() const; + + enum NetworkRequestCustomAttributes { + UserAttribute = QNetworkRequest::User + 1, + PasswordAttribute, + }; + + /** + * @returns whether abort() has been called on the job + * + * @since 5.87 + */ + bool isAborted() const; + +public Q_SLOTS: + void start(); + void abort(); + +Q_SIGNALS: + void finished(Attica::BaseJob *job); + +protected Q_SLOTS: + void dataFinished(); + +protected: + BaseJob(PlatformDependent *internals); + + void setMetadata(const Metadata &data) const; + + virtual QNetworkReply *executeRequest() = 0; + virtual void parse(const QString &xml) = 0; + PlatformDependent *internals(); + void setError(int errorCode); + +private Q_SLOTS: + ATTICA_NO_EXPORT void doWork(); + ATTICA_NO_EXPORT void authenticationRequired(QNetworkReply *, QAuthenticator *); + +private: + BaseJob(const BaseJob &other) = delete; + BaseJob &operator=(const BaseJob &other) = delete; + + class Private; + std::unique_ptr d; +}; + +} + +#endif diff --git a/local/recipes/kde/kf6-attica/source/src/atticautils.cpp b/local/recipes/kde/kf6-attica/source/src/atticautils.cpp new file mode 100644 index 00000000..558621bf --- /dev/null +++ b/local/recipes/kde/kf6-attica/source/src/atticautils.cpp @@ -0,0 +1,83 @@ +/* + This file is part of KDE. + + SPDX-FileCopyrightText: 2010 Intel Corporation + SPDX-FileContributor: Mateu Batle Sastre + + SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL +*/ + +#include "atticautils.h" +#include +#include + +using namespace Attica; + +QDateTime Utils::parseQtDateTimeIso8601(const QString &str) +{ + QDateTime result; + QStringList list; + QString datetime; + + int tzsign = 0; + if (str.indexOf(QLatin1String("+")) != -1) { + list = str.split(QStringLiteral("+")); + datetime = list[0]; + tzsign = 1; + } else if (str.indexOf(QLatin1String("-")) != -1) { + list = str.split(QStringLiteral("-")); + datetime = list[0]; + tzsign = -1; + } else { + datetime = str; + } + + // parse date time + result = QDateTime::fromString(datetime, Qt::ISODate); + result.setTimeZone(QTimeZone::utc()); + + // parse timezone + if (list.count() == 2) { + QString tz = list[1]; + int hh = 0; + int mm = 0; + int tzsecs = 0; + if (tz.indexOf(QLatin1Char(':')) != -1) { + QStringList tzlist = tz.split(QLatin1Char(':')); + if (tzlist.count() == 2) { + hh = tzlist[0].toInt(); + mm = tzlist[1].toInt(); + } + } else { + QStringView sv(tz); + hh = sv.left(2).toInt(); + mm = sv.mid(2).toInt(); + } + + tzsecs = 60 * 60 * hh + 60 * mm; + result = result.addSecs(-tzsecs * tzsign); + } + + return result; +} + +const char *Utils::toString(QNetworkAccessManager::Operation operation) +{ + switch (operation) { + case QNetworkAccessManager::GetOperation: + return "Get"; + case QNetworkAccessManager::HeadOperation: + return "Head"; + case QNetworkAccessManager::PutOperation: + return "Put"; + case QNetworkAccessManager::PostOperation: + return "Post"; + case QNetworkAccessManager::DeleteOperation: + return "Delete"; + case QNetworkAccessManager::CustomOperation: + return "Custom"; + default: + return "unknown"; + } + return "invalid"; +} diff --git a/local/recipes/kde/kf6-attica/source/src/atticautils.h b/local/recipes/kde/kf6-attica/source/src/atticautils.h new file mode 100644 index 00000000..313cb427 --- /dev/null +++ b/local/recipes/kde/kf6-attica/source/src/atticautils.h @@ -0,0 +1,29 @@ +/* + This file is part of KDE. + + SPDX-FileCopyrightText: 2010 Intel Corporation + SPDX-FileContributor: Mateu Batle Sastre + + SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL +*/ + +#ifndef ATTICAUTILS_H +#define ATTICAUTILS_H + +#include +#include +#include + +namespace Attica +{ +class Utils +{ +public: + /// parses the QtDateTime in ISO 8601 format correctly (recognizes TZ properly) + static QDateTime parseQtDateTimeIso8601(const QString &str); + static const char *toString(QNetworkAccessManager::Operation operation); +}; + +} + +#endif // ATTICAUTILS_H diff --git a/local/recipes/kde/kf6-attica/source/src/buildservice.cpp b/local/recipes/kde/kf6-attica/source/src/buildservice.cpp new file mode 100644 index 00000000..77c77b4e --- /dev/null +++ b/local/recipes/kde/kf6-attica/source/src/buildservice.cpp @@ -0,0 +1,90 @@ +/* + This file is part of KDE. + + SPDX-FileCopyrightText: 2010 Sebastian Kügler + + SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL +*/ + +#include "buildservice.h" + +using namespace Attica; + +class Q_DECL_HIDDEN BuildService::Private : public QSharedData +{ +public: + QString id; + QString name; + QString url; + // QStringList targets; + QList targets; + + Private() + { + } +}; + +BuildService::BuildService() + : d(new Private) +{ +} + +BuildService::BuildService(const BuildService &other) + : d(other.d) +{ +} + +BuildService &BuildService::operator=(const Attica::BuildService &other) +{ + d = other.d; + return *this; +} + +BuildService::~BuildService() +{ +} + +void BuildService::setId(const QString &u) +{ + d->id = u; +} + +QString BuildService::id() const +{ + return d->id; +} + +void BuildService::setName(const QString &u) +{ + d->name = u; +} + +QString BuildService::name() const +{ + return d->name; +} + +void BuildService::addTarget(const Target &t) +{ + d->targets << t; +} + +QList BuildService::targets() const +{ + return d->targets; +} + +void BuildService::setUrl(const QString &u) +{ + d->url = u; +} + +QString BuildService::url() const +{ + return d->url; +} + +bool BuildService::isValid() const +{ + return !(d->id.isEmpty()); +} diff --git a/local/recipes/kde/kf6-attica/source/src/buildservice.h b/local/recipes/kde/kf6-attica/source/src/buildservice.h new file mode 100644 index 00000000..bfb87337 --- /dev/null +++ b/local/recipes/kde/kf6-attica/source/src/buildservice.h @@ -0,0 +1,70 @@ +/* + This file is part of KDE. + + SPDX-FileCopyrightText: 2010 Sebastian Kügler + + SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL +*/ +#ifndef ATTICA_BUILDSERVICE_H +#define ATTICA_BUILDSERVICE_H + +#include +#include +#include +#include +#include +#include + +#include "attica_export.h" + +namespace Attica +{ + +/** + * @class Target buildservice.h + * + * The target in a build service. + */ +struct Target { + QString id; + QString name; +}; + +/** + * @class BuildService buildservice.h + * + * Represents a build service. + */ +class ATTICA_EXPORT BuildService +{ +public: + typedef QList List; + class Parser; + + BuildService(); + BuildService(const BuildService &other); + BuildService &operator=(const BuildService &other); + ~BuildService(); + + void setId(const QString &); + QString id() const; + + void setName(const QString &); + QString name() const; + + void setUrl(const QString &); + QString url() const; + + void addTarget(const Target &); + QList targets() const; + + bool isValid() const; + +private: + class Private; + QSharedDataPointer d; +}; + +} + +#endif diff --git a/local/recipes/kde/kf6-attica/source/src/buildservicejob.cpp b/local/recipes/kde/kf6-attica/source/src/buildservicejob.cpp new file mode 100644 index 00000000..650a4a43 --- /dev/null +++ b/local/recipes/kde/kf6-attica/source/src/buildservicejob.cpp @@ -0,0 +1,154 @@ +/* + This file is part of KDE. + + SPDX-FileCopyrightText: 2010 Sebastian Kügler + + SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL +*/ + +#include "buildservicejob.h" + +using namespace Attica; + +class Q_DECL_HIDDEN BuildServiceJob::Private : public QSharedData +{ +public: + QString id; + QString name; + int status; + qreal progress; + QString projectId; + QString target; + QString buildServiceId; + QString url; + QString message; + + Private() + { + } +}; + +BuildServiceJob::BuildServiceJob() + : d(new Private) +{ +} + +BuildServiceJob::BuildServiceJob(const BuildServiceJob &other) + : d(other.d) +{ +} + +BuildServiceJob &BuildServiceJob::operator=(const Attica::BuildServiceJob &other) +{ + d = other.d; + return *this; +} + +BuildServiceJob::~BuildServiceJob() +{ +} + +void BuildServiceJob::setId(const QString &u) +{ + d->id = u; +} + +QString BuildServiceJob::id() const +{ + return d->id; +} + +void BuildServiceJob::setName(const QString &u) +{ + d->name = u; +} + +QString BuildServiceJob::name() const +{ + return d->name; +} + +void BuildServiceJob::setProgress(const qreal p) +{ + d->progress = p; +} + +qreal BuildServiceJob::progress() const +{ + return d->progress; +} + +void BuildServiceJob::setStatus(const int status) +{ + d->status = status; +} + +bool BuildServiceJob::isRunning() const +{ + return d->status == 1; +} + +bool BuildServiceJob::isCompleted() const +{ + return d->status == 2; +} + +bool BuildServiceJob::isFailed() const +{ + return d->status == 3; +} + +void BuildServiceJob::setUrl(const QString &u) +{ + d->url = u; +} + +QString BuildServiceJob::url() const +{ + return d->url; +} + +void BuildServiceJob::setMessage(const QString &u) +{ + d->message = u; +} + +QString BuildServiceJob::message() const +{ + return d->message; +} + +void BuildServiceJob::setProjectId(const QString &u) +{ + d->projectId = u; +} + +QString BuildServiceJob::projectId() const +{ + return d->projectId; +} + +void BuildServiceJob::setTarget(const QString &u) +{ + d->target = u; +} + +QString BuildServiceJob::target() const +{ + return d->target; +} + +void BuildServiceJob::setBuildServiceId(const QString &u) +{ + d->buildServiceId = u; +} + +QString BuildServiceJob::buildServiceId() const +{ + return d->buildServiceId; +} + +bool BuildServiceJob::isValid() const +{ + return !(d->id.isEmpty()); +} diff --git a/local/recipes/kde/kf6-attica/source/src/buildservicejob.h b/local/recipes/kde/kf6-attica/source/src/buildservicejob.h new file mode 100644 index 00000000..f734cabd --- /dev/null +++ b/local/recipes/kde/kf6-attica/source/src/buildservicejob.h @@ -0,0 +1,77 @@ +/* + This file is part of KDE. + + SPDX-FileCopyrightText: 2010 Sebastian Kügler + + SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL +*/ +#ifndef ATTICA_BUILDSERVICEJOB_H +#define ATTICA_BUILDSERVICEJOB_H + +#include +#include +#include +#include +#include +#include + +#include "attica_export.h" + +namespace Attica +{ + +/** + * @class BuildServiceJob buildservicejob.h + * + * Represents a build service job. + */ +class ATTICA_EXPORT BuildServiceJob +{ +public: + typedef QList List; + class Parser; + + BuildServiceJob(); + BuildServiceJob(const BuildServiceJob &other); + BuildServiceJob &operator=(const BuildServiceJob &other); + ~BuildServiceJob(); + + void setId(const QString &); + QString id() const; + + void setName(const QString &); + QString name() const; + + void setUrl(const QString &); + QString url() const; + + void setProjectId(const QString &); + QString projectId() const; + + void setBuildServiceId(const QString &); + QString buildServiceId() const; + + void setMessage(const QString &); + QString message() const; + + void setTarget(const QString &); + QString target() const; + + void setProgress(const qreal); + qreal progress() const; + + void setStatus(const int); + bool isRunning() const; + bool isCompleted() const; + bool isFailed() const; + + bool isValid() const; + +private: + class Private; + QSharedDataPointer d; +}; + +} + +#endif diff --git a/local/recipes/kde/kf6-attica/source/src/buildservicejoboutput.cpp b/local/recipes/kde/kf6-attica/source/src/buildservicejoboutput.cpp new file mode 100644 index 00000000..f98fe6f1 --- /dev/null +++ b/local/recipes/kde/kf6-attica/source/src/buildservicejoboutput.cpp @@ -0,0 +1,56 @@ +/* + This file is part of KDE. + + SPDX-FileCopyrightText: 2010 Dan Leinir Turthra Jensen + + SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL +*/ + +#include "buildservicejoboutput.h" + +using namespace Attica; + +class Q_DECL_HIDDEN BuildServiceJobOutput::Private : public QSharedData +{ +public: + QString output; + + Private() + { + } +}; + +BuildServiceJobOutput::BuildServiceJobOutput() + : d(new Private) +{ +} + +BuildServiceJobOutput::BuildServiceJobOutput(const BuildServiceJobOutput &other) + : d(other.d) +{ +} + +BuildServiceJobOutput &BuildServiceJobOutput::operator=(const Attica::BuildServiceJobOutput &other) +{ + d = other.d; + return *this; +} + +BuildServiceJobOutput::~BuildServiceJobOutput() +{ +} + +void BuildServiceJobOutput::setOutput(const QString &output) +{ + d->output = output; +} + +QString BuildServiceJobOutput::output() const +{ + return d->output; +} + +bool BuildServiceJobOutput::isValid() const +{ + return !(d->output.isNull()); +} diff --git a/local/recipes/kde/kf6-attica/source/src/buildservicejoboutput.h b/local/recipes/kde/kf6-attica/source/src/buildservicejoboutput.h new file mode 100644 index 00000000..e268f88c --- /dev/null +++ b/local/recipes/kde/kf6-attica/source/src/buildservicejoboutput.h @@ -0,0 +1,52 @@ +/* + This file is part of KDE. + + SPDX-FileCopyrightText: 2010 Dan Leinir Turthra Jensen + + SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL +*/ +#ifndef ATTICA_BUILDSERVICEJOBOUTPUT_H +#define ATTICA_BUILDSERVICEJOBOUTPUT_H + +#include +#include +#include + +#include "attica_export.h" + +namespace Attica +{ + +/** + * @class BuildServiceJobOutput buildservicejoboutput.h + * + * Represents the ouput of a build service job. + */ +class ATTICA_EXPORT BuildServiceJobOutput +{ +public: + typedef QList List; + class Parser; + + BuildServiceJobOutput(); + BuildServiceJobOutput(const BuildServiceJobOutput &other); + BuildServiceJobOutput &operator=(const BuildServiceJobOutput &other); + ~BuildServiceJobOutput(); + + void setOutput(const QString &output); + QString output() const; + + bool isRunning() const; + bool isCompleted() const; + bool isFailed() const; + + bool isValid() const; + +private: + class Private; + QSharedDataPointer d; +}; + +} // namespace Attica + +#endif // ATTICA_BUILDSERVICEJOBOUTPUT_H diff --git a/local/recipes/kde/kf6-attica/source/src/buildservicejoboutputparser.cpp b/local/recipes/kde/kf6-attica/source/src/buildservicejoboutputparser.cpp new file mode 100644 index 00000000..4322ef92 --- /dev/null +++ b/local/recipes/kde/kf6-attica/source/src/buildservicejoboutputparser.cpp @@ -0,0 +1,36 @@ +/* + This file is part of KDE. + + SPDX-FileCopyrightText: 2010 Dan Leinir Turthra Jensen + + SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL +*/ + +#include "buildservicejoboutputparser.h" +#include "qdebug.h" + +using namespace Attica; + +BuildServiceJobOutput BuildServiceJobOutput::Parser::parseXml(QXmlStreamReader &xml) +{ + BuildServiceJobOutput buildservicejoboutput; + + // For specs about the XML provided, see here: + // http://www.freedesktop.org/wiki/Specifications/open-collaboration-services-draft#BuildServiceJobs + while (!xml.atEnd()) { + if (xml.isStartElement()) { + if (xml.name() == QLatin1String("output")) { + buildservicejoboutput.setOutput(xml.readElementText()); + } + } else if (xml.isEndElement() && xml.name() == QLatin1String("output")) { + break; + } + xml.readNext(); + } + return buildservicejoboutput; +} + +QStringList BuildServiceJobOutput::Parser::xmlElement() const +{ + return QStringList(QStringLiteral("output")); +} diff --git a/local/recipes/kde/kf6-attica/source/src/buildservicejoboutputparser.h b/local/recipes/kde/kf6-attica/source/src/buildservicejoboutputparser.h new file mode 100644 index 00000000..21b8123b --- /dev/null +++ b/local/recipes/kde/kf6-attica/source/src/buildservicejoboutputparser.h @@ -0,0 +1,26 @@ +/* + This file is part of KDE. + + SPDX-FileCopyrightText: 2010 Dan Leinir Turthra Jensen + + SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL +*/ + +#ifndef ATTICA_BUILDSERVICEJOBOUTPUTPARSER_H +#define ATTICA_BUILDSERVICEJOBOUTPUTPARSER_H + +#include "buildservicejoboutput.h" +#include "parser.h" + +namespace Attica +{ +class Q_DECL_HIDDEN BuildServiceJobOutput::Parser : public Attica::Parser +{ +public: + BuildServiceJobOutput parseXml(QXmlStreamReader &xml) override; + QStringList xmlElement() const override; +}; + +} // namespace Attica + +#endif // ATTICA_BUILDSERVICEJOBOUTPUTPARSER_H diff --git a/local/recipes/kde/kf6-attica/source/src/buildservicejobparser.cpp b/local/recipes/kde/kf6-attica/source/src/buildservicejobparser.cpp new file mode 100644 index 00000000..fde296ae --- /dev/null +++ b/local/recipes/kde/kf6-attica/source/src/buildservicejobparser.cpp @@ -0,0 +1,56 @@ +/* + This file is part of KDE. + + SPDX-FileCopyrightText: 2010 Sebastian Kügler + + SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL +*/ + +#include "buildservicejobparser.h" +#include + +using namespace Attica; + +BuildServiceJob BuildServiceJob::Parser::parseXml(QXmlStreamReader &xml) +{ + BuildServiceJob buildservicejob; + + // For specs about the XML provided, see here: + // http://www.freedesktop.org/wiki/Specifications/open-collaboration-services-draft#BuildServiceJobs + while (!xml.atEnd()) { + // qCDebug(ATTICA) << "XML returned:" << xml.text().toString(); + xml.readNext(); + + if (xml.isStartElement()) { + if (xml.name() == QLatin1String("id")) { // FIXME: server should give "id" here ... + buildservicejob.setId(xml.readElementText()); + } else if (xml.name() == QLatin1String("project")) { + buildservicejob.setProjectId(xml.readElementText()); + } else if (xml.name() == QLatin1String("buildservice")) { + buildservicejob.setBuildServiceId(xml.readElementText()); + } else if (xml.name() == QLatin1String("target")) { + buildservicejob.setTarget(xml.readElementText()); + } else if (xml.name() == QLatin1String("name")) { + buildservicejob.setName(xml.readElementText()); + } else if (xml.name() == QLatin1String("status")) { + int status = xml.readElementText().toInt(); + buildservicejob.setStatus(status); + } else if (xml.name() == QLatin1String("progress")) { + qreal progress = (qreal)(xml.readElementText().toFloat()); + buildservicejob.setProgress(progress); + } else if (xml.name() == QLatin1String("message")) { + buildservicejob.setMessage(xml.readElementText()); + } else if (xml.name() == QLatin1String("url")) { + buildservicejob.setUrl(xml.readElementText()); + } + } else if (xml.isEndElement() && (xml.name() == QLatin1String("buildjob") || xml.name() == QLatin1String("user"))) { + break; + } + } + return buildservicejob; +} + +QStringList BuildServiceJob::Parser::xmlElement() const +{ + return QStringList(QStringLiteral("buildjob")) << QStringLiteral("user"); +} diff --git a/local/recipes/kde/kf6-attica/source/src/buildservicejobparser.h b/local/recipes/kde/kf6-attica/source/src/buildservicejobparser.h new file mode 100644 index 00000000..e632e896 --- /dev/null +++ b/local/recipes/kde/kf6-attica/source/src/buildservicejobparser.h @@ -0,0 +1,26 @@ +/* + This file is part of KDE. + + SPDX-FileCopyrightText: 2010 Sebastian Kügler + + SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL +*/ + +#ifndef ATTICA_BUILDSERVICEJOBPARSER_H +#define ATTICA_BUILDSERVICEJOBPARSER_H + +#include "buildservicejob.h" +#include "parser.h" + +namespace Attica +{ +class Q_DECL_HIDDEN BuildServiceJob::Parser : public Attica::Parser +{ +private: + BuildServiceJob parseXml(QXmlStreamReader &xml) override; + QStringList xmlElement() const override; +}; + +} + +#endif diff --git a/local/recipes/kde/kf6-attica/source/src/buildserviceparser.cpp b/local/recipes/kde/kf6-attica/source/src/buildserviceparser.cpp new file mode 100644 index 00000000..c64f047c --- /dev/null +++ b/local/recipes/kde/kf6-attica/source/src/buildserviceparser.cpp @@ -0,0 +1,69 @@ +/* + This file is part of KDE. + + SPDX-FileCopyrightText: 2010 Sebastian Kügler + + SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL +*/ + +#include "buildserviceparser.h" +#include + +using namespace Attica; + +BuildService BuildService::Parser::parseXml(QXmlStreamReader &xml) +{ + // For specs about the XML provided, see here: + // http://www.freedesktop.org/wiki/Specifications/open-collaboration-services-draft + + BuildService buildservice; + + while (!xml.atEnd()) { + xml.readNext(); + + if (xml.isStartElement()) { + if (xml.name() == QLatin1String("id")) { + buildservice.setId(xml.readElementText()); + } else if (xml.name() == QLatin1String("name")) { + buildservice.setName(xml.readElementText()); + } else if (xml.name() == QLatin1String("registrationurl")) { + buildservice.setUrl(xml.readElementText()); + } else if (xml.name() == QLatin1String("supportedtargets")) { + while (!xml.atEnd()) { + xml.readNextStartElement(); + if (xml.isStartElement()) { + if (xml.name() == QLatin1String("target")) { + Target t; + while (!xml.atEnd()) { + xml.readNextStartElement(); + if (xml.isStartElement()) { + if (xml.name() == QLatin1String("id")) { + t.id = xml.readElementText(); + } else if (xml.name() == QLatin1String("name")) { + t.name = xml.readElementText(); + } + } else if (xml.isEndElement() && (xml.name() == QLatin1String("target"))) { + xml.readNext(); + break; + } + } + buildservice.addTarget(t); + } + } else if (xml.isEndElement() && (xml.name() == QLatin1String("supportedtargets"))) { + xml.readNext(); + break; + } + } + } + } else if (xml.isEndElement() // + && (xml.name() == QLatin1String("buildservice") || xml.name() == QLatin1String("user"))) { + break; + } + } + return buildservice; +} + +QStringList BuildService::Parser::xmlElement() const +{ + return QStringList(QStringLiteral("buildservice")) << QStringLiteral("user"); +} diff --git a/local/recipes/kde/kf6-attica/source/src/buildserviceparser.h b/local/recipes/kde/kf6-attica/source/src/buildserviceparser.h new file mode 100644 index 00000000..26e27120 --- /dev/null +++ b/local/recipes/kde/kf6-attica/source/src/buildserviceparser.h @@ -0,0 +1,26 @@ +/* + This file is part of KDE. + + SPDX-FileCopyrightText: 2010 Sebastian Kügler + + SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL +*/ + +#ifndef ATTICA_BUILDSERVICEPARSER_H +#define ATTICA_BUILDSERVICEPARSER_H + +#include "buildservice.h" +#include "parser.h" + +namespace Attica +{ +class Q_DECL_HIDDEN BuildService::Parser : public Attica::Parser +{ +private: + BuildService parseXml(QXmlStreamReader &xml) override; + QStringList xmlElement() const override; +}; + +} + +#endif diff --git a/local/recipes/kde/kf6-attica/source/src/category.cpp b/local/recipes/kde/kf6-attica/source/src/category.cpp new file mode 100644 index 00000000..e4da6f4b --- /dev/null +++ b/local/recipes/kde/kf6-attica/source/src/category.cpp @@ -0,0 +1,77 @@ +/* + This file is part of KDE. + + SPDX-FileCopyrightText: 2008 Cornelius Schumacher + + SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL +*/ + +#include "category.h" + +#include +#include + +using namespace Attica; + +class Q_DECL_HIDDEN Category::Private : public QSharedData +{ +public: + QString m_id; + QString m_name; + QString m_displayName; +}; + +Category::Category() + : d(new Private) +{ +} + +Category::Category(const Attica::Category &other) + : d(other.d) +{ +} + +Category &Category::operator=(const Attica::Category &other) +{ + d = other.d; + return *this; +} + +Category::~Category() +{ +} + +void Category::setId(const QString &u) +{ + d->m_id = u; +} + +QString Category::id() const +{ + return d->m_id; +} + +void Category::setName(const QString &name) +{ + d->m_name = name; +} + +QString Category::name() const +{ + return d->m_name; +} + +void Category::setDisplayName(const QString &name) +{ + d->m_displayName = name; +} + +QString Category::displayName() const +{ + return d->m_displayName; +} + +bool Category::isValid() const +{ + return !(d->m_id.isEmpty()); +} diff --git a/local/recipes/kde/kf6-attica/source/src/category.h b/local/recipes/kde/kf6-attica/source/src/category.h new file mode 100644 index 00000000..bfe92042 --- /dev/null +++ b/local/recipes/kde/kf6-attica/source/src/category.h @@ -0,0 +1,109 @@ +/* + This file is part of KDE. + + SPDX-FileCopyrightText: 2008 Cornelius Schumacher + + SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL +*/ +#ifndef ATTICA_CATEGORY_H +#define ATTICA_CATEGORY_H + +#include +#include + +#include "attica_export.h" + +namespace Attica +{ +/** + * @class Category category.h + * + * Represents a single content category + */ +class ATTICA_EXPORT Category +{ +public: + typedef QList List; + class Parser; + + /** + * Creates an empty Category + */ + Category(); + + /** + * Copy constructor. + * @param other the Category to copy from + */ + Category(const Category &other); + + /** + * Assignment operator. + * @param other the Category to assign from + * @return pointer to this Category + */ + Category &operator=(const Category &other); + + /** + * Destructor. + */ + ~Category(); + + /** + * Sets the id of the Category. + * The id uniquely identifies a Category with the OCS API. + * @param id the new id + */ + void setId(const QString &); + + /** + * Gets the id of the Category. + * The id uniquely identifies a Category with the OCS API. + * @return the id + */ + QString id() const; + + /** + * Sets the name of the Category. + * @param name the new name + */ + void setName(const QString &name); + + /** + * Gets the name of the Category. + * @return the name + */ + QString name() const; + + /** + * Checks whether this Category has an id + * @return @c true if an id has been set, @c false otherwise + */ + bool isValid() const; + + /** + * Sets the display name of the Category. + * This name is guaranteed to be user friendly, while name may be + * internal for the server + * @param name the new name + * @since 5.31 + */ + void setDisplayName(const QString &name); + + /** + * Gets the display name of the Category. + * This name is guaranteed to be user friendly, while name may be + * internal for the server + * @return the name + * @since 5.31 + */ + QString displayName() const; + +private: + class Private; + QSharedDataPointer d; +}; + +} + +#endif diff --git a/local/recipes/kde/kf6-attica/source/src/categoryparser.cpp b/local/recipes/kde/kf6-attica/source/src/categoryparser.cpp new file mode 100644 index 00000000..39b9fd73 --- /dev/null +++ b/local/recipes/kde/kf6-attica/source/src/categoryparser.cpp @@ -0,0 +1,39 @@ +/* + This file is part of KDE. + + SPDX-FileCopyrightText: 2008 Cornelius Schumacher + + SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL +*/ + +#include "categoryparser.h" + +using namespace Attica; + +Category Category::Parser::parseXml(QXmlStreamReader &xml) +{ + Category category; + + while (!xml.atEnd()) { + xml.readNext(); + + if (xml.isStartElement()) { + if (xml.name() == QLatin1String("id")) { + category.setId(xml.readElementText()); + } else if (xml.name() == QLatin1String("name")) { + category.setName(xml.readElementText()); + } else if (xml.name() == QLatin1String("display_name")) { + category.setDisplayName(xml.readElementText()); + } + } else if (xml.isEndElement() && xml.name() == QLatin1String("category")) { + break; + } + } + + return category; +} + +QStringList Category::Parser::xmlElement() const +{ + return QStringList(QStringLiteral("category")); +} diff --git a/local/recipes/kde/kf6-attica/source/src/categoryparser.h b/local/recipes/kde/kf6-attica/source/src/categoryparser.h new file mode 100644 index 00000000..7c3f24bd --- /dev/null +++ b/local/recipes/kde/kf6-attica/source/src/categoryparser.h @@ -0,0 +1,26 @@ +/* + This file is part of KDE. + + SPDX-FileCopyrightText: 2008 Cornelius Schumacher + + SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL +*/ + +#ifndef ATTICA_CATEGORYPARSER_H +#define ATTICA_CATEGORYPARSER_H + +#include "category.h" +#include "parser.h" + +namespace Attica +{ +class Q_DECL_HIDDEN Category::Parser : public Attica::Parser +{ +private: + Category parseXml(QXmlStreamReader &xml) override; + QStringList xmlElement() const override; +}; + +} + +#endif diff --git a/local/recipes/kde/kf6-attica/source/src/cloud.cpp b/local/recipes/kde/kf6-attica/source/src/cloud.cpp new file mode 100644 index 00000000..8dcb82a9 --- /dev/null +++ b/local/recipes/kde/kf6-attica/source/src/cloud.cpp @@ -0,0 +1,124 @@ +/* + This file is part of KDE. + + SPDX-FileCopyrightText: 2012 Laszlo Papp + + SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL +*/ + +#include "cloud.h" + +using namespace Attica; + +class Q_DECL_HIDDEN Cloud::Private : public QSharedData +{ +public: + QString m_name; + QString m_url; + QUrl m_icon; + qulonglong m_quota; + qulonglong m_free; + qulonglong m_used; + float m_relative; + QString m_key; +}; + +Cloud::Cloud() + : d(new Private) +{ +} + +Cloud::Cloud(const Attica::Cloud &other) + : d(other.d) +{ +} + +Cloud &Cloud::operator=(const Attica::Cloud &other) +{ + d = other.d; + return *this; +} + +Cloud::~Cloud() +{ +} + +void Cloud::setName(const QString &name) +{ + d->m_name = name; +} + +QString Cloud::name() const +{ + return d->m_name; +} + +void Cloud::setUrl(const QString &url) +{ + d->m_url = url; +} + +QString Cloud::url() const +{ + return d->m_url; +} + +void Cloud::setIcon(const QUrl &icon) +{ + d->m_icon = icon; +} + +QUrl Cloud::icon() const +{ + return d->m_icon; +} + +void Cloud::setQuota(qulonglong quota) +{ + d->m_quota = quota; +} + +qulonglong Cloud::quota() const +{ + return d->m_quota; +} + +void Cloud::setFree(qulonglong free) +{ + d->m_free = free; +} + +qulonglong Cloud::free() const +{ + return d->m_free; +} + +void Cloud::setUsed(qulonglong used) +{ + d->m_used = used; +} + +qulonglong Cloud::used() const +{ + return d->m_used; +} + +void Cloud::setRelative(float relative) +{ + d->m_relative = relative; +} + +float Cloud::relative() const +{ + return d->m_relative; +} + +void Cloud::setKey(const QString &key) +{ + d->m_key = key; +} + +QString Cloud::key() const +{ + return d->m_key; +} diff --git a/local/recipes/kde/kf6-attica/source/src/cloud.h b/local/recipes/kde/kf6-attica/source/src/cloud.h new file mode 100644 index 00000000..cd797134 --- /dev/null +++ b/local/recipes/kde/kf6-attica/source/src/cloud.h @@ -0,0 +1,194 @@ +/* + This file is part of KDE. + + SPDX-FileCopyrightText: 2012 Laszlo Papp + + SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL +*/ + +#ifndef ATTICA_CLOUD_H +#define ATTICA_CLOUD_H + +#include "attica_export.h" + +#include +#include +#include + +namespace Attica +{ + +/** + * @class Cloud cloud.h + * + * Represents a cloud service. + */ +class ATTICA_EXPORT Cloud +{ +public: + typedef QList List; + class Parser; + + /** + * Creates an empty Cloud + */ + + Cloud(); + + /** + * Copy constructor. + * @param other the Cloud to copy from + */ + + Cloud(const Cloud &other); + + /** + * Assignment operator. + * @param other the Cloud to assign from + * @return pointer to this Activity + */ + + Cloud &operator=(const Cloud &other); + + /** + * Destructor. + */ + + ~Cloud(); + + /** + * Sets the name of the Cloud service + * + * @param name the new name + */ + + void setName(const QString &name); + + /** + * Gets the name of the Cloud service. + * + * @return the name + */ + + QString name() const; + + /** + * Sets the url of the Cloud service + * + * @param url the new url + */ + + void setUrl(const QString &url); + + /** + * Gets the url of the Cloud service. + * + * @return the url + */ + + QString url() const; + + /** + * Sets the icon of the Cloud service + * + * @param icon the new icon + */ + + void setIcon(const QUrl &icon); + + /** + * Gets the icon of the Cloud service. + * + * @return the icon + */ + + QUrl icon() const; + + /** + * Sets the quota of the Cloud service + * + * @param quota the new quota + */ + + void setQuota(qulonglong quota); + + /** + * Gets the quota of the Cloud service. + * + * @return the quota + */ + + qulonglong quota() const; + + /** + * Sets the free amount of the Cloud service + * + * @param free the new free amount + */ + + void setFree(qulonglong free); + + /** + * Gets the free amount of the Cloud service. + * + * @return the free amount + */ + + qulonglong free() const; + + /** + * Sets the used amount of the Cloud service + * + * @param used the new used amount + */ + + void setUsed(qulonglong used); + + /** + * Gets the used amount of the Cloud service. + * + * @return the used amount + */ + + qulonglong used() const; + + /** + * Sets the relative of the Cloud service + * + * @param relative the new relative + */ + + void setRelative(float relative); + + /** + * Gets the relative of the Cloud service. + * + * @return the relative + */ + + float relative() const; + + /** + * Sets the private key of the Cloud service + * + * @param privateKey the new privateKey + */ + + void setKey(const QString &privateKey); + + /** + * Gets the private key of the Cloud service. + * + * @return the private key + */ + + QString key() const; + +private: + class Private; + QSharedDataPointer d; +}; + +} + +#endif diff --git a/local/recipes/kde/kf6-attica/source/src/cloudparser.cpp b/local/recipes/kde/kf6-attica/source/src/cloudparser.cpp new file mode 100644 index 00000000..6e376937 --- /dev/null +++ b/local/recipes/kde/kf6-attica/source/src/cloudparser.cpp @@ -0,0 +1,51 @@ +/* + This file is part of KDE. + + SPDX-FileCopyrightText: 2012 Laszlo Papp + + SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL +*/ + +#include "cloudparser.h" +#include "atticautils.h" + +using namespace Attica; + +Cloud Cloud::Parser::parseXml(QXmlStreamReader &xml) +{ + Cloud cloud; + + while (!xml.atEnd()) { + xml.readNext(); + + if (xml.isStartElement()) { + if (xml.name() == QLatin1String("name")) { + cloud.setName(xml.readElementText()); + } else if (xml.name() == QLatin1String("url")) { + cloud.setUrl(xml.readElementText()); + // TODO: there should be usage for the attica icon class + } else if (xml.name() == QLatin1String("icon")) { + cloud.setIcon(QUrl(xml.readElementText())); + } else if (xml.name() == QLatin1String("quota")) { + cloud.setQuota(xml.readElementText().toULongLong()); + } else if (xml.name() == QLatin1String("free")) { + cloud.setFree(xml.readElementText().toULongLong()); + } else if (xml.name() == QLatin1String("used")) { + cloud.setUsed(xml.readElementText().toULongLong()); + } else if (xml.name() == QLatin1String("relative")) { + cloud.setRelative(xml.readElementText().toFloat()); + } else if (xml.name() == QLatin1String("key")) { + cloud.setKey(xml.readElementText()); + } + } else if (xml.isEndElement() && xml.name() == QLatin1String("cloud")) { + break; + } + } + + return cloud; +} + +QStringList Cloud::Parser::xmlElement() const +{ + return QStringList(QLatin1String("cloud")); +} diff --git a/local/recipes/kde/kf6-attica/source/src/cloudparser.h b/local/recipes/kde/kf6-attica/source/src/cloudparser.h new file mode 100644 index 00000000..ad9da7bd --- /dev/null +++ b/local/recipes/kde/kf6-attica/source/src/cloudparser.h @@ -0,0 +1,26 @@ +/* + This file is part of KDE. + + SPDX-FileCopyrightText: 2012 Laszlo Papp + + SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL +*/ + +#ifndef ATTICA_CLOUDPARSER_H +#define ATTICA_CLOUDPARSER_H + +#include "cloud.h" +#include "parser.h" + +namespace Attica +{ +class Q_DECL_HIDDEN Cloud::Parser : public Attica::Parser +{ +private: + Cloud parseXml(QXmlStreamReader &xml); + QStringList xmlElement() const; +}; + +} + +#endif diff --git a/local/recipes/kde/kf6-attica/source/src/comment.cpp b/local/recipes/kde/kf6-attica/source/src/comment.cpp new file mode 100644 index 00000000..35071049 --- /dev/null +++ b/local/recipes/kde/kf6-attica/source/src/comment.cpp @@ -0,0 +1,155 @@ +/* + This file is part of KDE. + + SPDX-FileCopyrightText: 2010 Intel Corporation + SPDX-FileContributor: Mateu Batle Sastre + + SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL +*/ + +#include "comment.h" + +#include + +using namespace Attica; + +QString Comment::commentTypeToString(const Comment::Type type) +{ + switch (type) { + case ContentComment: + return QStringLiteral("1"); + case ForumComment: + return QStringLiteral("4"); + case KnowledgeBaseComment: + return QStringLiteral("7"); + case EventComment: + return QStringLiteral("8"); + } + + Q_ASSERT(false); + return QString(); +} + +class Q_DECL_HIDDEN Comment::Private : public QSharedData +{ +public: + QString m_id; + QString m_subject; + QString m_text; + int m_childCount; + QString m_user; + QDateTime m_date; + int m_score; + QList m_children; + + Private() + : m_childCount(0) + , m_score(0) + { + } +}; + +Comment::Comment() + : d(new Private) +{ +} + +Comment::Comment(const Comment &other) + : d(other.d) +{ +} + +Comment &Comment::operator=(const Attica::Comment &other) +{ + d = other.d; + return *this; +} + +Comment::~Comment() +{ +} + +void Comment::setId(const QString &id) +{ + d->m_id = id; +} + +QString Comment::id() const +{ + return d->m_id; +} + +void Comment::setSubject(const QString &subject) +{ + d->m_subject = subject; +} + +QString Comment::subject() const +{ + return d->m_subject; +} + +void Comment::setText(const QString &text) +{ + d->m_text = text; +} + +QString Comment::text() const +{ + return d->m_text; +} + +void Comment::setChildCount(const int childCount) +{ + d->m_childCount = childCount; +} + +int Comment::childCount() const +{ + return d->m_childCount; +} + +void Comment::setUser(const QString &user) +{ + d->m_user = user; +} + +QString Comment::user() const +{ + return d->m_user; +} + +void Comment::setDate(const QDateTime &date) +{ + d->m_date = date; +} + +QDateTime Comment::date() const +{ + return d->m_date; +} + +void Comment::setScore(const int score) +{ + d->m_score = score; +} + +int Comment::score() const +{ + return d->m_score; +} + +void Comment::setChildren(QList children) +{ + d->m_children = std::move(children); // TODO KF6 Make QList const & and remove the std::move +} + +QList Comment::children() const +{ + return d->m_children; +} + +bool Comment::isValid() const +{ + return !(d->m_id.isEmpty()); +} diff --git a/local/recipes/kde/kf6-attica/source/src/comment.h b/local/recipes/kde/kf6-attica/source/src/comment.h new file mode 100644 index 00000000..3d2e4c54 --- /dev/null +++ b/local/recipes/kde/kf6-attica/source/src/comment.h @@ -0,0 +1,88 @@ +/* + This file is part of KDE. + + SPDX-FileCopyrightText: 2010 Intel Corporation + SPDX-FileContributor: Mateu Batle Sastre + + SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL +*/ + +#ifndef ATTICA_COMMENT_H +#define ATTICA_COMMENT_H + +#include "attica_export.h" + +#include +#include + +#include + +namespace Attica +{ + +/** + * @class Comment comment.h + * + * Represents a comment. + */ +class ATTICA_EXPORT Comment +{ +public: + typedef QList List; + class Parser; + + enum Type { + ContentComment, + ForumComment, + KnowledgeBaseComment, + EventComment, + }; + static QString commentTypeToString(const Comment::Type type); + + Comment(); + Comment(const Comment &other); + Comment &operator=(const Comment &other); + ~Comment(); + + void setId(const QString &id); + QString id() const; + + void setSubject(const QString &subject); + QString subject() const; + + void setText(const QString &text); + QString text() const; + + void setChildCount(const int childCount); + int childCount() const; + + void setUser(const QString &user); + QString user() const; + + void setDate(const QDateTime &date); + QDateTime date() const; + + /** + This is for internal usage, @see Provider::setCommentScore to set scores in comments. + @param score average comment score in scale from 0 to 100 + */ + void setScore(const int score); + /** + Returns score of this comment. + @param score average comment score in scale from 0 to 100 + */ + int score() const; + + void setChildren(QList comments); + QList children() const; + + bool isValid() const; + +private: + class Private; + QSharedDataPointer d; +}; + +} + +#endif diff --git a/local/recipes/kde/kf6-attica/source/src/commentparser.cpp b/local/recipes/kde/kf6-attica/source/src/commentparser.cpp new file mode 100644 index 00000000..450d65e7 --- /dev/null +++ b/local/recipes/kde/kf6-attica/source/src/commentparser.cpp @@ -0,0 +1,77 @@ +/* + This file is part of KDE. + + SPDX-FileCopyrightText: 2010 Intel Corporation + SPDX-FileContributor: Mateu Batle Sastre + + SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL +*/ + +#include "commentparser.h" +#include "atticautils.h" +#include + +using namespace Attica; + +Comment Comment::Parser::parseXml(QXmlStreamReader &xml) +{ + Comment comment; + + while (!xml.atEnd()) { + xml.readNext(); + + if (xml.isStartElement()) { + if (xml.name() == QLatin1String("id")) { + comment.setId(xml.readElementText()); + } else if (xml.name() == QLatin1String("subject")) { + comment.setSubject(xml.readElementText()); + } else if (xml.name() == QLatin1String("text")) { + comment.setText(xml.readElementText()); + } else if (xml.name() == QLatin1String("childcount")) { + comment.setChildCount(xml.readElementText().toInt()); + } else if (xml.name() == QLatin1String("user")) { + comment.setUser(xml.readElementText()); + } else if (xml.name() == QLatin1String("date")) { + comment.setDate(Utils::parseQtDateTimeIso8601(xml.readElementText())); + } else if (xml.name() == QLatin1String("score")) { + comment.setScore(xml.readElementText().toInt()); + } else if (xml.name() == QLatin1String("children")) { + // This may seem strange, however we are dealing with a situation where we may + // receive multiple children subsections (the standard accepts this, and certain + // server implementations do do this) + QList children = comment.children(); + children += parseXmlChildren(xml); + comment.setChildren(children); + } + } else if (xml.isEndElement() && xml.name() == QLatin1String("comment")) { + break; + } + } + + return comment; +} + +QList Comment::Parser::parseXmlChildren(QXmlStreamReader &xml) +{ + QList children; + + while (!xml.atEnd()) { + xml.readNext(); + + if (xml.isStartElement()) { + if (xml.name() == QLatin1String("comment")) { + Comment comment = parseXml(xml); + children.append(comment); + } + } else if (xml.isEndElement() && xml.name() == QLatin1String("children")) { + break; + } + } + + return children; +} + +QStringList Comment::Parser::xmlElement() const +{ + return QStringList(QStringLiteral("comment")); +} diff --git a/local/recipes/kde/kf6-attica/source/src/commentparser.h b/local/recipes/kde/kf6-attica/source/src/commentparser.h new file mode 100644 index 00000000..5016a925 --- /dev/null +++ b/local/recipes/kde/kf6-attica/source/src/commentparser.h @@ -0,0 +1,28 @@ +/* + This file is part of KDE. + + SPDX-FileCopyrightText: 2010 Intel Corporation + SPDX-FileContributor: Mateu Batle Sastre + + SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL +*/ + +#ifndef ATTICA_COMMENTPARSER_H +#define ATTICA_COMMENTPARSER_H + +#include "comment.h" +#include "parser.h" + +namespace Attica +{ +class Q_DECL_HIDDEN Comment::Parser : public Attica::Parser +{ +private: + Comment parseXml(QXmlStreamReader &xml) override; + QList parseXmlChildren(QXmlStreamReader &xml); + QStringList xmlElement() const override; +}; + +} + +#endif diff --git a/local/recipes/kde/kf6-attica/source/src/config.cpp b/local/recipes/kde/kf6-attica/source/src/config.cpp new file mode 100644 index 00000000..21815a0f --- /dev/null +++ b/local/recipes/kde/kf6-attica/source/src/config.cpp @@ -0,0 +1,101 @@ +/* + This file is part of KDE. + + SPDX-FileCopyrightText: 2018 Ralf Habacker + + SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL +*/ + +#include "config.h" + +using namespace Attica; + +class Q_DECL_HIDDEN Config::Private : public QSharedData +{ +public: + QString m_version; + QString m_website; + QString m_host; + QString m_contact; + bool m_ssl; + + Private() + : m_ssl(false) + { + } +}; + +Config::Config() + : d(new Private) +{ +} + +Config::Config(const Attica::Config &other) + : d(other.d) +{ +} + +Config &Config::operator=(const Attica::Config &other) +{ + d = other.d; + return *this; +} + +Config::~Config() +{ +} + +QString Attica::Config::version() const +{ + return d->m_version; +} + +QString Config::website() const +{ + return d->m_website; +} + +QString Config::host() const +{ + return d->m_host; +} + +QString Config::contact() const +{ + return d->m_contact; +} + +bool Config::ssl() const +{ + return d->m_ssl; +} + +bool Config::isValid() const +{ + return !(d->m_version.isEmpty()); +} + +void Config::setContact(const QString &contact) +{ + d->m_contact = contact; +} + +void Config::setVersion(const QString &version) +{ + d->m_version = version; +} + +void Config::setWebsite(const QString &website) +{ + d->m_website = website; +} + +void Config::setHost(const QString &host) +{ + d->m_host = host; +} + +void Config::setSsl(bool ssl) +{ + d->m_ssl = ssl; +} diff --git a/local/recipes/kde/kf6-attica/source/src/config.h b/local/recipes/kde/kf6-attica/source/src/config.h new file mode 100644 index 00000000..faa296ee --- /dev/null +++ b/local/recipes/kde/kf6-attica/source/src/config.h @@ -0,0 +1,77 @@ +/* + This file is part of KDE. + + SPDX-FileCopyrightText: 2018 Ralf Habacker + + SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL +*/ +#ifndef ATTICA_CONFIG_H +#define ATTICA_CONFIG_H + +#include +#include + +#include "attica_export.h" + +namespace Attica +{ +/** + * @class Config config.h + * + * Represents a server config + */ +class ATTICA_EXPORT Config +{ +public: + typedef QList List; + class Parser; + + /** + * Creates an empty Config + */ + Config(); + + /** + * Copy constructor. + * @param other the Config to copy from + */ + Config(const Config &other); + + /** + * Assignment operator. + * @param other the Config to assign from + * @return pointer to this Config + */ + Config &operator=(const Config &other); + + /** + * Destructor. + */ + ~Config(); + + QString contact() const; + QString host() const; + QString version() const; + bool ssl() const; + QString website() const; + + void setContact(const QString &contact); + void setHost(const QString &host); + void setSsl(bool ssl); + void setVersion(const QString &version); + void setWebsite(const QString &website); + + /** + * Checks whether this config is valid + * @return @c true if config is valid, @c false otherwise + */ + bool isValid() const; + +private: + class Private; + QSharedDataPointer d; +}; + +} + +#endif diff --git a/local/recipes/kde/kf6-attica/source/src/configparser.cpp b/local/recipes/kde/kf6-attica/source/src/configparser.cpp new file mode 100644 index 00000000..46158e60 --- /dev/null +++ b/local/recipes/kde/kf6-attica/source/src/configparser.cpp @@ -0,0 +1,45 @@ +/* + This file is part of KDE. + + SPDX-FileCopyrightText: 2018 Ralf Habacker + + SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL +*/ + +#include "configparser.h" + +using namespace Attica; + +Config Config::Parser::parseXml(QXmlStreamReader &xml) +{ + Config config; + + while (!xml.atEnd()) { + xml.readNext(); + + if (xml.isStartElement()) { + if (xml.name() == QLatin1String("version")) { + config.setVersion(xml.readElementText()); + } else if (xml.name() == QLatin1String("website")) { + config.setWebsite(xml.readElementText()); + } else if (xml.name() == QLatin1String("host")) { + config.setHost(xml.readElementText()); + } else if (xml.name() == QLatin1String("contact")) { + config.setContact(xml.readElementText()); + } else if (xml.name() == QLatin1String("ssl")) { + config.setSsl(xml.readElementText() == QLatin1String("true")); + } + } + + if (xml.isEndElement() && xml.name() == QLatin1String("data")) { + break; + } + } + + return config; +} + +QStringList Config::Parser::xmlElement() const +{ + return QStringList(QStringLiteral("data")); +} diff --git a/local/recipes/kde/kf6-attica/source/src/configparser.h b/local/recipes/kde/kf6-attica/source/src/configparser.h new file mode 100644 index 00000000..b7807c49 --- /dev/null +++ b/local/recipes/kde/kf6-attica/source/src/configparser.h @@ -0,0 +1,29 @@ +/* + This file is part of KDE. + + SPDX-FileCopyrightText: 2018 Ralf Habacker + + SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL +*/ + +#ifndef ATTICA_CONFIGPARSER_H +#define ATTICA_CONFIGPARSER_H + +#include "config.h" +#include "parser.h" + +#include "attica_export.h" + +namespace Attica +{ +// exported for autotest +class ATTICA_EXPORT Config::Parser : public Attica::Parser +{ +private: + Config parseXml(QXmlStreamReader &xml) override; + QStringList xmlElement() const override; +}; + +} + +#endif diff --git a/local/recipes/kde/kf6-attica/source/src/content.cpp b/local/recipes/kde/kf6-attica/source/src/content.cpp new file mode 100644 index 00000000..2d0b1c77 --- /dev/null +++ b/local/recipes/kde/kf6-attica/source/src/content.cpp @@ -0,0 +1,328 @@ +/* + This file is part of KDE. + + SPDX-FileCopyrightText: 2008 Cornelius Schumacher + + SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL +*/ + +#include "content.h" + +#include + +using namespace Qt::StringLiterals; +using namespace Attica; + +class Q_DECL_HIDDEN Content::Private : public QSharedData +{ +public: + QString m_id; + QString m_name; + int m_downloads; + int m_numberOfComments; + int m_rating; + QDateTime m_created; + QDateTime m_updated; + QList m_icons; + QList m_videos; + QStringList m_tags; + + QMap m_extendedAttributes; + + Private() + : m_downloads(0) + , m_numberOfComments(0) + , m_rating(0) + { + } +}; + +Content::Content() + : d(new Private) +{ +} + +Content::Content(const Attica::Content &other) + : d(other.d) +{ +} + +Content &Content::operator=(const Attica::Content &other) +{ + d = other.d; + return *this; +} + +Content::~Content() +{ +} + +void Content::setId(const QString &u) +{ + d->m_id = u; +} + +QString Content::id() const +{ + return d->m_id; +} + +void Content::setName(const QString &name) +{ + d->m_name = name; +} + +QString Content::name() const +{ + return d->m_name; +} + +void Content::setRating(int v) +{ + d->m_rating = v; +} + +int Content::rating() const +{ + return d->m_rating; +} + +void Content::setDownloads(int v) +{ + d->m_downloads = v; +} + +int Content::downloads() const +{ + return d->m_downloads; +} + +void Content::setNumberOfComments(int v) +{ + d->m_numberOfComments = v; +} + +int Content::numberOfComments() const +{ + return d->m_numberOfComments; +} + +void Content::setCreated(const QDateTime &date) +{ + d->m_created = date; +} + +QDateTime Content::created() const +{ + return d->m_created; +} + +void Content::setUpdated(const QDateTime &date) +{ + d->m_updated = date; +} + +QDateTime Content::updated() const +{ + return d->m_updated; +} + +void Content::addAttribute(const QString &key, const QString &value) +{ + d->m_extendedAttributes.insert(key, value); +} + +QString Content::attribute(const QString &key) const +{ + return d->m_extendedAttributes.value(key); +} + +QMap Content::attributes() const +{ + return d->m_extendedAttributes; +} + +bool Content::isValid() const +{ + return !(d->m_id.isEmpty()); +} + +QString Content::summary() const +{ + return attribute(QStringLiteral("summary")); +} + +QString Content::description() const +{ + return attribute(QStringLiteral("description")); +} + +QUrl Content::detailpage() const +{ + return QUrl(attribute(QStringLiteral("detailpage"))); +} + +QString Attica::Content::changelog() const +{ + return attribute(QStringLiteral("changelog")); +} + +QString Attica::Content::depend() const +{ + return attribute(QStringLiteral("depend")); +} + +QList Attica::Content::downloadUrlDescriptions() const +{ + QList descriptions; + QMap::const_iterator iter = d->m_extendedAttributes.constBegin(); + while (iter != d->m_extendedAttributes.constEnd()) { + const QString &key = iter.key(); + static const QLatin1String tag("downloadname"); + if (key.startsWith(tag)) { + bool ok; + // remove "downloadlink", get the rest as number + const int num = QStringView(key).right(key.size() - tag.size()).toInt(&ok); + if (ok) { + // check if the download actually has a name + if (!iter.value().isEmpty()) { + descriptions.append(downloadUrlDescription(num)); + } + } + } + ++iter; + } + return descriptions; +} + +Attica::DownloadDescription Attica::Content::downloadUrlDescription(int number) const +{ + QString num(QString::number(number)); + DownloadDescription desc; + + Attica::DownloadDescription::Type downloadType = Attica::DownloadDescription::LinkDownload; + if (attribute(QLatin1String("downloadway") + num) == QLatin1Char('0')) { + downloadType = Attica::DownloadDescription::FileDownload; + } else if (attribute(QLatin1String("downloadway") + num) == QLatin1Char('1')) { + downloadType = Attica::DownloadDescription::LinkDownload; + } else if (attribute(QLatin1String("downloadway") + num) == QLatin1Char('2')) { + downloadType = Attica::DownloadDescription::PackageDownload; + } + desc.setType(downloadType); + desc.setId(number); + desc.setName(attribute(QLatin1String("downloadname") + num)); + desc.setDistributionType(attribute(QLatin1String("downloadtype") + num)); + desc.setHasPrice(attribute(QLatin1String("downloadbuy") + num) == QLatin1Char('1')); + desc.setLink(attribute(QLatin1String("downloadlink") + num)); + desc.setPriceReason(attribute(QLatin1String("downloadreason") + num)); + desc.setPriceAmount(attribute(QLatin1String("downloadprice") + num)); + desc.setSize(attribute(QLatin1String("downloadsize") + num).toUInt()); + desc.setGpgFingerprint(attribute(QLatin1String("downloadgpgfingerprint") + num)); + desc.setGpgSignature(attribute(QLatin1String("downloadgpgsignature") + num)); + desc.setPackageName(attribute(QLatin1String("downloadpackagename") + num)); + desc.setRepository(attribute(QLatin1String("downloadrepository") + num)); + desc.setTags(attribute(QLatin1String("downloadtags") + num).split(QLatin1Char(','))); + desc.setVersion(attribute("download_version"_L1 + num)); + return desc; +} + +QList Attica::Content::homePageEntries() +{ + QList homepages; + QMap::const_iterator iter = d->m_extendedAttributes.constBegin(); + while (iter != d->m_extendedAttributes.constEnd()) { + QString key = iter.key(); + if (key.startsWith(QLatin1String("homepagetype"))) { + bool ok; + // remove "homepage", get the rest as number + const int num = QStringView(key).right(key.size() - 12).toInt(&ok); + if (ok) { + // check if the homepage actually has a valid type + if (!iter.value().isEmpty()) { + homepages.append(homePageEntry(num)); + } + } + } + ++iter; + } + + return homepages; +} + +Attica::HomePageEntry Attica::Content::homePageEntry(int number) const +{ + QString num(QString::number(number)); + HomePageEntry homepage; + + if (number == 1 && attribute(QStringLiteral("homepage1")).isEmpty()) { + num.clear(); + } + homepage.setType(attribute(QLatin1String("homepagetype") + num)); + homepage.setUrl(QUrl(attribute(QLatin1String("homepage") + num))); + return homepage; +} + +QString Attica::Content::version() const +{ + return attribute(QStringLiteral("version")); +} + +QString Attica::Content::author() const +{ + return attribute(QStringLiteral("personid")); +} + +QString Attica::Content::license() const +{ + return attribute(QStringLiteral("licensetype")); +} + +QString Attica::Content::licenseName() const +{ + return attribute(QStringLiteral("license")); +} + +QString Attica::Content::previewPicture(const QString &number) const +{ + return attribute(QLatin1String("previewpic") + number); +} + +QString Attica::Content::smallPreviewPicture(const QString &number) const +{ + return attribute(QLatin1String("smallpreviewpic") + number); +} + +QList Attica::Content::icons() +{ + return d->m_icons; +} + +QList Attica::Content::icons() const +{ + return d->m_icons; +} + +void Attica::Content::setIcons(QList icons) +{ + d->m_icons = std::move(icons); // TODO KF6 Make QList const & and remove the std::move +} + +QList Attica::Content::videos() +{ + return d->m_videos; +} + +void Attica::Content::setVideos(QList videos) +{ + d->m_videos = std::move(videos); +} + +QStringList Attica::Content::tags() const +{ + return d->m_tags; +} + +void Attica::Content::setTags(const QStringList &tags) +{ + d->m_tags = tags; +} diff --git a/local/recipes/kde/kf6-attica/source/src/content.h b/local/recipes/kde/kf6-attica/source/src/content.h new file mode 100644 index 00000000..f4745f08 --- /dev/null +++ b/local/recipes/kde/kf6-attica/source/src/content.h @@ -0,0 +1,268 @@ +/* + This file is part of KDE. + + SPDX-FileCopyrightText: 2008 Cornelius Schumacher + + SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL +*/ + +#ifndef ATTICA_CONTENT_H +#define ATTICA_CONTENT_H + +#include +#include +#include +#include +#include + +#include "attica_export.h" +#include "downloaddescription.h" +#include "homepageentry.h" +#include "icon.h" + +class QDateTime; + +namespace Attica +{ +/** + * @class Content content.h + * + * Represents a single content + */ +class ATTICA_EXPORT Content +{ +public: + typedef QList List; + class Parser; + + /** + * Creates an empty Content + */ + Content(); + + /** + * Copy constructor. + * @param other the Content to copy from + */ + Content(const Content &other); + + /** + * Assignment operator. + * @param other the Content to assign from + * @return pointer to this Content + */ + Content &operator=(const Content &other); + + /** + * Destructor. + */ + ~Content(); + + /** + * Sets the id of the Content. + * The id uniquely identifies a Content with the OCS API. + * @param id the new id + */ + void setId(const QString &id); + + /** + * Gets the id of the Content. + * The id uniquely identifies a Content with the OCS API. + * @return the id + */ + QString id() const; + + /** + * Sets the name of the Content. + * @param name the new name + */ + void setName(const QString &name); + + /** + * Gets the name of the Content. + * @return the name + */ + QString name() const; + + /** + * Sets the rating of the Content. + * @param rating the new rating, has to be in the range 0-100 + */ + void setRating(int rating); + + /** + * Gets the rating of the Content. + * @return the rating in the range 0-100 + */ + int rating() const; + + /** + * Sets the number of downloads for the Content. + * @param downloads the new number of downloads + */ + void setDownloads(int downloads); + + /** + * Gets the number of downloads for the Content (how often this has been downloaded from the server). + * @return the number of downloads + */ + int downloads() const; + + /** + * Sets the number of comments for the Content. + * @param numComments the new number of downloads + */ + void setNumberOfComments(int numComments); + + /** + * Gets the number of comments for the Content. + * @return the number of comments + */ + int numberOfComments() const; + + /** + * Sets the date and time the Content has been created. + * @param created the new creation date and time + */ + void setCreated(const QDateTime &created); + + /** + * Gets the date and time the Content has been created. + * @return the date and time of the last update + */ + QDateTime created() const; + + /** + * Sets the time the Content has been last updated. + * @param updated the new date and time of the last update + */ + void setUpdated(const QDateTime &updated); + + /** + * Gets the date and time the Content has been last updated. + * @return the date and time of the last update + */ + QDateTime updated() const; + + /** + * A summary description of this content. + */ + QString summary() const; + + /** + * A description of this content. + */ + QString description() const; + + /** + * A webpage with the detailed description of this content. + */ + QUrl detailpage() const; + + QString changelog() const; + QString version() const; + QString depend() const; + + /** + Get the details about a download (a content can have multiple links, eg for different distros). + This is not very helpful if we don't know the allowed numbers. + */ + DownloadDescription downloadUrlDescription(int number) const; + + /** + Get all possible downloads. + This is slow searching through lots of strings, so beware and don't call it too often. + */ + QList downloadUrlDescriptions() const; + + /** + Get the details about a home page (a content can have multiple home pages, blog, bugs, ...). + This is not very helpful if we don't know the allowed numbers. + */ + HomePageEntry homePageEntry(int number) const; + + /** + Get all home pages for this content. + This is slow searching through lots of strings, so beware and don't call it too often. + */ + QList homePageEntries(); + + QString previewPicture(const QString &number = QStringLiteral("1")) const; + QString smallPreviewPicture(const QString &number = QStringLiteral("1")) const; + QString license() const; + QString licenseName() const; + QString author() const; + + /** + Get all icons for this content. + */ + QList icons(); + + /** + Get all icons for this content. + */ + QList icons() const; + + /** + * Set list of icons. + * @param icons list of icons for this content + */ + void setIcons(QList icons); + + /** + Get all videos for this content. + */ + QList videos(); + /** + * Set list of videos. + * @param videos list of videos for this content + */ + void setVideos(QList videos); + + /** + * Get all the tags for this content + * @since 5.50 + */ + QStringList tags() const; + /** + * Set the list of tags + * @param tags list of tags for this content + * @since 5.50 + */ + void setTags(const QStringList &tags); + + /** + * Add an attribute that is not included in the basis set of attributes exposed by the Content class. + * If the attribute already exists it gets overwritten. + * @param key the key of the attribute + * @param value the value of the attribute + */ + void addAttribute(const QString &key, const QString &value); + + /** + * Get an attribute that is not included in the basis set of attributes exposed by the Content class. + * @param key the key of the attribute + * @return the value of the attribute with the specified key, or an empty string, if the key has not been found + */ + QString attribute(const QString &key) const; + + /** + * Get all attributes that are not included in the basis set of attributes exposed by the Content class. + * @return the attribute mappings + */ + QMap attributes() const; + + /** + * Checks whether this Content has an id + * @return @c true if an id has been set, @c false otherwise + */ + bool isValid() const; + +private: + class Private; + QSharedDataPointer d; +}; + +} + +#endif diff --git a/local/recipes/kde/kf6-attica/source/src/contentparser.cpp b/local/recipes/kde/kf6-attica/source/src/contentparser.cpp new file mode 100644 index 00000000..1ec49431 --- /dev/null +++ b/local/recipes/kde/kf6-attica/source/src/contentparser.cpp @@ -0,0 +1,93 @@ +/* + This file is part of KDE. + + SPDX-FileCopyrightText: 2008 Cornelius Schumacher + + SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL +*/ + +#include "contentparser.h" + +#include +#include + +using namespace Attica; + +Content Content::Parser::parseXml(QXmlStreamReader &xml) +{ + Content content; + + while (!xml.atEnd()) { + xml.readNext(); + + if (xml.isStartElement()) { + if (xml.name() == QLatin1String("id")) { + content.setId(xml.readElementText()); + } else if (xml.name() == QLatin1String("name")) { + content.setName(xml.readElementText()); + } else if (xml.name() == QLatin1String("score")) { + content.setRating(xml.readElementText().toInt()); + } else if (xml.name() == QLatin1String("downloads")) { + content.setDownloads(xml.readElementText().toInt()); + } else if (xml.name() == QLatin1String("comments")) { + content.setNumberOfComments(xml.readElementText().toInt()); + } else if (xml.name() == QLatin1String("created")) { + // Qt doesn't accept +-Timezone modifiers, truncate if the string contains them + QString dateString = xml.readElementText().left(19); + content.setCreated(QDateTime::fromString(dateString, Qt::ISODate)); + } else if (xml.name() == QLatin1String("changed")) { + // Qt doesn't accept +-Timezone modifiers, truncate if the string contains them + QString dateString = xml.readElementText().left(19); + content.setUpdated(QDateTime::fromString(dateString, Qt::ISODate)); + } else if (xml.name() == QLatin1String("icon")) { + Icon icon; + icon.setUrl(QUrl(xml.readElementText())); + + const QXmlStreamAttributes attributes = xml.attributes(); + + const auto width = attributes.value(QLatin1String("width")); + if (!width.isEmpty()) { + icon.setWidth(width.toInt()); + } + + const auto height = attributes.value(QLatin1String("height")); + if (!height.isEmpty()) { + icon.setHeight(height.toInt()); + } + + // append the icon to the current list of icons + QList icons; + icons = content.icons(); + icons.append(icon); + content.setIcons(icons); + } else if (xml.name() == QLatin1String("video")) { + QUrl video(xml.readElementText()); + // append the video to the current list of videos + QList videos; + videos = content.videos(); + videos.append(video); + content.setVideos(videos); + } else if (xml.name() == QLatin1String("tags")) { + content.setTags(xml.readElementText().split(QLatin1Char(','))); + } else { + content.addAttribute(xml.name().toString(), xml.readElementText()); + } + } + + if (xml.isEndElement() && xml.name() == QLatin1String("content")) { + break; + } + } + + // in case the server only sets creation date, use that as updated also + if (content.updated().isNull()) { + content.setUpdated(content.created()); + } + + return content; +} + +QStringList Content::Parser::xmlElement() const +{ + return QStringList(QStringLiteral("content")); +} diff --git a/local/recipes/kde/kf6-attica/source/src/contentparser.h b/local/recipes/kde/kf6-attica/source/src/contentparser.h new file mode 100644 index 00000000..401ddae3 --- /dev/null +++ b/local/recipes/kde/kf6-attica/source/src/contentparser.h @@ -0,0 +1,26 @@ +/* + This file is part of KDE. + + SPDX-FileCopyrightText: 2008 Cornelius Schumacher + + SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL +*/ + +#ifndef ATTICA_CONTENTPARSER_H +#define ATTICA_CONTENTPARSER_H + +#include "content.h" +#include "parser.h" + +namespace Attica +{ +class Q_DECL_HIDDEN Content::Parser : public Attica::Parser +{ +private: + Content parseXml(QXmlStreamReader &xml) override; + QStringList xmlElement() const override; +}; + +} + +#endif diff --git a/local/recipes/kde/kf6-attica/source/src/deletejob.cpp b/local/recipes/kde/kf6-attica/source/src/deletejob.cpp new file mode 100644 index 00000000..f8d14449 --- /dev/null +++ b/local/recipes/kde/kf6-attica/source/src/deletejob.cpp @@ -0,0 +1,33 @@ +/* + This file is part of KDE. + + SPDX-FileCopyrightText: 2011 Laszlo Papp + + SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL +*/ + +#include "deletejob.h" + +#include + +#include "platformdependent_v2.h" + +using namespace Attica; + +DeleteJob::DeleteJob(PlatformDependent *internals, const QNetworkRequest &request) + : BaseJob(internals) + , m_request(request) +{ +} + +QNetworkReply *DeleteJob::executeRequest() +{ + Attica::PlatformDependentV2 *platformDependentV2 = dynamic_cast(internals()); + if (!platformDependentV2) { + return nullptr; + } + + return platformDependentV2->deleteResource(m_request); +} + +#include "moc_deletejob.cpp" diff --git a/local/recipes/kde/kf6-attica/source/src/deletejob.h b/local/recipes/kde/kf6-attica/source/src/deletejob.h new file mode 100644 index 00000000..c621e919 --- /dev/null +++ b/local/recipes/kde/kf6-attica/source/src/deletejob.h @@ -0,0 +1,39 @@ +/* + This file is part of KDE. + + SPDX-FileCopyrightText: 2011 Laszlo Papp + + SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL +*/ + +#ifndef ATTICA_DELETEJOB_H +#define ATTICA_DELETEJOB_H + +#include + +#include "attica_export.h" +#include "atticabasejob.h" + +namespace Attica +{ + +/** + * @class DeleteJob deletejob.h + * + * Represents a delete job. + */ +class ATTICA_EXPORT DeleteJob : public Attica::BaseJob +{ + Q_OBJECT + +protected: + DeleteJob(PlatformDependent *internals, const QNetworkRequest &request); + +private: + QNetworkReply *executeRequest() override; + const QNetworkRequest m_request; +}; + +} + +#endif diff --git a/local/recipes/kde/kf6-attica/source/src/distribution.cpp b/local/recipes/kde/kf6-attica/source/src/distribution.cpp new file mode 100644 index 00000000..1dd5022f --- /dev/null +++ b/local/recipes/kde/kf6-attica/source/src/distribution.cpp @@ -0,0 +1,64 @@ +/* + This file is part of KDE. + + SPDX-FileCopyrightText: 2010 Intel Corporation + SPDX-FileContributor: Mateu Batle Sastre + + SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL +*/ + +#include "distribution.h" + +using namespace Attica; + +class Q_DECL_HIDDEN Distribution::Private : public QSharedData +{ +public: + int id; + QString name; + + Private() + : id(-1) + { + } +}; + +Distribution::Distribution() + : d(new Private) +{ +} + +Distribution::Distribution(const Attica::Distribution &other) + : d(other.d) +{ +} + +Distribution &Distribution::operator=(const Attica::Distribution &other) +{ + d = other.d; + return *this; +} + +Distribution::~Distribution() +{ +} + +uint Distribution::id() const +{ + return d->id; +} + +void Distribution::setId(uint id) +{ + d->id = id; +} + +QString Distribution::name() const +{ + return d->name; +} + +void Distribution::setName(const QString &name) +{ + d->name = name; +} diff --git a/local/recipes/kde/kf6-attica/source/src/distribution.h b/local/recipes/kde/kf6-attica/source/src/distribution.h new file mode 100644 index 00000000..b617aad6 --- /dev/null +++ b/local/recipes/kde/kf6-attica/source/src/distribution.h @@ -0,0 +1,73 @@ +/* + This file is part of KDE. + + SPDX-FileCopyrightText: 2010 Intel Corporation + SPDX-FileContributor: Mateu Batle Sastre + + SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL +*/ + +#ifndef ATTICA_DISTRIBUTION_H +#define ATTICA_DISTRIBUTION_H + +#include +#include + +#include "attica_export.h" + +namespace Attica +{ +/** + @class Distribution distribution.h + + The Distribution class contains information about one distribution that the server offers. + It consists of an integer id and a distribution name. + */ +class ATTICA_EXPORT Distribution +{ +public: + typedef QList List; + class Parser; + + /** + * Creates an empty Distribution + */ + Distribution(); + + /** + * Copy constructor. + * @param other the Distribution to copy from + */ + Distribution(const Distribution &other); + + /** + * Assignment operator. + * @param other the Distribution to assign from + * @return pointer to this Distribution + */ + Distribution &operator=(const Distribution &other); + + /** + * Destructor. + */ + ~Distribution(); + + /* + 2000 + Ark + */ + + uint id() const; + void setId(uint id); + + QString name() const; + void setName(const QString &name); + +private: + class Private; + QSharedDataPointer d; +}; + +} + +#endif diff --git a/local/recipes/kde/kf6-attica/source/src/distributionparser.cpp b/local/recipes/kde/kf6-attica/source/src/distributionparser.cpp new file mode 100644 index 00000000..fc5bf98f --- /dev/null +++ b/local/recipes/kde/kf6-attica/source/src/distributionparser.cpp @@ -0,0 +1,37 @@ +/* + This file is part of KDE. + + SPDX-FileCopyrightText: 2010 Intel Corporation + SPDX-FileContributor: Mateu Batle Sastre + + SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL +*/ + +#include "distributionparser.h" + +using namespace Attica; + +QStringList Distribution::Parser::xmlElement() const +{ + return QStringList(QStringLiteral("distribution")); +} + +Distribution Distribution::Parser::parseXml(QXmlStreamReader &xml) +{ + Distribution item; + + while (!xml.atEnd()) { + xml.readNext(); + if (xml.isStartElement()) { + if (xml.name() == QLatin1String("id")) { + item.setId(xml.readElementText().toInt()); + } else if (xml.name() == QLatin1String("name")) { + item.setName(xml.readElementText()); + } + } + if (xml.isEndElement() && xml.name() == QLatin1String("distribution")) { + break; + } + } + return item; +} diff --git a/local/recipes/kde/kf6-attica/source/src/distributionparser.h b/local/recipes/kde/kf6-attica/source/src/distributionparser.h new file mode 100644 index 00000000..1abb433b --- /dev/null +++ b/local/recipes/kde/kf6-attica/source/src/distributionparser.h @@ -0,0 +1,27 @@ +/* + This file is part of KDE. + + SPDX-FileCopyrightText: 2010 Intel Corporation + SPDX-FileContributor: Mateu Batle Sastre + + SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL +*/ + +#ifndef ATTICA_DISTRIBUTION_PARSER_H +#define ATTICA_DISTRIBUTION_PARSER_H + +#include "distribution.h" +#include "parser.h" + +namespace Attica +{ +class Q_DECL_HIDDEN Distribution::Parser : public Attica::Parser +{ +private: + Distribution parseXml(QXmlStreamReader &xml) override; + QStringList xmlElement() const override; +}; + +} + +#endif diff --git a/local/recipes/kde/kf6-attica/source/src/downloaddescription.cpp b/local/recipes/kde/kf6-attica/source/src/downloaddescription.cpp new file mode 100644 index 00000000..041fbae6 --- /dev/null +++ b/local/recipes/kde/kf6-attica/source/src/downloaddescription.cpp @@ -0,0 +1,217 @@ +/* + This file is part of KDE. + + SPDX-FileCopyrightText: 2009 Frederik Gladhorn + + SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL +*/ + +#include "downloaddescription.h" + +#include + +namespace Attica +{ +class Q_DECL_HIDDEN DownloadDescription::Private : public QSharedData +{ +public: + int id = 0; + Attica::DownloadDescription::Type type = Attica::DownloadDescription::FileDownload; + bool hasPrice = false; + QString category; + QString name; + QString link; + QString distributionType; + QString priceReason; + QString priceAmount; + QString gpgFingerprint; + QString gpgSignature; + QString packageName; + QString repository; + uint size = 0; + QStringList tags; + QString version; +}; +} + +using namespace Attica; + +DownloadDescription::DownloadDescription() + : d(new Private) +{ +} + +DownloadDescription::DownloadDescription(const Attica::DownloadDescription &other) + : d(other.d) +{ +} + +DownloadDescription &DownloadDescription::operator=(const Attica::DownloadDescription &other) +{ + d = other.d; + return *this; +} + +DownloadDescription::~DownloadDescription() +{ +} + +QString Attica::DownloadDescription::category() const +{ + return d->category; +} + +int DownloadDescription::id() const +{ + return d->id; +} + +void DownloadDescription::setId(int id) +{ + d->id = id; +} + +void DownloadDescription::setCategory(const QString &category) +{ + d->category = category; +} + +QString Attica::DownloadDescription::distributionType() const +{ + return d->distributionType; +} + +void DownloadDescription::setDistributionType(const QString &distributionType) +{ + d->distributionType = distributionType; +} + +bool Attica::DownloadDescription::hasPrice() const +{ + return d->hasPrice; +} + +void DownloadDescription::setHasPrice(bool hasPrice) +{ + d->hasPrice = hasPrice; +} + +Attica::DownloadDescription::Type DownloadDescription::type() const +{ + return d->type; +} + +void DownloadDescription::setType(Attica::DownloadDescription::Type type) +{ + d->type = type; +} + +QString Attica::DownloadDescription::link() const +{ + return d->link; +} + +void DownloadDescription::setLink(const QString &link) +{ + d->link = link; +} + +QString Attica::DownloadDescription::name() const +{ + return d->name; +} + +void DownloadDescription::setName(const QString &name) +{ + d->name = name; +} + +QString Attica::DownloadDescription::priceAmount() const +{ + return d->priceAmount; +} + +void DownloadDescription::setPriceAmount(const QString &priceAmount) +{ + d->priceAmount = priceAmount; +} + +QString Attica::DownloadDescription::priceReason() const +{ + return d->priceReason; +} + +void Attica::DownloadDescription::setPriceReason(const QString &priceReason) +{ + d->priceReason = priceReason; +} + +uint Attica::DownloadDescription::size() const +{ + return d->size; +} + +void Attica::DownloadDescription::setSize(uint size) +{ + d->size = size; +} + +QString Attica::DownloadDescription::gpgFingerprint() const +{ + return d->gpgFingerprint; +} + +void Attica::DownloadDescription::setGpgFingerprint(const QString &fingerprint) +{ + d->gpgFingerprint = fingerprint; +} + +QString Attica::DownloadDescription::gpgSignature() const +{ + return d->gpgSignature; +} + +void Attica::DownloadDescription::setGpgSignature(const QString &signature) +{ + d->gpgSignature = signature; +} + +QString Attica::DownloadDescription::packageName() const +{ + return d->packageName; +} + +void Attica::DownloadDescription::setPackageName(const QString &packageName) +{ + d->packageName = packageName; +} + +QString Attica::DownloadDescription::repository() const +{ + return d->repository; +} + +void Attica::DownloadDescription::setRepository(const QString &repository) +{ + d->repository = repository; +} + +QStringList Attica::DownloadDescription::tags() const +{ + return d->tags; +} + +void Attica::DownloadDescription::setTags(const QStringList &tags) +{ + d->tags = tags; +} + +QString Attica::DownloadDescription::version() const +{ + return d->version; +} + +void Attica::DownloadDescription::setVersion(const QString &version) +{ + d->version = version; +} diff --git a/local/recipes/kde/kf6-attica/source/src/downloaddescription.h b/local/recipes/kde/kf6-attica/source/src/downloaddescription.h new file mode 100644 index 00000000..32f09662 --- /dev/null +++ b/local/recipes/kde/kf6-attica/source/src/downloaddescription.h @@ -0,0 +1,103 @@ +/* + This file is part of KDE. + + SPDX-FileCopyrightText: 2009 Frederik Gladhorn + + SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL +*/ + +#ifndef DOWNLOADDESCRIPTION_H +#define DOWNLOADDESCRIPTION_H + +#include +#include + +#include "attica_export.h" + +namespace Attica +{ + +/** + * @class DownloadDescription downloaddescription.h + * + * Represents a download description. + */ +class ATTICA_EXPORT DownloadDescription +{ +public: + enum Type { + FileDownload = 0, + LinkDownload, + PackageDownload, + }; + + DownloadDescription(); + DownloadDescription(const DownloadDescription &other); + + DownloadDescription &operator=(const DownloadDescription &other); + ~DownloadDescription(); + + /** + The id of the description - as one Content can have multiple download descriptions associated. + This will simply be 1, 2, ... + */ + int id() const; + + Attica::DownloadDescription::Type type() const; + bool hasPrice() const; + QString category() const; + QString name() const; + QString link() const; + QString distributionType() const; + QString priceReason() const; + QString priceAmount() const; + uint size() const; + QString gpgFingerprint() const; + QString gpgSignature() const; + QString packageName() const; + QString repository() const; + /** + * Get the list of tags for this download description + * @since 5.50 + */ + QStringList tags() const; + + void setId(int id); + void setType(Attica::DownloadDescription::Type type); + void setHasPrice(bool hasPrice); + void setCategory(const QString &category); + void setName(const QString &name); + void setLink(const QString &link); + void setDistributionType(const QString &distributionType); + void setPriceReason(const QString &priceReason); + void setPriceAmount(const QString &priceAmount); + void setSize(uint size); + void setGpgFingerprint(const QString &fingerprint); + void setGpgSignature(const QString &signature); + void setPackageName(const QString &packageName); + void setRepository(const QString &repository); + /** + * Set the list of tags for this download description + * @since 5.50 + */ + void setTags(const QStringList &tags); + + /** + * The download version as set on the remote. May be QString() when not set. + * @since 6.5 + */ + [[nodiscard]] QString version() const; + + /** + * @since 6.5 + */ + void setVersion(const QString &version); + +private: + class Private; + QSharedDataPointer d; +}; + +} + +#endif // DOWNLOADDESCRIPTION_H diff --git a/local/recipes/kde/kf6-attica/source/src/downloaditem.cpp b/local/recipes/kde/kf6-attica/source/src/downloaditem.cpp new file mode 100644 index 00000000..751f0f49 --- /dev/null +++ b/local/recipes/kde/kf6-attica/source/src/downloaditem.cpp @@ -0,0 +1,118 @@ +/* + This file is part of KDE. + + SPDX-FileCopyrightText: 2009 Frederik Gladhorn + + SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL +*/ + +#include "downloaditem.h" + +using namespace Attica; + +class Q_DECL_HIDDEN DownloadItem::Private : public QSharedData +{ +public: + QUrl m_url; + QString m_mimeType; + QString m_packageName; + QString m_packageRepository; + QString m_gpgFingerprint; + QString m_gpgSignature; + Attica::DownloadDescription::Type m_type; + + Private() + : m_type(DownloadDescription::FileDownload) + { + } +}; + +DownloadItem::DownloadItem() + : d(new Private) +{ +} + +DownloadItem::DownloadItem(const Attica::DownloadItem &other) + : d(other.d) +{ +} + +DownloadItem &DownloadItem::operator=(const Attica::DownloadItem &other) +{ + d = other.d; + return *this; +} + +DownloadItem::~DownloadItem() +{ +} + +void DownloadItem::setUrl(const QUrl &url) +{ + d->m_url = url; +} + +QUrl DownloadItem::url() const +{ + return d->m_url; +} + +void DownloadItem::setMimeType(const QString &mimeType) +{ + d->m_mimeType = mimeType; +} + +QString DownloadItem::mimeType() const +{ + return d->m_mimeType; +} + +void DownloadItem::setPackageName(const QString &packageName) +{ + d->m_packageName = packageName; +} + +QString DownloadItem::packageName() const +{ + return d->m_packageName; +} + +void DownloadItem::setPackageRepository(const QString &packageRepository) +{ + d->m_packageRepository = packageRepository; +} + +QString DownloadItem::packageRepository() const +{ + return d->m_packageRepository; +} + +void DownloadItem::setGpgFingerprint(const QString &gpgFingerprint) +{ + d->m_gpgFingerprint = gpgFingerprint; +} + +QString DownloadItem::gpgFingerprint() const +{ + return d->m_gpgFingerprint; +} + +void DownloadItem::setGpgSignature(const QString &gpgSignature) +{ + d->m_gpgSignature = gpgSignature; +} + +QString DownloadItem::gpgSignature() const +{ + return d->m_gpgSignature; +} + +void DownloadItem::setType(Attica::DownloadDescription::Type type) +{ + d->m_type = type; +} + +Attica::DownloadDescription::Type DownloadItem::type() +{ + return d->m_type; +} diff --git a/local/recipes/kde/kf6-attica/source/src/downloaditem.h b/local/recipes/kde/kf6-attica/source/src/downloaditem.h new file mode 100644 index 00000000..8f60ffb4 --- /dev/null +++ b/local/recipes/kde/kf6-attica/source/src/downloaditem.h @@ -0,0 +1,77 @@ +/* + This file is part of KDE. + + SPDX-FileCopyrightText: 2009 Frederik Gladhorn + + SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL +*/ + +#ifndef ATTICA_DOWNLOADITEM_H +#define ATTICA_DOWNLOADITEM_H + +#include +#include + +#include "attica_export.h" +#include "downloaddescription.h" + +namespace Attica +{ + +/** + * @class DownloadItem downloaditem.h + * + * Represents a download item. + */ +class ATTICA_EXPORT DownloadItem +{ +public: + typedef QList List; + class Parser; + + /** + * Creates an empty DownloadItem + */ + DownloadItem(); + + /** + * Copy constructor. + * @param other the DownloadItem to copy from + */ + DownloadItem(const DownloadItem &other); + + /** + * Assignment operator. + * @param other the DownloadItem to assign from + * @return pointer to this DownloadItem + */ + DownloadItem &operator=(const DownloadItem &other); + + /** + * Destructor. + */ + ~DownloadItem(); + + void setUrl(const QUrl &url); + QUrl url() const; + void setMimeType(const QString &mimeType); + QString mimeType() const; + void setPackageName(const QString &packageName); + QString packageName() const; + void setPackageRepository(const QString &packageRepository); + QString packageRepository() const; + void setGpgFingerprint(const QString &gpgFingerprint); + QString gpgFingerprint() const; + void setGpgSignature(const QString &gpgSignature); + QString gpgSignature() const; + void setType(Attica::DownloadDescription::Type type); + Attica::DownloadDescription::Type type(); + +private: + class Private; + QSharedDataPointer d; +}; + +} + +#endif // DOWNLOADITEM_H diff --git a/local/recipes/kde/kf6-attica/source/src/downloaditemparser.cpp b/local/recipes/kde/kf6-attica/source/src/downloaditemparser.cpp new file mode 100644 index 00000000..816e1c87 --- /dev/null +++ b/local/recipes/kde/kf6-attica/source/src/downloaditemparser.cpp @@ -0,0 +1,45 @@ +/* + This file is part of KDE. + + SPDX-FileCopyrightText: 2009 Frederik Gladhorn + + SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL +*/ + +#include "downloaditemparser.h" + +#include + +using namespace Attica; + +QStringList DownloadItem::Parser::xmlElement() const +{ + return QStringList(QStringLiteral("content")); +} + +DownloadItem DownloadItem::Parser::parseXml(QXmlStreamReader &xml) +{ + DownloadItem item; + + while (!xml.atEnd()) { + xml.readNext(); + if (xml.isStartElement()) { + if (xml.name() == QLatin1String("downloadlink")) { + item.setUrl(QUrl(xml.readElementText())); + } else if (xml.name() == QLatin1String("mimetype")) { + item.setMimeType(xml.readElementText()); + } else if (xml.name() == QLatin1String("packagename")) { + item.setPackageName(xml.readElementText()); + } else if (xml.name() == QLatin1String("packagerepository")) { + item.setPackageRepository(xml.readElementText()); + } else if (xml.name() == QLatin1String("gpgfingerprint")) { + item.setGpgFingerprint(xml.readElementText()); + } else if (xml.name() == QLatin1String("gpgsignature")) { + item.setGpgSignature(xml.readElementText()); + } else if (xml.name() == QLatin1String("downloadway")) { + item.setType(DownloadDescription::Type(xml.readElementText().toInt())); + } + } + } + return item; +} diff --git a/local/recipes/kde/kf6-attica/source/src/downloaditemparser.h b/local/recipes/kde/kf6-attica/source/src/downloaditemparser.h new file mode 100644 index 00000000..90580b20 --- /dev/null +++ b/local/recipes/kde/kf6-attica/source/src/downloaditemparser.h @@ -0,0 +1,26 @@ +/* + This file is part of KDE. + + SPDX-FileCopyrightText: 2008 Cornelius Schumacher + + SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL +*/ + +#ifndef ATTICA_DOWNLOADITEMPARSER_H +#define ATTICA_DOWNLOADITEMPARSER_H + +#include "downloaditem.h" +#include "parser.h" + +namespace Attica +{ +class Q_DECL_HIDDEN DownloadItem::Parser : public Attica::Parser +{ +private: + DownloadItem parseXml(QXmlStreamReader &xml) override; + QStringList xmlElement() const override; +}; + +} + +#endif diff --git a/local/recipes/kde/kf6-attica/source/src/event.cpp b/local/recipes/kde/kf6-attica/source/src/event.cpp new file mode 100644 index 00000000..113b162d --- /dev/null +++ b/local/recipes/kde/kf6-attica/source/src/event.cpp @@ -0,0 +1,184 @@ +/* + This file is part of KDE. + + SPDX-FileCopyrightText: 2009 Eckhart Wörner + + SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL +*/ + +#include "event.h" + +using namespace Attica; + +class Q_DECL_HIDDEN Event::Private : public QSharedData +{ +public: + QString m_id; + QString m_name; + QString m_description; + QString m_user; + QDate m_startDate; + QDate m_endDate; + qreal m_latitude; + qreal m_longitude; + QUrl m_homepage; + QString m_country; + QString m_city; + QMap m_extendedAttributes; + + Private() + : m_latitude(0) + , m_longitude(0) + { + } +}; + +Event::Event() + : d(new Private) +{ +} + +Event::Event(const Event &other) + : d(other.d) +{ +} + +Event &Event::operator=(const Event &other) +{ + d = other.d; + return *this; +} + +Event::~Event() +{ +} + +void Event::setId(const QString &id) +{ + d->m_id = id; +} + +QString Event::id() const +{ + return d->m_id; +} + +void Event::setName(const QString &name) +{ + d->m_name = name; +} + +QString Event::name() const +{ + return d->m_name; +} + +void Event::setDescription(const QString &text) +{ + d->m_description = text; +} + +QString Event::description() const +{ + return d->m_description; +} + +void Event::setUser(const QString &id) +{ + d->m_user = id; +} + +QString Event::user() const +{ + return d->m_user; +} + +void Event::setStartDate(const QDate &date) +{ + d->m_startDate = date; +} + +QDate Event::startDate() const +{ + return d->m_startDate; +} + +void Event::setEndDate(const QDate &date) +{ + d->m_endDate = date; +} + +QDate Event::endDate() const +{ + return d->m_endDate; +} + +void Event::setLatitude(qreal lat) +{ + d->m_latitude = lat; +} + +qreal Event::latitude() const +{ + return d->m_latitude; +} + +void Event::setLongitude(qreal lon) +{ + d->m_longitude = lon; +} + +qreal Event::longitude() const +{ + return d->m_longitude; +} + +void Event::setHomepage(const QUrl &url) +{ + d->m_homepage = url; +} + +QUrl Event::homepage() const +{ + return d->m_homepage; +} + +void Event::setCountry(const QString &country) +{ + d->m_country = country; +} + +QString Event::country() const +{ + return d->m_country; +} + +void Event::setCity(const QString &city) +{ + d->m_city = city; +} + +QString Event::city() const +{ + return d->m_city; +} + +void Event::addExtendedAttribute(const QString &key, const QString &value) +{ + d->m_extendedAttributes.insert(key, value); +} + +QString Event::extendedAttribute(const QString &key) const +{ + return d->m_extendedAttributes.value(key); +} + +QMap Event::extendedAttributes() const +{ + return d->m_extendedAttributes; +} + +bool Event::isValid() const +{ + return !(d->m_id.isEmpty()); +} diff --git a/local/recipes/kde/kf6-attica/source/src/event.h b/local/recipes/kde/kf6-attica/source/src/event.h new file mode 100644 index 00000000..345026d7 --- /dev/null +++ b/local/recipes/kde/kf6-attica/source/src/event.h @@ -0,0 +1,224 @@ +/* + This file is part of KDE. + + SPDX-FileCopyrightText: 2009 Eckhart Wörner + + SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL +*/ + +#ifndef ATTICA_EVENT_H +#define ATTICA_EVENT_H + +#include "attica_export.h" + +#include +#include +#include +#include +#include + +namespace Attica +{ +/** + * @class Event event.h + * + * Represents a single event + */ +class ATTICA_EXPORT Event +{ +public: + typedef QList List; + class Parser; + + /** + * Creates an empty Event + */ + Event(); + + /** + * Copy constructor. + * @param other the Event to copy from + */ + Event(const Event &other); + + /** + * Assignment operator. + * @param other the Event to assign from + * @return pointer to this Event + */ + Event &operator=(const Event &other); + + /** + * Destructor. + */ + ~Event(); + + /** + * Sets the id of the Event. + * The id uniquely identifies a Event with the OCS API. + * @param id the new id + */ + void setId(const QString &id); + + /** + * Gets the id of the Event. + * The id uniquely identifies a Event with the OCS API. + * @return the id + */ + QString id() const; + + /** + * Sets the name of the Event. + * @param name the new name + */ + void setName(const QString &name); + + /** + * Gets the name of the Event. + * @return the name + */ + QString name() const; + + /** + * Sets the description of the Event. + * @param description the new description + */ + void setDescription(const QString &description); + + /** + * Gets the description of the Event. + * @return the description + */ + QString description() const; + + /** + * Sets the id of the user bound to the Event. + * @param user the new user id + */ + void setUser(const QString &user); + + /** + * Gets the id of the user bound to the Event. + * @return the user id + */ + QString user() const; + + /** + * Sets the start date of the Event. + * @param startDate the start date + */ + void setStartDate(const QDate &startDate); + + /** + * Gets the start date of the Event. + * @return the start date + */ + QDate startDate() const; + + /** + * Sets the end date of the Event. + * @param endDate the end date + */ + void setEndDate(const QDate &endDate); + + /** + * Gets the start date of the Event. + * @return the end date + */ + QDate endDate() const; + + /** + * Sets the latitude of the position the Event takes place. + * @param latitude the new latitude + */ + void setLatitude(qreal latitude); + + /** + * Gets the latitude of the position the Event takes place. + * @return the latitude + */ + qreal latitude() const; + + /** + * Sets the longitude of the position the Event takes place. + * @param longitude the new latitude + */ + void setLongitude(qreal longitude); + + /** + * Gets the longitude of the position the Event takes place. + * @return the latitude + */ + qreal longitude() const; + + /** + * Sets the homepage of the Event. + * @param homepage the new homepage + */ + void setHomepage(const QUrl &homepage); + + /** + * Gets the homepage of the Event. + * @return the homepage + */ + QUrl homepage() const; + + /** + * Sets the country where the Event takes place. + * @param country the new country + */ + void setCountry(const QString &country); + + /** + * Gets the country where the Event takes place. + * @return the country + */ + QString country() const; + + /** + * Sets the city where the Event takes place. + * @param city the new city + */ + void setCity(const QString &city); + + /** + * Gets the city where the Event takes place. + * @return the city + */ + QString city() const; + + /** + * Add an attribute that is not included in the basis set of attributes exposed by the Event class. + * If the attribute already exists it gets overwritten. + * @param key the key of the attribute + * @param value the value of the attribute + */ + void addExtendedAttribute(const QString &key, const QString &value); + + /** + * Get an attribute that is not included in the basis set of attributes exposed by the Event class. + * @param key the key of the attribute + * @return the value of the attribute with the specified key, or an empty string, if the key has not been found + */ + QString extendedAttribute(const QString &key) const; + + /** + * Get all attributes that are not included in the basis set of attributes exposed by the Event class. + * @return the attribute mappings + */ + QMap extendedAttributes() const; + + /** + * Checks whether this Event has an id + * @return @c true if an id has been set, @c false otherwise + */ + bool isValid() const; + +private: + class Private; + QSharedDataPointer d; +}; + +} + +#endif diff --git a/local/recipes/kde/kf6-attica/source/src/eventparser.cpp b/local/recipes/kde/kf6-attica/source/src/eventparser.cpp new file mode 100644 index 00000000..e7a1c105 --- /dev/null +++ b/local/recipes/kde/kf6-attica/source/src/eventparser.cpp @@ -0,0 +1,61 @@ +/* + This file is part of KDE. + + SPDX-FileCopyrightText: 2009 Eckhart Wörner + + SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL +*/ + +#include "eventparser.h" + +#include + +using namespace Attica; + +Event Event::Parser::parseXml(QXmlStreamReader &xml) +{ + Event event; + + while (!xml.atEnd()) { + xml.readNext(); + + if (xml.isStartElement()) { + if (xml.name() == QLatin1String("id")) { + event.setId(xml.readElementText()); + } else if (xml.name() == QLatin1String("name")) { + event.setName(xml.readElementText()); + } else if (xml.name() == QLatin1String("description")) { + event.setDescription(xml.readElementText()); + } else if (xml.name() == QLatin1String("user")) { + event.setUser(xml.readElementText()); + } else if (xml.name() == QLatin1String("startdate")) { + QString date = xml.readElementText().remove(QRegularExpression(QStringLiteral("\\+.*$"))); + event.setStartDate(QDate::fromString(date, Qt::ISODate)); + } else if (xml.name() == QLatin1String("enddate")) { + QString date = xml.readElementText().remove(QRegularExpression(QStringLiteral("\\+.*$"))); + event.setEndDate(QDate::fromString(date, Qt::ISODate)); + } else if (xml.name() == QLatin1String("latitude")) { + event.setLatitude(xml.readElementText().toFloat()); + } else if (xml.name() == QLatin1String("longitude")) { + event.setLongitude(xml.readElementText().toFloat()); + } else if (xml.name() == QLatin1String("homepage")) { + event.setHomepage(QUrl(xml.readElementText())); + } else if (xml.name() == QLatin1String("country")) { + event.setCountry(xml.readElementText()); + } else if (xml.name() == QLatin1String("city")) { + event.setCity(xml.readElementText()); + } else { + event.addExtendedAttribute(xml.name().toString(), xml.readElementText()); + } + } else if (xml.isEndElement() && xml.name() == QLatin1String("event")) { + break; + } + } + + return event; +} + +QStringList Event::Parser::xmlElement() const +{ + return QStringList(QStringLiteral("event")); +} diff --git a/local/recipes/kde/kf6-attica/source/src/eventparser.h b/local/recipes/kde/kf6-attica/source/src/eventparser.h new file mode 100644 index 00000000..ca002f52 --- /dev/null +++ b/local/recipes/kde/kf6-attica/source/src/eventparser.h @@ -0,0 +1,26 @@ +/* + This file is part of KDE. + + SPDX-FileCopyrightText: 2009 Eckhart Wörner + + SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL +*/ + +#ifndef ATTICA_EVENTPARSER_H +#define ATTICA_EVENTPARSER_H + +#include "event.h" +#include "parser.h" + +namespace Attica +{ +class Q_DECL_HIDDEN Event::Parser : public Attica::Parser +{ +private: + Event parseXml(QXmlStreamReader &xml) override; + QStringList xmlElement() const override; +}; + +} + +#endif diff --git a/local/recipes/kde/kf6-attica/source/src/folder.cpp b/local/recipes/kde/kf6-attica/source/src/folder.cpp new file mode 100644 index 00000000..8db9d905 --- /dev/null +++ b/local/recipes/kde/kf6-attica/source/src/folder.cpp @@ -0,0 +1,90 @@ +/* + This file is part of KDE. + + SPDX-FileCopyrightText: 2008 Cornelius Schumacher + + SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL +*/ + +#include "folder.h" + +using namespace Attica; + +class Q_DECL_HIDDEN Folder::Private : public QSharedData +{ +public: + QString m_id; + QString m_name; + int m_messageCount; + QString m_type; + + Private() + : m_messageCount(0) + { + } +}; + +Folder::Folder() + : d(new Private) +{ +} + +Folder::Folder(const Folder &other) + : d(other.d) +{ +} + +Folder &Folder::operator=(const Folder &other) +{ + d = other.d; + return *this; +} + +Folder::~Folder() +{ +} + +void Folder::setId(const QString &u) +{ + d->m_id = u; +} + +QString Folder::id() const +{ + return d->m_id; +} + +void Folder::setName(const QString &name) +{ + d->m_name = name; +} + +QString Folder::name() const +{ + return d->m_name; +} + +void Folder::setMessageCount(int c) +{ + d->m_messageCount = c; +} + +int Folder::messageCount() const +{ + return d->m_messageCount; +} + +void Folder::setType(const QString &v) +{ + d->m_type = v; +} + +QString Folder::type() const +{ + return d->m_type; +} + +bool Folder::isValid() const +{ + return !(d->m_id.isEmpty()); +} diff --git a/local/recipes/kde/kf6-attica/source/src/folder.h b/local/recipes/kde/kf6-attica/source/src/folder.h new file mode 100644 index 00000000..6b8eba86 --- /dev/null +++ b/local/recipes/kde/kf6-attica/source/src/folder.h @@ -0,0 +1,116 @@ +/* + This file is part of KDE. + + SPDX-FileCopyrightText: 2008 Cornelius Schumacher + + SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL +*/ + +#ifndef ATTICA_FOLDER_H +#define ATTICA_FOLDER_H + +#include "attica_export.h" +#include +#include +#include + +namespace Attica +{ +/** + * @class Folder folder.h + * + * Represents a single mail folder + */ +class ATTICA_EXPORT Folder +{ +public: + typedef QList List; + class Parser; + + /** + * Creates an empty Folder + */ + Folder(); + + /** + * Copy constructor. + * @param other the Folder to copy from + */ + Folder(const Folder &other); + + /** + * Assignment operator. + * @param other the Folder to assign from + * @return pointer to this Folder + */ + Folder &operator=(const Folder &other); + + /** + * Destructor. + */ + ~Folder(); + + /** + * Sets the id of the Folder. + * The id uniquely identifies a Folder with the OCS API. + * @param id the new id + */ + void setId(const QString &id); + + /** + * Gets the id of the Folder. + * The id uniquely identifies a Folder with the OCS API. + * @return the id + */ + QString id() const; + + /** + * Sets the name of the Folder. + * @param name the new name + */ + void setName(const QString &name); + + /** + * Gets the name of the Folder. + * @return the name + */ + QString name() const; + + /** + * Sets the number of messages in the Folder. + * @param messageCount the new number of messages + */ + void setMessageCount(int messageCount); + + /** + * Gets the number of messages in the Folder. + * @return the number of messages + */ + int messageCount() const; + + /** + * Sets the type of the folder + * @param type the new type + */ + void setType(const QString &type); + + /** + * Gets the type of the Folder. + * @return the type + */ + QString type() const; + + /** + * Checks whether this Folder has an id + * @return @c true if an id has been set, @c false otherwise + */ + bool isValid() const; + +private: + class Private; + QSharedDataPointer d; +}; + +} + +#endif diff --git a/local/recipes/kde/kf6-attica/source/src/folderparser.cpp b/local/recipes/kde/kf6-attica/source/src/folderparser.cpp new file mode 100644 index 00000000..962872a3 --- /dev/null +++ b/local/recipes/kde/kf6-attica/source/src/folderparser.cpp @@ -0,0 +1,41 @@ +/* + This file is part of KDE. + + SPDX-FileCopyrightText: 2008 Cornelius Schumacher + + SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL +*/ + +#include "folderparser.h" + +using namespace Attica; + +Folder Folder::Parser::parseXml(QXmlStreamReader &xml) +{ + Folder folder; + + while (!xml.atEnd()) { + xml.readNext(); + + if (xml.isStartElement()) { + if (xml.name() == QLatin1String("id")) { + folder.setId(xml.readElementText()); + } else if (xml.name() == QLatin1String("name")) { + folder.setName(xml.readElementText()); + } else if (xml.name() == QLatin1String("messagecount")) { + folder.setMessageCount(xml.readElementText().toInt()); + } else if (xml.name() == QLatin1String("type")) { + folder.setType(xml.readElementText()); + } + } else if (xml.isEndElement() && xml.name() == QLatin1String("folder")) { + break; + } + } + + return folder; +} + +QStringList Folder::Parser::xmlElement() const +{ + return QStringList(QStringLiteral("folder")); +} diff --git a/local/recipes/kde/kf6-attica/source/src/folderparser.h b/local/recipes/kde/kf6-attica/source/src/folderparser.h new file mode 100644 index 00000000..d9b84067 --- /dev/null +++ b/local/recipes/kde/kf6-attica/source/src/folderparser.h @@ -0,0 +1,26 @@ +/* + This file is part of KDE. + + SPDX-FileCopyrightText: 2008 Cornelius Schumacher + + SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL +*/ + +#ifndef ATTICA_FOLDERPARSER_H +#define ATTICA_FOLDERPARSER_H + +#include "folder.h" +#include "parser.h" + +namespace Attica +{ +class Q_DECL_HIDDEN Folder::Parser : public Attica::Parser +{ +private: + Folder parseXml(QXmlStreamReader &xml) override; + QStringList xmlElement() const override; +}; + +} + +#endif diff --git a/local/recipes/kde/kf6-attica/source/src/forum.cpp b/local/recipes/kde/kf6-attica/source/src/forum.cpp new file mode 100644 index 00000000..9843a79d --- /dev/null +++ b/local/recipes/kde/kf6-attica/source/src/forum.cpp @@ -0,0 +1,135 @@ +/* + This file is part of KDE. + + SPDX-FileCopyrightText: 2011 Laszlo Papp + + SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL +*/ + +#include "forum.h" + +using namespace Attica; + +class Q_DECL_HIDDEN Forum::Private : public QSharedData +{ +public: + QString m_id; + QString m_name; + QString m_description; + QDateTime m_date; + QUrl m_icon; + int m_childCount; + int m_topics; + QList m_children; + + Private() + : m_childCount(0) + , m_topics(0) + { + } +}; + +Forum::Forum() + : d(new Private) +{ +} + +Forum::Forum(const Forum &other) + : d(other.d) +{ +} + +Forum &Forum::operator=(const Attica::Forum &other) +{ + d = other.d; + return *this; +} + +Forum::~Forum() +{ +} + +void Forum::setId(const QString &id) +{ + d->m_id = id; +} + +QString Forum::id() const +{ + return d->m_id; +} + +void Forum::setName(const QString &name) +{ + d->m_name = name; +} + +QString Forum::name() const +{ + return d->m_name; +} + +void Forum::setDescription(const QString &description) +{ + d->m_description = description; +} + +QString Forum::description() const +{ + return d->m_description; +} + +void Forum::setDate(const QDateTime &date) +{ + d->m_date = date; +} + +QDateTime Forum::date() const +{ + return d->m_date; +} + +void Forum::setIcon(const QUrl &icon) +{ + d->m_icon = icon; +} + +QUrl Forum::icon() const +{ + return d->m_icon; +} + +void Forum::setChildCount(const int childCount) +{ + d->m_childCount = childCount; +} + +int Forum::childCount() const +{ + return d->m_childCount; +} + +void Forum::setChildren(QList children) +{ + d->m_children = std::move(children); // TODO KF6 Make QList const & and remove the std::move +} + +QList Forum::children() const +{ + return d->m_children; +} + +void Forum::setTopics(const int topics) +{ + d->m_topics = topics; +} + +int Forum::topics() const +{ + return d->m_topics; +} + +bool Forum::isValid() const +{ + return !(d->m_id.isEmpty()); +} diff --git a/local/recipes/kde/kf6-attica/source/src/forum.h b/local/recipes/kde/kf6-attica/source/src/forum.h new file mode 100644 index 00000000..62c48c5b --- /dev/null +++ b/local/recipes/kde/kf6-attica/source/src/forum.h @@ -0,0 +1,72 @@ +/* + This file is part of KDE. + + SPDX-FileCopyrightText: 2011 Laszlo Papp + + SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL +*/ + +#ifndef ATTICA_FORUM_H +#define ATTICA_FORUM_H + +#include "attica_export.h" + +#include "topic.h" + +#include +#include +#include + +namespace Attica +{ + +/** + * @class Forum forum.h + * + * Represents a forum. + */ +class ATTICA_EXPORT Forum +{ +public: + typedef QList List; + class Parser; + + Forum(); + Forum(const Forum &other); + Forum &operator=(const Forum &other); + ~Forum(); + + void setId(const QString &id); + QString id() const; + + void setName(const QString &name); + QString name() const; + + void setDescription(const QString &description); + QString description() const; + + void setDate(const QDateTime &date); + QDateTime date() const; + + void setIcon(const QUrl &icon); + QUrl icon() const; + + void setChildCount(const int childCount); + int childCount() const; + + void setTopics(const int topics); + int topics() const; + + void setChildren(QList comments); + QList children() const; + + bool isValid() const; + +private: + class Private; + QSharedDataPointer d; +}; + +} + +#endif diff --git a/local/recipes/kde/kf6-attica/source/src/forumparser.cpp b/local/recipes/kde/kf6-attica/source/src/forumparser.cpp new file mode 100644 index 00000000..b310e534 --- /dev/null +++ b/local/recipes/kde/kf6-attica/source/src/forumparser.cpp @@ -0,0 +1,71 @@ +/* + This file is part of KDE. + + SPDX-FileCopyrightText: 2011 Laszlo Papp + + SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL +*/ + +#include "forumparser.h" +#include "atticautils.h" + +using namespace Attica; + +Forum Forum::Parser::parseXml(QXmlStreamReader &xml) +{ + Forum forum; + + while (!xml.atEnd()) { + xml.readNext(); + + if (xml.isStartElement()) { + if (xml.name() == QLatin1String("id")) { + forum.setId(xml.readElementText()); + } else if (xml.name() == QLatin1String("name")) { + forum.setName(xml.readElementText()); + } else if (xml.name() == QLatin1String("description")) { + forum.setDescription(xml.readElementText()); + } else if (xml.name() == QLatin1String("date")) { + forum.setDate(Utils::parseQtDateTimeIso8601(xml.readElementText())); + } else if (xml.name() == QLatin1String("icon")) { + forum.setIcon(QUrl(xml.readElementText())); + } else if (xml.name() == QLatin1String("childcount")) { + forum.setChildCount(xml.readElementText().toInt()); + } else if (xml.name() == QLatin1String("children")) { + QList children = parseXmlChildren(xml); + forum.setChildren(children); + } else if (xml.name() == QLatin1String("topics")) { + forum.setTopics(xml.readElementText().toInt()); + } + } else if (xml.isEndElement() && xml.name() == QLatin1String("forum")) { + break; + } + } + + return forum; +} + +QList Forum::Parser::parseXmlChildren(QXmlStreamReader &xml) +{ + QList children; + + while (!xml.atEnd()) { + xml.readNext(); + + if (xml.isStartElement()) { + if (xml.name() == QLatin1String("forum")) { + Forum forum = parseXml(xml); + children.append(forum); + } + } else if (xml.isEndElement() && xml.name() == QLatin1String("children")) { + break; + } + } + + return children; +} + +QStringList Forum::Parser::xmlElement() const +{ + return QStringList(QStringLiteral("forum")); +} diff --git a/local/recipes/kde/kf6-attica/source/src/forumparser.h b/local/recipes/kde/kf6-attica/source/src/forumparser.h new file mode 100644 index 00000000..2e99c1a7 --- /dev/null +++ b/local/recipes/kde/kf6-attica/source/src/forumparser.h @@ -0,0 +1,27 @@ +/* + This file is part of KDE. + + SPDX-FileCopyrightText: 2011 Laszlo Papp + + SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL +*/ + +#ifndef ATTICA_FORUMPARSER_H +#define ATTICA_FORUMPARSER_H + +#include "forum.h" +#include "parser.h" + +namespace Attica +{ +class Q_DECL_HIDDEN Forum::Parser : public Attica::Parser +{ +private: + Forum parseXml(QXmlStreamReader &xml) override; + QList parseXmlChildren(QXmlStreamReader &xml); + QStringList xmlElement() const override; +}; + +} + +#endif diff --git a/local/recipes/kde/kf6-attica/source/src/getjob.cpp b/local/recipes/kde/kf6-attica/source/src/getjob.cpp new file mode 100644 index 00000000..cdf3179c --- /dev/null +++ b/local/recipes/kde/kf6-attica/source/src/getjob.cpp @@ -0,0 +1,29 @@ +/* + This file is part of KDE. + + SPDX-FileCopyrightText: 2009 Eckhart Wörner + + SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL +*/ + +#include "getjob.h" + +#include + +#include "platformdependent.h" +#include + +using namespace Attica; + +GetJob::GetJob(PlatformDependent *internals, const QNetworkRequest &request) + : BaseJob(internals) + , m_request(request) +{ +} + +QNetworkReply *GetJob::executeRequest() +{ + return internals()->get(m_request); +} + +#include "moc_getjob.cpp" diff --git a/local/recipes/kde/kf6-attica/source/src/getjob.h b/local/recipes/kde/kf6-attica/source/src/getjob.h new file mode 100644 index 00000000..26adf091 --- /dev/null +++ b/local/recipes/kde/kf6-attica/source/src/getjob.h @@ -0,0 +1,39 @@ +/* + This file is part of KDE. + + SPDX-FileCopyrightText: 2009 Eckhart Wörner + + SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL +*/ + +#ifndef ATTICA_GETJOB_H +#define ATTICA_GETJOB_H + +#include + +#include "attica_export.h" +#include "atticabasejob.h" + +namespace Attica +{ + +/** + * @class GetJob getjob.h + * + * Represents a get job. + */ +class ATTICA_EXPORT GetJob : public Attica::BaseJob +{ + Q_OBJECT + +protected: + GetJob(PlatformDependent *internals, const QNetworkRequest &request); + +private: + QNetworkReply *executeRequest() override; + const QNetworkRequest m_request; +}; + +} + +#endif diff --git a/local/recipes/kde/kf6-attica/source/src/homepageentry.cpp b/local/recipes/kde/kf6-attica/source/src/homepageentry.cpp new file mode 100644 index 00000000..9d4bba91 --- /dev/null +++ b/local/recipes/kde/kf6-attica/source/src/homepageentry.cpp @@ -0,0 +1,63 @@ +/* + This file is part of KDE. + + SPDX-FileCopyrightText: 2010 Intel Corporation + SPDX-FileContributor: Mateu Batle Sastre + + SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL +*/ + +#include "homepageentry.h" + +using namespace Attica; + +class Q_DECL_HIDDEN HomePageEntry::Private : public QSharedData +{ +public: + QString type; + QUrl url; + + Private() + { + } +}; + +HomePageEntry::HomePageEntry() + : d(new Private) +{ +} + +HomePageEntry::HomePageEntry(const Attica::HomePageEntry &other) + : d(other.d) +{ +} + +HomePageEntry &HomePageEntry::operator=(const Attica::HomePageEntry &other) +{ + d = other.d; + return *this; +} + +HomePageEntry::~HomePageEntry() +{ +} + +QString HomePageEntry::type() const +{ + return d->type; +} + +void HomePageEntry::setType(const QString &type) +{ + d->type = type; +} + +QUrl HomePageEntry::url() const +{ + return d->url; +} + +void HomePageEntry::setUrl(const QUrl &url) +{ + d->url = url; +} diff --git a/local/recipes/kde/kf6-attica/source/src/homepageentry.h b/local/recipes/kde/kf6-attica/source/src/homepageentry.h new file mode 100644 index 00000000..3ab75129 --- /dev/null +++ b/local/recipes/kde/kf6-attica/source/src/homepageentry.h @@ -0,0 +1,67 @@ +/* + This file is part of KDE. + + SPDX-FileCopyrightText: 2010 Intel Corporation + SPDX-FileContributor: Mateu Batle Sastre + + SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL +*/ + +#ifndef ATTICA_HOMEPAGEENTRY_H +#define ATTICA_HOMEPAGEENTRY_H + +#include +#include + +#include "attica_export.h" + +namespace Attica +{ +/** + @class HomePageEntry homepageentry.h + + The HomePageEntry class contains information about one home page entry. + It consists of a type and a home page url. + */ +class ATTICA_EXPORT HomePageEntry +{ +public: + typedef QList List; + + /** + * Creates an empty HomePageEntry + */ + HomePageEntry(); + + /** + * Copy constructor. + * @param other the HomePageEntry to copy from + */ + HomePageEntry(const HomePageEntry &other); + + /** + * Assignment operator. + * @param other the HomePageEntry to assign from + * @return pointer to this HomePageEntry + */ + HomePageEntry &operator=(const HomePageEntry &other); + + /** + * Destructor. + */ + ~HomePageEntry(); + + QString type() const; + void setType(const QString &type); + + QUrl url() const; + void setUrl(const QUrl &url); + +private: + class Private; + QSharedDataPointer d; +}; + +} + +#endif diff --git a/local/recipes/kde/kf6-attica/source/src/homepagetype.cpp b/local/recipes/kde/kf6-attica/source/src/homepagetype.cpp new file mode 100644 index 00000000..454288a9 --- /dev/null +++ b/local/recipes/kde/kf6-attica/source/src/homepagetype.cpp @@ -0,0 +1,64 @@ +/* + This file is part of KDE. + + SPDX-FileCopyrightText: 2010 Intel Corporation + SPDX-FileContributor: Mateu Batle Sastre + + SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL +*/ + +#include "homepagetype.h" + +using namespace Attica; + +class Q_DECL_HIDDEN HomePageType::Private : public QSharedData +{ +public: + int id; + QString name; + + Private() + : id(-1) + { + } +}; + +HomePageType::HomePageType() + : d(new Private) +{ +} + +HomePageType::HomePageType(const Attica::HomePageType &other) + : d(other.d) +{ +} + +HomePageType &HomePageType::operator=(const Attica::HomePageType &other) +{ + d = other.d; + return *this; +} + +HomePageType::~HomePageType() +{ +} + +uint HomePageType::id() const +{ + return d->id; +} + +void HomePageType::setId(uint id) +{ + d->id = id; +} + +QString HomePageType::name() const +{ + return d->name; +} + +void HomePageType::setName(const QString &name) +{ + d->name = name; +} diff --git a/local/recipes/kde/kf6-attica/source/src/homepagetype.h b/local/recipes/kde/kf6-attica/source/src/homepagetype.h new file mode 100644 index 00000000..7335c44e --- /dev/null +++ b/local/recipes/kde/kf6-attica/source/src/homepagetype.h @@ -0,0 +1,73 @@ +/* + This file is part of KDE. + + SPDX-FileCopyrightText: 2010 Intel Corporation + SPDX-FileContributor: Mateu Batle Sastre + + SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL +*/ + +#ifndef ATTICA_HOMEPAGETYPE_H +#define ATTICA_HOMEPAGETYPE_H + +#include +#include + +#include "attica_export.h" + +namespace Attica +{ +/** + @class HomePageType homepagetype.h + + The HomePageType class contains information about one home page type. + It consists of an integer id and a home page type name. + */ +class ATTICA_EXPORT HomePageType +{ +public: + typedef QList List; + class Parser; + + /** + * Creates an empty HomePageType + */ + HomePageType(); + + /** + * Copy constructor. + * @param other the HomePageType to copy from + */ + HomePageType(const HomePageType &other); + + /** + * Assignment operator. + * @param other the HomePageType to assign from + * @return pointer to this HomePageType + */ + HomePageType &operator=(const HomePageType &other); + + /** + * Destructor. + */ + ~HomePageType(); + + /* + 10 + Blog + */ + + uint id() const; + void setId(uint id); + + QString name() const; + void setName(const QString &name); + +private: + class Private; + QSharedDataPointer d; +}; + +} + +#endif diff --git a/local/recipes/kde/kf6-attica/source/src/homepagetypeparser.cpp b/local/recipes/kde/kf6-attica/source/src/homepagetypeparser.cpp new file mode 100644 index 00000000..a46f96f7 --- /dev/null +++ b/local/recipes/kde/kf6-attica/source/src/homepagetypeparser.cpp @@ -0,0 +1,37 @@ +/* + This file is part of KDE. + + SPDX-FileCopyrightText: 2010 Intel Corporation + SPDX-FileContributor: Mateu Batle Sastre + + SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL +*/ + +#include "homepagetypeparser.h" + +using namespace Attica; + +QStringList HomePageType::Parser::xmlElement() const +{ + return QStringList(QStringLiteral("homepagetype")); +} + +HomePageType HomePageType::Parser::parseXml(QXmlStreamReader &xml) +{ + HomePageType item; + + while (!xml.atEnd()) { + xml.readNext(); + if (xml.isStartElement()) { + if (xml.name() == QLatin1String("id")) { + item.setId(xml.readElementText().toInt()); + } else if (xml.name() == QLatin1String("name")) { + item.setName(xml.readElementText()); + } + } + if (xml.isEndElement() && xml.name() == QLatin1String("homepagetype")) { + break; + } + } + return item; +} diff --git a/local/recipes/kde/kf6-attica/source/src/homepagetypeparser.h b/local/recipes/kde/kf6-attica/source/src/homepagetypeparser.h new file mode 100644 index 00000000..f3dea39c --- /dev/null +++ b/local/recipes/kde/kf6-attica/source/src/homepagetypeparser.h @@ -0,0 +1,27 @@ +/* + This file is part of KDE. + + SPDX-FileCopyrightText: 2010 Intel Corporation + SPDX-FileContributor: Mateu Batle Sastre + + SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL +*/ + +#ifndef ATTICA_HOMEPAGETYPE_PARSER_H +#define ATTICA_HOMEPAGETYPE_PARSER_H + +#include "homepagetype.h" +#include "parser.h" + +namespace Attica +{ +class Q_DECL_HIDDEN HomePageType::Parser : public Attica::Parser +{ +private: + HomePageType parseXml(QXmlStreamReader &xml) override; + QStringList xmlElement() const override; +}; + +} + +#endif diff --git a/local/recipes/kde/kf6-attica/source/src/icon.cpp b/local/recipes/kde/kf6-attica/source/src/icon.cpp new file mode 100644 index 00000000..415775e2 --- /dev/null +++ b/local/recipes/kde/kf6-attica/source/src/icon.cpp @@ -0,0 +1,76 @@ +/* + This file is part of KDE. + + SPDX-FileCopyrightText: 2010 Intel Corporation + SPDX-FileContributor: Mateu Batle Sastre + + SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL +*/ + +#include "icon.h" + +using namespace Attica; + +class Q_DECL_HIDDEN Icon::Private : public QSharedData +{ +public: + QUrl url; + uint width; + uint height; + + Private() + : width(0) + , height(0) + { + } +}; + +Icon::Icon() + : d(new Private) +{ +} + +Icon::Icon(const Attica::Icon &other) + : d(other.d) +{ +} + +Icon &Icon::operator=(const Attica::Icon &other) +{ + d = other.d; + return *this; +} + +Icon::~Icon() +{ +} + +QUrl Icon::url() const +{ + return d->url; +} + +void Icon::setUrl(const QUrl &url) +{ + d->url = url; +} + +uint Icon::width() const +{ + return d->width; +} + +void Icon::setWidth(uint width) +{ + d->width = width; +} + +uint Icon::height() const +{ + return d->height; +} + +void Icon::setHeight(uint height) +{ + d->height = height; +} diff --git a/local/recipes/kde/kf6-attica/source/src/icon.h b/local/recipes/kde/kf6-attica/source/src/icon.h new file mode 100644 index 00000000..d8fb722c --- /dev/null +++ b/local/recipes/kde/kf6-attica/source/src/icon.h @@ -0,0 +1,70 @@ +/* + This file is part of KDE. + + SPDX-FileCopyrightText: 2010 Intel Corporation + SPDX-FileContributor: Mateu Batle Sastre + + SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL +*/ + +#ifndef ATTICA_ICON_H +#define ATTICA_ICON_H + +#include +#include + +#include "attica_export.h" + +namespace Attica +{ +/** + @class Icon icon.h + + The Icon class contains information about an icon. + It consists of a Url and icon size information. + */ +class ATTICA_EXPORT Icon +{ +public: + typedef QList List; + + /** + * Creates an empty Icon + */ + Icon(); + + /** + * Copy constructor. + * @param other the Icon to copy from + */ + Icon(const Icon &other); + + /** + * Assignment operator. + * @param other the Icon to assign from + * @return pointer to this Icon + */ + Icon &operator=(const Icon &other); + + /** + * Destructor. + */ + ~Icon(); + + QUrl url() const; + void setUrl(const QUrl &url); + + uint width() const; + void setWidth(uint width); + + uint height() const; + void setHeight(uint height); + +private: + class Private; + QSharedDataPointer d; +}; + +} + +#endif diff --git a/local/recipes/kde/kf6-attica/source/src/itemjob.cpp b/local/recipes/kde/kf6-attica/source/src/itemjob.cpp new file mode 100644 index 00000000..6dcb40ec --- /dev/null +++ b/local/recipes/kde/kf6-attica/source/src/itemjob.cpp @@ -0,0 +1,104 @@ +/* + This file is part of KDE. + + SPDX-FileCopyrightText: 2009 Frederik Gladhorn + SPDX-FileCopyrightText: 2011 Laszlo Papp + + SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL +*/ + +#include "itemjob.h" + +using namespace Attica; + +template +ItemJob::ItemJob(PlatformDependent *internals, const QNetworkRequest &request) + : GetJob(internals, request) +{ +} + +template +void ItemJob::parse(const QString &xml) +{ + typename T::Parser p; + m_item = p.parse(xml); + setMetadata(p.metadata()); +} + +template +T ItemJob::result() const +{ + return m_item; +} + +template +ItemDeleteJob::ItemDeleteJob(PlatformDependent *internals, const QNetworkRequest &request) + : DeleteJob(internals, request) +{ +} + +template +void ItemDeleteJob::parse(const QString &xml) +{ + typename T::Parser p; + m_item = p.parse(xml); + setMetadata(p.metadata()); +} + +template +T ItemDeleteJob::result() const +{ + return m_item; +} + +template +ItemPostJob::ItemPostJob(PlatformDependent *internals, const QNetworkRequest &request, QIODevice *data) + : PostJob(internals, request, data) +{ +} + +template +ItemPostJob::ItemPostJob(PlatformDependent *internals, const QNetworkRequest &request, const StringMap ¶meters) + : PostJob(internals, request, parameters) +{ +} + +template +void ItemPostJob::parse(const QString &xml) +{ + typename T::Parser p; + m_item = p.parse(xml); + setMetadata(p.metadata()); +} + +template +T ItemPostJob::result() const +{ + return m_item; +} + +template +ItemPutJob::ItemPutJob(PlatformDependent *internals, const QNetworkRequest &request, QIODevice *data) + : PutJob(internals, request, data) +{ +} + +template +ItemPutJob::ItemPutJob(PlatformDependent *internals, const QNetworkRequest &request, const StringMap ¶meters) + : PutJob(internals, request, parameters) +{ +} + +template +void ItemPutJob::parse(const QString &xml) +{ + typename T::Parser p; + m_item = p.parse(xml); + setMetadata(p.metadata()); +} + +template +T ItemPutJob::result() const +{ + return m_item; +} diff --git a/local/recipes/kde/kf6-attica/source/src/itemjob.h b/local/recipes/kde/kf6-attica/source/src/itemjob.h new file mode 100644 index 00000000..29017952 --- /dev/null +++ b/local/recipes/kde/kf6-attica/source/src/itemjob.h @@ -0,0 +1,101 @@ +/* + This file is part of KDE. + + SPDX-FileCopyrightText: 2009 Frederik Gladhorn + SPDX-FileCopyrightText: 2011 Laszlo Papp + + SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL + */ + +#ifndef ATTICA_ITEMJOB_H +#define ATTICA_ITEMJOB_H + +#include "attica_export.h" +#include "deletejob.h" +#include "getjob.h" +#include "postjob.h" +#include "putjob.h" + +namespace Attica +{ +class Provider; + +/** + * @class ItemJob itemjob.h + * + * Represents an item get job. + */ +template +class ATTICA_EXPORT ItemJob : public GetJob +{ +public: + T result() const; + +private: + ItemJob(PlatformDependent *, const QNetworkRequest &request); + void parse(const QString &xml) override; + T m_item; + friend class Attica::Provider; +}; + +/** + * @class ItemDeleteJob itemjob.h + * + * Represents an item delete job. + */ +template +class ATTICA_EXPORT ItemDeleteJob : public DeleteJob +{ +public: + T result() const; + +private: + ItemDeleteJob(PlatformDependent *, const QNetworkRequest &request); + void parse(const QString &xml) override; + T m_item; + friend class Attica::Provider; +}; + +/** + * @class ItemPostJob itemjob.h + * + * Represents an item post job. + */ +template +class ATTICA_EXPORT ItemPostJob : public PostJob +{ +public: + T result() const; + +private: + ItemPostJob(PlatformDependent *internals, const QNetworkRequest &request, QIODevice *data); + ItemPostJob(PlatformDependent *internals, const QNetworkRequest &request, const StringMap ¶meters = StringMap()); + + void parse(const QString &xml) override; + T m_item; + friend class Attica::Provider; +}; + +/** + * @class ItemPutJob itemjob.h + * + * Represents an item put job. + */ +template +class ATTICA_EXPORT ItemPutJob : public PutJob +{ +public: + T result() const; + +private: + ItemPutJob(PlatformDependent *internals, const QNetworkRequest &request, QIODevice *data); + ItemPutJob(PlatformDependent *internals, const QNetworkRequest &request, const StringMap ¶meters = StringMap()); + + void parse(const QString &xml) override; + T m_item; + friend class Attica::Provider; +}; + +} + +#endif diff --git a/local/recipes/kde/kf6-attica/source/src/knowledgebaseentry.cpp b/local/recipes/kde/kf6-attica/source/src/knowledgebaseentry.cpp new file mode 100644 index 00000000..c846cd48 --- /dev/null +++ b/local/recipes/kde/kf6-attica/source/src/knowledgebaseentry.cpp @@ -0,0 +1,174 @@ +/* + This file is part of KDE. + + SPDX-FileCopyrightText: 2009 Marco Martin + + SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL +*/ + +#include "knowledgebaseentry.h" + +using namespace Attica; + +class Q_DECL_HIDDEN KnowledgeBaseEntry::Private : public QSharedData +{ +public: + QString m_id; + int m_contentId; + QString m_user; + QString m_status; + QDateTime m_changed; + QString m_name; + QString m_description; + QString m_answer; + int m_comments; + QUrl m_detailPage; + + QMap m_extendedAttributes; + + Private() + : m_contentId(0) + , m_comments(0) + { + } +}; + +KnowledgeBaseEntry::KnowledgeBaseEntry() + : d(new Private) +{ +} + +KnowledgeBaseEntry::KnowledgeBaseEntry(const KnowledgeBaseEntry &other) + : d(other.d) +{ +} + +KnowledgeBaseEntry &KnowledgeBaseEntry::operator=(const Attica::KnowledgeBaseEntry &other) +{ + d = other.d; + return *this; +} + +KnowledgeBaseEntry::~KnowledgeBaseEntry() +{ +} + +void KnowledgeBaseEntry::setId(QString id) +{ + d->m_id = std::move(id); // TODO KF6 Make QString const & and remove the std::move +} + +QString KnowledgeBaseEntry::id() const +{ + return d->m_id; +} + +void KnowledgeBaseEntry::setContentId(int id) +{ + d->m_contentId = id; +} + +int KnowledgeBaseEntry::contentId() const +{ + return d->m_contentId; +} + +void KnowledgeBaseEntry::setUser(const QString &user) +{ + d->m_user = user; +} + +QString KnowledgeBaseEntry::user() const +{ + return d->m_user; +} + +void KnowledgeBaseEntry::setStatus(const QString &status) +{ + d->m_status = status; +} + +QString KnowledgeBaseEntry::status() const +{ + return d->m_status; +} + +void KnowledgeBaseEntry::setChanged(const QDateTime &changed) +{ + d->m_changed = changed; +} + +QDateTime KnowledgeBaseEntry::changed() const +{ + return d->m_changed; +} + +void KnowledgeBaseEntry::setName(const QString &name) +{ + d->m_name = name; +} + +QString KnowledgeBaseEntry::name() const +{ + return d->m_name; +} + +void KnowledgeBaseEntry::setDescription(const QString &description) +{ + d->m_description = description; +} + +QString KnowledgeBaseEntry::description() const +{ + return d->m_description; +} + +void KnowledgeBaseEntry::setAnswer(const QString &answer) +{ + d->m_answer = answer; +} + +QString KnowledgeBaseEntry::answer() const +{ + return d->m_answer; +} + +void KnowledgeBaseEntry::setComments(int comments) +{ + d->m_comments = comments; +} + +int KnowledgeBaseEntry::comments() const +{ + return d->m_comments; +} + +void KnowledgeBaseEntry::setDetailPage(const QUrl &detailPage) +{ + d->m_detailPage = detailPage; +} + +QUrl KnowledgeBaseEntry::detailPage() const +{ + return d->m_detailPage; +} + +void KnowledgeBaseEntry::addExtendedAttribute(const QString &key, const QString &value) +{ + d->m_extendedAttributes.insert(key, value); +} + +QString KnowledgeBaseEntry::extendedAttribute(const QString &key) const +{ + return d->m_extendedAttributes.value(key); +} + +QMap KnowledgeBaseEntry::extendedAttributes() const +{ + return d->m_extendedAttributes; +} + +bool KnowledgeBaseEntry::isValid() const +{ + return !(d->m_id.isEmpty()); +} diff --git a/local/recipes/kde/kf6-attica/source/src/knowledgebaseentry.h b/local/recipes/kde/kf6-attica/source/src/knowledgebaseentry.h new file mode 100644 index 00000000..14d66696 --- /dev/null +++ b/local/recipes/kde/kf6-attica/source/src/knowledgebaseentry.h @@ -0,0 +1,83 @@ +/* + This file is part of KDE. + + SPDX-FileCopyrightText: 2009 Marco Martin + + SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL +*/ + +#ifndef ATTICA_KNOWLEDGEBASEENTRY_H +#define ATTICA_KNOWLEDGEBASEENTRY_H + +#include "attica_export.h" + +#include +#include +#include + +#include + +namespace Attica +{ + +/** + * @class KnowledgeBaseEntry knowledgebaseentry.h + * + * Represents a knowledge base entry. + */ +class ATTICA_EXPORT KnowledgeBaseEntry +{ +public: + typedef QList List; + class Parser; + + KnowledgeBaseEntry(); + KnowledgeBaseEntry(const KnowledgeBaseEntry &other); + KnowledgeBaseEntry &operator=(const KnowledgeBaseEntry &other); + ~KnowledgeBaseEntry(); + + void setId(QString id); + QString id() const; + + void setContentId(int id); + int contentId() const; + + void setUser(const QString &user); + QString user() const; + + void setStatus(const QString &status); + QString status() const; + + void setChanged(const QDateTime &changed); + QDateTime changed() const; + + void setName(const QString &name); + QString name() const; + + void setDescription(const QString &description); + QString description() const; + + void setAnswer(const QString &answer); + QString answer() const; + + void setComments(int comments); + int comments() const; + + void setDetailPage(const QUrl &detailPage); + QUrl detailPage() const; + + void addExtendedAttribute(const QString &key, const QString &value); + QString extendedAttribute(const QString &key) const; + + QMap extendedAttributes() const; + + bool isValid() const; + +private: + class Private; + QSharedDataPointer d; +}; + +} + +#endif diff --git a/local/recipes/kde/kf6-attica/source/src/knowledgebaseentryparser.cpp b/local/recipes/kde/kf6-attica/source/src/knowledgebaseentryparser.cpp new file mode 100644 index 00000000..ed20bb57 --- /dev/null +++ b/local/recipes/kde/kf6-attica/source/src/knowledgebaseentryparser.cpp @@ -0,0 +1,58 @@ +/* + This file is part of KDE. + + SPDX-FileCopyrightText: 2008 Cornelius Schumacher + SPDX-FileCopyrightText: 2009 Marco Martin + + SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL +*/ + +#include "knowledgebaseentryparser.h" + +using namespace Attica; + +KnowledgeBaseEntry KnowledgeBaseEntry::Parser::parseXml(QXmlStreamReader &xml) +{ + KnowledgeBaseEntry knowledgeBase; + + while (!xml.atEnd()) { + xml.readNext(); + + if (xml.isStartElement()) { + if (xml.name() == QLatin1String("id")) { + knowledgeBase.setId(xml.readElementText()); + } else if (xml.name() == QLatin1String("status")) { + knowledgeBase.setStatus(xml.readElementText()); + } else if (xml.name() == QLatin1String("contentId")) { + knowledgeBase.setContentId(xml.readElementText().toInt()); + } else if (xml.name() == QLatin1String("user")) { + knowledgeBase.setUser(xml.readElementText()); + } else if (xml.name() == QLatin1String("changed")) { + knowledgeBase.setChanged(QDateTime::fromString(xml.readElementText(), Qt::ISODate)); + } else if (xml.name() == QLatin1String("description")) { + knowledgeBase.setDescription(xml.readElementText()); + } else if (xml.name() == QLatin1String("answer")) { + knowledgeBase.setAnswer(xml.readElementText()); + } else if (xml.name() == QLatin1String("comments")) { + knowledgeBase.setComments(xml.readElementText().toInt()); + } else if (xml.name() == QLatin1String("detailpage")) { + knowledgeBase.setDetailPage(QUrl(xml.readElementText())); + } else if (xml.name() == QLatin1String("contentid")) { + knowledgeBase.setContentId(xml.readElementText().toInt()); + } else if (xml.name() == QLatin1String("name")) { + knowledgeBase.setName(xml.readElementText()); + } else { + knowledgeBase.addExtendedAttribute(xml.name().toString(), xml.readElementText()); + } + } else if (xml.isEndElement() && xml.name() == QLatin1String("content")) { + break; + } + } + + return knowledgeBase; +} + +QStringList KnowledgeBaseEntry::Parser::xmlElement() const +{ + return QStringList(QStringLiteral("content")); +} diff --git a/local/recipes/kde/kf6-attica/source/src/knowledgebaseentryparser.h b/local/recipes/kde/kf6-attica/source/src/knowledgebaseentryparser.h new file mode 100644 index 00000000..5537c7db --- /dev/null +++ b/local/recipes/kde/kf6-attica/source/src/knowledgebaseentryparser.h @@ -0,0 +1,27 @@ +/* + This file is part of KDE. + + SPDX-FileCopyrightText: 2008 Cornelius Schumacher + SPDX-FileCopyrightText: 2009 Marco Martin + + SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL +*/ + +#ifndef ATTICA_KNOWLEDGEBASEENTRYPARSER_H +#define ATTICA_KNOWLEDGEBASEENTRYPARSER_H + +#include "knowledgebaseentry.h" +#include "parser.h" + +namespace Attica +{ +class Q_DECL_HIDDEN KnowledgeBaseEntry::Parser : public Attica::Parser +{ +private: + KnowledgeBaseEntry parseXml(QXmlStreamReader &xml) override; + QStringList xmlElement() const override; +}; + +} + +#endif diff --git a/local/recipes/kde/kf6-attica/source/src/license.cpp b/local/recipes/kde/kf6-attica/source/src/license.cpp new file mode 100644 index 00000000..51818b0e --- /dev/null +++ b/local/recipes/kde/kf6-attica/source/src/license.cpp @@ -0,0 +1,72 @@ +/* + SPDX-FileCopyrightText: 2010 Frederik Gladhorn + + SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL +*/ + +#include "license.h" + +using namespace Attica; + +class Q_DECL_HIDDEN License::Private : public QSharedData +{ +public: + int id; + QString name; + QUrl url; + + Private() + : id(-1) + { + } +}; + +License::License() + : d(new Private) +{ +} + +License::License(const Attica::License &other) + : d(other.d) +{ +} + +License &License::operator=(const Attica::License &other) +{ + d = other.d; + return *this; +} + +License::~License() +{ +} + +uint License::id() const +{ + return d->id; +} + +void License::setId(uint id) +{ + d->id = id; +} + +QString License::name() const +{ + return d->name; +} + +void License::setName(const QString &name) +{ + d->name = name; +} + +void License::setUrl(const QUrl &url) +{ + d->url = url; +} + +QUrl License::url() const +{ + return d->url; +} diff --git a/local/recipes/kde/kf6-attica/source/src/license.h b/local/recipes/kde/kf6-attica/source/src/license.h new file mode 100644 index 00000000..df7444ac --- /dev/null +++ b/local/recipes/kde/kf6-attica/source/src/license.h @@ -0,0 +1,74 @@ +/* + SPDX-FileCopyrightText: 2010 Frederik Gladhorn + + SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL +*/ + +#ifndef ATTICA_LICENSE_H +#define ATTICA_LICENSE_H + +#include +#include + +#include "attica_export.h" + +namespace Attica +{ +/** + @class License license.h + + The License class contains information about one license that the server offers. + It consists of an integer id, a name and a link to a webpage describing the license. + */ +class ATTICA_EXPORT License +{ +public: + typedef QList List; + class Parser; + + /** + * Creates an empty License + */ + License(); + + /** + * Copy constructor. + * @param other the License to copy from + */ + License(const License &other); + + /** + * Assignment operator. + * @param other the License to assign from + * @return pointer to this License + */ + License &operator=(const License &other); + + /** + * Destructor. + */ + ~License(); + + /* + 3 + Artistic 2.0 + http://dev.perl.org/perl6/rfc/346.html + */ + + uint id() const; + void setId(uint id); + + QString name() const; + void setName(const QString &name); + + QUrl url() const; + void setUrl(const QUrl &url); + +private: + class Private; + QSharedDataPointer d; +}; + +} + +#endif diff --git a/local/recipes/kde/kf6-attica/source/src/licenseparser.cpp b/local/recipes/kde/kf6-attica/source/src/licenseparser.cpp new file mode 100644 index 00000000..07def636 --- /dev/null +++ b/local/recipes/kde/kf6-attica/source/src/licenseparser.cpp @@ -0,0 +1,36 @@ +/* + SPDX-FileCopyrightText: 2010 Frederik Gladhorn + + SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL +*/ + +#include "licenseparser.h" + +using namespace Attica; + +QStringList License::Parser::xmlElement() const +{ + return QStringList(QStringLiteral("license")); +} + +License License::Parser::parseXml(QXmlStreamReader &xml) +{ + License item; + + while (!xml.atEnd()) { + xml.readNext(); + if (xml.isStartElement()) { + if (xml.name() == QLatin1String("id")) { + item.setId(xml.readElementText().toInt()); + } else if (xml.name() == QLatin1String("name")) { + item.setName(xml.readElementText()); + } else if (xml.name() == QLatin1String("link")) { + item.setUrl(QUrl(xml.readElementText())); + } + } + if (xml.isEndElement() && xml.name() == QLatin1String("license")) { + break; + } + } + return item; +} diff --git a/local/recipes/kde/kf6-attica/source/src/licenseparser.h b/local/recipes/kde/kf6-attica/source/src/licenseparser.h new file mode 100644 index 00000000..febd1682 --- /dev/null +++ b/local/recipes/kde/kf6-attica/source/src/licenseparser.h @@ -0,0 +1,24 @@ +/* + SPDX-FileCopyrightText: 2010 Frederik Gladhorn + + SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL +*/ + +#ifndef ATTICA_LICENSE_PARSER_H +#define ATTICA_LICENSE_PARSER_H + +#include "license.h" +#include "parser.h" + +namespace Attica +{ +class Q_DECL_HIDDEN License::Parser : public Attica::Parser +{ +private: + License parseXml(QXmlStreamReader &xml) override; + QStringList xmlElement() const override; +}; + +} + +#endif diff --git a/local/recipes/kde/kf6-attica/source/src/listjob.cpp b/local/recipes/kde/kf6-attica/source/src/listjob.cpp new file mode 100644 index 00000000..841b151e --- /dev/null +++ b/local/recipes/kde/kf6-attica/source/src/listjob.cpp @@ -0,0 +1,36 @@ +/* + This file is part of KDE. + + SPDX-FileCopyrightText: 2009 Eckhart Wörner + + SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL +*/ + +#include "listjob.h" + +#include +#include + +using namespace Attica; + +template +ListJob::ListJob(PlatformDependent *internals, const QNetworkRequest &request) + : GetJob(internals, request) +{ + qCDebug(ATTICA) << "creating list job:" << request.url(); +} + +template +typename T::List ListJob::itemList() const +{ + return m_itemList; +} + +template +void ListJob::parse(const QString &xml) +{ + typename T::Parser parser; + m_itemList = parser.parseList(xml); + setMetadata(parser.metadata()); + qCDebug(ATTICA) << "received categories:" << m_itemList.size(); +} diff --git a/local/recipes/kde/kf6-attica/source/src/listjob.h b/local/recipes/kde/kf6-attica/source/src/listjob.h new file mode 100644 index 00000000..5fb193bb --- /dev/null +++ b/local/recipes/kde/kf6-attica/source/src/listjob.h @@ -0,0 +1,43 @@ +/* + This file is part of KDE. + + SPDX-FileCopyrightText: 2009 Eckhart Wörner + + SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL +*/ + +#ifndef LISTJOB_H +#define LISTJOB_H + +#include "attica_export.h" +#include "getjob.h" + +class QNetworkRequest; + +namespace Attica +{ +class Provider; + +/** + * @class ListJob listjob.h + * + * Represents a list job. + */ +template +class ATTICA_EXPORT ListJob : public GetJob +{ +public: + typename T::List itemList() const; + +protected: + void parse(const QString &xml) override; + +private: + ListJob(PlatformDependent *internals, const QNetworkRequest &request); + typename T::List m_itemList; + friend class Attica::Provider; +}; + +} + +#endif diff --git a/local/recipes/kde/kf6-attica/source/src/listjob_inst.cpp b/local/recipes/kde/kf6-attica/source/src/listjob_inst.cpp new file mode 100644 index 00000000..25296ec9 --- /dev/null +++ b/local/recipes/kde/kf6-attica/source/src/listjob_inst.cpp @@ -0,0 +1,151 @@ +/* + This file is part of KDE. + + SPDX-FileCopyrightText: 2009 Eckhart Wörner + SPDX-FileCopyrightText: 2011 Laszlo Papp + + SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL +*/ + +#include "itemjob.cpp" +#include "listjob.cpp" +#include "parser.cpp" + +#include "accountbalance.h" +#include "accountbalanceparser.h" +#include "achievement.h" +#include "achievementparser.h" +#include "activity.h" +#include "activityparser.h" +#include "buildservice.h" +#include "buildservicejob.h" +#include "buildservicejoboutput.h" +#include "buildservicejoboutputparser.h" +#include "buildservicejobparser.h" +#include "buildserviceparser.h" +#include "category.h" +#include "categoryparser.h" +#include "comment.h" +#include "commentparser.h" +#include "config.h" +#include "configparser.h" +#include "content.h" +#include "contentparser.h" +#include "distribution.h" +#include "distributionparser.h" +#include "downloaditemparser.h" +#include "event.h" +#include "eventparser.h" +#include "folder.h" +#include "folderparser.h" +#include "forum.h" +#include "forumparser.h" +#include "homepagetype.h" +#include "homepagetypeparser.h" +#include "knowledgebaseentry.h" +#include "knowledgebaseentryparser.h" +#include "license.h" +#include "licenseparser.h" +#include "message.h" +#include "messageparser.h" +#include "person.h" +#include "personparser.h" +#include "privatedata.h" +#include "privatedataparser.h" +#include "project.h" +#include "projectparser.h" +#include "publisher.h" +#include "publisherfield.h" +#include "publisherfieldparser.h" +#include "publisherparser.h" +#include "remoteaccount.h" +#include "remoteaccountparser.h" +#include "topic.h" +#include "topicparser.h" + +namespace Attica +{ +template class ListJob; +template class ListJob; +template class ListJob; +template class ListJob; +template class ListJob; +template class ListJob; +template class ListJob; +template class ListJob; +template class ListJob; +template class ListJob; +template class ListJob; +template class ListJob; +template class ListJob; +template class ListJob; +template class ListJob; +template class ListJob; +template class ListJob; +template class ListJob; +template class ItemJob; +template class ItemJob; +template class ItemJob; + +template class ItemPostJob; +template class ItemPostJob; +template class ItemPostJob; +template class ItemPostJob; +template class ItemPostJob; + +template class ListJob; +template class ListJob; +template class ListJob; +template class ListJob; + +template class ItemJob; +template class ItemJob; +template class ItemJob; +template class ItemJob; +template class ItemJob; +template class ItemJob; +template class ItemJob; +template class ItemJob; +template class ItemJob; +template class ItemJob; +template class ItemJob; +template class ItemJob; +template class ItemJob; +template class ItemJob; +template class ItemPostJob; +template class ItemPostJob; +template class ItemPostJob; +template class ItemPostJob; + +template class ItemPutJob; + +template class ItemDeleteJob; + +template class Parser; +template class Parser; +template class Parser; +template class Parser; +template class Parser; +template class Parser; +template class Parser; +template class Parser; +template class Parser; +template class Parser; +template class Parser; +template class Parser; +template class Parser; +template class Parser; +template class Parser; +template class Parser; +template class Parser; +template class Parser; +template class Parser; +template class Parser; +template class Parser; +template class Parser; +template class Parser; +template class Parser; +template class Parser; +template class Parser; + +} diff --git a/local/recipes/kde/kf6-attica/source/src/message.cpp b/local/recipes/kde/kf6-attica/source/src/message.cpp new file mode 100644 index 00000000..69bdf4a6 --- /dev/null +++ b/local/recipes/kde/kf6-attica/source/src/message.cpp @@ -0,0 +1,123 @@ +/* + This file is part of KDE. + + SPDX-FileCopyrightText: 2008 Cornelius Schumacher + + SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL +*/ + +#include "message.h" + +using namespace Attica; + +class Q_DECL_HIDDEN Message::Private : public QSharedData +{ +public: + QString m_id; + QString m_from; + QString m_to; + QDateTime m_sent; + Status m_status; + QString m_subject; + QString m_body; + + Private() + : m_status(Unread) + { + } +}; + +Message::Message() + : d(new Private) +{ +} + +Message::Message(const Message &other) + : d(other.d) +{ +} + +Message &Message::operator=(const Attica::Message &other) +{ + d = other.d; + return *this; +} + +Message::~Message() +{ +} + +void Message::setId(const QString &u) +{ + d->m_id = u; +} + +QString Message::id() const +{ + return d->m_id; +} + +void Message::setFrom(const QString &n) +{ + d->m_from = n; +} + +QString Message::from() const +{ + return d->m_from; +} + +void Message::setTo(const QString &n) +{ + d->m_to = n; +} + +QString Message::to() const +{ + return d->m_to; +} + +void Message::setSent(const QDateTime &date) +{ + d->m_sent = date; +} + +QDateTime Message::sent() const +{ + return d->m_sent; +} + +void Message::setStatus(Message::Status s) +{ + d->m_status = s; +} + +Message::Status Message::status() const +{ + return d->m_status; +} + +void Message::setSubject(const QString &subject) +{ + d->m_subject = subject; +} + +QString Message::subject() const +{ + return d->m_subject; +} + +void Message::setBody(const QString &body) +{ + d->m_body = body; +} + +QString Message::body() const +{ + return d->m_body; +} + +bool Message::isValid() const +{ + return !(d->m_id.isEmpty()); +} diff --git a/local/recipes/kde/kf6-attica/source/src/message.h b/local/recipes/kde/kf6-attica/source/src/message.h new file mode 100644 index 00000000..bb5ebc1c --- /dev/null +++ b/local/recipes/kde/kf6-attica/source/src/message.h @@ -0,0 +1,73 @@ +/* + This file is part of KDE. + + SPDX-FileCopyrightText: 2008 Cornelius Schumacher + + SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL +*/ + +#ifndef ATTICA_MESSAGE_H +#define ATTICA_MESSAGE_H + +#include +#include +#include + +#include "attica_export.h" + +namespace Attica +{ + +/** + * @class Message message.h + * + * Represents a message. + */ +class ATTICA_EXPORT Message +{ +public: + typedef QList List; + class Parser; + + enum Status { + Unread = 0, + Read = 1, + Answered = 2, + }; + + Message(); + Message(const Message &other); + Message &operator=(const Message &other); + ~Message(); + + void setId(const QString &); + QString id() const; + + void setFrom(const QString &); + QString from() const; + + void setTo(const QString &); + QString to() const; + + void setSent(const QDateTime &); + QDateTime sent() const; + + void setStatus(Status); + Status status() const; + + void setSubject(const QString &); + QString subject() const; + + void setBody(const QString &); + QString body() const; + + bool isValid() const; + +private: + class Private; + QSharedDataPointer d; +}; + +} + +#endif diff --git a/local/recipes/kde/kf6-attica/source/src/messageparser.cpp b/local/recipes/kde/kf6-attica/source/src/messageparser.cpp new file mode 100644 index 00000000..cefe9d9d --- /dev/null +++ b/local/recipes/kde/kf6-attica/source/src/messageparser.cpp @@ -0,0 +1,49 @@ +/* + This file is part of KDE. + + SPDX-FileCopyrightText: 2008 Cornelius Schumacher + + SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL +*/ + +#include "messageparser.h" + +using namespace Attica; + +Message Message::Parser::parseXml(QXmlStreamReader &xml) +{ + Message message; + + while (!xml.atEnd()) { + xml.readNext(); + + if (xml.isStartElement()) { + if (xml.name() == QLatin1String("id")) { + message.setId(xml.readElementText()); + } else if (xml.name() == QLatin1String("messagefrom")) { + message.setFrom(xml.readElementText()); + } else if (xml.name() == QLatin1String("messageto")) { + message.setTo(xml.readElementText()); + } else if (xml.name() == QLatin1String("senddate")) { + message.setSent(QDateTime::fromString(xml.readElementText(), Qt::ISODate)); + } else if (xml.name() == QLatin1String("status")) { + message.setStatus(Message::Status(xml.readElementText().toInt())); + } else if (xml.name() == QLatin1String("subject")) { + message.setSubject(xml.readElementText()); + } else if (xml.name() == QLatin1String("body")) { + message.setBody(xml.readElementText()); + } + } + + if (xml.isEndElement() && xml.name() == QLatin1String("message")) { + break; + } + } + + return message; +} + +QStringList Message::Parser::xmlElement() const +{ + return QStringList(QStringLiteral("message")); +} diff --git a/local/recipes/kde/kf6-attica/source/src/messageparser.h b/local/recipes/kde/kf6-attica/source/src/messageparser.h new file mode 100644 index 00000000..7e22f0eb --- /dev/null +++ b/local/recipes/kde/kf6-attica/source/src/messageparser.h @@ -0,0 +1,28 @@ +/* + This file is part of KDE. + + SPDX-FileCopyrightText: 2008 Cornelius Schumacher + + SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL +*/ + +#ifndef ATTICA_MESSAGEPARSER_H +#define ATTICA_MESSAGEPARSER_H + +#include + +#include "message.h" +#include "parser.h" + +namespace Attica +{ +class Q_DECL_HIDDEN Message::Parser : public Attica::Parser +{ +private: + Message parseXml(QXmlStreamReader &xml) override; + QStringList xmlElement() const override; +}; + +} + +#endif diff --git a/local/recipes/kde/kf6-attica/source/src/metadata.cpp b/local/recipes/kde/kf6-attica/source/src/metadata.cpp new file mode 100644 index 00000000..401a7ed5 --- /dev/null +++ b/local/recipes/kde/kf6-attica/source/src/metadata.cpp @@ -0,0 +1,147 @@ +/* + This file is part of KDE. + + SPDX-FileCopyrightText: 2009 Frederik Gladhorn + + SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL +*/ + +#include "metadata.h" + +#include + +using namespace Attica; + +class Q_DECL_HIDDEN Metadata::Private : public QSharedData +{ +public: + Error error; + + /// The status of the job, for example "Ok" + QString statusString; + /// The status as int, for easier interpretation. + /// 100 means "Ok", for other codes refer to http://www.freedesktop.org/wiki/Specifications/open-collaboration-services + int statusCode; + + /// An optional additional message from the server + QString message; + + /// The number of items returned by this job (only relevant for list jobs) + int totalItems; + /// The number of items per page the server was asked for + int itemsPerPage; + + QString resultingId; + + /// The http headers for the most recent network action in the case of a network error + QList headers; + + Private() + // values that make sense for single item jobs + : error(NoError) + , statusCode(0) + , totalItems(1) + , itemsPerPage(1) + { + } +}; + +Metadata::Metadata() + : d(new Private) +{ +} + +Metadata::~Metadata() +{ +} + +Metadata::Metadata(const Attica::Metadata &other) + : d(other.d) +{ +} + +Metadata &Metadata::operator=(const Attica::Metadata &other) +{ + d = other.d; + return *this; +} + +Metadata::Error Metadata::error() const +{ + return d->error; +} + +void Metadata::setError(Metadata::Error error) +{ + d->error = error; +} + +QString Metadata::message() +{ + return d->message; +} + +void Metadata::setMessage(const QString &message) +{ + d->message = message; +} + +QString Metadata::resultingId() +{ + return d->resultingId; +} + +void Metadata::setResultingId(const QString &id) +{ + d->resultingId = id; +} + +int Metadata::statusCode() const +{ + return d->statusCode; +} + +void Metadata::setStatusCode(int code) +{ + d->statusCode = code; +} + +QString Metadata::statusString() const +{ + return d->statusString; +} + +void Metadata::setStatusString(const QString &status) +{ + d->statusString = status; +} + +int Metadata::totalItems() +{ + return d->totalItems; +} + +void Metadata::setTotalItems(int items) +{ + d->totalItems = items; +} + +int Metadata::itemsPerPage() +{ + return d->itemsPerPage; +} + +void Metadata::setItemsPerPage(int itemsPerPage) +{ + d->itemsPerPage = itemsPerPage; +} + +QList Metadata::headers() const +{ + return d->headers; +} + +void Metadata::setHeaders(const QList &headers) +{ + d->headers = headers; +} diff --git a/local/recipes/kde/kf6-attica/source/src/metadata.h b/local/recipes/kde/kf6-attica/source/src/metadata.h new file mode 100644 index 00000000..48a85e22 --- /dev/null +++ b/local/recipes/kde/kf6-attica/source/src/metadata.h @@ -0,0 +1,105 @@ +/* + This file is part of KDE. + + SPDX-FileCopyrightText: 2009 Frederik Gladhorn + + SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL + */ + +#ifndef ATTICA_METADATA_H +#define ATTICA_METADATA_H + +#include + +#include +#include + +#include "attica_export.h" + +namespace Attica +{ +class BaseJob; + +/** + * @class Metadata metadata.h + * + * Status messages from the server + */ +class ATTICA_EXPORT Metadata +{ +public: + Metadata(); + Metadata(const Metadata &other); + ~Metadata(); + Metadata &operator=(const Metadata &other); + + enum Error { + NoError = 0, + NetworkError, + OcsError, + }; + + /** + * Check if the job was successful. + * @return the error state enum returns the type of error (network or ocs) + */ + Error error() const; + void setError(Error error); + + /** + * The status as integer. + * If the error is an OCS error, refer to http://www.freedesktop.org/wiki/Specifications/open-collaboration-services + * in any other case it is the network return code. + */ + int statusCode() const; + void setStatusCode(int code); + + /** + * The status of the job, for example "Ok" + */ + QString statusString() const; + void setStatusString(const QString &status); + + /// An optional additional message from the server + QString message(); + void setMessage(const QString &message); + + /// The number of items returned by this job (only relevant for list jobs) + int totalItems(); + void setTotalItems(int items); + + /// The number of items per page the server was asked for + int itemsPerPage(); + void setItemsPerPage(int itemsPerPage); + + /// The resulting ID when a PostJob created a new item. + QString resultingId(); + void setResultingId(const QString &id); + + /** + * The http headers for the most recent network action in the case of a network error + * Use this to further inspect the error condition if the OCS status code and string is + * not enough to work out precisely what has happened (for example in case of a HTTP + * 503 status, which would suggest the service is down for maintenance for an expected + * duration which might be read from the Retry-After header). + * @return The list of raw headers (equivalent to a QNetworkReply::rawHeaderPairs call) + * @since 5.83 + */ + QList headers() const; + /** + * Sets the http headers read by headers() + * @param headers The new list of raw headers + * @since 5.83 + */ + void setHeaders(const QList &headers); + +private: + class Private; + QSharedDataPointer d; + + friend class Attica::BaseJob; +}; + +} + +#endif diff --git a/local/recipes/kde/kf6-attica/source/src/parser.cpp b/local/recipes/kde/kf6-attica/source/src/parser.cpp new file mode 100644 index 00000000..9e33cc21 --- /dev/null +++ b/local/recipes/kde/kf6-attica/source/src/parser.cpp @@ -0,0 +1,166 @@ +/* + This file is part of KDE. + + SPDX-FileCopyrightText: 2009 Eckhart Wörner + + SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL +*/ + +#include "parser.h" +#include + +using namespace Attica; + +template +Parser::~Parser() +{ +} + +template +T Parser::parse(const QString &xmlString) +{ + QStringList elements = xmlElement(); + T item; + + QXmlStreamReader xml(xmlString); + + while (!xml.atEnd()) { + xml.readNext(); + + if (xml.isStartElement()) { + if (xml.name() == QLatin1String("meta")) { + parseMetadataXml(xml); + } else if (elements.contains(xml.name())) { + item = parseXml(xml); + } + } + } + if (xml.hasError()) { + // TODO: error handling in metadata? + qWarning() << "parse():: XML Error: " << xml.errorString() << "\nIn XML:\n" << xmlString; + } + + return item; +} + +template +typename T::List Parser::parseList(const QString &xmlString) +{ + /* + QString testxml = QString("\ + \ + \ + ok\ + 100\ + \ + \ + \ + \ + obs\ + openSUSE Build Service\ + foobar.com\ + \ + openSUSE 11.2 32bit Intel\ + openSUSE 11.3 64bit Intel\ + openSUSE 11.3 32bit Intel\ + openSUSE 11.3 64bit Intel\ + \ + \ + \ + mbs\ + MeeGo Build Service\ + foobar42.com\ + \ + MeeGo 1.0 Intel\ + MeeGo 1.0 ARM\ + MeeGo 1.1 Intel\ + MeeGo 1.1 ARM\ + \ + \ + \ + sbs\ + Sebas' Build Service\ + foobar42.com\ + \ + sebasix 1.3 33bit\ + sebasis 4.4 14bit\ + sebasix 1.3 65bit\ + sebasis 4.4 37bit\ + \ + \ + \ + \ + "); + + qCDebug(ATTICA) << "parsing list:" << xmlString; + */ + QStringList elements = xmlElement(); + typename T::List items; + + // QXmlStreamReader xml( xmlString ); + QXmlStreamReader xml(xmlString); + + while (!xml.atEnd()) { + xml.readNext(); + // qCDebug(ATTICA) << "parseList():: Looking for:" << xml.name().toString(); + if (xml.isStartElement()) { + if (xml.name() == QLatin1String("data")) { + while (!xml.atEnd()) { + xml.readNext(); + + if (xml.isEndElement() && xml.name() == QLatin1String("data")) { + break; + } + + if (xml.isStartElement() && elements.contains(xml.name())) { + // qCDebug(ATTICA) << "xxxxxxxxx New Item!" << xml.name().toString(); + items.append(parseXml(xml)); + } + } + } else if (xml.name() == QLatin1String("meta")) { + parseMetadataXml(xml); + } + } + } + if (xml.hasError()) { + // TODO: error handling in metadata? + qWarning() << "parseList():: XML Error: " << xml.errorString() << "\nIn xml name" << xml.name() << "with text" << xml.text() << "at offset:\n" + << xml.characterOffset() << "\nIn XML:\n" + << xmlString; + } + + return items; +} + +template +void Parser::parseMetadataXml(QXmlStreamReader &xml) +{ + while (!xml.atEnd()) { + xml.readNext(); + if (xml.isEndElement() && xml.name() == QLatin1String("meta")) { + break; + } else if (xml.isStartElement()) { + if (xml.name() == QLatin1String("status")) { + m_metadata.setStatusString(xml.readElementText()); + } else if (xml.name() == QLatin1String("statuscode")) { + m_metadata.setStatusCode(xml.readElementText().toInt()); + } else if (xml.name() == QLatin1String("message")) { + m_metadata.setMessage(xml.readElementText()); + } else if (xml.name() == QLatin1String("totalitems")) { + m_metadata.setTotalItems(xml.readElementText().toInt()); + } else if (xml.name() == QLatin1String("itemsperpage")) { + m_metadata.setItemsPerPage(xml.readElementText().toInt()); + } + } + } + if (xml.hasError()) { + // TODO: error handling in metadata? + qWarning() << "XML Error: " << xml.errorString(); + } +} + +template +Metadata Parser::metadata() const +{ + return m_metadata; +} diff --git a/local/recipes/kde/kf6-attica/source/src/parser.h b/local/recipes/kde/kf6-attica/source/src/parser.h new file mode 100644 index 00000000..d345bb8c --- /dev/null +++ b/local/recipes/kde/kf6-attica/source/src/parser.h @@ -0,0 +1,39 @@ +/* + This file is part of KDE. + + SPDX-FileCopyrightText: 2009 Eckhart Wörner + + SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL +*/ + +#ifndef ATTICA_PARSER_H +#define ATTICA_PARSER_H + +#include +#include + +#include "listjob.h" + +namespace Attica +{ +template +class ATTICA_EXPORT Parser +{ +public: + T parse(const QString &xml); + typename T::List parseList(const QString &xml); + Metadata metadata() const; + virtual ~Parser(); + +protected: + virtual QStringList xmlElement() const = 0; + virtual T parseXml(QXmlStreamReader &xml) = 0; + +private: + void parseMetadataXml(QXmlStreamReader &xml); + Metadata m_metadata; +}; + +} + +#endif diff --git a/local/recipes/kde/kf6-attica/source/src/person.cpp b/local/recipes/kde/kf6-attica/source/src/person.cpp new file mode 100644 index 00000000..d7ee554a --- /dev/null +++ b/local/recipes/kde/kf6-attica/source/src/person.cpp @@ -0,0 +1,173 @@ +/* + This file is part of KDE. + + SPDX-FileCopyrightText: 2008 Cornelius Schumacher + + SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL +*/ + +#include "person.h" + +using namespace Attica; + +class Q_DECL_HIDDEN Person::Private : public QSharedData +{ +public: + QString m_id; + QString m_firstName; + QString m_lastName; + QDate m_birthday; + QString m_country; + qreal m_latitude; + qreal m_longitude; + QUrl m_avatarUrl; + QString m_homepage; + QString m_city; + + QMap m_extendedAttributes; + + Private() + : m_latitude(0) + , m_longitude(0) + { + } +}; + +Person::Person() + : d(new Private) +{ +} + +Person::Person(const Person &other) + : d(other.d) +{ +} + +Person &Person::operator=(const Attica::Person &other) +{ + d = other.d; + return *this; +} + +Person::~Person() +{ +} + +void Person::setId(const QString &u) +{ + d->m_id = u; +} + +QString Person::id() const +{ + return d->m_id; +} + +void Person::setFirstName(const QString &name) +{ + d->m_firstName = name; +} + +QString Person::firstName() const +{ + return d->m_firstName; +} + +void Person::setLastName(const QString &name) +{ + d->m_lastName = name; +} + +QString Person::lastName() const +{ + return d->m_lastName; +} + +void Person::setBirthday(const QDate &date) +{ + d->m_birthday = date; +} + +QDate Person::birthday() const +{ + return d->m_birthday; +} + +void Person::setCountry(const QString &c) +{ + d->m_country = c; +} + +QString Person::country() const +{ + return d->m_country; +} + +void Person::setLatitude(qreal l) +{ + d->m_latitude = l; +} + +qreal Person::latitude() const +{ + return d->m_latitude; +} + +void Person::setLongitude(qreal l) +{ + d->m_longitude = l; +} + +qreal Person::longitude() const +{ + return d->m_longitude; +} + +void Person::setAvatarUrl(const QUrl &url) +{ + d->m_avatarUrl = url; +} + +QUrl Person::avatarUrl() const +{ + return d->m_avatarUrl; +} + +void Person::setHomepage(const QString &h) +{ + d->m_homepage = h; +} + +QString Person::homepage() const +{ + return d->m_homepage; +} + +void Person::setCity(const QString &h) +{ + d->m_city = h; +} + +QString Person::city() const +{ + return d->m_city; +} +void Person::addExtendedAttribute(const QString &key, const QString &value) +{ + d->m_extendedAttributes.insert(key, value); +} + +QString Person::extendedAttribute(const QString &key) const +{ + return d->m_extendedAttributes.value(key); +} + +QMap Person::extendedAttributes() const +{ + return d->m_extendedAttributes; +} + +bool Person::isValid() const +{ + return !(d->m_id.isEmpty()); +} diff --git a/local/recipes/kde/kf6-attica/source/src/person.h b/local/recipes/kde/kf6-attica/source/src/person.h new file mode 100644 index 00000000..6ff7fd58 --- /dev/null +++ b/local/recipes/kde/kf6-attica/source/src/person.h @@ -0,0 +1,83 @@ +/* + This file is part of KDE. + + SPDX-FileCopyrightText: 2008 Cornelius Schumacher + + SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL +*/ + +#ifndef ATTICA_PERSON_H +#define ATTICA_PERSON_H + +#include +#include +#include +#include +#include + +#include "attica_export.h" + +namespace Attica +{ + +/** + * @class Person person.h + * + * Represents a person. + */ +class ATTICA_EXPORT Person +{ +public: + typedef QList List; + class Parser; + + Person(); + Person(const Person &other); + Person &operator=(const Person &other); + ~Person(); + + void setId(const QString &); + QString id() const; + + void setFirstName(const QString &); + QString firstName() const; + + void setLastName(const QString &); + QString lastName() const; + + void setBirthday(const QDate &); + QDate birthday() const; + + void setCountry(const QString &); + QString country() const; + + void setLatitude(qreal); + qreal latitude() const; + + void setLongitude(qreal); + qreal longitude() const; + + void setAvatarUrl(const QUrl &); + QUrl avatarUrl() const; + + void setHomepage(const QString &); + QString homepage() const; + + void setCity(const QString &); + QString city() const; + + void addExtendedAttribute(const QString &key, const QString &value); + QString extendedAttribute(const QString &key) const; + + QMap extendedAttributes() const; + + bool isValid() const; + +private: + class Private; + QSharedDataPointer d; +}; + +} + +#endif diff --git a/local/recipes/kde/kf6-attica/source/src/personparser.cpp b/local/recipes/kde/kf6-attica/source/src/personparser.cpp new file mode 100644 index 00000000..78031f66 --- /dev/null +++ b/local/recipes/kde/kf6-attica/source/src/personparser.cpp @@ -0,0 +1,65 @@ +/* + This file is part of KDE. + + SPDX-FileCopyrightText: 2008 Cornelius Schumacher + + SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL +*/ + +#include "personparser.h" + +using namespace Attica; + +Person Person::Parser::parseXml(QXmlStreamReader &xml) +{ + Person person; + bool hasAvatarPic = false; + + while (!xml.atEnd()) { + xml.readNext(); + + if (xml.isStartElement()) { + if (xml.name() == QLatin1String("personid")) { + person.setId(xml.readElementText()); + } else if (xml.name() == QLatin1String("firstname")) { + person.setFirstName(xml.readElementText()); + } else if (xml.name() == QLatin1String("lastname")) { + person.setLastName(xml.readElementText()); + } else if (xml.name() == QLatin1String("homepage")) { + person.setHomepage(xml.readElementText()); + } else if (xml.name() == QLatin1String("avatarpic")) { + person.setAvatarUrl(QUrl(xml.readElementText())); + } else if (xml.name() == QLatin1String("avatarpicfound")) { + QString value = xml.readElementText(); + if (value.toInt()) { + hasAvatarPic = true; + } + } else if (xml.name() == QLatin1String("birthday")) { + person.setBirthday(QDate::fromString(xml.readElementText(), Qt::ISODate)); + } else if (xml.name() == QLatin1String("city")) { + person.setCity(xml.readElementText()); + } else if (xml.name() == QLatin1String("country")) { + person.setCountry(xml.readElementText()); + } else if (xml.name() == QLatin1String("latitude")) { + person.setLatitude(xml.readElementText().toFloat()); + } else if (xml.name() == QLatin1String("longitude")) { + person.setLongitude(xml.readElementText().toFloat()); + } else { + person.addExtendedAttribute(xml.name().toString(), xml.readElementText()); + } + } else if (xml.isEndElement() && (xml.name() == QLatin1String("person") || xml.name() == QLatin1String("user"))) { + break; + } + } + + if (!hasAvatarPic) { + person.setAvatarUrl(QUrl()); + } + + return person; +} + +QStringList Person::Parser::xmlElement() const +{ + return QStringList(QStringLiteral("person")) << QStringLiteral("user"); +} diff --git a/local/recipes/kde/kf6-attica/source/src/personparser.h b/local/recipes/kde/kf6-attica/source/src/personparser.h new file mode 100644 index 00000000..8f50525a --- /dev/null +++ b/local/recipes/kde/kf6-attica/source/src/personparser.h @@ -0,0 +1,29 @@ +/* + This file is part of KDE. + + SPDX-FileCopyrightText: 2008 Cornelius Schumacher + + SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL +*/ + +#ifndef ATTICA_PERSONPARSER_H +#define ATTICA_PERSONPARSER_H + +#include "parser.h" +#include "person.h" + +#include "attica_export.h" + +namespace Attica +{ +// exported for autotest +class ATTICA_EXPORT Person::Parser : public Attica::Parser +{ +private: + Person parseXml(QXmlStreamReader &xml) override; + QStringList xmlElement() const override; +}; + +} + +#endif diff --git a/local/recipes/kde/kf6-attica/source/src/platformdependent.h b/local/recipes/kde/kf6-attica/source/src/platformdependent.h new file mode 100644 index 00000000..35e9f355 --- /dev/null +++ b/local/recipes/kde/kf6-attica/source/src/platformdependent.h @@ -0,0 +1,82 @@ +/* + This file is part of KDE. + + SPDX-FileCopyrightText: 2009 Eckhart Wörner + SPDX-FileCopyrightText: 2011 Laszlo Papp + + SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL +*/ + +#ifndef ATTICA_PLATFORMDEPENDENT_H +#define ATTICA_PLATFORMDEPENDENT_H + +#include +#include + +class QByteArray; +class QIODevice; +class QNetworkAccessManager; +class QNetworkReply; +class QNetworkRequest; +class QString; +class QUrl; + +namespace Attica +{ +class PlatformDependent +{ +public: + virtual ~PlatformDependent() + { + } + virtual QList getDefaultProviderFiles() const = 0; + virtual void addDefaultProviderFile(const QUrl &url) = 0; + virtual void removeDefaultProviderFile(const QUrl &url) = 0; + + /** + * Providers are enabled by default. Use this call to disable or enable them later. + */ + virtual void enableProvider(const QUrl &baseUrl, bool enabled) const = 0; + virtual bool isEnabled(const QUrl &baseUrl) const = 0; + + /** + * Asks the PlatformDependent plugin if it have a credentials for baseUrl + */ + virtual bool hasCredentials(const QUrl &baseUrl) const = 0; + + /** + * Asks the PlatformDependent plugin to load credentials from storage, + * and save it in user, password. + */ + virtual bool loadCredentials(const QUrl &baseUrl, QString &user, QString &password) = 0; + + /** + * Asks the PlatformDependent plugin to ask user to login and expects it to be stored in + * user and password. + * TODO KF6: Remove, askForCredentials and loadCredentials is essentially same, loadCredentials + * can itself ask for credentials if it is not present in store. + */ + virtual bool askForCredentials(const QUrl &baseUrl, QString &user, QString &password) = 0; + + /** + * Method to be called by attica to store the user and password in storage used by PlatformDependent + * plugin. + * TODO KF6: Remove, if you let platform plugin ask for credentials, you don't want to save credentials + * yourself and let plugin handle it. + */ + virtual bool saveCredentials(const QUrl &baseUrl, const QString &user, const QString &password) = 0; + + virtual QNetworkReply *get(const QNetworkRequest &request) = 0; + virtual QNetworkReply *post(const QNetworkRequest &request, QIODevice *data) = 0; + virtual QNetworkReply *post(const QNetworkRequest &request, const QByteArray &data) = 0; + virtual void setNam(QNetworkAccessManager *) + { + } + virtual QNetworkAccessManager *nam() = 0; +}; + +} + +Q_DECLARE_INTERFACE(Attica::PlatformDependent, "org.kde.Attica.Internals/1.2") + +#endif diff --git a/local/recipes/kde/kf6-attica/source/src/platformdependent_v2.cpp b/local/recipes/kde/kf6-attica/source/src/platformdependent_v2.cpp new file mode 100644 index 00000000..9470cc26 --- /dev/null +++ b/local/recipes/kde/kf6-attica/source/src/platformdependent_v2.cpp @@ -0,0 +1,15 @@ +/* + This file is part of KDE. + + SPDX-FileCopyrightText: 2011 Laszlo Papp + + SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL +*/ + +#include "platformdependent_v2.h" + +using namespace Attica; + +Attica::PlatformDependentV2::~PlatformDependentV2() +{ +} diff --git a/local/recipes/kde/kf6-attica/source/src/platformdependent_v2.h b/local/recipes/kde/kf6-attica/source/src/platformdependent_v2.h new file mode 100644 index 00000000..e50995f8 --- /dev/null +++ b/local/recipes/kde/kf6-attica/source/src/platformdependent_v2.h @@ -0,0 +1,41 @@ +/* + This file is part of KDE. + + SPDX-FileCopyrightText: 2011 Laszlo Papp + + SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL +*/ + +#ifndef ATTICA_PLATFORMDEPENDENT_V2_H +#define ATTICA_PLATFORMDEPENDENT_V2_H + +#include +#include + +#include "attica_export.h" +#include "platformdependent.h" + +class QByteArray; +class QIODevice; +class QNetworkAccessManager; +class QNetworkReply; +class QNetworkRequest; +class QString; +class QUrl; + +namespace Attica +{ +class ATTICA_EXPORT PlatformDependentV2 : public PlatformDependent +{ +public: + ~PlatformDependentV2() override; + virtual QNetworkReply *deleteResource(const QNetworkRequest &request) = 0; + virtual QNetworkReply *put(const QNetworkRequest &request, QIODevice *data) = 0; + virtual QNetworkReply *put(const QNetworkRequest &request, const QByteArray &data) = 0; +}; + +} + +Q_DECLARE_INTERFACE(Attica::PlatformDependentV2, "org.kde.Attica.InternalsV2/1.2") + +#endif diff --git a/local/recipes/kde/kf6-attica/source/src/platformdependent_v3.cpp b/local/recipes/kde/kf6-attica/source/src/platformdependent_v3.cpp new file mode 100644 index 00000000..4758922e --- /dev/null +++ b/local/recipes/kde/kf6-attica/source/src/platformdependent_v3.cpp @@ -0,0 +1,6 @@ +// SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL +// SPDX-FileCopyrightText: 2024 Harald Sitter + +#include "platformdependent_v3.h" + +Attica::PlatformDependentV3::~PlatformDependentV3() = default; diff --git a/local/recipes/kde/kf6-attica/source/src/platformdependent_v3.h b/local/recipes/kde/kf6-attica/source/src/platformdependent_v3.h new file mode 100644 index 00000000..655a0bbf --- /dev/null +++ b/local/recipes/kde/kf6-attica/source/src/platformdependent_v3.h @@ -0,0 +1,45 @@ +// SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL +// SPDX-FileCopyrightText: 2024 Harald Sitter + +#pragma once + +#include + +#include "attica_export.h" +#include "platformdependent_v2.h" + +namespace Attica +{ + +/** + * @brief Platform integration plugin v3 + * + * Version 3 introduces an async ready state where dependents need to mark themselves ready for requests before + * Attica dispatches them. This in particular allows dependents to carry out async initializations such as loading + * credentials. + */ +class ATTICA_EXPORT PlatformDependentV3 : public QObject, public PlatformDependentV2 +{ + Q_OBJECT + Q_PROPERTY(bool ready READ isReady NOTIFY readyChanged) +public: + using QObject::QObject; + ~PlatformDependentV3() override; + Q_DISABLE_COPY_MOVE(PlatformDependentV3) + + /** + * Whether the dependent is ready for use (e.g. has loaded credentials). + * No requests are dispatched to this dependent until the ready change has been reached! + */ + [[nodiscard]] virtual bool isReady() = 0; + +Q_SIGNALS: + /** + * Emit this when the ready state changes. Please note that reverting to not ready results in undefined behavior. + */ + void readyChanged(); +}; + +} // namespace Attica + +Q_DECLARE_INTERFACE(Attica::PlatformDependentV3, "org.kde.Attica.InternalsV3/1.0") diff --git a/local/recipes/kde/kf6-attica/source/src/postfiledata.cpp b/local/recipes/kde/kf6-attica/source/src/postfiledata.cpp new file mode 100644 index 00000000..e7cc5520 --- /dev/null +++ b/local/recipes/kde/kf6-attica/source/src/postfiledata.cpp @@ -0,0 +1,129 @@ +/* + This file is part of KDE. + + SPDX-FileCopyrightText: 1999 Matthias Kalle Dalheimer + SPDX-FileCopyrightText: 2000 Charles Samuels + SPDX-FileCopyrightText: 2005 Joseph Wenninger + SPDX-FileCopyrightText: 2009 Frederik Gladhorn + + SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL +*/ + +#include "postfiledata.h" + +#include +#include +#include + +namespace Attica +{ +class PostFileDataPrivate +{ +public: + QByteArray buffer; + QByteArray boundary; + QUrl url; + bool finished = false; +}; + +PostFileData::PostFileData(const QUrl &url) + : d(std::make_unique()) +{ + d->url = url; + d->boundary = "----------" + randomString(42 + 13).toLatin1(); +} + +PostFileData::~PostFileData() = default; + +QString PostFileData::randomString(int length) +{ + if (length <= 0) { + return QString(); + } + + QString str; + str.resize(length); + int i = 0; + auto *generator = QRandomGenerator::global(); + while (length--) { + int r = generator->bounded(62); + r += 48; + if (r > 57) { + r += 7; + } + if (r > 90) { + r += 6; + } + str[i++] = QLatin1Char(char(r)); + } + return str; +} + +void PostFileData::addArgument(const QString &key, const QString &value) +{ + if (d->finished) { + qWarning() << "PostFileData::addFile: should not add data after calling request() or data()"; + } + QByteArray data( + "--" + d->boundary + "\r\n" + "Content-Disposition: form-data; name=\"" + key.toLatin1() + + "\"\r\n\r\n" + value.toUtf8() + "\r\n"); + + d->buffer.append(data); +} + +/* +void PostFileData::addFile(const QString& fileName, QIODevice* file, const QString& mimeType) +{ + if (d->finished) { + qCDebug(ATTICA) << "PostFileData::addFile: should not add data after calling request() or data()"; + } + QByteArray data = file->readAll(); + addFile(fileName, data, mimeType); +} +*/ + +void PostFileData::addFile(const QString &fileName, const QByteArray &file, const QString &mimeType, const QString &fieldName) +{ + if (d->finished) { + qWarning() << "PostFileData::addFile: should not add data after calling request() or data()"; + } + + QByteArray data( + "--" + d->boundary + "\r\n" + "Content-Disposition: form-data; name=\""); + data.append(fieldName.toLatin1()); + data.append("\"; filename=\"" + fileName.toUtf8() + "\"\r\nContent-Type: " + mimeType.toLatin1() + "\r\n\r\n"); + + d->buffer.append(data); + d->buffer.append(file + QByteArray("\r\n")); +} + +QNetworkRequest PostFileData::request() +{ + if (!d->finished) { + finish(); + } + QNetworkRequest request; + request.setUrl(d->url); + request.setHeader(QNetworkRequest::ContentTypeHeader, QByteArray("multipart/form-data; boundary=" + d->boundary)); + request.setHeader(QNetworkRequest::ContentLengthHeader, d->buffer.length()); + return request; +} + +QByteArray PostFileData::data() +{ + if (!d->finished) { + finish(); + } + return d->buffer; +} + +void PostFileData::finish() +{ + Q_ASSERT(!d->finished); + d->finished = true; + d->buffer.append("--" + d->boundary + "--"); +} + +} diff --git a/local/recipes/kde/kf6-attica/source/src/postfiledata.h b/local/recipes/kde/kf6-attica/source/src/postfiledata.h new file mode 100644 index 00000000..9bffd379 --- /dev/null +++ b/local/recipes/kde/kf6-attica/source/src/postfiledata.h @@ -0,0 +1,49 @@ +/* + This file is part of KDE. + + SPDX-FileCopyrightText: 2009 Frederik Gladhorn + + SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL +*/ + +#ifndef POSTFILEDATA_H +#define POSTFILEDATA_H + +#include + +#include +#include +#include + +namespace Attica +{ +class PostFileDataPrivate; + +class PostFileData +{ +public: + /** + * Prepare a QNetworkRequest and QByteArray for sending a HTTP POST. + * Parameters and files can be added with addArgument() and addFile() + * Do not add anything after calling request or data for the first time. + */ + PostFileData(const QUrl &url); + ~PostFileData(); + + void addArgument(const QString &key, const QString &value); + void addFile(const QString &fileName, QIODevice *file, const QString &mimeType); + void addFile(const QString &fileName, const QByteArray &file, const QString &mimeType, const QString &fieldName = QStringLiteral("localfile")); + + QNetworkRequest request(); + QByteArray data(); + +private: + void finish(); + QString randomString(int length); + std::unique_ptr d; + Q_DISABLE_COPY(PostFileData) +}; + +} + +#endif // POSTFILEDATA_H diff --git a/local/recipes/kde/kf6-attica/source/src/postjob.cpp b/local/recipes/kde/kf6-attica/source/src/postjob.cpp new file mode 100644 index 00000000..0f0b6a26 --- /dev/null +++ b/local/recipes/kde/kf6-attica/source/src/postjob.cpp @@ -0,0 +1,109 @@ +/* + This file is part of KDE. + + SPDX-FileCopyrightText: 2008 Cornelius Schumacher + + SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL +*/ + +#include "postjob.h" + +#include +#include + +#include + +#include "platformdependent.h" + +using namespace Attica; + +PostJob::PostJob(PlatformDependent *internals, const QNetworkRequest &request, QIODevice *iodevice) + : BaseJob(internals) + , m_ioDevice(iodevice) + , m_request(request) +{ +} + +Attica::PostJob::PostJob(PlatformDependent *internals, const QNetworkRequest &request, const QByteArray &byteArray) + : BaseJob(internals) + , m_ioDevice(nullptr) + , m_byteArray(byteArray) + , m_request(request) +{ +} + +PostJob::PostJob(PlatformDependent *internals, const QNetworkRequest &request, const StringMap ¶meters) + : BaseJob(internals) + , m_ioDevice(nullptr) + , m_request(request) +{ + // Create post data + int j = 0; + for (StringMap::const_iterator i = parameters.begin(); i != parameters.end(); ++i) { + if (j++ > 0) { + m_byteArray.append('&'); + } + m_byteArray.append(QUrl::toPercentEncoding(i.key())); + m_byteArray.append('='); + m_byteArray.append(QUrl::toPercentEncoding(i.value())); + } +} + +QNetworkReply *PostJob::executeRequest() +{ + if (m_ioDevice) { + return internals()->post(m_request, m_ioDevice); + } else { + return internals()->post(m_request, m_byteArray); + } +} + +void PostJob::parse(const QString &xmlString) +{ + // qCDebug(ATTICA) << "PostJob::parse" << xmlString; + QXmlStreamReader xml(xmlString); + Metadata data; + while (!xml.atEnd()) { + xml.readNext(); + + if (xml.isStartElement()) { + if (xml.name() == QLatin1String("meta")) { + while (!xml.atEnd()) { + xml.readNext(); + if (xml.isEndElement() && xml.name() == QLatin1String("meta")) { + break; + } else if (xml.isStartElement()) { + if (xml.name() == QLatin1String("status")) { + data.setStatusString(xml.readElementText()); + } else if (xml.name() == QLatin1String("statuscode")) { + data.setStatusCode(xml.readElementText().toInt()); + } else if (xml.name() == QLatin1String("message")) { + data.setMessage(xml.readElementText()); + } else if (xml.name() == QLatin1String("totalitems")) { + data.setTotalItems(xml.readElementText().toInt()); + } else if (xml.name() == QLatin1String("itemsperpage")) { + data.setItemsPerPage(xml.readElementText().toInt()); + } + } + } + } else if (xml.name() == QLatin1String("data")) { + while (!xml.atEnd()) { + xml.readNext(); + if (xml.isEndElement() && xml.name() == QLatin1String("data")) { + break; + } else if (xml.isStartElement()) { + if (xml.name() == QLatin1String("projectid")) { + data.setResultingId(xml.readElementText()); + } + if (xml.name() == QLatin1String("buildjobid")) { + data.setResultingId(xml.readElementText()); + } + } + } + } + } + } + setMetadata(data); +} + +#include "moc_postjob.cpp" diff --git a/local/recipes/kde/kf6-attica/source/src/postjob.h b/local/recipes/kde/kf6-attica/source/src/postjob.h new file mode 100644 index 00000000..dd5f3ffb --- /dev/null +++ b/local/recipes/kde/kf6-attica/source/src/postjob.h @@ -0,0 +1,56 @@ +/* + This file is part of KDE. + + SPDX-FileCopyrightText: 2008 Cornelius Schumacher + + SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL + */ + +#ifndef ATTICA_POSTJOB_H +#define ATTICA_POSTJOB_H + +#include + +#include "attica_export.h" +#include "atticabasejob.h" + +// workaround to get initialization working with gcc < 4.4 +typedef QMap StringMap; + +namespace Attica +{ +class Provider; + +/** + * @class PostJob postjob.h + * + * Represents a post job. + */ +class ATTICA_EXPORT PostJob : public BaseJob +{ + Q_OBJECT + +protected: + PostJob(PlatformDependent *internals, const QNetworkRequest &request, QIODevice *data); + PostJob(PlatformDependent *internals, const QNetworkRequest &request, const StringMap ¶meters = StringMap()); + PostJob(PlatformDependent *internals, const QNetworkRequest &request, const QByteArray &byteArray); + +private: + QNetworkReply *executeRequest() override; + void parse(const QString &) override; + + QIODevice *m_ioDevice; + QByteArray m_byteArray; + + QString m_responseData; + const QNetworkRequest m_request; + + QString m_status; + QString m_statusMessage; + + friend class Attica::Provider; +}; + +} + +#endif diff --git a/local/recipes/kde/kf6-attica/source/src/privatedata.cpp b/local/recipes/kde/kf6-attica/source/src/privatedata.cpp new file mode 100644 index 00000000..3de3b6ae --- /dev/null +++ b/local/recipes/kde/kf6-attica/source/src/privatedata.cpp @@ -0,0 +1,73 @@ +/* + This file is part of KDE. + + SPDX-FileCopyrightText: Martin Sandsmark + + SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL +*/ + +#include "privatedata.h" + +#include + +using namespace Attica; + +class Q_DECL_HIDDEN PrivateData::Private : public QSharedData +{ +public: + QMap m_attributes; + QMap m_attributesTimestamp; + + Provider *m_provider; + + Private() + : m_provider(nullptr) + { + } +}; + +PrivateData::PrivateData() + : d(new Private) +{ +} + +PrivateData::PrivateData(const PrivateData &other) + : d(other.d) +{ +} + +PrivateData &PrivateData::operator=(const Attica::PrivateData &other) +{ + d = other.d; + return *this; +} + +PrivateData::~PrivateData() +{ +} + +void PrivateData::setAttribute(const QString &key, const QString &value) +{ + d->m_attributes[key] = value; + d->m_attributesTimestamp[key] = QDateTime::currentDateTime(); +} + +QString PrivateData::attribute(const QString &key) const +{ + return d->m_attributes[key]; +} + +QDateTime PrivateData::timestamp(const QString &key) const +{ + return d->m_attributesTimestamp[key]; +} + +QStringList PrivateData::keys() const +{ + return d->m_attributes.keys(); +} + +void PrivateData::setTimestamp(const QString &key, const QDateTime &when) +{ + d->m_attributesTimestamp[key] = when; +} diff --git a/local/recipes/kde/kf6-attica/source/src/privatedata.h b/local/recipes/kde/kf6-attica/source/src/privatedata.h new file mode 100644 index 00000000..b6f92322 --- /dev/null +++ b/local/recipes/kde/kf6-attica/source/src/privatedata.h @@ -0,0 +1,73 @@ +/* + This file is part of KDE. + + SPDX-FileCopyrightText: 2010 Martin Sandsmark + + SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL +*/ +#ifndef ATTICA_PRIVATEDATA_H +#define ATTICA_PRIVATEDATA_H + +#include "provider.h" + +#include +#include +#include +#include +#include + +#include "attica_export.h" + +namespace Attica +{ + +/** + * @class PrivateData privatedata.h + * + * Represents private data. + */ +class ATTICA_EXPORT PrivateData +{ +public: + class Parser; + + typedef QList List; // nonsense + + PrivateData(); + PrivateData(const PrivateData &other); + PrivateData &operator=(const PrivateData &other); + ~PrivateData(); + + /** + * Sets an attribute referenced by \key to \value. + */ + void setAttribute(const QString &key, const QString &value); + + /** + * Returns an attribute referenced by \key. + */ + QString attribute(const QString &key) const; + + /** + * Sets when an attribute last was changed (mostly for internal use). + */ + void setTimestamp(const QString &key, const QDateTime &when); + + /** + * Returns the date and time an attribute last was changed. + */ + QDateTime timestamp(const QString &key) const; + + /** + * Returns a list of fetched keys. + */ + QStringList keys() const; + +private: + class Private; + QSharedDataPointer d; +}; + +} + +#endif // ATTICA_ATTRIBUTES_H diff --git a/local/recipes/kde/kf6-attica/source/src/privatedataparser.cpp b/local/recipes/kde/kf6-attica/source/src/privatedataparser.cpp new file mode 100644 index 00000000..dcfe5f06 --- /dev/null +++ b/local/recipes/kde/kf6-attica/source/src/privatedataparser.cpp @@ -0,0 +1,41 @@ +/* + This file is part of KDE. + + SPDX-FileCopyrightText: 2008 Cornelius Schumacher + + SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL +*/ + +#include "privatedataparser.h" + +using namespace Attica; + +PrivateData PrivateData::Parser::parseXml(QXmlStreamReader &xml) +{ + PrivateData data; + QString key; + + // TODO: when we get internet and some documentation + while (!xml.atEnd()) { + xml.readNext(); + + if (xml.isStartElement()) { + if (xml.name() == QLatin1String("key")) { + key = xml.readElementText(); + } else if (xml.name() == QLatin1String("value")) { + data.setAttribute(key, xml.readElementText()); + } else if (xml.name() == QLatin1String("timestamp")) { + data.setTimestamp(key, QDateTime::fromString(xml.readElementText(), Qt::ISODate)); + } + } else if (xml.isEndElement() && (xml.name() == QLatin1String("data") || xml.name() == QLatin1String("user"))) { + break; + } + } + + return data; +} + +QStringList PrivateData::Parser::xmlElement() const +{ + return QStringList(QStringLiteral("privatedata")); +} diff --git a/local/recipes/kde/kf6-attica/source/src/privatedataparser.h b/local/recipes/kde/kf6-attica/source/src/privatedataparser.h new file mode 100644 index 00000000..7c18f825 --- /dev/null +++ b/local/recipes/kde/kf6-attica/source/src/privatedataparser.h @@ -0,0 +1,26 @@ +/* + This file is part of KDE. + + SPDX-FileCopyrightText: 2008 Cornelius Schumacher + + SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL +*/ + +#ifndef ATTICA_PRIVATEDATAPARSER_H +#define ATTICA_PRIVATEDATAPARSER_H + +#include "parser.h" +#include "privatedata.h" + +namespace Attica +{ +class Q_DECL_HIDDEN PrivateData::Parser : public Attica::Parser +{ +private: + PrivateData parseXml(QXmlStreamReader &xml) override; + QStringList xmlElement() const override; +}; + +} + +#endif diff --git a/local/recipes/kde/kf6-attica/source/src/project.cpp b/local/recipes/kde/kf6-attica/source/src/project.cpp new file mode 100644 index 00000000..9008c73b --- /dev/null +++ b/local/recipes/kde/kf6-attica/source/src/project.cpp @@ -0,0 +1,172 @@ +/* + This file is part of KDE. + + SPDX-FileCopyrightText: 2010 Sebastian Kügler + + SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL +*/ + +#include "project.h" + +using namespace Attica; + +class Q_DECL_HIDDEN Project::Private : public QSharedData +{ +public: + QString m_id; + QString m_name; + QString m_version; + QString m_license; + QString m_url; + QString m_summary; + QString m_description; + QStringList m_developers; + QString m_requirements; + QString m_specFile; + + QMap m_extendedAttributes; + + Private() + { + } +}; + +Project::Project() + : d(new Private) +{ +} + +Project::Project(const Project &other) + : d(other.d) +{ +} + +Project &Project::operator=(const Attica::Project &other) +{ + d = other.d; + return *this; +} + +Project::~Project() +{ +} + +void Project::setId(const QString &u) +{ + d->m_id = u; +} + +QString Project::id() const +{ + return d->m_id; +} + +void Project::setName(const QString &name) +{ + d->m_name = name; +} + +QString Project::name() const +{ + return d->m_name; +} + +void Project::setVersion(const QString &name) +{ + d->m_version = name; +} + +QString Project::version() const +{ + return d->m_version; +} + +void Project::setLicense(const QString &name) +{ + d->m_license = name; +} + +QString Project::license() const +{ + return d->m_license; +} + +void Project::setUrl(const QString &name) +{ + d->m_url = name; +} + +QString Project::url() const +{ + return d->m_url; +} + +void Project::setSummary(const QString &name) +{ + d->m_summary = name; +} + +QString Project::summary() const +{ + return d->m_summary; +} + +void Project::setDescription(const QString &name) +{ + d->m_description = name; +} + +QString Project::description() const +{ + return d->m_description; +} + +void Project::setDevelopers(const QStringList &name) +{ + d->m_developers = name; +} + +QStringList Project::developers() const +{ + return d->m_developers; +} + +void Project::setRequirements(const QString &name) +{ + d->m_requirements = name; +} + +QString Project::requirements() const +{ + return d->m_requirements; +} + +void Project::setSpecFile(const QString &name) +{ + d->m_specFile = name; +} + +QString Project::specFile() const +{ + return d->m_specFile; +} + +void Project::addExtendedAttribute(const QString &key, const QString &value) +{ + d->m_extendedAttributes.insert(key, value); +} + +QString Project::extendedAttribute(const QString &key) const +{ + return d->m_extendedAttributes.value(key); +} + +QMap Project::extendedAttributes() const +{ + return d->m_extendedAttributes; +} + +bool Project::isValid() const +{ + return !(d->m_id.isEmpty()); +} diff --git a/local/recipes/kde/kf6-attica/source/src/project.h b/local/recipes/kde/kf6-attica/source/src/project.h new file mode 100644 index 00000000..acc880ba --- /dev/null +++ b/local/recipes/kde/kf6-attica/source/src/project.h @@ -0,0 +1,84 @@ +/* + This file is part of KDE. + + SPDX-FileCopyrightText: 2010 Sebastian Kügler + + SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL +*/ + +#ifndef ATTICA_PROJECT_H +#define ATTICA_PROJECT_H + +#include +#include +#include +#include +#include +#include + +#include "attica_export.h" + +namespace Attica +{ + +/** + * @class Project project.h + * + * Represents a project. + */ +class ATTICA_EXPORT Project +{ +public: + typedef QList List; + class Parser; + + Project(); + Project(const Project &other); + Project &operator=(const Project &other); + ~Project(); + + void setId(const QString &); + QString id() const; + + void setName(const QString &); + QString name() const; + + void setVersion(const QString &); + QString version() const; + + void setUrl(const QString &); + QString url() const; + + void setLicense(const QString &); + QString license() const; + + void setSummary(const QString &); + QString summary() const; + + void setDescription(const QString &); + QString description() const; + + void setDevelopers(const QStringList &); + QStringList developers() const; + + void setRequirements(const QString &); + QString requirements() const; + + void setSpecFile(const QString &); + QString specFile() const; + + void addExtendedAttribute(const QString &key, const QString &value); + QString extendedAttribute(const QString &key) const; + + QMap extendedAttributes() const; + + bool isValid() const; + +private: + class Private; + QSharedDataPointer d; +}; + +} + +#endif diff --git a/local/recipes/kde/kf6-attica/source/src/projectparser.cpp b/local/recipes/kde/kf6-attica/source/src/projectparser.cpp new file mode 100644 index 00000000..d7992b2d --- /dev/null +++ b/local/recipes/kde/kf6-attica/source/src/projectparser.cpp @@ -0,0 +1,62 @@ +/* + This file is part of KDE. + + SPDX-FileCopyrightText: 2010 Sebastian Kügler + + SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL +*/ + +#include "projectparser.h" +#include + +using namespace Attica; + +Project Project::Parser::parseXml(QXmlStreamReader &xml) +{ + Project project; + + // For specs about the XML provided, see here: + // http://www.freedesktop.org/wiki/Specifications/open-collaboration-services-draft#Projects + while (!xml.atEnd()) { + // qCDebug(ATTICA) << "XML returned:" << xml.text().toString(); + xml.readNext(); + + if (xml.isStartElement()) { + if (xml.name() == QLatin1String("projectid")) { + project.setId(xml.readElementText()); + } else if (xml.name() == QLatin1String("name")) { + project.setName(xml.readElementText()); + } else if (xml.name() == QLatin1String("version")) { + project.setVersion(xml.readElementText()); + } else if (xml.name() == QLatin1String("license")) { + project.setLicense(xml.readElementText()); + } else if (xml.name() == QLatin1String("url")) { + project.setUrl(xml.readElementText()); + } else if (xml.name() == QLatin1String("summary")) { + project.setSummary(xml.readElementText()); + } else if (xml.name() == QLatin1String("description")) { + project.setDescription(xml.readElementText()); + } else if (xml.name() == QLatin1String("specfile")) { + project.setSpecFile(xml.readElementText()); + } else if (xml.name() == QLatin1String("developers")) { + project.setDevelopers(xml.readElementText().split(QLatin1Char('\n'))); + } else if (xml.name() == QLatin1String("projectlist")) { + QXmlStreamReader list_xml(xml.readElementText()); + while (!list_xml.atEnd()) { + list_xml.readNext(); + if (xml.name() == QLatin1String("projectid")) { + project.setSpecFile(xml.readElementText()); + } + } + } + } else if (xml.isEndElement() && (xml.name() == QLatin1String("project") || xml.name() == QLatin1String("user"))) { + break; + } + } + return project; +} + +QStringList Project::Parser::xmlElement() const +{ + return QStringList(QStringLiteral("project")) << QStringLiteral("user"); +} diff --git a/local/recipes/kde/kf6-attica/source/src/projectparser.h b/local/recipes/kde/kf6-attica/source/src/projectparser.h new file mode 100644 index 00000000..f60c3a43 --- /dev/null +++ b/local/recipes/kde/kf6-attica/source/src/projectparser.h @@ -0,0 +1,26 @@ +/* + This file is part of KDE. + + SPDX-FileCopyrightText: 2010 Sebastian Kügler + + SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL +*/ + +#ifndef ATTICA_PROJECTPARSER_H +#define ATTICA_PROJECTPARSER_H + +#include "parser.h" +#include "project.h" + +namespace Attica +{ +class Q_DECL_HIDDEN Project::Parser : public Attica::Parser +{ +private: + Project parseXml(QXmlStreamReader &xml) override; + QStringList xmlElement() const override; +}; + +} + +#endif diff --git a/local/recipes/kde/kf6-attica/source/src/provider.cpp b/local/recipes/kde/kf6-attica/source/src/provider.cpp new file mode 100644 index 00000000..ed67a0d9 --- /dev/null +++ b/local/recipes/kde/kf6-attica/source/src/provider.cpp @@ -0,0 +1,1858 @@ +/* + This file is part of KDE. + + SPDX-FileCopyrightText: 2008 Cornelius Schumacher + SPDX-FileCopyrightText: 2010 Sebastian Kügler + SPDX-FileCopyrightText: 2011 Laszlo Papp + + SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL +*/ + +#include "provider.h" + +#include "accountbalance.h" +#include "accountbalanceparser.h" +#include "achievementparser.h" +#include "activity.h" +#include "activityparser.h" +#include "buildservice.h" +#include "buildservicejob.h" +#include "buildservicejoboutput.h" +#include "buildservicejoboutputparser.h" +#include "buildservicejobparser.h" +#include "buildserviceparser.h" +#include "categoryparser.h" +#include "commentparser.h" +#include "config.h" +#include "content.h" +#include "contentparser.h" +#include "distributionparser.h" +#include "downloaditem.h" +#include "downloaditemparser.h" +#include "event.h" +#include "eventparser.h" +#include "folder.h" +#include "folderparser.h" +#include "forumparser.h" +#include "homepagetype.h" +#include "homepagetypeparser.h" +#include "knowledgebaseentry.h" +#include "knowledgebaseentryparser.h" +#include "licenseparser.h" +#include "messageparser.h" +#include "person.h" +#include "personparser.h" +#include "platformdependent_v2.h" +#include "postfiledata.h" +#include "postjob.h" +#include "privatedata.h" +#include "privatedataparser.h" +#include "project.h" +#include "projectparser.h" +#include "publisher.h" +#include "publisherfield.h" +#include "publisherfieldparser.h" +#include "publisherparser.h" +#include "remoteaccount.h" +#include "remoteaccountparser.h" +#include "topic.h" +#include "topicparser.h" +#include "version.h" + +#include +#include +#include +#include +#include +#include +#include + +using namespace Attica; + +class Q_DECL_HIDDEN Provider::Private : public QSharedData +{ +public: + QUrl m_baseUrl; + QUrl m_icon; + QString m_name; + QString m_credentialsUserName; + QString m_credentialsPassword; + QString m_personVersion; + QString m_friendVersion; + QString m_messageVersion; + QString m_achievementVersion; + QString m_activityVersion; + QString m_contentVersion; + QString m_fanVersion; + QString m_forumVersion; + QString m_knowledgebaseVersion; + QString m_eventVersion; + QString m_commentVersion; + QString m_registerUrl; + PlatformDependent *m_internals; + QString m_additionalAgentInformation; + + Private() + : m_internals(nullptr) + { + } + + Private(const Private &other) + : QSharedData(other) + , m_baseUrl(other.m_baseUrl) + , m_name(other.m_name) + , m_credentialsUserName(other.m_credentialsUserName) + , m_credentialsPassword(other.m_credentialsPassword) + , m_personVersion(other.m_personVersion) + , m_friendVersion(other.m_friendVersion) + , m_messageVersion(other.m_messageVersion) + , m_achievementVersion(other.m_achievementVersion) + , m_activityVersion(other.m_activityVersion) + , m_contentVersion(other.m_contentVersion) + , m_fanVersion(other.m_fanVersion) + , m_forumVersion(other.m_forumVersion) + , m_knowledgebaseVersion(other.m_knowledgebaseVersion) + , m_eventVersion(other.m_eventVersion) + , m_commentVersion(other.m_commentVersion) + , m_registerUrl(other.m_registerUrl) + , m_internals(other.m_internals) + , m_additionalAgentInformation(other.m_additionalAgentInformation) + { + } + + Private(PlatformDependent *internals, + const QUrl &baseUrl, + const QString &name, + const QUrl &icon, + const QString &person, + const QString &friendV, + const QString &message, + const QString &achievement, + const QString &activity, + const QString &content, + const QString &fan, + const QString &forum, + const QString &knowledgebase, + const QString &event, + const QString &comment, + const QString ®isterUrl, + const QString &additionalAgentInformation) + : m_baseUrl(baseUrl) + , m_icon(icon) + , m_name(name) + , m_personVersion(person) + , m_friendVersion(friendV) + , m_messageVersion(message) + , m_achievementVersion(achievement) + , m_activityVersion(activity) + , m_contentVersion(content) + , m_fanVersion(fan) + , m_forumVersion(forum) + , m_knowledgebaseVersion(knowledgebase) + , m_eventVersion(event) + , m_commentVersion(comment) + , m_registerUrl(registerUrl) + , m_internals(internals) + , m_additionalAgentInformation(additionalAgentInformation) + { + if (m_baseUrl.isEmpty()) { + return; + } + QString user; + QString pass; + if (m_internals->hasCredentials(m_baseUrl) && m_internals->loadCredentials(m_baseUrl, user, pass)) { + m_credentialsUserName = user; + m_credentialsPassword = pass; + } + } + + ~Private() + { + } +}; + +Provider::Provider() + : d(new Private) +{ +} + +Provider::Provider(const Provider &other) + : d(other.d) +{ +} + +Provider::Provider(PlatformDependent *internals, + const QUrl &baseUrl, + const QString &name, + const QUrl &icon, + const QString &person, + const QString &friendV, + const QString &message, + const QString &achievement, + const QString &activity, + const QString &content, + const QString &fan, + const QString &forum, + const QString &knowledgebase, + const QString &event, + const QString &comment) + : d(new Private(internals, + baseUrl, + name, + icon, + person, + friendV, + message, + achievement, + activity, + content, + fan, + forum, + knowledgebase, + event, + comment, + QString(), + QString())) +{ +} + +Provider::Provider(PlatformDependent *internals, + const QUrl &baseUrl, + const QString &name, + const QUrl &icon, + const QString &person, + const QString &friendV, + const QString &message, + const QString &achievement, + const QString &activity, + const QString &content, + const QString &fan, + const QString &forum, + const QString &knowledgebase, + const QString &event, + const QString &comment, + const QString ®isterUrl) + : d(new Private(internals, + baseUrl, + name, + icon, + person, + friendV, + message, + achievement, + activity, + content, + fan, + forum, + knowledgebase, + event, + comment, + registerUrl, + QString())) +{ +} + +Provider::Provider(PlatformDependent *internals, + const QUrl &baseUrl, + const QString &name, + const QUrl &icon, + const QString &person, + const QString &friendV, + const QString &message, + const QString &achievement, + const QString &activity, + const QString &content, + const QString &fan, + const QString &forum, + const QString &knowledgebase, + const QString &event, + const QString &comment, + const QString ®isterUrl, + const QString &additionalAgentInformation) + : d(new Private(internals, + baseUrl, + name, + icon, + person, + friendV, + message, + achievement, + activity, + content, + fan, + forum, + knowledgebase, + event, + comment, + registerUrl, + additionalAgentInformation)) +{ +} + +Provider &Provider::operator=(const Attica::Provider &other) +{ + d = other.d; + return *this; +} + +Provider::~Provider() +{ +} + +QUrl Provider::baseUrl() const +{ + return d->m_baseUrl; +} + +bool Provider::isValid() const +{ + return d->m_baseUrl.isValid(); +} + +bool Provider::isEnabled() const +{ + if (!isValid()) { + return false; + } + + return d->m_internals->isEnabled(d->m_baseUrl); +} + +void Provider::setEnabled(bool enabled) +{ + if (!isValid()) { + return; + } + + d->m_internals->enableProvider(d->m_baseUrl, enabled); +} + +void Provider::setAdditionalAgentInformation(const QString &additionalInformation) +{ + d->m_additionalAgentInformation = additionalInformation; +} + +QString Provider::additionalAgentInformation() const +{ + return d->m_additionalAgentInformation; +} + +QString Provider::name() const +{ + return d->m_name; +} + +QUrl Attica::Provider::icon() const +{ + return d->m_icon; +} + +bool Provider::hasCredentials() +{ + if (!isValid()) { + return false; + } + + return d->m_internals->hasCredentials(d->m_baseUrl); +} + +bool Provider::hasCredentials() const +{ + if (!isValid()) { + return false; + } + + return d->m_internals->hasCredentials(d->m_baseUrl); +} + +bool Provider::loadCredentials(QString &user, QString &password) +{ + if (!isValid()) { + return false; + } + + if (d->m_internals->loadCredentials(d->m_baseUrl, user, password)) { + d->m_credentialsUserName = user; + d->m_credentialsPassword = password; + return true; + } + return false; +} + +bool Provider::saveCredentials(const QString &user, const QString &password) +{ + if (!isValid()) { + return false; + } + + d->m_credentialsUserName = user; + d->m_credentialsPassword = password; + return d->m_internals->saveCredentials(d->m_baseUrl, user, password); +} + +PostJob *Provider::checkLogin(const QString &user, const QString &password) +{ + if (!isValid()) { + return nullptr; + } + + QMap postParameters; + + postParameters.insert(QLatin1String("login"), user); + postParameters.insert(QLatin1String("password"), password); + + return new PostJob(d->m_internals, createRequest(QLatin1String("person/check")), postParameters); +} + +ItemJob *Provider::requestConfig() +{ + if (!isValid()) { + return nullptr; + } + + QUrl url = createUrl(QLatin1String("config")); + return doRequestConfig(url); +} + +PostJob *Provider::registerAccount(const QString &id, const QString &password, const QString &mail, const QString &firstName, const QString &lastName) +{ + if (!isValid()) { + return nullptr; + } + + QMap postParameters; + + postParameters.insert(QLatin1String("login"), id); + postParameters.insert(QLatin1String("password"), password); + postParameters.insert(QLatin1String("firstname"), firstName); + postParameters.insert(QLatin1String("lastname"), lastName); + postParameters.insert(QLatin1String("email"), mail); + + return new PostJob(d->m_internals, createRequest(QLatin1String("person/add")), postParameters); +} + +const QString &Provider::getRegisterAccountUrl() const +{ + return d->m_registerUrl; +} + +ItemJob *Provider::requestPerson(const QString &id) +{ + if (!isValid()) { + return nullptr; + } + + QUrl url = createUrl(QLatin1String("person/data/") + id); + return doRequestPerson(url); +} + +ItemJob *Provider::requestPersonSelf() +{ + if (!isValid()) { + return nullptr; + } + + QUrl url = createUrl(QLatin1String("person/self")); + return doRequestPerson(url); +} + +ItemJob *Provider::requestAccountBalance() +{ + if (!isValid()) { + return nullptr; + } + + QUrl url = createUrl(QLatin1String("person/balance")); + return doRequestAccountBalance(url); +} + +ListJob *Provider::requestPersonSearchByName(const QString &name) +{ + if (!isValid()) { + return nullptr; + } + + QUrl url = createUrl(QStringLiteral("person/data")); + QUrlQuery q(url); + q.addQueryItem(QStringLiteral("name"), name); + url.setQuery(q); + return doRequestPersonList(url); +} + +ListJob *Provider::requestPersonSearchByLocation(qreal latitude, qreal longitude, qreal distance, int page, int pageSize) +{ + if (!isValid()) { + return nullptr; + } + + QUrl url = createUrl(QStringLiteral("person/data")); + QUrlQuery q(url); + q.addQueryItem(QStringLiteral("latitude"), QString::number(latitude)); + q.addQueryItem(QStringLiteral("longitude"), QString::number(longitude)); + if (distance > 0.0) { + q.addQueryItem(QStringLiteral("distance"), QString::number(distance)); + } + q.addQueryItem(QStringLiteral("page"), QString::number(page)); + q.addQueryItem(QStringLiteral("pagesize"), QString::number(pageSize)); + url.setQuery(q); + + return doRequestPersonList(url); +} + +ListJob *Provider::requestFriends(const QString &id, int page, int pageSize) +{ + if (!isValid()) { + return nullptr; + } + + QUrl url = createUrl(QLatin1String("friend/data/") + id); + QUrlQuery q(url); + q.addQueryItem(QLatin1String("page"), QString::number(page)); + q.addQueryItem(QLatin1String("pagesize"), QString::number(pageSize)); + url.setQuery(q); + + return doRequestPersonList(url); +} + +ListJob *Provider::requestSentInvitations(int page, int pageSize) +{ + if (!isValid()) { + return nullptr; + } + + QUrl url = createUrl(QStringLiteral("friend/sentinvitations")); + QUrlQuery q(url); + q.addQueryItem(QStringLiteral("page"), QString::number(page)); + q.addQueryItem(QStringLiteral("pagesize"), QString::number(pageSize)); + url.setQuery(q); + + return doRequestPersonList(url); +} + +ListJob *Provider::requestReceivedInvitations(int page, int pageSize) +{ + if (!isValid()) { + return nullptr; + } + + QUrl url = createUrl(QStringLiteral("friend/receivedinvitations")); + QUrlQuery q(url); + q.addQueryItem(QStringLiteral("page"), QString::number(page)); + q.addQueryItem(QStringLiteral("pagesize"), QString::number(pageSize)); + url.setQuery(q); + + return doRequestPersonList(url); +} + +ListJob *Provider::requestAchievements(const QString &contentId, const QString &achievementId, const QString &userId) +{ + if (!isValid()) { + return nullptr; + } + + QUrl url = createUrl(QLatin1String("achievements/content/") + contentId + achievementId); + QUrlQuery q(url); + q.addQueryItem(QStringLiteral("user_id"), userId); + url.setQuery(q); + return doRequestAchievementList(url); +} + +ItemPostJob *Provider::addNewAchievement(const QString &contentId, const Achievement &newAchievement) +{ + if (!isValid()) { + return nullptr; + } + + StringMap postParameters; + int i = 0; + int j = 0; + + postParameters.insert(QLatin1String("name"), newAchievement.name()); + postParameters.insert(QLatin1String("description"), newAchievement.description()); + postParameters.insert(QLatin1String("explanation"), newAchievement.explanation()); + postParameters.insert(QLatin1String("points"), QString::number(newAchievement.points())); + postParameters.insert(QLatin1String("image"), newAchievement.image().toLocalFile()); + const auto dependenciesList = newAchievement.dependencies(); + for (const QString &dependency : dependenciesList) { + postParameters.insert(QString::fromLatin1("dependencies[%1]").arg(QString::number(i++)), dependency); + } + + postParameters.insert(QLatin1String("type"), Achievement::achievementTypeToString(newAchievement.type())); + const auto optionsList = newAchievement.options(); + for (const QString &option : optionsList) { + postParameters.insert(QString::fromLatin1("options[%1]").arg(QString::number(j++)), option); + } + + postParameters.insert(QLatin1String("steps"), QString::number(newAchievement.steps())); + postParameters.insert(QLatin1String("visibility"), Achievement::achievementVisibilityToString(newAchievement.visibility())); + + return new ItemPostJob(d->m_internals, createRequest(QLatin1String("achievements/content/") + contentId), postParameters); +} + +PutJob *Provider::editAchievement(const QString &contentId, const QString &achievementId, const Achievement &achievement) +{ + if (!isValid()) { + return nullptr; + } + + if (!dynamic_cast(d->m_internals)) { + return nullptr; + } + + StringMap postParameters; + int i = 0; + int j = 0; + + postParameters.insert(QLatin1String("name"), achievement.name()); + postParameters.insert(QLatin1String("description"), achievement.description()); + postParameters.insert(QLatin1String("explanation"), achievement.explanation()); + postParameters.insert(QLatin1String("points"), QString::number(achievement.points())); + postParameters.insert(QLatin1String("image"), achievement.image().toLocalFile()); + const auto dependenciesList = achievement.dependencies(); + for (const QString &dependency : dependenciesList) { + postParameters.insert(QString::fromLatin1("dependencies[%1]").arg(QString::number(i++)), dependency); + } + + postParameters.insert(QLatin1String("type"), Achievement::achievementTypeToString(achievement.type())); + const auto optionsList = achievement.options(); + for (const QString &option : optionsList) { + postParameters.insert(QString::fromLatin1("options[%1]").arg(QString::number(j++)), option); + } + + postParameters.insert(QLatin1String("steps"), QString::number(achievement.steps())); + postParameters.insert(QLatin1String("visibility"), Achievement::achievementVisibilityToString(achievement.visibility())); + + return new ItemPutJob(d->m_internals, createRequest(QLatin1String("achievement/content/") + contentId + achievementId), postParameters); +} + +DeleteJob *Provider::deleteAchievement(const QString &contentId, const QString &achievementId) +{ + if (!isValid()) { + return nullptr; + } + + if (!dynamic_cast(d->m_internals)) { + return nullptr; + } + + return new ItemDeleteJob(d->m_internals, createRequest(QLatin1String("achievements/progress/") + contentId + achievementId)); +} + +PostJob *Provider::setAchievementProgress(const QString &id, const QVariant &progress, const QDateTime ×tamp) +{ + if (!isValid()) { + return nullptr; + } + + StringMap postParameters; + + postParameters.insert(QLatin1String("progress"), progress.toString()); + postParameters.insert(QLatin1String("timestamp"), timestamp.toString()); + + return new ItemPostJob(d->m_internals, createRequest(QLatin1String("achievements/progress/") + id), postParameters); +} + +DeleteJob *Provider::resetAchievementProgress(const QString &id) +{ + if (!isValid()) { + return nullptr; + } + + if (!dynamic_cast(d->m_internals)) { + return nullptr; + } + + return new ItemDeleteJob(d->m_internals, createRequest(QLatin1String("achievements/progress/") + id)); +} + +ListJob *Provider::requestActivities() +{ + if (!isValid()) { + return nullptr; + } + + // qCDebug(ATTICA) << "request activity"; + QUrl url = createUrl(QLatin1String("activity")); + return doRequestActivityList(url); +} + +ListJob *Provider::requestProjects() +{ + if (!isValid()) { + return nullptr; + } + + // qCDebug(ATTICA) << "request projects"; + QUrl url = createUrl(QLatin1String("buildservice/project/list")); + return new ListJob(d->m_internals, createRequest(url)); +} + +ItemJob *Provider::requestProject(const QString &id) +{ + if (!isValid()) { + return nullptr; + } + + QUrl url = createUrl(QLatin1String("buildservice/project/get/") + id); + // qCDebug(ATTICA) << url; + return new ItemJob(d->m_internals, createRequest(url)); +} + +QMap projectPostParameters(const Project &project) +{ + QMap postParameters; + + if (!project.name().isEmpty()) { + postParameters.insert(QLatin1String("name"), project.name()); + } + if (!project.summary().isEmpty()) { + postParameters.insert(QLatin1String("summary"), project.summary()); + } + if (!project.description().isEmpty()) { + postParameters.insert(QLatin1String("description"), project.description()); + } + if (!project.url().isEmpty()) { + postParameters.insert(QLatin1String("url"), project.url()); + } + if (!project.developers().isEmpty()) { + postParameters.insert(QLatin1String("developers"), project.developers().join(QLatin1Char('\n'))); + } + if (!project.version().isEmpty()) { + postParameters.insert(QLatin1String("version"), project.version()); + } + if (!project.license().isEmpty()) { + postParameters.insert(QLatin1String("license"), project.license()); + } + if (!project.requirements().isEmpty()) { + postParameters.insert(QLatin1String("requirements"), project.requirements()); + } + // The specfile generator expects an empty string parameter if it is supposed to regenerate the spec file + // So we need to check for nullity here as opposed to an empty string. + if (!project.specFile().isNull()) { + postParameters.insert(QLatin1String("specfile"), project.specFile()); + } + return postParameters; +} + +PostJob *Provider::createProject(const Project &project) +{ + if (!isValid()) { + return nullptr; + } + + return new PostJob(d->m_internals, createRequest(QLatin1String("buildservice/project/create")), projectPostParameters(project)); +} + +PostJob *Provider::editProject(const Project &project) +{ + if (!isValid()) { + return nullptr; + } + + return new PostJob(d->m_internals, createRequest(QLatin1String("buildservice/project/edit/") + project.id()), projectPostParameters(project)); +} + +PostJob *Provider::deleteProject(const Project &project) +{ + if (!isValid()) { + return nullptr; + } + + return new PostJob(d->m_internals, createRequest(QLatin1String("buildservice/project/delete/") + project.id()), projectPostParameters(project)); +} + +ItemJob *Provider::requestBuildService(const QString &id) +{ + if (!isValid()) { + return nullptr; + } + + QUrl url = createUrl(QLatin1String("buildservice/buildservices/get/") + id); + return new ItemJob(d->m_internals, createRequest(url)); +} + +ItemJob *Provider::requestPublisher(const QString &id) +{ + if (!isValid()) { + return nullptr; + } + + // qCDebug(ATTICA) << "request publisher" << id; + QUrl url = createUrl(QLatin1String("buildservice/publishing/getpublisher/") + id); + return new ItemJob(d->m_internals, createRequest(url)); +} + +PostJob *Provider::savePublisherField(const Project &project, const PublisherField &field) +{ + if (!isValid()) { + return nullptr; + } + + StringMap postParameters; + postParameters.insert(QLatin1String("fields[0][name]"), field.name()); + postParameters.insert(QLatin1String("fields[0][fieldtype]"), field.type()); + postParameters.insert(QLatin1String("fields[0][data]"), field.data()); + + QString url = QLatin1String("buildservice/publishing/savefields/") + project.id(); + // qCDebug(ATTICA) << "saving field values..."; + return new PostJob(d->m_internals, createRequest(url), postParameters); +} + +PostJob *Provider::publishBuildJob(const BuildServiceJob &buildjob, const Publisher &publisher) +{ + if (!isValid()) { + return nullptr; + } + + StringMap postParameters; + postParameters.insert(QLatin1String("dummyparameter"), QLatin1String("dummyvalue")); + + QString url = QLatin1String("buildservice/publishing/publishtargetresult/") + buildjob.id() + QLatin1Char('/') + publisher.id(); + // qCDebug(ATTICA) << "pub'ing"; + return new PostJob(d->m_internals, createRequest(url), postParameters); +} + +// Buildservices and their jobs +ItemJob *Provider::requestBuildServiceJobOutput(const QString &id) +{ + if (!isValid()) { + return nullptr; + } + + QUrl url = createUrl(QLatin1String("buildservice/jobs/getoutput/") + id); + // qCDebug(ATTICA) << url; + return new ItemJob(d->m_internals, createRequest(url)); +} + +ItemJob *Provider::requestBuildServiceJob(const QString &id) +{ + if (!isValid()) { + return nullptr; + } + + QUrl url = createUrl(QLatin1String("buildservice/jobs/get/") + id); + // qCDebug(ATTICA) << url; + return new ItemJob(d->m_internals, createRequest(url)); +} + +QMap buildServiceJobPostParameters(const BuildServiceJob &buildjob) +{ + QMap postParameters; + + if (!buildjob.name().isEmpty()) { + postParameters.insert(QLatin1String("name"), buildjob.name()); + } + if (!buildjob.projectId().isEmpty()) { + postParameters.insert(QLatin1String("projectid"), buildjob.projectId()); + } + if (!buildjob.target().isEmpty()) { + postParameters.insert(QLatin1String("target"), buildjob.target()); + } + if (!buildjob.buildServiceId().isEmpty()) { + postParameters.insert(QLatin1String("buildservice"), buildjob.buildServiceId()); + } + + return postParameters; +} + +PostJob *Provider::cancelBuildServiceJob(const BuildServiceJob &job) +{ + if (!isValid()) { + return nullptr; + } + + StringMap postParameters; + postParameters.insert(QLatin1String("dummyparameter"), QLatin1String("dummyvalue")); + // qCDebug(ATTICA) << "b....................b"; + return new PostJob(d->m_internals, createRequest(QLatin1String("buildservice/jobs/cancel/") + job.id()), postParameters); +} + +PostJob *Provider::createBuildServiceJob(const BuildServiceJob &job) +{ + if (!isValid()) { + return nullptr; + } + + StringMap postParameters; + // A postjob won't be run without parameters. + // so even while we don't need any in this case, + // we add dummy data to the request + postParameters.insert(QLatin1String("dummyparameter"), QLatin1String("dummyvalue")); + // qCDebug(ATTICA) << "Creating new BSJ on" << job.buildServiceId(); + return new PostJob( + d->m_internals, + createRequest(QLatin1String("buildservice/jobs/create/") + job.projectId() + QLatin1Char('/') + job.buildServiceId() + QLatin1Char('/') + job.target()), + postParameters); +} + +ListJob *Provider::requestBuildServices() +{ + if (!isValid()) { + return nullptr; + } + + // qCDebug(ATTICA) << "request projects"; + QUrl url = createUrl(QLatin1String("buildservice/buildservices/list")); + return new ListJob(d->m_internals, createRequest(url)); +} + +ListJob *Provider::requestPublishers() +{ + if (!isValid()) { + return nullptr; + } + + QUrl url = createUrl(QLatin1String("buildservice/publishing/getpublishingcapabilities")); + // qCDebug(ATTICA) << "request publishers" << url; + return new ListJob(d->m_internals, createRequest(url)); +} + +ListJob *Provider::requestBuildServiceJobs(const Project &project) +{ + if (!isValid()) { + return nullptr; + } + + // qCDebug(ATTICA) << "request projects"; + QUrl url = createUrl(QLatin1String("buildservice/jobs/list/") + project.id()); + return new ListJob(d->m_internals, createRequest(url)); +} + +ListJob *Provider::requestRemoteAccounts() +{ + if (!isValid()) { + return nullptr; + } + + // qCDebug(ATTICA) << "request remoteaccounts"; + QUrl url = createUrl(QLatin1String("buildservice/remoteaccounts/list/")); + return new ListJob(d->m_internals, createRequest(url)); +} + +PostJob *Provider::createRemoteAccount(const RemoteAccount &account) +{ + if (!isValid()) { + return nullptr; + } + + StringMap postParameters; + // A postjob won't be run without parameters. + // so even while we don't need any in this case, + // we add dummy data to the request + postParameters.insert(QLatin1String("login"), account.login()); + postParameters.insert(QLatin1String("password"), account.password()); + postParameters.insert(QLatin1String("type"), account.type()); + postParameters.insert(QLatin1String("typeid"), account.remoteServiceId()); // FIXME: remoteserviceid? + postParameters.insert(QLatin1String("data"), account.data()); + // qCDebug(ATTICA) << "Creating new Remoteaccount" << account.id() << account.login() << account.password(); + return new PostJob(d->m_internals, createRequest(QLatin1String("buildservice/remoteaccounts/add")), postParameters); +} + +PostJob *Provider::editRemoteAccount(const RemoteAccount &account) +{ + if (!isValid()) { + return nullptr; + } + + StringMap postParameters; + // A postjob won't be run without parameters. + // so even while we don't need any in this case, + // we add dummy data to the request + postParameters.insert(QLatin1String("login"), account.login()); + postParameters.insert(QLatin1String("password"), account.password()); + postParameters.insert(QLatin1String("type"), account.type()); + postParameters.insert(QLatin1String("typeid"), account.remoteServiceId()); // FIXME: remoteserviceid? + postParameters.insert(QLatin1String("data"), account.data()); + // qCDebug(ATTICA) << "Creating new Remoteaccount" << account.id() << account.login() << account.password(); + return new PostJob(d->m_internals, createRequest(QLatin1String("buildservice/remoteaccounts/edit/") + account.id()), postParameters); +} + +ItemJob *Provider::requestRemoteAccount(const QString &id) +{ + if (!isValid()) { + return nullptr; + } + + QUrl url = createUrl(QLatin1String("buildservice/remoteaccounts/get/") + id); + // qCDebug(ATTICA) << url; + return new ItemJob(d->m_internals, createRequest(url)); +} + +PostJob *Provider::deleteRemoteAccount(const QString &id) +{ + if (!isValid()) { + return nullptr; + } + + StringMap postParameters; + return new PostJob(d->m_internals, createRequest(QLatin1String("buildservice/remoteaccounts/remove/") + id), postParameters); +} + +PostJob *Provider::uploadTarballToBuildService(const QString &projectId, const QString &fileName, const QByteArray &payload) +{ + if (!isValid()) { + return nullptr; + } + + QUrl url = createUrl(QLatin1String("buildservice/project/uploadsource/") + projectId); + // qCDebug(ATTICA) << "Up'ing tarball" << url << projectId << fileName << payload; + PostFileData postRequest(url); + postRequest.addFile(fileName, payload, QLatin1String("application/octet-stream"), QLatin1String("source")); + return new PostJob(d->m_internals, postRequest.request(), postRequest.data()); +} + +// Activity + +PostJob *Provider::postActivity(const QString &message) +{ + if (!isValid()) { + return nullptr; + } + + StringMap postParameters; + postParameters.insert(QLatin1String("message"), message); + return new PostJob(d->m_internals, createRequest(QLatin1String("activity")), postParameters); +} + +PostJob *Provider::inviteFriend(const QString &to, const QString &message) +{ + if (!isValid()) { + return nullptr; + } + + StringMap postParameters; + postParameters.insert(QLatin1String("message"), message); + return new PostJob(d->m_internals, createRequest(QLatin1String("friend/invite/") + to), postParameters); +} + +PostJob *Provider::approveFriendship(const QString &to) +{ + if (!isValid()) { + return nullptr; + } + + return new PostJob(d->m_internals, createRequest(QLatin1String("friend/approve/") + to)); +} + +PostJob *Provider::declineFriendship(const QString &to) +{ + if (!isValid()) { + return nullptr; + } + + return new PostJob(d->m_internals, createRequest(QLatin1String("friend/decline/") + to)); +} + +PostJob *Provider::cancelFriendship(const QString &to) +{ + if (!isValid()) { + return nullptr; + } + + return new PostJob(d->m_internals, createRequest(QLatin1String("friend/cancel/") + to)); +} + +PostJob *Provider::postLocation(qreal latitude, qreal longitude, const QString &city, const QString &country) +{ + if (!isValid()) { + return nullptr; + } + + StringMap postParameters; + postParameters.insert(QLatin1String("latitude"), QString::number(latitude)); + postParameters.insert(QLatin1String("longitude"), QString::number(longitude)); + postParameters.insert(QLatin1String("city"), city); + postParameters.insert(QLatin1String("country"), country); + return new PostJob(d->m_internals, createRequest(QLatin1String("person/self")), postParameters); +} + +ListJob *Provider::requestFolders() +{ + if (!isValid()) { + return nullptr; + } + + return doRequestFolderList(createUrl(QLatin1String("message"))); +} + +ListJob *Provider::requestMessages(const Folder &folder) +{ + if (!isValid()) { + return nullptr; + } + + return doRequestMessageList(createUrl(QLatin1String("message/") + folder.id())); +} + +ListJob *Provider::requestMessages(const Folder &folder, Message::Status status) +{ + if (!isValid()) { + return nullptr; + } + + QUrl url = createUrl(QLatin1String("message/") + folder.id()); + QUrlQuery q(url); + q.addQueryItem(QStringLiteral("status"), QString::number(status)); + url.setQuery(q); + return doRequestMessageList(url); +} + +ItemJob *Provider::requestMessage(const Folder &folder, const QString &id) +{ + if (!isValid()) { + return nullptr; + } + + return new ItemJob(d->m_internals, createRequest(QLatin1String("message/") + folder.id() + QLatin1Char('/') + id)); +} + +PostJob *Provider::postMessage(const Message &message) +{ + if (!isValid()) { + return nullptr; + } + + StringMap postParameters; + postParameters.insert(QLatin1String("message"), message.body()); + postParameters.insert(QLatin1String("subject"), message.subject()); + postParameters.insert(QLatin1String("to"), message.to()); + return new PostJob(d->m_internals, createRequest(QLatin1String("message/2")), postParameters); +} + +ListJob *Provider::requestCategories() +{ + if (!isValid()) { + return nullptr; + } + + const QUrl url = createUrl(QLatin1String("content/categories")); + + // Thread-local cache of categories requests. They are fairly slow and block startup + static QThreadStorage *>> reqs; + ListJob *job = reqs.localData().value(url); + if (!job) { + job = new ListJob(d->m_internals, createRequest(url)); + QObject::connect(job, &BaseJob::finished, [url] { + reqs.localData().remove(url); + }); + reqs.localData().insert(url, job); + } + return job; +} + +ListJob *Provider::requestLicenses() +{ + if (!isValid()) { + return nullptr; + } + + QUrl url = createUrl(QLatin1String("content/licenses")); + ListJob *job = new ListJob(d->m_internals, createRequest(url)); + return job; +} + +ListJob *Provider::requestDistributions() +{ + if (!isValid()) { + return nullptr; + } + + QUrl url = createUrl(QLatin1String("content/distributions")); + ListJob *job = new ListJob(d->m_internals, createRequest(url)); + return job; +} + +ListJob *Provider::requestHomePageTypes() +{ + if (!isValid()) { + return nullptr; + } + + QUrl url = createUrl(QLatin1String("content/homepages")); + ListJob *job = new ListJob(d->m_internals, createRequest(url)); + return job; +} + +ListJob *Provider::searchContents(const Category::List &categories, const QString &search, SortMode sortMode, uint page, uint pageSize) +{ + return searchContents(categories, QString(), Distribution::List(), License::List(), search, sortMode, page, pageSize); +} + +ListJob * +Provider::searchContentsByPerson(const Category::List &categories, const QString &person, const QString &search, SortMode sortMode, uint page, uint pageSize) +{ + return searchContents(categories, person, Distribution::List(), License::List(), search, sortMode, page, pageSize); +} + +ListJob *Provider::searchContents(const Category::List &categories, + const QString &person, + const Distribution::List &distributions, + const License::List &licenses, + const QString &search, + SortMode sortMode, + uint page, + uint pageSize) +{ + if (!isValid()) { + return nullptr; + } + + QUrl url = createUrl(QStringLiteral("content/data")); + QUrlQuery q(url); + QStringList categoryIds; + categoryIds.reserve(categories.count()); + for (const Category &category : categories) { + categoryIds.append(category.id()); + } + q.addQueryItem(QStringLiteral("categories"), categoryIds.join(QLatin1Char('x'))); + + QStringList distributionIds; + for (const Distribution &distribution : distributions) { + distributionIds.append(QString::number(distribution.id())); + } + q.addQueryItem(QStringLiteral("distribution"), distributionIds.join(QLatin1Char(','))); + + QStringList licenseIds; + for (const License &license : licenses) { + licenseIds.append(QString::number(license.id())); + } + q.addQueryItem(QStringLiteral("license"), licenseIds.join(QLatin1Char(','))); + + if (!person.isEmpty()) { + q.addQueryItem(QStringLiteral("user"), person); + } + + q.addQueryItem(QStringLiteral("search"), search); + QString sortModeString; + switch (sortMode) { + case Newest: + sortModeString = QLatin1String("new"); + break; + case Alphabetical: + sortModeString = QLatin1String("alpha"); + break; + case Rating: + sortModeString = QLatin1String("high"); + break; + case Downloads: + sortModeString = QLatin1String("down"); + break; + } + + if (!sortModeString.isEmpty()) { + q.addQueryItem(QStringLiteral("sortmode"), sortModeString); + } + + q.addQueryItem(QStringLiteral("page"), QString::number(page)); + q.addQueryItem(QStringLiteral("pagesize"), QString::number(pageSize)); + + url.setQuery(q); + ListJob *job = new ListJob(d->m_internals, createRequest(url)); + return job; +} + +ItemJob *Provider::requestContent(const QString &id) +{ + if (!isValid()) { + return nullptr; + } + + QUrl url = createUrl(QLatin1String("content/data/") + id); + ItemJob *job = new ItemJob(d->m_internals, createRequest(url)); + return job; +} + +ItemPostJob *Provider::addNewContent(const Category &category, const Content &cont) +{ + if (!isValid() || !category.isValid()) { + return nullptr; + } + + QUrl url = createUrl(QLatin1String("content/add")); + StringMap pars(cont.attributes()); + + pars.insert(QLatin1String("type"), category.id()); + pars.insert(QLatin1String("name"), cont.name()); + + // qCDebug(ATTICA) << "Parameter map: " << pars; + + return new ItemPostJob(d->m_internals, createRequest(url), pars); +} + +ItemPostJob *Provider::editContent(const Category &updatedCategory, const QString &contentId, const Content &updatedContent) +{ + if (!isValid()) { + return nullptr; + } + + // FIXME I get a server error message here, though the name of the item is changed + QUrl url = createUrl(QLatin1String("content/edit/") + contentId); + StringMap pars(updatedContent.attributes()); + + pars.insert(QLatin1String("type"), updatedCategory.id()); + pars.insert(QLatin1String("name"), updatedContent.name()); + + // qCDebug(ATTICA) << "Parameter map: " << pars; + + return new ItemPostJob(d->m_internals, createRequest(url), pars); +} + +/* +PostJob* Provider::setDownloadFile(const QString& contentId, QIODevice* payload) +{ + QUrl url = createUrl("content/uploaddownload/" + contentId); + PostFileData postRequest(url); + // FIXME mime type + //postRequest.addFile("localfile", payload, "application/octet-stream"); + postRequest.addFile("localfile", payload, "image/jpeg"); + return new PostJob(d->m_internals, postRequest.request(), postRequest.data()); +} +*/ + +PostJob *Provider::deleteContent(const QString &contentId) +{ + if (!isValid()) { + return nullptr; + } + + QUrl url = createUrl(QLatin1String("content/delete/") + contentId); + PostFileData postRequest(url); + postRequest.addArgument(QLatin1String("contentid"), contentId); + return new PostJob(d->m_internals, postRequest.request(), postRequest.data()); +} + +PostJob *Provider::setDownloadFile(const QString &contentId, const QString &fileName, const QByteArray &payload) +{ + if (!isValid()) { + return nullptr; + } + + QUrl url = createUrl(QLatin1String("content/uploaddownload/") + contentId); + PostFileData postRequest(url); + postRequest.addArgument(QLatin1String("contentid"), contentId); + // FIXME mime type + postRequest.addFile(fileName, payload, QLatin1String("application/octet-stream")); + return new PostJob(d->m_internals, postRequest.request(), postRequest.data()); +} + +PostJob *Provider::deleteDownloadFile(const QString &contentId) +{ + if (!isValid()) { + return nullptr; + } + + QUrl url = createUrl(QLatin1String("content/deletedownload/") + contentId); + PostFileData postRequest(url); + postRequest.addArgument(QLatin1String("contentid"), contentId); + return new PostJob(d->m_internals, postRequest.request(), postRequest.data()); +} + +PostJob *Provider::setPreviewImage(const QString &contentId, const QString &previewId, const QString &fileName, const QByteArray &image) +{ + if (!isValid()) { + return nullptr; + } + + QUrl url = createUrl(QLatin1String("content/uploadpreview/") + contentId + QLatin1Char('/') + previewId); + + PostFileData postRequest(url); + postRequest.addArgument(QLatin1String("contentid"), contentId); + postRequest.addArgument(QLatin1String("previewid"), previewId); + // FIXME mime type + postRequest.addFile(fileName, image, QLatin1String("application/octet-stream")); + + return new PostJob(d->m_internals, postRequest.request(), postRequest.data()); +} + +PostJob *Provider::deletePreviewImage(const QString &contentId, const QString &previewId) +{ + if (!isValid()) { + return nullptr; + } + + QUrl url = createUrl(QLatin1String("content/deletepreview/") + contentId + QLatin1Char('/') + previewId); + PostFileData postRequest(url); + postRequest.addArgument(QLatin1String("contentid"), contentId); + postRequest.addArgument(QLatin1String("previewid"), previewId); + return new PostJob(d->m_internals, postRequest.request(), postRequest.data()); +} + +PostJob *Provider::voteForContent(const QString &contentId, uint rating) +{ + if (!isValid()) { + return nullptr; + } + + // according to OCS API, the rating is 0..100 + if (rating > 100) { + qWarning() << "Rating cannot be superior to 100, fallback to 100."; + rating = 100; + } + + StringMap postParameters; + postParameters.insert(QLatin1String("vote"), QString::number(rating)); + // qCDebug(ATTICA) << "vote: " << QString::number(rating); + return new PostJob(d->m_internals, createRequest(QLatin1String("content/vote/") + contentId), postParameters); +} + +PostJob *Provider::becomeFan(const QString &contentId) +{ + if (!isValid()) { + return nullptr; + } + + QUrl url = createUrl(QLatin1String("fan/add/") + contentId); + PostFileData postRequest(url); + postRequest.addArgument(QLatin1String("contentid"), contentId); + return new PostJob(d->m_internals, postRequest.request(), postRequest.data()); +} + +ListJob *Provider::requestFans(const QString &contentId, uint page, uint pageSize) +{ + if (!isValid()) { + return nullptr; + } + + QUrl url = createUrl(QLatin1String("fan/data/") + contentId); + QUrlQuery q(url); + q.addQueryItem(QStringLiteral("contentid"), contentId); + q.addQueryItem(QStringLiteral("page"), QString::number(page)); + q.addQueryItem(QStringLiteral("pagesize"), QString::number(pageSize)); + url.setQuery(q); + ListJob *job = new ListJob(d->m_internals, createRequest(url)); + return job; +} + +ListJob *Provider::requestForums(uint page, uint pageSize) +{ + if (!isValid()) { + return nullptr; + } + + QUrl url = createUrl(QStringLiteral("forum/list")); + QUrlQuery q(url); + q.addQueryItem(QStringLiteral("page"), QString::number(page)); + q.addQueryItem(QStringLiteral("pagesize"), QString::number(pageSize)); + url.setQuery(q); + + return doRequestForumList(url); +} + +ListJob * +Provider::requestTopics(const QString &forum, const QString &search, const QString &description, Provider::SortMode mode, int page, int pageSize) +{ + if (!isValid()) { + return nullptr; + } + + QUrl url = createUrl(QStringLiteral("forum/topics/list")); + QUrlQuery q(url); + q.addQueryItem(QStringLiteral("forum"), forum); + q.addQueryItem(QStringLiteral("search"), search); + q.addQueryItem(QStringLiteral("description"), description); + QString sortModeString; + switch (mode) { + case Newest: + sortModeString = QLatin1String("new"); + break; + case Alphabetical: + sortModeString = QLatin1String("alpha"); + break; + default: + break; + } + if (!sortModeString.isEmpty()) { + q.addQueryItem(QStringLiteral("sortmode"), sortModeString); + } + q.addQueryItem(QStringLiteral("page"), QString::number(page)); + q.addQueryItem(QStringLiteral("pagesize"), QString::number(pageSize)); + url.setQuery(q); + + return doRequestTopicList(url); +} + +PostJob *Provider::postTopic(const QString &forumId, const QString &subject, const QString &content) +{ + if (!isValid()) { + return nullptr; + } + + StringMap postParameters; + postParameters.insert(QLatin1String("subject"), subject); + postParameters.insert(QLatin1String("content"), content); + postParameters.insert(QLatin1String("forum"), forumId); + return new PostJob(d->m_internals, createRequest(QLatin1String("forum/topic/add")), postParameters); +} + +ItemJob *Provider::downloadLink(const QString &contentId, const QString &itemId) +{ + if (!isValid()) { + return nullptr; + } + + QUrl url = createUrl(QLatin1String("content/download/") + contentId + QLatin1Char('/') + itemId); + ItemJob *job = new ItemJob(d->m_internals, createRequest(url)); + return job; +} + +ItemJob *Provider::requestKnowledgeBaseEntry(const QString &id) +{ + if (!isValid()) { + return nullptr; + } + + QUrl url = createUrl(QLatin1String("knowledgebase/data/") + id); + ItemJob *job = new ItemJob(d->m_internals, createRequest(url)); + return job; +} + +ListJob *Provider::searchKnowledgeBase(const Content &content, const QString &search, Provider::SortMode sortMode, int page, int pageSize) +{ + if (!isValid()) { + return nullptr; + } + + QUrl url = createUrl(QStringLiteral("knowledgebase/data")); + QUrlQuery q(url); + if (content.isValid()) { + q.addQueryItem(QStringLiteral("content"), content.id()); + } + + q.addQueryItem(QStringLiteral("search"), search); + QString sortModeString; + switch (sortMode) { + case Newest: + sortModeString = QLatin1String("new"); + break; + case Alphabetical: + sortModeString = QLatin1String("alpha"); + break; + case Rating: + sortModeString = QLatin1String("high"); + break; + // FIXME: knowledge base doesn't have downloads + case Downloads: + sortModeString = QLatin1String("new"); + break; + } + if (!sortModeString.isEmpty()) { + q.addQueryItem(QStringLiteral("sortmode"), sortModeString); + } + + q.addQueryItem(QStringLiteral("page"), QString::number(page)); + q.addQueryItem(QStringLiteral("pagesize"), QString::number(pageSize)); + url.setQuery(q); + + ListJob *job = new ListJob(d->m_internals, createRequest(url)); + return job; +} + +ItemJob *Provider::requestEvent(const QString &id) +{ + if (!isValid()) { + return nullptr; + } + + ItemJob *job = new ItemJob(d->m_internals, createRequest(QLatin1String("event/data/") + id)); + return job; +} + +ListJob *Provider::requestEvent(const QString &country, const QString &search, const QDate &startAt, Provider::SortMode mode, int page, int pageSize) +{ + if (!isValid()) { + return nullptr; + } + + QUrl url = createUrl(QStringLiteral("event/data")); + QUrlQuery q(url); + + if (!search.isEmpty()) { + q.addQueryItem(QStringLiteral("search"), search); + } + + QString sortModeString; + switch (mode) { + case Newest: + sortModeString = QLatin1String("new"); + break; + case Alphabetical: + sortModeString = QLatin1String("alpha"); + break; + default: + break; + } + if (!sortModeString.isEmpty()) { + q.addQueryItem(QStringLiteral("sortmode"), sortModeString); + } + + if (!country.isEmpty()) { + q.addQueryItem(QStringLiteral("country"), country); + } + + q.addQueryItem(QStringLiteral("startat"), startAt.toString(Qt::ISODate)); + + q.addQueryItem(QStringLiteral("page"), QString::number(page)); + q.addQueryItem(QStringLiteral("pagesize"), QString::number(pageSize)); + url.setQuery(q); + + ListJob *job = new ListJob(d->m_internals, createRequest(url)); + return job; +} + +ListJob *Provider::requestComments(const Comment::Type commentType, const QString &id, const QString &id2, int page, int pageSize) +{ + if (!isValid()) { + return nullptr; + } + + QString commentTypeString; + commentTypeString = Comment::commentTypeToString(commentType); + if (commentTypeString.isEmpty()) { + return nullptr; + } + + QUrl url = createUrl(QLatin1String("comments/data/") + commentTypeString + QLatin1Char('/') + id + QLatin1Char('/') + id2); + + QUrlQuery q(url); + q.addQueryItem(QStringLiteral("page"), QString::number(page)); + q.addQueryItem(QStringLiteral("pagesize"), QString::number(pageSize)); + url.setQuery(q); + + ListJob *job = new ListJob(d->m_internals, createRequest(url)); + return job; +} + +ItemPostJob *Provider::addNewComment(const Comment::Type commentType, + const QString &id, + const QString &id2, + const QString &parentId, + const QString &subject, + const QString &message) +{ + if (!isValid()) { + return nullptr; + } + + QString commentTypeString; + commentTypeString = Comment::commentTypeToString(commentType); + if (commentTypeString.isEmpty()) { + return nullptr; + } + + QMap postParameters; + + postParameters.insert(QLatin1String("type"), commentTypeString); + postParameters.insert(QLatin1String("content"), id); + postParameters.insert(QLatin1String("content2"), id2); + postParameters.insert(QLatin1String("parent"), parentId); + postParameters.insert(QLatin1String("subject"), subject); + postParameters.insert(QLatin1String("message"), message); + + return new ItemPostJob(d->m_internals, createRequest(QLatin1String("comments/add")), postParameters); +} + +PostJob *Provider::voteForComment(const QString &id, uint rating) +{ + if (!isValid() || (rating > 100)) { + return nullptr; + } + + QMap postParameters; + postParameters.insert(QLatin1String("vote"), QString::number(rating)); + + QUrl url = createUrl(QLatin1String("comments/vote/") + id); + return new PostJob(d->m_internals, createRequest(url), postParameters); +} + +PostJob *Provider::setPrivateData(const QString &app, const QString &key, const QString &value) +{ + if (!isValid()) { + return nullptr; + } + + QUrl url = createUrl(QLatin1String("privatedata/setattribute/") + app + QLatin1Char('/') + key); + PostFileData postRequest(url); + + postRequest.addArgument(QLatin1String("value"), value); + + return new PostJob(d->m_internals, postRequest.request(), postRequest.data()); +} + +ItemJob *Provider::requestPrivateData(const QString &app, const QString &key) +{ + if (!isValid()) { + return nullptr; + } + + ItemJob *job = + new ItemJob(d->m_internals, createRequest(QLatin1String("privatedata/getattribute/") + app + QLatin1Char('/') + key)); + return job; +} + +QUrl Provider::createUrl(const QString &path) +{ + QUrl url(d->m_baseUrl.toString() + path); + return url; +} + +QNetworkRequest Provider::createRequest(const QUrl &url) +{ + QNetworkRequest request(url); + request.setHeader(QNetworkRequest::ContentTypeHeader, QStringLiteral("application/x-www-form-urlencoded")); + + QString agentHeader; + if (QCoreApplication::instance()) { + agentHeader = QString::fromLocal8Bit("%1/%2").arg(QCoreApplication::instance()->applicationName(), QCoreApplication::instance()->applicationVersion()); + } else { + agentHeader = QString::fromLocal8Bit("Attica/%1").arg(QLatin1String(LIBATTICA_VERSION_STRING)); + } + if (!d->m_additionalAgentInformation.isEmpty()) { + agentHeader = QString::fromLocal8Bit("%1 (+%2)").arg(agentHeader, d->m_additionalAgentInformation); + } + request.setHeader(QNetworkRequest::UserAgentHeader, agentHeader); + + if (!d->m_credentialsUserName.isEmpty()) { + request.setAttribute((QNetworkRequest::Attribute)BaseJob::UserAttribute, QVariant(d->m_credentialsUserName)); + request.setAttribute((QNetworkRequest::Attribute)BaseJob::PasswordAttribute, QVariant(d->m_credentialsPassword)); + } + return request; +} + +QNetworkRequest Provider::createRequest(const QString &path) +{ + return createRequest(createUrl(path)); +} + +ItemJob *Provider::doRequestConfig(const QUrl &url) +{ + return new ItemJob(d->m_internals, createRequest(url)); +} + +ItemJob *Provider::doRequestPerson(const QUrl &url) +{ + return new ItemJob(d->m_internals, createRequest(url)); +} + +ItemJob *Provider::doRequestAccountBalance(const QUrl &url) +{ + return new ItemJob(d->m_internals, createRequest(url)); +} + +ListJob *Provider::doRequestPersonList(const QUrl &url) +{ + return new ListJob(d->m_internals, createRequest(url)); +} + +ListJob *Provider::doRequestAchievementList(const QUrl &url) +{ + return new ListJob(d->m_internals, createRequest(url)); +} + +ListJob *Provider::doRequestActivityList(const QUrl &url) +{ + return new ListJob(d->m_internals, createRequest(url)); +} + +ListJob *Provider::doRequestFolderList(const QUrl &url) +{ + return new ListJob(d->m_internals, createRequest(url)); +} + +ListJob *Provider::doRequestForumList(const QUrl &url) +{ + return new ListJob(d->m_internals, createRequest(url)); +} + +ListJob *Provider::doRequestTopicList(const QUrl &url) +{ + return new ListJob(d->m_internals, createRequest(url)); +} + +ListJob *Provider::doRequestMessageList(const QUrl &url) +{ + return new ListJob(d->m_internals, createRequest(url)); +} + +QString Provider::achievementServiceVersion() const +{ + return d->m_achievementVersion; +} + +QString Provider::activityServiceVersion() const +{ + return d->m_activityVersion; +} +QString Provider::commentServiceVersion() const +{ + return d->m_commentVersion; +} +QString Provider::contentServiceVersion() const +{ + return d->m_contentVersion; +} +QString Provider::fanServiceVersion() const +{ + return d->m_fanVersion; +} +QString Provider::forumServiceVersion() const +{ + return d->m_forumVersion; +} +QString Provider::friendServiceVersion() const +{ + return d->m_friendVersion; +} +QString Provider::knowledgebaseServiceVersion() const +{ + return d->m_knowledgebaseVersion; +} +QString Provider::messageServiceVersion() const +{ + return d->m_messageVersion; +} +QString Provider::personServiceVersion() const +{ + return d->m_personVersion; +} + +bool Provider::hasAchievementService() const +{ + return !d->m_achievementVersion.isEmpty(); +} + +bool Provider::hasActivityService() const +{ + return !d->m_activityVersion.isEmpty(); +} +bool Provider::hasCommentService() const +{ + return !d->m_commentVersion.isEmpty(); +} +bool Provider::hasContentService() const +{ + return !d->m_contentVersion.isEmpty(); +} +bool Provider::hasFanService() const +{ + return !d->m_fanVersion.isEmpty(); +} +bool Provider::hasForumService() const +{ + return !d->m_forumVersion.isEmpty(); +} +bool Provider::hasFriendService() const +{ + return !d->m_friendVersion.isEmpty(); +} +bool Provider::hasKnowledgebaseService() const +{ + return !d->m_knowledgebaseVersion.isEmpty(); +} +bool Provider::hasMessageService() const +{ + return !d->m_messageVersion.isEmpty(); +} +bool Provider::hasPersonService() const +{ + return !d->m_personVersion.isEmpty(); +} diff --git a/local/recipes/kde/kf6-attica/source/src/provider.h b/local/recipes/kde/kf6-attica/source/src/provider.h new file mode 100644 index 00000000..bec791d2 --- /dev/null +++ b/local/recipes/kde/kf6-attica/source/src/provider.h @@ -0,0 +1,783 @@ +/* + This file is part of KDE. + + SPDX-FileCopyrightText: 2008 Cornelius Schumacher + SPDX-FileCopyrightText: 2011 Laszlo Papp + + SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL +*/ + +#ifndef ATTICA_PROVIDER_H +#define ATTICA_PROVIDER_H + +#include +#include +#include +#include + +#include + +#include "achievement.h" +#include "attica_export.h" +#include "category.h" +#include "comment.h" +#include "distribution.h" +#include "forum.h" +#include "itemjob.h" +#include "license.h" +#include "listjob.h" +#include "message.h" + +class QDate; +class QUrl; + +namespace Attica +{ +class PlatformDependent; + +class PostJobStatus; + +class AccountBalance; +class Activity; +class BuildServiceJobOutput; +class BuildServiceJob; +class BuildService; +class PrivateData; +class Config; +class Content; +class DownloadItem; +class Distribution; +class Event; +class Folder; +class HomePageType; +class KnowledgeBaseEntry; +class License; +class Person; +class PostJob; +class Project; +class Provider; +class Publisher; +class PublisherField; +class RemoteAccount; + +/** + * @class Provider provider.h + * + * The Provider class represents one Open Collaboration Service provider. + * Use the ProviderManager to instantiate a Provider. + * + * Accessing functions of the Provider returns a Job class that + * takes care of accessing the server and parsing the result. + * + * Provider files are xml of the form: +
+ 
+ opendesktop
+ https://api.opendesktop.org/v1/
+ openDesktop.org
+ 
+ https://opendesktop.org/terms/
+ https://opendesktop.org/usermanager/new.php
+ 
+   
+   
+   
+   
+   
+   
+   
+   
+   
+ 
+
+ 
+ * The server provides the services specified in the services section, not necessarily all of them. + */ +class ATTICA_EXPORT Provider +{ +public: + /** + * Default construct a Provider. Please note that this provider is incomplete and never valid. + */ + Provider(); + Provider(const Provider &other); + Provider &operator=(const Provider &other); + ~Provider(); + + /** + Returns true if the provider has been set up and can be used. + */ + bool isValid() const; + + /** + Test if the provider is enabled by the settings. + The application can choose to ignore this, but the user settings should be respected. + */ + bool isEnabled() const; + void setEnabled(bool enabled); + + /** + * Set a custom identifier for your application (sent along with the requests as + * the http agent header in addition to the application name and version). + * + * For example, you might have an application named SomeApplication, version 23, + * and wish to send along the data "lookandfeel.knsrc". Call this function, and + * the resulting agent header would be: + * + * SomeApplication/23 (+lookandfeel.knsrc) + * + * If you do not set this (or set it to an empty string), the agent string becomes + * + * SomeApplication/23 + * + * @param additionalAgentInformation The extra string + * @since 5.66 + */ + void setAdditionalAgentInformation(const QString &additionalInformation); + /** + * The custom identifier sent along with requests + * + * @return The custom identifier + * @see setAdditionalAgentInformation(const QString&) + * @since 5.66 + */ + QString additionalAgentInformation() const; + + /** + A url that identifies this provider. + This should be used as identifier when referring to this provider but you don't want to use the full provider object. + */ + QUrl baseUrl() const; + + /** + A name for the provider that can be displayed to the user + */ + QString name() const; + + /** + * An icon used to visually identify this provider + * @return A URL for an icon image (or an invalid URL if one was not defined by the provider) + * @since 5.85 + */ + QUrl icon() const; + + enum SortMode { + Newest, + Alphabetical, + Rating, + Downloads, + }; + + /** + Test if the server supports the person part of the API + */ + bool hasPersonService() const; + /** + Version of the person part of the API + */ + QString personServiceVersion() const; + + /** + Test if the server supports the friend part of the API + */ + bool hasFriendService() const; + + /** + Version of the friend part of the API + */ + QString friendServiceVersion() const; + + /** + Test if the server supports the message part of the API + */ + bool hasMessageService() const; + /** + Version of the message part of the API + */ + QString messageServiceVersion() const; + + /** + Test if the server supports the achievement part of the API + */ + bool hasAchievementService() const; + /** + Version of the achievement part of the API + */ + QString achievementServiceVersion() const; + + /** + Test if the server supports the activity part of the API + */ + bool hasActivityService() const; + /** + Version of the activity part of the API + */ + QString activityServiceVersion() const; + + /** + Test if the server supports the content part of the API + */ + bool hasContentService() const; + /** + Version of the content part of the API + */ + QString contentServiceVersion() const; + + /** + Test if the server supports the fan part of the API + */ + bool hasFanService() const; + /** + Version of the fan part of the API + */ + QString fanServiceVersion() const; + + /** + Test if the server supports the forum part of the API + */ + bool hasForumService() const; + /** + Version of the forum part of the API + */ + QString forumServiceVersion() const; + + /** + * + Test if the server supports the knowledgebase part of the API + */ + bool hasKnowledgebaseService() const; + /** + Version of the knowledgebase part of the API + */ + QString knowledgebaseServiceVersion() const; + + /** + Test if the server supports the comments part of the API + */ + bool hasCommentService() const; + /** + Version of the comments part of the API + */ + QString commentServiceVersion() const; + + /** + Test if the provider has user name/password available. + This does not yet open kwallet in case the KDE plugin is used. + @return true if the provider has login information + */ + bool hasCredentials() const; + bool hasCredentials(); + + /** + Load user name and password from the store. + Attica will remember the loaded values and use them from this point on. + @param user reference that returns the user name + @param password reference that returns the password + @return if credentials could be loaded + */ + bool loadCredentials(QString &user, QString &password); + + /** + Sets (and remembers) user name and password for this provider. + To remove the data an empty username should be passed. + @param user the user (login) name + @param password the password + @return if credentials could be saved + */ + bool saveCredentials(const QString &user, const QString &password); + + /** + Test if the server accepts the login/password. + This function does not actually set the credentials. Use saveCredentials for that purpose. + @param user the user (login) name + @param password the password + @return the job that will contain the success of the login as metadata + */ + PostJob *checkLogin(const QString &user, const QString &password); + + /** + * Fetches server config + * @return The job responsible for fetching data + */ + ItemJob *requestConfig(); + + // Person part of OCS + + PostJob *registerAccount(const QString &id, const QString &password, const QString &mail, const QString &firstName, const QString &lastName); + ItemJob *requestPerson(const QString &id); + ItemJob *requestPersonSelf(); + ItemJob *requestAccountBalance(); + ListJob *requestPersonSearchByName(const QString &name); + ListJob *requestPersonSearchByLocation(qreal latitude, qreal longitude, qreal distance = 0.0, int page = 0, int pageSize = 20); + PostJob *postLocation(qreal latitude, qreal longitude, const QString &city = QString(), const QString &country = QString()); + + ////////////////////////// + // PrivateData part of OCS + + /** + * Fetches the a given attribute from an OCS-compliant server. + * @param app The application name + * @param key The key of the attribute to fetch (optional) + * @return The job that is responsible for fetching the data + */ + ItemJob *requestPrivateData(const QString &app, const QString &key = QString()); + + /** + * Fetches all stored private data. + * @return The job responsible for fetching data + */ + ItemJob *requestPrivateData() + { + return requestPrivateData(QString(), QString()); + } + + /** + * Sets the value of an attribute. + * @param app The application name + * @param key The key of the attribute + * @param value The new value of the attribute + * @return The job responsible for setting data + */ + PostJob *setPrivateData(const QString &app, const QString &key, const QString &value); + + // Friend part of OCS + + ListJob *requestFriends(const QString &id, int page = 0, int pageSize = 20); + ListJob *requestSentInvitations(int page = 0, int pageSize = 20); + ListJob *requestReceivedInvitations(int page = 0, int pageSize = 20); + PostJob *inviteFriend(const QString &to, const QString &message); + PostJob *approveFriendship(const QString &to); + PostJob *declineFriendship(const QString &to); + PostJob *cancelFriendship(const QString &to); + + // Message part of OCS + + ListJob *requestFolders(); + ListJob *requestMessages(const Folder &folder); + ListJob *requestMessages(const Folder &folder, Message::Status status); + ItemJob *requestMessage(const Folder &folder, const QString &id); + PostJob *postMessage(const Message &message); + + // Achievement part of OCS + /** + * Get a list of achievements + * @return ListJob listing Achievements + */ + ListJob *requestAchievements(const QString &contentId, const QString &achievementId, const QString &userId); + + /** Add a new achievement. + * @param id id of the achievement entry + * @param achievement The new Achievement added + * @return item post job for adding the new achievement + */ + ItemPostJob *addNewAchievement(const QString &id, const Achievement &newAchievement); + + /** + * Post modifications to an Achievement on the server + * @param achievement Achievement to update on the server + */ + PutJob *editAchievement(const QString &contentId, const QString &achievementId, const Achievement &achievement); + + /** + * Deletes an achievement on the server. The achievement passed as an argument doesn't need complete + * information as just the id() is used. + * @param achievement Achievement to delete on the server. + */ + DeleteJob *deleteAchievement(const QString &contentId, const QString &achievementId); + + // PostJob* postAchievement(const Achievement& achievement); + PostJob *setAchievementProgress(const QString &id, const QVariant &progress, const QDateTime ×tamp); + DeleteJob *resetAchievementProgress(const QString &id); + + // Activity part of OCS + + ListJob *requestActivities(); + PostJob *postActivity(const QString &message); + + // Project part of OCS + /** + * Get a list of build service projects + * @return ListJob listing Projects + */ + ListJob *requestProjects(); + + /** + * Get a Project's data + * @return ItemJob receiving data + */ + ItemJob *requestProject(const QString &id); + + /** + * Post modifications to a Project on the server. The resulting project ID can be found in + * the Attica::MetaData of the finished() PostJob. You can retrieve it using + * Attica::MetaData::resultingProjectId(). + * @param project Project to create on the server + */ + PostJob *createProject(const Project &project); + + /** + * Deletes a project on the server. The project passed as an argument doesn't need complete + * information as just the id() is used. + * @param project Project to delete on the server. + */ + PostJob *deleteProject(const Project &project); + + /** + * Post modifications to a Project on the server + * @param project Project to update on the server + */ + PostJob *editProject(const Project &project); + + // Buildservice part of OCS + + /** + * Get the information for a specific build service instance. + * @return ItemJob receiving data + */ + ItemJob *requestBuildService(const QString &id); + + /** + * Get the information for a specific publisher. + * @return ItemJob receiving data + */ + ItemJob *requestPublisher(const QString &id); + + /** + * Save the value of a single publishing field + * @return PostJob* + */ + PostJob *savePublisherField(const Project &project, const PublisherField &field); + + /** + * Publish the result of a completed build job to a publisher. + * @return ItemJob receiving data + */ + PostJob *publishBuildJob(const BuildServiceJob &buildjob, const Publisher &publisher); + + /** + * Get the build output for a specific build service job + * @return ItemJob receiving and containing the output data + */ + ItemJob *requestBuildServiceJobOutput(const QString &id); + + /** + * Get the information for a specific build service job, such as status and progress. + * @return ItemJob receiving and containing the data + */ + ItemJob *requestBuildServiceJob(const QString &id); + + /** + * Get a list of build service build services + * @return ListJob listing BuildServices + */ + ListJob *requestBuildServices(); + + /** + * Get a list of publishers + * @return ListJob listing Publishers + */ + ListJob *requestPublishers(); + + /** + * Get a list of build service projects + * @return ListJob listing BuildServiceJobs + */ + ListJob *requestBuildServiceJobs(const Project &project); + + /** + * Create a new job for a given project on a given buildservice for a given target. + * Those three items are mandatory for the job to succeed. + * @param job Buildservicejob to create on the server + */ + PostJob *createBuildServiceJob(const BuildServiceJob &job); + + /** + * Cancel a job. + * Setting the ID on the build service parameter is enough for it to work. + * @param job Buildservicejob to cancel on the server, needs at least id set. + */ + PostJob *cancelBuildServiceJob(const BuildServiceJob &job); + + /** + * Get a list of remote accounts, account for a build service instance + * which is stored in the OCS service in order to authenticate with the + * build service instance. + * @return ListJob listing RemoteAccounts + */ + ListJob *requestRemoteAccounts(); + + /** + * Deletes a remote account stored on the OCS server. + * @param id The ID of the remote account on the OCS instance. + */ + PostJob *deleteRemoteAccount(const QString &id); + + /** + * Create a new remote account, an account for a build service instance + * which is stored in the OCS service in order to authenticate with the + * build service instance. + * Type, Type ID, login and password are mandatory. + * @param account RemoteAccount to create on the server + */ + PostJob *createRemoteAccount(const RemoteAccount &account); + + /** + * Edit an existing remote account. + * @param account RemoteAccount to create on the server + */ + PostJob *editRemoteAccount(const RemoteAccount &account); + + /** Get a remote account by its ID. + * @param id The ID of the remote account + */ + ItemJob *requestRemoteAccount(const QString &id); + + /** Upload a tarball to the buildservice. + * @param projectId The ID of the project this source file belongs to + * @param payload A reference to the complete file data + * @return A postjob to keep keep track of the upload + */ + Attica::PostJob *uploadTarballToBuildService(const QString &projectId, const QString &fileName, const QByteArray &payload); + + // Content part of OCS + + /** + * Get a list of categories (such as wallpaper) + * @return the categories of the server + */ + ListJob *requestCategories(); + + /** + * Get a list of licenses (such as GPL) + * @return the licenses available from the server + */ + ListJob *requestLicenses(); + + /** + * Get a list of distributions (such as Ark, Debian) + * @return the licenses available from the server + */ + ListJob *requestDistributions(); + + /** + * Get a list of home page types (such as blog, Facebook) + * @return the licenses available from the server + */ + ListJob *requestHomePageTypes(); + + /** + Request a list of Contents. + Note that @p categories is not optional. If left empty, no results will be returned. + An empty search string @p search returns the top n items. + @param categories categories to search in + @param search optional search string (in name/description of the content) + @param mode sorting mode + @param page request nth page in the list of results + @param pageSize requested size of pages when calculating the list of results + @return list job for the search results + */ + ListJob * + searchContents(const Category::List &categories, const QString &search = QString(), SortMode mode = Rating, uint page = 0, uint pageSize = 10); + + /** + Request a list of Contents. + Like @see searchContents, but only contents created by one person. + @param person the person-id that created the contents. + */ + ListJob *searchContentsByPerson(const Category::List &categories, + const QString &person, + const QString &search = QString(), + SortMode mode = Rating, + uint page = 0, + uint pageSize = 10); + + /** + Request a list of Contents. More complete version. + Note that @p categories is not optional. If left empty, no results will be returned. + An empty search string @p search returns the top n items. + @param categories categories to search in + @param person the person-id that created the contents + @param distributions list of distributions to filter by, if empty no filtering by distribution is done + @param licenses list of licenses to filter by, if empty no filtering by license is done + @param search optional search string (in name/description of the content) + @param mode sorting mode + @param page request nth page in the list of results + @param pageSize requested size of pages when calculating the list of results + @return list job for the search results + */ + ListJob *searchContents(const Category::List &categories, + const QString &person, + const Distribution::List &distributions, + const License::List &licenses, + const QString &search = QString(), + SortMode sortMode = Rating, + uint page = 0, + uint pageSize = 10); + + /** + Retrieve a single content. + @param contentId the id of the content + @return job that retrieves the content object + */ + ItemJob *requestContent(const QString &contentId); + + ItemJob *downloadLink(const QString &contentId, const QString &itemId = QStringLiteral("1")); + + /** Vote for a content item + * @param contentId the content which this voting is for + * @param rating - the rating, must be between 0 (bad) and 100 (good) + * @return the post job for this voting + */ + PostJob *voteForContent(const QString &contentId, uint rating); + + ItemPostJob *addNewContent(const Category &category, const Content &newContent); + ItemPostJob *editContent(const Category &updatedCategory, const QString &contentId, const Content &updatedContent); + PostJob *deleteContent(const QString &contentId); + + PostJob *setDownloadFile(const QString &contentId, const QString &fileName, QIODevice *payload); + PostJob *setDownloadFile(const QString &contentId, const QString &fileName, const QByteArray &payload); + PostJob *deleteDownloadFile(const QString &contentId); + + /** + * Upload an image file as preview for the content + * @param contentId + * @param previewId each content can have previews with the id 1,2 or 3 + * @param payload the image file + */ + PostJob *setPreviewImage(const QString &contentId, const QString &previewId, const QString &fileName, const QByteArray &image); + PostJob *deletePreviewImage(const QString &contentId, const QString &previewId); + + // KnowledgeBase part of OCS + + ItemJob *requestKnowledgeBaseEntry(const QString &id); + ListJob *searchKnowledgeBase(const Content &content, const QString &search, SortMode, int page, int pageSize); + + // Event part of OCS + + ItemJob *requestEvent(const QString &id); + ListJob *requestEvent(const QString &country, const QString &search, const QDate &startAt, SortMode mode, int page, int pageSize); + + // Comment part of OCS + /** Request a list of comments for a content / forum / knowledgebase / event. + * @param comment::Type type of the comment @see Comment::Type (content / forum / knowledgebase / event) + * @param id id of the content entry where you want to get the comments is from + * @param id2 id of the content entry where you want to get the comments is from + * @param page request nth page in the list of results + * @param pageSize requested size of pages when calculating the list of results + * @return list job for the comments results + */ + ListJob *requestComments(const Comment::Type commentType, const QString &id, const QString &id2, int page, int pageSize); + + /** Add a new comment. + * @param commentType type of the comment @see CommentType (content / forum / knowledgebase / event) + * @param id id of the content entry where you want to get the comments is from + * @param id2 id of the sub content entry where you want to get the comments is from + * @param parentId the id of the parent comment if the new comment is a reply + * @param subject title of the comment + * @param message text of the comment + * @return item post job for adding the new comment + */ + ItemPostJob *addNewComment(const Comment::Type commentType, + const QString &id, + const QString &id2, + const QString &parentId, + const QString &subject, + const QString &message); + + /** Vote a comment item + * @param id the comment id which this voting is for + * @param rating the rating, must be between 0 (bad) and 100 (good) + * @return the post job for this voting + */ + PostJob *voteForComment(const QString &id, uint rating); + + // Fan part of OCS + + PostJob *becomeFan(const QString &contentId); + ListJob *requestFans(const QString &contentId, uint page = 0, uint pageSize = 10); + + // Forum part of OCS + ListJob *requestForums(uint page = 0, uint pageSize = 10); + ListJob *requestTopics(const QString &forum, const QString &search, const QString &description, SortMode mode, int page, int pageSize); + PostJob *postTopic(const QString &forumId, const QString &subject, const QString &content); + + const QString &getRegisterAccountUrl() const; + +protected: + QUrl createUrl(const QString &path); + QNetworkRequest createRequest(const QUrl &url); + // Convenience overload + QNetworkRequest createRequest(const QString &path); + + ItemJob *doRequestConfig(const QUrl &url); + ItemJob *doRequestPerson(const QUrl &url); + ItemJob *doRequestAccountBalance(const QUrl &url); + ListJob *doRequestPersonList(const QUrl &url); + ListJob *doRequestAchievementList(const QUrl &url); + ListJob *doRequestActivityList(const QUrl &url); + ListJob *doRequestFolderList(const QUrl &url); + ListJob *doRequestForumList(const QUrl &url); + ListJob *doRequestTopicList(const QUrl &url); + ListJob *doRequestMessageList(const QUrl &url); + +private: + class Private; + QExplicitlySharedDataPointer d; + + Provider(PlatformDependent *internals, const QUrl &baseUrl, const QString &name, const QUrl &icon = QUrl()); + Provider(PlatformDependent *internals, + const QUrl &baseUrl, + const QString &name, + const QUrl &icon, + const QString &person, + const QString &friendV, + const QString &message, + const QString &achievements, + const QString &activity, + const QString &content, + const QString &fan, + const QString &forum, + const QString &knowledgebase, + const QString &event, + const QString &comment); + // kde-SC5: merge with the constructor above (i.e. remove the above one) + Provider(PlatformDependent *internals, + const QUrl &baseUrl, + const QString &name, + const QUrl &icon, + const QString &person, + const QString &friendV, + const QString &message, + const QString &achievements, + const QString &activity, + const QString &content, + const QString &fan, + const QString &forum, + const QString &knowledgebase, + const QString &event, + const QString &comment, + const QString ®isterUrl); + // TODO KF6: merge with the constructor above (i.e. remove the above one - and actually do it this time :P ) + Provider(PlatformDependent *internals, + const QUrl &baseUrl, + const QString &name, + const QUrl &icon, + const QString &person, + const QString &friendV, + const QString &message, + const QString &achievements, + const QString &activity, + const QString &content, + const QString &fan, + const QString &forum, + const QString &knowledgebase, + const QString &event, + const QString &comment, + const QString ®isterUrl, + const QString &additionalAgentInformation); + + friend class ProviderManager; +}; +} + +#endif diff --git a/local/recipes/kde/kf6-attica/source/src/providermanager.cpp b/local/recipes/kde/kf6-attica/source/src/providermanager.cpp new file mode 100644 index 00000000..5e81f244 --- /dev/null +++ b/local/recipes/kde/kf6-attica/source/src/providermanager.cpp @@ -0,0 +1,329 @@ +/* + This file is part of KDE. + + SPDX-FileCopyrightText: 2009 Eckhart Wörner + SPDX-FileCopyrightText: 2009 Frederik Gladhorn + + SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL +*/ + +#include "providermanager.h" + +#include "attica_debug.h" +#include "atticautils.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "platformdependent.h" +#include "platformdependent_v3.h" +#include "qtplatformdependent_p.h" +#include + +using namespace Attica; + +class Q_DECL_HIDDEN ProviderManager::Private +{ +public: + PlatformDependent *m_internals; + QHash m_providers; + QHash m_providerTargets; + QHash m_downloads; + bool m_authenticationSuppressed; + + Private() + : m_internals(nullptr) + , m_authenticationSuppressed(false) + { + } + ~Private() + { + // do not delete m_internals: it is the root component of a plugin! + } +}; + +PlatformDependent *ProviderManager::loadPlatformDependent(const ProviderFlags &flags) +{ + if (flags & ProviderManager::DisablePlugins) { + return new QtPlatformDependent; + } + + QPluginLoader loader(QStringLiteral("attica_kde")); + PlatformDependent *ret = qobject_cast(loader.instance()); + + return ret ? ret : new QtPlatformDependent; +} + +ProviderManager::ProviderManager(const ProviderFlags &flags) + : d(new Private) +{ + d->m_internals = loadPlatformDependent(flags); + connect(d->m_internals->nam(), &QNetworkAccessManager::authenticationRequired, this, &ProviderManager::authenticate); +} + +void ProviderManager::loadDefaultProviders() +{ + auto platformDependentV3 = dynamic_cast(d->m_internals); + if (platformDependentV3 && !platformDependentV3->isReady()) { + connect(platformDependentV3, + &Attica::PlatformDependentV3::readyChanged, + this, + &ProviderManager::slotLoadDefaultProvidersInternal, + Qt::QueuedConnection); + return; + } + + QTimer::singleShot(0, this, &ProviderManager::slotLoadDefaultProvidersInternal); +} + +void ProviderManager::setAuthenticationSuppressed(bool suppressed) +{ + d->m_authenticationSuppressed = suppressed; +} + +void ProviderManager::clear() +{ + d->m_providerTargets.clear(); + d->m_providers.clear(); +} + +void ProviderManager::slotLoadDefaultProvidersInternal() +{ + const auto providerFiles = d->m_internals->getDefaultProviderFiles(); + for (const QUrl &url : providerFiles) { + addProviderFile(url); + } + if (d->m_downloads.isEmpty()) { + Q_EMIT defaultProvidersLoaded(); + } +} + +QList ProviderManager::defaultProviderFiles() +{ + return d->m_internals->getDefaultProviderFiles(); +} + +ProviderManager::~ProviderManager() +{ + delete d; +} + +void ProviderManager::addProviderFileToDefaultProviders(const QUrl &url) +{ + d->m_internals->addDefaultProviderFile(url); + addProviderFile(url); +} + +void ProviderManager::removeProviderFileFromDefaultProviders(const QUrl &url) +{ + d->m_internals->removeDefaultProviderFile(url); +} + +void ProviderManager::addProviderFile(const QUrl &url) +{ + if (url.isLocalFile()) { + QFile file(url.toLocalFile()); + if (!file.open(QIODevice::ReadOnly)) { + qWarning() << "ProviderManager::addProviderFile: could not open provider file: " << url.toString(); + return; + } + parseProviderFile(QLatin1String(file.readAll()), url); + } else { + if (!d->m_downloads.contains(url.toString())) { + QNetworkRequest req(url); + req.setAttribute(QNetworkRequest::RedirectPolicyAttribute, QNetworkRequest::RedirectPolicy::NoLessSafeRedirectPolicy); + QNetworkReply *reply = d->m_internals->get(req); + qCDebug(ATTICA) << "executing" << Utils::toString(reply->operation()) << "for" << reply->url(); + connect(reply, &QNetworkReply::finished, this, [this, url]() { + fileFinished(url.toString()); + }); + d->m_downloads.insert(url.toString(), reply); + } + } +} + +void ProviderManager::fileFinished(const QString &url) +{ + QNetworkReply *reply = d->m_downloads.take(url); + if (reply) { + if (reply->error()) { + Q_EMIT failedToLoad(QUrl(url), reply->error()); + } else { + parseProviderFile(QLatin1String(reply->readAll()), QUrl(url)); + } + reply->deleteLater(); + } else { + Q_EMIT failedToLoad(QUrl(url), QNetworkReply::UnknownNetworkError); + } +} + +void ProviderManager::addProviderFromXml(const QString &providerXml) +{ + parseProviderFile(providerXml, QUrl()); +} + +void ProviderManager::parseProviderFile(const QString &xmlString, const QUrl &url) +{ + QXmlStreamReader xml(xmlString); + while (!xml.atEnd() && xml.readNext()) { + if (xml.isStartElement() && xml.name() == QLatin1String("provider")) { + QUrl baseUrl; + QString name; + QUrl icon; + QString person; + QString friendV; + QString message; + QString achievement; + QString activity; + QString content; + QString fan; + QString forum; + QString knowledgebase; + QString event; + QString comment; + QString registerUrl; + + while (!xml.atEnd() && xml.readNext()) { + if (xml.isStartElement()) { + if (xml.name() == QLatin1String("location")) { + baseUrl = QUrl(xml.readElementText()); + } else if (xml.name() == QLatin1String("name")) { + name = xml.readElementText(); + } else if (xml.name() == QLatin1String("icon")) { + icon = QUrl(xml.readElementText()); + } else if (xml.name() == QLatin1String("person")) { + person = xml.attributes().value(QLatin1String("ocsversion")).toString(); + } else if (xml.name() == QLatin1String("friend")) { + friendV = xml.attributes().value(QLatin1String("ocsversion")).toString(); + } else if (xml.name() == QLatin1String("message")) { + message = xml.attributes().value(QLatin1String("ocsversion")).toString(); + } else if (xml.name() == QLatin1String("achievement")) { + achievement = xml.attributes().value(QLatin1String("ocsversion")).toString(); + } else if (xml.name() == QLatin1String("activity")) { + activity = xml.attributes().value(QLatin1String("ocsversion")).toString(); + } else if (xml.name() == QLatin1String("content")) { + content = xml.attributes().value(QLatin1String("ocsversion")).toString(); + } else if (xml.name() == QLatin1String("fan")) { + fan = xml.attributes().value(QLatin1String("ocsversion")).toString(); + } else if (xml.name() == QLatin1String("forum")) { + forum = xml.attributes().value(QLatin1String("ocsversion")).toString(); + } else if (xml.name() == QLatin1String("knowledgebase")) { + knowledgebase = xml.attributes().value(QLatin1String("ocsversion")).toString(); + } else if (xml.name() == QLatin1String("event")) { + event = xml.attributes().value(QLatin1String("ocsversion")).toString(); + } else if (xml.name() == QLatin1String("comment")) { + comment = xml.attributes().value(QLatin1String("ocsversion")).toString(); + } else if (xml.name() == QLatin1String("register")) { + registerUrl = xml.readElementText(); + } + } else if (xml.isEndElement() && xml.name() == QLatin1String("provider")) { + break; + } + } + if (!baseUrl.isEmpty()) { + // qCDebug(ATTICA) << "Adding provider" << baseUrl; + d->m_providers.insert(baseUrl, + Provider(d->m_internals, + baseUrl, + name, + icon, + person, + friendV, + message, + achievement, + activity, + content, + fan, + forum, + knowledgebase, + event, + comment, + registerUrl)); + d->m_providerTargets[url] = baseUrl; + Q_EMIT providerAdded(d->m_providers.value(baseUrl)); + } + } + } + + if (xml.error() != QXmlStreamReader::NoError) { + qCDebug(ATTICA) << "error:" << xml.errorString() << "in" << url; + } + + if (d->m_downloads.isEmpty()) { + Q_EMIT defaultProvidersLoaded(); + } +} + +Provider ProviderManager::providerFor(const QUrl &url) const +{ + return providerByUrl(d->m_providerTargets.value(url)); +} + +Provider ProviderManager::providerByUrl(const QUrl &url) const +{ + return d->m_providers.value(url); +} + +QList ProviderManager::providers() const +{ + return d->m_providers.values(); +} + +QList ProviderManager::providerFiles() const +{ + return d->m_providerTargets.keys(); +} + +void ProviderManager::authenticate(QNetworkReply *reply, QAuthenticator *auth) +{ + QUrl baseUrl; + const QList urls = d->m_providers.keys(); + for (const QUrl &url : urls) { + if (url.isParentOf(reply->url())) { + baseUrl = url; + break; + } + } + + // qCDebug(ATTICA) << "ProviderManager::authenticate" << baseUrl; + + QString user; + QString password; + if (auth->user().isEmpty() && auth->password().isEmpty()) { + if (d->m_internals->hasCredentials(baseUrl)) { + if (d->m_internals->loadCredentials(baseUrl, user, password)) { + // qCDebug(ATTICA) << "ProviderManager::authenticate: loading authentication"; + auth->setUser(user); + auth->setPassword(password); + return; + } + } + } + + if (!d->m_authenticationSuppressed && d->m_internals->askForCredentials(baseUrl, user, password)) { + // qCDebug(ATTICA) << "ProviderManager::authenticate: asking internals for new credentials"; + // auth->setUser(user); + // auth->setPassword(password); + return; + } + + qWarning() << "ProviderManager::authenticate: No authentication credentials provided, aborting." << reply->url().toString(); + Q_EMIT authenticationCredentialsMissing(d->m_providers.value(baseUrl)); + reply->abort(); +} + +void ProviderManager::proxyAuthenticationRequired(const QNetworkProxy &proxy, QAuthenticator *authenticator) +{ + Q_UNUSED(proxy) + Q_UNUSED(authenticator) +} + +#include "moc_providermanager.cpp" diff --git a/local/recipes/kde/kf6-attica/source/src/providermanager.h b/local/recipes/kde/kf6-attica/source/src/providermanager.h new file mode 100644 index 00000000..71cdede0 --- /dev/null +++ b/local/recipes/kde/kf6-attica/source/src/providermanager.h @@ -0,0 +1,181 @@ +/* + This file is part of KDE. + + SPDX-FileCopyrightText: 2009 Eckhart Wörner + SPDX-FileCopyrightText: 2009 Frederik Gladhorn + + SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL +*/ + +#ifndef ATTICA_PROVIDERMANAGER_H +#define ATTICA_PROVIDERMANAGER_H + +#include +#include + +#include "attica_export.h" +#include "provider.h" + +/** + * The Attica namespace, + */ +namespace Attica +{ +/** + * @class ProviderManager providermanager.h + * + * Attica ProviderManager + * + * This class is the primary access to Attica's functions. + * Use the ProviderManager to load Open Collaboration Service providers, + * either the default system ones, or from XML or custom locations. + * + * \section providerfiles Provider Files + * Provider files are defined here: + * http://www.freedesktop.org/wiki/Specifications/open-collaboration-services + * + * \section basicuse Basic Use + * + * See addProviderFileToDefaultProviders(const QUrl &url) for an example of + * what the provider file sohuld look like. You can add providers to the + * ProviderManager as either raw XML data using addProviderFromXml(const QString &providerXml), + * or from a file somewhere on the system through addProviderFile(const QUrl &file), + * or you can simply load the default providers provided by your system + * (which generally means KDE's provider opendesktop.org). + * + * Importantly, to be able to detect when the ProviderManager is ready to + * manage things, before initialising it you will want to connect to the + * providerAdded(const Attica::Provider &provider) signal, which is fired + * every time a new provider is added to the manager. + * + * If you manually add all providers from XML, you can expect this to happen + * immediately. This means that once you have added your providers that way, + * you can access them through the providers() function, which returns + * a list of all loaded Providers. + * + * Once you have loaded a Provider, you can use its functions to access the + * services offered by that provider. + */ +class ATTICA_EXPORT ProviderManager : public QObject +{ + Q_OBJECT + +public: + enum ProviderFlag { + NoFlags = 0x0, + DisablePlugins = 0x1, + }; + Q_DECLARE_FLAGS(ProviderFlags, ProviderFlag) + + ProviderManager(const ProviderFlags &flags = NoFlags); + ~ProviderManager() override; + + /** + * Load available providers from configuration + */ + void loadDefaultProviders(); + + /** + * The list of provider files that get loaded by loadDefaultProviders. + * Each of these files can contain multiple providers. + * @return list of provider file urls + */ + QList defaultProviderFiles(); + + /** + * Add a provider file to the default providers (xml that contains provider descriptions). + Provider files contain information about each provider: +
+     
+     
+        opendesktop
+        https://api.opendesktop.org/v1/
+        openDesktop.org
+        
+        https://opendesktop.org/terms/
+        https://opendesktop.org/usermanager/new.php
+        
+            
+            
+            
+            
+            
+            
+            
+            
+        
+     
+     
+     
+ * @param url the url of the provider file + */ + void addProviderFileToDefaultProviders(const QUrl &url); + + void removeProviderFileFromDefaultProviders(const QUrl &url); + + /** + * Suppresses the authentication, so that the application can take care of authenticating itself + */ + void setAuthenticationSuppressed(bool suppressed); + + /** + * Remove all providers and provider files that have been loaded + */ + void clear(); + + /** + * Parse a xml file containing a provider description + */ + void addProviderFromXml(const QString &providerXml); + void addProviderFile(const QUrl &file); + QList providerFiles() const; + + /** + * @returns all loaded providers + */ + QList providers() const; + + /** + * @returns whether there's a provider with base url @p provider + */ + bool contains(const QUrl &provider) const; + + /** + * @returns the provider with @p url base url. + */ + Provider providerByUrl(const QUrl &url) const; + + /** + * @returns the provider for a given provider @p url. + */ + Provider providerFor(const QUrl &url) const; + +Q_SIGNALS: + void providerAdded(const Attica::Provider &provider); + void defaultProvidersLoaded(); + void authenticationCredentialsMissing(const Provider &provider); + void failedToLoad(const QUrl &provider, QNetworkReply::NetworkError error); + +private Q_SLOTS: + ATTICA_NO_EXPORT void fileFinished(const QString &url); + ATTICA_NO_EXPORT void authenticate(QNetworkReply *, QAuthenticator *); + ATTICA_NO_EXPORT void proxyAuthenticationRequired(const QNetworkProxy &proxy, QAuthenticator *authenticator); + ATTICA_NO_EXPORT void slotLoadDefaultProvidersInternal(); + +private: + ProviderManager(const ProviderManager &other) = delete; + ProviderManager &operator=(const ProviderManager &other) = delete; + + ATTICA_NO_EXPORT PlatformDependent *loadPlatformDependent(const ProviderFlags &flags); + + ATTICA_NO_EXPORT void parseProviderFile(const QString &xmlString, const QUrl &url); + + class Private; + Private *const d; +}; + +Q_DECLARE_OPERATORS_FOR_FLAGS(ProviderManager::ProviderFlags) + +} + +#endif diff --git a/local/recipes/kde/kf6-attica/source/src/publisher.cpp b/local/recipes/kde/kf6-attica/source/src/publisher.cpp new file mode 100644 index 00000000..255e7c90 --- /dev/null +++ b/local/recipes/kde/kf6-attica/source/src/publisher.cpp @@ -0,0 +1,100 @@ +/* + This file is part of KDE. + + SPDX-FileCopyrightText: 2010 Sebastian Kügler + + SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL +*/ + +#include "publisher.h" + +using namespace Attica; + +class Q_DECL_HIDDEN Publisher::Private : public QSharedData +{ +public: + QString id; + QString name; + QString url; + QList fields; + QList targets; + + Private() + { + } +}; + +Publisher::Publisher() + : d(new Private) +{ +} + +Publisher::Publisher(const Publisher &other) + : d(other.d) +{ +} + +Publisher &Publisher::operator=(const Attica::Publisher &other) +{ + d = other.d; + return *this; +} + +Publisher::~Publisher() +{ +} + +void Publisher::setId(const QString &u) +{ + d->id = u; +} + +QString Publisher::id() const +{ + return d->id; +} + +void Publisher::setName(const QString &u) +{ + d->name = u; +} + +QString Publisher::name() const +{ + return d->name; +} + +void Publisher::addField(const Field &t) +{ + d->fields << t; +} + +QList Publisher::fields() const +{ + return d->fields; +} + +void Publisher::setUrl(const QString &u) +{ + d->url = u; +} + +QString Publisher::url() const +{ + return d->url; +} + +void Publisher::addTarget(const Attica::Target &t) +{ + d->targets << t; +} + +QList Publisher::targets() const +{ + return d->targets; +} + +bool Publisher::isValid() const +{ + return !(d->id.isEmpty()); +} diff --git a/local/recipes/kde/kf6-attica/source/src/publisher.h b/local/recipes/kde/kf6-attica/source/src/publisher.h new file mode 100644 index 00000000..eb42bb5e --- /dev/null +++ b/local/recipes/kde/kf6-attica/source/src/publisher.h @@ -0,0 +1,78 @@ +/* + This file is part of KDE. + + SPDX-FileCopyrightText: 2010 Sebastian Kügler + + SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL +*/ + +#ifndef ATTICA_PUBLISHER_H +#define ATTICA_PUBLISHER_H + +#include +#include +#include +#include +#include +#include + +#include "attica_export.h" +#include "buildservice.h" + +namespace Attica +{ + +/** + * @class Field publisher.h + * + * Field as set for the class Publisher. + */ +struct Field { + QString type; + QString name; + int fieldsize; + bool required; + QStringList options; +}; + +/** + * @class Publisher publisher.h + * + * Represents a publisher. + */ +class ATTICA_EXPORT Publisher +{ +public: + typedef QList List; + class Parser; + + Publisher(); + Publisher(const Publisher &other); + Publisher &operator=(const Publisher &other); + ~Publisher(); + + void setId(const QString &); + QString id() const; + + void setName(const QString &); + QString name() const; + + void setUrl(const QString &); + QString url() const; + + void addField(const Field &); + QList fields() const; + + void addTarget(const Target &); + QList targets() const; + + bool isValid() const; + +private: + class Private; + QSharedDataPointer d; +}; + +} + +#endif diff --git a/local/recipes/kde/kf6-attica/source/src/publisherfield.cpp b/local/recipes/kde/kf6-attica/source/src/publisherfield.cpp new file mode 100644 index 00000000..0bfef886 --- /dev/null +++ b/local/recipes/kde/kf6-attica/source/src/publisherfield.cpp @@ -0,0 +1,78 @@ +/* + This file is part of KDE. + + SPDX-FileCopyrightText: 2011 Dan Leinir Turthra Jensen + + SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL + */ + +#include "publisherfield.h" + +using namespace Attica; + +class Q_DECL_HIDDEN PublisherField::Private : public QSharedData +{ +public: + QString name; + QString type; + QString data; + + Private() + { + } +}; + +PublisherField::PublisherField() + : d(new Private) +{ +} + +PublisherField::PublisherField(const PublisherField &other) + : d(other.d) +{ +} + +PublisherField &PublisherField::operator=(const Attica::PublisherField &other) +{ + d = other.d; + return *this; +} + +PublisherField::~PublisherField() +{ +} + +void PublisherField::setName(const QString &value) +{ + d->name = value; +} + +QString PublisherField::name() const +{ + return d->name; +} + +void PublisherField::setType(const QString &value) +{ + d->type = value; +} + +QString PublisherField::type() const +{ + return d->type; +} + +void PublisherField::setData(const QString &value) +{ + d->data = value; +} + +QString PublisherField::data() const +{ + return d->data; +} + +bool PublisherField::isValid() const +{ + return true; +} diff --git a/local/recipes/kde/kf6-attica/source/src/publisherfield.h b/local/recipes/kde/kf6-attica/source/src/publisherfield.h new file mode 100644 index 00000000..08c97ccf --- /dev/null +++ b/local/recipes/kde/kf6-attica/source/src/publisherfield.h @@ -0,0 +1,52 @@ +/* + This file is part of KDE. + + SPDX-FileCopyrightText: 2011 Dan Leinir Turthra Jensen + + SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL + */ + +#ifndef PUBLISHERFIELD_H +#define PUBLISHERFIELD_H + +#include "attica_export.h" +#include "buildservice.h" + +namespace Attica +{ + +/** + * @class PublisherField publisherfield.h + * + * Represents a publisher field. + */ +class ATTICA_EXPORT PublisherField +{ +public: + typedef QList List; + class Parser; + + PublisherField(); + PublisherField(const PublisherField &other); + PublisherField &operator=(const PublisherField &other); + ~PublisherField(); + + void setName(const QString &value); + QString name() const; + + void setType(const QString &value); + QString type() const; + + void setData(const QString &value); + QString data() const; + + bool isValid() const; + +private: + class Private; + QSharedDataPointer d; +}; + +} // namespace Attica + +#endif // PUBLISHERFIELD_H diff --git a/local/recipes/kde/kf6-attica/source/src/publisherfieldparser.cpp b/local/recipes/kde/kf6-attica/source/src/publisherfieldparser.cpp new file mode 100644 index 00000000..7c60c725 --- /dev/null +++ b/local/recipes/kde/kf6-attica/source/src/publisherfieldparser.cpp @@ -0,0 +1,37 @@ +/* + This file is part of KDE. + + SPDX-FileCopyrightText: 2011 Dan Leinir Turthra Jensen + + SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL + */ + +#include "publisherfieldparser.h" + +using namespace Attica; + +PublisherField PublisherField::Parser::parseXml(QXmlStreamReader &xml) +{ + PublisherField fld; + while (!xml.atEnd()) { + xml.readNextStartElement(); + if (xml.isStartElement()) { + if (xml.name() == QLatin1String("fieldtype")) { + fld.setType(xml.readElementText()); + } else if (xml.name() == QLatin1String("name")) { + fld.setName(xml.readElementText()); + } else if (xml.name() == QLatin1String("data")) { + fld.setData(xml.readElementText()); + } + } else if (xml.isEndElement() && (xml.name() == QLatin1String("field"))) { + xml.readNext(); + break; + } + } + return fld; +} + +QStringList PublisherField::Parser::xmlElement() const +{ + return QStringList(QStringLiteral("field")); +} diff --git a/local/recipes/kde/kf6-attica/source/src/publisherfieldparser.h b/local/recipes/kde/kf6-attica/source/src/publisherfieldparser.h new file mode 100644 index 00000000..84d608e1 --- /dev/null +++ b/local/recipes/kde/kf6-attica/source/src/publisherfieldparser.h @@ -0,0 +1,26 @@ +/* + This file is part of KDE. + + SPDX-FileCopyrightText: 2011 Dan Leinir Turthra Jensen + + SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL + */ + +#ifndef PUBLISHERFIELDPARSER_H +#define PUBLISHERFIELDPARSER_H + +#include "parser.h" +#include "publisherfield.h" + +namespace Attica +{ +class Q_DECL_HIDDEN PublisherField::Parser : public Attica::Parser +{ +private: + PublisherField parseXml(QXmlStreamReader &xml) override; + QStringList xmlElement() const override; +}; + +} // namespace Attica + +#endif // PUBLISHERFIELDPARSER_H diff --git a/local/recipes/kde/kf6-attica/source/src/publisherparser.cpp b/local/recipes/kde/kf6-attica/source/src/publisherparser.cpp new file mode 100644 index 00000000..f0f1d9f6 --- /dev/null +++ b/local/recipes/kde/kf6-attica/source/src/publisherparser.cpp @@ -0,0 +1,101 @@ +/* + This file is part of KDE. + + SPDX-FileCopyrightText: 2010 Sebastian Kügler + + SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL +*/ + +#include "publisherparser.h" +#include + +using namespace Attica; + +Publisher Publisher::Parser::parseXml(QXmlStreamReader &xml) +{ + // For specs about the XML provided, see here: + // http://www.freedesktop.org/wiki/Specifications/open-collaboration-services-draft + + Publisher publisher; + QStringList fields; + + while (!xml.atEnd()) { + // qCDebug(ATTICA) << "XML returned:" << xml.text().toString(); + xml.readNext(); + + if (xml.isStartElement()) { + if (xml.name() == QLatin1String("id")) { + publisher.setId(xml.readElementText()); + } else if (xml.name() == QLatin1String("name")) { + publisher.setName(xml.readElementText()); + } else if (xml.name() == QLatin1String("registrationurl")) { + publisher.setUrl(xml.readElementText()); + } else if (xml.name() == QLatin1String("fields")) { + while (!xml.atEnd()) { + xml.readNextStartElement(); + if (xml.isStartElement()) { + if (xml.name() == QLatin1String("field")) { + Field t; + while (!xml.atEnd()) { + xml.readNextStartElement(); + if (xml.isStartElement()) { + if (xml.name() == QLatin1String("fieldtype")) { + t.type = xml.readElementText(); + } else if (xml.name() == QLatin1String("name")) { + t.name = xml.readElementText(); + } else if (xml.name() == QLatin1String("fieldsize")) { + t.fieldsize = xml.readElementText().toInt(); + } else if (xml.name() == QLatin1String("required")) { + t.required = xml.readElementText() == QLatin1String("true"); + } else if (xml.name() == QLatin1String("options")) { + while (!xml.atEnd()) { + xml.readNextStartElement(); + if (xml.isStartElement()) { + if (xml.name() == QLatin1String("option")) { + t.options << xml.readElementText(); + } + } else if (xml.isEndElement() && xml.name() == QLatin1String("options")) { + xml.readNext(); + break; + } + } + } + } else if (xml.isEndElement() && (xml.name() == QLatin1String("field"))) { + xml.readNext(); + break; + } + } + publisher.addField(t); + } + } else if (xml.isEndElement() && (xml.name() == QLatin1String("fields"))) { + xml.readNext(); + break; + } + } + } else if (xml.name() == QLatin1String("supportedtargets")) { + while (!xml.atEnd()) { + xml.readNextStartElement(); + if (xml.isStartElement()) { + if (xml.name() == QLatin1String("target")) { + Target t; + t.name = xml.readElementText(); + publisher.addTarget(t); + } + } else if (xml.isEndElement() && (xml.name() == QLatin1String("supportedtargets"))) { + xml.readNext(); + break; + } + } + } + } else if (xml.isEndElement() // + && (xml.name() == QLatin1String("publisher") || xml.name() == QLatin1String("user"))) { + break; + } + } + return publisher; +} + +QStringList Publisher::Parser::xmlElement() const +{ + return QStringList(QStringLiteral("publisher")) << QStringLiteral("user"); +} diff --git a/local/recipes/kde/kf6-attica/source/src/publisherparser.h b/local/recipes/kde/kf6-attica/source/src/publisherparser.h new file mode 100644 index 00000000..7f4806eb --- /dev/null +++ b/local/recipes/kde/kf6-attica/source/src/publisherparser.h @@ -0,0 +1,26 @@ +/* + This file is part of KDE. + + SPDX-FileCopyrightText: 2010 Sebastian Kügler + + SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL +*/ + +#ifndef ATTICA_PUBLISHERPARSER_H +#define ATTICA_PUBLISHERPARSER_H + +#include "parser.h" +#include "publisher.h" + +namespace Attica +{ +class Q_DECL_HIDDEN Publisher::Parser : public Attica::Parser +{ +private: + Publisher parseXml(QXmlStreamReader &xml) override; + QStringList xmlElement() const override; +}; + +} + +#endif diff --git a/local/recipes/kde/kf6-attica/source/src/putjob.cpp b/local/recipes/kde/kf6-attica/source/src/putjob.cpp new file mode 100644 index 00000000..f5f63b7f --- /dev/null +++ b/local/recipes/kde/kf6-attica/source/src/putjob.cpp @@ -0,0 +1,114 @@ +/* + This file is part of KDE. + + SPDX-FileCopyrightText: 2011 Laszlo Papp + + SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL +*/ + +#include "putjob.h" + +#include +#include + +#include + +#include "platformdependent_v2.h" + +using namespace Attica; + +PutJob::PutJob(PlatformDependent *internals, const QNetworkRequest &request, QIODevice *iodevice) + : BaseJob(internals) + , m_ioDevice(iodevice) + , m_request(request) +{ +} + +Attica::PutJob::PutJob(PlatformDependent *internals, const QNetworkRequest &request, const QByteArray &byteArray) + : BaseJob(internals) + , m_ioDevice(nullptr) + , m_byteArray(byteArray) + , m_request(request) +{ +} + +PutJob::PutJob(PlatformDependent *internals, const QNetworkRequest &request, const StringMap ¶meters) + : BaseJob(internals) + , m_ioDevice(nullptr) + , m_request(request) +{ + // Create put data + int j = 0; + for (StringMap::const_iterator i = parameters.begin(); i != parameters.end(); ++i) { + if (j++ > 0) { + m_byteArray.append('&'); + } + m_byteArray.append(QUrl::toPercentEncoding(i.key())); + m_byteArray.append('='); + m_byteArray.append(QUrl::toPercentEncoding(i.value())); + } +} + +QNetworkReply *PutJob::executeRequest() +{ + Attica::PlatformDependentV2 *platformDependentV2 = dynamic_cast(internals()); + if (!platformDependentV2) { + return nullptr; + } + + if (m_ioDevice) { + return platformDependentV2->put(m_request, m_ioDevice); + } else { + return platformDependentV2->put(m_request, m_byteArray); + } +} + +void PutJob::parse(const QString &xmlString) +{ + // qCDebug(ATTICA) << "PutJob::parse" << xmlString; + QXmlStreamReader xml(xmlString); + Metadata data; + while (!xml.atEnd()) { + xml.readNext(); + + if (xml.isStartElement()) { + if (xml.name() == QLatin1String("meta")) { + while (!xml.atEnd()) { + xml.readNext(); + if (xml.isEndElement() && xml.name() == QLatin1String("meta")) { + break; + } else if (xml.isStartElement()) { + if (xml.name() == QLatin1String("status")) { + data.setStatusString(xml.readElementText()); + } else if (xml.name() == QLatin1String("statuscode")) { + data.setStatusCode(xml.readElementText().toInt()); + } else if (xml.name() == QLatin1String("message")) { + data.setMessage(xml.readElementText()); + } else if (xml.name() == QLatin1String("totalitems")) { + data.setTotalItems(xml.readElementText().toInt()); + } else if (xml.name() == QLatin1String("itemsperpage")) { + data.setItemsPerPage(xml.readElementText().toInt()); + } + } + } + } else if (xml.name() == QLatin1String("data")) { + while (!xml.atEnd()) { + xml.readNext(); + if (xml.isEndElement() && xml.name() == QLatin1String("data")) { + break; + } else if (xml.isStartElement()) { + if (xml.name() == QLatin1String("projectid")) { + data.setResultingId(xml.readElementText()); + } + if (xml.name() == QLatin1String("buildjobid")) { + data.setResultingId(xml.readElementText()); + } + } + } + } + } + } + setMetadata(data); +} + +#include "moc_putjob.cpp" diff --git a/local/recipes/kde/kf6-attica/source/src/putjob.h b/local/recipes/kde/kf6-attica/source/src/putjob.h new file mode 100644 index 00000000..2d85d964 --- /dev/null +++ b/local/recipes/kde/kf6-attica/source/src/putjob.h @@ -0,0 +1,56 @@ +/* + This file is part of KDE. + + SPDX-FileCopyrightText: 2011 Laszlo Papp + + SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL + */ + +#ifndef ATTICA_PUTJOB_H +#define ATTICA_PUTJOB_H + +#include + +#include "attica_export.h" +#include "atticabasejob.h" + +// workaround to get initialization working with gcc < 4.4 +typedef QMap StringMap; + +namespace Attica +{ +class Provider; + +/** + * @class PutJob putjob.h + * + * Represents a put job. + */ +class ATTICA_EXPORT PutJob : public BaseJob +{ + Q_OBJECT + +protected: + PutJob(PlatformDependent *internals, const QNetworkRequest &request, QIODevice *data); + PutJob(PlatformDependent *internals, const QNetworkRequest &request, const StringMap ¶meters = StringMap()); + PutJob(PlatformDependent *internals, const QNetworkRequest &request, const QByteArray &byteArray); + +private: + QNetworkReply *executeRequest() override; + void parse(const QString &) override; + + QIODevice *m_ioDevice; + QByteArray m_byteArray; + + QString m_responseData; + const QNetworkRequest m_request; + + QString m_status; + QString m_statusMessage; + + friend class Attica::Provider; +}; + +} + +#endif diff --git a/local/recipes/kde/kf6-attica/source/src/qtplatformdependent.cpp b/local/recipes/kde/kf6-attica/source/src/qtplatformdependent.cpp new file mode 100644 index 00000000..50f75476 --- /dev/null +++ b/local/recipes/kde/kf6-attica/source/src/qtplatformdependent.cpp @@ -0,0 +1,172 @@ +/* + This file is part of KDE. + + SPDX-FileCopyrightText: 2009 Eckhart Wörner + SPDX-FileCopyrightText: 2011 Laszlo Papp + SPDX-FileCopyrightText: 2012 Jeff Mitchell + + SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL +*/ + +#include "qtplatformdependent_p.h" + +#include +#include +#include + +using namespace Attica; + +QtPlatformDependent::QtPlatformDependent() +{ + m_threadNamHash[QThread::currentThread()] = new QNetworkAccessManager(); + m_ourNamSet.insert(QThread::currentThread()); + QMetaObject::invokeMethod(this, &QtPlatformDependent::readyChanged, Qt::QueuedConnection); +} + +QtPlatformDependent::~QtPlatformDependent() +{ + QThread *currThread = QThread::currentThread(); + if (m_threadNamHash.contains(currThread)) { + if (m_ourNamSet.contains(currThread)) { + delete m_threadNamHash[currThread]; + } + m_threadNamHash.remove(currThread); + m_ourNamSet.remove(currThread); + } +} + +void QtPlatformDependent::setNam(QNetworkAccessManager *nam) +{ + if (!nam) { + return; + } + + QMutexLocker l(&m_accessMutex); + QThread *currThread = QThread::currentThread(); + QNetworkAccessManager *oldNam = nullptr; + if (m_threadNamHash.contains(currThread) && m_ourNamSet.contains(currThread)) { + oldNam = m_threadNamHash[currThread]; + } + + if (oldNam == nam) { + // If we're being passed back our own NAM, assume they want to + // ensure that we don't delete it out from under them + m_ourNamSet.remove(currThread); + return; + } + + m_threadNamHash[currThread] = nam; + m_ourNamSet.remove(currThread); + + if (oldNam) { + delete oldNam; + } +} + +QNetworkAccessManager *QtPlatformDependent::nam() +{ + QMutexLocker l(&m_accessMutex); + QThread *currThread = QThread::currentThread(); + if (!m_threadNamHash.contains(currThread)) { + QNetworkAccessManager *newNam = new QNetworkAccessManager(); + m_threadNamHash[currThread] = newNam; + m_ourNamSet.insert(currThread); + return newNam; + } + + return m_threadNamHash[currThread]; +} + +// TODO actually save and restore providers! +QList Attica::QtPlatformDependent::getDefaultProviderFiles() const +{ + // Return the defaultiest default provider (since that's what our documentation says we'll do) + return QList{QUrl(QStringLiteral("https://autoconfig.kde.org/ocs/providers.xml"))}; +} + +void QtPlatformDependent::addDefaultProviderFile(const QUrl &) +{ + qWarning() << "attica-qt does not support default providers yet"; +} + +void QtPlatformDependent::removeDefaultProviderFile(const QUrl &) +{ +} + +void QtPlatformDependent::enableProvider(const QUrl &baseUrl, bool enabled) const +{ + Q_UNUSED(baseUrl) + Q_UNUSED(enabled) + qWarning() << "attica-qt does not support disabling of providers yet"; +} + +bool QtPlatformDependent::isEnabled(const QUrl &baseUrl) const +{ + Q_UNUSED(baseUrl) + return true; +} + +QNetworkReply *QtPlatformDependent::post(const QNetworkRequest &request, const QByteArray &data) +{ + return nam()->post(request, data); +} + +QNetworkReply *QtPlatformDependent::post(const QNetworkRequest &request, QIODevice *data) +{ + return nam()->post(request, data); +} + +QNetworkReply *QtPlatformDependent::put(const QNetworkRequest &request, const QByteArray &data) +{ + return nam()->put(request, data); +} + +QNetworkReply *QtPlatformDependent::put(const QNetworkRequest &request, QIODevice *data) +{ + return nam()->put(request, data); +} + +QNetworkReply *QtPlatformDependent::get(const QNetworkRequest &request) +{ + return nam()->get(request); +} + +QNetworkReply *QtPlatformDependent::deleteResource(const QNetworkRequest &request) +{ + return nam()->deleteResource(request); +} + +bool QtPlatformDependent::hasCredentials(const QUrl &baseUrl) const +{ + return m_passwords.contains(baseUrl.toString()); +} + +bool QtPlatformDependent::saveCredentials(const QUrl &baseUrl, const QString &user, const QString &password) +{ + m_passwords[baseUrl.toString()] = QPair(user, password); + return true; +} + +bool QtPlatformDependent::loadCredentials(const QUrl &baseUrl, QString &user, QString &password) +{ + if (!hasCredentials(baseUrl)) { + return false; + } + QPair userPass = m_passwords.value(baseUrl.toString()); + user = userPass.first; + password = userPass.second; + return true; +} + +bool Attica::QtPlatformDependent::askForCredentials(const QUrl &baseUrl, QString &user, QString &password) +{ + Q_UNUSED(baseUrl) + Q_UNUSED(user) + Q_UNUSED(password) + return false; +} + +bool Attica::QtPlatformDependent::isReady() +{ + return true; +} diff --git a/local/recipes/kde/kf6-attica/source/src/qtplatformdependent_p.h b/local/recipes/kde/kf6-attica/source/src/qtplatformdependent_p.h new file mode 100644 index 00000000..4cc6a17f --- /dev/null +++ b/local/recipes/kde/kf6-attica/source/src/qtplatformdependent_p.h @@ -0,0 +1,60 @@ +/* + This file is part of KDE. + + SPDX-FileCopyrightText: 2009 Eckhart Wörner + SPDX-FileCopyrightText: 2011 Laszlo Papp + SPDX-FileCopyrightText: 2012 Jeff Mitchell + + SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL +*/ + +#ifndef ATTICA_QTPLATFORMDEPENDENT_P_H +#define ATTICA_QTPLATFORMDEPENDENT_P_H + +#include "platformdependent_v3.h" + +#include +#include +#include +#include +#include + +namespace Attica +{ +class QtPlatformDependent : public Attica::PlatformDependentV3 +{ +public: + QtPlatformDependent(); + ~QtPlatformDependent() override; + + void setNam(QNetworkAccessManager *nam) override; + QNetworkAccessManager *nam() override; + + QList getDefaultProviderFiles() const override; + void addDefaultProviderFile(const QUrl &url) override; + void removeDefaultProviderFile(const QUrl &url) override; + void enableProvider(const QUrl &baseUrl, bool enabled) const override; + bool isEnabled(const QUrl &baseUrl) const override; + + QNetworkReply *post(const QNetworkRequest &request, const QByteArray &data) override; + QNetworkReply *post(const QNetworkRequest &request, QIODevice *data) override; + QNetworkReply *get(const QNetworkRequest &request) override; + bool hasCredentials(const QUrl &baseUrl) const override; + bool saveCredentials(const QUrl &baseUrl, const QString &user, const QString &password) override; + bool loadCredentials(const QUrl &baseUrl, QString &user, QString &password) override; + bool askForCredentials(const QUrl &baseUrl, QString &user, QString &password) override; + QNetworkReply *deleteResource(const QNetworkRequest &request) override; + QNetworkReply *put(const QNetworkRequest &request, const QByteArray &data) override; + QNetworkReply *put(const QNetworkRequest &request, QIODevice *data) override; + [[nodiscard]] bool isReady() override; + +private: + QMutex m_accessMutex; + QHash m_threadNamHash; + QSet m_ourNamSet; + QHash> m_passwords; +}; + +} + +#endif diff --git a/local/recipes/kde/kf6-attica/source/src/remoteaccount.cpp b/local/recipes/kde/kf6-attica/source/src/remoteaccount.cpp new file mode 100644 index 00000000..6af2cb77 --- /dev/null +++ b/local/recipes/kde/kf6-attica/source/src/remoteaccount.cpp @@ -0,0 +1,111 @@ +/* + This file is part of KDE. + + SPDX-FileCopyrightText: 2010 Sebastian Kügler + + SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL +*/ + +#include "remoteaccount.h" + +using namespace Attica; + +class Q_DECL_HIDDEN RemoteAccount::Private : public QSharedData +{ +public: + QString id; + QString type; + QString remoteServiceId; + QString data; + QString login; + QString password; + + Private() + { + } +}; + +RemoteAccount::RemoteAccount() + : d(new Private) +{ +} + +RemoteAccount::RemoteAccount(const RemoteAccount &other) + : d(other.d) +{ +} + +RemoteAccount &RemoteAccount::operator=(const Attica::RemoteAccount &other) +{ + d = other.d; + return *this; +} + +RemoteAccount::~RemoteAccount() +{ +} + +void RemoteAccount::setId(const QString &u) +{ + d->id = u; +} + +QString RemoteAccount::id() const +{ + return d->id; +} + +void RemoteAccount::setType(const QString &arg) +{ + d->type = arg; +} + +QString RemoteAccount::type() const +{ + return d->type; +} + +void RemoteAccount::setRemoteServiceId(const QString &arg) +{ + d->remoteServiceId = arg; +} + +QString RemoteAccount::remoteServiceId() const +{ + return d->remoteServiceId; +} + +void RemoteAccount::setData(const QString &arg) +{ + d->data = arg; +} + +QString RemoteAccount::data() const +{ + return d->data; +} + +void RemoteAccount::setLogin(const QString &arg) +{ + d->login = arg; +} + +QString RemoteAccount::login() const +{ + return d->login; +} + +void RemoteAccount::setPassword(const QString &arg) +{ + d->password = arg; +} + +QString RemoteAccount::password() const +{ + return d->password; +} + +bool RemoteAccount::isValid() const +{ + return !(d->id.isEmpty()); +} diff --git a/local/recipes/kde/kf6-attica/source/src/remoteaccount.h b/local/recipes/kde/kf6-attica/source/src/remoteaccount.h new file mode 100644 index 00000000..f95838e7 --- /dev/null +++ b/local/recipes/kde/kf6-attica/source/src/remoteaccount.h @@ -0,0 +1,67 @@ +/* + This file is part of KDE. + + SPDX-FileCopyrightText: 2010 Sebastian Kügler + + SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL +*/ + +#ifndef ATTICA_REMOTEACCOUNT_H +#define ATTICA_REMOTEACCOUNT_H + +#include +#include +#include +#include +#include +#include + +#include "attica_export.h" + +namespace Attica +{ + +/** + * @class RemoteAccount remoteaccount.h + * + * Represents a remote account. + */ +class ATTICA_EXPORT RemoteAccount +{ +public: + typedef QList List; + class Parser; + + RemoteAccount(); + RemoteAccount(const RemoteAccount &other); + RemoteAccount &operator=(const RemoteAccount &other); + ~RemoteAccount(); + + void setId(const QString &); + QString id() const; + + void setType(const QString &); + QString type() const; + + void setRemoteServiceId(const QString &); + QString remoteServiceId() const; + + void setData(const QString &); + QString data() const; + + void setLogin(const QString &); + QString login() const; + + void setPassword(const QString &); + QString password() const; + + bool isValid() const; + +private: + class Private; + QSharedDataPointer d; +}; + +} + +#endif diff --git a/local/recipes/kde/kf6-attica/source/src/remoteaccountparser.cpp b/local/recipes/kde/kf6-attica/source/src/remoteaccountparser.cpp new file mode 100644 index 00000000..2ee3e703 --- /dev/null +++ b/local/recipes/kde/kf6-attica/source/src/remoteaccountparser.cpp @@ -0,0 +1,48 @@ +/* + This file is part of KDE. + + SPDX-FileCopyrightText: 2010 Sebastian Kügler + + SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL +*/ + +#include "remoteaccountparser.h" +#include + +using namespace Attica; + +RemoteAccount RemoteAccount::Parser::parseXml(QXmlStreamReader &xml) +{ + RemoteAccount remoteaccount; + + // For specs about the XML provided, see here: + // http://www.freedesktop.org/wiki/Specifications/open-collaboration-services-draft#RemoteAccounts + while (!xml.atEnd()) { + // qCDebug(ATTICA) << "XML returned:" << xml.text().toString(); + xml.readNext(); + + if (xml.isStartElement()) { + if (xml.name() == QLatin1String("id")) { + remoteaccount.setId(xml.readElementText()); + } else if (xml.name() == QLatin1String("type")) { + remoteaccount.setType(xml.readElementText()); + } else if (xml.name() == QLatin1String("typeid")) { // FIXME: change to remoteserviceid sometime soon (OCS API change pending + remoteaccount.setRemoteServiceId(xml.readElementText()); + } else if (xml.name() == QLatin1String("data")) { + remoteaccount.setData(xml.readElementText()); + } else if (xml.name() == QLatin1String("login")) { + remoteaccount.setLogin(xml.readElementText()); + } else if (xml.name() == QLatin1String("password")) { + remoteaccount.setPassword(xml.readElementText()); + } + } else if (xml.isEndElement() && (xml.name() == QLatin1String("remoteaccount") || xml.name() == QLatin1String("user"))) { + break; + } + } + return remoteaccount; +} + +QStringList RemoteAccount::Parser::xmlElement() const +{ + return QStringList(QStringLiteral("remoteaccount")) << QStringLiteral("user"); +} diff --git a/local/recipes/kde/kf6-attica/source/src/remoteaccountparser.h b/local/recipes/kde/kf6-attica/source/src/remoteaccountparser.h new file mode 100644 index 00000000..9fbd012b --- /dev/null +++ b/local/recipes/kde/kf6-attica/source/src/remoteaccountparser.h @@ -0,0 +1,26 @@ +/* + This file is part of KDE. + + SPDX-FileCopyrightText: 2010 Sebastian Kügler + + SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL +*/ + +#ifndef ATTICA_REMOTEACCOUNTPARSER_H +#define ATTICA_REMOTEACCOUNTPARSER_H + +#include "parser.h" +#include "remoteaccount.h" + +namespace Attica +{ +class Q_DECL_HIDDEN RemoteAccount::Parser : public Attica::Parser +{ +private: + RemoteAccount parseXml(QXmlStreamReader &xml) override; + QStringList xmlElement() const override; +}; + +} + +#endif diff --git a/local/recipes/kde/kf6-attica/source/src/topic.cpp b/local/recipes/kde/kf6-attica/source/src/topic.cpp new file mode 100644 index 00000000..ac7c1ae3 --- /dev/null +++ b/local/recipes/kde/kf6-attica/source/src/topic.cpp @@ -0,0 +1,123 @@ +/* + This file is part of KDE. + + SPDX-FileCopyrightText: 2011 Laszlo Papp + + SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL +*/ + +#include "topic.h" + +using namespace Attica; + +class Q_DECL_HIDDEN Topic::Private : public QSharedData +{ +public: + QString m_id; + QString m_forumId; + QString m_user; + QDateTime m_date; + QString m_subject; + QString m_content; + int m_comments; + + Private() + : m_comments(0) + { + } +}; + +Topic::Topic() + : d(new Private) +{ +} + +Topic::Topic(const Topic &other) + : d(other.d) +{ +} + +Topic &Topic::operator=(const Topic &other) +{ + d = other.d; + return *this; +} + +Topic::~Topic() +{ +} + +void Topic::setId(const QString &id) +{ + d->m_id = id; +} + +QString Topic::id() const +{ + return d->m_id; +} + +void Topic::setForumId(const QString &forumId) +{ + d->m_forumId = forumId; +} + +QString Topic::forumId() const +{ + return d->m_forumId; +} + +void Topic::setUser(const QString &user) +{ + d->m_user = user; +} + +QString Topic::user() const +{ + return d->m_user; +} + +void Topic::setDate(const QDateTime &date) +{ + d->m_date = date; +} + +QDateTime Topic::date() const +{ + return d->m_date; +} + +void Topic::setSubject(const QString &subject) +{ + d->m_subject = subject; +} + +QString Topic::subject() const +{ + return d->m_subject; +} + +void Topic::setContent(const QString &content) +{ + d->m_content = content; +} + +QString Topic::content() const +{ + return d->m_content; +} + +void Topic::setComments(const int comments) +{ + d->m_comments = comments; +} + +int Topic::comments() const +{ + return d->m_comments; +} + +bool Topic::isValid() const +{ + return !(d->m_id.isEmpty()); +} diff --git a/local/recipes/kde/kf6-attica/source/src/topic.h b/local/recipes/kde/kf6-attica/source/src/topic.h new file mode 100644 index 00000000..04e9cdab --- /dev/null +++ b/local/recipes/kde/kf6-attica/source/src/topic.h @@ -0,0 +1,66 @@ +/* + This file is part of KDE. + + SPDX-FileCopyrightText: 2011 Laszlo Papp + + SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL +*/ + +#ifndef ATTICA_TOPIC_H +#define ATTICA_TOPIC_H + +#include "attica_export.h" + +#include +#include + +namespace Attica +{ + +/** + * @class Topic topic.h + * + * Represents a topic. + */ +class ATTICA_EXPORT Topic +{ +public: + typedef QList List; + class Parser; + + Topic(); + Topic(const Topic &other); + Topic &operator=(const Topic &other); + ~Topic(); + + void setId(const QString &id); + QString id() const; + + void setForumId(const QString &forumId); + QString forumId() const; + + void setUser(const QString &user); + QString user() const; + + void setDate(const QDateTime &date); + QDateTime date() const; + + void setSubject(const QString &subject); + QString subject() const; + + void setContent(const QString &content); + QString content() const; + + void setComments(const int comments); + int comments() const; + + bool isValid() const; + +private: + class Private; + QSharedDataPointer d; +}; + +} + +#endif diff --git a/local/recipes/kde/kf6-attica/source/src/topicparser.cpp b/local/recipes/kde/kf6-attica/source/src/topicparser.cpp new file mode 100644 index 00000000..af82c726 --- /dev/null +++ b/local/recipes/kde/kf6-attica/source/src/topicparser.cpp @@ -0,0 +1,48 @@ +/* + This file is part of KDE. + + SPDX-FileCopyrightText: 2011 Laszlo Papp + + SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL +*/ + +#include "topicparser.h" +#include "atticautils.h" + +using namespace Attica; + +Topic Topic::Parser::parseXml(QXmlStreamReader &xml) +{ + Topic topic; + + while (!xml.atEnd()) { + xml.readNext(); + + if (xml.isStartElement()) { + if (xml.name() == QLatin1String("id")) { + topic.setId(xml.readElementText()); + } else if (xml.name() == QLatin1String("forumId")) { + topic.setForumId(xml.readElementText()); + } else if (xml.name() == QLatin1String("user")) { + topic.setUser(xml.readElementText()); + } else if (xml.name() == QLatin1String("date")) { + topic.setDate(Utils::parseQtDateTimeIso8601(xml.readElementText())); + } else if (xml.name() == QLatin1String("subject")) { + topic.setSubject(xml.readElementText()); + } else if (xml.name() == QLatin1String("content")) { + topic.setContent(xml.readElementText()); + } else if (xml.name() == QLatin1String("comments")) { + topic.setComments(xml.readElementText().toInt()); + } + } else if (xml.isEndElement() && xml.name() == QLatin1String("topic")) { + break; + } + } + + return topic; +} + +QStringList Topic::Parser::xmlElement() const +{ + return QStringList(QStringLiteral("topic")); +} diff --git a/local/recipes/kde/kf6-attica/source/src/topicparser.h b/local/recipes/kde/kf6-attica/source/src/topicparser.h new file mode 100644 index 00000000..bd8cb3d6 --- /dev/null +++ b/local/recipes/kde/kf6-attica/source/src/topicparser.h @@ -0,0 +1,26 @@ +/* + This file is part of KDE. + + SPDX-FileCopyrightText: 2011 Laszlo Papp + + SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL +*/ + +#ifndef ATTICA_TOPICPARSER_H +#define ATTICA_TOPICPARSER_H + +#include "parser.h" +#include "topic.h" + +namespace Attica +{ +class Q_DECL_HIDDEN Topic::Parser : public Attica::Parser +{ +private: + Topic parseXml(QXmlStreamReader &xml) override; + QStringList xmlElement() const override; +}; + +} + +#endif diff --git a/local/recipes/kde/kf6-attica/source/src/version.h.cmake b/local/recipes/kde/kf6-attica/source/src/version.h.cmake new file mode 100644 index 00000000..4ed7e730 --- /dev/null +++ b/local/recipes/kde/kf6-attica/source/src/version.h.cmake @@ -0,0 +1,93 @@ +/* + * SPDX-FileCopyrightText: 2007 Sebastian Trueg + * SPDX-FileCopyrightText: 2009 Frederik Gladhorn + * + * SPDX-License-Identifier: LGPL-2.0-or-later + */ + +#ifndef _ATTICA_VERSION_H_ +#define _ATTICA_VERSION_H_ + +#include "attica_export.h" + +/// @brief Attica version as string at compile time. +#define LIBATTICA_VERSION_STRING "${ATTICA_VERSION}" + +/// @brief The major Attica version number at compile time +#define LIBATTICA_VERSION_MAJOR ${ATTICA_VERSION_MAJOR} + +/// @brief The minor Attica version number at compile time +#define LIBATTICA_VERSION_MINOR ${ATTICA_VERSION_MINOR} + +/// @brief The Attica release version number at compile time +#define LIBATTICA_VERSION_RELEASE ${ATTICA_VERSION_PATCH} + +/** + * \brief Create a unique number from the major, minor and release number of a %Attica version + * + * This function can be used for preprocessing. For version information at runtime + * use the version methods in the Attica namespace. + */ +#define LIBATTICA_MAKE_VERSION( a,b,c ) (((a) << 16) | ((b) << 8) | (c)) + +/** + * \brief %Attica Version as a unique number at compile time + * + * This macro calculates the %Attica version into a number. It is mainly used + * through LIBATTICA_IS_VERSION in preprocessing. For version information at runtime + * use the version methods in the Attica namespace. + */ +#define LIBATTICA_VERSION \ + LIBATTICA_MAKE_VERSION(LIBATTICA_VERSION_MAJOR,LIBATTICA_VERSION_MINOR,LIBATTICA_VERSION_RELEASE) + +/** + * \brief Check if the %Attica version matches a certain version or is higher + * + * This macro is typically used to compile conditionally a part of code: + * \code + * #if LIBATTICA_IS_VERSION(2,1) + * // Code for Attica 2.1 + * #else + * // Code for Attica 2.0 + * #endif + * \endcode + * + * For version information at runtime + * use the version methods in the Attica namespace. + */ +#define LIBATTICA_IS_VERSION(a,b,c) ( LIBATTICA_VERSION >= LIBATTICA_MAKE_VERSION(a,b,c) ) + + +namespace Attica { + /** + * @brief Returns the major number of Attica's version, e.g. + * 1 for %Attica 1.0.2. + * @return the major version number at runtime. + */ + ATTICA_EXPORT unsigned int versionMajor(); + + /** + * @brief Returns the minor number of Attica's version, e.g. + * 0 for %Attica 1.0.2. + * @return the minor version number at runtime. + */ + ATTICA_EXPORT unsigned int versionMinor(); + + /** + * @brief Returns the release of Attica's version, e.g. + * 2 for %Attica 1.0.2. + * @return the release number at runtime. + */ + ATTICA_EXPORT unsigned int versionRelease(); + + /** + * @brief Returns the %Attica version as string, e.g. "1.0.2". + * + * On contrary to the macro LIBATTICA_VERSION_STRING this function returns + * the version number of Attica at runtime. + * @return the %Attica version. You can keep the string forever + */ + ATTICA_EXPORT const char* versionString(); +} + +#endif diff --git a/local/recipes/kde/kf6-attica/source/tests/CMakeLists.txt b/local/recipes/kde/kf6-attica/source/tests/CMakeLists.txt new file mode 100644 index 00000000..e20e8af5 --- /dev/null +++ b/local/recipes/kde/kf6-attica/source/tests/CMakeLists.txt @@ -0,0 +1 @@ +add_subdirectory(projecttest) diff --git a/local/recipes/kde/kf6-attica/source/tests/projecttest/CMakeLists.txt b/local/recipes/kde/kf6-attica/source/tests/projecttest/CMakeLists.txt new file mode 100644 index 00000000..db5d6899 --- /dev/null +++ b/local/recipes/kde/kf6-attica/source/tests/projecttest/CMakeLists.txt @@ -0,0 +1,18 @@ +include(ECMMarkAsTest) + +find_package(Qt6Widgets ${REQUIRED_QT_VERSION} CONFIG REQUIRED) +set_package_properties(Qt6Widgets PROPERTIES PURPOSE "Required for tests") + +add_executable(projecttest) +ecm_mark_as_test(projecttest) + +set(editproject_UI_H) +qt_wrap_ui(editproject_UI_H editproject.ui) + +target_sources(projecttest PRIVATE + projecttest.cpp + main.cpp + ${editproject_UI_H} +) + +target_link_libraries(projecttest Qt6::Widgets KF6::Attica) diff --git a/local/recipes/kde/kf6-attica/source/tests/projecttest/editproject.ui b/local/recipes/kde/kf6-attica/source/tests/projecttest/editproject.ui new file mode 100644 index 00000000..28a7f7c4 --- /dev/null +++ b/local/recipes/kde/kf6-attica/source/tests/projecttest/editproject.ui @@ -0,0 +1,381 @@ + + + EditProject + + + + 0 + 0 + 516 + 584 + + + + Form + + + + + + 0 + + + + Project + + + + + + <b>Edit Project</b> + + + + + + + ID: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + + + Name: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + + + Description: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + + + URL: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + + + Summary: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + + + Developers: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + + + License: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + + + Version: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + + + Requirements: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + + + RPM Specfile: + + + Qt::AlignRight|Qt::AlignTop|Qt::AlignTrailing + + + + + + + + + + Save Project + + + + + + + Create new Project + + + + + + + Delete Project + + + + + + + Qt::Vertical + + + + 265 + 9 + + + + + + + + + Accounts + + + + + + + + + + + PushButton + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + + + + + + + true + + + + + + + Username: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + Password: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + Save + + + + + + + Create + + + + + + + + Build Jobs + + + + + + <b>Build Services</b> + + + + + + + + + + Project: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + + + Target: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + + + Build + + + + + + + Qt::Horizontal + + + + + + + <b>Build Jobs</b> + + + + + + + + + + Update + + + + + + + Cancel + + + + + + + + + + + The Quick Brown Fox Jumped over the Lazy Dog. + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + true + + + + + + + + diff --git a/local/recipes/kde/kf6-attica/source/tests/projecttest/main.cpp b/local/recipes/kde/kf6-attica/source/tests/projecttest/main.cpp new file mode 100644 index 00000000..2bbe9974 --- /dev/null +++ b/local/recipes/kde/kf6-attica/source/tests/projecttest/main.cpp @@ -0,0 +1,18 @@ +/* + This file is part of KDE. + + SPDX-FileCopyrightText: 2010 Sebastian Kügler + + SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL +*/ + +#include "projecttest.h" +#include + +int main(int argc, char **argv) +{ + QApplication app(argc, argv); + ProjectTest foo; + foo.show(); + return app.exec(); +} diff --git a/local/recipes/kde/kf6-attica/source/tests/projecttest/projecttest.cpp b/local/recipes/kde/kf6-attica/source/tests/projecttest/projecttest.cpp new file mode 100644 index 00000000..aef7e2e3 --- /dev/null +++ b/local/recipes/kde/kf6-attica/source/tests/projecttest/projecttest.cpp @@ -0,0 +1,476 @@ +/* + This file is part of KDE. + + SPDX-FileCopyrightText: 2010 Sebastian Kügler + + SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL +*/ + +#include "projecttest.h" + +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include + +using namespace Attica; + +ProjectTest::ProjectTest() + : QMainWindow() + , m_mainWidget(nullptr) +{ + m_mainWidget = new QWidget(); + setCentralWidget(m_mainWidget); + + m_editor = new Ui::EditProject(); + m_editor->setupUi(m_mainWidget); + + // Project page + connect(m_editor->save, &QAbstractButton::clicked, this, &ProjectTest::save); + connect(m_editor->create, SIGNAL(clicked()), this, SLOT(create())); + connect(m_editor->deleteProject, SIGNAL(clicked()), this, SLOT(deleteProject())); + + // build service / job page + connect(m_editor->build, &QAbstractButton::clicked, this, &ProjectTest::createBuildServiceJob); + connect(m_editor->cancelJob, &QAbstractButton::clicked, this, &ProjectTest::cancelBuildServiceJob); + connect(m_editor->updateJob, &QAbstractButton::clicked, this, &ProjectTest::updateCurrentProject); + connect(m_editor->buildServices, &QListWidget::currentItemChanged, this, &ProjectTest::selectedBuildServiceChanged); + + QAction *a = new QAction(this); + a->setText(QLatin1String("Quit")); + connect(a, &QAction::triggered, this, &QWidget::close); + menuBar()->addMenu(QLatin1String("File"))->addAction(a); + + initOcs(); +} + +ProjectTest::~ProjectTest() +{ +} + +void ProjectTest::initOcs() +{ + m_pm.setAuthenticationSuppressed(true); + connect(&m_pm, &ProviderManager::providerAdded, this, &ProjectTest::providerAdded); + m_pm.loadDefaultProviders(); + m_mainWidget->setEnabled(false); + setStatus(QLatin1String("Loading providers...")); + // connect(m_serviceUpdates.data(), SIGNAL(mapped(QString)), SLOT(serviceUpdates(QString))); +} + +void ProjectTest::providerAdded(const Attica::Provider &provider) +{ + qDebug() << "providerAdded" << provider.baseUrl(); + setStatus(QLatin1String("Provider found:") + provider.baseUrl().toString()); + m_mainWidget->setEnabled(true); + + if (provider.isValid()) { + QString _id = QLatin1String("1"); + m_provider = provider; + + getProject(_id); + + listProjects(); + + listBuildServices(); + + Project p; + p.setId(_id); + listBuildServiceJobs(p); + } +} + +void ProjectTest::getProject(QString id) +{ + ItemJob *job = m_provider.requestProject(id); + connect(job, &BaseJob::finished, this, &ProjectTest::projectResult); + job->start(); + setStatus(QString(QLatin1String("Loading project %")).arg(id)); + m_mainWidget->setEnabled(false); +} + +void ProjectTest::listProjects() +{ + ListJob *job = m_provider.requestProjects(); + connect(job, &BaseJob::finished, this, &ProjectTest::projectListResult); + job->start(); +} + +void ProjectTest::listBuildServices() +{ + ListJob *job = m_provider.requestBuildServices(); + connect(job, &BaseJob::finished, this, &ProjectTest::buildServiceListResult); + job->start(); +} + +void ProjectTest::listBuildServiceJobs(const Project &p) +{ + ListJob *job = m_provider.requestBuildServiceJobs(p); + connect(job, &BaseJob::finished, this, &ProjectTest::buildServiceJobListResult); + job->start(); +} + +void ProjectTest::projectResult(Attica::BaseJob *j) +{ + qDebug() << "Project job returned"; + QString output; + m_mainWidget->setEnabled(true); + + if (j->metadata().error() == Metadata::NoError) { + Attica::ItemJob *itemJob = static_cast *>(j); + Attica::Project p = itemJob->result(); + output.append(QLatin1String("Project loaded.")); + + projectToUi(p); + } else if (j->metadata().error() == Metadata::OcsError) { + output.append(QString(QLatin1String("OCS Error: %1")).arg(j->metadata().message())); + } else if (j->metadata().error() == Metadata::NetworkError) { + output.append(QString(QLatin1String("Network Error: %1")).arg(j->metadata().message())); + } else { + output.append(QString(QLatin1String("Unknown Error: %1")).arg(j->metadata().message())); + } + setStatus(output); +} + +void ProjectTest::projectToUi(const Project &p) +{ + m_editor->id->setText(p.id()); + m_editor->name->setText(p.name()); + m_editor->description->setText(p.description()); + m_editor->url->setText(p.url()); + m_editor->summary->setText(p.summary()); + m_editor->developers->setText(p.developers().join(QLatin1String(", "))); + m_editor->license->setText(p.license()); + m_editor->version->setText(p.version()); + m_editor->requirements->setText(p.requirements()); + m_editor->specFile->setPlainText(p.specFile()); +} + +Project ProjectTest::uiToProject() +{ + qDebug() << "Saving project"; + + Project project = Project(); + + project.setId(m_editor->id->text()); + project.setName(m_editor->name->text()); + project.setVersion(m_editor->version->text()); + project.setLicense(m_editor->license->text()); + project.setUrl(m_editor->url->text()); + const QStringList _d = m_editor->developers->text().split(QLatin1Char(',')); + QStringList devs; + for (const QString &dev : _d) { + devs << dev.trimmed(); + } + project.setDevelopers(devs); + project.setSummary(m_editor->summary->text()); + project.setDescription(m_editor->description->text()); + project.setRequirements(m_editor->requirements->text()); + project.setSpecFile(m_editor->specFile->toPlainText()); + + return project; +} + +void ProjectTest::save() +{ + Attica::PostJob *postjob = m_provider.editProject(uiToProject()); + connect(postjob, &BaseJob::finished, this, &ProjectTest::saveProjectResult); + postjob->start(); + m_mainWidget->setEnabled(false); +} + +void ProjectTest::create() +{ + Attica::PostJob *postjob = m_provider.createProject(uiToProject()); + connect(postjob, &BaseJob::finished, this, &ProjectTest::createProjectResult); + postjob->start(); + m_mainWidget->setEnabled(false); +} + +void ProjectTest::deleteProject() +{ + Attica::PostJob *postjob = m_provider.deleteProject(uiToProject()); + connect(postjob, &BaseJob::finished, this, &ProjectTest::deleteProjectResult); + postjob->start(); + m_mainWidget->setEnabled(false); +} + +void ProjectTest::createProjectResult(Attica::BaseJob *j) +{ + qDebug() << "createProject() job returned"; + QString output; + m_mainWidget->setEnabled(true); + + if (j->metadata().error() == Metadata::NoError) { + m_currentProjectId = j->metadata().resultingId(); + qDebug() << "Yay, no errors ... resulting ID:" << m_currentProjectId; + output.append(QString(QLatin1String("Project [%1] successfully created:")).arg(m_currentProjectId)); + } else if (j->metadata().error() == Metadata::OcsError) { + output.append(QString(QLatin1String("OCS Error: %1")).arg(j->metadata().message())); + } else if (j->metadata().error() == Metadata::NetworkError) { + output.append(QString(QLatin1String("Network Error: %1")).arg(j->metadata().message())); + } else { + output.append(QString(QLatin1String("Unknown Error: %1")).arg(j->metadata().message())); + } + setStatus(output); +} + +void ProjectTest::saveProjectResult(Attica::BaseJob *j) +{ + qDebug() << "editProject() job returned"; + QString output; + m_mainWidget->setEnabled(true); + + if (j->metadata().error() == Metadata::NoError) { + m_currentProjectId = j->metadata().resultingId(); + qDebug() << "Yay, no errors ... resulting ID:" << m_currentProjectId; + output.append(QString(QLatin1String("Project [%1] successfully saved.")).arg(m_currentProjectId)); + } else if (j->metadata().error() == Metadata::OcsError) { + output.append(QString(QLatin1String("OCS Error: %1")).arg(j->metadata().message())); + } else if (j->metadata().error() == Metadata::NetworkError) { + output.append(QString(QLatin1String("Network Error: %1")).arg(j->metadata().message())); + } else { + output.append(QString(QLatin1String("Unknown Error: %1")).arg(j->metadata().message())); + } + setStatus(output); +} + +void ProjectTest::deleteProjectResult(Attica::BaseJob *j) +{ + qDebug() << "deleteProject() job returned"; + QString output; + m_mainWidget->setEnabled(true); + + if (j->metadata().error() == Metadata::NoError) { + qDebug() << "Yay, no errors ... deleted project."; + output.append(QString(QLatin1String("Project [%1] successfully deleted")).arg(m_currentProjectId)); + } else if (j->metadata().error() == Metadata::OcsError) { + output.append(QString(QLatin1String("OCS Error: %1")).arg(j->metadata().message())); + } else if (j->metadata().error() == Metadata::NetworkError) { + output.append(QString(QLatin1String("Network Error: %1")).arg(j->metadata().message())); + } else { + output.append(QString(QLatin1String("Unknown Error: %1")).arg(j->metadata().message())); + } + setStatus(output); + m_currentProjectId.clear(); + projectToUi(Project()); +} + +void ProjectTest::projectListResult(Attica::BaseJob *j) +{ + qDebug() << "Project list job returned"; + QString output = QLatin1String("Projects:"); + m_mainWidget->setEnabled(true); + + if (j->metadata().error() == Metadata::NoError) { + Attica::ListJob *listJob = static_cast *>(j); + qDebug() << "Yay, no errors ..."; + QStringList projectIds; + + const auto itemList = listJob->itemList(); + for (const Project &p : itemList) { + m_projects[p.id()] = p; + qDebug() << "New project:" << p.id() << p.name(); + output.append(QString(QLatin1String("
%1 (%2)")).arg(p.name(), p.id())); + projectIds << p.id(); + m_editor->projects->insertItem(0, p.name(), p.id()); + // TODO: start project jobs here + } + if (listJob->itemList().isEmpty()) { + output.append(QLatin1String("No Projects found.")); + } + } else if (j->metadata().error() == Metadata::OcsError) { + output.append(QString(QLatin1String("OCS Error: %1")).arg(j->metadata().message())); + } else if (j->metadata().error() == Metadata::NetworkError) { + output.append(QString(QLatin1String("Network Error: %1")).arg(j->metadata().message())); + } else { + output.append(QString(QLatin1String("Unknown Error: %1")).arg(j->metadata().message())); + } + qDebug() << output; + setStatus(output); +} + +void ProjectTest::buildServiceListResult(Attica::BaseJob *j) +{ + qDebug() << "BuildService list job returned"; + QString output = QLatin1String("BuildServices:"); + // m_mainWidget->setEnabled(true); // fixme: tab + + if (j->metadata().error() == Metadata::NoError) { + Attica::ListJob *listJob = static_cast *>(j); + qDebug() << "Yay, no errors ..."; + + const auto itemList = listJob->itemList(); + for (const BuildService &bs : itemList) { + m_buildServices[bs.id()] = bs; + qDebug() << "New OBS:" << bs.id() << bs.name() << bs.url(); + output.append(QString(QLatin1String("
%1 (%2) at %3")).arg(bs.name(), bs.id(), bs.url())); + QListWidgetItem *new_bs = new QListWidgetItem(bs.name(), m_editor->buildServices); + new_bs->setData(Qt::UserRole, QVariant(bs.id())); + + m_editor->accountsServers->insertItem(0, bs.name(), bs.id()); + // QListWidgetItem* new_bsa = new QListWidgetItem(bs.name(), m_editor->accountsServers); + // new_bsa->setData(Qt::UserRole, QVariant(bs.id())); + } + if (listJob->itemList().isEmpty()) { + output.append(QLatin1String("No OBS'en found.")); + } + } else if (j->metadata().error() == Metadata::OcsError) { + output.append(QString(QLatin1String("OCS Error: %1")).arg(j->metadata().message())); + } else if (j->metadata().error() == Metadata::NetworkError) { + output.append(QString(QLatin1String("Network Error: %1")).arg(j->metadata().message())); + } else { + output.append(QString(QLatin1String("Unknown Error: %1")).arg(j->metadata().message())); + } + qDebug() << output; + // setBuildStatus(output); +} + +void ProjectTest::buildServiceJobListResult(Attica::BaseJob *j) +{ + qDebug() << "BuildServiceJobList list job returned"; + QString output = QLatin1String("BuildServiceJobs: "); + // m_mainWidget->setEnabled(true); // fixme: tab + + if (j->metadata().error() == Metadata::NoError) { + Attica::ListJob *listJob = static_cast *>(j); + qDebug() << "Yay, no errors. Items found:" << listJob->itemList().count(); + + const auto itemList = listJob->itemList(); + for (const BuildServiceJob &bsj : itemList) { + m_buildServiceJobs[bsj.id()] = bsj; + qDebug() << "New BuildServiceJob:" << bsj.id() << bsj.name() << bsj.target(); + output.append(QString(QLatin1String("
%1 (%2) for %3")).arg(bsj.name(), bsj.id(), bsj.target())); + QListWidgetItem *new_bsj = new QListWidgetItem(bsj.name(), m_editor->buildServiceJobs); + new_bsj->setData(Qt::UserRole, QVariant(bsj.id())); + } + if (listJob->itemList().isEmpty()) { + output.append(QLatin1String("No jobs found.")); + } + } else if (j->metadata().error() == Metadata::OcsError) { + output.append(QString(QLatin1String("OCS Error: %1")).arg(j->metadata().message())); + } else if (j->metadata().error() == Metadata::NetworkError) { + output.append(QString(QLatin1String("Network Error: %1")).arg(j->metadata().message())); + } else { + output.append(QString(QLatin1String("Unknown Error: %1")).arg(j->metadata().message())); + } + qDebug() << output; + // setBuildStatus(output); +} + +void ProjectTest::selectedBuildServiceChanged(QListWidgetItem *current, QListWidgetItem *previous) +{ + Q_UNUSED(previous) + qDebug() << "current item changed to " << current->data(Qt::UserRole).toString(); + m_editor->targets->clear(); + const QList targetlist = m_buildServices[current->data(Qt::UserRole).toString()].targets(); + for (const Target &t : targetlist) { + // m_editor->targets->insertItems(0, m_buildServices[current->data(Qt::UserRole).toString()].targets()); + m_editor->targets->insertItem(0, t.name, t.id); + // FIXME: target id. + qDebug() << "target:" << t.name << t.id; + } +} + +void ProjectTest::createBuildServiceJob() +{ + BuildServiceJob b = BuildServiceJob(); + b.setProjectId(m_editor->projects->itemData(m_editor->projects->currentIndex()).toString()); + b.setTarget(m_editor->targets->itemData(m_editor->targets->currentIndex()).toString()); + b.setBuildServiceId(m_editor->buildServices->currentItem()->data(Qt::UserRole).toString()); + b.setTarget(m_editor->targets->itemData(m_editor->targets->currentIndex()).toString()); + + ///* + qDebug() << "Create build job:" << m_editor->targets->itemData(m_editor->targets->currentIndex()).toString() << m_editor->targets->currentIndex() + << m_editor->targets->itemData(m_editor->targets->currentIndex()); + qDebug() << "Project:" << b.projectId(); + qDebug() << "Target:" << b.target(); + qDebug() << "Buildservice:" << b.buildServiceId(); + //*/ + Attica::PostJob *j = m_provider.createBuildServiceJob(b); + connect(j, &BaseJob::finished, this, &ProjectTest::buildServiceJobCreated); + j->start(); + setStatus(QLatin1String("Starting a build job on the server.")); +} + +void ProjectTest::cancelBuildServiceJob() +{ + const QString bsj_id = m_editor->buildServiceJobs->currentItem()->data(Qt::UserRole).toString(); + qDebug() << "Cancelling build job:" << bsj_id; + BuildServiceJob b = BuildServiceJob(); + b.setId(bsj_id); + Attica::PostJob *j = m_provider.cancelBuildServiceJob(b); + connect(j, &BaseJob::finished, this, &ProjectTest::buildServiceJobCanceled); + j->start(); +} + +void ProjectTest::buildServiceJobCanceled(Attica::BaseJob *j) +{ + // m_mainWidget->setEnabled(true); // fixme: tab + QString output; + if (j->metadata().error() == Metadata::NoError) { + qDebug() << "job canceled."; + // TODO: refresh jobs + } else if (j->metadata().error() == Metadata::OcsError) { + output.append(QString(QLatin1String("OCS Error: %1")).arg(j->metadata().message())); + } else if (j->metadata().error() == Metadata::NetworkError) { + output.append(QString(QLatin1String("Network Error: %1")).arg(j->metadata().message())); + } else { + output.append(QString(QLatin1String("Unknown Error: %1")).arg(j->metadata().message())); + } + qDebug() << output; + updateCurrentProject(); + setStatus(output); +} + +void ProjectTest::buildServiceJobCreated(Attica::BaseJob *j) +{ + qDebug() << "JOB CREATED!!!!!!!!!!!!!!!!"; + // m_mainWidget->setEnabled(true); // fixme: tab + QString output; + if (j->metadata().error() == Metadata::NoError) { + qDebug() << "job created. I think."; + // TODO: refresh jobs + } else if (j->metadata().error() == Metadata::OcsError) { + output.append(QString(QLatin1String("OCS Error: %1")).arg(j->metadata().message())); + } else if (j->metadata().error() == Metadata::NetworkError) { + output.append(QString(QLatin1String("Network Error: %1")).arg(j->metadata().message())); + } else { + output.append(QString(QLatin1String("Unknown Error: %1")).arg(j->metadata().message())); + } + qDebug() << "New BuildServiceJob created with ID:" << j->metadata().resultingId(); + qDebug() << output; + updateCurrentProject(); + setStatus(output); +} + +void ProjectTest::setStatus(QString status) +{ + qDebug() << "[ii] Status:" << status; + m_editor->status->setText(status); +} + +QString ProjectTest::currentProject() +{ + return m_editor->projects->itemData(m_editor->projects->currentIndex()).toString(); +} + +void ProjectTest::updateCurrentProject() +{ + m_editor->buildServiceJobs->clear(); + qDebug() << "Updating project ..."; + Project p = Project(); + p.setId(currentProject()); + listBuildServiceJobs(p); +} + +#include "moc_projecttest.cpp" diff --git a/local/recipes/kde/kf6-attica/source/tests/projecttest/projecttest.h b/local/recipes/kde/kf6-attica/source/tests/projecttest/projecttest.h new file mode 100644 index 00000000..074c9a86 --- /dev/null +++ b/local/recipes/kde/kf6-attica/source/tests/projecttest/projecttest.h @@ -0,0 +1,86 @@ +/* + This file is part of KDE. + + SPDX-FileCopyrightText: 2010 Sebastian Kügler + + SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL +*/ + +#ifndef PROJECTTEST_H +#define PROJECTTEST_H + +#include "ui_editproject.h" + +#include +#include + +#include +#include + +namespace Attica +{ +class Project; +class BaseJob; +class Provider; +} + +class ProjectTest : public QMainWindow +{ + Q_OBJECT +public: + ProjectTest(); + ~ProjectTest() override; + +private Q_SLOTS: + void providerAdded(const Attica::Provider &provider); + + void projectListResult(Attica::BaseJob *); + void projectResult(Attica::BaseJob *); + void createProjectResult(Attica::BaseJob *j); + void saveProjectResult(Attica::BaseJob *j); + void deleteProjectResult(Attica::BaseJob *j); + + void buildServiceListResult(Attica::BaseJob *); + void buildServiceJobListResult(Attica::BaseJob *); + + void save(); + void create(); + void deleteProject(); // don't clashs with keyword + + void selectedBuildServiceChanged(QListWidgetItem *current, QListWidgetItem *previous); + void createBuildServiceJob(); + void buildServiceJobCreated(Attica::BaseJob *j); + void cancelBuildServiceJob(); + void buildServiceJobCanceled(Attica::BaseJob *j); + + void updateCurrentProject(); + +private: + void initOcs(); + void getProject(QString id); + void deleteProject(QString id); + void listProjects(); + void listBuildServices(); + void listBuildServiceJobs(const Attica::Project &p); + + void setStatus(QString status); + Attica::Project uiToProject(); + void projectToUi(const Attica::Project &p); + QString currentProject(); + + Attica::ProviderManager m_pm; + Attica::Provider m_provider; + QHash> m_providers; + + QString m_currentProjectId; + + QWidget *m_mainWidget; + + Ui::EditProject *m_editor; + + QHash m_buildServices; + QHash m_buildServiceJobs; + QHash m_projects; +}; + +#endif // PROJECTTEST_H diff --git a/local/recipes/kde/kf6-knewstuff/recipe.toml b/local/recipes/kde/kf6-knewstuff/recipe.toml index 265e2023..6452b436 100644 --- a/local/recipes/kde/kf6-knewstuff/recipe.toml +++ b/local/recipes/kde/kf6-knewstuff/recipe.toml @@ -1,9 +1,4 @@ -#TODO: KNewStuff — attempt an honest core-only build on Redox. Qt Quick, widgets, tools, and Kirigami-facing surfaces stay disabled; the remaining hard blockers are the missing KF6Attica package in-tree and the still-disabled QtNetwork surface in qtbase. -[source] -tar = "https://invent.kde.org/frameworks/knewstuff/-/archive/v6.10.0/knewstuff-v6.10.0.tar.gz" - -[build] -template = "custom" +#TODO: KNewStuff — core-only build on Redox. Qt Quick, widgets, tools, and Kirigami-facing surfaces disabled. KF6Attica now available in-tree (kf6-attica recipe). dependencies = [ "qtbase", "kf6-extra-cmake-modules", @@ -12,6 +7,8 @@ dependencies = [ "kf6-kconfig", "kf6-karchive", "kf6-kpackage", + "kf6-kwidgetsaddons", + "kf6-attica", ] script = """ DYNAMIC_INIT @@ -38,6 +35,10 @@ sed -i 's/^add_subdirectory(tools)/# add_subdirectory(tools) # disabled for Redo "${COOKBOOK_SOURCE}/src/CMakeLists.txt" 2>/dev/null || true sed -i 's/^add_subdirectory(widgets)/# add_subdirectory(widgets) # disabled for Redox core-only build/' \ "${COOKBOOK_SOURCE}/src/CMakeLists.txt" 2>/dev/null || true +sed -i 's/^add_subdirectory(tools)/# add_subdirectory(tools) # disabled for Redox core-only build/' \ + "${COOKBOOK_SOURCE}/src/CMakeLists.txt" 2>/dev/null || true +sed -i 's/^add_subdirectory(widgets)/# add_subdirectory(widgets) # disabled for Redox core-only build/' \ + "${COOKBOOK_SOURCE}/src/CMakeLists.txt" 2>/dev/null || true rm -f CMakeCache.txt rm -rf CMakeFiles diff --git a/local/scripts/integrate-redbear.sh b/local/scripts/integrate-redbear.sh index 9e86e652..b93ad3c4 100755 --- a/local/scripts/integrate-redbear.sh +++ b/local/scripts/integrate-redbear.sh @@ -184,6 +184,7 @@ symlink "../../local/recipes/kde/kf6-kcolorscheme" "recipes/kde/kf6-kcolorscheme symlink "../../local/recipes/kde/kf6-kauth" "recipes/kde/kf6-kauth" symlink "../../local/recipes/kde/kf6-kitemmodels" "recipes/kde/kf6-kitemmodels" symlink "../../local/recipes/kde/kf6-kitemviews" "recipes/kde/kf6-kitemviews" +symlink "../../local/recipes/kde/kf6-attica" "recipes/kde/kf6-attica" symlink "../../local/recipes/kde/kf6-karchive" "recipes/kde/kf6-karchive" symlink "../../local/recipes/kde/kf6-kwindowsystem" "recipes/kde/kf6-kwindowsystem" symlink "../../local/recipes/kde/kf6-knotifications" "recipes/kde/kf6-knotifications" diff --git a/recipes/kde/kf6-attica b/recipes/kde/kf6-attica new file mode 120000 index 00000000..ceb21ddf --- /dev/null +++ b/recipes/kde/kf6-attica @@ -0,0 +1 @@ +../../local/recipes/kde/kf6-attica \ No newline at end of file diff --git a/src/recipe.rs b/src/recipe.rs index 13f50d97..49da9e22 100644 --- a/src/recipe.rs +++ b/src/recipe.rs @@ -570,7 +570,7 @@ fn topological_sort(recipes: Vec) -> Result, Package } if sorted.len() != recipes.len() { - return Ok(recipes); + return Err(PackageError::Recursion(Default::default())); } Ok(sorted)