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 NumberActionMap
8 from Components.Button import Button
9 from Components.SelectionList import SelectionList
10 from enigma import eServiceReference, eServiceCenter, iServiceInformation
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)
25 class TagEditor(Screen):
27 <screen name="TagEditor" title="Edit Tags" position="75,155" size="565,280">
28 <widget name="list" position="5,5" size="555,225" scrollbarMode="showOnDemand" />
29 <ePixmap position="0,235" zPosition="4" size="140,40" pixmap="skin_default/buttons/red.png" transparent="1" alphatest="on" />
30 <ePixmap position="140,235" zPosition="4" size="140,40" pixmap="skin_default/buttons/green.png" transparent="1" alphatest="on" />
31 <ePixmap position="280,235" zPosition="4" size="140,40" pixmap="skin_default/buttons/yellow.png" transparent="1" alphatest="on" />
32 <ePixmap position="420,235" zPosition="4" size="140,40" pixmap="skin_default/buttons/blue.png" transparent="1" alphatest="on" />
33 <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" />
34 <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" />
35 <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" />
36 <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" />
39 def __init__(self, session, tags, txt = None, args = 0):
40 Screen.__init__(self, session, args)
43 self["key_red"] = Button(_("Cancel"))
44 self["key_green"] = Button(_("OK"))
45 self["key_yellow"] = Button(_("New"))
46 self["key_blue"] = Button(_("Load"))
48 self.tags = self.loadTagsFile()
49 self.origtags = self.tags + []
50 self.ghosttags = self.tags + []
51 self.joinTags(self.tags, tags)
53 self["list"] = SelectionList()
54 self.updateMenuList(self.tags, tags)
57 self["actions"] = NumberActionMap(["OkCancelActions", "ColorActions", "MenuActions"],
59 "ok": self["list"].toggleSelection,
60 "cancel": self.cancel,
63 "yellow": self.addCustom,
64 "blue": self.loadFromHdd,
69 self.session.openWithCallback(
70 self.addCustomCallback,
72 title = _("Please enter the new tag")
75 def addCustomCallback(self, ret):
76 ret = ret and ret.strip().replace(" ","_").capitalize()
77 if ret and ret not in self.tags:
79 self.updateMenuList(self.tags, [ret])
81 def loadTagsFile(self):
83 file = open("/etc/enigma2/movietags")
84 tags = [x.rstrip() for x in file.readlines()]
92 def saveTagsFile(self, tags):
94 file = open("/etc/enigma2/movietags", "w")
95 file.write("\n".join(tags)+"\n")
100 def joinTags(self, taglist, newtags):
102 if not tag in taglist:
105 def setTimerTags(self, timer, tags):
106 if timer.tags != tags:
108 self.timerdirty = True
110 def setMovieTags(self, ref, tags):
112 if file.endswith(".ts") is True:
113 file = file + ".meta"
115 file = file + ".ts.meta"
116 if os.path.exists(file):
117 metafile = open(file, "r")
118 sid = metafile.readline()
119 title = metafile.readline()
120 descr = metafile.readline()
121 time = metafile.readline()
122 oldtags = metafile.readline().rstrip()
124 tags = " ".join(tags)
126 metafile = open(file, "w")
127 metafile.write("%s%s%s%s%s" %(sid, title, descr, time, tags))
130 def foreachTimerTags(self, func):
131 self.timerdirty = False
132 for timer in self.session.nav.RecordTimer.timer_list + self.session.nav.RecordTimer.processed_timers:
134 func(timer, timer.tags+[])
136 self.session.nav.RecordTimer.saveTimer()
138 def foreachMovieTags(self, func):
139 serviceHandler = eServiceCenter.getInstance()
140 for dir in config.movielist.videodirs.value:
141 if os.path.isdir(dir):
142 root = eServiceReference("2:0:1:0:0:0:0:0:0:0:" + dir)
143 list = serviceHandler.list(root)
147 serviceref = list.getNext()
148 if not serviceref.valid():
150 if (serviceref.flags & eServiceReference.mustDescent):
152 info = serviceHandler.info(serviceref)
155 tags = info.getInfoString(serviceref, iServiceInformation.sTags).split(' ')
159 func(serviceref, tags)
161 def updateMenuList(self, tags, extrasel = []):
162 seltags = [x[1] for x in self["list"].getSelectionsList()] + extrasel
164 self["list"].setList([])
166 self["list"].addSelection(tag, tag, 0, tag in seltags)
168 def loadFromHdd(self):
169 tags = self.tags + []
170 self.foreachTimerTags(lambda t, tg: self.joinTags(tags, tg))
171 self.foreachMovieTags(lambda r, tg: self.joinTags(tags, tg))
172 self.updateMenuList(tags)
175 def removeUnused(self):
176 tags = [x[1] for x in self["list"].getSelectionsList()]
177 self.foreachTimerTags(lambda t, tg: self.joinTags(tags, tg))
178 self.foreachMovieTags(lambda r, tg: self.joinTags(tags, tg))
179 self.updateMenuList(tags)
182 def listReplace(self, lst, fr, to=None):
185 if to != None and not to in lst:
191 self.thistag = self["list"].list[self["list"].getSelectedIndex()][0]
192 self.session.openWithCallback(
193 self.renameTagCallback,
195 title = _("Replace tag \"%s\" everywhere with: (Note that 'Cancel' will not undo this!)") % (self.thistag[1]),
196 text = self.thistag[1]
199 def renameTagCallback(self, res):
200 res = res and res.strip().replace(" ", "_").capitalize()
201 if res and len(res) and res != self.thistag[1]:
202 thistag = self.thistag[1]
203 self.foreachTimerTags(lambda t, tg: (thistag in tg) and self.setTimerTags(t, self.listReplace(tg, thistag, res)))
204 self.foreachMovieTags(lambda r, tg: (thistag in tg) and self.setMovieTags(r, self.listReplace(tg, thistag, res)))
205 self.listReplace(self.tags, thistag, res)
206 self.listReplace(self.ghosttags, thistag, res)
207 self.updateMenuList(self.tags, self.thistag[3] and [res] or [])
210 self.thistag = self["list"].list[self["list"].getSelectedIndex()][0]
211 self.session.openWithCallback(
212 self.removeTagCallback,
214 _("Do you really want to delete tag \"%s\" everywhere?\n(Note that 'Cancel' will not undo this!)") % (self.thistag[1])
217 def removeTagCallback(self, res):
219 thistag = self.thistag[1]
220 self.foreachTimerTags(lambda t, tg: (thistag in tg) and self.setTimerTags(t, self.listReplace(tg, thistag)))
221 self.foreachMovieTags(lambda r, tg: (thistag in tg) and self.setMovieTags(r, self.listReplace(tg, thistag)))
222 self.listReplace(self.tags, thistag)
223 self.listReplace(self.ghosttags, thistag)
224 self.updateMenuList(self.tags)
227 self.session.openWithCallback(
228 self.removeAllCallback,
230 _("Do you really want to delete all tags everywhere?\n(Note that 'Cancel' will not undo this!)")
233 def removeAllCallback(self, res):
235 self.foreachTimerTags(lambda t, tg: tg and self.setTimerTags(t, []))
236 self.foreachMovieTags(lambda r, tg: tg and self.setMovieTags(r, []))
239 self.updateMenuList(self.tags)
243 menu.append((_("Add new tag"), self.addCustom))
244 menu.append((_("Rename this tag"), self.renameTag))
245 menu.append((_("Delete this tag"), self.removeTag))
246 menu.append((_("Delete unused tags"), self.removeUnused))
247 menu.append((_("Delete all tags"), self.removeAll))
248 self.session.openWithCallback(self.menuCallback, ChoiceBox, title="", list=menu)
250 def menuCallback(self, choice):
256 if not self.origtags == self.ghosttags:
257 self.saveTagsFile(self.ghosttags)
261 list = [x[1] for x in self["list"].getSelectionsList()]
262 if not self.origtags == self.tags:
263 self.saveTagsFile(self.tags)
266 class MovieTagEditor(TagEditor):
267 def __init__(self, session, service, parent, args = 0):
268 self.service = service
269 self.parentscreen = parent
270 serviceHandler = eServiceCenter.getInstance()
271 info = serviceHandler.info(self.service)
272 self.path = self.service.getPath()
273 if self.path.endswith(".ts") is True:
274 self.path = self.path[:-3]
275 tags = info.getInfoString(self.service, iServiceInformation.sTags)
277 self.tags = tags.split(' ')
280 TagEditor.__init__(self, session, self.tags, args)
281 # self.session.openWithCallback(self.tagsConfirmed, TagEditor, self.tags)
283 def saveTags(self, file, tags):
284 if os.path.exists(file + ".ts.meta"):
285 metafile = open(file + ".ts.meta", "r")
286 sid = metafile.readline()
287 title = metafile.readline()
288 descr = metafile.readline()
289 time = metafile.readline()
290 oldtags = metafile.readline().rstrip()
292 tags = " ".join(tags)
294 metafile = open(file + ".ts.meta", "w")
295 metafile.write("%s%s%s%s%s" %(sid, title, descr, time, tags))
299 if not self.origtags == self.ghosttags:
300 self.saveTagsFile(self.ghosttags)
306 list = [x[1] for x in self["list"].getSelectionsList()]
307 if not self.origtags == self.tags:
308 self.saveTagsFile(self.tags)
309 self.saveTags(self.path, list)
312 def exitDialog(self):
314 # This will try to get back to an updated movie list.
315 # A proper way to do this should be provided in enigma2.
317 self.parentscreen.csel.reloadList()
318 self.parentscreen.close()
319 except AttributeError: