def load_itunes(self): import sources.iTunes libs = [] libs.append(path('~/My Documents/My Music/iTunes/iTunes Music Library.xml')) libs.append(path('~/Music/iTunes/iTunes Music Library.xml')) libs.append(path('iTunes Music Library.xml')) myxml = "" tracks = [] for filename in libs: if filename.expand().exists(): myxml = filename.expand() break try: if mypickle.mtime < myxml.mtime: filepath = str(myxml) lib = sources.iTunes.Library(filepath) lib.load() tracks = list(lib) f = open('data/lib.pickle','wb') cPickle.dump(tracks,f) else: f = open('data/lib.pickle') tracks = cPickle.load(f) except: filepath = str(myxml) lib = sources.iTunes.Library(filepath) lib.load() tracks = list(lib) f = open('data/lib.pickle','wb') cPickle.dump(tracks,f) return tracks
def testFaultyPlugin(self): "Tries to load a plugin with syntax errors. Then replaces this with a correct one" print logging.info( "********************************************") logging.info( "********** testFaultyPlugin *********") logging.info( "********************************************") if PluginInterface.pluginMetaData.exists(): PluginInterface.pluginMetaData.remove() pi = PluginInterface("modules") fakebot = FakeBot() pi.registerInformTarget(fakebot) try: # wrap in try block to ensure file deletion CreateTestFile("FaultyPlugin.py") pi.updatePlugins() self.assert_(fakebot.informRemovedPluginDuringLoadCalled, "Errors not detected when reading erroneous plugin") self.assert_(fakebot.informPluginChangesCalled) self.assert_(len(pi.getPluginNames()) == 1) self.assert_(len(pi.getPlugins()) == 0) time.sleep(2) RemoveTestFiles() CreateTestFile("FaultyPlugin2.py") path("modules/FaultyPlugin2.py").rename(path("modules/FaultyPlugin.py")) pi.updatePlugins() self.assert_(fakebot.informPluginChangesCalled, "informPluginChangesCalled not called after plugin change") self.assert_(len(pi.getPlugins()) == 1, "Not all plugins were registered after plugin change") self.assert_(pi.fireEvent("onEvent",3,4) == None, "Error when firing event") finally: RemoveTestFiles()
def get_next_image(self): try: next = self.images.next() except StopIteration: self.images = path(self.slidepath).walkfiles("*.jpg") next = self.images.next() return next
def getTracks(folder): p = path(folder) tracks = [] walked = p.walkfiles('*.mp3') files = enumerate(walked) for i, f in files: track = {} track['Track ID'] = i track['Location'] = unicode(f.abspath(),'utf-8') tags = tagger.ID3v2(f) for frame in tags.frames: vals = frame.strings val = None if vals and isinstance(vals, list): val = vals[0] if frame.fid == 'TRCK': track['Track Number'] = int(val.split('/')[0]) if frame.fid == 'TALB': track['Album'] = val if frame.fid == 'TPE1': track['Artist'] = val if frame.fid == 'TIT2': track['Name'] = val if 'Name' not in track: print "empty tag?", f.abspath() else: tracks.append(track) if 'Location' in track and not track['Location'].endswith('mp3'): print repr(track['Location']) return tracks
def load_folders(self, mp3path): import sources.folders from datetime import datetime saved = path('data/lib.pickle') mp3path = path(mp3path) log.debug("%s %s", saved, datetime.fromtimestamp(saved.mtime)) log.debug("%s %s", mp3path, datetime.fromtimestamp(mp3path.mtime)) if saved.exists and saved.mtime > mp3path.mtime: f = open(saved) tracks = cPickle.load(f) else: log.debug("Loading folders") tracks = sources.folders.getTracks(mp3path) f = open(saved,'wb') cPickle.dump(tracks,f) log.debug("Done loading %s tracks.", len(tracks)) return tracks
def __init__(self, parent): ListboxPlugin.__init__(self, parent) self.titles = ["Video"] root = path('/Users/snoe/media/video') self.current = root self.items = self.get_items(root) self.listbox.Bind(wx.EVT_LEFT_UP, self.on_click) self.listbox.set_items(self.items)
def cache_covers(folder, size): p = path(folder) walked = p.walkfiles('cover.jpg') covers = {} for i, f in enumerate(walked): source = Image.open(f) source = source.resize(size) image = apply( wx.EmptyImage, source.size ) image.SetData( source.convert( "RGB").tostring() ) bmp = image.ConvertToBitmap() covers[f] = bmp return covers
def __init__(self, parent, plugin): wx.Panel.__init__(self, parent, -1) self.art = wx.StaticBitmap(self) sizer = wx.BoxSizer(wx.VERTICAL) sizer.AddStretchSpacer() sizer.Add(self.art, flag=wx.ALIGN_CENTER_HORIZONTAL) sizer.AddStretchSpacer() self.SetSizer(sizer) self.plugin = plugin self.slidepath = API.config.slidepath self.images = path(self.slidepath).walkfiles("*.jpg") self.set_next_vis() self.timer = wx.Timer(self) self.Bind(wx.EVT_TIMER, self.OnTimer) self.timer.Start(10000)
def get_album_art(self, loc): art = path(loc).parent / 'cover.jpg' if art.exists(): return art else: return 'plugins/default.png'
def __init__(self, mp3path): log.debug("Library initializing") tracks = [] # check the date on the xml file, # if it is newer than pickle reload mypickle = path('data/lib.pickle') tracks = None itunes = False if itunes == True: tracks = self.load_itunes() else: tracks = self.load_folders(mp3path) self.conn = sqlite.connect('sqlite', factory=DictConnnection) cur = self.conn.cursor() columns = set() for track in tracks: for k,v in track.items(): k = k.lower() k = k.replace(' ','_') if v == None: pass elif type(v) == int: columns.add(k + " integer") elif type(v) == datetime.datetime: columns.add(k + " timestamp") else: columns.add(k + "") try: cur.execute('DROP TABLE song') except: pass sql = u''' CREATE TABLE song( %s )''' % ",\n".join(columns) cur.execute(sql) for track in tracks: parms = [] parms.append(track.get('Name',None)) parms.append(track.get('Album',None)) parms.append(track.get('Artist',None)) parms.append(track.get('Track Number', 0)) parms.append(track.get('Track ID', -1)) location = track.get('Location', None).encode('utf8') if itunes: url = urlparse.urlparse(location) url = urllib.unquote(url[2]) url = url.replace('C:/', '') parms.append(url) else: parms.append(location) sql = """ insert into song (name,album,artist,track_number,track_id,location) values (?, ?, ?, ?, ?, ?) """ try: cur.execute(sql, parms) except UnicodeEncodeError: print 'couldnt store', name, album, artist, type(name) except (sqlite.OperationalError, pysqlite2.dbapi2.OperationalError), e: print "op error", e, parms pass except sqlite.IntegrityError, e: print "integrityerror", e pass
def __init__(self, frame): GradientPanel.__init__(self, frame, percent=0.35) self.frame = frame theme = path('images/themes') / API.config.theme_name self.statebmps = {} self.statebmps[API.media.STATE_PLAYING] = utils.get_bitmap(theme / "play.png") self.statebmps[API.media.STATE_STOPPED] = utils.get_bitmap(theme / "stop.png") self.statebmps[API.media.STATE_PAUSED] = utils.get_bitmap(theme / "pause.png") self.shufflebmps = {} self.shufflebmps[API.media.SHUFFLE_TRACK] = utils.get_bitmap(theme / "random_track.png") self.shufflebmps[API.media.SHUFFLE_ALBUM] = utils.get_bitmap(theme / "random_album.png") self.shufflebmps[API.media.SHUFFLE_NONE] = utils.get_bitmap(theme / "random_no.png") self.volumebmps = {} self.volumebmps["volume_mute"] = utils.get_bitmap(theme / "volume_mute.png") self.volumebmps["volume_low"] = utils.get_bitmap(theme / "volume_low.png") self.volumebmps["volume_medium"] = utils.get_bitmap(theme / "volume_medium.png") self.volumebmps["volume_high"] = utils.get_bitmap(theme / "volume_high.png") c1 = wx.Colour(34, 55, 84, wx.ALPHA_OPAQUE) c2 = wx.Colour(83, 120, 234, wx.ALPHA_OPAQUE) self.stripe = GradientPanel(self, c1, c1) self.stripe.SetBackgroundColour(c1) self.titles = [None, None, None] self.titles[0] = wx.StaticText(self.stripe, style=wx.ALIGN_RIGHT) self.titles[1] = wx.StaticText(self.stripe, style=wx.ALIGN_RIGHT) self.titles[2] = wx.StaticText(self.stripe, style=wx.ALIGN_RIGHT) self.wifi = wx.StaticText(self, -1, '--', style=wx.ALIGN_LEFT) font = self.titles[0].GetFont() font.SetPointSize(24) self.titles[0].SetFont(font) font.SetPointSize(18) self.titles[1].SetFont(font) font.SetPointSize(12) self.titles[2].SetFont(font) asizer = wx.BoxSizer(wx.HORIZONTAL) asizer.AddStretchSpacer() asizer.Add(self.titles[2], flag=wx.ALIGN_RIGHT|wx.ALIGN_BOTTOM) asizer.AddSpacer(20) asizer.Add(self.titles[1], flag=wx.ALIGN_RIGHT|wx.ALIGN_BOTTOM) asizer.AddSpacer(20) asizer.Add(self.titles[0], flag=wx.ALIGN_RIGHT|wx.EXPAND) asizer.AddSpacer(20) self.stripe.SetSizer(asizer) self.statebmp = wx.StaticBitmap(self) self.shufflebmp = wx.StaticBitmap(self) self.volumebmp = wx.StaticBitmap(self) self.quit = wx.StaticBitmap(self) bmp = utils.get_bitmap(theme / "quit.png") self.quit.SetBitmap(bmp) self.quit.SetSize(bmp.Size) self.nowplayingline1 = wx.StaticText(self, -1, 'artist', style=wx.ALIGN_RIGHT) self.nowplayingline2 = wx.StaticText(self, -1, 'song', style=wx.ALIGN_RIGHT) self.clock = wx.StaticText(self, -1, datetime.now().strftime('%H:%M')) font = self.clock.GetFont() font.SetPointSize(24) self.clock.SetFont(font) nsizer = wx.BoxSizer(wx.VERTICAL) nsizer.Add(self.nowplayingline1, flag=wx.ALIGN_CENTER|wx.EXPAND) nsizer.Add(self.nowplayingline2, flag=wx.ALIGN_CENTER|wx.EXPAND) ssizer = wx.BoxSizer(wx.HORIZONTAL) ssizer.Add(nsizer, flag=wx.ALIGN_CENTER) ssizer.AddSpacer(10) ssizer.Add(self.statebmp, flag=wx.ALIGN_CENTER) ssizer.AddSpacer(10) ssizer.Add(self.shufflebmp, flag=wx.ALIGN_CENTER) ssizer.AddSpacer(10) ssizer.Add(self.volumebmp, flag=wx.ALIGN_CENTER) ssizer.AddSpacer(10) ssizer.Add(self.quit, flag=wx.ALIGN_CENTER) self.ssizer = ssizer xsizer = wx.GridBagSizer(2, 3) xsizer.Add(self.wifi, (0,0), flag=wx.ALIGN_CENTER|wx.EXPAND) xsizer.Add(self.ssizer, (0,1), flag=wx.ALIGN_CENTER|wx.EXPAND) xsizer.Add(self.clock, (0,2), flag=wx.ALIGN_CENTER) xsizer.Add(self.stripe, (1,0), (1,3), flag=wx.ALIGN_RIGHT|wx.EXPAND|wx.ALIGN_CENTER) xsizer.AddGrowableCol(1) xsizer.AddGrowableCol(0) self.SetSizerAndFit(xsizer) utils.setColours(self) utils.setColours(self.stripe) self.timer = wx.Timer(self) self.Bind(wx.EVT_TIMER, self.on_update) self.timer.Start(1000) self.stripe.stripe_timer = wx.Timer(self.stripe) self.stripe.Bind(wx.EVT_TIMER, self.on_stripe_update) self.stripe.stripe_timer.Start(100) self.quit.Bind(wx.EVT_LEFT_UP, self.on_quit) self.volumebmp.Bind(wx.EVT_LEFT_UP, API.media.toggle_mute) self.statebmp.Bind(wx.EVT_LEFT_UP, API.media.play_pause) self.shufflebmp.Bind(wx.EVT_LEFT_UP, API.media.change_shuffle) # os x text tends to erase background, so we no op self.titles[0].Bind(wx.EVT_ERASE_BACKGROUND, lambda e: None) self.titles[1].Bind(wx.EVT_ERASE_BACKGROUND, lambda e: None) self.titles[2].Bind(wx.EVT_ERASE_BACKGROUND, lambda e: None) self.nowplayingline1.Bind(wx.EVT_ERASE_BACKGROUND, lambda e: None) self.nowplayingline2.Bind(wx.EVT_ERASE_BACKGROUND, lambda e: None) self.wifi.Bind(wx.EVT_ERASE_BACKGROUND, lambda e: None) self.clock.Bind(wx.EVT_ERASE_BACKGROUND, lambda e: None) API.media.attach('current', self.check_current) API.media.attach('state', self.check_state) API.media.attach('shuffle', self.check_shuffle) API.media.attach('volume', self.check_volume)
def testGetStatus(self): pi = PluginInterface(path("plugins/")) fakebot = FakeBot() pi.registerInformTarget(fakebot) pi.updatePlugins() print pi.getStatus()
import Log from lib import coverage, colorize from lib.path import path class FakeBot: def informPluginChanges(self, loadedPluginsList, reloadedPluginsList, removedPluginsList, unused): logging.critical("InformPluginChanges called. parameters: %s" % (str(locals()),)) self.informPluginChangesCalled = True def informErrorRemovedPlugin(self, plugin): logging.critical("informErrorRemovedPlugin called. parameter: %s" % (plugin,)) self.informErrorRemovedPluginCalled = True def informRemovedPluginDuringLoad(self, pluginfile): logging.critical("informRemovedPluginDuringLoad called. parameter: %s" % (pluginfile,)) self.informRemovedPluginDuringLoadCalled = True TestPluginDirectory = path("modules") TestFiles = {} TestFiles["TestPlugin.py"] = """ import random, logging from modules import PluginInterface class TestPlugin: def __init__(self, pluginInterface): logging.debug("PLUGIN: constructor called") @PluginInterface.Priorities.prioritized( PluginInterface.Priorities.PRIORITY_VERYHIGH ) def onEvent(self, param1, param2): logging.debug("PLUGIN: event fired (" + str(param1) + "|" + str(param2) + ")") logging.debug("PLUGIN: random number: " + str(random.random())) def onFaultyEvent(self):