Completed
Push — master ( 91d748...e1a893 )
by Andreas
19s queued 12s
created

CMS.getconfig()   A

Complexity

Conditions 2

Size

Total Lines 10
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

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