Skip to content

Commit 7c35564

Browse files
committed
adding config option console_theme
1 parent d67e2bd commit 7c35564

File tree

9 files changed

+144
-42
lines changed

9 files changed

+144
-42
lines changed

README.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -141,11 +141,11 @@ This will display the program's window with a list of predefined radio stations
141141

142142
- Press "**+**" (or "**.**") and "**-**" (or "**,**") to adjust the volume, and "**v**" to save it.
143143

144-
- Pressing "**?**" will give you access to the help screens; "**\\h**" will give you access to the help pages.
144+
- Pressing "**?**" will give you access to the help screens; "**\\h**" will give you access to the HTML help pages.
145145

146146
- "**Esc**" or "**q**" will exit the program.
147147

148-
In case the list of predefined stations are not enough for you, you can press "**O**" (capital "**o**") to access **RadioBrowser** online directory; you will probably have to read [this page](docs/radio-browser.md) to learn how to navigate the interface.
148+
In case the list of predefined stations is not enough for you, you can press "**O**" (capital "**o**") to access **RadioBrowser** online directory; you will probably have to read [this page](docs/radio-browser.md) to learn how to navigate the interface.
149149

150150
**PyRadio** comes with a number of themes; press "**t**" to get a list of themes, and
151151

@@ -211,4 +211,5 @@ If you are a packager and would like to produce a package for your distribution
211211
## Special thanks
212212

213213
1. [edunfelt](https://github.com/edunfelt), for her wonderful work on [base16 themes](https://github.com/edunfelt/base16-pyradio), and ideas regarding theming and such.
214+
214215
2. [amano-kenji](https://github.com/amano-kenji), for his valuable suggestions and bug reports.

devel/pre-commit

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,7 @@ cd docs
121121
# update brew link in macos.md
122122
[ -z "$RUN_ALL_PROGRAMS" ] || update_brew_link
123123

124-
echo -ne "Updating files ... "
124+
echo -ne "Updating ${cBlue}HTML${cReset} files "
125125

126126
# Create HTML file from md files
127127
for afile in index.md \
@@ -140,6 +140,7 @@ for afile in index.md \
140140
headless.md \
141141
rec-dir.md
142142
do
143+
echo -ne '.'
143144
#[ -z "$(git status | grep ${afile})" ] || {
144145
out=${afile/%.md/.html}
145146
if [ "$afile" = "index.md" ];then
@@ -311,8 +312,7 @@ cd ..
311312
# git add pyradio/win.py
312313
# git add devel/update_win_mplayer
313314
# }
314-
315-
echo -e "${cGreen}done${sReset}
315+
echo -e "${cGreen} done${sReset}
316316
"
317317

318318
echo -e "${cBlue}Version:${cReset}"
@@ -340,6 +340,9 @@ then
340340
echo -e "${cReset}
341341
You should also run
342342
${cGreen}${0} -a${cReset}
343-
when you are ready to publish a new release"
343+
when you are ready to publish a new release
344+
"
345+
else
346+
echo
344347
fi
345348

docs/packaging.md

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
* [pyradio/\_\_pycache\_\_](#pyradio/\_\_pycache\_\_)
1313
* [Recordings Directory](#recordings-directory)
1414
* [MKVToolNix cli installation](#mkvtoolnix-cli-installation)
15+
* [Resource opener (Linux only)](#resource-opener-(linux-only))
1516

1617
<!-- vim-markdown-toc -->
1718

@@ -36,11 +37,6 @@ Then you have to add the following python modules to the relevant section of you
3637
5. netifaces
3738
6. dateutil
3839

39-
Linux users will have to install the "**xdg-utils**" package (may be named differently in your distro) which will provide "**xdg-open**", the utility to open directories, html pages, etc.
40-
41-
Linux and macOS users will have to have installed a font that supports the "**Unicode Geometric Shapes Block**". Any font mentioned in the [Font Support for Unicode Block 'Geometric Shapes'](https://www.fileformat.info/info/unicode/block/geometric_shapes/fontsupport.htm) page will do; as you can see these include **DejaVu**, **FreeMono**, **Unifont**, etc, some of which will fopefully be installed by default.
42-
43-
4440
## Files to change
4541

4642
You will have to modify a couple of files to tailor **PyRadio**' to your needs and liking.
@@ -139,4 +135,20 @@ I would suggest to do so, in order to provide your users the best experience pos
139135

140136
In case you decide to do so, please make sure you mark as a dependency the **command line utilities**, not the GUI program, if that's on a different package on your distro. For examle, Arch Linux provides both a *mkvtoolnix-cli* and a *mkvtoolnix-gui* package; the first one should be used. Same thing with Debian Linux; it provides both a *mkvtoolnix* and a *mkvtoolnix-gui* package; in which case you'd use the later.
141137

138+
## Resource opener (Linux only)
139+
140+
A [resource opener](https://wiki.archlinux.org/title/default_applications#Resource_openers) is a utility to open directories, html pages, etc.
141+
142+
**PyRadio** running on Linux will look for *xdg-open*, *gio*, *mimeopen*, *mimeo* or *handlr*, in that order of detection.
143+
144+
If none of the above if found, the requested file will simply not open.
145+
146+
Most Linux distros will probably have *xdg-open* (from *xdg-utils* package) installed or available (or any of the ones in the list above), so no action will be nesesary.
147+
148+
In case a different *resource opener* is to be used, one can declare it like so:
149+
150+
sed -i 's/resource_opener = auto/resource_opener = MY_RESOURCE_OPENER/' config
151+
152+
This will instruct **PyRadio** to use the file **MY_RESOURCE_OPENER** as a *resource opener*.
142153

154+
**MY_RESOURCE_OPENER** can be just the name of the file (if it is in the *PATH*), or an absolute path to a file, it it's not.

pyradio/config

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ player = mpv, mplayer, vlc
1111

1212
# Default playlist
1313
# This is the playlist to open if none is specified
14-
# You can scecify full path to CSV file, or if the playlist is in the config
14+
# You can specify full path to CSV file, or if the playlist is in the config
1515
# directory, playlist name (filename without extension or playlist number (as
1616
# reported by -ls command line option)
1717
#
@@ -98,7 +98,7 @@ connection_timeout = 10
9898
force_http = False
9999

100100
# Default theme
101-
# Hardcooded themes:
101+
# Hard coded themes:
102102
# dark (default) (8 colors)
103103
# light (8 colors)
104104
# dark_16_colors (16 colors dark theme alternative)
@@ -131,7 +131,7 @@ use_transparency = False
131131
force_transparency = False
132132

133133
# Calculated color factor
134-
# This is to produce Secondary Windows background color. A value of 0 dissables
134+
# This is to produce Secondary Windows background color. A value of 0 disables
135135
# it, otherwise it is the factor to change (lighten or darken) the base color.
136136
# For more info, please refer to
137137
# https://github.com/coderholic/pyradio#secondary-windows-background
@@ -140,6 +140,14 @@ force_transparency = False
140140
# Default value: 0
141141
calculated_color_factor = 0
142142

143+
# Console theme
144+
# This is the theme to be used when a PyRasio is executed either in a linux
145+
# virtual console, or on a terminal that does not support color change.
146+
# Possible values: dark / light
147+
#
148+
# Default value: dark
149+
console_theme = dark
150+
143151

144152
# Playlist management
145153
#
@@ -186,7 +194,7 @@ remote_control_server_auto_start = False
186194
# Packagers should set this paramater as resired!
187195
#
188196
# Default value: False
189-
xdg_compliant = False
197+
xdg_compliant = True
190198

191199
# The name of the distribution providing the package. If this parameter is set
192200
# to anything other than "None" PyRadio will not permit updating (-U command

pyradio/config.py

Lines changed: 53 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1295,6 +1295,7 @@ class PyRadioConfig(PyRadioStations):
12951295
opts['use_transparency'] = ['Use transparency: ', False]
12961296
opts['force_transparency'] = [' Force transparency: ', False]
12971297
opts['calculated_color_factor'] = ['Calculated color: ', '0']
1298+
opts['console_theme'] = ['Console theme: ', 'dark']
12981299
opts['playlist_manngement_title'] = ['Playlist Management Options', '']
12991300
opts['confirm_station_deletion'] = ['Confirm station deletion: ', True]
13001301
opts['confirm_playlist_reload'] = ['Confirm playlist reload: ', True]
@@ -1657,6 +1658,17 @@ def theme(self, val):
16571658
self.opts['auto_update_theme'][1] = False
16581659
self.opts['dirty_config'][1] = True
16591660

1661+
@property
1662+
def console_theme(self):
1663+
return self.opts['console_theme'][1]
1664+
1665+
@console_theme.setter
1666+
def console_theme(self, val):
1667+
if val in ('dark', 'light'):
1668+
if val != self.opts['console_theme'][1]:
1669+
self.opts['dirty_config'][1] = True
1670+
self.opts['console_theme'][1] = val
1671+
16601672
@property
16611673
def theme_path(self):
16621674
return path.join(self.stations_dir, 'themes', self.opts['theme'][1] + '.pyradio-theme')
@@ -1939,21 +1951,38 @@ def remove_session_lock_file(self):
19391951
return -1, self._session_lock_file
19401952

19411953
def change_to_no_theme_mode(self, show_colors_cannot_change):
1942-
curses.init_pair(1, curses.COLOR_CYAN, curses.COLOR_BLACK)
1943-
curses.init_pair(2, curses.COLOR_BLUE, curses.COLOR_BLACK)
1944-
curses.init_pair(3, curses.COLOR_YELLOW, curses.COLOR_BLACK)
1945-
curses.init_pair(4, curses.COLOR_GREEN, curses.COLOR_BLACK)
1946-
curses.init_pair(5, curses.COLOR_WHITE, curses.COLOR_BLACK)
1947-
curses.init_pair(6, curses.COLOR_BLACK, curses.COLOR_MAGENTA)
1948-
curses.init_pair(7, curses.COLOR_BLACK, curses.COLOR_GREEN)
1949-
curses.init_pair(8, curses.COLOR_WHITE, curses.COLOR_BLACK)
1950-
curses.init_pair(9, curses.COLOR_BLACK, curses.COLOR_GREEN)
1951-
curses.init_pair(10, curses.COLOR_WHITE, curses.COLOR_BLACK)
1952-
curses.init_pair(11, curses.COLOR_GREEN, curses.COLOR_BLACK)
1953-
curses.init_pair(12, curses.COLOR_WHITE, curses.COLOR_BLACK)
1954-
curses.init_pair(13, curses.COLOR_WHITE, curses.COLOR_BLACK)
1955-
curses.init_pair(14, curses.COLOR_WHITE, curses.COLOR_BLACK)
1956-
curses.init_pair(15, curses.COLOR_WHITE, curses.COLOR_BLACK)
1954+
if self.console_theme == 'light':
1955+
curses.init_pair(1, curses.COLOR_MAGENTA, curses.COLOR_WHITE )
1956+
curses.init_pair(2, curses.COLOR_BLUE, curses.COLOR_WHITE)
1957+
curses.init_pair(3, curses.COLOR_RED, curses.COLOR_WHITE)
1958+
curses.init_pair(4, curses.COLOR_RED, curses.COLOR_WHITE)
1959+
curses.init_pair(5, curses.COLOR_BLACK, curses.COLOR_WHITE)
1960+
curses.init_pair(6, curses.COLOR_WHITE, curses.COLOR_MAGENTA)
1961+
curses.init_pair(7, curses.COLOR_WHITE, curses.COLOR_BLUE)
1962+
curses.init_pair(8, curses.COLOR_BLACK, curses.COLOR_WHITE)
1963+
curses.init_pair(9, curses.COLOR_WHITE, curses.COLOR_BLUE)
1964+
curses.init_pair(10, curses.COLOR_BLACK, curses.COLOR_WHITE)
1965+
curses.init_pair(11, curses.COLOR_RED, curses.COLOR_WHITE)
1966+
curses.init_pair(12, curses.COLOR_BLACK, curses.COLOR_WHITE)
1967+
curses.init_pair(13, curses.COLOR_BLACK, curses.COLOR_WHITE)
1968+
curses.init_pair(14, curses.COLOR_BLACK, curses.COLOR_WHITE)
1969+
curses.init_pair(15, curses.COLOR_BLACK, curses.COLOR_WHITE)
1970+
else:
1971+
curses.init_pair(1, curses.COLOR_CYAN, curses.COLOR_BLACK)
1972+
curses.init_pair(2, curses.COLOR_BLUE, curses.COLOR_BLACK)
1973+
curses.init_pair(3, curses.COLOR_YELLOW, curses.COLOR_BLACK)
1974+
curses.init_pair(4, curses.COLOR_GREEN, curses.COLOR_BLACK)
1975+
curses.init_pair(5, curses.COLOR_WHITE, curses.COLOR_BLACK)
1976+
curses.init_pair(6, curses.COLOR_BLACK, curses.COLOR_MAGENTA)
1977+
curses.init_pair(7, curses.COLOR_BLACK, curses.COLOR_GREEN)
1978+
curses.init_pair(8, curses.COLOR_WHITE, curses.COLOR_BLACK)
1979+
curses.init_pair(9, curses.COLOR_BLACK, curses.COLOR_GREEN)
1980+
curses.init_pair(10, curses.COLOR_WHITE, curses.COLOR_BLACK)
1981+
curses.init_pair(11, curses.COLOR_GREEN, curses.COLOR_BLACK)
1982+
curses.init_pair(12, curses.COLOR_WHITE, curses.COLOR_BLACK)
1983+
curses.init_pair(13, curses.COLOR_WHITE, curses.COLOR_BLACK)
1984+
curses.init_pair(14, curses.COLOR_WHITE, curses.COLOR_BLACK)
1985+
curses.init_pair(15, curses.COLOR_WHITE, curses.COLOR_BLACK)
19571986
''' Theme values backup '''
19581987
self.bck_opts['use_transparency'] = self.opts['use_transparency'][1]
19591988
self.bck_opts['force_transparency'] = self.opts['force_transparency'][1]
@@ -1963,7 +1992,7 @@ def change_to_no_theme_mode(self, show_colors_cannot_change):
19631992
''' No theme values '''
19641993
self.opts['use_transparency'][1] = False
19651994
self.opts['force_transparency'][1] = False
1966-
self.opts['theme'][1] = 'dark'
1995+
self.opts['theme'][1] = self.console_theme
19671996
self.opts['auto_update_theme'][1] = False
19681997
self.opts['calculated_color_factor'][1] = "0"
19691998
self._show_colors_cannot_change = show_colors_cannot_change
@@ -2107,6 +2136,12 @@ def _read_config(self, distro_config=False):
21072136
self.opts['auto_update_theme'][1] = True
21082137
else:
21092138
self.opts['auto_update_theme'][1] = False
2139+
elif sp[0] == 'console_theme':
2140+
tmp = sp[1].strip()
2141+
if not tmp in ('dark', 'light'):
2142+
self.opts['console_theme'][1] = 'dark'
2143+
else:
2144+
self.opts['console_theme'][1] = tmp
21102145
elif sp[0] == 'default_playlist':
21112146
self.opts['default_playlist'][1] = sp[1].strip()
21122147
elif sp[0] == 'default_station':
@@ -2598,9 +2633,9 @@ def save_config(self, from_command_line=False):
25982633
if self.use_themes:
25992634
theme = self.opts['theme'][1] if not self.opts['auto_update_theme'][1] else '*' + self.opts['theme'][1]
26002635
trnsp = self.opts['use_transparency'][1]
2601-
f_trnsp = self.opts['force_transparency']
2636+
f_trnsp = self.opts['force_transparency'][1]
26022637
calcf = self.opts['calculated_color_factor'][1]
2603-
auto = self.opts['auto_update_theme']
2638+
auto = self.opts['auto_update_theme'][1]
26042639
else:
26052640
theme = self.bck_opts['theme'] if not self.bck_opts['auto_update_theme'] else '*' + self.bck_opts['theme']
26062641
trnsp = self.bck_opts['use_transparency']

pyradio/config_window.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@ class PyRadioConfigWindow(object):
8888
"If True and a compositor is running, the stations' window background will be transparent.", '|', "If True and a compositor is not running, the terminal's background color will be used.", '|', 'Default value: False'])
8989
_help_text.append(['This option, when enabled, will make all themes behave as if their transparency setting was set to 2 (Obey config setting), in which case the windows\'s transparency will depend entirely on the value of the "Use transparency" setting (the option above this one).', '|', 'Default value: False'])
9090
_help_text.append(['Pyradio can calculate and use an alternative color for secondary windows.', '|', 'This option will determine if this color will be used (value > 0) or not (value = 0), provided that the theme used does not already provide it.', '|', 'The value of this option is actually the factor to darken or lighten the main (stations) background color.', '|', 'You can get more info on this at https://github.com/coderholic/pyradio#secondary-windows-background', '|', 'Valid Values: 0-0.2', 'Default value: 0'])
91+
_help_text.append(['The console theme is the one used when PyRadio is executed either from the Linux Virtual Console or the terminal used does not support color changes.', '|', 'This change will take effect after PyRadio is restarted.', '|', 'Default value: dark'])
9192
_help_text.append(None)
9293
_help_text.append(['Specify whether you will be asked to confirm every station deletion action.',
9394
'|', 'Default value: True'])
@@ -882,6 +883,17 @@ def keypress(self, char):
882883
self._win.refresh()
883884
return -1, []
884885

886+
elif val[0] == 'console_theme':
887+
if char in (
888+
curses.KEY_RIGHT, ord('l'), ord(' ')
889+
):
890+
if self._config_options['console_theme'][1] == 'dark':
891+
self._config_options['console_theme'][1] = 'light'
892+
else:
893+
self._config_options['console_theme'][1] = 'dark'
894+
self.refresh_selection()
895+
return -1, []
896+
885897
elif val[0] == 'connection_timeout':
886898
if char in (curses.KEY_RIGHT, ord('l')):
887899
t = int(val[1][1])

pyradio/html_help.py

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
import subprocess
33
import logging
44
from sys import platform
5-
from os import path, environ
5+
from os import path, environ, listdir
66
from shutil import which
77
from .install import get_a_linux_resource_opener
88
try:
@@ -16,22 +16,36 @@
1616
import locale
1717
locale.setlocale(locale.LC_ALL, "")
1818

19+
'''
20+
0 : perform detection
21+
1 : Graphical Environment running
22+
2 : Graphical Environment not running
23+
'''
24+
HAS_GRAPHICAL_ENV = 0
25+
1926
def convert_to_md(a_file):
2027
tmp_file = a_file[:-4] + 'md'
2128
return tmp_file if path.exists(tmp_file) else a_file
2229

2330
def is_graphical_environment_running():
31+
global HAS_GRAPHICAL_ENV
32+
if HAS_GRAPHICAL_ENV == 1:
33+
return True
34+
elif HAS_GRAPHICAL_ENV == 2:
35+
return False
2436
if which('pgrep'):
2537
# Check if Xorg is running
2638
xorg_process = subprocess.run(['pgrep', '-x', 'Xorg'], stdout=subprocess.PIPE)
2739
if xorg_process.returncode == 0:
40+
HAS_GRAPHICAL_ENV = 1
2841
return True
2942
# Check if Wayland is running
3043
wayland_process = subprocess.run(['pgrep', '-x', 'wayland'], stdout=subprocess.PIPE)
3144
if wayland_process.returncode == 0:
45+
HAS_GRAPHICAL_ENV = 1
3246
return True
3347
elif path.exists('/proc'):
34-
for pid in os.listdir('/proc'):
48+
for pid in listdir('/proc'):
3549
if pid.isdigit():
3650
try:
3751
with open(f'/proc/{pid}/cmdline', 'rb') as f:
@@ -45,12 +59,15 @@ def is_graphical_environment_running():
4559
for proc in psutil.process_iter(['pid', 'name']):
4660
if proc.info['name'] == 'Xorg' \
4761
or proc.info['name'] == 'wayland':
62+
HAS_GRAPHICAL_ENV = 1
4863
return True
4964

5065
# Check if DISPLAY environment variable is set
5166
if 'DISPLAY' in environ:
67+
HAS_GRAPHICAL_ENV = 1
5268
return True
5369

70+
HAS_GRAPHICAL_ENV = 2
5471
return False
5572

5673
class HtmlHelp(object):

pyradio/main.py

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
from .common import StationsChanges
2424
from .schedule import PyRadioScheduleList
2525
from .install import get_a_linux_resource_opener
26+
from .html_help import is_graphical_environment_running
2627
import locale
2728
locale.setlocale(locale.LC_ALL, "")
2829

@@ -952,7 +953,18 @@ def shell():
952953
upd.user = is_pyradio_user_installed()
953954
upd.update_pyradio()
954955
else:
955-
print('\nThank you for using [magenta]PyRadio[/magenta]. Cheers!')
956+
st = en = ''
957+
if platform.startswith('win') or \
958+
platform.lower().startswith('dar'):
959+
st = '\n'
960+
else:
961+
if is_graphical_environment_running():
962+
st = '\n'
963+
else:
964+
import subprocess
965+
subprocess.call('clear')
966+
en = '\n'
967+
print(st + 'Thank you for using [magenta]PyRadio[/magenta]. Cheers!' + en)
956968
else:
957969
print('\nThis terminal can not display colors.\nPyRadio cannot function in such a terminal.\n')
958970

0 commit comments

Comments
 (0)