Skip to content

Commit d04bac3

Browse files
committed
- Version 0.7.9
- implemented search function for config windows - fixed history cycling - updated docs
1 parent d3f1c9b commit d04bac3

9 files changed

+85
-47
lines changed

Changelog

+4-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
1-
2019-07-09 s-n-g
1+
2019-07-15 s-n-g
2+
* Searching is now available on any window presenting a list of items
3+
* Transparency indication presentation always reflects setting
24
* A locked session is indicated next to PyRadio version
35
* Adding "Top" link to html files
6+
* Docs updated
47

58
2019-07-08 s-n-g
69

README.html

+1-3
Original file line numberDiff line numberDiff line change
@@ -236,10 +236,8 @@ <h2 id="search-function">Search function <span style="padding-left: 10px;"><sup
236236
<p>On any window presenting a list of items (stations, playlists, themes) a <strong>search function</strong> is available by pressing “<strong>/</strong>”.</p>
237237
<p>The <em>Search Window</em> supports normal and extend editing and in session history.</p>
238238
<p>One can always get help by pressing the “<strong>?</strong>” key.</p>
239-
<p>The search will be case insensitive under <strong>python 3</strong>; it will be case sensitive under <strong>python 2</strong>.</p>
240-
<p>After a search term has been successfully found, next occurrence can be obtained using the “<strong>n</strong>” key and previous occurrence can be obtained using the “<strong>N</strong>” key.</p>
239+
<p>After a search term has been successfully found (search is case insensitive), next occurrence can be obtained using the “<strong>n</strong>” key and previous occurrence can be obtained using the “<strong>N</strong>” key.</p>
241240
<p style="margin: 1.5em 4em 0 4em; text-indent: -2.5em;"><strong>Note:</strong> <strong>Python 2</strong> users are confined in typing ASCII characters only.</p>
242-
<p style="margin: 1.5em 4em 0 4em; text-indent: -2.5em;"><strong>Note:</strong> Currently, the <strong>search function</strong> is available on the stations’ and playlists’ and themes’ window only.</p>
243241
<h2 id="pyradio-themes">PyRadio Themes <span style="padding-left: 10px;"><sup style="font-size: 50%"><a href="#" title="Go to top of the page">Top</a></sup></style></h2>
244242
<p><strong>PyRadio</strong> comes with 6 preconfigured (hard coded) themes:</p>
245243
<ol type="1">

README.md

+1-5
Original file line numberDiff line numberDiff line change
@@ -338,14 +338,10 @@ The *Search Window* supports normal and extend editing and in session history.
338338

339339
One can always get help by pressing the "**?**" key.
340340

341-
The search will be case insensitive under **python 3**; it will be case sensitive under **python 2**.
342-
343-
After a search term has been successfully found, next occurrence can be obtained using the "**n**" key and previous occurrence can be obtained using the "**N**" key.
341+
After a search term has been successfully found (search is case insensitive), next occurrence can be obtained using the "**n**" key and previous occurrence can be obtained using the "**N**" key.
344342

345343
**Note:** **Python 2** users are confined in typing ASCII characters only.
346344

347-
**Note:** Currently, the **search function** is available on the stations' and playlists' and themes' window only.
348-
349345
## PyRadio Themes
350346

351347
**PyRadio** comes with 6 preconfigured (hard coded) themes:

pyradio.1

+1-6
Original file line numberDiff line numberDiff line change
@@ -350,16 +350,11 @@ The \fISearch Window\fR supports normal and extend editing and in session histor
350350

351351
One can always get help by pressing the "\fI?\fR" key.
352352

353-
The search will be case insensitive under \fBpython 3\fR; it will be case sensitive under \fBpython 2\fR.
354-
355-
After a search term has been successfully found, next occurrence can be obtained using the "\fIn\fR" key and previous occurrence can be obtained using the "\fIN\fR" key.
353+
After a search term has been successfully found (search is case insensitive), next occurrence can be obtained using the "\fIn\fR" key and previous occurrence can be obtained using the "\fIN\fR" key.
356354

357355
.IP \fBNote\fR
358356
\fBPython 2\fR users are confined in typing ASCII characters only.
359357

360-
.IP \fBNote\fR
361-
Currently, the \fBsearch function\fR is available on the stations', playlists' and themes' window only.
362-
363358
.SH PYRADIO THEMES
364359
.PP
365360

pyradio/__init__.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
" pyradio -- Console radio player. "
22

3-
version_info = (0, 7, 8)
3+
version_info = (0, 7, 9)
44

55
__version__ = version = '.'.join(map(str, version_info))
66
__project__ = __name__

pyradio/edit.py

+13-7
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,8 @@ class PyRadioSearch(SimpleCursesLineEdit):
1818

1919
def __init__(self, parent, begin_y, begin_x, **kwargs):
2020
SimpleCursesLineEdit.__init__(self, parent, begin_y, begin_x,
21-
key_up_function_handler=self._get_history_next,
22-
key_down_function_handler=self._get_history_previous,
21+
key_up_function_handler=self._get_history_previous,
22+
key_down_function_handler=self._get_history_next,
2323
**kwargs)
2424
if version_info < (3, 0):
2525
self._range_command='xrange'
@@ -64,13 +64,13 @@ def _get_history_previous(self):
6464
def get_next(self, a_list, start=0, stop=None):
6565
if self.string:
6666
for n in eval(self._range_command)(start, len(a_list)):
67-
if self.string.lower() in a_list[n][0].lower():
67+
if self.string.lower() in self._get_string(a_list[n]):
6868
if logger.isEnabledFor(logging.DEBUG):
6969
logger.debug('forward search term "{0}" found at {1}'.format(self.string, n))
7070
return n
7171
""" if not found start from list top """
7272
for n in eval(self._range_command)(0, start):
73-
if self.string.lower() in a_list[n][0].lower():
73+
if self.string.lower() in self._get_string(a_list[n]):
7474
if logger.isEnabledFor(logging.DEBUG):
7575
logger.debug('forward search term "{0}" found at {1}'.format(self.string, n))
7676
return n
@@ -84,13 +84,13 @@ def get_next(self, a_list, start=0, stop=None):
8484
def get_previous(self, a_list, start=0, stop=None):
8585
if self.string:
8686
for n in eval(self._range_command)(start, -1, -1):
87-
if self.string.lower() in a_list[n][0].lower():
87+
if self.string.lower() in self._get_string(a_list[n]):
8888
if logger.isEnabledFor(logging.DEBUG):
8989
logger.debug('backward search term "{0}" found at {1}'.format(self.string, n))
9090
return n
9191
""" if not found start from list end """
9292
for n in eval(self._range_command)(len(a_list) - 1, start, -1):
93-
if self.string.lower() in a_list[n][0].lower():
93+
if self.string.lower() in self._get_string(a_list[n]):
9494
if logger.isEnabledFor(logging.DEBUG):
9595
logger.debug('backward search term "{0}" found at {1}'.format(self.string, n))
9696
return n
@@ -106,4 +106,10 @@ def print_not_found(self):
106106
self._edit_win.refresh()
107107
sleep(.3)
108108
self.refreshEditWindow()
109-
109+
110+
def _get_string(self, item):
111+
if isinstance(item, str):
112+
return item.lower()
113+
else:
114+
return item[0].lower()
115+

pyradio/radio.py

+48-12
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
# Ben Dowling - 2009 - 2010
66
# Kirill Klenov - 2012
77
# Peter Stevenson (2E0PGS) - 2018
8-
# Spiros Georgaras - 2018
8+
# Spiros Georgaras - 2018, 2019
99

1010
import curses
1111
import threading
@@ -77,6 +77,9 @@ class PyRadio(object):
7777
ord(','), ord('+'), ord('-'),
7878
ord('?'), ord('#'), curses.KEY_RESIZE)
7979

80+
""" Characters to be "ignored" by windows that support search"""
81+
_chars_to_bypass_for_search = (ord('/'), ord('n'), ord('N'))
82+
8083
# Number of stations to change with the page up/down keys
8184
pageChange = 5
8285

@@ -208,6 +211,8 @@ def __init__(self, pyradio_config, play=False, req_player='', theme=''):
208211
self.ws.NORMAL_MODE: self.ws.SEARCH_NORMAL_MODE,
209212
self.ws.PLAYLIST_MODE: self.ws.SEARCH_PLAYLIST_MODE,
210213
self.ws.THEME_MODE: self.ws.SEARCH_THEME_MODE,
214+
self.ws.SELECT_PLAYLIST_MODE: self.ws.SEARCH_SELECT_PLAYLIST_MODE,
215+
self.ws.SELECT_STATION_MODE: self.ws.SEARCH_SELECT_STATION_MODE,
211216
}
212217
# search modes opened from main windows
213218
self.search_main_window_modes = (
@@ -507,9 +512,6 @@ def run(self):
507512
lambda: self.stop_update_notification_thread))
508513
self._update_notification_thread.start()
509514

510-
""" set up stations search """
511-
self._give_me_a_search_class(self.ws.operation_mode)
512-
513515
#signal.signal(signal.SIGINT, self.ctrl_c_handler)
514516
self.log.write('Selected player: {}'.format(self._format_player_string()), help_msg=True)
515517
#self.log.write_right('Press ? for help')
@@ -558,6 +560,10 @@ def _give_me_a_search_class(self, operation_mode):
558560
edit_color = curses.color_pair(5),
559561
cursor_color = curses.color_pair(6))
560562
self.search = self._search_classes[self._mode_to_search[operation_mode]]
563+
if self.ws.previous_operation_mode == self.ws.CONFIG_MODE:
564+
self.search.box_color = curses.color_pair(3)
565+
else:
566+
self.search.box_color = curses.color_pair(5)
561567

562568
def ctrl_c_handler(self, signum, frame):
563569
self.ctrl_c_pressed = True
@@ -800,7 +806,6 @@ def _show_theme_selector(self, changed_from_config=False):
800806
self.jumpnr = ''
801807
self._random_requested = False
802808
self._theme_selector = None
803-
self._give_me_a_search_class(self.ws.THEME_MODE)
804809
#if logger.isEnabledFor(logging.ERROR):
805810
# logger.error('DE\n\nself._theme = {0}\nself._theme_name = {1}\nself._cnf.theme = {2}\n\n'.format(self._theme, self._theme_name, self._cnf.theme))
806811
self._theme_selector = PyRadioThemeSelector(self.bodyWin, self._cnf, self._theme,
@@ -1068,7 +1073,7 @@ def _show_search_help(self):
10681073
^U |Clear line.
10691074
DEL|,|^D |Delete character.
10701075
Backspace|,|^H |Backspace (delete previous character).
1071-
Up|,|^N| / |Down|,|^P |Get previous / next history item.
1076+
Up|,|^P| / |Down|,|^N |Get previous / next history item.
10721077
Enter| / |Esc |Perform / cancel search.
10731078
10741079
|Managing player volume does not work in search mode.
@@ -1108,6 +1113,7 @@ def _show_config_playlist_help(self):
11081113
g| / |<n>G |Jump to first or n-th / last playlist.
11091114
Enter|,|Space|,
11101115
Right|,|l |Select default playlist.
1116+
/| / |n| / |N |Search, go to next / previous result.
11111117
r |Revert to saved value.
11121118
Esc|,|q|,|Left|,|h |Canel.
11131119
%_Player Keys_
@@ -1122,6 +1128,7 @@ def _show_config_station_help(self):
11221128
M |Jump to the middle of the list.
11231129
Enter|,|Space|,
11241130
Right|,|l |Select default station.
1131+
/| / |n| / |N |Search, go to next / previous result.
11251132
r |Revert to saved value.
11261133
Esc|,|q|,|Left|,|h |Canel.
11271134
%_Player Keys_
@@ -1372,7 +1379,6 @@ def _print_update_notification(self):
13721379
is_message=True)
13731380
self._update_version = ''
13741381

1375-
13761382
def _align_stations_and_refresh(self, cur_mode):
13771383
need_to_scan_playlist = False
13781384
""" refresh reference """
@@ -1482,7 +1488,6 @@ def _open_playlist(self):
14821488
self._show_help(txt, self.ws.NORMAL_MODE, caption=' ', prompt=' ', is_message=True)
14831489
self.selections[self.ws.operation_mode] = [self.selection, self.startPos, self.playing, self._cnf.stations]
14841490
self.ws.window_mode = self.ws.PLAYLIST_MODE
1485-
self._give_me_a_search_class(self.ws.PLAYLIST_MODE)
14861491
self.selection, self.startPos, self.playing, self.stations = self.selections[self.ws.operation_mode]
14871492
self.number_of_items, self.playing = self.readPlaylists()
14881493
self.stations = self._cnf.playlists
@@ -1768,13 +1773,21 @@ def _apply_main_windows(ret):
17681773
_apply_main_windows(ret)
17691774
elif self.ws.operation_mode == self.ws.THEME_MODE:
17701775
self._theme_selector.set_theme(self._theme_selector._themes[ret])
1776+
elif self.ws.operation_mode == self.ws.SELECT_PLAYLIST_MODE:
1777+
self._playlist_select_win.setPlaylistById(ret, adjust=True)
1778+
elif self.ws.operation_mode == self.ws.SELECT_STATION_MODE:
1779+
self._station_select_win.setPlaylistById(ret, adjust=True)
17711780
self.refreshBody()
17721781

17731782
else:
17741783
if self.ws.operation_mode in self.search_main_window_modes:
17751784
_apply_main_windows(ret)
17761785
elif self.ws.previous_operation_mode == self.ws.THEME_MODE:
17771786
self._theme_selector.set_theme(self._theme_selector._themes[ret])
1787+
elif self.ws.previous_operation_mode == self.ws.SELECT_PLAYLIST_MODE:
1788+
self._playlist_select_win.setPlaylistById(ret, adjust=True)
1789+
elif self.ws.previous_operation_mode == self.ws.SELECT_STATION_MODE:
1790+
self._station_select_win.setPlaylistById(ret, adjust=True)
17781791
self.ws.close_window()
17791792
self.refreshBody()
17801793

@@ -1992,7 +2005,8 @@ def keypress(self, char):
19922005
return
19932006

19942007
elif self.ws.operation_mode == self.ws.SELECT_PLAYLIST_MODE:
1995-
if char not in self._chars_to_bypass:
2008+
if char not in self._chars_to_bypass and \
2009+
char not in self._chars_to_bypass_for_search:
19962010
ret, ret_playlist = self._playlist_select_win.keypress(char)
19972011
if ret >= 0:
19982012
if ret == 0:
@@ -2008,7 +2022,8 @@ def keypress(self, char):
20082022
return
20092023

20102024
elif self.ws.operation_mode == self.ws.SELECT_STATION_MODE:
2011-
if char not in self._chars_to_bypass:
2025+
if char not in self._chars_to_bypass and \
2026+
char not in self._chars_to_bypass_for_search:
20122027
ret, ret_station = self._station_select_win.keypress(char)
20132028
if ret >= 0:
20142029
if ret == 0:
@@ -2043,7 +2058,8 @@ def keypress(self, char):
20432058

20442059
elif self.ws.operation_mode == self.ws.THEME_MODE:
20452060
if char not in self._chars_to_bypass and \
2046-
char not in (ord('T'), ord('/'), ord('n'), ord('N'), ):
2061+
char not in self._chars_to_bypass_for_search and \
2062+
char not in (ord('T'),):
20472063
theme_id, save_theme = self._theme_selector.keypress(char)
20482064

20492065
#if self._cnf.theme_not_supported:
@@ -2114,6 +2130,7 @@ def keypress(self, char):
21142130
self.jumpnr = ''
21152131
self._random_requested = False
21162132
#self.search.string = '부'
2133+
self._give_me_a_search_class(self.ws.operation_mode)
21172134
self.search.show(self.bodyWin)
21182135
self.ws.operation_mode = self._search_modes[self.ws.operation_mode]
21192136
return
@@ -2133,6 +2150,13 @@ def keypress(self, char):
21332150
elif self.ws.operation_mode == self.ws.THEME_MODE:
21342151
self._search_list = self._theme_selector._themes
21352152
sel = self._theme_selector.selection + 1
2153+
elif self.ws.operation_mode == self.ws.SELECT_PLAYLIST_MODE:
2154+
self._search_list = self._playlist_select_win._items
2155+
sel = self._playlist_select_win._selected_playlist_id + 1
2156+
elif self.ws.operation_mode == self.ws.SELECT_STATION_MODE:
2157+
self._search_list = self._station_select_win._items
2158+
sel = self._station_select_win._selected_playlist_id + 1
2159+
21362160
if self.search.string:
21372161
if sel == len(self._search_list):
21382162
sel = 0
@@ -2157,6 +2181,13 @@ def keypress(self, char):
21572181
elif self.ws.operation_mode == self.ws.THEME_MODE:
21582182
self._search_list = self._theme_selector._themes
21592183
sel = self._theme_selector.selection - 1
2184+
elif self.ws.operation_mode == self.ws.SELECT_PLAYLIST_MODE:
2185+
self._search_list = self._playlist_select_win._items
2186+
sel = self._playlist_select_win._selected_playlist_id - 1
2187+
elif self.ws.operation_mode == self.ws.SELECT_STATION_MODE:
2188+
self._search_list = self._station_select_win._items
2189+
sel = self._station_select_win._selected_playlist_id - 1
2190+
21602191
if self.search.string:
21612192
if sel < 0:
21622193
sel = len(self._search_list) - 1
@@ -2178,12 +2209,17 @@ def keypress(self, char):
21782209
elif self.ws.previous_operation_mode == self.ws.THEME_MODE:
21792210
self._search_list = self._theme_selector._themes
21802211
sel = self._theme_selector.selection + 1
2212+
elif self.ws.previous_operation_mode == self.ws.SELECT_PLAYLIST_MODE:
2213+
self._search_list = self._playlist_select_win._items
2214+
sel = self._playlist_select_win._selected_playlist_id + 1
2215+
elif self.ws.previous_operation_mode == self.ws.SELECT_STATION_MODE:
2216+
self._search_list = self._station_select_win._items
2217+
sel = self._station_select_win._selected_playlist_id + 1
21812218

21822219
# perform search
21832220
if sel == len(self._search_list):
21842221
sel = 0
21852222
ret = self.search.get_next(self._search_list, sel)
2186-
logger.error('DE ret = {}'.format(ret))
21872223
if ret is None:
21882224
if self.search.string:
21892225
self.search.print_not_found()

pyradio/simple_curses_widgets.py

+4-4
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ class SimpleCursesLineEdit(object):
5050
focused = True
5151
_focused = True
5252

53+
_max_width = 0
5354

5455
log = None
5556
_log_file = ''
@@ -242,6 +243,7 @@ def keypress(self, win, char):
242243
""" ESCAPE """
243244
self._string = ''
244245
self._curs_pos = 0
246+
self._input_history.reset_index()
245247
return -1
246248
else:
247249
if self.log is not None:
@@ -491,11 +493,9 @@ def return_history(self, direction):
491493
if self._history:
492494
self._active_history_index += direction
493495
if self._active_history_index <= -1:
494-
self._active_history_index = -1
495-
return ''
496+
self._active_history_index = len(self._history) - 1
496497
elif self._active_history_index >= len(self._history):
497-
self._active_history_index = len(self._history)
498-
return ''
498+
self._active_history_index = 0
499499
ret = self._history[self._active_history_index]
500500
return ret
501501
return ''

pyradio/window_stack.py

+12-8
Original file line numberDiff line numberDiff line change
@@ -14,14 +14,16 @@ class Window_Stack_Constants(object):
1414
SEARCH_NORMAL_MODE = 2
1515
SEARCH_PLAYLIST_MODE = 3
1616
SEARCH_THEME_MODE = 4
17-
CONFIG_MODE = 5
18-
SELECT_PLAYER_MODE = 6
19-
SELECT_ENCODING_MODE = 7
20-
SELECT_PLAYLIST_MODE = 8
21-
SELECT_STATION_MODE = 9
22-
SELECT_STATION_ENCODING_MODE = 10
23-
NEW_THEME_MODE = 11
24-
EDIT_THEME_MODE = 12
17+
SEARCH_SELECT_PLAYLIST_MODE = 5
18+
SEARCH_SELECT_STATION_MODE = 6
19+
CONFIG_MODE = 7
20+
SELECT_PLAYER_MODE = 8
21+
SELECT_ENCODING_MODE = 9
22+
SELECT_PLAYLIST_MODE = 10
23+
SELECT_STATION_MODE = 11
24+
SELECT_STATION_ENCODING_MODE = 12
25+
NEW_THEME_MODE = 13
26+
EDIT_THEME_MODE = 14
2527
REMOVE_STATION_MODE = 50
2628
SAVE_PLAYLIST_MODE = 51
2729
ASK_TO_SAVE_PLAYLIST_WHEN_OPENING_PLAYLIST_MODE = 52
@@ -64,6 +66,8 @@ class Window_Stack_Constants(object):
6466
SEARCH_NORMAL_MODE: 'SEARCH_NORMAL_MODE',
6567
SEARCH_PLAYLIST_MODE: 'SEARCH_PLAYLIST_MODE',
6668
SEARCH_THEME_MODE: 'SEARCH_THEME_MODE',
69+
SEARCH_SELECT_PLAYLIST_MODE: 'SEARCH_SELECT_PLAYLIST_MODE',
70+
SEARCH_SELECT_STATION_MODE: 'SEARCH_SELECT_STATION_MODE',
6771
CONFIG_MODE: 'CONFIG_MODE',
6872
SELECT_PLAYER_MODE: 'SELECT_PLAYER_MODE',
6973
SELECT_ENCODING_MODE: 'SELECT_ENCODING_MODE',

0 commit comments

Comments
 (0)