diff --git a/app/config.py b/app/config.py index 1838606..be36d5b 100644 --- a/app/config.py +++ b/app/config.py @@ -1,5 +1,6 @@ import logging import os +from typing import List, Optional class Config(object): @@ -31,6 +32,8 @@ class Config(object): COLUMN_NAME_TITLE = "Title" DBFS_FADE = -12 DBFS_SILENCE = -50 + DEBUG_FUNCTIONS: List[Optional[str]] = [] + DEBUG_MODULES: List[Optional[str]] = ['dbconfig'] DEFAULT_COLUMN_WIDTH = 200 DEFAULT_IMPORT_DIRECTORY = "/home/kae/Nextcloud/tmp" DEFAULT_OUTPUT_DIRECTORY = "/home/kae/music/Singles" @@ -40,7 +43,7 @@ class Config(object): FADE_TIME = 3000 INFO_TAB_TITLE_LENGTH = 15 INFO_TAB_URL = "https://www.wikipedia.org/w/index.php?search=%s" - LOG_LEVEL_STDERR = logging.INFO + LOG_LEVEL_STDERR = logging.DEBUG LOG_LEVEL_SYSLOG = logging.DEBUG LOG_NAME = "musicmuster" MAIL_PASSWORD = os.environ.get('MAIL_PASSWORD') diff --git a/app/dbconfig.py b/app/dbconfig.py index 41bf6ce..e860e81 100644 --- a/app/dbconfig.py +++ b/app/dbconfig.py @@ -1,58 +1,32 @@ -# import inspect +import logging import os -# from config import Config from sqlalchemy import create_engine -# from contextlib import contextmanager -# from log import DEBUG -# from sqlalchemy.orm import (sessionmaker, scoped_session) -# -# -# class Counter: -# def __init__(self): -# self.count = 0 -# -# def __repr__(self): -# return(f"") -# -# def inc(self): -# self.count += 1 -# return self.count -# -# def dec(self): -# self.count -= 1 -# return self.count -# -# +from contextlib import contextmanager +from sqlalchemy.orm import (sessionmaker, scoped_session) + +from log import log + MYSQL_CONNECT = os.environ.get('MM_DB') if MYSQL_CONNECT is None: raise ValueError("MYSQL_CONNECT is undefined") +else: + dbname = MYSQL_CONNECT.split('/')[-1] + log.debug(f"Database: {dbname}") # MM_ENV = os.environ.get('MM_ENV', 'PRODUCTION') # testing = False -# -# if MM_ENV == 'PRODUCTION': -# dbname = os.environ.get('MM_PRODUCTION_DBNAME', 'musicmuster_prod') -# dbuser = os.environ.get('MM_PRODUCTION_DBUSER', 'musicmuster') -# dbpw = os.environ.get('MM_PRODUCTION_DBPW', 'musicmuster') -# dbhost = os.environ.get('MM_PRODUCTION_DBHOST', 'localhost') -# elif MM_ENV == 'TESTING': +# if MM_ENV == 'TESTING': # dbname = os.environ.get('MM_TESTING_DBNAME', 'musicmuster_testing') # dbuser = os.environ.get('MM_TESTING_DBUSER', 'musicmuster_testing') # dbpw = os.environ.get('MM_TESTING_DBPW', 'musicmuster_testing') # dbhost = os.environ.get('MM_TESTING_DBHOST', 'localhost') # testing = True -# elif MM_ENV == 'DEVELOPMENT': -# dbname = os.environ.get('MM_DEVELOPMENT_DBNAME', 'musicmuster_dev') -# dbuser = os.environ.get('MM_DEVELOPMENT_DBUSER', 'musicmuster') -# dbpw = os.environ.get('MM_DEVELOPMENT_DBPW', 'musicmuster') -# dbhost = os.environ.get('MM_DEVELOPMENT_DBHOST', 'localhost') # else: # raise ValueError(f"Unknown MusicMuster environment: {MM_ENV=}") # -# DEBUG(f"Using {dbname} database") # MYSQL_CONNECT = f"mysql+mysqldb://{dbuser}:{dbpw}@{dbhost}/{dbname}" -# + engine = create_engine( MYSQL_CONNECT, encoding='utf-8', @@ -60,17 +34,17 @@ engine = create_engine( pool_pre_ping=True, future=True ) -# -# # -# # @contextmanager -# # def Session(): -# # frame = inspect.stack()[2] -# # file = frame.filename -# # function = frame.function -# # lineno = frame.lineno -# # Session = scoped_session(sessionmaker(bind=engine, future=True)) -# # DEBUG(f"Session acquired, {file=}, {function=}, {lineno=}, {Session=}") -# # yield Session -# # DEBUG(" Session released") -# # Session.commit() -# # Session.close() + + +@contextmanager +def Session(): + frame = inspect.stack()[2] + file = frame.filename + function = frame.function + lineno = frame.lineno + Session = scoped_session(sessionmaker(bind=engine, future=True)) + log.debug(f"Session acquired, {file=}, {function=}, {lineno=}, {Session=}") + yield Session + log.debug(" Session released") + Session.commit() + Session.close() diff --git a/app/log.py b/app/log.py index 44f17f0..101987d 100644 --- a/app/log.py +++ b/app/log.py @@ -20,6 +20,19 @@ class LevelTagFilter(logging.Filter): return True +class DebugStdoutFilter(logging.Filter): + """Filter debug messages sent to stdout""" + + def filter(self, record): + if record.levelno != logging.DEBUG: + return True + if record.module in Config.DEBUG_MODULES: + return True + if record.funcName in Config.DEBUG_FUNCTIONS: + return True + return False + + log = logging.getLogger(Config.LOG_NAME) log.setLevel(logging.DEBUG) @@ -33,13 +46,19 @@ syslog.setLevel(Config.LOG_LEVEL_SYSLOG) # Filter local_filter = LevelTagFilter() +debug_filter = DebugStdoutFilter() + syslog.addFilter(local_filter) + stderr.addFilter(local_filter) +stderr.addFilter(debug_filter) # create formatter and add it to the handlers stderr_fmt = logging.Formatter('[%(asctime)s] %(leveltag)s: %(message)s', datefmt='%H:%M:%S') -syslog_fmt = logging.Formatter('[%(name)s] %(leveltag)s: %(message)s') +syslog_fmt = logging.Formatter( + '[%(name)s] %(module)s.%(funcName)s - %(leveltag)s: %(message)s' +) stderr.setFormatter(stderr_fmt) syslog.setFormatter(syslog_fmt) @@ -57,52 +76,3 @@ def log_uncaught_exceptions(ex_cls, ex, tb): sys.excepthook = log_uncaught_exceptions - - -def DEBUG(msg: str, force_stderr: bool = False) -> None: - """ - Outupt a log message at level DEBUG. If force_stderr is True, - output this message to stderr regardless of default stderr level - setting. - """ - - if force_stderr: - old_level = stderr.level - stderr.setLevel(logging.DEBUG) - log.debug(msg) - stderr.setLevel(old_level) - else: - log.debug(msg) - - -def EXCEPTION(msg: str) -> None: - log.exception(msg, exc_info=True, stack_info=True) - - -def ERROR(msg: str) -> None: - log.error(msg) - - -def INFO(msg: str) -> None: - log.info(msg) - - -if __name__ == "__main__": - DEBUG("hi debug") - ERROR("hi error") - INFO("hi info") - EXCEPTION("hi exception") - - def f(): - return g() - - def g(): - return h() - - def h(): - return i() - - def i(): - return 1 / 0 - - f() diff --git a/app/models.py b/app/models.py index b3a397a..a5db814 100644 --- a/app/models.py +++ b/app/models.py @@ -39,7 +39,7 @@ from sqlalchemy.orm import ( # leading_silence, # trailing_silence, # ) -# from log import DEBUG, ERROR +# from log import log.debug, log.error # Base = declarative_base() # @@ -134,7 +134,7 @@ Base = declarative_base() # row: int, text: str) -> None: # """Create note""" # -# DEBUG(f"Notes.__init__({playlist_id=}, {row=}, {text=})") +# log.debug(f"Notes.__init__({playlist_id=}, {row=}, {text=})") # self.playlist_id = playlist_id # self.row = row # self.note = text @@ -149,7 +149,7 @@ Base = declarative_base() # def delete_note(self, session: Session) -> None: # """Delete note""" # -# DEBUG(f"delete_note({self.id=}") +# log.debug(f"delete_note({self.id=}") # # session.query(Notes).filter_by(id=self.id).delete() # session.flush() @@ -183,11 +183,11 @@ Base = declarative_base() # """Return note or None""" # # try: -# DEBUG(f"Notes.get_track(track_id={note_id})") +# log.debug(f"Notes.get_track(track_id={note_id})") # note = session.query(cls).filter(cls.id == note_id).one() # return note # except NoResultFound: -# ERROR(f"get_track({note_id}): not found") +# log.error(f"get_track({note_id}): not found") # return None # # def update( @@ -197,7 +197,7 @@ Base = declarative_base() # Update note details. If text=None, don't change text. # """ # -# DEBUG(f"Notes.update_note({self.id=}, {row=}, {text=})") +# log.debug(f"Notes.update_note({self.id=}, {row=}, {text=})") # # self.row = row # if text: @@ -217,7 +217,7 @@ Base = declarative_base() # def __init__(self, session: Session, track_id: int) -> None: # """Record that track was played""" # -# DEBUG(f"add_playdate({track_id=})") +# log.debug(f"add_playdate({track_id=})") # # self.lastplayed = datetime.now() # self.track_id = track_id @@ -370,7 +370,7 @@ Base = declarative_base() # session.flush() # # def remove_track(self, session: Session, row: int) -> None: -# DEBUG(f"Playlist.remove_track({self.id=}, {row=})") +# log.debug(f"Playlist.remove_track({self.id=}, {row=})") # # # Refresh self first (this is necessary when calling remove_track # # multiple times before session.commit()) @@ -409,7 +409,7 @@ Base = declarative_base() # def __init__( # self, session: Session, playlist_id: int, track_id: int, # row: int) -> None: -# DEBUG(f"PlaylistTracks.__init__({playlist_id=}, {track_id=}, {row=})") +# log.debug(f"PlaylistTracks.__init__({playlist_id=}, {track_id=}, {row=})") # # self.playlist_id = playlist_id # self.track_id = track_id @@ -549,7 +549,7 @@ Base = declarative_base() # else created new track and return it # """ # -# DEBUG(f"Tracks.get_or_create({path=})") +# log.debug(f"Tracks.get_or_create({path=})") # # try: # track = session.query(cls).filter(cls.path == path).one() @@ -567,7 +567,7 @@ Base = declarative_base() # than one track matches. # """ # -# DEBUG(f"Tracks.get_track_from_filename({filename=})") +# log.debug(f"Tracks.get_track_from_filename({filename=})") # try: # track = session.query(Tracks).filter(Tracks.path.ilike( # f'%{os.path.sep}{filename}')).one() @@ -581,7 +581,7 @@ Base = declarative_base() # Return track with passee path, or None. # """ # -# DEBUG(f"Tracks.get_track_from_path({path=})") +# log.debug(f"Tracks.get_track_from_path({path=})") # # return session.query(Tracks).filter(Tracks.path == path).first() # @@ -590,11 +590,11 @@ Base = declarative_base() # """Return track or None""" # # try: -# DEBUG(f"Tracks.get_track(track_id={track_id})") +# log.debug(f"Tracks.get_track(track_id={track_id})") # track = session.query(Tracks).filter(Tracks.id == track_id).one() # return track # except NoResultFound: -# ERROR(f"get_track({track_id}): not found") +# log.error(f"get_track({track_id}): not found") # return None # # def rescan(self, session: Session) -> None: @@ -617,13 +617,13 @@ Base = declarative_base() # def remove_by_path(session: Session, path: str) -> None: # """Remove track with passed path from database""" # -# DEBUG(f"Tracks.remove_path({path=})") +# log.debug(f"Tracks.remove_path({path=})") # # try: # session.query(Tracks).filter(Tracks.path == path).delete() # session.flush() # except IntegrityError as exception: -# ERROR(f"Can't remove track with {path=} ({exception=})") +# log.error(f"Can't remove track with {path=} ({exception=})") # # @classmethod # def search_artists(cls, session: Session, text: str) -> List["Tracks"]: diff --git a/app/music.py b/app/music.py index 7bbfa42..f3ae303 100644 --- a/app/music.py +++ b/app/music.py @@ -6,7 +6,7 @@ # from datetime import datetime # from time import sleep # -# from log import DEBUG, ERROR +# from log import log.debug, log.error # # lock = threading.Lock() # @@ -32,7 +32,7 @@ # to hold up the UI during the fade. # """ # -# DEBUG("music.fade()", True) +# log.debug("music.fade()", True) # # if not self.player: # return @@ -53,13 +53,13 @@ # # Take a copy of current player to allow another track to be # # started without interfering here # -# DEBUG(f"music._fade(), {self.player=}", True) +# log.debug(f"music._fade(), {self.player=}", True) # # with lock: # p = self.player # self.player = None # -# DEBUG("music._fade() post-lock", True) +# log.debug("music._fade() post-lock", True) # # fade_time = Config.FADE_TIME / 1000 # steps = Config.FADE_STEPS @@ -81,10 +81,10 @@ # sleep(sleep_time) # # with lock: -# DEBUG(f"music._fade(), stopping {p=}", True) +# log.debug(f"music._fade(), stopping {p=}", True) # # p.stop() -# DEBUG(f"Releasing player {p=}", True) +# log.debug(f"Releasing player {p=}", True) # p.release() # # self.fading -= 1 @@ -102,7 +102,7 @@ # """Return current position""" # # with lock: -# DEBUG("music.get_position", True) +# log.debug("music.get_position", True) # # print(f"get_position, {self.player=}") # if not self.player: @@ -116,17 +116,17 @@ # Log and return if path not found. # """ # -# DEBUG(f"music.play({path=})", True) +# log.debug(f"music.play({path=})", True) # # if not os.access(path, os.R_OK): -# ERROR(f"play({path}): path not found") +# log.error(f"play({path}): path not found") # return # # self.track_path = path # # self.player = self.VLC.media_player_new(path) # self.player.audio_set_volume(self.max_volume) -# DEBUG(f"music.play({path=}), {self.player}", True) +# log.debug(f"music.play({path=}), {self.player}", True) # self.player.play() # self.current_track_start_time = datetime.now() # @@ -166,7 +166,7 @@ # def stop(self): # """Immediately stop playing""" # -# DEBUG(f"music.stop(), {self.player=}", True) +# log.debug(f"music.stop(), {self.player=}", True) # # with lock: # if not self.player: @@ -174,7 +174,7 @@ # # position = self.player.get_position() # self.player.stop() -# DEBUG(f"music.stop(): Releasing player {self.player=}", True) +# log.debug(f"music.stop(): Releasing player {self.player=}", True) # self.player.release() # # Ensure we don't reference player after release # self.player = None diff --git a/app/musicmuster.py b/app/musicmuster.py index fc99fcd..6c5a602 100755 --- a/app/musicmuster.py +++ b/app/musicmuster.py @@ -1,5 +1,6 @@ #!/usr/bin/env python +from log import log # import argparse # import psutil import sys @@ -9,8 +10,6 @@ import sys # # # from datetime import datetime, timedelta -from log import EXCEPTION -# from log import DEBUG, EXCEPTION # from typing import Callable, Dict, List, Optional, Tuple # # from PyQt5.QtCore import QDate, QEvent, QProcess, Qt, QTime, QTimer, QUrl @@ -46,10 +45,12 @@ from models import ( # from ui.dlg_search_database_ui import Ui_Dialog # from ui.dlg_SelectPlaylist_ui import Ui_dlgSelectPlaylist # from ui.downloadcsv_ui import Ui_DateSelect +from config import Config from ui.main_window_ui import Ui_MainWindow # from utilities import create_track_from_file, update_db # # +# log = logging.getLogger(Config.LOG_NAME) # class TrackData: # def __init__(self, track): # self.id = track.id @@ -94,7 +95,7 @@ class Window(QMainWindow, Ui_MainWindow): # self.visible_playlist_tab: Callable[[], PlaylistTab] = \ # self.tabPlaylist.currentWidget # -# self.load_last_playlists() + #self.load_last_playlists() # self.enable_play_next_controls() # self.check_audacity() # self.timer.start(Config.TIMER_MS) @@ -144,13 +145,13 @@ class Window(QMainWindow, Ui_MainWindow): # """Don't allow window to close when a track is playing""" # # if self.music.playing(): -# DEBUG("closeEvent() ignored as music is playing") +# log.debug("closeEvent() ignored as music is playing") # event.ignore() # helpers.show_warning( # "Track playing", # "Can't close application while track is playing") # else: -# DEBUG("closeEvent() accepted") +# log.debug("closeEvent() accepted") # # with Session() as session: # record = Settings.get_int_settings( @@ -287,7 +288,7 @@ class Window(QMainWindow, Ui_MainWindow): # Disable "play next" keyboard controls # """ # -# DEBUG("disable_play_next_controls()") +# log.debug("disable_play_next_controls()") # self.actionPlay_next.setEnabled(False) # self.statusbar.showMessage("Play controls: Disabled", 0) # @@ -330,7 +331,7 @@ class Window(QMainWindow, Ui_MainWindow): # Enable "play next" keyboard controls # """ # -# DEBUG("enable_play_next_controls()") +# log.debug("enable_play_next_controls()") # self.actionPlay_next.setEnabled(True) # self.statusbar.showMessage("Play controls: Enabled", 0) # @@ -420,7 +421,7 @@ class Window(QMainWindow, Ui_MainWindow): # def fade(self) -> None: # """Fade currently playing track""" # -# DEBUG("musicmuster:fade()", True) +# log.debug("musicmuster:fade()", True) # # self.stop_playing(fade=True) # @@ -495,7 +496,7 @@ class Window(QMainWindow, Ui_MainWindow): # self.visible_playlist_tab().insert_track(session, track) # # def load_last_playlists(self): -# """Load the playlists that we loaded at end of last session""" +# """Load the playlists that were loaded at end of last session""" # # with Session() as session: # for playlist in Playlists.get_open(session): @@ -564,14 +565,14 @@ class Window(QMainWindow, Ui_MainWindow): # if title in self.info_tabs.keys(): # # We already have a tab for this track # continue -# if len(self.info_tabs) >= Config.MAX_INFO_TABS: +# if len(self.info_tabs) >= Config.MAX_log.info_TABS: # # Find an unneeded info tab # try: # old_title = list( # set(self.info_tabs.keys()) - set(title_list) # )[0] # except IndexError: -# DEBUG( +# log.debug( # f"ensure_info_tabs({title_list}): unable to add " # f"{title=}" # ) @@ -580,16 +581,16 @@ class Window(QMainWindow, Ui_MainWindow): # widget = self.info_tabs[title] = self.info_tabs[old_title] # idx = self.tabPlaylist.indexOf(widget) # self.tabPlaylist.setTabText( -# idx, title[:Config.INFO_TAB_TITLE_LENGTH]) +# idx, title[:Config.log.info_TAB_TITLE_LENGTH]) # del self.info_tabs[old_title] # else: # # Create a new tab for this title # widget = self.info_tabs[title] = QWebView() # widget.setZoomFactor(Config.WEB_ZOOM_FACTOR) # self.tabPlaylist.addTab( -# widget, title[:Config.INFO_TAB_TITLE_LENGTH]) +# widget, title[:Config.log.info_TAB_TITLE_LENGTH]) # txt = urllib.parse.quote_plus(title) -# url = Config.INFO_TAB_URL % txt +# url = Config.log.info_TAB_URL % txt # widget.setUrl(QUrl(url)) # # def play_next(self) -> None: @@ -613,7 +614,7 @@ class Window(QMainWindow, Ui_MainWindow): # - Update clocks # """ # -# DEBUG( +# log.debug( # "musicmuster.play_next(), " # f"next_track={self.next_track.title if self.next_track else None} " # "current_track=" @@ -623,7 +624,7 @@ class Window(QMainWindow, Ui_MainWindow): # # # If there is no next track set, return. # if not self.next_track: -# DEBUG("musicmuster.play_next(): no next track selected", True) +# log.debug("musicmuster.play_next(): no next track selected", True) # return # # with Session() as session: @@ -772,13 +773,13 @@ class Window(QMainWindow, Ui_MainWindow): # title = self.current_track.title # if title: # txt = urllib.parse.quote_plus(title) -# url = Config.INFO_TAB_URL % txt +# url = Config.log.info_TAB_URL % txt # webbrowser.open(url, new=2) # # def stop(self) -> None: # """Stop playing immediately""" # -# DEBUG("musicmuster.stop()") +# log.debug("musicmuster.stop()") # # self.stop_playing(fade=False) # @@ -793,20 +794,20 @@ class Window(QMainWindow, Ui_MainWindow): # - Run end-of-track actions # """ # -# DEBUG(f"musicmuster.stop_playing({fade=})", True) +# log.debug(f"musicmuster.stop_playing({fade=})", True) # # # Return if not playing # if not self.playing: -# DEBUG("musicmuster.stop_playing(): not playing", True) +# log.debug("musicmuster.stop_playing(): not playing", True) # return # # # Stop/fade track # self.previous_track_position = self.music.get_position() # if fade: -# DEBUG("musicmuster.stop_playing(): fading music", True) +# log.debug("musicmuster.stop_playing(): fading music", True) # self.music.fade() # else: -# DEBUG("musicmuster.stop_playing(): stopping music", True) +# log.debug("musicmuster.stop_playing(): stopping music", True) # self.music.stop() # # # Reset playlist_tab colour @@ -1157,11 +1158,11 @@ if __name__ == "__main__": # # # Run as required # if args.update: - # DEBUG("Updating database") + # log.debug("Updating database") # with Session() as session: # update_db(session) # # elif args.full_update: - # # DEBUG("Full update of database") + # # log.debug("Full update of database") # # with Session() as session: # # full_update_db(session) # else: @@ -1173,4 +1174,5 @@ if __name__ == "__main__": win.show() sys.exit(app.exec()) except Exception: - EXCEPTION("Unhandled Exception caught by musicmuster.main()") + msg = "Unhandled Exception caught by musicmuster.main()" + log.exception(msg, exc_info=True, stack_info=True) diff --git a/app/playlists.py b/app/playlists.py index 8b70254..8d9a317 100644 --- a/app/playlists.py +++ b/app/playlists.py @@ -28,7 +28,7 @@ # from config import Config # from datetime import datetime, timedelta # from helpers import get_relative_date, open_in_audacity -# from log import DEBUG, ERROR +# from log import log.debug, log.error # from models import ( # Notes, # Playdates, @@ -230,7 +230,7 @@ # self.scrollToItem(self.item(row, 1)) # super().dropEvent(event) # -# DEBUG( +# log.debug( # "playlist.dropEvent(): " # f"Moved row(s) {rows} to become row {drop_row}" # ) @@ -258,7 +258,7 @@ # item = self.itemAt(event.pos()) # if item is not None: # row = item.row() -# DEBUG(f"playlist.eventFilter(): Right-click on row {row}") +# log.debug(f"playlist.eventFilter(): Right-click on row {row}") # current = row == self._get_current_track_row() # next_row = row == self._get_next_track_row() # self.menu = QMenu(self) @@ -300,7 +300,7 @@ # def closeEvent(self, event) -> None: # """Save column widths""" # -# DEBUG(f"playlists.closeEvent()") +# log.debug(f"playlists.closeEvent()") # with Session() as session: # for column in range(self.columnCount()): # width = self.columnWidth(column) @@ -381,7 +381,7 @@ # row = self.currentRow() # else: # row = self.rowCount() -# DEBUG( +# log.debug( # f"playlists.insert_track({session=}, {track=}, {repaint=}), " # f"{row=}" # ) @@ -613,7 +613,7 @@ # session.add(note) # playlist_notes[note.id] = note # if row != note.row: -# DEBUG(f"Updating: {playlist.name=}, {row=}, {note.row=}") +# log.debug(f"Updating: {playlist.name=}, {row=}, {note.row=}") # note.update(session=session, row=row) # # # Database @@ -626,7 +626,7 @@ # # # Notes to remove from database # for note_id in set(database_notes.keys()) - set(playlist_notes.keys()): -# DEBUG( +# log.debug( # "_save_playlist(): " # f"Delete {note_id=} from {self=} in database" # ) @@ -635,7 +635,7 @@ # # Note rows to update in playlist database # for note_id in set(playlist_notes.keys()) & set(database_notes.keys()): # if playlist_notes[note_id].row != database_notes[note_id].row: -# DEBUG( +# log.debug( # f"_save_playlist(): Update notes row in database " # f"from {database_notes[note_id]=} " # f"to {playlist_notes[note_id]=}" @@ -973,7 +973,7 @@ # def _audacity(self, row: int) -> None: # """Open track in Audacity. Audacity must be already running""" # -# DEBUG(f"_audacity({row})") +# log.debug(f"_audacity({row})") # # if row in self._get_notes_rows(): # return None @@ -1003,7 +1003,7 @@ # Otherwise, return None. # """ # -# DEBUG(f"_copy_path({row})") +# log.debug(f"_copy_path({row})") # # if row in self._get_notes_rows(): # return None @@ -1024,7 +1024,7 @@ # return # # new_text: str = self.item(row, column).text() -# DEBUG(f"_cell_changed({row=}, {column=}, {new_text=}") +# log.debug(f"_cell_changed({row=}, {column=}, {new_text=}") # # with Session() as session: # if row in self._get_notes_rows(): @@ -1035,14 +1035,14 @@ # start_time = self._get_note_text_time(new_text) # if start_time: # self._set_row_start_time(row, start_time) -# DEBUG( +# log.debug( # f"_cell_changed:Note {new_text} contains valid " # f"{start_time=}" # ) # else: # # Reset row start time in case it used to have one # self._set_row_start_time(row, None) -# DEBUG( +# log.debug( # f"_cell_changed:Note {new_text} does not contain " # "start time" # ) @@ -1053,12 +1053,12 @@ # elif column == self.COL_TITLE: # track.update_title(session, title=new_text) # else: -# ERROR("_cell_changed(): unrecognised column") +# log.error("_cell_changed(): unrecognised column") # # def _cell_edit_ended(self) -> None: # """Called when cell edit ends""" # -# DEBUG("_cell_edit_ended()") +# log.debug("_cell_edit_ended()") # # self.editing_cell = False # @@ -1075,7 +1075,7 @@ # that keys work during edit. # """ # -# DEBUG(f"_cell_edit_started({row=}, {column=})") +# log.debug(f"_cell_edit_started({row=}, {column=})") # # self.editing_cell = True # # Disable play controls so that keyboard input doesn't disturb playing @@ -1119,7 +1119,7 @@ # def _delete_rows(self) -> None: # """Delete mutliple rows""" # -# DEBUG("playlist._delete_rows()") +# log.debug("playlist._delete_rows()") # # selected_rows: List[int] = sorted( # set(item.row() for item in self.selectedItems()) @@ -1378,7 +1378,7 @@ # # if row is None: # row = self.rowCount() -# DEBUG(f"playlist.inset_note(): row={row}") +# log.debug(f"playlist.inset_note(): row={row}") # # self.insertRow(row) # @@ -1493,7 +1493,7 @@ # if len(matches) <= 1: # return matches # else: -# ERROR( +# log.error( # f"Multiple matches for metadata '{metadata}' found " # f"in rows: {', '.join([str(x) for x in matches])}" # ) @@ -1516,7 +1516,7 @@ # def _mplayer(self, row: int) -> None: # """Play track with mplayer""" # -# DEBUG(f"_mplayer({row})") +# log.debug(f"_mplayer({row})") # # if row in self._get_notes_rows(): # return None @@ -1534,7 +1534,7 @@ # Otherwise, return None. # """ # -# DEBUG(f"_rescan({row=})") +# log.debug(f"_rescan({row=})") # # with Session() as session: # if row in self._get_track_rows(): @@ -1650,7 +1650,7 @@ # - Notify musicmuster # """ # -# DEBUG(f"_set_next({row=})") +# log.debug(f"_set_next({row=})") # # # Check row is a track row # if row in self._get_notes_rows(): @@ -1740,7 +1740,7 @@ # duration = helpers.ms_to_mmss(ms) # note_object = self._get_row_notes_object(start_row, session) # if not note_object: -# ERROR("Can't get note_object in playlists._set_timed_section") +# log.error("Can't get note_object in playlists._set_timed_section") # note_text = note_object.note # caveat = "" # if no_end: @@ -1754,7 +1754,7 @@ # Update the passed row with info from the passed track. # """ # -# DEBUG(f"_update_row({row=}, {track=}") +# log.debug(f"_update_row({row=}, {track=}") # # item_startgap: QTableWidgetItem = self.item(row, self.COL_MSS) # item_startgap.setText(str(track.start_gap)) diff --git a/app/utilities.py b/app/utilities.py index 5cfb8f0..0377fda 100755 --- a/app/utilities.py +++ b/app/utilities.py @@ -14,7 +14,7 @@ # leading_silence, # trailing_silence, # ) -# from log import DEBUG, INFO +# from log import log.debug, log.info # from models import Notes, Playdates, Session, Tracks # from mutagen.flac import FLAC # from mutagen.mp3 import MP3 @@ -27,7 +27,7 @@ # def main(): # """Main loop""" # -# DEBUG("Starting") +# log.debug("Starting") # # p = argparse.ArgumentParser() # # Only allow one option to be specified @@ -42,17 +42,17 @@ # # # Run as required # if args.update: -# DEBUG("Updating database") +# log.debug("Updating database") # with Session() as session: # update_db(session) # elif args.full_update: -# DEBUG("Full update of database") +# log.debug("Full update of database") # with Session() as session: # full_update_db(session) # else: -# INFO("No action specified") +# log.info("No action specified") # -# DEBUG("Finished") +# log.debug("Finished") # # # def create_track_from_file(session, path, normalise=None, tags=None): @@ -85,7 +85,7 @@ # # Check type # ftype = os.path.splitext(path)[1][1:] # if ftype not in ['mp3', 'flac']: -# INFO(f"File type {ftype} not implemented") +# log.info(f"File type {ftype} not implemented") # return track # # # Get current file gid, uid and permissions @@ -95,7 +95,7 @@ # fd, temp_path = tempfile.mkstemp() # shutil.copyfile(path, temp_path) # except Exception as err: -# DEBUG(f"songdb.create_track_from_file({path}): err1: {repr(err)}") +# log.debug(f"songdb.create_track_from_file({path}): err1: {repr(err)}") # return # # # Overwrite original file with normalised output @@ -118,7 +118,7 @@ # dst[tag] = src[tag] # dst.save() # except Exception as err: -# DEBUG(f"songdb.create_track_from_file({path}): err2: {repr(err)}") +# log.debug(f"songdb.create_track_from_file({path}): err2: {repr(err)}") # # Restore original file # shutil.copyfile(path, temp_path) # finally: @@ -132,7 +132,7 @@ # """Rescan all entries in database""" # # def log(msg): -# INFO(f"full_update_db(): {msg}") +# log.info(f"full_update_db(): {msg}") # # def check_change(track_id, title, attribute, old, new): # if new > (old * 1.1) or new < (old * 0.9): @@ -235,7 +235,7 @@ # # track = Tracks.get_by_path(session, path) # if not track: -# ERROR(f"update_db: {path} not found in db") +# log.error(f"update_db: {path} not found in db") # continue # # paths_not_found.append(track) @@ -264,7 +264,7 @@ # # Spike # # # # # Manage tracks listed in database but where path is invalid -# # DEBUG(f"Invalid {path=} in database", True) +# # log.debug(f"Invalid {path=} in database", True) # # track = Tracks.get_by_path(session, path) # # messages.append(f"Remove from database: {path=} {track=}") # # @@ -279,10 +279,10 @@ # # for playlist_track in track.playlists: # # row = playlist_track.row # # # Remove playlist entry -# # DEBUG(f"Remove {row=} from {playlist_track.playlist_id}", True) +# # log.debug(f"Remove {row=} from {playlist_track.playlist_id}", True) # # playlist_track.playlist.remove_track(session, row) # # # Create note -# # DEBUG(f"Add note at {row=} to {playlist_track.playlist_id=}", True) +# # log.debug(f"Add note at {row=} to {playlist_track.playlist_id=}", True) # # Notes(session, playlist_track.playlist_id, row, note_txt) # # # # # Remove Track entry pointing to invalid path