https://habr.com/ru/post/468311/Введение
Как человек, который только начинает осваивать 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
Планы на будущее
Следующей на очереди программа, которая будет напоминать о важных событиях из таблицы Google Sheets в Telegram'е. Как только закончу её расскажу здесь. Любые свои вопросы и feedback по работе Perfectionist Organizer можете оставлять в комментариях или в личку. Спасибо за внимание!