Example #1
0
    def run(self):
        args = self.args

        # start event loop
        self.event_loop.start()

        # login
        print("Logging in...")
        if args.last:
            self.login_as_last()
        elif args.user is not None and args.password is None:
            password = getpass.getpass()
            self.login(args.user[0], password)
        else:
            self.login(args.user[0], args.password[0])

        if not self.login_success:
            print(Fore.RED + "Encountered issue while logging into "
                  "Spotify, aborting..." + Fore.RESET)
            self.stop_event_loop()
            self.finished.set()
            return

        # check if we were passed a file name or search
        if len(args.uri) == 1 and os.path.exists(args.uri[0]):
            uris = [line.strip() for line in open(args.uri[0])]
        elif len(args.uri) == 1 and not args.uri[0].startswith("spotify:"):
            uris = [list(self.search_query(args.uri[0]))]
        else:
            uris = args.uri

        def get_tracks_from_uri(uri):
            if isinstance(uri, list):
                return uri
            else:
                if (args.exclude_appears_on
                        and uri.startswith("spotify:artist:")):
                    album_uris = self.load_artist_albums(uri)
                    return itertools.chain(*[
                        self.load_link(album_uri) for album_uri in album_uris
                    ])
                else:
                    return self.load_link(uri)

        # calculate total size and time
        all_tracks = []
        for uri in uris:
            tracks = get_tracks_from_uri(uri)
            all_tracks += list(tracks)

        self.progress.calc_total(all_tracks)

        if self.progress.total_size > 0:
            print("Total Download Size: " +
                  format_size(self.progress.total_size))

        # create track iterator
        for uri in uris:
            if self.abort.is_set():
                break

            tracks = list(get_tracks_from_uri(uri))

            if args.flat_with_index and self.current_playlist:
                self.idx_digits = len(str(len(self.current_playlist.tracks)))

            if args.playlist_sync and self.current_playlist:
                self.sync = Sync(args, self)
                self.sync.sync_playlist(self.current_playlist)

            # ripping loop
            for idx, track in enumerate(tracks):
                try:
                    if self.abort.is_set():
                        break

                    print('Loading track...')
                    track.load()
                    if track.availability != 1:
                        print(Fore.RED + 'Track is not available, '
                              'skipping...' + Fore.RESET)
                        self.post.log_failure(track)
                        continue

                    self.audio_file = self.format_track_path(idx, track)

                    if not args.overwrite and os.path.exists(self.audio_file):
                        print(Fore.YELLOW + "Skipping " + track.link.uri +
                              Fore.RESET)
                        print(Fore.CYAN + self.audio_file + Fore.RESET)
                        self.post.queue_remove_from_playlist(idx)
                        continue

                    self.session.player.load(track)
                    self.prepare_rip(idx, track)
                    self.session.player.play()

                    while not self.end_of_track.is_set() or \
                            not self.rip_queue.empty():
                        try:
                            if self.abort.is_set():
                                break

                            rip_item = self.rip_queue.get(timeout=1)
                            self.rip(self.session, rip_item[0], rip_item[1],
                                     rip_item[2])
                        except queue.Empty:
                            pass

                    if self.abort.is_set():
                        self.session.player.play(False)
                        self.end_of_track.set()
                        self.post.clean_up_partial()
                        self.post.log_failure(track)
                        break

                    self.end_of_track.clear()

                    self.finish_rip(track)

                    # update id3v2 with metadata and embed front cover image
                    set_metadata_tags(args, self.audio_file, track)

                    # make a note of the index and remove all the
                    # tracks from the playlist when everything is done
                    self.post.queue_remove_from_playlist(idx)

                except (spotify.Error, Exception) as e:
                    if isinstance(e, Exception):
                        print(Fore.RED + "Spotify error detected" + Fore.RESET)
                    print(str(e))
                    print("Skipping to next track...")
                    self.session.player.play(False)
                    self.post.clean_up_partial()
                    self.post.log_failure(track)
                    continue

            if not self.abort.is_set():
                # create playlist m3u file if needed
                self.post.create_playlist_m3u(tracks)

                # create playlist wpl file if needed
                self.post.create_playlist_wpl(tracks)

                # actually removing the tracks from playlist
                self.post.remove_tracks_from_playlist()

        # logout, we are done
        self.post.end_failure_log()
        self.post.print_summary()
        self.logout()
        self.stop_event_loop()
        self.finished.set()
Example #2
0
    def run(self):
        args = self.args

        # start event loop
        self.event_loop.start()

        # login
        print("Logging in...")
        if args.last:
            self.login_as_last()
        elif args.user is not None and args.password is None:
            password = getpass.getpass()
            self.login(args.user[0], password)
        else:
            self.login(args.user[0], args.password[0])

        if not self.login_success:
            print(
                Fore.RED + "Encountered issue while logging into "
                           "Spotify, aborting..." + Fore.RESET)
            self.stop_event_loop()
            self.finished.set()
            return

        # check if we were passed a file name or search
        if len(args.uri) == 1 and os.path.exists(args.uri[0]):
            uris = [line.strip() for line in open(args.uri[0])]
        elif len(args.uri) == 1 and not args.uri[0].startswith("spotify:"):
            uris = [list(self.search_query(args.uri[0]))]
        else:
            uris = args.uri

        def get_tracks_from_uri(uri):
            if isinstance(uri, list):
                return uri
            else:
                if (args.exclude_appears_on and
                        uri.startswith("spotify:artist:")):
                    album_uris = self.load_artist_albums(uri)
                    return itertools.chain(
                        *[self.load_link(album_uri) for
                          album_uri in album_uris])
                else:
                    return self.load_link(uri)

        # calculate total size and time
        all_tracks = []
        for uri in uris:
            tracks = get_tracks_from_uri(uri)
            all_tracks += list(tracks)

        self.progress.calc_total(all_tracks)

        if self.progress.total_size > 0:
            print(
                "Total Download Size: " +
                format_size(self.progress.total_size))

        # create track iterator
        for uri in uris:
            if self.abort.is_set():
                break

            tracks = list(get_tracks_from_uri(uri))

            if args.flat_with_index and self.current_playlist:
                self.idx_digits = len(str(len(self.current_playlist.tracks)))

            if args.playlist_sync and self.current_playlist:
                self.sync = Sync(args, self)
                self.sync.sync_playlist(self.current_playlist)

            # ripping loop
            for idx, track in enumerate(tracks):
                try:
                    if self.abort.is_set():
                        break

                    print('Loading track...')
                    track.load()
                    if track.availability != 1:
                        print(
                            Fore.RED + 'Track is not available, '
                                       'skipping...' + Fore.RESET)
                        self.post.log_failure(track)
                        continue

                    self.audio_file = self.format_track_path(idx, track)

                    if not args.overwrite and os.path.exists(self.audio_file):
                        print(
                            Fore.YELLOW + "Skipping " +
                            track.link.uri + Fore.RESET)
                        print(Fore.CYAN + self.audio_file + Fore.RESET)
                        self.post.queue_remove_from_playlist(idx)
                        continue

                    self.session.player.load(track)
                    self.prepare_rip(idx, track)
                    self.session.player.play()

                    while not self.end_of_track.is_set() or \
                            not self.rip_queue.empty():
                        try:
                            if self.abort.is_set():
                                break

                            rip_item = self.rip_queue.get(timeout=1)
                            self.rip(self.session, rip_item[0],
                                     rip_item[1], rip_item[2])
                        except queue.Empty:
                            pass

                    if self.abort.is_set():
                        self.session.player.play(False)
                        self.end_of_track.set()
                        self.post.clean_up_partial()
                        self.post.log_failure(track)
                        break

                    self.end_of_track.clear()

                    self.finish_rip(track)

                    # update id3v2 with metadata and embed front cover image
                    set_metadata_tags(args, self.audio_file, track)

                    # make a note of the index and remove all the
                    # tracks from the playlist when everything is done
                    self.post.queue_remove_from_playlist(idx)

                except (spotify.Error, Exception) as e:
                    if isinstance(e, Exception):
                        print(Fore.RED + "Spotify error detected" + Fore.RESET)
                    print(str(e))
                    print("Skipping to next track...")
                    self.session.player.play(False)
                    self.post.clean_up_partial()
                    self.post.log_failure(track)
                    continue

            if not self.abort.is_set():
                # create playlist m3u file if needed
                self.post.create_playlist_m3u(tracks)

                # create playlist wpl file if needed
                self.post.create_playlist_wpl(tracks)

                # actually removing the tracks from playlist
                self.post.remove_tracks_from_playlist()

        # logout, we are done
        self.post.end_failure_log()
        self.post.print_summary()
        self.logout()
        self.stop_event_loop()
        self.finished.set()
Example #3
0
    def run(self):
        args = self.args

        # start event loop
        self.event_loop.start()

        # wait for main thread to login
        self.ripper_continue.wait()
        if self.abort.is_set():
            return
        #set session to provate
        self.session.social.private_session = True

        # list of spotify URIs
        uris = args.uri

        def get_tracks_from_uri(uri):
            self.current_playlist = None
            self.current_album = None
            self.current_chart = None

            if isinstance(uri, list):
                return uri
            else:
                if (uri.startswith("spotify:artist:")
                        and (args.artist_album_type is not None
                             or args.artist_album_market is not None)):
                    album_uris = self.web.get_albums_with_filter(uri)
                    return itertools.chain(*[
                        self.load_link(album_uri) for album_uri in album_uris
                    ])
                elif uri.startswith("spotify:charts:"):
                    charts = self.web.get_charts(uri)
                    if charts is not None:
                        self.current_chart = charts
                        chart_uris = charts["tracks"]
                        return itertools.chain(*[
                            self.load_link(chart_uri)
                            for chart_uri in chart_uris
                        ])
                    else:
                        return iter([])
                else:
                    return self.load_link(uri)

        # calculate total size and time
        all_tracks = []
        for uri in uris:
            tracks = list(get_tracks_from_uri(uri))

            # TODO: remove dependency on current_album, ...
            for idx, track in enumerate(tracks):

                # ignore local tracks
                if track.is_local:
                    continue

                audio_file = self.format_track_path(idx, track)
                all_tracks.append((track, audio_file))

        self.progress.calc_total(all_tracks)

        if self.progress.total_size > 0:
            print("Total Download Size: " +
                  format_size(self.progress.total_size))

        # create track iterator
        for uri in uris:
            if self.abort.is_set():
                break

            tracks = list(get_tracks_from_uri(uri))

            if args.playlist_sync and self.current_playlist:
                self.sync = Sync(args, self)
                self.sync.sync_playlist(self.current_playlist)

            # ripping loop
            for idx, track in enumerate(tracks):
                try:
                    self.check_stop_time()
                    self.skip.clear()

                    if self.abort.is_set():
                        break

                    print('Loading track...')
                    track.load(args.timeout)
                    if track.availability != 1 or track.is_local:
                        print(Fore.RED + 'Track is not available, '
                              'skipping...' + Fore.RESET)
                        self.post.log_failure(track)
                        continue

                    self.audio_file = self.format_track_path(idx, track)

                    if not args.overwrite and path_exists(self.audio_file):
                        if is_partial(self.audio_file, track):
                            print("Overwriting partial file")
                        else:
                            print(Fore.YELLOW + "Skipping " + track.link.uri +
                                  Fore.RESET)
                            print(Fore.CYAN + self.audio_file + Fore.RESET)
                            continue

                    self.session.player.load(track)
                    self.prepare_rip(idx, track)
                    self.session.player.play()

                    timeout_count = 0
                    while not self.end_of_track.is_set() or \
                            not self.rip_queue.empty():
                        try:
                            if self.abort.is_set() or self.skip.is_set():
                                break

                            rip_item = self.rip_queue.get(timeout=1)

                            if self.abort.is_set() or self.skip.is_set():
                                break

                            self.rip(self.session, rip_item[0], rip_item[1],
                                     rip_item[2])
                        except queue.Empty:
                            timeout_count += 1
                            if timeout_count > 60:
                                raise spotify.Error("Timeout while "
                                                    "ripping track")

                    if self.skip.is_set():
                        extra_line = "" if self.play_token_resume.is_set() \
                                        else "\n"
                        print(extra_line + Fore.YELLOW +
                              "User skipped track... " + Fore.RESET)
                        self.session.player.play(False)
                        self.post.clean_up_partial()
                        self.post.log_failure(track)
                        self.end_of_track.clear()
                        self.progress.end_track(show_end=False)
                        self.ripping.clear()
                        continue

                    if self.abort.is_set():
                        self.session.player.play(False)
                        self.end_of_track.set()
                        self.post.clean_up_partial()
                        self.post.log_failure(track)
                        break

                    self.end_of_track.clear()

                    self.finish_rip(track)

                    # update id3v2 with metadata and embed front cover image
                    set_metadata_tags(args, self.audio_file, idx, track, self)

                    # finally log success
                    self.post.log_success(track)

                except (spotify.Error, Exception) as e:
                    if isinstance(e, Exception):
                        print(Fore.RED + "Spotify error detected" + Fore.RESET)
                    print(str(e))
                    traceback.print_exc()
                    print("Skipping to next track...")
                    self.session.player.play(False)
                    self.post.clean_up_partial()
                    self.post.log_failure(track)
                    continue

            # create playlist m3u file if needed
            self.post.create_playlist_m3u(tracks)

            # create playlist wpl file if needed
            self.post.create_playlist_wpl(tracks)

            # remove libspotify's offline storage cache
            self.post.remove_offline_cache()

        # logout, we are done
        self.post.end_failure_log()
        self.post.print_summary()
        self.logout()
        self.stop_event_loop()
        self.finished.set()
        sys.exit()
Example #4
0
    def run(self):
        args = self.args

        # login
        print("Logging in...")
        if args.last:
            self.login_as_last()
        elif args.user != None and args.password == None:
            password = getpass.getpass()
            self.login(args.user[0], password)
        else:
            self.login(args.user[0], args.password[0])

        if not self.login_success:
            print(Fore.RED + "Encountered issue while logging into Spotify, aborting..." + Fore.RESET)
            self.finished = True
            return

        # create track iterator
        for uri in args.uri:
            if os.path.exists(uri):
                tracks = itertools.chain(*[self.load_link(line.strip()) for line in open(uri)])
            elif uri.startswith("spotify:"):
                if args.exclude_appears_on and uri.startswith("spotify:artist:"):
                    album_uris = self.load_artist_albums(uri)
                    tracks = itertools.chain(*[self.load_link(album_uri) for album_uri in album_uris])
                else:
                    tracks = self.load_link(uri)
            else:
                tracks = self.search_query(uri)

            if args.flat_with_index and self.current_playlist:
                self.idx_digits = len(str(len(self.current_playlist.tracks)))

            tracks = list(tracks)
            self.progress.calc_total(tracks)

            if self.progress.total_size > 0:
                print("Total Download Size: " + format_size(self.progress.total_size))

            # ripping loop
            for idx, track in enumerate(tracks):
                try:
                    print('Loading track...')
                    track.load()
                    if track.availability != 1:
                        print(Fore.RED + 'Track is not available, skipping...' + Fore.RESET)
                        continue

                    self.audio_file = self.track_path(idx, track)

                    if not args.overwrite and os.path.exists(self.audio_file):
                        print(Fore.YELLOW + "Skipping " + track.link.uri + Fore.RESET)
                        print(Fore.CYAN + self.audio_file + Fore.RESET)
                        self.queue_remove_from_playlist(idx)
                        continue

                    self.session.player.load(track)
                    self.prepare_rip(idx, track)
                    self.session.player.play()

                    self.end_of_track.wait()
                    self.end_of_track.clear()

                    self.finish_rip(track)

                    # update id3v2 with metadata and embed front cover image
                    set_metadata_tags(args, self.audio_file, track)

                    # make a note of the index and remove all the
                    # tracks from the playlist when everything is done
                    self.queue_remove_from_playlist(idx)

                except spotify.Error as e:
                    print(Fore.RED + "Spotify error detected" + Fore.RESET)
                    print(str(e))
                    print("Skipping to next track...")
                    self.session.player.play(False)
                    self.clean_up_partial()
                    continue

            # actually removing the tracks from playlist
            self.remove_tracks_from_playlist()

        # logout, we are done
        self.logout()
        self.finished = True
Example #5
0
    def run(self):
        args = self.args

        # start event loop
        self.event_loop.start()

        # wait for main thread to login
        self.ripper_continue.wait()
        if self.abort.is_set():
            return

        # check if we were passed a file name or search
        if len(args.uri) == 1 and path_exists(args.uri[0]):
            uris = [line.strip() for line in open(args.uri[0])]
        elif len(args.uri) == 1 and not args.uri[0].startswith("spotify:"):
            uris = [list(self.search_query(args.uri[0]))]
        else:
            uris = args.uri

        def get_tracks_from_uri(uri):
            current_playlist = None
            current_album = None
            current_chart = None

            if isinstance(uri, list):
                return uri
            else:
                if (args.exclude_appears_on
                        and uri.startswith("spotify:artist:")):
                    album_uris = self.web.get_non_appears_on_albums(uri)
                    return itertools.chain(*[
                        self.load_link(album_uri) for album_uri in album_uris
                    ])
                elif uri.startswith("spotify:charts:"):
                    charts = self.web.get_charts(uri)
                    if charts is not None:
                        self.current_chart = charts
                        chart_uris = [
                            t["track"]["uri"]
                            for t in charts["entries"]["items"]
                        ]
                        return itertools.chain(*[
                            self.load_link(chart_uri)
                            for chart_uri in chart_uris
                        ])
                    else:
                        return iter([])
                else:
                    return self.load_link(uri)

        # calculate total size and time
        all_tracks = []
        for uri in uris:
            tracks = get_tracks_from_uri(uri)
            all_tracks += list(tracks)

        self.progress.calc_total(all_tracks)

        if self.progress.total_size > 0:
            print("Total Download Size: " +
                  format_size(self.progress.total_size))

        # create track iterator
        for uri in uris:
            if self.abort.is_set():
                break

            tracks = list(get_tracks_from_uri(uri))

            if args.playlist_sync and self.current_playlist:
                self.sync = Sync(args, self)
                self.sync.sync_playlist(self.current_playlist)

            # ripping loop
            for idx, track in enumerate(tracks):
                try:
                    self.check_stop_time()
                    self.skip.clear()

                    if self.abort.is_set():
                        break

                    print('Loading track...')
                    track.load()
                    if track.availability != 1:
                        print(Fore.RED + 'Track is not available, '
                              'skipping...' + Fore.RESET)
                        self.post.log_failure(track)
                        continue

                    self.audio_file = self.format_track_path(idx, track)

                    if not args.overwrite and path_exists(self.audio_file):
                        print(Fore.YELLOW + "Skipping " + track.link.uri +
                              Fore.RESET)
                        print(Fore.CYAN + self.audio_file + Fore.RESET)
                        self.post.queue_remove_from_playlist(idx)
                        continue

                    self.session.player.load(track)
                    self.prepare_rip(idx, track)
                    self.session.player.play()

                    timeout_count = 0
                    while not self.end_of_track.is_set() or \
                            not self.rip_queue.empty():
                        try:
                            if self.abort.is_set() or self.skip.is_set():
                                break

                            rip_item = self.rip_queue.get(timeout=1)

                            if self.abort.is_set() or self.skip.is_set():
                                break

                            self.rip(self.session, rip_item[0], rip_item[1],
                                     rip_item[2])
                        except queue.Empty:
                            timeout_count += 1
                            if timeout_count > 60:
                                raise spotify.Error("Timeout while "
                                                    "ripping track")

                    if self.skip.is_set():
                        print("\n" + Fore.YELLOW + "User skipped track... " +
                              Fore.RESET)
                        self.session.player.play(False)
                        self.post.clean_up_partial()
                        self.post.log_failure(track)
                        self.end_of_track.clear()
                        self.progress.end_track(show_end=False)
                        self.ripping.clear()
                        continue

                    if self.abort.is_set():
                        self.session.player.play(False)
                        self.end_of_track.set()
                        self.post.clean_up_partial()
                        self.post.log_failure(track)
                        break

                    self.end_of_track.clear()

                    self.finish_rip(track)

                    # update id3v2 with metadata and embed front cover image
                    set_metadata_tags(args, self.audio_file, idx, track, self)

                    # make a note of the index and remove all the
                    # tracks from the playlist when everything is done
                    self.post.queue_remove_from_playlist(idx)

                except (spotify.Error, Exception) as e:
                    if isinstance(e, Exception):
                        print(Fore.RED + "Spotify error detected" + Fore.RESET)
                    print(str(e))
                    print("Skipping to next track...")
                    self.session.player.play(False)
                    self.post.clean_up_partial()
                    self.post.log_failure(track)
                    continue

            # create playlist m3u file if needed
            self.post.create_playlist_m3u(tracks)

            # create playlist wpl file if needed
            self.post.create_playlist_wpl(tracks)

            # actually removing the tracks from playlist
            self.post.remove_tracks_from_playlist()

        # logout, we are done
        self.post.end_failure_log()
        self.post.print_summary()
        self.logout()
        self.stop_event_loop()
        self.finished.set()
Example #6
0
    def run(self):
        args = self.args

        # start event loop
        self.event_loop.start()

        # wait for main thread to login
        self.ripper_continue.wait()
        if self.abort.is_set():
            return

        # list of spotify URIs
        uris = args.uri

        def get_tracks_from_uri(uri):
            self.current_playlist = None
            self.current_album = None
            self.current_chart = None

            if isinstance(uri, list):
                return uri
            else:
                if (uri.startswith("spotify:artist:") and
                        (args.artist_album_type is not None or
                         args.artist_album_market is not None)):
                    album_uris = self.web.get_albums_with_filter(uri)
                    return itertools.chain(
                        *[self.load_link(album_uri) for
                          album_uri in album_uris])
                elif uri.startswith("spotify:charts:"):
                    charts = self.web.get_charts(uri)
                    if charts is not None:
                        self.current_chart = charts
                        chart_uris = charts["tracks"]
                        return itertools.chain(
                            *[self.load_link(chart_uri) for
                              chart_uri in chart_uris])
                    else:
                        return iter([])
                else:
                    return self.load_link(uri)

        # calculate total size and time
        all_tracks = []
        for uri in uris:
            tracks = list(get_tracks_from_uri(uri))

            # TODO: remove dependency on current_album, ...
            for idx, track in enumerate(tracks):

                # ignore local tracks
                if track.is_local:
                    continue

                audio_file = self.format_track_path(idx, track)
                all_tracks.append((track, audio_file))

        self.progress.calc_total(all_tracks)

        if self.progress.total_size > 0:
            print(
                "Total Download Size: " +
                format_size(self.progress.total_size))

        # create track iterator
        for uri in uris:
            if self.abort.is_set():
                break

            tracks = list(get_tracks_from_uri(uri))

            if args.playlist_sync and self.current_playlist:
                self.sync = Sync(args, self)
                self.sync.sync_playlist(self.current_playlist)

            # ripping loop
            for idx, track in enumerate(tracks):
                try:
                    self.check_stop_time()
                    self.skip.clear()

                    if self.abort.is_set():
                        break

                    print('Loading track...')
                    track.load()
                    if track.availability != 1 or track.is_local:
                        print(
                            Fore.RED + 'Track is not available, '
                                       'skipping...' + Fore.RESET)
                        self.post.log_failure(track)
                        continue

                    self.audio_file = self.format_track_path(idx, track)

                    if not args.overwrite and path_exists(self.audio_file):
                        if is_partial(self.audio_file, track):
                            print("Overwriting partial file")
                        else:
                            print(
                                Fore.YELLOW + "Skipping " +
                                track.link.uri + Fore.RESET)
                            print(Fore.CYAN + self.audio_file + Fore.RESET)
                            self.post.queue_remove_from_playlist(idx)
                            continue

                    self.session.player.load(track)
                    self.prepare_rip(idx, track)
                    self.session.player.play()

                    timeout_count = 0
                    while not self.end_of_track.is_set() or \
                            not self.rip_queue.empty():
                        try:
                            if self.abort.is_set() or self.skip.is_set():
                                break

                            rip_item = self.rip_queue.get(timeout=1)

                            if self.abort.is_set() or self.skip.is_set():
                                break

                            self.rip(self.session, rip_item[0],
                                     rip_item[1], rip_item[2])
                        except queue.Empty:
                            timeout_count += 1
                            if timeout_count > 60:
                                raise spotify.Error("Timeout while "
                                                    "ripping track")

                    if self.skip.is_set():
                        extra_line = "" if self.play_token_resume.is_set() \
                                        else "\n"
                        print(extra_line + Fore.YELLOW +
                            "User skipped track... " + Fore.RESET)
                        self.session.player.play(False)
                        self.post.clean_up_partial()
                        self.post.log_failure(track)
                        self.end_of_track.clear()
                        self.progress.end_track(show_end=False)
                        self.ripping.clear()
                        continue

                    if self.abort.is_set():
                        self.session.player.play(False)
                        self.end_of_track.set()
                        self.post.clean_up_partial()
                        self.post.log_failure(track)
                        break

                    self.end_of_track.clear()

                    self.finish_rip(track)

                    # update id3v2 with metadata and embed front cover image
                    set_metadata_tags(args, self.audio_file, idx, track, self)

                    # make a note of the index and remove all the
                    # tracks from the playlist when everything is done
                    self.post.queue_remove_from_playlist(idx)

                    # finally log success
                    self.post.log_success(track)

                except (spotify.Error, Exception) as e:
                    if isinstance(e, Exception):
                        print(Fore.RED + "Spotify error detected" + Fore.RESET)
                    print(str(e))
                    traceback.print_exc()
                    print("Skipping to next track...")
                    self.session.player.play(False)
                    self.post.clean_up_partial()
                    self.post.log_failure(track)
                    continue

            # create playlist m3u file if needed
            self.post.create_playlist_m3u(tracks)

            # create playlist wpl file if needed
            self.post.create_playlist_wpl(tracks)

            # actually removing the tracks from playlist
            self.post.remove_tracks_from_playlist()

            # remove libspotify's offline storage cache
            self.post.remove_offline_cache()

        # logout, we are done
        self.post.end_failure_log()
        self.post.print_summary()
        self.logout()
        self.stop_event_loop()
        self.finished.set()
Example #7
0
    def run(self):
        args = self.args

        # start event loop
        self.event_loop.start()

        # wait for main thread to login
        self.ripper_continue.wait()
        if self.abort.is_set():
            return

        # check if we were passed a file name or search
        if len(args.uri) == 1 and path_exists(args.uri[0]):
            uris = [line.strip() for line in open(args.uri[0])]
        elif len(args.uri) == 1 and not args.uri[0].startswith("spotify:"):
            uris = [list(self.search_query(args.uri[0]))]
        else:
            uris = args.uri

        def get_tracks_from_uri(uri):
            current_playlist = None
            current_album = None
            current_chart = None

            if isinstance(uri, list):
                return uri
            else:
                if args.market is None:
                    market = "any"
                elif isinstance(args.market, basestring):
                    market = args.market
                else:
                    market = args.market[0]
                if (args.filter_albums is not None and
                        uri.startswith("spotify:artist:")):
                    if isinstance(args.filter_albums, basestring):
                        filter = args.filter_albums
                    else:
                        filter = args.filter_albums.first

                    album_uris = self.web.get_albums_with_filter(uri, filter, market)
                    return itertools.chain(
                        *[self.load_link(album_uri) for
                          album_uri in album_uris])
                elif (args.exclude_appears_on and
                        uri.startswith("spotify:artist:")):
                    album_uris = self.web.get_albums_with_filter(uri, "album,single,compilation", market)
                    return itertools.chain(
                        *[self.load_link(album_uri) for
                          album_uri in album_uris])
                elif uri.startswith("spotify:charts:"):
                    charts = self.web.get_charts(uri)
                    if charts is not None:
                        self.current_chart = charts
                        chart_uris = ["spotify:track:" + t["track"]["id"]
                            for t in charts["entries"]["items"]]
                        return itertools.chain(
                            *[self.load_link(chart_uri) for
                              chart_uri in chart_uris])
                    else:
                        return iter([])
                else:
                    return self.load_link(uri)

        # calculate total size and time
        all_tracks = []
        for uri in uris:
            tracks = get_tracks_from_uri(uri)
            all_tracks += list(tracks)

        self.progress.calc_total(all_tracks)

        if self.progress.total_size > 0:
            print(
                "Total Download Size: " +
                format_size(self.progress.total_size))

        # create track iterator
        for uri in uris:
            if self.abort.is_set():
                break

            tracks = list(get_tracks_from_uri(uri))

            if args.playlist_sync and self.current_playlist:
                self.sync = Sync(args, self)
                self.sync.sync_playlist(self.current_playlist)

            # ripping loop
            for idx, track in enumerate(tracks):
                try:
                    self.check_stop_time()
                    self.skip.clear()

                    if self.abort.is_set():
                        break

                    print('Loading track...')
                    track.load()
                    if track.availability != 1:
                        print(
                            Fore.RED + 'Track is not available, '
                                       'skipping...' + Fore.RESET)
                        self.post.log_failure(track)
                        continue

                    self.audio_file = self.format_track_path(idx, track)

                    if not args.overwrite and path_exists(self.audio_file):
                        if is_partial(self.audio_file, track):
                            print("Overwriting partial file")
                        else:
                            print(
                                Fore.YELLOW + "Skipping " +
                                track.link.uri + Fore.RESET)
                            print(Fore.CYAN + self.audio_file + Fore.RESET)
                            self.post.queue_remove_from_playlist(idx)
                            continue

                    self.session.player.load(track)
                    self.prepare_rip(idx, track)
                    self.session.player.play()

                    timeout_count = 0
                    while not self.end_of_track.is_set() or \
                            not self.rip_queue.empty():
                        try:
                            if self.abort.is_set() or self.skip.is_set():
                                break

                            rip_item = self.rip_queue.get(timeout=1)

                            if self.abort.is_set() or self.skip.is_set():
                                break

                            self.rip(self.session, rip_item[0],
                                     rip_item[1], rip_item[2])
                        except queue.Empty:
                            timeout_count += 1
                            if timeout_count > 60:
                                raise spotify.Error("Timeout while "
                                                    "ripping track")

                    if self.skip.is_set():
                        print("\n" + Fore.YELLOW +
                            "User skipped track... " + Fore.RESET)
                        self.session.player.play(False)
                        self.post.clean_up_partial()
                        self.post.log_failure(track)
                        self.end_of_track.clear()
                        self.progress.end_track(show_end=False)
                        self.ripping.clear()
                        continue

                    if self.abort.is_set():
                        self.session.player.play(False)
                        self.end_of_track.set()
                        self.post.clean_up_partial()
                        self.post.log_failure(track)
                        break

                    self.end_of_track.clear()

                    self.finish_rip(track)

                    # update id3v2 with metadata and embed front cover image
                    set_metadata_tags(args, self.audio_file, idx, track, self)

                    # make a note of the index and remove all the
                    # tracks from the playlist when everything is done
                    self.post.queue_remove_from_playlist(idx)

                except (spotify.Error, Exception) as e:
                    if isinstance(e, Exception):
                        print(Fore.RED + "Spotify error detected" + Fore.RESET)
                    print(str(e))
                    print("Skipping to next track...")
                    self.session.player.play(False)
                    self.post.clean_up_partial()
                    self.post.log_failure(track)
                    continue

            # create playlist m3u file if needed
            self.post.create_playlist_m3u(tracks)

            # create playlist wpl file if needed
            self.post.create_playlist_wpl(tracks)

            # actually removing the tracks from playlist
            self.post.remove_tracks_from_playlist()

            # remove libspotify's offline storage cache
            self.post.remove_offline_cache()

        # logout, we are done
        self.post.end_failure_log()
        self.post.print_summary()
        self.logout()
        self.stop_event_loop()
        self.finished.set()
Example #8
0
    def run(self):
        args = self.args

        # start event loop
        self.event_loop.start()

        # wait for main thread to login
        self.ripper_continue.wait()
        if self.abort.is_set():
            return
        #set session to private
        self.session.social.private_session = True

        # list of spotify URIs
        uris = args.uri

        # calculate total size and time
        all_tracks = []
        uri_tracks = {}
        for uri in uris:
            tracks = list(self.get_tracks_from_uri(uri))
            uri_tracks[uri] = tracks
            for idx, track in enumerate(tracks):

                # ignore local tracks
                if track.is_local:
                    continue

                audio_file = self.format_track_path(idx, track)
                all_tracks.append((track, audio_file))

        self.progress.calc_total(all_tracks)

        if self.progress.total_size > 0:
            print(
                "Total Download Size: " +
                format_size(self.progress.total_size))

        # create track iterator
        for uri in uris:
            if self.abort.is_set():
                break

            tracks = uri_tracks[uri]

            """acepta una playlist album para sincronizar, aunque es al pedo"""

            if args.playlist_sync and self.current_playlist:
                self.sync = Sync(args, self)
                self.sync.sync_playlist(self.current_playlist)

            # ripping loop
            for idx, track in enumerate(tracks):
                try:
                    self.check_stop_time()
                    self.skip.clear()

                    if self.abort.is_set():
                        break

                    print('Loading track...')
                    track.load(args.timeout)
                    if track.availability != 1 or track.is_local:
                        print(
                            Fore.RED + 'Track is not available, '
                                       'skipping...' + Fore.RESET)
                        self.post.log_failure(track)
                        self.progress.track_idx += 1
                        continue

                    self.audio_file = self.format_track_path(idx, track)

                    if not args.overwrite and path_exists(self.audio_file):
                        if is_partial(self.audio_file, track):
                            print("Overwriting partial file")
                        else:
                            print(
                                Fore.YELLOW + "Skipping " +
                                track.link.uri + Fore.RESET)
                            print(Fore.CYAN + self.audio_file + Fore.RESET)
                            self.post.queue_remove_from_playlist(track.link.uri)
                            self.progress.track_idx += 1
                            continue

                    self.session.player.load(track)
                    self.prepare_rip(track)
                    self.session.player.play()

                    timeout_count = 0
                    while not self.end_of_track.is_set() or \
                            not self.rip_queue.empty():
                        try:
                            if self.abort.is_set() or self.skip.is_set():
                                break

                            rip_item = self.rip_queue.get(timeout=1)

                            if self.abort.is_set() or self.skip.is_set():
                                break

                            self.rip(self.session, rip_item[0],
                                     rip_item[1], rip_item[2])
                        except queue.Empty:
                            timeout_count += 1
                            if timeout_count > 60:
                                raise spotify.Error("Timeout while "
                                                    "ripping track")

                    if self.skip.is_set():
                        extra_line = "" if self.play_token_resume.is_set() \
                                        else "\n"
                        print(extra_line + Fore.YELLOW +
                            "User skipped track... " + Fore.RESET)
                        self.session.player.play(False)
                        self.post.clean_up_partial()
                        self.post.log_failure(track)
                        self.end_of_track.clear()
                        self.progress.end_track(show_end=False)
                        self.ripping.clear()
                        continue

                    if self.abort.is_set():
                        self.session.player.play(False)
                        self.end_of_track.set()
                        self.post.clean_up_partial()
                        self.post.log_failure(track)
                        break

                    self.end_of_track.clear()

                    self.finish_rip(track)

                    # update id3v2 with metadata and embed front cover image
                    set_metadata_tags(args, self.audio_file, idx, track, self)

                    # make a note of the index and remove all the
                    # tracks from the playlist when everything is done
                    self.post.queue_remove_from_playlist(track.link.uri)

                    # finally log success
                    self.post.log_success(track)

                except (spotify.Error, Exception) as e:
                    if isinstance(e, Exception):
                        print(Fore.RED + "Spotify error detected" + Fore.RESET)
                    print(str(e))
                    traceback.print_exc()
                    print("Skipping to next track...")
                    self.session.player.play(False)
                    self.post.clean_up_partial()
                    self.post.log_failure(track)
                    continue

            # create playlist m3u file if needed
            self.post.create_playlist_m3u(tracks)

            # create playlist wpl file if needed
            self.post.create_playlist_wpl(tracks)

            # actually removing the tracks from playlist
            self.post.remove_tracks_from_playlist()

            # remove libspotify's offline storage cache
            self.post.remove_offline_cache()

        # logout, we are done
        self.post.end_failure_log()
        self.post.print_summary()
        self.logout()
        self.stop_event_loop()
        self.finished.set()
        sys.exit()