{"id":2116,"date":"2025-03-30T21:59:03","date_gmt":"2025-03-30T18:59:03","guid":{"rendered":"http:\/\/csnotes.ru\/?p=2116"},"modified":"2025-03-30T21:59:04","modified_gmt":"2025-03-30T18:59:04","slug":"%d1%81%d0%be%d1%80%d1%82%d0%b8%d1%80%d0%be%d0%b2%d0%ba%d0%b0-%d1%84%d0%be%d1%82%d0%be%d0%b3%d1%80%d0%b0%d1%84%d0%b8%d0%b9-%d0%b8-%d0%b2%d0%b8%d0%b4%d0%b5%d0%be-%d1%81-%d0%bf%d0%b5%d1%80%d0%b5%d0%bc","status":"publish","type":"post","link":"https:\/\/csnotes.ru\/?p=2116","title":{"rendered":"\u0421\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u043a\u0430 \u0444\u043e\u0442\u043e\u0433\u0440\u0430\u0444\u0438\u0439 \u0438 \u0432\u0438\u0434\u0435\u043e \u0441 \u043f\u0435\u0440\u0435\u043c\u0435\u0449\u0435\u043d\u0438\u0435\u043c"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\">\u0421\u043a\u0440\u0438\u043f\u0442 \u0441\u043e\u0440\u0442\u0438\u0440\u0443\u0435\u0442 \u0444\u043e\u0442\u043e\u0433\u0440\u0430\u0444\u0438\u0438 \u0438 \u0432\u0438\u0434\u0435\u043e \u043f\u043e \u0433\u043e\u0434\u0443 \u0438 \u043c\u0435\u0441\u044f\u0446\u0443 \u0441\u044a\u0435\u043c\u043a\u0438 \u0438 \u043a\u043e\u043f\u0438\u0440\u0443\u0435\u0442 \u0432 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0443\u044e \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u044e.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u041f\u043e\u043d\u0430\u0434\u043e\u0431\u0438\u0442\u0441\u044f \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430 pillow: <strong>pip install pillow<\/strong><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>import os\nimport shutil\nfrom PIL import Image\nfrom PIL.ExifTags import TAGS\nfrom datetime import datetime\n\n# \u0418\u0441\u0445\u043e\u0434\u043d\u0430\u044f \u043f\u0430\u043f\u043a\u0430 \u0441 \u0444\u043e\u0442\u043e\u0433\u0440\u0430\u0444\u0438\u044f\u043c\u0438 \u0438 \u0432\u0438\u0434\u0435\u043e\nSOURCE_DIR = r\"D:\\dir\\dir\"\n\n# \u041f\u0430\u043f\u043a\u0430, \u043a\u0443\u0434\u0430 \u0441\u043a\u043b\u0430\u0434\u044b\u0432\u0430\u0442\u044c \u043e\u0442\u0441\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0435 \u0444\u0430\u0439\u043b\u044b\nDEST_DIR = r\"dir\"\n\n# \u041f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u043c\u044b\u0435 \u0444\u043e\u0440\u043c\u0430\u0442\u044b\nPHOTO_EXTENSIONS = (\".jpg\", \".jpeg\", \".png\")\nVIDEO_EXTENSIONS = (\".mp4\", \".avi\", \".mov\", \".mkv\", \".wmv\", \".flv\", \".webm\")\n\n\n# \u0424\u0443\u043d\u043a\u0446\u0438\u044f \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f \u0434\u0430\u0442\u044b \u0444\u043e\u0442\u043e\ndef get_photo_date(photo_path):\n    try:\n        img = Image.open(photo_path)\n        exif_data = img._getexif()\n\n        if exif_data:\n            for tag, value in exif_data.items():\n                if TAGS.get(tag) == \"DateTimeOriginal\":  # \u0414\u0430\u0442\u0430 \u0441\u044a\u0435\u043c\u043a\u0438 \u0438\u0437 EXIF\n                    return datetime.strptime(value, \"%Y:%m:%d %H:%M:%S\")\n\n    except Exception as e:\n        print(f\"\u041e\u0448\u0438\u0431\u043a\u0430 \u0447\u0442\u0435\u043d\u0438\u044f EXIF {photo_path}: {e}\")\n\n    # \u0415\u0441\u043b\u0438 EXIF \u043d\u0435\u0442, \u0431\u0435\u0440\u0435\u043c \u0434\u0430\u0442\u0443 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u0444\u0430\u0439\u043b\u0430\n    return datetime.fromtimestamp(os.path.getctime(photo_path))\n\n\n# \u0424\u0443\u043d\u043a\u0446\u0438\u044f \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f \u0434\u0430\u0442\u044b \u0432\u0438\u0434\u0435\u043e\ndef get_video_date(video_path):\n    # \u0423 \u0432\u0438\u0434\u0435\u043e EXIF \u043d\u0435\u0442, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0431\u0435\u0440\u0435\u043c \u0434\u0430\u0442\u0443 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u0444\u0430\u0439\u043b\u0430\n    return datetime.fromtimestamp(os.path.getctime(video_path))\n\n\n# \u0424\u0443\u043d\u043a\u0446\u0438\u044f \u0441\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u043a\u0438 \u0444\u0430\u0439\u043b\u043e\u0432\ndef sort_media(source_dir, dest_dir):\n    if not os.path.exists(dest_dir):\n        os.makedirs(dest_dir)\n\n    for root, _, files in os.walk(source_dir):\n        for file in files:\n            file_path = os.path.join(root, file)\n            file_ext = file.lower().endswith\n\n            if file_ext(PHOTO_EXTENSIONS):  # \u041e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0430 \u0444\u043e\u0442\u043e\n                media_date = get_photo_date(file_path)\n            elif file_ext(VIDEO_EXTENSIONS):  # \u041e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0430 \u0432\u0438\u0434\u0435\u043e\n                media_date = get_video_date(file_path)\n            else:\n                continue  # \u041f\u0440\u043e\u043f\u0443\u0441\u043a\u0430\u0435\u043c \u0444\u0430\u0439\u043b\u044b \u0434\u0440\u0443\u0433\u0438\u0445 \u0444\u043e\u0440\u043c\u0430\u0442\u043e\u0432\n\n            if media_date:\n                year = str(media_date.year)\n                month = f\"{media_date.month:02d}\"\n\n                # \u0421\u043e\u0437\u0434\u0430\u0435\u043c \u043f\u0430\u043f\u043a\u0443: \u0413\u043e\u0434\/\u041c\u0435\u0441\u044f\u0446\n                target_folder = os.path.join(dest_dir, year, month)\n                os.makedirs(target_folder, exist_ok=True)\n\n                # \u041f\u0435\u0440\u0435\u043c\u0435\u0449\u0430\u0435\u043c \u0444\u0430\u0439\u043b\n                shutil.move(file_path, os.path.join(target_folder, file))\n                print(f\"{file} \u2192 {target_folder}\")\n\n\n# \u0417\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u043c \u0441\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u043a\u0443\nsort_media(SOURCE_DIR, DEST_DIR)\nprint(\"\u0421\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u043a\u0430 \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u0430!\")<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n","protected":false},"excerpt":{"rendered":"<p>\u0421\u043a\u0440\u0438\u043f\u0442 \u0441\u043e\u0440\u0442\u0438\u0440\u0443\u0435\u0442 \u0444\u043e\u0442\u043e\u0433\u0440\u0430\u0444\u0438\u0438 \u0438 \u0432\u0438\u0434\u0435\u043e \u043f\u043e \u0433\u043e\u0434\u0443 \u0438 \u043c\u0435\u0441\u044f\u0446\u0443 \u0441\u044a\u0435\u043c\u043a\u0438 \u0438 \u043a\u043e\u043f\u0438\u0440\u0443\u0435\u0442 \u0432 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0443\u044e \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u044e. \u041f\u043e\u043d\u0430\u0434\u043e\u0431\u0438\u0442\u0441\u044f \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430 pillow: pip install pillow<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[43],"tags":[48,47,49,45,46],"class_list":["post-2116","post","type-post","status-publish","format-standard","hentry","category-scrypts","tag-os","tag-pillow","tag-shutil","tag-45","tag-46"],"views":69,"_links":{"self":[{"href":"https:\/\/csnotes.ru\/index.php?rest_route=\/wp\/v2\/posts\/2116","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/csnotes.ru\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/csnotes.ru\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/csnotes.ru\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/csnotes.ru\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=2116"}],"version-history":[{"count":1,"href":"https:\/\/csnotes.ru\/index.php?rest_route=\/wp\/v2\/posts\/2116\/revisions"}],"predecessor-version":[{"id":2118,"href":"https:\/\/csnotes.ru\/index.php?rest_route=\/wp\/v2\/posts\/2116\/revisions\/2118"}],"wp:attachment":[{"href":"https:\/\/csnotes.ru\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=2116"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/csnotes.ru\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=2116"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/csnotes.ru\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=2116"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}