diff --git a/CMakeLists.txt b/CMakeLists.txt index f7df6970..c66c4418 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,81 +1,88 @@ project(discover) set(PROJECT_VERSION "5.13.80") set(PROJECT_VERSION_MAJOR 5) cmake_minimum_required(VERSION 2.8.12) find_package(ECM REQUIRED NO_MODULE) set(CMAKE_MODULE_PATH ${ECM_MODULE_PATH} ${ECM_KDE_MODULE_DIR} "${CMAKE_SOURCE_DIR}/cmake") find_package(Qt5 5.10.0 REQUIRED CONFIG COMPONENTS Widgets Test Network Xml Concurrent DBus Quick) include(KDEInstallDirs) include(KDECMakeSettings) include(KDEFrameworkCompilerSettings NO_POLICY_SCOPE) include(ECMInstallIcons) include(ECMMarkAsTest) include(ECMAddTests) include(GenerateExportHeader) find_package(PkgConfig REQUIRED) find_package(KF5 5.45 REQUIRED CoreAddons Config Crash DBusAddons I18n Archive XmlGui ItemModels KIO) find_package(KF5Kirigami2 2.1.0) find_package(packagekitqt5 CONFIG) find_package(AppStreamQt 0.11.1 CONFIG) find_package(KF5Attica 5.23 CONFIG) find_package(KF5NewStuff 5.23 CONFIG) set(CMAKE_AUTORCC ON) pkg_check_modules(FLATPAK flatpak>=0.6.12) +find_package(LIBFWUPD 1.0.7 REQUIRED) + if(NOT CMAKE_VERSION VERSION_LESS "3.10.0") # CMake 3.9+ warns about automoc on files without Q_OBJECT, and doesn't know about other macros. # 3.10+ lets us provide more macro names that require automoc. list(APPEND CMAKE_AUTOMOC_MACRO_NAMES "DISCOVER_BACKEND_PLUGIN") endif() configure_file(DiscoverVersion.h.in DiscoverVersion.h) add_subdirectory(libdiscover) add_subdirectory(discover) add_subdirectory(exporter) option(WITH_NOTIFIER "Build and install the notifier plasmoid" ON) if(WITH_NOTIFIER) find_package(KF5 REQUIRED Notifications KIO) add_subdirectory(notifier) endif() set_package_properties(KF5Attica PROPERTIES DESCRIPTION "KDE Framework that implements the Open Collaboration Services API" PURPOSE "Required to build the KNewStuff3 backend" TYPE OPTIONAL) set_package_properties(KF5Kirigami2 PROPERTIES DESCRIPTION "KDE's lightweight user interface framework for mobile and convergent applications" URL "https://techbase.kde.org/Kirigami" PURPOSE "Required by discover qml components" TYPE RUNTIME) set_package_properties(KF5NewStuff PROPERTIES DESCRIPTION "Qt library that allows to interact with KNewStuff implementations" PURPOSE "Required to build the KNS backend" TYPE OPTIONAL) set_package_properties(packagekitqt5 PROPERTIES DESCRIPTION "Library that exposes PackageKit resources" URL "http://www.packagekit.org" PURPOSE "Required to build the PackageKit backend" TYPE OPTIONAL) set_package_properties(AppStreamQt PROPERTIES DESCRIPTION "Library that lists Appstream resources" URL "http://www.freedesktop.org" PURPOSE "Required to build the PackageKit backend" TYPE OPTIONAL) set_package_properties(FLATPAK PROPERTIES DESCRIPTION "Library that exposes flatpak repositories" URL "http://www.freedesktop.org" PURPOSE "Required to build the Flatpak backend" TYPE OPTIONAL) +set_package_properties(LIBFWUPD PROPERTIES + DESCRIPTION "Library that exposes fwupd" + URL "http://www.fwupd.org" + PURPOSE "Required to build the Fwupd backend" + TYPE OPTIONAL) feature_summary(WHAT ALL FATAL_ON_MISSING_REQUIRED_PACKAGES) diff --git a/cmake/FindGIO.cmake b/cmake/FindGIO.cmake new file mode 100644 index 00000000..71ac7d89 --- /dev/null +++ b/cmake/FindGIO.cmake @@ -0,0 +1,198 @@ +# FindGIO.cmake +# +# +# CMake support for GIO. +# +# License: +# +# Copyright (c) 2016 Evan Nemerson +# +# Permission is hereby granted, free of charge, to any person +# obtaining a copy of this software and associated documentation +# files (the "Software"), to deal in the Software without +# restriction, including without limitation the rights to use, copy, +# modify, merge, publish, distribute, sublicense, and/or sell copies +# of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be +# included in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +# HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +# DEALINGS IN THE SOFTWARE. + +find_package(PkgConfig) + +set(GIO_DEPS + GObject) + +if(PKG_CONFIG_FOUND) + pkg_search_module(GIO_PKG gio-2.0) +endif() + +find_library(GIO_LIBRARY gio-2.0 HINTS ${GIO_PKG_LIBRARY_DIRS}) +set(GIO "gio-2.0") + +if(GIO_LIBRARY AND NOT GIO_FOUND) + add_library(${GIO} SHARED IMPORTED) + set_property(TARGET ${GIO} PROPERTY IMPORTED_LOCATION "${GIO_LIBRARY}") + set_property(TARGET ${GIO} PROPERTY INTERFACE_COMPILE_OPTIONS "${GIO_PKG_CFLAGS_OTHER}") + + find_path(GIO_INCLUDE_DIR "gio/gio.h" + HINTS ${GIO_PKG_INCLUDE_DIRS}) + + find_package(GLib) + find_package(GObject) + set(GIO_VERSION "${GLib_VERSION}") + + list(APPEND GIO_DEPS_FOUND_VARS "GObject_FOUND") + list(APPEND GIO_INCLUDE_DIRS ${GObject_INCLUDE_DIRS}) + + set_property (TARGET "${GIO}" APPEND PROPERTY INTERFACE_LINK_LIBRARIES "gobject-2.0") + set_property(TARGET ${GIO} PROPERTY INTERFACE_INCLUDE_DIRECTORIES "${GIO_INCLUDE_DIR}") +endif() + +find_program(GLib_COMPILE_SCHEMAS glib-compile-schemas) +if(GLib_COMPILE_SCHEMAS AND NOT GLib_FOUND) + add_executable(glib-compile-schemas IMPORTED) + set_property(TARGET glib-compile-schemas PROPERTY IMPORTED_LOCATION "${GLib_COMPILE_SCHEMAS}") +endif() + +# glib_install_schemas( +# [DESTINATION directory] +# schemas…) +# +# Validate and install the listed schemas. +function(glib_install_schemas) + set (options) + set (oneValueArgs DESTINATION) + set (multiValueArgs) + cmake_parse_arguments(GSCHEMA "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) + unset (options) + unset (oneValueArgs) + unset (multiValueArgs) + + foreach(schema ${GSCHEMA_UNPARSED_ARGUMENTS}) + get_filename_component(schema_name "${schema}" NAME) + string(REGEX REPLACE "^(.+)\.gschema.xml$" "\\1" schema_name "${schema_name}") + set(schema_output "${CMAKE_CURRENT_BINARY_DIR}/${schema_name}.gschema.xml.valid") + + add_custom_command( + OUTPUT "${schema_output}" + COMMAND glib-compile-schemas + --strict + --dry-run + --schema-file="${schema}" + COMMAND "${CMAKE_COMMAND}" ARGS -E touch "${schema_output}" + DEPENDS "${schema}" + WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" + COMMENT "Validating ${schema}") + + add_custom_target("gsettings-schema-${schema_name}" ALL + DEPENDS "${schema_output}") + + if(CMAKE_INSTALL_FULL_DATADIR) + set(SCHEMADIR "${CMAKE_INSTALL_FULL_DATADIR}/glib-2.0/schemas") + else() + set(SCHEMADIR "${CMAKE_INSTALL_PREFIX}/share/glib-2.0/schemas") + endif() + install(FILES "${schema}" + DESTINATION "${SCHEMADIR}") + install(CODE "execute_process(COMMAND \"${GLib_COMPILE_SCHEMAS}\" \"${SCHEMADIR}\")") + endforeach() +endfunction() + +find_program(GLib_COMPILE_RESOURCES glib-compile-resources) +if(GLib_COMPILE_RESOURCES AND NOT GLib_FOUND) + add_executable(glib-compile-resources IMPORTED) + set_property(TARGET glib-compile-resources PROPERTY IMPORTED_LOCATION "${GLib_COMPILE_RESOURCES}") +endif() + +function(glib_compile_resources SPEC_FILE) + set (options INTERNAL) + set (oneValueArgs TARGET SOURCE_DIR HEADER SOURCE C_NAME) + set (multiValueArgs) + cmake_parse_arguments(GLib_COMPILE_RESOURCES "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) + unset (options) + unset (oneValueArgs) + unset (multiValueArgs) + + if(NOT GLib_COMPILE_RESOURCES_SOURCE_DIR) + set(GLib_COMPILE_RESOURCES_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}") + endif() + + set(FLAGS) + + if(GLib_COMPILE_RESOURCES_INTERNAL) + list(APPEND FLAGS "--internal") + endif() + + if(GLib_COMPILE_RESOURCES_C_NAME) + list(APPEND FLAGS "--c-name" "${GLib_COMPILE_RESOURCES_C_NAME}") + endif() + + get_filename_component(SPEC_FILE "${SPEC_FILE}" ABSOLUTE BASE_DIR "${CMAKE_CURRENT_SOURCE_DIR}") + + execute_process( + COMMAND glib-compile-resources + --generate-dependencies + --sourcedir "${GLib_COMPILE_RESOURCES_SOURCE_DIR}" + "${SPEC_FILE}" + OUTPUT_VARIABLE deps + WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" + OUTPUT_STRIP_TRAILING_WHITESPACE) + string(REPLACE "\n" ";" deps ${deps}) + + if(GLib_COMPILE_RESOURCES_HEADER) + get_filename_component(GLib_COMPILE_RESOURCES_HEADER "${GLib_COMPILE_RESOURCES_HEADER}" ABSOLUTE BASE_DIR "${CMAKE_CURRENT_BINARY_DIR}") + + add_custom_command( + OUTPUT "${GLib_COMPILE_RESOURCES_HEADER}" + COMMAND glib-compile-resources + --sourcedir "${GLib_COMPILE_RESOURCES_SOURCE_DIR}" + --generate-header + --target "${GLib_COMPILE_RESOURCES_HEADER}" + ${FLAGS} + "${SPEC_FILE}" + DEPENDS "${SPEC_FILE}" ${deps} + WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}") + endif() + + if(GLib_COMPILE_RESOURCES_SOURCE) + get_filename_component(GLib_COMPILE_RESOURCES_SOURCE "${GLib_COMPILE_RESOURCES_SOURCE}" ABSOLUTE BASE_DIR "${CMAKE_CURRENT_BINARY_DIR}") + + add_custom_command( + OUTPUT "${GLib_COMPILE_RESOURCES_SOURCE}" + COMMAND glib-compile-resources + --sourcedir "${GLib_COMPILE_RESOURCES_SOURCE_DIR}" + --generate-source + --target "${GLib_COMPILE_RESOURCES_SOURCE}" + ${FLAGS} + "${SPEC_FILE}" + DEPENDS "${SPEC_FILE}" ${deps} + WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}") + endif() +endfunction() + +find_program(GDBUS_CODEGEN gdbus-codegen) +if(GDBUS_CODEGEN AND NOT GLib_FOUND) + add_executable(gdbus-codegen IMPORTED) + set_property(TARGET gdbus-codegen PROPERTY IMPORTED_LOCATION "${GDBUS_CODEGEN}") +endif() + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(GIO + REQUIRED_VARS + GIO_LIBRARY + GIO_INCLUDE_DIRS + ${GIO_DEPS_FOUND_VARS} + VERSION_VAR + GIO_VERSION) + +unset(GIO_DEPS_FOUND_VARS) diff --git a/cmake/FindGLib.cmake b/cmake/FindGLib.cmake new file mode 100644 index 00000000..8939d857 --- /dev/null +++ b/cmake/FindGLib.cmake @@ -0,0 +1,83 @@ +# FindGLib.cmake +# +# +# CMake support for GLib/GObject/GIO. +# +# License: +# +# Copyright (c) 2016 Evan Nemerson +# +# Permission is hereby granted, free of charge, to any person +# obtaining a copy of this software and associated documentation +# files (the "Software"), to deal in the Software without +# restriction, including without limitation the rights to use, copy, +# modify, merge, publish, distribute, sublicense, and/or sell copies +# of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be +# included in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +# HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +# DEALINGS IN THE SOFTWARE. + +find_package(PkgConfig) + +if(PKG_CONFIG_FOUND) + pkg_search_module(GLib_PKG glib-2.0) +endif() + +find_library(GLib_LIBRARY glib-2.0 HINTS ${GLib_PKG_LIBRARY_DIRS}) +set(GLib glib-2.0) + +if(GLib_LIBRARY AND NOT GLib_FOUND) + add_library(${GLib} SHARED IMPORTED) + set_property(TARGET ${GLib} PROPERTY IMPORTED_LOCATION "${GLib_LIBRARY}") + set_property(TARGET ${GLib} PROPERTY INTERFACE_COMPILE_OPTIONS "${GLib_PKG_CFLAGS_OTHER}") + + find_path(GLib_INCLUDE_DIRS "glib.h" + HINTS ${GLib_PKG_INCLUDE_DIRS} + PATH_SUFFIXES "glib-2.0") + + get_filename_component(GLib_LIBDIR "${GLib}" DIRECTORY) + find_path(GLib_CONFIG_INCLUDE_DIR "glibconfig.h" + HINTS + ${GLib_LIBDIR} + ${GLib_PKG_INCLUDE_DIRS} + PATHS + "${CMAKE_LIBRARY_PATH}" + PATH_SUFFIXES + "glib-2.0/include" + "glib-2.0") + unset(GLib_LIBDIR) + + if(GLib_CONFIG_INCLUDE_DIR) + file(STRINGS "${GLib_CONFIG_INCLUDE_DIR}/glibconfig.h" GLib_MAJOR_VERSION REGEX "^#define GLIB_MAJOR_VERSION +([0-9]+)") + string(REGEX REPLACE "^#define GLIB_MAJOR_VERSION ([0-9]+)$" "\\1" GLib_MAJOR_VERSION "${GLib_MAJOR_VERSION}") + file(STRINGS "${GLib_CONFIG_INCLUDE_DIR}/glibconfig.h" GLib_MINOR_VERSION REGEX "^#define GLIB_MINOR_VERSION +([0-9]+)") + string(REGEX REPLACE "^#define GLIB_MINOR_VERSION ([0-9]+)$" "\\1" GLib_MINOR_VERSION "${GLib_MINOR_VERSION}") + file(STRINGS "${GLib_CONFIG_INCLUDE_DIR}/glibconfig.h" GLib_MICRO_VERSION REGEX "^#define GLIB_MICRO_VERSION +([0-9]+)") + string(REGEX REPLACE "^#define GLIB_MICRO_VERSION ([0-9]+)$" "\\1" GLib_MICRO_VERSION "${GLib_MICRO_VERSION}") + set(GLib_VERSION "${GLib_MAJOR_VERSION}.${GLib_MINOR_VERSION}.${GLib_MICRO_VERSION}") + unset(GLib_MAJOR_VERSION) + unset(GLib_MINOR_VERSION) + unset(GLib_MICRO_VERSION) + + list(APPEND GLib_INCLUDE_DIRS ${GLib_CONFIG_INCLUDE_DIR}) + set_property(TARGET ${GLib} PROPERTY INTERFACE_INCLUDE_DIRECTORIES "${GLib_INCLUDE_DIRS}") + endif() +endif() + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(GLib + REQUIRED_VARS + GLib_LIBRARY + GLib_INCLUDE_DIRS + VERSION_VAR + GLib_VERSION) diff --git a/cmake/FindGObject.cmake b/cmake/FindGObject.cmake new file mode 100644 index 00000000..7da34309 --- /dev/null +++ b/cmake/FindGObject.cmake @@ -0,0 +1,81 @@ +# FindGObject.cmake +# +# +# CMake support for GObject. +# +# License: +# +# Copyright (c) 2016 Evan Nemerson +# +# Permission is hereby granted, free of charge, to any person +# obtaining a copy of this software and associated documentation +# files (the "Software"), to deal in the Software without +# restriction, including without limitation the rights to use, copy, +# modify, merge, publish, distribute, sublicense, and/or sell copies +# of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be +# included in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +# HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +# DEALINGS IN THE SOFTWARE. + +find_package(PkgConfig) + +set(GObject_DEPS + GLib) + +if(PKG_CONFIG_FOUND) + pkg_search_module(GObject_PKG gobject-2.0) +endif() + +find_library(GObject_LIBRARY gobject-2.0 HINTS ${GObject_PKG_LIBRARY_DIRS}) +set(GObject gobject-2.0) + +if(GObject_LIBRARY AND NOT GObject_FOUND) + add_library(${GObject} SHARED IMPORTED) + set_property(TARGET ${GObject} PROPERTY IMPORTED_LOCATION "${GObject_LIBRARY}") + set_property(TARGET ${GObject} PROPERTY INTERFACE_COMPILE_OPTIONS "${GObject_PKG_CFLAGS_OTHER}") + + find_path(GObject_INCLUDE_DIR "gobject/gobject.h" + HINTS ${GObject_PKG_INCLUDE_DIRS}) + + find_package(GLib) + set(GObject_VERSION "${GLib_VERSION}") + + list(APPEND GObject_DEPS_FOUND_VARS "GLib_FOUND") + list(APPEND GObject_INCLUDE_DIRS ${GLib_INCLUDE_DIRS}) + set_property(TARGET ${GObject} PROPERTY INTERFACE_INCLUDE_DIRECTORIES "${GObject_INCLUDE_DIR}") + + set_property (TARGET "${GObject}" APPEND PROPERTY INTERFACE_LINK_LIBRARIES "${GLib}") +endif() + +find_program(GLib_GENMARSHAL glib-genmarshal) +if(GLib_GENMARSHAL AND NOT GLib_FOUND) + add_executable(glib-genmarshal IMPORTED) + set_property(TARGET glib-genmarshal PROPERTY IMPORTED_LOCATION "${GLib_GENMARSHAL}") +endif() + +find_program(GLib_MKENUMS glib-mkenums) +if(GLib_MKENUMS AND NOT GLib_FOUND) + add_executable(glib-mkenums IMPORTED) + set_property(TARGET glib-mkenums PROPERTY IMPORTED_LOCATION "${GLib_MKENUMS}") +endif() + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(GObject + REQUIRED_VARS + GObject_LIBRARY + GObject_INCLUDE_DIRS + ${GObject_DEPS_FOUND_VARS} + VERSION_VAR + GObject_VERSION) + +unset(GObject_DEPS_FOUND_VARS) diff --git a/cmake/FindGObjectIntrospection.cmake b/cmake/FindGObjectIntrospection.cmake new file mode 100644 index 00000000..c42e31d9 --- /dev/null +++ b/cmake/FindGObjectIntrospection.cmake @@ -0,0 +1,98 @@ +# FindGObjectIntrospection.cmake +# +# +# License: +# +# Copyright (c) 2016 Evan Nemerson +# +# Permission is hereby granted, free of charge, to any person +# obtaining a copy of this software and associated documentation +# files (the "Software"), to deal in the Software without +# restriction, including without limitation the rights to use, copy, +# modify, merge, publish, distribute, sublicense, and/or sell copies +# of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be +# included in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +# HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +# DEALINGS IN THE SOFTWARE. + +find_program(GObjectIntrospection_COMPILER_EXECUTABLE g-ir-compiler) +find_program(GObjectIntrospection_SCANNER_EXECUTABLE g-ir-scanner) + +if(CMAKE_INSTALL_FULL_DATADIR) + set(GObjectIntrospection_REPOSITORY_DIR "${CMAKE_INSTALL_FULL_DATADIR}/gir-1.0") +else() + set(GObjectIntrospection_REPOSITORY_DIR "${CMAKE_INSTALL_PREFIX}/share/gir-1.0") +endif() + +if(CMAKE_INSTALL_FULL_LIBDIR) + set(GObjectIntrospection_TYPELIB_DIR "${CMAKE_INSTALL_FULL_LIBDIR}/girepository-1.0") +else() + set(GObjectIntrospection_TYPELIB_DIR "${CMAKE_INSTALL_LIBDIR}/girepository-1.0") +endif() + +if(GObjectIntrospection_COMPILER_EXECUTABLE) + # Imported target + add_executable(g-ir-compiler IMPORTED) + set_property(TARGET g-ir-compiler PROPERTY IMPORTED_LOCATION "${GObjectIntrospection_COMPILER_EXECUTABLE}") +endif() + +if(GObjectIntrospection_SCANNER_EXECUTABLE) + # Imported target + add_executable(g-ir-scanner IMPORTED) + set_property(TARGET g-ir-scanner PROPERTY IMPORTED_LOCATION "${GObjectIntrospection_SCANNER_EXECUTABLE}") +endif() + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(GObjectIntrospection + REQUIRED_VARS + GObjectIntrospection_COMPILER_EXECUTABLE + GObjectIntrospection_SCANNER_EXECUTABLE) + +function(gobject_introspection_compile TYPELIB) + set (options DEBUG VERBOSE) + set (oneValueArgs MODULE SHARED_LIBRARY) + set (multiValueArgs FLAGS INCLUDE_DIRS) + cmake_parse_arguments(GObjectIntrospection_COMPILER "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) + unset (options) + unset (oneValueArgs) + unset (multiValueArgs) + + get_filename_component(TYPELIB "${TYPELIB}" ABSOLUTE + BASE_DIR "${CMAKE_CURRENT_BINARY_DIR}") + + if(GObjectIntrospection_COMPILER_DEBUG) + list(APPEND GObjectIntrospection_COMPILER_FLAGS "--debug") + endif() + + if(GObjectIntrospection_COMPILER_VERBOSE) + list(APPEND GObjectIntrospection_COMPILER_FLAGS "--verbose") + endif() + + if(GObjectIntrospection_SHARED_LIBRARY) + list(APPEND GObjectIntrospection_COMPILER_FLAGS "--shared-library" "${GObjectIntrospection_SHARED_LIBRARY}") + endif() + + foreach(include_dir ${GObjectIntrospection_COMPILER_INCLUDE_DIRS}) + list(APPEND GObjectIntrospection_COMPILER_FLAGS "--includedir" "${include_dir}") + endforeach() + + add_custom_command( + OUTPUT "${TYPELIB}" + COMMAND g-ir-compiler + ARGS + "-o" "${TYPELIB}" + ${GObjectIntrospection_COMPILER_FLAGS} + ${GObjectIntrospection_COMPILER_UNPARSED_ARGUMENTS} + DEPENDS + ${GObjectIntrospection_COMPILER_UNPARSED_ARGUMENTS}) +endfunction() diff --git a/cmake/FindLIBFWUPD.cmake b/cmake/FindLIBFWUPD.cmake new file mode 100644 index 00000000..2b592cac --- /dev/null +++ b/cmake/FindLIBFWUPD.cmake @@ -0,0 +1,58 @@ +# - Try to find the Fwupd library +# Once done this will define +# +# LIBFWUPD_FOUND - system has the fwupd library +# LIBFWUPD_INCLUDE_DIR - the Fwupd include directory +# LIBFWUPD_LIBRARY - Link this to use the fwupd +# +# Copyright © 2018, Abhijeet Sharma +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# 3. Neither the name of the University nor the names of its contributors +# may be used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +# SUCH DAMAGE. + +if(LIBFWUPD_INCLUDE_DIRS AND LIBFWUPD_LIBRARIES) + set(LIBFWUPD_FOUND TRUE) + +else (LIBFWUPD_INCLUDE_DIRS AND LIBFWUPD_LIBRARIES) + + find_library (LIBFWUPD_LIBRARIES + NAMES fwupd libfwupd + ) + + find_path (LIBFWUPD_INCLUDE_DIRS + NAMES fwupd.h + PATH_SUFFIXES fwupd-1 + HINTS fwupd-1/libfwupd + ) + set(LIBFWUPD_FOUND TRUE) + +endif (LIBFWUPD_INCLUDE_DIRS AND LIBFWUPD_LIBRARIES) + +if (LIBFWUPD_FOUND) + add_library(LIBFWUPD SHARED IMPORTED) + set_target_properties(LIBFWUPD PROPERTIES + INTERFACE_INCLUDE_DIRECTORIES ${LIBFWUPD_INCLUDE_DIRS} + IMPORTED_LOCATION ${LIBFWUPD_LIBRARIES} + ) +endif() diff --git a/cmake/FindSoup.cmake b/cmake/FindSoup.cmake new file mode 100644 index 00000000..6a5955cc --- /dev/null +++ b/cmake/FindSoup.cmake @@ -0,0 +1,86 @@ +# FindSoup.cmake +# +# +# CMake support for libsoup. +# +# License: +# +# Copyright (c) 2016 Evan Nemerson +# +# Permission is hereby granted, free of charge, to any person +# obtaining a copy of this software and associated documentation +# files (the "Software"), to deal in the Software without +# restriction, including without limitation the rights to use, copy, +# modify, merge, publish, distribute, sublicense, and/or sell copies +# of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be +# included in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +# HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +# DEALINGS IN THE SOFTWARE. + +find_package(PkgConfig) + +set(Soup_DEPS + GIO) + +if(PKG_CONFIG_FOUND) + pkg_search_module(Soup_PKG libsoup-2.4) +endif() + +find_library(Soup_LIBRARY soup-2.4 HINTS ${Soup_PKG_LIBRARY_DIRS}) +set(Soup soup-2.4) + +if(Soup_LIBRARY AND NOT Soup_FOUND) + add_library(${Soup} SHARED IMPORTED) + set_property(TARGET ${Soup} PROPERTY IMPORTED_LOCATION "${Soup_LIBRARY}") + set_property(TARGET ${Soup} PROPERTY INTERFACE_COMPILE_OPTIONS "${Soup_PKG_CFLAGS_OTHER}") + + find_path(Soup_INCLUDE_DIR "libsoup/soup.h" + HINTS ${Soup_PKG_INCLUDE_DIRS}) + + if(Soup_INCLUDE_DIR) + file(STRINGS "${Soup_INCLUDE_DIR}/libsoup/soup-version.h" Soup_MAJOR_VERSION REGEX "^#define SOUP_MAJOR_VERSION +\\(?([0-9]+)\\)?$") + string(REGEX REPLACE "^#define SOUP_MAJOR_VERSION \\(([0-9]+)\\)$" "\\1" Soup_MAJOR_VERSION "${Soup_MAJOR_VERSION}") + file(STRINGS "${Soup_INCLUDE_DIR}/libsoup/soup-version.h" Soup_MINOR_VERSION REGEX "^#define SOUP_MINOR_VERSION +\\(?([0-9]+)\\)?$") + string(REGEX REPLACE "^#define SOUP_MINOR_VERSION \\(([0-9]+)\\)$" "\\1" Soup_MINOR_VERSION "${Soup_MINOR_VERSION}") + file(STRINGS "${Soup_INCLUDE_DIR}/libsoup/soup-version.h" Soup_MICRO_VERSION REGEX "^#define SOUP_MICRO_VERSION +\\(?([0-9]+)\\)?$") + string(REGEX REPLACE "^#define SOUP_MICRO_VERSION \\(([0-9]+)\\)$" "\\1" Soup_MICRO_VERSION "${Soup_MICRO_VERSION}") + set(Soup_VERSION "${Soup_MAJOR_VERSION}.${Soup_MINOR_VERSION}.${Soup_MICRO_VERSION}") + unset(Soup_MAJOR_VERSION) + unset(Soup_MINOR_VERSION) + unset(Soup_MICRO_VERSION) + + list(APPEND Soup_INCLUDE_DIRS ${Soup_INCLUDE_DIR}) + set_property(TARGET ${Soup} PROPERTY INTERFACE_INCLUDE_DIRECTORIES "${Soup_INCLUDE_DIR}") + endif() +endif() + +set(Soup_DEPS_FOUND_VARS) +foreach(soup_dep ${Soup_DEPS}) + find_package(${soup_dep}) + + list(APPEND Soup_DEPS_FOUND_VARS "${soup_dep}_FOUND") + list(APPEND Soup_INCLUDE_DIRS ${${soup_dep}_INCLUDE_DIRS}) + + set_property (TARGET "${Soup}" APPEND PROPERTY INTERFACE_LINK_LIBRARIES "${${soup_dep}}") +endforeach(soup_dep) + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(Soup + REQUIRED_VARS + Soup_LIBRARY + Soup_INCLUDE_DIRS + ${Soup_DEPS_FOUND_VARS} + VERSION_VAR + Soup_VERSION) + +unset(Soup_DEPS_FOUND_VARS) diff --git a/libdiscover/backends/CMakeLists.txt b/libdiscover/backends/CMakeLists.txt index 83b8b506..4cf4b22b 100644 --- a/libdiscover/backends/CMakeLists.txt +++ b/libdiscover/backends/CMakeLists.txt @@ -1,41 +1,46 @@ function(add_unit_test name) add_executable(${name} ${CMAKE_SOURCE_DIR}/libdiscover/tests/modeltest.cpp ${ARGN}) add_test(${name} ${name}) ecm_mark_as_test(${name}) target_link_libraries(${name} Discover::Common Qt5::Test Qt5::Core ${EXTRA_LIBS}) endfunction() if(KF5Attica_FOUND AND KF5NewStuff_FOUND) add_subdirectory(KNSBackend) endif() if(packagekitqt5_FOUND AND AppStreamQt_FOUND) add_subdirectory(PackageKitBackend) endif() option(BUILD_DummyBackend "Build the DummyBackend" "OFF") if(BUILD_DummyBackend) add_subdirectory(DummyBackend) endif() option(BUILD_FlatpakBackend "Build Flatpak support" "ON") if(FLATPAK_FOUND AND AppStreamQt_FOUND AND BUILD_FlatpakBackend) add_subdirectory(FlatpakBackend) elseif(BUILD_FlatpakBackend) message(WARNING "BUILD_FlatpakBackend enabled but Flatpak=${FLATPAK_FOUND} or AppStreamQt=${AppStreamQt_FOUND} not found") endif() find_package(Snapd) set_package_properties(Snapd PROPERTIES DESCRIPTION "Library that exposes Snapd" URL "http://www.snapcraft.io" PURPOSE "Required to build the Snap backend" TYPE OPTIONAL) option(BUILD_SnapBackend "Build Snap support." "ON") if(BUILD_SnapBackend AND Snapd_FOUND) add_subdirectory(SnapBackend) endif() + +option(BUILD_FwupdBackend "Build Fwupd support." "ON") +if(BUILD_FwupdBackend AND LIBFWUPD_FOUND) + add_subdirectory(FwupdBackend) +endif() \ No newline at end of file diff --git a/libdiscover/backends/FwupdBackend/CMakeLists.txt b/libdiscover/backends/FwupdBackend/CMakeLists.txt new file mode 100644 index 00000000..9988ce7b --- /dev/null +++ b/libdiscover/backends/FwupdBackend/CMakeLists.txt @@ -0,0 +1,41 @@ +add_subdirectory(tests) +add_definitions( -DPROJECT_NAME=${PROJECT_NAME} -DPROJECT_VERSION=${PROJECT_VERSION}) + +set(fwupd-backend_SRCS + FwupdResource.cpp + FwupdBackend.cpp + FwupdReviewsBackend.cpp + FwupdTransaction.cpp + FwupdSourcesBackend.cpp +) + + + + +#find_package(GIO) +find_package(Soup) +find_package(GLib) + + +MESSAGE( STATUS "FWUPD_INCLUDE_DIRS variable is: " ${LIBFWUPD_INCLUDE_DIRS} ) +MESSAGE( STATUS "FWUPD_LIBRARIES variable is: " ${LIBFWUPD_LIBRARIES} ) + +include_directories(${LIBFWUPD_INCLUDE_DIRS} ) + + + +add_library(fwupd-backend MODULE ${fwupd-backend_SRCS}) +target_link_libraries(fwupd-backend Qt5::Core Qt5::Widgets KF5::CoreAddons KF5::ConfigCore Discover::Common LIBFWUPD ${Soup} ${GIO} ${GLib} ) + + + +install(TARGETS fwupd-backend DESTINATION ${PLUGIN_INSTALL_DIR}/discover) +install(FILES fwupd-backend-categories.xml DESTINATION ${DATA_INSTALL_DIR}/libdiscover/categories) + +add_library(FwupdNotifier MODULE FwupdNotifier.cpp ) +target_link_libraries(FwupdNotifier Discover::Notifiers) +set_target_properties(FwupdNotifier PROPERTIES INSTALL_RPATH ${CMAKE_INSTALL_FULL_LIBDIR}/plasma-discover) + +install(TARGETS FwupdNotifier DESTINATION ${PLUGIN_INSTALL_DIR}/discover-notifier) + + diff --git a/libdiscover/backends/FwupdBackend/FwupdBackend.cpp b/libdiscover/backends/FwupdBackend/FwupdBackend.cpp new file mode 100644 index 00000000..b384af90 --- /dev/null +++ b/libdiscover/backends/FwupdBackend/FwupdBackend.cpp @@ -0,0 +1,233 @@ +/*************************************************************************** + * Copyright © 2013 Aleix Pol Gonzalez * + * Copyright © 2018 Abhijeet Sharma * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License as * + * published by the Free Software Foundation; either version 2 of * + * the License or (at your option) version 3 or any later version * + * 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 * + * defined in Section 14 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. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + ***************************************************************************/ + +#include "FwupdBackend.h" +#include "FwupdResource.h" +#include "FwupdReviewsBackend.h" +#include "FwupdTransaction.h" +#include "FwupdSourcesBackend.h" +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +DISCOVER_BACKEND_PLUGIN(FwupdBackend) + +#define STRING(s) #s + +FwupdBackend::FwupdBackend(QObject* parent) + : AbstractResourcesBackend(parent) + , m_updater(new StandardBackendUpdater(this)) + , m_reviews(new FwupdReviewsBackend(this)) + , m_fetching(true) + , m_startElements(120) +{ + + QTimer::singleShot(500, this, &FwupdBackend::toggleFetching); + connect(m_reviews, &FwupdReviewsBackend::ratingsReady, this, &AbstractResourcesBackend::emitRatingsReady); + connect(m_updater, &StandardBackendUpdater::updatesCountChanged, this, &FwupdBackend::updatesCountChanged); + + client = fwupd_client_new (); + to_download = g_ptr_array_new_with_free_func (g_free); + to_ignore = g_ptr_array_new_with_free_func (g_free); + + /* use a custom user agent to provide the fwupd version */ + user_agent = fwupd_build_user_agent (STRING(PROJECT_NAME),STRING(PROJECT_VERSION)); + soup_session = soup_session_new_with_options (SOUP_SESSION_USER_AGENT, user_agent, + SOUP_SESSION_TIMEOUT, 10, + NULL); + soup_session_remove_feature_by_type (soup_session, + SOUP_TYPE_CONTENT_DECODER); + + + populate(QStringLiteral("Devices")); + if (!m_fetching) + m_reviews->initialize(); + + SourcesModel::global()->addSourcesBackend(new FwupdSourcesBackend(this)); +} + +FwupdBackend::~FwupdBackend() +{ + g_object_unref (client); + g_ptr_array_unref (to_download); + g_ptr_array_unref (to_ignore); +} + +void FwupdBackend::populate(const QString& n) +{ + g_autoptr(GPtrArray) remotes = NULL; + g_autoptr(GCancellable) cancellable = g_cancellable_new(); + g_autoptr(GError) error = NULL; + g_autoptr(GError) error2 = NULL; + g_autoptr(GPtrArray) devices = NULL; + g_autoptr(GPtrArray) rels = NULL; + + /* get devices */ + devices = fwupd_client_get_devices (client, cancellable, &error); + //releases = fwupd_client_get_releases (client,gs_fwupd_app_get_device_id (app),cancellable,&error_local); + if(devices == NULL){ + if (g_error_matches (error,FWUPD_ERROR,FWUPD_ERROR_NOTHING_TO_DO)){ + qDebug() << "No Devices Found"; + } + } + else{ + for (guint i = 0; i < devices->len; i++) { + FwupdDevice *device = (FwupdDevice *)g_ptr_array_index (devices, i); + const QString name = QLatin1String(fwupd_device_get_name(device)); + FwupdResource* res = new FwupdResource(name, false, this); + + res->addCategories(n); + res->setSummary(QLatin1String(fwupd_device_get_summary(device))); + res->setVendor(QLatin1String(fwupd_device_get_vendor(device))); + res->setVersion(QLatin1String(fwupd_device_get_version(device))); + res->setDescription(QLatin1String(fwupd_device_get_description(device))); + m_resources.insert(name.toLower(), res); + + connect(res, &FwupdResource::stateChanged, this, &FwupdBackend::updatesCountChanged); + + rels = fwupd_client_get_upgrades (client,fwupd_device_get_id(device),cancellable, &error2); + + if (rels == NULL) { + if (g_error_matches (error2,FWUPD_ERROR,FWUPD_ERROR_NOTHING_TO_DO)){ + qDebug() << "No Packages Found for "<< fwupd_device_get_id(device); + continue; + } + } + else{ + for (guint j = 0; j < rels->len; j++) { + FwupdRelease *rel = (FwupdRelease *)g_ptr_array_index (rels, j); + const QString name_ = QLatin1String(fwupd_release_get_name(rel)); + FwupdResource* res_ = new FwupdResource(name_, false, this); + res_->addCategories(QLatin1String("Releases")); + res_->setSummary(QLatin1String(fwupd_release_get_summary(rel))); + res_->setVendor(QLatin1String(fwupd_release_get_vendor(rel))); + res_->setVersion(QLatin1String(fwupd_release_get_version(rel))); + res_->setDescription(QLatin1String(fwupd_release_get_description(rel))); + res_->setHomePage(QUrl(QLatin1String(fwupd_release_get_homepage(rel)))); + res_->setLicense(QLatin1String(fwupd_release_get_license(rel))); + m_resources.insert(name_.toLower(), res_); + } + } + } + } +} + +void FwupdBackend::toggleFetching() +{ + m_fetching = !m_fetching; +// qDebug() << "fetching..." << m_fetching; + emit fetchingChanged(); + if (!m_fetching) + m_reviews->initialize(); +} + +int FwupdBackend::updatesCount() const +{ + return m_updater->updatesCount(); +} + +ResultsStream* FwupdBackend::search(const AbstractResourcesBackend::Filters& filter) +{ + QVector ret; + if (!filter.resourceUrl.isEmpty() && filter.resourceUrl.scheme() == QLatin1String("fwupd")) + return findResourceByPackageName(filter.resourceUrl); + else foreach(AbstractResource* r, m_resources) { + if(r->name().contains(filter.search, Qt::CaseInsensitive) || r->comment().contains(filter.search, Qt::CaseInsensitive)) + ret += r; + } + return new ResultsStream(QStringLiteral("FwupdStream"), ret); +} + +ResultsStream * FwupdBackend::findResourceByPackageName(const QUrl& search) +{ + auto res = search.scheme() == QLatin1String("fwupd") ? m_resources.value(search.host().replace(QLatin1Char('.'), QLatin1Char(' '))) : nullptr; + if (!res) { + return new ResultsStream(QStringLiteral("FwupdStream"), {}); + } else + return new ResultsStream(QStringLiteral("FwupdStream"), { res }); +} + +AbstractBackendUpdater* FwupdBackend::backendUpdater() const +{ + return m_updater; +} + +AbstractReviewsBackend* FwupdBackend::reviewsBackend() const +{ + return m_reviews; +} + +Transaction* FwupdBackend::installApplication(AbstractResource* app, const AddonList& addons) +{ + return new FwupdTransaction(qobject_cast(app), addons, Transaction::InstallRole); +} + +Transaction* FwupdBackend::installApplication(AbstractResource* app) +{ + return new FwupdTransaction(qobject_cast(app), Transaction::InstallRole); +} + +Transaction* FwupdBackend::removeApplication(AbstractResource* app) +{ + return new FwupdTransaction(qobject_cast(app), Transaction::RemoveRole); +} + +void FwupdBackend::checkForUpdates() +{ + if(m_fetching) + return; + toggleFetching(); + populate(QStringLiteral("Devices")); + QTimer::singleShot(500, this, &FwupdBackend::toggleFetching); + qDebug() << "FwupdBackend::checkForUpdates"; +} + +AbstractResource * FwupdBackend::resourceForFile(const QUrl& path) +{ + FwupdResource* res = new FwupdResource(path.fileName(), true, this); + res->setSize(666); + res->setState(AbstractResource::None); + m_resources.insert(res->packageName(), res); + connect(res, &FwupdResource::stateChanged, this, &FwupdBackend::updatesCountChanged); + return res; +} + +QString FwupdBackend::displayName() const +{ + return QStringLiteral("Fwupd"); +} + +bool FwupdBackend::hasApplications() const +{ + return true; +} + +#include "FwupdBackend.moc" diff --git a/libdiscover/backends/FwupdBackend/FwupdBackend.h b/libdiscover/backends/FwupdBackend/FwupdBackend.h new file mode 100644 index 00000000..dde621ee --- /dev/null +++ b/libdiscover/backends/FwupdBackend/FwupdBackend.h @@ -0,0 +1,95 @@ +/*************************************************************************** + * Copyright © 2013 Aleix Pol Gonzalez * + * Copyright © 2018 Abhijeet Sharma * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License as * + * published by the Free Software Foundation; either version 2 of * + * the License or (at your option) version 3 or any later version * + * 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 * + * defined in Section 14 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. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + ***************************************************************************/ + +#ifndef FWUPDBACKEND_H +#define FWUPDBACKEND_H + +#include +#include + +extern "C" { +#include +} +#include +#include +#include +#include +#include + + +#include +#include +#include + + + +class QAction; +class FwupdReviewsBackend; +class StandardBackendUpdater; +class FwupdResource; +class FwupdBackend : public AbstractResourcesBackend +{ +Q_OBJECT +Q_PROPERTY(int startElements MEMBER m_startElements) +public: + explicit FwupdBackend(QObject* parent = nullptr); + ~FwupdBackend(); + + int updatesCount() const override; + AbstractBackendUpdater* backendUpdater() const override; + AbstractReviewsBackend* reviewsBackend() const override; + ResultsStream* search(const AbstractResourcesBackend::Filters & search) override; + ResultsStream * findResourceByPackageName(const QUrl& search) ; + QHash resources() const { return m_resources; } + bool isValid() const override { return true; } // No external file dependencies that could cause runtime errors + + Transaction* installApplication(AbstractResource* app) override; + Transaction* installApplication(AbstractResource* app, const AddonList& addons) override; + Transaction* removeApplication(AbstractResource* app) override; + bool isFetching() const override { return m_fetching; } + AbstractResource * resourceForFile(const QUrl & ) override; + void checkForUpdates() override; + QString displayName() const override; + bool hasApplications() const override; + FwupdClient *client; + GPtrArray *to_download; + GPtrArray *to_ignore; + + +public Q_SLOTS: + void toggleFetching(); + +private: + void populate(const QString& name); + + QHash m_resources; + StandardBackendUpdater* m_updater; + FwupdReviewsBackend* m_reviews; + bool m_fetching; + int m_startElements; + + + g_autofree gchar *user_agent = NULL; + g_autoptr(SoupSession) soup_session = NULL; + +}; + +#endif // FWUPDBACKEND_H diff --git a/libdiscover/backends/FwupdBackend/FwupdNotifier.cpp b/libdiscover/backends/FwupdBackend/FwupdNotifier.cpp new file mode 100644 index 00000000..0bb14906 --- /dev/null +++ b/libdiscover/backends/FwupdBackend/FwupdNotifier.cpp @@ -0,0 +1,46 @@ +/*************************************************************************** + * Copyright © 2013 Lukas Appelhans * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License as * + * published by the Free Software Foundation; either version 2 of * + * the License or (at your option) version 3 or any later version * + * 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 * + * defined in Section 14 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. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + ***************************************************************************/ +#include "FwupdNotifier.h" + +#include + +FwupdNotifier::FwupdNotifier(QObject* parent) + : BackendNotifierModule(parent) +{ +} + +FwupdNotifier::~FwupdNotifier() +{ +} + +void FwupdNotifier::recheckSystemUpdateNeeded() +{ + emit foundUpdates(); +} + +uint FwupdNotifier::securityUpdatesCount() +{ + return 0; +} + +uint FwupdNotifier::updatesCount() +{ + return 0; +} diff --git a/libdiscover/backends/FwupdBackend/FwupdNotifier.h b/libdiscover/backends/FwupdBackend/FwupdNotifier.h new file mode 100644 index 00000000..329f8d61 --- /dev/null +++ b/libdiscover/backends/FwupdBackend/FwupdNotifier.h @@ -0,0 +1,39 @@ +/*************************************************************************** + * Copyright © 2013 Lukas Appelhans * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License as * + * published by the Free Software Foundation; either version 2 of * + * the License or (at your option) version 3 or any later version * + * 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 * + * defined in Section 14 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. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + ***************************************************************************/ +#ifndef FWUPDNOTIFIER_H +#define FWUPDNOTIFIER_H + +#include + +class FwupdNotifier : public BackendNotifierModule +{ +Q_OBJECT +Q_PLUGIN_METADATA(IID "org.kde.discover.BackendNotifierModule") +Q_INTERFACES(BackendNotifierModule) +public: + explicit FwupdNotifier(QObject* parent = nullptr); + ~FwupdNotifier() override; + + void recheckSystemUpdateNeeded() override; + uint securityUpdatesCount() override; + uint updatesCount() override; +}; + +#endif diff --git a/libdiscover/backends/FwupdBackend/FwupdResource.cpp b/libdiscover/backends/FwupdBackend/FwupdResource.cpp new file mode 100644 index 00000000..93b23c2d --- /dev/null +++ b/libdiscover/backends/FwupdBackend/FwupdResource.cpp @@ -0,0 +1,199 @@ +/*************************************************************************** + * Copyright © 2013 Aleix Pol Gonzalez * + * Copyright © 2018 Abhijeet Sharma * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License as * + * published by the Free Software Foundation; either version 2 of * + * the License or (at your option) version 3 or any later version * + * 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 * + * defined in Section 14 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. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + ***************************************************************************/ + +#include "FwupdResource.h" +#include "FwupdBackend.h" + +#include +#include +#include +#include +#include + +Q_GLOBAL_STATIC_WITH_ARGS(QVector, s_icons, ({ QLatin1String("kdevelop"), QLatin1String("kalgebra"), QLatin1String("kmail"), QLatin1String("akregator"), QLatin1String("korganizer") })) + +FwupdResource::FwupdResource(QString name, bool isTechnical, AbstractResourcesBackend* parent) + : AbstractResource(parent) + , m_name(std::move(name)) + , m_state(State::Broken) + , m_iconName((*s_icons)[KRandom::random() % s_icons->size()]) + , m_addons({ PackageState(QStringLiteral("a"), QStringLiteral("aaaaaa"), false), PackageState(QStringLiteral("b"), QStringLiteral("aaaaaa"), false), PackageState(QStringLiteral("c"), QStringLiteral("aaaaaa"), false)}) + , m_isTechnical(isTechnical) +{ + const int nofScreenshots = KRandom::random() % 5; + m_screenshots = QList{ + QUrl(QStringLiteral("http://screenshots.debian.net/screenshots/000/014/863/large.png")), + QUrl(QStringLiteral("https://c2.staticflickr.com/6/5656/21772158034_dc84382527_o.jpg")), + QUrl(QStringLiteral("https://c1.staticflickr.com/9/8479/8166397343_b78106f353_k.jpg")), + QUrl(QStringLiteral("https://c2.staticflickr.com/4/3685/9954407993_dad10a6943_k.jpg")), + QUrl(QStringLiteral("https://c1.staticflickr.com/1/653/22527103378_8ce572e1de_k.jpg")) + }.mid(nofScreenshots); + m_screenshotThumbnails = m_screenshots; +} + +QList FwupdResource::addonsInformation() +{ + return m_addons; +} + +QString FwupdResource::availableVersion() const +{ + return m_version; +} + +QStringList FwupdResource::categories() +{ + return m_categories; +} + +void FwupdResource::addCategories(const QString &category){ + m_categories.append(category); +} + +QString FwupdResource::comment() +{ + return m_summary; +} + +int FwupdResource::size() +{ + return m_size; +} + +QUrl FwupdResource::homepage() +{ + return m_homepage; +} + +QUrl FwupdResource::helpURL() +{ + return QUrl(QStringLiteral("http://very-very-excellent-docs.lol")); +} + +QUrl FwupdResource::bugURL() +{ + return QUrl(QStringLiteral("file:///dev/null")); +} + +QUrl FwupdResource::donationURL() +{ + return QUrl(QStringLiteral("https://youtu.be/0o8XMlL8rqY")); +} + +QVariant FwupdResource::icon() const +{ + return isTechnical() ? QStringLiteral("kalarm") : m_iconName; +} + +QString FwupdResource::installedVersion() const +{ + return m_version; +} + +QString FwupdResource::license() +{ + return m_license; +} + +QString FwupdResource::longDescription() +{ + return m_description; +} + +QString FwupdResource::name() const +{ + return m_name; +} + +QString FwupdResource::vendor() const +{ + return m_vendor; +} + +QString FwupdResource::origin() const +{ + return QStringLiteral("FwupdSource1"); +} + +QString FwupdResource::packageName() const +{ + return m_name; +} + +QString FwupdResource::section() +{ + return QStringLiteral("fwupd"); +} + +AbstractResource::State FwupdResource::state() +{ + return m_state; +} + +void FwupdResource::fetchChangelog() +{ + QString log = longDescription(); + log.replace(QLatin1Char('\n'), QLatin1String("
")); + + emit changelogFetched(log); +} + +void FwupdResource::fetchScreenshots() +{ + Q_EMIT screenshotsFetched(m_screenshotThumbnails, m_screenshots); +} + +void FwupdResource::setState(AbstractResource::State state) +{ + m_state = state; + emit stateChanged(); +} + +void FwupdResource::setAddons(const AddonList& addons) +{ + Q_FOREACH (const QString& toInstall, addons.addonsToInstall()) { + setAddonInstalled(toInstall, true); + } + Q_FOREACH (const QString& toRemove, addons.addonsToRemove()) { + setAddonInstalled(toRemove, false); + } +} + +void FwupdResource::setAddonInstalled(const QString& addon, bool installed) +{ + for(auto & elem : m_addons) { + if(elem.name() == addon) { + elem.setInstalled(installed); + } + } +} + + +void FwupdResource::invokeApplication() const +{ + QDesktopServices d; + d.openUrl(QUrl(QStringLiteral("https://projects.kde.org/projects/extragear/sysadmin/muon"))); +} + +QUrl FwupdResource::url() const +{ + return QUrl(QLatin1String("fwupd://") + packageName().replace(QLatin1Char(' '), QLatin1Char('.'))); +} diff --git a/libdiscover/backends/FwupdBackend/FwupdResource.h b/libdiscover/backends/FwupdBackend/FwupdResource.h new file mode 100644 index 00000000..1980d9bb --- /dev/null +++ b/libdiscover/backends/FwupdBackend/FwupdResource.h @@ -0,0 +1,100 @@ +/*************************************************************************** + * Copyright © 2013 Aleix Pol Gonzalez * + * Copyright © 2018 Abhijeet Sharma * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License as * + * published by the Free Software Foundation; either version 2 of * + * the License or (at your option) version 3 or any later version * + * 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 * + * defined in Section 14 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. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + ***************************************************************************/ + +#ifndef FWUPDRESOURCE_H +#define FWUPDRESOURCE_H + +#include + +class AddonList; +class FwupdResource : public AbstractResource +{ +Q_OBJECT +public: + explicit FwupdResource(QString name, bool isTechnical, AbstractResourcesBackend* parent); + + QList addonsInformation() override; + QString section() override; + QString origin() const override; + QString longDescription() override; + QString availableVersion() const override; + QString installedVersion() const override; + QString license() override; + int size() override; + QUrl homepage() override; + QUrl helpURL() override; + QUrl bugURL() override; + QUrl donationURL() override; + QStringList categories() override; + AbstractResource::State state() override; + QVariant icon() const override; + QString comment() override; + QString name() const override; + QString packageName() const override; + QString vendor() const; + bool isTechnical() const override { return m_isTechnical; } + bool canExecute() const override { return true; } + void invokeApplication() const override; + void fetchChangelog() override; + void fetchScreenshots() override; + QUrl url() const override; + + void setState(State state); + void setSize(int size) { m_size = size; } + void setAddons(const AddonList& addons); + bool setId(const QString &id); + void setName(const QString &name){ m_name = name;}; + void setSummary(const QString &summary){ m_summary = summary;}; + void setDescription(const QString &description){ m_description = description;}; + void setVersion(const QString &version){ m_version = version;}; + void setVendor(const QString &vendor){ m_vendor = vendor;}; + void addCategories(const QString &category); + void setHomePage(const QUrl &homepage){ m_homepage = homepage;}; + void setLicense(const QString &license){ m_license = license;}; + + void setAddonInstalled(const QString& addon, bool installed); + QString sourceIcon() const override { return QStringLiteral("player-time"); } + QDate releaseDate() const override { return {}; } + +public: + QString m_id; + QString m_name; + QString m_summary; + QString m_description; + QString m_version; + QString m_vendor; + QStringList m_categories; + QString m_license; + + AbstractResource::State m_state; + QList m_screenshots; + QList m_screenshotThumbnails; + QUrl m_homepage; + QString m_iconName; + QList m_addons; + bool m_isTechnical; + int m_size; + + + +}; + +#endif // FWUPDRESOURCE_H diff --git a/libdiscover/backends/FwupdBackend/FwupdReviewsBackend.cpp b/libdiscover/backends/FwupdBackend/FwupdReviewsBackend.cpp new file mode 100644 index 00000000..32b2b4dd --- /dev/null +++ b/libdiscover/backends/FwupdBackend/FwupdReviewsBackend.cpp @@ -0,0 +1,82 @@ +/*************************************************************************** + * Copyright © 2013 Aleix Pol Gonzalez * * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License as * + * published by the Free Software Foundation; either version 2 of * + * the License or (at your option) version 3 or any later version * + * 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 * + * defined in Section 14 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. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + ***************************************************************************/ + +#include "FwupdReviewsBackend.h" +#include "FwupdBackend.h" +#include "FwupdResource.h" +#include +#include +#include +#include +#include + +FwupdReviewsBackend::FwupdReviewsBackend(FwupdBackend* parent) + : AbstractReviewsBackend(parent) +{} + +void FwupdReviewsBackend::fetchReviews(AbstractResource* app, int page) +{ + if (page>=5) + return; + + QVector review; + for(int i=0; i<33; i++) { + review += ReviewPtr(new Review(app->name(), app->packageName(), QStringLiteral("en_US"), QStringLiteral("good morning"), QStringLiteral("the morning is very good"), QStringLiteral("fwupd"), + QDateTime(), true, page+i, i%5, 1, 1, app->packageName())); + } + emit reviewsReady(app, review, false); +} + +Rating* FwupdReviewsBackend::ratingForApplication(AbstractResource* app) const +{ + return m_ratings[app]; +} + +void FwupdReviewsBackend::initialize() +{ + int i = 11; + FwupdBackend* b = qobject_cast(parent()); + foreach(FwupdResource* app, b->resources()) { + if (m_ratings.contains(app)) + continue; + auto randomRating = qrand()%10; + Rating* rating = new Rating(app->packageName(), ++i, {{QStringLiteral("star5"), randomRating}}); + rating->setParent(this); + m_ratings.insert(app, rating); + app->ratingFetched(); + } + emit ratingsReady(); +} + +void FwupdReviewsBackend::submitUsefulness(Review* r, bool useful) +{ + qDebug() << "usefulness..." << r->applicationName() << r->reviewer() << useful; + r->setUsefulChoice(useful ? ReviewsModel::Yes : ReviewsModel::No); +} + +void FwupdReviewsBackend::submitReview(AbstractResource* res, const QString& a, const QString& b, const QString& c) +{ + qDebug() << "fwupd submit review" << res->name() << a << b << c; +} + +bool FwupdReviewsBackend::isResourceSupported(AbstractResource* /*res*/) const +{ + return true; +} diff --git a/libdiscover/backends/FwupdBackend/FwupdReviewsBackend.h b/libdiscover/backends/FwupdBackend/FwupdReviewsBackend.h new file mode 100644 index 00000000..671219e9 --- /dev/null +++ b/libdiscover/backends/FwupdBackend/FwupdReviewsBackend.h @@ -0,0 +1,59 @@ +/*************************************************************************** + * Copyright © 2013 Aleix Pol Gonzalez * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License as * + * published by the Free Software Foundation; either version 2 of * + * the License or (at your option) version 3 or any later version * + * 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 * + * defined in Section 14 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. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + ***************************************************************************/ + +#ifndef FWUPDREVIEWSBACKEND_H +#define FWUPDREVIEWSBACKEND_H + +#include +#include +#include + +class FwupdBackend; +class FwupdReviewsBackend : public AbstractReviewsBackend +{ +Q_OBJECT +public: + explicit FwupdReviewsBackend(FwupdBackend* parent = nullptr); + + QString userName() const override { return QStringLiteral("fwupd"); } + void login() override {} + void logout() override {} + void registerAndLogin() override {} + + Rating* ratingForApplication(AbstractResource* app) const override; + bool hasCredentials() const override { return false; } + void deleteReview(Review*) override {} + void fetchReviews(AbstractResource* app, int page = 1) override; + bool isFetching() const override { return false; } + void submitReview(AbstractResource*, const QString&, const QString&, const QString&) override; + void flagReview(Review*, const QString&, const QString&) override {} + void submitUsefulness(Review*, bool) override; + + void initialize(); + bool isResourceSupported(AbstractResource * res) const override; + +Q_SIGNALS: + void ratingsReady(); + +private: + QHash m_ratings; +}; + +#endif // FWUPDREVIEWSBACKEND_H diff --git a/libdiscover/backends/FwupdBackend/FwupdSourcesBackend.cpp b/libdiscover/backends/FwupdBackend/FwupdSourcesBackend.cpp new file mode 100644 index 00000000..c8e11c7c --- /dev/null +++ b/libdiscover/backends/FwupdBackend/FwupdSourcesBackend.cpp @@ -0,0 +1,94 @@ +/*************************************************************************** + * Copyright © 2014 Aleix Pol Gonzalez * + * Copyright © 2018 Abhijeet Sharma * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License as * + * published by the Free Software Foundation; either version 2 of * + * the License or (at your option) version 3 or any later version * + * 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 * + * defined in Section 14 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. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + ***************************************************************************/ + +#include "FwupdSourcesBackend.h" +#include "FwupdBackend.h" + +#include +#include +#include + + + +FwupdSourcesBackend::FwupdSourcesBackend(AbstractResourcesBackend * parent) + : AbstractSourcesBackend(parent) + , m_sources(new QStandardItemModel(this)) + , m_testAction(new QAction(QIcon::fromTheme(QStringLiteral("kalgebra")), QStringLiteral("FwupdAction"), this)) +{ + FwupdBackend* backend = qobject_cast(parent); + g_autoptr(GPtrArray) remotes = NULL; + g_autoptr(GCancellable) cancellable = g_cancellable_new(); + g_autoptr(GError) error = NULL; + /* find all remotes */ + remotes = fwupd_client_get_remotes (backend->client,cancellable,&error); + + for (guint i = 0; i < remotes->len; i++) { + FwupdRemote *remote = (FwupdRemote *)g_ptr_array_index (remotes, i); + g_autofree gchar *id = NULL; + /* ignore these, they're built in */ + if (fwupd_remote_get_kind (remote) == FWUPD_REMOTE_KIND_LOCAL) + continue; + /* create something that we can use to enable/disable */ + id = g_strdup_printf ("org.fwupd.%s.remote", fwupd_remote_get_id (remote)); + addSource(QLatin1String(id)); + } + //for (int i = 0; i<10; ++i) + //s addSource(QStringLiteral("FwupdSource%1").arg(i)); + + connect(m_testAction, &QAction::triggered, [](){ qDebug() << "action triggered!"; }); + connect(m_sources, &QStandardItemModel::itemChanged, this, [](QStandardItem* item) { qDebug() << "FwupdSource changed" << item << item->checkState(); }); +} + +QAbstractItemModel* FwupdSourcesBackend::sources() +{ + return m_sources; +} + +bool FwupdSourcesBackend::addSource(const QString& id) +{ + if (id.isEmpty()) + return false; + + + QStandardItem* it = new QStandardItem(id); + it->setData(QVariant(id + QLatin1Char(' ') + id), Qt::ToolTipRole); + it->setCheckable(true); + it->setCheckState(Qt::Checked); + m_sources->appendRow(it); + return true; +} + +bool FwupdSourcesBackend::removeSource(const QString& id) +{ + QList items = m_sources->findItems(id); + if (items.count()==1) { + m_sources->removeRow(items.first()->row()); + } else { + qWarning() << "couldn't find " << id << items; + } + return items.count()==1; +} + +QList FwupdSourcesBackend::actions() const +{ + return QList() << m_testAction; +} + diff --git a/libdiscover/backends/FwupdBackend/FwupdSourcesBackend.h b/libdiscover/backends/FwupdBackend/FwupdSourcesBackend.h new file mode 100644 index 00000000..4a2ed690 --- /dev/null +++ b/libdiscover/backends/FwupdBackend/FwupdSourcesBackend.h @@ -0,0 +1,46 @@ +/*************************************************************************** + * Copyright © 2014 Aleix Pol Gonzalez * + * Copyright © 2018 Abhijeet Sharma * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License as * + * published by the Free Software Foundation; either version 2 of * + * the License or (at your option) version 3 or any later version * + * 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 * + * defined in Section 14 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. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + ***************************************************************************/ + +#ifndef FWUPDSOURCESBACKEND_H +#define FWUPDSOURCESBACKEND_H + +#include +#include + + +class FwupdSourcesBackend : public AbstractSourcesBackend +{ +public: + explicit FwupdSourcesBackend(AbstractResourcesBackend * parent); + + QAbstractItemModel* sources() override; + bool addSource(const QString& id) override; + bool removeSource(const QString& id) override; + QString idDescription() override { return QStringLiteral("Random weird text"); } + QList actions() const override; + bool supportsAdding() const override { return true; } + +private: + QStandardItemModel* m_sources; + QAction* m_testAction; +}; + +#endif // FWUPDSOURCESBACKEND_H diff --git a/libdiscover/backends/FwupdBackend/FwupdTransaction.cpp b/libdiscover/backends/FwupdBackend/FwupdTransaction.cpp new file mode 100644 index 00000000..ad26bf6c --- /dev/null +++ b/libdiscover/backends/FwupdBackend/FwupdTransaction.cpp @@ -0,0 +1,88 @@ +/*************************************************************************** + * Copyright © 2013 Aleix Pol Gonzalez * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License as * + * published by the Free Software Foundation; either version 2 of * + * the License or (at your option) version 3 or any later version * + * 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 * + * defined in Section 14 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. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + ***************************************************************************/ + +#include "FwupdTransaction.h" +#include "FwupdBackend.h" +#include "FwupdResource.h" +#include +#include +#include + +// #define TEST_PROCEED + +FwupdTransaction::FwupdTransaction(FwupdResource* app, Role role) + : FwupdTransaction(app, {}, role) +{ +} + +FwupdTransaction::FwupdTransaction(FwupdResource* app, const AddonList& addons, Transaction::Role role) + : Transaction(app->backend(), app, role, addons) + , m_app(app) +{ + setCancellable(true); + iterateTransaction(); +} + +void FwupdTransaction::iterateTransaction() +{ + if (!m_iterate) + return; + + setStatus(CommittingStatus); + if(progress()<100) { + setProgress(qBound(0, progress()+(KRandom::random()%30), 100)); + QTimer::singleShot(/*KRandom::random()%*/100, this, &FwupdTransaction::iterateTransaction); + } else +#ifdef TEST_PROCEED + Q_EMIT proceedRequest(QStringLiteral("yadda yadda"), QStringLiteral("Biii BOooo
  • A
  • A
  • A
  • A
")); +#else + finishTransaction(); +#endif +} + +void FwupdTransaction::proceed() +{ + finishTransaction(); +} + +void FwupdTransaction::cancel() +{ + m_iterate = false; + + setStatus(CancelledStatus); +} + +void FwupdTransaction::finishTransaction() +{ + AbstractResource::State newState; + switch(role()) { + case InstallRole: + case ChangeAddonsRole: + newState = AbstractResource::Installed; + break; + case RemoveRole: + newState = AbstractResource::None; + break; + } + m_app->setAddons(addons()); + m_app->setState(newState); + setStatus(DoneStatus); + deleteLater(); +} diff --git a/libdiscover/backends/FwupdBackend/FwupdTransaction.h b/libdiscover/backends/FwupdBackend/FwupdTransaction.h new file mode 100644 index 00000000..bcb2cfef --- /dev/null +++ b/libdiscover/backends/FwupdBackend/FwupdTransaction.h @@ -0,0 +1,47 @@ +/*************************************************************************** + * Copyright © 2013 Aleix Pol Gonzalez * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License as * + * published by the Free Software Foundation; either version 2 of * + * the License or (at your option) version 3 or any later version * + * 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 * + * defined in Section 14 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. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + ***************************************************************************/ + +#ifndef FWUPDTRANSACTION_H +#define FWUPDTRANSACTION_H + +#include + + +class FwupdResource; +class FwupdTransaction : public Transaction +{ + Q_OBJECT + public: + FwupdTransaction(FwupdResource* app, Role role); + FwupdTransaction(FwupdResource* app, const AddonList& list, Role role); + + void cancel() override; + void proceed() override; + + private Q_SLOTS: + void iterateTransaction(); + void finishTransaction(); + + private: + bool m_iterate = true; + FwupdResource* m_app; +}; + +#endif // FWUPDTRANSACTION_H diff --git a/libdiscover/backends/FwupdBackend/fwupd-backend-categories.xml b/libdiscover/backends/FwupdBackend/fwupd-backend-categories.xml new file mode 100644 index 00000000..cccbb494 --- /dev/null +++ b/libdiscover/backends/FwupdBackend/fwupd-backend-categories.xml @@ -0,0 +1,38 @@ + + + + + Firmware Updates + applications-internet + pkcategories/applicationcrop.jpg + + + Firmware Updates + + + + + Devices + pkcategories/officecrop.jpg + applications-office + + + Devices + + + + + + Releases + pkcategories/officecrop.jpg + applications-office + + + Releases + + + + + + + diff --git a/libdiscover/backends/FwupdBackend/tests/CMakeLists.txt b/libdiscover/backends/FwupdBackend/tests/CMakeLists.txt new file mode 100644 index 00000000..ddac8b17 --- /dev/null +++ b/libdiscover/backends/FwupdBackend/tests/CMakeLists.txt @@ -0,0 +1,4 @@ +#add_unit_test(fwupdtest FwupdTest.cpp) +add_unit_test(updatefwupdtest UpdateFwupdTest.cpp) + +target_link_libraries(updatefwupdtest KF5::CoreAddons) diff --git a/libdiscover/backends/FwupdBackend/tests/FwupdTest.cpp b/libdiscover/backends/FwupdBackend/tests/FwupdTest.cpp new file mode 100644 index 00000000..e4b4b0cd --- /dev/null +++ b/libdiscover/backends/FwupdBackend/tests/FwupdTest.cpp @@ -0,0 +1,289 @@ +/*************************************************************************** + * Copyright © 2012 Aleix Pol Gonzalez * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License as * + * published by the Free Software Foundation; either version 2 of * + * the License or (at your option) version 3 or any later version * + * 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 * + * defined in Section 14 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. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + ***************************************************************************/ + +#include "FwupdTest.h" +#include "DiscoverBackendsFactory.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +QTEST_MAIN(FwupdTest) + +AbstractResourcesBackend* backendByName(ResourcesModel* m, const QString& name) +{ + QVector backends = m->backends(); + foreach(AbstractResourcesBackend* backend, backends) { + if(QString::fromLatin1(backend->metaObject()->className()) == name) { + return backend; + } + } + return nullptr; +} + +FwupdTest::FwupdTest(QObject* parent): QObject(parent) +{ + DiscoverBackendsFactory::setRequestedBackends({ QStringLiteral("fwupd-backend") }); + + m_model = new ResourcesModel(QStringLiteral("fwupd-backend"), this); + m_appBackend = backendByName(m_model, QStringLiteral("FwupdBackend")); + + // CategoryModel::global()->populateCategories(); +} + +void FwupdTest::initTestCase() +{ + QVERIFY(m_appBackend); + while(m_appBackend->isFetching()) { + QSignalSpy spy(m_appBackend, &AbstractResourcesBackend::fetchingChanged); + QVERIFY(spy.wait()); + } +} + +QVector fetchResources(ResultsStream* stream) +{ + QVector ret; + QObject::connect(stream, &ResultsStream::resourcesFound, stream, [&ret](const QVector& res) { ret += res; }); + QSignalSpy spy(stream, &ResultsStream::destroyed); + Q_ASSERT(spy.wait()); + return ret; +} + +void FwupdTest::testReadData() +{ + const auto resources = fetchResources(m_appBackend->search({})); + + QCOMPARE(m_appBackend->property("startElements").toInt()*2, resources.size()); + QBENCHMARK { + for(AbstractResource* res: resources) { + QVERIFY(!res->name().isEmpty()); + } + } +} + +void FwupdTest::testProxy() +{ + ResourcesProxyModel pm; + QSignalSpy spy(&pm, &ResourcesProxyModel::busyChanged); +// QVERIFY(spy.wait()); + QVERIFY(!pm.isBusy()); + + pm.setFiltersFromCategory(CategoryModel::global()->rootCategories().first()); + pm.componentComplete(); + QVERIFY(pm.isBusy()); + QVERIFY(spy.wait()); + QVERIFY(!pm.isBusy()); + + QCOMPARE(m_appBackend->property("startElements").toInt()*2, pm.rowCount()); + pm.setSearch(QStringLiteral("techie")); + QVERIFY(pm.isBusy()); + QVERIFY(spy.wait()); + QVERIFY(!pm.isBusy()); + QCOMPARE(m_appBackend->property("startElements").toInt(), pm.rowCount()); + QCOMPARE(pm.subcategories().count(), 7); + pm.setSearch(QString()); + QVERIFY(pm.isBusy()); + QVERIFY(spy.wait()); + QVERIFY(!pm.isBusy()); + QCOMPARE(m_appBackend->property("startElements").toInt()*2, pm.rowCount()); +} + +void FwupdTest::testProxySorting() +{ + ResourcesProxyModel pm; + QSignalSpy spy(&pm, &ResourcesProxyModel::busyChanged); +// QVERIFY(spy.wait()); + QVERIFY(!pm.isBusy()); + + pm.setFiltersFromCategory(CategoryModel::global()->rootCategories().first()); + pm.setSortOrder(Qt::DescendingOrder); + pm.setSortRole(ResourcesProxyModel::RatingCountRole); + pm.componentComplete(); + QVERIFY(pm.isBusy()); + QVERIFY(spy.wait()); + QVERIFY(!pm.isBusy()); + + QCOMPARE(m_appBackend->property("startElements").toInt()*2, pm.rowCount()); + QVariant lastRatingCount; + for(int i=0, rc=pm.rowCount(); isearch({})); + QCOMPARE(m_appBackend->property("startElements").toInt()*2, resources.count()); + + //fetches updates, adds new things + m_appBackend->checkForUpdates(); + QSignalSpy spy(m_model, SIGNAL(allInitialized())); + QVERIFY(spy.wait(80000)); + auto resources2 = fetchResources(m_appBackend->search({})); + QCOMPARE(m_appBackend->property("startElements").toInt()*4, resources2.count()); +} + +void FwupdTest::testSort() +{ + ResourcesProxyModel pm; + + QCollator c; + QBENCHMARK_ONCE { + pm.setSortRole(ResourcesProxyModel::NameRole); + pm.sort(0); + QCOMPARE(pm.sortOrder(), Qt::AscendingOrder); + QString last; + for(int i = 0, count = pm.rowCount(); ifindResourceByPackageName(QUrl(QStringLiteral("fwupd://Fwupd.1")))); + QCOMPARE(resources.count(), 1); + AbstractResource* res = resources.first(); + QVERIFY(res); + + ApplicationAddonsModel m; + new ModelTest(&m, &m); + m.setApplication(res); + QCOMPARE(m.rowCount(), res->addonsInformation().count()); + QCOMPARE(res->addonsInformation().at(0).isInstalled(), false); + + QString firstAddonName = m.data(m.index(0,0)).toString(); + m.changeState(firstAddonName, true); + QVERIFY(m.hasChanges()); + + m.applyChanges(); + QSignalSpy sR(TransactionModel::global(), &TransactionModel::transactionRemoved); + QVERIFY(sR.wait()); + QVERIFY(!m.hasChanges()); + + QCOMPARE(m.data(m.index(0,0)).toString(), firstAddonName); + QCOMPARE(res->addonsInformation().at(0).name(), firstAddonName); + QCOMPARE(res->addonsInformation().at(0).isInstalled(), true); + + m.changeState(m.data(m.index(1,0)).toString(), true); + QVERIFY(m.hasChanges()); + for(int i=0, c=m.rowCount(); ifindResourceByPackageName(QUrl(QStringLiteral("fwupd://Fwupd.1")))); + QCOMPARE(resources.count(), 1); + AbstractResource* res = resources.first(); + QVERIFY(res); + + ReviewsModel m; + new ModelTest(&m, &m); + m.setResource(res); + m.fetchMore(); + + QVERIFY(m.rowCount()>0); + + QCOMPARE(ReviewsModel::UserChoice(m.data(m.index(0,0), ReviewsModel::UsefulChoice).toInt()), ReviewsModel::None); + m.markUseful(0, true); + QCOMPARE(ReviewsModel::UserChoice(m.data(m.index(0,0), ReviewsModel::UsefulChoice).toInt()), ReviewsModel::Yes); + m.markUseful(0, false); + QCOMPARE(ReviewsModel::UserChoice(m.data(m.index(0,0), ReviewsModel::UsefulChoice).toInt()), ReviewsModel::No); + + const auto resources2 = fetchResources(m_appBackend->findResourceByPackageName(QUrl(QStringLiteral("fwupd://Fwupd.1")))); + QCOMPARE(resources2.count(), 1); + res = resources2.first(); + m.setResource(res); + m.fetchMore(); + + QSignalSpy spy(&m, &ReviewsModel::rowsChanged); + QVERIFY(m.rowCount()>0); +} + +void FwupdTest::testUpdateModel() +{ + const auto backend = m_model->backends().first(); + + ResourcesUpdatesModel ruModel; + new ModelTest(&ruModel, &ruModel); + UpdateModel model; + new ModelTest(&model, &model); + model.setBackend(&ruModel); + + QCOMPARE(model.rowCount(), 4*backend->property("startElements").toInt()/3); + QCOMPARE(model.hasUpdates(), true); +} + +void FwupdTest::testScreenshotsModel() +{ + ScreenshotsModel m; + new ModelTest(&m, &m); + + const auto resources = fetchResources(m_appBackend->findResourceByPackageName(QUrl(QStringLiteral("fwupd://Fwupd.1")))); + QCOMPARE(resources.count(), 1); + AbstractResource* res = resources.first(); + QVERIFY(res); + m.setResource(res); + QCOMPARE(res, m.resource()); + + int c=m.rowCount(); + for(int i=0; i * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License as * + * published by the Free Software Foundation; either version 2 of * + * the License or (at your option) version 3 or any later version * + * 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 * + * defined in Section 14 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. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + ***************************************************************************/ + +#ifndef DUMMYTEST_H +#define DUMMYTEST_H + +#include + +class ResourcesModel; +class AbstractResourcesBackend; + +class FwupdTest : public QObject +{ + Q_OBJECT +public: + explicit FwupdTest(QObject* parent = nullptr); + +private Q_SLOTS: + void initTestCase(); + + void testReadData(); + void testProxy(); + void testProxySorting(); + void testFetch(); + void testSort(); + void testInstallAddons(); + void testReviewsModel(); + void testUpdateModel(); + void testScreenshotsModel(); + +private: + AbstractResourcesBackend* m_appBackend; + ResourcesModel* m_model; +}; + +#endif // DUMMYTEST_H diff --git a/libdiscover/backends/FwupdBackend/tests/UpdateFwupdTest.cpp b/libdiscover/backends/FwupdBackend/tests/UpdateFwupdTest.cpp new file mode 100644 index 00000000..4add299b --- /dev/null +++ b/libdiscover/backends/FwupdBackend/tests/UpdateFwupdTest.cpp @@ -0,0 +1,171 @@ +/*************************************************************************** + * Copyright © 2012 Aleix Pol Gonzalez * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License as * + * published by the Free Software Foundation; either version 2 of * + * the License or (at your option) version 3 or any later version * + * 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 * + * defined in Section 14 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. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + ***************************************************************************/ + +#include "FwupdTest.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +class UpdateFwupdTest + : public QObject +{ + Q_OBJECT +public: + AbstractResourcesBackend* backendByName(ResourcesModel* m, const QString& name) + { + QVector backends = m->backends(); + foreach(AbstractResourcesBackend* backend, backends) { + if(QLatin1String(backend->metaObject()->className()) == name) { + return backend; + } + } + return nullptr; + } + + UpdateFwupdTest(QObject* parent = nullptr): QObject(parent) + { + m_model = new ResourcesModel(QStringLiteral("fwupd-backend"), this); + m_appBackend = backendByName(m_model, QStringLiteral("FwupdBackend")); + } + +private Q_SLOTS: + void init() + { + QVERIFY(m_appBackend); + while(m_appBackend->isFetching()) { + QSignalSpy spy(m_appBackend, &AbstractResourcesBackend::fetchingChanged); + QVERIFY(spy.wait()); + } + } + + void testInformation() + { + ResourcesUpdatesModel* rum = new ResourcesUpdatesModel(this); + new ModelTest(rum, rum); + + UpdateModel* m = new UpdateModel(this); + new ModelTest(m, m); + m->setBackend(rum); + + rum->prepare(); + QSignalSpy spySetup(m_appBackend->backendUpdater(), &AbstractBackendUpdater::progressingChanged); + QVERIFY(!m_appBackend->backendUpdater()->isProgressing() || spySetup.wait()); + QCOMPARE(m_appBackend->updatesCount(), m_appBackend->property("startElements").toInt()*2/3); + QCOMPARE(m->hasUpdates(), true); + + QCOMPARE(m->index(0,0).data(UpdateModel::ChangelogRole).toString(), {}); + + QSignalSpy spy(m, &QAbstractItemModel::dataChanged); + m->fetchChangelog(0); + QVERIFY(spy.count() || spy.wait()); + QCOMPARE(spy.count(), 1); + delete m; + } + + void testUpdate() + { + ResourcesUpdatesModel* rum = new ResourcesUpdatesModel(this); + new ModelTest(rum, rum); + + UpdateModel* m = new UpdateModel(this); + new ModelTest(m, m); + m->setBackend(rum); + + rum->prepare(); + QSignalSpy spySetup(m_appBackend->backendUpdater(), &AbstractBackendUpdater::progressingChanged); + QVERIFY(!m_appBackend->backendUpdater()->isProgressing() || spySetup.wait()); + QCOMPARE(m_appBackend->updatesCount(), m_appBackend->property("startElements").toInt()*2/3); + QCOMPARE(m->hasUpdates(), true); + + for(int i=0, c=m->rowCount(); iindex(i,0); + QVERIFY(resourceIdx.isValid()); + + AbstractResource* res = qobject_cast(resourceIdx.data(UpdateModel::ResourceRole).value()); + QVERIFY(res); + + QCOMPARE(Qt::CheckState(resourceIdx.data(Qt::CheckStateRole).toInt()), Qt::Checked); + QVERIFY(m->setData(resourceIdx, int(Qt::Unchecked), Qt::CheckStateRole)); + QCOMPARE(Qt::CheckState(resourceIdx.data(Qt::CheckStateRole).toInt()), Qt::Unchecked); + QCOMPARE(resourceIdx.data(Qt::DisplayRole).toString(), res->name()); + + if (i!=0) { + QVERIFY(m->setData(resourceIdx, int(Qt::Checked), Qt::CheckStateRole)); + } + } + + QSignalSpy spy(rum, &ResourcesUpdatesModel::progressingChanged); + QVERIFY(!rum->isProgressing() || spy.wait()); + QCOMPARE(rum->isProgressing(), false); + + QCOMPARE(m_appBackend->updatesCount(), m->rowCount()); + QCOMPARE(m->hasUpdates(), true); + + rum->prepare(); + + spy.clear(); + QCOMPARE(rum->isProgressing(), false); + rum->updateAll(); + QVERIFY(spy.count() || spy.wait()); + QCOMPARE(rum->isProgressing(), true); + + QCOMPARE(TransactionModel::global()->rowCount(), 1); + connect(TransactionModel::global(), &TransactionModel::progressChanged, this, []() { + const int progress = TransactionModel::global()->progress(); + static int lastProgress = -1; + Q_ASSERT(progress >= lastProgress || (TransactionModel::global()->rowCount() == 0 && progress == 0)); + lastProgress = progress; + }); + + QTest::qWait(20); + QScopedPointer rum2(new ResourcesUpdatesModel(this)); + new ModelTest(rum2.data(), rum2.data()); + + QScopedPointer m2(new UpdateModel(this)); + new ModelTest(m2.data(), m2.data()); + m->setBackend(rum2.data()); + + QCOMPARE(rum->isProgressing(), true); + QVERIFY(spy.wait()); + QCOMPARE(rum->isProgressing(), false); + + QCOMPARE(m_appBackend->updatesCount(), 0); + QCOMPARE(m->hasUpdates(), false); + } + +private: + ResourcesModel* m_model; + AbstractResourcesBackend* m_appBackend; +}; + +QTEST_MAIN(UpdateFwupdTest) + +#include "UpdateFwupdTest.moc"