Hello community,
here is the log from the commit of package python-pyvdr for openSUSE:Factory checked in at 2020-07-31 15:55:12
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-pyvdr (Old)
and /work/SRC/openSUSE:Factory/.python-pyvdr.new.3592 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-pyvdr"
Fri Jul 31 15:55:12 2020 rev:4 rq:823626 version:0.2.3
Changes:
--------
--- /work/SRC/openSUSE:Factory/python-pyvdr/python-pyvdr.changes 2020-07-14 07:58:40.369669811 +0200
+++ /work/SRC/openSUSE:Factory/.python-pyvdr.new.3592/python-pyvdr.changes 2020-07-31 15:59:38.792493506 +0200
@@ -1,0 +2,6 @@
+Wed Jul 29 21:12:34 UTC 2020 - Martin Hauke
+
+- Update to version 0.2.3
+ * Parsing of timers couldn't handle channel numbers > 10
+
+-------------------------------------------------------------------
Old:
----
pyvdr-0.2.2.tar.gz
New:
----
pyvdr-0.2.3.tar.gz
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ python-pyvdr.spec ++++++
--- /var/tmp/diff_new_pack.7TLgxp/_old 2020-07-31 16:00:00.204511852 +0200
+++ /var/tmp/diff_new_pack.7TLgxp/_new 2020-07-31 16:00:00.208511851 +0200
@@ -20,7 +20,7 @@
%{?!python_module:%define python_module() python-%{**} python3-%{**}}
%define skip_python2 1
Name: python-pyvdr
-Version: 0.2.2
+Version: 0.2.3
Release: 0
Summary: Python library for accessing a Linux VDR via SVDRP
License: MIT
++++++ pyvdr-0.2.2.tar.gz -> pyvdr-0.2.3.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pyvdr-0.2.2/README.md new/pyvdr-0.2.3/README.md
--- old/pyvdr-0.2.2/README.md 2020-07-10 17:46:47.000000000 +0200
+++ new/pyvdr-0.2.3/README.md 2020-07-29 23:00:01.000000000 +0200
@@ -78,6 +78,10 @@
```
Those flags are bit-representations in the timers' status field.
+## Test
+```
+python -m unittest discover -v
+```
## Module lifecycle
### Build module
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pyvdr-0.2.2/pyvdr/pyvdr.py new/pyvdr-0.2.3/pyvdr/pyvdr.py
--- old/pyvdr-0.2.2/pyvdr/pyvdr.py 2020-07-10 17:46:47.000000000 +0200
+++ new/pyvdr-0.2.3/pyvdr/pyvdr.py 2020-07-29 23:00:01.000000000 +0200
@@ -1,13 +1,14 @@
#!/usr/bin/env python3
from .svdrp import SVDRP
+import logging
import re
from collections import namedtuple
EPG_DATA_RECORD = '215'
epg_info = namedtuple('EPGDATA', 'Channel Title Description')
-#timer_info = namedtuple('TIMER', 'Status Name Date Description')
-#channel_info = namedtuple('CHANNEL', 'Number Name')
+# timer_info = namedtuple('TIMER', 'Status Name Date Description')
+# channel_info = namedtuple('CHANNEL', 'Number Name')
FLAG_TIMER_ACTIVE = 1
FLAG_TIMER_INSTANT_RECORDING = 2
@@ -15,6 +16,9 @@
FLAG_TIMER_RECORDING = 8
+_LOGGER = logging.getLogger(__name__)
+
+
class PYVDR(object):
def __init__(self, hostname='localhost', timeout=10):
@@ -72,7 +76,7 @@
def _parse_timer_response(response):
timer = {}
m = re.match(
- r'^(\d) (\d{1,2}):(\d):(\d{4}-\d{2}-\d{2}):(\d{4}):(\d{4}):(\d+):(\d+):(.*):(.*)$',
+ r'^(\d) (\d{1,2}):(\d{1,2}):(\d{4}-\d{2}-\d{2}):(\d{4}):(\d{4}):(\d+):(\d+):(.*):(.*)$',
response.Value,
re.M | re.I)
@@ -84,6 +88,9 @@
timer['description'] = ""
timer['series'] = timer['name'].find('~') != -1
timer['instant'] = False
+ _LOGGER.debug("Parsed timer: {}".format(timer))
+ else:
+ _LOGGER.debug("You might want to check the regex for timer parsing?! {}".format(response))
return timer
@@ -111,6 +118,9 @@
continue
timer = self._parse_timer_response(response)
self.svdrp.disconnect()
+ if len(timer) <= 0:
+ _LOGGER.debug("No output from timer parsing.")
+ return None
if self._check_timer_recording_flag(timer, FLAG_TIMER_INSTANT_RECORDING):
timer['instant'] = True
return timer
@@ -141,10 +151,10 @@
if epg_field_type == 'D':
epg_description = epg_field_value
- return channel, \
- epg_info(Channel=epg_channel,
- Title=epg_title,
- Description=epg_description)
+ return channel, epg_info(
+ Channel=epg_channel,
+ Title=epg_title,
+ Description=epg_description)
def channel_up(self):
self.svdrp.connect()
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pyvdr-0.2.2/pyvdr/svdrp.py new/pyvdr-0.2.3/pyvdr/svdrp.py
--- old/pyvdr-0.2.2/pyvdr/svdrp.py 2020-07-10 17:46:47.000000000 +0200
+++ new/pyvdr-0.2.3/pyvdr/svdrp.py 2020-07-29 23:00:01.000000000 +0200
@@ -25,6 +25,7 @@
def connect(self):
if self.socket is None:
try:
+ _LOGGER.debug("Setting up connection to {}".format(self.hostname))
self.socket = socket.create_connection((self.hostname, self.port), timeout=self.timeout)
self.socket_file = self.socket.makefile('r')
except socket.error as se:
@@ -34,6 +35,7 @@
return self.socket is not None
def disconnect(self):
+ _LOGGER.debug("Closing communication with server.")
if self.socket is not None:
self.send_cmd("quit")
self.socket_file.close()
@@ -43,6 +45,7 @@
self.socket = None
def send_cmd(self, cmd):
+ _LOGGER.debug("Send cmd: {}".format(cmd))
if not self.is_connected():
return
@@ -51,7 +54,11 @@
if isinstance(cmd, str):
cmd = cmd.encode("utf-8")
- self.socket.sendall(cmd)
+ try:
+ self.socket.sendall(cmd)
+ except IOError as e:
+ _LOGGER.debug("IOError e {}, closing connection".format(e))
+ self.socket.close()
def _parse_response(self, resp):
# <Reply code:3><-|Space><Text><Newline>
@@ -93,8 +100,10 @@
self._read_response()
if single_line:
+ _LOGGER.debug("Returning single item")
return self.responses[2]
else:
+ _LOGGER.debug("Returning {} items".format(len(self.responses)))
return self.responses
def shutdown(self):
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pyvdr-0.2.2/setup.py new/pyvdr-0.2.3/setup.py
--- old/pyvdr-0.2.2/setup.py 2020-07-10 17:46:47.000000000 +0200
+++ new/pyvdr-0.2.3/setup.py 2020-07-29 23:00:01.000000000 +0200
@@ -4,7 +4,7 @@
long_description = fh.read()
setup(name='pyvdr',
- version='0.2.2',
+ version='0.2.3',
description='Python library for accessing a Linux VDR via SVDRP',
long_description=long_description,
long_description_content_type="text/markdown",
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pyvdr-0.2.2/test/test_PYVDR.py new/pyvdr-0.2.3/test/test_PYVDR.py
--- old/pyvdr-0.2.2/test/test_PYVDR.py 2020-07-10 17:46:47.000000000 +0200
+++ new/pyvdr-0.2.3/test/test_PYVDR.py 2020-07-29 23:00:01.000000000 +0200
@@ -8,15 +8,18 @@
class TestPYVDR(unittest.TestCase):
def setUp(self):
self.func = PYVDR()
- self.func.stat = MagicMock( return_value = 3)
- self.func.is_recording = MagicMock( return_value = ['220 easyVDR SVDRP VideoDiskRecorder 2.2.0; Sun Sep 1 16:27:17 2019; UTF-8'])
+ self.func.stat = MagicMock(return_value=3)
+ self.func.is_recording = MagicMock(
+ return_value=[
+ '220 easyVDR SVDRP VideoDiskRecorder 2.2.0; Sun Sep 1 16:27:17 2019; UTF-8']
+ )
def test__parse_channel_response(self):
- chan_ard = self.func._parse_channel_response(["", "","1 ARD"])
+ chan_ard = self.func._parse_channel_response(["", "", "1 ARD"])
self.assertEqual(chan_ard['number'], "1")
self.assertEqual(chan_ard['name'], "ARD")
- chan_prosieben = self.func._parse_channel_response(["", "","11 Pro Sieben"])
+ chan_prosieben = self.func._parse_channel_response(["", "", "11 Pro Sieben"])
self.assertEqual(chan_prosieben['number'], "11")
self.assertEqual(chan_prosieben['name'], "Pro Sieben")
@@ -25,10 +28,34 @@
t_inactive = {}
t_active_and_recording = {}
t_active_and_instant_recording = {}
- t_active.update({'status': 1, 'name': "Test1", 'description': "Description1", 'date': "2018-08-01"})
- t_inactive.update({'status': 1, 'name':"Test1", 'description':"Description1", 'date':"2018-08-01"})
- t_active_and_recording.update({'status':9, 'name':"t_active_and_recording", 'description':"Description1", 'date':"2018-08-01"})
- t_active_and_instant_recording.update({'status':11, 'name':"t_active_and_instantrecording", 'description':"Description1", 'date':"2018-08-01"})
+ t_active.update(
+ {
+ 'status': 1,
+ 'name': "Test1",
+ 'description': "Description1",
+ 'date': "2018-08-01"
+ })
+ t_inactive.update(
+ {
+ 'status': 1,
+ 'name': "Test1",
+ 'description': "Description1",
+ 'date': "2018-08-01"
+ })
+ t_active_and_recording.update(
+ {
+ 'status': 9,
+ 'name': "t_active_and_recording",
+ 'description': "Description1",
+ 'date': "2018-08-01"
+ })
+ t_active_and_instant_recording.update(
+ {
+ 'status': 11,
+ 'name': "t_active_and_instantrecording",
+ 'description': "Description1",
+ 'date': "2018-08-01"
+ })
# timer active, not yet recording
self.assertTrue(self.func._check_timer_recording_flag(t_active, pyvdr.FLAG_TIMER_ACTIVE), "Timer should be active")
@@ -43,15 +70,25 @@
self.assertTrue(self.func._check_timer_recording_flag(t_active_and_instant_recording, pyvdr.FLAG_TIMER_RECORDING), "Timer recording")
self.assertTrue(self.func._check_timer_recording_flag(t_active_and_instant_recording, pyvdr.FLAG_TIMER_INSTANT_RECORDING), "Timer instant recording")
- def test__parse_searchtimer_response(self):
- response = response_data(
- "250",
- "-",
- "3 1:7:2020-07-13:1858:2025:50:99:Das perfekte Dinner~2020.07.13-19|00-Mo:<epgsearch><channel>7 - VOX</channel><searchtimer>das perfekte dinner</searchtimer><start>1594659480</start><stop>1594664700</stop><s-id>0</s-id><eventid>4572</eventid></epgsearch>"
- )
- timer = self.func._parse_timer_response(response)
- self.assertEqual(
- timer,
+ def test__parse_timer_responses(self):
+ parseable_responses = [
+ response_data(
+ "250",
+ "-",
+ "3 1:7:2020-07-13:1858:2025:50:99:Das perfekte Dinner~2020.07.13-19|00-Mo:<epgsearch><channel>7 - VOX</channel><searchtimer>das perfekte dinner</searchtimer><start>1594659480</start><stop>1594664700</stop><s-id>0</s-id><eventid>4572</eventid></epgsearch>"
+ ),
+ response_data(
+ "250",
+ "-",
+ "3 1:17:2020-07-31:0243:0345:50:99:Bad Banks~Ein halbes Jahr ist seit dem Crash der DGI-Bank vergangen. Gabriel Fenger befindet sich noch immer in U-Haft.:<epgsearch><channel>17 - ZDF_neo HD</channel><searchtimer>Bad Banks</searchtimer><start>1596156180</start><stop>1596159900</stop><s-id>8</s-id><eventid>4357</eventid></epgsearch>"
+ ),
+ response_data(
+ "250",
+ "-",
+ "4 11:1:2020-07-08:2215:0145:50:99:@Tagesthemen mit Wetter:"
+ )
+ ]
+ expected_parsed_timers = [
{
'status': '1',
'channel': '7',
@@ -60,19 +97,16 @@
'description': '',
'series': True,
'instant': False
- }
- )
-
- def test__parse_instanttimer_response(self):
- response = response_data(
- "250",
- "-",
- "4 11:1:2020-07-08:2215:0145:50:99:@Tagesthemen mit Wetter:"
- )
- timer = self.func._parse_timer_response(response)
-
- self.assertEqual(
- timer,
+ },
+ {
+ 'status': '1',
+ 'channel': '17',
+ 'date': '2020-07-31',
+ 'name': 'Bad Banks~Ein halbes Jahr ist seit dem Crash der DGI-Bank vergangen. Gabriel Fenger befindet sich noch immer in U-Haft.',
+ 'description': '',
+ 'series': True,
+ 'instant': False
+ },
{
'status': '11',
'channel': '1',
@@ -82,7 +116,14 @@
'series': False,
'instant': False
}
- )
+ ]
+
+ for i in range(len(parseable_responses)):
+ timer = self.func._parse_timer_response(parseable_responses[i])
+ self.assertEqual(
+ timer,
+ expected_parsed_timers[i]
+ )
if __name__ == '__main__':