Skip to content

Commit 492a007

Browse files
committed
station history ready (for same playlist only)
1 parent d432d76 commit 492a007

File tree

6 files changed

+212
-16
lines changed

6 files changed

+212
-16
lines changed

README.html

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1497,6 +1497,8 @@ <h2 id="packaging-pyradio">Packaging PyRadio <span style="padding-left: 10px;"><
14971497
<p>If you are a packager and would like to produce a package for your distribution please do follow this mini guide.</p>
14981498
<p>First of all, make sure you declare the pacakges’s requirements to the relevant section of your manifest (or whatever) file. These are:</p>
14991499
<ol type="1">
1500+
<li>setuptools</li>
1501+
<li>wheel</li>
15001502
<li>requests</li>
15011503
<li>dnspython</li>
15021504
<li>psutil</li>

README.md

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1061,9 +1061,11 @@ If you are a packager and would like to produce a package for your distribution
10611061

10621062
First of all, make sure you declare the pacakges's requirements to the relevant section of your manifest (or whatever) file. These are:
10631063

1064-
1. requests
1065-
2. dnspython
1066-
3. psutil
1064+
1. setuptools
1065+
2. wheel
1066+
3. requests
1067+
4. dnspython
1068+
5. psutil
10671069

10681070
After that, you will have to modify some files, because **PyRadio** is able to update and uninstall itself, when installed from source. This is something you do not want to be happening when your package is used; **PyRadio** should be updated and uninstalled using the distro package manager.
10691071

pyradio/config.py

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,9 @@ class PyRadioStations(object):
104104
''' last opened playlist splitted on , '''
105105
last_playlist_to_open = []
106106

107+
station_history = None
108+
play_from_history = False
109+
107110
def __init__(self, stationFile=''):
108111
if platform.startswith('win'):
109112
self._open_string_id = 1
@@ -292,6 +295,18 @@ def can_go_back_in_time(self):
292295
def can_go_back_in_time(self, value):
293296
raise ValueError('property is read only')
294297

298+
def set_station_history(self,
299+
execute_funct,
300+
pass_first_item_funct,
301+
pass_last_item_funct,
302+
no_items_funct):
303+
self.stations_history = PyRadioStationsStack(
304+
execute_function=execute_funct,
305+
pass_first_item_function=pass_first_item_funct,
306+
pass_last_item_function=pass_last_item_funct,
307+
no_items_function=no_items_funct
308+
)
309+
295310
def save_last_playlist(self, sel):
296311
lp = path.join(self.stations_dir, 'last_playlist')
297312
llp = self._ps.last_local_playlist
@@ -2411,6 +2426,77 @@ def replace(self, a_search_path, new_item):
24112426
return ret
24122427

24132428

2429+
class PyRadioStationsStack(object):
2430+
pass_first_item_func=None
2431+
pass_last_item_func=None
2432+
no_items_func=None
2433+
2434+
def __init__(
2435+
self,
2436+
execute_function,
2437+
pass_first_item_function=None,
2438+
pass_last_item_function=None,
2439+
no_items_function=None
2440+
):
2441+
self.items = []
2442+
self.item = -1
2443+
self.execute_func = execute_function
2444+
self.pass_first_item_func = pass_first_item_function
2445+
self.pass_last_item_func = pass_last_item_function
2446+
self.no_items_func = no_items_function
2447+
2448+
def add(self, a_playlist, a_station, a_station_id):
2449+
if a_playlist and a_station:
2450+
if self.item == -1:
2451+
self.items.append((a_playlist, a_station, a_station_id))
2452+
self.item = 0
2453+
else:
2454+
if not self.play_from_history and \
2455+
(self.items[-1][0] != a_playlist \
2456+
or self.items[-1][1] != a_station) and \
2457+
(self.items[self.item][0] != a_playlist \
2458+
or self.items[self.item][1] != a_station):
2459+
self.items.append((a_playlist, a_station, a_station_id))
2460+
logger.error('adding item...')
2461+
self.item = len(self.items) - 1
2462+
self.play_from_history = False
2463+
if logger.isEnabledFor(logging.DEBUG):
2464+
logger.debug('>>> Stations history')
2465+
for n in self.items:
2466+
logger.debug(' {}'.format(n))
2467+
logger.debug(' item = {}'.format(self.item))
2468+
2469+
def _get(self):
2470+
if self.item == -1:
2471+
if self.no_items_func is not None:
2472+
self.no_items_func()
2473+
return tuple(self.items[self.item])
2474+
2475+
def play_previous(self):
2476+
if self.item == -1:
2477+
if self.no_items_func is not None:
2478+
self.no_items_func()
2479+
elif self.item == 0:
2480+
if self.pass_first_item_func is not None:
2481+
self.pass_first_item_func()
2482+
else:
2483+
old_item = self._get()
2484+
self.item -= 1
2485+
self.execute_func(old_item, self._get())
2486+
2487+
def play_next(self):
2488+
if self.item == -1:
2489+
if self.no_items_func is not None:
2490+
self.no_items_func()
2491+
elif self.item == len(self.items) - 1:
2492+
if self.pass_last_item_func is not None:
2493+
self.pass_last_item_func()
2494+
else:
2495+
old_item = self._get()
2496+
self.item += 1
2497+
self.execute_func(old_item, self._get())
2498+
2499+
24142500
class PyRadioLog(object):
24152501

24162502
PATTERN = '%(asctime)s - %(name)s - %(levelname)s - %(message)s'

pyradio/player.py

Lines changed: 36 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -230,7 +230,7 @@ class Player(object):
230230
icy_tokens = ()
231231
icy_audio_tokens = {}
232232

233-
playback_is_on = False
233+
playback_is_on = connecting = False
234234

235235
_station_encoding = 'utf-8'
236236

@@ -255,9 +255,11 @@ def __init__(self,
255255
outputStream,
256256
playback_timeout_counter,
257257
playback_timeout_handler,
258-
info_display_handler):
258+
info_display_handler,
259+
history_add_function):
259260
self.outputStream = outputStream
260261
self._cnf = config
262+
self.stations_history_add_function = history_add_function
261263
self.config_encoding = self._cnf.default_encoding
262264
self.config_dir = self._cnf.stations_dir
263265
try:
@@ -632,7 +634,9 @@ def updateStatus(self, *args):
632634
new_input = self.oldUserInput['Title']
633635
self.outputStream.write(msg=new_input, counter='')
634636
self.playback_is_on = True
637+
self.connecting = False
635638
self._stop_delay_thread()
639+
self.stations_history_add_function()
636640
if 'AO: [' in subsystemOut:
637641
with self.status_update_lock:
638642
if version_info > (3, 0):
@@ -665,6 +669,8 @@ def updateStatus(self, *args):
665669
if logger.isEnabledFor(logging.INFO):
666670
logger.info('*** updateStatus(): Start of playback detected (Icy-Title received) ***')
667671
self.playback_is_on = True
672+
self.connecting = False
673+
self.stations_history_add_function()
668674
''' detect empty Icy-Title '''
669675
title_without_prefix = title[len(self.icy_title_prefix):].strip()
670676
# logger.error('DE title_without_prefix = "{}"'.format(title_without_prefix))
@@ -707,6 +713,8 @@ def updateStatus(self, *args):
707713
if logger.isEnabledFor(logging.INFO):
708714
logger.info('*** updateStatus(): Start of playback detected (Icy audio token received) ***')
709715
self.playback_is_on = True
716+
self.connecting = False
717+
self.stations_history_add_function()
710718
if enable_crash_detection_function:
711719
enable_crash_detection_function()
712720
# logger.error('DE token = "{}"'.format(a_token))
@@ -968,7 +976,9 @@ def do_crash_detection(detect_if_player_exited, stop):
968976
new_input = self.oldUserInput['Title']
969977
self.outputStream.write(msg=new_input, counter='')
970978
self.playback_is_on = True
979+
self.connecting = False
971980
self._stop_delay_thread()
981+
self.stations_history_add_function()
972982
if 'AO: [' in subsystemOut:
973983
with self.status_update_lock:
974984
if version_info > (3, 0):
@@ -989,7 +999,9 @@ def do_crash_detection(detect_if_player_exited, stop):
989999
except:
9901000
pass
9911001
self.playback_is_on = True
1002+
self.connecting = False
9921003
self._stop_delay_thread()
1004+
self.stations_history_add_function()
9931005
if enable_crash_detection_function:
9941006
enable_crash_detection_function()
9951007

@@ -1033,7 +1045,9 @@ def do_crash_detection(detect_if_player_exited, stop):
10331045
except:
10341046
pass
10351047
self.playback_is_on = True
1048+
self.connecting = False
10361049
self._stop_delay_thread()
1050+
self.stations_history_add_function()
10371051
if enable_crash_detection_function:
10381052
enable_crash_detection_function()
10391053
# logger.error('DE token = "{}"'.format(a_token))
@@ -1233,12 +1247,14 @@ def _set_mpv_playback_is_on(self, stop, enable_crash_detection_function):
12331247
self.detect_if_player_exited = True
12341248
if (not self.playback_is_on) and (logger.isEnabledFor(logging.INFO)):
12351249
logger.info('*** _set_mpv_playback_is_on(): Start of playback detected ***')
1250+
self.stations_history_add_function()
12361251
new_input = 'Playing: ' + self.name
12371252
self.outputStream.write(msg=new_input, counter='')
12381253
if self.oldUserInput['Title'] == '':
12391254
self.oldUserInput['Input'] = new_input
12401255
self.oldUserInput['Title'] = new_input
12411256
self.playback_is_on = True
1257+
self.connecting = False
12421258
if stop():
12431259
return False
12441260
enable_crash_detection_function()
@@ -1381,6 +1397,10 @@ def play(self,
13811397
# start playback check timer thread
13821398
self.stop_timeout_counter_thread = False
13831399
if self.playback_timeout > 0:
1400+
''' set connecting here insead of Player.play()
1401+
so that we do not use it when timeout = 0
1402+
'''
1403+
self.connecting = True
13841404
try:
13851405
self.connection_timeout_thread = threading.Thread(
13861406
target=self.playback_timeout_counter,
@@ -1392,10 +1412,12 @@ def play(self,
13921412
if (logger.isEnabledFor(logging.DEBUG)):
13931413
logger.debug('playback detection thread started')
13941414
except:
1415+
self.connecting = False
13951416
self.connection_timeout_thread = None
13961417
if (logger.isEnabledFor(logging.ERROR)):
13971418
logger.error('playback detection thread failed to start')
13981419
else:
1420+
self.connecting = False
13991421
if logger.isEnabledFor(logging.DEBUG):
14001422
logger.debug('playback detection thread not starting (timeout is 0)')
14011423
if logger.isEnabledFor(logging.INFO):
@@ -1614,14 +1636,16 @@ def __init__(self,
16141636
outputStream,
16151637
playback_timeout_counter,
16161638
playback_timeout_handler,
1617-
info_display_handler):
1639+
info_display_handler,
1640+
history_add_function):
16181641
config.PLAYER_NAME = 'mpv'
16191642
super(MpvPlayer, self).__init__(
16201643
config,
16211644
outputStream,
16221645
playback_timeout_counter,
16231646
playback_timeout_handler,
1624-
info_display_handler
1647+
info_display_handler,
1648+
history_add_function
16251649
)
16261650
self.config_files = self.all_config_files['mpv']
16271651

@@ -2039,14 +2063,16 @@ def __init__(self,
20392063
outputStream,
20402064
playback_timeout_counter,
20412065
playback_timeout_handler,
2042-
info_display_handler):
2066+
info_display_handler,
2067+
history_add_function):
20432068
config.PLAYER_NAME = 'mplayer'
20442069
super(MpPlayer, self).__init__(
20452070
config,
20462071
outputStream,
20472072
playback_timeout_counter,
20482073
playback_timeout_handler,
2049-
info_display_handler
2074+
info_display_handler,
2075+
history_add_function
20502076
)
20512077
self.config_files = self.all_config_files['mplayer']
20522078

@@ -2247,14 +2273,16 @@ def __init__(self,
22472273
outputStream,
22482274
playback_timeout_counter,
22492275
playback_timeout_handler,
2250-
info_display_handler):
2276+
info_display_handler,
2277+
history_add_function):
22512278
config.PLAYER_NAME = 'vlc'
22522279
super(VlcPlayer, self).__init__(
22532280
config,
22542281
outputStream,
22552282
playback_timeout_counter,
22562283
playback_timeout_handler,
2257-
info_display_handler
2284+
info_display_handler,
2285+
history_add_function
22582286
)
22592287
# self.config_files = self.all_config_files['vlc']
22602288

0 commit comments

Comments
 (0)