diff options
| author | Volpeon <git@volpeon.ink> | 2021-02-27 18:53:24 +0100 | 
|---|---|---|
| committer | Volpeon <git@volpeon.ink> | 2021-02-27 18:53:24 +0100 | 
| commit | 1ded730280cfdc8b448f3cd39b91ffd5e45cb019 (patch) | |
| tree | 74df0d35f54aabe3d0e35a059f3335dc88548853 | |
| parent | Cleanup (diff) | |
| download | mpris-to-text-1ded730280cfdc8b448f3cd39b91ffd5e45cb019.tar.gz mpris-to-text-1ded730280cfdc8b448f3cd39b91ffd5e45cb019.tar.bz2 mpris-to-text-1ded730280cfdc8b448f3cd39b91ffd5e45cb019.zip | |
Ran formatter, fixed missing output with current blessing package
| -rwxr-xr-x | mpris_to_text.py | 218 | 
1 files changed, 117 insertions, 101 deletions
| diff --git a/mpris_to_text.py b/mpris_to_text.py index 24baabf..c5d65d8 100755 --- a/mpris_to_text.py +++ b/mpris_to_text.py | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | #!/usr/bin/python | 1 | #!/usr/bin/env python | 
| 2 | 2 | ||
| 3 | import sys | 3 | import sys | 
| 4 | import re | 4 | import re | 
| @@ -17,29 +17,31 @@ dbus.mainloop.glib.DBusGMainLoop(set_as_default=True) | |||
| 17 | 17 | ||
| 18 | 18 | ||
| 19 | class MetaWriter: | 19 | class MetaWriter: | 
| 20 | filename = "" | 20 | filename = "" | 
| 21 | output_format = "" | 21 | output_format = "" | 
| 22 | output_format_artist = "" | 22 | output_format_artist = "" | 
| 23 | output_format_title = "" | 23 | output_format_title = "" | 
| 24 | output_format_album = "" | 24 | output_format_album = "" | 
| 25 | last_output = "" | 25 | last_output = "" | 
| 26 | 26 | ||
| 27 | def __init__(self, filename, output_format, output_format_artist, output_format_title, output_format_album): | 27 | def __init__(self, filename, output_format, output_format_artist, output_format_title, output_format_album): | 
| 28 | self.filename = filename | 28 | self.filename = filename | 
| 29 | self.output_format = output_format | 29 | self.output_format = output_format | 
| 30 | self.output_format_album = output_format_album | 30 | self.output_format_album = output_format_album | 
| 31 | self.output_format_artist = output_format_artist | 31 | self.output_format_artist = output_format_artist | 
| 32 | self.output_format_title = output_format_title | 32 | self.output_format_title = output_format_title | 
| 33 | 33 | ||
| 34 | def write_meta(self, metadata): | 34 | def write_meta(self, metadata): | 
| 35 | artist = metadata["xesam:artist"][0] if "xesam:artist" in metadata else "" | 35 | artist = metadata["xesam:artist"][0] if "xesam:artist" in metadata else "" | 
| 36 | title = metadata["xesam:title"] if "xesam:title" in metadata else "" | 36 | title = metadata["xesam:title"] if "xesam:title" in metadata else "" | 
| 37 | album = metadata["xesam:album"] if "xesam:album" in metadata else "" | 37 | album = metadata["xesam:album"] if "xesam:album" in metadata else "" | 
| 38 | 38 | ||
| 39 | self.write(self.output_format.format( | 39 | self.write(self.output_format.format( | 
| 40 | artist = self.output_format_artist.format(artist) if artist != "" else "", | 40 | artist=self.output_format_artist.format( | 
| 41 | title = self.output_format_title.format(title) if title != "" else "", | 41 | artist) if artist != "" else "", | 
| 42 | album = self.output_format_album.format(album) if album != "" else "" | 42 | title=self.output_format_title.format( | 
| 43 | title) if title != "" else "", | ||
| 44 | album=self.output_format_album.format(album) if album != "" else "" | ||
| 43 | )) | 45 | )) | 
| 44 | 46 | ||
| 45 | def write(self, text): | 47 | def write(self, text): | 
| @@ -50,43 +52,48 @@ class MetaWriter: | |||
| 50 | 52 | ||
| 51 | 53 | ||
| 52 | class PlayerSelector(threading.Thread): | 54 | class PlayerSelector(threading.Thread): | 
| 53 | service_regex = re.compile("^org\.mpris\.MediaPlayer2\.") | 55 | service_regex = re.compile("^org\.mpris\.MediaPlayer2\.") | 
| 54 | bus = None | 56 | bus = None | 
| 55 | loop = None | 57 | loop = None | 
| 56 | signal_receiver = None | 58 | signal_receiver = None | 
| 57 | players = {} | 59 | players = {} | 
| 58 | players_indexes = [] | 60 | players_indexes = [] | 
| 59 | active_player = "" | 61 | active_player = "" | 
| 60 | menu = None | 62 | menu = None | 
| 61 | meta_writer = None | 63 | meta_writer = None | 
| 62 | 64 | ||
| 63 | def __init__(self, meta_writer, menu=None): | 65 | def __init__(self, meta_writer, menu=None): | 
| 64 | super().__init__() | 66 | super().__init__() | 
| 65 | 67 | ||
| 66 | self.bus = dbus.SessionBus() | 68 | self.bus = dbus.SessionBus() | 
| 67 | self.meta_writer = meta_writer | 69 | self.meta_writer = meta_writer | 
| 68 | self.menu = menu | 70 | self.menu = menu | 
| 69 | 71 | ||
| 70 | def set_menu(self, menu): | 72 | def set_menu(self, menu): | 
| 71 | self.menu = menu | 73 | self.menu = menu | 
| 72 | 74 | ||
| 73 | def get_players(self): | 75 | def get_players(self): | 
| 74 | self.players = {} | 76 | self.players = {} | 
| 75 | self.players_indexes = [] | 77 | self.players_indexes = [] | 
| 76 | 78 | ||
| 77 | bus_path = self.bus.get_object("org.freedesktop.DBus", "/org/freedesktop/DBus") | 79 | bus_path = self.bus.get_object( | 
| 80 | "org.freedesktop.DBus", "/org/freedesktop/DBus") | ||
| 78 | bus_proxy = dbus.Interface(bus_path, "org.freedesktop.DBus") | 81 | bus_proxy = dbus.Interface(bus_path, "org.freedesktop.DBus") | 
| 79 | 82 | ||
| 80 | for service in bus_proxy.ListNames(): | 83 | for service in bus_proxy.ListNames(): | 
| 81 | if self.service_regex.match(service): | 84 | if self.service_regex.match(service): | 
| 82 | split_service = service.split(".") | 85 | split_service = service.split(".") | 
| 83 | name_start_index = len(split_service[0]) + len(split_service[1]) + len(split_service[2]) + 3 | 86 | name_start_index = len( | 
| 87 | split_service[0]) + len(split_service[1]) + len(split_service[2]) + 3 | ||
| 84 | 88 | ||
| 85 | player_path = self.bus.get_object(service, "/org/mpris/MediaPlayer2") | 89 | player_path = self.bus.get_object( | 
| 86 | player_props = dbus.Interface(player_path, "org.freedesktop.DBus.Properties") | 90 | service, "/org/mpris/MediaPlayer2") | 
| 87 | player_name = service[name_start_index:] | 91 | player_props = dbus.Interface( | 
| 92 | player_path, "org.freedesktop.DBus.Properties") | ||
| 93 | player_name = service[name_start_index:] | ||
| 88 | try: | 94 | try: | 
| 89 | player_name = player_props.Get("org.mpris.MediaPlayer2.Player", "Identity") | 95 | player_name = player_props.Get( | 
| 96 | "org.mpris.MediaPlayer2.Player", "Identity") | ||
| 90 | except dbus.exceptions.DBusException: | 97 | except dbus.exceptions.DBusException: | 
| 91 | pass | 98 | pass | 
| 92 | 99 | ||
| @@ -112,35 +119,39 @@ class PlayerSelector(threading.Thread): | |||
| 112 | 119 | ||
| 113 | if self.active_player != "": | 120 | if self.active_player != "": | 
| 114 | self.signal_receiver = self.bus.add_signal_receiver( | 121 | self.signal_receiver = self.bus.add_signal_receiver( | 
| 115 | handler_function = self.playing_song_changed, | 122 | handler_function=self.playing_song_changed, | 
| 116 | bus_name = self.active_player, | 123 | bus_name=self.active_player, | 
| 117 | dbus_interface = "org.freedesktop.DBus.Properties", | 124 | dbus_interface="org.freedesktop.DBus.Properties", | 
| 118 | signal_name = "PropertiesChanged", | 125 | signal_name="PropertiesChanged", | 
| 119 | path = "/org/mpris/MediaPlayer2" | 126 | path="/org/mpris/MediaPlayer2" | 
| 120 | ) | 127 | ) | 
| 121 | 128 | ||
| 122 | player_path = self.bus.get_object(self.active_player, "/org/mpris/MediaPlayer2") | 129 | player_path = self.bus.get_object( | 
| 123 | player_props = dbus.Interface(player_path, "org.freedesktop.DBus.Properties") | 130 | self.active_player, "/org/mpris/MediaPlayer2") | 
| 131 | player_props = dbus.Interface( | ||
| 132 | player_path, "org.freedesktop.DBus.Properties") | ||
| 124 | 133 | ||
| 125 | self.meta_writer.write_meta(player_props.Get("org.mpris.MediaPlayer2.Player", "Metadata")) | 134 | self.meta_writer.write_meta(player_props.Get( | 
| 135 | "org.mpris.MediaPlayer2.Player", "Metadata")) | ||
| 126 | else: | 136 | else: | 
| 127 | self.meta_writer.write("") | 137 | self.meta_writer.write("") | 
| 128 | 138 | ||
| 129 | |||
| 130 | def run(self): | 139 | def run(self): | 
| 131 | bus_path = self.bus.get_object("org.freedesktop.DBus", "/org/freedesktop/DBus") | 140 | bus_path = self.bus.get_object( | 
| 141 | "org.freedesktop.DBus", "/org/freedesktop/DBus") | ||
| 132 | bus_proxy = dbus.Interface(bus_path, "org.freedesktop.DBus") | 142 | bus_proxy = dbus.Interface(bus_path, "org.freedesktop.DBus") | 
| 133 | bus_proxy.connect_to_signal("NameOwnerChanged", self.dbus_name_owner_changed) | 143 | bus_proxy.connect_to_signal( | 
| 144 | "NameOwnerChanged", self.dbus_name_owner_changed) | ||
| 134 | 145 | ||
| 135 | self.get_players() | 146 | self.get_players() | 
| 136 | self.menu.refresh() | 147 | self.menu.refresh() | 
| 137 | 148 | ||
| 138 | self.loop = GLib.MainLoop() | 149 | self.loop = GLib.MainLoop() | 
| 139 | self.loop.run() | 150 | self.loop.run() | 
| 140 | 151 | ||
| 141 | def quit(self): | 152 | def quit(self): | 
| 142 | self.loop.quit() | 153 | self.loop.quit() | 
| 143 | 154 | ||
| 144 | def dbus_name_owner_changed(self, name, old_owner, new_owner): | 155 | def dbus_name_owner_changed(self, name, old_owner, new_owner): | 
| 145 | if self.service_regex.match(name): | 156 | if self.service_regex.match(name): | 
| 146 | self.get_players() | 157 | self.get_players() | 
| @@ -153,36 +164,38 @@ class PlayerSelector(threading.Thread): | |||
| 153 | 164 | ||
| 154 | 165 | ||
| 155 | class Menu(threading.Thread): | 166 | class Menu(threading.Thread): | 
| 156 | refresh_cond = threading.Condition() | 167 | refresh_cond = threading.Condition() | 
| 157 | refresh_flag = True | 168 | refresh_flag = True | 
| 158 | exit_flag = False | 169 | exit_flag = False | 
| 159 | player_selector = None | 170 | player_selector = None | 
| 160 | meta_writer = None | 171 | meta_writer = None | 
| 161 | 172 | ||
| 162 | def __init__(self, term, player_selector, meta_writer): | 173 | def __init__(self, term, player_selector, meta_writer): | 
| 163 | super().__init__() | 174 | super().__init__() | 
| 164 | 175 | ||
| 165 | self.player_selector = player_selector | 176 | self.player_selector = player_selector | 
| 166 | self.meta_writer = meta_writer | 177 | self.meta_writer = meta_writer | 
| 167 | 178 | ||
| 168 | def refresh(self, exit_flag=False): | 179 | def refresh(self, exit_flag=False): | 
| 169 | with self.refresh_cond: | 180 | with self.refresh_cond: | 
| 170 | self.refresh_flag = True | 181 | self.refresh_flag = True | 
| 171 | self.exit_flag = self.exit_flag or exit_flag | 182 | self.exit_flag = self.exit_flag or exit_flag | 
| 172 | self.refresh_cond.notify() | 183 | self.refresh_cond.notify() | 
| 173 | 184 | ||
| 174 | def run(self): | 185 | def run(self): | 
| 175 | while not self.exit_flag: | 186 | with term.fullscreen(): | 
| 176 | with self.refresh_cond: | 187 | while not self.exit_flag: | 
| 177 | while not self.refresh_flag and not self.exit_flag: | 188 | with self.refresh_cond: | 
| 178 | self.refresh_cond.wait() | 189 | while not self.refresh_flag and not self.exit_flag: | 
| 190 | self.refresh_cond.wait() | ||
| 179 | 191 | ||
| 180 | self.refresh_flag = False | 192 | self.refresh_flag = False | 
| 181 | 193 | ||
| 182 | with term.fullscreen(): | 194 | print(term.clear) | 
| 183 | print(term.move(0, 0) + term.bold_bright_white_on_bright_black(("{0:<{width}}").format("MPRIS To Text", width=term.width)) + "\n") | 195 | print(term.move_xy(0, 0) + term.bold_bright_white_on_bright_black( | 
| 196 | ("{0:<{width}}").format("MPRIS To Text", width=term.width)) + "\n") | ||
| 184 | print(term.move_x(2) + term.bold("Player: ") + term.move_up()) | 197 | print(term.move_x(2) + term.bold("Player: ") + term.move_up()) | 
| 185 | 198 | ||
| 186 | for i, (id, name) in enumerate(self.player_selector.players.items()): | 199 | for i, (id, name) in enumerate(self.player_selector.players.items()): | 
| 187 | output = "%d: %s" % (i, name) | 200 | output = "%d: %s" % (i, name) | 
| 188 | 201 | ||
| @@ -191,26 +204,28 @@ class Menu(threading.Thread): | |||
| 191 | else: | 204 | else: | 
| 192 | print(term.move_x(10) + output) | 205 | print(term.move_x(10) + output) | 
| 193 | 206 | ||
| 194 | print(term.move_x(2) + term.bold("File: ") + self.meta_writer.filename) | 207 | print(term.move_x(2) + term.bold("File: ") + | 
| 195 | print(term.move_x(2) + term.bold("Output: ") + "\n".join(term.wrap(self.meta_writer.last_output, width=term.width - 10, subsequent_indent=" " * 10))) | 208 | self.meta_writer.filename) | 
| 209 | print(term.move_x(2) + term.bold("Output: ") + "\n".join(term.wrap( | ||
| 210 | self.meta_writer.last_output, width=term.width - 10, subsequent_indent=" " * 10))) | ||
| 196 | 211 | ||
| 197 | print(term.move_x(0) + "\nEnter number to select player or q to exit." + term.move_up()) | 212 | print(term.move_x( | 
| 213 | 0) + "\nEnter number to select player or q to exit." + term.move_up()) | ||
| 198 | 214 | ||
| 199 | with term.fullscreen(): | 215 | print(term.move_xy(0, 0) + "Exiting...") | 
| 200 | print(term.move(0, 0) + "Exiting...") | ||
| 201 | 216 | ||
| 202 | 217 | ||
| 203 | class Input(threading.Thread): | 218 | class Input(threading.Thread): | 
| 204 | player_selector = None | 219 | player_selector = None | 
| 205 | meta_writer = None | 220 | meta_writer = None | 
| 206 | menu = None | 221 | menu = None | 
| 207 | 222 | ||
| 208 | def __init__(self, term, player_selector, meta_writer, menu): | 223 | def __init__(self, term, player_selector, meta_writer, menu): | 
| 209 | super().__init__() | 224 | super().__init__() | 
| 210 | 225 | ||
| 211 | self.player_selector = player_selector | 226 | self.player_selector = player_selector | 
| 212 | self.meta_writer = meta_writer | 227 | self.meta_writer = meta_writer | 
| 213 | self.menu = menu | 228 | self.menu = menu | 
| 214 | 229 | ||
| 215 | def run(self): | 230 | def run(self): | 
| 216 | with term.cbreak(): | 231 | with term.cbreak(): | 
| @@ -237,50 +252,51 @@ def on_resize(*args): | |||
| 237 | 252 | ||
| 238 | 253 | ||
| 239 | def create_writer(): | 254 | def create_writer(): | 
| 240 | parser = argparse.ArgumentParser(description="Write metadata from MPRIS-compliant media players into a text file.") | 255 | parser = argparse.ArgumentParser( | 
| 256 | description="Write metadata from MPRIS-compliant media players into a text file.") | ||
| 241 | parser.add_argument("--file", | 257 | parser.add_argument("--file", | 
| 242 | type = str, | 258 | type=str, | 
| 243 | dest = "filename", | 259 | dest="filename", | 
| 244 | default = "/tmp/mpris_info.txt", | 260 | default="/tmp/mpris_info.txt", | 
| 245 | help = "Full path to file (default: \"/tmp/mpris_info.txt\")" | 261 | help="Full path to file (default: \"/tmp/mpris_info.txt\")" | 
| 246 | ) | 262 | ) | 
| 247 | parser.add_argument("--format-artist", | 263 | parser.add_argument("--format-artist", | 
| 248 | type = str, | 264 | type=str, | 
| 249 | dest = "format_artist", | 265 | dest="format_artist", | 
| 250 | default = "{} ", | 266 | default=" by {}", | 
| 251 | help = "Format string for the artist part (default: \"{} \")" | 267 | help="Format string for the artist part (default: \" by {}\")" | 
| 252 | ) | 268 | ) | 
| 253 | parser.add_argument("--format-title", | 269 | parser.add_argument("--format-title", | 
| 254 | type = str, | 270 | type=str, | 
| 255 | dest = "format_title", | 271 | dest="format_title", | 
| 256 | default = "\"{}\"", | 272 | default="\"{}\"", | 
| 257 | help = "Format string for the title part (default: \"\"{}\"\")" | 273 | help="Format string for the title part (default: \"\"{}\"\")" | 
| 258 | ) | 274 | ) | 
| 259 | parser.add_argument("--format-album", | 275 | parser.add_argument("--format-album", | 
| 260 | type = str, | 276 | type=str, | 
| 261 | dest = "format_album", | 277 | dest="format_album", | 
| 262 | default = " from \"{}\"", | 278 | default=" from \"{}\"", | 
| 263 | help = "Format string for the album part (default: \" from \"{}\"\")" | 279 | help="Format string for the album part (default: \" from \"{}\"\")" | 
| 264 | ) | 280 | ) | 
| 265 | parser.add_argument("--format", | 281 | parser.add_argument("--format", | 
| 266 | type = str, | 282 | type=str, | 
| 267 | dest = "format", | 283 | dest="format", | 
| 268 | default = "{artist}{title}{album} ", | 284 | default="{title}{album}{artist} ", | 
| 269 | help = "Full format string (default: \"{artist}{title}{album} \")" | 285 | help="Full format string (default: \"{artist}{title}{album} \")" | 
| 270 | ) | 286 | ) | 
| 271 | 287 | ||
| 272 | args = parser.parse_args() | 288 | args = parser.parse_args() | 
| 273 | 289 | ||
| 274 | return MetaWriter( | 290 | return MetaWriter( | 
| 275 | filename = args.filename, | 291 | filename=args.filename, | 
| 276 | output_format = args.format, | 292 | output_format=args.format, | 
| 277 | output_format_artist = args.format_artist, | 293 | output_format_artist=args.format_artist, | 
| 278 | output_format_title = args.format_title, | 294 | output_format_title=args.format_title, | 
| 279 | output_format_album = args.format_album | 295 | output_format_album=args.format_album | 
| 280 | ) | 296 | ) | 
| 281 | 297 | ||
| 282 | 298 | ||
| 283 | term = Terminal() | 299 | term = Terminal() | 
| 284 | meta_writer = create_writer() | 300 | meta_writer = create_writer() | 
| 285 | 301 | ||
| 286 | signal.signal(signal.SIGWINCH, on_resize) | 302 | signal.signal(signal.SIGWINCH, on_resize) | 
