{ "info": { "author": "Ecometrica", "author_email": "info@ecometrica.com", "bugtrack_url": null, "classifiers": [ "Development Status :: 5 - Production/Stable", "Intended Audience :: Developers", "Intended Audience :: System Administrators", "License :: OSI Approved :: BSD License", "Operating System :: OS Independent", "Programming Language :: Python", "Programming Language :: Python :: 2.6", "Programming Language :: Python :: 2.7", "Topic :: Software Development :: Libraries", "Topic :: System :: Archiving" ], "description": "GrandFatherSon is a backup rotation calculator that implements the\n`grandfather-father-son rotation scheme\n`_.\n\nThis is usually done by keeping a certain number of daily, weekly, and\nmonthly backups. Older backups should be removed to reduce the amount\nof space used.\n\n\nUsage\n-----\n\nThis module expects either ``datetime.date`` or ``datetime.datetime``\nobjects as inputs. As an example, let's assume you have daily backups\nfor the all of year 1999 that need rotating::\n\n >>> import datetime\n >>> start_date = datetime.date(1999, 1, 1)\n >>> end_date = datetime.date(1999, 12, 31)\n >>> backups = [start_date + datetime.timedelta(days=i)\n ... for i in range((end_date - start_date).days + 1)]\n >>> backups\n [datetime.date(1999, 1, 1),\n datetime.date(1999, 1, 2),\n datetime.date(1999, 1, 3),\n ...\n datetime.date(1999, 12, 30),\n datetime.date(1999, 12, 31)]\n\nLet's say that full backups are taken every Saturday, with incremental\nbackups done daily. A week, or 7 days, of incremental backups should\nbe kept. A months, or 4 weeks, of full backups are kept. In addition,\nfor three months, the first full backup is kept for each month, with\nthe others discarded.\n\nIt's the last day of the year and you want to figure out which backups\nneed to be pruned::\n\n >>> now = datetime.date(1999, 12, 31)\n\nTo see which files will be preserved, use the ``dates_to_keep``\nfunction::\n\n >>> from grandfatherson import dates_to_keep, SATURDAY\n >>> sorted(dates_to_keep(backups, days=7, weeks=4, months=3,\n ... firstweekday=SATURDAY, now=now))\n [datetime.date(1999, 10, 1),\n datetime.date(1999, 11, 1),\n datetime.date(1999, 12, 1),\n datetime.date(1999, 12, 4),\n datetime.date(1999, 12, 11),\n datetime.date(1999, 12, 18),\n datetime.date(1999, 12, 25),\n datetime.date(1999, 12, 26),\n datetime.date(1999, 12, 27),\n datetime.date(1999, 12, 28),\n datetime.date(1999, 12, 29),\n datetime.date(1999, 12, 30),\n datetime.date(1999, 12, 31)]\n\nIf you leave off the ``now`` argument, it will default to using\n``datetime.datetime.now()``.\n\nTo see which files should be deleted, use the ``dates_to_delete``\nfunction::\n\n >>> from grandfatherson import dates_to_delete, SATURDAY\n >>> sorted(dates_to_delete(backups, days=7, weeks=4, months=3,\n ... firstweekday=SATURDAY, now=now))\n [datetime.date(1999, 1, 1),\n ...\n datetime.date(1999, 9, 30),\n datetime.date(1999, 10, 2),\n ...\n datetime.date(1999, 10, 31),\n datetime.date(1999, 11, 2),\n ...\n datetime.date(1999, 11, 30),\n datetime.date(1999, 12, 2),\n datetime.date(1999, 12, 3),\n datetime.date(1999, 12, 5),\n ...\n datetime.date(1999, 12, 10),\n datetime.date(1999, 12, 12),\n ...\n datetime.date(1999, 12, 17),\n datetime.date(1999, 12, 19),\n ...\n datetime.date(1999, 12, 24)]\n\nFinally, if you need to rotate backups that have timestamps in\n``datetime`` format, you can use the corresponding ``to_keep`` and\n``to_delete`` functions::\n\n >>> now = datetime.datetime(1999, 12, 31, 23, 59, 59)\n >>> start_datetime = datetime.datetime(1999, 12, 31, 0, 0, 0)\n >>> end_datetime = datetime.datetime(1999, 12, 31, 23, 59, 59)\n >>> backups = [start_datetime + datetime.timedelta(seconds=i)\n ... for i\n ... in range((end_datetime - start_datetime).seconds + 1)]\n >>> backups\n [datetime.datetime(1999, 12, 31, 0, 0),\n datetime.datetime(1999, 12, 31, 0, 0, 1),\n datetime.datetime(1999, 12, 31, 0, 0, 2),\n ...\n datetime.datetime(1999, 12, 31, 23, 59, 58),\n datetime.datetime(1999, 12, 31, 23, 59, 59)]\n\n >>> from grandfatherson import to_keep\n >>> sorted(to_keep(backups, hours=2, minutes=10, seconds=10, now=now))\n [datetime.datetime(1999, 12, 31, 22, 0),\n datetime.datetime(1999, 12, 31, 23, 0),\n datetime.datetime(1999, 12, 31, 23, 50),\n ...\n datetime.datetime(1999, 12, 31, 23, 59),\n datetime.datetime(1999, 12, 31, 23, 59, 50),\n ...\n datetime.datetime(1999, 12, 31, 23, 59, 59)]\n\n >>> from grandfatherson import to_delete\n >>> sorted(to_delete(backups, hours=2, minutes=10, seconds=10, now=now))\n [datetime.datetime(1999, 12, 31, 0, 0),\n ...\n datetime.datetime(1999, 12, 31, 21, 59, 59),\n datetime.datetime(1999, 12, 31, 22, 0, 1),\n ...\n datetime.datetime(1999, 12, 31, 22, 59, 59),\n datetime.datetime(1999, 12, 31, 23, 0, 1),\n ...\n datetime.datetime(1999, 12, 31, 23, 49, 59),\n datetime.datetime(1999, 12, 31, 23, 50, 1),\n ...\n datetime.datetime(1999, 12, 31, 23, 58, 59),\n datetime.datetime(1999, 12, 31, 23, 59, 1),\n ...\n datetime.datetime(1999, 12, 31, 23, 59, 49)]", "description_content_type": null, "docs_url": null, "download_url": "UNKNOWN", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "http://github.com/ecometrica/grandfatherson/", "keywords": null, "license": "BSD License", "maintainer": null, "maintainer_email": null, "name": "GrandFatherSon", "package_url": "https://pypi.org/project/GrandFatherSon/", "platform": "UNKNOWN", "project_url": "https://pypi.org/project/GrandFatherSon/", "project_urls": { "Download": "UNKNOWN", "Homepage": "http://github.com/ecometrica/grandfatherson/" }, "release_url": "https://pypi.org/project/GrandFatherSon/1.3/", "requires_dist": null, "requires_python": null, "summary": "Grandfather-father-son backup rotation calculator", "version": "1.3" }, "last_serial": 4304732, "releases": { "1.0": [ { "comment_text": "", "digests": { "md5": "a8d2ab83bc11caf8ea64c908e05c3883", "sha256": "2d8ebd58bb507f23e0e82ddc9379fc1cbc1cac330d6088b3dd793b8135f353b5" }, "downloads": -1, "filename": "GrandFatherSon-1.0.tar.gz", "has_sig": false, "md5_digest": "a8d2ab83bc11caf8ea64c908e05c3883", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 7894, "upload_time": "2012-05-19T01:54:13", "url": "https://files.pythonhosted.org/packages/b3/65/930fb5bfe82b990131913ffd6063842db671565830104c7b96fee605d5a3/GrandFatherSon-1.0.tar.gz" } ], "1.1": [ { "comment_text": "", "digests": { "md5": "daa3ac0756ce59dceea185276fda8c3f", "sha256": "76decdf6390fbbd13b9a227648b2bcf6c374f698edef085dd4168c0a60efb548" }, "downloads": -1, "filename": "GrandFatherSon-1.1.tar.gz", "has_sig": false, "md5_digest": "daa3ac0756ce59dceea185276fda8c3f", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 8321, "upload_time": "2013-02-08T21:21:49", "url": "https://files.pythonhosted.org/packages/90/d9/df49cc3d2523b422f8b375d0a634ab787488e7f1bcf4953016696b53cbcf/GrandFatherSon-1.1.tar.gz" } ], "1.2": [ { "comment_text": "", "digests": { "md5": "5e8ee0df373866bcd125cc8797d02c8c", "sha256": "dac81eaa596d8642e7a1bafca59de1033dfcfb8fc53b3795a98e1657932037ae" }, "downloads": -1, "filename": "GrandFatherSon-1.2.tar.gz", "has_sig": false, "md5_digest": "5e8ee0df373866bcd125cc8797d02c8c", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 8835, "upload_time": "2013-07-05T14:38:34", "url": "https://files.pythonhosted.org/packages/64/b3/8e94ae228eaebe39e20d3882c2367b7be600a0c01c7b4346dc36f76107b4/GrandFatherSon-1.2.tar.gz" } ], "1.3": [ { "comment_text": "", "digests": { "md5": "4915275335a60acb6cc15559d64423eb", "sha256": "b70a262c3ed10cacea3a1fd3f7ba53095479c4d68bd46f0869bc215fdc89f6fc" }, "downloads": -1, "filename": "GrandFatherSon-1.3.tar.gz", "has_sig": false, "md5_digest": "4915275335a60acb6cc15559d64423eb", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 8426, "upload_time": "2016-09-16T19:25:28", "url": "https://files.pythonhosted.org/packages/09/1a/aa26eaab11c1e0fcd3ae778c3def6d95a008c711b6b72797297d8675061d/GrandFatherSon-1.3.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "4915275335a60acb6cc15559d64423eb", "sha256": "b70a262c3ed10cacea3a1fd3f7ba53095479c4d68bd46f0869bc215fdc89f6fc" }, "downloads": -1, "filename": "GrandFatherSon-1.3.tar.gz", "has_sig": false, "md5_digest": "4915275335a60acb6cc15559d64423eb", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 8426, "upload_time": "2016-09-16T19:25:28", "url": "https://files.pythonhosted.org/packages/09/1a/aa26eaab11c1e0fcd3ae778c3def6d95a008c711b6b72797297d8675061d/GrandFatherSon-1.3.tar.gz" } ] }