Esempio n. 1
0
 def login(self):
     config = ConfigParser.ConfigParser()
     cwd = os.path.realpath(os.path.dirname(__file__) + u'/..')
     config.read(os.path.join(cwd, u'scrobbler.cfg'))
     username = config.get(u'scrobbler', u'username')
     password = hashlib.md5(config.get(u'scrobbler', u'password')).hexdigest()
     try:
         scrobbler.login(user=username, password=password)
     except scrobbler.ProtocolError:
         time.sleep(49)
     except Exception as e:
         log.exception(u"Couldn't login: %s" % e)
Esempio n. 2
0
 def osc_creds(self):
         if (not hasattr(self, 'username') or
                         not hasattr(self, 'password')):
                 return
         try:
                 scrobbler.login(self.username,
                                 self.password, hashpw=True)
         except scrobbler.AuthError:
                 self.l.error('Couldn\'t authenticate with last.fm')
                 self.authenticated = False
                 return
         self.authenticated = True
Esempio n. 3
0
 def login(self):
     config = ConfigParser.ConfigParser()
     cwd = os.path.realpath(os.path.dirname(__file__) + u'/..')
     config.read(os.path.join(cwd, u'scrobbler.cfg'))
     username = config.get(u'scrobbler', u'username')
     password = hashlib.md5(config.get(u'scrobbler',
                                       u'password')).hexdigest()
     try:
         scrobbler.login(user=username, password=password)
     except scrobbler.ProtocolError:
         time.sleep(49)
     except Exception as e:
         log.exception(u"Couldn't login: %s" % e)
Esempio n. 4
0
def main():
    import sys, os
    import plistlib
    from time import strftime

    # get modus operandi and additional arguments
    mode = None
    try:
        mode = sys.argv[1]
    except:
        mode = 'scrobble'
    if mode not in ('update', 'scrobble'):
        exit(__doc__)
        
    # load internal database
    dbPath = 'itunesScrobbler.sqlite3'
    print 'loading internal database...'
    db = openDatabase(dbPath)
    
    # load itunes media library
    print 'loading iTunes Media Library...'
    mediaLibPath = os.path.join(os.path.expanduser('~'), 'Music', 'iTunes', 'iTunes Music Library.xml')
    mediaLib = plistlib.readPlist(mediaLibPath)

    # synchronize libraries
    tracks = mediaLib['Tracks']
    tracksToScrobble = []
    print 'synchronizing databases...'
    for trackId, track in tracks.iteritems():
        try:
            if mode == 'update':
                updateDatabaseWithTrack(db, track)
            # gather scrobble data
            elif mode == 'scrobble':
                try:
                    count = playCountDiffWithDatabaseForTrack(db, track)
                except ValueError, e:
                    print 'Warning!', e.message
                else:
                    if count:
                        tracksToScrobble.append((count, track))
        except KeyError:
            pass
    # process gathered information
    if mode == 'update':
        print 'done! - internal database updated.'
    elif mode == 'scrobble':
        if not tracksToScrobble:
            print 'done! - nothing changed; nothing to scrobble.'
        else:
            # sort tracks
            tracksToScrobble.sort(key=lambda t:(t[1]['Artist']+t[1]['Name']).lower())
            # fix tracks' play time
            fauxPlayTime = datetime.now() # could be any datetime instance, like datetime(2012,1,1)
            patchAll = False
            for count, track in tracksToScrobble:
                if patchAll or 'Play Date UTC' not in track:
                    track['Play Date UTC'] = fauxPlayTime
                    trackLength = track.get('Total Time', 0) // 1000
                    fauxPlayTime = dateTimeWithOffsetFromDateTime(-count * trackLength, fauxPlayTime)
            # print what we want to scrobble
            print
            print 'This is what we\'ll send to last.fm:'
            print
            for count, track in tracksToScrobble:
                playDate = strftime('%Y-%m-%d %H:%M', track['Play Date UTC'].timetuple())
                print count, ('x %(Artist)s - %(Name)s' % track).encode('unicode-escape'), ('(%s)' % playDate)
            print
            okay = raw_input('is this okay with you? (y/N)  ')
            if okay != 'y':
                print 'alright, let\'s forget about it.'
            else:
                # try to load username and password and log in
                with open('.itunesScrobbler') as fd:
                    username = fd.readline().rstrip('\r\n')
                    password = fd.readline().rstrip('\r\n')
                print 'trying to log in to last.fm...'
                scrobbler.login(username, password)
                # scrobble!
                print 'scrobble ...',
                for count, track in tracksToScrobble:
                    trackDescription = ('%(Name)s by %(Artist)s' % track).encode('unicode-escape')
                    if len(trackDescription) > 69:
                        trackDescription = trackDescription[:67] + '..'
                    print '\rscrobble', trackDescription,
                    for i in xrange(count):
                        # need to compensate; we only know when the track was *last* played
                        if i is 0:
                            fixedTrack = track
                        else:
                            trackLength = track.get('Total Time', 0) // 1000
                            fixedTrack = track.copy()
                            fixedTrack['Play Date UTC'] = dateTimeWithOffsetFromDateTime(-i * trackLength, track['Play Date UTC'])
                        # send the fixed track information off to last.fm
                        if not scrobble(fixedTrack):
                            print
                            raise scrobbler.PostError('could not scrobble!')
                    updateDatabaseWithTrack(db, track)
                if not scrobbler.flush():
                    # Damn! Something went wrong right at the end.
                    # We could roll back our internal database now, which could lead to duplicate scrobbles,
                    # or we could just ignore this error, which could/will lead to tracks not being scrobbled at all;
                    # both scenarios suck donkey dick!
                    print 'b0rked hard; so sorry :f - you just lost some scrobbles due to bad caching.'
                else:
                    print
                    print 'all done! :)'
    
    db.commit()
    db.close()
Esempio n. 5
0
    def _real_commit(self, now_playing, cachefile, username, password,
                     scrobbler_url):
        """this is quite ugly spaghetti code. maybe we could make this a little bit more tidy?"""
        logger.info('Begin scrobbling to %s', scrobbler_url)
        if (not do_now_playing):
            logger.debug('Now playing disabled')
            now_playing = None
        success = False
        tosubmit = set()
        tosubmitted = set()
        cache_count = 0
        retry_sleep = None
        retry_count = 0
        while not success:
            if retry_sleep is None:
                retry_sleep = 60
            else:
                retry_count = retry_count + 1
                if retry_count > 7:
                    logger.info('Giving up scrobbling to %s', scrobbler_url)
                    break
                logger.info('Sleeping %d minute(s)', retry_sleep / 60)
                time.sleep(retry_sleep)
                retry_sleep = min(retry_sleep * 2, 120 * 60)
            #handshake phase
            logger.debug('Handshake')
            try:
                scrobbler.login(username,
                                password,
                                hashpw=False,
                                client=CmuScrobbler.CLIENTID,
                                url=scrobbler_url)
            except Exception, e:
                logger.error('Handshake with %s failed: %s', scrobbler_url, e)
                log_traceback(e)
                continue

            #submit phase
            if os.path.exists(cachefile):
                logger.info('Scrobbling songs to %s', scrobbler_url)
                (_, _, _, _, _, _, _, _, mtime, _) = os.stat(cachefile)
                fo = file(cachefile, 'r')
                line = fo.readline()
                while len(line) > 0:
                    (path, artist, track, playtime, source, length, album,
                     trackno) = line.split('\t')
                    trackno = trackno.strip()
                    mbid = get_mbid(unquote(path).decode('utf-8'))
                    tosubmit.add((playtime, artist, track, source, length,
                                  album, trackno, mbid))
                    line = fo.readline()
                fo.close()
                logger.info('Read %d songs from cachefile %s', len(tosubmit),
                            cachefile)

                logger.debug('Sorting songlist')
                submitlist = list(tosubmit)
                submitlist.sort(key=lambda x: int(x[0]))
                retry = False
                for (playtime, artist, track, source, length, album, trackno,
                     mbid) in submitlist:
                    if (playtime, artist, track, source, length, album,
                            trackno, mbid) in tosubmitted:
                        logger.debug(
                            'Track already submitted or in cache: %s - %s',
                            unquote(artist), unquote(track))
                        continue
                    if cache_count >= 3:
                        logger.info('Flushing. cache_count=%d', cache_count)
                        if self._flush():
                            logger.info('Flush successful.')
                            retry_sleep = None
                            cache_count = 0
                        else:
                            retry = True
                            break
                    sb_success = False
                    for tries in xrange(1, 4):
                        logger.debug(
                            'Try to submit: %s, %s, playtime=%d, source=%s, length=%s, album=%s, trackno=%s, mbid=%s',
                            unquote(artist), unquote(track), int(playtime),
                            source, length, unquote(album), trackno, mbid)
                        try:
                            sb_success = scrobbler.submit(
                                unquote(artist).decode('utf-8'),
                                unquote(track).decode('utf-8'),
                                int(playtime),
                                source=source.decode('utf-8'),
                                length=length.decode('utf-8'),
                                album=unquote(album).decode('utf-8'),
                                trackno=trackno.decode('utf-8'),
                                mbid=mbid,
                            )
                        except Exception, e:
                            logger.error('Submit error: %s', e)
                            log_traceback(e)
                            sb_success = False
                        if sb_success:
                            tosubmitted.add((playtime, artist, track, source,
                                             length, album, trackno, mbid))
                            cache_count += 1
                            logger.info('Submitted. cache_count=%d: %s - %s',
                                        cache_count, unquote(artist),
                                        unquote(track))
                            break
                        logger.error('Submit failed. Try %d', tries)
                    if not sb_success:
                        retry = True
                        break
                    if cache_count >= 3:
                        logger.info('Flushing. cache_count=%d', cache_count)
                        if self._flush():
                            logger.info('Flush successful.')
                            retry_sleep = None
                            cache_count = 0
                        else:
                            retry = True
                            break
                if retry:
                    logger.error('Restaring')
                    continue

                if cache_count > 0:
                    logger.info('Cache not empty: flushing')
                    if self._flush():
                        logger.info('Flush successful.')
                        retry_sleep = None
                        cache_count = 0
                    else:
                        logger.error('Restarting')
                        continue

                (_, _, _, _, _, _, _, _, newmtime, _) = os.stat(cachefile)
                if newmtime != mtime:
                    logger.info(
                        'Cachefile changed since we started. Restarting')
                    continue
                logger.info('Scrobbled all Songs, removing cachefile')
                os.remove(cachefile)
Esempio n. 6
0
    def _real_commit(self, now_playing, cachefile, username, password, scrobbler_url):
        """this is quite ugly spaghetti code. maybe we could make this a little bit more tidy?"""
        logger.info('Begin scrobbling to %s', scrobbler_url)
        if (not do_now_playing):
            logger.debug('Now playing disabled')
            now_playing = None
        success = False
        tosubmit = set()
        tosubmitted = set()
        cache_count = 0
        retry_sleep = None
        retry_count = 0
        while not success:
            if retry_sleep is None:
                retry_sleep = 60
            else:
                retry_count = retry_count + 1
                if retry_count > 7:
                    logger.info('Giving up scrobbling to %s', scrobbler_url)
                    break
                logger.info('Sleeping %d minute(s)', retry_sleep / 60)
                time.sleep(retry_sleep)
                retry_sleep = min(retry_sleep * 2, 120 * 60)
            #handshake phase
            logger.debug('Handshake')
            try:
                scrobbler.login(username, password, hashpw=False, client=CmuScrobbler.CLIENTID, url=scrobbler_url)
            except Exception, e:
                logger.error('Handshake with %s failed: %s', scrobbler_url, e)
                log_traceback(e)
                continue

            #submit phase
            if os.path.exists(cachefile):
                logger.info('Scrobbling songs to %s', scrobbler_url)
                (_, _, _, _, _, _, _, _, mtime, _) = os.stat(cachefile)
                fo = file(cachefile,'r')
                line = fo.readline()
                while len(line) > 0:
                    try:
                        (path, artist, track, playtime, source, length, album, trackno) = line.split('\t')
                        trackno = trackno.strip()
                        mbid = get_mbid(unquote(path).decode('utf-8'))
                        tosubmit.add((playtime, artist, track, source, length, album, trackno, mbid))
                    except Exception, e:
                        logger.debug('cache read error: %s', e)
                    line = fo.readline()
                fo.close()
                logger.info('Read %d songs from cachefile %s', len(tosubmit), cachefile)

                logger.debug('Sorting songlist')
                submitlist = list(tosubmit)
                submitlist.sort(key=lambda x: int(x[0]))
                retry = False
                for (playtime, artist, track, source, length, album, trackno, mbid) in submitlist:
                    if (playtime, artist, track, source, length, album, trackno, mbid) in tosubmitted:
                        logger.debug('Track already submitted or in cache: %s - %s', unquote(artist), unquote(track))
                        continue
                    if cache_count >= 3:
                        logger.info('Flushing. cache_count=%d', cache_count)
                        if self._flush():
                            logger.info('Flush successful.')
                            retry_sleep = None
                            cache_count = 0
                        else:
                            retry = True
                            break
                    sb_success = False
                    for tries in xrange(1, 4):
                        logger.debug('Try to submit: %s, %s, playtime=%d, source=%s, length=%s, album=%s, trackno=%s, mbid=%s',
                            unquote(artist), unquote(track), int(playtime), source, length, unquote(album), trackno, mbid)
                        try:
                            sb_success = scrobbler.submit(unquote(artist).decode('utf-8'), unquote(track).decode('utf-8'),
                                int(playtime),
                                source=source.decode('utf-8'),
                                length=length.decode('utf-8'),
                                album=unquote(album).decode('utf-8'),
                                trackno=trackno.decode('utf-8'),
                                mbid=mbid,
                            )
                        except Exception, e:
                            logger.error('Submit error: %s', e)
                            log_traceback(e)
                            sb_success = False
                        if sb_success:
                            tosubmitted.add((playtime, artist, track, source, length, album, trackno, mbid))
                            cache_count += 1
                            logger.info('Submitted. cache_count=%d: %s - %s', cache_count, unquote(artist), unquote(track))
                            break
                        logger.error('Submit failed. Try %d', tries)
                    if not sb_success:
                       retry = True
                       break
                    if cache_count >= 3:
                        logger.info('Flushing. cache_count=%d', cache_count)
                        if self._flush():
                            logger.info('Flush successful.')
                            retry_sleep = None
                            cache_count = 0
                        else:
                            retry = True
                            break
def lastfm_login():
    try:
        scrobbler.login(USERNAME, PASSWORD, True)
    except: pass