def get_cover(self, entry):
        if entry:

            # Try to find an album cover in the folder of the currently playing track
            cover_dir = path.dirname(
                url2pathname(entry.get_playback_uri()).replace('file://', ''))
            # TODO: use os.walk()
            if path.isdir(cover_dir):
                for f in listdir(cover_dir):
                    file_name = path.join(cover_dir, f)
                    mt = mimetypes.guess_type(file_name)[0]
                    if mt and mt.startswith('image/'):
                        if True in [
                                x in path.splitext(f)[0].lower() for x in
                            ['cover', 'album', 'albumart', 'folder', 'front']
                        ]:
                            return GdkPixbuf.Pixbuf.new_from_file_at_size(
                                file_name, self.ALBUM_ART_W, self.ALBUM_ART_H)

            # Otherwise use what's found by the album art plugin
            key = entry.create_ext_db_key(RB.RhythmDBPropType.ALBUM)
            cover_db = RB.ExtDB(name='album-art')
            art_location = cover_db.lookup(key)
            if art_location and not isinstance(art_location, str):
                # RB 3.2 returns a tuple (path, key)
                art_location = art_location[0]

            if art_location and path.exists(art_location):
                return GdkPixbuf.Pixbuf.new_from_file_at_size(
                    art_location, self.ALBUM_ART_W, self.ALBUM_ART_H)
Example #2
0
    def do_activate(self):
        shell = self.object
        self.db = shell.props.db

        self.artcache = os.path.join(RB.user_cache_dir(), "album-art", "")
        self.art_store = RB.ExtDB(name="album-art")
        self.art_store.connect("added", self.art_added_cb)

        self.shell_player = shell.props.shell_player
        self.shell_player.connect("playing-song-changed",
                                  self.playing_song_changed_cb)
        self.shell_player.connect("playing-song-property-changed",
                                  self.playing_song_property_changed_cb)
        self.shell_player.connect("playing-changed", self.playing_changed_cb)
        self.shell_player.connect("elapsed-nano-changed",
                                  self.elapsed_nano_changed_cb)
        self.playing_song_changed_cb(self.shell_player,
                                     self.shell_player.get_playing_entry())

        self.http_server = Soup.Server()
        self.http_server.add_handler(path="/art/", callback=self.http_art_cb)
        self.http_server.add_handler(path="/icon/", callback=self.http_icon_cb)
        self.http_server.add_handler(path="/entry/current/stream",
                                     callback=self.http_track_cb)
        self.http_server.add_handler(path="/css/",
                                     callback=self.http_static_css_cb)
        self.http_server.add_handler(path="/js/",
                                     callback=self.http_static_js_cb)
        self.http_server.add_websocket_handler("/ws/player", None, None,
                                               self.player_websocket_cb)
        self.http_server.add_handler(path="/", callback=self.http_root_cb)

        self.http_listen()
Example #3
0
    def do_activate(self):
        self.art_store = RB.ExtDB(name="album-art")
        self.req_id = self.art_store.connect("request",
                                             self.album_art_requested)

        shell = self.object
        self.csi_id = shell.connect("create_song_info", self.create_song_info)
Example #4
0
    def __init__(self):
        RB.BrowserSource.__init__(self)
        self.hate = self

        self.__popup = None
        self.__settings = Gio.Settings("org.gnome.rhythmbox.plugins.magnatune")
        # source state
        self.__activated = False
        self.__db = None
        self.__info_screen = None  # the loading screen

        # track data
        self.__sku_dict = {}
        self.__home_dict = {}
        self.__art_dict = {}

        # catalogue stuff
        self.__has_loaded = False  # whether the catalog has been loaded yet
        self.__update_id = 0  # GLib.idle_add id for catalog updates
        self.__catalogue_loader = None
        self.__catalogue_check = None
        self.__load_progress = None
        self.__download_progress = None

        # album download stuff
        self.__downloads = {}  # keeps track of download progress for each file
        self.__copies = {}  # keeps copy objects for each file

        self.__art_store = RB.ExtDB(name="album-art")
Example #5
0
    def do_activate(self):
        """
        Called by rhythmbox when the plugin is activated
        """
        super(Caveman, self).do_activate()
        app = self.object.props.application

        self.track_ids = {}
        self.import_queue = {
            'songs': [],
            'playlists': [],
        }
        self.export_queue = {
            'songs': [],
            'playlists': [],
        }
        self.existing_songs = set()
        self.ext_db = RB.ExtDB(name="caveman")

        self.config = configparser.RawConfigParser()
        self.config_file = os.path.join(os.environ['HOME'],
                                        '.local/share/rhythmbox/cavemanrc')
        if os.path.isfile(self.config_file):
            self.config.read(self.config_file)
        else:
            self.config.read(
                os.path.join(
                    os.environ['HOME'],
                    '.local/share/rhythmbox/caveman/defaults.cavemanrc'))

        if self.config.get('DEFAULT', 'music_root_dir') == "XDG_MUSIC_DIR":
            self.config.set('DEFAULT', 'music_root_dir',
                            self.get_xdg_music_dir())
        self.our_prefix = 'file://' + self.config.get('DEFAULT',
                                                      'music_root_dir')
        if self.our_prefix[-1] != '/':
            self.our_prefix = self.our_prefix + "/"

        self.add_action('import-from-itunes',
                        self.import_from_itunes,
                        parentMenu='tools',
                        menuName='Import from iTunes')
        self.add_action('export-to-itunes',
                        self.export_to_itunes,
                        parentMenu='tools',
                        menuName='Export to iTunes')

        for row in self.object.props.library_source.props.base_query_model:
            entry = row[0]
            loc = self.object.props.db.entry_get(entry, prop.LOCATION)
            self.existing_songs.add(loc)

        if self.config.getboolean('DEFAULT', 'auto_import'):
            self.import_from_itunes()
Example #6
0
 def __init__(self, hostname, port, plugin):
     self.plugin = plugin
     self.running = True
     self.artist = None
     self.album = None
     self.title = None
     self.stream = None
     self.initial_playlist_rows = None
     self._httpd = make_server(hostname, port, self._wsgi)
     self._watch_cb_id = GObject.io_add_watch(self._httpd.socket,
                                              GObject.IO_IN, self._idle_cb)
     self._cover_db = RB.ExtDB(name='album-art')
    def __init__(self, plugin, sprite_name, size=None):
        popups = rb.find_plugin_file(plugin, 'img/popups.xml')
        root = ET.parse(open(popups)).getroot()
        base = 'theme/theme[@folder_name="' + Theme(plugin).current \
               + '"]/spritesheet[@name="' + sprite_name + '"]/'
        image = rb.find_plugin_file(plugin, 'img/' + Theme(plugin).current \
                                    + '/' + root.xpath(base + 'image')[0].text)
        icon_width = int(root.xpath(base + 'icon')[0].attrib['width'])
        icon_height = int(root.xpath(base + 'icon')[0].attrib['height'])
        x_spacing = int(root.xpath(base + 'spacing')[0].attrib['x'])
        y_spacing = int(root.xpath(base + 'spacing')[0].attrib['y'])
        x_start = int(root.xpath(base + 'start-position')[0].attrib['x'])
        y_start = int(root.xpath(base + 'start-position')[0].attrib['y'])
        across_dimension = int(
            root.xpath(base + 'dimension')[0].attrib['across'])
        down_dimension = int(root.xpath(base + 'dimension')[0].attrib['down'])

        try:
            alpha_color = list(
                map(int,
                    root.xpath(base + 'alpha')[0].text.split(' ')))
        except:
            alpha_color = None

        self.names = []
        self.locale_names = {}

        cl = CoverLocale()
        lang = cl.get_locale()

        base = sprite_name + '/' + sprite_name + \
               '[@spritesheet="' + sprite_name + '"]'

        for elem in root.xpath(base + '[not(@xml:lang)]'):
            self.names.append(elem.text)

        for elem in root.xpath(base + '[@xml:lang="' + lang + '"]'):
            self.locale_names[elem.text] = elem.attrib['name']

        if (not self.locale_names) and len(lang) > 2:
            for elem in root.xpath(base + '[@xml:lang="' + \
                    lang[0:2] + '"]'):
                self.locale_names[elem.text] = elem.attrib['name']

        self._sheet = SpriteSheet(image, icon_width, icon_height, x_spacing,
                                  y_spacing, x_start, y_start,
                                  across_dimension, down_dimension,
                                  alpha_color, size)

        self._genre_db = RB.ExtDB(name='cb_genre')
Example #8
0
    def __init__(self, db, uri):
        self.db = db
        self.it_db = RB.ExtDB(name="caveman")
        self.it_data = {}

        self.entry = db.entry_lookup_by_location(uri)
        if self.entry:
            self.isNew = False
            key = entry.create_ext_db_key(prop.LOCATION)
            self.it_db.request(key, it_data_fetched_cb)
        else:
            if uri[0:7] == 'file://':
                entry_type = db.entry_type_get_by_name('song')
            else:
                entry_type = db.entry_type_get_by_name('iradio')
            self.entry = RB.RhythmDBEntry.new(db, entry_type, uri)
            self.isNew = True
Example #9
0
        def do_activate(self):
                # activate source if inactive
                if not self.__activated:
                        self.__activated = True

                        self.__shell = self.props.shell
                        self.__db = self.__shell.props.db
                        self.__entry_type = self.props.entry_type

                        # connect playing-song-changed signal
                        self.__art_store = RB.ExtDB(name="album-art")
                        self.__art_request = self.__art_store.connect("request", self.__album_art_requested)

                        # create cache directory if it doesn't exist
                        cache_path = os.path.dirname(self.__songs_cache_filename)
                        if not os.path.exists(cache_path):
                                os.mkdir(cache_path, 0o700)

                        self.update(False)
    def __init__(self):
        super(BaseSource, self).__init__()

        self.songs = []             # the song ids in this source
        self.activated = False      # the tag of activate
        self.popup = None           # the popup menu
        self.index = -1             # the index of position where insert song

        # get_status function
        self.updating = False       # the status of update
        self.status = ""            # the message of source's status
        self.progress = 0           # the progress of update

        self.entry_widgets = []     # a list includes the toolitems

        # set up the coverart
        self.__art_store = RB.ExtDB(name="album-art")
        self.__req_id = self.__art_store.connect(
                "request", self.__album_art_requested
                )
    def show_fullscreen(self, *args):
        self.window = FullscreenWindow.FullscreenWindow(plugin=self)

        # Receive notification of song changes
        self.player = self.shell.props.shell_player
        self.player.connect("playing-source-changed", self.reload_playlist)
        self.player.connect("playing-song-changed",
                            self.on_playing_song_changed)
        self.player.connect("playing-changed", self.reload_play_pause)

        # TODO: This signal is not fired - which should we listen for?
        # We should use the cover_db,
        # but what are its signals??
        cover_db = RB.ExtDB(name='album-art')
        self.player.connect("playing-song-property-changed",
                            self.notify_metadata)
        cover_db.connect("added", self.notify_cover_art_change)

        # Load current state
        self.reload_playlist(self.player, self.player.get_playing_entry())
Example #12
0
    def __init__(self, shell, song_info):
        self.visible = False
        self.art_key = None

        self.shell = shell
        self.song_info = song_info
        self.entry = song_info.props.current_entry
        self.art_store = RB.ExtDB(name="album-art")
        self.art_store.connect("added", self.art_added_cb)

        grid = Gtk.Grid(hexpand=True, vexpand=True, margin=6, row_spacing=6)

        self.image = RB.FadingImage(fallback="rhythmbox-missing-artwork",
                                    use_tooltip=False)
        self.image.props.hexpand = True
        self.image.props.vexpand = True
        grid.attach(self.image, 0, 0, 1, 1)

        buttons = Gtk.ButtonBox(orientation=Gtk.Orientation.HORIZONTAL)
        buttons.set_spacing(6)
        buttons.set_layout(Gtk.ButtonBoxStyle.CENTER)
        grid.attach(buttons, 0, 1, 1, 1)

        clear = Gtk.Button(label=_("Clear"), use_underline=True)
        clear.connect('clicked', self.clear_button_cb)
        buttons.add(clear)

        fetch = Gtk.Button(label=_("_Fetch"), use_underline=True)
        fetch.connect('clicked', self.fetch_button_cb)
        buttons.add(fetch)

        browse_file = Gtk.Button(label=_("_Browse"), use_underline=True)
        browse_file.connect('clicked', self.browse_button_cb)
        buttons.add(browse_file)

        self.page_num = song_info.append_page(_("Album Art"), grid)

        self.ec_id = song_info.connect("notify::current-entry",
                                       self.entry_changed_cb)
        self.sp_id = grid.get_parent().connect("switch-page",
                                               self.switch_page_cb)
    def __init__(self, plugin, cover_model):
        '''
        Initialises the loader, getting the needed objects from the plugin and
        saving the model that will be used to assign the loaded albums.
        '''
        self.albums = {}
        self.db = plugin.shell.props.db
        self.cover_model = cover_model
        self.cover_db = RB.ExtDB(name='album-art')

        # connect the signal to update cover arts when added
        self.req_id = self.cover_db.connect('added',
                                            self._albumart_added_callback)

        # connect signals for updating the albums
        self.entry_changed_id = self.db.connect('entry-changed',
                                                self._entry_changed_callback)
        self.entry_added_id = self.db.connect('entry-added',
                                              self._entry_added_callback)
        self.entry_deleted_id = self.db.connect('entry-deleted',
                                                self._entry_deleted_callback)

        # initialise unkown cover for albums without cover
        Album.init_unknown_cover(plugin)
Example #14
0
    def get_cover(self, db_entry=None):
        # Find cover in music dir
        if db_entry:
            print("dbentry")
            cover_dir = path.dirname(
                url2pathname(db_entry.get_playback_uri()).replace(
                    'file://', ''))
            if path.isdir(cover_dir):
                print(cover_dir)
                for f in listdir(cover_dir):
                    file_name = path.join(cover_dir, f)
                    mt = mimetypes.guess_type(file_name)[0]
                    if mt and mt.startswith('image/'):
                        if path.splitext(f)[0].lower() in IMAGE_NAMES:
                            print("spli")
                            print(file_name)
                            return file_name

            # Find cover saved by artdisplay plugin
            song_info = self.get_song_info(db_entry)
            for rb_cover_path in ('~/.gnome2/rhythmbox/covers',
                                  '~/.cache/rhythmbox/covers/'):
                for file_type in ('jpg', 'png', 'jpeg', 'gif', 'svg'):
                    cover_file = path.join(
                        path.expanduser(rb_cover_path), '%s - %s.%s' %
                        (song_info['artist'], song_info['album'], file_type))
                    if path.isfile(cover_file):
                        print("Found image in cache folder")
                        print(cover_file)
                        return cover_file

            key = db_entry.create_ext_db_key(RB.RhythmDBPropType.ALBUM)
            cover_db = RB.ExtDB(name='album-art')
            art_location = cover_db.lookup(key)

            if art_location and not isinstance(art_location, str):
                art_location = art_location[0]  # hack for RB 3.2 api

            if art_location and path.exists(art_location):
                print(art_location)
                return art_location
                # Find the image from AlbumArt plugin
                #cover_art = self.db.entry_request_extra_metadata(db_entry, "rb:coverArt")

                # If image not found return
                #if cover_art==None:
                #    print "Image not found, bloody timeouts"
                #    return DesktopControl.UNKNOWN_COVER

                # Do the dirty work here
                cover_file = path.expanduser(STORAGE_LOC) + song_info[
                    'title'] + "-" + song_info['artist'] + ".jpg"
                print(cover_file)
                cover_art.save(cover_file, "jpeg", {"quality": "100"})
                print("Returning cover file")
                print(cover_file)
                return cover_file

            # No cover found
            print("no cover")
            return DesktopControl.UNKNOWN_COVER
        # Not playing
        print("not playing")
        return None
Example #15
0
	def setup(self):
		shell = self.props.shell

		builder = Gtk.Builder()
		builder.add_from_file(rb.find_plugin_file(self.props.plugin, "soundcloud.ui"))

		self.scrolled = builder.get_object("container-scrolled")
		self.scrolled.set_no_show_all(True)
		self.scrolled.hide()

		self.more_containers_idle = 0
		adj = self.scrolled.get_vadjustment()
		adj.connect("changed", self.scroll_adjust_changed_cb)
		adj.connect("value-changed", self.scroll_adjust_changed_cb)

		self.search_entry = RB.SearchEntry(spacing=6)
		self.search_entry.props.explicit_mode = True

		self.fetch_more_button = Gtk.Button.new_with_label(_("Fetch more tracks"))
		self.fetch_more_button.connect("clicked", self.show_more_cb)

		action = Gio.SimpleAction.new("soundcloud-search-type", GLib.VariantType.new('s'))
		action.connect("activate", self.search_type_action_cb)
		shell.props.window.add_action(action)

		m = Gio.Menu()
		for st in sorted(self.search_types):
			i = Gio.MenuItem()
			i.set_label(self.search_types[st]['label'])
			i.set_action_and_target_value("win.soundcloud-search-type", GLib.Variant.new_string(st))
			m.append_item(i)

		self.search_popup = Gtk.Menu.new_from_model(m)

		action.activate(GLib.Variant.new_string("tracks"))

		grid = builder.get_object("soundcloud-source")

		self.search_entry.connect("search", self.search_entry_cb)
		self.search_entry.connect("activate", self.search_entry_cb)
		self.search_entry.connect("show-popup", self.search_popup_cb)
		self.search_entry.set_size_request(400, -1)

		searchbox = builder.get_object("search-box")
		searchbox.pack_start(self.search_entry, False, True, 0)
		searchbox.pack_start(self.fetch_more_button, False, True, 0)


		self.search_popup.attach_to_widget(self.search_entry, None)

		self.containers = builder.get_object("container-store")
		self.container_view = builder.get_object("containers")
		self.container_view.set_model(self.containers)

		action = Gio.SimpleAction.new("soundcloud-open-uri", GLib.VariantType.new('s'))
		action.connect("activate", self.open_uri_action_cb)
		shell.props.window.add_action(action)

		r = Gtk.CellRendererText()
		c = Gtk.TreeViewColumn("", r, text=0)
		self.container_view.append_column(c)

		self.container_view.get_selection().connect('changed', self.selection_changed_cb)

		self.songs = RB.EntryView(db=shell.props.db,
					  shell_player=shell.props.shell_player,
					  is_drag_source=True,
					  is_drag_dest=False,
					  shadow_type=Gtk.ShadowType.NONE)
		self.songs.append_column(RB.EntryViewColumn.TITLE, True)
		self.songs.append_column(RB.EntryViewColumn.ARTIST, True)
		self.songs.append_column(RB.EntryViewColumn.DURATION, True)
		self.songs.append_column(RB.EntryViewColumn.YEAR, False)
		self.songs.append_column(RB.EntryViewColumn.GENRE, False)
		self.songs.append_column(RB.EntryViewColumn.BPM, False)
		self.songs.append_column(RB.EntryViewColumn.FIRST_SEEN, False)
		self.songs.set_model(self.props.query_model)
		self.songs.connect("notify::sort-order", self.sort_order_changed_cb)
		self.songs.connect("selection-changed", self.songs_selection_changed_cb)

		paned = builder.get_object("paned")
		paned.pack2(self.songs)

		self.bind_settings(self.songs, paned, None, True)

		self.sc_button = Gtk.MenuButton()
		self.sc_button.set_relief(Gtk.ReliefStyle.NONE)
		img = Gtk.Image.new_from_file(rb.find_plugin_file(self.props.plugin, "powered-by-soundcloud.png"))
		self.sc_button.add(img)
		box = builder.get_object("soundcloud-button-box")
		box.pack_start(self.sc_button, True, True, 0)

		self.build_sc_menu()

		self.pack_start(grid, expand=True, fill=True, padding=0)
		grid.show_all()

		self.art_store = RB.ExtDB(name="album-art")
		player = shell.props.shell_player
		player.connect('playing-song-changed', self.playing_entry_changed_cb)
Example #16
0
    def __init__(self, toggle_action_group, plugin):

        self.shell = plugin.object
        self.player = self.shell.props.shell_player
        self.backend = plugin  # Plugin instance

        # The fullscreen window
        Gtk.Window.__init__(self)
        # Referenced in CSS
        self.set_name("szyrics-fullscreen-window")
        # If the window is closed in any event, 'delete_event' method is called
        self.connect("delete_event", self.delete_event)
        # For specific keyboard key presses
        self.connect("key_press_event", self.key_press)

        w = self
        s = w.get_screen()
        # Using the screen of the Window, the monitor it's on can be identified
        m = s.get_monitor_at_window(s.get_active_window())
        # Then get the geometry of that monitor
        monitor = s.get_monitor_geometry(m)
        # This is an example output
        print("Height: %s, Width: %s" % (monitor.height, monitor.width))
        if monitor.height < monitor.width:
            self._albumCoverHeight = monitor.height / 3
            self._albumCoverWidth = monitor.height / 3
        else:
            self._albumCoverHeight = monitor.width / 3
            self._albumCoverWidth = monitor.width / 3

        # Setting the icon that shows on Alt+Tab
        try:
            icon_theme = Gtk.icon_theme_get_default()
            self.set_icon(icon_theme.load_icon("view-fullscreen",
                                               Gtk.ICON_SIZE_DIALOG, Gtk.ICON_LOOKUP_FORCE_SVG))
        except:
            pass

        # If no album art is available, the default image
        self.no_artwork = GdkPixbuf.Pixbuf.new_from_file_at_size(
            rb.find_plugin_file(self.backend, "img/missing-artwork.svg"),
            self._albumCoverWidth,
            self._albumCoverHeight
        )

        # Retrieve the lyrics folder location
        self.lyrics_folder = Util.set_lyrics_folder()

        # Create and put together all the elements in the sidebar (but don't show yet)
        self.init_window(monitor)

        # If nothing is playing, opens fullscreen window -> (show default image)
        self.set_artwork()        
        # Add the background colour, text properties
        self.gtk_style()
        # Show and go fullscreen
        self.show_all()
        self.fullscreen()

        # Initialise here, displays in file chooser dialog
        self.title = None
        self.artist = None
        # Must exist for file selected in chooser dialog to be copied
        self.path = None

        self.pause_circle_exists = False
        # Used for synchronized lyrics
        self.tags = None
        self.current_tag = None
        # Signal flags
        self.fsc_id = None
        self.fsrc_id = None
        self.fec_id = None
        self.fspc_id = None
        # The toggle switch for the plugin in the view menu bar
        self.toggle_action_group = toggle_action_group

        # If window opened with the song paused, show the play circle
        if self.player.get_playing_source():
            if not self.player.get_playing()[1]:
                self.add_play_circle()

        # Colour for highlighting text
        rgba = Gdk.RGBA()
        rgba.parse("#009fd4")
        # tag to style headers bold and underlined
        self.tag = self.textbuffer.create_tag(None, size_points=24, underline=Pango.Underline.SINGLE, weight=Pango.Weight.BOLD, foreground_rgba=rgba, pixels_above_lines=10, pixels_below_lines=20)
        # tag to highlight synchronized lyrics
        self.sync_tag = self.textbuffer.create_tag(None, weight=Pango.Weight.BOLD, foreground_rgba=rgba)

        # Receive notification of song changes
        self.fsrc_id = self.player.connect("playing-source-changed", self.reload_lyrics)
        self.fsc_id = self.player.connect("playing-song-changed", self.reload_lyrics)
        # self.player.connect("playing-changed", self.reload_lyrics)

        # TODO: This signal is not fired - which should we listen for?
        # We should use the cover_db,
        # but what are its signals??
        cover_db = RB.ExtDB(name='album-art')
        self.fspc_id = self.player.connect("playing-song-property-changed", self.notify_metadata)
        cover_db.connect("added", self.notify_cover_art_change)

        # Load lyrics on immediatley opening the fullscreen window
        self.reload_lyrics(self.player, self.player.get_playing_entry())
Example #17
0
	def do_activate (self):
		self.art_store = RB.ExtDB(name="album-art")
		self.req_id = self.art_store.connect("request", self.album_art_requested)