[Checkins] SVN: z3c.pypimirror/trunk/ initial import
Andreas Jung
andreas at andreas-jung.com
Wed Aug 27 07:59:23 EDT 2008
Log message for revision 90436:
initial import
Changed:
A z3c.pypimirror/trunk/.bzr/
A z3c.pypimirror/trunk/.bzr/README
A z3c.pypimirror/trunk/.bzr/branch/
A z3c.pypimirror/trunk/.bzr/branch/branch.conf
A z3c.pypimirror/trunk/.bzr/branch/format
A z3c.pypimirror/trunk/.bzr/branch/last-revision
A z3c.pypimirror/trunk/.bzr/branch/lock/
A z3c.pypimirror/trunk/.bzr/branch/tags
A z3c.pypimirror/trunk/.bzr/branch-format
A z3c.pypimirror/trunk/.bzr/branch-lock/
A z3c.pypimirror/trunk/.bzr/checkout/
A z3c.pypimirror/trunk/.bzr/checkout/conflicts
A z3c.pypimirror/trunk/.bzr/checkout/dirstate
A z3c.pypimirror/trunk/.bzr/checkout/format
A z3c.pypimirror/trunk/.bzr/checkout/lock/
A z3c.pypimirror/trunk/.bzr/checkout/merge-hashes
A z3c.pypimirror/trunk/.bzr/repository/
A z3c.pypimirror/trunk/.bzr/repository/format
A z3c.pypimirror/trunk/.bzr/repository/indices/
A z3c.pypimirror/trunk/.bzr/repository/indices/00b68f444f8857884a3e5628bd9b349d.iix
A z3c.pypimirror/trunk/.bzr/repository/indices/00b68f444f8857884a3e5628bd9b349d.rix
A z3c.pypimirror/trunk/.bzr/repository/indices/00b68f444f8857884a3e5628bd9b349d.six
A z3c.pypimirror/trunk/.bzr/repository/indices/00b68f444f8857884a3e5628bd9b349d.tix
A z3c.pypimirror/trunk/.bzr/repository/indices/7b9c3297673308f8a7148448d7cbc103.iix
A z3c.pypimirror/trunk/.bzr/repository/indices/7b9c3297673308f8a7148448d7cbc103.rix
A z3c.pypimirror/trunk/.bzr/repository/indices/7b9c3297673308f8a7148448d7cbc103.six
A z3c.pypimirror/trunk/.bzr/repository/indices/7b9c3297673308f8a7148448d7cbc103.tix
A z3c.pypimirror/trunk/.bzr/repository/indices/911a8a19d2201c543f667abdc28619b0.iix
A z3c.pypimirror/trunk/.bzr/repository/indices/911a8a19d2201c543f667abdc28619b0.rix
A z3c.pypimirror/trunk/.bzr/repository/indices/911a8a19d2201c543f667abdc28619b0.six
A z3c.pypimirror/trunk/.bzr/repository/indices/911a8a19d2201c543f667abdc28619b0.tix
A z3c.pypimirror/trunk/.bzr/repository/indices/a985ba7829211e0521c4df5004e3146b.iix
A z3c.pypimirror/trunk/.bzr/repository/indices/a985ba7829211e0521c4df5004e3146b.rix
A z3c.pypimirror/trunk/.bzr/repository/indices/a985ba7829211e0521c4df5004e3146b.six
A z3c.pypimirror/trunk/.bzr/repository/indices/a985ba7829211e0521c4df5004e3146b.tix
A z3c.pypimirror/trunk/.bzr/repository/indices/f431359076136e5f0f3cdbe26c6958f0.iix
A z3c.pypimirror/trunk/.bzr/repository/indices/f431359076136e5f0f3cdbe26c6958f0.rix
A z3c.pypimirror/trunk/.bzr/repository/indices/f431359076136e5f0f3cdbe26c6958f0.six
A z3c.pypimirror/trunk/.bzr/repository/indices/f431359076136e5f0f3cdbe26c6958f0.tix
A z3c.pypimirror/trunk/.bzr/repository/indices/fdf4e5ef10839aa0da2d6439c6549d69.iix
A z3c.pypimirror/trunk/.bzr/repository/indices/fdf4e5ef10839aa0da2d6439c6549d69.rix
A z3c.pypimirror/trunk/.bzr/repository/indices/fdf4e5ef10839aa0da2d6439c6549d69.six
A z3c.pypimirror/trunk/.bzr/repository/indices/fdf4e5ef10839aa0da2d6439c6549d69.tix
A z3c.pypimirror/trunk/.bzr/repository/lock/
A z3c.pypimirror/trunk/.bzr/repository/obsolete_packs/
A z3c.pypimirror/trunk/.bzr/repository/obsolete_packs/0272bcdd948ec0f6000bb020a556e522.iix
A z3c.pypimirror/trunk/.bzr/repository/obsolete_packs/0272bcdd948ec0f6000bb020a556e522.pack
A z3c.pypimirror/trunk/.bzr/repository/obsolete_packs/0272bcdd948ec0f6000bb020a556e522.rix
A z3c.pypimirror/trunk/.bzr/repository/obsolete_packs/0272bcdd948ec0f6000bb020a556e522.six
A z3c.pypimirror/trunk/.bzr/repository/obsolete_packs/0272bcdd948ec0f6000bb020a556e522.tix
A z3c.pypimirror/trunk/.bzr/repository/obsolete_packs/09249752d45fd3059b755a8a5cf8f59d.iix
A z3c.pypimirror/trunk/.bzr/repository/obsolete_packs/09249752d45fd3059b755a8a5cf8f59d.pack
A z3c.pypimirror/trunk/.bzr/repository/obsolete_packs/09249752d45fd3059b755a8a5cf8f59d.rix
A z3c.pypimirror/trunk/.bzr/repository/obsolete_packs/09249752d45fd3059b755a8a5cf8f59d.six
A z3c.pypimirror/trunk/.bzr/repository/obsolete_packs/09249752d45fd3059b755a8a5cf8f59d.tix
A z3c.pypimirror/trunk/.bzr/repository/obsolete_packs/24cef783082e32434f52b17cdd33f513.iix
A z3c.pypimirror/trunk/.bzr/repository/obsolete_packs/24cef783082e32434f52b17cdd33f513.pack
A z3c.pypimirror/trunk/.bzr/repository/obsolete_packs/24cef783082e32434f52b17cdd33f513.rix
A z3c.pypimirror/trunk/.bzr/repository/obsolete_packs/24cef783082e32434f52b17cdd33f513.six
A z3c.pypimirror/trunk/.bzr/repository/obsolete_packs/24cef783082e32434f52b17cdd33f513.tix
A z3c.pypimirror/trunk/.bzr/repository/obsolete_packs/80feda071b5555b557c40134560f2a61.iix
A z3c.pypimirror/trunk/.bzr/repository/obsolete_packs/80feda071b5555b557c40134560f2a61.pack
A z3c.pypimirror/trunk/.bzr/repository/obsolete_packs/80feda071b5555b557c40134560f2a61.rix
A z3c.pypimirror/trunk/.bzr/repository/obsolete_packs/80feda071b5555b557c40134560f2a61.six
A z3c.pypimirror/trunk/.bzr/repository/obsolete_packs/80feda071b5555b557c40134560f2a61.tix
A z3c.pypimirror/trunk/.bzr/repository/obsolete_packs/d7abcef8d702f8e3298c6d01a571158e.iix
A z3c.pypimirror/trunk/.bzr/repository/obsolete_packs/d7abcef8d702f8e3298c6d01a571158e.pack
A z3c.pypimirror/trunk/.bzr/repository/obsolete_packs/d7abcef8d702f8e3298c6d01a571158e.rix
A z3c.pypimirror/trunk/.bzr/repository/obsolete_packs/d7abcef8d702f8e3298c6d01a571158e.six
A z3c.pypimirror/trunk/.bzr/repository/obsolete_packs/d7abcef8d702f8e3298c6d01a571158e.tix
A z3c.pypimirror/trunk/.bzr/repository/obsolete_packs/ed0cbeda1e0a0bf4bdf674618ad38120.iix
A z3c.pypimirror/trunk/.bzr/repository/obsolete_packs/ed0cbeda1e0a0bf4bdf674618ad38120.pack
A z3c.pypimirror/trunk/.bzr/repository/obsolete_packs/ed0cbeda1e0a0bf4bdf674618ad38120.rix
A z3c.pypimirror/trunk/.bzr/repository/obsolete_packs/ed0cbeda1e0a0bf4bdf674618ad38120.six
A z3c.pypimirror/trunk/.bzr/repository/obsolete_packs/ed0cbeda1e0a0bf4bdf674618ad38120.tix
A z3c.pypimirror/trunk/.bzr/repository/obsolete_packs/f304cea097218d27efe732db691cb352.iix
A z3c.pypimirror/trunk/.bzr/repository/obsolete_packs/f304cea097218d27efe732db691cb352.pack
A z3c.pypimirror/trunk/.bzr/repository/obsolete_packs/f304cea097218d27efe732db691cb352.rix
A z3c.pypimirror/trunk/.bzr/repository/obsolete_packs/f304cea097218d27efe732db691cb352.six
A z3c.pypimirror/trunk/.bzr/repository/obsolete_packs/f304cea097218d27efe732db691cb352.tix
A z3c.pypimirror/trunk/.bzr/repository/pack-names
A z3c.pypimirror/trunk/.bzr/repository/packs/
A z3c.pypimirror/trunk/.bzr/repository/packs/00b68f444f8857884a3e5628bd9b349d.pack
A z3c.pypimirror/trunk/.bzr/repository/packs/7b9c3297673308f8a7148448d7cbc103.pack
A z3c.pypimirror/trunk/.bzr/repository/packs/911a8a19d2201c543f667abdc28619b0.pack
A z3c.pypimirror/trunk/.bzr/repository/packs/a985ba7829211e0521c4df5004e3146b.pack
A z3c.pypimirror/trunk/.bzr/repository/packs/f431359076136e5f0f3cdbe26c6958f0.pack
A z3c.pypimirror/trunk/.bzr/repository/packs/fdf4e5ef10839aa0da2d6439c6549d69.pack
A z3c.pypimirror/trunk/.bzr/repository/upload/
A z3c.pypimirror/trunk/.bzrignore
A z3c.pypimirror/trunk/.installed.cfg
A z3c.pypimirror/trunk/CHANGES.txt
A z3c.pypimirror/trunk/README.txt
A z3c.pypimirror/trunk/ZPL.txt
A z3c.pypimirror/trunk/bootstrap.py
A z3c.pypimirror/trunk/build/
A z3c.pypimirror/trunk/build/bdist.macosx-10.3-i386/
A z3c.pypimirror/trunk/build/lib/
A z3c.pypimirror/trunk/build/lib/z3c/
A z3c.pypimirror/trunk/build/lib/z3c/__init__.py
A z3c.pypimirror/trunk/build/lib/z3c/pypimirror/
A z3c.pypimirror/trunk/build/lib/z3c/pypimirror/__init__.py
A z3c.pypimirror/trunk/build/lib/z3c/pypimirror/mirror.py
A z3c.pypimirror/trunk/build/lib/z3c/pypimirror/pypimirror.cfg.sample
A z3c.pypimirror/trunk/build/lib/z3c/pypimirror/tests.py
A z3c.pypimirror/trunk/build/lib/z3c/pypimirror/util.py
A z3c.pypimirror/trunk/buildout.cfg
A z3c.pypimirror/trunk/dist/
A z3c.pypimirror/trunk/dist/z3c.pypimirror-0.1.0-py2.4.egg
A z3c.pypimirror/trunk/dist/z3c.pypimirror-0.1.0.tar.gz
A z3c.pypimirror/trunk/setup.py
A z3c.pypimirror/trunk/src/
A z3c.pypimirror/trunk/src/z3c/
A z3c.pypimirror/trunk/src/z3c/__init__.py
A z3c.pypimirror/trunk/src/z3c/pypimirror/
A z3c.pypimirror/trunk/src/z3c/pypimirror/README.txt
A z3c.pypimirror/trunk/src/z3c/pypimirror/__init__.py
A z3c.pypimirror/trunk/src/z3c/pypimirror/mirror.py
A z3c.pypimirror/trunk/src/z3c/pypimirror/pypimirror.cfg.sample
A z3c.pypimirror/trunk/src/z3c/pypimirror/tests.py
A z3c.pypimirror/trunk/src/z3c/pypimirror/util.py
A z3c.pypimirror/trunk/src/z3c.pypimirror.egg-info/
A z3c.pypimirror/trunk/src/z3c.pypimirror.egg-info/PKG-INFO
A z3c.pypimirror/trunk/src/z3c.pypimirror.egg-info/SOURCES.txt
A z3c.pypimirror/trunk/src/z3c.pypimirror.egg-info/dependency_links.txt
A z3c.pypimirror/trunk/src/z3c.pypimirror.egg-info/entry_points.txt
A z3c.pypimirror/trunk/src/z3c.pypimirror.egg-info/namespace_packages.txt
A z3c.pypimirror/trunk/src/z3c.pypimirror.egg-info/not-zip-safe
A z3c.pypimirror/trunk/src/z3c.pypimirror.egg-info/requires.txt
A z3c.pypimirror/trunk/src/z3c.pypimirror.egg-info/top_level.txt
-=-
Added: z3c.pypimirror/trunk/.bzr/README
===================================================================
--- z3c.pypimirror/trunk/.bzr/README (rev 0)
+++ z3c.pypimirror/trunk/.bzr/README 2008-08-27 11:59:22 UTC (rev 90436)
@@ -0,0 +1,3 @@
+This is a Bazaar control directory.
+Do not change any files in this directory.
+See http://bazaar-vcs.org/ for more information about Bazaar.
Property changes on: z3c.pypimirror/trunk/.bzr/README
___________________________________________________________________
Name: svn:executable
+
Added: z3c.pypimirror/trunk/.bzr/branch/branch.conf
===================================================================
--- z3c.pypimirror/trunk/.bzr/branch/branch.conf (rev 0)
+++ z3c.pypimirror/trunk/.bzr/branch/branch.conf 2008-08-27 11:59:22 UTC (rev 90436)
@@ -0,0 +1,2 @@
+bound_location = sftp://dev@172.29.254.21/home/dev/REPOSITORY/z3c.pypimirror/
+bound = True
Added: z3c.pypimirror/trunk/.bzr/branch/format
===================================================================
--- z3c.pypimirror/trunk/.bzr/branch/format (rev 0)
+++ z3c.pypimirror/trunk/.bzr/branch/format 2008-08-27 11:59:22 UTC (rev 90436)
@@ -0,0 +1 @@
+Bazaar Branch Format 6 (bzr 0.15)
Property changes on: z3c.pypimirror/trunk/.bzr/branch/format
___________________________________________________________________
Name: svn:executable
+
Added: z3c.pypimirror/trunk/.bzr/branch/last-revision
===================================================================
--- z3c.pypimirror/trunk/.bzr/branch/last-revision (rev 0)
+++ z3c.pypimirror/trunk/.bzr/branch/last-revision 2008-08-27 11:59:22 UTC (rev 90436)
@@ -0,0 +1 @@
+47 dk at d9t.de-20080827113307-m8f9v4x7a0u8wsmr
Added: z3c.pypimirror/trunk/.bzr/branch/tags
===================================================================
Property changes on: z3c.pypimirror/trunk/.bzr/branch/tags
___________________________________________________________________
Name: svn:executable
+
Added: z3c.pypimirror/trunk/.bzr/branch-format
===================================================================
--- z3c.pypimirror/trunk/.bzr/branch-format (rev 0)
+++ z3c.pypimirror/trunk/.bzr/branch-format 2008-08-27 11:59:22 UTC (rev 90436)
@@ -0,0 +1 @@
+Bazaar-NG meta directory, format 1
Property changes on: z3c.pypimirror/trunk/.bzr/branch-format
___________________________________________________________________
Name: svn:executable
+
Added: z3c.pypimirror/trunk/.bzr/checkout/conflicts
===================================================================
--- z3c.pypimirror/trunk/.bzr/checkout/conflicts (rev 0)
+++ z3c.pypimirror/trunk/.bzr/checkout/conflicts 2008-08-27 11:59:22 UTC (rev 90436)
@@ -0,0 +1 @@
+BZR conflict list format 1
Added: z3c.pypimirror/trunk/.bzr/checkout/dirstate
===================================================================
(Binary files differ)
Property changes on: z3c.pypimirror/trunk/.bzr/checkout/dirstate
___________________________________________________________________
Name: svn:executable
+
Name: svn:mime-type
+ application/octet-stream
Added: z3c.pypimirror/trunk/.bzr/checkout/format
===================================================================
--- z3c.pypimirror/trunk/.bzr/checkout/format (rev 0)
+++ z3c.pypimirror/trunk/.bzr/checkout/format 2008-08-27 11:59:22 UTC (rev 90436)
@@ -0,0 +1 @@
+Bazaar Working Tree Format 4 (bzr 0.15)
Property changes on: z3c.pypimirror/trunk/.bzr/checkout/format
___________________________________________________________________
Name: svn:executable
+
Added: z3c.pypimirror/trunk/.bzr/checkout/merge-hashes
===================================================================
--- z3c.pypimirror/trunk/.bzr/checkout/merge-hashes (rev 0)
+++ z3c.pypimirror/trunk/.bzr/checkout/merge-hashes 2008-08-27 11:59:22 UTC (rev 90436)
@@ -0,0 +1,3 @@
+BZR merge-modified list format 1
+file_id: mirror.py-20080826141818-oywrkcxvwj6tvkkd-5
+hash: f1381bb19cefad3b34b279651d463583fa2e8907
Added: z3c.pypimirror/trunk/.bzr/repository/format
===================================================================
--- z3c.pypimirror/trunk/.bzr/repository/format (rev 0)
+++ z3c.pypimirror/trunk/.bzr/repository/format 2008-08-27 11:59:22 UTC (rev 90436)
@@ -0,0 +1 @@
+Bazaar pack repository format 1 (needs bzr 0.92)
Property changes on: z3c.pypimirror/trunk/.bzr/repository/format
___________________________________________________________________
Name: svn:executable
+
Added: z3c.pypimirror/trunk/.bzr/repository/indices/00b68f444f8857884a3e5628bd9b349d.iix
===================================================================
(Binary files differ)
Property changes on: z3c.pypimirror/trunk/.bzr/repository/indices/00b68f444f8857884a3e5628bd9b349d.iix
___________________________________________________________________
Name: svn:executable
+
Name: svn:mime-type
+ application/octet-stream
Added: z3c.pypimirror/trunk/.bzr/repository/indices/00b68f444f8857884a3e5628bd9b349d.rix
===================================================================
(Binary files differ)
Property changes on: z3c.pypimirror/trunk/.bzr/repository/indices/00b68f444f8857884a3e5628bd9b349d.rix
___________________________________________________________________
Name: svn:executable
+
Name: svn:mime-type
+ application/octet-stream
Added: z3c.pypimirror/trunk/.bzr/repository/indices/00b68f444f8857884a3e5628bd9b349d.six
===================================================================
--- z3c.pypimirror/trunk/.bzr/repository/indices/00b68f444f8857884a3e5628bd9b349d.six (rev 0)
+++ z3c.pypimirror/trunk/.bzr/repository/indices/00b68f444f8857884a3e5628bd9b349d.six 2008-08-27 11:59:22 UTC (rev 90436)
@@ -0,0 +1,5 @@
+Bazaar Graph Index 1
+node_ref_lists=0
+key_elements=1
+len=0
+
Property changes on: z3c.pypimirror/trunk/.bzr/repository/indices/00b68f444f8857884a3e5628bd9b349d.six
___________________________________________________________________
Name: svn:executable
+
Added: z3c.pypimirror/trunk/.bzr/repository/indices/00b68f444f8857884a3e5628bd9b349d.tix
===================================================================
(Binary files differ)
Property changes on: z3c.pypimirror/trunk/.bzr/repository/indices/00b68f444f8857884a3e5628bd9b349d.tix
___________________________________________________________________
Name: svn:executable
+
Name: svn:mime-type
+ application/octet-stream
Added: z3c.pypimirror/trunk/.bzr/repository/indices/7b9c3297673308f8a7148448d7cbc103.iix
===================================================================
(Binary files differ)
Property changes on: z3c.pypimirror/trunk/.bzr/repository/indices/7b9c3297673308f8a7148448d7cbc103.iix
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: z3c.pypimirror/trunk/.bzr/repository/indices/7b9c3297673308f8a7148448d7cbc103.rix
===================================================================
(Binary files differ)
Property changes on: z3c.pypimirror/trunk/.bzr/repository/indices/7b9c3297673308f8a7148448d7cbc103.rix
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: z3c.pypimirror/trunk/.bzr/repository/indices/7b9c3297673308f8a7148448d7cbc103.six
===================================================================
--- z3c.pypimirror/trunk/.bzr/repository/indices/7b9c3297673308f8a7148448d7cbc103.six (rev 0)
+++ z3c.pypimirror/trunk/.bzr/repository/indices/7b9c3297673308f8a7148448d7cbc103.six 2008-08-27 11:59:22 UTC (rev 90436)
@@ -0,0 +1,5 @@
+Bazaar Graph Index 1
+node_ref_lists=0
+key_elements=1
+len=0
+
Added: z3c.pypimirror/trunk/.bzr/repository/indices/7b9c3297673308f8a7148448d7cbc103.tix
===================================================================
(Binary files differ)
Property changes on: z3c.pypimirror/trunk/.bzr/repository/indices/7b9c3297673308f8a7148448d7cbc103.tix
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: z3c.pypimirror/trunk/.bzr/repository/indices/911a8a19d2201c543f667abdc28619b0.iix
===================================================================
(Binary files differ)
Property changes on: z3c.pypimirror/trunk/.bzr/repository/indices/911a8a19d2201c543f667abdc28619b0.iix
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: z3c.pypimirror/trunk/.bzr/repository/indices/911a8a19d2201c543f667abdc28619b0.rix
===================================================================
(Binary files differ)
Property changes on: z3c.pypimirror/trunk/.bzr/repository/indices/911a8a19d2201c543f667abdc28619b0.rix
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: z3c.pypimirror/trunk/.bzr/repository/indices/911a8a19d2201c543f667abdc28619b0.six
===================================================================
--- z3c.pypimirror/trunk/.bzr/repository/indices/911a8a19d2201c543f667abdc28619b0.six (rev 0)
+++ z3c.pypimirror/trunk/.bzr/repository/indices/911a8a19d2201c543f667abdc28619b0.six 2008-08-27 11:59:22 UTC (rev 90436)
@@ -0,0 +1,5 @@
+Bazaar Graph Index 1
+node_ref_lists=0
+key_elements=1
+len=0
+
Added: z3c.pypimirror/trunk/.bzr/repository/indices/911a8a19d2201c543f667abdc28619b0.tix
===================================================================
(Binary files differ)
Property changes on: z3c.pypimirror/trunk/.bzr/repository/indices/911a8a19d2201c543f667abdc28619b0.tix
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: z3c.pypimirror/trunk/.bzr/repository/indices/a985ba7829211e0521c4df5004e3146b.iix
===================================================================
(Binary files differ)
Property changes on: z3c.pypimirror/trunk/.bzr/repository/indices/a985ba7829211e0521c4df5004e3146b.iix
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: z3c.pypimirror/trunk/.bzr/repository/indices/a985ba7829211e0521c4df5004e3146b.rix
===================================================================
(Binary files differ)
Property changes on: z3c.pypimirror/trunk/.bzr/repository/indices/a985ba7829211e0521c4df5004e3146b.rix
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: z3c.pypimirror/trunk/.bzr/repository/indices/a985ba7829211e0521c4df5004e3146b.six
===================================================================
--- z3c.pypimirror/trunk/.bzr/repository/indices/a985ba7829211e0521c4df5004e3146b.six (rev 0)
+++ z3c.pypimirror/trunk/.bzr/repository/indices/a985ba7829211e0521c4df5004e3146b.six 2008-08-27 11:59:22 UTC (rev 90436)
@@ -0,0 +1,5 @@
+Bazaar Graph Index 1
+node_ref_lists=0
+key_elements=1
+len=0
+
Added: z3c.pypimirror/trunk/.bzr/repository/indices/a985ba7829211e0521c4df5004e3146b.tix
===================================================================
(Binary files differ)
Property changes on: z3c.pypimirror/trunk/.bzr/repository/indices/a985ba7829211e0521c4df5004e3146b.tix
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: z3c.pypimirror/trunk/.bzr/repository/indices/f431359076136e5f0f3cdbe26c6958f0.iix
===================================================================
(Binary files differ)
Property changes on: z3c.pypimirror/trunk/.bzr/repository/indices/f431359076136e5f0f3cdbe26c6958f0.iix
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: z3c.pypimirror/trunk/.bzr/repository/indices/f431359076136e5f0f3cdbe26c6958f0.rix
===================================================================
(Binary files differ)
Property changes on: z3c.pypimirror/trunk/.bzr/repository/indices/f431359076136e5f0f3cdbe26c6958f0.rix
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: z3c.pypimirror/trunk/.bzr/repository/indices/f431359076136e5f0f3cdbe26c6958f0.six
===================================================================
--- z3c.pypimirror/trunk/.bzr/repository/indices/f431359076136e5f0f3cdbe26c6958f0.six (rev 0)
+++ z3c.pypimirror/trunk/.bzr/repository/indices/f431359076136e5f0f3cdbe26c6958f0.six 2008-08-27 11:59:22 UTC (rev 90436)
@@ -0,0 +1,5 @@
+Bazaar Graph Index 1
+node_ref_lists=0
+key_elements=1
+len=0
+
Added: z3c.pypimirror/trunk/.bzr/repository/indices/f431359076136e5f0f3cdbe26c6958f0.tix
===================================================================
(Binary files differ)
Property changes on: z3c.pypimirror/trunk/.bzr/repository/indices/f431359076136e5f0f3cdbe26c6958f0.tix
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: z3c.pypimirror/trunk/.bzr/repository/indices/fdf4e5ef10839aa0da2d6439c6549d69.iix
===================================================================
(Binary files differ)
Property changes on: z3c.pypimirror/trunk/.bzr/repository/indices/fdf4e5ef10839aa0da2d6439c6549d69.iix
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: z3c.pypimirror/trunk/.bzr/repository/indices/fdf4e5ef10839aa0da2d6439c6549d69.rix
===================================================================
(Binary files differ)
Property changes on: z3c.pypimirror/trunk/.bzr/repository/indices/fdf4e5ef10839aa0da2d6439c6549d69.rix
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: z3c.pypimirror/trunk/.bzr/repository/indices/fdf4e5ef10839aa0da2d6439c6549d69.six
===================================================================
--- z3c.pypimirror/trunk/.bzr/repository/indices/fdf4e5ef10839aa0da2d6439c6549d69.six (rev 0)
+++ z3c.pypimirror/trunk/.bzr/repository/indices/fdf4e5ef10839aa0da2d6439c6549d69.six 2008-08-27 11:59:22 UTC (rev 90436)
@@ -0,0 +1,5 @@
+Bazaar Graph Index 1
+node_ref_lists=0
+key_elements=1
+len=0
+
Added: z3c.pypimirror/trunk/.bzr/repository/indices/fdf4e5ef10839aa0da2d6439c6549d69.tix
===================================================================
(Binary files differ)
Property changes on: z3c.pypimirror/trunk/.bzr/repository/indices/fdf4e5ef10839aa0da2d6439c6549d69.tix
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: z3c.pypimirror/trunk/.bzr/repository/obsolete_packs/0272bcdd948ec0f6000bb020a556e522.iix
===================================================================
(Binary files differ)
Property changes on: z3c.pypimirror/trunk/.bzr/repository/obsolete_packs/0272bcdd948ec0f6000bb020a556e522.iix
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: z3c.pypimirror/trunk/.bzr/repository/obsolete_packs/0272bcdd948ec0f6000bb020a556e522.pack
===================================================================
(Binary files differ)
Property changes on: z3c.pypimirror/trunk/.bzr/repository/obsolete_packs/0272bcdd948ec0f6000bb020a556e522.pack
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: z3c.pypimirror/trunk/.bzr/repository/obsolete_packs/0272bcdd948ec0f6000bb020a556e522.rix
===================================================================
(Binary files differ)
Property changes on: z3c.pypimirror/trunk/.bzr/repository/obsolete_packs/0272bcdd948ec0f6000bb020a556e522.rix
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: z3c.pypimirror/trunk/.bzr/repository/obsolete_packs/0272bcdd948ec0f6000bb020a556e522.six
===================================================================
--- z3c.pypimirror/trunk/.bzr/repository/obsolete_packs/0272bcdd948ec0f6000bb020a556e522.six (rev 0)
+++ z3c.pypimirror/trunk/.bzr/repository/obsolete_packs/0272bcdd948ec0f6000bb020a556e522.six 2008-08-27 11:59:22 UTC (rev 90436)
@@ -0,0 +1,5 @@
+Bazaar Graph Index 1
+node_ref_lists=0
+key_elements=1
+len=0
+
Added: z3c.pypimirror/trunk/.bzr/repository/obsolete_packs/0272bcdd948ec0f6000bb020a556e522.tix
===================================================================
(Binary files differ)
Property changes on: z3c.pypimirror/trunk/.bzr/repository/obsolete_packs/0272bcdd948ec0f6000bb020a556e522.tix
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: z3c.pypimirror/trunk/.bzr/repository/obsolete_packs/09249752d45fd3059b755a8a5cf8f59d.iix
===================================================================
(Binary files differ)
Property changes on: z3c.pypimirror/trunk/.bzr/repository/obsolete_packs/09249752d45fd3059b755a8a5cf8f59d.iix
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: z3c.pypimirror/trunk/.bzr/repository/obsolete_packs/09249752d45fd3059b755a8a5cf8f59d.pack
===================================================================
(Binary files differ)
Property changes on: z3c.pypimirror/trunk/.bzr/repository/obsolete_packs/09249752d45fd3059b755a8a5cf8f59d.pack
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: z3c.pypimirror/trunk/.bzr/repository/obsolete_packs/09249752d45fd3059b755a8a5cf8f59d.rix
===================================================================
(Binary files differ)
Property changes on: z3c.pypimirror/trunk/.bzr/repository/obsolete_packs/09249752d45fd3059b755a8a5cf8f59d.rix
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: z3c.pypimirror/trunk/.bzr/repository/obsolete_packs/09249752d45fd3059b755a8a5cf8f59d.six
===================================================================
--- z3c.pypimirror/trunk/.bzr/repository/obsolete_packs/09249752d45fd3059b755a8a5cf8f59d.six (rev 0)
+++ z3c.pypimirror/trunk/.bzr/repository/obsolete_packs/09249752d45fd3059b755a8a5cf8f59d.six 2008-08-27 11:59:22 UTC (rev 90436)
@@ -0,0 +1,5 @@
+Bazaar Graph Index 1
+node_ref_lists=0
+key_elements=1
+len=0
+
Added: z3c.pypimirror/trunk/.bzr/repository/obsolete_packs/09249752d45fd3059b755a8a5cf8f59d.tix
===================================================================
(Binary files differ)
Property changes on: z3c.pypimirror/trunk/.bzr/repository/obsolete_packs/09249752d45fd3059b755a8a5cf8f59d.tix
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: z3c.pypimirror/trunk/.bzr/repository/obsolete_packs/24cef783082e32434f52b17cdd33f513.iix
===================================================================
(Binary files differ)
Property changes on: z3c.pypimirror/trunk/.bzr/repository/obsolete_packs/24cef783082e32434f52b17cdd33f513.iix
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: z3c.pypimirror/trunk/.bzr/repository/obsolete_packs/24cef783082e32434f52b17cdd33f513.pack
===================================================================
(Binary files differ)
Property changes on: z3c.pypimirror/trunk/.bzr/repository/obsolete_packs/24cef783082e32434f52b17cdd33f513.pack
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: z3c.pypimirror/trunk/.bzr/repository/obsolete_packs/24cef783082e32434f52b17cdd33f513.rix
===================================================================
(Binary files differ)
Property changes on: z3c.pypimirror/trunk/.bzr/repository/obsolete_packs/24cef783082e32434f52b17cdd33f513.rix
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: z3c.pypimirror/trunk/.bzr/repository/obsolete_packs/24cef783082e32434f52b17cdd33f513.six
===================================================================
--- z3c.pypimirror/trunk/.bzr/repository/obsolete_packs/24cef783082e32434f52b17cdd33f513.six (rev 0)
+++ z3c.pypimirror/trunk/.bzr/repository/obsolete_packs/24cef783082e32434f52b17cdd33f513.six 2008-08-27 11:59:22 UTC (rev 90436)
@@ -0,0 +1,5 @@
+Bazaar Graph Index 1
+node_ref_lists=0
+key_elements=1
+len=0
+
Added: z3c.pypimirror/trunk/.bzr/repository/obsolete_packs/24cef783082e32434f52b17cdd33f513.tix
===================================================================
(Binary files differ)
Property changes on: z3c.pypimirror/trunk/.bzr/repository/obsolete_packs/24cef783082e32434f52b17cdd33f513.tix
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: z3c.pypimirror/trunk/.bzr/repository/obsolete_packs/80feda071b5555b557c40134560f2a61.iix
===================================================================
(Binary files differ)
Property changes on: z3c.pypimirror/trunk/.bzr/repository/obsolete_packs/80feda071b5555b557c40134560f2a61.iix
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: z3c.pypimirror/trunk/.bzr/repository/obsolete_packs/80feda071b5555b557c40134560f2a61.pack
===================================================================
(Binary files differ)
Property changes on: z3c.pypimirror/trunk/.bzr/repository/obsolete_packs/80feda071b5555b557c40134560f2a61.pack
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: z3c.pypimirror/trunk/.bzr/repository/obsolete_packs/80feda071b5555b557c40134560f2a61.rix
===================================================================
(Binary files differ)
Property changes on: z3c.pypimirror/trunk/.bzr/repository/obsolete_packs/80feda071b5555b557c40134560f2a61.rix
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: z3c.pypimirror/trunk/.bzr/repository/obsolete_packs/80feda071b5555b557c40134560f2a61.six
===================================================================
--- z3c.pypimirror/trunk/.bzr/repository/obsolete_packs/80feda071b5555b557c40134560f2a61.six (rev 0)
+++ z3c.pypimirror/trunk/.bzr/repository/obsolete_packs/80feda071b5555b557c40134560f2a61.six 2008-08-27 11:59:22 UTC (rev 90436)
@@ -0,0 +1,5 @@
+Bazaar Graph Index 1
+node_ref_lists=0
+key_elements=1
+len=0
+
Added: z3c.pypimirror/trunk/.bzr/repository/obsolete_packs/80feda071b5555b557c40134560f2a61.tix
===================================================================
(Binary files differ)
Property changes on: z3c.pypimirror/trunk/.bzr/repository/obsolete_packs/80feda071b5555b557c40134560f2a61.tix
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: z3c.pypimirror/trunk/.bzr/repository/obsolete_packs/d7abcef8d702f8e3298c6d01a571158e.iix
===================================================================
(Binary files differ)
Property changes on: z3c.pypimirror/trunk/.bzr/repository/obsolete_packs/d7abcef8d702f8e3298c6d01a571158e.iix
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: z3c.pypimirror/trunk/.bzr/repository/obsolete_packs/d7abcef8d702f8e3298c6d01a571158e.pack
===================================================================
(Binary files differ)
Property changes on: z3c.pypimirror/trunk/.bzr/repository/obsolete_packs/d7abcef8d702f8e3298c6d01a571158e.pack
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: z3c.pypimirror/trunk/.bzr/repository/obsolete_packs/d7abcef8d702f8e3298c6d01a571158e.rix
===================================================================
(Binary files differ)
Property changes on: z3c.pypimirror/trunk/.bzr/repository/obsolete_packs/d7abcef8d702f8e3298c6d01a571158e.rix
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: z3c.pypimirror/trunk/.bzr/repository/obsolete_packs/d7abcef8d702f8e3298c6d01a571158e.six
===================================================================
--- z3c.pypimirror/trunk/.bzr/repository/obsolete_packs/d7abcef8d702f8e3298c6d01a571158e.six (rev 0)
+++ z3c.pypimirror/trunk/.bzr/repository/obsolete_packs/d7abcef8d702f8e3298c6d01a571158e.six 2008-08-27 11:59:22 UTC (rev 90436)
@@ -0,0 +1,5 @@
+Bazaar Graph Index 1
+node_ref_lists=0
+key_elements=1
+len=0
+
Added: z3c.pypimirror/trunk/.bzr/repository/obsolete_packs/d7abcef8d702f8e3298c6d01a571158e.tix
===================================================================
(Binary files differ)
Property changes on: z3c.pypimirror/trunk/.bzr/repository/obsolete_packs/d7abcef8d702f8e3298c6d01a571158e.tix
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: z3c.pypimirror/trunk/.bzr/repository/obsolete_packs/ed0cbeda1e0a0bf4bdf674618ad38120.iix
===================================================================
(Binary files differ)
Property changes on: z3c.pypimirror/trunk/.bzr/repository/obsolete_packs/ed0cbeda1e0a0bf4bdf674618ad38120.iix
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: z3c.pypimirror/trunk/.bzr/repository/obsolete_packs/ed0cbeda1e0a0bf4bdf674618ad38120.pack
===================================================================
(Binary files differ)
Property changes on: z3c.pypimirror/trunk/.bzr/repository/obsolete_packs/ed0cbeda1e0a0bf4bdf674618ad38120.pack
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: z3c.pypimirror/trunk/.bzr/repository/obsolete_packs/ed0cbeda1e0a0bf4bdf674618ad38120.rix
===================================================================
(Binary files differ)
Property changes on: z3c.pypimirror/trunk/.bzr/repository/obsolete_packs/ed0cbeda1e0a0bf4bdf674618ad38120.rix
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: z3c.pypimirror/trunk/.bzr/repository/obsolete_packs/ed0cbeda1e0a0bf4bdf674618ad38120.six
===================================================================
--- z3c.pypimirror/trunk/.bzr/repository/obsolete_packs/ed0cbeda1e0a0bf4bdf674618ad38120.six (rev 0)
+++ z3c.pypimirror/trunk/.bzr/repository/obsolete_packs/ed0cbeda1e0a0bf4bdf674618ad38120.six 2008-08-27 11:59:22 UTC (rev 90436)
@@ -0,0 +1,5 @@
+Bazaar Graph Index 1
+node_ref_lists=0
+key_elements=1
+len=0
+
Added: z3c.pypimirror/trunk/.bzr/repository/obsolete_packs/ed0cbeda1e0a0bf4bdf674618ad38120.tix
===================================================================
(Binary files differ)
Property changes on: z3c.pypimirror/trunk/.bzr/repository/obsolete_packs/ed0cbeda1e0a0bf4bdf674618ad38120.tix
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: z3c.pypimirror/trunk/.bzr/repository/obsolete_packs/f304cea097218d27efe732db691cb352.iix
===================================================================
(Binary files differ)
Property changes on: z3c.pypimirror/trunk/.bzr/repository/obsolete_packs/f304cea097218d27efe732db691cb352.iix
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: z3c.pypimirror/trunk/.bzr/repository/obsolete_packs/f304cea097218d27efe732db691cb352.pack
===================================================================
(Binary files differ)
Property changes on: z3c.pypimirror/trunk/.bzr/repository/obsolete_packs/f304cea097218d27efe732db691cb352.pack
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: z3c.pypimirror/trunk/.bzr/repository/obsolete_packs/f304cea097218d27efe732db691cb352.rix
===================================================================
(Binary files differ)
Property changes on: z3c.pypimirror/trunk/.bzr/repository/obsolete_packs/f304cea097218d27efe732db691cb352.rix
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: z3c.pypimirror/trunk/.bzr/repository/obsolete_packs/f304cea097218d27efe732db691cb352.six
===================================================================
--- z3c.pypimirror/trunk/.bzr/repository/obsolete_packs/f304cea097218d27efe732db691cb352.six (rev 0)
+++ z3c.pypimirror/trunk/.bzr/repository/obsolete_packs/f304cea097218d27efe732db691cb352.six 2008-08-27 11:59:22 UTC (rev 90436)
@@ -0,0 +1,5 @@
+Bazaar Graph Index 1
+node_ref_lists=0
+key_elements=1
+len=0
+
Added: z3c.pypimirror/trunk/.bzr/repository/obsolete_packs/f304cea097218d27efe732db691cb352.tix
===================================================================
(Binary files differ)
Property changes on: z3c.pypimirror/trunk/.bzr/repository/obsolete_packs/f304cea097218d27efe732db691cb352.tix
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: z3c.pypimirror/trunk/.bzr/repository/pack-names
===================================================================
(Binary files differ)
Property changes on: z3c.pypimirror/trunk/.bzr/repository/pack-names
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: z3c.pypimirror/trunk/.bzr/repository/packs/00b68f444f8857884a3e5628bd9b349d.pack
===================================================================
(Binary files differ)
Property changes on: z3c.pypimirror/trunk/.bzr/repository/packs/00b68f444f8857884a3e5628bd9b349d.pack
___________________________________________________________________
Name: svn:executable
+
Name: svn:mime-type
+ application/octet-stream
Added: z3c.pypimirror/trunk/.bzr/repository/packs/7b9c3297673308f8a7148448d7cbc103.pack
===================================================================
(Binary files differ)
Property changes on: z3c.pypimirror/trunk/.bzr/repository/packs/7b9c3297673308f8a7148448d7cbc103.pack
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: z3c.pypimirror/trunk/.bzr/repository/packs/911a8a19d2201c543f667abdc28619b0.pack
===================================================================
(Binary files differ)
Property changes on: z3c.pypimirror/trunk/.bzr/repository/packs/911a8a19d2201c543f667abdc28619b0.pack
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: z3c.pypimirror/trunk/.bzr/repository/packs/a985ba7829211e0521c4df5004e3146b.pack
===================================================================
(Binary files differ)
Property changes on: z3c.pypimirror/trunk/.bzr/repository/packs/a985ba7829211e0521c4df5004e3146b.pack
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: z3c.pypimirror/trunk/.bzr/repository/packs/f431359076136e5f0f3cdbe26c6958f0.pack
===================================================================
(Binary files differ)
Property changes on: z3c.pypimirror/trunk/.bzr/repository/packs/f431359076136e5f0f3cdbe26c6958f0.pack
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: z3c.pypimirror/trunk/.bzr/repository/packs/fdf4e5ef10839aa0da2d6439c6549d69.pack
===================================================================
(Binary files differ)
Property changes on: z3c.pypimirror/trunk/.bzr/repository/packs/fdf4e5ef10839aa0da2d6439c6549d69.pack
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: z3c.pypimirror/trunk/.bzrignore
===================================================================
--- z3c.pypimirror/trunk/.bzrignore (rev 0)
+++ z3c.pypimirror/trunk/.bzrignore 2008-08-27 11:59:22 UTC (rev 90436)
@@ -0,0 +1,6 @@
+eggs
+bin
+develop-eggs
+parts
+src/z3c.pypimirror.egg-info
+.installed.cfg
Property changes on: z3c.pypimirror/trunk/.bzrignore
___________________________________________________________________
Name: svn:executable
+
Added: z3c.pypimirror/trunk/.installed.cfg
===================================================================
--- z3c.pypimirror/trunk/.installed.cfg (rev 0)
+++ z3c.pypimirror/trunk/.installed.cfg 2008-08-27 11:59:22 UTC (rev 90436)
@@ -0,0 +1,35 @@
+[buildout]
+installed_develop_eggs =
+parts = py test
+
+[py]
+__buildout_installed__ = /Users/ajung/src/z3c.pypimirror/bin/mirror
+ /Users/ajung/src/z3c.pypimirror/bin/py
+ /Users/ajung/src/z3c.pypimirror/bin/pypimirror
+__buildout_signature__ = zc.recipe.egg-1.1.0-py2.4.egg setuptools-0.6c8-py2.4.egg zc.buildout-1.1.1-py2.4.egg
+_b = /Users/ajung/src/z3c.pypimirror/bin
+_d = /Users/ajung/src/z3c.pypimirror/develop-eggs
+_e = /Users/ajung/.buildout/eggs
+bin-directory = /Users/ajung/src/z3c.pypimirror/bin
+develop-eggs-directory = /Users/ajung/src/z3c.pypimirror/develop-eggs
+eggs = z3c.pypimirror
+eggs-directory = /Users/ajung/.buildout/eggs
+executable = /opt/python-2.4.4/bin/python2.4
+interpreter = py
+recipe = zc.recipe.egg
+
+[test]
+__buildout_installed__ = /Users/ajung/src/z3c.pypimirror/parts/test
+ /Users/ajung/src/z3c.pypimirror/bin/test
+__buildout_signature__ = zc.recipe.testrunner-1.1.0-py2.4.egg zc.recipe.egg-1.1.0-py2.4.egg setuptools-0.6c8-py2.4.egg zope.testing-3.6.0-py2.4.egg zc.buildout-1.1.1-py2.4.egg zc.buildout-1.1.1-py2.4.egg zope.interface-3.4.1-py2.4-macosx-10.3-i386.egg
+_b = /Users/ajung/src/z3c.pypimirror/bin
+_d = /Users/ajung/src/z3c.pypimirror/develop-eggs
+_e = /Users/ajung/.buildout/eggs
+bin-directory = /Users/ajung/src/z3c.pypimirror/bin
+develop-eggs-directory = /Users/ajung/src/z3c.pypimirror/develop-eggs
+eggs = z3c.pypimirror[test]
+eggs-directory = /Users/ajung/.buildout/eggs
+executable = /opt/python-2.4.4/bin/python2.4
+location = /Users/ajung/src/z3c.pypimirror/parts/test
+recipe = zc.recipe.testrunner
+script = /Users/ajung/src/z3c.pypimirror/bin/test
Property changes on: z3c.pypimirror/trunk/.installed.cfg
___________________________________________________________________
Name: svn:executable
+
Added: z3c.pypimirror/trunk/CHANGES.txt
===================================================================
--- z3c.pypimirror/trunk/CHANGES.txt (rev 0)
+++ z3c.pypimirror/trunk/CHANGES.txt 2008-08-27 11:59:22 UTC (rev 90436)
@@ -0,0 +1,7 @@
+Change history
+~~~~~~~~~~~~~~
+
+0.1.0 (2008-08-27)
+------------------
+
+- initial release
Property changes on: z3c.pypimirror/trunk/CHANGES.txt
___________________________________________________________________
Name: svn:executable
+
Added: z3c.pypimirror/trunk/README.txt
===================================================================
--- z3c.pypimirror/trunk/README.txt (rev 0)
+++ z3c.pypimirror/trunk/README.txt 2008-08-27 11:59:22 UTC (rev 90436)
@@ -0,0 +1,19 @@
+Setting up a PyPI "simple" index
+================================
+
+This package provides a mirror for the PyPI simple interface,
+http://cheeseshop.python.org/simple/.
+
+To set up a mirror:
+
+- install this package using setuptools (easy_install, buildout, etc.)
+ so that the script, pypimirror script is installed.
+
+- create your mirror configuration file maybe based on config.cfg.sample
+
+- Run the pypimirror script passing the name of the mirror configuration
+ file
+
+ This will initialize the mirror.
+
+- Set up a cron job to run update-mirror periodically.
Added: z3c.pypimirror/trunk/ZPL.txt
===================================================================
--- z3c.pypimirror/trunk/ZPL.txt (rev 0)
+++ z3c.pypimirror/trunk/ZPL.txt 2008-08-27 11:59:22 UTC (rev 90436)
@@ -0,0 +1,59 @@
+Zope Public License (ZPL) Version 2.0
+-----------------------------------------------
+
+This software is Copyright (c) Zope Corporation (tm) and
+Contributors. All rights reserved.
+
+This license has been certified as open source. It has also
+been designated as GPL compatible by the Free Software
+Foundation (FSF).
+
+Redistribution and use in source and binary forms, with or
+without modification, are permitted provided that the
+following conditions are met:
+
+1. Redistributions in source code must retain the above
+ copyright notice, this list of conditions, and the following
+ disclaimer.
+
+2. Redistributions in binary form must reproduce the above
+ copyright notice, this list of conditions, and the following
+ disclaimer in the documentation and/or other materials
+ provided with the distribution.
+
+3. The name Zope Corporation (tm) must not be used to
+ endorse or promote products derived from this software
+ without prior written permission from Zope Corporation.
+
+4. The right to distribute this software or to use it for
+ any purpose does not give you the right to use Servicemarks
+ (sm) or Trademarks (tm) of Zope Corporation. Use of them is
+ covered in a separate agreement (see
+ http://www.zope.com/Marks).
+
+5. If any files are modified, you must cause the modified
+ files to carry prominent notices stating that you changed
+ the files and the date of any change.
+
+Disclaimer
+
+ THIS SOFTWARE IS PROVIDED BY ZOPE CORPORATION ``AS IS''
+ AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT
+ NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
+ NO EVENT SHALL ZOPE CORPORATION OR ITS CONTRIBUTORS BE
+ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+ DAMAGE.
+
+
+This software consists of contributions made by Zope
+Corporation and many individuals on behalf of Zope
+Corporation. Specific attributions are listed in the
+accompanying credits file.
Added: z3c.pypimirror/trunk/bootstrap.py
===================================================================
--- z3c.pypimirror/trunk/bootstrap.py (rev 0)
+++ z3c.pypimirror/trunk/bootstrap.py 2008-08-27 11:59:22 UTC (rev 90436)
@@ -0,0 +1,55 @@
+##############################################################################
+#
+# Copyright (c) 2006 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""Bootstrap a buildout-based project
+
+Simply run this script in a directory containing a buildout.cfg.
+The script accepts buildout command-line options, so you can
+use the -c option to specify an alternate configuration file.
+
+$Id: bootstrap.py 78032 2007-07-16 14:26:49Z jim $
+"""
+
+import os, shutil, sys, tempfile, urllib2
+
+tmpeggs = tempfile.mkdtemp()
+
+try:
+ import pkg_resources
+except ImportError:
+ ez = {}
+ exec urllib2.urlopen('http://peak.telecommunity.com/dist/ez_setup.py'
+ ).read() in ez
+ ez['use_setuptools'](to_dir=tmpeggs, download_delay=0)
+
+ import pkg_resources
+
+cmd = 'from setuptools.command.easy_install import main; main()'
+if sys.platform == 'win32':
+ cmd = '"%s"' % cmd # work around spawn lamosity on windows
+
+ws = pkg_resources.working_set
+assert os.spawnle(
+ os.P_WAIT, sys.executable, sys.executable,
+ '-c', cmd, '-mqNxd', tmpeggs, 'zc.buildout',
+ dict(os.environ,
+ PYTHONPATH=
+ ws.find(pkg_resources.Requirement.parse('setuptools')).location
+ ),
+ ) == 0
+
+ws.add_entry(tmpeggs)
+ws.require('zc.buildout')
+import zc.buildout.buildout
+zc.buildout.buildout.main(sys.argv[1:] + ['bootstrap'])
+shutil.rmtree(tmpeggs)
Property changes on: z3c.pypimirror/trunk/bootstrap.py
___________________________________________________________________
Name: svn:executable
+
Added: z3c.pypimirror/trunk/build/lib/z3c/__init__.py
===================================================================
--- z3c.pypimirror/trunk/build/lib/z3c/__init__.py (rev 0)
+++ z3c.pypimirror/trunk/build/lib/z3c/__init__.py 2008-08-27 11:59:22 UTC (rev 90436)
@@ -0,0 +1,2 @@
+# namespace package boilerplate
+__import__('pkg_resources').declare_namespace(__name__)
Added: z3c.pypimirror/trunk/build/lib/z3c/pypimirror/__init__.py
===================================================================
--- z3c.pypimirror/trunk/build/lib/z3c/pypimirror/__init__.py (rev 0)
+++ z3c.pypimirror/trunk/build/lib/z3c/pypimirror/__init__.py 2008-08-27 11:59:22 UTC (rev 90436)
@@ -0,0 +1,2 @@
+# namespace package boilerplate
+__import__('pkg_resources').declare_namespace(__name__)
Added: z3c.pypimirror/trunk/build/lib/z3c/pypimirror/mirror.py
===================================================================
--- z3c.pypimirror/trunk/build/lib/z3c/pypimirror/mirror.py (rev 0)
+++ z3c.pypimirror/trunk/build/lib/z3c/pypimirror/mirror.py 2008-08-27 11:59:22 UTC (rev 90436)
@@ -0,0 +1,561 @@
+import os
+import xmlrpclib
+import sys
+import util
+import urllib
+import urllib2
+import time
+import ConfigParser
+from glob import fnmatch
+from md5 import md5
+from BeautifulSoup import BeautifulSoup
+import zc.lockfile
+
+import socket
+# timeout in seconds
+timeout = 10
+socket.setdefaulttimeout(timeout)
+
+class Stats:
+ """ This is just for statistics """
+ def __init__(self):
+ self._found = []
+ self._stored = []
+ self._error_404 = []
+ self._error_invalid_package = []
+ self._error_invalid_url = []
+ self._starttime = time.time()
+
+ def runtime(self):
+ runtime = time.time() - self._starttime
+ if runtime > 60:
+ return "%dm%2ds" % (runtime//60, runtime%60)
+ return "%ds" % runtime
+
+ def found(self, name):
+ self._found.append(name)
+
+ def stored(self, name):
+ self._stored.append(name)
+
+ def error_404(self, name):
+ self._error_404.append(name)
+
+ def error_invalid_package(self, name):
+ self._error_invalid_package.append(name)
+
+ def error_invalid_url(self, name):
+ self._error_invalid_url.append(name)
+
+ def __str__(self):
+ ret = []
+ ret.append("Statistics")
+ ret.append("----------")
+ ret.append("Found (cached): %d" % len(self._found))
+ ret.append("Stored (downloaded): %d" % len(self._stored))
+ ret.append("Not found (404): %d" % len(self._error_404))
+ ret.append("Invalid packages: %d" % len(self._error_invalid_package))
+ ret.append("Invalid URLs: %d" % len(self._error_invalid_url))
+ ret.append("Runtime: %s" % self.runtime())
+ return "\n".join(ret)
+
+
+class PypiPackageList:
+ """
+ This fetches and represents a package list
+ """
+ def __init__(self, pypi_xmlrpc_url='http://pypi.python.org/pypi'):
+ self._pypi_xmlrpc_url = pypi_xmlrpc_url
+
+ def list(self, filter_by=None):
+ server = xmlrpclib.Server(self._pypi_xmlrpc_url)
+ packages = server.list_packages()
+ if not filter_by:
+ return packages
+
+ filtered_packages = []
+ for package in packages:
+ if not True in [fnmatch.fnmatch(package, f) for f in filter_by]:
+ continue
+ filtered_packages.append(package)
+ return filtered_packages
+
+
+class PackageError(Exception):
+ pass
+
+class Package:
+ """
+ This handles the list of versions and fetches the
+ files
+ """
+ def __init__(self, package_name, pypi_base_url="http://pypi.python.org/simple"):
+ self._links_cache = None
+
+ if not util.isASCII(package_name):
+ raise PackageError("%s is not a valid package name." % package_name)
+
+ try:
+ package_name = urllib.quote(package_name)
+ except KeyError:
+ raise PackageError("%s is not a valid package name." % package_name)
+
+ self.name = package_name
+ self._pypi_base_url = pypi_base_url
+
+ def url(self, filename=None, splittag=True):
+ if filename:
+ (filename, rest) = urllib.splittag(filename)
+ try:
+ filename = urllib.quote(filename)
+ except KeyError:
+ raise PackageError("%s is not a valid filename." % filename)
+ url = "%s/%s" % (self._pypi_base_url, self.name)
+ if filename:
+ url = "%s/%s" % (url, filename)
+ return url
+
+ def _fetch_index(self):
+ try:
+ html = urllib2.urlopen(self.url()).read()
+ except urllib2.HTTPError, v:
+ if '404' in str(v): # sigh
+ raise PackageError("Package not available: %s" % self.url())
+ return html
+
+ def _fetch_links(self, html):
+ soup = BeautifulSoup(html)
+ links = []
+ for link in soup.findAll("a"):
+ href = link.get("href")
+ if href:
+ links.append(href)
+ return links
+
+ def _links_external(self, html, filename_matches=None):
+ """ pypi has external "download_url"s. We try to get anything
+ from there too. This is really ugly and I'm not sure if there's
+ a sane way.
+ The download_url directs either to a website which contains many
+ download links or directly to a package.
+ """
+ download_links = set()
+ soup = BeautifulSoup(html)
+ links = soup.findAll("a")
+ for link in links:
+ if link.renderContents().endswith("download_url"):
+ # we have a download_url!! Yeah.
+ url = link.get("href")
+ if not url: continue
+ download_links.add(url)
+ for link in download_links:
+ # check if the link points directly to a file
+ # and get it if it matches filename_matches
+ if filename_matches:
+ if self.matches(link, filename_matches):
+ yield link
+ continue
+ # fetch what is behind the link and see if it's html.
+ # If it is html, download anything from there.
+ site = urllib2.urlopen(link)
+ if site.headers.type != "text/html":
+ continue
+
+ # we have a valid html page now. Parse links and download them.
+ # They have mostly no md5 hash.
+ html = site.read()
+ real_download_links = self._fetch_links(html)
+ for real_download_link in real_download_links:
+ # build absolute links
+ real_download_link = urllib.basejoin(site.url, real_download_link)
+ if not filename_matches or self.matches(real_download_link, filename_matches):
+ yield(real_download_link)
+
+
+ def _links(self, filename_matches=None, external_links=False):
+ """ This is an iterator which returns useful links on files for
+ mirroring
+ """
+ remote_index_html = self._fetch_index()
+ for link in self._fetch_links(remote_index_html):
+ # then handle "normal" packages in pypi.
+ (url, hash) = urllib.splittag(link)
+ if not hash:
+ continue
+ try:
+ (hashname, hash) = hash.split("=")
+ except ValueError:
+ continue
+ if not hashname == "md5":
+ continue
+
+ if filename_matches:
+ if not self.matches(url, filename_matches):
+ continue
+
+ yield (url, hash)
+
+ if external_links:
+ for link in self._links_external(remote_index_html, filename_matches):
+ yield (link, None)
+
+ def matches(self, filename, filename_matches):
+ for filename_match in filename_matches:
+ if fnmatch.fnmatch(filename, filename_match):
+ return True
+ return False
+
+ def ls(self, filename_matches=None, external_links=False):
+ links = self._links(filename_matches=filename_matches)
+ return [(link[0], os.path.basename(link[0]), link[1]) for link in links]
+
+ def _get(self, url, filename, md5_hex=None):
+ """ fetches a file and checks for the md5_hex if given
+ """
+ try:
+ data = urllib2.urlopen(url).read()
+ except urllib2.HTTPError, v:
+ if '404' in str(v): # sigh
+ raise PackageError("404: %s" % url)
+ except urllib2.URLError, v:
+ raise PackageError("URL Error: %s " % url)
+ if md5_hex:
+ # check for md5 checksum
+ data_md5 = md5(data).hexdigest()
+ if md5_hex != data_md5:
+ raise PackageError("MD5 sum does not match: %s / %s on package %s" %
+ (md5_hex, data_md5, url))
+ return data
+
+ def get(self, link):
+ """ link is a tuple of url, md5_hex
+ """
+ return self._get(*link)
+
+ def content_length(self, link):
+ try:
+ return long(urllib2.urlopen(link).headers.get("content-length"))
+ except:
+ return 0
+
+class Mirror:
+ """ This represents the whole mirror directory
+ """
+ def __init__(self, base_path):
+ self.base_path = base_path
+ self.mkdir()
+
+ def mkdir(self):
+ try:
+ os.mkdir(self.base_path)
+ except OSError:
+ # like "File exists"
+ pass
+
+ def package(self, package_name):
+ return MirrorPackage(self, package_name)
+
+ def cleanup(self, remote_list, verbose=False):
+ local_list = self.ls()
+ for local_dir in local_list:
+ try:
+ if local_dir not in remote_list:
+ if verbose:
+ print "Removing package: %s" % local_dir
+ self.rmr(os.path.join(self.base_path, local_dir))
+ except UnicodeDecodeError:
+ if verbose:
+ print "Removing package: %s" % local_dir
+ self.rmr(os.path.join(self.base_path, local_dir))
+
+ def rmr(self, path):
+ """ delete a package recursively (not really.)
+ """
+ # delete files
+ for filename in os.listdir(path):
+ os.unlink(os.path.join(path, filename))
+ # delete dir
+ os.rmdir(path)
+
+ def ls(self):
+ filenames = []
+ for filename in os.listdir(self.base_path):
+ if os.path.isdir(os.path.join(self.base_path, filename)):
+ filenames.append(filename)
+ return filenames
+
+ def _html_link(self, filename):
+ return "<a href='%s'>%s</a>" % (filename, filename)
+
+ def _index_html(self):
+ header = "<html><body><h1>PyPi Mirror</h1><h2>Last update: " + \
+ time.strftime("%c %Z")+"</h2>"
+ links = "<br />\n".join([self._html_link(link) for link in self.ls()])
+ footer = "</body></html>"
+ return "%s%s%s" % (header, links, footer)
+
+ def index_html(self):
+ content = self._index_html()
+ open(os.path.join(self.base_path, "index.html"), "wb").write(content)
+
+ def mirror(self, package_list, filename_matches, verbose, cleanup, create_indexes, external_links):
+ stats = Stats()
+ for package_name in package_list:
+ try:
+ package = Package(package_name)
+ except PackageError, v:
+ stats.error_invalid_package(package_name)
+ print "Package is not valid."
+ continue
+
+ try:
+ links = package.ls(filename_matches, external_links)
+ except PackageError, v:
+ stats.error_404(package_name)
+ print "Package not available: %s" % v
+ continue
+
+ mirror_package = self.package(package_name)
+
+ for link in links:
+ (url, filename, md5_hash) = link
+ if not md5_hash or not mirror_package.md5_match(filename, md5_hash):
+ # if we don't have a md5, check for the filesize, if available
+ # and continue if it's the same:
+ if not md5_hash:
+ remote_size = package.content_length(url)
+ if mirror_package.size_match(filename, remote_size):
+ if verbose: print "Found: %s" % filename
+ continue
+
+ try:
+ data = package.get(link)
+ except PackageError, v:
+ stats.error_invalid_url(link)
+ print "Invalid URL: %s" % v
+ continue
+
+ mirror_package.write(filename, data, md5_hash)
+ stats.stored(filename)
+ if verbose:
+ print "Stored: %s [%d kB]" % (filename, len(data)//1024)
+ else:
+ stats.found(filename)
+ if verbose:
+ print "Found: %s" % filename
+ if cleanup:
+ mirror_package.cleanup(links, verbose)
+ if create_indexes:
+ mirror_package.index_html()
+ if cleanup:
+ self.cleanup(package_list, verbose)
+ if create_indexes:
+ self.index_html()
+ print stats
+
+class MirrorPackage:
+ """ This checks for already existing files and creates the index
+ """
+ def __init__(self, mirror, package_name):
+ self.package_name = package_name
+ self.mirror = mirror
+ self.mkdir()
+
+ def mkdir(self):
+ try:
+ os.mkdir(self.path())
+ except OSError:
+ # like "File exists"
+ pass
+
+ def path(self, filename=None):
+ if not filename:
+ return os.path.join(self.mirror.base_path, self.package_name)
+ return os.path.join(self.mirror.base_path, self.package_name, filename)
+
+ def md5_match(self, filename, md5):
+ file = MirrorFile(self, filename)
+ return file.md5 == md5
+
+ def size_match(self, filename, size):
+ file = MirrorFile(self, filename)
+ return file.size == size
+
+ def write(self, filename, data, hash=""):
+ self.mkdir()
+ file = MirrorFile(self, filename)
+ file.write(data)
+ if hash:
+ file.write_md5(hash)
+
+ def rm(self, filename):
+ MirrorFile(self, filename).rm()
+
+ def ls(self):
+ filenames = []
+ for filename in os.listdir(self.path()):
+ if os.path.isfile(self.path(filename)) and filename != "index.html"\
+ and not filename.endswith(".md5"):
+ filenames.append(filename)
+ return filenames
+
+ def _html_link(self, filename, md5_hash):
+ return "<a href='%s#md5=%s'>%s</a>" % (filename, md5_hash, filename)
+
+ def _index_html(self):
+ header = "<html><body>"
+ footer = "</body></html>"
+
+ link_list = []
+ for link in self.ls():
+ file = MirrorFile(self, link)
+ md5_hash = file.md5
+ link_list.append(self._html_link(link, md5_hash))
+ links = "<br />\n".join(link_list)
+ return "%s%s%s" % (header, links, footer)
+
+ def index_html(self):
+ content = self._index_html()
+ self.write("index.html", content)
+
+ def cleanup(self, original_file_list, verbose=False):
+ remote_list = [link[1] for link in original_file_list]
+ local_list = self.ls()
+ for local_file in local_list:
+ if not local_file.endswith(".md5") and \
+ local_file not in remote_list:
+ if verbose:
+ print "Removing: %s" % local_file
+ self.rm(local_file)
+
+
+class MirrorFile:
+ """ This represents a mirrored file. It doesn't have to
+ exist.
+ """
+ def __init__(self, mirror_package, filename):
+ self.path = mirror_package.path(filename)
+
+ @property
+ def md5(self):
+ # use cached md5 sum if available.
+ if os.path.exists(self.md5_filename):
+ return open(self.md5_filename,"r").read()
+
+ if os.path.exists(self.path):
+ return md5(open(self.path, "rb").read()).hexdigest()
+ return None
+
+ @property
+ def size(self):
+ if os.path.exists(self.path):
+ return os.path.getsize(self.path)
+ return 0
+
+ def write(self, data):
+ open(self.path, "wb").write(data)
+
+ def rm(self):
+ """ deletes the file
+ """
+ if os.path.exists(self.path):
+ os.unlink(self.path)
+ if os.path.exists(self.md5_filename):
+ os.unlink(self.md5_filename)
+
+ def write_md5(self, hash):
+ md5_filename = ".%s.md5" % os.path.basename(self.path)
+ md5_path = os.path.dirname(self.path)
+ open(os.path.join(md5_path, md5_filename),"w").write(hash)
+
+ @property
+ def md5_filename(self):
+ md5_filename = ".%s.md5" % os.path.basename(self.path)
+ md5_path = os.path.dirname(self.path)
+ return os.path.join(md5_path, md5_filename)
+
+
+
+
+
+
+################# Config file parser
+
+config_defaults = {
+ 'mirror_file_path': '/tmp/mirror',
+ 'lock_file_name': 'pypi-poll-access.lock',
+ 'filename_matches': '*.zip *.tgz *.egg *.tar.gz *.tar.bz2', # may be "" for *
+ 'package_matches': "zope.app.* plone.app.*", # may be "" for *
+ 'cleanup': True, # delete local copies that are remotely not available
+ 'create_indexes': True, # create index.html files
+ 'verbose': True, # log output
+ 'external_links': False, # experimental external link resolve and download
+}
+
+def get_config_options(config_filename):
+ """
+ Get options from the DEFAULT section of our config file
+
+ @param dest
+ Directory configuration file
+
+ @return
+ dict containing a key per option
+ values are not reformatted - especially multiline options contain
+ newlines
+ this contains at least the following key/values:
+ - include - Glob-Patterns for package names to include
+ - suffixes - list of suffixes to mirror
+ """
+ if not os.path.exists(config_filename):
+ return config_defaults
+
+ config = ConfigParser.ConfigParser(config_defaults)
+ config.read(config_filename)
+ return config.defaults()
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+def run(args=None):
+ if args is None:
+ args = sys.argv[1:]
+
+ if len(args) != 1:
+ print "Usage: mirror <config-file>"
+ sys.exit(1)
+
+ config_file_name = os.path.abspath(args[0])
+ config = get_config_options(config_file_name)
+
+ # correct things from config
+ filename_matches = config["filename_matches"].split()
+ package_matches = config["package_matches"].split()
+ cleanup = config["cleanup"] in ("True", "1")
+ create_indexes = config["create_indexes"] in ("True", "1")
+ verbose = config["verbose"] in ("True", "1")
+ external_links = config["external_links"] in ("True", "1")
+
+ package_list = PypiPackageList().list(package_matches)
+ mirror = Mirror(config["mirror_file_path"])
+ lock = zc.lockfile.LockFile(os.path.join(config["mirror_file_path"], config["lock_file_name"]))
+ mirror.mirror(package_list, filename_matches, verbose, cleanup, create_indexes, external_links)
+
+
Added: z3c.pypimirror/trunk/build/lib/z3c/pypimirror/pypimirror.cfg.sample
===================================================================
--- z3c.pypimirror/trunk/build/lib/z3c/pypimirror/pypimirror.cfg.sample (rev 0)
+++ z3c.pypimirror/trunk/build/lib/z3c/pypimirror/pypimirror.cfg.sample 2008-08-27 11:59:22 UTC (rev 90436)
@@ -0,0 +1,34 @@
+[DEFAULT]
+# the root folder of all mirrored packages.
+# if necessary it will be created for you
+mirror_file_path = /tmp/mirror
+
+# ???
+lock_file_name = pypi-poll-access.lock
+
+# Pattern for package files, only those matching will be mirrored
+filename_matches =
+ *.zip
+ *.tgz
+ *.egg
+ *.tar.gz
+ *.tar.bz2
+
+# Pattern for package names; only packages having matching names will
+# be mirrored
+package_matches =
+ zope.app.*
+ plone.app.*
+
+# remove packages not on pypi anymore
+cleanup = True
+
+# create index.html files
+create_indexes = True
+
+# be more verbose
+verbose = True
+
+# This is highly experimental and shouldn't be used right now.
+external_links = False
+
Added: z3c.pypimirror/trunk/build/lib/z3c/pypimirror/tests.py
===================================================================
--- z3c.pypimirror/trunk/build/lib/z3c/pypimirror/tests.py (rev 0)
+++ z3c.pypimirror/trunk/build/lib/z3c/pypimirror/tests.py 2008-08-27 11:59:22 UTC (rev 90436)
@@ -0,0 +1,61 @@
+# *-* coding: iso-8859-15 *-*
+"""
+Test runner for 'z3c.pypimirror'.
+"""
+__docformat__ = 'restructuredtext'
+
+import unittest
+import zc.buildout.tests
+import zc.buildout.testing
+
+from zope.testing import doctest, renormalizing
+
+optionflags = (doctest.ELLIPSIS |
+ doctest.NORMALIZE_WHITESPACE |
+ doctest.REPORT_ONLY_FIRST_FAILURE)
+import util
+
+
+class UtilityTests(unittest.TestCase):
+
+ def testIsAscii(self):
+
+ self.assertEqual(util.isASCII('foo'), True)
+ self.assertEqual(util.isASCII(u'foo'), True)
+ self.assertEqual(util.isASCII('üöä'), False)
+ self.assertEqual(util.isASCII(u'üöä'), False)
+ self.assertRaises(TypeError, util.isASCII, 2)
+
+
+def setUp(test):
+ zc.buildout.testing.buildoutSetUp(test)
+
+ # Install the recipe in develop mode
+ # zc.buildout.testing.install_develop('boing', test)
+
+ # Install any other recipes that should be available in the tests
+ #zc.buildout.testing.install('collective.recipe.foobar', test)
+
+def test_suite():
+ suite = unittest.TestSuite((
+ doctest.DocFileSuite(
+ 'README.txt',
+ setUp=setUp,
+ tearDown=zc.buildout.testing.buildoutTearDown,
+ optionflags=optionflags,
+ checker=renormalizing.RENormalizing([
+ # If want to clean up the doctest output you
+ # can register additional regexp normalizers
+ # here. The format is a two-tuple with the RE
+ # as the first item and the replacement as the
+ # second item, e.g.
+ # (re.compile('my-[rR]eg[eE]ps'), 'my-regexps')
+ zc.buildout.testing.normalize_path,
+ ]),
+ ),
+ ))
+ suite.addTest(unittest.makeSuite(UtilityTests))
+ return suite
+
+if __name__ == '__main__':
+ unittest.main(defaultTest='test_suite')
Added: z3c.pypimirror/trunk/build/lib/z3c/pypimirror/util.py
===================================================================
--- z3c.pypimirror/trunk/build/lib/z3c/pypimirror/util.py (rev 0)
+++ z3c.pypimirror/trunk/build/lib/z3c/pypimirror/util.py 2008-08-27 11:59:22 UTC (rev 90436)
@@ -0,0 +1,22 @@
+
+
+def isASCII(s):
+ """ Checks if a string/unicode string contains only ASCII chars. """
+
+ if isinstance(s, unicode):
+ try:
+ s.encode('ascii')
+ return True
+ except UnicodeError:
+ return False
+
+ elif isinstance(s, str):
+ try:
+ unicode(s, 'ascii')
+ return True
+ except UnicodeError:
+ return False
+
+ else:
+ raise TypeError('isASCII() requires a string or unicode string')
+
Added: z3c.pypimirror/trunk/buildout.cfg
===================================================================
--- z3c.pypimirror/trunk/buildout.cfg (rev 0)
+++ z3c.pypimirror/trunk/buildout.cfg 2008-08-27 11:59:22 UTC (rev 90436)
@@ -0,0 +1,12 @@
+[buildout]
+parts = py test
+develop = .
+
+[py]
+recipe = zc.recipe.egg
+eggs = z3c.pypimirror
+interpreter = py
+
+[test]
+recipe = zc.recipe.testrunner
+eggs = z3c.pypimirror[test]
Added: z3c.pypimirror/trunk/dist/z3c.pypimirror-0.1.0-py2.4.egg
===================================================================
(Binary files differ)
Property changes on: z3c.pypimirror/trunk/dist/z3c.pypimirror-0.1.0-py2.4.egg
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: z3c.pypimirror/trunk/dist/z3c.pypimirror-0.1.0.tar.gz
===================================================================
(Binary files differ)
Property changes on: z3c.pypimirror/trunk/dist/z3c.pypimirror-0.1.0.tar.gz
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: z3c.pypimirror/trunk/setup.py
===================================================================
--- z3c.pypimirror/trunk/setup.py (rev 0)
+++ z3c.pypimirror/trunk/setup.py 2008-08-27 11:59:22 UTC (rev 90436)
@@ -0,0 +1,43 @@
+from setuptools import setup, find_packages, find_packages
+
+
+CLASSIFIERS = [
+ 'Development Status :: 5 - Production/Stable',
+ 'Intended Audience :: Developers',
+ 'License :: OSI Approved :: Zope Public License',
+ 'Operating System :: OS Independent',
+ 'Programming Language :: Python',
+]
+
+desc = open('README.txt').read().strip()
+changes = open('CHANGES.txt').read().strip()
+long_description = desc + '\n\nChanges\n=======\n\n' + changes
+
+setup(
+ name='z3c.pypimirror',
+ version='0.1.0',
+ author='Daniel Kraft et al.',
+ author_email='dk at d9t.de',
+ description='A module for building a complete or a partial PyPI mirror',
+ long_description=long_description,
+ maintainer='Daniel Kraft et al.',
+ maintainer_email='dk at d9t.de',
+ classifiers=CLASSIFIERS,
+ package_dir = {'': 'src'},
+ namespace_packages=['z3c', 'z3c.pypimirror'],
+ packages=find_packages('src'),
+ include_package_data=True,
+ zip_safe=False,
+ package_data = {
+ '': ['*.sample'],
+ },
+ install_requires = ['setuptools',
+ 'zc.lockfile',
+ 'BeautifulSoup'],
+ extras_require = {
+ 'test': [ 'zc.buildout' ],
+ },
+ entry_points = dict(console_scripts=[
+ 'pypimirror = z3c.pypimirror.mirror:run',
+ ])
+ )
Added: z3c.pypimirror/trunk/src/z3c/__init__.py
===================================================================
--- z3c.pypimirror/trunk/src/z3c/__init__.py (rev 0)
+++ z3c.pypimirror/trunk/src/z3c/__init__.py 2008-08-27 11:59:22 UTC (rev 90436)
@@ -0,0 +1,2 @@
+# namespace package boilerplate
+__import__('pkg_resources').declare_namespace(__name__)
Property changes on: z3c.pypimirror/trunk/src/z3c/__init__.py
___________________________________________________________________
Name: svn:executable
+
Added: z3c.pypimirror/trunk/src/z3c/pypimirror/README.txt
===================================================================
--- z3c.pypimirror/trunk/src/z3c/pypimirror/README.txt (rev 0)
+++ z3c.pypimirror/trunk/src/z3c/pypimirror/README.txt 2008-08-27 11:59:22 UTC (rev 90436)
@@ -0,0 +1,95 @@
+z3c.pypimirror
+==============
+
+>>> import os, sys
+
+First we try to get a list from pypi, to test xmlrpc connection.
+
+>>> packageprefix = 'zope.app.c'
+>>> from z3c.pypimirror.mirror import PypiPackageList, Mirror, Package
+>>> pypi_pl = PypiPackageList()
+>>> pypi_list = pypi_pl.list()
+>>> pypi_list2 = pypi_pl.list([packageprefix + '*'])
+>>> False not in [item.startswith(packageprefix) for item in pypi_list2]
+True
+>>> len(pypi_list) > len(pypi_list2)
+True
+
+If we got an list from pypi we try parse the output and download a
+file.
+
+>>> mirror = Mirror(join(sample_buildout, "mirror"))
+>>> packagename = pypi_list2[0]
+>>> package = Package(packagename)
+>>> mirrorpackage = mirror.package(packagename)
+>>> file = package.ls()[0]
+>>> data = package.get(file)
+>>> mirrorpackage.write(file[1], data)
+>>> packagename in os.listdir(join(sample_buildout, 'mirror'))
+True
+
+Now we create a `index.html` for the package.
+
+>>> mirrorpackage.index_html()
+>>> path_package_index = mirrorpackage.path('index.html')
+>>> packagename in open(path_package_index, 'r').read()
+True
+
+Now we create a `index.html` for the mirror.
+
+>>> mirror.index_html()
+>>> path_index = join(mirror.base_path, 'index.html')
+>>> packagename in open(path_index, 'r').read()
+True
+
+If a file is not on the mirror and cleanup is activated it will
+be removed. First we add a dummy file.
+
+>>> write(mirrorpackage.path(), 'dummy.egg',
+... """
+... Banane
+... """)
+>>> ls(mirrorpackage.path())
+- dummy.egg
+...
+>>> mirrorpackage.cleanup([file,])
+>>> 'dummy.egg' not in os.listdir(mirrorpackage.path())
+True
+
+
+Now we're trying everything in concert
+
+First cleanup a bit
+
+>>> remove(mirrorpackage.path())
+>>> packagename in os.listdir(join(sample_buildout, 'mirror'))
+False
+
+Create a configuration involving our mirror path
+
+>>> cfg = join (mirror.base_path, 'mirror.cfg')
+>>> write(cfg, """
+... [DEFAULT]
+... mirror_file_path = %s
+... package_matches =
+... %s
+... """ % (mirror.base_path, packagename))
+
+Generate a script (don't know how to use the one generated by buildout)
+
+>>> write ('pypimirror.py',
+... '''
+... import sys
+... sys.path[:] = [
+... "%s"
+... ]
+... from z3c.pypimirror.mirror import run
+... run()
+... ''' % '",\n "'.join (sys.path))
+
+Let it run ...
+
+>>> system('%s pypimirror.py %s' % (sys.executable, cfg))
+'Statistics...
+>>> packagename in os.listdir(join(sample_buildout, 'mirror'))
+True
Property changes on: z3c.pypimirror/trunk/src/z3c/pypimirror/README.txt
___________________________________________________________________
Name: svn:executable
+
Added: z3c.pypimirror/trunk/src/z3c/pypimirror/__init__.py
===================================================================
--- z3c.pypimirror/trunk/src/z3c/pypimirror/__init__.py (rev 0)
+++ z3c.pypimirror/trunk/src/z3c/pypimirror/__init__.py 2008-08-27 11:59:22 UTC (rev 90436)
@@ -0,0 +1,2 @@
+# namespace package boilerplate
+__import__('pkg_resources').declare_namespace(__name__)
Property changes on: z3c.pypimirror/trunk/src/z3c/pypimirror/__init__.py
___________________________________________________________________
Name: svn:executable
+
Added: z3c.pypimirror/trunk/src/z3c/pypimirror/mirror.py
===================================================================
--- z3c.pypimirror/trunk/src/z3c/pypimirror/mirror.py (rev 0)
+++ z3c.pypimirror/trunk/src/z3c/pypimirror/mirror.py 2008-08-27 11:59:22 UTC (rev 90436)
@@ -0,0 +1,561 @@
+import os
+import xmlrpclib
+import sys
+import util
+import urllib
+import urllib2
+import time
+import ConfigParser
+from glob import fnmatch
+from md5 import md5
+from BeautifulSoup import BeautifulSoup
+import zc.lockfile
+
+import socket
+# timeout in seconds
+timeout = 10
+socket.setdefaulttimeout(timeout)
+
+class Stats:
+ """ This is just for statistics """
+ def __init__(self):
+ self._found = []
+ self._stored = []
+ self._error_404 = []
+ self._error_invalid_package = []
+ self._error_invalid_url = []
+ self._starttime = time.time()
+
+ def runtime(self):
+ runtime = time.time() - self._starttime
+ if runtime > 60:
+ return "%dm%2ds" % (runtime//60, runtime%60)
+ return "%ds" % runtime
+
+ def found(self, name):
+ self._found.append(name)
+
+ def stored(self, name):
+ self._stored.append(name)
+
+ def error_404(self, name):
+ self._error_404.append(name)
+
+ def error_invalid_package(self, name):
+ self._error_invalid_package.append(name)
+
+ def error_invalid_url(self, name):
+ self._error_invalid_url.append(name)
+
+ def __str__(self):
+ ret = []
+ ret.append("Statistics")
+ ret.append("----------")
+ ret.append("Found (cached): %d" % len(self._found))
+ ret.append("Stored (downloaded): %d" % len(self._stored))
+ ret.append("Not found (404): %d" % len(self._error_404))
+ ret.append("Invalid packages: %d" % len(self._error_invalid_package))
+ ret.append("Invalid URLs: %d" % len(self._error_invalid_url))
+ ret.append("Runtime: %s" % self.runtime())
+ return "\n".join(ret)
+
+
+class PypiPackageList:
+ """
+ This fetches and represents a package list
+ """
+ def __init__(self, pypi_xmlrpc_url='http://pypi.python.org/pypi'):
+ self._pypi_xmlrpc_url = pypi_xmlrpc_url
+
+ def list(self, filter_by=None):
+ server = xmlrpclib.Server(self._pypi_xmlrpc_url)
+ packages = server.list_packages()
+ if not filter_by:
+ return packages
+
+ filtered_packages = []
+ for package in packages:
+ if not True in [fnmatch.fnmatch(package, f) for f in filter_by]:
+ continue
+ filtered_packages.append(package)
+ return filtered_packages
+
+
+class PackageError(Exception):
+ pass
+
+class Package:
+ """
+ This handles the list of versions and fetches the
+ files
+ """
+ def __init__(self, package_name, pypi_base_url="http://pypi.python.org/simple"):
+ self._links_cache = None
+
+ if not util.isASCII(package_name):
+ raise PackageError("%s is not a valid package name." % package_name)
+
+ try:
+ package_name = urllib.quote(package_name)
+ except KeyError:
+ raise PackageError("%s is not a valid package name." % package_name)
+
+ self.name = package_name
+ self._pypi_base_url = pypi_base_url
+
+ def url(self, filename=None, splittag=True):
+ if filename:
+ (filename, rest) = urllib.splittag(filename)
+ try:
+ filename = urllib.quote(filename)
+ except KeyError:
+ raise PackageError("%s is not a valid filename." % filename)
+ url = "%s/%s" % (self._pypi_base_url, self.name)
+ if filename:
+ url = "%s/%s" % (url, filename)
+ return url
+
+ def _fetch_index(self):
+ try:
+ html = urllib2.urlopen(self.url()).read()
+ except urllib2.HTTPError, v:
+ if '404' in str(v): # sigh
+ raise PackageError("Package not available: %s" % self.url())
+ return html
+
+ def _fetch_links(self, html):
+ soup = BeautifulSoup(html)
+ links = []
+ for link in soup.findAll("a"):
+ href = link.get("href")
+ if href:
+ links.append(href)
+ return links
+
+ def _links_external(self, html, filename_matches=None):
+ """ pypi has external "download_url"s. We try to get anything
+ from there too. This is really ugly and I'm not sure if there's
+ a sane way.
+ The download_url directs either to a website which contains many
+ download links or directly to a package.
+ """
+ download_links = set()
+ soup = BeautifulSoup(html)
+ links = soup.findAll("a")
+ for link in links:
+ if link.renderContents().endswith("download_url"):
+ # we have a download_url!! Yeah.
+ url = link.get("href")
+ if not url: continue
+ download_links.add(url)
+ for link in download_links:
+ # check if the link points directly to a file
+ # and get it if it matches filename_matches
+ if filename_matches:
+ if self.matches(link, filename_matches):
+ yield link
+ continue
+ # fetch what is behind the link and see if it's html.
+ # If it is html, download anything from there.
+ site = urllib2.urlopen(link)
+ if site.headers.type != "text/html":
+ continue
+
+ # we have a valid html page now. Parse links and download them.
+ # They have mostly no md5 hash.
+ html = site.read()
+ real_download_links = self._fetch_links(html)
+ for real_download_link in real_download_links:
+ # build absolute links
+ real_download_link = urllib.basejoin(site.url, real_download_link)
+ if not filename_matches or self.matches(real_download_link, filename_matches):
+ yield(real_download_link)
+
+
+ def _links(self, filename_matches=None, external_links=False):
+ """ This is an iterator which returns useful links on files for
+ mirroring
+ """
+ remote_index_html = self._fetch_index()
+ for link in self._fetch_links(remote_index_html):
+ # then handle "normal" packages in pypi.
+ (url, hash) = urllib.splittag(link)
+ if not hash:
+ continue
+ try:
+ (hashname, hash) = hash.split("=")
+ except ValueError:
+ continue
+ if not hashname == "md5":
+ continue
+
+ if filename_matches:
+ if not self.matches(url, filename_matches):
+ continue
+
+ yield (url, hash)
+
+ if external_links:
+ for link in self._links_external(remote_index_html, filename_matches):
+ yield (link, None)
+
+ def matches(self, filename, filename_matches):
+ for filename_match in filename_matches:
+ if fnmatch.fnmatch(filename, filename_match):
+ return True
+ return False
+
+ def ls(self, filename_matches=None, external_links=False):
+ links = self._links(filename_matches=filename_matches)
+ return [(link[0], os.path.basename(link[0]), link[1]) for link in links]
+
+ def _get(self, url, filename, md5_hex=None):
+ """ fetches a file and checks for the md5_hex if given
+ """
+ try:
+ data = urllib2.urlopen(url).read()
+ except urllib2.HTTPError, v:
+ if '404' in str(v): # sigh
+ raise PackageError("404: %s" % url)
+ except urllib2.URLError, v:
+ raise PackageError("URL Error: %s " % url)
+ if md5_hex:
+ # check for md5 checksum
+ data_md5 = md5(data).hexdigest()
+ if md5_hex != data_md5:
+ raise PackageError("MD5 sum does not match: %s / %s on package %s" %
+ (md5_hex, data_md5, url))
+ return data
+
+ def get(self, link):
+ """ link is a tuple of url, md5_hex
+ """
+ return self._get(*link)
+
+ def content_length(self, link):
+ try:
+ return long(urllib2.urlopen(link).headers.get("content-length"))
+ except:
+ return 0
+
+class Mirror:
+ """ This represents the whole mirror directory
+ """
+ def __init__(self, base_path):
+ self.base_path = base_path
+ self.mkdir()
+
+ def mkdir(self):
+ try:
+ os.mkdir(self.base_path)
+ except OSError:
+ # like "File exists"
+ pass
+
+ def package(self, package_name):
+ return MirrorPackage(self, package_name)
+
+ def cleanup(self, remote_list, verbose=False):
+ local_list = self.ls()
+ for local_dir in local_list:
+ try:
+ if local_dir not in remote_list:
+ if verbose:
+ print "Removing package: %s" % local_dir
+ self.rmr(os.path.join(self.base_path, local_dir))
+ except UnicodeDecodeError:
+ if verbose:
+ print "Removing package: %s" % local_dir
+ self.rmr(os.path.join(self.base_path, local_dir))
+
+ def rmr(self, path):
+ """ delete a package recursively (not really.)
+ """
+ # delete files
+ for filename in os.listdir(path):
+ os.unlink(os.path.join(path, filename))
+ # delete dir
+ os.rmdir(path)
+
+ def ls(self):
+ filenames = []
+ for filename in os.listdir(self.base_path):
+ if os.path.isdir(os.path.join(self.base_path, filename)):
+ filenames.append(filename)
+ return filenames
+
+ def _html_link(self, filename):
+ return "<a href='%s'>%s</a>" % (filename, filename)
+
+ def _index_html(self):
+ header = "<html><body><h1>PyPi Mirror</h1><h2>Last update: " + \
+ time.strftime("%c %Z")+"</h2>"
+ links = "<br />\n".join([self._html_link(link) for link in self.ls()])
+ footer = "</body></html>"
+ return "%s%s%s" % (header, links, footer)
+
+ def index_html(self):
+ content = self._index_html()
+ open(os.path.join(self.base_path, "index.html"), "wb").write(content)
+
+ def mirror(self, package_list, filename_matches, verbose, cleanup, create_indexes, external_links):
+ stats = Stats()
+ for package_name in package_list:
+ try:
+ package = Package(package_name)
+ except PackageError, v:
+ stats.error_invalid_package(package_name)
+ print "Package is not valid."
+ continue
+
+ try:
+ links = package.ls(filename_matches, external_links)
+ except PackageError, v:
+ stats.error_404(package_name)
+ print "Package not available: %s" % v
+ continue
+
+ mirror_package = self.package(package_name)
+
+ for link in links:
+ (url, filename, md5_hash) = link
+ if not md5_hash or not mirror_package.md5_match(filename, md5_hash):
+ # if we don't have a md5, check for the filesize, if available
+ # and continue if it's the same:
+ if not md5_hash:
+ remote_size = package.content_length(url)
+ if mirror_package.size_match(filename, remote_size):
+ if verbose: print "Found: %s" % filename
+ continue
+
+ try:
+ data = package.get(link)
+ except PackageError, v:
+ stats.error_invalid_url(link)
+ print "Invalid URL: %s" % v
+ continue
+
+ mirror_package.write(filename, data, md5_hash)
+ stats.stored(filename)
+ if verbose:
+ print "Stored: %s [%d kB]" % (filename, len(data)//1024)
+ else:
+ stats.found(filename)
+ if verbose:
+ print "Found: %s" % filename
+ if cleanup:
+ mirror_package.cleanup(links, verbose)
+ if create_indexes:
+ mirror_package.index_html()
+ if cleanup:
+ self.cleanup(package_list, verbose)
+ if create_indexes:
+ self.index_html()
+ print stats
+
+class MirrorPackage:
+ """ This checks for already existing files and creates the index
+ """
+ def __init__(self, mirror, package_name):
+ self.package_name = package_name
+ self.mirror = mirror
+ self.mkdir()
+
+ def mkdir(self):
+ try:
+ os.mkdir(self.path())
+ except OSError:
+ # like "File exists"
+ pass
+
+ def path(self, filename=None):
+ if not filename:
+ return os.path.join(self.mirror.base_path, self.package_name)
+ return os.path.join(self.mirror.base_path, self.package_name, filename)
+
+ def md5_match(self, filename, md5):
+ file = MirrorFile(self, filename)
+ return file.md5 == md5
+
+ def size_match(self, filename, size):
+ file = MirrorFile(self, filename)
+ return file.size == size
+
+ def write(self, filename, data, hash=""):
+ self.mkdir()
+ file = MirrorFile(self, filename)
+ file.write(data)
+ if hash:
+ file.write_md5(hash)
+
+ def rm(self, filename):
+ MirrorFile(self, filename).rm()
+
+ def ls(self):
+ filenames = []
+ for filename in os.listdir(self.path()):
+ if os.path.isfile(self.path(filename)) and filename != "index.html"\
+ and not filename.endswith(".md5"):
+ filenames.append(filename)
+ return filenames
+
+ def _html_link(self, filename, md5_hash):
+ return "<a href='%s#md5=%s'>%s</a>" % (filename, md5_hash, filename)
+
+ def _index_html(self):
+ header = "<html><body>"
+ footer = "</body></html>"
+
+ link_list = []
+ for link in self.ls():
+ file = MirrorFile(self, link)
+ md5_hash = file.md5
+ link_list.append(self._html_link(link, md5_hash))
+ links = "<br />\n".join(link_list)
+ return "%s%s%s" % (header, links, footer)
+
+ def index_html(self):
+ content = self._index_html()
+ self.write("index.html", content)
+
+ def cleanup(self, original_file_list, verbose=False):
+ remote_list = [link[1] for link in original_file_list]
+ local_list = self.ls()
+ for local_file in local_list:
+ if not local_file.endswith(".md5") and \
+ local_file not in remote_list:
+ if verbose:
+ print "Removing: %s" % local_file
+ self.rm(local_file)
+
+
+class MirrorFile:
+ """ This represents a mirrored file. It doesn't have to
+ exist.
+ """
+ def __init__(self, mirror_package, filename):
+ self.path = mirror_package.path(filename)
+
+ @property
+ def md5(self):
+ # use cached md5 sum if available.
+ if os.path.exists(self.md5_filename):
+ return open(self.md5_filename,"r").read()
+
+ if os.path.exists(self.path):
+ return md5(open(self.path, "rb").read()).hexdigest()
+ return None
+
+ @property
+ def size(self):
+ if os.path.exists(self.path):
+ return os.path.getsize(self.path)
+ return 0
+
+ def write(self, data):
+ open(self.path, "wb").write(data)
+
+ def rm(self):
+ """ deletes the file
+ """
+ if os.path.exists(self.path):
+ os.unlink(self.path)
+ if os.path.exists(self.md5_filename):
+ os.unlink(self.md5_filename)
+
+ def write_md5(self, hash):
+ md5_filename = ".%s.md5" % os.path.basename(self.path)
+ md5_path = os.path.dirname(self.path)
+ open(os.path.join(md5_path, md5_filename),"w").write(hash)
+
+ @property
+ def md5_filename(self):
+ md5_filename = ".%s.md5" % os.path.basename(self.path)
+ md5_path = os.path.dirname(self.path)
+ return os.path.join(md5_path, md5_filename)
+
+
+
+
+
+
+################# Config file parser
+
+config_defaults = {
+ 'mirror_file_path': '/tmp/mirror',
+ 'lock_file_name': 'pypi-poll-access.lock',
+ 'filename_matches': '*.zip *.tgz *.egg *.tar.gz *.tar.bz2', # may be "" for *
+ 'package_matches': "zope.app.* plone.app.*", # may be "" for *
+ 'cleanup': True, # delete local copies that are remotely not available
+ 'create_indexes': True, # create index.html files
+ 'verbose': True, # log output
+ 'external_links': False, # experimental external link resolve and download
+}
+
+def get_config_options(config_filename):
+ """
+ Get options from the DEFAULT section of our config file
+
+ @param dest
+ Directory configuration file
+
+ @return
+ dict containing a key per option
+ values are not reformatted - especially multiline options contain
+ newlines
+ this contains at least the following key/values:
+ - include - Glob-Patterns for package names to include
+ - suffixes - list of suffixes to mirror
+ """
+ if not os.path.exists(config_filename):
+ return config_defaults
+
+ config = ConfigParser.ConfigParser(config_defaults)
+ config.read(config_filename)
+ return config.defaults()
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+def run(args=None):
+ if args is None:
+ args = sys.argv[1:]
+
+ if len(args) != 1:
+ print "Usage: mirror <config-file>"
+ sys.exit(1)
+
+ config_file_name = os.path.abspath(args[0])
+ config = get_config_options(config_file_name)
+
+ # correct things from config
+ filename_matches = config["filename_matches"].split()
+ package_matches = config["package_matches"].split()
+ cleanup = config["cleanup"] in ("True", "1")
+ create_indexes = config["create_indexes"] in ("True", "1")
+ verbose = config["verbose"] in ("True", "1")
+ external_links = config["external_links"] in ("True", "1")
+
+ package_list = PypiPackageList().list(package_matches)
+ mirror = Mirror(config["mirror_file_path"])
+ lock = zc.lockfile.LockFile(os.path.join(config["mirror_file_path"], config["lock_file_name"]))
+ mirror.mirror(package_list, filename_matches, verbose, cleanup, create_indexes, external_links)
+
+
Added: z3c.pypimirror/trunk/src/z3c/pypimirror/pypimirror.cfg.sample
===================================================================
--- z3c.pypimirror/trunk/src/z3c/pypimirror/pypimirror.cfg.sample (rev 0)
+++ z3c.pypimirror/trunk/src/z3c/pypimirror/pypimirror.cfg.sample 2008-08-27 11:59:22 UTC (rev 90436)
@@ -0,0 +1,34 @@
+[DEFAULT]
+# the root folder of all mirrored packages.
+# if necessary it will be created for you
+mirror_file_path = /tmp/mirror
+
+# ???
+lock_file_name = pypi-poll-access.lock
+
+# Pattern for package files, only those matching will be mirrored
+filename_matches =
+ *.zip
+ *.tgz
+ *.egg
+ *.tar.gz
+ *.tar.bz2
+
+# Pattern for package names; only packages having matching names will
+# be mirrored
+package_matches =
+ zope.app.*
+ plone.app.*
+
+# remove packages not on pypi anymore
+cleanup = True
+
+# create index.html files
+create_indexes = True
+
+# be more verbose
+verbose = True
+
+# This is highly experimental and shouldn't be used right now.
+external_links = False
+
Added: z3c.pypimirror/trunk/src/z3c/pypimirror/tests.py
===================================================================
--- z3c.pypimirror/trunk/src/z3c/pypimirror/tests.py (rev 0)
+++ z3c.pypimirror/trunk/src/z3c/pypimirror/tests.py 2008-08-27 11:59:22 UTC (rev 90436)
@@ -0,0 +1,61 @@
+# *-* coding: iso-8859-15 *-*
+"""
+Test runner for 'z3c.pypimirror'.
+"""
+__docformat__ = 'restructuredtext'
+
+import unittest
+import zc.buildout.tests
+import zc.buildout.testing
+
+from zope.testing import doctest, renormalizing
+
+optionflags = (doctest.ELLIPSIS |
+ doctest.NORMALIZE_WHITESPACE |
+ doctest.REPORT_ONLY_FIRST_FAILURE)
+import util
+
+
+class UtilityTests(unittest.TestCase):
+
+ def testIsAscii(self):
+
+ self.assertEqual(util.isASCII('foo'), True)
+ self.assertEqual(util.isASCII(u'foo'), True)
+ self.assertEqual(util.isASCII('üöä'), False)
+ self.assertEqual(util.isASCII(u'üöä'), False)
+ self.assertRaises(TypeError, util.isASCII, 2)
+
+
+def setUp(test):
+ zc.buildout.testing.buildoutSetUp(test)
+
+ # Install the recipe in develop mode
+ # zc.buildout.testing.install_develop('boing', test)
+
+ # Install any other recipes that should be available in the tests
+ #zc.buildout.testing.install('collective.recipe.foobar', test)
+
+def test_suite():
+ suite = unittest.TestSuite((
+ doctest.DocFileSuite(
+ 'README.txt',
+ setUp=setUp,
+ tearDown=zc.buildout.testing.buildoutTearDown,
+ optionflags=optionflags,
+ checker=renormalizing.RENormalizing([
+ # If want to clean up the doctest output you
+ # can register additional regexp normalizers
+ # here. The format is a two-tuple with the RE
+ # as the first item and the replacement as the
+ # second item, e.g.
+ # (re.compile('my-[rR]eg[eE]ps'), 'my-regexps')
+ zc.buildout.testing.normalize_path,
+ ]),
+ ),
+ ))
+ suite.addTest(unittest.makeSuite(UtilityTests))
+ return suite
+
+if __name__ == '__main__':
+ unittest.main(defaultTest='test_suite')
Property changes on: z3c.pypimirror/trunk/src/z3c/pypimirror/tests.py
___________________________________________________________________
Name: svn:executable
+
Added: z3c.pypimirror/trunk/src/z3c/pypimirror/util.py
===================================================================
--- z3c.pypimirror/trunk/src/z3c/pypimirror/util.py (rev 0)
+++ z3c.pypimirror/trunk/src/z3c/pypimirror/util.py 2008-08-27 11:59:22 UTC (rev 90436)
@@ -0,0 +1,22 @@
+
+
+def isASCII(s):
+ """ Checks if a string/unicode string contains only ASCII chars. """
+
+ if isinstance(s, unicode):
+ try:
+ s.encode('ascii')
+ return True
+ except UnicodeError:
+ return False
+
+ elif isinstance(s, str):
+ try:
+ unicode(s, 'ascii')
+ return True
+ except UnicodeError:
+ return False
+
+ else:
+ raise TypeError('isASCII() requires a string or unicode string')
+
Property changes on: z3c.pypimirror/trunk/src/z3c/pypimirror/util.py
___________________________________________________________________
Name: svn:executable
+
Added: z3c.pypimirror/trunk/src/z3c.pypimirror.egg-info/PKG-INFO
===================================================================
--- z3c.pypimirror/trunk/src/z3c.pypimirror.egg-info/PKG-INFO (rev 0)
+++ z3c.pypimirror/trunk/src/z3c.pypimirror.egg-info/PKG-INFO 2008-08-27 11:59:22 UTC (rev 90436)
@@ -0,0 +1,44 @@
+Metadata-Version: 1.0
+Name: z3c.pypimirror
+Version: 0.1.0
+Summary: A module for building a complete or a partial PyPI mirror
+Home-page: UNKNOWN
+Author: Daniel Kraft et al.
+Author-email: dk at d9t.de
+License: UNKNOWN
+Description: Setting up a PyPI "simple" index
+ ================================
+
+ This package provides a mirror for the PyPI simple interface,
+ http://cheeseshop.python.org/simple/.
+
+ To set up a mirror:
+
+ - install this package using setuptools (easy_install, buildout, etc.)
+ so that the script, pypimirror script is installed.
+
+ - create your mirror configuration file maybe based on config.cfg.sample
+
+ - Run the pypimirror script passing the name of the mirror configuration
+ file
+
+ This will initialize the mirror.
+
+ - Set up a cron job to run update-mirror periodically.
+
+ Changes
+ =======
+
+ Change history
+ ~~~~~~~~~~~~~~
+
+ 0.1.0 (2008-08-27)
+ ------------------
+
+ - initial release
+Platform: UNKNOWN
+Classifier: Development Status :: 5 - Production/Stable
+Classifier: Intended Audience :: Developers
+Classifier: License :: OSI Approved :: Zope Public License
+Classifier: Operating System :: OS Independent
+Classifier: Programming Language :: Python
Added: z3c.pypimirror/trunk/src/z3c.pypimirror.egg-info/SOURCES.txt
===================================================================
--- z3c.pypimirror/trunk/src/z3c.pypimirror.egg-info/SOURCES.txt (rev 0)
+++ z3c.pypimirror/trunk/src/z3c.pypimirror.egg-info/SOURCES.txt 2008-08-27 11:59:22 UTC (rev 90436)
@@ -0,0 +1,15 @@
+README.txt
+setup.py
+src/z3c/__init__.py
+src/z3c.pypimirror.egg-info/PKG-INFO
+src/z3c.pypimirror.egg-info/SOURCES.txt
+src/z3c.pypimirror.egg-info/dependency_links.txt
+src/z3c.pypimirror.egg-info/entry_points.txt
+src/z3c.pypimirror.egg-info/namespace_packages.txt
+src/z3c.pypimirror.egg-info/not-zip-safe
+src/z3c.pypimirror.egg-info/requires.txt
+src/z3c.pypimirror.egg-info/top_level.txt
+src/z3c/pypimirror/__init__.py
+src/z3c/pypimirror/mirror.py
+src/z3c/pypimirror/tests.py
+src/z3c/pypimirror/util.py
\ No newline at end of file
Added: z3c.pypimirror/trunk/src/z3c.pypimirror.egg-info/dependency_links.txt
===================================================================
--- z3c.pypimirror/trunk/src/z3c.pypimirror.egg-info/dependency_links.txt (rev 0)
+++ z3c.pypimirror/trunk/src/z3c.pypimirror.egg-info/dependency_links.txt 2008-08-27 11:59:22 UTC (rev 90436)
@@ -0,0 +1 @@
+
Added: z3c.pypimirror/trunk/src/z3c.pypimirror.egg-info/entry_points.txt
===================================================================
--- z3c.pypimirror/trunk/src/z3c.pypimirror.egg-info/entry_points.txt (rev 0)
+++ z3c.pypimirror/trunk/src/z3c.pypimirror.egg-info/entry_points.txt 2008-08-27 11:59:22 UTC (rev 90436)
@@ -0,0 +1,3 @@
+[console_scripts]
+pypimirror = z3c.pypimirror.mirror:run
+
Added: z3c.pypimirror/trunk/src/z3c.pypimirror.egg-info/namespace_packages.txt
===================================================================
--- z3c.pypimirror/trunk/src/z3c.pypimirror.egg-info/namespace_packages.txt (rev 0)
+++ z3c.pypimirror/trunk/src/z3c.pypimirror.egg-info/namespace_packages.txt 2008-08-27 11:59:22 UTC (rev 90436)
@@ -0,0 +1,2 @@
+z3c
+z3c.pypimirror
Added: z3c.pypimirror/trunk/src/z3c.pypimirror.egg-info/not-zip-safe
===================================================================
--- z3c.pypimirror/trunk/src/z3c.pypimirror.egg-info/not-zip-safe (rev 0)
+++ z3c.pypimirror/trunk/src/z3c.pypimirror.egg-info/not-zip-safe 2008-08-27 11:59:22 UTC (rev 90436)
@@ -0,0 +1 @@
+
Added: z3c.pypimirror/trunk/src/z3c.pypimirror.egg-info/requires.txt
===================================================================
--- z3c.pypimirror/trunk/src/z3c.pypimirror.egg-info/requires.txt (rev 0)
+++ z3c.pypimirror/trunk/src/z3c.pypimirror.egg-info/requires.txt 2008-08-27 11:59:22 UTC (rev 90436)
@@ -0,0 +1,6 @@
+setuptools
+zc.lockfile
+BeautifulSoup
+
+[test]
+zc.buildout
\ No newline at end of file
Added: z3c.pypimirror/trunk/src/z3c.pypimirror.egg-info/top_level.txt
===================================================================
--- z3c.pypimirror/trunk/src/z3c.pypimirror.egg-info/top_level.txt (rev 0)
+++ z3c.pypimirror/trunk/src/z3c.pypimirror.egg-info/top_level.txt 2008-08-27 11:59:22 UTC (rev 90436)
@@ -0,0 +1 @@
+z3c
More information about the Checkins
mailing list