Completed
Push — master ( 931044...cb1112 )
by Andreas
22s queued 11s
created

CMS.printlog()   A

Complexity

Conditions 1

Size

Total Lines 6
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 5
dl 0
loc 6
rs 10
c 0
b 0
f 0
cc 1
nop 1
1
"""Car Music Sorter."""
2
import gettext
3
import os
4
import re
5
import shutil
6
import w_settings
7
8
from sys import exit
9
from tkinter import Tk, PhotoImage, Menu, LabelFrame
10
from tkinter import Toplevel
11
from tkinter.ttk import Button, Label, Progressbar
12
from pathlib import Path
13
from f_getconfig import getconfig
14
from f_logging import writelog
15
16
import tkinter.filedialog as fd
17
input_dir = ''
18
output_dir = ''
19
source_file = []
20
21
22
# BEGIN FUNCTIONS #
23
# FIXME: Вынести по возможности в отдельные файлы
24
# Определение исходной и целевой директорий
25
def workdirs(param):
26
    """Открывает диалог выбора директории."""
27
    if param == 'indir':
28
        global input_dir
29
        input_dir = fd.askdirectory(title = _('Open source directory'))
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable _ does not seem to be defined.
Loading history...
30
        if input_dir != '':
31
            source_label.config(text = f'...{path_short(input_dir, 2)}')
32
            writelog(_('Input DIR set to: ') + input_dir)
33
        else:
34
            input_dir = ''
35
    elif param == 'outdir':
36
        global output_dir
37
        output_dir = fd.askdirectory(title = _('Set destination directory'))
38
        if output_dir != '':
39
            dest_label.config(text = f'...{path_short(output_dir, 2)}')
40
            writelog(_('Output DIR set to: ') + output_dir)
41
        else:
42
            output_dir = ''
43
    elif param == 'clear':
44
        source_label.config(text = _('Input DIR not defined'))
45
        dest_label.config(text = _('Output DIR not defined'))
46
        main_progressbar['value'] = 0
47
        input_dir = output_dir = ''
48
49
50
def path_short(path_string, len):
51
    """Сокращает путь для корректного отображения в лейбле."""
52
    return Path(*Path(path_string).parts[-len:])
53
54
55
# Вызов "О программе"
56
def popup_about(vers):
57
    """Открывает окно 'О программе'."""
58
# Центровка окна
59
    main_width = 400
60
    main_height = 150
61
    center_x_pos = int(window.winfo_screenwidth() / 2) - main_width
62
    center_y_pos = int(window.winfo_screenheight() / 2) - main_height
63
64
    popup = Toplevel()
65
    popup.geometry(f'{main_width}x{main_height}+{center_x_pos}+{center_y_pos}')
66
    popup.title(_('About'))
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable _ does not seem to be defined.
Loading history...
67
    imagepath = 'data/imgs/main.png'
68
    img = PhotoImage(file = imagepath)
69
    poplabel1 = Label(popup, image = img)
70
    poplabel1.grid(sticky = 'W', column = 0, row = 0, rowspan = 2)
71
72
    name_vers_str = 'Car Music Sorter\n\n' + _('Version: ') + vers
73
    author_github = 'https://github.com/intervisionlord'
74
    prog_author = _('\nAuthor: ') + 'Intervision\nGithub: ' + author_github
75
    poplabel_maindesc = Label(popup,
76
                              text = name_vers_str + prog_author,
77
                              justify = 'left')
78
    poplabel_maindesc.grid(sticky = 'W', column = 1, row = 0)
79
# Автор иконок
80
    icons_author = _('Icons: ') + 'icon king1 ' + _('on') + ' freeicons.io'
81
    poplabel_icons = Label(popup, text = icons_author, justify = 'left')
82
    poplabel_icons.grid(sticky = 'W', column = 1, row = 1)
83
84
    popup.grab_set()
85
    popup.focus_set()
86
    popup.wait_window()
87
88
89
# Основные операции
90
def check_paths():
91
    """Проверяет, что все пути заданы корректно и запускает копирование."""
92
    if input_dir == '' or output_dir == '':
93
        writelog(_('Input DIR or Output DIR are not defined!'))
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable _ does not seem to be defined.
Loading history...
94
    elif input_dir == output_dir:
95
        writelog(_('Input DIR and Output DIR must be different!'))
96
        return
97
    else:
98
        for path, subdirs, files in os.walk(input_dir):
99
            for file in files:
100
                # Перегоняем MP3 без лайвов и ремиксов в целевую директорию.
101
                filtered = re.search(r'^(?!(.*[Rr]emix.*|.*[Ll]ive.*)).*mp3',
102
                                     file)
103
                if filtered is not None:
104
                    source_file.append(f'{path}/{filtered.group(0)}')
105
    main_progressbar['maximum'] = len(source_file)
106
    for files in source_file:
107
        maincopy(files, output_dir)
108
    source_file.clear()
109
110
111
def processing():
112
    """Удаляет ремиксы и лайвы."""
113
    check_paths()
114
# Удаление ремиксов и лайвов
115
# TODO: Depricated
116
    liveregexp = r'.*\(.*[Rr]emix.*\).*|.*\(.*[Ll]ive.*\).*'
117
    for files in os.walk(output_dir):
118
        for file in files[2]:
119
            try:
120
                source_file.append(re.search(liveregexp, file).group(0))
121
            except Exception:
122
                pass
123
    for file in source_file:
124
        writelog(_('Removing Remix: ') + file)
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable _ does not seem to be defined.
Loading history...
125
        os.remove(f'{output_dir}/{file}')
126
        main_progressbar['value'] = main_progressbar['value'] + 1
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable main_progressbar does not seem to be defined.
Loading history...
127
        window.update_idletasks()
128
    source_file.clear()  # Очищаем список
129
    polish_filenames()
130
131
132
def polish_filenames():
133
    """Удаляет из имен треков мусор."""
134
# Готовим список свежепринесенных файлов с вычищенными ремиксами и лайвами
135
    for files in os.walk(output_dir):
136
        for file in files[2]:
137
            try:
138
                source_file.append(file)
139
            except Exception:
140
                pass
141
142
# Убираем из имен файлов мусор (номера треков в различном формате)
143
    main_progressbar['maximum'] = (main_progressbar['maximum'] +
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable main_progressbar does not seem to be defined.
Loading history...
144
                                   len(source_file))
145
    trashregexp = r'^[\d{1,2}\s\-\.]*'
146
    for file in source_file:
147
        new_file = re.sub(trashregexp, '', file)
148
        shutil.move(f'{output_dir}/{file}', f'{output_dir}/{new_file}')
149
        main_progressbar['value'] = main_progressbar['value'] + 1
150
        window.update_idletasks()
151
    source_file.clear()
152
    writelog(_('Completed!'))
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable _ does not seem to be defined.
Loading history...
153
154
155
# Копируем файлы
156
def maincopy(files, output_dir):
157
    """Копирует файлы."""
158
    writelog(f'{files}')
159
    filename = str.split(files, '/')
160
    writelog(filename[-1])
161
    shutil.copyfile(f'{files}', f'{output_dir}/{filename[-1]}')
162
    main_progressbar['value'] = main_progressbar['value'] + 1
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable main_progressbar does not seem to be defined.
Loading history...
163
    window.update_idletasks()
164
# END FUNCTIONS #
165
166
167
# Вводим основные переменные
168
vers = getconfig()['core']['version']
169
langcode = getconfig()['settings']['locale']
170
# Локализация
171
gettext.translation('CarMusicSorter', localedir='l10n',
172
                    languages=[langcode]).install()
173
writelog('init')
174
# Рисуем окно
175
window = Tk()
176
window.iconphoto(True, PhotoImage(file = 'data/imgs/main.png'))
177
window.geometry('370x270')
178
window.eval('tk::PlaceWindow . center')
179
window.title('Car Music Sorter')
180
window.resizable(False, False)
181
182
# Пути к оформлению
183
sourceicon = PhotoImage(file = 'data/imgs/20source.png')
184
desticon = PhotoImage(file = 'data/imgs/20dest.png')
185
launchicon = PhotoImage(file = 'data/imgs/20ok.png')
186
clearicon = PhotoImage(file = 'data/imgs/20clear.png')
187
188
# Основное меню
189
menu = Menu(window)
190
menu_about = Menu(menu, tearoff = 0)
191
menu_file = Menu(menu, tearoff = 0)
192
menu.add_cascade(label = _('File'), menu = menu_file)
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable _ does not seem to be defined.
Loading history...
193
menu.add_cascade(label = _('Info'), menu = menu_about)
194
195
# Элементы меню
196
menu_about.add_command(label = _('About'),
197
                       command = lambda: popup_about(vers),
198
                       accelerator = 'F1')
199
menu_file.add_command(label = _('Input Dir'),
200
                      command = lambda: workdirs('indir'),
201
                      accelerator = 'CTRL+O')
202
menu_file.add_command(label = _('Output Dir'),
203
                      command = lambda: workdirs('outdirs'),
204
                      accelerator = 'CTRL+D')
205
menu_file.add_command(label = _('Clear'),
206
                      command = lambda: workdirs('clear'),
207
                      accelerator = 'CTRL+R')
208
menu_file.add_separator()
209
menu_file.add_command(label = _('Settings'),
210
                      command = w_settings.popup_settings)
211
menu_file.add_separator()
212
menu_file.add_command(label = _('Exit'),
213
                      command = exit,
214
                      accelerator = 'CTRL+E')
215
216
# Биндим хоткеи к функциям
217
menu_file.bind_all('<Command-o>', lambda event: workdirs('indir'))
218
menu_file.bind_all('<Command-d>', lambda event: workdirs('outdir'))
219
menu_file.bind_all('<Command-r>', lambda event: workdirs('clear'))
220
menu_file.bind_all('<Command-e>', exit)
221
222
menu_about.bind_all('<F1>', lambda event: popup_about(vers))
223
window.config(menu = menu)
224
225
# Строим элеметны основного окна и группы
226
first_group = LabelFrame(window, text = _('IO Directories'))
227
228
first_group.grid(sticky = 'WE', column = 0, row = 0, padx = 5, pady = 10,
229
                 ipadx = 2, ipady = 4)
230
231
operation_group = LabelFrame(window, text = _('Operations'))
232
operation_group.grid(sticky = 'WE', column = 0, row = 3, padx = 5, pady = 5,
233
                     ipadx = 5, ipady = 5)
234
235
progress_group = LabelFrame(window, text = _('Progress'))
236
progress_group.grid(sticky = 'WE', column = 0, row = 1, padx = 5, pady = 5,
237
                    ipadx = 0, ipady = 2, rowspan = 2)
238
239
# Прогрессбар
240
main_progressbar = Progressbar(progress_group, length = 350, value = 0,
241
                               orient = 'horizontal', mode = 'determinate')
242
main_progressbar.grid(pady = 4, column = 0, row = 1)
243
244
# Поясняющие лейблы
245
source_label_text = _('Input DIR not defined')
246
dest_label_text = _('Output DIR not defined')
247
source_label = Label(first_group, text = source_label_text, justify = 'left')
248
source_label.grid(column = 1, row = 0)
249
dest_label = Label(first_group, text = dest_label_text, justify = 'left')
250
dest_label.grid(column = 1, row = 1)
251
252
# Кнопки
253
source_button = Button(first_group, text = _('Input Dir'),
254
                       command = lambda: workdirs('indir'), image = sourceicon,
255
                       width = 20, compound = 'left')
256
source_button.grid(row = 0, ipadx = 2, ipady = 2, padx = 4)
257
258
dest_button = Button(first_group, text = _('Output Dir'),
259
                     command = lambda: workdirs('outdir'), image = desticon,
260
                     width = 20, compound = 'left')
261
dest_button.grid(row = 1, ipadx = 2, ipady = 2, padx = 4)
262
263
launch_button = Button(operation_group, text = _('Process'),
264
                       command = processing, image = launchicon,
265
                       width = 20, compound = 'left')
266
launch_button.grid(column = 0, row = 2, ipadx = 2, ipady = 2, padx = 12)
267
268
clear_button = Button(operation_group, text = _('Clear'),
269
                      command = lambda: workdirs('clear'), image = clearicon,
270
                      width = 20, compound = 'left')
271
272
clear_button.grid(column = 1, row = 2, ipadx = 2, ipady = 2, padx = 0)
273
274
if __name__ == '__main__':
275
    window.mainloop()
276