Exemple #1
0
    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()
Exemple #3
0
 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
Exemple #4
0
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
Exemple #5
0
    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
Exemple #6
0
    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)
Exemple #7
0
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
Exemple #8
0
    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)
Exemple #9
0
 def get_album_art(self, loc):
     art = path(loc).parent / 'cover.jpg'
     if art.exists():
         return art
     else:
         return 'plugins/default.png'
Exemple #10
0
    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
Exemple #11
0
    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):