diff --git a/.travis.yml b/.travis.yml index 44a16c14..ea37b42d 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,11 +3,18 @@ compiler: gcc sudo: require dist: trusty +install: + - sudo apt-get update -qq + - sudo apt-get install -qq docbook* fop xsltproc less + script: - appimage/build-appimage after_success: - cd appimage/build - find ./appdir -executable -type f -exec ldd {} \; | grep " => /usr" | cut -d " " -f 2-3 | sort | uniq + - ls -l # for more debugging in Travis' log - curl --upload-file ./qpdf*.AppImage https://transfer.sh/qpdf-git.$(git rev-parse --short HEAD)-x86_64.AppImage - - sha512sum ./qpdf*.AppImage + - sha512sum ./qpdf*.AppImage* + - wget -c https://github.com/probonopd/uploadtool/raw/master/upload.sh + - bash upload.sh qpdf-*x86_64.AppImage* # This should upload the .zsync file as well diff --git a/README-appimage.md b/README-appimage.md new file mode 100644 index 00000000..790d5d02 --- /dev/null +++ b/README-appimage.md @@ -0,0 +1,21 @@ +# Using the QPDF AppImage bundle (for Linux x86_64 systems only) + +First advice: + +- After downloading, you have to set the executable bit for any AppImage (for security reasons + this is disabled by default): `chmod +x .AppImage` + +- Run the QPDF AppImage with the '--usage' parameter to start learning some useful details about + built-in features of this specific AppImage. + + +More tips: + +- You can rename the AppImage to any name allowed for file names on Linux. The '.AppImage' suffix + is not required for it to function. It will also work as expected if you invoke it from a + symlink. Using 'qpdf' as its filename or symlink name is OK. However, you may want to continue + using the QPDF package provided by your system's package manager side by side with the AppImage + bundle: in this case it is recommended to use 'qpdf.ai' as a short name for (or as the symlink + name to) the qpdf-.AppImage. + +- [...more tips to come... work in progress...] diff --git a/README.md b/README.md index e25754e5..74fa7c1d 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,13 @@ # QPDF [![Build Status](https://travis-ci.org/qpdf/qpdf.svg?branch=master)](https://travis-ci.org/qpdf/qpdf) +---- + + +(This repository is a temporary clone of the original upstream one in order to test (and possibly improve) the AppImage created via the Travis CI integration which was recently added by Jay.) + + +---- + [![QPDF](logo/qpdf.svg)](http://qpdf.sourceforge.net) This is the QPDF package. Information about it can be found at http://qpdf.sourceforge.net. The source code repository is hosted at github: https://github.com/qpdf/qpdf. diff --git a/appimage/AppRun b/appimage/AppRun index 8a2e5935..40af9071 100644 --- a/appimage/AppRun +++ b/appimage/AppRun @@ -1,19 +1,492 @@ #!/bin/bash -# The purpose of this custom AppRun script is -# to allow symlinking the AppImage and invoking -# the corresponding binary depending on which -# symlink was used to invoke the AppImage +# Copyright (c) 2017 Simon Peter (@probonopd) +# Copyright (c) 2018 Kurt Pfeifle (@pdfkungfoo) +# +# License: MIT +# +# The purpose of this custom AppRun script is to enable symlinking the AppImage and invoking the corresponding +# binary depending on which symlink name was used to invoke the AppImage. +# +# At the same time it also allows to invoke the embedded binaries as 'sub-commands'. This is in the interest of +# saving users from creating extra symlinks (without preventing others from STILL using such, should they want +# or need these). +# +# It also provides some additional help parameters in order to allow faster familiarization with functionality +# embedded in this AppImage. For example it support the listing and viewing of embedded manpages, HTML files, +# PDF files, licenses and READMEs. +# +# Note, the AppImage can be renamed to anything what's 'legal' for an executable name under Linux or used via +# a symlink under any name and it should behave like 'qpdf' is expected to behave. If the symlink name is +# 'fix-qdf' or 'zlib-flate' it should behave like these... HERE="$(dirname "$(readlink -f "${0}")")" -if [ ! -z $APPIMAGE ] ; then - BINARY_NAME=$(basename "$ARGV0") - if [ -e "$HERE/usr/bin/$BINARY_NAME" ] ; then - exec "$HERE/usr/bin/$BINARY_NAME" "$@" - else - exec "$HERE/usr/bin/qpdf" "$@" - fi -else - exec "$HERE/usr/bin/qpdf" "$@" +# Set APPDIR and ARGV0 when running directly from the AppDir. +# Running from the AppDir can be beneficial when debugging the AppImage (or give performance improvements): +if [ -z $APPDIR ]; then + APPDIR="$HERE" + ARGV0="$0" fi + +# This is a semi-secret environment variable which can be set for debugging the AppImage. +# For now it is only meant for temporary use and may be removed again in the near future once things have +# settled: +if [ "x$SET_BASH_X_FOR_APPRUN" == "xYeSS" ] ; then + set -x +else + set +x +fi + +# Another semi-secret environment var: +if [ "x$SET_SHOW_ENV_FOR_APPRUN" == "xYeSS" ] ; then + env | less +fi + +if [ "x$SET_SHOW_ENV_FOR_APPIMAGE" == "xYeSS" ] ; then + env | grep --color -E '(APPIMAGE|APPDIR|APP|ARGV0|HERE)' +fi + + +function usage() { +echo " + -------------------------------------------------------------------------- + All QPDF command line functionality inside an AppImage package. + -------------------------------------------------------------------------- + + (This package uses the AppImage software packaging technology for Linux ['One App == One File'] + for easy availability of the newest QPDF releases across all major Linux distributions.) + + Usage: + ------ + + $ARGV0 --help + # Show help screen of QPDF itself + + $ARGV0 --ai-usage + # This message (it's only present in the AppImage incarnation of QPDF) + + $ARGV0 fix-qdf|zlib-flate + # Run the named sub-command + + $ARGV0 --list-exe + # List all executables embedded in AppImage + + $ARGV0 --list-man + # List available, embedded manual pages + + $ARGV0 --man qpdf|zlib-flate|fix-qdf + # Display embedded manual page(s) + + $ARGV0 --list-html + # List all HTML documents embedded in AppImage + + $ARGV0 --html + # Use browser to show HTML file embedded in AppImage + # (for list of available HTML files see \"$ARGV0 --list-html\") + + $ARGV0 --list-pdf + # List all PDF documents embedded in AppImage + + $ARGV0 --pdf + # Use system default PDF viewer to display embedded PDF document(s) + # (for list of available PDF files see \"$ARGV0 --list-pdf\") + + $ARGV0 --list-readme + # List all READMEs embedded in AppImage + + $ARGV0 --readme + # Show content of README embedded in AppImage + # (for list of available READMEs see \"$ARGV0 --list-readme\") + + $ARGV0 --list-license + # List all LICENSE files embedded in AppImage + + $ARGV0 --license + # Show content of LICENSE file embedded in AppImage (piped thru 'less -N') + + $ARGV0 --show-apprun|--self-show|--selfshow + # Show 'AppRun' invoked by 'less -N'; type '-N' to toogle line number display + + $ARGV0 --appimage-help + # Show AppImage options available for all 'type 2' AppImages + + $ARGV0 --help + # Show help screen of QPDF itself + + ------------------------------------------------------------------------------------------------ + NOTE: The execution of this AppImage is controlled by a custom AppRun script. The state of this + script is experimental and preliminary. Hence it may not work as expected, or miss some + functionality. You can hack on this script by unpacking this AppImage into a local sub directory + [currently named 'squashfs-root'] with this command: + + $ARGV0 --appimage-extract + + After you're done with your hacks, repackage the AppImage again with this command: + + appimagetool [/path/to/]squashfs-root [/path/to/]QPDF-*.AppImage + + Latest versions of tools provided by AppImageKit are always available from + * https://github.com/AppImage/AppImageKit/releases/ and + * https://github.com/AppImage/AppImageUpdate/releases/ and + * https://github.com/AppImage/zsync2/releases and + * https://github.com/probonopd/linuxdeployqt/releases/ + ------------------------------------------------------------------------------------------------ +" +} + + +function mimetype() { +case "$#" in + 1) + # 'file --mime-type some-foo-file.ext' usually returns: 'some-foo-file.ext: major/minor', on stderr... + # However, we want to get back only 'major/minor', on stdout! + file --mime-type "$1" 2>&1 | sed 's#'"$1"':##;s# ##' + ;; + 0) + echo "" 1>&2 + echo " # This is a Bash function, named \"$FUNCNAME\"." 1>&2 + echo " # You cannot run it without an argument. If you run it with a" 1>&2 + echo " # [path to a] file as a single argument, it simply returns the" 1>&2 + echo " # 'major/minor' MIME type. If you add multiple [paths to] files" 1>&2 + echo " # as arguments, it returns a list of 'major/minor' MIME types with" 1>&2 + echo " # the respective file names prepended. Example usage:" 1>&2 + echo " #" 1>&2 + echo " # $> $FUNCNAME /path/to/a.pdf" 1>&2 + echo " #" 1>&2 + echo " # $> $FUNCNAME /path/to/a.txt ./myscript.sh ../some.txt" 1>&2 + echo " #" 1>&2 + echo " # This Bash function's source code is this:" 1>&2 + echo "" 1>&2 + typeset -f "${FUNCNAME}" 1>&2 + echo "" 1>&2 + ;; + *) + file --mime-type "$@" + ;; +esac +} + + +if [ x"$1" == "xshow-apprun" -o x"$1" == "x--show-apprun" -o x"$1" == "x--apprunshow" -o x"$1" == "x--apprun-show" -o x"$1" == "xselfshow" -o x"$1" == "x--selfshow" -o x"$1" == "xself-show" -o x"$1" == "x--self-show" -o x"$1" == "x--show-self" -o x"$1" == "x--showself" -o x"$1" == "xshow-self" -o x"$1" == "xshowself" ] ; then + cd "$HERE" + less -N AppRun + exit $? +fi + + +if [ x"$1" == "xlistlicense" -o x"$1" == "x--listlicense" -o x"$1" == "xlist-license" -o x"$1" == "x--list-license" -o x"$1" == "x--licenselist" -o x"$1" == "x--license-list" ] ; then + cd "$HERE" + echo "" + echo "You may invoke \"$ARGV0\" with one of the following additional arguments." + echo "This will then display the respective license file:" + echo "" + find . -type f -name "*LICENSE*" -o -name "*license*" | sed 's#^./# --license #' + echo "" + exit $? +fi + + +if [ "x$1" == "xai-usage" -o "x$1" == "x--aiusage" -o "x$1" == "x--ai-usage" -o "x$1" == "x-u" ] ; then + usage | less + #usage + exit $? +fi + + +if [ x"$1" == "xlistman" -o x"$1" == "x--listman" -o x"$1" == "xlist-man" -o x"$1" == "x--list-man" -o x"$1" == "x--manlist" -o x"$1" == "x--man-list" ] ; then + cd "$HERE" + echo "" + echo "You may invoke \"$ARGV0\" with one of the following additional arguments." + echo "This will then open the respective manual page:" + echo "" + find usr/share/man* -type f | sed 's#^# --man #' + echo "" + exit $? +fi + + +if [ x"$1" == "xlistexe" -o x"$1" == "x--listexe" -o x"$1" == "xlist-exe" -o x"$1" == "x--list-exe" -o x"$1" == "x--exelist" -o x"$1" == "x--exe-list" ] ; then + cd "$HERE" + echo "" + echo "You may invoke \"$ARGV0\" with one of the following additional arguments." + echo "This would run the respective exe as a 'sub-command':" + echo "" + find . \( \( -type f -o -type l -o -type s -o -type p \) -a -executable \) | grep '/bin/' | grep -v qpdf | sed 's#./usr/bin/# #' | sort -V | grep -v ".sh$" + echo "" + find . \( \( -type f -o -type l -o -type s -o -type p \) -a -executable \) | grep '/bin/' | grep -v qpdf | sed 's#./usr/bin/# #' | sort -V | grep ".sh$" + echo "" + exit $? +fi + + +if [ x"$1" == "xlistreadme" -o x"$1" == "x--listreadme" -o x"$1" == "xlist-readme" -o x"$1" == "x--list-readme" -o x"$1" == "x--readmelist" -o x"$1" == "x--readme-list" ] ; then + cd "$HERE" + echo "" + echo "You may invoke \"$ARGV0\" with one of the following additional arguments." + echo "This will then display the respective README file:" + echo "" + find . -type f -iname "*README*" -o -iname "*.txt" -o -iname "*.md" -o -iname "*copyright*" -o -iname "*changelog*" -o -iname "*todo*" | sed 's#^./# --readme #' + echo "" + exit $? +fi + + +if [ x"$1" == "xlisthtml" -o x"$1" == "x--listhtml" -o x"$1" == "xlist-html" -o x"$1" == "x--list-html" -o x"$1" == "x--htmllist" -o x"$1" == "x--html-list" ] ; then + cd "$HERE" + echo "" + echo "You may invoke \"$ARGV0\" with one of the following additional arguments." + echo "This will then open the respective HTML file in your preferred browser:" + echo "" + find . -type f -name "*.html" | sed 's#^./# --html #' + echo "" + exit $? +fi + + +if [ x"$1" == "xlistpdf" -o x"$1" == "x--listpdf" -o x"$1" == "xlist-pdf" -o x"$1" == "x--list-pdf" -o x"$1" == "x--pdflist" -o x"$1" == "x--pdf-list" ] ; then + cd "$HERE" + echo "" + echo "You may invoke \"$ARGV0\" with one of the following additional arguments." + echo "This will then open the respective PDF file in your preferred viewer program:" + echo "" + find . -type f -name "*.pdf" | sed 's#^./# --pdf #' + echo "" + exit $? +fi + + +if [ x"$1" == "xreadme" -o x"$1" == "x--readme" ] ; then + cd "$HERE" + shift + echo "" + if [ x"$1" == "x" ] ; then + echo " You must give a path to the README you want to open." + echo " For available READMEs run \"$ARGV0 --listreadme\"." + else + readmefile=$( find . -type f -iname "*README*" -o -iname "*.txt" -o -iname "*.md" -o -iname "*copyright*" -o -iname "*changelog*" | grep "${1}" | sort -rV | head -n 1 ) + MIME=$(mimetype $readmefile) + case $MIME in + text/html|application/pdf|application/epub*) + xdg-open "$readmefile" + sleep 3 # sleep to allow slow xdg-open do its job + ;; + inode/x-empty) + echo "" + echo " Sorry, this file, \"$readmefile\", is empty and has no content." + echo "" + ;; + text/*) + less -N "$readmefile" + ;; + esac + sleep 0 + fi + echo "" + exit $? +fi + + +if [ x"$1" == "xlicense" -o x"$1" == "x--license" ] ; then + cd "$HERE" + shift + echo "" + if [ x"$1" == "x" ] ; then + echo " You must give a path to the LICENSE you want to open." + echo " For available LICENSE run \"$ARGV0 --list-license\"." + else + licensefile=$( find . -type f -iname "*LICENSE*" | grep "${1}" | sort -rV | head -n 1 ) + #if PDF or EPUB or HTML ; then xdg-open $licensefile ; else + MIME=$(mimetype $licensefile) + case $MIME in + text/html|application/pdf|application/epub*) + xdg-open "$licensefile" + sleep 3 # sleep to allow slow xdg-open do its job + ;; + inode/x-empty) + echo "" + echo " Sorry, this file, \"$licensefile\", is empty and has no content." + echo "" + ;; + text/*) + less -N "$licensefile" + ;; + esac + sleep 0 + fi + echo "" + exit $? +fi + + +if [ x"$1" == "xman" -o x"$1" == "x--man" ] ; then + export MANPATH="$HERE/usr/share/man:$MANPATH" + shift + exec man "$@" || man $(basename $1) +fi + + +if [ x"$1" == "xpdf" -o x"$1" == "x--pdf" ] ; then + cd "$HERE" + shift + echo "" + if [ x"$1" == "x" ] ; then + echo "" + echo " You must give a path to the PDF file you want to open." + echo " For available PDFs run \"$ARGV0 --list-pdf\"" + echo "" + else + pdffile=$( find . -type f -name "*.pdf" | grep "${1/.pdf/}.pdf" | sort -rV | head -n 1 ) + xdg-open "$pdffile" + sleep 5 + fi + echo "" + exit $? +fi + + +if [ x"$1" == "xhtml" -o x"$1" == "x--html" ] ; then + cd "$HERE" + shift + if [ x"$1" == "x" ] ; then + echo "" + echo " You must give a path to the HTML file you want to open." + echo " For available HTMLs run \"$ARGV0 --list-html\"" + echo "" + else + htmlfile=$( find . -type f -name "*.html" | grep "${1}" | sort -rV | head -n 1 ) + xdg-open "$htmlfile" + sleep 5 + fi + exit $? +fi + + +if [ x"$1" == "x--appimage-help" ] ; then + cd "$HERE" + shift + if [ x"$APPIMAGE" == "x" ] ; then + echo "" + echo " The parameter '--appimage-help' does not work if you run this application from an AppDir (as you do)." + echo " To create an AppImage from your AppDir run this command:" + echo "" + echo " appimagetool -n $APPDIR qpdf.AppImage" + echo "" + echo " You can download the latest version of 'appimagetool' (as an AppImage) from here:" + echo "" + echo " https://github.com/AppImage/AppImageKit/releases" + echo "" + fi + exit $? +fi + + +if [ "x$SET_SHOW_ENV_FOR_APPRUN" == "xYeSS" ] ; then + echo APPIMAGE=$APPIMAGE 1>&2 # Don't leak strings into output of qpdf|fix-qdf|zlib-flate which goes to stdout! + echo ARGV0=$ARGV0 1>&2 # Don't leak strings into output of qpdf|fix-qdf|zlib-flate which goes to stdout! + echo dollar0=$0 1>&2 # Don't leak strings into output of qpdf|fix-qdf|zlib-flate which goes to stdout! + echo dollar1=$1 1>&2 # Don't leak strings into output of qpdf|fix-qdf|zlib-flate which goes to stdout! + echo dollar_at="$@" 1>&2 # Don't leak strings into output of qpdf|fix-qdf|zlib-flate which goes to stdout! +fi + + +### Main stuff happens from here: +if [ ! -z $APPIMAGE ] ; then + # We run as an AppImage + BINARY_NAME=$(basename "$ARGV0") + APPIMAGE=$APPIMAGE + CALLED_SUBCMD=$( basename $1 2>/dev/null ) + if [ "x$SET_SHOW_ENV_FOR_APPRUN" == "xYeSS" ] ; then + # We have the (hidden) env var for debugging stuff set + echo BINARY_NAME=$BINARY_NAME 1>&2 # Don't leak strings into output of qpdf|fix-pdf|zlib-flate going to stdout! + echo APPIMAGE=$APPIMAGE 1>&2 # Don't leak strings into output of qpdf|fix-pdf|zlib-flate going to stdout! + echo CALLED_SUBCMD=$CALLED_SUBCMD 1>&2 # Don't leak strings into output of qpdf|fix-pdf|zlib-flate going to stdout! + fi + + if [ -x "$HERE/usr/bin/$BINARY_NAME" ] && [ x"$BINARY_NAME" != "x" ] ; then + # We are invoked from a symlink (like 'fix-qdf' or 'zlib-flate') + if [ "x$SET_SHOW_ENV_FOR_APPRUN" == "xYeSS" ] ; then + # We have the (hidden) env var for debugging stuff set + echo BINARY_NAME=$BINARY_NAME 1>&2 # Don't leak strings into qpdf|fix-pdf|zlib-flate output going to stdout! + echo APPIMAGE=$APPIMAGE 1>&2 # Don't leak strings into qpdf|fix-pdf|zlib-flate output going to stdout! + echo CALLED_SUBCMD=$CALLED_SUBCMD 1>&2 # Don't leak strings into qpdf|fix-pdf|zlib-flate output going to stdout! + fi + shift + exec "$HERE/usr/bin/$BINARY_NAME" "$@" + + else + if [ -x "$HERE/usr/bin/$CALLED_SUBCMD" ] && [ x"$CALLED_SUBCMD" != "x" ] ; then + # We are invoked by a (currently not yet known future) binary name which may be located in ./usr/bin/ ... + BINARY_NAME=$1 + if [ "x$SET_SHOW_ENV_FOR_APPRUN" == "xYeSS" ] ; then + # We have the (hidden) env var for debugging stuff set + echo BINARY_NAME=$BINARY_NAME 1>&2 # Don't leak strings into qpdf|fix-pdf|zlib-flate output going to stdout! + echo APPIMAGE=$APPIMAGE 1>&2 # Don't leak strings into qpdf|fix-pdf|zlib-flate output going to stdout! + echo CALLED_SUBCMD=$CALLED_SUBCMD 1>&2 # Don't leak strings into qpdf|fix-pdf|zlib-flate output going to stdout! + fi + shift + exec "$HERE/usr/bin/$BINARY_NAME" "$@" + elif [ -x "$HERE/$CALLED_SUBCMD" ] && [ x"$CALLED_SUBCMD" != "x" ] ; then + # We are invoked by a (currently not yet known future) binary name which may be located in our root AppDir ... + BINARY_NAME=$CALLED_SUBCMD + if [ "x$SET_SHOW_ENV_FOR_APPRUN" == "xYeSS" ] ; then + # We have the (hidden) env var for debugging stuff set + echo BINARY_NAME=$BINARY_NAME 1>&2 # Don't leak strings into qpdf|fix-pdf|zlib-flate output going to stdout! + echo APPIMAGE=$APPIMAGE 1>&2 # Don't leak strings into qpdf|fix-pdf|zlib-flate output going to stdout! + echo CALLED_SUBCMD=$CALLED_SUBCMD 1>&2 # Don't leak strings into qpdf|fix-pdf|zlib-flate output going to stdout! + fi + shift + exec "$HERE/$BINARY_NAME" "$@" + else + # this clause may not be necessary... + exec "$HERE/usr/bin/qpdf" "$@" + fi + fi + +else + # Most likely we run from an AppDir, not as an AppImage: + BINARY_NAME=$(basename "$ARGV0") + APPIMAGE=$APPIMAGE + CALLED_SUBCMD=$( basename $1 2>/dev/null ) + if [ "x$SET_SHOW_ENV_FOR_APPRUN" == "xYeSS" ] ; then + # We have the (hidden) env var for debugging stuff set + echo BINARY_NAME=$BINARY_NAME 1>&2 # Don't leak strings into qpdf|fix-pdf|zlib-flate output going to stdout! + echo APPIMAGE=$APPIMAGE 1>&2 # Don't leak strings into qpdf|fix-pdf|zlib-flate output going to stdout! + echo CALLED_SUBCMD=$CALLED_SUBCMD 1>&2 # Don't leak strings into qpdf|fix-pdf|zlib-flate output going to stdout! + fi + + if [ -x "$HERE/usr/bin/$CALLED_SUBCMD" ] && [ "x$CALLED_SUBCMD" != "x" ]; then + #echo befor shift dollar_at=$@ + if [ "x$SET_SHOW_ENV_FOR_APPRUN" == "xYeSS" ] ; then + # We have the (hidden) env var for debugging stuff set + echo BINARY_NAME=$BINARY_NAME 1>&2 # Don't leak strings into qpdf|fix-pdf|zlib-flate output going to stdout! + echo APPIMAGE=$APPIMAGE 1>&2 # Don't leak strings into qpdf|fix-pdf|zlib-flate output going to stdout! + echo CALLED_SUBCMD=$CALLED_SUBCMD 1>&2 # Don't leak strings into qpdf|fix-pdf|zlib-flate output going to stdout! + fi + shift + #echo after shift dollar_at=$@ + #echo CALLED_SUBCMD=$CALLED_SUBCMD + exec "$HERE/usr/bin/$CALLED_SUBCMD" "$@" + + elif [ -x "$HERE/usr/bin/$BINARY_NAME" ] && [ "x$BINARY_NAME" != "x" ] ; then + if [ "x$SET_SHOW_ENV_FOR_APPRUN" == "xYeSS" ] ; then + # We have the (hidden) env var for debugging stuff set + echo BINARY_NAME=$BINARY_NAME 1>&2 # Don't leak strings into qpdf|fix-pdf|zlib-flate output going to stdout! + echo APPIMAGE=$APPIMAGE 1>&2 # Don't leak strings into qpdf|fix-pdf|zlib-flate output going to stdout! + echo CALLED_SUBCMD=$CALLED_SUBCMD 1>&2 # Don't leak strings into qpdf|fix-pdf|zlib-flate output going to stdout! + fi + shift + exec "$HERE/usr/bin/$BINARY_NAME" "$@" + + else + if [ "x$SET_SHOW_ENV_FOR_APPRUN" == "xYeSS" ] ; then + # We have the (hidden) env var for debugging stuff set + echo BINARY_NAME=$BINARY_NAME 1>&2 # Don't leak strings into qpdf|fix-pdf|zlib-flate output going to stdout! + echo APPIMAGE=$APPIMAGE 1>&2 # Don't leak strings into qpdf|fix-pdf|zlib-flate output going to stdout! + echo CALLED_SUBCMD=$CALLED_SUBCMD 1>&2 # Don't leak strings into qpdf|fix-pdf|zlib-flate output going to stdout! + fi + exec "$HERE/usr/bin/qpdf" "$@" + fi + +fi + diff --git a/appimage/build-appimage b/appimage/build-appimage index 58fc9d0e..7e22d495 100755 --- a/appimage/build-appimage +++ b/appimage/build-appimage @@ -1,40 +1,162 @@ -#!/bin/sh +#!/bin/bash + +# Copyright (c) 2018 Jay Berkenbilt and Kurt Pfeifle +# +# This script is mainly meant to build an 'AppImage' from GitHub sources of QPDF via Travis CI on an +# Ubuntu Trusty (14.04) LTS system (see https://appimage.org/). +# +# But it also allows Linux users to build such an AppImage on their own systems. Please read +# 'README.md' from the top level Git sources to see what preconditions you must meet to build QPDF +# in general. The same apply to build an AppImage. Then follow these three steps: +# +# 1. Clone Git sources: `git clone https://github.com/qpdf/qpdf.git git.qpdf` +# 2. Change into git dir: `cd git.qpdf` +# 3. Run this script: `bash appimage/build-appimage` +# +# The resulting AppImage will be placed in './appimage/build/QPDF-x86_64.AppImage'. +# Read the output of the script for hints in case something goes wrong. +# +# You may pass custom options for the configure step by setting them into the 'CUSTOM_CONFIGURE' +# environment variable and exporting it before running this script. For example: +# +# export CUSTOM_CONFIGURE=" --enable-test-compare-images [--more-other-options]" +# +# ATTENTION: +# +# 1. To build the AppImage you should have a working internet connection. +# Reason: the script downloads the most recent 'linuxdeployqt' utility for building the AppImage. +# 2. If you build the AppImage on a too recent Linux distribution, it may only work on the exact +# distribution you build it on. For an AppImage to work on a wide range of different +# distributions from the last 3-4 years if should be built on Ubuntu Trusty (14.04). + + set -ex + +# Support for signing the AppImage (only by original maintainer): sign= -if [ "$1" = "--sign" ]; then +if [ "x$1" == "x--sign" ] ; then sign=--sign fi + + +# Check if we are on Ubuntu Trusty +_osversion=$(cat /etc/os-release | grep PRETTY_NAME | awk -F'=' '{print $2}' | sed 's#"##g') + +# Warn users building the AppImage locally: +if [ x"$_osversion" != x"Ubuntu 14.04.5 LTS" ] ; then +set +x + echo "" + echo "+==============================================================================================================+" + echo "|| WARNING: You are about to build a QPDF AppImage on a system which is NOT Ubuntu 14.04.5 LTS ('Trusty'). ||" + echo "|| ||" + echo "|| Very likely you use a newer Linux distribution. ||" + echo "|| The resulting AppImage will not be 'universally' usable. ||" + echo "|| Hence, it likely will not be capable of running on a large range of Linux distributions. ||" + echo "|| It will only reliably run on the very same systems it has been created on, and maybe some similar ones. ||" + echo "+==============================================================================================================+" + echo "" +set -x +fi + + +# From where do we run this script? here="$(dirname $(readlink -f "$0"))" top=$(dirname $here) + +# Move to root of GitHub sources: cd $top + +# Set 'appdir' environment variable name: appdir=$here/build/appdir + +# Clean up stuff from previous build attempts: rm -rf $here/build + +# Prepare build of QPDF from sources: ./autogen.sh -./configure --prefix=/usr --enable-werror --enable-show-failed-test-output +./configure --prefix=/usr --enable-werror --enable-show-failed-test-output --enable-html-doc --enable-pdf-doc "$CUSTOM_CONFIGURE" + +# Build! make -j$(nproc) + +# Run built-in QPDF checks: make check + +# Prepare AppDir which is the basis for the AppImage: mkdir -p $appdir -make install DESTDIR=$appdir; find $appdir + +# Install build result into AppDir: +make install DESTDIR=$appdir ; find $appdir + +# Change into build directory: cd $here/build + # Don't bundle developer stuff rm -rf appdir/usr/include appdir/usr/lib/pkgconfig appdir/usr/lib/*.{a,la,so} -rm -rf appdir/usr/share/doc appdir/usr/share/man -for i in appdir/usr/share/icons/hicolor/128x128/apps; do + +# Copy icon which is needed for desktop integration into place: +for i in appdir/usr/share/icons/hicolor/512x512/apps ; do mkdir -p $i - cp $top/logo/qpdf.svg $i - convert -resize '128x128>' $top/logo/qpdf.svg $i/qpdf.png + cp $top/logo/qpdf.png $i done -for i in appdir/usr/share/applications; do mkdir -p $i; cp $top/appimage/qpdf.desktop $i; done + +# Copy .desktop and .appdata.xml metadata for desktop integration into place: +for i in appdir/usr/share/applications ; do mkdir -p $i ; cp $top/appimage/qpdf.desktop $i ; done +for i in appdir/usr/share/metainfo ; do mkdir -p $i ; cp $top/appimage/qpdf.appdata.xml $i ; done +for i in appdir/usr/share/doc/qpdf ; do mkdir -p $i ; cp $top/README* $i ; cp $top/NOTICE.md $i/README-notice.md ; cp $top/LICENSE.txt $i ; cp $top/Artistic-2.0 $i/Artistic-LICENSE.txt ; cp $top/ChangeLog $i/README-ChangeLog ; cp $top/TODO $i/README-todo ; done + +# The following lines are experimental (for debugging; and to test support for unexpected future binaries added to QPDF): +for i in /usr/bin/env /bin/less /bin/busybox ; do cp $i appdir/usr/bin/ ; done +ls -l /usr/bin/env /bin/less /bin/busybox + +# Fetch 'linuxdeployqt' which will transform the AppDir into an AppImage: wget -c "https://github.com/probonopd/linuxdeployqt/releases/download/continuous/linuxdeployqt-continuous-x86_64.AppImage" chmod a+x linuxdeployqt*.AppImage -unset QTDIR; unset QT_PLUGIN_PATH ; unset LD_LIBRARY_PATH + +# Set up a clean environment: +unset QTDIR ; unset QT_PLUGIN_PATH ; unset LD_LIBRARY_PATH + +# Let 'linuxdeployqt' do its first stage of work: ./linuxdeployqt*.AppImage appdir/usr/share/applications/*.desktop -bundle-non-qt-libs + # In addition to the main executable, we have additional ones to process ./linuxdeployqt*.AppImage appdir/usr/bin/zlib-flate -bundle-non-qt-libs -# Generate AppImage + +# To eventually generate the AppImage we extract the linuxdeployqt AppImage to get access to the embedded 'appimagetool': ./linuxdeployqt*.AppImage --appimage-extract -rm appdir/AppRun ; cp $top/appimage/AppRun appdir; chmod a+x appdir/AppRun # Replace symlink with custom script -PATH=./squashfs-root/usr/bin:$PATH ./squashfs-root/usr/bin/appimagetool $sign appdir + +# We want to run our custom AppRun script: +rm appdir/AppRun ; cp $top/appimage/AppRun appdir ; chmod a+x appdir/AppRun # Replace symlink with custom script + +# If we are not on Ubuntu Trusty, we need to disable 'appstreamcli' validation: +if [ x"$_osversion" == x"Ubuntu 14.04.5 LTS" ] ; then + appimagetool_param="" +else + appimagetool_param="-n" + set +x + echo "" + echo " Running 'appimagetool' with '-n' parameter..." + echo " Reason: this does not seem to be a Travis CI build running on Ubuntu Trusty 14.04." + echo " '-n' disables checking of AppStream data by the 'appstreamcli' utility since post-Trusty versions have incompatible changes." + echo "" + set -x +fi + +# Set up a version string to include in the AppImage name +MAJOR_QPDF_VERSION=$( ./appdir/usr/bin/qpdf --version | grep "qpdf version" | awk '{print $3}' ) +VERSION=${MAJOR_QPDF_VERSION}-continuous-${TRAVIS_JOB_NUMBER}-$(date "+%Y-%m-%d")-git.$(git rev-parse --short HEAD)-x86_64 + +# Remove the default AppRun/symlink and use our own custom AppRun script +rm appdir/AppRun ; cp $top/appimage/AppRun appdir; chmod a+x appdir/AppRun + +set +x +# Finally, generate the AppImage: +PATH=./squashfs-root/usr/bin:$PATH ./squashfs-root/usr/bin/appimagetool $sign -g $appimagetool_param appdir qpdf-$VERSION.AppImage + +# Tell everyone where our result is stored: echo "" -echo "*** AppImage is ready in appimage/build ***" +echo "====================================================================================" +echo " === AppImage is ready in $top/appimage/build ===" +echo "====================================================================================" echo "" + diff --git a/appimage/qpdf-screenshot.jpeg b/appimage/qpdf-screenshot.jpeg new file mode 100644 index 00000000..b17b1661 Binary files /dev/null and b/appimage/qpdf-screenshot.jpeg differ diff --git a/appimage/qpdf.appdata.xml b/appimage/qpdf.appdata.xml new file mode 100644 index 00000000..6632a5ea --- /dev/null +++ b/appimage/qpdf.appdata.xml @@ -0,0 +1,45 @@ + + + + org.QPDF.qpdf.desktop + MIT + Apache-2.0 + QPDF + Structural, content-preserving transformations on PDF files + +

QPDF is a command-line program that does structural, content-preserving transformations on PDF files. + It could have been called something like pdf-to-pdf. + It also provides many useful capabilities to developers of PDF-producing software or for people + who just want to look at the innards of a PDF file to learn more about how they work.

+

QPDF is capable of creating linearized (also known as web-optimized) files and encrypted files. + It is also capable of converting PDF files with object streams (also known as compressed objects) + to files with no compressed objects or to generate object streams from files that don't have them + (or even those that already do). QPDF also supports a special mode designed to allow you to edit + the content of PDF files in a text editor. For more details, please see the documentation links + below.

+

QPDF includes support for merging and splitting PDFs through the ability to copy objects from one PDF + file into another and to manipulate the list of pages in a PDF file. The QPDF library also makes + it possible for you to create PDF files from scratch. In this mode, you are responsible for + supplying all the contents of the file, while the QPDF library takes care off all the syntactical + representation of the objects, creation of cross references tables and, if you use them, object + streams, encryption, linearization, and other syntactic details.

+

QPDF is not a PDF content creation library, a PDF viewer, or a program capable of converting PDF into + other formats. In particular, QPDF knows nothing about the semantics of PDF content streams. + If you are looking for something that can do that, you should look elsewhere. + However, once you have a valid PDF file, QPDF can be used to transform that file in ways perhaps + your original PDF creation can't handle. For example, programs generate simple PDF files but + can't password-protect them, web-optimize them, or perform other transformations of that type.

+
+ qpdf.desktop + http://qpdf.sourceforge.net/ + https://github.com/qpdf/qpdf/issues + + + https://i.stack.imgur.com/coCKR.jpg + + + + org.QPDF.qpdf.desktop + + +
diff --git a/appimage/qpdf.desktop b/appimage/qpdf.desktop index 466663ab..6193599d 100644 --- a/appimage/qpdf.desktop +++ b/appimage/qpdf.desktop @@ -5,3 +5,4 @@ Exec=qpdf Name=qpdf Comment=Structural, content-preserving transformations on PDF files Icon=qpdf +Categories=Utility;Office;ConsoleOnly; diff --git a/logo/qpdf.png b/logo/qpdf.png new file mode 100644 index 00000000..e600a223 Binary files /dev/null and b/logo/qpdf.png differ