mirror of
https://github.com/SoongNoonien/mpdevil.git
synced 2023-08-10 21:12:44 +03:00
Compare commits
14 Commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
89ffc03cb2 | ||
![]() |
d04c84e5d0 | ||
![]() |
6990d59f72 | ||
![]() |
421f685b58 | ||
![]() |
6238df4d21 | ||
![]() |
b8d1f9aafc | ||
![]() |
3414212173 | ||
![]() |
ab7c9c6bd6 | ||
![]() |
4c7f953c98 | ||
![]() |
8ba986bb4d | ||
![]() |
0230544df4 | ||
![]() |
0b08bd80bf | ||
![]() |
b786b55644 | ||
![]() |
6f608d923b |
33
README.md
Normal file
33
README.md
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
README for mpdevil
|
||||||
|
==================
|
||||||
|
mpdevil is focused on playing your local music directly instead of managing playlists or playing network streams. So it neither supports saving playlists nor restoring them. Therefore mpdevil is mainly a music browser which aims to be easy to use. mpdevil dosen't store any client side database of your music library. Instead all tags and covers get presented to you in real time. So you'll never see any outdated information in your browser. mpdevil strongly relies on tags especially on the AlbumArtist tag.
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
Features
|
||||||
|
--------
|
||||||
|
|
||||||
|
1. playing songs without doubleclicking
|
||||||
|
2. displaying covers
|
||||||
|
3. fetching lyrics form the web (based on PyLyrics 1.1.0)
|
||||||
|
4. searching songs in your music library
|
||||||
|
5. removing single tracks form playlist by hovering and pressing del
|
||||||
|
6. appending albums by middleclick
|
||||||
|
7. query albums by rightclick
|
||||||
|
8. sending notifications on title change
|
||||||
|
9. managing multiple mpd servers
|
||||||
|
|
||||||
|
TODO
|
||||||
|
----
|
||||||
|
1. MPRIS interface
|
||||||
|
2. connecting to mpd servers with password
|
||||||
|
|
||||||
|
Building and installation
|
||||||
|
-------------------------
|
||||||
|
|
||||||
|
To build from source, use::
|
||||||
|
|
||||||
|
./autogen.sh
|
||||||
|
make
|
||||||
|
make install
|
||||||
|
|
30
README.rst
30
README.rst
@@ -1,30 +0,0 @@
|
|||||||
README for mpdevil
|
|
||||||
==================
|
|
||||||
mpdevil is focused on playing your local music directly instead of managing playlists or playing network streams. So it neither supports saving playlists nor restoring them. Therefore mpdevil is mainly a music browser which aims to be easy to use. mpdevil dosen't store any client side database of your music library. Instead all tags and covers get presented to you in real time. So you'll never see any outdated information in your browser.
|
|
||||||
|
|
||||||
Features
|
|
||||||
--------
|
|
||||||
|
|
||||||
-playing songs without doubleclicking
|
|
||||||
|
|
||||||
-displaying covers
|
|
||||||
|
|
||||||
-fetching lyrics form the web (based on PyLyrics 1.1.0)
|
|
||||||
|
|
||||||
-searching songs in your music library
|
|
||||||
|
|
||||||
-removing single tracks form playlist by hovering and pressing del
|
|
||||||
|
|
||||||
-sending notifications on title change
|
|
||||||
|
|
||||||
-managing multiple mpd servers
|
|
||||||
|
|
||||||
Building and installation
|
|
||||||
-------------------------
|
|
||||||
|
|
||||||
To build from source, use::
|
|
||||||
|
|
||||||
./autogen.sh
|
|
||||||
make
|
|
||||||
make install
|
|
||||||
|
|
208
bin/mpdevil.py
208
bin/mpdevil.py
@@ -89,6 +89,104 @@ class Client(MPDClient):
|
|||||||
except:
|
except:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
class AlbumDialog(Gtk.Dialog):
|
||||||
|
def __init__(self, parent, client, album, artist, year):
|
||||||
|
Gtk.Dialog.__init__(self, title=(artist+" - "+album+" ("+year+")"), transient_for=parent)
|
||||||
|
self.add_buttons(Gtk.STOCK_ADD, Gtk.ResponseType.ACCEPT, Gtk.STOCK_MEDIA_PLAY, Gtk.ResponseType.YES, Gtk.STOCK_OK, Gtk.ResponseType.OK, Gtk.STOCK_CLOSE, Gtk.ResponseType.CLOSE)
|
||||||
|
self.set_default_size(800, 600)
|
||||||
|
|
||||||
|
#adding vars
|
||||||
|
self.client=client
|
||||||
|
|
||||||
|
#scroll
|
||||||
|
scroll=Gtk.ScrolledWindow()
|
||||||
|
scroll.set_policy(Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC)
|
||||||
|
|
||||||
|
#Store
|
||||||
|
#(track, title, artist, duration, file)
|
||||||
|
self.store = Gtk.ListStore(str, str, str, str, str)
|
||||||
|
|
||||||
|
#TreeView
|
||||||
|
self.treeview = Gtk.TreeView(model=self.store)
|
||||||
|
self.treeview.set_search_column(-1)
|
||||||
|
self.treeview.columns_autosize()
|
||||||
|
|
||||||
|
self.selection = self.treeview.get_selection()
|
||||||
|
self.selection.set_mode(Gtk.SelectionMode.SINGLE)
|
||||||
|
|
||||||
|
#Column
|
||||||
|
renderer_text = Gtk.CellRendererText()
|
||||||
|
|
||||||
|
self.column_track = Gtk.TreeViewColumn(_("No"), renderer_text, text=0)
|
||||||
|
self.column_track.set_sizing(Gtk.TreeViewColumnSizing.AUTOSIZE)
|
||||||
|
self.column_track.set_property("resizable", False)
|
||||||
|
self.treeview.append_column(self.column_track)
|
||||||
|
|
||||||
|
self.column_title = Gtk.TreeViewColumn(_("Title"), renderer_text, text=1)
|
||||||
|
self.column_title.set_sizing(Gtk.TreeViewColumnSizing.AUTOSIZE)
|
||||||
|
self.column_title.set_property("resizable", False)
|
||||||
|
self.treeview.append_column(self.column_title)
|
||||||
|
|
||||||
|
self.column_artist = Gtk.TreeViewColumn(_("Artist"), renderer_text, text=2)
|
||||||
|
self.column_artist.set_sizing(Gtk.TreeViewColumnSizing.AUTOSIZE)
|
||||||
|
self.column_artist.set_property("resizable", False)
|
||||||
|
self.treeview.append_column(self.column_artist)
|
||||||
|
|
||||||
|
self.column_time = Gtk.TreeViewColumn(_("Length"), renderer_text, text=3)
|
||||||
|
self.column_time.set_sizing(Gtk.TreeViewColumnSizing.AUTOSIZE)
|
||||||
|
self.column_time.set_property("resizable", False)
|
||||||
|
self.treeview.append_column(self.column_time)
|
||||||
|
|
||||||
|
self.populate_treeview(album, artist, year)
|
||||||
|
|
||||||
|
#connect
|
||||||
|
self.title_activated=self.treeview.connect("row-activated", self.on_row_activated)
|
||||||
|
|
||||||
|
#packing
|
||||||
|
scroll.add(self.treeview)
|
||||||
|
self.vbox.pack_start(scroll, True, True, 0) #vbox default widget of dialogs
|
||||||
|
self.show_all()
|
||||||
|
|
||||||
|
#selection workaround
|
||||||
|
self.selection.unselect_all()
|
||||||
|
self.title_change=self.selection.connect("changed", self.on_selection_change)
|
||||||
|
|
||||||
|
def on_row_activated(self, widget, path, view_column):
|
||||||
|
treeiter=self.store.get_iter(path)
|
||||||
|
selected_title=self.store.get_value(treeiter, 4)
|
||||||
|
self.client.clear()
|
||||||
|
self.client.add(selected_title)
|
||||||
|
self.client.play(0)
|
||||||
|
|
||||||
|
def on_selection_change(self, widget):
|
||||||
|
treeiter=widget.get_selected()[1]
|
||||||
|
if not treeiter == None:
|
||||||
|
selected_title=self.store.get_value(treeiter, 4)
|
||||||
|
self.client.add(selected_title)
|
||||||
|
|
||||||
|
def populate_treeview(self, album, artist, year):
|
||||||
|
songs=self.client.find("album", album, "date", year, "albumartist", artist)
|
||||||
|
if not songs == []:
|
||||||
|
for song in songs:
|
||||||
|
try:
|
||||||
|
title=song["title"]
|
||||||
|
except:
|
||||||
|
title=_("Unknown Title")
|
||||||
|
try:
|
||||||
|
artist=song["artist"]
|
||||||
|
except:
|
||||||
|
artist=_("Unknown Artist")
|
||||||
|
try:
|
||||||
|
track=song["track"].zfill(2)
|
||||||
|
except:
|
||||||
|
track="00"
|
||||||
|
try:
|
||||||
|
dura=float(song["duration"])
|
||||||
|
except:
|
||||||
|
dura=0.0
|
||||||
|
duration=str(datetime.timedelta(seconds=int(dura)))
|
||||||
|
self.store.append([track, title, artist, duration, song["file"]] )
|
||||||
|
|
||||||
class ArtistView(Gtk.ScrolledWindow):
|
class ArtistView(Gtk.ScrolledWindow):
|
||||||
def __init__(self, client):
|
def __init__(self, client):
|
||||||
Gtk.ScrolledWindow.__init__(self)
|
Gtk.ScrolledWindow.__init__(self)
|
||||||
@@ -113,7 +211,7 @@ class ArtistView(Gtk.ScrolledWindow):
|
|||||||
|
|
||||||
#Old Name Column
|
#Old Name Column
|
||||||
renderer_text = Gtk.CellRendererText()
|
renderer_text = Gtk.CellRendererText()
|
||||||
self.column_name = Gtk.TreeViewColumn(_("Artist"), renderer_text, text=0)
|
self.column_name = Gtk.TreeViewColumn(_("Album Artist"), renderer_text, text=0)
|
||||||
self.column_name.set_sizing(Gtk.TreeViewColumnSizing.AUTOSIZE)
|
self.column_name.set_sizing(Gtk.TreeViewColumnSizing.AUTOSIZE)
|
||||||
self.column_name.set_property("resizable", True)
|
self.column_name.set_property("resizable", True)
|
||||||
self.column_name.set_sort_column_id(0)
|
self.column_name.set_sort_column_id(0)
|
||||||
@@ -161,28 +259,19 @@ class AlbumView(Gtk.ScrolledWindow):
|
|||||||
|
|
||||||
self.add(self.iconview)
|
self.add(self.iconview)
|
||||||
|
|
||||||
def gen_title_list(self, album, artist, year): #needed for tooltips
|
def gen_tooltip(self, album, artist, year):
|
||||||
if self.settings.get_boolean("show-album-view-tooltips"):
|
if self.settings.get_boolean("show-album-view-tooltips"):
|
||||||
songs=self.client.find("album", album, "date", year, "albumartist", artist)
|
songs=self.client.find("album", album, "date", year, "albumartist", artist)
|
||||||
length=float(0)
|
length=float(0)
|
||||||
title_list=""
|
|
||||||
for song in songs:
|
for song in songs:
|
||||||
try:
|
try:
|
||||||
title=song["title"]
|
dura=float(song["duration"])
|
||||||
except:
|
except:
|
||||||
title=_("Unknown Title")
|
dura=0.0
|
||||||
try:
|
length=length+dura
|
||||||
track=song["track"].zfill(2)
|
|
||||||
except:
|
|
||||||
track="00"
|
|
||||||
length=length+float(song["duration"])
|
|
||||||
duration=str(datetime.timedelta(seconds=int(float(song["duration"]))))
|
|
||||||
title_list=title_list+"\n"+(track+" - "+title+" ("+duration+")")
|
|
||||||
if not year == "":
|
|
||||||
year=" ("+year+")"
|
|
||||||
length_human_readable=str(datetime.timedelta(seconds=int(length)))
|
length_human_readable=str(datetime.timedelta(seconds=int(length)))
|
||||||
title_list=(_("%(album)s%(year)s (tracks: %(total_tracks)i) (%(total_length)s):") % {"album": album, "year": year, "total_tracks": len(songs), "total_length": length_human_readable})+title_list
|
tooltip=(_("%(total_tracks)i titles (%(total_length)s)") % {"total_tracks": len(songs), "total_length": length_human_readable})
|
||||||
return title_list.replace("&", "") #& must not be in tooltips
|
return tooltip
|
||||||
else:
|
else:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
@@ -202,9 +291,9 @@ class AlbumView(Gtk.ScrolledWindow):
|
|||||||
cover=Cover(client=self.client, lib_path=self.settings.get_value("paths")[self.settings.get_int("active-profile")], song_file=song_file)
|
cover=Cover(client=self.client, lib_path=self.settings.get_value("paths")[self.settings.get_int("active-profile")], song_file=song_file)
|
||||||
img=cover.get_pixbuf(size)
|
img=cover.get_pixbuf(size)
|
||||||
if album["year"] == "":
|
if album["year"] == "":
|
||||||
self.store.append([img, album["album"], self.gen_title_list(album["album"], artist, album["year"]), album["album"], album["year"]])
|
self.store.append([img, album["album"], self.gen_tooltip(album["album"], artist, album["year"]), album["album"], album["year"]])
|
||||||
else:
|
else:
|
||||||
self.store.append([img, album["album"]+" ("+album["year"]+")", self.gen_title_list(album["album"], artist, album["year"]), album["album"], album["year"]])
|
self.store.append([img, album["album"]+" ("+album["year"]+")", self.gen_tooltip(album["album"], artist, album["year"]), album["album"], album["year"]])
|
||||||
while Gtk.events_pending():
|
while Gtk.events_pending():
|
||||||
Gtk.main_iteration_do(True)
|
Gtk.main_iteration_do(True)
|
||||||
|
|
||||||
@@ -227,7 +316,6 @@ class TrackView(Gtk.Box):
|
|||||||
#TreeView
|
#TreeView
|
||||||
self.treeview = Gtk.TreeView(model=self.store)
|
self.treeview = Gtk.TreeView(model=self.store)
|
||||||
self.treeview.set_search_column(-1)
|
self.treeview.set_search_column(-1)
|
||||||
self.treeview.set_tooltip_column(5)
|
|
||||||
self.treeview.columns_autosize()
|
self.treeview.columns_autosize()
|
||||||
|
|
||||||
#selection
|
#selection
|
||||||
@@ -302,14 +390,11 @@ class TrackView(Gtk.Box):
|
|||||||
for song in songs:
|
for song in songs:
|
||||||
self.client.add(song["file"])
|
self.client.add(song["file"])
|
||||||
else:
|
else:
|
||||||
if self.settings.get_boolean("add-album") and not force:
|
if self.settings.get_boolean("add-album") and not force and not self.client.status()["state"] == "stop":
|
||||||
self.selection.handler_block(self.title_change)
|
self.selection.handler_block(self.title_change)
|
||||||
status=self.client.status()
|
status=self.client.status()
|
||||||
try:
|
self.client.moveid(status["songid"], 0)
|
||||||
self.client.moveid(status["songid"], 0) #bad song index possible
|
self.song_to_delete=self.client.playlistinfo()[0]["file"]
|
||||||
self.song_to_delete=self.client.playlistinfo()[0]["file"]
|
|
||||||
except:
|
|
||||||
pass
|
|
||||||
self.selection.handler_unblock(self.title_change)
|
self.selection.handler_unblock(self.title_change)
|
||||||
try:
|
try:
|
||||||
self.client.delete((1,)) # delete all songs, but the first. #bad song index possible
|
self.client.delete((1,)) # delete all songs, but the first. #bad song index possible
|
||||||
@@ -356,7 +441,11 @@ class TrackView(Gtk.Box):
|
|||||||
album=song["album"]
|
album=song["album"]
|
||||||
except:
|
except:
|
||||||
album=_("Unknown Album")
|
album=_("Unknown Album")
|
||||||
duration=str(datetime.timedelta(seconds=int(float(song["duration"]))))
|
try:
|
||||||
|
dura=float(song["duration"])
|
||||||
|
except:
|
||||||
|
dura=0.0
|
||||||
|
duration=str(datetime.timedelta(seconds=int(dura )))
|
||||||
self.store.append([track, title, artist, album, duration, song["file"].replace("&", "")])
|
self.store.append([track, title, artist, album, duration, song["file"].replace("&", "")])
|
||||||
self.playlist=self.client.playlist()
|
self.playlist=self.client.playlist()
|
||||||
else:
|
else:
|
||||||
@@ -417,12 +506,13 @@ class TrackView(Gtk.Box):
|
|||||||
self.client.play(selected_title)
|
self.client.play(selected_title)
|
||||||
|
|
||||||
class Browser(Gtk.Box):
|
class Browser(Gtk.Box):
|
||||||
def __init__(self, client, settings):
|
def __init__(self, client, settings, window):
|
||||||
Gtk.Box.__init__(self, orientation=Gtk.Orientation.HORIZONTAL, spacing=3)
|
Gtk.Box.__init__(self, orientation=Gtk.Orientation.HORIZONTAL, spacing=3)
|
||||||
|
|
||||||
#adding vars
|
#adding vars
|
||||||
self.client=client
|
self.client=client
|
||||||
self.settings=settings
|
self.settings=settings
|
||||||
|
self.window=window
|
||||||
|
|
||||||
#widgets
|
#widgets
|
||||||
self.artist_list=ArtistView(self.client)
|
self.artist_list=ArtistView(self.client)
|
||||||
@@ -502,14 +592,26 @@ class Browser(Gtk.Box):
|
|||||||
|
|
||||||
def on_album_view_button_press_event(self, widget, event):
|
def on_album_view_button_press_event(self, widget, event):
|
||||||
path = widget.get_path_at_pos(int(event.x), int(event.y))
|
path = widget.get_path_at_pos(int(event.x), int(event.y))
|
||||||
if event.button == 3:
|
if not path == None:
|
||||||
if not path == None:
|
if not event.button == 1:
|
||||||
treeiter=self.album_list.store.get_iter(path)
|
treeiter=self.album_list.store.get_iter(path)
|
||||||
selected_album=self.album_list.store.get_value(treeiter, 3)
|
selected_album=self.album_list.store.get_value(treeiter, 3)
|
||||||
selected_album_year=self.album_list.store.get_value(treeiter, 4)
|
selected_album_year=self.album_list.store.get_value(treeiter, 4)
|
||||||
treeiter=self.artist_list.selection.get_selected()[1]
|
treeiter=self.artist_list.selection.get_selected()[1]
|
||||||
selected_artist=self.artist_list.store.get_value(treeiter, 0)
|
selected_artist=self.artist_list.store.get_value(treeiter, 0)
|
||||||
|
if event.button == 2:
|
||||||
self.title_list.album_to_playlist(selected_album, selected_artist, selected_album_year, True)
|
self.title_list.album_to_playlist(selected_album, selected_artist, selected_album_year, True)
|
||||||
|
elif event.button == 3:
|
||||||
|
if self.client.connected():
|
||||||
|
album = AlbumDialog(self.window, self.client, selected_album, selected_artist, selected_album_year)
|
||||||
|
response = album.run()
|
||||||
|
if response == Gtk.ResponseType.OK:
|
||||||
|
self.title_list.album_to_playlist(selected_album, selected_artist, selected_album_year, False)
|
||||||
|
elif response == Gtk.ResponseType.ACCEPT:
|
||||||
|
self.title_list.album_to_playlist(selected_album, selected_artist, selected_album_year, True)
|
||||||
|
elif response == Gtk.ResponseType.YES:
|
||||||
|
self.title_list.album_to_playlist(selected_album, selected_artist, selected_album_year, False, True)
|
||||||
|
album.destroy()
|
||||||
|
|
||||||
def on_album_selection_change(self, widget):
|
def on_album_selection_change(self, widget):
|
||||||
paths=widget.get_selected_items()
|
paths=widget.get_selected_items()
|
||||||
@@ -711,7 +813,7 @@ class GeneralSettings(Gtk.Grid):
|
|||||||
show_stop=Gtk.CheckButton(label=_("Show stop button"))
|
show_stop=Gtk.CheckButton(label=_("Show stop button"))
|
||||||
show_stop.set_active(self.settings.get_boolean("show-stop"))
|
show_stop.set_active(self.settings.get_boolean("show-stop"))
|
||||||
|
|
||||||
show_album_view_tooltips=Gtk.CheckButton(label=_("Show title list as tooltip in album view"))
|
show_album_view_tooltips=Gtk.CheckButton(label=_("Show tooltips in album view"))
|
||||||
show_album_view_tooltips.set_active(self.settings.get_boolean("show-album-view-tooltips"))
|
show_album_view_tooltips.set_active(self.settings.get_boolean("show-album-view-tooltips"))
|
||||||
|
|
||||||
send_notify=Gtk.CheckButton(label=_("Send notification on title change"))
|
send_notify=Gtk.CheckButton(label=_("Send notification on title change"))
|
||||||
@@ -779,10 +881,10 @@ class ClientControl(Gtk.ButtonBox):
|
|||||||
self.settings=settings
|
self.settings=settings
|
||||||
|
|
||||||
#widgets
|
#widgets
|
||||||
self.play_button = Gtk.Button(image=Gtk.Image.new_from_icon_name("media-playback-start", Gtk.IconSize.DND))
|
self.play_button = Gtk.Button(image=Gtk.Image.new_from_icon_name("media-playback-start-symbolic", Gtk.IconSize.DND))
|
||||||
self.stop_button = Gtk.Button(image=Gtk.Image.new_from_icon_name("media-playback-stop", Gtk.IconSize.DND))
|
self.stop_button = Gtk.Button(image=Gtk.Image.new_from_icon_name("media-playback-stop-symbolic", Gtk.IconSize.DND))
|
||||||
self.prev_button = Gtk.Button(image=Gtk.Image.new_from_icon_name("media-skip-backward", Gtk.IconSize.DND))
|
self.prev_button = Gtk.Button(image=Gtk.Image.new_from_icon_name("media-skip-backward-symbolic", Gtk.IconSize.DND))
|
||||||
self.next_button = Gtk.Button(image=Gtk.Image.new_from_icon_name("media-skip-forward", Gtk.IconSize.DND))
|
self.next_button = Gtk.Button(image=Gtk.Image.new_from_icon_name("media-skip-forward-symbolic", Gtk.IconSize.DND))
|
||||||
|
|
||||||
#connect
|
#connect
|
||||||
self.play_button.connect("clicked", self.on_play_clicked)
|
self.play_button.connect("clicked", self.on_play_clicked)
|
||||||
@@ -805,15 +907,15 @@ class ClientControl(Gtk.ButtonBox):
|
|||||||
if self.client.connected():
|
if self.client.connected():
|
||||||
status=self.client.status()
|
status=self.client.status()
|
||||||
if status["state"] == "play":
|
if status["state"] == "play":
|
||||||
self.play_button.set_image(Gtk.Image.new_from_icon_name("media-playback-pause", Gtk.IconSize.DND))
|
self.play_button.set_image(Gtk.Image.new_from_icon_name("media-playback-pause-symbolic", Gtk.IconSize.DND))
|
||||||
self.prev_button.set_sensitive(True)
|
self.prev_button.set_sensitive(True)
|
||||||
self.next_button.set_sensitive(True)
|
self.next_button.set_sensitive(True)
|
||||||
elif status["state"] == "pause":
|
elif status["state"] == "pause":
|
||||||
self.play_button.set_image(Gtk.Image.new_from_icon_name("media-playback-start", Gtk.IconSize.DND))
|
self.play_button.set_image(Gtk.Image.new_from_icon_name("media-playback-start-symbolic", Gtk.IconSize.DND))
|
||||||
self.prev_button.set_sensitive(True)
|
self.prev_button.set_sensitive(True)
|
||||||
self.next_button.set_sensitive(True)
|
self.next_button.set_sensitive(True)
|
||||||
else:
|
else:
|
||||||
self.play_button.set_image(Gtk.Image.new_from_icon_name("media-playback-start", Gtk.IconSize.DND))
|
self.play_button.set_image(Gtk.Image.new_from_icon_name("media-playback-start-symbolic", Gtk.IconSize.DND))
|
||||||
self.prev_button.set_sensitive(False)
|
self.prev_button.set_sensitive(False)
|
||||||
self.next_button.set_sensitive(False)
|
self.next_button.set_sensitive(False)
|
||||||
return True
|
return True
|
||||||
@@ -882,13 +984,10 @@ class SeekBar(Gtk.Box):
|
|||||||
|
|
||||||
def seek(self, range, scroll, value):
|
def seek(self, range, scroll, value):
|
||||||
status=self.client.status()
|
status=self.client.status()
|
||||||
try:
|
duration=float(status["duration"])
|
||||||
duration=float(status["duration"])
|
factor=(value/100)
|
||||||
factor=(value/100)
|
pos=(duration*factor)
|
||||||
pos=(duration*factor)
|
self.client.seekcur(pos)
|
||||||
self.client.seekcur(pos)
|
|
||||||
except:
|
|
||||||
pass
|
|
||||||
|
|
||||||
def update(self):
|
def update(self):
|
||||||
try:
|
try:
|
||||||
@@ -1168,7 +1267,7 @@ class ServerStats(Gtk.Dialog):
|
|||||||
class Search(Gtk.Dialog):
|
class Search(Gtk.Dialog):
|
||||||
def __init__(self, parent, client):
|
def __init__(self, parent, client):
|
||||||
Gtk.Dialog.__init__(self, title=_("Search"), transient_for=parent)
|
Gtk.Dialog.__init__(self, title=_("Search"), transient_for=parent)
|
||||||
self.add_button(Gtk.STOCK_OK, Gtk.ResponseType.OK)
|
self.add_button(Gtk.STOCK_CLOSE, Gtk.ResponseType.CLOSE)
|
||||||
self.set_default_size(800, 600)
|
self.set_default_size(800, 600)
|
||||||
|
|
||||||
#adding vars
|
#adding vars
|
||||||
@@ -1180,7 +1279,6 @@ class Search(Gtk.Dialog):
|
|||||||
|
|
||||||
#search entry
|
#search entry
|
||||||
self.search_entry=Gtk.SearchEntry()
|
self.search_entry=Gtk.SearchEntry()
|
||||||
self.search_entry.connect("search-changed", self.on_search_changed)
|
|
||||||
|
|
||||||
#label
|
#label
|
||||||
self.label=Gtk.Label()
|
self.label=Gtk.Label()
|
||||||
@@ -1193,7 +1291,6 @@ class Search(Gtk.Dialog):
|
|||||||
#TreeView
|
#TreeView
|
||||||
self.treeview = Gtk.TreeView(model=self.store)
|
self.treeview = Gtk.TreeView(model=self.store)
|
||||||
self.treeview.set_search_column(-1)
|
self.treeview.set_search_column(-1)
|
||||||
self.treeview.set_tooltip_column(5)
|
|
||||||
self.treeview.columns_autosize()
|
self.treeview.columns_autosize()
|
||||||
|
|
||||||
self.selection = self.treeview.get_selection()
|
self.selection = self.treeview.get_selection()
|
||||||
@@ -1230,6 +1327,7 @@ class Search(Gtk.Dialog):
|
|||||||
#connect
|
#connect
|
||||||
self.title_activated=self.treeview.connect("row-activated", self.on_row_activated)
|
self.title_activated=self.treeview.connect("row-activated", self.on_row_activated)
|
||||||
self.title_change=self.selection.connect("changed", self.on_selection_change)
|
self.title_change=self.selection.connect("changed", self.on_selection_change)
|
||||||
|
self.search_entry.connect("search-changed", self.on_search_changed)
|
||||||
|
|
||||||
#packing
|
#packing
|
||||||
scroll.add(self.treeview)
|
scroll.add(self.treeview)
|
||||||
@@ -1270,7 +1368,11 @@ class Search(Gtk.Dialog):
|
|||||||
album=song["album"]
|
album=song["album"]
|
||||||
except:
|
except:
|
||||||
album=_("Unknown Album")
|
album=_("Unknown Album")
|
||||||
duration=str(datetime.timedelta(seconds=int(float(song["duration"]))))
|
try:
|
||||||
|
dura=float(song["duration"])
|
||||||
|
except:
|
||||||
|
dura=0.0
|
||||||
|
duration=str(datetime.timedelta(seconds=int(dura)))
|
||||||
self.store.append([track, title, artist, album, duration, song["file"].replace("&", "")] )
|
self.store.append([track, title, artist, album, duration, song["file"].replace("&", "")] )
|
||||||
self.label.set_text(_("Hits: %i") % (len(self.store)))
|
self.label.set_text(_("Hits: %i") % (len(self.store)))
|
||||||
|
|
||||||
@@ -1407,16 +1509,16 @@ class MainWindow(Gtk.ApplicationWindow):
|
|||||||
self.add_action(update_action)
|
self.add_action(update_action)
|
||||||
|
|
||||||
#widgets
|
#widgets
|
||||||
self.browser=Browser(self.client, self.settings)
|
self.browser=Browser(self.client, self.settings, self)
|
||||||
self.profiles=ProfileSelect(self.client, self.settings)
|
self.profiles=ProfileSelect(self.client, self.settings)
|
||||||
self.profiles.set_tooltip_text(_("Select profile"))
|
self.profiles.set_tooltip_text(_("Select profile"))
|
||||||
self.control=ClientControl(self.client, self.settings)
|
self.control=ClientControl(self.client, self.settings)
|
||||||
self.progress=SeekBar(self.client)
|
self.progress=SeekBar(self.client)
|
||||||
self.go_home_button=Gtk.Button(image=Gtk.Image.new_from_icon_name("go-home", Gtk.IconSize.DND))
|
self.go_home_button=Gtk.Button(image=Gtk.Image.new_from_icon_name("go-home-symbolic", Gtk.IconSize.DND))
|
||||||
self.go_home_button.set_tooltip_text(_("Return to album of current title"))
|
self.go_home_button.set_tooltip_text(_("Return to album of current title"))
|
||||||
self.search_button=Gtk.Button(image=Gtk.Image.new_from_icon_name("system-search", Gtk.IconSize.DND))
|
self.search_button=Gtk.Button(image=Gtk.Image.new_from_icon_name("system-search-symbolic", Gtk.IconSize.DND))
|
||||||
self.search_button.set_tooltip_text(_("Title search"))
|
self.search_button.set_tooltip_text(_("Title search"))
|
||||||
self.lyrics_button=Gtk.ToggleButton(image=Gtk.Image.new_from_icon_name("media-view-subtitles", Gtk.IconSize.DND))
|
self.lyrics_button=Gtk.ToggleButton(image=Gtk.Image.new_from_icon_name("media-view-subtitles-symbolic", Gtk.IconSize.DND))
|
||||||
self.lyrics_button.set_tooltip_text(_("Show lyrics"))
|
self.lyrics_button.set_tooltip_text(_("Show lyrics"))
|
||||||
self.play_opts=PlaybackOptions(self.client)
|
self.play_opts=PlaybackOptions(self.client)
|
||||||
|
|
||||||
@@ -1561,6 +1663,7 @@ class mpdevil(Gtk.Application):
|
|||||||
BASE_KEY = "org.mpdevil"
|
BASE_KEY = "org.mpdevil"
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
super().__init__(*args, application_id="org.mpdevil", flags=Gio.ApplicationFlags.FLAGS_NONE, **kwargs)
|
super().__init__(*args, application_id="org.mpdevil", flags=Gio.ApplicationFlags.FLAGS_NONE, **kwargs)
|
||||||
|
#Gtk.window_set_default_icon_name("mpdevil")
|
||||||
self.client=Client()
|
self.client=Client()
|
||||||
self.settings = Gio.Settings.new(self.BASE_KEY)
|
self.settings = Gio.Settings.new(self.BASE_KEY)
|
||||||
self.window=None
|
self.window=None
|
||||||
@@ -1592,6 +1695,7 @@ class mpdevil(Gtk.Application):
|
|||||||
dialog.set_version(VERSION)
|
dialog.set_version(VERSION)
|
||||||
dialog.set_comments(_("A small MPD client written in python"))
|
dialog.set_comments(_("A small MPD client written in python"))
|
||||||
dialog.set_authors(["Martin Wagner"])
|
dialog.set_authors(["Martin Wagner"])
|
||||||
|
dialog.set_website("https://github.com/SoongNoonien/mpdevil")
|
||||||
dialog.set_logo_icon_name(PACKAGE)
|
dialog.set_logo_icon_name(PACKAGE)
|
||||||
dialog.run()
|
dialog.run()
|
||||||
dialog.destroy()
|
dialog.destroy()
|
||||||
|
18
configure.ac
18
configure.ac
@@ -1,7 +1,7 @@
|
|||||||
dnl -*- Mode: autoconf -*-
|
dnl -*- Mode: autoconf -*-
|
||||||
dnl Process this file with autoconf to produce a configure script.
|
dnl Process this file with autoconf to produce a configure script.
|
||||||
AC_PREREQ([2.68])
|
AC_PREREQ([2.68])
|
||||||
AC_INIT([mpdevil], [0.3])
|
AC_INIT([mpdevil], [0.4.0])
|
||||||
AC_CONFIG_SRCDIR([bin/mpdevil.py])
|
AC_CONFIG_SRCDIR([bin/mpdevil.py])
|
||||||
AM_INIT_AUTOMAKE
|
AM_INIT_AUTOMAKE
|
||||||
AC_CONFIG_MACRO_DIR([m4])
|
AC_CONFIG_MACRO_DIR([m4])
|
||||||
@@ -50,7 +50,7 @@ if $PYTHON -c "$prog" 1>&AS_MESSAGE_LOG_FD 2>&AS_MESSAGE_LOG_FD; then
|
|||||||
AC_MSG_RESULT(found)
|
AC_MSG_RESULT(found)
|
||||||
else
|
else
|
||||||
AC_MSG_RESULT(not found)
|
AC_MSG_RESULT(not found)
|
||||||
AC_MSG_ERROR(MPDClient not found)
|
AC_MSG_ERROR(python module mpd not found)
|
||||||
fi
|
fi
|
||||||
|
|
||||||
dnl Check for beautifulsoup
|
dnl Check for beautifulsoup
|
||||||
@@ -62,7 +62,19 @@ if $PYTHON -c "$prog" 1>&AS_MESSAGE_LOG_FD 2>&AS_MESSAGE_LOG_FD; then
|
|||||||
AC_MSG_RESULT(found)
|
AC_MSG_RESULT(found)
|
||||||
else
|
else
|
||||||
AC_MSG_RESULT(not found)
|
AC_MSG_RESULT(not found)
|
||||||
AC_MSG_ERROR(beautifulsoup not found)
|
AC_MSG_ERROR(python module bs4 not found)
|
||||||
|
fi
|
||||||
|
|
||||||
|
dnl Check for requests
|
||||||
|
AC_MSG_CHECKING(for requests installed)
|
||||||
|
prog="
|
||||||
|
import requests
|
||||||
|
"
|
||||||
|
if $PYTHON -c "$prog" 1>&AS_MESSAGE_LOG_FD 2>&AS_MESSAGE_LOG_FD; then
|
||||||
|
AC_MSG_RESULT(found)
|
||||||
|
else
|
||||||
|
AC_MSG_RESULT(not found)
|
||||||
|
AC_MSG_ERROR(python module requests not found)
|
||||||
fi
|
fi
|
||||||
|
|
||||||
AC_CONFIG_FILES([Makefile
|
AC_CONFIG_FILES([Makefile
|
||||||
|
140
po/de.po
140
po/de.po
@@ -7,8 +7,8 @@ msgid ""
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: \n"
|
"Project-Id-Version: \n"
|
||||||
"Report-Msgid-Bugs-To: \n"
|
"Report-Msgid-Bugs-To: \n"
|
||||||
"POT-Creation-Date: 2020-01-06 00:53+0100\n"
|
"POT-Creation-Date: 2020-01-17 22:33+0100\n"
|
||||||
"PO-Revision-Date: 2020-01-06 00:55+0100\n"
|
"PO-Revision-Date: 2020-01-17 22:34+0100\n"
|
||||||
"Last-Translator: \n"
|
"Last-Translator: \n"
|
||||||
"Language-Team: \n"
|
"Language-Team: \n"
|
||||||
"Language: de\n"
|
"Language: de\n"
|
||||||
@@ -18,136 +18,140 @@ msgstr ""
|
|||||||
"X-Generator: Poedit 2.2.4\n"
|
"X-Generator: Poedit 2.2.4\n"
|
||||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||||
|
|
||||||
#: mpdevil.py:116 mpdevil.py:250 mpdevil.py:1215
|
#: mpdevil.py:120 mpdevil.py:328 mpdevil.py:1302
|
||||||
msgid "Artist"
|
|
||||||
msgstr "Künstler"
|
|
||||||
|
|
||||||
#: mpdevil.py:173 mpdevil.py:346 mpdevil.py:1260
|
|
||||||
msgid "Unknown Title"
|
|
||||||
msgstr "Unbekannter Titel"
|
|
||||||
|
|
||||||
#: mpdevil.py:184
|
|
||||||
#, python-format
|
|
||||||
msgid "%(album)s%(year)s (tracks: %(total_tracks)i) (%(total_length)s):"
|
|
||||||
msgstr "%(album)s%(year)s (Titel: %(total_tracks)i) (%(total_length)s):"
|
|
||||||
|
|
||||||
#: mpdevil.py:240 mpdevil.py:1205
|
|
||||||
msgid "No"
|
msgid "No"
|
||||||
msgstr "Nr."
|
msgstr "Nr."
|
||||||
|
|
||||||
#: mpdevil.py:245 mpdevil.py:1210
|
#: mpdevil.py:125 mpdevil.py:333 mpdevil.py:1307
|
||||||
msgid "Title"
|
msgid "Title"
|
||||||
msgstr "Titel"
|
msgstr "Titel"
|
||||||
|
|
||||||
#: mpdevil.py:255 mpdevil.py:1225
|
#: mpdevil.py:130 mpdevil.py:338 mpdevil.py:1312
|
||||||
|
msgid "Artist"
|
||||||
|
msgstr "Interpret"
|
||||||
|
|
||||||
|
#: mpdevil.py:135 mpdevil.py:343 mpdevil.py:1322
|
||||||
msgid "Length"
|
msgid "Length"
|
||||||
msgstr "Länge"
|
msgstr "Länge"
|
||||||
|
|
||||||
#: mpdevil.py:354 mpdevil.py:1268
|
#: mpdevil.py:174 mpdevil.py:431 mpdevil.py:1358
|
||||||
|
msgid "Unknown Title"
|
||||||
|
msgstr "Unbekannter Titel"
|
||||||
|
|
||||||
|
#: mpdevil.py:178 mpdevil.py:439 mpdevil.py:1366
|
||||||
msgid "Unknown Artist"
|
msgid "Unknown Artist"
|
||||||
msgstr "Unbekannter Künstler"
|
msgstr "Unbekannter Künstler"
|
||||||
|
|
||||||
#: mpdevil.py:358 mpdevil.py:1272
|
#: mpdevil.py:214
|
||||||
|
msgid "Album Artist"
|
||||||
|
msgstr "Albuminterpret"
|
||||||
|
|
||||||
|
#: mpdevil.py:273
|
||||||
|
#, python-format
|
||||||
|
msgid "%(total_tracks)i titles (%(total_length)s)"
|
||||||
|
msgstr "%(total_tracks)i Titel (%(total_length)s)"
|
||||||
|
|
||||||
|
#: mpdevil.py:443 mpdevil.py:1370
|
||||||
msgid "Unknown Album"
|
msgid "Unknown Album"
|
||||||
msgstr "Unbekanntes Album"
|
msgstr "Unbekanntes Album"
|
||||||
|
|
||||||
#: mpdevil.py:567
|
#: mpdevil.py:669
|
||||||
msgid "Select"
|
msgid "Select"
|
||||||
msgstr "Auswählen"
|
msgstr "Auswählen"
|
||||||
|
|
||||||
#: mpdevil.py:569
|
#: mpdevil.py:671
|
||||||
msgid "Profile:"
|
msgid "Profile:"
|
||||||
msgstr "Profil:"
|
msgstr "Profil:"
|
||||||
|
|
||||||
#: mpdevil.py:571
|
#: mpdevil.py:673
|
||||||
msgid "Name:"
|
msgid "Name:"
|
||||||
msgstr "Name:"
|
msgstr "Name:"
|
||||||
|
|
||||||
#: mpdevil.py:573
|
#: mpdevil.py:675
|
||||||
msgid "Host:"
|
msgid "Host:"
|
||||||
msgstr "Host:"
|
msgstr "Host:"
|
||||||
|
|
||||||
#: mpdevil.py:575
|
#: mpdevil.py:677
|
||||||
msgid "Port:"
|
msgid "Port:"
|
||||||
msgstr "Port:"
|
msgstr "Port:"
|
||||||
|
|
||||||
#: mpdevil.py:577
|
#: mpdevil.py:679
|
||||||
msgid "Music lib:"
|
msgid "Music lib:"
|
||||||
msgstr "Musikverzeichnis:"
|
msgstr "Musikverzeichnis:"
|
||||||
|
|
||||||
#: mpdevil.py:667
|
#: mpdevil.py:769
|
||||||
msgid "Choose directory"
|
msgid "Choose directory"
|
||||||
msgstr "Verzeichnis Wählen"
|
msgstr "Verzeichnis Wählen"
|
||||||
|
|
||||||
#: mpdevil.py:703
|
#: mpdevil.py:805
|
||||||
msgid "Main cover size:"
|
msgid "Main cover size:"
|
||||||
msgstr "Größe des Haupt-Covers:"
|
msgstr "Größe des Haupt-Covers:"
|
||||||
|
|
||||||
#: mpdevil.py:705
|
#: mpdevil.py:807
|
||||||
msgid "Album-view cover size:"
|
msgid "Album-view cover size:"
|
||||||
msgstr "Covergröße in Albumansicht:"
|
msgstr "Covergröße in Albumansicht:"
|
||||||
|
|
||||||
#: mpdevil.py:711
|
#: mpdevil.py:813
|
||||||
msgid "Show stop button"
|
msgid "Show stop button"
|
||||||
msgstr "Zeige Stopp-Knopf"
|
msgstr "Zeige Stopp-Knopf"
|
||||||
|
|
||||||
#: mpdevil.py:714
|
#: mpdevil.py:816
|
||||||
msgid "Show title list as tooltip in album view"
|
msgid "Show tooltips in album view"
|
||||||
msgstr "Zeige Titellisten als Tooltips in Albumansicht"
|
msgstr "Zeige Tooltips in Albumansicht"
|
||||||
|
|
||||||
#: mpdevil.py:717
|
#: mpdevil.py:819
|
||||||
msgid "Send notification on title change"
|
msgid "Send notification on title change"
|
||||||
msgstr "Sende Benachrichtigung bei Titelwechsel"
|
msgstr "Sende Benachrichtigung bei Titelwechsel"
|
||||||
|
|
||||||
#: mpdevil.py:720
|
#: mpdevil.py:822
|
||||||
msgid "Stop playback on quit"
|
msgid "Stop playback on quit"
|
||||||
msgstr "Wiedergabe beim Beenden stoppen"
|
msgstr "Wiedergabe beim Beenden stoppen"
|
||||||
|
|
||||||
#: mpdevil.py:723
|
#: mpdevil.py:825
|
||||||
msgid "Play selected album after current title"
|
msgid "Play selected album after current title"
|
||||||
msgstr "Ausgewähltes Album hinter aktuellem Titel einreihen"
|
msgstr "Ausgewähltes Album hinter aktuellem Titel einreihen"
|
||||||
|
|
||||||
#: mpdevil.py:754 mpdevil.py:1432
|
#: mpdevil.py:856 mpdevil.py:1534
|
||||||
msgid "Settings"
|
msgid "Settings"
|
||||||
msgstr "Einstellungen"
|
msgstr "Einstellungen"
|
||||||
|
|
||||||
#: mpdevil.py:767
|
#: mpdevil.py:869
|
||||||
msgid "General"
|
msgid "General"
|
||||||
msgstr "Allgemein"
|
msgstr "Allgemein"
|
||||||
|
|
||||||
#: mpdevil.py:768
|
#: mpdevil.py:870
|
||||||
msgid "Profiles"
|
msgid "Profiles"
|
||||||
msgstr "Profile"
|
msgstr "Profile"
|
||||||
|
|
||||||
#: mpdevil.py:919
|
#: mpdevil.py:1018
|
||||||
msgid "Random mode"
|
msgid "Random mode"
|
||||||
msgstr "Zufallsmodus"
|
msgstr "Zufallsmodus"
|
||||||
|
|
||||||
#: mpdevil.py:921
|
#: mpdevil.py:1020
|
||||||
msgid "Repeat mode"
|
msgid "Repeat mode"
|
||||||
msgstr "Dauerschleife"
|
msgstr "Dauerschleife"
|
||||||
|
|
||||||
#: mpdevil.py:923
|
#: mpdevil.py:1022
|
||||||
msgid "Single mode"
|
msgid "Single mode"
|
||||||
msgstr "Einzelstückmodus"
|
msgstr "Einzelstückmodus"
|
||||||
|
|
||||||
#: mpdevil.py:925
|
#: mpdevil.py:1024
|
||||||
msgid "Consume mode"
|
msgid "Consume mode"
|
||||||
msgstr "Playliste verbrauchen"
|
msgstr "Playliste verbrauchen"
|
||||||
|
|
||||||
#: mpdevil.py:1019
|
#: mpdevil.py:1118
|
||||||
msgid "Right click to show additional information"
|
msgid "Right click to show additional information"
|
||||||
msgstr "Rechtsclick für weitere Informationen"
|
msgstr "Rechtsclick für weitere Informationen"
|
||||||
|
|
||||||
#: mpdevil.py:1042
|
#: mpdevil.py:1141
|
||||||
msgid "MPD-Tag"
|
msgid "MPD-Tag"
|
||||||
msgstr "MPD-Tag"
|
msgstr "MPD-Tag"
|
||||||
|
|
||||||
#: mpdevil.py:1045 mpdevil.py:1153
|
#: mpdevil.py:1144 mpdevil.py:1252
|
||||||
msgid "Value"
|
msgid "Value"
|
||||||
msgstr "Wert"
|
msgstr "Wert"
|
||||||
|
|
||||||
#: mpdevil.py:1066
|
#: mpdevil.py:1165
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid ""
|
msgid ""
|
||||||
"%(bitrate)s kb/s, %(frequency)s kHz, %(resolution)s bit, %(channels)s "
|
"%(bitrate)s kb/s, %(frequency)s kHz, %(resolution)s bit, %(channels)s "
|
||||||
@@ -156,88 +160,88 @@ msgstr ""
|
|||||||
"%(bitrate)s kb/s, %(frequency)s kHz, %(resolution)s bit, %(channels)s "
|
"%(bitrate)s kb/s, %(frequency)s kHz, %(resolution)s bit, %(channels)s "
|
||||||
"Kanäle, %(file_type)s"
|
"Kanäle, %(file_type)s"
|
||||||
|
|
||||||
#: mpdevil.py:1132
|
#: mpdevil.py:1231
|
||||||
msgid "Stats"
|
msgid "Stats"
|
||||||
msgstr "Statistik"
|
msgstr "Statistik"
|
||||||
|
|
||||||
#: mpdevil.py:1150
|
#: mpdevil.py:1249
|
||||||
msgid "Tag"
|
msgid "Tag"
|
||||||
msgstr "Tag"
|
msgstr "Tag"
|
||||||
|
|
||||||
#: mpdevil.py:1170
|
#: mpdevil.py:1269
|
||||||
msgid "Search"
|
msgid "Search"
|
||||||
msgstr "Suche"
|
msgstr "Suche"
|
||||||
|
|
||||||
#: mpdevil.py:1220
|
#: mpdevil.py:1317
|
||||||
msgid "Album"
|
msgid "Album"
|
||||||
msgstr "Album"
|
msgstr "Album"
|
||||||
|
|
||||||
#: mpdevil.py:1275
|
#: mpdevil.py:1377
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid "Hits: %i"
|
msgid "Hits: %i"
|
||||||
msgstr "Treffer: %i"
|
msgstr "Treffer: %i"
|
||||||
|
|
||||||
#: mpdevil.py:1279
|
#: mpdevil.py:1381
|
||||||
msgid "Lyrics"
|
msgid "Lyrics"
|
||||||
msgstr "Liedtext"
|
msgstr "Liedtext"
|
||||||
|
|
||||||
#: mpdevil.py:1323
|
#: mpdevil.py:1425
|
||||||
msgid "searching..."
|
msgid "searching..."
|
||||||
msgstr "suche..."
|
msgstr "suche..."
|
||||||
|
|
||||||
#: mpdevil.py:1327
|
#: mpdevil.py:1429
|
||||||
msgid "not found"
|
msgid "not found"
|
||||||
msgstr "nicht gefunden"
|
msgstr "nicht gefunden"
|
||||||
|
|
||||||
#: mpdevil.py:1332
|
#: mpdevil.py:1434
|
||||||
msgid "not connected"
|
msgid "not connected"
|
||||||
msgstr "nicht verbunden"
|
msgstr "nicht verbunden"
|
||||||
|
|
||||||
#: mpdevil.py:1412
|
#: mpdevil.py:1514
|
||||||
msgid "Select profile"
|
msgid "Select profile"
|
||||||
msgstr "Profil auswählen"
|
msgstr "Profil auswählen"
|
||||||
|
|
||||||
#: mpdevil.py:1416
|
#: mpdevil.py:1518
|
||||||
msgid "Return to album of current title"
|
msgid "Return to album of current title"
|
||||||
msgstr "Zu Album des aktuellen Titels zurückkehren"
|
msgstr "Zu Album des aktuellen Titels zurückkehren"
|
||||||
|
|
||||||
#: mpdevil.py:1418
|
#: mpdevil.py:1520
|
||||||
msgid "Title search"
|
msgid "Title search"
|
||||||
msgstr "Titelsuche"
|
msgstr "Titelsuche"
|
||||||
|
|
||||||
#: mpdevil.py:1420
|
#: mpdevil.py:1522
|
||||||
msgid "Show lyrics"
|
msgid "Show lyrics"
|
||||||
msgstr "Zeige Liedtext"
|
msgstr "Zeige Liedtext"
|
||||||
|
|
||||||
#: mpdevil.py:1427
|
#: mpdevil.py:1529
|
||||||
msgid "Not connected to MPD-server. Reconnect?"
|
msgid "Not connected to MPD-server. Reconnect?"
|
||||||
msgstr "Nicht mit MPD-Server verbunden. Verbindung wiederherstellen?"
|
msgstr "Nicht mit MPD-Server verbunden. Verbindung wiederherstellen?"
|
||||||
|
|
||||||
#: mpdevil.py:1431
|
#: mpdevil.py:1533
|
||||||
msgid "Save window size"
|
msgid "Save window size"
|
||||||
msgstr "Fenstergröße speichern"
|
msgstr "Fenstergröße speichern"
|
||||||
|
|
||||||
#: mpdevil.py:1433
|
#: mpdevil.py:1535
|
||||||
msgid "Update database"
|
msgid "Update database"
|
||||||
msgstr "Datenbank aktualisieren"
|
msgstr "Datenbank aktualisieren"
|
||||||
|
|
||||||
#: mpdevil.py:1434
|
#: mpdevil.py:1536
|
||||||
msgid "Server stats"
|
msgid "Server stats"
|
||||||
msgstr "Serverstatistik"
|
msgstr "Serverstatistik"
|
||||||
|
|
||||||
#: mpdevil.py:1435
|
#: mpdevil.py:1537
|
||||||
msgid "About"
|
msgid "About"
|
||||||
msgstr "Über"
|
msgstr "Über"
|
||||||
|
|
||||||
#: mpdevil.py:1436
|
#: mpdevil.py:1538
|
||||||
msgid "Quit"
|
msgid "Quit"
|
||||||
msgstr "Beenden"
|
msgstr "Beenden"
|
||||||
|
|
||||||
#: mpdevil.py:1441
|
#: mpdevil.py:1543
|
||||||
msgid "Main menu"
|
msgid "Main menu"
|
||||||
msgstr "Hauptmenu"
|
msgstr "Hauptmenu"
|
||||||
|
|
||||||
#: mpdevil.py:1593
|
#: mpdevil.py:1696
|
||||||
msgid "A small MPD client written in python"
|
msgid "A small MPD client written in python"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
136
po/mpdevil.pot
136
po/mpdevil.pot
@@ -8,7 +8,7 @@ msgid ""
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: PACKAGE VERSION\n"
|
"Project-Id-Version: PACKAGE VERSION\n"
|
||||||
"Report-Msgid-Bugs-To: \n"
|
"Report-Msgid-Bugs-To: \n"
|
||||||
"POT-Creation-Date: 2020-01-06 00:53+0100\n"
|
"POT-Creation-Date: 2020-01-17 22:33+0100\n"
|
||||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||||
@@ -17,223 +17,227 @@ msgstr ""
|
|||||||
"Content-Type: text/plain; charset=CHARSET\n"
|
"Content-Type: text/plain; charset=CHARSET\n"
|
||||||
"Content-Transfer-Encoding: 8bit\n"
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
|
|
||||||
#: mpdevil.py:116 mpdevil.py:250 mpdevil.py:1215
|
#: mpdevil.py:120 mpdevil.py:328 mpdevil.py:1302
|
||||||
msgid "Artist"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: mpdevil.py:173 mpdevil.py:346 mpdevil.py:1260
|
|
||||||
msgid "Unknown Title"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: mpdevil.py:184
|
|
||||||
#, python-format
|
|
||||||
msgid "%(album)s%(year)s (tracks: %(total_tracks)i) (%(total_length)s):"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: mpdevil.py:240 mpdevil.py:1205
|
|
||||||
msgid "No"
|
msgid "No"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: mpdevil.py:245 mpdevil.py:1210
|
#: mpdevil.py:125 mpdevil.py:333 mpdevil.py:1307
|
||||||
msgid "Title"
|
msgid "Title"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: mpdevil.py:255 mpdevil.py:1225
|
#: mpdevil.py:130 mpdevil.py:338 mpdevil.py:1312
|
||||||
|
msgid "Artist"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: mpdevil.py:135 mpdevil.py:343 mpdevil.py:1322
|
||||||
msgid "Length"
|
msgid "Length"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: mpdevil.py:354 mpdevil.py:1268
|
#: mpdevil.py:174 mpdevil.py:431 mpdevil.py:1358
|
||||||
|
msgid "Unknown Title"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: mpdevil.py:178 mpdevil.py:439 mpdevil.py:1366
|
||||||
msgid "Unknown Artist"
|
msgid "Unknown Artist"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: mpdevil.py:358 mpdevil.py:1272
|
#: mpdevil.py:214
|
||||||
|
msgid "Album Artist"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: mpdevil.py:273
|
||||||
|
#, python-format
|
||||||
|
msgid "%(total_tracks)i titles (%(total_length)s)"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: mpdevil.py:443 mpdevil.py:1370
|
||||||
msgid "Unknown Album"
|
msgid "Unknown Album"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: mpdevil.py:567
|
#: mpdevil.py:669
|
||||||
msgid "Select"
|
msgid "Select"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: mpdevil.py:569
|
#: mpdevil.py:671
|
||||||
msgid "Profile:"
|
msgid "Profile:"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: mpdevil.py:571
|
#: mpdevil.py:673
|
||||||
msgid "Name:"
|
msgid "Name:"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: mpdevil.py:573
|
#: mpdevil.py:675
|
||||||
msgid "Host:"
|
msgid "Host:"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: mpdevil.py:575
|
#: mpdevil.py:677
|
||||||
msgid "Port:"
|
msgid "Port:"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: mpdevil.py:577
|
#: mpdevil.py:679
|
||||||
msgid "Music lib:"
|
msgid "Music lib:"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: mpdevil.py:667
|
#: mpdevil.py:769
|
||||||
msgid "Choose directory"
|
msgid "Choose directory"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: mpdevil.py:703
|
#: mpdevil.py:805
|
||||||
msgid "Main cover size:"
|
msgid "Main cover size:"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: mpdevil.py:705
|
#: mpdevil.py:807
|
||||||
msgid "Album-view cover size:"
|
msgid "Album-view cover size:"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: mpdevil.py:711
|
#: mpdevil.py:813
|
||||||
msgid "Show stop button"
|
msgid "Show stop button"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: mpdevil.py:714
|
#: mpdevil.py:816
|
||||||
msgid "Show title list as tooltip in album view"
|
msgid "Show tooltips in album view"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: mpdevil.py:717
|
#: mpdevil.py:819
|
||||||
msgid "Send notification on title change"
|
msgid "Send notification on title change"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: mpdevil.py:720
|
#: mpdevil.py:822
|
||||||
msgid "Stop playback on quit"
|
msgid "Stop playback on quit"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: mpdevil.py:723
|
#: mpdevil.py:825
|
||||||
msgid "Play selected album after current title"
|
msgid "Play selected album after current title"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: mpdevil.py:754 mpdevil.py:1432
|
#: mpdevil.py:856 mpdevil.py:1534
|
||||||
msgid "Settings"
|
msgid "Settings"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: mpdevil.py:767
|
#: mpdevil.py:869
|
||||||
msgid "General"
|
msgid "General"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: mpdevil.py:768
|
#: mpdevil.py:870
|
||||||
msgid "Profiles"
|
msgid "Profiles"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: mpdevil.py:919
|
#: mpdevil.py:1018
|
||||||
msgid "Random mode"
|
msgid "Random mode"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: mpdevil.py:921
|
#: mpdevil.py:1020
|
||||||
msgid "Repeat mode"
|
msgid "Repeat mode"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: mpdevil.py:923
|
#: mpdevil.py:1022
|
||||||
msgid "Single mode"
|
msgid "Single mode"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: mpdevil.py:925
|
#: mpdevil.py:1024
|
||||||
msgid "Consume mode"
|
msgid "Consume mode"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: mpdevil.py:1019
|
#: mpdevil.py:1118
|
||||||
msgid "Right click to show additional information"
|
msgid "Right click to show additional information"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: mpdevil.py:1042
|
#: mpdevil.py:1141
|
||||||
msgid "MPD-Tag"
|
msgid "MPD-Tag"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: mpdevil.py:1045 mpdevil.py:1153
|
#: mpdevil.py:1144 mpdevil.py:1252
|
||||||
msgid "Value"
|
msgid "Value"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: mpdevil.py:1066
|
#: mpdevil.py:1165
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid ""
|
msgid ""
|
||||||
"%(bitrate)s kb/s, %(frequency)s kHz, %(resolution)s bit, %(channels)s "
|
"%(bitrate)s kb/s, %(frequency)s kHz, %(resolution)s bit, %(channels)s "
|
||||||
"channels, %(file_type)s"
|
"channels, %(file_type)s"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: mpdevil.py:1132
|
#: mpdevil.py:1231
|
||||||
msgid "Stats"
|
msgid "Stats"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: mpdevil.py:1150
|
#: mpdevil.py:1249
|
||||||
msgid "Tag"
|
msgid "Tag"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: mpdevil.py:1170
|
#: mpdevil.py:1269
|
||||||
msgid "Search"
|
msgid "Search"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: mpdevil.py:1220
|
#: mpdevil.py:1317
|
||||||
msgid "Album"
|
msgid "Album"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: mpdevil.py:1275
|
#: mpdevil.py:1377
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid "Hits: %i"
|
msgid "Hits: %i"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: mpdevil.py:1279
|
#: mpdevil.py:1381
|
||||||
msgid "Lyrics"
|
msgid "Lyrics"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: mpdevil.py:1323
|
#: mpdevil.py:1425
|
||||||
msgid "searching..."
|
msgid "searching..."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: mpdevil.py:1327
|
#: mpdevil.py:1429
|
||||||
msgid "not found"
|
msgid "not found"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: mpdevil.py:1332
|
#: mpdevil.py:1434
|
||||||
msgid "not connected"
|
msgid "not connected"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: mpdevil.py:1412
|
#: mpdevil.py:1514
|
||||||
msgid "Select profile"
|
msgid "Select profile"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: mpdevil.py:1416
|
#: mpdevil.py:1518
|
||||||
msgid "Return to album of current title"
|
msgid "Return to album of current title"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: mpdevil.py:1418
|
#: mpdevil.py:1520
|
||||||
msgid "Title search"
|
msgid "Title search"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: mpdevil.py:1420
|
#: mpdevil.py:1522
|
||||||
msgid "Show lyrics"
|
msgid "Show lyrics"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: mpdevil.py:1427
|
#: mpdevil.py:1529
|
||||||
msgid "Not connected to MPD-server. Reconnect?"
|
msgid "Not connected to MPD-server. Reconnect?"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: mpdevil.py:1431
|
#: mpdevil.py:1533
|
||||||
msgid "Save window size"
|
msgid "Save window size"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: mpdevil.py:1433
|
#: mpdevil.py:1535
|
||||||
msgid "Update database"
|
msgid "Update database"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: mpdevil.py:1434
|
#: mpdevil.py:1536
|
||||||
msgid "Server stats"
|
msgid "Server stats"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: mpdevil.py:1435
|
#: mpdevil.py:1537
|
||||||
msgid "About"
|
msgid "About"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: mpdevil.py:1436
|
#: mpdevil.py:1538
|
||||||
msgid "Quit"
|
msgid "Quit"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: mpdevil.py:1441
|
#: mpdevil.py:1543
|
||||||
msgid "Main menu"
|
msgid "Main menu"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: mpdevil.py:1593
|
#: mpdevil.py:1696
|
||||||
msgid "A small MPD client written in python"
|
msgid "A small MPD client written in python"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
BIN
screenshots/mainwindow.png
Normal file
BIN
screenshots/mainwindow.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1021 KiB |
Reference in New Issue
Block a user