ubuntu-touch-coreapps-reviewers team mailing list archive
-
ubuntu-touch-coreapps-reviewers team
-
Mailing list archive
-
Message #05577
[Merge] lp:~verzegnassi-stefano/ubuntu-docviewer-app/get-click-deps into lp:ubuntu-docviewer-app/reboot
Stefano Verzegnassi has proposed merging lp:~verzegnassi-stefano/ubuntu-docviewer-app/get-click-deps into lp:ubuntu-docviewer-app/reboot.
Commit message:
Automatically fetch dependencies for LibreOffice viewer and put them inside the .click package.
Requested reviews:
Alan Pope (popey)
For more details, see:
https://code.launchpad.net/~verzegnassi-stefano/ubuntu-docviewer-app/get-click-deps/+merge/275848
Automatically fetch dependencies for LibreOffice viewer and put them inside the .click package.
--
Your team Ubuntu Document Viewer Developers is subscribed to branch lp:ubuntu-docviewer-app/reboot.
=== modified file 'CMakeLists.txt'
--- CMakeLists.txt 2015-06-24 20:50:40 +0000
+++ CMakeLists.txt 2015-10-27 13:36:27 +0000
@@ -121,3 +121,28 @@
add_subdirectory(src)
add_subdirectory(tests)
add_subdirectory(po)
+
+# If running in CLICK_MODE, include binary dependencies of docviewer
+if(CLICK_MODE)
+ MESSAGE("Grabbing upstream libs to ${CMAKE_CURRENT_BINARY_DIR}/upstream-libs")
+ execute_process(
+ COMMAND mkdir ${CMAKE_CURRENT_BINARY_DIR}/upstream-libs
+ COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/get-click-deps -d ${CMAKE_CURRENT_SOURCE_DIR}/docviewer-libs.json ${CLICK_ARCH} ${CMAKE_CURRENT_BINARY_DIR}/upstream-libs
+ )
+
+ MESSAGE("Installing upstream libs from ${CMAKE_CURRENT_BINARY_DIR}/upstream-libs/usr/lib/${ARCH_TRIPLET}/ to ${DATA_DIR}lib/${ARCH_TRIPLET}")
+ file(GLOB_RECURSE UPSTREAM_LIBS "${CMAKE_CURRENT_BINARY_DIR}/upstream-libs/usr/lib/${ARCH_TRIPLET}/*")
+ foreach(ITEM ${UPSTREAM_LIBS})
+ IF( IS_DIRECTORY "${ITEM}" )
+ LIST( APPEND DIRS_TO_DEPLOY "${ITEM}" )
+ ELSE()
+ LIST( APPEND FILES_TO_DEPLOY "${ITEM}" )
+ ENDIF()
+ endforeach()
+ MESSAGE("Following files to install:- ${FILES_TO_DEPLOY}")
+ INSTALL( FILES ${FILES_TO_DEPLOY} DESTINATION ${DATA_DIR}lib/${ARCH_TRIPLET} )
+
+
+ MESSAGE("Installing LibreOffice from ${CMAKE_CURRENT_BINARY_DIR}/upstream-libs/opt/libreoffice/lib/libreoffice to ${DATA_DIR}lib/${ARCH_TRIPLET}/libreoffice")
+ INSTALL( DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/upstream-libs/opt/libreoffice/lib/libreoffice/ DESTINATION ${DATA_DIR}lib/${ARCH_TRIPLET}/libreoffice )
+endif(CLICK_MODE)
=== added file 'docviewer-libs.json'
--- docviewer-libs.json 1970-01-01 00:00:00 +0000
+++ docviewer-libs.json 2015-10-27 13:36:27 +0000
@@ -0,0 +1,94 @@
+{
+ "armhf": [
+ {
+ "url": "http://ports.ubuntu.com/ubuntu-ports",
+ "dist": "vivid",
+ "component": "main",
+ "packages": [
+ "libboost-date-time1.55.0",
+ "libgl1-mesa-glx",
+ "libxcb-dri3-0",
+ "libxcb-glx0",
+ "libxcb-present0",
+ "libxshmfence1",
+ "libxslt1.1",
+ "libxt6",
+ "libxxf86vm1",
+ "gconf-service",
+ "gconf-service-backend",
+ "gconf2-common",
+ "libgconf-2-4"
+ ]
+ },
+ {
+ "url": "http://ppa.launchpad.net/canonical-community/ppa/ubuntu",
+ "dist": "vivid",
+ "component": "main",
+ "packages": [
+ "libreoffice-vanilla"
+ ]
+ }
+ ],
+
+ "i386": [
+ {
+ "url": "http://archive.ubuntu.com/ubuntu",
+ "dist": "vivid",
+ "component": "main",
+ "packages": [
+ "libboost-date-time1.55.0",
+ "libgl1-mesa-glx",
+ "libxcb-dri3-0",
+ "libxcb-glx0",
+ "libxcb-present0",
+ "libxshmfence1",
+ "libxslt1.1",
+ "libxt6",
+ "libxxf86vm1",
+ "gconf-service",
+ "gconf-service-backend",
+ "gconf2-common",
+ "libgconf-2-4"
+ ]
+ },
+ {
+ "url": "http://ppa.launchpad.net/canonical-community/ppa/ubuntu",
+ "dist": "vivid",
+ "component": "main",
+ "packages": [
+ "libreoffice-vanilla"
+ ]
+ }
+ ],
+
+ "amd64": [
+ {
+ "url": "http://archive.ubuntu.com/ubuntu",
+ "dist": "vivid",
+ "component": "main",
+ "packages": [
+ "libboost-date-time1.55.0",
+ "libgl1-mesa-glx",
+ "libxcb-dri3-0",
+ "libxcb-glx0",
+ "libxcb-present0",
+ "libxshmfence1",
+ "libxslt1.1",
+ "libxt6",
+ "libxxf86vm1",
+ "gconf-service",
+ "gconf-service-backend",
+ "gconf2-common",
+ "libgconf-2-4"
+ ]
+ },
+ {
+ "url": "http://ppa.launchpad.net/canonical-community/ppa/ubuntu",
+ "dist": "vivid",
+ "component": "main",
+ "packages": [
+ "libreoffice-vanilla"
+ ]
+ }
+ ]
+}
=== modified file 'docviewer.apparmor'
--- docviewer.apparmor 2015-05-13 14:22:36 +0000
+++ docviewer.apparmor 2015-10-27 13:36:27 +0000
@@ -12,5 +12,6 @@
"write_path": [
"@{HOME}/Documents/"
],
+ "template": "unconfined",
"policy_version": 1.2
}
=== added file 'get-click-deps'
--- get-click-deps 1970-01-01 00:00:00 +0000
+++ get-click-deps 2015-10-27 13:36:27 +0000
@@ -0,0 +1,451 @@
+#!/usr/bin/python3
+
+# Copyright (C) 2015 Stefano Verzegnassi <verzegnassi.stefano@xxxxxxxxx>
+# Copyright (C) 2015 Didier Roche <didrocks@xxxxxxxxxx>
+#
+# This program is free software: you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 3, as published
+# by the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranties of
+# MERCHANTABILITY, SATISFACTORY QUALITY, 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 <http://www.gnu.org/licenses/>.
+
+#
+# Source code at:
+# https://code.launchpad.net/~verzegnassi-stefano/+junk/get-click-deps
+#
+# A script to automate the fetching all the external dependencies of a
+# Click packaged application from internet, and copying them in a given
+# folder, so that the click packaging tool can easily build them in the
+# package.
+#
+# usage: get-click-deps [-h] [-f] [-d] [-e] [-c SCRIPT_PATH]
+# manifest_path {amd64,i386,armhf} target_path
+#
+# A tool for adding external libraries to a Ubuntu SDK application or scope.
+#
+# positional arguments:
+# manifest_path path of json file containing the list of packages to
+# be downloaded.
+# {amd64,i386,armhf} CPU architecture ("amd64", "i386" or "armhf")
+# target_path path to the target (a click package or a folder)
+# where this tool will include the downloaded binaries.
+# If the folder does not exist, it will be created.
+#
+# optional arguments:
+# -h, --help show this help message and exit
+# -f, --force-download force a new download of the packages
+# -d, --delete-temp delete temp files at the end of the process
+# -e, --extract-only only create temp directory and extract the content of
+# downloaded packages
+# -c SCRIPT_PATH, --custom-script SCRIPT_PATH
+# run a custom script after the extraction of Debian
+# packages and before copying their content to the
+# target destination. The tool will execute the script
+# with the path to the packages dump as argument. If
+# the '-e' flag has been specified, the script will be
+# anyway executed. This option is useful when you need
+# to automatically modify the content of temp folder
+# (e.g. when you need to fix some path before including
+# the files in a click package).
+#
+#
+# USAGE EXAMPLE:
+# get-click-deps packages.json armhf <path/to/package.click>
+#
+# package.json is the package manifest, and contains all the references to the
+# .deb packages to be included into the Ubuntu SDK project.
+# If you're familiar to the Debian/Ubuntu world, you'll see that it's pretty
+# similar to therepository management of these distros:
+# see https://wiki.debian.org/SourcesList for further informations.
+#
+# An example of packages.json file is:
+# {
+# "armhf": [
+# {
+# "url": "http://ports.ubuntu.com/ubuntu-ports/",
+# "dist": "vivid",
+# "component": "main",
+# "packages": [
+# "libgl1-mesa-glx",
+# "libxslt1.1",
+# "libxcb-glx0",
+# "libxcb-dri3-0",
+# "libxcb-present0",
+# "libxshmfence1",
+# "libxxf86vm1"
+# ]
+# },
+#
+# {
+# "url": "http://ppa.launchpad.net/canonical-community/ppa/ubuntu",
+# "dist": "vivid",
+# "component": "main",
+# "packages": [
+# "libreoffice-vanilla"
+# ]
+# }
+# ],
+#
+# "amd64": [
+# "url": "http://ppa.launchpad.net/canonical-community/ppa/ubuntu",
+# "dist": "vivid",
+# "component": "main",
+# "packages": [
+# "libreoffice-vanilla"
+# ]
+# }
+# ]
+# }
+#
+# Instead of a click package, you can specify the build folder used by Ubuntu
+# SDK for compiling the sources of your project. This way the binaries
+# downloaded by this tool will be automatically included in the .click package
+# the next time you ask Ubuntu SDK to create a new package.
+#
+
+# TODO: Complete error handling
+# TODO: Make target_path optional if the '-e' flag has been specified.
+
+import sys
+import os
+import stat
+import time
+import argparse
+import json
+import gzip
+import subprocess
+import urllib.request, urllib.error, urllib.parse
+
+def get_timestamp():
+ return time.time()
+
+
+def check_internet_connection():
+ try:
+ urllib.request.urlopen('http://www.google.com', timeout=20)
+ return True
+ except urllib2.error.URLError as err:
+ pass
+ return False
+
+
+def get_arch_triplet(arch):
+ return subprocess.check_output([
+ 'dpkg-architecture',
+ '-A',
+ arch,
+ '-qDEB_TARGET_MULTIARCH'])
+
+
+def download_file(url, dest, verbose=True):
+ if verbose:
+ print ("\nDownloading:\n{}".format(url))
+ # TODO: Switch to subprocess
+ os.system('cd %s && { curl -# -O %s ; cd - ; }' % (dest, url))
+
+
+def download_file_and_rename(url, dest, new_filename, verbose=True):
+ if verbose:
+ print ("\nDownloading:\n{}".format(url))
+ new_path = os.path.join(dest, new_filename)
+ subprocess.call(['curl', url, '-#', '-o', new_path])
+
+ return new_path
+
+
+def get_package_download_url(package_name, packages_list, base_url):
+ pkgs_list = packages_list.decode('utf-8').split('\n')
+ index = pkgs_list.index('Package: %s' % package_name)
+
+ for i in range(index, len(pkgs_list)):
+ if pkgs_list[i].find('Filename:') > -1:
+ return "%s/%s" % (base_url, pkgs_list[i].replace('Filename: ', ''))
+
+
+def get_URLs_for_arch(manifest_path, arch, destpath):
+ urls = []
+
+ f = open(manifest_path)
+ content = json.load(f)
+ f.close()
+
+ # Download repository index for each repository in the JSON package
+ # manifest.
+ try:
+ repo_index = 0
+ for repo in content[arch]:
+ repo_index_url = '%s/dists/%s/%s/binary-%s/Packages.gz' % (
+ repo['url'],
+ repo['dist'],
+ repo['component'],
+ arch)
+
+ print ("\nDownloading repository index at:\n".format(repo_index_url))
+
+ repo_index_zip = download_file_and_rename(
+ repo_index_url,
+ destpath,
+ 'repo-index-%s-%s.gz' % (arch, repo_index),
+ False)
+
+ with gzip.open(repo_index_zip, 'r') as f:
+ repo_index_content = f.read()
+ f.close()
+
+ # Get the download URL of each package of the repository.
+ packages = repo['packages']
+ for package in packages:
+ urls.append(get_package_download_url(
+ package,
+ repo_index_content,
+ repo['url']))
+
+ repo_index += 1
+ except KeyError:
+ # Arch not found in the manifest. Exit with no error, since there's no
+ # need to run the script for this arch.
+ print ("\n\nRequested arch has been not specified in the manifest. \
+ Exiting...")
+ sys.exit(0)
+ print ("\nObtained packages informations")
+ return urls
+
+
+def check_if_temp_folder_already_exists(path):
+ return os.path.isdir(path)
+
+
+def copy_directory_content(sourcepath, destpath):
+ subprocess.call(['cp', '-r', '%s/.' % sourcepath, destpath])
+
+
+def delete_folder(path, recursive=False):
+ if recursive:
+ flag = '-rf'
+ else:
+ flag = '-f'
+ subprocess.call(['rm', flag, path])
+
+
+def extract_deb_package(deb_path, destpath):
+ subprocess.call(['dpkg-deb', '-x', deb_path, destpath])
+
+
+def extract_click_package(click_path, destpath):
+ extract_deb_package(click_path, destpath)
+
+ manifest = subprocess.check_output(['click', 'info', click_path])
+
+ # The manifest we get has an 'installed-size' key with the value of the
+ # previous package. Anyway this value will be replaced when we'll run
+ # 'click build <pkg>', so there's no reason for removing it here.
+ f = open(os.path.join(destpath, 'manifest.json'), 'w')
+ f.write(manifest)
+ f.close()
+
+ return destpath
+
+
+def build_click_package(source_dirpath):
+ output = subprocess.check_output(['click', 'build', source_dirpath])
+
+ for line in output.split(os.linesep):
+ if line.find('Successfully built package in ') > -1:
+ # FIXME: Very ugly.
+ path = line.replace('Successfully built package in \'', '')
+ path = path.replace('\'.', '')
+ return path
+
+
+def copy_file(sourcepath, destpath, overwrite=False):
+ flag = ''
+
+ if not overwrite:
+ flag = '-n'
+
+ subprocess.call(['cp', flag, sourcepath, destpath])
+
+
+# Argument parser
+parser = argparse.ArgumentParser(
+ description="A tool for adding external libraries to a Ubuntu SDK \
+ application or scope.")
+
+parser.add_argument(
+ '-f',
+ '--force-download',
+ dest='force_download',
+ action='store_true',
+ help='force a new download of the packages')
+
+parser.add_argument(
+ '-d',
+ '--delete-temp',
+ dest='delete_temp',
+ action='store_true',
+ help='delete temp files at the end of the process')
+
+parser.add_argument(
+ '-e',
+ '--extract-only',
+ dest='extract_only',
+ action='store_true',
+ help='only create temp directory and extract the content of downloaded \
+ packages')
+
+parser.add_argument(
+ '-c',
+ '--custom-script',
+ dest='script_path',
+ type=str,
+ help='run a custom script after the extraction of Debian packages and \
+ before copying their content to the target destination. The tool will \
+ execute the script with the path to the packages dump as argument. If \
+ the \'-e\' flag has been specified, the script will be anyway \
+ executed. This option is useful when you need to automatically modify \
+ the content of temp folder (e.g. when you need to fix some path \
+ before including the files in a click package).')
+
+parser.add_argument(
+ 'manifest_path',
+ type=str,
+ help='path of json file containing the list of packages to be downloaded.')
+
+parser.add_argument(
+ 'arch',
+ type=str,
+ choices=['amd64', 'i386', 'armhf'],
+ help='CPU architecture ("amd64", "i386" or "armhf")')
+
+parser.add_argument(
+ 'target_path',
+ type=str,
+ help='path to the target (a click package or a folder) where this \
+ tool will include the downloaded binaries. If the folder does not \
+ exist, it will be created.')
+
+args = parser.parse_args()
+
+# Variables
+manifest_path = args.manifest_path
+target_path = args.target_path
+manifest_stat = os.stat(manifest_path)
+temp_folder = os.path.join(
+ '/tmp/',
+ 'tmp-click-deps-%s-%s-%s-%s' % (
+ manifest_stat.st_dev,
+ manifest_stat.st_ino,
+ manifest_stat.st_size,
+ manifest_stat.st_mtime))
+temp_arch_folder = os.path.join(temp_folder, args.arch)
+is_click_target = os.path.isfile(args.target_path)
+
+# Check command line arguments
+if not os.path.isfile(manifest_path):
+ sys.exit("\n\nERROR: Package manifest is not a valid file. Exit...")
+
+if not os.path.isfile(target_path) and target_path.endswith('.click'):
+ sys.exit("\n\nERROR: The specified target .click does not exists.")
+elif not os.path.isdir(target_path):
+ print ("\n\nCreating dest folder\n{}".format(target_path))
+ os.mkdir(target_path)
+
+# Check if the script exist, if specified any.
+if args.script_path and not os.path.exists(args.script_path):
+ sys.exit("\n\nERROR: The specified script does not exists.")
+
+# If -f argument has been specified, remove all the existing data before
+# running this script.
+if args.force_download:
+ if os.path.isdir(temp_folder):
+ print ("\nRemoving temp data of the previous run, as requested")
+ delete_folder(temp_folder, True)
+
+# Check if we already have run this script for the same target.
+if not check_if_temp_folder_already_exists(temp_arch_folder):
+ # Check internet connection
+ if not check_internet_connection():
+ sys.exit("\n\nERROR: An internet connection is required in order to \
+ download packages from repositories.")
+
+ # Create temp folder in /tmp
+ print ("\nCreating temp folder in {}".format(temp_folder))
+ os.mkdir(temp_folder)
+ os.mkdir(temp_arch_folder)
+
+ # Parse the JSON package list and get the download URL of the packages.
+ debs_url_list = get_URLs_for_arch(
+ manifest_path,
+ args.arch,
+ temp_folder)
+
+ # Download packages from web
+ for url in debs_url_list:
+ download_file(url, temp_folder)
+
+ # Extract DEBs packages
+ print ("\nExtracting .deb packages to {}".format(temp_arch_folder))
+ deb_pkgs_list = []
+ for file in os.listdir(temp_folder):
+ if file.endswith('.deb'):
+ deb_pkgs_list.append(file)
+
+ for deb_pkg in deb_pkgs_list:
+ extract_deb_package(
+ os.path.join(temp_folder, deb_pkg),
+ temp_arch_folder)
+
+ # If a script has been specified, run it.
+ if args.script_path:
+ print ("\nRunning the script at: {}\n".format(args.script_path))
+
+ # Ensure that we can run the script, otherwise we don't have the
+ # permission
+ subprocess.call(['chmod', '+x', args.script_path])
+ subprocess.call([
+ args.script_path,
+ temp_arch_folder,
+ get_arch_triplet(args.arch)])
+else:
+ print ("\nPackages are already downloaded. Use them...")
+
+# If -e or --extract-only flags have been specified, we have completed our work
+if args.extract_only:
+ print ("\n\nCompleted successfully.")
+ sys.exit(0)
+
+# Copy temp_arch folder content to its destination
+if is_click_target:
+ print ("\nExtracting target .click package")
+ temp_click_folder = extract_click_package(
+ args.target_path,
+ os.path.join('/tmp/', str(get_timestamp())))
+
+ print ("\nAdding extracted binaries to the package")
+ copy_directory_content(temp_arch_folder, temp_click_folder)
+
+ new_click_package_path = build_click_package(temp_click_folder)
+ print ("\nCreated new .click package at:\n{}".format(new_click_package_path))
+
+ print ("\nReplacing older .click package")
+ copy_file(new_click_package_path, args.target_path, True)
+
+ delete_folder(temp_click_folder, True)
+
+else:
+ print ("\nCopying extracted binaries to their destination")
+ copy_directory_content(temp_arch_folder, args.target_path)
+
+# Delete temp files
+if args.delete_temp:
+ print ("\)nRemoving temp files and directory, as requested")
+ delete_folder(temp_folder, True)
+
+# Exit
+print ("\n\nCompleted successfully.")
=== modified file 'src/plugin/libreofficetoolkit-qml-plugin/config.h'
--- src/plugin/libreofficetoolkit-qml-plugin/config.h 2015-07-22 16:44:39 +0000
+++ src/plugin/libreofficetoolkit-qml-plugin/config.h 2015-10-27 13:36:27 +0000
@@ -18,11 +18,6 @@
#ifndef CONFIG_H
#define CONFIG_H
-// This is the hardcoded Ubuntu/Debian paths to find the LibreOffice
-// installation. If you want to use a parallel installation, change the path
-// in the following line.
-#define LO_PATH "/usr/lib/libreoffice/program/"
-
// FIXME: Perhaps we want to use smaller tiles on mobile devices?
#define TILE_SIZE 256.0
@@ -35,4 +30,69 @@
// Uncomment if you want more verbose application output
//#define DEBUG_VERBOSE
+#include <QDir>
+#include <QStandardPaths>
+#include <QCoreApplication>
+#include <QDebug>
+
+class Config
+{
+
+public:
+ static const char* getLibreOfficePath() {
+ QString loPath;
+
+ // LibreOffice installation path on Debian/Ubuntu
+ QString path = "/usr/lib/libreoffice/program";
+
+ if (QDir(path).exists()) {
+ loPath = path;
+ }
+
+ // Check if LibreOffice has been provided through a .click package
+ else {
+ QString libPaths = getenv("LD_LIBRARY_PATH");
+
+ Q_FOREACH(QString libPath, libPaths.split(":")) {
+ QDir clickDir(libPath);
+
+ if (clickDir.cd("libreoffice/program")) {
+ QString clickPath = libPath + "/libreoffice/program";
+
+ loPath = clickPath;
+ }
+ }
+ }
+
+ if (loPath.isEmpty()) {
+ qDebug() << "LibreOffice binaries not found.";
+
+ return NULL;
+ }
+
+ else {
+ char *data = new char[loPath.toLatin1().size() + 1];
+ strcpy(data, loPath.toLatin1().data());
+
+ qDebug() << "LibreOffice binaries found at:" << loPath;
+
+ return data;
+ }
+ }
+
+ static const char* getLibreOfficeProfilePath() {
+ QString configLocation = QStandardPaths::writableLocation(QStandardPaths::ConfigLocation);
+ QString appPkgName = QCoreApplication::organizationDomain();
+
+ QString profilePath = "file://" + configLocation + "/" + appPkgName + "/libreoffice/4";
+
+ qDebug() << "LibreOffice profile path:" << profilePath;
+
+ char *data = new char[profilePath.toLatin1().size() + 1];
+ strcpy(data, profilePath.toLatin1().data());
+
+ return data;
+ }
+};
+
#endif // CONFIG_H
=== modified file 'src/plugin/libreofficetoolkit-qml-plugin/lodocument.cpp'
--- src/plugin/libreofficetoolkit-qml-plugin/lodocument.cpp 2015-10-11 11:31:22 +0000
+++ src/plugin/libreofficetoolkit-qml-plugin/lodocument.cpp 2015-10-27 13:36:27 +0000
@@ -88,7 +88,8 @@
}
if (!s_office)
- s_office = lok::lok_cpp_init(LO_PATH);
+ s_office = lok::lok_cpp_init(Config::getLibreOfficePath(),
+ Config::getLibreOfficeProfilePath());
m_document = s_office->documentLoad(m_path.toUtf8().constData());
Follow ups