--- sugar-read-activity-0.86-78.orig/debian/README.source +++ sugar-read-activity-0.86-78/debian/README.source @@ -0,0 +1,94 @@ +Building this package for Debian +-------------------------------- + +This source package uses quilt to apply and remove its patches. Please +refer to /usr/share/doc/quilt/README.source for information about how to +use quilt for source packages. + + +Developing this package for Debian +---------------------------------- + +The source of this package is developed using git and the helper tool +git-buildpackage, with all official releases tagged and signed and +binary diffs of tarballs stored using pristine-tar. This is documented +below /usr/share/doc/git-buildpackage/manual-html/ . + +Upstream development is tracked both in the Git branch "upstream-git" +and using upstream tarballs. + +A custom build target shows current upstream and packaging versions: + + debian/rules print-version + +Current upstream tarball can be prepared using this other build target: + + debian/rules get-orig-source + +To switch to newer upstream source, first add a dummy changelog entry +and comment out DEB_UPSTREAM_TARBALL_MD5 before getting the source: + + dch -v ${new_upstream_version}-1 "Dummy changelog entry" + sed -i -e 's/^\(DEB_UPSTREAM_TARBALL_MD5\b\)/#\1/' debian/rules + debian/rules get-orig-source + +Store new md5sum to help ensure identical source is received later. + +Before injecting a newer upstream tarball, use below commands to sync +with upstream Git, to adopt upstream commit messages and to minimize +size of our Git. + +The following commands updates the local mirror of upstream source: + + git checkout upstream-git + git pull + git fetch --tags + +The following command shows upstream changes possibly relevant to merge +or cherry-pick (replace leading "upstream" with "HEAD^" and invoke +immediately after syncing to show recently merged changes possibly +relevant to mention in our changelog): + + git log --pretty="format:%h %s" upstream..upstream-git + +The following commands merges all upstream changes with our packaging +branches (to skip newest upstream changes, replace dot in first pull +command with either a tag or an explicit commit hash): + + git checkout upstream + git pull . upstream-git + git checkout master + git pull . upstream + +If git-import-orig fails complaining about no changes, revert both pulls +(using "git reset --hard HEAD^" in both master and upstream branches), +and try again skipping the very newest changes to cheat git-import-orig. + +To do a package release from upstream Git snapshot, first look at +upstream development for a good place to release, and tag by its date, +replacing "~" with "." to mimic git-buildpackage logic (replace +timestamp and commit hash below with real ones based on chosen commit). + + git log --abbrev-commit upstream-git + git tag -s -m "Upstream snapshot" upstream/0.2.git20080130 61279f8 + dch -r -v "0.2~git20080130-1" "New upstream Git snapshot." + +Setting DEB_MAINTAINER_MODE=1 enables additional build routines helpful +during development of the package, but unfit for normal builds. This +typically includes the CDBS feature of auto-updating debian/control with +CDBS-related build-dependencies, which is forbidden by Debian Policy as +build environment must not change during automated builds. + + +Maintaining packaging build routines +------------------------------------ + +This source package wraps debhelper commands and other tedious parts of +the build routines using the CDBS framework. Please refer to the actual +makefile snippets included from debian/rules for details on their +purpose and ways to override defaults. Additionally, makefile snippets +included from below /usr/share/cdbs may also be documented in +/usr/share/doc/cdbs/cdbs-doc.pdf.gz . + + + -- Jonas Smedegaard Sun, 29 Mar 2009 16:02:47 +0200 --- sugar-read-activity-0.86-78.orig/debian/gbp.conf +++ sugar-read-activity-0.86-78/debian/gbp.conf @@ -0,0 +1,5 @@ +# Configuration file for git-buildpackage and friends + +[DEFAULT] +pristine-tar = True +sign-tags = True --- sugar-read-activity-0.86-78.orig/debian/pycompat +++ sugar-read-activity-0.86-78/debian/pycompat @@ -0,0 +1 @@ +2 --- sugar-read-activity-0.86-78.orig/debian/compat +++ sugar-read-activity-0.86-78/debian/compat @@ -0,0 +1 @@ +6 --- sugar-read-activity-0.86-78.orig/debian/watch +++ sugar-read-activity-0.86-78/debian/watch @@ -0,0 +1,3 @@ +# run the "uscan" command to check for upstream updates and more. +version=3 +http://download.sugarlabs.org/sources/sucrose/fructose/Read/Read-(.*)\.tar\.bz2 --- sugar-read-activity-0.86-78.orig/debian/copyright +++ sugar-read-activity-0.86-78/debian/copyright @@ -0,0 +1,40 @@ +Format: http://svn.debian.org/wsvn/dep/web/deps/dep5.mdwn?op=file&rev=54 +Name: Read +Contact: Sugarlabs + http://lists.sugarlabs.org/listinfo/sugar-devel + irc://irc.freenode.net/sugar +Source: http://download.sugarlabs.org/sources/sucrose/fructose/Read/ + git://git.sugarlabs.org/read/mainline + +Copyright: 2009, One Laptop Per Child +License: GPL-2+ + +Files: readtoolbar.py, + setup.py +Copyright: 2006, Red Hat, Inc +License: GPL-2+ + +Files: readtopbar.py +Copyright: 2006-2007, Red Hat, Inc + 2009, One Laptop Per Child +License: GPL-2+ + +Files: readactivity.py +Copyright: 2007, Collabora Ltd. , + 2007, Red Hat, Inc, + 2008, One Laptop Per Child, + 2009, Simon Schampijer +License: GPL-2+ + +Files: debian/* +Copyright: 2003-2009, Jonas Smedegaard +License: GPL-2+ + +License: GPL-2+ + 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, or (at + your option) any later version. + . + On Debian GNU systems, the complete text of GNU General Public License + (GPL) version 2 can be found at /usr/share/common-licenses/GPL-2. --- sugar-read-activity-0.86-78.orig/debian/rules +++ sugar-read-activity-0.86-78/debian/rules @@ -0,0 +1,52 @@ +#!/usr/bin/make -f +# -*- mode: makefile; coding: utf-8 -*- +# Copyright © 2009 Jonas Smedegaard +# Description: Main Debian packaging script for Read +# +# 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, or (at +# your option) any later version. +# +# 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, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA +# 02111-1307 USA. + +DEB_PYTHON_SYSTEM = pycentral +DEB_SUGAR_BRANCHES = 0.86 +ifneq (,$(DEB_MAINTAINER_MODE)) + # Enable stuff not policy compliant (eg. unsuitable for build daemons) + DEB_COPYRIGHT_CHECK_STRICT = yes + DEB_AUTO_UPDATE_DEBIAN_CONTROL = yes +endif +include debian/cdbs/1/rules/upstream-tarball.mk +include debian/cdbs/1/class/python-sugar.mk +include debian/cdbs/1/rules/copyright-check.mk +include /usr/share/cdbs/1/rules/patchsys-quilt.mk +include debian/cdbs/1/rules/buildinfo.mk + +DEB_UPSTREAM_PACKAGE = Read +DEB_UPSTREAM_URL = http://download.sugarlabs.org/sources/sucrose/fructose/$(DEB_UPSTREAM_PACKAGE) +DEB_UPSTREAM_TARBALL_EXTENSION = tar.bz2 +DEB_UPSTREAM_TARBALL_MD5 = 56149150047f350a09047eccc7f420de + +# Needed (always/seldom) at runtime +# Python libs only recommended are tied to optional epubview support +CDBS_DEPENDS = $(call cdbs_sugar_anybranchdeps,python-sugar-toolkit, python-sugar) +CDBS_DEPENDS += , python-gobject, python-gtk2, python-dbus, python-cjson, python-evince, python-gconf, python-telepathy +CDBS_RECOMMENDS = ttf-dejavu-core +CDBS_RECOMMENDS += , python-lxml, python-cairo, python-beautifulsoup, python-webkit + +# Ensure only one variant is installed at a time (Debian Policy 7.6.2) +CDBS_PROVIDES = $(DEB_SUGAR_SOURCE_PKGBASE) +CDBS_CONFLICTS = $(DEB_SUGAR_SOURCE_PKGBASE) +CDBS_REPLACES = $(DEB_SUGAR_SOURCE_PKGBASE) + +# Resolve, cleanup and apply CDBS-declared dependencies +include debian/cdbs/1/rules/package-relations.mk --- sugar-read-activity-0.86-78.orig/debian/control.in +++ sugar-read-activity-0.86-78/debian/control.in @@ -0,0 +1,28 @@ +Source: sugar-read-activity-0.86 +Section: x11 +Priority: optional +Maintainer: Debian OLPC +Uploaders: Jonas Smedegaard +Build-Depends: @cdbs@ +Standards-Version: 3.8.3 +Vcs-Git: git://git.debian.org/git/collab-maint/sugar-read-activity.git +Vcs-Browser: http://git.debian.org/?p=collab-maint/sugar-read-activity.git;a=summary +Homepage: http://wiki.sugarlabs.org/go/Activities/Read +XS-Python-Version: >= 2.5 + +Package: sugar-read-activity-0.86 +Architecture: all +Depends: ${shlibs:Depends}, ${python:Depends}, ${cdbs:Depends}, ${misc:Depends} +Recommends: ${cdbs:Recommends} +Provides: ${python:Provides}, ${cdbs:Provides} +Conflicts: ${cdbs:Conflicts} +Replaces: ${cdbs:Replaces} +XB-Python-Version: ${python:Versions} +Description: book reader activity for the Sugar graphical shell + Sugar is a graphical user interface aimed at children. + . + Originating as intregral part of the OLPC "XO" a.k.a. the $100 laptop, + Sugar has since grown into a more widely usable low-ressource desktop + environment for kids. + . + This package contains the Read activity, providing a simple book reader. --- sugar-read-activity-0.86-78.orig/debian/copyright_hints +++ sugar-read-activity-0.86-78/debian/copyright_hints @@ -0,0 +1,176 @@ +Format: http://svn.debian.org/wsvn/dep/web/deps/dep5.mdwn?op=file&rev=REVISION +Name: Untrusted draft - double-check copyrights yourself! + +Files: po/Read.pot + po/af.po + po/am.po + po/ay.po + po/bg.po + po/bi.po + po/bn.po + po/bn_IN.po + po/ca.po + po/cpp.po + po/cs.po + po/da.po + po/dz.po + po/el.po + po/en.po + po/en_US.po + po/fa.po + po/fa_AF.po + po/ff.po + po/fi.po + po/fr.po + po/gu.po + po/ha.po + po/he.po + po/hi.po + po/ht.po + po/hu.po + po/id.po + po/ig.po + po/is.po + po/it.po + po/ja.po + po/km.po + po/ko.po + po/kos.po + po/mg.po + po/mi.po + po/mk.po + po/ml.po + po/mn.po + po/mr.po + po/ms.po + po/mvo.po + po/nb.po + po/ne.po + po/nl.po + po/pa.po + po/pap.po + po/pis.po + po/pl.po + po/ps.po + po/pseudo.po + po/pt_BR.po + po/qu.po + po/ro.po + po/ru.po + po/rw.po + po/sd.po + po/si.po + po/sk.po + po/sl.po + po/sq.po + po/sv.po + po/sw.po + po/ta.po + po/te.po + po/th.po + po/tpi.po + po/tr.po + po/tzo.po + po/ug.po + po/ur.po + po/vi.po + po/wa.po + po/yo.po +Copyright: YEAR THE PACKAGE'S HOLDER +License: UNKNOWN + +Files: AUTHORS + NEWS + activity/activity-read.svg + activity/activity.info + activity/mimetypes.xml + debian/README.source + debian/compat + debian/control + debian/control.in + debian/gbp.conf + debian/patches/1001_use_plain_dejavu.patch + debian/patches/1002_include_python26_zipfile.patch + debian/patches/README + debian/patches/series + debian/pycompat + debian/watch + epubadapter.py + epubview/epubinfo.py + epubview/navmap.py + epubview/widgets.py + po/de.po + po/zh_CN.po + po/zh_TW.po + read_v1.db + readdialog.py +Copyright: *No copyright* +License: UNKNOWN + +Files: epubview/__init__.py + epubview/epub.py + epubview/epubview.py + epubview/jobs.py + readbookmark.py + readdb.py + readsidebar.py +Copyright: 2009, One Laptop Per Child +License: GPL-2+ + +Files: debian/cdbs/1/class/python-sugar.mk + debian/cdbs/1/rules/package-relations.mk +Copyright: 2008, Jonas Smedegaard +License: GPL + +Files: readtoolbar.py + setup.py +Copyright: 2006, Red Hat, Inc +License: GPL-2+ + +Files: po/es.po + po/pt.po +Copyright: 2007, THE PACKAGE'S HOLDER +License: UNKNOWN + +Files: debian/cdbs/1/class/python-vars.mk +Copyright: 2003,2008, Jonas Smedegaard +License: GPL + +Files: debian/cdbs/1/rules/buildinfo.mk +Copyright: 2004-2007, Jonas Smedegaard +License: GPL + +Files: debian/cdbs/1/rules/upstream-tarball.mk +Copyright: 2007-2008, Jonas Smedegaard +License: GPL + +Files: debian/rules +Copyright: 2009, Jonas Smedegaard +License: GPL + +Files: debian/cdbs/1/rules/copyright-check.mk +Copyright: \s*(\S.*?)\s*\ +License: GPL + +Files: readtopbar.py +Copyright: 2006-2007, Red Hat, Inc + 2009, One Laptop Per Child +License: GPL-2+ + +Files: readactivity.py +Copyright: 2008, One Laptop Per Child + 2009, Simon Schampijer + 2007, Red Hat, Inc + 2007, Collabora Ltd. +License: GPL-2+ + +Files: COPYING +Copyright: 1989, 1991, Free Software Foundation, Inc. + the software, and +License: UNKNOWN + +Files: po/ar.po +Copyright: YEAR THE PACKAGE'S HOLDER + %(user)s %(time)s" +License: UNKNOWN + --- sugar-read-activity-0.86-78.orig/debian/control +++ sugar-read-activity-0.86-78/debian/control @@ -0,0 +1,28 @@ +Source: sugar-read-activity-0.86 +Section: x11 +Priority: optional +Maintainer: Debian OLPC +Uploaders: Jonas Smedegaard +Build-Depends: cdbs (>= 0.4.39), debhelper (>= 6), python-sugar-0.86, python-sugar-toolkit-0.86, unzip, python-dev (>= 2.3.5-11), python-central (>= 0.5.6), devscripts (>= 2.10.7), quilt, patchutils (>= 0.2.25), dh-buildinfo +Standards-Version: 3.8.3 +Vcs-Git: git://git.debian.org/git/collab-maint/sugar-read-activity.git +Vcs-Browser: http://git.debian.org/?p=collab-maint/sugar-read-activity.git;a=summary +Homepage: http://wiki.sugarlabs.org/go/Activities/Read +XS-Python-Version: >= 2.5 + +Package: sugar-read-activity-0.86 +Architecture: all +Depends: ${shlibs:Depends}, ${python:Depends}, ${cdbs:Depends}, ${misc:Depends} +Recommends: ${cdbs:Recommends} +Provides: ${python:Provides}, ${cdbs:Provides} +Conflicts: ${cdbs:Conflicts} +Replaces: ${cdbs:Replaces} +XB-Python-Version: ${python:Versions} +Description: book reader activity for the Sugar graphical shell + Sugar is a graphical user interface aimed at children. + . + Originating as intregral part of the OLPC "XO" a.k.a. the $100 laptop, + Sugar has since grown into a more widely usable low-ressource desktop + environment for kids. + . + This package contains the Read activity, providing a simple book reader. --- sugar-read-activity-0.86-78.orig/debian/changelog +++ sugar-read-activity-0.86-78/debian/changelog @@ -0,0 +1,26 @@ +sugar-read-activity-0.86 (78-3) unstable; urgency=low + + * Add patch 1002 to include zipfile.py fetched from Python2.6 sources, + as workaround for zip handling not Python 2.5 compatible. + * Include upstream shipped sqlite db (needed after all). + + -- Jonas Smedegaard Mon, 30 Nov 2009 15:44:21 +0100 + +sugar-read-activity-0.86 (78-2) unstable; urgency=low + + * Fix recommend python-lxml, python-cairo, python-beautifulsoup and + python-webkit. + + -- Jonas Smedegaard Mon, 30 Nov 2009 04:14:09 +0100 + +sugar-read-activity-0.86 (78-1) unstable; urgency=low + + * New upstream release. + + -- Jonas Smedegaard Mon, 30 Nov 2009 02:50:20 +0100 + +sugar-read-activity-0.86 (76-1) unstable; urgency=low + + * Initial release. Closes: bug#444021. + + -- Jonas Smedegaard Sun, 25 Oct 2009 16:59:22 +0100 --- sugar-read-activity-0.86-78.orig/debian/cdbs/1/class/python-sugar.mk +++ sugar-read-activity-0.86-78/debian/cdbs/1/class/python-sugar.mk @@ -0,0 +1,127 @@ +# -*- mode: makefile; coding: utf-8 -*- +# Copyright © 2008 Jonas Smedegaard +# Description: Class to build and install Sugar packages +# +# 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, or (at +# your option) any later version. +# +# 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, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02111-1307 USA. +# + +_cdbs_scripts_path ?= /usr/lib/cdbs +_cdbs_rules_path ?= /usr/share/cdbs/1/rules +_cdbs_class_path ?= /usr/share/cdbs/1/class + +ifndef _cdbs_class_python_sugar +_cdbs_class_python_sugar = 1 + +#include $(_cdbs_class_path)/python-vars.mk$(_cdbs_makefile_suffix) +include debian/cdbs/1/class/python-vars.mk +include $(_cdbs_rules_path)/debhelper.mk$(_cdbs_makefile_suffix) + +# Space-delimited list of supported branches, lowest listed first +# (comment out if all current branches are supported) +# NB! This variable must be declared *above* inclusion of this snippet +#DEB_SUGAR_BRANCHES = 0.84 0.86 + +# FIXME: move these to buildvars.mk +comma = , +cdbs_delimit = $(firstword $1)$(foreach word,$(wordlist 2,$(words $1),$1),$2$(word)) + +# List "packages multiplied with branches", or just packages if no branches +# FIXME: move this to buildvars.mk +cdbs_expand_branches = $(subst WORDDELIMITER,$3,$(subst BRANCHDELIMITER,$4,$(call cdbs_delimit,$(if $2,$(foreach pkg,$1,$(call cdbs_delimit,$(foreach branch,$2,$(pkg)$(branch:%=-%)),BRANCHDELIMITER)),$1),WORDDELIMITER))) + +# convenience wrappers to expand Sugar branches for package dependencies +cdbs_sugar_allbranchdeps = $(call cdbs_expand_branches,$1,$(DEB_SUGAR_BRANCHES),$(comma) ,$(comma) ) +cdbs_sugar_anybranchdeps = $(call cdbs_expand_branches,$1,$(DEB_SUGAR_BRANCHES),$(comma) , | ) + +# Declare Build-Deps for packages using this file +CDBS_BUILD_DEPENDS := $(CDBS_BUILD_DEPENDS), $(call cdbs_sugar_anybranchdeps,python-sugar python-sugar-toolkit), unzip +# FIXME: Resolve DEB_PYTHON_PACKAGES in build targets only +ifeq (,$(cdbs_python_pkg_check)$(DEB_PYTHON_ARCH_PACKAGES)) + ifneq (, $(cdbs_python_compile_version)) + CDBS_BUILD_DEPENDS := $(CDBS_BUILD_DEPENDS), python$(cdbs_python_compile_version)-dev, python (>= 2.3.5-11) + else + CDBS_BUILD_DEPENDS := $(CDBS_BUILD_DEPENDS), python-dev (>= 2.3.5-11) + endif +else +CDBS_BUILD_DEPENDS := $(CDBS_BUILD_DEPENDS), python-all-dev (>= 2.3.5-11) +endif +ifeq (pysupport, $(DEB_PYTHON_SYSTEM)) +CDBS_BUILD_DEPENDS := $(CDBS_BUILD_DEPENDS), python-support (>= 0.3.2) +else +CDBS_BUILD_DEPENDS := $(CDBS_BUILD_DEPENDS), python-central (>= 0.5.6) +endif + +# Convenience variable for e.g. conflicts/provides/replaces +DEB_SUGAR_SOURCE_PKGBASE ?= $(DEB_SOURCE_PACKAGE:%-$(firstword $(DEB_SUGAR_BRANCHES))=%) + +DEB_PYTHON_SUGAR_PACKAGES ?= $(filter $(call cdbs_expand_branches,sugar-%-activity,$(DEB_SUGAR_BRANCHES)), $(DEB_PACKAGES)) + +# TODO: Move this to buildvars.mk +cdbs_pkgsrcdir = $(if $(DEB_PKGSRCDIR_$(cdbs_curpkg)),$(DEB_PKGSRCDIR_$(cdbs_curpkg)),$(DEB_SRCDIR)) + +pre-build:: + mkdir -p debian/stamps-configure + +$(patsubst %,build/%,$(DEB_PYTHON_SUGAR_PACKAGES)) :: build/%: + [ ! -e $(cdbs_pkgsrcdir)/MANIFEST ] || [ -e $(cdbs_pkgsrcdir)/MANIFEST.upstream ] || mv $(cdbs_pkgsrcdir)/MANIFEST $(cdbs_pkgsrcdir)/MANIFEST.upstream + [ ! -e $(cdbs_pkgsrcdir)/MANIFEST.upstream ] || egrep -v '^locale/.*/(.*\.mo|activity\.linfo)$$' $(cdbs_pkgsrcdir)/MANIFEST.upstream > $(cdbs_pkgsrcdir)/MANIFEST + for pythonver in $(cdbs_python_build_versions); do \ + /usr/bin/python$$ver $(cdbs_pkgsrcdir)/setup.py build; \ + done + [ ! -e $(cdbs_pkgsrcdir)/MANIFEST.upstream ] || IFS="`printf '\n'`" find "$(cdbs_pkgsrcdir)/locale" -type f \( -name '*.mo' -or -name 'activity.linfo' \) | while read path; do \ + echo "$$path" | sed 's!^$(cdbs_pkgsrcdir)/!!' >> $(cdbs_pkgsrcdir)/MANIFEST; \ + done + +$(patsubst %,install/%,$(DEB_PYTHON_SUGAR_PACKAGES)) :: install/%: + mkdir -p $(DEB_DESTDIR)usr/share/sugar/activities + for pythonver in $(cdbs_python_build_versions); do \ + LANG=C /usr/bin/python$$ver $(cdbs_pkgsrcdir)/setup.py install --prefix="$(DEB_DESTDIR)/usr"; \ + done + +$(patsubst %,binary-install/%,$(DEB_PYTHON_SUGAR_PACKAGES)) :: binary-install/%: +ifeq (pysupport, $(DEB_PYTHON_SYSTEM)) + dh_pysupport -p$(cdbs_curpkg) $(DEB_PYTHON_PRIVATE_MODULES_DIRS) $(DEB_PYTHON_PRIVATE_MODULES_DIRS_$(cdbs_curpkg)) +else + dh_pycentral -p$(cdbs_curpkg) +endif + +# Replace superfluous COPYING files with symlinks +$(patsubst %,binary-post-install/%,$(DEB_PYTHON_SUGAR_PACKAGES)) :: binary-post-install/%: + ! test -f $(DEB_DESTDIR)/usr/share/sugar/activities/*.activity/COPYING \ + || ! diff -q /usr/share/common-licenses/GPL-2 $(DEB_DESTDIR)/usr/share/sugar/activities/*.activity/COPYING \ + || ln -sfT ../../../common-licenses/GPL-2 $(DEB_DESTDIR)/usr/share/sugar/activities/*.activity/COPYING + +reverse-config:: $(patsubst %,cleanpythonsugar-reverse-config/%,$(DEB_PYTHON_SUGAR_PACKAGES)) +$(patsubst %,cleanpythonsugar-reverse-config/%,$(DEB_PYTHON_SUGAR_PACKAGES)) :: cleanpythonsugar-reverse-config/% : + [ ! -e $(cdbs_pkgsrcdir)/MANIFEST.upstream ] || mv -f $(cdbs_pkgsrcdir)/MANIFEST.upstream $(cdbs_pkgsrcdir)/MANIFEST + +clean:: $(patsubst %,cleanpythonsugar/%,$(DEB_PYTHON_SUGAR_PACKAGES)) +ifeq (, $(cdbs_selected_pycompat)) + echo "$(cdbs_pycompat)" >debian/pycompat +endif # use pycompat + +$(patsubst %,cleanpythonsugar/%,$(DEB_PYTHON_SUGAR_PACKAGES)) :: cleanpythonsugar/% : + -IFS="`printf '\n'`" find "$(cdbs_pkgsrcdir)/locale" -type f \( -name '*.mo' -or -name 'activity.linfo' \) | while read path; do \ + rm -f "$$path"; \ + rmdir --ignore-fail-on-non-empty "`dirname "$$path"`"; \ + done + -rmdir --ignore-fail-on-non-empty "$(cdbs_pkgsrcdir)/locale" + +## TODO: Drop this when DEB_PYTHON_PACKAGES is only resolved in build targets +pre-build clean:: + $(cdbs_python_pkgresolve_check) + +endif --- sugar-read-activity-0.86-78.orig/debian/cdbs/1/class/python-vars.mk +++ sugar-read-activity-0.86-78/debian/cdbs/1/class/python-vars.mk @@ -0,0 +1,109 @@ +# -*- mode: makefile; coding: utf-8 -*- +# Copyright © 2003,2008 Jonas Smedegaard +# Description: Defines useful variables for Python packages +# +# 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, or (at +# your option) any later version. +# +# 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, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02111-1307 USA. +# + + +_cdbs_scripts_path ?= /usr/lib/cdbs +_cdbs_rules_path ?= /usr/share/cdbs/1/rules +_cdbs_class_path ?= /usr/share/cdbs/1/class + +ifndef _cdbs_class_python_vars +_cdbs_class_python_vars = 1 + +include $(_cdbs_rules_path)/buildvars.mk$(_cdbs_makefile_suffix) + +DEB_PYTHON_PACKAGES = $(filter-out %-doc %-dev %-common, $(DEB_PACKAGES)) + +DEB_PYTHON_ARCH_PACKAGES = $(filter $(DEB_PYTHON_PACKAGES), $(DEB_ARCH_PACKAGES)) +DEB_PYTHON_INDEP_PACKAGES = $(filter $(DEB_PYTHON_PACKAGES), $(DEB_INDEP_PACKAGES)) + +## FIXME: Resolve DEB_PYTHON_PACKAGES in build targets only +# Avoid including buildcore.mk to not risk breaking when hopefully removing again +cdbs_python_streq = $(if $(filter-out xx,x$(subst $1,,$2)$(subst $2,,$1)x),,yes) +cdbs_python_packages_pre := $(DEB_PYTHON_ARCH_PACKAGES)$(DEB_PYTHON_INDEP_PACKAGES) +cdbs_python_pkgresolve_check = $(if $(call cdbs_python_streq,$(DEB_PYTHON_ARCH_PACKAGES)$(DEB_PYTHON_INDEP_PACKAGES),$(cdbs_python_packages_pre)),, $(warning Setting DEB_PYTHON_*PACKAGES after python-vars in included is currently unsupported)) +## TODO: Rephrase when DEB_PYTHON_PACKAGES is only resolved in build targets +cdbs_python_pkg_check = $(if $(DEB_PYTHON_ARCH_PACKAGES)$(DEB_PYTHON_INDEP_PACKAGES),, $(warning No Python packages found or declared - either rename binary packages or set DEB_PYTHON_PACKAGES (or one or both of DEB_PYTHON_ARCH_PACKAGES and DEB_PYTHON_INDEP_PACKAGES) before including python-vars.mk)) + +# check python system +cdbs_use_xs_field := $(shell grep -q "^XS-Python-Version:" debian/control && echo yes) +cdbs_selected_pycompat := $(shell if [ -e debian/pycompat ]; then cat debian/pycompat; fi) +cdbs_pycompat = $(cdbs_selected_pycompat) +ifeq (pysupport, $(DEB_PYTHON_SYSTEM)) + ifeq (, $(cdbs_selected_pycompat)) + cdbs_pycompat = 2 + endif # use pycompat + # warning pysupport compatibility mode + ifneq (, $(cdbs_use_xs_field)) + $(warning Use of XS-Python-Version and XB-Python-Version fields in 'debian/control' is deprecated with pysupport method, use 'debian/pyversions' if you need to specify specific versions) + endif # use XS field (compat) +else + ifeq (pycentral, $(DEB_PYTHON_SYSTEM)) + ifeq (, $(cdbs_selected_pycompat)) + cdbs_pycompat = 2 + endif # use pycompat + else + ifneq (, $(DEB_PYTHON_SYSTEM)) + $(error unsupported Python system: $(DEB_PYTHON_SYSTEM) (select either pysupport or pycentral)) + else + ifneq (, $(cdbs_use_xs_field)) + $(error Your package uses the new Python policy; you must set DEB_PYTHON_SYSTEM to "pysupport" or "pycentral".) + endif + ifneq (, $(cdbs_selected_pycompat)) + ifeq (yes, $(shell expr $(cdbs_selected_pycompat) \> 1 >/dev/null && echo yes)) + $(error Your package uses the new Python policy; you must set DEB_PYTHON_SYSTEM to "pysupport" or "pycentral".) + endif + endif # use pycompat + endif # unknown method + endif # pycentral +endif # pysupport + +# Calculate cdbs_python_build_versions +cdbs_python_current_version := $(shell pyversions -vd) +## FIXME: Resolve DEB_PYTHON_PACKAGES in build targets only +ifeq (,$(cdbs_python_pkg_check)$(DEB_PYTHON_ARCH_PACKAGES)) + # check if current is in build versions + ifneq ($(cdbs_python_current_version), $(filter $(cdbs_python_current_version), $(shell pyversions -vr))) + cdbs_python_compile_version := $(firstword $(strip $(sort $(shell pyversions -vr)))) + cdbs_python_build_versions := $(cdbs_python_compile_version) + else + cdbs_python_build_versions := $(cdbs_python_current_version) + endif +else +cdbs_python_build_versions := $(shell pyversions -vr) +endif # archall + +# check if build is possible +ifeq (, $(cdbs_python_build_versions)) +ifeq (pysupport, $(DEB_PYTHON_SYSTEM)) +$(error invalid setting in 'debian/pyversions') +else +$(error invalid setting for XS-Python-Version) +endif # system selected +endif # build versions empty + +# TODO: Support multiple python programs built for different python versions +# FIXME: Understand the above sentence and rephrase it +cdbs_python_curpkg_build_versions = $(cdbs_python_build_versions) + +## TODO: Drop this when DEB_PYTHON_PACKAGES is only resolved in build targets +pre-build clean:: + $(cdbs_python_pkgresolve_check) + +endif --- sugar-read-activity-0.86-78.orig/debian/cdbs/1/rules/buildinfo.mk +++ sugar-read-activity-0.86-78/debian/cdbs/1/rules/buildinfo.mk @@ -0,0 +1,40 @@ +# -*- mode: makefile; coding: utf-8 -*- +# Copyright © 2004-2007 Jonas Smedegaard +# Description: Generate and include build information +# +# 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, or (at +# your option) any later version. +# +# 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, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA +# 02111-1307 USA. + +_cdbs_scripts_path ?= /usr/lib/cdbs +_cdbs_rules_path ?= /usr/share/cdbs/1/rules +_cdbs_class_path ?= /usr/share/cdbs/1/class + +ifndef _cdbs_rules_buildinfo +_cdbs_rules_buildinfo = 1 + +include $(_cdbs_rules_path)/buildcore.mk$(_cdbs_makefile_suffix) + +CDBS_BUILD_DEPENDS := $(CDBS_BUILD_DEPENDS), dh-buildinfo + +common-install-arch common-install-indep:: debian/stamp-buildinfo + +debian/stamp-buildinfo: + dh_buildinfo + touch debian/stamp-buildinfo + +clean:: + rm -f debian/stamp-buildinfo + +endif --- sugar-read-activity-0.86-78.orig/debian/cdbs/1/rules/copyright-check.mk +++ sugar-read-activity-0.86-78/debian/cdbs/1/rules/copyright-check.mk @@ -0,0 +1,113 @@ +# -*- mode: makefile; coding: utf-8 -*- +# Copyright © 2005-2008 Jonas Smedegaard +# Description: Check for changes to copyright notices in source +# +# 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, or (at +# your option) any later version. +# +# 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, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA +# 02111-1307 USA. + +_cdbs_scripts_path ?= /usr/lib/cdbs +_cdbs_rules_path ?= /usr/share/cdbs/1/rules +_cdbs_class_path ?= /usr/share/cdbs/1/class + +ifndef _cdbs_rules_copyright_check +_cdbs_rules_copyright_check := 1 + +include $(_cdbs_rules_path)/buildcore.mk$(_cdbs_makefile_suffix) + +CDBS_BUILD_DEPENDS := $(CDBS_BUILD_DEPENDS), devscripts (>= 2.10.7) + +# Set to yes to fail on changed/new hints are found +#DEB_COPYRIGHT_CHECK_STRICT := yes + +# Single regular expression for files to include or ignore +DEB_COPYRIGHT_CHECK_REGEX = .* +#DEB_COPYRIGHT_CHECK_IGNORE_REGEX = ^(debian/.*|(.*/)?config\.(guess|sub|rpath)(\..*)?)$ +DEB_COPYRIGHT_CHECK_IGNORE_REGEX = ^debian/(changelog|copyright(|_hints|_newhints))$ + +pre-build:: debian/stamp-copyright-check + +debian/stamp-copyright-check: + @echo 'Scanning upstream source for new/changed copyright notices...' + @echo licensecheck -c '$(DEB_COPYRIGHT_CHECK_REGEX)' -r --copyright -i '$(DEB_COPYRIGHT_CHECK_IGNORE_REGEX)' * \ + "| some-output-filtering..." + +# Perl in shell in make requires extra care: +# * Single-quoting ('...') protects against shell expansion +# * Double-dollar ($$) expands to plain dollar ($) in make + @licensecheck -c '$(DEB_COPYRIGHT_CHECK_REGEX)' -r --copyright -i '$(DEB_COPYRIGHT_CHECK_IGNORE_REGEX)' * \ + | LC_ALL=C perl -e \ + 'print "Format: http://svn.debian.org/wsvn/dep/web/deps/dep5.mdwn?op=file&rev=REVISION\n";'\ + 'print "Name: Untrusted draft - double-check copyrights yourself!\n\n";'\ + '$$n=0; while (<>) {'\ + ' s/[^[:print:]]//g;'\ + ' if (/^([^:\s][^:]+):[\s]+(\S.*?)\s*$$/) {'\ + ' $$files[$$n]{name}=$$1;'\ + ' $$files[$$n]{license}=$$2;'\ + ' };'\ + ' if (/^\s*\[Copyright:\s*(\S.*?)\s*\]/) {'\ + ' $$files[$$n]{copyright}=$$1;'\ + ' };'\ + ' /^$$/ and $$n++;'\ + '};'\ + 'foreach $$file (@files) {'\ + ' $$file->{license} =~ s/\s*\(with incorrect FSF address\)//;'\ + ' $$file->{license} =~ s/\s+\(v([^)]+) or later\)/-$$1+/;'\ + ' $$file->{license} =~ s/\s+\(v([^)]+)\)/-$$1/;'\ + ' $$file->{license} =~ s/\s*(\*No copyright\*)\s*// and $$file->{copyright} = $$1;'\ + ' $$file->{license} =~ s/^\s*(GENERATED FILE)/UNKNOWN ($$1)/;'\ + ' $$file->{license} =~ s/\s+(GENERATED FILE)/ ($$1)/;'\ + ' $$file->{copyright} =~ s/(?<=(\b\d{4}))(?{$$y=$$^N})\s*[,-]\s*((??{$$y+1}))\b/-$$2/g;'\ + ' $$file->{copyright} =~ s/(?<=\b\d{4})\s*-\s*\d{4}(?=\s*-\s*(\d{4})\b)//g;'\ + ' $$file->{copyright} =~ s/\b(\d{4})\s+([\S^\d])/$$1, $$2/g;'\ + ' $$file->{copyright} =~ s/^\W*\s+\/\s+//g;'\ + ' $$file->{copyright} =~ s/\s+\/\s+\W*$$//;'\ + ' $$file->{copyright} =~ s/\s+\/\s+/\n\t/g;'\ + ' $$pattern = "$$file->{license} [$$file->{copyright}]";'\ + ' push @{ $$patternfiles{"$$pattern"} }, $$file->{name};'\ + '};'\ + 'foreach $$pattern ( sort {'\ + ' @{$$patternfiles{$$b}} <=> @{$$patternfiles{$$a}}'\ + ' ||'\ + ' $$a cmp $$b'\ + ' } keys %patternfiles ) {'\ + ' ($$license, $$copyright) = $$pattern =~ /(.*) \[(.*)\]/s;'\ + ' print "Files: ", join("\n\t", sort @{ $$patternfiles{$$pattern} }), "\n";'\ + ' print "Copyright: $$copyright\n";'\ + ' print "License: $$license\n\n";'\ + '};'\ + > debian/copyright_newhints + @patterncount="`cat debian/copyright_newhints | sed 's/^[^:]*://' | LANG=C sort -u | grep . -c -`"; \ + echo "Found $$patterncount different copyright and licensing combinations." + @if [ ! -f debian/copyright_hints ]; then touch debian/copyright_hints; fi + @newstrings=`diff -u debian/copyright_hints debian/copyright_newhints | sed '1,2d' | egrep '^\+' - | sed 's/^\+//'`; \ + if [ -n "$$newstrings" ]; then \ + echo "$(if $(DEB_COPYRIGHT_CHECK_STRICT),ERROR,WARNING): The following new or changed copyright notices discovered:"; \ + echo; \ + echo "$$newstrings"; \ + echo; \ + echo "To fix the situation please do the following:"; \ + echo " 1) Investigate the above changes and update debian/copyright as needed"; \ + echo " 2) Replace debian/copyright_hints with debian/copyright_newhints"; \ + $(if $(DEB_COPYRIGHT_CHECK_STRICT),exit 1,:); \ + else \ + echo 'No new copyright notices found - assuming no news is good news...'; \ + rm -f debian/copyright_newhints; \ + fi + touch $@ + +clean:: + rm -f debian/stamp-copyright-check + +endif --- sugar-read-activity-0.86-78.orig/debian/cdbs/1/rules/upstream-tarball.mk +++ sugar-read-activity-0.86-78/debian/cdbs/1/rules/upstream-tarball.mk @@ -0,0 +1,150 @@ +# -*- mode: makefile; coding: utf-8 -*- +# Copyright © 2007-2008 Jonas Smedegaard +# Description: Convenience rules for dealing with upstream tarballs +# +# 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, or (at +# your option) any later version. +# +# 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, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA +# 02111-1307 USA. + +_cdbs_scripts_path ?= /usr/lib/cdbs +_cdbs_rules_path ?= /usr/share/cdbs/1/rules +_cdbs_class_path ?= /usr/share/cdbs/1/class + +ifndef _cdbs_rules_upstream_tarball +_cdbs_rules_upstream_tarball := 1 + +include $(_cdbs_rules_path)/buildvars.mk$(_cdbs_makefile_suffix) + +CDBS_BUILD_DEPENDS := $(CDBS_BUILD_DEPENDS), cdbs (>= 0.4.39) + +# Prefix for upstream location of all upstream tarballs (mandatory!) +#DEB_UPSTREAM_URL = + +DEB_UPSTREAM_PACKAGE = $(DEB_SOURCE_PACKAGE) +DEB_UPSTREAM_TARBALL_VERSION = $(if $(strip $(DEB_UPSTREAM_REPACKAGE_EXCLUDE)),$(DEB_UPSTREAM_VERSION:$(DEB_UPSTREAM_REPACKAGE_DELIMITER)$(DEB_UPSTREAM_REPACKAGE_TAG)=),$(DEB_UPSTREAM_VERSION)) +DEB_UPSTREAM_TARBALL_EXTENSION = tar.gz +# Checksum to ensure integrity of downloadeds using get-orig-source (optional) +#DEB_UPSTREAM_TARBALL_MD5 = + +DEB_UPSTREAM_WORKDIR = ../tarballs + +# Base filename (without extension) as used in upstream URL +DEB_UPSTREAM_TARBALL_BASENAME = $(DEB_UPSTREAM_PACKAGE)-$(DEB_UPSTREAM_TARBALL_VERSION) + +# Perl regexp to change locally used string into that in upstream URL and srcdir +#DEB_UPSTREAM_TARBALL_BASENAME_MANGLE = + +# Base directory within tarball +DEB_UPSTREAM_TARBALL_SRCDIR = $(cdbs_upstream_tarball_basename) + +# Space-delimited list of directories and files to strip (optional) +#DEB_UPSTREAM_REPACKAGE_EXCLUDE = CVS .cvsignore doc/rfc*.txt doc/draft*.txt +DEB_UPSTREAM_REPACKAGE_TAG = dfsg +DEB_UPSTREAM_REPACKAGE_DELIMITER = ~ + +# TODO: Move this to buildcore.mk +cdbs_findargs-path-or-name = $(if $(findstring /,$(firstword $(1))),-path './$(patsubst ./%,%,$(firstword $(1)))',-name '$(firstword $(1))') $(foreach obj,$(wordlist 2,$(words $(1)),$(1)),-or $(if $(findstring /,$(obj)),-path './$(obj:./%=%)',-name '$(obj)')) + +cdbs_upstream_tarball_basename = $(if $(strip $(DEB_UPSTREAM_TARBALL_BASENAME_MANGLE)),$(shell echo '$(DEB_UPSTREAM_TARBALL_BASENAME)' | perl -pe '$(DEB_UPSTREAM_TARBALL_BASENAME_MANGLE)'),$(DEB_UPSTREAM_TARBALL_BASENAME)) +cdbs_upstream_tarball = $(cdbs_upstream_tarball_basename).$(DEB_UPSTREAM_TARBALL_EXTENSION) +cdbs_upstream_received_tarball = $(DEB_SOURCE_PACKAGE)_$(DEB_UPSTREAM_TARBALL_VERSION).orig.$(if $(findstring $(DEB_UPSTREAM_TARBALL_EXTENSION),tgz),tar.gz,$(DEB_UPSTREAM_TARBALL_EXTENSION)) +cdbs_upstream_local_basename = $(DEB_SOURCE_PACKAGE)_$(DEB_UPSTREAM_TARBALL_VERSION)$(if $(strip $(DEB_UPSTREAM_REPACKAGE_EXCLUDE)),$(DEB_UPSTREAM_REPACKAGE_DELIMITER)$(DEB_UPSTREAM_REPACKAGE_TAG)) +cdbs_upstream_local_srcdir = $(cdbs_upstream_tarball_basename)$(if $(strip $(DEB_UPSTREAM_REPACKAGE_EXCLUDE)),$(DEB_UPSTREAM_REPACKAGE_DELIMITER)$(DEB_UPSTREAM_REPACKAGE_TAG)) + +# # These variables are deprecated +_cdbs_deprecated_vars += DEB_UPSTREAM_TARBALL DEB_UPSTREAM_LOCAL_TARBALL DEB_UPSTREAM_REPACKAGE_TARBALL DEB_UPSTREAM_TARBALL_VERSION_MANGLE +_cdbs_deprecated_vars += DEB_UPSTREAM_REPACKAGE_EXCLUDES +DEB_UPSTREAM_REPACKAGE_EXCLUDE += $(DEB_UPSTREAM_REPACKAGE_EXCLUDES) + +print-version: + @@echo "Debian version: $(DEB_VERSION)" + @@echo "Upstream version: $(DEB_UPSTREAM_TARBALL_VERSION)" + +get-orig-source: + @@dh_testdir + @@mkdir -p "$(DEB_UPSTREAM_WORKDIR)" + + @if [ ! -s "$(DEB_UPSTREAM_WORKDIR)/$(cdbs_upstream_received_tarball)" ] ; then \ + if [ -f "$(DEB_UPSTREAM_WORKDIR)/$(cdbs_upstream_received_tarball)" ] ; then \ + rm "$(DEB_UPSTREAM_WORKDIR)/$(cdbs_upstream_received_tarball)" ; \ + fi ; \ + echo "Downloading $(cdbs_upstream_received_tarball) from $(DEB_UPSTREAM_URL)/$(cdbs_upstream_tarball) ..." ; \ + wget -nv -T10 -t3 -O "$(DEB_UPSTREAM_WORKDIR)/$(cdbs_upstream_received_tarball)" "$(DEB_UPSTREAM_URL)/$(cdbs_upstream_tarball)" ; \ + else \ + echo "Upstream source tarball have been already downloaded: $(DEB_UPSTREAM_WORKDIR)/$(cdbs_upstream_received_tarball)" ; \ + fi + + @md5current=`md5sum "$(DEB_UPSTREAM_WORKDIR)/$(cdbs_upstream_received_tarball)" | sed -e 's/ .*//'`; \ + if [ -n "$(DEB_UPSTREAM_TARBALL_MD5)" ] ; then \ + if [ "$$md5current" != "$(DEB_UPSTREAM_TARBALL_MD5)" ] ; then \ + echo "Expecting upstream tarball md5sum $(DEB_UPSTREAM_TARBALL_MD5), but $$md5current found" ; \ + echo "Upstream tarball md5sum is NOT trusted! Possible upstream tarball forge!" ; \ + echo "Purging downloaded file. Try new download." ; \ + rm -f "$(DEB_UPSTREAM_WORKDIR)/$(cdbs_upstream_received_tarball)" ; \ + false ; \ + else \ + echo "Upstream tarball is trusted!" ; \ + fi; \ + else \ + echo "Upstream tarball NOT trusted (current md5sum is $$md5current)!" ; \ + fi + +# TODO: Rewrite using make variables like cdbs_upstream_unpack_cmd and +# DEB_UPSTREAM_SUPPORTED_COMPRESSIONS (recent dpkg supports bz2) +# TODO: Add .orig suffix to top folder inside tarball when only +# recompressing (when $uncompress set and ...REPACKAGE_EXCLUDE unset) + @untar="tar -x -C"; \ + case "$(cdbs_upstream_received_tarball)" in \ + *.tar.gz) unpack="gunzip -c";; \ + *.tar.bz2) unpack="bunzip2 -c"; uncompress="bunzip2";; \ + *.tar.Z) unpack="uncompress -c"; uncompress="uncompress";; \ + *.zip) unpack="unzip -q"; uncompress="false"; untar="-d"; nopipe="true";; \ + *.tar) unpack="cat"; uncompress="true";; \ + *) echo "Unknown extension for upstream tarball $(cdbs_upstream_received_tarball)"; false;; \ + esac && \ + if [ -n "$(strip $(DEB_UPSTREAM_REPACKAGE_EXCLUDE))" ] || [ "$$uncompress" = "false" ]; then \ + echo "Repackaging tarball ..." && \ + mkdir -p "$(DEB_UPSTREAM_WORKDIR)/$(DEB_UPSTREAM_REPACKAGE_TAG)" && \ + if [ -n "$$nopipe" ]; then \ + $$unpack "$(DEB_UPSTREAM_WORKDIR)/$(cdbs_upstream_received_tarball)" \ + $$untar "$(DEB_UPSTREAM_WORKDIR)/$(DEB_UPSTREAM_REPACKAGE_TAG)" $(patsubst %,--exclude='%',$(DEB_UPSTREAM_REPACKAGE_EXCLUDE)); \ + else \ + $$unpack "$(DEB_UPSTREAM_WORKDIR)/$(cdbs_upstream_received_tarball)" \ + | $$untar "$(DEB_UPSTREAM_WORKDIR)/$(DEB_UPSTREAM_REPACKAGE_TAG)" $(patsubst %,--exclude='%',$(DEB_UPSTREAM_REPACKAGE_EXCLUDE)); \ + fi && \ + if [ "$(DEB_UPSTREAM_TARBALL_SRCDIR)" != "$(cdbs_upstream_local_srcdir)" ]; then \ + mv -T "$(DEB_UPSTREAM_WORKDIR)/$(DEB_UPSTREAM_REPACKAGE_TAG)/$(DEB_UPSTREAM_TARBALL_SRCDIR)" "$(DEB_UPSTREAM_WORKDIR)/$(DEB_UPSTREAM_REPACKAGE_TAG)/$(cdbs_upstream_local_srcdir)"; \ + fi && \ + GZIP=-9 tar -b1 -czf "$(DEB_UPSTREAM_WORKDIR)/$(cdbs_upstream_local_basename).orig.tar.gz" -C "$(DEB_UPSTREAM_WORKDIR)/$(DEB_UPSTREAM_REPACKAGE_TAG)" "$(cdbs_upstream_local_srcdir)" && \ + echo "Cleaning up" && \ + rm -rf "$(DEB_UPSTREAM_WORKDIR)/$(DEB_UPSTREAM_REPACKAGE_TAG)"; \ + elif [ -n "$$uncompress" ]; then \ + echo "Recompressing tarball ..." && \ + $$uncompress "$(DEB_UPSTREAM_WORKDIR)/$(cdbs_upstream_received_tarball)"; \ + gzip -9 "$(DEB_UPSTREAM_WORKDIR)/$(cdbs_upstream_local_basename).orig.tar"; \ + fi + +fail-source-not-repackaged: + @if find . $(call cdbs_findargs-path-or-name,$(DEB_UPSTREAM_REPACKAGE_EXCLUDE)) | grep '.*'; then \ + echo; \ + echo 'ERROR: Source contains the files/paths listed above'; \ + echo ' which was intended to not be distributed with the source.'; \ + echo ' Please repackage source with these items stripped!'; \ + echo ' (get-orig-source target can automate this - see README.source)'; \ + exit 1; \ + fi + +DEB_PHONY_RULES += print-version get-orig-source fail-source-not-repackaged + +endif --- sugar-read-activity-0.86-78.orig/debian/cdbs/1/rules/package-relations.mk +++ sugar-read-activity-0.86-78/debian/cdbs/1/rules/package-relations.mk @@ -0,0 +1,66 @@ +# -*- mode: makefile; coding: utf-8 -*- +# Copyright © 2008 Jonas Smedegaard +# Description: Resolve, cleanup and apply package relationships +# +# 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, or (at +# your option) any later version. +# +# 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, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA +# 02111-1307 USA. + +_cdbs_scripts_path ?= /usr/lib/cdbs +_cdbs_rules_path ?= /usr/share/cdbs/1/rules +_cdbs_class_path ?= /usr/share/cdbs/1/class + +ifndef _cdbs_rules_package_relations +_cdbs_rules_package_relations = 1 + +include $(_cdbs_rules_path)/buildcore.mk$(_cdbs_makefile_suffix) + +# Merge build-dependencies on same packages +# TODO: rewrite (in perl, probably) to be more generic +CDBS_BUILD_DEPENDS := $(shell echo '$(CDBS_BUILD_DEPENDS)' | sed -e '/\bcdbs (>= 0.4.43)/ s/\bcdbs *\(,\|(>= \(0.4.23-1.1\|0.4.27\|0.4.39\))\)/, /g') +CDBS_BUILD_DEPENDS := $(shell echo '$(CDBS_BUILD_DEPENDS)' | sed -e '/\bcdbs (>= 0.4.39)/ s/\bcdbs *\(,\|(>= \(0.4.23-1.1\|0.4.27\))\)/, /g') +CDBS_BUILD_DEPENDS := $(shell echo '$(CDBS_BUILD_DEPENDS)' | sed -e '/\bcdbs (>= 0.4.27)/ s/\bcdbs *\(,\|(>= \(0.4.23-1.1\))\)/, /g') +CDBS_BUILD_DEPENDS := $(shell echo '$(CDBS_BUILD_DEPENDS)' | sed -e '/\bdebhelper (>= 7.0.1)/ s/\bdebhelper *\(,\|(>= \(4.1.60\|4.2.0\|4.2.21\|4.2.28\|5\|5.0.37.2\|5.0.44\|6\))\)/, /g') +CDBS_BUILD_DEPENDS := $(shell echo '$(CDBS_BUILD_DEPENDS)' | sed -e '/\bdebhelper (>= 6)/ s/\bdebhelper *\(,\|(>= \(4.1.60\|4.2.0\|4.2.21\|4.2.28\|5\|5.0.37.2\|5.0.44\))\)/, /g') +CDBS_BUILD_DEPENDS := $(shell echo '$(CDBS_BUILD_DEPENDS)' | sed -e '/\bdebhelper (>= 5.0.44)/ s/\bdebhelper *\(,\|(>= \(4.1.60\|4.2.0\|4.2.21\|4.2.28\|5\|5.0.37.2\))\)/, /g') +CDBS_BUILD_DEPENDS := $(shell echo '$(CDBS_BUILD_DEPENDS)' | sed -e '/\bdebhelper (>= 5.0.37.2)/ s/\bdebhelper *\(,\|(>= \(4.1.60\|4.2.0\|4.2.21\|4.2.28\|5\))\)/, /g') +CDBS_BUILD_DEPENDS := $(shell echo '$(CDBS_BUILD_DEPENDS)' | sed -e '/\bdebhelper (>= 5)/ s/\bdebhelper *\(,\|(>= \(4.1.60\|4.2.0\|4.2.21\|4.2.28\))\)/, /g') +CDBS_BUILD_DEPENDS := $(shell echo '$(CDBS_BUILD_DEPENDS)' | sed -e '/\bdebhelper (>= 4.2.28)/ s/\bdebhelper *\(,\|(>= \(4.1.60\|4.2.0\|4.2.21\))\)/, /g') +CDBS_BUILD_DEPENDS := $(shell echo '$(CDBS_BUILD_DEPENDS)' | sed -e '/\bdebhelper (>= 4.2.21)/ s/\bdebhelper *\(,\|(>= \(4.1.60\|4.2.0\))\)/, /g') +CDBS_BUILD_DEPENDS := $(shell echo '$(CDBS_BUILD_DEPENDS)' | sed -e '/\bdebhelper (>= 4.2.0)/ s/\bdebhelper *\(,\|(>= \(4.1.60\))\)/, /g') + +# TODO: Move these to buildcore.mk +cdbs_curvar = $(or $($(1)_$(cdbs_curpkg)),$($1)) +cdbs_squash_commas = $(shell echo '$1' | sed -e 's/ *,[ ,]*/, /g' -e 's/^[ ,]*//' -e 's/[ ,]*$$//') + +# Cleanup superfluous commas and whitespace +CDBS_BUILD_DEPENDS := $(call cdbs_squash_commas,$(CDBS_BUILD_DEPENDS)) + +comma = , +cdbs_all_cur_squash_commas = $(call cdbs_squash_commas,$($(1)_ALL)$(comma) $(call cdbs_curvar,$1)) + +# Apply CDBS-declared dependencies to binary packages +$(patsubst %,binary-predeb/%,$(DEB_PACKAGES)) :: binary-predeb/%: + @echo 'Adding cdbs dependencies to debian/$(cdbs_curpkg).substvars' + @echo 'cdbs:Depends=$(call cdbs_all_cur_squash_commas,CDBS_DEPENDS)' >> debian/$(cdbs_curpkg).substvars + @echo 'cdbs:Pre-Depends=$(call cdbs_all_cur_squash_commas,CDBS_PREDEPENDS)' >> debian/$(cdbs_curpkg).substvars + @echo 'cdbs:Recommends=$(call cdbs_all_cur_squash_commas,CDBS_RECOMMENDS)' >> debian/$(cdbs_curpkg).substvars + @echo 'cdbs:Suggests=$(call cdbs_all_cur_squash_commas,CDBS_SUGGESTS)' >> debian/$(cdbs_curpkg).substvars + @echo 'cdbs:Breaks=$(call cdbs_all_cur_squash_commas,CDBS_BREAKS)' >> debian/$(cdbs_curpkg).substvars + @echo 'cdbs:Provides=$(call cdbs_all_cur_squash_commas,CDBS_PROVIDES)' >> debian/$(cdbs_curpkg).substvars + @echo 'cdbs:Replaces=$(call cdbs_all_cur_squash_commas,CDBS_REPLACES)' >> debian/$(cdbs_curpkg).substvars + @echo 'cdbs:Conflicts=$(call cdbs_all_cur_squash_commas,CDBS_CONFLICTS)' >> debian/$(cdbs_curpkg).substvars + @echo 'cdbs:Enhances=$(call cdbs_all_cur_squash_commas,CDBS_ENHANCES)' >> debian/$(cdbs_curpkg).substvars + +endif --- sugar-read-activity-0.86-78.orig/debian/patches/series +++ sugar-read-activity-0.86-78/debian/patches/series @@ -0,0 +1,2 @@ +1001_use_plain_dejavu.patch +1002_include_python26_zipfile.patch --- sugar-read-activity-0.86-78.orig/debian/patches/1002_include_python26_zipfile.patch +++ sugar-read-activity-0.86-78/debian/patches/1002_include_python26_zipfile.patch @@ -0,0 +1,1411 @@ +Origin: http://svn.python.org/projects/python/branches/release26-maint/Lib/zipfile.py +Date: 2009-11-30 +--- a/epubview/zipfile.py ++++ b/epubview/zipfile.py +@@ -0,0 +1,1406 @@ ++""" ++Read and write ZIP files. ++""" ++import struct, os, time, sys, shutil ++import binascii, cStringIO, stat ++ ++try: ++ import zlib # We may need its compression method ++ crc32 = zlib.crc32 ++except ImportError: ++ zlib = None ++ crc32 = binascii.crc32 ++ ++__all__ = ["BadZipfile", "error", "ZIP_STORED", "ZIP_DEFLATED", "is_zipfile", ++ "ZipInfo", "ZipFile", "PyZipFile", "LargeZipFile" ] ++ ++class BadZipfile(Exception): ++ pass ++ ++ ++class LargeZipFile(Exception): ++ """ ++ Raised when writing a zipfile, the zipfile requires ZIP64 extensions ++ and those extensions are disabled. ++ """ ++ ++error = BadZipfile # The exception raised by this module ++ ++ZIP64_LIMIT = (1 << 31) - 1 ++ZIP_FILECOUNT_LIMIT = 1 << 16 ++ZIP_MAX_COMMENT = (1 << 16) - 1 ++ ++# constants for Zip file compression methods ++ZIP_STORED = 0 ++ZIP_DEFLATED = 8 ++# Other ZIP compression methods not supported ++ ++# Below are some formats and associated data for reading/writing headers using ++# the struct module. The names and structures of headers/records are those used ++# in the PKWARE description of the ZIP file format: ++# http://www.pkware.com/documents/casestudies/APPNOTE.TXT ++# (URL valid as of January 2008) ++ ++# The "end of central directory" structure, magic number, size, and indices ++# (section V.I in the format document) ++structEndArchive = "<4s4H2LH" ++stringEndArchive = "PK\005\006" ++sizeEndCentDir = struct.calcsize(structEndArchive) ++ ++_ECD_SIGNATURE = 0 ++_ECD_DISK_NUMBER = 1 ++_ECD_DISK_START = 2 ++_ECD_ENTRIES_THIS_DISK = 3 ++_ECD_ENTRIES_TOTAL = 4 ++_ECD_SIZE = 5 ++_ECD_OFFSET = 6 ++_ECD_COMMENT_SIZE = 7 ++# These last two indices are not part of the structure as defined in the ++# spec, but they are used internally by this module as a convenience ++_ECD_COMMENT = 8 ++_ECD_LOCATION = 9 ++ ++# The "central directory" structure, magic number, size, and indices ++# of entries in the structure (section V.F in the format document) ++structCentralDir = "<4s4B4HL2L5H2L" ++stringCentralDir = "PK\001\002" ++sizeCentralDir = struct.calcsize(structCentralDir) ++ ++# indexes of entries in the central directory structure ++_CD_SIGNATURE = 0 ++_CD_CREATE_VERSION = 1 ++_CD_CREATE_SYSTEM = 2 ++_CD_EXTRACT_VERSION = 3 ++_CD_EXTRACT_SYSTEM = 4 ++_CD_FLAG_BITS = 5 ++_CD_COMPRESS_TYPE = 6 ++_CD_TIME = 7 ++_CD_DATE = 8 ++_CD_CRC = 9 ++_CD_COMPRESSED_SIZE = 10 ++_CD_UNCOMPRESSED_SIZE = 11 ++_CD_FILENAME_LENGTH = 12 ++_CD_EXTRA_FIELD_LENGTH = 13 ++_CD_COMMENT_LENGTH = 14 ++_CD_DISK_NUMBER_START = 15 ++_CD_INTERNAL_FILE_ATTRIBUTES = 16 ++_CD_EXTERNAL_FILE_ATTRIBUTES = 17 ++_CD_LOCAL_HEADER_OFFSET = 18 ++ ++# The "local file header" structure, magic number, size, and indices ++# (section V.A in the format document) ++structFileHeader = "<4s2B4HL2L2H" ++stringFileHeader = "PK\003\004" ++sizeFileHeader = struct.calcsize(structFileHeader) ++ ++_FH_SIGNATURE = 0 ++_FH_EXTRACT_VERSION = 1 ++_FH_EXTRACT_SYSTEM = 2 ++_FH_GENERAL_PURPOSE_FLAG_BITS = 3 ++_FH_COMPRESSION_METHOD = 4 ++_FH_LAST_MOD_TIME = 5 ++_FH_LAST_MOD_DATE = 6 ++_FH_CRC = 7 ++_FH_COMPRESSED_SIZE = 8 ++_FH_UNCOMPRESSED_SIZE = 9 ++_FH_FILENAME_LENGTH = 10 ++_FH_EXTRA_FIELD_LENGTH = 11 ++ ++# The "Zip64 end of central directory locator" structure, magic number, and size ++structEndArchive64Locator = "<4sLQL" ++stringEndArchive64Locator = "PK\x06\x07" ++sizeEndCentDir64Locator = struct.calcsize(structEndArchive64Locator) ++ ++# The "Zip64 end of central directory" record, magic number, size, and indices ++# (section V.G in the format document) ++structEndArchive64 = "<4sQ2H2L4Q" ++stringEndArchive64 = "PK\x06\x06" ++sizeEndCentDir64 = struct.calcsize(structEndArchive64) ++ ++_CD64_SIGNATURE = 0 ++_CD64_DIRECTORY_RECSIZE = 1 ++_CD64_CREATE_VERSION = 2 ++_CD64_EXTRACT_VERSION = 3 ++_CD64_DISK_NUMBER = 4 ++_CD64_DISK_NUMBER_START = 5 ++_CD64_NUMBER_ENTRIES_THIS_DISK = 6 ++_CD64_NUMBER_ENTRIES_TOTAL = 7 ++_CD64_DIRECTORY_SIZE = 8 ++_CD64_OFFSET_START_CENTDIR = 9 ++ ++def is_zipfile(filename): ++ """Quickly see if file is a ZIP file by checking the magic number.""" ++ try: ++ fpin = open(filename, "rb") ++ endrec = _EndRecData(fpin) ++ fpin.close() ++ if endrec: ++ return True # file has correct magic number ++ except IOError: ++ pass ++ return False ++ ++def _EndRecData64(fpin, offset, endrec): ++ """ ++ Read the ZIP64 end-of-archive records and use that to update endrec ++ """ ++ fpin.seek(offset - sizeEndCentDir64Locator, 2) ++ data = fpin.read(sizeEndCentDir64Locator) ++ sig, diskno, reloff, disks = struct.unpack(structEndArchive64Locator, data) ++ if sig != stringEndArchive64Locator: ++ return endrec ++ ++ if diskno != 0 or disks != 1: ++ raise BadZipfile("zipfiles that span multiple disks are not supported") ++ ++ # Assume no 'zip64 extensible data' ++ fpin.seek(offset - sizeEndCentDir64Locator - sizeEndCentDir64, 2) ++ data = fpin.read(sizeEndCentDir64) ++ sig, sz, create_version, read_version, disk_num, disk_dir, \ ++ dircount, dircount2, dirsize, diroffset = \ ++ struct.unpack(structEndArchive64, data) ++ if sig != stringEndArchive64: ++ return endrec ++ ++ # Update the original endrec using data from the ZIP64 record ++ endrec[_ECD_SIGNATURE] = sig ++ endrec[_ECD_DISK_NUMBER] = disk_num ++ endrec[_ECD_DISK_START] = disk_dir ++ endrec[_ECD_ENTRIES_THIS_DISK] = dircount ++ endrec[_ECD_ENTRIES_TOTAL] = dircount2 ++ endrec[_ECD_SIZE] = dirsize ++ endrec[_ECD_OFFSET] = diroffset ++ return endrec ++ ++ ++def _EndRecData(fpin): ++ """Return data from the "End of Central Directory" record, or None. ++ ++ The data is a list of the nine items in the ZIP "End of central dir" ++ record followed by a tenth item, the file seek offset of this record.""" ++ ++ # Determine file size ++ fpin.seek(0, 2) ++ filesize = fpin.tell() ++ ++ # Check to see if this is ZIP file with no archive comment (the ++ # "end of central directory" structure should be the last item in the ++ # file if this is the case). ++ fpin.seek(-sizeEndCentDir, 2) ++ data = fpin.read() ++ if data[0:4] == stringEndArchive and data[-2:] == "\000\000": ++ # the signature is correct and there's no comment, unpack structure ++ endrec = struct.unpack(structEndArchive, data) ++ endrec=list(endrec) ++ ++ # Append a blank comment and record start offset ++ endrec.append("") ++ endrec.append(filesize - sizeEndCentDir) ++ ++ # Try to read the "Zip64 end of central directory" structure ++ return _EndRecData64(fpin, -sizeEndCentDir, endrec) ++ ++ # Either this is not a ZIP file, or it is a ZIP file with an archive ++ # comment. Search the end of the file for the "end of central directory" ++ # record signature. The comment is the last item in the ZIP file and may be ++ # up to 64K long. It is assumed that the "end of central directory" magic ++ # number does not appear in the comment. ++ maxCommentStart = max(filesize - (1 << 16) - sizeEndCentDir, 0) ++ fpin.seek(maxCommentStart, 0) ++ data = fpin.read() ++ start = data.rfind(stringEndArchive) ++ if start >= 0: ++ # found the magic number; attempt to unpack and interpret ++ recData = data[start:start+sizeEndCentDir] ++ endrec = list(struct.unpack(structEndArchive, recData)) ++ comment = data[start+sizeEndCentDir:] ++ # check that comment length is correct ++ if endrec[_ECD_COMMENT_SIZE] == len(comment): ++ # Append the archive comment and start offset ++ endrec.append(comment) ++ endrec.append(maxCommentStart + start) ++ ++ # Try to read the "Zip64 end of central directory" structure ++ return _EndRecData64(fpin, maxCommentStart + start - filesize, ++ endrec) ++ ++ # Unable to find a valid end of central directory structure ++ return ++ ++ ++class ZipInfo (object): ++ """Class with attributes describing each file in the ZIP archive.""" ++ ++ __slots__ = ( ++ 'orig_filename', ++ 'filename', ++ 'date_time', ++ 'compress_type', ++ 'comment', ++ 'extra', ++ 'create_system', ++ 'create_version', ++ 'extract_version', ++ 'reserved', ++ 'flag_bits', ++ 'volume', ++ 'internal_attr', ++ 'external_attr', ++ 'header_offset', ++ 'CRC', ++ 'compress_size', ++ 'file_size', ++ '_raw_time', ++ ) ++ ++ def __init__(self, filename="NoName", date_time=(1980,1,1,0,0,0)): ++ self.orig_filename = filename # Original file name in archive ++ ++ # Terminate the file name at the first null byte. Null bytes in file ++ # names are used as tricks by viruses in archives. ++ null_byte = filename.find(chr(0)) ++ if null_byte >= 0: ++ filename = filename[0:null_byte] ++ # This is used to ensure paths in generated ZIP files always use ++ # forward slashes as the directory separator, as required by the ++ # ZIP format specification. ++ if os.sep != "/" and os.sep in filename: ++ filename = filename.replace(os.sep, "/") ++ ++ self.filename = filename # Normalized file name ++ self.date_time = date_time # year, month, day, hour, min, sec ++ # Standard values: ++ self.compress_type = ZIP_STORED # Type of compression for the file ++ self.comment = "" # Comment for each file ++ self.extra = "" # ZIP extra data ++ if sys.platform == 'win32': ++ self.create_system = 0 # System which created ZIP archive ++ else: ++ # Assume everything else is unix-y ++ self.create_system = 3 # System which created ZIP archive ++ self.create_version = 20 # Version which created ZIP archive ++ self.extract_version = 20 # Version needed to extract archive ++ self.reserved = 0 # Must be zero ++ self.flag_bits = 0 # ZIP flag bits ++ self.volume = 0 # Volume number of file header ++ self.internal_attr = 0 # Internal attributes ++ self.external_attr = 0 # External file attributes ++ # Other attributes are set by class ZipFile: ++ # header_offset Byte offset to the file header ++ # CRC CRC-32 of the uncompressed file ++ # compress_size Size of the compressed file ++ # file_size Size of the uncompressed file ++ ++ def FileHeader(self): ++ """Return the per-file header as a string.""" ++ dt = self.date_time ++ dosdate = (dt[0] - 1980) << 9 | dt[1] << 5 | dt[2] ++ dostime = dt[3] << 11 | dt[4] << 5 | (dt[5] // 2) ++ if self.flag_bits & 0x08: ++ # Set these to zero because we write them after the file data ++ CRC = compress_size = file_size = 0 ++ else: ++ CRC = self.CRC ++ compress_size = self.compress_size ++ file_size = self.file_size ++ ++ extra = self.extra ++ ++ if file_size > ZIP64_LIMIT or compress_size > ZIP64_LIMIT: ++ # File is larger than what fits into a 4 byte integer, ++ # fall back to the ZIP64 extension ++ fmt = '= 24: ++ counts = unpack('> 1) & 0x7FFFFFFF) ^ poly ++ else: ++ crc = ((crc >> 1) & 0x7FFFFFFF) ++ table[i] = crc ++ return table ++ crctable = _GenerateCRCTable() ++ ++ def _crc32(self, ch, crc): ++ """Compute the CRC32 primitive on one byte.""" ++ return ((crc >> 8) & 0xffffff) ^ self.crctable[(crc ^ ord(ch)) & 0xff] ++ ++ def __init__(self, pwd): ++ self.key0 = 305419896 ++ self.key1 = 591751049 ++ self.key2 = 878082192 ++ for p in pwd: ++ self._UpdateKeys(p) ++ ++ def _UpdateKeys(self, c): ++ self.key0 = self._crc32(c, self.key0) ++ self.key1 = (self.key1 + (self.key0 & 255)) & 4294967295 ++ self.key1 = (self.key1 * 134775813 + 1) & 4294967295 ++ self.key2 = self._crc32(chr((self.key1 >> 24) & 255), self.key2) ++ ++ def __call__(self, c): ++ """Decrypt a single character.""" ++ c = ord(c) ++ k = self.key2 | 2 ++ c = c ^ (((k * (k^1)) >> 8) & 255) ++ c = chr(c) ++ self._UpdateKeys(c) ++ return c ++ ++class ZipExtFile: ++ """File-like object for reading an archive member. ++ Is returned by ZipFile.open(). ++ """ ++ ++ def __init__(self, fileobj, zipinfo, decrypt=None): ++ self.fileobj = fileobj ++ self.decrypter = decrypt ++ self.bytes_read = 0L ++ self.rawbuffer = '' ++ self.readbuffer = '' ++ self.linebuffer = '' ++ self.eof = False ++ self.univ_newlines = False ++ self.nlSeps = ("\n", ) ++ self.lastdiscard = '' ++ ++ self.compress_type = zipinfo.compress_type ++ self.compress_size = zipinfo.compress_size ++ ++ self.closed = False ++ self.mode = "r" ++ self.name = zipinfo.filename ++ ++ # read from compressed files in 64k blocks ++ self.compreadsize = 64*1024 ++ if self.compress_type == ZIP_DEFLATED: ++ self.dc = zlib.decompressobj(-15) ++ ++ def set_univ_newlines(self, univ_newlines): ++ self.univ_newlines = univ_newlines ++ ++ # pick line separator char(s) based on universal newlines flag ++ self.nlSeps = ("\n", ) ++ if self.univ_newlines: ++ self.nlSeps = ("\r\n", "\r", "\n") ++ ++ def __iter__(self): ++ return self ++ ++ def next(self): ++ nextline = self.readline() ++ if not nextline: ++ raise StopIteration() ++ ++ return nextline ++ ++ def close(self): ++ self.closed = True ++ ++ def _checkfornewline(self): ++ nl, nllen = -1, -1 ++ if self.linebuffer: ++ # ugly check for cases where half of an \r\n pair was ++ # read on the last pass, and the \r was discarded. In this ++ # case we just throw away the \n at the start of the buffer. ++ if (self.lastdiscard, self.linebuffer[0]) == ('\r','\n'): ++ self.linebuffer = self.linebuffer[1:] ++ ++ for sep in self.nlSeps: ++ nl = self.linebuffer.find(sep) ++ if nl >= 0: ++ nllen = len(sep) ++ return nl, nllen ++ ++ return nl, nllen ++ ++ def readline(self, size = -1): ++ """Read a line with approx. size. If size is negative, ++ read a whole line. ++ """ ++ if size < 0: ++ size = sys.maxint ++ elif size == 0: ++ return '' ++ ++ # check for a newline already in buffer ++ nl, nllen = self._checkfornewline() ++ ++ if nl >= 0: ++ # the next line was already in the buffer ++ nl = min(nl, size) ++ else: ++ # no line break in buffer - try to read more ++ size -= len(self.linebuffer) ++ while nl < 0 and size > 0: ++ buf = self.read(min(size, 100)) ++ if not buf: ++ break ++ self.linebuffer += buf ++ size -= len(buf) ++ ++ # check for a newline in buffer ++ nl, nllen = self._checkfornewline() ++ ++ # we either ran out of bytes in the file, or ++ # met the specified size limit without finding a newline, ++ # so return current buffer ++ if nl < 0: ++ s = self.linebuffer ++ self.linebuffer = '' ++ return s ++ ++ buf = self.linebuffer[:nl] ++ self.lastdiscard = self.linebuffer[nl:nl + nllen] ++ self.linebuffer = self.linebuffer[nl + nllen:] ++ ++ # line is always returned with \n as newline char (except possibly ++ # for a final incomplete line in the file, which is handled above). ++ return buf + "\n" ++ ++ def readlines(self, sizehint = -1): ++ """Return a list with all (following) lines. The sizehint parameter ++ is ignored in this implementation. ++ """ ++ result = [] ++ while True: ++ line = self.readline() ++ if not line: break ++ result.append(line) ++ return result ++ ++ def read(self, size = None): ++ # act like file() obj and return empty string if size is 0 ++ if size == 0: ++ return '' ++ ++ # determine read size ++ bytesToRead = self.compress_size - self.bytes_read ++ ++ # adjust read size for encrypted files since the first 12 bytes ++ # are for the encryption/password information ++ if self.decrypter is not None: ++ bytesToRead -= 12 ++ ++ if size is not None and size >= 0: ++ if self.compress_type == ZIP_STORED: ++ lr = len(self.readbuffer) ++ bytesToRead = min(bytesToRead, size - lr) ++ elif self.compress_type == ZIP_DEFLATED: ++ if len(self.readbuffer) > size: ++ # the user has requested fewer bytes than we've already ++ # pulled through the decompressor; don't read any more ++ bytesToRead = 0 ++ else: ++ # user will use up the buffer, so read some more ++ lr = len(self.rawbuffer) ++ bytesToRead = min(bytesToRead, self.compreadsize - lr) ++ ++ # avoid reading past end of file contents ++ if bytesToRead + self.bytes_read > self.compress_size: ++ bytesToRead = self.compress_size - self.bytes_read ++ ++ # try to read from file (if necessary) ++ if bytesToRead > 0: ++ bytes = self.fileobj.read(bytesToRead) ++ self.bytes_read += len(bytes) ++ self.rawbuffer += bytes ++ ++ # handle contents of raw buffer ++ if self.rawbuffer: ++ newdata = self.rawbuffer ++ self.rawbuffer = '' ++ ++ # decrypt new data if we were given an object to handle that ++ if newdata and self.decrypter is not None: ++ newdata = ''.join(map(self.decrypter, newdata)) ++ ++ # decompress newly read data if necessary ++ if newdata and self.compress_type == ZIP_DEFLATED: ++ newdata = self.dc.decompress(newdata) ++ self.rawbuffer = self.dc.unconsumed_tail ++ if self.eof and len(self.rawbuffer) == 0: ++ # we're out of raw bytes (both from the file and ++ # the local buffer); flush just to make sure the ++ # decompressor is done ++ newdata += self.dc.flush() ++ # prevent decompressor from being used again ++ self.dc = None ++ ++ self.readbuffer += newdata ++ ++ ++ # return what the user asked for ++ if size is None or len(self.readbuffer) <= size: ++ bytes = self.readbuffer ++ self.readbuffer = '' ++ else: ++ bytes = self.readbuffer[:size] ++ self.readbuffer = self.readbuffer[size:] ++ ++ return bytes ++ ++ ++class ZipFile: ++ """ Class with methods to open, read, write, close, list zip files. ++ ++ z = ZipFile(file, mode="r", compression=ZIP_STORED, allowZip64=False) ++ ++ file: Either the path to the file, or a file-like object. ++ If it is a path, the file will be opened and closed by ZipFile. ++ mode: The mode can be either read "r", write "w" or append "a". ++ compression: ZIP_STORED (no compression) or ZIP_DEFLATED (requires zlib). ++ allowZip64: if True ZipFile will create files with ZIP64 extensions when ++ needed, otherwise it will raise an exception when this would ++ be necessary. ++ ++ """ ++ ++ fp = None # Set here since __del__ checks it ++ ++ def __init__(self, file, mode="r", compression=ZIP_STORED, allowZip64=False): ++ """Open the ZIP file with mode read "r", write "w" or append "a".""" ++ if mode not in ("r", "w", "a"): ++ raise RuntimeError('ZipFile() requires mode "r", "w", or "a"') ++ ++ if compression == ZIP_STORED: ++ pass ++ elif compression == ZIP_DEFLATED: ++ if not zlib: ++ raise RuntimeError,\ ++ "Compression requires the (missing) zlib module" ++ else: ++ raise RuntimeError, "That compression method is not supported" ++ ++ self._allowZip64 = allowZip64 ++ self._didModify = False ++ self.debug = 0 # Level of printing: 0 through 3 ++ self.NameToInfo = {} # Find file info given name ++ self.filelist = [] # List of ZipInfo instances for archive ++ self.compression = compression # Method of compression ++ self.mode = key = mode.replace('b', '')[0] ++ self.pwd = None ++ self.comment = '' ++ ++ # Check if we were passed a file-like object ++ if isinstance(file, basestring): ++ self._filePassed = 0 ++ self.filename = file ++ modeDict = {'r' : 'rb', 'w': 'wb', 'a' : 'r+b'} ++ try: ++ self.fp = open(file, modeDict[mode]) ++ except IOError: ++ if mode == 'a': ++ mode = key = 'w' ++ self.fp = open(file, modeDict[mode]) ++ else: ++ raise ++ else: ++ self._filePassed = 1 ++ self.fp = file ++ self.filename = getattr(file, 'name', None) ++ ++ if key == 'r': ++ self._GetContents() ++ elif key == 'w': ++ pass ++ elif key == 'a': ++ try: # See if file is a zip file ++ self._RealGetContents() ++ # seek to start of directory and overwrite ++ self.fp.seek(self.start_dir, 0) ++ except BadZipfile: # file is not a zip file, just append ++ self.fp.seek(0, 2) ++ else: ++ if not self._filePassed: ++ self.fp.close() ++ self.fp = None ++ raise RuntimeError, 'Mode must be "r", "w" or "a"' ++ ++ def _GetContents(self): ++ """Read the directory, making sure we close the file if the format ++ is bad.""" ++ try: ++ self._RealGetContents() ++ except BadZipfile: ++ if not self._filePassed: ++ self.fp.close() ++ self.fp = None ++ raise ++ ++ def _RealGetContents(self): ++ """Read in the table of contents for the ZIP file.""" ++ fp = self.fp ++ endrec = _EndRecData(fp) ++ if not endrec: ++ raise BadZipfile, "File is not a zip file" ++ if self.debug > 1: ++ print endrec ++ size_cd = endrec[_ECD_SIZE] # bytes in central directory ++ offset_cd = endrec[_ECD_OFFSET] # offset of central directory ++ self.comment = endrec[_ECD_COMMENT] # archive comment ++ ++ # "concat" is zero, unless zip was concatenated to another file ++ concat = endrec[_ECD_LOCATION] - size_cd - offset_cd ++ if endrec[_ECD_SIGNATURE] == stringEndArchive64: ++ # If Zip64 extension structures are present, account for them ++ concat -= (sizeEndCentDir64 + sizeEndCentDir64Locator) ++ ++ if self.debug > 2: ++ inferred = concat + offset_cd ++ print "given, inferred, offset", offset_cd, inferred, concat ++ # self.start_dir: Position of start of central directory ++ self.start_dir = offset_cd + concat ++ fp.seek(self.start_dir, 0) ++ data = fp.read(size_cd) ++ fp = cStringIO.StringIO(data) ++ total = 0 ++ while total < size_cd: ++ centdir = fp.read(sizeCentralDir) ++ if centdir[0:4] != stringCentralDir: ++ raise BadZipfile, "Bad magic number for central directory" ++ centdir = struct.unpack(structCentralDir, centdir) ++ if self.debug > 2: ++ print centdir ++ filename = fp.read(centdir[_CD_FILENAME_LENGTH]) ++ # Create ZipInfo instance to store file information ++ x = ZipInfo(filename) ++ x.extra = fp.read(centdir[_CD_EXTRA_FIELD_LENGTH]) ++ x.comment = fp.read(centdir[_CD_COMMENT_LENGTH]) ++ x.header_offset = centdir[_CD_LOCAL_HEADER_OFFSET] ++ (x.create_version, x.create_system, x.extract_version, x.reserved, ++ x.flag_bits, x.compress_type, t, d, ++ x.CRC, x.compress_size, x.file_size) = centdir[1:12] ++ x.volume, x.internal_attr, x.external_attr = centdir[15:18] ++ # Convert date/time code to (year, month, day, hour, min, sec) ++ x._raw_time = t ++ x.date_time = ( (d>>9)+1980, (d>>5)&0xF, d&0x1F, ++ t>>11, (t>>5)&0x3F, (t&0x1F) * 2 ) ++ ++ x._decodeExtra() ++ x.header_offset = x.header_offset + concat ++ x.filename = x._decodeFilename() ++ self.filelist.append(x) ++ self.NameToInfo[x.filename] = x ++ ++ # update total bytes read from central directory ++ total = (total + sizeCentralDir + centdir[_CD_FILENAME_LENGTH] ++ + centdir[_CD_EXTRA_FIELD_LENGTH] ++ + centdir[_CD_COMMENT_LENGTH]) ++ ++ if self.debug > 2: ++ print "total", total ++ ++ ++ def namelist(self): ++ """Return a list of file names in the archive.""" ++ l = [] ++ for data in self.filelist: ++ l.append(data.filename) ++ return l ++ ++ def infolist(self): ++ """Return a list of class ZipInfo instances for files in the ++ archive.""" ++ return self.filelist ++ ++ def printdir(self): ++ """Print a table of contents for the zip file.""" ++ print "%-46s %19s %12s" % ("File Name", "Modified ", "Size") ++ for zinfo in self.filelist: ++ date = "%d-%02d-%02d %02d:%02d:%02d" % zinfo.date_time[:6] ++ print "%-46s %s %12d" % (zinfo.filename, date, zinfo.file_size) ++ ++ def testzip(self): ++ """Read all the files and check the CRC.""" ++ chunk_size = 2 ** 20 ++ for zinfo in self.filelist: ++ try: ++ # Read by chunks, to avoid an OverflowError or a ++ # MemoryError with very large embedded files. ++ f = self.open(zinfo.filename, "r") ++ while f.read(chunk_size): # Check CRC-32 ++ pass ++ except BadZipfile: ++ return zinfo.filename ++ ++ def getinfo(self, name): ++ """Return the instance of ZipInfo given 'name'.""" ++ info = self.NameToInfo.get(name) ++ if info is None: ++ raise KeyError( ++ 'There is no item named %r in the archive' % name) ++ ++ return info ++ ++ def setpassword(self, pwd): ++ """Set default password for encrypted files.""" ++ self.pwd = pwd ++ ++ def read(self, name, pwd=None): ++ """Return file bytes (as a string) for name.""" ++ return self.open(name, "r", pwd).read() ++ ++ def open(self, name, mode="r", pwd=None): ++ """Return file-like object for 'name'.""" ++ if mode not in ("r", "U", "rU"): ++ raise RuntimeError, 'open() requires mode "r", "U", or "rU"' ++ if not self.fp: ++ raise RuntimeError, \ ++ "Attempt to read ZIP archive that was already closed" ++ ++ # Only open a new file for instances where we were not ++ # given a file object in the constructor ++ if self._filePassed: ++ zef_file = self.fp ++ else: ++ zef_file = open(self.filename, 'rb') ++ ++ # Make sure we have an info object ++ if isinstance(name, ZipInfo): ++ # 'name' is already an info object ++ zinfo = name ++ else: ++ # Get info object for name ++ zinfo = self.getinfo(name) ++ ++ zef_file.seek(zinfo.header_offset, 0) ++ ++ # Skip the file header: ++ fheader = zef_file.read(sizeFileHeader) ++ if fheader[0:4] != stringFileHeader: ++ raise BadZipfile, "Bad magic number for file header" ++ ++ fheader = struct.unpack(structFileHeader, fheader) ++ fname = zef_file.read(fheader[_FH_FILENAME_LENGTH]) ++ if fheader[_FH_EXTRA_FIELD_LENGTH]: ++ zef_file.read(fheader[_FH_EXTRA_FIELD_LENGTH]) ++ ++ if fname != zinfo.orig_filename: ++ raise BadZipfile, \ ++ 'File name in directory "%s" and header "%s" differ.' % ( ++ zinfo.orig_filename, fname) ++ ++ # check for encrypted flag & handle password ++ is_encrypted = zinfo.flag_bits & 0x1 ++ zd = None ++ if is_encrypted: ++ if not pwd: ++ pwd = self.pwd ++ if not pwd: ++ raise RuntimeError, "File %s is encrypted, " \ ++ "password required for extraction" % name ++ ++ zd = _ZipDecrypter(pwd) ++ # The first 12 bytes in the cypher stream is an encryption header ++ # used to strengthen the algorithm. The first 11 bytes are ++ # completely random, while the 12th contains the MSB of the CRC, ++ # or the MSB of the file time depending on the header type ++ # and is used to check the correctness of the password. ++ bytes = zef_file.read(12) ++ h = map(zd, bytes[0:12]) ++ if zinfo.flag_bits & 0x8: ++ # compare against the file type from extended local headers ++ check_byte = (zinfo._raw_time >> 8) & 0xff ++ else: ++ # compare against the CRC otherwise ++ check_byte = (zinfo.CRC >> 24) & 0xff ++ if ord(h[11]) != check_byte: ++ raise RuntimeError("Bad password for file", name) ++ ++ # build and return a ZipExtFile ++ if zd is None: ++ zef = ZipExtFile(zef_file, zinfo) ++ else: ++ zef = ZipExtFile(zef_file, zinfo, zd) ++ ++ # set universal newlines on ZipExtFile if necessary ++ if "U" in mode: ++ zef.set_univ_newlines(True) ++ return zef ++ ++ def extract(self, member, path=None, pwd=None): ++ """Extract a member from the archive to the current working directory, ++ using its full name. Its file information is extracted as accurately ++ as possible. `member' may be a filename or a ZipInfo object. You can ++ specify a different directory using `path'. ++ """ ++ if not isinstance(member, ZipInfo): ++ member = self.getinfo(member) ++ ++ if path is None: ++ path = os.getcwd() ++ ++ return self._extract_member(member, path, pwd) ++ ++ def extractall(self, path=None, members=None, pwd=None): ++ """Extract all members from the archive to the current working ++ directory. `path' specifies a different directory to extract to. ++ `members' is optional and must be a subset of the list returned ++ by namelist(). ++ """ ++ if members is None: ++ members = self.namelist() ++ ++ for zipinfo in members: ++ self.extract(zipinfo, path, pwd) ++ ++ def _extract_member(self, member, targetpath, pwd): ++ """Extract the ZipInfo object 'member' to a physical ++ file on the path targetpath. ++ """ ++ # build the destination pathname, replacing ++ # forward slashes to platform specific separators. ++ # Strip trailing path separator, unless it represents the root. ++ if (targetpath[-1:] in (os.path.sep, os.path.altsep) ++ and len(os.path.splitdrive(targetpath)[1]) > 1): ++ targetpath = targetpath[:-1] ++ ++ # don't include leading "/" from file name if present ++ if member.filename[0] == '/': ++ targetpath = os.path.join(targetpath, member.filename[1:]) ++ else: ++ targetpath = os.path.join(targetpath, member.filename) ++ ++ targetpath = os.path.normpath(targetpath) ++ ++ # Create all upper directories if necessary. ++ upperdirs = os.path.dirname(targetpath) ++ if upperdirs and not os.path.exists(upperdirs): ++ os.makedirs(upperdirs) ++ ++ if member.filename[-1] == '/': ++ if not os.path.isdir(targetpath): ++ os.mkdir(targetpath) ++ return targetpath ++ ++ source = self.open(member, pwd=pwd) ++ target = file(targetpath, "wb") ++ shutil.copyfileobj(source, target) ++ source.close() ++ target.close() ++ ++ return targetpath ++ ++ def _writecheck(self, zinfo): ++ """Check for errors before writing a file to the archive.""" ++ if zinfo.filename in self.NameToInfo: ++ if self.debug: # Warning for duplicate names ++ print "Duplicate name:", zinfo.filename ++ if self.mode not in ("w", "a"): ++ raise RuntimeError, 'write() requires mode "w" or "a"' ++ if not self.fp: ++ raise RuntimeError, \ ++ "Attempt to write ZIP archive that was already closed" ++ if zinfo.compress_type == ZIP_DEFLATED and not zlib: ++ raise RuntimeError, \ ++ "Compression requires the (missing) zlib module" ++ if zinfo.compress_type not in (ZIP_STORED, ZIP_DEFLATED): ++ raise RuntimeError, \ ++ "That compression method is not supported" ++ if zinfo.file_size > ZIP64_LIMIT: ++ if not self._allowZip64: ++ raise LargeZipFile("Filesize would require ZIP64 extensions") ++ if zinfo.header_offset > ZIP64_LIMIT: ++ if not self._allowZip64: ++ raise LargeZipFile("Zipfile size would require ZIP64 extensions") ++ ++ def write(self, filename, arcname=None, compress_type=None): ++ """Put the bytes from filename into the archive under the name ++ arcname.""" ++ if not self.fp: ++ raise RuntimeError( ++ "Attempt to write to ZIP archive that was already closed") ++ ++ st = os.stat(filename) ++ isdir = stat.S_ISDIR(st.st_mode) ++ mtime = time.localtime(st.st_mtime) ++ date_time = mtime[0:6] ++ # Create ZipInfo instance to store file information ++ if arcname is None: ++ arcname = filename ++ arcname = os.path.normpath(os.path.splitdrive(arcname)[1]) ++ while arcname[0] in (os.sep, os.altsep): ++ arcname = arcname[1:] ++ if isdir: ++ arcname += '/' ++ zinfo = ZipInfo(arcname, date_time) ++ zinfo.external_attr = (st[0] & 0xFFFF) << 16L # Unix attributes ++ if compress_type is None: ++ zinfo.compress_type = self.compression ++ else: ++ zinfo.compress_type = compress_type ++ ++ zinfo.file_size = st.st_size ++ zinfo.flag_bits = 0x00 ++ zinfo.header_offset = self.fp.tell() # Start of header bytes ++ ++ self._writecheck(zinfo) ++ self._didModify = True ++ ++ if isdir: ++ zinfo.file_size = 0 ++ zinfo.compress_size = 0 ++ zinfo.CRC = 0 ++ self.filelist.append(zinfo) ++ self.NameToInfo[zinfo.filename] = zinfo ++ self.fp.write(zinfo.FileHeader()) ++ return ++ ++ fp = open(filename, "rb") ++ # Must overwrite CRC and sizes with correct data later ++ zinfo.CRC = CRC = 0 ++ zinfo.compress_size = compress_size = 0 ++ zinfo.file_size = file_size = 0 ++ self.fp.write(zinfo.FileHeader()) ++ if zinfo.compress_type == ZIP_DEFLATED: ++ cmpr = zlib.compressobj(zlib.Z_DEFAULT_COMPRESSION, ++ zlib.DEFLATED, -15) ++ else: ++ cmpr = None ++ while 1: ++ buf = fp.read(1024 * 8) ++ if not buf: ++ break ++ file_size = file_size + len(buf) ++ CRC = crc32(buf, CRC) & 0xffffffff ++ if cmpr: ++ buf = cmpr.compress(buf) ++ compress_size = compress_size + len(buf) ++ self.fp.write(buf) ++ fp.close() ++ if cmpr: ++ buf = cmpr.flush() ++ compress_size = compress_size + len(buf) ++ self.fp.write(buf) ++ zinfo.compress_size = compress_size ++ else: ++ zinfo.compress_size = file_size ++ zinfo.CRC = CRC ++ zinfo.file_size = file_size ++ # Seek backwards and write CRC and file sizes ++ position = self.fp.tell() # Preserve current position in file ++ self.fp.seek(zinfo.header_offset + 14, 0) ++ self.fp.write(struct.pack(" ZIP64_LIMIT \ ++ or zinfo.compress_size > ZIP64_LIMIT: ++ extra.append(zinfo.file_size) ++ extra.append(zinfo.compress_size) ++ file_size = 0xffffffff ++ compress_size = 0xffffffff ++ else: ++ file_size = zinfo.file_size ++ compress_size = zinfo.compress_size ++ ++ if zinfo.header_offset > ZIP64_LIMIT: ++ extra.append(zinfo.header_offset) ++ header_offset = 0xffffffffL ++ else: ++ header_offset = zinfo.header_offset ++ ++ extra_data = zinfo.extra ++ if extra: ++ # Append a ZIP64 field to the extra's ++ extra_data = struct.pack( ++ '>sys.stderr, (structCentralDir, ++ stringCentralDir, create_version, ++ zinfo.create_system, extract_version, zinfo.reserved, ++ zinfo.flag_bits, zinfo.compress_type, dostime, dosdate, ++ zinfo.CRC, compress_size, file_size, ++ len(zinfo.filename), len(extra_data), len(zinfo.comment), ++ 0, zinfo.internal_attr, zinfo.external_attr, ++ header_offset) ++ raise ++ self.fp.write(centdir) ++ self.fp.write(filename) ++ self.fp.write(extra_data) ++ self.fp.write(zinfo.comment) ++ ++ pos2 = self.fp.tell() ++ # Write end-of-zip-archive record ++ centDirCount = count ++ centDirSize = pos2 - pos1 ++ centDirOffset = pos1 ++ if (centDirCount >= ZIP_FILECOUNT_LIMIT or ++ centDirOffset > ZIP64_LIMIT or ++ centDirSize > ZIP64_LIMIT): ++ # Need to write the ZIP64 end-of-archive records ++ zip64endrec = struct.pack( ++ structEndArchive64, stringEndArchive64, ++ 44, 45, 45, 0, 0, centDirCount, centDirCount, ++ centDirSize, centDirOffset) ++ self.fp.write(zip64endrec) ++ ++ zip64locrec = struct.pack( ++ structEndArchive64Locator, ++ stringEndArchive64Locator, 0, pos2, 1) ++ self.fp.write(zip64locrec) ++ centDirCount = min(centDirCount, 0xFFFF) ++ centDirSize = min(centDirSize, 0xFFFFFFFF) ++ centDirOffset = min(centDirOffset, 0xFFFFFFFF) ++ ++ # check for valid comment length ++ if len(self.comment) >= ZIP_MAX_COMMENT: ++ if self.debug > 0: ++ msg = 'Archive comment is too long; truncating to %d bytes' \ ++ % ZIP_MAX_COMMENT ++ self.comment = self.comment[:ZIP_MAX_COMMENT] ++ ++ endrec = struct.pack(structEndArchive, stringEndArchive, ++ 0, 0, centDirCount, centDirCount, ++ centDirSize, centDirOffset, len(self.comment)) ++ self.fp.write(endrec) ++ self.fp.write(self.comment) ++ self.fp.flush() ++ ++ if not self._filePassed: ++ self.fp.close() ++ self.fp = None ++ ++ ++class PyZipFile(ZipFile): ++ """Class to create ZIP archives with Python library files and packages.""" ++ ++ def writepy(self, pathname, basename = ""): ++ """Add all files from "pathname" to the ZIP archive. ++ ++ If pathname is a package directory, search the directory and ++ all package subdirectories recursively for all *.py and enter ++ the modules into the archive. If pathname is a plain ++ directory, listdir *.py and enter all modules. Else, pathname ++ must be a Python *.py file and the module will be put into the ++ archive. Added modules are always module.pyo or module.pyc. ++ This method will compile the module.py into module.pyc if ++ necessary. ++ """ ++ dir, name = os.path.split(pathname) ++ if os.path.isdir(pathname): ++ initname = os.path.join(pathname, "__init__.py") ++ if os.path.isfile(initname): ++ # This is a package directory, add it ++ if basename: ++ basename = "%s/%s" % (basename, name) ++ else: ++ basename = name ++ if self.debug: ++ print "Adding package in", pathname, "as", basename ++ fname, arcname = self._get_codename(initname[0:-3], basename) ++ if self.debug: ++ print "Adding", arcname ++ self.write(fname, arcname) ++ dirlist = os.listdir(pathname) ++ dirlist.remove("__init__.py") ++ # Add all *.py files and package subdirectories ++ for filename in dirlist: ++ path = os.path.join(pathname, filename) ++ root, ext = os.path.splitext(filename) ++ if os.path.isdir(path): ++ if os.path.isfile(os.path.join(path, "__init__.py")): ++ # This is a package directory, add it ++ self.writepy(path, basename) # Recursive call ++ elif ext == ".py": ++ fname, arcname = self._get_codename(path[0:-3], ++ basename) ++ if self.debug: ++ print "Adding", arcname ++ self.write(fname, arcname) ++ else: ++ # This is NOT a package directory, add its files at top level ++ if self.debug: ++ print "Adding files from directory", pathname ++ for filename in os.listdir(pathname): ++ path = os.path.join(pathname, filename) ++ root, ext = os.path.splitext(filename) ++ if ext == ".py": ++ fname, arcname = self._get_codename(path[0:-3], ++ basename) ++ if self.debug: ++ print "Adding", arcname ++ self.write(fname, arcname) ++ else: ++ if pathname[-3:] != ".py": ++ raise RuntimeError, \ ++ 'Files added with writepy() must end with ".py"' ++ fname, arcname = self._get_codename(pathname[0:-3], basename) ++ if self.debug: ++ print "Adding file", arcname ++ self.write(fname, arcname) ++ ++ def _get_codename(self, pathname, basename): ++ """Return (filename, archivename) for the path. ++ ++ Given a module name path, return the correct file path and ++ archive name, compiling if necessary. For example, given ++ /python/lib/string, return (/python/lib/string.pyc, string). ++ """ ++ file_py = pathname + ".py" ++ file_pyc = pathname + ".pyc" ++ file_pyo = pathname + ".pyo" ++ if os.path.isfile(file_pyo) and \ ++ os.stat(file_pyo).st_mtime >= os.stat(file_py).st_mtime: ++ fname = file_pyo # Use .pyo file ++ elif not os.path.isfile(file_pyc) or \ ++ os.stat(file_pyc).st_mtime < os.stat(file_py).st_mtime: ++ import py_compile ++ if self.debug: ++ print "Compiling", file_py ++ try: ++ py_compile.compile(file_py, file_pyc, None, True) ++ except py_compile.PyCompileError,err: ++ print err.msg ++ fname = file_pyc ++ else: ++ fname = file_pyc ++ archivename = os.path.split(fname)[1] ++ if basename: ++ archivename = "%s/%s" % (basename, archivename) ++ return (fname, archivename) ++ ++ ++def main(args = None): ++ import textwrap ++ USAGE=textwrap.dedent("""\ ++ Usage: ++ zipfile.py -l zipfile.zip # Show listing of a zipfile ++ zipfile.py -t zipfile.zip # Test if a zipfile is valid ++ zipfile.py -e zipfile.zip target # Extract zipfile into target dir ++ zipfile.py -c zipfile.zip src ... # Create zipfile from sources ++ """) ++ if args is None: ++ args = sys.argv[1:] ++ ++ if not args or args[0] not in ('-l', '-c', '-e', '-t'): ++ print USAGE ++ sys.exit(1) ++ ++ if args[0] == '-l': ++ if len(args) != 2: ++ print USAGE ++ sys.exit(1) ++ zf = ZipFile(args[1], 'r') ++ zf.printdir() ++ zf.close() ++ ++ elif args[0] == '-t': ++ if len(args) != 2: ++ print USAGE ++ sys.exit(1) ++ zf = ZipFile(args[1], 'r') ++ zf.testzip() ++ print "Done testing" ++ ++ elif args[0] == '-e': ++ if len(args) != 3: ++ print USAGE ++ sys.exit(1) ++ ++ zf = ZipFile(args[1], 'r') ++ out = args[2] ++ for path in zf.namelist(): ++ if path.startswith('./'): ++ tgt = os.path.join(out, path[2:]) ++ else: ++ tgt = os.path.join(out, path) ++ ++ tgtdir = os.path.dirname(tgt) ++ if not os.path.exists(tgtdir): ++ os.makedirs(tgtdir) ++ fp = open(tgt, 'wb') ++ fp.write(zf.read(path)) ++ fp.close() ++ zf.close() ++ ++ elif args[0] == '-c': ++ if len(args) < 3: ++ print USAGE ++ sys.exit(1) ++ ++ def addToZip(zf, path, zippath): ++ if os.path.isfile(path): ++ zf.write(path, zippath, ZIP_DEFLATED) ++ elif os.path.isdir(path): ++ for nm in os.listdir(path): ++ addToZip(zf, ++ os.path.join(path, nm), os.path.join(zippath, nm)) ++ # else: ignore ++ ++ zf = ZipFile(args[1], 'w', allowZip64=True) ++ for src in args[2:]: ++ addToZip(zf, src, os.path.basename(src)) ++ ++ zf.close() ++ ++if __name__ == "__main__": ++ main() --- sugar-read-activity-0.86-78.orig/debian/patches/1001_use_plain_dejavu.patch +++ sugar-read-activity-0.86-78/debian/patches/1001_use_plain_dejavu.patch @@ -0,0 +1,28 @@ +--- a/epubview/epubview.py ++++ b/epubview/epubview.py +@@ -73,7 +73,7 @@ class _View(gtk.HBox): + self._view = widgets._WebView() + self._view.load_string(LOADING_HTML, 'text/html', 'utf-8', '/') + settings = self._view.get_settings() +- settings.props.default_font_family = 'DejaVu LGC Serif' ++ settings.props.default_font_family = 'DejaVu Serif' + settings.props.enable_plugins = False + settings.props.default_encoding = 'utf-8' + self._view.connect('load-finished', self._view_load_finished_cb) +--- a/epubview/jobs.py ++++ b/epubview/jobs.py +@@ -114,10 +114,10 @@ class _JobPaginator(gobject.GObject): + self._temp_view = widgets._WebView() + + settings = self._temp_view.get_settings() +- settings.props.default_font_family = 'DejaVu LGC Serif' +- settings.props.sans_serif_font_family = 'DejaVu LGC Sans' +- settings.props.serif_font_family = 'DejaVu LGC Serif' +- settings.props.monospace_font_family = 'DejaVu LGC Sans Mono' ++ settings.props.default_font_family = 'DejaVu Serif' ++ settings.props.sans_serif_font_family = 'DejaVu Sans' ++ settings.props.serif_font_family = 'DejaVu Serif' ++ settings.props.monospace_font_family = 'DejaVu Sans Mono' + settings.props.enforce_96_dpi = True + #settings.props.auto_shrink_images = False #FIXME: This does not seem to work + settings.props.enable_plugins = False --- sugar-read-activity-0.86-78.orig/debian/patches/README +++ sugar-read-activity-0.86-78/debian/patches/README @@ -0,0 +1,3 @@ +0xxx: Grabbed from upstream development. +1xxx: Possibly relevant for upstream adoption. +2xxx: Only relevant for official Debian release.