1 from Plugins.Plugin import PluginDescriptor
2 from Screens.Screen import Screen
3 from Screens.InputBox import InputBox
4 from Screens.ChoiceBox import ChoiceBox
5 from Screens.MessageBox import MessageBox
6 from Components.config import config
7 from Components.ActionMap import ActionMap
8 from Components.Button import Button
9 from Components.SelectionList import SelectionList
10 from enigma import eServiceReference, eServiceCenter, iServiceInformation
11 from os import path as os_path
13 def main(session, service, **kwargs):
14 session.open(MovieTagEditor, service, session.current_dialog, **kwargs)
16 def Plugins(**kwargs):
18 from Screens.MovieSelection import setPreferredTagEditor
19 setPreferredTagEditor(TagEditor)
22 return PluginDescriptor(name = "TagEditor", description = _("Edit tags..."), where = PluginDescriptor.WHERE_MOVIELIST, fnc = main)
24 class TagEditor(Screen):
26 <screen name="TagEditor" title="Edit Tags" position="75,155" size="565,280">
27 <widget name="list" position="5,5" size="555,225" scrollbarMode="showOnDemand" />
28 <ePixmap position="0,235" zPosition="4" size="140,40" pixmap="skin_default/buttons/red.png" transparent="1" alphatest="on" />
29 <ePixmap position="140,235" zPosition="4" size="140,40" pixmap="skin_default/buttons/green.png" transparent="1" alphatest="on" />
30 <ePixmap position="280,235" zPosition="4" size="140,40" pixmap="skin_default/buttons/yellow.png" transparent="1" alphatest="on" />
31 <ePixmap position="420,235" zPosition="4" size="140,40" pixmap="skin_default/buttons/blue.png" transparent="1" alphatest="on" />
32 <widget name="key_red" position="0,235" zPosition="5" size="140,40" valign="center" halign="center" font="Regular;21" transparent="1" foregroundColor="white" shadowColor="black" shadowOffset="-1,-1" />
33 <widget name="key_green" position="140,235" zPosition="5" size="140,40" valign="center" halign="center" font="Regular;21" transparent="1" foregroundColor="white" shadowColor="black" shadowOffset="-1,-1" />
34 <widget name="key_yellow" position="280,235" zPosition="5" size="140,40" valign="center" halign="center" font="Regular;21" transparent="1" foregroundColor="white" shadowColor="black" shadowOffset="-1,-1" />
35 <widget name="key_blue" position="420,235" zPosition="5" size="140,40" valign="center" halign="center" font="Regular;21" transparent="1" foregroundColor="white" shadowColor="black" shadowOffset="-1,-1" />
38 def __init__(self, session, tags, txt = None, args = 0, parent = None):
39 Screen.__init__(self, session, parent = parent)
42 self["key_red"] = Button(_("Cancel"))
43 self["key_green"] = Button(_("OK"))
44 self["key_yellow"] = Button(_("New"))
45 self["key_blue"] = Button(_("Load"))
47 self["list"] = SelectionList()
49 allTags = self.loadTagsFile()
50 self.joinTags(allTags, tags)
51 self.updateMenuList(allTags, tags)
53 self.ghostlist = tags[:]
54 self.ghosttags = allTags[:]
55 self.origtags = allTags[:]
59 self["actions"] = ActionMap(["OkCancelActions", "ColorActions", "MenuActions"],
61 "ok": self["list"].toggleSelection,
62 "cancel": self.cancel,
65 "yellow": self.addCustom,
66 "blue": self.loadFromHdd,
71 self.session.openWithCallback(
72 self.addCustomCallback,
74 title = _("Please enter the new tag")
77 def addCustomCallback(self, ret):
78 ret = ret and ret.strip().replace(" ","_").capitalize()
80 if ret and ret not in tags:
82 self.updateMenuList(tags, [ret])
84 def loadTagsFile(self):
86 file = open("/etc/enigma2/movietags")
87 tags = [x.rstrip() for x in file.readlines()]
95 def saveTagsFile(self, tags):
97 file = open("/etc/enigma2/movietags", "w")
98 file.write("\n".join(tags)+"\n")
103 def joinTags(self, taglist, newtags):
105 if not tag in taglist:
108 def setTimerTags(self, timer, tags):
109 if timer.tags != tags:
111 self.timerdirty = True
113 def setMovieTags(self, ref, tags):
115 if file.endswith(".ts"):
116 file = file + ".meta"
118 file = file + ".ts.meta"
119 if os_path.exists(file):
120 metafile = open(file, "r")
121 sid = metafile.readline()
122 title = metafile.readline()
123 descr = metafile.readline()
124 time = metafile.readline()
125 oldtags = metafile.readline().rstrip()
127 tags = " ".join(tags)
129 metafile = open(file, "w")
130 metafile.write("%s%s%s%s%s" %(sid, title, descr, time, tags))
133 def foreachTimerTags(self, func):
134 self.timerdirty = False
135 for timer in self.session.nav.RecordTimer.timer_list + self.session.nav.RecordTimer.processed_timers:
137 func(timer, timer.tags[:])
139 self.session.nav.RecordTimer.saveTimer()
141 def foreachMovieTags(self, func):
142 serviceHandler = eServiceCenter.getInstance()
143 for dir in config.movielist.videodirs.value:
144 if os_path.isdir(dir):
145 root = eServiceReference("2:0:1:0:0:0:0:0:0:0:" + dir)
146 list = serviceHandler.list(root)
150 serviceref = list.getNext()
151 if not serviceref.valid():
153 if (serviceref.flags & eServiceReference.mustDescent):
155 info = serviceHandler.info(serviceref)
158 tags = info.getInfoString(serviceref, iServiceInformation.sTags).split(' ')
159 if not tags or tags == ['']:
161 func(serviceref, tags)
163 def updateMenuList(self, tags, extrasel = []):
164 seltags = [x[1] for x in self["list"].getSelectionsList()] + extrasel
166 self["list"].setList([])
168 self["list"].addSelection(tag, tag, 0, tag in seltags)
170 def loadFromHdd(self):
172 self.foreachTimerTags(lambda t, tg: self.joinTags(tags, tg))
173 self.foreachMovieTags(lambda r, tg: self.joinTags(tags, tg))
174 self.updateMenuList(tags)
177 def removeUnused(self):
178 tags = [x[1] for x in self["list"].getSelectionsList()]
179 self.foreachTimerTags(lambda t, tg: self.joinTags(tags, tg))
180 self.foreachMovieTags(lambda r, tg: self.joinTags(tags, tg))
181 self.updateMenuList(tags)
184 def listReplace(self, lst, fr, to = None):
187 if to != None and not to in lst:
193 self.thistag = self["list"].list[self["list"].getSelectedIndex()][0]
194 self.session.openWithCallback(
195 self.renameTagCallback,
197 title = _("Replace tag \"%s\" everywhere with: (Note that 'Cancel' will not undo this!)") % (self.thistag[1]),
198 text = self.thistag[1]
201 def renameTagCallback(self, res):
202 res = res and res.strip().replace(" ", "_").capitalize()
203 if res and len(res) and res != self.thistag[1]:
204 thistag = self.thistag[1]
205 self.foreachTimerTags(lambda t, tg: (thistag in tg) and self.setTimerTags(t, self.listReplace(tg, thistag, res)))
206 self.foreachMovieTags(lambda r, tg: (thistag in tg) and self.setMovieTags(r, self.listReplace(tg, thistag, res)))
207 self.listReplace(self.tags, thistag, res)
208 self.listReplace(self.ghosttags, thistag, res)
209 self.listReplace(self.ghostlist, thistag, res)
210 self.updateMenuList(self.tags, self.thistag[3] and [res] or [])
213 self.thistag = self["list"].list[self["list"].getSelectedIndex()][0]
214 self.session.openWithCallback(
215 self.removeTagCallback,
217 _("Do you really want to delete tag \"%s\" everywhere?\n(Note that 'Cancel' will not undo this!)") % (self.thistag[1])
220 def removeTagCallback(self, res):
222 thistag = self.thistag[1]
223 self.foreachTimerTags(lambda t, tg: (thistag in tg) and self.setTimerTags(t, self.listReplace(tg, thistag)))
224 self.foreachMovieTags(lambda r, tg: (thistag in tg) and self.setMovieTags(r, self.listReplace(tg, thistag)))
225 self.listReplace(self.tags, thistag)
226 self.listReplace(self.ghosttags, thistag)
227 self.listReplace(self.ghostlist, thistag)
228 self.updateMenuList(self.tags)
231 self.session.openWithCallback(
232 self.removeAllCallback,
234 _("Do you really want to delete all tags everywhere?\n(Note that 'Cancel' will not undo this!)")
237 def removeAllCallback(self, res):
239 self.foreachTimerTags(lambda t, tg: tg and self.setTimerTags(t, []))
240 self.foreachMovieTags(lambda r, tg: tg and self.setMovieTags(r, []))
244 self.updateMenuList(self.tags)
248 (_("Add new tag"), self.addCustom),
249 (_("Rename this tag"), self.renameTag),
250 (_("Delete this tag"), self.removeTag),
251 (_("Delete unused tags"), self.removeUnused),
252 (_("Delete all tags"), self.removeAll)
254 self.session.openWithCallback(self.menuCallback, ChoiceBox, title = "", list = menu)
256 def menuCallback(self, choice):
261 if not self.origtags == self.ghosttags:
262 self.saveTagsFile(self.ghosttags)
263 self.close(self.ghostlist)
268 list = [x[1] for x in self["list"].getSelectionsList()]
269 if not self.origtags == self.tags:
270 self.saveTagsFile(self.tags)
273 class MovieTagEditor(TagEditor):
274 def __init__(self, session, service, parent, args = 0):
275 self.service = service
276 serviceHandler = eServiceCenter.getInstance()
277 info = serviceHandler.info(service)
278 path = service.getPath()
279 if path.endswith(".ts"):
282 tags = info.getInfoString(service, iServiceInformation.sTags)
284 tags = tags.split(' ')
287 TagEditor.__init__(self, session, tags, args, parent = parent)
289 def saveTags(self, file, tags):
290 if os_path.exists(file + ".ts.meta"):
291 metafile = open(file + ".ts.meta", "r")
292 sid = metafile.readline()
293 title = metafile.readline()
294 descr = metafile.readline()
295 time = metafile.readline()
296 oldtags = metafile.readline().rstrip()
298 tags = " ".join(tags)
300 metafile = open(file + ".ts.meta", "w")
301 metafile.write("%s%s%s%s%s" %(sid, title, descr, time, tags))
305 if not self.origtags == self.ghosttags:
306 self.saveTagsFile(self.ghosttags)
312 list = [x[1] for x in self["list"].getSelectionsList()]
313 if not self.origtags == self.tags:
314 self.saveTagsFile(self.tags)
315 self.saveTags(self.path, list)
318 def exitDialog(self):
320 # This will try to get back to an updated movie list.
321 # A proper way to do this should be provided in enigma2.
323 parentscreen = self.parent
324 parentscreen.csel.reloadList()
326 except AttributeError: