Очищаем папку с загрузками при помощи программы на Python -19



Введение


Как человек, который только начинает осваивать Python, я стараюсь получать новые знания и умения путём непосредственной практики. На мой взгляд, данный подход лучше штрудирования гайдов и многотомников по программированию. В первую очередь проектами подобным тому, о котором расскажу, я пытаюсь закрыть свои потребности. На втором месте находится надежда на то, что кому-то ещё может пригодиться то, что я создам (после того, как все имеющиеся ошибки будут исправлены)

Идея данной программы пришла в момент, когда пытался найти ранее загруженный файл среди «помойки», образовавшейся в папке «Загрузки». Изображения, документы, архивы и видео с музыкой: разобраться в этой мешанине и отфильтровать файлы можно было бы конечно, но неохота из-за больших временных затрат. И я подумал о том, что неплохо иметь программу, которая сама разберёт папку «Загрузки» и распределит файлы по стандартным папкам системы «Изображения», «Документы», «Видео» и «Музыка», а ненужные файлы удалит. В итоге на свет появился Perfectionist Organizer, о котором я хотел бы рассказать. Сразу скажу, что это статья от новичка для новичков, потому опытные Python-программисты не найдут здесь ничего полезного (кроме возможности поковыряться в коде и указать на множество ошибок).

Общая идея


Первое, что должна делать программа — определять в какой операционной системе она запущена. Это нужно потому, что в Linux и Windows папка «Загрузки» расположена по разным путям (возможности тестировать программу на Mac у меня нет, потому эту ОС я не учитывал). В обнаруженной папке с загрузками программа перебирает все имеющиеся файлы и определяет к какому типу они относятся (музыка, видео, документы и пр.). После происходит перемещение обнаруженных файлов в дефолтные папки и программа узнаёт у пользователя, что делать с теми файлами, которые не подходят для перемещения — оставить или удалить.

Импорт необходимых библиотек и определение типа системы


Для работы с операционной системой и файлами в ней нам понадобится библиотека os. Библиотека getpass позволит узнать имя пользователя в системе, а platform определит Windows это или Linux. Все нужные библиотеки подключаем в самом начале через import и после определяем тип ОС и имя пользователя.

import os
import getpass
import platform
type_os = platform.system()
usermane = getpass.getuser()

Создание словаря с расширениями популярных файлов и дефолтными папками, которые с ними связаны


Стандартными средствами Python создадим четыре словаря с самыми популярными типами файлов: музыка, изображения, видео и документы.

video_folder = {".3gp" : "Видео/", ".avi" : "Видео/", ".flv" : "Видео/", ".m4v" : "Видео/", ".mkv" : "Видео/", ".mov" : "Видео/", ".mp4" : "Видео/", ".wmv" : "Видео/", ".webm" : "Видео/"}
music_folder = {".mp3" : "Музыка/", ".aac": "Музыка/", ".flac" : "Музыка/", ".mpc" : "Музыка/", ".wma" : "Музыка/", ".wav" : "Музыка/"}
pic_folder = {".raw" : "Изображения/", ".jpg" : "Изображения/", ".tiff" : "Изображения/", ".psd" : "Изображения/", ".bmp" : "Изображения/", ".gif" : "Изображения/", ".png" : "Изображения/", ".jp2" : "Изображения/", ".jpeg" : "Изображения/"}
doc_folder = {".doc" : "Документы/", ".docx" : "Документы/", ".txt" : "Документы/", ".rtf" : "Документы/", ".pdf" : "Документы/", ".fb2" : "Документы/", ".djvu" : "Документы/", ".xls" : "Документы/", ".xlsx" : "Документы/", ".ppt" : "Документы/", ".pptx" : "Документы/", ".mdb" : "Документы/", ".accdb" : "Документы/", ".rar" : "Документы/", ".zip" : "Документы/", ".7z" : "Документы/"}

Не забываем, что после имени папки будет ещё идти имя файла, потому в конце у меня стоит /. Новые типы файлов легко добавляются путём редактирования словаря.

Запрашиваем у пользователя название папки с загрузками


В Windows и Linux папка с загрузками видится в системе с разными названиями. Для Windows это независимо от локализации папка Downloads, тогда на Linux-дистрибутивах эта папка называется «Загрузки». К тому же может произойти так, что пользователь изменил название папки с загруженными файлами и его нужно спросить отличается ли текущее название директории от стандартных.

if type_os == "Linux":
    user_downloads_path = input("Как у вас называется папка с загрузками? (по-умолчанию: Загрузки) ") or "Загрузки"
if type_os == "Windows":
user_downloads_path = input("Как у вас называется папка с загрузками? (по-умолчанию: Загрузки) ") or "Downloads"

Конструкция or позволяет использовать в input значения по-умолчанию. То есть, пользователю в случае если у него нет изменений в имени папки с загрузками, не нужно ничего делать, программа сама подставит нужные значения в дальнейший код.

Устанавливаем путь до папки с загрузками


В зависимости от операционной системы папка с загрузками может находиться в разных местах. Для Linux — это папка расположена по пути /home/имя пользователя/Загрузки/, в Windows же это путь C:/Users/имяпользователя/Downloads/. Чтобы в дальнейшем не прописывать эти пути вручную, проще создать переменные, в которых эти пути будут указаны.

if type_os == "Linux":
    default_path_d = "/home/" + usermane + "/" + user_downloads_path + "/"
else:
    default_path_d_win = r"C:/Users/" + usermane + r"/" + user_downloads_path+ r"/"

Задаём путь к папке с загрузками для конкретного пользователя


Чтобы в дальнейшем использовать возможности ранее подключённых модулей для работы с операционной системой и файлами, мы должны задать путь к папке с загрузками, применяя те переменные, которые создали и получили ранее.

if type_os == "Linux":
    downloads_path = os.listdir("/home/" + usermane + "/" + user_downloads_path)
else:
    downloads_path_win = os.listdir(r"C:/Users/" + usermane + r"/" + user_downloads_path)

Ну и также для удобства дальнейшего использования кода зададим путь вида /домашняяпапка/имяпользователя

if type_os == "Linux":
    default_path_u = "/home/" + usermane + "/"
else:
    default_path_u_win = r"C:/Users/" + usermane + r"/"

Проверяем наличие конкретных файлов в папке с загрузками


Путём перебора словаря мы сравниваем его ключи с расширениями файлов, которые находятся в папке с загрузками. Если расширение соответствует ключу, то нужный файл нужно переместить в соответствующую дефолтную папку (имя которой является значением в словаре).

#Проверяем есть ли в папке загрузок аудиофайлы. Если есть, кидаем их в папку Музыка
for music_format in music_folder:
    if type_os == "Linux":
        for name_file in downloads_path:
            if name_file.endswith(music_format):
                result = name_file.split(str(music_format), 1)
                os.rename(default_path_d + result[0] + music_format, default_path_u + music_folder.get(music_format) + result[0] + music_format)
    if type_os == "Windows":
        for name_file in downloads_path_win:
            if name_file.endswith(music_format):
                result = name_file.split(str(music_format), 1)
                os.rename(default_path_d_win + result[0] + music_format, default_path_u_win + "Music" + r"/" + result[0] + music_format)
#Проверяем есть ли в папке загрузок изображения. Если есть, кидаем их в папку Изображения
for pic_format in pic_folder:
    if type_os == "Linux":
        for name_file in downloads_path:
            if name_file.endswith(pic_format):
                result = name_file.split(str(pic_format), 1)
                os.rename(default_path_d + result[0] + pic_format, default_path_u + pic_folder.get(pic_format) + result[0] + pic_format)
    if type_os == "Windows":
        for name_file in downloads_path_win:
            if name_file.endswith(pic_format):
                result = name_file.split(str(pic_format), 1)
                os.rename(default_path_d_win + result[0] + pic_format, default_path_u_win + "Pictures" + r"/" + result[0] + pic_format)
#Проверяем есть ли в папке загрузок документы или архивы. Если есть, кидаем их в папку Документы
for doc_format in doc_folder:
    if type_os == "Linux":
        for name_file in downloads_path:
            if name_file.endswith(doc_format):
                result = name_file.split(str(doc_format), 1)
                os.rename(default_path_d + result[0] + doc_format, default_path_u + doc_folder.get(doc_format) + result[0] + doc_format)
    if type_os == "Windows":
        for name_file in downloads_path_win:
            if name_file.endswith(doc_format):
                result = name_file.split(str(doc_format), 1)
                os.rename(default_path_d_win + result[0] + doc_format, default_path_u_win + "Documents" + r"/" + result[0] + doc_format)

Изначально я планировал решить задачу поиска расширений файлов путём использования регулярных выражений и занимался их формулировкой. Но потом прочитал на одном из сайтов, что если вы желаете решить какую-либо задачу, то только в последнюю очередь нужно пользоваться регулярными выражениями. Python имеет иные более простые и понятные способы сделать то, что от вас требуется. Потому вместо этих выражений расширение файла определяется путём использования строкового метода endswith(). Он берёт ключ из словаря и проверяет заканчивается ли файл на него. Затем при помощи метода split() берётся только имя файла для дальнейшего перемещения при помощи os.rename(). В качестве аргументов последнего используются все ранее созданные переменные.

Спрашиваем у пользователя, что делать с оставшимися файлами


После того, как нужные файлы отсортированы программа должна либо завершиться, либо удалить те файлы, которые не попали под перемещение (например, exe-файлы или deb-пакеты). Решение об этом принимает пользователь, по-умолчанию удаление не происходит.

#Запрос на удаление оставшихся файлов в директории загрузок
delete_user_confirm = input('Удалить из папки загрузок оставшиеся файлы? Напишите да или нет (по-умолчанию: нет) ' or 'нет')
if delete_user_confirm == 'да':
    if type_os == "Linux":
        files_to_remove = os.listdir(default_path_d)
        for remove_files in files_to_remove:
            os.remove(default_path_d + "/" + remove_files)
    if type_os == "Windows":
        files_to_remove = os.listdir(default_path_d_win)
        for remove_files in files_to_remove:
            os.remove(default_path_d_win + "/" + remove_files)
else:
    print('Программа завершила работу. Все файлы размещены.')

Подводя итог


Постарался объяснить то, как работает созданная мной программа как можно понятнее. Но думаю, что желающие разбираться всё равно пересмотрят сам код несколько раз. Perfectionist Organizer представлен в двух версиях — консольной и графической. По ссылке на мой Github можно найти обе, там же приведены инструкции по тому, как скачать и использовать программу. Я прогнал консольную версию на своей основной ОС (Archlinux) и GUI-версию в виртуальной машине на Windows 7. В обоих случаях программа сработала на «УРА». Также хочу прикрепить демонстрацию того, как она работает под Linux. Если эта тема кому-то будет интересна, то в следующей статье расскажу, как я делал GUI-версию и с какими сложностями столкнулся.

Демонстрация работы программы Perfectionist Organizer
image

Планы на будущее


Следующей на очереди программа, которая будет напоминать о важных событиях из таблицы Google Sheets в Telegram'е. Как только закончу её расскажу здесь. Любые свои вопросы и feedback по работе Perfectionist Organizer можете оставлять в комментариях или в личку. Спасибо за внимание!

Вы можете помочь и перевести немного средств на развитие сайта



Комментарии (54):

  1. eumorozov
    /#20651507

    Можно побыть немного занудой?


    if type_os == "Linux":
        default_path_d = "/home/" + usermane + "/" + user_downloads_path + "/"
    else:
        default_path_d_win = r"C:/Users/" + usermane + r"/" + user_downloads_path+ r"/"

    Использование модуля pathlib из стандартной библиотеки приводит к гораздо более читаемому и удобному коду. Префикс r в части после else совершенно не нужен. С pathlib код стал бы намного более читабельный, сейчас это какая-то каша, в которой глаза постоянно спотыкаются на бесконечных +.


    Пользовательские каталоги типа Downloads под Linux правильно брать из xdg-user-dirs. В Windows, кстати, пользователь тоже может менять их местоположение.

    • Aleksashka1990
      /#20651531

      конечно можно и даже нужно :) спасибо за дополнения, учту в сл. раз или может даже перепишу это, чтобы не было кашей. да, в данный момент вообще не учитывается, что пользователь мог перенести Загрузки в другое место.

    • Lazytech
      /#20653401

      Тоже немного побуду занудой: наверное, все-таки не usermane («грива пользователя»), а username («имя пользователя»). :)

      • maxzhurkin
        /#20653939

        Кто-то уже отписал кучу сообщений об ошибке в личку

        • Aleksashka1990
          /#20653943

          ошибки в основном грамматические, по крайней мере в личке инфа о них

    • maxzhurkin
      /#20653917

      Занудой надо быть последовательно: есть ещё относительно распространённые ОС вроде Free/Net/Open/DraginFlyBSD (пожалуй, примерно в порядке убывания распространённости/популярности), для которых код бы вполне работал, если бы не линуксовиндовый шовинизм автора

      P.S. кажется, я не учёл, что если последовать вашим рекомендациям, он, видимо, и заработает и там. Тем они (рекомендации) ещё ценнее

      • Aleksashka1990
        /#20653931 / -1

        ну на Windows и Linux работает. а на др. системы я даже не ориентировался. потому что не надо.

        • eumorozov
          /#20653937 / +1

          Оно только у вас работает. Например, я после установки Linux часто меняю каталоги типа ~/Загрузки, потому что много работаю в командной строке, и мне неудобно в командной строке постоянно менять язык и регистр. И все программы корректно это отрабатывают, потому что есть стандарты Free Desktop, которые описывают, где брать местоположения подобных каталогов.


          Для Windows такие стандарты тоже есть, и многие пользователи в Windows тоже переносят подобные каталоги. Например, разбивают диск на два: системный и пользовательский, и переносят каталоги типа Мои Документы на пользовательский раздел (D:\).


          И универсальный инструмент должен использовать эти настройки, тем более, что это совсем несложно.

          • Aleksashka1990
            /#20653967 / -3

            вы полагаете, что только я после установки системы оставляю папку с загрузками там, где она стоит по-умолчанию? :) а все иные пользователи сразу же начинают её перемещать в другие места? говоря многие вы оперируете достаточно размытыми понятиями. например, число пользователей Office 365 (а следовательно пользователей Windows) достигло 135 млн человек. вы можете назвать какой процент из этих людей переносит папку загрузок после установки системы?

            • BoogieMan75
              /#20654485

              Вы просто делаете не универсальное решение и вам на это пытаются указать, а вы старательно отмазываетесь. Хотите делать что то — старайтесь делать это хорошо.

              • Aleksashka1990
                /#20654711

                Это не попытка указать на ошибки, а попытка умничать. В этом случае человек пытается выдать свой опыт за то, что делают другие. Чего делать не стоит. Обратите внимание на нормальные указания на ошибки и мою реакцию — увидите разницу. Я с радостью воспринимаю и принимаю критику, но только если это критика, а не выпендреж.

                • eumorozov
                  /#20656463

                  Если я пытаюсь умничать, то как быть с тем, что, например, Ubuntu для установки в каждом языке создает свои каталоги: ~/Рабочий Стол vs ~/Desktop, ~/Загрузки vs ~/Downloads, и т.д. для каждого языка. У каждого пользователя, который при установке выбрал язык отличный от английского, будут другие названия каталогов.


                  Ну и вообще, ваш подход напоминает анекдот про машину для бритья. Что лица у всех разные… до первого использования машины.


                  Удачи в реальном мире с таким подходом!

                  • Aleksashka1990
                    /#20656497 / -1

                    Ну так у меня и прописан вариант для русской версии установки. Я не заявлял нигде, что этот код будет работать на всех локализациях Linux. Вы читайте внимательно — в первую очередь я делал это для себя. У меня русская версия Archlinux, Windows в виртуалке. На основании этого и делал. Зачем в таком случае требовать универсальности? Если её изначально не заявлено на данный момент.

                    • eumorozov
                      /#20656513

                      Критику никто не любит, и критиковать правильно никто не умеет.


                      Просто получается, что вы выложили скрипт:


                      1. Неоптимально написаный: трудно читается, не является идиоматичным python-кодом, не использует все возможности стандартной библиотеки, использует неоптимальные структуры данных.
                      2. Не универсальный, подходит для определенных усредненных конфигураций ОС

                      Ну и в чем тогда смысл? Как пример хорошего кода на Python ­— он таким не является. Как инструмент, который может быть полезен другим — тогда надо было сделать более универсальным. Чтобы покритиковали — так мы и критикуем. :)

  2. eumorozov
    /#20651533 / +1

    Вот эти словари:


    video_folder = {".3gp" : "Видео/", ".avi" : "Видео/", ".flv" : "Видео/", ".m4v" : "Видео/", ".mkv" : "Видео/", ".mov" : "Видео/", ".mp4" : "Видео/", ".wmv" : "Видео/", ".webm" : "Видео/"}
    music_folder = {".mp3" : "Музыка/", ".aac": "Музыка/", ".flac" : "Музыка/", ".mpc" : "Музыка/", ".wma" : "Музыка/", ".wav" : "Музыка/"}
    pic_folder = {".raw" : "Изображения/", ".jpg" : "Изображения/", ".tiff" : "Изображения/", ".psd" : "Изображения/", ".bmp" : "Изображения/", ".gif" : "Изображения/", ".png" : "Изображения/", ".jp2" : "Изображения/", ".jpeg" : "Изображения/"}
    doc_folder = {".doc" : "Документы/", ".docx" : "Документы/", ".txt" : "Документы/", ".rtf" : "Документы/", ".pdf" : "Документы/", ".fb2" : "Документы/", ".djvu" : "Документы/", ".xls" : "Документы/", ".xlsx" : "Документы/", ".ppt" : "Документы/", ".pptx" : "Документы/", ".mdb" : "Документы/", ".accdb" : "Документы/", ".rar" : "Документы/", ".zip" : "Документы/", ".7z" : "Документы/"}

    отформатированы просто ужасно, невозможно читать. Кроме того, зачем здесь использовать словарь, если у всех ключей одно и то же значение? Налицо неверный выбор структуры данных.


    Ну и дальше работа с этими словарями вызывает… гм… вопросы… Вот это:
    result = name_file.split(str(doc_format), 1)


    Да за такое надо линейкой по рукам бить, простите. Потому что это просто адский способ работы со словарями, просто намеренное запутывание кода какое-то.

    • Aleksashka1990
      /#20652109

      Тонкость в том, что совсем не намеренная :) За комментарий спасибо!

    • Aleksashka1990
      /#20653481

      некому линейкой по рукам бить, я одинок и познаю Python самостоятельно :) потому мне и нужна критика, разбор кода, указание на ошибки. на мой взгляд, это лучше, чем писание «в стол».

      • eumorozov
        /#20653631

        Начинать самостоятельно надо с Python Tutorial. Потом пробежаться по Library Reference, хотя бы бегло, чтобы не изобретать велосипед.


        И когда вы пишете код типа этих адских словарей, которые на 90% состоят из копи-пасты, в тот момент, когда вы 5-й раз писали одно и то же, уже надо остановиться и задать себе вопрос: «А то ли я делаю?»


        Хороший программист почти никогда не копипастит. И не пишет такой boilerplate код. Кстати, вот эти бесконечные конкатенации путей file_name_a + file_name_b в общем из той же оперы.

        • Aleksashka1990
          /#20653635

          Ну так я пока что и не хороший программист, я только учусь :)

  3. vpiskunov
    /#20651553 / +4

    Да простит меня комьюнити за мое мнение, но, еще раз ИМХО, статьи с подобным уровнем подготовки а-ля курсач 3-го курса первого полугодия способствуют общему понижению уровня ресурса.
    Особенно, если учесть использование жутких антипаттернов.

  4. DollaR84
    /#20651741

    Я тоже сделаю небольшое замечание по словарям. Постоянное повторение одного и того же куска кода, или значения в словаре, или еще что повторяющееся должно сразу наталкивать на мысль, что здесь что-то не так, и наверняка можно оптимизировать более доступно.
    Например все эти 4 словаря можно преобразовать к одному словарю типа:

    folders = {
                "Видео/": [".3gp", ".avi", ".flv", ".m4v", ".mkv", ".mov", ".mp4", ".wmv", ".webm"],
                "Музыка/": [".mp3", ".aac", ".flac", ".mpc", ".wma", ".wav"],
                "Изображения/": [".raw", ".jpg", ".tiff", ".psd", ".bmp", ".gif", ".png", ".jp2", ".jpeg"],
                "Документы/": [".doc", ".docx", ".txt", ".rtf", ".pdf", ".fb2", ".djvu", ".xls", ".xlsx", ".ppt", ".pptx", ".mdb", ".accdb", ".rar", ".zip", ".7z"]
    }
    

    Тогда потом получится один маленький цикл на 4 итерации. А Наличие расширения в списке можно проверять оператором in.
    Например что-то типа такого:
    ext = #тут вы получаете расширение файла
    for folder, ext_list in folders.items():
        if ext in ext_list:
            #ваш код
    

    • Denai
      /#20652987

      Здесь точка в каждом из значений не менее лишняя, чем повторение имени папки

      • DollaR84
        /#20653675

        Возможно. Способ получения расширения файлов и работа с ними оставлена автору. Я просто показал как можно реорганизовать словарь для более короткого определения и более удобной работы с ним. Так же замечу, что мой вариант не является единственно правильным, а просто один из вариантов, который как по мне в первую очередь бросается в голову, глядя на словари автора. Каждый может построить свои структуры, как кому по нраву.

  5. tsklab
    /#20652127

    C:/Users/имяпользователя/Downloads/
    В разных версиях Windows эта папка находится в других местах. И это по-умолчанию, так как её можно переместить или переопределить, опять же в зависимости от версии Windows/

    • Aleksashka1990
      /#20652431

      В версиях с 7 до 10 папка загрузок всегда находится по одному пути. Проверено уже. А вот возможность переноса это да — я это не учитывал намеренно пока что.

      • maxzhurkin
        /#20666915

        Это только если:

        1. Windows установлена на диске C:
        2. Профиль пользователя находится в C:/Users/имяпользователя/
        3. пользователь никуда не переместил папку загрузок
        4. пользователь не переопределил путь к папке загрузок

        Не многовато ли оговорок для того, чтобы ваши слова соответствовали истине?

  6. Denai
    /#20652475

    А с чего вы взяли что папка с загрузками лежит по пути «C:/Users/» + usermane + r"/" + user_downloads_path"?

    ru.wikipedia.org/wiki/%D0%9F%D0%B5%D1%80%D0%B5%D0%BC%D0%B5%D0%BD%D0%BD%D0%B0%D1%8F_%D1%81%D1%80%D0%B5%D0%B4%D1%8B

    • Aleksashka1990
      /#20652651

      Ну вот у вас где папка Загрузки находится?

      • Denai
        /#20652653 / +1

        D:/downloads/

        • DollaR84
          /#20652757 / +1

          Кстати, у меня точно такой же адрес :)

        • Aleksashka1990
          /#20652817

          Но это явно не стандартный путь. Вариант, при котором папка перемещена пользователем я пока что не рассматривал даже.

          • andreymal
            /#20652829

            А зря. Плюс одна ошибка в статье. У меня вот папки загрузки тоже расположены не по стандартным путям ни в винде, ни в линуксе.


            И домашняя папка пользователя целиком тоже может быть перемещена как минимум в линуксе.

  7. cy-ernado
    /#20652493 / +1

    Очень напомнило мою первую программу на питоне восьмилетней давности, правда я там всё же выбрал регекспы :)

  8. resetme
    /#20653011

    А если у меня MacOS?

  9. Denai
    /#20653015

    А что произойдёт, если в папку для перемещения прав на запись не будет или самой папки не будет или она совпадёт с исходной или файл будет занят другим процессом на момент перемещения, но не будет занят на момент завершения (при включённом удалении)? А с симлинками и вложенными папками что будет? Если места не хватит для переноса файлов, они все в конце удалятся?

  10. BoogieMan75
    /#20653473

    А почему типы файлов не хранить в отдельном конфиге?

    • Oxyd
      /#20653647

      И собственно пути до целевых директорий.

  11. felix21
    /#20653479

    Надо сделать примерно то же, но с целым диском (500 Гб, ntfs). На нем после восстановления данных образовалось около четырехсот папок до тысячи файлов в каждой. Надо отсортировать их по расширениям и положить в соответствующие папки. Система основана на Archlinux, если что.
    Есть ли несложный способ для выполнения этой задачи?

    • svk28
      /#20653869

      Примерно так:
      shell>: export OUTDIR=~/tmp/mp3; mkdir $OUTDIR; find /mnt/disk/ -type f -name "*.mp3" -print -exec cp {} $OUTDIR \;

      Данная команда найдет все mp3-файлы в каталоге /mnt/disk (куда примонтирован диск) и скопирует их в созданный каталог tmp/mp3 в домашнем каталоге пользователя.
      Если я правильно понял задачу.
      Если нужно переместить, то «cp» меняется на «mv», но сперва лучше попробовать с копированием =)

      Это решение в лоб, но по хорошему надо сразу автоматом анализировать типы файлов, создавать соответственно каталоги и копировать туда.

      • felix21
        /#20658369

        Спасибо, Вы правильно поняли задачу. Только желательно сразу перемещать файлы в соответствующие папки на том же диске, ибо под линукс отрезано не так много места на диске.
        Если бы ещё и папки автоматом создавались… ))) Но это не принципиально.

  12. bogolt
    /#20653577

    лучше объединять пути через

    os.path.join(root, dir)

    Спрашивать у пользователя в тексте ввод директории не очень для него удобно. Легко допустить ошибку при вводе. Навреное лучше подключиться к одной из гуи библиотек и показать нормальное окно выбора директории. что-то типа PyWx или PyQt подойдет, хотя конечно подключать их для одного окна это жуткий оверкилл ( хотя кого я обманываю сейчас весь софт так пишется ).

    • eumorozov
      /#20653605

      Нет уже смысла использовать os.path.joinpathlib во много раз удобнее.

      • devpony
        /#20654205 / -1

        Код использующий pathlib очень плохо читается и слишком неявный в отличии от os.path.join.

        • eumorozov
          /#20654233

          А можно пример, где он плохо читается? Я мало работаю с путями, и там, где использюу, мне кажется, что выглядит вполне читаемо.

          • devpony
            /#20657815

            В одном открытом проекте встречал:


            path = long_var_name_a / long_var_name_b /
                long_var_name_c / long_var_name_d / long_var_name_e

            Вместо:


            path = os.path.join(
                long_var_name_a,
                long_var_name_b,
                long_var_name_c,
                long_var_name_d,
                long_var_name_e,
            )

            Форматирование это только одна проблема. Если не держать в голове, что в переменных пути, придётся отматывать контекст назад, пытаясь понять, что же здесь на что делится. С join такой проблемы нет, он задаёт контекст сразу же.

    • kAIST
      /#20655587

      Да можно же использовать tkinter, который на windows к тому же идет в комплекте с питоном. Системный диалог выбор директории, реализуется в одну строчку (кроме импорта конечно же)

      • Aleksashka1990
        /#20655605

        У меня Archlinux, потому я ориентировался в первую очередь на Linux-based дистрибутивы.

        • andreymal
          /#20655619

          У арча tkinter тоже никто не отбирал.

  13. oldmelnik99
    /#20655547 / -1

    Wow. Гениально, лайк!

  14. puyol_dev2
    /#20655801 / -1

    Одной строчкой на питоне. Где-то уже это слышал…