def create_track(self, release_id, track_no, track_name, track_artist): insert_tuple = (release_id, track_artist, track_no, track_name) update_tuple = (release_id, track_artist, track_no, track_name, release_id, track_no) c = self.db_conn.cursor() with self.db_conn: try: c.execute( '''INSERT INTO track(d_release_id, d_artist, d_track_no, d_track_name, import_timestamp) VALUES(?, ?, ?, ?, datetime('now', 'localtime'))''', insert_tuple) return c.rowcount except sqlerr as e: if "UNIQUE constraint failed" in e.args[0]: log.warning( "Track details already in DiscoBASE, updating ...") try: c.execute( '''UPDATE track SET (d_release_id, d_artist, d_track_no, d_track_name, import_timestamp) = (?, ?, ?, ?, datetime('now', 'localtime')) WHERE d_release_id == ? AND d_track_no == ?''', update_tuple) log.info("MODEL: rowcount: %d, lastrowid: %d", c.rowcount, c.lastrowid) return c.rowcount except sqlerr as e: log.error("MODEL: %s", e.args[0]) return False else: log.error("MODEL: %s", e.args[0]) return False
def edit_track(self, edit_track): if self.mix.id_existing: print_help("Editing track "+edit_track+" in \""+ self.mix.name+"\":") track_details = self.mix.get_one_mix_track(edit_track) if track_details: print_help("{} - {} - {}".format( track_details['discogs_title'], track_details['d_track_no'], track_details['d_track_name'])) log.info("current d_release_id: %s", track_details['d_release_id']) edit_answers = self._edit_track_ask_details(track_details, self.cli._edit_track_questions) for a in edit_answers.items(): log.info("answers: %s", str(a)) update_ok = self.mix.update_track_in_mix(track_details, edit_answers) if update_ok: print_help("Track edit was successful.") else: log.error("Something went wrong on mix_track edit!") raise SystemExit(1) self.view() else: print_help("No track "+edit_track+" in \""+ self.mix.name+"\".") else: print_help("Mix unknown: \"{}\".".format(self.mix.name_or_id))
def create_table(conn, create_table_sql): try: c = conn.cursor() c.execute(create_table_sql) log.info("DB: Executed sql: %s", create_table_sql) except Error as e: log.error("DB: %s", e)
def search_release_offline(self, id_or_title): if is_number(id_or_title): try: release = self._select_simple(['*'], 'release', 'discogs_id LIKE {}'.format( id_or_title, id_or_title), fetchone=True, orderby='d_artist') if release: return [release] else: release_not_found = None return release_not_found except Exception as Exc: log.error("Not found or Database Exception: %s\n", Exc) raise Exc else: try: releases = self._select_simple( ['*'], 'release', 'discogs_title LIKE "%{}%" OR d_artist LIKE "%{}%"'.format( id_or_title, id_or_title), fetchone=False, orderby='d_artist') if releases: log.debug("First found release: {}".format(releases[0])) log.debug("All found releases: {}".format(releases)) return releases # this is a list else: return None except Exception as Exc: log.error("Not found or Database Exception: %s\n", Exc) raise Exc
def create_conn(file): try: conn = sqlite3.connect(file) return conn except Error as e: log.error("DB: Connection error: %s", e) return None
def create_conn(self, db_file): try: conn = sqlite3.connect(str(db_file)) # make sure it's a string return conn except sqlerr as e: log.error("DB-NEW: Connection error: %s", e) return None
def update_track_in_mix(self, track_details, edit_answers): try: db.update_track_in_mix(self.db_conn, track_details['mix_track_id'], edit_answers['d_release_id'], edit_answers['d_track_no'], edit_answers['track_pos'], edit_answers['trans_rating'], edit_answers['trans_notes']) db.update_or_insert_track_ext( self.db_conn, track_details['d_release_id'], edit_answers['d_release_id'], edit_answers['d_track_no'], edit_answers['key'], edit_answers['key_notes'], edit_answers['bpm'], edit_answers['notes'], ) log.info("MODEL: Track edit was successful.") return True except Exception as edit_err: log.error("MODEL: Something went wrong in update_track_in_mix!") raise edit_err return False
def reorder_tracks(self, startpos = 1): reorder_pos = int(startpos) reordered = self.mix.reorder_tracks(startpos) if not reordered: log.error("Reorder failed. No track {} in mix.".format(startpos)) else: log.info("Reordering tracks successful") self.view()
def error_not_the_release(self): log.error("This is not the release you are looking for!") print(r''' .=. '==c| [)-+| //'_| snd /]==;\ ''')
def create(self): if is_number(self.mix.name_or_id): log.error("Mix name can't be a number!") # log is everywhere, also in view else: print_help("Creating new mix \"{}\".".format(self.mix.name)) # view answers = self._create_ask_details() # view with questions from common created_id = self.mix.create(answers['played'], answers['venue']) # model self.mix.db_conn.commit() # model print_help("New mix created with ID {}.".format(created_id)) # view self.view_mixes_list() # view
def _add_track(self, _release_id, _release_title, _track_no, _pos): if not _track_no: track_to_add = self.cli.ask_user_for_track() else: log.debug("_track_no was given, value is".format(_track_no)) track_to_add = _track_no if _pos == None: log.debug("_pos was None, setting to 0") _pos = 0 log.debug("This is _pos: {}".format(_pos)) log.debug("This is track_to_add: {}".format(track_to_add)) log.debug("This is _release_id: %s", _release_id) log.debug("This is _release_title: %s", _release_title) if self.mix.id_existing: last_track = self.mix.get_last_track() log.debug("Currently last track in mix is: %s", last_track[0]) current_id = False if _pos: # a position to squeeze in the track was given # get current tracks >= pos tracks_to_shift = self.mix.get_tracks_from_position(_pos) if self.cli.really_add_track(track_to_add, _release_title, self.mix.id, _pos): current_id = self.mix.add_track(_release_id, track_to_add, track_pos = _pos) # all good? reorder tracks if current_id: log.info("Add track to mix successful, now reordering ...") self.mix.reorder_tracks_squeeze_in(_pos, tracks_to_shift) elif is_number(last_track[0]): # no position was given, tracks already mix if self.cli.really_add_track(track_to_add, _release_title, self.mix.id, last_track[0]+1): current_id = self.mix.add_track(_release_id, track_to_add, track_pos = last_track[0] + 1) else: # no position and it's the first track ever added if self.cli.really_add_track(track_to_add, _release_title, self.mix.id, 1): current_id = self.mix.add_track(_release_id, track_to_add, track_pos = 1) # FIXME untested if this is actually a proper sanity check log.debug("Value of current_id in add_offline_track: {}".format(current_id)) if current_id: self.view() #return True else: log.error("Add track to DB failed!") #return False else: self.cli.print_help("Mix ID {} is not existing yet.".format(self.mix.id)) return False
def __init__(self, _db_conn, _user_int, _userToken, _appIdentifier): self.user = _user_int # take an instance of the User_int class and set as attribute self.db_conn = _db_conn self.user = _user_int self.collection = Collection(self.db_conn) self.cli = Collection_view_cli() # instantiate cli frontend class if self.user.WANTS_ONLINE: if not self.collection.discogs_connect(_userToken, _appIdentifier): log.error("connecting to Discogs API, let's stay offline!\n") # just set this for compatibilty reasons, currently used in cli.py, will prob. removed #self.ONLINE = self.collection.ONLINE log.info("CTRL: Initial ONLINE status is %s", self.ONLINE)
def update_pos_in_mix(conn, mix_track_id, track_pos_new): log.info("DB: update_pos_in_mix: track_pos_new is {}".format(track_pos_new)) cur = conn.cursor() try: cur.execute('''UPDATE mix_track SET track_pos = ? WHERE mix_track_id == ? ''', (track_pos_new, mix_track_id)) conn.commit() log.info("DB: update_pos_in_mix rowcount: %s", cur.rowcount) return True except sqlite3.Error as er: log.error("DB: update_pos_in_mix error: %s", er.message) return False
def execute_sql(self, sql, values_tuple=False): '''used for eg. creating tables or inserts''' log.info("DB-NEW: Executing sql: %s", sql) try: c = self.cur if values_tuple: c.execute(sql, values_tuple) log.info("DB-NEW: ...with this tuple: {%s}", values_tuple) else: c.execute(sql) log.info("DB-NEW: rowcount: %d, lastrowid: %d", c.rowcount, c.lastrowid) return c.rowcount except sqlerr as e: #log.error("DB-NEW: %s", dir(e)) log.error("DB-NEW: %s", e.args[0]) #raise e return False
def import_collection(self): self.cli.exit_if_offline(self.collection.ONLINE) self.cli.print_help( "Gathering your Discogs collection and importing necessary fields into DiscoBASE") insert_count = 0 for r in self.collection.me.collection_folders[0].releases: self.collection.rate_limit_slow_downer(remaining=20, sleep=3) artists = self.collection.d_artists_to_str(r.release.artists) print("Release :", r.release.id, "-", artists, "-", r.release.title) rowcount = self.collection.create_release(r.release.id, r.release.title, artists, d_coll = True) # create_release will return False if unsuccessful if rowcount: insert_count = insert_count + 1 print("Created so far:", insert_count, "") log.info("discogs-rate-limit-remaining: %s", self.collection.d._fetcher.rate_limit_remaining) print() else: log.error("Something wrong while importing \"{}\"\n".format(r.release.title))
def pull_track_info_from_discogs(self, coll_ctrl, start_pos = False): if coll_ctrl.ONLINE: if self.mix.id_existing: self.cli.print_help("Let's update current mixes tracks with info from Discogs...") mixed_tracks = self.mix.get_tracks_of_one_mix(start_pos) else: self.cli.print_help("Let's update ALL tracks in ALL mixes with info from Discogs...") mixed_tracks = self.mix.get_all_tracks_in_mixes() for mix_track in mixed_tracks: name, artist = "", "" coll_ctrl.collection.rate_limit_slow_downer(remaining=20, sleep=3) #try: # handle error 404 when release is not on discogs # quick and dirty: 404 is handled in this method: if coll_ctrl.collection.get_d_release(mix_track[2]): name = coll_ctrl.cli.d_tracklist_parse( coll_ctrl.d.release(mix_track[2]).tracklist, mix_track[3]) artist = coll_ctrl.collection.d_artists_parse( coll_ctrl.d.release(mix_track[2]).tracklist, mix_track[3], coll_ctrl.d.release(mix_track[2]).artists) else: print("") # space for readability if name: print("Adding track info: {} {} - {} - {}".format( mix_track[2], mix_track[3], artist, name)) coll_ctrl.collection.create_track(mix_track[2], mix_track[3], name, artist) else: #print("Adding track info: "+ str(mix_track[2])+" "+ # mix_track[3]) print("Adding track info: {} {}".format( mix_track[2], mix_track[3])) log.error("No trackname found for Tr.Pos %s", mix_track[3]) log.error("Probably you misspelled? (eg A vs. A1)\n") else: self.cli.print_help("Not online, can't pull from Discogs...")
def create_release(self, release_id, release_title, release_artists, d_coll=False): #return db.create_release(self.db_conn, release_id, release_title) c = self.db_conn.cursor() try: c.execute( '''INSERT INTO release(discogs_id, discogs_title, import_timestamp, d_artist, in_d_collection) VALUES("{}", "{}", datetime('now', 'localtime'), "{}", {})''' .format(release_id, release_title, release_artists, d_coll)) log.info("MODEL: rowcount: %d, lastrowid: %d", c.rowcount, c.lastrowid) return c.rowcount except sqlerr as e: if "UNIQUE constraint failed" in e.args[0]: log.warning("Release already in DiscoBASE, updating ...") try: c.execute( '''UPDATE release SET (discogs_title, import_timestamp, d_artist, in_d_collection) = ("{}", datetime('now', 'localtime'), "{}", {}) WHERE discogs_id == {}'''.format( release_title, release_artists, d_coll, release_id)) log.info("MODEL: rowcount: %d, lastrowid: %d", c.rowcount, c.lastrowid) return c.rowcount except sqlerr as e: log.error("MODEL: %s", e.args[0]) return False else: log.error("MODEL: %s", e.args[0]) return False
def get_d_release(self, release_id): try: r = self.d.release(release_id) log.debug("try to access r here to catch err {}".format(r.title)) return r except errors.HTTPError as HtErr: log.error('Release not existing on Discogs ({})'.format(HtErr)) #log.error("%s", HtErr) return False except urlerrors.NewConnectionError as ConnErr: log.error("%s", ConnErr) return False except urlerrors.MaxRetryError as RetryErr: log.error("%s", RetryErr) return False except Exception as Exc: log.error("Exception: %s", Exc) #raise Exc return False
def search_release_online(self, id_or_title): try: if is_number(id_or_title): release = self.d.release(id_or_title) #return '|'+str(release.id)+'|'+ str(release.title)+'|' return [release] else: releases = self.d.search(id_or_title, type='release') log.info("First found release: {}".format(releases[0])) log.debug("All found releases: {}".format(releases)) return releases except errors.HTTPError as HtErr: log.error("%s", HtErr) return False except urlerrors.NewConnectionError as ConnErr: log.error("%s", ConnErr) return False except urlerrors.MaxRetryError as RetryErr: log.error("%s", RetryErr) return False except Exception as Exc: log.error("Exception: %s", Exc) return False
def exit_if_offline(self, online): if not online: log.error("Need to be ONLINE to do that!") raise SystemExit(3)
def __init__(self, _args): self.args = _args self.WANTS_ONLINE = True self.WANTS_TO_LIST_ALL_RELEASES = False self.WANTS_TO_SEARCH_FOR_RELEASE = False self.WANTS_TO_ADD_TO_MIX = False self.WANTS_TO_SHOW_MIX_OVERVIEW = False self.WANTS_TO_SHOW_MIX_TRACKLIST = False self.WANTS_TO_CREATE_MIX = False self.WANTS_TO_EDIT_MIX_TRACK = False self.WANTS_TO_PULL_TRACK_INFO = False self.WANTS_TO_PULL_TRACK_INFO_IN_MIX_MODE = False self.WANTS_VERBOSE_MIX_TRACKLIST = False self.WANTS_TO_REORDER_MIX_TRACKLIST = False self.WANTS_TO_ADD_AT_POSITION = False self.WANTS_TO_DELETE_MIX_TRACK = False self.WANTS_TO_ADD_RELEASE_IN_MIX_MODE = False self.WANTS_TO_ADD_AT_POS_IN_MIX_MODE = False self.WANTS_TO_COPY_MIX = False self.WANTS_TO_TRACK_SEARCH = False self.WANTS_TO_DELETE_MIX = False self.WANTS_TRACK_REPORT = False self.WANTS_TO_BULK_EDIT = False # RELEASE MODE: if hasattr(self.args, 'release_search'): if "all" in self.args.release_search: self.WANTS_TO_LIST_ALL_RELEASES = True self.WANTS_ONLINE = False else: self.WANTS_TO_SEARCH_FOR_RELEASE = True if (self.args.add_to_mix != 0 and self.args.track_to_add != 0 and self.args.add_at_pos): self.WANTS_TO_ADD_AT_POSITION = True #self.WANTS_TO_SHOW_MIX_TRACKLIST = True elif self.args.add_to_mix != 0 and self.args.track_to_add != 0: self.WANTS_TO_ADD_TO_MIX = True else: log.error( "args.add_to_mix, args.track_to_add or args.add_at_pos is 0" ) raise SystemExit(1) # MIX MODE if hasattr(self.args, 'mix_name'): if self.args.mix_name == "all": self.WANTS_TO_SHOW_MIX_OVERVIEW = True self.WANTS_ONLINE = False if self.args.create_mix == True: log.error("Please provide a mix name to be created!") log.error("(Mix name \"all\" is not valid.)") raise SystemExit(1) elif self.args.delete_mix == True: log.error("Please provide a mix name or ID to be deleted!") raise SystemExit(1) if self.args.discogs_update: self.WANTS_TO_PULL_TRACK_INFO_IN_MIX_MODE = True self.WANTS_ONLINE = True else: self.WANTS_TO_SHOW_MIX_TRACKLIST = True self.WANTS_ONLINE = False #if hasattr(self.args, 'create_mix') if self.args.create_mix: self.WANTS_TO_CREATE_MIX = True self.WANTS_ONLINE = False if self.args.edit_mix_track: self.WANTS_TO_EDIT_MIX_TRACK = True self.WANTS_ONLINE = False if self.args.verbose_tracklist: self.WANTS_VERBOSE_MIX_TRACKLIST = True self.WANTS_ONLINE = False if self.args.reorder_from_pos: self.WANTS_TO_REORDER_MIX_TRACKLIST = True self.WANTS_ONLINE = False if self.args.delete_track_pos: self.WANTS_TO_DELETE_MIX_TRACK = True self.WANTS_ONLINE = False if self.args.add_release_to_mix: self.WANTS_TO_ADD_RELEASE_IN_MIX_MODE = True self.WANTS_ONLINE = True if self.args.mix_mode_add_at_pos: self.WANTS_TO_ADD_AT_POS_IN_MIX_MODE = True if self.args.copy_mix: self.WANTS_TO_COPY_MIX = True self.WANTS_ONLINE = False if self.args.discogs_update: self.WANTS_TO_PULL_TRACK_INFO_IN_MIX_MODE = True self.WANTS_ONLINE = True if self.args.delete_mix: self.WANTS_TO_DELETE_MIX = True self.WANTS_ONLINE = False if self.args.bulk_edit: self.WANTS_TO_BULK_EDIT = True # TRACK MODE if hasattr(self.args, 'track_search'): self.WANTS_TO_TRACK_SEARCH = True if self.args.track_pull: self.WANTS_TO_PULL_TRACK_INFO = True else: self.WANTS_TRACK_REPORT = True log.debug("Entered Track-combination report.") #log.error("track search not implemented yet.") #raise SystemExit(1) if self.args.offline_mode == True: self.WANTS_ONLINE = False
def add_discogs_track(self, rel_list, track_no, pos): log.info("discogs rel_list: {}".format(rel_list)) if rel_list: self._add_track(rel_list[0][0], rel_list[0][2], track_no, pos) else: log.error("No release to add.")