|
12 | 12 | from . import _const |
13 | 13 |
|
14 | 14 |
|
15 | | -class EditMeta(npy.ActionFormV2): |
16 | | - """Edit the metadata of a track. |
17 | | -
|
18 | | - Attributes: |
19 | | - in_insert_mode(bool): |
20 | | - Used to decide whether the form is in insert/normal |
21 | | - mode(if vi_keybindings are enabled). This is actually |
22 | | - set as an attribute of the parent form so that all |
23 | | - text boxes in the form are in the same mode. |
24 | | - """ |
25 | | - |
26 | | - def __init__(self, *args, **kwags): |
27 | | - super().__init__(*args, **kwags) |
28 | | - self.handlers.update({ |
29 | | - '^S': self.h_ok, |
30 | | - '^Q': self.h_cancel |
31 | | - }) |
32 | | - |
33 | | - self.in_insert_mode = False |
34 | | - |
| 15 | +class SingleEditMeta(base.ClidEditMeta): |
| 16 | + """Edit the metadata of a *single* track.""" |
35 | 17 | def create(self): |
36 | | - # error if placed in __init__ |
37 | | - self.TEXTBOX = base.ClidVimTitleText \ |
38 | | - if self.parentApp.settings['vim_mode'] == 'true'\ |
39 | | - else base.ClidTitleText # vim keybindings if enabled |
40 | | - |
41 | | - self.file = self.parentApp.current_file |
| 18 | + self.set_textbox() |
| 19 | + file = self.parentApp.current_files[0] |
42 | 20 | try: |
43 | | - self.meta = stagger.read_tag(self.file) |
44 | | - except stagger.errors.NoTagError: |
45 | | - temp = stagger.Tag23() # create a id3v2.3 tag instance |
46 | | - temp.album = ' ' # so that there is something to write to the file |
47 | | - temp.write(self.parentApp.current_file) |
48 | | - |
49 | | - self.meta = stagger.read_tag(self.parentApp.current_file) |
50 | | - self.meta.album = '' # revert what was just done |
51 | | - self.meta.write() |
| 21 | + meta = stagger.read_tag(file) |
| 22 | + except stagger.NoTagError: |
| 23 | + meta = stagger.Tag23() # create a id3v2.3 tag instance |
52 | 24 |
|
53 | | - self.filenamebox = self.add(self.TEXTBOX, name='Filename', |
54 | | - value=os.path.basename(self.file).replace('.mp3', '')) |
| 25 | + self.filenamebox = self.add(self._title_textbox, name='Filename', |
| 26 | + value=os.path.basename(file).replace('.mp3', '')) |
55 | 27 | self.nextrely += 2 |
| 28 | + super().create() |
56 | 29 |
|
57 | | - self.tit = self.add(self.TEXTBOX, name='Title', value=self.meta.title) |
58 | | - self.nextrely += 1 |
59 | | - self.alb = self.add(self.TEXTBOX, name='Album', value=self.meta.album) |
60 | | - self.nextrely += 1 |
61 | | - self.art = self.add(self.TEXTBOX, name='Artist', value=self.meta.artist) |
62 | | - self.nextrely += 1 |
63 | | - self.ala = self.add(self.TEXTBOX, name='Album Artist', value=self.meta.album_artist) |
64 | | - self.nextrely += 2 |
65 | | - |
66 | | - self.gen = self.add(self.TEXTBOX, name='Genre', value=self.resolve_genre(self.meta.genre)) |
67 | | - self.nextrely += 1 |
68 | | - self.dat = self.add(self.TEXTBOX, name='Date/Year', value=self.meta.date) |
69 | | - self.nextrely += 1 |
70 | | - self.tno = self.add(self.TEXTBOX, name='Track Number', |
71 | | - value=str(self.meta.track if self.meta.track != 0 else '')) |
72 | | - self.nextrely += 2 |
73 | | - self.com = self.add(self.TEXTBOX, name='Comment', value=self.meta.comment) |
74 | | - |
75 | | - |
76 | | - def resolve_genre(self, num_gen): |
77 | | - """Convert numerical genre values to readable values. Genre may be |
78 | | - saved as a str of the format '(int)' by applications like EasyTag. |
79 | | -
|
80 | | - Args: |
81 | | - num_gen (str): str representing the genre. |
82 | | -
|
83 | | - Returns: |
84 | | - str: Name of the genre (Electronic, Blues, etc). Returns |
85 | | - num_gen itself if it doesn't match the format. |
86 | | - """ |
87 | | - match = _const.GENRE_PAT.findall(num_gen) |
| 30 | + for tbox, field in _const.TAG_FIELDS.items(): # show file's tag |
| 31 | + getattr(self, tbox).value = str(getattr(meta, field)) # str for track_number |
88 | 32 |
|
89 | | - if match: |
90 | | - try: |
91 | | - return _const.GENRES[int(match[0])] |
92 | | - except IndexError: |
93 | | - return '' |
94 | | - else: |
95 | | - return num_gen |
| 33 | + def get_fields_to_save(self): |
| 34 | + return _const.TAG_FIELDS |
96 | 35 |
|
97 | | - def h_ok(self, char): |
98 | | - """Handler to save the tags""" |
99 | | - self.on_ok() |
| 36 | + def on_ok(self): |
| 37 | + c = super().on_ok() |
| 38 | + if c is None: |
| 39 | + return None # some error like invalid date or track number has occured |
| 40 | + mp3 = self.files[0] |
| 41 | + new_filename = os.path.dirname(mp3) + '/' + self.filenamebox.value + '.mp3' |
| 42 | + if mp3 != new_filename: # filename was changed |
| 43 | + os.rename(mp3, new_filename) |
| 44 | + main_form = self.parentApp.getForm("MAIN") |
| 45 | + main_form.value.replace_file(old=mp3, new=new_filename) |
| 46 | + main_form.load_files() |
100 | 47 |
|
101 | | - def h_cancel(self, char): |
102 | | - """Handler to cancel the operation""" |
103 | | - self.on_cancel() |
| 48 | + self.switch_to_main() |
104 | 49 |
|
105 | | - def on_cancel(self): # char is for handlers |
106 | | - """Switch to standard view at once without saving""" |
107 | | - self.editing = False |
108 | | - self.parentApp.switchForm("MAIN") |
109 | 50 |
|
110 | | - def on_ok(self): # char is for handlers |
111 | | - """Save and switch to standard view""" |
112 | | - try: |
113 | | - self.meta.date = self.dat.value |
114 | | - except ValueError: |
115 | | - npy.notify_confirm(message='Date should be of the form YYYY-MM-DD', |
116 | | - title='Invalid Date Format', editw=1) |
117 | | - return None |
118 | | - |
119 | | - track = self.tno.value if self.tno.value != '' else '0' # automatically converted to int by stagger |
120 | | - try: |
121 | | - int(track) |
122 | | - except ValueError: |
123 | | - npy.notify_confirm(message='Track number can only take integer values', |
124 | | - title='Invalid Track Number', editw=1) |
125 | | - return None |
126 | | - else: |
127 | | - self.meta.track = track |
128 | | - # FIXME: values of tags are reset to initial when ok is pressed(no prob with ^S) |
129 | | - |
130 | | - self.meta.title = self.tit.value |
131 | | - self.meta.album = self.alb.value |
132 | | - self.meta.genre = self.gen.value |
133 | | - self.meta.artist = self.art.value |
134 | | - self.meta.comment = self.com.value |
135 | | - self.meta.album_artist = self.ala.value |
136 | | - |
137 | | - self.meta.write() |
138 | | - |
139 | | - new_filename = os.path.dirname(self.file) + '/' + self.filenamebox.value + '.mp3' |
140 | | - if self.file != new_filename: # filename was changed |
141 | | - os.rename(self.file, new_filename) |
142 | | - |
143 | | - main_form = self.parentApp.getForm("MAIN") |
144 | | - main_form.value.load_files_and_set_values() |
145 | | - |
146 | | - main_form.wMain.set_status(filename=os.path.basename(new_filename)) # show the new tags in the status line |
147 | | - main_form.load_files() |
148 | | - |
149 | | - self.editing = False |
150 | | - self.parentApp.switchForm("MAIN") |
| 51 | +class MultiEditMeta(base.ClidEditMeta): |
| 52 | + def create(self): |
| 53 | + self.set_textbox() |
| 54 | + self.add(npy.Textfield, color='STANDOUT', editable=False, |
| 55 | + value='Batch tagging {} files'.format(len(self.parentApp.current_files))) |
| 56 | + self.nextrely += 2 |
| 57 | + super().create() |
| 58 | + |
| 59 | + def get_fields_to_save(self): |
| 60 | + # save only those fields which are not empty, to files |
| 61 | + return {tbox: field for tbox, field in _const.TAG_FIELDS.items()\ |
| 62 | + if getattr(self, tbox).value} |
| 63 | + |
| 64 | + def on_ok(self): |
| 65 | + c = super().on_ok() |
| 66 | + if c is None: |
| 67 | + return None # some error like invalid date or track number has occured |
| 68 | + self.switch_to_main() |
0 commit comments