← Back to team overview

openlp-core team mailing list archive

[Merge] lp:~alisonken1/openlp/pjlink2-c into lp:openlp

 

Ken Roberts has proposed merging lp:~alisonken1/openlp/pjlink2-c into lp:openlp with lp:~alisonken1/openlp/pjlink2-c-resources as a prerequisite.

Requested reviews:
  OpenLP Core (openlp-core)

For more details, see:
https://code.launchpad.net/~alisonken1/openlp/pjlink2-c/+merge/324360

-- Update test data for Class 2 tests
-- Update Projector() db class with new data
-- Update test_projectordb tests
-- Rename PJLink1 class to PJLink
-- Fix/update power on/off tests (Qt error not caught properly during test)
-- Remove skip from projector constants test

--------------------------------
lp:~alisonken1/openlp/pjlink2-c (revision 2739)
[SUCCESS] https://ci.openlp.io/job/Branch-01-Pull/2020/
[SUCCESS] https://ci.openlp.io/job/Branch-02-Functional-Tests/1930/
[SUCCESS] https://ci.openlp.io/job/Branch-03-Interface-Tests/1865/
[SUCCESS] https://ci.openlp.io/job/Branch-04a-Code_Analysis/1245/
[SUCCESS] https://ci.openlp.io/job/Branch-04b-Test_Coverage/1103/
[SUCCESS] https://ci.openlp.io/job/Branch-04c-Code_Analysis2/232/
[FAILURE] https://ci.openlp.io/job/Branch-05-AppVeyor-Tests/80/

-- 
Your team OpenLP Core is requested to review the proposed merge of lp:~alisonken1/openlp/pjlink2-c into lp:openlp.
=== modified file 'openlp/core/lib/__init__.py'
--- openlp/core/lib/__init__.py	2017-05-17 20:06:45 +0000
+++ openlp/core/lib/__init__.py	2017-05-20 06:06:27 +0000
@@ -621,5 +621,5 @@
 from .renderer import Renderer
 from .mediamanageritem import MediaManagerItem
 from .projector.db import ProjectorDB, Projector
-from .projector.pjlink1 import PJLink1
+from .projector.pjlink1 import PJLink
 from .projector.constants import PJLINK_PORT, ERROR_MSG, ERROR_STRING

=== modified file 'openlp/core/lib/projector/db.py'
--- openlp/core/lib/projector/db.py	2016-12-31 11:01:36 +0000
+++ openlp/core/lib/projector/db.py	2017-05-20 06:06:27 +0000
@@ -150,11 +150,15 @@
         name:           Column(String(20))
         location:       Column(String(30))
         notes:          Column(String(200))
-        pjlink_name:    Column(String(128))  # From projector (future)
-        manufacturer:   Column(String(128))  # From projector (future)
-        model:          Column(String(128))  # From projector (future)
-        other:          Column(String(128))  # From projector (future)
-        sources:        Column(String(128))  # From projector (future)
+        pjlink_name:    Column(String(128))  # From projector
+        manufacturer:   Column(String(128))  # From projector
+        model:          Column(String(128))  # From projector
+        other:          Column(String(128))  # From projector
+        sources:        Column(String(128))  # From projector
+        serial_no:      Column(String(30))   # From projector (Class 2)
+        sw_version:     Column(String(30))   # From projector (Class 2)
+        model_filter:   Column(String(30))   # From projector (Class 2)
+        model_lamp:     Column(String(30))   # From projector (Class 2)
 
         ProjectorSource relates
     """
@@ -164,20 +168,25 @@
         """
         return '< Projector(id="{data}", ip="{ip}", port="{port}", pin="{pin}", name="{name}", ' \
             'location="{location}", notes="{notes}", pjlink_name="{pjlink_name}", ' \
-            'manufacturer="{manufacturer}", model="{model}", other="{other}", ' \
-            'sources="{sources}", source_list="{source_list}") >'.format(data=self.id,
-                                                                         ip=self.ip,
-                                                                         port=self.port,
-                                                                         pin=self.pin,
-                                                                         name=self.name,
-                                                                         location=self.location,
-                                                                         notes=self.notes,
-                                                                         pjlink_name=self.pjlink_name,
-                                                                         manufacturer=self.manufacturer,
-                                                                         model=self.model,
-                                                                         other=self.other,
-                                                                         sources=self.sources,
-                                                                         source_list=self.source_list)
+            'manufacturer="{manufacturer}", model="{model}", serial_no="{serial}", other="{other}", ' \
+            'sources="{sources}", source_list="{source_list}", model_filter="{mfilter}", ' \
+            'model_lamp="{mlamp}", sw_version="{sw_ver}") >'.format(data=self.id,
+                                                                    ip=self.ip,
+                                                                    port=self.port,
+                                                                    pin=self.pin,
+                                                                    name=self.name,
+                                                                    location=self.location,
+                                                                    notes=self.notes,
+                                                                    pjlink_name=self.pjlink_name,
+                                                                    manufacturer=self.manufacturer,
+                                                                    model=self.model,
+                                                                    other=self.other,
+                                                                    sources=self.sources,
+                                                                    source_list=self.source_list,
+                                                                    serial=self.serial_no,
+                                                                    mfilter=self.model_filter,
+                                                                    mlamp=self.model_lamp,
+                                                                    sw_ver=self.sw_version)
     ip = Column(String(100))
     port = Column(String(8))
     pin = Column(String(20))
@@ -189,6 +198,10 @@
     model = Column(String(128))
     other = Column(String(128))
     sources = Column(String(128))
+    serial_no = Column(String(30))
+    sw_version = Column(String(30))
+    model_filter = Column(String(30))
+    model_lamp = Column(String(30))
     source_list = relationship('ProjectorSource',
                                order_by='ProjectorSource.code',
                                backref='projector',
@@ -359,6 +372,10 @@
         old_projector.model = projector.model
         old_projector.other = projector.other
         old_projector.sources = projector.sources
+        old_projector.serial_no = projector.serial_no
+        old_projector.sw_version = projector.sw_version
+        old_projector.model_filter = projector.model_filter
+        old_projector.model_lamp = projector.model_lamp
         return self.save_object(old_projector)
 
     def delete_projector(self, projector):

=== modified file 'openlp/core/lib/projector/pjlink1.py'
--- openlp/core/lib/projector/pjlink1.py	2017-05-17 20:35:43 +0000
+++ openlp/core/lib/projector/pjlink1.py	2017-05-20 06:06:27 +0000
@@ -42,7 +42,7 @@
 
 log.debug('pjlink1 loaded')
 
-__all__ = ['PJLink1']
+__all__ = ['PJLink']
 
 from codecs import decode
 
@@ -68,7 +68,7 @@
 PJLINK_SUFFIX = CR
 
 
-class PJLink1(QtNetwork.QTcpSocket):
+class PJLink(QtNetwork.QTcpSocket):
     """
     Socket service for connecting to a PJLink-capable projector.
     """
@@ -129,7 +129,7 @@
         self.ip = ip
         self.port = port
         self.pin = pin
-        super(PJLink1, self).__init__()
+        super(PJLink, self).__init__()
         self.dbid = None
         self.location = None
         self.notes = None
@@ -162,7 +162,7 @@
         # Socket timer for some possible brain-dead projectors or network cable pulled
         self.socket_timer = None
         # Map command to function
-        self.pjlink1_functions = {
+        self.pjlink_functions = {
             'AVMT': self.process_avmt,
             'CLSS': self.process_clss,
             'ERST': self.process_erst,
@@ -286,7 +286,7 @@
         elif status in STATUS_STRING:
             return STATUS_STRING[status], ERROR_MSG[status]
         else:
-            return status, translate('OpenLP.PJLink1', 'Unknown status')
+            return status, translate('OpenLP.PJLink', 'Unknown status')
 
     def change_status(self, status, msg=None):
         """
@@ -296,7 +296,7 @@
         :param status: Status code
         :param msg: Optional message
         """
-        message = translate('OpenLP.PJLink1', 'No message') if msg is None else msg
+        message = translate('OpenLP.PJLink', 'No message') if msg is None else msg
         (code, message) = self._get_status(status)
         if msg is not None:
             message = msg
@@ -576,7 +576,7 @@
         if sent == -1:
             # Network error?
             self.change_status(E_NETWORK,
-                               translate('OpenLP.PJLink1', 'Error while sending data to projector'))
+                               translate('OpenLP.PJLink', 'Error while sending data to projector'))
 
     def process_command(self, cmd, data):
         """
@@ -625,8 +625,9 @@
             self.projectorReceivedData.emit()
             return
 
-        if cmd in self.pjlink1_functions:
-            self.pjlink1_functions[cmd](data)
+        if cmd in self.pjlink_functions:
+            log.debug('({ip}) Calling function for {cmd}'.format(ip=self.ip, cmd=cmd))
+            self.pjlink_functions[cmd](data)
         else:
             log.warning('({ip}) Invalid command {data}'.format(ip=self.ip, data=cmd))
         self.send_busy = False
@@ -662,6 +663,7 @@
 
         :param data: Power status
         """
+        log.debug('({ip}: Processing POWR command'.format(ip=self.ip))
         if data in PJLINK_POWR_STATUS:
             power = PJLINK_POWR_STATUS[data]
             update_icons = self.power != power

=== modified file 'openlp/core/ui/projector/manager.py'
--- openlp/core/ui/projector/manager.py	2016-12-31 11:01:36 +0000
+++ openlp/core/ui/projector/manager.py	2017-05-20 06:06:27 +0000
@@ -38,7 +38,7 @@
     E_NETWORK, E_NOT_CONNECTED, E_UNKNOWN_SOCKET_ERROR, STATUS_STRING, S_CONNECTED, S_CONNECTING, S_COOLDOWN, \
     S_INITIALIZE, S_NOT_CONNECTED, S_OFF, S_ON, S_STANDBY, S_WARMUP
 from openlp.core.lib.projector.db import ProjectorDB
-from openlp.core.lib.projector.pjlink1 import PJLink1
+from openlp.core.lib.projector.pjlink1 import PJLink
 from openlp.core.ui.projector.editform import ProjectorEditForm
 from openlp.core.ui.projector.sourceselectform import SourceSelectTabs, SourceSelectSingle
 
@@ -690,19 +690,19 @@
         Helper app to build a projector instance
 
         :param projector: Dict of projector database information
-        :returns: PJLink1() instance
+        :returns: PJLink() instance
         """
         log.debug('_add_projector()')
-        return PJLink1(dbid=projector.id,
-                       ip=projector.ip,
-                       port=int(projector.port),
-                       name=projector.name,
-                       location=projector.location,
-                       notes=projector.notes,
-                       pin=None if projector.pin == '' else projector.pin,
-                       poll_time=self.poll_time,
-                       socket_timeout=self.socket_timeout
-                       )
+        return PJLink(dbid=projector.id,
+                      ip=projector.ip,
+                      port=int(projector.port),
+                      name=projector.name,
+                      location=projector.location,
+                      notes=projector.notes,
+                      pin=None if projector.pin == '' else projector.pin,
+                      poll_time=self.poll_time,
+                      socket_timeout=self.socket_timeout
+                      )
 
     def add_projector(self, projector, start=False):
         """
@@ -961,7 +961,7 @@
         """
         Initialization for ProjectorItem instance
 
-        :param link: PJLink1 instance for QListWidgetItem
+        :param link: PJLink instance for QListWidgetItem
         """
         self.link = link
         self.thread = None

=== modified file 'tests/functional/openlp_core_lib/test_projector_constants.py'
--- tests/functional/openlp_core_lib/test_projector_constants.py	2017-05-12 09:51:56 +0000
+++ tests/functional/openlp_core_lib/test_projector_constants.py	2017-05-20 06:06:27 +0000
@@ -29,7 +29,6 @@
     """
     Test specific functions in the projector constants module.
     """
-    @skip('Waiting for merge of ~alisonken1/openlp/pjlink2-resource-data')
     def build_pjlink_video_label_test(self):
         """
         Test building PJLINK_DEFAULT_CODES dictionary

=== modified file 'tests/functional/openlp_core_lib/test_projector_pjlink1.py'
--- tests/functional/openlp_core_lib/test_projector_pjlink1.py	2017-05-13 09:00:29 +0000
+++ tests/functional/openlp_core_lib/test_projector_pjlink1.py	2017-05-20 06:06:27 +0000
@@ -25,13 +25,13 @@
 from unittest import TestCase
 from unittest.mock import call, patch, MagicMock
 
-from openlp.core.lib.projector.pjlink1 import PJLink1
+from openlp.core.lib.projector.pjlink1 import PJLink
 from openlp.core.lib.projector.constants import E_PARAMETER, ERROR_STRING, S_OFF, S_STANDBY, S_ON, \
     PJLINK_POWR_STATUS, S_CONNECTED
 
 from tests.resources.projector.data import TEST_PIN, TEST_SALT, TEST_CONNECT_AUTHENTICATE, TEST_HASH
 
-pjlink_test = PJLink1(name='test', ip='127.0.0.1', pin=TEST_PIN, no_poll=True)
+pjlink_test = PJLink(name='test', ip='127.0.0.1', pin=TEST_PIN, no_poll=True)
 
 
 class TestPJLink(TestCase):
@@ -164,23 +164,36 @@
                           'Lamp 3 hours should have been set to 33333')
 
     @patch.object(pjlink_test, 'projectorReceivedData')
-    def test_projector_process_power_on(self, mock_projectorReceivedData):
+    @patch.object(pjlink_test, 'projectorUpdateIcons')
+    @patch.object(pjlink_test, 'send_command')
+    @patch.object(pjlink_test, 'change_status')
+    def test_projector_process_power_on(self, mock_change_status,
+                                        mock_send_command,
+                                        mock_UpdateIcons,
+                                        mock_ReceivedData):
         """
         Test status power to ON
         """
         # GIVEN: Test object and preset
         pjlink = pjlink_test
         pjlink.power = S_STANDBY
-        pjlink.socket_timer = MagicMock()
 
         # WHEN: Call process_command with turn power on command
         pjlink.process_command('POWR', PJLINK_POWR_STATUS[S_ON])
 
         # THEN: Power should be set to ON
         self.assertEquals(pjlink.power, S_ON, 'Power should have been set to ON')
+        mock_send_command.assert_called_once_with('INST')
+        self.assertEquals(mock_UpdateIcons.emit.called, True, 'projectorUpdateIcons should have been called')
 
     @patch.object(pjlink_test, 'projectorReceivedData')
-    def test_projector_process_power_off(self, mock_projectorReceivedData):
+    @patch.object(pjlink_test, 'projectorUpdateIcons')
+    @patch.object(pjlink_test, 'send_command')
+    @patch.object(pjlink_test, 'change_status')
+    def test_projector_process_power_off(self, mock_change_status,
+                                         mock_send_command,
+                                         mock_UpdateIcons,
+                                         mock_ReceivedData):
         """
         Test status power to STANDBY
         """
@@ -193,6 +206,8 @@
 
         # THEN: Power should be set to STANDBY
         self.assertEquals(pjlink.power, S_STANDBY, 'Power should have been set to STANDBY')
+        self.assertEquals(mock_send_command.called, False, 'send_command should not have been called')
+        self.assertEquals(mock_UpdateIcons.emit.called, True, 'projectorUpdateIcons should have been called')
 
     @patch.object(pjlink_test, 'projectorUpdateIcons')
     def test_projector_process_avmt_closed_unmuted(self, mock_projectorReceivedData):
@@ -372,7 +387,7 @@
     @patch.object(pjlink_test, '_not_implemented')
     def not_implemented_test(self, mock_not_implemented):
         """
-        Test pjlink1._not_implemented method being called
+        Test PJLink._not_implemented method being called
         """
         # GIVEN: test object
         pjlink = pjlink_test
@@ -381,13 +396,13 @@
         # WHEN: A future command is called that is not implemented yet
         pjlink.process_command(test_cmd, "Garbage data for test only")
 
-        # THEN: pjlink1.__not_implemented should have been called with test_cmd
+        # THEN: PJLink.__not_implemented should have been called with test_cmd
         mock_not_implemented.assert_called_with(test_cmd)
 
     @patch.object(pjlink_test, 'disconnect_from_host')
     def socket_abort_test(self, mock_disconnect):
         """
-        Test PJLink1.socket_abort calls disconnect_from_host
+        Test PJLink.socket_abort calls disconnect_from_host
         """
         # GIVEN: Test object
         pjlink = pjlink_test
@@ -400,7 +415,7 @@
 
     def poll_loop_not_connected_test(self):
         """
-        Test PJLink1.poll_loop not connected return
+        Test PJLink.poll_loop not connected return
         """
         # GIVEN: Test object and mocks
         pjlink = pjlink_test
@@ -409,7 +424,7 @@
         pjlink.state.return_value = False
         pjlink.ConnectedState = True
 
-        # WHEN: PJLink1.poll_loop called
+        # WHEN: PJLink.poll_loop called
         pjlink.poll_loop()
 
         # THEN: poll_loop should exit without calling any other method
@@ -418,7 +433,7 @@
     @patch.object(pjlink_test, 'send_command')
     def poll_loop_start_test(self, mock_send_command):
         """
-        Test PJLink1.poll_loop makes correct calls
+        Test PJLink.poll_loop makes correct calls
         """
         # GIVEN: test object and test data
         pjlink = pjlink_test
@@ -450,7 +465,7 @@
             call('NAME', queue=True),
         ]
 
-        # WHEN: PJLink1.poll_loop is called
+        # WHEN: PJLink.poll_loop is called
         pjlink.poll_loop()
 
         # THEN: proper calls were made to retrieve projector data

=== modified file 'tests/functional/openlp_core_lib/test_projectordb.py'
--- tests/functional/openlp_core_lib/test_projectordb.py	2017-04-24 05:17:55 +0000
+++ tests/functional/openlp_core_lib/test_projectordb.py	2017-05-20 06:06:27 +0000
@@ -26,13 +26,15 @@
 PREREQUISITE: add_record() and get_all() functions validated.
 """
 import os
+import shutil
 from unittest import TestCase
 from unittest.mock import MagicMock, patch
 
 from openlp.core.lib.projector.db import Manufacturer, Model, Projector, ProjectorDB, ProjectorSource, Source
 from openlp.core.lib.projector.constants import PJLINK_PORT
 
-from tests.resources.projector.data import TEST_DB, TEST1_DATA, TEST2_DATA, TEST3_DATA
+from tests.resources.projector.data import TEST_DB_PJLINK1, TEST_DB, TEST1_DATA, TEST2_DATA, TEST3_DATA
+from tests.utils.constants import TEST_RESOURCES_PATH
 
 
 def compare_data(one, two):
@@ -45,7 +47,11 @@
         one.port == two.port and \
         one.name == two.name and \
         one.location == two.location and \
-        one.notes == two.notes
+        one.notes == two.notes and \
+        one.sw_version == two.sw_version and \
+        one.serial_no == two.serial_no and \
+        one.model_filter == two.model_filter and \
+        one.model_lamp == two.model_lamp
 
 
 def compare_source(one, two):
@@ -168,6 +174,10 @@
         record.name = TEST3_DATA['name']
         record.location = TEST3_DATA['location']
         record.notes = TEST3_DATA['notes']
+        record.sw_version = TEST3_DATA['sw_version']
+        record.serial_no = TEST3_DATA['serial_no']
+        record.model_filter = TEST3_DATA['model_filter']
+        record.model_lamp = TEST3_DATA['model_lamp']
         updated = self.projector.update_projector(record)
         self.assertTrue(updated, 'Save updated record should have returned True')
         record = self.projector.get_projector_by_ip(TEST3_DATA['ip'])
@@ -246,7 +256,8 @@
         projector = Projector()
 
         # WHEN: projector() is populated
-        # NOTE: projector.pin, projector.other, projector.sources should all return None
+        # NOTE: projector.[pin, other, sources, sw_version, serial_no, sw_version, model_lamp, model_filter]
+        #           should all return None.
         #       projector.source_list should return an empty list
         projector.id = 0
         projector.ip = '127.0.0.1'
@@ -262,8 +273,9 @@
         self.assertEqual(str(projector),
                          '< Projector(id="0", ip="127.0.0.1", port="4352", pin="None", name="Test One", '
                          'location="Somewhere over the rainbow", notes="Not again", pjlink_name="TEST", '
-                         'manufacturer="IN YOUR DREAMS", model="OpenLP", other="None", sources="None", '
-                         'source_list="[]") >',
+                         'manufacturer="IN YOUR DREAMS", model="OpenLP", serial_no="None", other="None", '
+                         'sources="None", source_list="[]", model_filter="None", model_lamp="None", '
+                         'sw_version="None") >',
                          'Projector.__repr__() should have returned a proper representation string')
 
     def test_projectorsource_repr(self):

=== modified file 'tests/resources/projector/data.py'
--- tests/resources/projector/data.py	2017-05-07 10:15:10 +0000
+++ tests/resources/projector/data.py	2017-05-20 06:06:27 +0000
@@ -27,6 +27,8 @@
 from tempfile import gettempdir
 
 # Test data
+TEST_DB_PJLINK1 = 'projector_pjlink1.sqlite'
+
 TEST_DB = os.path.join(gettempdir(), 'openlp-test-projectordb.sql')
 
 TEST_SALT = '498e4a67'
@@ -44,21 +46,33 @@
                   pin='1111',
                   name='___TEST_ONE___',
                   location='location one',
-                  notes='notes one')
+                  notes='notes one',
+                  serial_no='Serial Number 1',
+                  sw_version='Version 1',
+                  model_filter='Filter type 1',
+                  model_lamp='Lamp type 1')
 
 TEST2_DATA = dict(ip='222.222.222.222',
                   port='2222',
                   pin='2222',
                   name='___TEST_TWO___',
                   location='location two',
-                  notes='notes two')
+                  notes='notes one',
+                  serial_no='Serial Number 2',
+                  sw_version='Version 2',
+                  model_filter='Filter type 2',
+                  model_lamp='Lamp type 2')
 
 TEST3_DATA = dict(ip='333.333.333.333',
                   port='3333',
                   pin='3333',
                   name='___TEST_THREE___',
                   location='location three',
-                  notes='notes three')
+                  notes='notes one',
+                  serial_no='Serial Number 3',
+                  sw_version='Version 3',
+                  model_filter='Filter type 3',
+                  model_lamp='Lamp type 3')
 
 TEST_VIDEO_CODES = {
     '11': 'RGB 1',


Follow ups