Exemple #1
0
    def do_import(self):
        self.running = True

        self.cont = threading.Event()

        self.transcoder.set_format(self.format)
        if self.quality != -1:
            self.transcoder.set_quality(self.quality)
        self.transcoder.end_cb = self._end_cb

        for tr in self.tracks:
            self.cont.clear()
            self.current = tr
            self.current_len = tr.get_tag_raw('__length')
            loc = tr.get_loc_for_io()
            trackno, device = loc[7:].split("/#")
            src = "cdparanoiasrc track=%s device=\"%s\"" % (trackno, device)
            self.transcoder.set_raw_input(src)
            outloc = self.get_output_location(tr)
            self.transcoder.set_output(outloc)
            self.transcoder.start_transcode()
            self.cont.wait()
            if not self.running:
                break
            tr2 = trax.Track("file://" + outloc)
            for t in tr.list_tags():
                if not t.startswith("__"):
                    tr2.set_tag_raw(t, tr.get_tag_raw(t))
            tr2.write_tags()
            try:
                incr = tr.get_tag_raw('__length') / self.duration
                self.progress += incr
            except Exception:
                raise
        self.progress = 100.0
Exemple #2
0
    def _parse_podcast(self, url, add_to_db=False):
        try:
            url = url.replace('itpc://', 'http://')

            self._set_status(_('Loading %s...') % url)
            d = fp.parse(url)
            entries = d['entries']

            title = d['feed']['title']

            if add_to_db:
                self._add_to_db(url, title)

            pl = playlist.Playlist(md5(url).hexdigest())

            tracks = []
            for e in entries:
                for link in e.get('enclosures', []):
                    tr = trax.Track(link.href)
                    date = e['updated_parsed']
                    tr.set_tag_raw('artist', title)
                    tr.set_tag_raw('title', '%s: %s' % (e['title'], link.href.split('/')[-1]))
                    tr.set_tag_raw('date', "%d-%02d-%02d" %
                            (date.tm_year, date.tm_mon, date.tm_mday))
                    tracks.append(tr)

            pl.extend(tracks)
            self._set_status('')

            self._open_podcast(pl, title)
            self.podcast_playlists.save_playlist(pl, overwrite=True)
        except:
            traceback.print_exc()
            self._set_status(_('Error loading podcast.'), 2)
Exemple #3
0
    def open_disc(self):

        toc = CDTocParser(self.device)
        lengths = toc.get_track_lengths()

        songs = {}

        for count, length in enumerate(lengths):
            count += 1
            song = trax.Track("cdda://%d/#%s" % (count, self.device))
            song.set_tag_raw('title', "Track %d" % count)
            song.set_tag_raw('tracknumber', str(count))
            song.set_tag_raw('__length', length)
            songs[song.get_loc_for_io()] = song

        # FIXME: this can probably be cleaner
        sort_tups = [ (int(s.get_tag_raw('tracknumber')[0]),s) \
                for s in songs.values() ]
        sort_tups.sort()
        sorted = [s[1] for s in sort_tups]

        self.extend(sorted)

        if CDDB_AVAIL:
            self.get_cddb_info()
Exemple #4
0
    def update_track(self, gloc, force_update=False):
        """
            Rescan the track at a given location

            :param gloc: the location
            :type gloc: :class:`Gio.File`
            :param force_update: Force update of file (default only updates file
                                 when mtime has changed)

            returns: the Track object, None if it could not be updated
        """
        uri = gloc.get_uri()
        if not uri:  # we get segfaults if this check is removed
            return None
        mtime = gloc.query_info("time::modified", Gio.FileQueryInfoFlags.NONE,
                                None).get_modification_time()
        mtime = mtime.tv_sec + (mtime.tv_usec / 100000.0)
        tr = self.collection.get_track_by_loc(uri)
        if tr:
            if force_update or tr.get_tag_raw('__modified') < mtime:
                tr.read_tags()
                tr.set_tag_raw('__modified', mtime)
        else:
            tr = trax.Track(uri)
            if tr._scan_valid == True:
                tr.set_tag_raw('__date_added', time.time())
                self.collection.add(tr)
                tr.set_tag_raw('__modified', mtime)

            # Track already existed. This fixes trax.get_tracks_from_uri
            # on windows, unknown why fix isnt needed on linux.
            elif not tr._init:
                self.collection.add(tr)
        return tr
Exemple #5
0
    def update_track(self,
                     gloc: Gio.File,
                     force_update: bool = False) -> Optional[trax.Track]:
        """
        Rescan the track at a given location

        :param gloc: the location
        :type gloc: :class:`Gio.File`
        :param force_update: Force update of file (default only updates file
                             when mtime has changed)

        returns: the Track object, None if it could not be updated
        """
        uri = gloc.get_uri()
        if not uri:  # we get segfaults if this check is removed
            return None

        tr = self.collection.get_track_by_loc(uri)
        if tr:
            tr.read_tags(force=force_update)
        else:
            tr = trax.Track(uri)
            if tr._scan_valid:
                self.collection.add(tr)

            # Track already existed. This fixes trax.get_tracks_from_uri
            # on windows, unknown why fix isnt needed on linux.
            elif not tr._init:
                self.collection.add(tr)
        return tr
Exemple #6
0
    def add_to_playlist(self, widget, start_editing=None, wget=False):
        playlist_handle = self.play.get_selected_playlist().playlist
        model, mysel = self.tw.get_selection().get_selected_rows()
        myTrack = []
        for i in mysel:
            tr = trax.Track(self.comp[i[0]]["mp3"])
            tr.set_tag_raw("artist", self.comp[i[0]]["artist"])
            tr.set_tag_raw("title", self.comp[i[0]]["track"])
            tr.set_tag_raw("album", "Vkontakte.ru")
            myTrack.append(tr)
        if not wget:
            playlist_handle.add_tracks(myTrack, None)
        else:
            for i in mysel:
                path = settings.get_option("vk_exaile/path", os.getenv("HOME"))
                if path.strip() == "":
                    settings.set_option("vk_exaile/path", os.getenv("HOME"))
                    path = os.getenv("HOME")
                elif not os.path.exists(path.strip()):
                    os.system("mkdir '%s'" % path.strip())

                res = os.system(
                    'wget -b -O "%s/%s - %s.mp3" %s -o /dev/null' %
                    (path, self.comp[i[0]]["artist"], self.comp[i[0]]["track"],
                     self.comp[i[0]]["mp3"]))
Exemple #7
0
    def on_location_changed(self, monitor, gfile, other_gfile, event):
        """
            Updates the library on changes of the location
        """

        if event == Gio.FileMonitorEvent.CHANGES_DONE_HINT:
            self.__process_change_queue(gfile)
        elif event == Gio.FileMonitorEvent.CREATED or \
                event == Gio.FileMonitorEvent.CHANGED:

            # Enqueue tracks retrieval
            if gfile not in self.__queue:
                self.__queue[gfile] = True

                # File monitor only emits the DONE_HINT when using inotify,
                # and only on single files. Give it some time, but don't
                # lose the change notification
                GLib.timeout_add(500, self.__process_change_queue, gfile)

            # Set up new monitor if directory
            fileinfo = gfile.query_info('standard::type', Gio.FileQueryInfoFlags.NONE, None)

            if fileinfo.get_file_type() == Gio.FileType.DIRECTORY and \
               gfile not in self.__monitors:

                for directory in common.walk_directories(gfile):
                    monitor = directory.monitor_directory(Gio.FileMonitorFlags.NONE, None)
                    monitor.connect('changed', self.on_location_changed)
                    self.__monitors[directory] = monitor

                    self.emit('location-added', directory)

        elif event == Gio.FileMonitorEvent.DELETED:
            removed_tracks = []

            track = trax.Track(gfile.get_uri())

            if track in self.__library.collection:
                # Deleted file was a regular track
                removed_tracks += [track]
            else:
                # Deleted file was most likely a directory
                for track in self.__library.collection:
                    track_gfile = Gio.File.new_for_uri(track.get_loc_for_io())

                    if track_gfile.has_prefix(gfile):
                        removed_tracks += [track]

            self.__library.collection.remove_tracks(removed_tracks)

            # Remove obsolete monitors
            removed_directories = [d for d in self.__monitors
                                   if d == gfile or d.has_prefix(gfile)]

            for directory in removed_directories:
                self.__monitors[directory].cancel()
                del self.__monitors[directory]

                self.emit('location-removed', directory)
Exemple #8
0
def _migrate_old_tracks(oldsettings, db, ntdb):
    libraries = eval(oldsettings.get('DEFAULT', 'search_paths'))

    oldtracks = oldexailelib.load_tracks(db)
    rating_steps = 5  # old dbs are hardcoded to 5 steps

    for library in libraries:
        ntdb.add_library(collection.Library(library))

    newtracks = []
    for oldtrack in oldtracks:
        # we shouldn't be checking os.path.isfile() here, since if it is a radio link, it will not be migrated
        newtrack = trax.Track(uri=oldtrack.loc, scan=False)

        if oldtrack._rating:  # filter '' and 0
            oldtrack._rating = max(0, oldtrack._rating)
            oldtrack._rating = min(oldtrack._rating, rating_steps)
            newtrack.set_tag_raw(
                '__rating', float((100.0 * oldtrack._rating) / rating_steps))

        db_map = {
            'artist': 'artist',
            'album': 'album',
            'track': 'tracknumber',
            'genre': 'genre',
            'date': 'date',
            'title': 'title',
            'playcount': '__playcount'
        }

        newtrack.set_tag_raw('__length', int(getattr(oldtrack, 'duration')))

        # Apparently, there is a bug in exaile 0.2.xx that dumps the time as hh:mm:YYYY, rather than hh:mm:ss. This is a workaround, that takes the seconds == 0, since this information is lost b/c of the bug
        temp_time = oldtrack.time_added

        try:
            newtrack.set_tag_raw(
                '__date_added',
                time.mktime(
                    time.strptime(temp_time[0:len(temp_time) - 5],
                                  '%Y-%m-%d %H:%M')))
        except ValueError:
            try:
                newtrack.set_tag_raw(
                    '__date_added',
                    time.mktime(
                        time.strptime(temp_time[0:len(temp_time) - 3],
                                      '%Y-%m-%d %H:%M')))
            except ValueError:
                pass

        for item in db_map.keys():
            newtrack.set_tag_raw(db_map[item], getattr(oldtrack, item))

        newtrack._dirty = True
        newtracks.append(newtrack)

    ntdb.add_tracks(newtracks)
    ntdb.save_to_location()
Exemple #9
0
 def generate_tracks(self, chapters):
     tracks = []
     for chapter in chapters:
         chapter_track = trax.Track(chapter[1])
         chapter_track.set_tag_raw('artist', 'Librivox.org')
         chapter_track.set_tag_raw('title', chapter[0])
         chapter_track.set_tag_raw('album', 'Audiobook')
         tracks.append(chapter_track)
     return tracks
Exemple #10
0
 def get_track(self, f):
     """
         Returns a single track from a Gio.File
     """
     uri = f.get_uri()
     if not trax.is_valid_track(uri):
         return None
     tr = trax.Track(uri)
     return tr
Exemple #11
0
 def generate_tracks(self, chapters):
     tracks = []
     for chapter in chapters:
         chapter_track = trax.Track(chapter[1])
         chapter_track.set_tags(artist='Librivox.org',
                                title=chapter[0],
                                album='Audiobook')
         tracks.append(chapter_track)
     return tracks
Exemple #12
0
    def get_cover_data(self, db_string):
        tag, index, uri = db_string.split(':', 2)
        track = trax.Track(uri, scan=False)
        covers = track.get_tag_disk(tag)

        if not covers:
            return None

        return covers[int(index)].data
Exemple #13
0
 def add_tracks_to_playlist(self, track_list):
     # convert list to list of xl.Track objects as opposed to jamtree.Track objects
     xltrack_list = []
     for track in track_list:
         tr = xltrack.Track(track.url, scan=False)
         tr.set_tags(title=track.name,
                     artist=track.artist_name,
                     album=track.album_name)
         xltrack_list.append(tr)
     self.exaile.gui.main.get_selected_page().playlist.extend(xltrack_list)
Exemple #14
0
    def convert_list(self):
        """
            Converts the DAAP track database into Exaile Tracks.
        """
        # Convert DAAPTrack's attributes to Tracks.
        eqiv = {
            'title': 'minm',
            'artist': 'asar',
            'album': 'asal',
            'tracknumber': 'astn',
            'date': 'asyr',
            'discnumber': 'asdn',
            'albumartist': 'asaa',
        }
        #            'genre':'asgn','enc':'asfm','bitrate':'asbr'}

        for tr in self.tracks:
            if tr is not None:
                # http://<server>:<port>/databases/<dbid>/items/<id>.<type>?session-id=<sessionid>

                uri = "http://%s:%s/databases/%s/items/%s.%s?session-id=%s" % (
                    self.server,
                    self.port,
                    self.database.id,
                    tr.id,
                    tr.type,
                    self.session.sessionid,
                )

                # Don't scan tracks because gio is slow!
                temp = trax.Track(uri, scan=False)

                for field in eqiv.keys():
                    try:
                        tag = '%s' % tr.atom.getAtom(eqiv[field])
                        if tag != 'None':
                            temp.set_tag_raw(field, [tag],
                                             notify_changed=False)

                    except Exception:
                        if field == 'tracknumber':
                            temp.set_tag_raw('tracknumber', [0],
                                             notify_changed=False)

                # TODO: convert year (asyr) here as well, what's the formula?
                try:
                    temp.set_tag_raw(
                        "__length",
                        tr.atom.getAtom('astm') // 1000,
                        notify_changed=False,
                    )
                except Exception:
                    temp.set_tag_raw("__length", 0, notify_changed=False)

                self.all.append(temp)
Exemple #15
0
    def display_bookmark(self, key, pos):
        """
            Create menu entrees for this bookmark.
        """
        pix = None
        # add menu item
        try:
            item = trax.Track(key)
            title = item.get_tag_display('title')
            if self.use_covers:
                image = covers.MANAGER.get_cover(item, set_only=True)
                if image:
                    try:
                        pix = icons.MANAGER.pixbuf_from_data(image,
                                                             size=(16, 16))
                    except GLib.GError:
                        logger.warn('Could not load cover')
                        pix = None
                        # no cover
                else:
                    pix = None
        except Exception:
            logger.exception("Cannot open %s", key)
            # delete offending key?
            return
        time = '%d:%02d' % (pos / 60, pos % 60)
        label = '%s @ %s' % (title, time)

        counter = self.counter  # closure magic (workaround for factories not having access to item)

        # factory for new bookmarks
        def factory(menu_, parent, context):
            menu_item = Gtk.ImageMenuItem.new_with_mnemonic(label)
            if pix:
                menu_item.set_image(Gtk.image_new_from_pixbuf(pix))

            if menu_ is self.menu:
                menu_item.connect('activate', self.do_bookmark, (key, pos))
            else:
                menu_item.connect('activate', self.delete_bookmark,
                                  (counter, key, pos))

            return menu_item

        item = menu.MenuItem('bookmark{0}'.format(self.counter), factory,
                             ['sep'])
        self.menu.add_item(item)
        self.delete_menu.add_item(item)

        self.counter += 1

        # save addition
        self.save_db()
Exemple #16
0
 def __on_bookmark_activated(self, _widget):
     """
         This is called to resume a bookmark.
     """
     # check if it's already playing
     track = player.PLAYER.current
     if track and track.get_loc_for_io() == self.__path:
         player.PLAYER.unpause()
         player.PLAYER.seek(self.__time)
     else:
         # play it using the QUEUE
         track = trax.Track(self.__path)
         if track:  # make sure we got one
             player.QUEUE.play(track)
             player.PLAYER.seek(self.__time)
Exemple #17
0
    def add(self, loc: str, move: bool = False) -> None:
        """
        Copies (or moves) a file into the library and adds it to the
        collection
        """
        oldgloc = Gio.File.new_for_uri(loc)

        newgloc = Gio.File.new_for_uri(self.location).resolve_relative_path(
            oldgloc.get_basename())

        if move:
            oldgloc.move(newgloc)
        else:
            oldgloc.copy(newgloc)
        tr = trax.Track(newgloc.get_uri())
        if tr._scan_valid:
            self.collection.add(tr)
Exemple #18
0
    def open_disc(self):

        toc = CDTocParser(self.__device)
        lengths = toc._get_track_lengths()

        songs = []

        for count, length in enumerate(lengths):
            count += 1
            song = trax.Track("cdda://%d/#%s" % (count, self.__device))
            song.set_tags(
                title="Track %d" % count, tracknumber=str(count), __length=length
            )
            songs.append(song)

        self.extend(songs)

        if CDDB_AVAIL:
            self.get_cddb_info()
Exemple #19
0
    def _handle_unknown_drag_data(self, loc):
        """
            Handles unknown drag data that has been recieved by
            drag_data_received.  Unknown drag data is classified as
            any loc (location) that is not in the collection of tracks
            (i.e. a new song, or a new playlist)

            @param loc:
                the location of the unknown drag data

            @returns: a 2 tuple in which the first part is a list of tracks
                and the second is a list of playlist
        """
        filetype = None
        info = urlparse.urlparse(loc)

        # don't use gio to test the filetype if it's a non-local file
        # (otherwise gio will try to connect to every remote url passed in and
        # cause the gui to hang)
        if info.scheme in ('file', ''):
            try:
                filetype = (
                    Gio.File.new_for_uri(loc)
                    .query_info('standard::type', Gio.FileQueryInfoFlags.NONE, None)
                    .get_file_type()
                )
            except GLib.Error:
                filetype = None

        if trax.is_valid_track(loc) or info.scheme not in ('file', ''):
            new_track = trax.Track(loc)
            return ([new_track], [])
        elif xl_playlist.is_valid_playlist(loc):
            # User is dragging a playlist into the playlist list
            # so we add all of the songs in the playlist
            # to the list
            new_playlist = xl_playlist.import_playlist(loc)
            return ([], [new_playlist])
        elif filetype == Gio.FileType.DIRECTORY:
            return (trax.get_tracks_from_uri(loc), [])
        else:  # We don't know what they dropped
            return ([], [])
Exemple #20
0
    def do_bookmark(self, widget, data):
        """
            This is called to resume a bookmark.
        """
        key, pos = data
        exaile = self.exaile

        if not (key and pos):
            return

        # check if it's already playing
        track = player.PLAYER.current
        if track and track.get_loc_for_io() == key:
            player.PLAYER.unpause()
            player.PLAYER.seek(pos)
            return
        else:
            # play it using the QUEUE
            track = trax.Track(key)
            if track:  # make sure we got one
                player.QUEUE.play(track)
                player.PLAYER.seek(pos)
Exemple #21
0
    def __fetch_metadata(self, *_args):
        # "gtk-menu-images" is deprecated and is being ignored on most
        # platforms. On GNOME/Wayland it can be enabled by editing
        # ~/.config/gtk-3.0/settings.ini and adding `gtk-menu-images=1`.
        use_covers = Gtk.Settings.get_default().props.gtk_menu_images

        try:
            item = trax.Track(self.__path)
            if not self.__title:
                self.__title = item.get_tag_display('title')
            if use_covers:
                image = covers.MANAGER.get_cover(item, set_only=True)
                if image:
                    try:
                        self.__cover_pixbuf = pixbuf_from_data(image,
                                                               size=(16, 16))
                    except GLib.GError:
                        LOGGER.warning('Could not load cover')
            else:
                self.__cover_pixbuf = None
        except Exception:
            LOGGER.exception("Cannot open %s", self.__path)
            return
Exemple #22
0
 def get_playlist(self):
     tr = trax.Track()
     tr['title'] = 'Test Track'
     pl = playlist.Playlist('Test Playlist')
     pl.add_tracks([tr])
     return pl