Ejemplo n.º 1
0
class Controller:
    'The controller implements all application logic.'         
    def __init__(self, arguments):
        'Main entry point for iTunes-Discogs.'
        self.arguments = arguments
        self.config = Config(arguments.home)
        self.model = Model(self.config, arguments.database)
        self.itunes = iTunes(self.model, arguments.library)
        self.discogs = Discogs(self.model, arguments.junk)
                
        if arguments.cli:
            if not arguments.playlist:
                arguments.playlist = 'Library'
                
            for playlist in self.get_playlists().values():
                if playlist.Name == arguments.playlist:
                    self._process_playlist(playlist)
        else:
            Window(self)
            
        self.shutdown()
        
    def search(self, track):
        'Search storing results in the database.'
        track.search = self.discogs.search(track.Artist, track.Name)
        if track.search:
            self.model.set_bundle('track.search', track.PersistentID, track.search._id)
            if track.search.raw_results and not track.release:
                self.set_release(track, track.search.raw_results[0])
            
    def set_release(self, track, result):
        'Sets the track release to the specified result.'
        track.release = self.discogs.get_release(result)
        if track.release:
            self.model.set_bundle('track.release', track.PersistentID, track.release._id)
             
    def _process_playlist(self, playlist):
        'Resolve releases for the specified playlist.'
        for tid in playlist.Items:
            track = self.get_track(tid)
            if not track.release:
                self.search(track)
                if track.search and track.search.results():
                    self.set_release(track, track.search.results()[0])
                
    def shutdown(self):
        'Shutdown the worker thread and flush the database.'
        self.model.flush(self.arguments.database)
        
    def get_tracks(self):
        return self.itunes.library.tracks
    
    def get_track(self, tid):
        return self.get_tracks()[tid]
    
    def get_playlists(self):
        return self.itunes.library.playlists
        
    def get_playlist(self, pid):
        return self.get_playlists()[pid]
Ejemplo n.º 2
0
class ImageScraper:
    """
    Takes CSV file of music releases and searches Discogs API for cover image.
    Creates a dictionary mapping the column headers to search terms which can
    be customized.

    Cover images are saved in 'images' directory using the cover id from
    Discogs. Creates an output CSV copying each row and adding the cover id
    of 'Null' if nothing found.
    """
    def __init__(self,
                 filepath,
                 delimiter=',',
                 encoding='utf-8',
                 quotechar='"'):
        self.discogs = Discogs()
        self.filepath = filepath
        self.delimiter = delimiter
        self.encoding = encoding
        self.quotechar = quotechar
        self.search_terms = ('title', 'artist', 'format', 'album', 'label',
                             'year')
        self.output_csv = 'output.csv'

        if not os.path.exists('images/'):
            os.mkdir('images/')
        self.image_path = 'images/'

        self.get_columns()
        self.get_param_dict()

    def get_columns(self):
        """
        Returns the columns from CSV file as a list
        """
        with open(self.filepath, 'r', encoding=self.encoding) as file:
            csv_reader = csv.reader(file,
                                    delimiter=self.delimiter,
                                    quotechar=self.quotechar)
            headers = next(csv_reader)
            self.columns = [col for col in headers]

    def get_param_dict(self):
        self.param_dict = {}
        for i, col in enumerate(self.columns):
            for param in self.search_terms:
                if col.lower() == param:
                    self.param_dict[param] = i

    def confirm_dict(self):
        update_dict = True
        while update_dict:
            for param, col in self.param_dict.items():
                print(f'{param} found in column {col}')
            print('\nTo procede with these settings press Enter.')
            print('To add an item enter the header-text then col eg: title 1.')
            print('To delete an item enter the item eg: artist.')
            update_dict = input('> ')
            if update_dict:
                if len(update_dict.split()) == 2:
                    param, col = update_dict.split()
                    self.param_dict[param] = int(col)
                elif len(update_dict.split()) == 1:
                    del self.param_dict[update_dict]
                else:
                    print("I didn't understand that, please try again.")

    def get_search_params(self, row):
        """
        Takes row from csv file and returns a dictionary mapping the search
        parameters to their values
        """
        params = {}
        for k, v in self.param_dict.items():
            params[k] = row[v].replace(" ", "+")
        return params

    def run(self):
        with open(filepath, 'r', encoding=self.encoding) as input_file:
            csv_reader = csv.reader(input_file, delimiter=self.delimiter)
            next(csv_reader)
            for row in csv_reader:
                params = self.get_search_params(row)
                try:
                    response, cover_id = self.discogs.search(params)
                    with open(self.output_csv, 'a') as output_file:
                        output_csv = csv.writer(output_file)
                        output_csv.writerow(row + [cover_id])
                        with open(self.image_path + cover_id + '.jpg',
                                  'wb') as f:
                            shutil.copyfileobj(response.raw, f)
                        del response

                except TypeError:
                    with open(self.output_csv, 'a') as output_file:
                        output_csv = csv.writer(output_file)
                        output_csv.writerow(row + ['Null'])
                time.sleep(1.2)