{ "info": { "author": "Reinout van Rees", "author_email": "reinout@vanrees.org", "bugtrack_url": null, "classifiers": [ "Development Status :: 6 - Mature", "Framework :: Buildout", "Intended Audience :: Developers", "License :: OSI Approved", "License :: OSI Approved :: Zope Public License", "Programming Language :: Python", "Programming Language :: Python :: 2", "Programming Language :: Python :: 2.7", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3.4", "Programming Language :: Python :: 3.5", "Programming Language :: Python :: 3.6", "Programming Language :: Python :: 3.7", "Programming Language :: Python :: Implementation", "Programming Language :: Python :: Implementation :: CPython", "Programming Language :: Python :: Implementation :: PyPy", "Topic :: Software Development", "Topic :: Software Development :: Build Tools", "Topic :: Software Development :: Libraries :: Python Modules" ], "description": "z3c.recipe.usercrontab\n======================\n\nThe problem\n-----------\n\nWhen deploying applications, it can be useful to have maintenance\ntasks be started periodically. On Unix platforms this is usually done\nusing ``cron`` which starts `cronjobs`. Adding cronjobs to the\nsystem-wide cron directory (for example by placing a file in\n``/etc/cron.d``) can be handled using the ``zc.recipe.deployment``\npackage, but it does not support adding cronjobs by normal\nusers. (as ``/etc/cron.d`` usually is world-writable).\n\nThe solution\n------------\n\n``z3c.recipe.usercrontab`` interfaces with cron using ``crontab(1)``,\nand allows normal users to install their own cronjobs. This is done by\nhaving buildout add and remove cronjobs when installing and\nuninstalling packages.\n\nHow to use it\n-------------\n\nTo use ``z3c.recipe.usercrontab`` you need to add the following to\nyour buildout.cfg::\n\n [mycronjob]\n recipe = z3c.recipe.usercrontab\n times = 0 12 * * *\n command = echo nothing happens at noon\n\nand finally add ``mycronjob`` to the ``parts`` line(s) of your\nbuildout.cfg\n\nTo add a comment to your cron-entry::\n\n [mycronjob]\n recipe = z3c.recipe.usercrontab\n times = 0 12 * * *\n command = echo nothing happens at noon\n comment = Run daily at noon\n\nIf you prefer to manually enable cronjobs, you can generate a cron-entry\nthat is commented out by setting ``enabled`` to ``False``::\n\n [mycronjob]\n recipe = z3c.recipe.usercrontab\n times = 0 12 * * *\n command = echo nothing happens at noon\n enabled = false\n\nAfter running the buildout, you can check the generated cron-entries\nvia ``crontab -l``.\n\n\nCredits\n-------\n\nOriginal authors: Jasper Spaans and Jan-Jaap Driessen.\n\nMost recent versions and current maintainer: `Reinout van Rees\n`_.\n\n\n.. -*- mode: doctest -*-\n\nDetailed documentation\n======================\n\nThe recipe z3c.recipe.usercrontab is a small recipe to facilitate the\ninstalling of cronjobs into user crontabs.\n\n >>> from z3c.recipe.usercrontab.usercrontab import UserCrontabManager\n\n\nEntry handling\n--------------\n\nA user crontab manager manages a user's crontab for one specific buildout\npart. The part ends up in the identifier. We'll use 'test' here.\n\n >>> c = UserCrontabManager(identifier='test')\n\nIn these tests, we can fake a crontab by filling the list of cron entries\nmanually:\n\n >>> c.crontab = ['@reboot echo \"hello world\"']\n >>> print(c) # Handy shortcut\n @reboot echo \"hello world\"\n\nNow, we're adding an entry to it using the official way. The entry is\nsurrounded by markers:\n\n >>> c.add_entry('@reboot echo \"I just got added\"')\n >>> print(c)\n @reboot echo \"hello world\"\n \n # Generated by test\n @reboot echo \"I just got added\"\n # END test\n \n\nRemoving entries also works. As long as the \"Generated by\" markers are\npresent, it doesn't matter which entry you remove: everything surrounded by\nthe markers is zapped:\n\n >>> c.del_entry('bla bla') == 1\n True\n >>> print(c)\n @reboot echo \"hello world\"\n\nAn entry can also include an explanatory comment line:\n\n >>> c.add_entry('@reboot echo \"I just got added\"',\n ... comment=\"This ought to happen first\")\n >>> print(c)\n @reboot echo \"hello world\"\n \n # Generated by test\n # This ought to happen first\n @reboot echo \"I just got added\"\n # END test\n \n\nPre-0.6, a WARNING environment variable was used. An entry (which content\nmatters now!) is found there:\n\n >>> c.crontab = ['@reboot echo \"hello world\"',\n ... 'WARNING=\"Everything below is added by bla bla',\n ... '@reboot echo \"old entry 1\"',\n ... '@reboot echo \"old entry 2\"']\n >>> print(c)\n @reboot echo \"hello world\"\n WARNING=\"Everything below is added by bla bla\n @reboot echo \"old entry 1\"\n @reboot echo \"old entry 2\"\n >>> c.del_entry('@reboot echo \"old entry 1\"')\n 1\n >>> print(c)\n @reboot echo \"hello world\"\n WARNING=\"Everything below is added by bla bla\n @reboot echo \"old entry 2\"\n\nRemoving the last remaining entry under WARNING also removes the WARNING:\n\n >>> c.del_entry('@reboot echo \"old entry 2\"')\n 1\n >>> print(c)\n @reboot echo \"hello world\"\n\nBriefly in the 0.5 version, a 'BUILDOUT' environment variable was used for\ngrouping items per buildout. Now for some up/downgrade testing. 0.5.1 removes\nthe environment variable again. We'll add an entry with such a (now\ndeprecated) \"grouping environment variable\". First the start situation:\n\n >>> c.crontab=[\n ... 'WARNING=\"Everything below is added by bla bla',\n ... 'BUILDOUT=my/buildout',\n ... '@reboot echo nothing happens']\n >>> print(c)\n WARNING=\"Everything below is added by bla bla\n BUILDOUT=my/buildout\n @reboot echo nothing happens\n\nDoing anything (adding/removing) zaps BUILDOUT statement:\n\n >>> c.del_entry('nonexisting')\n 0\n >>> print(c)\n WARNING=\"Everything below is added by bla bla\n @reboot echo nothing happens\n\nAnd just to make sure, deleting that entry empties out the whole file:\n\n >>> c.del_entry('@reboot echo nothing happens')\n 1\n >>> print(c)\n \n\n\nRead/write crontab methods\n--------------------------\n\nNext, test the read_crontab and write_crontab methods; we'll use\n``cat`` and a temporary file to not modifiy the crontab of the user\nrunning these tests:\n\n >>> import tempfile\n >>> t = tempfile.NamedTemporaryFile('w')\n >>> crontestfile = t.name\n >>> dont_care = t.write(\"#dummy\\n\")\n\n >>> c = UserCrontabManager(readcrontab=\"cat %s\" % crontestfile,\n ... writecrontab=\"cat >%s\" % crontestfile,\n ... identifier='test')\n >>> c.read_crontab()\n >>> a = repr(c)\n >>> c.add_entry('# improbable entry')\n >>> c.write_crontab()\n >>> c.read_crontab()\n >>> b =repr(c)\n >>> a == b\n False\n\nNow, delete this entry again and make sure the old crontab is restored:\n\n >>> c.del_entry('# improbable entry') == 1\n True\n >>> c.write_crontab()\n >>> c.read_crontab()\n >>> b = repr(c)\n >>> a == b\n True\n\n\nBuildout recipe usage\n---------------------\n\nDo the buildout shuffle:\n\n >>> write('buildout.cfg',\n ... '''\n ... [buildout]\n ... parts = foo\n ...\n ... [foo]\n ... recipe = z3c.recipe.usercrontab\n ... times = @reboot\n ... command = echo nothing happens\n ... readcrontab = cat %(crontest)s\n ... writecrontab = cat >%(crontest)s\n ... ''' % ( { 'crontest': crontestfile } ))\n\n >>> import os\n >>> 'Installing foo' in system(buildout)\n True\n\nCheck that it really was added to the crontab:\n\n >>> c.read_crontab()\n >>> b = repr(c)\n >>> a == b\n False\n\n >>> '@reboot\\techo nothing happens' in c.crontab\n True\n >>> print(c)\n # Generated by /sample-buildout [foo]\n @reboot echo nothing happens\n # END /sample-buildout [foo]\n\nRe-running buildout runs the crontab recipe even when there's no change:\n\n >>> output = system(buildout)\n >>> 'Updating foo' in output or 'Installing foo' in output\n True\n >>> c.read_crontab()\n >>> print(c)\n # Generated by /sample-buildout [foo]\n @reboot echo nothing happens\n # END /sample-buildout [foo]\n\nThis means that a crontab is fixed up if we mucked it up by hand:\n\n >>> c.crontab = []\n >>> c.write_crontab()\n >>> c.read_crontab()\n >>> print(c)\n >>> output = system(buildout)\n >>> 'Updating foo' in output or 'Installing foo' in output\n True\n >>> c.read_crontab()\n >>> print(c)\n # Generated by /sample-buildout [foo]\n @reboot echo nothing happens\n # END /sample-buildout [foo]\n\nYou can also add a comment to the crontab entry:\n\n >>> write('buildout.cfg',\n ... '''\n ... [buildout]\n ... parts = foo\n ...\n ... [foo]\n ... recipe = z3c.recipe.usercrontab\n ... times = @reboot\n ... command = echo nothing happens\n ... comment = Step 1: mention that nothing happens\n ... readcrontab = cat %(crontest)s\n ... writecrontab = cat >%(crontest)s\n ... ''' % ( { 'crontest': crontestfile } ))\n >>> 'Installing foo' in system(buildout)\n True\n >>> c.read_crontab()\n >>> print(c)\n # Generated by /sample-buildout [foo]\n # Step 1: mention that nothing happens\n @reboot echo nothing happens\n # END /sample-buildout [foo]\n\nAn entry is by default enabled, leading to an active cronjob:\n\n >>> write('buildout.cfg',\n ... '''\n ... [buildout]\n ... parts = foo\n ...\n ... [foo]\n ... recipe = z3c.recipe.usercrontab\n ... times = @reboot\n ... command = echo nothing happens\n ... enabled = true\n ... readcrontab = cat %(crontest)s\n ... writecrontab = cat >%(crontest)s\n ... ''' % ( { 'crontest': crontestfile } ))\n >>> 'Installing foo' in system(buildout)\n True\n >>> c.read_crontab()\n >>> print(c)\n # Generated by /sample-buildout [foo]\n @reboot echo nothing happens\n # END /sample-buildout [foo]\n\nYou can also generate an inactive cronjob that is commented out, by setting\nthe enabled-option to False:\n\n >>> write('buildout.cfg',\n ... '''\n ... [buildout]\n ... parts = foo\n ...\n ... [foo]\n ... recipe = z3c.recipe.usercrontab\n ... times = @reboot\n ... command = echo nothing happens\n ... enabled = false\n ... readcrontab = cat %(crontest)s\n ... writecrontab = cat >%(crontest)s\n ... ''' % ( { 'crontest': crontestfile } ))\n >>> 'Installing foo' in system(buildout)\n True\n >>> c.read_crontab()\n >>> print(c)\n # Generated by /sample-buildout [foo]\n # @reboot echo nothing happens\n # END /sample-buildout [foo]\n\n\nUninstall the recipe:\n\n >>> write('buildout.cfg',\n ... '''\n ... [buildout]\n ... parts =\n ... ''' % ( { 'crontest': crontestfile } ))\n >>> 'Uninstalling foo' in system(buildout)\n True\n\nAnd check that its entry was removed (i.e., the contents of the\ncrontab are the same as when this test was started; in any case, the\nteardown from the testrunner makes sure the old situation is\nrestored):\n\n >>> c.read_crontab()\n >>> b = repr(c)\n >>> a == b\n True\n\nA second part installs fine:\n\n >>> write('buildout.cfg',\n ... '''\n ... [buildout]\n ... parts = foo bar\n ...\n ... [foo]\n ... recipe = z3c.recipe.usercrontab\n ... times = @reboot\n ... command = echo nothing happens\n ... readcrontab = cat %(crontest)s\n ... writecrontab = cat >%(crontest)s\n ...\n ... [bar]\n ... recipe = z3c.recipe.usercrontab\n ... times = @reboot\n ... command = echo something happens\n ... readcrontab = cat %(crontest)s\n ... writecrontab = cat >%(crontest)s\n ... ''' % ( { 'crontest': crontestfile } ))\n >>> output = system(buildout)\n >>> 'Installing foo' in output\n True\n >>> 'Installing bar' in output\n True\n >>> c.read_crontab()\n >>> print(c)\n \n # Generated by /sample-buildout [foo]\n @reboot echo nothing happens\n # END /sample-buildout [foo]\n \n \n # Generated by /sample-buildout [bar]\n @reboot echo something happens\n # END /sample-buildout [bar]\n \n\nUninstalling also works fine\n\n >>> write('buildout.cfg',\n ... '''\n ... [buildout]\n ... parts =\n ... ''' % ( { 'crontest': crontestfile } ))\n >>> output = system(buildout)\n >>> 'Uninstalling bar' in output\n True\n >>> 'Uninstalling foo' in output\n True\n\n\nSafety valves\n-------------\n\nIf the section has been removed, nothing can be found by the uninstall. You\nget warnings that way:\n\n >>> write('buildout.cfg',\n ... '''\n ... [buildout]\n ... parts = foo\n ...\n ... [foo]\n ... recipe = z3c.recipe.usercrontab\n ... times = @reboot\n ... command = echo nothing happens\n ... readcrontab = cat %(crontest)s\n ... writecrontab = cat >%(crontest)s\n ... ''' % ( { 'crontest': crontestfile } ))\n\n >>> import os\n >>> 'Installing foo' in system(buildout)\n True\n >>> c.crontab = []\n >>> c.write_crontab()\n >>> write('buildout.cfg',\n ... '''\n ... [buildout]\n ... parts =\n ... ''' % ( { 'crontest': crontestfile } ))\n >>> 'WARNING: Did not find a crontab-entry during uninstall' in system(buildout)\n True\n\nAnother test: pre-0.6 config simulation:\n\n >>> write('buildout.cfg',\n ... '''\n ... [buildout]\n ... parts = foo\n ...\n ... [foo]\n ... recipe = z3c.recipe.usercrontab\n ... times = @reboot\n ... command = echo nothing happens\n ... readcrontab = cat %(crontest)s\n ... writecrontab = cat >%(crontest)s\n ... ''' % ( { 'crontest': crontestfile } ))\n\n >>> import os\n >>> 'Installing foo' in system(buildout)\n True\n >>> c.crontab = ['WARNING=\"Everything below is added by bla bla\"',\n ... 'BUILDOUT=/somewhere/out/there',\n ... '@reboot\\techo nothing happens']\n >>> c.write_crontab()\n >>> write('buildout.cfg',\n ... '''\n ... [buildout]\n ... parts =\n ... ''' % ( { 'crontest': crontestfile } ))\n >>> 'Running uninstall recipe' in system(buildout)\n True\n >>> c.read_crontab()\n >>> print(c)\n \n\n\nz3c.recipe.usercrontab changes\n==============================\n\n1.5 (2018-12-20)\n----------------\n\n- Officially support Python 3.5, 3.6, 3.7, PyPy and PyPy3.\n\n\n1.4 (2015-10-29)\n----------------\n\n- Added an ``enabled`` option that's on by default. By setting this to false,\n you can generate cronjobs that are commented out.\n\n This can be useful if you have to perform other tasks in your deployment\n before a cronjob can be switched on (by uncommenting manually or by a\n script).\n [WouterVH]\n\n\n1.3 (2015-10-05)\n----------------\n\n- New 'comment' option. This way you can add a small explanatory one-line\n option to your crontab entry.\n [reinout]\n\n\n1.2.1 (2015-09-11)\n------------------\n\n- Moved development to https://github.com/reinout/z3c.recipe.usercrontab\n [reinout]\n\n- Made a few small fixes to get everything running on python 3.\n [reinout]\n\n\n1.1 (2010-11-09)\n----------------\n\n- Append and prepend less white space per cron item, so you do not get\n increasing extra white space everytime you run bin/buildout.\n [maurits]\n\n\n1.0 (2009-11-10)\n----------------\n\n- Only small documentation changes; version bumped to 1.0 to signal\n stability. [reinout]\n\n\n0.7 (2009-08-24)\n----------------\n\n- The crontab now gets checked every time buildout runs, not only when there's\n a change in the configuration. [reinout]\n\n\n0.6.1 (2009-06-17)\n------------------\n\n- Documentation fixes. [reinout]\n\n\n0.6 (2009-06-16)\n----------------\n\n- Removed essentially-unused complete environment variable handling.\n [reinout]\n\n- Adding our entries with descriptive comments now: it includes the buildout\n file and the part name. [reinout]\n\n\n0.5.1 (2009-06-16)\n------------------\n\n- Reverted the \"BUILDOUT=...\" environment variable, including migration. I'll\n add a better way after this release. [reinout]\n\n\n0.5 (2009-06-15)\n----------------\n\n* Added migration code for pre-0.5 entries without a BUILDOUT variable.\n [reinout]\n\n* Added extra blank line in front of \"BUILDOUT=...\" variable to allow for\n better readability. [reinout]\n\n* Added \"BUILDOUT=....\" as environment variable for every set of crontab lines\n handled by one buildout. This makes it much easier to spot what got added\n by which buildout (in case you have multiple) or which buildout at all (if\n you have no clue where the buildout can be found). [reinout]\n\n0.4 (2008-02-25)\n----------------\n\n* Fix bug where UserCrontabs with empty readcrontab and writecrontab\n constructor arguments where broken\n\n0.3 (2008-02-23)\n----------------\n\n* Renamed to z3c.recipe.usercrontab\n* Add an option to change the command used to read and write crontabs\n* Improved tests to not modify the real crontab\n\n0.2 (2008-01-12)\n----------------\n\n* Warn if an entry cannot be removed in buildout uninstall\n* Break if multiple entries would be removed in buildout uninstall\n* Have del_entry return the number of removed\n\n0.1 (2008-01-12)\n----------------\n\n* Initial release.", "description_content_type": "", "docs_url": null, "download_url": "", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "https://github.com/reinout/z3c.recipe.usercrontab", "keywords": "", "license": "ZPL", "maintainer": "", "maintainer_email": "", "name": "z3c.recipe.usercrontab", "package_url": "https://pypi.org/project/z3c.recipe.usercrontab/", "platform": "", "project_url": "https://pypi.org/project/z3c.recipe.usercrontab/", "project_urls": { "Homepage": "https://github.com/reinout/z3c.recipe.usercrontab" }, "release_url": "https://pypi.org/project/z3c.recipe.usercrontab/1.5/", "requires_dist": null, "requires_python": "", "summary": "User Crontab install buildout recipe", "version": "1.5" }, "last_serial": 4619890, "releases": { "0.3": [ { "comment_text": "", "digests": { "md5": "c81a04a6741aa90aa759979f5e74a8f3", "sha256": "f6f13fc546a3de9e012361cf86cc10ec55fdf81d161a319bfb195e65a0ce4f26" }, "downloads": -1, "filename": "z3c.recipe.usercrontab-0.3.tar.gz", "has_sig": false, "md5_digest": "c81a04a6741aa90aa759979f5e74a8f3", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 8068, "upload_time": "2009-02-23T14:35:43", "url": "https://files.pythonhosted.org/packages/d0/97/d92248351859c0ad01662f07888f489a9ccc4db4e8b8213d0ed0d1b0f2c2/z3c.recipe.usercrontab-0.3.tar.gz" } ], "0.4": [ { "comment_text": "", "digests": { "md5": "c67d8dd730a0f9f75c9ab656e23178fa", "sha256": "3b0f253270ab7aaec97ae8ce524e3ad61a514f50b876879870b899f103e62cf6" }, "downloads": -1, "filename": "z3c.recipe.usercrontab-0.4.tar.gz", "has_sig": false, "md5_digest": "c67d8dd730a0f9f75c9ab656e23178fa", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 8127, "upload_time": "2009-02-25T22:41:01", "url": "https://files.pythonhosted.org/packages/ad/60/0b2a40b1e1cb78cd074571102b24c952a9b64df5c57232d38507fd2fadfd/z3c.recipe.usercrontab-0.4.tar.gz" } ], "0.5": [ { "comment_text": "", "digests": { "md5": "5e712ce9d82b05bd74f14f0582b55a4c", "sha256": "332634dd03777d0a94372e680dd7b3df560139cd680ced9c2e3480ead220d4bf" }, "downloads": -1, "filename": "z3c.recipe.usercrontab-0.5.tar.gz", "has_sig": false, "md5_digest": "5e712ce9d82b05bd74f14f0582b55a4c", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 10783, "upload_time": "2009-06-15T17:33:40", "url": "https://files.pythonhosted.org/packages/b9/17/b42d805db6ee86b7d7619e5c11e10d318848b44bb95d95b99a7809f974f9/z3c.recipe.usercrontab-0.5.tar.gz" } ], "0.5.1": [ { "comment_text": "", "digests": { "md5": "3e0157000de2a8bf59c57bb682880182", "sha256": "d6b20bd0ce5945d42548030adbae7aa21442632404a76fa68fa295ff373ee59d" }, "downloads": -1, "filename": "z3c.recipe.usercrontab-0.5.1.tar.gz", "has_sig": false, "md5_digest": "3e0157000de2a8bf59c57bb682880182", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 10091, "upload_time": "2009-06-16T10:57:01", "url": "https://files.pythonhosted.org/packages/3d/bb/aa1cb7cdce3c87a74343457c3972691111073cd354a101ad1bcebbdb73be/z3c.recipe.usercrontab-0.5.1.tar.gz" } ], "0.6": [ { "comment_text": "", "digests": { "md5": "0937b9f0eb217d2089064de3ab7c428b", "sha256": "8524501650b45647a471cb99de5b12ca23afde95963e62440fee1937ae69960f" }, "downloads": -1, "filename": "z3c.recipe.usercrontab-0.6.tar.gz", "has_sig": false, "md5_digest": "0937b9f0eb217d2089064de3ab7c428b", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 10184, "upload_time": "2009-06-16T15:34:54", "url": "https://files.pythonhosted.org/packages/80/07/1bb7b5d66cfae5b8c0c2c86c8dd4a4ed9768892756c2a8acc225ffe22577/z3c.recipe.usercrontab-0.6.tar.gz" } ], "0.6.1": [ { "comment_text": "", "digests": { "md5": "9f166daccaeec7b57b7a29b6c9d6f248", "sha256": "6db6af7003b29cee48a66ebe0fea8cc5f3c98d09a56e7c67f31827df8f10f77c" }, "downloads": -1, "filename": "z3c.recipe.usercrontab-0.6.1.tar.gz", "has_sig": false, "md5_digest": "9f166daccaeec7b57b7a29b6c9d6f248", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 10832, "upload_time": "2009-06-17T12:29:18", "url": "https://files.pythonhosted.org/packages/bf/47/ca3588e6e33fe0c3e0a7410e2889c157d190cc6b689a5e095020ddb31345/z3c.recipe.usercrontab-0.6.1.tar.gz" } ], "0.7": [ { "comment_text": "", "digests": { "md5": "e296ef4288daf29d9bd25960f4f3ed40", "sha256": "6179dc0f1f49b9eb07ee9d0fb61ea67a0b82bb92fe0750b31f3ef706eaf7b720" }, "downloads": -1, "filename": "z3c.recipe.usercrontab-0.7.tar.gz", "has_sig": false, "md5_digest": "e296ef4288daf29d9bd25960f4f3ed40", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 11085, "upload_time": "2009-08-24T12:27:03", "url": "https://files.pythonhosted.org/packages/bd/cd/8ba7323b1db614fa53b5c274d5b008e1553c790fbeda24826508879aaec0/z3c.recipe.usercrontab-0.7.tar.gz" } ], "1.0": [ { "comment_text": "", "digests": { "md5": "97ccfda740005f70942b1a874f756ee5", "sha256": "d02356fd3dadae909a7d9b85f24671fac948aba2ece8d53013a5f927404b9e0e" }, "downloads": -1, "filename": "z3c.recipe.usercrontab-1.0.tar.gz", "has_sig": false, "md5_digest": "97ccfda740005f70942b1a874f756ee5", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 11430, "upload_time": "2009-11-10T15:41:39", "url": "https://files.pythonhosted.org/packages/e3/f6/2c4391390bc0ba21070ae61cbbc505d0cd0b29daef0f8281b29ea79a17a5/z3c.recipe.usercrontab-1.0.tar.gz" } ], "1.1": [ { "comment_text": "", "digests": { "md5": "a77d83a730289797cfb37845508b87f4", "sha256": "4a6d2c16a60743632eda09eaf2d86648797455f830fea8e04f9635bbe40b1ced" }, "downloads": -1, "filename": "z3c.recipe.usercrontab-1.1.tar.gz", "has_sig": false, "md5_digest": "a77d83a730289797cfb37845508b87f4", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 10518, "upload_time": "2010-11-09T09:33:35", "url": "https://files.pythonhosted.org/packages/a0/05/308382a0fac85dadef9e8fe75c1b6c456c3faab7ec4a1e22e32a3097c902/z3c.recipe.usercrontab-1.1.tar.gz" } ], "1.2.1": [ { "comment_text": "", "digests": { "md5": "9c46688396bac5ef10ffecaa22814274", "sha256": "4368cc21add94b12cbc968633f97be904263b7ad98721fce8316e7d7f24adb4e" }, "downloads": -1, "filename": "z3c.recipe.usercrontab-1.2.1.tar.gz", "has_sig": false, "md5_digest": "9c46688396bac5ef10ffecaa22814274", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 14674, "upload_time": "2015-09-11T13:49:02", "url": "https://files.pythonhosted.org/packages/be/f4/844100d8d7d5e66006da28f5f63be1e97d52a3215323781576b474434cea/z3c.recipe.usercrontab-1.2.1.tar.gz" } ], "1.3": [ { "comment_text": "", "digests": { "md5": "83eeb0bb8bf759384a5405370bc9c140", "sha256": "1e22ae1bec19f09da33d302e60700e8967cf3d1e69c600d730315e78c4d3cdf4" }, "downloads": -1, "filename": "z3c.recipe.usercrontab-1.3.tar.gz", "has_sig": false, "md5_digest": "83eeb0bb8bf759384a5405370bc9c140", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 15103, "upload_time": "2015-10-05T07:40:02", "url": "https://files.pythonhosted.org/packages/58/51/de8efae385b30965278fe51494a7e60eb87aedf167d8f22d0b2c3e60b028/z3c.recipe.usercrontab-1.3.tar.gz" } ], "1.4": [ { "comment_text": "", "digests": { "md5": "af2e8ca5826c254e0e43bc15af0768a9", "sha256": "bae911589e4a80b4dee08bf18caa41558b3590e3d65ad3cc5c93029d715a95cd" }, "downloads": -1, "filename": "z3c.recipe.usercrontab-1.4.tar.gz", "has_sig": false, "md5_digest": "af2e8ca5826c254e0e43bc15af0768a9", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 16158, "upload_time": "2015-10-29T09:09:29", "url": "https://files.pythonhosted.org/packages/a6/18/b9657c51e8ef030524c7df3d97f98fd8286b863008a641f16a98663f7948/z3c.recipe.usercrontab-1.4.tar.gz" } ], "1.5": [ { "comment_text": "", "digests": { "md5": "24dc4a8147ad38b32fbc16a49bcb5b68", "sha256": "b4a827e805213f90af58661e35f8f65dfd0180ecd12bc6248481600a646752ed" }, "downloads": -1, "filename": "z3c.recipe.usercrontab-1.5.tar.gz", "has_sig": false, "md5_digest": "24dc4a8147ad38b32fbc16a49bcb5b68", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 17319, "upload_time": "2018-12-20T08:21:19", "url": "https://files.pythonhosted.org/packages/4d/d8/e7cf9d5779fe049aa01805ff752946f1ef5920b0aa697572db15b7d18d10/z3c.recipe.usercrontab-1.5.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "24dc4a8147ad38b32fbc16a49bcb5b68", "sha256": "b4a827e805213f90af58661e35f8f65dfd0180ecd12bc6248481600a646752ed" }, "downloads": -1, "filename": "z3c.recipe.usercrontab-1.5.tar.gz", "has_sig": false, "md5_digest": "24dc4a8147ad38b32fbc16a49bcb5b68", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 17319, "upload_time": "2018-12-20T08:21:19", "url": "https://files.pythonhosted.org/packages/4d/d8/e7cf9d5779fe049aa01805ff752946f1ef5920b0aa697572db15b7d18d10/z3c.recipe.usercrontab-1.5.tar.gz" } ] }