mytunes-pro 2.0.4__py3-none-any.whl → 2.0.5__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- mytunes/app.py +51 -11
- {mytunes_pro-2.0.4.dist-info → mytunes_pro-2.0.5.dist-info}/METADATA +12 -4
- mytunes_pro-2.0.5.dist-info/RECORD +8 -0
- mytunes_pro-2.0.4.dist-info/RECORD +0 -8
- {mytunes_pro-2.0.4.dist-info → mytunes_pro-2.0.5.dist-info}/WHEEL +0 -0
- {mytunes_pro-2.0.4.dist-info → mytunes_pro-2.0.5.dist-info}/entry_points.txt +0 -0
- {mytunes_pro-2.0.4.dist-info → mytunes_pro-2.0.5.dist-info}/licenses/LICENSE +0 -0
- {mytunes_pro-2.0.4.dist-info → mytunes_pro-2.0.5.dist-info}/top_level.txt +0 -0
mytunes/app.py
CHANGED
|
@@ -4,6 +4,18 @@ MyTunes Pro - Professional TUI Edition v1.0
|
|
|
4
4
|
# Premium CLI Media Workflow Experiment with Curses Interface
|
|
5
5
|
Enhanced with Context7-researched MPV IPC & Resize Handling
|
|
6
6
|
"""
|
|
7
|
+
import warnings
|
|
8
|
+
# Suppress urllib3 NotOpenSSLWarning (LibreSSL compatibility)
|
|
9
|
+
# This must be defined before ANY imports that might trigger urllib3
|
|
10
|
+
warnings.filterwarnings("ignore", message=".*urllib3 v2 only supports OpenSSL 1.1.1+.*")
|
|
11
|
+
|
|
12
|
+
try:
|
|
13
|
+
import urllib3
|
|
14
|
+
# Optional: also ignore by category if already imported
|
|
15
|
+
from urllib3.exceptions import NotOpenSSLWarning
|
|
16
|
+
warnings.filterwarnings("ignore", category=NotOpenSSLWarning)
|
|
17
|
+
except: pass
|
|
18
|
+
|
|
7
19
|
import curses
|
|
8
20
|
import curses.textpad
|
|
9
21
|
import json
|
|
@@ -32,7 +44,7 @@ MPV_SOCKET = "/tmp/mpv_socket"
|
|
|
32
44
|
LOG_FILE = "/tmp/mytunes_mpv.log"
|
|
33
45
|
PID_FILE = "/tmp/mytunes_mpv.pid"
|
|
34
46
|
APP_NAME = "MyTunes Pro"
|
|
35
|
-
APP_VERSION = "2.0.
|
|
47
|
+
APP_VERSION = "2.0.5"
|
|
36
48
|
|
|
37
49
|
# === [Strings & Localization] ===
|
|
38
50
|
STRINGS = {
|
|
@@ -63,7 +75,9 @@ STRINGS = {
|
|
|
63
75
|
"favorites_info": "즐겨찾기 저장 위치: {}",
|
|
64
76
|
"hist_info": "최근 재생 기록 (최대 100곡)",
|
|
65
77
|
"time_fmt": "{}/{}",
|
|
66
|
-
"vol_fmt": "볼륨: {}%"
|
|
78
|
+
"vol_fmt": "볼륨: {}%",
|
|
79
|
+
"ime_warning": "영문 모드로 전환 후 단축키를 눌러주세요.",
|
|
80
|
+
"invalid_key": "잘못된 키 입력: '{}'"
|
|
67
81
|
},
|
|
68
82
|
"en": {
|
|
69
83
|
"title": "MyTunes Pro v{}",
|
|
@@ -92,7 +106,9 @@ STRINGS = {
|
|
|
92
106
|
"favorites_info": "Favorites stored at: {}",
|
|
93
107
|
"hist_info": "Recent Playback History (Max 100)",
|
|
94
108
|
"time_fmt": "{}/{}",
|
|
95
|
-
"vol_fmt": "Vol: {}%"
|
|
109
|
+
"vol_fmt": "Vol: {}%",
|
|
110
|
+
"ime_warning": "Switch to English for shortcuts.",
|
|
111
|
+
"invalid_key": "Invalid key: '{}'"
|
|
96
112
|
}
|
|
97
113
|
}
|
|
98
114
|
|
|
@@ -437,7 +453,7 @@ class MyTunesApp:
|
|
|
437
453
|
self.playback_duration = 0
|
|
438
454
|
self.is_paused = False
|
|
439
455
|
self.last_save_time = time.time()
|
|
440
|
-
self.
|
|
456
|
+
self.status_set_time = 0
|
|
441
457
|
|
|
442
458
|
# Throttling Counters
|
|
443
459
|
self.loop_count = 0
|
|
@@ -646,13 +662,20 @@ class MyTunesApp:
|
|
|
646
662
|
str(curses.KEY_F7): "OPEN_BROWSER",
|
|
647
663
|
str(curses.KEY_DC): "DELETE", "d": "DELETE"
|
|
648
664
|
}
|
|
649
|
-
|
|
665
|
+
cmd = mapping.get(k_char)
|
|
666
|
+
if cmd: return cmd
|
|
667
|
+
return ("UNKNOWN", key)
|
|
650
668
|
|
|
651
669
|
def handle_input(self):
|
|
652
670
|
"""Clean dispatcher: Get normalized command and execute it."""
|
|
653
671
|
cmd = self.get_next_event()
|
|
654
672
|
if not cmd: return
|
|
655
673
|
|
|
674
|
+
# Reset transient state for valid commands
|
|
675
|
+
is_transient = any(kw in self.status_msg for kw in ["Invalid key", "잘못된 키", "영문", "English"])
|
|
676
|
+
if is_transient:
|
|
677
|
+
self.status_msg = ""
|
|
678
|
+
|
|
656
679
|
current_list = self.get_current_list()
|
|
657
680
|
|
|
658
681
|
# 1. Functional Commands (Require Logic)
|
|
@@ -745,6 +768,17 @@ class MyTunesApp:
|
|
|
745
768
|
elif cmd == "EXIT_BKG":
|
|
746
769
|
self.stop_on_exit = False; self.running = False
|
|
747
770
|
|
|
771
|
+
elif isinstance(cmd, tuple) and cmd[0] == "UNKNOWN":
|
|
772
|
+
key = cmd[1]
|
|
773
|
+
if isinstance(key, str) and ord(key[0]) > 127:
|
|
774
|
+
self.status_msg = self.t("ime_warning")
|
|
775
|
+
self.status_set_time = time.time()
|
|
776
|
+
self.draw() # Internal redraw for instant feedback
|
|
777
|
+
elif isinstance(key, str) and key.isprintable():
|
|
778
|
+
self.status_msg = self.t("invalid_key", key)
|
|
779
|
+
self.status_set_time = time.time()
|
|
780
|
+
self.draw() # Internal redraw for instant feedback
|
|
781
|
+
|
|
748
782
|
def handle_deletion(self, current_list):
|
|
749
783
|
"""Sub-logic for DELETE command to keep dispatcher clean."""
|
|
750
784
|
if not current_list or not (0 <= self.selection_idx < len(current_list)): return
|
|
@@ -1278,12 +1312,18 @@ class MyTunesApp:
|
|
|
1278
1312
|
if self.player.loading:
|
|
1279
1313
|
self.stdscr.addstr(h - 2, 2, f"⏳ Loading...", curses.color_pair(6) | curses.A_BLINK)
|
|
1280
1314
|
elif self.status_msg:
|
|
1281
|
-
|
|
1282
|
-
|
|
1283
|
-
|
|
1284
|
-
|
|
1285
|
-
|
|
1286
|
-
|
|
1315
|
+
# Auto-clear transient warnings after 5 seconds
|
|
1316
|
+
is_transient = "Invalid key" in self.status_msg or "잘못된 키" in self.status_msg or "영문" in self.status_msg or "English" in self.status_msg
|
|
1317
|
+
if time.time() - self.status_set_time > 5 and is_transient:
|
|
1318
|
+
self.status_msg = ""
|
|
1319
|
+
|
|
1320
|
+
if self.status_msg:
|
|
1321
|
+
avail_w = branding_x - 4
|
|
1322
|
+
if avail_w > 5:
|
|
1323
|
+
msg = self.truncate(self.status_msg, avail_w)
|
|
1324
|
+
# Use Bold Yellow (Pair 3) for premium static warning
|
|
1325
|
+
attr = curses.color_pair(3) | curses.A_BOLD
|
|
1326
|
+
self.stdscr.addstr(h - 2, 2, f"📢 {msg}", attr)
|
|
1287
1327
|
|
|
1288
1328
|
# List Area (Remaining Middle)
|
|
1289
1329
|
list_top = 4
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: mytunes-pro
|
|
3
|
-
Version: 2.0.
|
|
3
|
+
Version: 2.0.5
|
|
4
4
|
Summary: A lightweight, keyboard-centric terminal player for streaming YouTube music.
|
|
5
5
|
Author-email: loxo <loxo5432@gmail.com>
|
|
6
6
|
Project-URL: Homepage, https://github.com/postgresql-co-kr/mytunes
|
|
@@ -13,13 +13,14 @@ Requires-Python: >=3.9
|
|
|
13
13
|
Description-Content-Type: text/markdown
|
|
14
14
|
License-File: LICENSE
|
|
15
15
|
Requires-Dist: requests
|
|
16
|
+
Requires-Dist: urllib3<2.0.0
|
|
16
17
|
Requires-Dist: yt-dlp
|
|
17
18
|
Requires-Dist: pusher
|
|
18
19
|
Dynamic: license-file
|
|
19
20
|
|
|
20
|
-
# 🎵 MyTunes Pro - Professional TUI Edition v2.0.
|
|
21
|
+
# 🎵 MyTunes Pro - Professional TUI Edition v2.0.5
|
|
21
22
|
|
|
22
|
-
## 🚀 Terminal-based Media Workflow Experiment v2.0.
|
|
23
|
+
## 🚀 Terminal-based Media Workflow Experiment v2.0.5
|
|
23
24
|
|
|
24
25
|
> [!IMPORTANT]
|
|
25
26
|
> **Legal Disclaimer:** This project is a personal, non-commercial research experiment for developer education.
|
|
@@ -214,7 +215,7 @@ Windows 환경에서 한글 검색이 안 되거나 설치가 어려운 분들
|
|
|
214
215
|
|
|
215
216
|
# 🎵 MyTunes Pro (Experimental Media Tool - KR)
|
|
216
217
|
|
|
217
|
-
## 🚀 터미널 기반 미디어 워크플로우 실험 v2.0.
|
|
218
|
+
## 🚀 터미널 기반 미디어 워크플로우 실험 v2.0.5
|
|
218
219
|
|
|
219
220
|
> [!IMPORTANT]
|
|
220
221
|
> **법적 면책 고지:** 본 프로젝트는 개발자 교육 및 연구를 목적으로 하는 개인적, 비상업적 실험입니다.
|
|
@@ -236,6 +237,13 @@ Python `curses` 라이브러리를 통해 터미널 환경에서 미디어 URL
|
|
|
236
237
|
|
|
237
238
|
## 🔄 Changelog
|
|
238
239
|
|
|
240
|
+
### v2.0.5 (2026-02-01)
|
|
241
|
+
- **Input Feedback Refinement**: Transitioned from blinking warnings to a static Bold Yellow status message for better accessibility and premium feel.
|
|
242
|
+
- **Auto-clear Optimization**: Implemented a 5-second auto-clear timer for all transient status messages.
|
|
243
|
+
- **Zero Latency Feedback**: Added instant redraw mechanisms to ensure input warnings appear immediately upon key press.
|
|
244
|
+
- **Stability Fixes**: Resolved a critical attribute error that caused crashes when selecting menu items.
|
|
245
|
+
- **SSL Compatibility**: Improved `urllib3` compatibility for macOS systems using LibreSSL.
|
|
246
|
+
|
|
239
247
|
### v2.0.4 (2026-02-01)
|
|
240
248
|
- **Legal Polish**: Comprehensive scrubbing of brand identifiers and service-oriented terminology across the ecosystem.
|
|
241
249
|
- **Localization**: Fully localized Korean landing page and technical experiment descriptions.
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
mytunes/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
2
|
+
mytunes/app.py,sha256=-vJSyC0gF0rj0Q3LkJWwlDH0c75OHZRxQ3l4Nxj19Ps,59412
|
|
3
|
+
mytunes_pro-2.0.5.dist-info/licenses/LICENSE,sha256=lOrP0EIjxcgJia__W3f3PVDZkRd2oRzFkyH2g3LRRCg,1063
|
|
4
|
+
mytunes_pro-2.0.5.dist-info/METADATA,sha256=GelVLtHE3uFp4s76DylYNpNFF4lgz8hY4hokILwIE6g,23172
|
|
5
|
+
mytunes_pro-2.0.5.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
|
|
6
|
+
mytunes_pro-2.0.5.dist-info/entry_points.txt,sha256=6-MsC13nIgzLvrREaGotc32FgxHx_Iuu1z2qCzJs1_4,65
|
|
7
|
+
mytunes_pro-2.0.5.dist-info/top_level.txt,sha256=KWzdFyNNG_sO7GT83-sN5fYArP4_DL5I8HYIwgazXyY,8
|
|
8
|
+
mytunes_pro-2.0.5.dist-info/RECORD,,
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
mytunes/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
2
|
-
mytunes/app.py,sha256=iu9LN4WtJrSQLSMreBMZqnXYotm_9Bk5eoQVTxk6dCo,57463
|
|
3
|
-
mytunes_pro-2.0.4.dist-info/licenses/LICENSE,sha256=lOrP0EIjxcgJia__W3f3PVDZkRd2oRzFkyH2g3LRRCg,1063
|
|
4
|
-
mytunes_pro-2.0.4.dist-info/METADATA,sha256=H_ujUXf1ofYs1seveke-gV_ivc-VAPYU9kKJgpaCpdE,22542
|
|
5
|
-
mytunes_pro-2.0.4.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
|
|
6
|
-
mytunes_pro-2.0.4.dist-info/entry_points.txt,sha256=6-MsC13nIgzLvrREaGotc32FgxHx_Iuu1z2qCzJs1_4,65
|
|
7
|
-
mytunes_pro-2.0.4.dist-info/top_level.txt,sha256=KWzdFyNNG_sO7GT83-sN5fYArP4_DL5I8HYIwgazXyY,8
|
|
8
|
-
mytunes_pro-2.0.4.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|