{ "info": { "author": "G\u00f6ran Roseen", "author_email": "goran@roseen.se", "bugtrack_url": null, "classifiers": [ "License :: OSI Approved :: MIT License", "Operating System :: OS Independent", "Programming Language :: Python :: 3" ], "description": "# photoarchive\nA simple tool to copy all unique photos to an archive\n\n## Background\nI often backup phones and cameras, but to different places, using no consistent naming conventions, and more importantly, with no check for duplicates.\nThis tool takes such a backup location and copies all image files to a better structured archive, excluding duplicates and renaming unique files with duplicate file names.\n\n## Usage\nSelect a place where you will put your archive.\nMake sure that your source files will have unique paths (i.e. if you have a bunch of usb sticks that would all be called \"D:\\\", copy the files to a hard drive first).\n\n```\npip install photoarchive\ncd \npython -mphotoarchive \n```\n\n## Alternative\n\n```\ngit clone https://github.com/roseeng/photoarchive\ncd photoarchive\npython __main__.py \n```\n\n## Notes of interest\n### Uniqueness\nFiles to be copied are checked against the files in the existing archive using the following logic:\n\n* Are the file names similar? If they do, go to next check, if not, copy.\n* Do they have the exact same size? If they do, go to next check, if not, copy.\n* Do they have the same MD5 checksum? If they do, mark as duplicate, if not, copy.\n\nAll treated files are added to a list, so you can run the command against the exact same folder and only working on new files.\nThis is saved in `treatedfiles.txt`.\nAll copied files are added to a dictionary, with file size and hash value, to avoid recomputation.\nThis is saved in `filedict.json`.\n\n### Name comparison\nThe logic for \"similar names\" are as follows:\n\n* If file suffix is different, the files are different. Else remove suffix from comparison.\n* Take the first 5 chars\n* From the remainder, remove all digits\n* From the result, remove underscores and parenthesis.\n\nThe aim is to make files like \"DSC4711.jpg\" and \"DSC4711(1).jpg\" similar, but \"47122.jpg\" and \"47123.jpg\" different.\nIn a future version, this should be tweakable.\nIt is not the end of the world if it's not perfect though, the result is just more fstat() calls and hash calculations.\n\n## Archive structure\nWhen copying a file, we try to get the original date from the EXIF information. If that does not succeed, we take the creation date of the file. \n\nThat is then used to build the folder structure in the archive as: Bilder/YYYY/MM/DD.\nThe files keep the old name in that folder, optionally with \"-n\" added if there already is a file with the same name in the folder.", "description_content_type": "text/markdown", "docs_url": null, "download_url": "", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "https://github.com/roseeng/photoarchive", "keywords": "", "license": "MIT", "maintainer": "", "maintainer_email": "", "name": "photoarchive", "package_url": "https://pypi.org/project/photoarchive/", "platform": "", "project_url": "https://pypi.org/project/photoarchive/", "project_urls": { "Homepage": "https://github.com/roseeng/photoarchive" }, "release_url": "https://pypi.org/project/photoarchive/0.5/", "requires_dist": null, "requires_python": "", "summary": "A simple tool to archive photos", "version": "0.5" }, "last_serial": 4251500, "releases": { "0.4": [ { "comment_text": "", "digests": { "md5": "8536257882127bea76480eb494b9617c", "sha256": "e9f66015bb2cbec5f9eb8d41bb1e86b0c54c0e343885027c42032963058e0155" }, "downloads": -1, "filename": "photoarchive-0.4-py3-none-any.whl", "has_sig": false, "md5_digest": "8536257882127bea76480eb494b9617c", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 5691, "upload_time": "2018-09-07T23:21:26", "url": "https://files.pythonhosted.org/packages/4b/80/4ae63925f25144833a7692748324f0b4d1d10192569e6a9721905cbb6077/photoarchive-0.4-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "7d43ab031ceb317200a4b150da6e4444", "sha256": "b35fca92c16657be57c9337cd7b8fb6051b997fd5e31cf74979d48d9cfc0b8b5" }, "downloads": -1, "filename": "photoarchive-0.4.tar.gz", "has_sig": false, "md5_digest": "7d43ab031ceb317200a4b150da6e4444", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 4147, "upload_time": "2018-09-07T23:21:27", "url": "https://files.pythonhosted.org/packages/bb/b6/4ff25f157dc7bc996f29585690992c648d0bcd8c530784938af75ebb34b1/photoarchive-0.4.tar.gz" } ], "0.5": [ { "comment_text": "", "digests": { "md5": "35fe6be03de6c24e4f9cf04cd70ecc74", "sha256": "c2b44be9393aa6f444d7ea82a0e3f8ea5b3ad18d4f3aa906101e4ba8fd7cff5a" }, "downloads": -1, "filename": "photoarchive-0.5-py3-none-any.whl", "has_sig": false, "md5_digest": "35fe6be03de6c24e4f9cf04cd70ecc74", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 6771, "upload_time": "2018-09-08T11:52:49", "url": "https://files.pythonhosted.org/packages/6e/2f/a20c8f735ba0fb1cae01d6c591c2adc5e0cbe266b908a6c52295b62a8cec/photoarchive-0.5-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "2e798a18664f8a6f6dae99faa06881b1", "sha256": "7bdc23cbde3a7b16808b4d4215dcb763ee1703b60961f3e61b629cb12cdf4b78" }, "downloads": -1, "filename": "photoarchive-0.5.tar.gz", "has_sig": false, "md5_digest": "2e798a18664f8a6f6dae99faa06881b1", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 5420, "upload_time": "2018-09-08T11:52:33", "url": "https://files.pythonhosted.org/packages/26/c1/0baa364ff2a2fb97fc473221f89bab8f5343ab3ccdc64fc0e4242f2d0eed/photoarchive-0.5.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "35fe6be03de6c24e4f9cf04cd70ecc74", "sha256": "c2b44be9393aa6f444d7ea82a0e3f8ea5b3ad18d4f3aa906101e4ba8fd7cff5a" }, "downloads": -1, "filename": "photoarchive-0.5-py3-none-any.whl", "has_sig": false, "md5_digest": "35fe6be03de6c24e4f9cf04cd70ecc74", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 6771, "upload_time": "2018-09-08T11:52:49", "url": "https://files.pythonhosted.org/packages/6e/2f/a20c8f735ba0fb1cae01d6c591c2adc5e0cbe266b908a6c52295b62a8cec/photoarchive-0.5-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "2e798a18664f8a6f6dae99faa06881b1", "sha256": "7bdc23cbde3a7b16808b4d4215dcb763ee1703b60961f3e61b629cb12cdf4b78" }, "downloads": -1, "filename": "photoarchive-0.5.tar.gz", "has_sig": false, "md5_digest": "2e798a18664f8a6f6dae99faa06881b1", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 5420, "upload_time": "2018-09-08T11:52:33", "url": "https://files.pythonhosted.org/packages/26/c1/0baa364ff2a2fb97fc473221f89bab8f5343ab3ccdc64fc0e4242f2d0eed/photoarchive-0.5.tar.gz" } ] }