[gnome-music/wip/mschraal/glib-logging: 1/9] Add GLib logging support



commit 8169410292c5c4151b6dc34a1c120c2cf6020606
Author: Marinus Schraal <mschraal gnome org>
Date:   Tue Jan 14 10:29:40 2020 +0100

    Add GLib logging support
    
    Use the GLib logging facilities to support logging in Music.

 gnomemusic/application.py                     | 24 ++++----
 gnomemusic/artistart.py                       | 37 ++++++++-----
 gnomemusic/grilowrappers/grltrackerwrapper.py | 48 +++++++++-------
 gnomemusic/musiclogger.py                     | 80 +++++++++++++++++++++++++++
 4 files changed, 145 insertions(+), 44 deletions(-)
---
diff --git a/gnomemusic/application.py b/gnomemusic/application.py
index cec31d2c..af57125b 100644
--- a/gnomemusic/application.py
+++ b/gnomemusic/application.py
@@ -31,15 +31,14 @@
 # delete this exception statement from your version.
 
 from gettext import gettext as _
-import logging
 
 from gi.repository import Gtk, Gio, GLib, Gdk, GObject
 
-from gnomemusic import log
 from gnomemusic.coremodel import CoreModel
 from gnomemusic.coreselection import CoreSelection
 from gnomemusic.inhibitsuspend import InhibitSuspend
 from gnomemusic.mpris import MPRIS
+from gnomemusic.musiclogger import MusicLogger
 from gnomemusic.pauseonsuspend import PauseOnSuspend
 from gnomemusic.player import Player
 from gnomemusic.scrobbler import LastFmScrobbler
@@ -48,10 +47,7 @@ from gnomemusic.window import Window
 
 
 class Application(Gtk.Application):
-    def __repr__(self):
-        return '<Application>'
 
-    @log
     def __init__(self, application_id):
         super().__init__(
             application_id=application_id,
@@ -64,6 +60,7 @@ class Application(Gtk.Application):
         self._init_style()
         self._window = None
 
+        self._log = MusicLogger()
         self._coreselection = CoreSelection()
         self._coremodel = CoreModel(self)
 
@@ -82,6 +79,16 @@ class Application(Gtk.Application):
         style_context.add_provider_for_screen(
             screen, css_provider, Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION)
 
+    @GObject.Property(
+        type=MusicLogger, default=None, flags=GObject.ParamFlags.READABLE)
+    def log(self):
+        """Get application-wide logging facility.
+
+        :returns: the logger
+        :rtype: MusicLogger
+        """
+        return self._log
+
     @GObject.Property(
         type=Player, default=None, flags=GObject.ParamFlags.READABLE)
     def player(self):
@@ -140,7 +147,6 @@ class Application(Gtk.Application):
         """
         return self._window
 
-    @log
     def _set_actions(self):
         action_entries = [
             ('about', self._about, None),
@@ -155,25 +161,21 @@ class Application(Gtk.Application):
             if accel is not None:
                 self.set_accels_for_action(*accel)
 
-    @log
     def _help(self, action, param):
         try:
             Gtk.show_uri(None, "help:gnome-music", Gdk.CURRENT_TIME)
         except GLib.Error:
-            logging.warning("Help handler not available.")
+            self._log.message("Help handler not available.")
 
-    @log
     def _about(self, action, param):
         about = AboutDialog()
         about.props.transient_for = self._window
         about.present()
 
-    @log
     def do_startup(self):
         Gtk.Application.do_startup(self)
         self._set_actions()
 
-    @log
     def _quit(self, action=None, param=None):
         self._window.destroy()
 
diff --git a/gnomemusic/artistart.py b/gnomemusic/artistart.py
index 907cbc42..08b11baa 100644
--- a/gnomemusic/artistart.py
+++ b/gnomemusic/artistart.py
@@ -23,7 +23,6 @@
 # delete this exception statement from your version.
 
 from enum import Enum
-import logging
 from math import pi
 
 import cairo
@@ -31,8 +30,7 @@ import gi
 gi.require_version("MediaArt", "2.0")
 from gi.repository import Gdk, GdkPixbuf, Gio, GLib, GObject, Gtk, MediaArt
 
-
-logger = logging.getLogger(__name__)
+from gnomemusic.musiclogger import MusicLogger
 
 
 def _make_icon_frame(icon_surface, art_size=None, scale=1, default_icon=False):
@@ -127,6 +125,8 @@ class DefaultIcon(GObject.GObject):
 
 class ArtistArt(GObject.GObject):
 
+    _log = MusicLogger()
+
     def __init__(self, coreartist, coremodel):
         """Initialize the ArtistArt.
 
@@ -175,14 +175,16 @@ class ArtistArt(GObject.GObject):
         try:
             istream = src.read_finish(result)
         except GLib.Error as error:
-            logger.warning("Error: {}, {}".format(error.domain, error.message))
+            self._log.warning(
+                "Error: {}, {}".format(error.domain, error.message))
             self._coreartist.props.cached_thumbnail_uri = ""
             return
 
         try:
             [tmp_file, iostream] = Gio.File.new_tmp()
         except GLib.Error as error:
-            logger.warning("Error: {}, {}".format(error.domain, error.message))
+            self._log.warning(
+                "Error: {}, {}".format(error.domain, error.message))
             self._coreartist.props.cached_thumbnail_uri = ""
             return
 
@@ -198,7 +200,8 @@ class ArtistArt(GObject.GObject):
         try:
             src.delete_finish(result)
         except GLib.Error as error:
-            logger.warning("Error: {}, {}".format(error.domain, error.message))
+            self._log.warning(
+                "Error: {}, {}".format(error.domain, error.message))
 
     def _splice_callback(self, src, result, data):
         tmp_file, iostream = data
@@ -209,7 +212,8 @@ class ArtistArt(GObject.GObject):
         try:
             src.splice_finish(result)
         except GLib.Error as error:
-            logger.warning("Error: {}, {}".format(error.domain, error.message))
+            self._log.warning(
+                "Error: {}, {}".format(error.domain, error.message))
             self._coreartist.props.cached_thumbnail_uri = ""
             return
 
@@ -223,7 +227,8 @@ class ArtistArt(GObject.GObject):
             # FIXME: I/O blocking
             MediaArt.file_to_jpeg(tmp_file.get_path(), cache_path)
         except GLib.Error as error:
-            logger.warning("Error: {}, {}".format(error.domain, error.message))
+            self._log.warning(
+                "Error: {}, {}".format(error.domain, error.message))
             self._coreartist.props.cached_thumbnail_uri = ""
             return
 
@@ -236,7 +241,8 @@ class ArtistArt(GObject.GObject):
         try:
             src.close_finish(result)
         except GLib.Error as error:
-            logger.warning("Error: {}, {}".format(error.domain, error.message))
+            self._log.warning(
+                "Error: {}, {}".format(error.domain, error.message))
 
 
 class ArtistCache(GObject.GObject):
@@ -251,6 +257,8 @@ class ArtistCache(GObject.GObject):
         "result": (GObject.SignalFlags.RUN_FIRST, None, (object, ))
     }
 
+    _log = MusicLogger()
+
     def __repr__(self):
         return "<ArtistCache>"
 
@@ -279,7 +287,7 @@ class ArtistCache(GObject.GObject):
             try:
                 cache_dir_file.make_directory(None)
             except GLib.Error as error:
-                logger.warning(
+                self._log.warning(
                     "Error: {}, {}".format(error.domain, error.message))
 
     def query(self, coreartist):
@@ -306,7 +314,8 @@ class ArtistCache(GObject.GObject):
         try:
             stream = thumb_file.read_finish(result)
         except GLib.Error as error:
-            logger.warning("Error: {}, {}".format(error.domain, error.message))
+            self._log.warning(
+                "Error: {}, {}".format(error.domain, error.message))
             self.emit("result", self._default_icon)
             return
 
@@ -317,7 +326,8 @@ class ArtistCache(GObject.GObject):
         try:
             pixbuf = GdkPixbuf.Pixbuf.new_from_stream_finish(result)
         except GLib.Error as error:
-            logger.warning("Error: {}, {}".format(error.domain, error.message))
+            self._log.warning(
+                "Error: {}, {}".format(error.domain, error.message))
             self.emit("result", self._default_icon)
             return
 
@@ -333,4 +343,5 @@ class ArtistCache(GObject.GObject):
         try:
             stream.close_finish(result)
         except GLib.Error as error:
-            logger.warning("Error: {}, {}".format(error.domain, error.message))
+            self._log.warning(
+                "Error: {}, {}".format(error.domain, error.message))
diff --git a/gnomemusic/grilowrappers/grltrackerwrapper.py b/gnomemusic/grilowrappers/grltrackerwrapper.py
index debe4d21..86596609 100644
--- a/gnomemusic/grilowrappers/grltrackerwrapper.py
+++ b/gnomemusic/grilowrappers/grltrackerwrapper.py
@@ -82,6 +82,7 @@ class GrlTrackerWrapper(GObject.GObject):
         self._coreselection = application.props.coreselection
         self._grilo = grilo
         self._source = source
+        self._log = application.props.log
         self._model = self._coremodel.props.songs
         self._albums_model = self._coremodel.props.albums
         self._album_ids = {}
@@ -141,10 +142,12 @@ class GrlTrackerWrapper(GObject.GObject):
             # it means 'added' to Music.
             if (change_type == Grl.SourceChangeType.CHANGED
                     or change_type == Grl.SourceChangeType.ADDED):
-                print("ADDED/CHANGED", media_ids)
+                self._log.debug(
+                    "Added/Changed media(s): {}".format(media_ids))
                 self._changed_media(media_ids)
             elif change_type == Grl.SourceChangeType.REMOVED:
-                print("REMOVED", media_ids)
+                self._log.debug(
+                    "Removed media(s): {}".format(media_ids))
                 self._remove_media(media_ids)
 
         self._check_album_change()
@@ -181,13 +184,15 @@ class GrlTrackerWrapper(GObject.GObject):
 
         def check_album_cb(source, op_id, media, user_data, error):
             if error:
-                print("ERROR", error)
+                self._log.warning("Error: {}".format(error))
                 return
 
             if not media:
                 changed_ids = set(
                     album_ids.keys()) ^ set(self._album_ids.keys())
-                print("ALBUMS CHANGED", changed_ids)
+
+                self._log.debug(
+                    "Albums changed ID's: {}".format(changed_ids))
 
                 for key in changed_ids:
                     if key in album_ids:
@@ -240,13 +245,14 @@ class GrlTrackerWrapper(GObject.GObject):
 
         def check_artist_cb(source, op_id, media, user_data, error):
             if error:
-                print("ERROR", error)
+                self._log.warning("Error: {}".format(error))
                 return
 
             if not media:
                 changed_ids = set(
                     artist_ids.keys()) ^ set(self._artist_ids.keys())
-                print("ARTISTS CHANGED", changed_ids)
+                self._log.debug(
+                    "Artists changed ID's: {}".format(changed_ids))
 
                 for key in changed_ids:
                     if key in artist_ids:
@@ -277,14 +283,14 @@ class GrlTrackerWrapper(GObject.GObject):
             try:
                 coresong = self._hash.pop(media_id)
             except KeyError:
-                print("Removal KeyError")
+                self._log.warning("Removal KeyError.")
                 return
 
             for idx, coresong_model in enumerate(self._model):
                 if coresong_model is coresong:
-                    print(
-                        "removing", coresong.props.media.get_id(),
-                        coresong.props.title)
+                    self._log.debug("Removing: {}, {}".format(
+                        coresong.props.media.get_id(), coresong.props.title))
+
                     self._model.remove(idx)
                     break
 
@@ -327,14 +333,16 @@ class GrlTrackerWrapper(GObject.GObject):
 
         def _update_changed_media(source, op_id, media, user_data, error):
             if error:
-                print("ERROR", error)
+                self._log.warning("Error: {}".format(error))
                 return
 
             if not media:
                 return
 
             if media.get_id() not in self._hash:
-                print("Media not in hash", media.get_id())
+                self._log.debug(
+                    "Media {} not in hash".format(media.get_id()))
+
                 song = CoreSong(media, self._coreselection, self._grilo)
                 self._model.append(song)
                 self._hash[media.get_id()] = song
@@ -353,7 +361,7 @@ class GrlTrackerWrapper(GObject.GObject):
 
         def _add_to_model(source, op_id, media, user_data, error):
             if error:
-                print("ERROR", error)
+                self._log.warning("Error: {}".format(error))
                 self._window.notifications_popup.pop_loading()
                 return
 
@@ -407,7 +415,7 @@ class GrlTrackerWrapper(GObject.GObject):
 
         def _add_to_albums_model(source, op_id, media, user_data, error):
             if error:
-                print("ERROR", error)
+                self._log.warning("Error: {}".format(error))
                 self._window.notifications_popup.pop_loading()
                 return
 
@@ -461,7 +469,7 @@ class GrlTrackerWrapper(GObject.GObject):
 
         def _add_to_artists_model(source, op_id, media, user_data, error):
             if error:
-                print("ERROR", error)
+                self._log.warning("Error: {}".format(error))
                 self._window.notifications_popup.pop_loading()
                 return
 
@@ -544,7 +552,7 @@ class GrlTrackerWrapper(GObject.GObject):
 
         def query_cb(source, op_id, media, user_data, error):
             if error:
-                print("ERROR", error)
+                self._log.warning("Error: {}".format(error))
                 self._window.notifications_popup.pop_loading()
                 return
 
@@ -594,7 +602,7 @@ class GrlTrackerWrapper(GObject.GObject):
 
         def _disc_nr_cb(source, op_id, media, user_data, error):
             if error:
-                print("ERROR", error)
+                self._log.warning("Error: {}".format(error))
                 self._window.notifications_popup.pop_loading()
                 return
 
@@ -708,7 +716,7 @@ class GrlTrackerWrapper(GObject.GObject):
 
         def artist_search_cb(source, op_id, media, data, error):
             if error:
-                print("ERROR", error)
+                self._log.warning("Error: {}".format(error))
                 self._window.notifications_popup.pop_loading()
                 return
 
@@ -763,7 +771,7 @@ class GrlTrackerWrapper(GObject.GObject):
 
         def albums_search_cb(source, op_id, media, data, error):
             if error:
-                print("ERROR", error)
+                self._log.warning("Error: {}".format(error))
                 self._window.notifications_popup.pop_loading()
                 return
 
@@ -824,7 +832,7 @@ class GrlTrackerWrapper(GObject.GObject):
 
         def songs_search_cb(source, op_id, media, data, error):
             if error:
-                print("ERROR", error)
+                self._log.warning("Error: {}".format(error))
                 self._window.notifications_popup.pop_loading()
                 return
 
diff --git a/gnomemusic/musiclogger.py b/gnomemusic/musiclogger.py
new file mode 100644
index 00000000..928b50c1
--- /dev/null
+++ b/gnomemusic/musiclogger.py
@@ -0,0 +1,80 @@
+# Copyright 2020 The GNOME Music developers
+#
+# GNOME Music is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# GNOME Music is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along
+# with GNOME Music; if not, write to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# The GNOME Music authors hereby grant permission for non-GPL compatible
+# GStreamer plugins to be used and distributed together with GStreamer
+# and GNOME Music.  This permission is above and beyond the permissions
+# granted by the GPL license by which GNOME Music is covered.  If you
+# modify this code, you may extend this exception to your version of the
+# code, but you are not obligated to do so.  If you do not wish to do so,
+# delete this exception statement from your version.
+
+from gi.repository import GLib, GObject
+
+
+class MusicLogger(GObject.GObject):
+    """GLib logging wrapper
+
+    A tiny wrapper aroung the default GLib logger.
+
+    * Message is for user facing warnings, which ideally should be in
+      the application.
+    * Warning is for logging non-fatal errors during execution.
+    * Debug is for developer use as a way to get more runtime info.
+    """
+
+    _DOMAIN = "org.gnome.Music"
+
+    def _log(self, message, level):
+        variant_message = GLib.Variant("s", message)
+        variant_dict = GLib.Variant("a{sv}", {"MESSAGE": variant_message})
+        GLib.log_variant(self._DOMAIN, level, variant_dict)
+
+    def message(self, message):
+        """The default user facing message
+
+        Wraps g_message.
+
+        :param string message: Message
+        """
+        self._log(message, GLib.LogLevelFlags.LEVEL_MESSAGE)
+
+    def warning(self, message):
+        """Warning message
+
+        Wraps g_warning.
+
+        :param string message: Warning message
+        """
+        self._log(message, GLib.LogLevelFlags.LEVEL_WARNING)
+
+    def info(self, message):
+        """Informational message
+
+        Wraps g_info.
+
+        :param string message: Informational message
+        """
+        self._log(message, GLib.LogLevelFlags.LEVEL_INFO)
+
+    def debug(self, message):
+        """Debug message
+
+        Wraps g_debug.
+
+        :param string message: Debug message
+        """
+        self._log(message, GLib.LogLevelFlags.LEVEL_DEBUG)


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]