Skip to content

Commit f52f49c

Browse files
committed
remote control server can now accept rela IP:PORT, same thing for headles function
1 parent 81e3c8c commit f52f49c

File tree

10 files changed

+132
-37
lines changed

10 files changed

+132
-37
lines changed

docs/headless.html

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@
3939
<body>
4040
<header id="title-block-header">
4141
</header>
42-
<h1 style="color: SaddleBrown" id="pyradio-headless-operation">PyRadio Headless Operation</h1>
42+
<p># PyRadio Headless Operation</p>
4343
<h2 id="table-of-contents">Table of Contents <span style="padding-left: 10px;"><sup style="font-size: 50%"><a href="#" title="Go to top of the page">Top</a></sup></span></h2>
4444
<!-- vim-markdown-toc Marked -->
4545
<ul>
@@ -83,11 +83,15 @@ <h3 id="usage">Usage</h3>
8383
The server will be accessible only by programs running in the system. The ip is 127.0.0.1.</li>
8484
<li><strong>lan</strong><br />
8585
The server will be accessible by any system on the LAN. The ip is the one assigned to the network interface of the system.</li>
86+
<li>An actual <strong>IP</strong><br />
87+
This is in case when a machine has more than one network interfaces and the **lan* setting is ambigous.</li>
8688
</ol>
8789
<p>For example:</p>
8890
<ul>
8991
<li><p>using <strong>–headless lan:12345</strong><br />
9092
will make the web server listen to the network interface IP address, port 12345.</p></li>
93+
<li><p>using <strong>–headless 192.168.122.101:4567</strong><br />
94+
will make the web server listen to the IP 192.168.122.101, port 4567.</p></li>
9195
<li><p>using <strong>–headless localhost:23456</strong><br />
9296
will make the web server listen to 127.0.0.1, port 23456</p></li>
9397
<li><p>using <strong>–headless auto</strong><br />

docs/headless.md

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# PyRadio Headless Operation
1+
\fR# PyRadio Headless Operation
22

33
## Table of Contents
44
<!-- vim-markdown-toc Marked -->
@@ -51,12 +51,17 @@ The `ip` can either be:
5151
The server will be accessible only by programs running in the system. The `ip` is 127.0.0.1.
5252
2. **lan** \
5353
The server will be accessible by any system on the LAN. The `ip` is the one assigned to the network interface of the system.
54+
3. An actual **IP** \
55+
This is in case when a machine has more than one network interfaces and the **lan* setting is ambigous.
5456

5557
For example:
5658

5759
- using **--headless lan:12345** \
5860
will make the web server listen to the network interface IP address, port 12345.
5961

62+
- using **--headless 192.168.122.101:4567** \
63+
will make the web server listen to the IP 192.168.122.101, port 4567.
64+
6065
- using **--headless localhost:23456** \
6166
will make the web server listen to 127.0.0.1, port 23456
6267

docs/pyradio_server.1

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@ The options one can set are:
2525
.IP 1.\ \fBServer\ IP
2626
This can either be \fIlocalhost\fR (the server will be accessible from the current system only) or \fILAN\fR (the server will be accessible from any PC on the local network).
2727

28+
If the machine has more that one interface (network card), the actual \fIIPs\fR will be available for selection.
29+
2830
.IP 2.\ \fBServer\ Port
2931
This is the port the server is listening to. Any free port number between 1025 and 65535 can be set here (default value is 9998).
3032

docs/server.html

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,9 @@ <h2 id="remote-control-server">Remote Control Server <span style="padding-left:
6767
<p>The options one can set are:</p>
6868
<ol type="1">
6969
<li><p><strong>Server IP</strong><br />
70-
This can either be <strong>localhost</strong> (the server will be accessible from the current system only) or <strong>LAN</strong> (the server will be accessible from any PC on the local network).</p></li>
70+
This can either be <strong>localhost</strong> (the server will be accessible from the current system only) or <strong>LAN</strong> (the server will be accessible from any PC on the local network).<br />
71+
<br />
72+
If the machine has more that one interface (network card), the actual IPs will be available for selection.</p></li>
7173
<li><p><strong>Server Port</strong><br />
7274
This is the port the server is listening to. Any free port number between 1025 and 65535 can be set here (default value is 9998).</p></li>
7375
<li><p><strong>Auto-start Server</strong><br />

docs/server.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,9 @@ Setting the **Remote Control Server** options ins the config file, especially se
2727
The options one can set are:
2828

2929
1. **Server IP** \
30-
This can either be **localhost** (the server will be accessible from the current system only) or **LAN** (the server will be accessible from any PC on the local network).
30+
This can either be **localhost** (the server will be accessible from the current system only) or **LAN** (the server will be accessible from any PC on the local network). \
31+
\
32+
If the machine has more that one interface (network card), the actual IPs will be available for selection.
3133

3234
2. **Server Port** \
3335
This is the port the server is listening to. Any free port number between 1025 and 65535 can be set here (default value is 9998).

pyradio/config.py

Lines changed: 24 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
import curses
77
import collections
88
import json
9-
import socket
9+
# import socket
1010
from os import path, getenv, makedirs, remove, rename, readlink, SEEK_END, SEEK_CUR, environ, getpid
1111
from sys import platform
1212
from time import ctime, sleep
@@ -27,6 +27,7 @@
2727
from .install import get_github_long_description
2828
from .common import is_rasberrypi
2929
from .player import pywhich
30+
from .server import IPsWithNumbers
3031
HAS_REQUESTS = True
3132

3233
try:
@@ -71,10 +72,18 @@ def to_ip_port(string):
7172
if sp[0] == 'lan' or sp[0] == 'localhost':
7273
host = sp[0]
7374
else:
74-
try:
75-
x = socket.inet_pton(socket.AF_INET, sp[0])
75+
x = IPsWithNumbers(
76+
default_ip=sp[0],
77+
fat=True
78+
)
79+
if x.current() == sp[0]:
7680
host = sp[0]
77-
except:
81+
# try:
82+
# x = socket.inet_pton(socket.AF_INET, sp[0])
83+
# host = sp[0]
84+
# except:
85+
# return 'localhost', '11111'
86+
else:
7887
return 'localhost', '11111'
7988
try:
8089
x = int(sp[1])
@@ -2096,13 +2105,18 @@ def read_config(self):
20962105
'vlc_parameter'):
20972106
self._config_to_params(sp)
20982107
elif sp[0] == 'remote_control_server_ip':
2099-
hosts = ('localhost', 'LAN', 'lan')
2108+
# hosts = ('localhost', 'LAN', 'lan')
21002109
sp[1] = sp[1].strip()
2101-
x = [r for r in hosts if r == sp[1]]
2102-
if x:
2103-
self.opts['remote_control_server_ip'][1] = x[0]
2104-
else:
2105-
self.opts['remote_control_server_ip'][1] = 'localhost'
2110+
nip = IPsWithNumbers(
2111+
default_ip=sp[1]
2112+
)
2113+
self.opts['remote_control_server_ip'][1] = nip.current()
2114+
nip = None
2115+
# x = [r for r in hosts if r == sp[1]]
2116+
# if x:
2117+
# self.opts['remote_control_server_ip'][1] = x[0]
2118+
# else:
2119+
# self.opts['remote_control_server_ip'][1] = 'localhost'
21062120
elif sp[0] == 'remote_control_server_port':
21072121
try:
21082122
x = int(sp[1])

pyradio/config_window.py

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
from .cjkwrap import cjklen
1313
from .encodings import *
1414
from .themes import *
15+
from .server import IPsWithNumbers
1516
from .simple_curses_widgets import SimpleCursesLineEdit, SimpleCursesHorizontalPushButtons, SimpleCursesMenu
1617
import logging
1718
import locale
@@ -88,7 +89,7 @@ class PyRadioConfigWindow(object):
8889
'|', 'Default value: True'])
8990
_help_text.append(['Specify whether you will be asked to save a modified playlist whenever it needs saving.', '|', 'Default value: False'])
9091
_help_text.append(None)
91-
_help_text.append(['This is the IP for the Remote Control Server.', '|', 'Available options:', '- localhost', ' PyRadio will be accessible from within the current system only.', '- LAN', ' PyRadio will be accessible from any computer in the local network.', '|', r'One can see the active IP using the "\s" command from the program\'s Main Window.', '|', 'Use "Space", "Enter", "l/Right" to change the value.','|', 'Default value: localhost'])
92+
_help_text.append(['This is the IP for the Remote Control Server.', '|', 'Available options:', '- localhost : PyRadio will be accessible from within the current system only.', '- lsn : PyRadio will be accessible from any computer in the local network.', '- IP : In case the system has more than one interfaces.', '|', 'Use "Space", "Enter", "l/Right" to change the value.','|', 'Default value: localhost'])
9293
_help_text.append(
9394
['This is the port used by the Remote Control Server (the port the server is listening to).', '|', 'Please make sure that a "free" port is specified here, to avoid any conflicts with existing services and daemons.', '|', 'If an invalid port number is inserted, the cursor will not move to another field.', '|', 'Valid values: 1025-65535', 'Default value: 9998'])
9495
_help_text.append(['If set to True, the Server wiil be automatically started when PyRadio starts.', r'If set to False, one can start the Server using the "\s" command from the Main program window.', '|', 'Default value: False'])
@@ -190,6 +191,9 @@ def __init__(self, parent, config,
190191
for a_key in self._cnf.saved_params.keys():
191192
if self._cnf.saved_params[a_key] != self._cnf.params[a_key]:
192193
self._cnf.dirty_config = True
194+
self.nip = IPsWithNumbers(
195+
default_ip=self._config_options['remote_control_server_ip'][1]
196+
)
193197

194198
def __del__(self):
195199
self._toggle_transparency_function = None
@@ -803,12 +807,14 @@ def keypress(self, char):
803807

804808
elif val[0] == 'remote_control_server_ip':
805809
if char in (curses.KEY_RIGHT, ord('l'), ord(' '), ord('\n'), curses.KEY_ENTER):
806-
if self._config_options[val[0]][1] == 'localhost':
807-
self._config_options[val[0]][1] = 'LAN'
808-
disp = 'LAN '
809-
else:
810-
self._config_options[val[0]][1] = 'localhost'
811-
disp = 'localhost'
810+
self._config_options[val[0]][1] = self.nip.next()
811+
disp = self._config_options[val[0]][1].ljust(15)
812+
# if self._config_options[val[0]][1] == 'localhost':
813+
# self._config_options[val[0]][1] = 'LAN'
814+
# disp = 'LAN '
815+
# else:
816+
# self._config_options[val[0]][1] = 'localhost'
817+
# disp = 'localhost'
812818
self._win.addstr(
813819
Y, 3 + len(val[1][0]),
814820
disp, curses.color_pair(6)

pyradio/edit.py

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
from .simple_curses_widgets import SimpleCursesLineEdit, SimpleCursesCheckBox, SimpleCursesHorizontalPushButtons, DisabledWidget
1515
from .player import PlayerCache
1616
from .log import Log
17+
from .server import IPsWithNumbers
1718

1819
import locale
1920
locale.setlocale(locale.LC_ALL, '') # set your locale
@@ -1472,13 +1473,16 @@ class PyRadioServerWindow(object):
14721473

14731474
_win = _editor = None
14741475

1476+
_nips = None
1477+
14751478
def __init__(
14761479
self,
14771480
parent,
14781481
config,
14791482
port_number_error_message=None,
14801483
global_functions=None
14811484
):
1485+
self._nips = IPsWithNumbers()
14821486
self._cnf = config
14831487
self._parent = parent
14841488
self._win = None
@@ -1488,7 +1492,8 @@ def __init__(
14881492
self._showed = False
14891493
self._selection = 0
14901494
self._field_x = 4 + len('Server Port: ')
1491-
self._the_ip = self._cnf.active_remote_control_server_ip
1495+
self._the_ip = self._nips.validate_ip(self._cnf.active_remote_control_server_ip)
1496+
self._nips.set(self._the_ip)
14921497
self._the_port = self._cnf.active_remote_control_server_port
14931498
self._editor = None
14941499
self._port_number_error_message = port_number_error_message
@@ -1537,7 +1542,6 @@ def show(self, parent=None):
15371542
self._win.addstr(self._the_ip.ljust(self._field_width, ' '), curses.color_pair(10))
15381543
self._win.addstr(5, 4, 'Server Port: ', curses.color_pair(10))
15391544

1540-
15411545
try:
15421546
self._win.addstr(7, 3, '─' * (self.maxX - 6), curses.color_pair(3))
15431547
except:
@@ -1628,25 +1632,31 @@ def keypress(self, char):
16281632
char in (
16291633
ord(' '), ord('\n'),
16301634
curses.KEY_ENTER,
1631-
ord('h'), ord('l'),
1632-
curses.KEY_LEFT,
1635+
ord('l'),
16331636
curses.KEY_RIGHT,
16341637
):
1635-
if self._the_ip == 'localhost':
1636-
self._the_ip = 'LAN'
1637-
else:
1638-
self._the_ip = 'localhost'
1638+
self._the_ip = self._nips.next()
1639+
self._win.addstr(4, self._field_x, self._the_ip.ljust(self._field_width), curses.color_pair(6))
1640+
self._refresh()
1641+
elif self._selection == 0 and \
1642+
char in (
1643+
ord('h'),
1644+
curses.KEY_LEFT,
1645+
):
1646+
self._the_ip = self._nips.previous()
16391647
self._win.addstr(4, self._field_x, self._the_ip.ljust(self._field_width), curses.color_pair(6))
16401648
self._refresh()
16411649

16421650
elif char == ord('r'):
16431651
self._the_ip = self._cnf.active_remote_control_server_ip
1652+
self._nips.set(self._the_ip)
16441653
self._the_port = self._cnf.active_remote_control_server_port
16451654
self._editor.string = self._the_port
16461655
self._refresh()
16471656

16481657
elif char == ord('d'):
16491658
self._the_ip = 'localhost'
1659+
self._nips.set('localhost')
16501660
self._the_port = '9998'
16511661
self._editor.string = self._the_port
16521662
self._refresh()

pyradio/main.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -335,7 +335,7 @@ def shell():
335335
else:
336336
gr_headless = parser.add_argument_group('• Headless operation')
337337
gr_headless.add_argument('--headless', default=None, metavar=('IP_AND_PORT', ),
338-
help='Start in headless mode. IP_AND_PORT can be a) auto (use localhost:11111), b) localhost:XXXXX (access the web server through localhost) or c) lan:XXXXX (access the web server through the LAN). XXXXX can be any port number above 1025. Please make sure it is different than the one set in the configuration file.')
338+
help='Start in headless mode. IP_AND_PORT can be a) auto (use localhost:11111), b) localhost:XXXXX (access the web server through localhost), c) lan:XXXXX (access the web server through the LAN) or d) IP_ADDRESS:XXXX (the IP_ADDRESS must be an assigned to one of the network interfaces). XXXXX can be any port number above 1025. Please make sure it is different than the one set in the configuration file.')
339339
gr_headless.add_argument('--address', action='store_true',
340340
help='Show remote control server address.')
341341
gr_headless.add_argument('-fd', '--free-dead-headless-server', action='store_true',

pyradio/server.py

Lines changed: 57 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -71,13 +71,14 @@ def _get_linux_ips(self):
7171
for n in interfaces:
7272
iface=netifaces.ifaddresses(n).get(netifaces.AF_INET)
7373
if iface:
74-
# dirty way to get real interfaces
75-
if 'broadcast' in str(iface):
76-
if version_info[0] > 2:
77-
out.append(iface[0]['addr'])
78-
else:
79-
out.append(iface[0]['addr'].encode('utf-8'))
80-
return out
74+
for entry in iface:
75+
# dirty way to get real interfaces
76+
if 'broadcast' in str(entry):
77+
if version_info[0] > 2:
78+
out.append(entry['addr'])
79+
else:
80+
out.append(entry['addr'].encode('utf-8'))
81+
return sorted(list(set(out)))
8182

8283
def _get_win_ips(self):
8384
out = ['127.0.0.1']
@@ -94,6 +95,55 @@ def _get_win_ips(self):
9495
return out
9596

9697

98+
class IPsWithNumbers(object):
99+
100+
def __init__(self, default_ip=None, fat=False):
101+
self._ips = ['localhost', 'lan']
102+
ips = IPs()
103+
if fat or len(ips.IPs) > 2:
104+
self._ips.extend(ips.IPs[1:])
105+
self._index = 0
106+
if default_ip:
107+
try:
108+
self._index = self._ips.index(default_ip.lower())
109+
except ValueError:
110+
pass
111+
112+
def set(self, new_ip):
113+
try:
114+
self._index = self._ips.index(new_ip.lower())
115+
except ValueError:
116+
pass
117+
return self._ips[self._index]
118+
119+
def current(self):
120+
return self._ips[self._index]
121+
122+
def next(self):
123+
self._index += 1
124+
if self._index >= len(self._ips):
125+
self._index = 0
126+
return self._ips[self._index]
127+
128+
def previous(self):
129+
self._index -= 1
130+
if self._index <0:
131+
self._index = len(self._ips) - 1
132+
return self._ips[self._index]
133+
134+
def ip_exists(self, ip):
135+
try:
136+
x = self._ips.index(ip.lower())
137+
return True
138+
except ValueError:
139+
return False
140+
141+
def validate_ip(self, ip):
142+
''' if ip is in the list of ips, return it
143+
else return localhost
144+
'''
145+
return ip.lower() if self.ip_exists(ip) else 'localhost'
146+
97147
class PyRadioServer(object):
98148
_filter_string = '''
99149
<script>

0 commit comments

Comments
 (0)