Merge lp:~alisonken1/openlp/pjlink2-u into lp:openlp

Proposed by Ken Roberts on 2019-03-09
Status: Merged
Merged at revision: 2849
Proposed branch: lp:~alisonken1/openlp/pjlink2-u
Merge into: lp:openlp
Diff against target: 375 lines (+60/-49)
13 files modified
openlp/core/projectors/db.py (+7/-1)
openlp/core/projectors/manager.py (+11/-27)
openlp/core/projectors/pjlink.py (+15/-4)
openlp/core/ui/advancedtab.py (+2/-2)
openlp/core/ui/icons.py (+8/-4)
openlp/core/ui/themestab.py (+1/-1)
setup.cfg (+1/-0)
tests/functional/openlp_core/lib/test_image_manager.py (+2/-2)
tests/functional/openlp_plugins/media/test_mediaplugin.py (+1/-1)
tests/functional/openlp_plugins/songs/test_lib.py (+1/-1)
tests/functional/openlp_plugins/songusage/test_songusage.py (+2/-2)
tests/openlp_core/projectors/test_projector_db.py (+4/-3)
tests/openlp_core/projectors/test_projector_pjlink_commands_01.py (+5/-1)
To merge this branch: bzr merge lp:~alisonken1/openlp/pjlink2-u
Reviewer Review Type Date Requested Status
Phill Approve on 2019-03-09
Tim Bentley 2019-03-09 Approve on 2019-03-09
Review via email: mp+364200@code.launchpad.net

This proposal supersedes a proposal from 2019-03-08.

Commit message

PJLink2 Update U

Description of the change

Honest - last merge request for this series
(found oops in running code not found during test)

- Fix projector S_ON status icon selection
- Remove unused status items (status icons changed to FA)
- Fix projector icon status update for network errors
    (keep error icon until network reconnects rather than disconnect icon)
- Fix colors to projector toolbar connect/power icons
- Fix toolbar select input icon not always enabled after selecting/connecting projector
- Add max-line-length option for flake8 tests in setup.cfg
- Fix projector source select check for db id in projector object
- Fix projector tests
- Minor cleanups

--------------------------------------------------------------------------------
lp:~alisonken1/openlp/pjlink2-u (revision 2850)
https://ci.openlp.io/job/Branch-01-Pull/2702/ [SUCCESS]
https://ci.openlp.io/job/Branch-02a-Linux-Tests/2596/ [SUCCESS]
https://ci.openlp.io/job/Branch-02b-macOS-Tests/366/ [FAILURE]
https://ci.openlp.io/job/Branch-03a-Build-Source/195/ [SUCCESS]
https://ci.openlp.io/job/Branch-03b-Build-macOS/174/ [FAILURE]
https://ci.openlp.io/job/Branch-04a-Code-Lint/1657/ [SUCCESS]
https://ci.openlp.io/job/Branch-04b-Test-Coverage/1470/ [SUCCESS]
https://ci.openlp.io/job/Branch-05-AppVeyor-Tests/357/ [SUCCESS]

To post a comment you must log in.
Raoul Snyman (raoul-snyman) wrote : Posted in a previous version of this proposal

Linux tests passed!

Raoul Snyman (raoul-snyman) wrote : Posted in a previous version of this proposal

Linting passed!

Raoul Snyman (raoul-snyman) wrote : Posted in a previous version of this proposal

macOS tests failed, please see https://ci.openlp.io/job/MP-04-macOS-Tests/42/ for more details

Raoul Snyman (raoul-snyman) wrote : Posted in a previous version of this proposal

Linux tests passed!

Raoul Snyman (raoul-snyman) wrote : Posted in a previous version of this proposal

Linting passed!

Raoul Snyman (raoul-snyman) wrote : Posted in a previous version of this proposal

macOS tests failed, please see https://ci.openlp.io/job/MP-04-macOS-Tests/43/ for more details

Raoul Snyman (raoul-snyman) wrote : Posted in a previous version of this proposal

Linux tests passed!

Raoul Snyman (raoul-snyman) wrote : Posted in a previous version of this proposal

Linting passed!

Raoul Snyman (raoul-snyman) wrote : Posted in a previous version of this proposal

macOS tests failed, please see https://ci.openlp.io/job/MP-04-macOS-Tests/44/ for more details

Phill (phill-ridout) wrote : Posted in a previous version of this proposal

Few minor inlines.

review: Needs Fixing
Raoul Snyman (raoul-snyman) wrote :

Linux tests passed!

Raoul Snyman (raoul-snyman) wrote :

Linting passed!

Raoul Snyman (raoul-snyman) wrote :

macOS tests failed, please see https://ci.openlp.io/job/MP-04-macOS-Tests/46/ for more details

Tim Bentley (trb143) : Posted in a previous version of this proposal
review: Approve
Tim Bentley (trb143) :
review: Approve
Phill (phill-ridout) :
review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'openlp/core/projectors/db.py'
2--- openlp/core/projectors/db.py 2019-02-14 15:09:09 +0000
3+++ openlp/core/projectors/db.py 2019-03-09 04:02:45 +0000
4@@ -417,11 +417,17 @@
5 value: (str) From ProjectorSource, Sources tables or PJLink default code list
6 """
7 source_dict = {}
8+ # Apparently, there was a change to the projector object. Test for which object has db id
9+ if hasattr(projector, "id"):
10+ chk = projector.id
11+ elif hasattr(projector.entry, "id"):
12+ chk = projector.entry.id
13+
14 # Get default list first
15 for key in projector.source_available:
16 item = self.get_object_filtered(ProjectorSource,
17 and_(ProjectorSource.code == key,
18- ProjectorSource.projector_id == projector.id))
19+ ProjectorSource.projector_id == chk))
20 if item is None:
21 source_dict[key] = PJLINK_DEFAULT_CODES[key]
22 else:
23
24=== modified file 'openlp/core/projectors/manager.py'
25--- openlp/core/projectors/manager.py 2019-02-14 15:09:09 +0000
26+++ openlp/core/projectors/manager.py 2019-03-09 04:02:45 +0000
27@@ -46,31 +46,10 @@
28 from openlp.core.ui.icons import UiIcons
29 from openlp.core.widgets.toolbar import OpenLPToolbar
30
31-
32 log = logging.getLogger(__name__)
33 log.debug('projectormanager loaded')
34
35
36-# Dict for matching projector status to display icon
37-STATUS_ICONS = {
38- S_NOT_CONNECTED: ':/projector/projector_item_disconnect.png',
39- S_CONNECTING: ':/projector/projector_item_connect.png',
40- S_CONNECTED: ':/projector/projector_off.png',
41- S_OFF: ':/projector/projector_off.png',
42- S_INITIALIZE: ':/projector/projector_off.png',
43- S_STANDBY: ':/projector/projector_off.png',
44- S_WARMUP: ':/projector/projector_warmup.png',
45- S_ON: ':/projector/projector_on.png',
46- S_COOLDOWN: ':/projector/projector_cooldown.png',
47- E_ERROR: ':/projector/projector_error.png',
48- E_NETWORK: ':/projector/projector_not_connected_error.png',
49- E_SOCKET_TIMEOUT: ':/projector/projector_not_connected_error.png',
50- E_AUTHENTICATION: ':/projector/projector_not_connected_error.png',
51- E_UNKNOWN_SOCKET_ERROR: ':/projector/projector_not_connected_error.png',
52- E_NOT_CONNECTED: ':/projector/projector_not_connected_error.png'
53-}
54-
55-
56 class UiProjectorManager(object):
57 """
58 UI part of the Projector Manager
59@@ -122,7 +101,7 @@
60 self.one_toolbar.add_toolbar_action('connect_projector',
61 text=translate('OpenLP.ProjectorManager',
62 'Connect to selected projector.'),
63- icon=UiIcons().projector_connect,
64+ icon=UiIcons().projector_select_connect,
65 tooltip=translate('OpenLP.ProjectorManager',
66 'Connect to selected projector.'),
67 triggers=self.on_connect_projector)
68@@ -136,7 +115,7 @@
69 self.one_toolbar.add_toolbar_action('disconnect_projector',
70 text=translate('OpenLP.ProjectorManager',
71 'Disconnect from selected projectors'),
72- icon=UiIcons().projector_disconnect,
73+ icon=UiIcons().projector_select_disconnect,
74 tooltip=translate('OpenLP.ProjectorManager',
75 'Disconnect from selected projector.'),
76 triggers=self.on_disconnect_projector)
77@@ -151,7 +130,7 @@
78 self.one_toolbar.add_toolbar_action('poweron_projector',
79 text=translate('OpenLP.ProjectorManager',
80 'Power on selected projector'),
81- icon=UiIcons().projector_on,
82+ icon=UiIcons().projector_power_on,
83 tooltip=translate('OpenLP.ProjectorManager',
84 'Power on selected projector.'),
85 triggers=self.on_poweron_projector)
86@@ -164,7 +143,7 @@
87 triggers=self.on_poweron_projector)
88 self.one_toolbar.add_toolbar_action('poweroff_projector',
89 text=translate('OpenLP.ProjectorManager', 'Standby selected projector'),
90- icon=UiIcons().projector_off,
91+ icon=UiIcons().projector_power_off,
92 tooltip=translate('OpenLP.ProjectorManager',
93 'Put selected projector in standby.'),
94 triggers=self.on_poweroff_projector)
95@@ -309,7 +288,7 @@
96 S_INITIALIZE: UiIcons().projector_on,
97 S_STANDBY: UiIcons().projector_off,
98 S_WARMUP: UiIcons().projector_warmup,
99- S_ON: UiIcons().projector_off,
100+ S_ON: UiIcons().projector_on,
101 S_COOLDOWN: UiIcons().projector_cooldown,
102 E_ERROR: UiIcons().projector_error,
103 E_NETWORK: UiIcons().error,
104@@ -880,6 +859,7 @@
105 """
106 Update the icons when the selected projectors change
107 """
108+ log.debug('update_icons(): Checking for selected projector items in list')
109 count = len(self.projector_list_widget.selectedItems())
110 projector = None
111 if count == 0:
112@@ -900,6 +880,7 @@
113 self.get_toolbar_item('blank_projector_multiple', hidden=True)
114 self.get_toolbar_item('show_projector_multiple', hidden=True)
115 elif count == 1:
116+ log.debug('update_icons(): Found one item selected')
117 projector = self.projector_list_widget.selectedItems()[0].data(QtCore.Qt.UserRole)
118 connected = QSOCKET_STATE[projector.link.state()] == S_CONNECTED
119 power = projector.link.power == S_ON
120@@ -910,12 +891,14 @@
121 self.get_toolbar_item('blank_projector_multiple', hidden=True)
122 self.get_toolbar_item('show_projector_multiple', hidden=True)
123 if connected:
124+ log.debug('update_icons(): Updating icons for connected state')
125 self.get_toolbar_item('view_projector', enabled=True)
126 self.get_toolbar_item('source_view_projector',
127- enabled=connected and power and projector.link.source_available is not None)
128+ enabled=projector.link.source_available is not None and connected and power)
129 self.get_toolbar_item('edit_projector', hidden=True)
130 self.get_toolbar_item('delete_projector', hidden=True)
131 else:
132+ log.debug('update_icons(): Updating for not connected state')
133 self.get_toolbar_item('view_projector', hidden=True)
134 self.get_toolbar_item('source_view_projector', hidden=True)
135 self.get_toolbar_item('edit_projector', enabled=True)
136@@ -931,6 +914,7 @@
137 self.get_toolbar_item('blank_projector', enabled=False)
138 self.get_toolbar_item('show_projector', enabled=False)
139 else:
140+ log.debug('update_icons(): Updating for multiple items selected')
141 self.get_toolbar_item('edit_projector', enabled=False)
142 self.get_toolbar_item('delete_projector', enabled=False)
143 self.get_toolbar_item('view_projector', hidden=True)
144
145=== modified file 'openlp/core/projectors/pjlink.py'
146--- openlp/core/projectors/pjlink.py 2019-02-14 15:09:09 +0000
147+++ openlp/core/projectors/pjlink.py 2019-03-09 04:02:45 +0000
148@@ -528,8 +528,9 @@
149 sources.append(source)
150 sources.sort()
151 self.source_available = sources
152- log.debug('({ip}) Setting projector sources_available to "{data}"'.format(ip=self.entry.name,
153- data=self.source_available))
154+ log.debug('({ip}) Setting projector source_available to "{data}"'.format(ip=self.entry.name,
155+ data=self.source_available))
156+ self.projectorUpdateIcons.emit()
157 return
158
159 def process_lamp(self, data):
160@@ -886,6 +887,9 @@
161 elif status >= S_NOT_CONNECTED and status in QSOCKET_STATE:
162 # Socket connection status update
163 self.status_connect = status
164+ # Check if we need to update error state as well
165+ if self.error_status != S_OK and status != S_NOT_CONNECTED:
166+ self.error_status = S_OK
167 elif status >= S_NOT_CONNECTED and status in PROJECTOR_STATE:
168 # Only affects the projector status
169 self.projector_status = status
170@@ -905,7 +909,14 @@
171 message=status_message if msg is None else msg))
172
173 # Now that we logged extra information for debugging, broadcast the original change/message
174- (code, message) = self._get_status(status)
175+ # Check for connection errors first
176+ if self.error_status != S_OK:
177+ log.debug('({ip}) Signalling error code'.format(ip=self.entry.name))
178+ code, message = self._get_status(self.error_status)
179+ status = self.error_status
180+ else:
181+ log.debug('({ip}) Signalling status code'.format(ip=self.entry.name))
182+ code, message = self._get_status(status)
183 if msg is not None:
184 message = msg
185 elif message is None:
186@@ -953,7 +964,7 @@
187 log.error('({ip}) Invalid initial packet received - closing socket'.format(ip=self.entry.name))
188 return self.disconnect_from_host()
189 # Convert the initial login prompt with the expected PJLink normal command format for processing
190- log.debug('({ip}) check_login(): Formatting initial connection prompt'
191+ log.debug('({ip}) check_login(): Formatting initial connection prompt '
192 'to PJLink packet'.format(ip=self.entry.name))
193 return self.get_data('{start}{clss}{data}'.format(start=PJLINK_PREFIX,
194 clss='1',
195
196=== modified file 'openlp/core/ui/advancedtab.py'
197--- openlp/core/ui/advancedtab.py 2019-02-14 15:09:09 +0000
198+++ openlp/core/ui/advancedtab.py 2019-03-09 04:02:45 +0000
199@@ -455,7 +455,7 @@
200 Service Name options changed
201 """
202 self.service_name_day.setEnabled(default_service_enabled)
203- time_enabled = default_service_enabled and self.service_name_day.currentIndex() is not 7
204+ time_enabled = default_service_enabled and self.service_name_day.currentIndex() != 7
205 self.service_name_time.setEnabled(time_enabled)
206 self.service_name_edit.setEnabled(default_service_enabled)
207 self.service_name_revert_button.setEnabled(default_service_enabled)
208@@ -497,7 +497,7 @@
209 """
210 React to the day of the service name changing.
211 """
212- self.service_name_time.setEnabled(service_day is not 7)
213+ self.service_name_time.setEnabled(service_day != 7)
214 self.update_service_name_example(None)
215
216 def on_service_name_revert_button_clicked(self):
217
218=== modified file 'openlp/core/ui/icons.py'
219--- openlp/core/ui/icons.py 2019-02-15 22:34:53 +0000
220+++ openlp/core/ui/icons.py 2019-03-09 04:02:45 +0000
221@@ -117,13 +117,17 @@
222 'presentation': {'icon': 'fa.bar-chart'},
223 'preview': {'icon': 'fa.laptop'},
224 'projector': {'icon': 'op.video'},
225- 'projector_connect': {'icon': 'fa.plug'},
226+ 'projector_connect': {'icon': 'fa.plug'}, # Projector connect
227 'projector_cooldown': {'icon': 'fa.video-camera', 'attr': 'blue'},
228- 'projector_disconnect': {'icon': 'fa.plug', 'attr': 'lightGray'},
229+ 'projector_disconnect': {'icon': 'fa.plug', 'attr': 'lightGray'}, # Projector disconnect
230 'projector_error': {'icon': 'fa.video-camera', 'attr': 'red'},
231 'projector_hdmi': {'icon': 'op.hdmi'},
232- 'projector_off': {'icon': 'fa.video-camera', 'attr': 'black'},
233- 'projector_on': {'icon': 'fa.video-camera', 'attr': 'green'},
234+ 'projector_power_off': {'icon': 'fa.video-camera', 'attr': 'red'}, # Toolbar power off
235+ 'projector_power_on': {'icon': 'fa.video-camera', 'attr': 'green'}, # Toolbar power on
236+ 'projector_off': {'icon': 'fa.video-camera', 'attr': 'black'}, # Projector off
237+ 'projector_on': {'icon': 'fa.video-camera', 'attr': 'green'}, # Projector on
238+ 'projector_select_connect': {'icon': 'fa.plug', 'attr': 'green'}, # Toolbar connect
239+ 'projector_select_disconnect': {'icon': 'fa.plug', 'attr': 'red'}, # Toolbar disconnect
240 'projector_warmup': {'icon': 'fa.video-camera', 'attr': 'yellow'},
241 'picture': {'icon': 'fa.picture-o'},
242 'print': {'icon': 'fa.print'},
243
244=== modified file 'openlp/core/ui/themestab.py'
245--- openlp/core/ui/themestab.py 2019-02-14 15:09:09 +0000
246+++ openlp/core/ui/themestab.py 2019-03-09 04:02:45 +0000
247@@ -206,7 +206,7 @@
248 find_and_set_in_combo_box(self.default_combo_box, self.global_theme)
249 # self.renderer.set_global_theme()
250 self.renderer.set_theme_level(self.theme_level)
251- if self.global_theme is not '':
252+ if self.global_theme != '':
253 self._preview_global_theme()
254
255 def _preview_global_theme(self):
256
257=== modified file 'setup.cfg'
258--- setup.cfg 2018-10-30 19:46:55 +0000
259+++ setup.cfg 2019-03-09 04:02:45 +0000
260@@ -9,6 +9,7 @@
261
262 [flake8]
263 exclude=resources.py,vlc.py
264+max-line-length = 120
265 ignore = E402,W503,W504,D
266
267 [pycodestyle]
268
269=== modified file 'tests/functional/openlp_core/lib/test_image_manager.py'
270--- tests/functional/openlp_core/lib/test_image_manager.py 2019-02-14 15:09:09 +0000
271+++ tests/functional/openlp_core/lib/test_image_manager.py 2019-03-09 04:02:45 +0000
272@@ -178,7 +178,7 @@
273 # THEN a KeyError is thrown
274 with self.assertRaises(KeyError) as context:
275 self.image_manager.get_image(TEST_PATH, 'church1.jpg')
276- assert context.exception is not '', 'KeyError exception should have been thrown for missing image'
277+ assert context.exception != '', 'KeyError exception should have been thrown for missing image'
278
279 @patch('openlp.core.lib.imagemanager.run_thread')
280 def test_different_dimension_image(self, mocked_run_thread):
281@@ -211,7 +211,7 @@
282 # WHEN: calling with correct image, but wrong dimensions
283 with self.assertRaises(KeyError) as context:
284 self.image_manager.get_image(full_path, 'church.jpg', 120, 120)
285- assert context.exception is not '', 'KeyError exception should have been thrown for missing dimension'
286+ assert context.exception != '', 'KeyError exception should have been thrown for missing dimension'
287
288 @patch('openlp.core.lib.imagemanager.resize_image')
289 @patch('openlp.core.lib.imagemanager.image_to_byte')
290
291=== modified file 'tests/functional/openlp_plugins/media/test_mediaplugin.py'
292--- tests/functional/openlp_plugins/media/test_mediaplugin.py 2019-02-14 15:09:09 +0000
293+++ tests/functional/openlp_plugins/media/test_mediaplugin.py 2019-03-09 04:02:45 +0000
294@@ -57,4 +57,4 @@
295 # THEN: about() should return a string object
296 assert isinstance(MediaPlugin.about(), str)
297 # THEN: about() should return a non-empty string
298- assert len(MediaPlugin.about()) is not 0
299+ assert len(MediaPlugin.about()) != 0
300
301=== modified file 'tests/functional/openlp_plugins/songs/test_lib.py'
302--- tests/functional/openlp_plugins/songs/test_lib.py 2019-02-14 15:09:09 +0000
303+++ tests/functional/openlp_plugins/songs/test_lib.py 2019-03-09 04:02:45 +0000
304@@ -199,7 +199,7 @@
305 result = _remove_typos(diff)
306
307 # THEN: There should be no typos in the middle anymore. The remaining equals should have been merged.
308- assert len(result) is 1, 'The result should contain only one element.'
309+ assert len(result) == 1, 'The result should contain only one element.'
310 assert result[0][0] == 'equal', 'The result should contain an equal element.'
311 assert result[0][1] == 0, 'The start indices should be kept.'
312 assert result[0][2] == 22, 'The stop indices should be kept.'
313
314=== modified file 'tests/functional/openlp_plugins/songusage/test_songusage.py'
315--- tests/functional/openlp_plugins/songusage/test_songusage.py 2019-02-14 15:09:09 +0000
316+++ tests/functional/openlp_plugins/songusage/test_songusage.py 2019-03-09 04:02:45 +0000
317@@ -45,8 +45,8 @@
318 # THEN: about() should return a string object
319 assert isinstance(SongUsagePlugin.about(), str)
320 # THEN: about() should return a non-empty string
321- assert len(SongUsagePlugin.about()) is not 0
322- assert len(SongUsagePlugin.about()) is not 0
323+ assert len(SongUsagePlugin.about()) != 0
324+ assert len(SongUsagePlugin.about()) != 0
325
326 @patch('openlp.plugins.songusage.songusageplugin.Manager')
327 def test_song_usage_init(self, MockedManager):
328
329=== modified file 'tests/openlp_core/projectors/test_projector_db.py'
330--- tests/openlp_core/projectors/test_projector_db.py 2019-02-14 15:09:09 +0000
331+++ tests/openlp_core/projectors/test_projector_db.py 2019-03-09 04:02:45 +0000
332@@ -134,6 +134,7 @@
333 """
334 Set up anything necessary for all tests
335 """
336+ self.tmp_folder = mkdtemp(prefix='openlp_')
337 # Create a test app to keep from segfaulting
338 Registry.create()
339 self.registry = Registry()
340@@ -153,11 +154,11 @@
341 patch('openlp.core.ui.mainwindow.ThemeManager'), \
342 patch('openlp.core.ui.mainwindow.ProjectorManager'), \
343 patch('openlp.core.ui.mainwindow.websockets.WebSocketServer'), \
344- patch('openlp.core.ui.mainwindow.server.HttpServer'):
345+ patch('openlp.core.ui.mainwindow.server.HttpServer'), \
346+ patch('openlp.core.state.State.list_plugins') as mock_plugins:
347+ mock_plugins.return_value = []
348 self.main_window = MainWindow()
349
350- # Create a temporary database directory and database
351- self.tmp_folder = mkdtemp(prefix='openlp_')
352 tmpdb_url = 'sqlite:///{db}'.format(db=os.path.join(self.tmp_folder, TEST_DB))
353 mocked_init_url.return_value = tmpdb_url
354 self.projector = ProjectorDB()
355
356=== modified file 'tests/openlp_core/projectors/test_projector_pjlink_commands_01.py'
357--- tests/openlp_core/projectors/test_projector_pjlink_commands_01.py 2019-02-14 15:09:09 +0000
358+++ tests/openlp_core/projectors/test_projector_pjlink_commands_01.py 2019-03-09 04:02:45 +0000
359@@ -452,12 +452,16 @@
360 """
361 Test saving video source available information
362 """
363+
364 # GIVEN: Test object
365 with patch.object(openlp.core.projectors.pjlink, 'log') as mock_log:
366 pjlink = PJLink(Projector(**TEST1_DATA), no_poll=True)
367 pjlink.source_available = []
368- log_debug_calls = [call('({ip}) Setting projector sources_available to '
369+ log_debug_calls = [call('({ip}) reset_information() connect status is '
370+ 'S_NOT_CONNECTED'.format(ip=pjlink.name)),
371+ call('({ip}) Setting projector source_available to '
372 '"[\'11\', \'12\', \'21\', \'22\', \'31\', \'32\']"'.format(ip=pjlink.name))]
373+
374 chk_data = '21 12 11 22 32 31' # Although they should already be sorted, use unsorted to verify method
375 chk_test = ['11', '12', '21', '22', '31', '32']
376