class Shuffler(dbus.gobject_service.ExportedGObject, log.Loggable): SUPPORTS_MULTIPLE_CONNECTIONS = True def __init__(self, bus=None, config_filename=None): log.Loggable.__init__(self) bus = bus or dbus.SessionBus() self._bus = bus try: bus_name = dbus.service.BusName(BUS_NAME, self._bus) except: bus_name = None self.tube = self._bus else: self.tube = None dbus.gobject_service.ExportedGObject.__init__(self, self._bus, bus_name=bus_name, object_path=ROOT_PATH) self._config_filename = config_filename or DEFAULT_CONFIG_FILENAME def _prepare(self): self.config = config.Config(self._bus, self._config_filename, DEFAULT_CONFIG) self.config.load() if self.config.first_load: music_dir = utils.xdg_dirs().get('music') if music_dir: media_dir = {'label': os.path.basename(music_dir), 'path': music_dir, 'scan_interval': '3600'} self.config.media_scanner['media_dir'] = media_dir self._loop = gobject.MainLoop() self._prepare_db() self._prepare_media_scanner() self._prepare_scrobbler() self._prepare_player() self._prepare_publisher() self._prepare_im_notifier() def _prepare_db(self): db_filename = self.config.db.filename full_path = os.path.join(self.config.config_dir, db_filename) self.db = db.DB(self._bus, full_path) def _prepare_media_scanner(self): media_scanner_cfg = dict(self.config.media_scanner) media_scanner_cfg['db_path'] = self.db.filename self._media_scanner = media_scanner.MediaScanner(media_scanner_cfg) def _prepare_scrobbler(self): #scrobbler_config = dict(self.config.audioscrobbler) #self._scrobbler = audioscrobbler.AudioScrobbler(scrobbler_config) self._scrobbler = self.config.register(audioscrobbler.AudioScrobbler, self.config.audioscrobbler) logged = self._scrobbler.handshake(block=True) if not logged: self.config.audioscrobbler = self._scrobbler.config self._scrobbler = None def _prepare_player(self): player_config = self.config.player playlist_config = self.config.playlist smart_queue_config = self.config.smart_queue self.player = player.Player(self._bus, self.db, player_config, playlist_config, smart_queue_config) self._media_scanner.connect('scan-finished', self._reload_db) if self._scrobbler: self.player.connect('track-ended', self._scrobbler.submit_new_track) self.player.connect('now-playing', self._scrobbler.now_playing) self.player.create_pipeline() def _prepare_publisher(self): connection, chatroom = tp_connect.get_connection(self) tubes_to_offer = {PLAYER_INTERFACE: {}, DB_INTERFACE: {}} self._publisher = ShufflerTubePublisher(connection, chatroom, tubes_to_offer, self) def _prepare_im_notifier(self): im_options = dict(self.config.im_notify) enabled = int(im_options["enabled"]) if enabled: template = im_options["template"] self._im_manager = imstatus.ImStatusManager(self._bus, template) self._im_manager.save_status() self.player.connect('now-playing', self._im_manager.now_playing) else: self._im_manager = None def _reload_db(self, object, media_dir_path): self.db.reopen() if not self.player.playing: self.player.next_track() def start(self): self._prepare() self.db.open() self._media_scanner.start() self.player.start() self._publisher.start() def stop(self): if self._scrobbler: self._scrobbler.saveTracks() if self._im_manager: self._im_manager.restore_status() self._publisher.stop() self.player.stop() self._media_scanner.stop() self.db.close() self._loop.quit() self.config.save() def run(self): exit_code = 0 self.start() try: self._loop.run() except KeyboardInterrupt: self.info("Exit on user request") except Exception, exc: self.warning("Unexpected error: %r", exc) exit_code = 1 self.stop() return exit_code
def _prepare_publisher(self): connection, chatroom = tp_connect.get_connection(self) tubes_to_offer = {PLAYER_INTERFACE: {}, DB_INTERFACE: {}} self._publisher = ShufflerTubePublisher(connection, chatroom, tubes_to_offer, self)