Skip to content

Commit c0d47aa

Browse files
committed
v2.1.0 update
1 parent 6685404 commit c0d47aa

File tree

6 files changed

+65
-1849
lines changed

6 files changed

+65
-1849
lines changed

code/README.txt

Lines changed: 6 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,10 @@
1-
Minimal MPD Client - v2.0.9
1+
Minimal MPD Client - v2.1.0
22

3-
Check out the offline help under the Help menu. (updated for v2.0.9)
3+
Check out the offline help under the Help menu. (updated for v2.1.0)
44

5-
v2.0.9
6-
- Expanded commands that can be used in search windows. 'help;' tells all.
7-
- Renamed menus to names I like. Moved options around so they almost make sense.
8-
- Discovered and fixed bugs related to art window.
9-
- Improved Linux experience. Configuration changes exit MMC4W. Reload applies them.
10-
- In Linux, Mode button also exits so reloading can pick up titlebar change.
11-
More testing on other WM's needed.
12-
- Finally got "scaling factor" working. Set scale factor by sizing main win. In Config menu.
13-
- Massive redo of the help document. New pics required.
14-
- Resolved Help and About window sizing on scaled displays.
15-
- Resolved a couple of bugs uncovered by LuSP19 related to brand new MPD installs.
16-
- Resolved a path issue when Pyinstaller is not used. (just copying mmc4w.py)
17-
18-
v2.0.8
19-
- Added a 'Close' button to Outputs and Server windows.
20-
- This allows you to make multiple changes to outputs
21-
and change your mind about which server you want.
5+
v2.1.0
6+
- Provided a kinder solution when trying to run MMC4W against a server that is not running.
7+
- Added Config menu option to delete the debug log file.
8+
- Corrected bug preventing logo from being displayed when there is no album art.
229

2310

code/_internal/mmc4w_help.html

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
<html>
33
<body>
44
<h1>MMC4W - Minimal MPD Client for Windows</h1>
5-
<p>This help file was updated for the v2.0.9 release. As of v2.0.8 the same Python code runs in Linux without needing any tweaks.</p>
5+
<p>This help file was updated for the v2.1.0 release. As of v2.0.8 the same Python code runs in Linux without needing any tweaks.</p>
66
<p>I recommend reading the <strong>First Run Process</strong> section below before installing.</p>
77
<h1>Putting the Music First</h1>
88
<p><strong>MMC4W</strong> is first and foremost <strong>Minimal</strong>. That may be a little misleading, because it does quite a lot. The GUI is minimal so as to quietly go about its business. This is about the music. That was the original point of this exercise.</p>
@@ -24,6 +24,7 @@ <h3>The <strong>'Config'</strong> menu contains these functions:</h3>
2424
<li><strong>Select a Server</strong> : Allows you to select a server from the list in mmc4w.ini. Prompts you to select a playlist also.</li>
2525
<li><strong>Toggle an Output</strong> : Allows you to enable and disable configured outputs on the MPD server.</li>
2626
<li><strong>Toggle Logging</strong> : Toggles logging On or Off. Restart the app after toggling.</li>
27+
<li><strong>Delete Debug Log</strong> : If you are not currently logging in debug mode, deletes the log for you.</li>
2728
<li><strong>Reset Win Positions</strong> : Puts the two primary windows back where they were originally.</li>
2829
<li><strong>Get Scaling Factors</strong> : Calculates and saves two values based on display scaling.</li>
2930
<li><strong>Apply Scaling Factors</strong> : Updates window geometry numbers based on saved Scaling Factors.</li>
@@ -78,7 +79,7 @@ <h2>First Run Process</h2>
7879
<p><img alt="inside the mmc4w.ini file" src="./config_ini_basics.png" /></p>
7980
<p>If you have more than one server, just string those IP addresses together as seen there.</p>
8081
<p>After typing your server IP address(es) in the [basic] section, save and close the file.</p>
81-
<p>Restart <strong>MMC4W</strong>. When it starts, you will get a dialog showing you the first IP address you provided. If the connection is not successful, an error will be displayed. In this case, you'll need to verify your server's IP address is correctly entered into mmc4w.ini file. Open the text editor you were using to input that IP address. You should be able to find mmc4w.ini in the recent files list.</p>
82+
<p>Restart <strong>MMC4W</strong>. When it starts, you will get a dialog showing you the first IP address you provided. If the connection is not successful, an error will be displayed. In this case, you'll need to verify your server's IP address is correctly entered into mmc4w.ini file. The process opens mmc4w.ini for editing.</p>
8283
<p>Once you have a valid server IP under the serverlist key of the basic section, run MMC4W again.</p>
8384
<h3>Position and size windows to your liking.</h3>
8485
<p>The first time you run MMC4W, it runs with titlebars on. You can move and size the windows to your liking. When you have things to your liking, hit the <strong>mode</strong> button. If you are running in Linux, mmc4w.py will exit. Restart the app. </p>
@@ -141,7 +142,7 @@ <h3>Search and Play directly from the music library</h3>
141142
<p><strong>Note:</strong> The Search window is resizeable. If you want, type 'savewin;' in the Search: bar to save size and placement.</p>
142143
<p><strong>Play a Single</strong> opens the Search window and allows you to type some search term. This is a <strong>Title</strong> search. If any song title in the entire library contains the search term, it will be displayed when you press <strong>[enter]</strong>.</p>
143144
<p><img alt="Title Search." src="./search_title.png" /></br><span style="color:green; font-size:smaller;">Song title search.</span></p>
144-
<p>When you click on one of them, it plays that one title then stops. Use another <strong>'Look'</strong> menu option to do something else.</p>
145+
<p>When you click on one of them, it plays that one title then stops. Use another <strong>'Lists'</strong> menu option to do something else.</p>
145146
<p><strong>Play an Album</strong> opens the same Search window. This time you are searching for text contained in <strong>Album</strong> names.</p>
146147
<p>Clicking on a list entry loads up the songs on that album and plays them sequentially, first to last. You will notice the text area turns blue with white text. That is the visual indicator that <strong>Random Mode</strong> has been turned off. </p>
147148
<p><img alt="Album Search." src="./album_mode.png" /></br><span style="color:green; font-size:smaller;">True Blue Album Mode.</span></p>
@@ -153,7 +154,7 @@ <h3>Search and Play directly from the music library</h3>
153154
<h2>Working with Saved Playlists</h2>
154155
<p>Saved playlists are the heart of <strong>MMC4W</strong>. To differentiate between <strong>saved playlists</strong> and the list of songs currently being played, the latter is called <strong>"the queue"</strong>. <strong>Playlists</strong> are lists of songs saved to a file on disk with some meaningful name.</p>
155156
<p>You load playlists into the queue and then MPD plays that queue using the settings in force at the moment. </p>
156-
<p><strong>MMC4W</strong> will create a special playlist called "Everything" that contains all the songs in your library. That option is found in the <strong>'Look'</strong> Menu.</p>
157+
<p><strong>MMC4W</strong> will create a special playlist called "Everything" that contains all the songs in your library. That option is found in the <strong>'Lists'</strong> Menu.</p>
157158
<h3>You can manipulate playlists in these ways:</h3>
158159
<ul>
159160
<li>Load a playlist into the queue. <strong>Lists Menu</strong> - Select a Playlist.</li>

code/_internal/mmc4w_help.md

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
<body markdown="1">
44
# MMC4W - Minimal MPD Client for Windows
55

6-
This help file was updated for the v2.0.9 release. As of v2.0.8 the same Python code runs in Linux without needing any tweaks.
6+
This help file was updated for the v2.1.0 release. As of v2.0.8 the same Python code runs in Linux without needing any tweaks.
77

88
I recommend reading the **First Run Process** section below before installing.
99

@@ -29,6 +29,7 @@ The interface contains the basic required buttons to control a MPD server:
2929
- **Select a Server** : Allows you to select a server from the list in mmc4w.ini. Prompts you to select a playlist also.
3030
- **Toggle an Output** : Allows you to enable and disable configured outputs on the MPD server.
3131
- **Toggle Logging** : Toggles logging On or Off. Restart the app after toggling.
32+
- **Delete Debug Log** : If you are not currently logging in debug mode, deletes the log for you.
3233
- **Reset Win Positions** : Puts the two primary windows back where they were originally.
3334
- **Get Scaling Factors** : Calculates and saves two values based on display scaling.
3435
- **Apply Scaling Factors** : Updates window geometry numbers based on saved Scaling Factors.
@@ -93,7 +94,7 @@ If you have more than one server, just string those IP addresses together as see
9394

9495
After typing your server IP address(es) in the [basic] section, save and close the file.
9596

96-
Restart **MMC4W**. When it starts, you will get a dialog showing you the first IP address you provided. If the connection is not successful, an error will be displayed. In this case, you'll need to verify your server's IP address is correctly entered into mmc4w.ini file. Open the text editor you were using to input that IP address. You should be able to find mmc4w.ini in the recent files list.
97+
Restart **MMC4W**. When it starts, you will get a dialog showing you the first IP address you provided. If the connection is not successful, an error will be displayed. In this case, you'll need to verify your server's IP address is correctly entered into mmc4w.ini file. The process opens mmc4w.ini for editing.
9798

9899
Once you have a valid server IP under the serverlist key of the basic section, run MMC4W again.
99100

@@ -201,7 +202,7 @@ Anywhere you see a Search: bar, you can use colon-separated key:value pairs for
201202

202203
![Title Search.](./search_title.png)</br><span style="color:green; font-size:smaller;">Song title search.</span>
203204

204-
When you click on one of them, it plays that one title then stops. Use another **'Look'** menu option to do something else.
205+
When you click on one of them, it plays that one title then stops. Use another **'Lists'** menu option to do something else.
205206

206207
**Play an Album** opens the same Search window. This time you are searching for text contained in **Album** names.
207208

@@ -225,7 +226,7 @@ Saved playlists are the heart of **MMC4W**. To differentiate between **saved pla
225226

226227
You load playlists into the queue and then MPD plays that queue using the settings in force at the moment.
227228

228-
**MMC4W** will create a special playlist called "Everything" that contains all the songs in your library. That option is found in the **'Look'** Menu.
229+
**MMC4W** will create a special playlist called "Everything" that contains all the songs in your library. That option is found in the **'Lists'** Menu.
229230

230231
### You can manipulate playlists in these ways:
231232

code/mmc4w.py

Lines changed: 44 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,8 @@
3232
ctypes.windll.shcore.SetProcessDpiAwareness(0)
3333
ctypes.windll.user32.SetProcessDPIAware()
3434

35-
version = "v2.0.9"
35+
version = "v2.1.0"
36+
# v2.1.0 - Gently handle attempting to run with no server. Add 'delete debug log'.
3637
# v2.0.9 - Finally get scale factors working. Renamed menus. Browse help.html.
3738
# v2.0.8 - Use buttons in search windows for added flexibility.
3839
# v2.0.7 - Trade pathlib for os.path. Deal with 'already connected' error.
@@ -124,11 +125,10 @@
124125
serverip = confparse.get('serverstats', 'lastsrvr')
125126
serverport = confparse.get('basic','serverport')
126127
firstrun = confparse.get('basic','firstrun')
127-
if firstrun == '1':
128-
ran = 'r'
129-
rpt = 'p'
130-
sin = 's'
131-
con = 'c'
128+
ran = 'r'
129+
rpt = 'p'
130+
sin = 's'
131+
con = 'c'
132132
if serverlist == "":
133133
proceed = messagebox.askokcancel("Edit Config File","OK closes the app and opens mmc4w.ini for editing.")
134134
if proceed == True:
@@ -344,6 +344,18 @@ def getscalefactors():
344344
with open(mmc4wIni, 'w') as SLcnf:
345345
confparse.write(SLcnf)
346346

347+
def deletedebuglog():
348+
if os.path.isfile(path_to_dat / "mmc4w_DEBUG.log"):
349+
ddlsure = messagebox.askyesno("Delete Debug Log","Are you sure?")
350+
if ddlsure == True:
351+
try:
352+
os.remove(path_to_dat / "mmc4w_DEBUG.log")
353+
messagebox.showinfo("Debug Log Deleted","mmc4w_DEBUG.log has been removed.")
354+
except:
355+
messagebox.showinfo("File in Use","Toggle Logging before attempting to delete the log.")
356+
else:
357+
messagebox.showinfo("No Debug Log Found","The operating system reports no such file.")
358+
347359
def loadplsongs(song,album):
348360
connext()
349361
pls_on_srvr = []
@@ -395,6 +407,10 @@ def connext(): ## Checks connection, then connects if necessary.
395407
if err2var == 'Already connected':
396408
cxstat = 1
397409
pass
410+
if 'WinError' in str(err2var) or 'Not connected' in str(err2var):
411+
messagebox.showinfo("Server Down","The server you selected is not responding. Edit mmc4w.ini to ensure the 'lastsrvr' IP address is for a running server.")
412+
cxstat = 0
413+
configurator("Double-check all the IP addresses. OK sends you to edit mmc4w.ini.")
398414
else:
399415
logger.debug("D1| Second level errvar: {}".format(err2var))
400416
cxstat = 0
@@ -762,7 +778,7 @@ def getcurrsong():
762778
lastpl = confparse.get('serverstats','lastsetpl')
763779
logger.debug('D2| Headed to getaartpic(**cs).')
764780
getaartpic(**cs)
765-
aart = artWindow(1)
781+
aart = artWindow(aartvar)
766782
if aatgl == '1':
767783
artw.aartLabel.configure(image=aart)
768784
if 'volume' in stat:
@@ -865,6 +881,7 @@ def getaartpic(**cs):
865881
aartvar = 0
866882
if aatgl == '1':
867883
logger.info('2) Bottom of getaartpic(). Headed to artWindow(). aartvar is {}, len(eadict) is {}, len(fadict) is {}.'.format(aartvar,len(eadict),len(fadict)))
884+
868885
artWindow(aartvar)
869886
else:
870887
logger.debug('D6| aartvar is: {}, len(eadict) is {}, len(fadict) is {}.'.format(aartvar,len(eadict),len(fadict)))
@@ -895,29 +912,35 @@ def songtitlefollower():
895912
logger.info(" - - - - - songtitlefollower - - - - - - ")
896913
getcurrsong()
897914

898-
def configurator():
899-
proceed = messagebox.askokcancel("Edit Config File","OK closes the app and opens mmc4w.ini for editing.")
915+
def configurator(confmsg):
916+
if confmsg == '':
917+
confmsg = "OK closes the app and opens mmc4w.ini for editing."
918+
proceed = messagebox.askokcancel("Edit Config File",confmsg)
900919
if proceed == True:
901920
if sys.platform == "win32":
902921
os.startfile(mmc4wIni)
903922
else:
904923
subprocess.run(["xdg-open", mmc4wIni])
905924
sleep(1)
906925
exit()
926+
else:
927+
sys.exit()
907928

908929
def logtoggler():
909930
confparse.read(mmc4wIni)
910931
logtog = confparse.get("program","logging")
932+
loglevel = confparse.get("program","loglevel")
911933
if logtog.upper() == "ON":
912-
confparse.set('program','logging','off')
913-
msg = 'Logging turned OFF.'
934+
newlog = "off"
935+
confparse.set('program','logging',newlog)
914936
elif logtog.upper() == 'OFF':
915-
confparse.set('program','logging','on')
916-
msg = 'Logging turned ON.'
917-
logger.debug("{}. Wrote to .ini file.".format(msg))
937+
newlog = "on"
938+
confparse.set('program','logging',newlog)
939+
logger.debug("{}. Wrote to .ini file.".format(newlog))
918940
with open(mmc4wIni, 'w') as SLcnf:
919941
confparse.write(SLcnf)
920-
displaytext1(msg)
942+
messagebox.showinfo("Logging Toggled","Logging is now " + newlog + ".\nLogging level is " + loglevel + ".\nExiting. Restart to refresh config.")
943+
exit()
921944

922945
def getcurrstat():
923946
connext()
@@ -1342,7 +1365,6 @@ def pushret(event,lookupT):
13421365
connext()
13431366
dispitems = []
13441367
srchterm = editing_item.get().replace('Search: ','')
1345-
print(srchterm.upper())
13461368
valid_list = ['file','title','artist','album','genre','date']
13471369
editing_item.set('Search: ')
13481370
if srchterm.upper() == "HELP;":
@@ -1357,7 +1379,6 @@ def pushret(event,lookupT):
13571379
if srchterm.upper() == "KEYS;":
13581380
findit = valid_list
13591381
dispitems = []
1360-
print(findit)
13611382
for f in findit:
13621383
dispitems.append(f)
13631384
plsngwin.listbx.delete(0,tk.END)
@@ -1555,6 +1576,7 @@ def rtnplsel(ipvar):
15551576
confparse.write(SLcnf)
15561577
logger.info('0) Connected to server {}.'.format(serverip))
15571578
getcurrsong()
1579+
15581580
def outputtggl(outputvar):
15591581
selection = srvrw.listbx.curselection()[0]
15601582
outputs = getoutputs()[1]
@@ -1579,7 +1601,6 @@ def outputtggl(outputvar):
15791601
if swaction == 'output':
15801602
srvrw.listbx.bind('<<ListboxSelect>>', outputtggl)
15811603
outputs = getoutputs()[1]
1582-
print("initial outputs: {}".format(outputs))
15831604
srvrw.listbx.delete(0,tk.END)
15841605
srvrw.listbx.update()
15851606
srvrw.listvar.set(outputs)
@@ -1745,10 +1766,11 @@ def browserplayer():
17451766
window.config(menu=menu)
17461767
nnFont = Font(family="Segoe UI", size=10) ## Set the base font
17471768
confMenu = tk.Menu(menu, tearoff=False)
1748-
confMenu.add_command(label="Edit mmc4w.ini", command=configurator)
1769+
confMenu.add_command(label="Edit mmc4w.ini", command=lambda: configurator(''))
17491770
confMenu.add_command(label="Select a Server", command=lambda: SrvrWindow('server'))
17501771
confMenu.add_command(label="Toggle an Output", command=lambda: SrvrWindow('output'))
17511772
confMenu.add_command(label='Toggle Logging', command=logtoggler)
1773+
confMenu.add_command(label='Delete Debug Log',command=deletedebuglog)
17521774
confMenu.add_command(label='Reset Win Positions', command=resetwins)
17531775
confMenu.add_command(label="Get Scaling Factors",command=getscalefactors)
17541776
confMenu.add_command(label="Apply Scaling Factors",command=applyscalefactors)
@@ -1828,6 +1850,9 @@ def browserplayer():
18281850
# Make all threads daemon threads, and whenever the main thread dies all threads will die with it.
18291851
## tk.END THREADING NOTES =====================================
18301852
#
1853+
cxstat = connext()
1854+
if cxstat == 0:
1855+
SrvrWindow('server')
18311856
t1 = threading.Thread(target=songtitlefollower)
18321857
t1.daemon = True
18331858
t1.start()

0 commit comments

Comments
 (0)