Пример #1
0
def combos_config(datos_conexion, objeto, tabla, cod):
    if tabla == "ajustemotivos":
        lista = ListStore(int, str, int)
    elif tabla == "impuestos":
        lista = ListStore(int, str, float)
    elif tabla == "monedas_s":
        lista = ListStore(int, str, int, str, str)
    elif tabla == "turnos":
        lista = ListStore(int, str, str, str)
    else:
        tipo = str if tabla in ("generos", "tipodocumentos",
                                "unidadmedidas") else int
        lista = ListStore(tipo, str)
    objeto.set_model(lista)

    cell = CellRendererText()
    objeto.pack_start(cell, True)
    objeto.add_attribute(cell, 'text', 1)  # Mostrar segunda columna

    conexion = conectar(datos_conexion)
    cursor = consultar(conexion, "*", tabla, " ORDER BY " + cod)
    datos = cursor.fetchall()
    cant = cursor.rowcount
    conexion.close()

    lista.clear()
    for i in range(0, cant):
        listafila = [datos[i][0], datos[i][1]]
        if tabla in ("ajustemotivos", "impuestos"):
            listafila.append(datos[i][2])
        elif tabla == "monedas_s":
            listafila.extend([datos[i][2], datos[i][3], datos[i][4]])
        elif tabla == "turnos":
            listafila.extend([str(datos[i][2]), str(datos[i][3])])
        lista.append(listafila)
Пример #2
0
    def configurar_combo_pagos(self):
        lista = ListStore(str)
        self.obj("cmb_pago").set_model(lista)

        cell = CellRendererText()
        self.obj("cmb_pago").pack_start(cell, True)
        self.obj("cmb_pago").add_attribute(cell, 'text', 0)

        lista.clear()
        lista.append(["Mensual"])
        lista.append(["Quincenal"])
        lista.append(["Semanal"])
Пример #3
0
    def cmb_it_02_config(self):
        lista = ListStore(int, str, float)
        objeto.set_model(lista)

        cell = CellRendererText()
        objeto.pack_start(cell, True)
        objeto.add_attribute(cell, 'text', 2)

        conexion = Op.conectar(self.nav.datos_conexion)
        cursor = Op.consultar(conexion, "*", tabla, " ORDER BY " + cod)
        datos = cursor.fetchall()
        cant = cursor.rowcount
        conexion.close()

        lista.clear()
        for i in range(0, cant):
            listafila = [datos[i][0], datos[i][1]]
            if tabla in ("ajustemotivos", "impuestos"):
                listafila.append(datos[i][2])
            if tabla == "turnos":
                listafila.extend([str(datos[i][2]), str(datos[i][3])])
            lista.append(listafila)
Пример #4
0
class PeersTab(Tab):
    def __init__(self):
        super(PeersTab, self).__init__('Peers', 'peers_tab', 'peers_tab_label')

        self.peer_menu = self.main_builder.get_object('menu_peer_tab')
        component.get('MainWindow').connect_signals(self)

        self.listview = self.main_builder.get_object('peers_listview')
        self.listview.props.has_tooltip = True
        self.listview.connect('button-press-event',
                              self._on_button_press_event)
        self.listview.connect('query-tooltip', self._on_query_tooltip)

        # flag, ip, client, downspd, upspd, country code, int_ip, seed/peer icon, progress
        self.liststore = ListStore(Pixbuf, str, str, int, int, str, float,
                                   Pixbuf, float)
        self.cached_flag_pixbufs = {}

        self.seed_pixbuf = icon_seeding
        self.peer_pixbuf = icon_downloading

        # key is ip address, item is row iter
        self.peers = {}

        # Country column
        column = TreeViewColumn()
        render = CellRendererPixbuf()
        column.pack_start(render, False)
        column.add_attribute(render, 'pixbuf', 0)
        column.set_sort_column_id(5)
        column.set_clickable(True)
        column.set_resizable(True)
        column.set_expand(False)
        column.set_min_width(20)
        column.set_reorderable(True)
        self.listview.append_column(column)

        # Address column
        column = TreeViewColumn(_('Address'))
        render = CellRendererPixbuf()
        column.pack_start(render, False)
        column.add_attribute(render, 'pixbuf', 7)
        render = CellRendererText()
        column.pack_start(render, False)
        column.add_attribute(render, 'text', 1)
        column.set_sort_column_id(6)
        column.set_clickable(True)
        column.set_resizable(True)
        column.set_expand(False)
        column.set_min_width(100)
        column.set_reorderable(True)
        self.listview.append_column(column)

        # Client column
        column = TreeViewColumn(_('Client'))
        render = CellRendererText()
        column.pack_start(render, False)
        column.add_attribute(render, 'text', 2)
        column.set_sort_column_id(2)
        column.set_clickable(True)
        column.set_resizable(True)
        column.set_expand(False)
        column.set_min_width(100)
        column.set_reorderable(True)
        self.listview.append_column(column)

        # Progress column
        column = TreeViewColumn(_('Progress'))
        render = CellRendererProgress()
        column.pack_start(render, True)
        column.set_cell_data_func(render, cell_data_peer_progress, 8)
        column.set_sort_column_id(8)
        column.set_clickable(True)
        column.set_resizable(True)
        column.set_expand(False)
        column.set_min_width(100)
        column.set_reorderable(True)
        self.listview.append_column(column)

        # Down Speed column
        column = TreeViewColumn(_('Down Speed'))
        render = CellRendererText()
        column.pack_start(render, False)
        column.set_cell_data_func(render, cell_data_speed_down, 3)
        column.set_sort_column_id(3)
        column.set_clickable(True)
        column.set_resizable(True)
        column.set_expand(False)
        column.set_min_width(50)
        column.set_reorderable(True)
        self.listview.append_column(column)

        # Up Speed column
        column = TreeViewColumn(_('Up Speed'))
        render = CellRendererText()
        column.pack_start(render, False)
        column.set_cell_data_func(render, cell_data_speed_up, 4)
        column.set_sort_column_id(4)
        column.set_clickable(True)
        column.set_resizable(True)
        column.set_expand(False)
        column.set_min_width(50)
        # Bugfix: Last column needs max_width set to stop scrollbar appearing
        column.set_max_width(150)
        column.set_reorderable(True)
        self.listview.append_column(column)

        self.listview.set_model(self.liststore)

        self.load_state()

        self.torrent_id = None

    def save_state(self):
        # Get the current sort order of the view
        column_id, sort_order = self.liststore.get_sort_column_id()

        # Setup state dict
        state = {
            'columns': {},
            'sort_id': column_id,
            'sort_order': int(sort_order) if sort_order else None,
        }

        for index, column in enumerate(self.listview.get_columns()):
            state['columns'][column.get_title()] = {
                'position': index,
                'width': column.get_width(),
            }
        save_pickled_state_file('peers_tab.state', state)

    def load_state(self):
        state = load_pickled_state_file('peers_tab.state')

        if state is None:
            return

        if len(state['columns']) != len(self.listview.get_columns()):
            log.warning('peers_tab.state is not compatible! rejecting..')
            return

        if state['sort_id'] and state['sort_order'] is not None:
            self.liststore.set_sort_column_id(state['sort_id'],
                                              state['sort_order'])

        for (index, column) in enumerate(self.listview.get_columns()):
            cname = column.get_title()
            if cname in state['columns']:
                cstate = state['columns'][cname]
                column.set_sizing(TreeViewColumnSizing.FIXED)
                column.set_fixed_width(
                    cstate['width'] if cstate['width'] > 0 else 10)
                if state['sort_id'] == index and state[
                        'sort_order'] is not None:
                    column.set_sort_indicator(True)
                    column.set_sort_order(state['sort_order'])
                if cstate['position'] != index:
                    # Column is in wrong position
                    if cstate['position'] == 0:
                        self.listview.move_column_after(column, None)
                    elif (self.listview.get_columns()[cstate['position'] -
                                                      1].get_title() != cname):
                        self.listview.move_column_after(
                            column,
                            self.listview.get_columns()[cstate['position'] -
                                                        1])

    def update(self):
        # Get the first selected torrent
        torrent_id = component.get('TorrentView').get_selected_torrents()

        # Only use the first torrent in the list or return if None selected
        if len(torrent_id) != 0:
            torrent_id = torrent_id[0]
        else:
            # No torrent is selected in the torrentview
            self.liststore.clear()
            return

        if torrent_id != self.torrent_id:
            # We only want to do this if the torrent_id has changed
            self.liststore.clear()
            self.peers = {}
            self.torrent_id = torrent_id

        component.get('SessionProxy').get_torrent_status(
            torrent_id, ['peers']).addCallback(self._on_get_torrent_status)

    def get_flag_pixbuf(self, country):
        if not country.strip():
            return None

        if country not in self.cached_flag_pixbufs:
            # We haven't created a pixbuf for this country yet
            try:
                self.cached_flag_pixbufs[country] = Pixbuf.new_from_file(
                    deluge.common.resource_filename(
                        'deluge',
                        os.path.join('ui', 'data', 'pixmaps', 'flags',
                                     country.lower() + '.png'),
                    ))
            except Exception as ex:
                log.debug('Unable to load flag: %s', ex)
                return None

        return self.cached_flag_pixbufs[country]

    def _on_get_torrent_status(self, status):
        new_ips = set()
        for peer in status['peers']:
            new_ips.add(peer['ip'])
            if peer['ip'] in self.peers:
                # We already have this peer in our list, so lets just update it
                row = self.peers[peer['ip']]
                if not self.liststore.iter_is_valid(row):
                    # This iter is invalid, delete it and continue to next iteration
                    del self.peers[peer['ip']]
                    continue
                values = self.liststore.get(row, 3, 4, 5, 7, 8)
                if peer['down_speed'] != values[0]:
                    self.liststore.set_value(row, 3, peer['down_speed'])
                if peer['up_speed'] != values[1]:
                    self.liststore.set_value(row, 4, peer['up_speed'])
                if peer['country'] != values[2]:
                    self.liststore.set_value(row, 5, peer['country'])
                    self.liststore.set_value(
                        row, 0, self.get_flag_pixbuf(peer['country']))
                if peer['seed']:
                    icon = self.seed_pixbuf
                else:
                    icon = self.peer_pixbuf

                if icon != values[3]:
                    self.liststore.set_value(row, 7, icon)

                if peer['progress'] != values[4]:
                    self.liststore.set_value(row, 8, peer['progress'])
            else:
                # Peer is not in list so we need to add it

                # Create an int IP address for sorting purposes
                if peer['ip'].count(':') == 1:
                    # This is an IPv4 address
                    ip_int = sum(
                        int(byte) << shift for byte, shift in zip(
                            peer['ip'].split(':')[0].split('.'), (24, 16, 8,
                                                                  0)))
                    peer_ip = peer['ip']
                else:
                    # This is an IPv6 address
                    import socket
                    import binascii

                    # Split out the :port
                    ip = ':'.join(peer['ip'].split(':')[:-1])
                    ip_int = int(
                        binascii.hexlify(socket.inet_pton(socket.AF_INET6,
                                                          ip)), 16)
                    peer_ip = '[%s]:%s' % (ip, peer['ip'].split(':')[-1])

                if peer['seed']:
                    icon = self.seed_pixbuf
                else:
                    icon = self.peer_pixbuf

                row = self.liststore.append([
                    self.get_flag_pixbuf(peer['country']),
                    peer_ip,
                    peer['client'],
                    peer['down_speed'],
                    peer['up_speed'],
                    peer['country'],
                    float(ip_int),
                    icon,
                    peer['progress'],
                ])

                self.peers[peer['ip']] = row

        # Now we need to remove any ips that were not in status["peers"] list
        for ip in set(self.peers).difference(new_ips):
            self.liststore.remove(self.peers[ip])
            del self.peers[ip]

    def clear(self):
        self.liststore.clear()

    def _on_button_press_event(self, widget, event):
        """This is a callback for showing the right-click context menu."""
        log.debug('on_button_press_event')
        # We only care about right-clicks
        if self.torrent_id and event.button == 3:
            self.peer_menu.popup(None, None, None, None, event.button,
                                 event.time)
            return True

    def _on_query_tooltip(self, widget, x, y, keyboard_tip, tooltip):
        is_tooltip, x, y, model, path, _iter = widget.get_tooltip_context(
            x, y, keyboard_tip)
        if is_tooltip:
            country_code = model.get(_iter, 5)[0]
            if country_code != '  ' and country_code in COUNTRIES:
                tooltip.set_text(COUNTRIES[country_code])
                # widget here is self.listview
                widget.set_tooltip_cell(tooltip, path, widget.get_column(0),
                                        None)
                return True
        return False

    def on_menuitem_add_peer_activate(self, menuitem):
        """This is a callback for manually adding a peer"""
        log.debug('on_menuitem_add_peer')
        builder = Builder()
        builder.add_from_file(
            deluge.common.resource_filename(
                __package__, os.path.join('glade', 'connect_peer_dialog.ui')))
        peer_dialog = builder.get_object('connect_peer_dialog')
        txt_ip = builder.get_object('txt_ip')
        response = peer_dialog.run()

        if response:
            value = txt_ip.get_text()
            ip, port = parse_ip_port(value)
            if ip and port:
                log.info('Adding peer IP: %s port: %s to %s', ip, port,
                         self.torrent_id)
                client.core.connect_peer(self.torrent_id, ip, port)
            else:
                log.error('Error parsing peer "%s"', value)

        peer_dialog.destroy()
        return True
Пример #5
0
class Playlist:
    def __init__(self, extensionsloader):
        self.extensions = extensionsloader
        self.module = {'name': 'Playlist'}

        self.functions = Functions()
        self.userconf = ConfigLoader()

        self.config = {}
        rpt = self.userconf.config['Playlist']['repeat']
        self.config['repeat'] = bool(int(rpt))
        shf = self.userconf.config['Playlist']['shuffle']
        self.config['shuffle'] = bool(int(shf))
        shm = self.userconf.config['Playlist']['shuffle_mode']
        self.config['shuffle_mode'] = shm

        self.lastfm = LastFm()
        self.playlists_mgmnt = Playlists()

        self.playlist_content = {}
        self.playlist_identifier = 0
        self.playlist_current = None
        self.current_playlist_id = 0
        self.user_playlists = {}
        self.last_user_playlist = None

        self.similar_artists = []
        self.is_in_similar_thread = False

        # Create the Playlist view
        def launch_playlist(wdg):
            self.widgets = wdg[1]

            self.playlist_label = self.widgets.get_object('label_playlist')
            self.playlist_repeat = self.widgets.get_object('tool-repeat')
            self.playlist_shuffle = self.widgets.get_object('tool-shuffle')
            self.playlist_clean = self.widgets.get_object('tool-clean')
            self.playlist_combo = self.widgets.get_object('combo-playlist')
            self.playlist_save = self.widgets.get_object('tool-saveplaylist')
            self.playlist_lyrics = self.widgets.get_object('tool-lyrics')

            self.playlist_tree = self.widgets.get_object('treeview_playlist')
            self.playlist_tree.set_headers_visible(False)
            self.playlist_tree.props.reorderable = True
            self.playlist_tree.connect('key_press_event', self.key_pressed)
            self.playlist_tree.connect('row_activated', self.row_activated)

            self.liststore = ListStore(str, str, str, str, int)
            self.playlist_tree.set_model(self.liststore)

            renderer_pix = CellRendererPixbuf()
            column_pixbuf = TreeViewColumn('1', renderer_pix, icon_name=0)
            column_pixbuf.set_fixed_width(18)
            self.playlist_tree.append_column(column_pixbuf)

            renderer_text = CellRendererText()
            column_text = TreeViewColumn('2', renderer_text, markup=1)
            column_text.props.expand = True
            column_text.props.max_width = 192
            self.playlist_tree.append_column(column_text)

            column_text = TreeViewColumn('3', renderer_text, markup=2)
            column_text.set_fixed_width(40)
            self.playlist_tree.append_column(column_text)

            self.repeat_btn = self.widgets.get_object('tool-repeat')
            if self.config['repeat']:
                self.repeat_btn.set_active(True)
            self.repeat_btn.connect('clicked', self.toggle, 'repeat')

            self.shuffle_btn = self.widgets.get_object('tool-shuffle')
            if self.config['shuffle']:
                self.shuffle_btn.set_active(True)
            self.shuffle_btn.connect('clicked', self.toggle, 'shuffle')

            def clean_wdg(widget):
                # Clean playlist
                self.clean()

                # Show popover
                if self.current_playlist_id > 3:
                    self.clean_btn.set_sensitive(True)
                    self.clean_pop.show_all()

            self.clean_btn = self.widgets.get_object('tool-clean')
            self.clean_btn.connect('clicked', clean_wdg)
            self.clean_pop = Popover.new(self.clean_btn)
            self.clean_pop.set_size_request(100, 30)

            gtkpla = join(self.functions.datadir, 'glade', 'plist-del-pop.ui')
            win = gtk_builder()
            win.set_translation_domain('bluemindo')
            win.add_from_file(gtkpla)
            hbox = win.get_object('box-playlist')
            lbl = win.get_object('label')
            lbl.set_text(_('Do you also want to remove the playlist?'))
            btn = win.get_object('del-btn')
            btn.set_label(_('Delete'))
            btn.connect('clicked', self.delete_playlist)
            self.clean_pop.add(hbox)

            # Populate combobox
            self.combolist = ListStore(int, str)

            self.combobox = self.widgets.get_object('combobox')
            self.combobox.set_model(self.combolist)
            self.combobox.set_popup_fixed_width(False)
            self.combobox.props.expand = False

            renderer_text = CellRendererText()
            renderer_text.props.ellipsize = EllipsizeMode.END
            self.combobox.pack_start(renderer_text, True)
            self.combobox.set_entry_text_column(1)
            self.combobox.add_attribute(renderer_text, 'text', 1)

            self.combolist.append([0, _('Current')])
            self.combolist.append([1, _('Top 50 songs')])
            self.combolist.append([2, _('Top 10 albums')])

            playlists = self.playlists_mgmnt.get_playlists()

            if len(playlists) > 0:
                self.combolist.append([3, ''])
                item_id = 3

                playlists.sort(key=lambda it: it[1])
                for item in playlists:
                    item_id += 1
                    self.combolist.append([item_id, item])
                    self.user_playlists[item_id] = item
                    self.last_user_playlist = item_id

            def combo_sep(model, iter):
                if model[iter][0] == 3:
                    return True
            self.combobox.set_row_separator_func(combo_sep)

            def on_combo_changed(widget):
                path = widget.get_active()
                item_id = self.combolist[path][0]

                # First, clean the playlist
                self.clean(None)

                # Second, populate the playlist
                if item_id > 0:
                    self.populate(item_id)

                # Then, update playlist identifier
                self.current_playlist_id = item_id

                # Show delete/remove button if the playlist is from the user
                if item_id > 3:
                    self.clean_btn.set_sensitive(True)

            self.combobox.set_active(0)
            self.combobox.connect('changed', on_combo_changed)
            
            self.tool_save = self.widgets.get_object('tool-saveplaylist')
            self.tool_save.connect('clicked', self.save_playlist)
            self.save_pop = Popover.new(self.tool_save)
            self.save_pop.set_size_request(100, 30)

            gtkpla = join(self.functions.datadir, 'glade', 'plist-add-pop.ui')
            win = gtk_builder()
            win.set_translation_domain('bluemindo')
            win.add_from_file(gtkpla)
            hbox = win.get_object('box-playlist')
            self.save_pop.add(hbox)

            self.save_entry = win.get_object('save-entry')
            self.save_entry.connect('key_press_event', self.save_playlist_key)
            self.save_btn = win.get_object('save-btn')
            self.save_btn.connect('clicked', self.save_playlist_button)
            self.save_btn.set_label(_('Save'))

            self.clean_btn.set_sensitive(False)
            self.tool_save.set_sensitive(False)

        # Acquire the songs tree
        def acquire_tree(st):
            self.songs_tree = st

        self.extensions.connect('OnBluemindoStarted', launch_playlist)
        self.extensions.connect('OnSongsTreeCreated', acquire_tree)
        self.extensions.connect('OnSongQueued', self.on_new_song_queued)
        self.extensions.connect('OnAlbumQueued', self.on_new_album_queued)
        self.extensions.connect('AskPreviousSong', self.ask_previous_song)
        self.extensions.connect('AskNextSong', self.ask_next_song)
        self.extensions.connect('HasStartedSong', self.song_started)


    def toggle(self, widget, action):
        if action == 'repeat' and self.config['repeat']:
            self.config['repeat'] = False
            self.repeat_btn.set_active(False)
            self.userconf.update_key('Playlist', 'repeat', str(int(False)))
        elif action == 'repeat' and not self.config['repeat']:
            self.config['repeat'] = True
            self.repeat_btn.set_active(True)
            self.userconf.update_key('Playlist', 'repeat', str(int(True)))
        elif action == 'shuffle' and self.config['shuffle']:
            self.config['shuffle'] = False
            self.shuffle_btn.set_active(False)
            self.userconf.update_key('Playlist', 'shuffle', str(int(False)))
        elif action == 'shuffle' and not self.config['shuffle']:
            self.config['shuffle'] = True
            self.shuffle_btn.set_active(True)
            self.userconf.update_key('Playlist', 'shuffle', str(int(True)))

    def row_activated(self, widget, path, column):
        item_iter = self.liststore.get_iter(path)

        # Get the founded element.
        item_identifier = self.liststore.get_value(item_iter, 4)
        current_item = self.playlist_content[item_identifier]

        # The element is a song.
        if self.playlist_content[item_identifier].kind == 'song':
            self.playlist_current = [item_iter, item_identifier, None]
            self.extensions.load_event('OnPlayNewSong', current_item)
        # The element is an album.
        else:
            self.extensions.load_event('OnAbortPlayback')
            sng = self.playlist_content[item_identifier].tracks[0]
            self.playlist_current = [item_iter, item_identifier, 0]
            self.extensions.load_event('OnPlayNewSong', sng)

    def key_pressed(self, widget, eventkey):
        if eventkey.get_keyval()[1] == KEY_Delete:
            # Delete an item from the playlist
            selection = self.playlist_tree.get_selection()
            selected = selection.get_selected_rows()
            liststore = selected[0]
            listpath = selected[1]

            if len(listpath) > 0:
                selpath = listpath[0]
                playlist_identifier = liststore[selpath][4]

                # Are we removing the currently playing item?
                if self.playlist_current is not None:
                    item_iter, item_path, item_in_album = self.playlist_current
                    if selpath == TreePath.new_from_string(str(item_path)):
                        self.playlist_current = None

                # Removal
                del self.playlist_content[playlist_identifier]
                del liststore[selpath]

    def clean(self, data=None):
        self.playlist_content = {}
        self.playlist_identifier = 0
        self.playlist_current = None
        self.liststore.clear()

        # Update GUI
        self.clean_btn.set_sensitive(False)
        self.tool_save.set_sensitive(False)

    def populate(self, playlist_id):
        if playlist_id in (1, 2):
            # Automatic playlists based on listening stats
            if playlist_id == 1:
                tb = 'stats_songs'
                lm = 50
            elif playlist_id == 2:
                tb = 'stats_albums'
                lm = 10

            result = []
            txt = ('select * from %s order by tracks desc limit %u' % (tb, lm))

            sql = SQLite()
            cur = sql.execute(txt)
            for sg in cur:
                result.append(sg)
            sql.close()

            for item in result:
                if playlist_id == 1:
                    sng = Song(filename=item[0])
                    if hasattr(sng, 'title'):
                        self.on_new_song_queued(sng)
                elif playlist_id == 2:
                    album_name = item[0]
                    for it in self.songs_tree:
                        if album_name in self.songs_tree[it]:
                            self.on_new_album_queued(Album(it, album_name,
                                                           self.songs_tree))
                            break
        elif playlist_id > 3:
            # User-created playlists
            user_plist = self.user_playlists[playlist_id]
            plist = self.playlists_mgmnt.load_playlist(user_plist)

            for item in plist:
                sng = Song(filename=item)
                if hasattr(sng, 'title'):
                    self.on_new_song_queued(sng)

    def delete_playlist(self, widget):
        if self.current_playlist_id > 3:
            user_plist = self.user_playlists[self.current_playlist_id]
            self.playlists_mgmnt.delete_playlist(user_plist)

            # Delete the playlist from the list
            del self.user_playlists[self.current_playlist_id]

            cblid = 0
            for item in self.combolist:
                if item[0] == self.current_playlist_id:
                    del self.combolist[cblid]
                    break
                cblid += 1

            # Move back to "Current" playlist
            self.combobox.set_active(0)

    def save_playlist_key(self, widget, eventkey):
        if eventkey.get_keyval()[1] == KEY_Return:
            self.save_playlist_button(None)

    def save_playlist_button(self, widget):
        user_entry = self.save_entry.get_text()
        user_entry = user_entry.replace('\\', '-')
        user_entry = user_entry.replace('/', '-')
        user_entry = user_entry.replace('*', '-')
        user_entry = user_entry.replace('|', '-')

        if len(user_entry) > 0:
            rtn_value = self.playlists_mgmnt.create_new_playlist(user_entry)

            if rtn_value:
                self.save_pop.hide()

                # Add playlist to GUI
                if self.last_user_playlist is None:
                    self.combolist.append([3, ''])
                    self.last_user_playlist = 3

                self.last_user_playlist += 1
                self.combolist.append([self.last_user_playlist, user_entry])
                self.user_playlists[self.last_user_playlist] = user_entry

                # Write the playlist
                self.write_playlist(user_entry)

                # Select the new playlist
                self.combobox.set_active(self.last_user_playlist)

    def save_playlist(self, widget):
        if self.current_playlist_id < 3:
            # Create a new playlist
            self.save_entry.set_text('')
            self.save_pop.show_all()
        elif self.current_playlist_id > 3:
            # Update an existing playlist
            user_plist = self.user_playlists[self.current_playlist_id]
            self.write_playlist(user_plist)

    def write_playlist(self, user_plist):
        plist_content = []
        for item in self.liststore:
            item_id = item[4]
            plist_content.append(self.playlist_content[item_id])

        self.playlists_mgmnt.write_playlist(user_plist, plist_content)

    def on_new_song_queued(self, song_info):
        title = song_info.title
        artist = song_info.artist
        album = song_info.album
        filename = song_info.filename
        length = self.functions.human_length(song_info.length)

        self.liststore.append(('audio-x-generic-symbolic', '<b>' +
                               self.functions.view_encode(title, 99) +
                               '</b>\n' + self.functions.view_encode(artist),
                               '<span foreground="grey">' +
                               length + '</span>',
                               filename, self.playlist_identifier))

        self.playlist_content[self.playlist_identifier] = song_info
        self.playlist_identifier += 1

        # Update GUI
        self.clean_btn.set_sensitive(True)
        self.tool_save.set_sensitive(True)

    def on_new_album_queued(self, album_info):
        artist = album_info.artist
        album = album_info.name
        songs_count = str(len(album_info.tracks)) + ' ♫'

        self.liststore.append(('media-optical-symbolic', '<b>' +
                               self.functions.view_encode(album, 99) +
                               '</b>\n' + self.functions.view_encode(artist),
                               '<span foreground="grey">' +
                               songs_count + '</span>', '[album]',
                               self.playlist_identifier))

        self.playlist_content[self.playlist_identifier] = album_info
        self.playlist_identifier += 1

        # Update GUI
        self.clean_btn.set_sensitive(True)
        self.tool_save.set_sensitive(True)

    def ask_next_song(self, current_song):
        self.ask_for_a_song(True, current_song)

    def ask_previous_song(self, current_song):
        self.ask_for_a_song(False, current_song)

    def ask_for_a_song(self, next=True, current_song=None):
        def walk_in_playlist(item_iter, next=True):
            base_item_iter = item_iter
            if item_iter is None:
                # Find first song.
                item_iter = self.liststore.get_iter_first()
            elif next:
                # Find next song.
                path = self.liststore.get_path(self.playlist_current[0])
                path_int = int(path.to_string())
                max_id = len(self.playlist_content) - 1

                if (path_int + 1 <= max_id): # There is a song to launch!
                    item_iter = self.liststore.get_iter(path_int + 1)
                else: # There is no song to launch!
                    if not self.config['repeat']:
                        self.extensions.load_event('OnAbortPlayback')
                        return
                    else:
                        item_iter = self.liststore.get_iter_first()
            elif not next:
                # Find previous song.
                path = self.liststore.get_path(self.playlist_current[0])
                path_int = int(path.to_string())
                max_id = len(self.playlist_content) - 1

                if (path_int -1 >= 0): # There is a song to launch.
                    item_iter = self.liststore.get_iter(path_int - 1)
                else: # There is no song to launch!
                    if not self.config['repeat']:
                        self.extensions.load_event('OnAbortPlayback')
                        return
                    else:
                        item_iter = self.liststore.get_iter_from_string(str(max_id))

            # Get the founded element.
            item_identifier = self.liststore.get_value(item_iter, 4)
            current_item = self.playlist_content[item_identifier]

            def launch_founded_item(item_identifier, item_iter, current_item):
                # The element is a song.
                if self.playlist_content[item_identifier].kind == 'song':
                    self.playlist_current = [item_iter, item_identifier, None]
                    self.extensions.load_event('OnPlayNewSong', current_item)
                # The element is an album.
                else:
                    self.extensions.load_event('OnAbortPlayback')
                    sng = self.playlist_content[item_identifier].tracks[0]
                    sng.rg_mode_guess = 'album'
                    self.playlist_current = [item_iter, item_identifier, 0]
                    self.extensions.load_event('OnPlayNewSong', sng)

            # Are we currently listening from an album?
            if base_item_iter is not None:
                kind = self.playlist_content[self.playlist_current[1]].kind

                if kind == 'album':
                    base_item_identifier = self.liststore.get_value(base_item_iter, 4)
                    tracks = self.playlist_content[self.playlist_current[1]].tracks
                    max_sng = len(tracks) - 1

                    if next:
                        if self.playlist_current[2] < max_sng:
                            item_in_album = self.playlist_current[2] + 1
                        else:
                            return launch_founded_item(item_identifier, item_iter, current_item)
                    elif not next:
                        if self.playlist_current[2] - 1 > -1:
                            item_in_album = self.playlist_current[2] - 1
                        else:
                            return launch_founded_item(item_identifier, item_iter, current_item)

                    sng = self.playlist_content[base_item_identifier].tracks[item_in_album]
                    sng.rg_mode_guess = 'album'
                    self.playlist_current = [base_item_iter, base_item_identifier, item_in_album]
                    self.extensions.load_event('OnPlayNewSong', sng)
                    return

            launch_founded_item(item_identifier, item_iter, current_item)

        if len(self.playlist_content) == 0:
            # Playlist is empty.
            if not self.config['shuffle']:
                # Shuffle disabled: abort playback.
                self.extensions.load_event('OnAbortPlayback')
            else:
                # Shuffle enabled.
                if self.config['shuffle_mode'] == 'random':
                    # Random mode: seek for shuffle song.
                    self.extensions.load_event('AskShuffleSong')
                elif self.config['shuffle_mode'] == 'similar':
                    # Similar mode: seek for a similar song.
                    if len(self.similar_artists) == 0:
                        # No similar song founded: seek for any one.
                        self.extensions.load_event('AskShuffleSong')
                        return

                    # Choose one song in the list of similar artists
                    index = randrange(len(self.similar_artists))
                    artist = self.similar_artists[index]

                    mdb = MusicDatabase(None)
                    songs_list = mdb.load_from_artist(artist)
                    if len(songs_list) > 1:
                        index = randrange(len(songs_list))
                        song = songs_list[index]

                        sng = Song(filename=song[8])
                        print ('[SIMILAR] Playing a song from ' + sng.artist)
                        self.extensions.load_event('OnPlayNewSong', sng)
                    else:
                        self.extensions.load_event('AskShuffleSong')
        else:
            # Playlist is not empty, walk in it!
            if self.playlist_current is None:
                # Currently no current item in playlist, choose the first one!
                walk_in_playlist(None)
            else:
                # The current playling song is in the playlist!
                if next:
                    walk_in_playlist(self.playlist_current[0])
                else:
                    walk_in_playlist(self.playlist_current[0], False)


    def song_started(self, song):
        # First, try to download a few similar artists names
        if self.config['shuffle_mode'] == 'similar':
            def download_similars():
                threads_enter()
                art = self.lastfm.get_similar_artists(song.artist)

                self.similar_artists = []
                mdb = MusicDatabase(None)

                for artist in art:
                    if mdb.artist_exists(artist):
                        self.similar_artists.append(artist)

                self.is_in_similar_thread = False
                threads_leave()

            if not self.is_in_similar_thread:
                self.is_in_similar_thread = True
                thread = Thread(group=None, target=download_similars,
                                name='similars', args=())
                thread.start()

        # Second, update statistics for this song
        song.increment_statistics()
        alb = Album(song.artist, song.album, self.songs_tree)
        alb.increment_statistics()

        # Then, highlight currently playing song/album if it's in playlist
        if self.playlist_current is not None:
            # Currently playing item is in the playlist
            item_iter, item_path, item_in_album = self.playlist_current

            # Remove marker of all items
            for item in self.liststore:
                current_label = item[1]
                if current_label[:2] == '◎ ':
                    item[1] = current_label[2:]

            # Add marker on one item
            current_label = self.liststore[item_iter][1]
            if current_label[:2] != '◎ ':
                self.liststore[item_iter][1] = '◎ ' + current_label
Пример #6
0
class AlbumsView:
    def __init__(self, widgets, extensions):
        self.widgets = widgets
        self.extensions = extensions

        self.functions = Functions()
        self.userconf = ConfigLoader()
        self.dblclick = None

        # Create the IconView
        self.albumview = self.widgets[1].get_object('albumview')
        self.albummodel = ListStore(Pixbuf, str, str, str, int, str, str)

        self.albumview.set_pixbuf_column(0)
        self.albumview.set_markup_column(1)

        self.albumview.set_column_spacing(0)
        self.albumview.set_spacing(0)
        self.albumview.set_item_width(100)
        self.albumview.set_property('activate-on-single-click', False)

        # Add a filter to the ListStore model
        self.albumfilter = self.albummodel.filter_new(None)
        self.remove_filter_data()
        self.matched = False

        def filter_visible(model, iter, data):
            usrf = self.widgets[1].get_object('searchentry').get_text()
            search_a = model.get_value(iter, 3)
            search_b = model.get_value(iter, 2)
            pre_result = False

            if self.matched:
                usrf_a = self.matched[0]
                usrf_b = self.matched[1]

                if usrf_b == 'blm.!ARTIST!':
                    if usrf_a.lower() == search_b.lower():
                        # Matched an artist
                        pre_result = True
                else:   
                    if (usrf_a.lower() == search_a.lower() and
                        usrf_b.lower() == search_b.lower()):
                        # Matched an album
                        pre_result = True
            else:
                if len(model) > 0:
                    if (usrf.lower() in search_a.lower() or
                        usrf.lower() in search_b.lower()):
                        # Found an element (artist or album name is close)
                        pre_result = True
                    else:
                        # No element founded at all, return False anyway
                        return False

            # Apply filters
            fdg = self.filter_data['genre']
            fdy = self.filter_data['year']

            # Filter results by genres
            if fdg is not None and fdg != model.get_value(iter, 5):
                pre_result = False

            # Filter results by years
            if fdy is not None and fdy != model.get_value(iter, 6):
                pre_result = False

            # Return the final result
            return pre_result


        self.albumfilter.set_visible_func(filter_visible)
        self.albumview.set_model(self.albumfilter)

        # Connect to signals
        def grab_entry_focus(widget, event):
            key = event.string
            if (key.lower() in 'a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,'
                               'x,y,z,0,1,2,3,4,5,6,7,8,9'.split(',')):
                self.widgets[1].get_object('searchentry').grab_focus()
                self.widgets[1].get_object('searchentry').set_text(key)
                self.widgets[1].get_object('searchentry').set_position(-1)

        self.albumview.connect('key-press-event', grab_entry_focus)
        self.albumview.connect('selection_changed', self.on_selection_changed)


    def populate_albums(self, albums_tree, albums, songs_tree, search):
        self.albums_tree = albums_tree
        self.albums = albums
        self.songs_tree = songs_tree
        self.search_entry = search.searchentry

        # Clear the tree model first
        self.albummodel.clear()

        # Show albums in the main explorer view
        self.album_nf = []
        album_id = 0
        for alb in self.albums_tree:
            bdir = join(self.userconf.datadir, 'modules', 'player', 'covers')
            album = alb['album']
            artist = alb['artist']

            cover = join(bdir, self.functions.get_hash(album, artist))
            if isfile(cover):
                cover_px = Pixbuf.new_from_file_at_scale(cover, 150, 150, True)
            else:
                cover_px = Pixbuf.new_from_file(join(self.functions.datadir,
                                                'image', 'logo_head_big.png'))

            self.albums[album_id] = Album(artist, album, self.songs_tree)

            ap = self.albummodel.append([cover_px, '<b>' +
                                        self.functions.view_encode(album) +
                                        '</b>\n<span foreground="grey">' +
                                        self.functions.view_encode(artist) +
                                        '</span>',
                                        artist, album, album_id, '', ''])
            album_id += 1

            if not isfile(cover):
                self.album_nf.append([cover, ap, None])

        # Check if we have to regenerate thumbnail (cover not found at startup)
        if len(self.album_nf) > 0:
            def regenerate_thumb():
                new_album = []

                for alb in self.album_nf:
                    if isfile(alb[0]):
                        item_iter = alb[1]

                        cover_md5 = md5(open(alb[0], 'rb').read()).hexdigest()

                        if alb[2] == None or alb[2] != cover_md5:
                            cover_px = Pixbuf.new_from_file_at_scale(alb[0],
                                                                     150, 150,
                                                                     True)
                            self.albummodel.set_value(item_iter, 0, cover_px)
                            alb[2] = cover_md5
                            new_album.append(alb)
                    else:
                        new_album.append(alb)

                if len(new_album) > 0:
                    self.album_nf = new_album
                    return True

            timeout_add(15000, regenerate_thumb)


    def on_album_matched(self, album):
        for item in self.albummodel:
            if item[2] == album.artist and item[3] == album.name:
                self.on_selection_changed(self.albumview, album)


    def on_selection_changed(self, icon_view, album=None):
        popup = Popover.new(self.albumview)
        popup.set_size_request(810, 240)

        if album is None:
            selection = icon_view.get_selected_items()
            if len(selection) != 1:
                return

            path = selection[0]
            treeiter = self.albumfilter.get_iter(path)

            isset, path, cell = icon_view.get_cursor()
            isset, rect = icon_view.get_cell_rect(path, cell)
            popup.set_pointing_to(rect)

            album_id = self.albumfilter.get_value(treeiter, 4)
            album_obj = self.albums[album_id]
        else:
            album_obj = album
            popup.set_relative_to(self.search_entry)

        # Handle double clicks
        def empty_dblclick():
            self.dblclick = None

        if self.dblclick is None:
            self.dblclick = album_obj
            timeout_add(1000, empty_dblclick)
        elif self.dblclick == album_obj:
            self.play(album_obj)
            return

        album = album_obj.name
        artist = album_obj.artist

        glade_album = join(self.functions.datadir, 'glade', 'albumview.ui')
        box = gtk_builder()
        box.set_translation_domain('bluemindo')
        box.add_from_file(glade_album)
        popup.add(box.get_object('box1'))

        box.get_object('label_album').set_text(album)
        box.get_object('label_artist').set_text(artist)

        bdir = join(self.userconf.datadir, 'modules', 'player', 'covers')
        cover = join(bdir, self.functions.get_hash(album, artist))
        if isfile(cover):
            cover_px = Pixbuf.new_from_file_at_scale(cover, 180, 180, True)
        else:
            cover_px = Pixbuf.new_from_file(join(self.functions.datadir,
                                            'image', 'logo_head_big.png'))

        box.get_object('album_cover').set_from_pixbuf(cover_px)

        def play_album(wdg, album):
            self.play(album)

        def queue_album(wdg, album):
            self.queue(album)

        def change_cover(wdg, ka, album):
            artist_name = album.artist
            album_name = album.name

            fcdialog = FileChooserDialog(
                        title=_('Change the cover picture for this album'),
                        buttons=(_('Select'), ResponseType.OK))

            fcdialog.set_transient_for(self.widgets[0][11])
            response = fcdialog.run()
            if response == ResponseType.OK:
                filename = fcdialog.get_filename()

                datadir = self.userconf.datadir
                hash_a = self.functions.get_hash(album_name, artist_name)
                pictures_dir = join(datadir, 'modules', 'player', 'covers')
                album_file = join(pictures_dir, hash_a)

                copyfile(filename, album_file)

                new = Pixbuf.new_from_file_at_scale(album_file, 180, 180, True)
                box.get_object('album_cover').set_from_pixbuf(new)

            fcdialog.destroy()

        box.get_object('button_play').connect('clicked', play_album, album_obj)

        box.get_object('button_add').connect('clicked', queue_album, album_obj)

        box.get_object('coverevent').connect('button-press-event',
                                             change_cover, album_obj)

        i = 0
        a = -1
        previous_column = 0

        grid_songs = box.get_object('grid_songs')
        grid_songs.set_size_request(-1, 200)
        grid_songs.set_column_spacing(5)

        try:
            kids = grid_songs.get_children()
            for kid in kids:
                grid_songs.remove(kid)
        except IndexError:
            pass

        for song in album_obj.tracks:
            i += 1
            a += 1

            def queue(wdg, song):
                self.queue(song)

            def play(wdg, song):
                self.play(song)

            song_wdg = Box(spacing=0)
            song_btr = Button()
            song_btr.connect('clicked', play, song)
            song_btr.set_relief(ReliefStyle.NONE)
            song_btr_content = Box(spacing=0)
            song_btr.add(song_btr_content)

            song_tr = Label()
            song_tr.set_markup('<span foreground="grey">' + str(song.track)
                               + '</span>')
            song_tr.set_width_chars(3)
            song_btr_content.pack_start(song_tr, False, True, 0)
            song_ti = Label()
            song_ti.set_markup('<b>' + self.functions.view_encode(song.title, 22)
                               + '</b>')
            song_ti.set_alignment(0.0, 0.5)
            song_ti.set_size_request(190, -1)
            song_btr_content.pack_start(song_ti, False, False, 0)

            length = self.functions.human_length(song.length)
            song_le = Label()
            song_le.set_markup('<span foreground="grey">' + length
                               + '</span>')
            song_le.set_width_chars(5)
            song_btr_content.pack_start(song_le, False, True, 0)

            song_wdg.pack_start(song_btr, False, False, 0)

            song_add = Button.new_from_icon_name('list-add-symbolic', 0)
            song_add.set_property('relief', 2)
            song_add.set_size_request(14, 14)
            song_add.connect('clicked', queue, song)
            song_wdg.pack_start(song_add, False, False, 0)

            if i <= len(album_obj.tracks)/2:
                column = 0
                previous_column = 0
                row = a
            else:
                if previous_column == 0:
                    a = 0
                column = 1
                previous_column = 1
                row = a

            grid_songs.attach(song_wdg, column, row, 1, 1)
        popup.show_all()


    def play(self, usrobject):
        kind = usrobject.kind

        if kind == 'album':
            self.extensions.load_event('OnPlayNewAlbum', usrobject)
        else:
            self.extensions.load_event('OnPlayNewSong', usrobject)

    def queue(self, usrobject):
        kind = usrobject.kind

        if kind == 'album':
            self.extensions.load_event('OnAlbumQueued', usrobject)
        else:
            self.extensions.load_event('OnSongQueued', usrobject)

    def generate_filter_data(self, album_data):
        for element in self.albummodel:
            artist = element[2]
            album = element[3]

            datalb = album_data[artist][album]
            datalb_genre = datalb['genre']
            datalb_year = datalb['year']

            element[5] = datalb_genre
            element[6] = datalb_year

    def add_filter_data(self, value, field):
        self.filter_data[field] = value
        self.albumfilter.refilter()

    def remove_filter_data(self, cmb=None):
        if cmb is None:
            self.filter_data = {'genre': None, 'year': None}
        else:
            self.filter_data[cmb] = None
        self.albumfilter.refilter()
Пример #7
0
class QueuedTorrents(component.Component):
    def __init__(self):
        component.Component.__init__(
            self, 'QueuedTorrents', depend=['StatusBar', 'AddTorrentDialog']
        )
        self.queue = []
        self.status_item = None

        self.config = ConfigManager('gtk3ui.conf')
        self.builder = Builder()
        self.builder.add_from_file(
            deluge.common.resource_filename(
                __package__, os.path.join('glade', 'queuedtorrents.ui')
            )
        )
        self.builder.get_object('chk_autoadd').set_active(self.config['autoadd_queued'])
        self.dialog = self.builder.get_object('queued_torrents_dialog')
        self.dialog.set_icon(get_logo(32))

        self.builder.connect_signals(self)

        self.treeview = self.builder.get_object('treeview')
        self.treeview.append_column(
            TreeViewColumn(_('Torrent'), CellRendererText(), text=0)
        )

        self.liststore = ListStore(str, str)
        self.treeview.set_model(self.liststore)
        self.treeview.set_tooltip_column(1)

    def run(self):
        self.dialog.set_transient_for(component.get('MainWindow').window)
        self.dialog.show()

    def start(self):
        if len(self.queue) == 0:
            return

        # Make sure status bar info is showing
        self.update_status_bar()

        # We only want the add button sensitive if we're connected to a host
        self.builder.get_object('button_add').set_sensitive(True)

        if self.config['autoadd_queued'] or self.config['standalone']:
            self.on_button_add_clicked(None)
        else:
            self.run()

    def stop(self):
        # We only want the add button sensitive if we're connected to a host
        self.builder.get_object('button_add').set_sensitive(False)
        self.update_status_bar()

    def add_to_queue(self, torrents):
        """Adds the list of torrents to the queue"""
        # Add to the queue while removing duplicates
        self.queue = list(set(self.queue + torrents))

        # Update the liststore
        self.liststore.clear()
        for torrent in self.queue:
            if deluge.common.is_magnet(torrent):
                magnet = deluge.common.get_magnet_info(torrent)
                self.liststore.append([magnet['name'], torrent])
            else:
                self.liststore.append([os.path.split(torrent)[1], torrent])

        # Update the status bar
        self.update_status_bar()

    def update_status_bar(self):
        """Attempts to update status bar"""
        # If there are no queued torrents.. remove statusbar widgets and return
        if len(self.queue) == 0:
            if self.status_item is not None:
                component.get('StatusBar').remove_item(self.status_item)
                self.status_item = None
            return False

        try:
            component.get('StatusBar')
        except Exception:
            # The statusbar hasn't been loaded yet, so we'll add a timer to
            # update it later.
            timeout_add(100, self.update_status_bar)
            return False

        # Set the label text for statusbar
        if len(self.queue) > 1:
            label = str(len(self.queue)) + _(' Torrents Queued')
        else:
            label = str(len(self.queue)) + _(' Torrent Queued')

        # Add the statusbar items if needed, or just modify the label if they
        # have already been added.
        if self.status_item is None:
            self.status_item = component.get('StatusBar').add_item(
                icon='view-sort-descending',
                text=label,
                callback=self.on_statusbar_click,
            )
        else:
            self.status_item.set_text(label)

        # We return False so the timer stops
        return False

    def on_statusbar_click(self, widget, event):
        log.debug('on_statusbar_click')
        self.run()

    def on_button_remove_clicked(self, widget):
        selected = self.treeview.get_selection().get_selected()[1]
        if selected is not None:
            path = self.liststore.get_value(selected, 1)
            self.liststore.remove(selected)
            self.queue.remove(path)
            self.update_status_bar()

    def on_button_clear_clicked(self, widget):
        self.liststore.clear()
        del self.queue[:]
        self.update_status_bar()

    def on_button_close_clicked(self, widget):
        self.dialog.hide()

    def on_button_add_clicked(self, widget):
        # Add all the torrents in the liststore
        def add_torrent(model, path, _iter, data):
            torrent_path = deluge.common.decode_bytes(model.get_value(_iter, 1))
            process_args([torrent_path])

        self.liststore.foreach(add_torrent, None)
        del self.queue[:]
        self.dialog.hide()
        self.update_status_bar()

    def on_chk_autoadd_toggled(self, widget):
        self.config['autoadd_queued'] = widget.get_active()
Пример #8
0
def fill_list_store(store: Gtk.ListStore, models: list):
    store.clear()
    for model in models:
        pass
Пример #9
0
class Filter:
    def __init__(self, widgets, aview):
        self.widgets = widgets

        self.functions = Functions()
        self.userconf = ConfigLoader()

        # GUI
        self.filter_button = self.widgets[1].get_object('tool-filter')
        self.filter_button.connect('clicked', self.on_button_clicked)

        gladefile = join(self.functions.datadir, 'glade', 'filterbar.ui')
        self.fbox = gtk_builder()
        self.fbox.set_translation_domain('bluemindo')
        self.fbox.add_from_file(gladefile)
        self.filter_box = self.fbox.get_object('infobar')

        wdg_place = self.widgets[1].get_object('filter-emplacement')
        wdg_place.add(self.filter_box)

        self.fbox.get_object('label_filter').set_text(_('Filter the results:'))

        # Create ComboBoxes
        self.genre_fstore = ListStore(int, str)
        self.genre_fcombo = self.fbox.get_object('combobox-genre')
        self.genre_fcombo.set_model(self.genre_fstore)
        renderer_text = CellRendererText()
        self.genre_fcombo.pack_start(renderer_text, True)
        self.genre_fcombo.set_entry_text_column(1)
        self.genre_fcombo.add_attribute(renderer_text, 'text', 1)

        self.year_fstore = ListStore(int, str)
        self.year_fcombo = self.fbox.get_object('combobox-year')
        self.year_fcombo.set_model(self.year_fstore)
        renderer_text = CellRendererText()
        self.year_fcombo.pack_start(renderer_text, True)
        self.year_fcombo.set_entry_text_column(1)
        self.year_fcombo.add_attribute(renderer_text, 'text', 1)

    def on_button_clicked(self, widget):
        if self.filter_box.props.visible is True:
            self.filter_box.hide()
        else:
            self.filter_box.show_all()

        # Reset filters
        self.genre_fcombo.set_active(0)
        self.year_fcombo.set_active(0)

    def launch(self, albums_tree, songs_tree, aview):
        self.albums_tree = albums_tree
        self.songs_tree = songs_tree
        self.aview = aview

        album_data = {}
        data_genre = []
        data_year = []

        # Gather data
        for item in self.albums_tree:
            item_artist = item['artist']
            item_album = item['album']

            if item_artist not in album_data.keys():
                album_data[item_artist] = {}

            album_data[item_artist][item_album] = {}

            album = Album(item_artist, item_album, self.songs_tree)

            album_genre = ''
            album_year = ''

            for sng in album.tracks:
                if album_genre == '':
                    album_genre = sng.genre

                if album_year == '':
                    album_year = sng.year

            if album_genre != '' and album_genre not in data_genre:
                data_genre.append(album_genre)

            if album_year != '' and album_year not in data_year:
                data_year.append(album_year)

            album_data[item_artist][item_album]['genre'] = album_genre
            album_data[item_artist][item_album]['year'] = album_year

        # Populate combobox
        self.genre_fstore.clear()
        self.genre_fstore.append([-2, _('All genres')])
        self.genre_fstore.append([-1, ''])

        data_genre.sort()
        i = 0
        for genre in data_genre:
            self.genre_fstore.append([i, genre])
            i += 1

        self.year_fstore.clear()
        self.year_fstore.append([-2, _('All years')])
        self.year_fstore.append([-1, ''])

        data_year.sort()
        i = 0
        for year in data_year:
            self.year_fstore.append([i, year])
            i += 1

        def combo_sep(model, iter):
            if model[iter][0] == -1:
                return True

        self.year_fcombo.set_row_separator_func(combo_sep)
        self.genre_fcombo.set_row_separator_func(combo_sep)

        self.aview.generate_filter_data(album_data)

        self.genre_fcombo.connect('changed', self.on_fcombo_changed, 'genre')
        self.year_fcombo.connect('changed', self.on_fcombo_changed, 'year')

        # Hide filters
        self.filter_box.hide()
        self.filter_button.set_active(False)

    def on_fcombo_changed(self, widget, cmb):
        path = widget.get_active()

        try:
            if cmb == 'genre':
                item_value = self.genre_fstore[path][1]
                item_key = self.genre_fstore[path][0]
            else:
                item_value = self.year_fstore[path][1]
                item_key = self.year_fstore[path][0]
        except IndexError:
            item_key = -42

        if item_key >= 0:
            self.aview.add_filter_data(item_value, cmb)
        else:
            self.aview.remove_filter_data(cmb)
Пример #10
0
class Search:
    def __init__(self, widgets, aview):
        self.widgets = widgets

        self.aview = aview
        self.albumview = aview.albumview
        self.albumfilter = aview.albumfilter
        self.matched = aview.matched

        self.functions = Functions()
        self.userconf = ConfigLoader()

        # Create the autocompletion columns
        self.completion_model = ListStore(Pixbuf, str, str, str, str, str, str,
                                          str)
        ecomplet = EntryCompletion()
        ecomplet.set_model(self.completion_model)

        pixbufcell = CellRendererPixbuf()
        ecomplet.pack_start(pixbufcell, False)
        ecomplet.add_attribute(pixbufcell, 'pixbuf', 0)

        markupcell = CellRendererText()
        markupcell.props.xpad = 10
        ecomplet.pack_start(markupcell, True)
        ecomplet.add_attribute(markupcell, 'markup', 1)

        markupcell = CellRendererText()
        markupcell.props.xpad = 5
        ecomplet.pack_start(markupcell, False)
        ecomplet.add_attribute(markupcell, 'markup', 2)

        pixbufcell = CellRendererPixbuf()
        ecomplet.pack_start(pixbufcell, False)
        ecomplet.add_attribute(pixbufcell, 'icon_name', 3)

        ecomplet.props.text_column = 4

        def matched(widget, model, iter):
            item = model[iter]
            data_a = item[4]
            data_b = item[5]

            self.aview.matched = [data_a, data_b]
            self.albumfilter.refilter()

            if data_b == 'blm.!ARTIST!':
                # Matched an artist: show albums
                return False
            elif exists(data_b):
                # Matched a song: queue to playlist
                sng = Song(filename=item[5])
                self.aview.queue(sng)

                # Go back to empty search
                self.aview.matched = False
                searchentry = widget.get_entry()
                searchentry.set_text('')
                return True
            #elif len(self.albumfilter) == 1:
            else:
                # Matched an album: load it in a panel
                album = Album(data_b, data_a, self.songs_tree)
                if hasattr(album, 'name'):
                    self.aview.on_album_matched(album)

                    # Go back to empty search
                    self.aview.matched = False
                    searchentry = widget.get_entry()
                    searchentry.set_text('')
                    return True

        ecomplet.connect('match-selected', matched)

        searchentry = self.widgets[1].get_object('searchentry')
        searchentry.set_completion(ecomplet)
        searchentry.grab_focus()

        def do_filter(widget):
            self.albumfilter.refilter()
            self.aview.matched = False

        searchentry.connect('changed', do_filter)
        self.searchentry = searchentry

    def generate_autocompletion(self, artists, albums, songs_tree):
        self.songs_tree = songs_tree

        albums_without_cover = []
        artists_without_picture = []

        # Launch autocompletion now that the songs tree is generated
        def append_autocompletion(name, kind):
            fnf = join(self.functions.datadir, 'image', 'logo_head_big.png')

            if kind == 1:
                # Artist
                icon = 'face-smile-symbolic'

                pic = join(self.userconf.datadir, 'modules', 'explorer',
                           'artists', self.functions.get_hash(name, 'picture'))

                try:
                    if isfile(pic):
                        pxbf = Pixbuf.new_from_file_at_scale(pic, 70, 70, True)
                    else:
                        pxbf = Pixbuf.new_from_file_at_scale(fnf, 70, 70, True)
                        artists_without_picture.append(name)
                except GLIBError:
                    pxbf = Pixbuf.new_from_file_at_scale(fnf, 70, 70, True)

                dname = '<b>' + self.functions.view_encode(name, 99) + '</b>'

                infos = ('<b>' + _('Artist') + '</b>\n' +
                         _('%s albums in collection.' %
                           ('<b>' + str(len(self.songs_tree[name])) + '</b>')))

                add = 'blm.!ARTIST!'
                add_a = ''
                add_b = ''
            elif kind == 2:
                # Album
                icon = 'media-optical-symbolic'

                artist = name[0]
                name = name[1]

                cover = join(self.userconf.datadir, 'modules', 'player',
                             'covers', self.functions.get_hash(name, artist))
                if isfile(cover):
                    pxbf = Pixbuf.new_from_file_at_scale(cover, 70, 70, True)
                else:
                    pxbf = Pixbuf.new_from_file_at_scale(fnf, 70, 70, True)
                    albums_without_cover.append([artist, name])

                dname = ('<b>' + self.functions.view_encode(name, 99) +
                         '</b>\n<i>' + self.functions.view_encode(artist, 99) +
                         '</i>')

                length = 0
                songs = 0
                for song in self.songs_tree[artist][name]:
                    songs += 1
                    length += song[7]

                hlgth = self.functions.human_length(length)
                infos = (_('%s songs' % ('<b>' + str(songs) + '</b>')) + '\n' +
                         _('Total playing time: %s.' %
                           ('<i>' + hlgth + '</i>')))

                self.cur_pxbf = pxbf

                add = artist
                add_a = ''
                add_b = ''
            elif kind == 3:
                # Song
                icon = 'media-record-symbolic'

                artist = name[1]
                album = name[2]

                add = name[8]
                add_a = artist
                add_b = album

                name = name[0]

                dname = ('<b>' + self.functions.view_encode(name, 99) +
                         '</b>\n<i>' + self.functions.view_encode(artist, 99) +
                         ' - ' + self.functions.view_encode(album, 99) +
                         '</i>')

                infos = '<b>' + _('Song') + '</b>'

                pxbf = self.cur_pxbf

            self.completion_model.append(
                [pxbf, dname, infos, icon, name, add, add_a, add_b])

        self.completion_model.clear()

        for a in artists:
            append_autocompletion(a, 1)

        for a in albums:
            append_autocompletion(a, 2)

            for sng in self.songs_tree[a[0]][a[1]]:
                append_autocompletion(sng, 3)

        # Retrieve album covers
        lastfm = LastFm()
        thread = Thread(group=None,
                        target=lastfm.get_albums_pictures,
                        name='coverart',
                        kwargs={'albums': albums_without_cover})
        thread.start()

        # Retrieve artist pictures
        thread = Thread(group=None,
                        target=lastfm.get_artists_pictures,
                        name='coverart',
                        kwargs={'artists': artists_without_picture})
        thread.start()