1
2
3 """A simple, lightweight Python Package Index (aka Cheeseshop) clone.
4
5 Overview
6 --------
7
8 EggBasket_ is a web application which provides a service similar and compatible
9 to the `Python Package Index`_ (aka Cheeseshop). It allows you to maintain your
10 own local repository of Python packages required by your installations.
11
12 It is implemented using the TurboGears_ web framework, Genshi_ and SQLAlchemy_.
13
14 .. warning::
15 This is still alpha-stage software. All the basic operations necessary
16 to support a setuptools-based infrastructure are there, but some
17 convenience features are missing and the software has not been tested
18 extensively. **Use at your own risk!**
19
20
21 Features
22 --------
23
24 * Can be used by setuptools/easy_install as the package index and repository.
25
26 * Supports the distutils ``upload`` protocol.
27
28 * Has a simple, role-based permission system to grant/deny access to the
29 functions of the server (for example package uploads) to groups of users.
30
31 * Requires only SQLite as the database system (included with Python 2.5).
32
33 * Is able to read and display meta data from the following distribution package
34 formats (source and binary):
35
36 ``.egg``, ``.tar``, ``.tar.bz2``, ``.tar.gz``, ``.tgz``, ``.zip``
37
38 * Any other file format can be configured to be listed under the distribution
39 files for a package (by default this includes ``.exe`` and ``.rpm`` and
40 ``.tar.Z`` files in addition to the filetypes listed above).
41
42 * Can be run without any configuration by just initializing the database and
43 starting the server from within a directory containing package directories
44 (see "Usage").
45
46
47 Todo
48 ----
49
50 * Add support for MD5 check sums and GPG signatures.
51 * Add more error and sanity checks to the upload handling.
52 * Add pagination to the main package list.
53 * Support deletion of packages through web interface.
54 * Cache package listings and meta data.
55 * Improve DBmechanic-based admin interface for adding users and groups and
56 setting configuration values (currently disabled by default).
57
58
59 Acknowledgments
60 ---------------
61
62 This application is a re-implementation (almost no shared code) of the
63 haufe.eggserver_ Grok application with some improvements.
64
65
66 Installation
67 ------------
68
69 To install EggBasket_ from the Cheeseshop_ use `easy_install`_::
70
71 [sudo] easy_install EggBasket
72
73 This requires the setuptools_ package to be installed. If you have not done so
74 already, download the `ez_setup.py`_ script and run it to install setuptools.
75
76
77 Usage
78 -----
79
80 EggBasket server
81 ~~~~~~~~~~~~~~~~
82
83 * Your packages should all reside under a common root directory, with a
84 sub-directory for each package with the same base name as the distribution.
85 The sub-directories should each contain the egg files and source archives for
86 all available versions of the package. The package directories will be created
87 by the application when using the upload command (see below).
88
89 * Open a terminal, change to the directory which contains the packages and, if
90 you are haven't already done so, initialize the database with::
91
92 eggbasket-server --init [<config file>]
93
94 * Start the application server with::
95
96 eggbasket-server [<config file>]
97
98 You can also set the location of the package root directory in the
99 configuration with the ``eggbasket.package_root`` setting and start the
100 server anywhere you want.
101
102 If no configuration file is specified on the command line, the default
103 configuration file included in the egg will be used. The default
104 configuration file can also be found in the source distribution and be
105 adapted for your environment.
106
107 The server either needs write permissions in the directory where it is
108 started, or you need to change the path of the database and the access log in
109 the configuration so they can be written by the server. Of course, package
110 uploads will also only work if the server has the permissions to create any
111 missing package directories or write in existing ones.
112
113 * To stop the server just hit ``Control-C`` in the terminal or kill the process.
114
115 * You can look at the package index with your web browser by opening the URL
116 ``http://localhost:3442/``. The default port ``3442`` can be changed by
117 setting the ``server.socket_port`` option in the configuration file.
118
119
120 Using EggBasket with ``distutils`` & ``easy_install``
121 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
122
123 * You can instruct easy_install_ to search & download packages from your
124 package repository by specifying the URL to your server with the ``-i``
125 option. Example::
126
127 easy_install -i http://localhost:3442/ PACKAGE_NAME
128
129 * Additionally, it might be necessary to restrict the hosts from which
130 easy_install will download to your EggBasket server with the ``-H`` option.
131 Example::
132
133 easy_install -H localhost:3442 -i http::/localhost:3442/ PACKAGE_NAME
134
135 * You can also set the ``eggbasket.rewrite_download_url`` resp.
136 ``eggbasket.rewrite_homepage_url`` settings in the configuration to ``True``
137 and EggBasket will replace the download resp. homepage URL of each package
138 in the package meta data view with the URL of the package distribution files
139 listing on the EggBasket server.
140
141 * You can upload a package to your repository with the distutils ``upload``
142 command, for example::
143
144 python setup.py bdist_egg upload -r http://localhost:3442/upload
145
146 This command will ask for your username and password on the server. You can
147 store these and the repository URL in your ``.pypirc`` file. See the
148 `distutils documentation`_ for more information.
149
150 * Of course you can always just copy package distribution files manually in the
151 filesystem to your repository or upload them to the appropriate place with
152 ``scp`` etc. The application will find and list new files without the need to
153 "register" them as is necessary with the original PyPI.
154
155
156 Permissions
157 ~~~~~~~~~~~
158
159 EggBasket uses a simple, role-based permission system to grant/restrict access
160 to the functions of the server. Here is a list of the defined permissions and
161 their meaning:
162
163 * ``viewpkgs`` - User can view the list of all packages
164 * ``viewfiles`` - User can view the list of distribution files for a package.
165 * ``viewinfo`` - User can view the meta data for a package distribution file.
166 * ``download`` - User can download a package distribution file.
167 * ``upload`` - User can upload a package distribution file.
168 * ``overwrite`` - User can overwrite and existing package distribution file.
169 * ``delete`` - User can delete a package distribution file through the web
170 interface.
171
172 You can let EggBasket create an initial admin user, groups and permissions in
173 the database by giving the ``--init`` option to the ``eggbasket-server``
174 command::
175
176 eggbasket-server --init [<config file>]
177
178 This will create the following objects and relations in the database:
179
180 * The above listed permissions.
181
182 * The following groups (with permissions in brackets):
183
184 * anonymous (viewpkgs, viewfiles, viewinfo, download)
185 * authenticated (viewpkgs, viewfiles, viewinfo, download)
186 * maintainer (upload, overwrite, delete)
187 * admin
188
189 * A user with user name/password "admin", belonging to the groups "maintainer"
190 and "admin".
191
192 The groups "anonymous" and "authenticated" are special groups to which all
193 anonymous (i.e. not logged in) resp. all authenticated (logged in) users belong
194 automatically.
195
196 With the default permission setup, uploading through the server is restricted
197 to users that are members of a group that has the "upload" permission. The
198 configuration page can only be accessed by members of the "admin" group.
199 Everything else can be accessed all users, whether authenticated or not.
200
201 Please note that if you want to give a certain permission to all users, whether
202 logged in or not, you need to give this permission to both the "anonymous" AND
203 the "authenticated" group. This is what the standard permission setup already
204 does for all permissions except "upload".
205
206 See the TurboGears documentation on Identity_ for background information.
207
208
209 .. _turbogears: http://www.turbogears.org/
210 .. _genshi: http://genshi.edgewall.org/
211 .. _sqlalchemy: http://www.sqlalchemy.org/
212 .. _haufe.eggserver: http://cheeseshop.python.org/pypi/haufe.eggserver
213 .. _eggbasket: http://chrisarndt.de/projects/eggbasket/
214 .. _cheeseshop:
215 .. _python package index: http://cheeseshop.python.org/pypi/
216 .. _setuptools: http://peak.telecommunity.com/DevCenter/setuptools
217 .. _easy_install: http://peak.telecommunity.com/DevCenter/EasyInstall
218 .. _ez_setup.py: http://peak.telecommunity.com/dist/ez_setup.py
219 .. _distutils documentation: http://docs.python.org/dist/package-upload.html
220 .. _identity: http://docs.turbogears.org/1.0/GettingStartedWithIdentity
221 """
222 __docformat__ = 'restructuredtext'
223
224 name = "EggBasket"
225 version = "0.6b"
226 date = "$Date: 2008-06-30 21:50:55 +0200 (Mo, 30 Jun 2008) $"
227
228 _doclines = __doc__.split('\n')
229 description = _doclines[0]
230 long_description = '\n'.join(_doclines[2:])
231
232 author = "Christopher Arndt"
233 author_email = "chris@chrisarndt.de"
234 copyright = "(c) 2008 Christopher Arndt"
235 license = "MIT License, Zope Public License (rest.py), BSD License (odict.py)"
236
237 url = "http://chrisarndt.de/projects/%s/" % name.lower()
238 download_url = "http://cheeseshop.python.org/pypi/%s" % name
239
240
241
242 keywords = """
243 # if this has widgets, uncomment the next line
244 # turbogears.widgets
245
246 # if this has a tg-admin command, uncomment the next line
247 # turbogears.command
248
249 # if this has identity providers, uncomment the next line
250 # turbogears.identity.provider
251
252 # If this is a template plugin, uncomment the next line
253 # python.templating.engines
254
255 # If this is a full application, uncomment the next line
256 turbogears.app
257 """
258
259 keywords = [line.strip() for line in keywords.split('\n')
260 if line.strip() and not line.strip().startswith('#')]
261
262
263
264 classifiers = """
265 Development Status :: 4 - Beta
266 Operating System :: OS Independent
267 Programming Language :: Python
268 Topic :: Software Development :: Libraries :: Python Modules
269 Framework :: TurboGears
270
271 # if this is an application that you'll distribute through
272 # the Cheeseshop, uncomment the next line
273 Framework :: TurboGears :: Applications
274
275 # if this is a package that includes widgets that you'll distribute
276 # through the Cheeseshop, uncomment the next line
277 # Framework :: TurboGears :: Widgets
278 """
279 classifiers = [line.strip() for line in classifiers.split('\n')
280 if line.strip() and not line.strip().startswith('#')]
281