Merge lp:~phill-ridout/openlp/fixes-mkII into lp:openlp
- fixes-mkII
- Merge into trunk
Status: | Merged | ||||||||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Approved by: | Raoul Snyman | ||||||||||||||||||||||||||||||||||||||||||||
Approved revision: | 2794 | ||||||||||||||||||||||||||||||||||||||||||||
Merged at revision: | 2784 | ||||||||||||||||||||||||||||||||||||||||||||
Proposed branch: | lp:~phill-ridout/openlp/fixes-mkII | ||||||||||||||||||||||||||||||||||||||||||||
Merge into: | lp:openlp | ||||||||||||||||||||||||||||||||||||||||||||
Diff against target: |
1063 lines (+167/-143) 47 files modified
openlp/core/common/__init__.py (+21/-3) openlp/core/common/applocation.py (+1/-1) openlp/core/common/httputils.py (+4/-4) openlp/core/common/i18n.py (+1/-1) openlp/core/common/mixins.py (+14/-0) openlp/core/common/path.py (+1/-1) openlp/core/common/settings.py (+4/-1) openlp/core/lib/__init__.py (+1/-1) openlp/core/lib/mediamanageritem.py (+4/-2) openlp/core/ui/exceptionform.py (+1/-1) openlp/core/ui/formattingtagcontroller.py (+1/-1) openlp/core/ui/mainwindow.py (+2/-2) openlp/core/ui/servicemanager.py (+28/-28) openlp/core/ui/thememanager.py (+3/-3) openlp/core/version.py (+2/-2) openlp/core/widgets/edits.py (+13/-3) openlp/core/widgets/views.py (+1/-1) openlp/plugins/bibles/forms/booknameform.py (+1/-2) openlp/plugins/bibles/lib/__init__.py (+3/-3) openlp/plugins/bibles/lib/db.py (+1/-2) openlp/plugins/images/lib/mediaitem.py (+2/-1) openlp/plugins/presentations/lib/pptviewcontroller.py (+1/-1) openlp/plugins/songs/forms/editsongform.py (+3/-3) openlp/plugins/songs/lib/__init__.py (+2/-3) openlp/plugins/songs/lib/importers/easyslides.py (+2/-1) openlp/plugins/songs/lib/importers/mediashout.py (+1/-1) openlp/plugins/songs/lib/importers/openoffice.py (+2/-2) openlp/plugins/songs/lib/importers/opensong.py (+2/-1) openlp/plugins/songs/lib/importers/songimport.py (+2/-21) openlp/plugins/songs/lib/importers/songsoffellowship.py (+0/-1) openlp/plugins/songs/lib/importers/zionworx.py (+5/-15) openlp/plugins/songs/lib/openlyricsxml.py (+1/-1) openlp/plugins/songusage/forms/songusagedetailform.py (+8/-2) openlp/plugins/songusage/songusageplugin.py (+6/-9) tests/functional/openlp_core/common/test_actions.py (+1/-0) tests/functional/openlp_core/common/test_httputils.py (+1/-1) tests/functional/openlp_core/common/test_i18n.py (+1/-1) tests/functional/openlp_core/common/test_path.py (+4/-4) tests/functional/openlp_core/lib/test_lib.py (+1/-1) tests/functional/openlp_core/ui/test_first_time.py (+1/-1) tests/functional/openlp_core/widgets/test_views.py (+0/-1) tests/functional/openlp_plugins/presentations/test_presentationcontroller.py (+1/-1) tests/interfaces/openlp_core/ui/test_projectormanager.py (+1/-1) tests/interfaces/openlp_core/ui/test_projectorsourceform.py (+1/-1) tests/interfaces/openlp_core/ui/test_thememanager.py (+1/-1) tests/utils/__init__.py (+1/-1) tests/utils/test_pylint.py (+9/-5) |
||||||||||||||||||||||||||||||||||||||||||||
To merge this branch: | bzr merge lp:~phill-ridout/openlp/fixes-mkII | ||||||||||||||||||||||||||||||||||||||||||||
Related bugs: |
|
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Raoul Snyman | Pending | ||
Tim Bentley | Pending | ||
Review via email: mp+333573@code.launchpad.net |
This proposal supersedes a proposal from 2017-11-10.
Commit message
Description of the change
Fixed a number of bugs, and tests.
Failing on Code Analysis2, but this looks like fallout from the refactors (it hasn't passed since the beginning of october)
Also contains superflys branch lp:~raoul-snyman/openlp/fix-linting
-------
lp:~phill-ridout/openlp/fixes-mkII (revision 2794)
[SUCCESS] https:/
[SUCCESS] https:/
[SUCCESS] https:/
[SUCCESS] https:/
[SUCCESS] https:/
[SUCCESS] https:/
[FAILURE] https:/
Stopping after failure
Tim Bentley (trb143) wrote : Posted in a previous version of this proposal | # |
Tim Bentley (trb143) wrote : Posted in a previous version of this proposal | # |
Still approved
Raoul Snyman (raoul-snyman) wrote : Posted in a previous version of this proposal | # |
One small request....
Preview Diff
1 | === modified file 'openlp/core/common/__init__.py' |
2 | --- openlp/core/common/__init__.py 2017-10-07 07:05:07 +0000 |
3 | +++ openlp/core/common/__init__.py 2017-11-10 23:08:30 +0000 |
4 | @@ -43,9 +43,13 @@ |
5 | |
6 | FIRST_CAMEL_REGEX = re.compile('(.)([A-Z][a-z]+)') |
7 | SECOND_CAMEL_REGEX = re.compile('([a-z0-9])([A-Z])') |
8 | -CONTROL_CHARS = re.compile(r'[\x00-\x1F\x7F-\x9F]', re.UNICODE) |
9 | -INVALID_FILE_CHARS = re.compile(r'[\\/:\*\?"<>\|\+\[\]%]', re.UNICODE) |
10 | +CONTROL_CHARS = re.compile(r'[\x00-\x1F\x7F-\x9F]') |
11 | +INVALID_FILE_CHARS = re.compile(r'[\\/:\*\?"<>\|\+\[\]%]') |
12 | IMAGES_FILTER = None |
13 | +REPLACMENT_CHARS_MAP = str.maketrans({'\u2018': '\'', '\u2019': '\'', '\u201c': '"', '\u201d': '"', '\u2026': '...', |
14 | + '\u2013': '-', '\u2014': '-', '\v': '\n\n', '\f': '\n\n'}) |
15 | +NEW_LINE_REGEX = re.compile(r' ?(\r\n?|\n) ?') |
16 | +WHITESPACE_REGEX = re.compile(r'[ \t]+') |
17 | |
18 | |
19 | def trace_error_handler(logger): |
20 | @@ -339,7 +343,7 @@ |
21 | if file_path.exists(): |
22 | file_path.unlink() |
23 | return True |
24 | - except (IOError, OSError): |
25 | + except OSError: |
26 | log.exception('Unable to delete file {file_path}'.format(file_path=file_path)) |
27 | return False |
28 | |
29 | @@ -436,3 +440,17 @@ |
30 | return detector.result |
31 | except OSError: |
32 | log.exception('Error detecting file encoding') |
33 | + |
34 | + |
35 | +def normalize_str(irreg_str): |
36 | + """ |
37 | + Normalize the supplied string. Remove unicode control chars and tidy up white space. |
38 | + |
39 | + :param str irreg_str: The string to normalize. |
40 | + :return: The normalized string |
41 | + :rtype: str |
42 | + """ |
43 | + irreg_str = irreg_str.translate(REPLACMENT_CHARS_MAP) |
44 | + irreg_str = CONTROL_CHARS.sub('', irreg_str) |
45 | + irreg_str = NEW_LINE_REGEX.sub('\n', irreg_str) |
46 | + return WHITESPACE_REGEX.sub(' ', irreg_str) |
47 | |
48 | === modified file 'openlp/core/common/applocation.py' |
49 | --- openlp/core/common/applocation.py 2017-10-07 07:05:07 +0000 |
50 | +++ openlp/core/common/applocation.py 2017-11-10 23:08:30 +0000 |
51 | @@ -83,7 +83,7 @@ |
52 | """ |
53 | # Check if we have a different data location. |
54 | if Settings().contains('advanced/data path'): |
55 | - path = Settings().value('advanced/data path') |
56 | + path = Path(Settings().value('advanced/data path')) |
57 | else: |
58 | path = AppLocation.get_directory(AppLocation.DataDir) |
59 | create_paths(path) |
60 | |
61 | === modified file 'openlp/core/common/httputils.py' |
62 | --- openlp/core/common/httputils.py 2017-10-07 07:05:07 +0000 |
63 | +++ openlp/core/common/httputils.py 2017-11-10 23:08:30 +0000 |
64 | @@ -97,8 +97,8 @@ |
65 | response = requests.get(url, headers=headers, proxies=proxies, timeout=float(CONNECTION_TIMEOUT)) |
66 | log.debug('Downloaded page {url}'.format(url=response.url)) |
67 | break |
68 | - except IOError: |
69 | - # For now, catch IOError. All requests errors inherit from IOError |
70 | + except OSError: |
71 | + # For now, catch OSError. All requests errors inherit from OSError |
72 | log.exception('Unable to connect to {url}'.format(url=url)) |
73 | response = None |
74 | if retries >= CONNECTION_RETRIES: |
75 | @@ -127,7 +127,7 @@ |
76 | try: |
77 | response = requests.head(url, timeout=float(CONNECTION_TIMEOUT), allow_redirects=True) |
78 | return int(response.headers['Content-Length']) |
79 | - except IOError: |
80 | + except OSError: |
81 | if retries > CONNECTION_RETRIES: |
82 | raise ConnectionError('Unable to download {url}'.format(url=url)) |
83 | else: |
84 | @@ -173,7 +173,7 @@ |
85 | file_path.unlink() |
86 | return False |
87 | break |
88 | - except IOError: |
89 | + except OSError: |
90 | trace_error_handler(log) |
91 | if retries > CONNECTION_RETRIES: |
92 | if file_path.exists(): |
93 | |
94 | === modified file 'openlp/core/common/i18n.py' |
95 | --- openlp/core/common/i18n.py 2017-10-07 07:05:07 +0000 |
96 | +++ openlp/core/common/i18n.py 2017-11-10 23:08:30 +0000 |
97 | @@ -53,7 +53,7 @@ |
98 | |
99 | Language = namedtuple('Language', ['id', 'name', 'code']) |
100 | ICU_COLLATOR = None |
101 | -DIGITS_OR_NONDIGITS = re.compile(r'\d+|\D+', re.UNICODE) |
102 | +DIGITS_OR_NONDIGITS = re.compile(r'\d+|\D+') |
103 | LANGUAGES = sorted([ |
104 | Language(1, translate('common.languages', '(Afan) Oromo', 'Language code: om'), 'om'), |
105 | Language(2, translate('common.languages', 'Abkhazian', 'Language code: ab'), 'ab'), |
106 | |
107 | === modified file 'openlp/core/common/mixins.py' |
108 | --- openlp/core/common/mixins.py 2017-10-23 22:09:57 +0000 |
109 | +++ openlp/core/common/mixins.py 2017-11-10 23:08:30 +0000 |
110 | @@ -101,6 +101,20 @@ |
111 | """ |
112 | This adds registry components to classes to use at run time. |
113 | """ |
114 | + _application = None |
115 | + _plugin_manager = None |
116 | + _image_manager = None |
117 | + _media_controller = None |
118 | + _service_manager = None |
119 | + _preview_controller = None |
120 | + _live_controller = None |
121 | + _main_window = None |
122 | + _renderer = None |
123 | + _theme_manager = None |
124 | + _settings_form = None |
125 | + _alerts_manager = None |
126 | + _projector_manager = None |
127 | + |
128 | @property |
129 | def application(self): |
130 | """ |
131 | |
132 | === modified file 'openlp/core/common/path.py' |
133 | --- openlp/core/common/path.py 2017-10-07 07:05:07 +0000 |
134 | +++ openlp/core/common/path.py 2017-11-10 23:08:30 +0000 |
135 | @@ -233,7 +233,7 @@ |
136 | try: |
137 | if not path.exists(): |
138 | path.mkdir(parents=True) |
139 | - except IOError: |
140 | + except OSError: |
141 | if not kwargs.get('do_not_log', False): |
142 | log.exception('failed to check if directory exists or create directory') |
143 | |
144 | |
145 | === modified file 'openlp/core/common/settings.py' |
146 | --- openlp/core/common/settings.py 2017-10-07 07:05:07 +0000 |
147 | +++ openlp/core/common/settings.py 2017-11-10 23:08:30 +0000 |
148 | @@ -255,7 +255,10 @@ |
149 | ('core/logo file', 'core/logo file', [(str_to_path, None)]), |
150 | ('presentations/last directory', 'presentations/last directory', [(str_to_path, None)]), |
151 | ('images/last directory', 'images/last directory', [(str_to_path, None)]), |
152 | - ('media/last directory', 'media/last directory', [(str_to_path, None)]) |
153 | + ('media/last directory', 'media/last directory', [(str_to_path, None)]), |
154 | + ('songuasge/db password', 'songusage/db password', []), |
155 | + ('songuasge/db hostname', 'songusage/db hostname', []), |
156 | + ('songuasge/db database', 'songusage/db database', []) |
157 | ] |
158 | |
159 | @staticmethod |
160 | |
161 | === modified file 'openlp/core/lib/__init__.py' |
162 | --- openlp/core/lib/__init__.py 2017-10-10 07:08:44 +0000 |
163 | +++ openlp/core/lib/__init__.py 2017-11-10 23:08:30 +0000 |
164 | @@ -104,7 +104,7 @@ |
165 | # no BOM was found |
166 | file_handle.seek(0) |
167 | content = file_handle.read() |
168 | - except (IOError, UnicodeError): |
169 | + except (OSError, UnicodeError): |
170 | log.exception('Failed to open text file {text}'.format(text=text_file_path)) |
171 | return content |
172 | |
173 | |
174 | === modified file 'openlp/core/lib/mediamanageritem.py' |
175 | --- openlp/core/lib/mediamanageritem.py 2017-10-23 22:09:57 +0000 |
176 | +++ openlp/core/lib/mediamanageritem.py 2017-11-10 23:08:30 +0000 |
177 | @@ -92,7 +92,7 @@ |
178 | Run some initial setup. This method is separate from __init__ in order to mock it out in tests. |
179 | """ |
180 | self.hide() |
181 | - self.whitespace = re.compile(r'[\W_]+', re.UNICODE) |
182 | + self.whitespace = re.compile(r'[\W_]+') |
183 | visible_title = self.plugin.get_string(StringContent.VisibleName) |
184 | self.title = str(visible_title['title']) |
185 | Registry().register(self.plugin.name, self) |
186 | @@ -344,7 +344,9 @@ |
187 | else: |
188 | new_files.append(file_name) |
189 | if new_files: |
190 | - self.validate_and_load(new_files, data['target']) |
191 | + if 'target' in data: |
192 | + self.validate_and_load(new_files, data['target']) |
193 | + self.validate_and_load(new_files) |
194 | |
195 | def dnd_move_internal(self, target): |
196 | """ |
197 | |
198 | === modified file 'openlp/core/ui/exceptionform.py' |
199 | --- openlp/core/ui/exceptionform.py 2017-10-23 22:09:57 +0000 |
200 | +++ openlp/core/ui/exceptionform.py 2017-11-10 23:08:30 +0000 |
201 | @@ -155,7 +155,7 @@ |
202 | try: |
203 | with file_path.open('w') as report_file: |
204 | report_file.write(report_text) |
205 | - except IOError: |
206 | + except OSError: |
207 | log.exception('Failed to write crash report') |
208 | |
209 | def on_send_report_button_clicked(self): |
210 | |
211 | === modified file 'openlp/core/ui/formattingtagcontroller.py' |
212 | --- openlp/core/ui/formattingtagcontroller.py 2017-10-07 07:05:07 +0000 |
213 | +++ openlp/core/ui/formattingtagcontroller.py 2017-11-10 23:08:30 +0000 |
214 | @@ -43,7 +43,7 @@ |
215 | r'(?P<tag>[^\s/!\?>]+)(?:\s+[^\s=]+="[^"]*")*\s*(?P<empty>/)?' |
216 | r'|(?P<cdata>!\[CDATA\[(?:(?!\]\]>).)*\]\])' |
217 | r'|(?P<procinst>\?(?:(?!\?>).)*\?)' |
218 | - r'|(?P<comment>!--(?:(?!-->).)*--))>', re.UNICODE) |
219 | + r'|(?P<comment>!--(?:(?!-->).)*--))>') |
220 | self.html_regex = re.compile(r'^(?:[^<>]*%s)*[^<>]*$' % self.html_tag_regex.pattern) |
221 | |
222 | def pre_save(self): |
223 | |
224 | === added directory 'openlp/core/ui/lib' |
225 | === modified file 'openlp/core/ui/mainwindow.py' |
226 | --- openlp/core/ui/mainwindow.py 2017-10-23 22:09:57 +0000 |
227 | +++ openlp/core/ui/mainwindow.py 2017-11-10 23:08:30 +0000 |
228 | @@ -180,7 +180,7 @@ |
229 | triggers=self.service_manager_contents.on_load_service_clicked) |
230 | self.file_save_item = create_action(main_window, 'fileSaveItem', icon=':/general/general_save.png', |
231 | can_shortcuts=True, category=UiStrings().File, |
232 | - triggers=self.service_manager_contents.save_file) |
233 | + triggers=self.service_manager_contents.decide_save_method) |
234 | self.file_save_as_item = create_action(main_window, 'fileSaveAsItem', can_shortcuts=True, |
235 | category=UiStrings().File, |
236 | triggers=self.service_manager_contents.save_file_as) |
237 | @@ -1367,7 +1367,7 @@ |
238 | '- Please wait for copy to finish').format(path=self.new_data_path)) |
239 | dir_util.copy_tree(str(old_data_path), str(self.new_data_path)) |
240 | log.info('Copy successful') |
241 | - except (IOError, os.error, DistutilsFileError) as why: |
242 | + except (OSError, DistutilsFileError) as why: |
243 | self.application.set_normal_cursor() |
244 | log.exception('Data copy failed {err}'.format(err=str(why))) |
245 | err_text = translate('OpenLP.MainWindow', |
246 | |
247 | === modified file 'openlp/core/ui/servicemanager.py' |
248 | --- openlp/core/ui/servicemanager.py 2017-10-23 22:09:57 +0000 |
249 | +++ openlp/core/ui/servicemanager.py 2017-11-10 23:08:30 +0000 |
250 | @@ -193,18 +193,6 @@ |
251 | text=translate('OpenLP.ServiceManager', 'Move to &bottom'), icon=':/services/service_bottom.png', |
252 | tooltip=translate('OpenLP.ServiceManager', 'Move item to the end of the service.'), |
253 | can_shortcuts=True, category=UiStrings().Service, triggers=self.on_service_end) |
254 | - self.down_action = self.order_toolbar.add_toolbar_action( |
255 | - 'down', |
256 | - text=translate('OpenLP.ServiceManager', 'Move &down'), can_shortcuts=True, |
257 | - tooltip=translate('OpenLP.ServiceManager', 'Moves the selection down the window.'), visible=False, |
258 | - triggers=self.on_move_selection_down) |
259 | - action_list.add_action(self.down_action) |
260 | - self.up_action = self.order_toolbar.add_toolbar_action( |
261 | - 'up', |
262 | - text=translate('OpenLP.ServiceManager', 'Move up'), can_shortcuts=True, |
263 | - tooltip=translate('OpenLP.ServiceManager', 'Moves the selection up the window.'), visible=False, |
264 | - triggers=self.on_move_selection_up) |
265 | - action_list.add_action(self.up_action) |
266 | self.order_toolbar.addSeparator() |
267 | self.delete_action = self.order_toolbar.add_toolbar_action( |
268 | 'delete', can_shortcuts=True, |
269 | @@ -300,8 +288,8 @@ |
270 | self.theme_menu = QtWidgets.QMenu(translate('OpenLP.ServiceManager', '&Change Item Theme')) |
271 | self.menu.addMenu(self.theme_menu) |
272 | self.service_manager_list.addActions([self.move_down_action, self.move_up_action, self.make_live_action, |
273 | - self.move_top_action, self.move_bottom_action, self.up_action, |
274 | - self.down_action, self.expand_action, self.collapse_action]) |
275 | + self.move_top_action, self.move_bottom_action, self.expand_action, |
276 | + self.collapse_action]) |
277 | Registry().register_function('theme_update_list', self.update_theme_list) |
278 | Registry().register_function('config_screen_changed', self.regenerate_service_items) |
279 | Registry().register_function('theme_update_global', self.theme_change) |
280 | @@ -474,6 +462,12 @@ |
281 | Load a recent file as the service triggered by mainwindow recent service list. |
282 | :param field: |
283 | """ |
284 | + if self.is_modified(): |
285 | + result = self.save_modified_service() |
286 | + if result == QtWidgets.QMessageBox.Cancel: |
287 | + return False |
288 | + elif result == QtWidgets.QMessageBox.Save: |
289 | + self.decide_save_method() |
290 | sender = self.sender() |
291 | self.load_file(sender.data()) |
292 | |
293 | @@ -603,7 +597,7 @@ |
294 | if not os.path.exists(save_file): |
295 | shutil.copy(audio_from, save_file) |
296 | zip_file.write(audio_from, audio_to) |
297 | - except IOError: |
298 | + except OSError: |
299 | self.log_exception('Failed to save service to disk: {name}'.format(name=temp_file_name)) |
300 | self.main_window.error_message(translate('OpenLP.ServiceManager', 'Error Saving File'), |
301 | translate('OpenLP.ServiceManager', 'There was an error saving your file.')) |
302 | @@ -664,7 +658,7 @@ |
303 | zip_file = zipfile.ZipFile(temp_file_name, 'w', zipfile.ZIP_STORED, True) |
304 | # First we add service contents. |
305 | zip_file.writestr(service_file_name, service_content) |
306 | - except IOError: |
307 | + except OSError: |
308 | self.log_exception('Failed to save service to disk: {name}'.format(name=temp_file_name)) |
309 | self.main_window.error_message(translate('OpenLP.ServiceManager', 'Error Saving File'), |
310 | translate('OpenLP.ServiceManager', 'There was an error saving your file.')) |
311 | @@ -712,18 +706,23 @@ |
312 | default_file_path = directory_path / default_file_path |
313 | # SaveAs from osz to oszl is not valid as the files will be deleted on exit which is not sensible or usable in |
314 | # the long term. |
315 | + lite_filter = translate('OpenLP.ServiceManager', 'OpenLP Service Files - lite (*.oszl)') |
316 | + packaged_filter = translate('OpenLP.ServiceManager', 'OpenLP Service Files (*.osz)') |
317 | + |
318 | if self._file_name.endswith('oszl') or self.service_has_all_original_files: |
319 | file_path, filter_used = FileDialog.getSaveFileName( |
320 | self.main_window, UiStrings().SaveService, default_file_path, |
321 | - translate('OpenLP.ServiceManager', |
322 | - 'OpenLP Service Files (*.osz);; OpenLP Service Files - lite (*.oszl)')) |
323 | + '{packaged};; {lite}'.format(packaged=packaged_filter, lite=lite_filter)) |
324 | else: |
325 | file_path, filter_used = FileDialog.getSaveFileName( |
326 | - self.main_window, UiStrings().SaveService, file_path, |
327 | - translate('OpenLP.ServiceManager', 'OpenLP Service Files (*.osz);;')) |
328 | + self.main_window, UiStrings().SaveService, default_file_path, |
329 | + '{packaged};;'.format(packaged=packaged_filter)) |
330 | if not file_path: |
331 | return False |
332 | - file_path.with_suffix('.osz') |
333 | + if filter_used == lite_filter: |
334 | + file_path = file_path.with_suffix('.oszl') |
335 | + else: |
336 | + file_path = file_path.with_suffix('.osz') |
337 | self.set_file_name(file_path) |
338 | self.decide_save_method() |
339 | |
340 | @@ -791,11 +790,11 @@ |
341 | else: |
342 | critical_error_message_box(message=translate('OpenLP.ServiceManager', 'File is not a valid service.')) |
343 | self.log_error('File contains no service data') |
344 | - except (IOError, NameError): |
345 | + except (OSError, NameError): |
346 | self.log_exception('Problem loading service file {name}'.format(name=file_name)) |
347 | critical_error_message_box(message=translate('OpenLP.ServiceManager', |
348 | 'File could not be opened because it is corrupt.')) |
349 | - except zipfile.BadZipfile: |
350 | + except zipfile.BadZipFile: |
351 | if os.path.getsize(file_name) == 0: |
352 | self.log_exception('Service file is zero sized: {name}'.format(name=file_name)) |
353 | QtWidgets.QMessageBox.information(self, translate('OpenLP.ServiceManager', 'Empty File'), |
354 | @@ -1657,14 +1656,15 @@ |
355 | if start_pos == -1: |
356 | return |
357 | if item is None: |
358 | - end_pos = len(self.service_items) |
359 | + end_pos = len(self.service_items) - 1 |
360 | else: |
361 | end_pos = get_parent_item_data(item) - 1 |
362 | service_item = self.service_items[start_pos] |
363 | - self.service_items.remove(service_item) |
364 | - self.service_items.insert(end_pos, service_item) |
365 | - self.repaint_service_list(end_pos, child) |
366 | - self.set_modified() |
367 | + if start_pos != end_pos: |
368 | + self.service_items.remove(service_item) |
369 | + self.service_items.insert(end_pos, service_item) |
370 | + self.repaint_service_list(end_pos, child) |
371 | + self.set_modified() |
372 | else: |
373 | # we are not over anything so drop |
374 | replace = False |
375 | |
376 | === modified file 'openlp/core/ui/thememanager.py' |
377 | --- openlp/core/ui/thememanager.py 2017-10-23 22:09:57 +0000 |
378 | +++ openlp/core/ui/thememanager.py 2017-11-10 23:08:30 +0000 |
379 | @@ -604,7 +604,7 @@ |
380 | else: |
381 | with full_name.open('wb') as out_file: |
382 | out_file.write(theme_zip.read(zipped_file)) |
383 | - except (IOError, zipfile.BadZipfile): |
384 | + except (OSError, zipfile.BadZipFile): |
385 | self.log_exception('Importing theme from zip failed {name}'.format(name=file_path)) |
386 | raise ValidationError |
387 | except ValidationError: |
388 | @@ -667,7 +667,7 @@ |
389 | theme_path = theme_dir / '{file_name}.json'.format(file_name=name) |
390 | try: |
391 | theme_path.write_text(theme_pretty) |
392 | - except IOError: |
393 | + except OSError: |
394 | self.log_exception('Saving theme to file failed') |
395 | if image_source_path and image_destination_path: |
396 | if self.old_background_image_path and image_destination_path != self.old_background_image_path: |
397 | @@ -675,7 +675,7 @@ |
398 | if image_source_path != image_destination_path: |
399 | try: |
400 | copyfile(image_source_path, image_destination_path) |
401 | - except IOError: |
402 | + except OSError: |
403 | self.log_exception('Failed to save theme image') |
404 | self.generate_and_save_image(name, theme) |
405 | |
406 | |
407 | === modified file 'openlp/core/version.py' |
408 | --- openlp/core/version.py 2017-10-07 07:05:07 +0000 |
409 | +++ openlp/core/version.py 2017-11-10 23:08:30 +0000 |
410 | @@ -96,7 +96,7 @@ |
411 | remote_version = response.text |
412 | log.debug('New version found: %s', remote_version) |
413 | break |
414 | - except IOError: |
415 | + except OSError: |
416 | log.exception('Unable to connect to OpenLP server to download version file') |
417 | retries += 1 |
418 | else: |
419 | @@ -182,7 +182,7 @@ |
420 | try: |
421 | version_file = open(file_path, 'r') |
422 | full_version = str(version_file.read()).rstrip() |
423 | - except IOError: |
424 | + except OSError: |
425 | log.exception('Error in version file.') |
426 | full_version = '0.0.0-bzr000' |
427 | finally: |
428 | |
429 | === modified file 'openlp/core/widgets/edits.py' |
430 | --- openlp/core/widgets/edits.py 2017-10-23 22:09:57 +0000 |
431 | +++ openlp/core/widgets/edits.py 2017-11-10 23:08:30 +0000 |
432 | @@ -27,6 +27,7 @@ |
433 | |
434 | from PyQt5 import QtCore, QtGui, QtWidgets |
435 | |
436 | +from openlp.core.common import CONTROL_CHARS |
437 | from openlp.core.common.i18n import UiStrings, translate |
438 | from openlp.core.common.path import Path, path_to_str, str_to_path |
439 | from openlp.core.common.settings import Settings |
440 | @@ -241,7 +242,7 @@ |
441 | self.line_edit.editingFinished.connect(self.on_line_edit_editing_finished) |
442 | self.update_button_tool_tips() |
443 | |
444 | - @property |
445 | + @QtCore.pyqtProperty('QVariant') |
446 | def path(self): |
447 | """ |
448 | A property getter method to return the selected path. |
449 | @@ -349,7 +350,7 @@ |
450 | :rtype: None |
451 | """ |
452 | if self._path != path: |
453 | - self.path = path |
454 | + self._path = path |
455 | self.pathChanged.emit(path) |
456 | |
457 | |
458 | @@ -470,12 +471,21 @@ |
459 | cursor.insertText(html['start tag']) |
460 | cursor.insertText(html['end tag']) |
461 | |
462 | + def insertFromMimeData(self, source): |
463 | + """ |
464 | + Reimplement `insertFromMimeData` so that we can remove any control characters |
465 | + |
466 | + :param QtCore.QMimeData source: The mime data to insert |
467 | + :rtype: None |
468 | + """ |
469 | + self.insertPlainText(CONTROL_CHARS.sub('', source.text())) |
470 | + |
471 | |
472 | class Highlighter(QtGui.QSyntaxHighlighter): |
473 | """ |
474 | Provides a text highlighter for pointing out spelling errors in text. |
475 | """ |
476 | - WORDS = r'(?iu)[\w\']+' |
477 | + WORDS = r'(?i)[\w\']+' |
478 | |
479 | def __init__(self, *args): |
480 | """ |
481 | |
482 | === modified file 'openlp/core/widgets/views.py' |
483 | --- openlp/core/widgets/views.py 2017-10-23 22:09:57 +0000 |
484 | +++ openlp/core/widgets/views.py 2017-11-10 23:08:30 +0000 |
485 | @@ -336,7 +336,7 @@ |
486 | for file in listing: |
487 | files.append(os.path.join(local_file, file)) |
488 | Registry().execute('{mime_data}_dnd'.format(mime_data=self.mime_data_text), |
489 | - {'files': files, 'target': self.itemAt(event.pos())}) |
490 | + {'files': files}) |
491 | else: |
492 | event.ignore() |
493 | |
494 | |
495 | === modified file 'openlp/plugins/bibles/forms/booknameform.py' |
496 | --- openlp/plugins/bibles/forms/booknameform.py 2017-10-07 07:05:07 +0000 |
497 | +++ openlp/plugins/bibles/forms/booknameform.py 2017-11-10 23:08:30 +0000 |
498 | @@ -113,8 +113,7 @@ |
499 | cor_book = self.corresponding_combo_box.currentText() |
500 | for character in '\\.^$*+?{}[]()': |
501 | cor_book = cor_book.replace(character, '\\' + character) |
502 | - books = [key for key in list(self.book_names.keys()) if re.match(cor_book, str(self.book_names[key]), |
503 | - re.UNICODE)] |
504 | + books = [key for key in list(self.book_names.keys()) if re.match(cor_book, str(self.book_names[key]))] |
505 | books = [_f for _f in map(BiblesResourcesDB.get_book, books) if _f] |
506 | if books: |
507 | self.book_id = books[0]['id'] |
508 | |
509 | === modified file 'openlp/plugins/bibles/lib/__init__.py' |
510 | --- openlp/plugins/bibles/lib/__init__.py 2017-10-07 07:05:07 +0000 |
511 | +++ openlp/plugins/bibles/lib/__init__.py 2017-11-10 23:08:30 +0000 |
512 | @@ -224,13 +224,13 @@ |
513 | range_regex = '(?:(?P<from_chapter>[0-9]+){sep_v})?' \ |
514 | '(?P<from_verse>[0-9]+)(?P<range_to>{sep_r}(?:(?:(?P<to_chapter>' \ |
515 | '[0-9]+){sep_v})?(?P<to_verse>[0-9]+)|{sep_e})?)?'.format_map(REFERENCE_SEPARATORS) |
516 | - REFERENCE_MATCHES['range'] = re.compile(r'^\s*{range}\s*$'.format(range=range_regex), re.UNICODE) |
517 | - REFERENCE_MATCHES['range_separator'] = re.compile(REFERENCE_SEPARATORS['sep_l'], re.UNICODE) |
518 | + REFERENCE_MATCHES['range'] = re.compile(r'^\s*{range}\s*$'.format(range=range_regex)) |
519 | + REFERENCE_MATCHES['range_separator'] = re.compile(REFERENCE_SEPARATORS['sep_l']) |
520 | # full reference match: <book>(<range>(,(?!$)|(?=$)))+ |
521 | REFERENCE_MATCHES['full'] = \ |
522 | re.compile(r'^\s*(?!\s)(?P<book>[\d]*[.]?[^\d\.]+)\.*(?<!\s)\s*' |
523 | r'(?P<ranges>(?:{range_regex}(?:{sep_l}(?!\s*$)|(?=\s*$)))+)\s*$'.format( |
524 | - range_regex=range_regex, sep_l=REFERENCE_SEPARATORS['sep_l']), re.UNICODE) |
525 | + range_regex=range_regex, sep_l=REFERENCE_SEPARATORS['sep_l'])) |
526 | |
527 | |
528 | def get_reference_separator(separator_type): |
529 | |
530 | === modified file 'openlp/plugins/bibles/lib/db.py' |
531 | --- openlp/plugins/bibles/lib/db.py 2017-10-23 22:09:57 +0000 |
532 | +++ openlp/plugins/bibles/lib/db.py 2017-11-10 23:08:30 +0000 |
533 | @@ -307,8 +307,7 @@ |
534 | book_escaped = book |
535 | for character in RESERVED_CHARACTERS: |
536 | book_escaped = book_escaped.replace(character, '\\' + character) |
537 | - regex_book = re.compile('\\s*{book}\\s*'.format(book='\\s*'.join(book_escaped.split())), |
538 | - re.UNICODE | re.IGNORECASE) |
539 | + regex_book = re.compile('\\s*{book}\\s*'.format(book='\\s*'.join(book_escaped.split())), re.IGNORECASE) |
540 | if language_selection == LanguageSelection.Bible: |
541 | db_book = self.get_book(book) |
542 | if db_book: |
543 | |
544 | === modified file 'openlp/plugins/images/lib/mediaitem.py' |
545 | --- openlp/plugins/images/lib/mediaitem.py 2017-10-23 22:09:57 +0000 |
546 | +++ openlp/plugins/images/lib/mediaitem.py 2017-11-10 23:08:30 +0000 |
547 | @@ -366,7 +366,7 @@ |
548 | if validate_thumb(image.file_path, thumbnail_path): |
549 | icon = build_icon(thumbnail_path) |
550 | else: |
551 | - icon = create_thumb(image.file_path, thumbnail_path) |
552 | + icon = create_thumb(str(image.file_path), str(thumbnail_path)) |
553 | item_name = QtWidgets.QTreeWidgetItem([file_name]) |
554 | item_name.setText(0, file_name) |
555 | item_name.setIcon(0, icon) |
556 | @@ -390,6 +390,7 @@ |
557 | :param files: A List of strings containing the filenames of the files to be loaded |
558 | :param target_group: The QTreeWidgetItem of the group that will be the parent of the added files |
559 | """ |
560 | + file_paths = [Path(file) for file in file_paths] |
561 | self.application.set_normal_cursor() |
562 | self.load_list(file_paths, target_group) |
563 | last_dir = file_paths[0].parent |
564 | |
565 | === modified file 'openlp/plugins/presentations/lib/pptviewcontroller.py' |
566 | --- openlp/plugins/presentations/lib/pptviewcontroller.py 2017-10-10 07:08:44 +0000 |
567 | +++ openlp/plugins/presentations/lib/pptviewcontroller.py 2017-11-10 23:08:30 +0000 |
568 | @@ -70,7 +70,7 @@ |
569 | try: |
570 | self.start_process() |
571 | return self.process.CheckInstalled() |
572 | - except WindowsError: |
573 | + except OSError: |
574 | return False |
575 | |
576 | def start_process(self): |
577 | |
578 | === modified file 'openlp/plugins/songs/forms/editsongform.py' |
579 | --- openlp/plugins/songs/forms/editsongform.py 2017-10-23 22:09:57 +0000 |
580 | +++ openlp/plugins/songs/forms/editsongform.py 2017-11-10 23:08:30 +0000 |
581 | @@ -105,9 +105,9 @@ |
582 | self.topics_list_view.setSortingEnabled(False) |
583 | self.topics_list_view.setAlternatingRowColors(True) |
584 | self.audio_list_widget.setAlternatingRowColors(True) |
585 | - self.find_verse_split = re.compile('---\[\]---\n', re.UNICODE) |
586 | - self.whitespace = re.compile(r'\W+', re.UNICODE) |
587 | - self.find_tags = re.compile(u'\{/?\w+\}', re.UNICODE) |
588 | + self.find_verse_split = re.compile('---\[\]---\n') |
589 | + self.whitespace = re.compile(r'\W+') |
590 | + self.find_tags = re.compile(r'\{/?\w+\}') |
591 | |
592 | def _load_objects(self, cls, combo, cache): |
593 | """ |
594 | |
595 | === modified file 'openlp/plugins/songs/lib/__init__.py' |
596 | --- openlp/plugins/songs/lib/__init__.py 2017-10-10 02:29:56 +0000 |
597 | +++ openlp/plugins/songs/lib/__init__.py 2017-11-10 23:08:30 +0000 |
598 | @@ -24,7 +24,6 @@ |
599 | """ |
600 | |
601 | import logging |
602 | -import os |
603 | import re |
604 | |
605 | from PyQt5 import QtWidgets |
606 | @@ -39,8 +38,8 @@ |
607 | |
608 | log = logging.getLogger(__name__) |
609 | |
610 | -WHITESPACE = re.compile(r'[\W_]+', re.UNICODE) |
611 | -APOSTROPHE = re.compile('[\'`’ʻ′]', re.UNICODE) |
612 | +WHITESPACE = re.compile(r'[\W_]+') |
613 | +APOSTROPHE = re.compile(r'[\'`’ʻ′]') |
614 | # PATTERN will look for the next occurence of one of these symbols: |
615 | # \controlword - optionally preceded by \*, optionally followed by a number |
616 | # \'## - where ## is a pair of hex digits, representing a single character |
617 | |
618 | === modified file 'openlp/plugins/songs/lib/importers/easyslides.py' |
619 | --- openlp/plugins/songs/lib/importers/easyslides.py 2017-09-30 20:16:30 +0000 |
620 | +++ openlp/plugins/songs/lib/importers/easyslides.py 2017-11-10 23:08:30 +0000 |
621 | @@ -25,6 +25,7 @@ |
622 | |
623 | from lxml import etree, objectify |
624 | |
625 | +from openlp.core.common import normalize_str |
626 | from openlp.plugins.songs.lib import VerseType |
627 | from openlp.plugins.songs.lib.importers.songimport import SongImport |
628 | |
629 | @@ -225,7 +226,7 @@ |
630 | verses[reg].setdefault(vt, {}) |
631 | verses[reg][vt].setdefault(vn, {}) |
632 | verses[reg][vt][vn].setdefault(inst, []) |
633 | - verses[reg][vt][vn][inst].append(self.tidy_text(line)) |
634 | + verses[reg][vt][vn][inst].append(normalize_str(line)) |
635 | # done parsing |
636 | versetags = [] |
637 | # we use our_verse_order to ensure, we insert lyrics in the same order |
638 | |
639 | === modified file 'openlp/plugins/songs/lib/importers/mediashout.py' |
640 | --- openlp/plugins/songs/lib/importers/mediashout.py 2017-10-07 07:05:07 +0000 |
641 | +++ openlp/plugins/songs/lib/importers/mediashout.py 2017-11-10 23:08:30 +0000 |
642 | @@ -101,7 +101,7 @@ |
643 | self.song_book_name = song.SongID |
644 | for verse in verses: |
645 | tag = VERSE_TAGS[verse.Type] + str(verse.Number) if verse.Type < len(VERSE_TAGS) else 'O' |
646 | - self.add_verse(self.tidy_text(verse.Text), tag) |
647 | + self.add_verse(verse.Text, tag) |
648 | for order in verse_order: |
649 | if order.Type < len(VERSE_TAGS): |
650 | self.verse_order_list.append(VERSE_TAGS[order.Type] + str(order.Number)) |
651 | |
652 | === modified file 'openlp/plugins/songs/lib/importers/openoffice.py' |
653 | --- openlp/plugins/songs/lib/importers/openoffice.py 2017-10-10 02:29:56 +0000 |
654 | +++ openlp/plugins/songs/lib/importers/openoffice.py 2017-11-10 23:08:30 +0000 |
655 | @@ -24,7 +24,7 @@ |
656 | |
657 | from PyQt5 import QtCore |
658 | |
659 | -from openlp.core.common import is_win, get_uno_command, get_uno_instance |
660 | +from openlp.core.common import get_uno_command, get_uno_instance, is_win, normalize_str |
661 | from openlp.core.common.i18n import translate |
662 | from .songimport import SongImport |
663 | |
664 | @@ -241,7 +241,7 @@ |
665 | |
666 | :param text: The text. |
667 | """ |
668 | - song_texts = self.tidy_text(text).split('\f') |
669 | + song_texts = normalize_str(text).split('\f') |
670 | self.set_defaults() |
671 | for song_text in song_texts: |
672 | if song_text.strip(): |
673 | |
674 | === modified file 'openlp/plugins/songs/lib/importers/opensong.py' |
675 | --- openlp/plugins/songs/lib/importers/opensong.py 2017-10-10 02:29:56 +0000 |
676 | +++ openlp/plugins/songs/lib/importers/opensong.py 2017-11-10 23:08:30 +0000 |
677 | @@ -25,6 +25,7 @@ |
678 | from lxml import objectify |
679 | from lxml.etree import Error, LxmlError |
680 | |
681 | +from openlp.core.common import normalize_str |
682 | from openlp.core.common.i18n import translate |
683 | from openlp.core.common.settings import Settings |
684 | from openlp.plugins.songs.lib import VerseType |
685 | @@ -262,7 +263,7 @@ |
686 | post=this_line[offset + column:]) |
687 | offset += len(chord) + 2 |
688 | # Tidy text and remove the ____s from extended words |
689 | - this_line = self.tidy_text(this_line) |
690 | + this_line = normalize_str(this_line) |
691 | this_line = this_line.replace('_', '') |
692 | this_line = this_line.replace('||', '\n[---]\n') |
693 | this_line = this_line.strip() |
694 | |
695 | === modified file 'openlp/plugins/songs/lib/importers/songimport.py' |
696 | --- openlp/plugins/songs/lib/importers/songimport.py 2017-10-23 22:09:57 +0000 |
697 | +++ openlp/plugins/songs/lib/importers/songimport.py 2017-11-10 23:08:30 +0000 |
698 | @@ -25,6 +25,7 @@ |
699 | |
700 | from PyQt5 import QtCore |
701 | |
702 | +from openlp.core.common import normalize_str |
703 | from openlp.core.common.applocation import AppLocation |
704 | from openlp.core.common.i18n import translate |
705 | from openlp.core.common.path import copyfile, create_paths |
706 | @@ -130,26 +131,6 @@ |
707 | def register(self, import_wizard): |
708 | self.import_wizard = import_wizard |
709 | |
710 | - def tidy_text(self, text): |
711 | - """ |
712 | - Get rid of some dodgy unicode and formatting characters we're not interested in. Some can be converted to ascii. |
713 | - """ |
714 | - text = text.replace('\u2018', '\'') |
715 | - text = text.replace('\u2019', '\'') |
716 | - text = text.replace('\u201c', '"') |
717 | - text = text.replace('\u201d', '"') |
718 | - text = text.replace('\u2026', '...') |
719 | - text = text.replace('\u2013', '-') |
720 | - text = text.replace('\u2014', '-') |
721 | - # Replace vertical tab with 2 linebreaks |
722 | - text = text.replace('\v', '\n\n') |
723 | - # Replace form feed (page break) with 2 linebreaks |
724 | - text = text.replace('\f', '\n\n') |
725 | - # Remove surplus blank lines, spaces, trailing/leading spaces |
726 | - text = re.sub(r'[ \t]+', ' ', text) |
727 | - text = re.sub(r' ?(\r\n?|\n) ?', '\n', text) |
728 | - return text |
729 | - |
730 | def process_song_text(self, text): |
731 | """ |
732 | Process the song text from import |
733 | @@ -368,7 +349,7 @@ |
734 | verse_tag = VerseType.tags[VerseType.Other] |
735 | log.info('Versetype {old} changing to {new}'.format(old=verse_def, new=new_verse_def)) |
736 | verse_def = new_verse_def |
737 | - sxml.add_verse_to_lyrics(verse_tag, verse_def[1:], verse_text, lang) |
738 | + sxml.add_verse_to_lyrics(verse_tag, verse_def[1:], normalize_str(verse_text), lang) |
739 | song.lyrics = str(sxml.extract_xml(), 'utf-8') |
740 | if not self.verse_order_list and self.verse_order_list_generated_useful: |
741 | self.verse_order_list = self.verse_order_list_generated |
742 | |
743 | === modified file 'openlp/plugins/songs/lib/importers/songsoffellowship.py' |
744 | --- openlp/plugins/songs/lib/importers/songsoffellowship.py 2016-12-31 11:01:36 +0000 |
745 | +++ openlp/plugins/songs/lib/importers/songsoffellowship.py 2017-11-10 23:08:30 +0000 |
746 | @@ -194,7 +194,6 @@ |
747 | :param text_portion: A Piece of text |
748 | """ |
749 | text = text_portion.getString() |
750 | - text = self.tidy_text(text) |
751 | if text.strip() == '': |
752 | return text |
753 | if text_portion.CharWeight == BOLD: |
754 | |
755 | === modified file 'openlp/plugins/songs/lib/importers/zionworx.py' |
756 | --- openlp/plugins/songs/lib/importers/zionworx.py 2017-10-10 02:29:56 +0000 |
757 | +++ openlp/plugins/songs/lib/importers/zionworx.py 2017-11-10 23:08:30 +0000 |
758 | @@ -30,9 +30,6 @@ |
759 | |
760 | log = logging.getLogger(__name__) |
761 | |
762 | -# Used to strip control chars (except 10=LF, 13=CR) |
763 | -CONTROL_CHARS_MAP = dict.fromkeys(list(range(10)) + [11, 12] + list(range(14, 32)) + [127]) |
764 | - |
765 | |
766 | class ZionWorxImport(SongImport): |
767 | """ |
768 | @@ -95,12 +92,12 @@ |
769 | return |
770 | self.set_defaults() |
771 | try: |
772 | - self.title = self._decode(record['Title1']) |
773 | + self.title = record['Title1'] |
774 | if record['Title2']: |
775 | - self.alternate_title = self._decode(record['Title2']) |
776 | - self.parse_author(self._decode(record['Writer'])) |
777 | - self.add_copyright(self._decode(record['Copyright'])) |
778 | - lyrics = self._decode(record['Lyrics']) |
779 | + self.alternate_title = record['Title2'] |
780 | + self.parse_author(record['Writer']) |
781 | + self.add_copyright(record['Copyright']) |
782 | + lyrics = record['Lyrics'] |
783 | except UnicodeDecodeError as e: |
784 | self.log_error(translate('SongsPlugin.ZionWorxImport', 'Record {index}').format(index=index), |
785 | translate('SongsPlugin.ZionWorxImport', 'Decoding error: {error}').format(error=e)) |
786 | @@ -122,10 +119,3 @@ |
787 | if not self.finish(): |
788 | self.log_error(translate('SongsPlugin.ZionWorxImport', 'Record %d') % index + |
789 | (': "' + title + '"' if title else '')) |
790 | - |
791 | - def _decode(self, str): |
792 | - """ |
793 | - Strips all control characters (except new lines). |
794 | - """ |
795 | - # ZionWorx has no option for setting the encoding for its songs, so we assume encoding is always the same. |
796 | - return str.translate(CONTROL_CHARS_MAP) |
797 | |
798 | === modified file 'openlp/plugins/songs/lib/openlyricsxml.py' |
799 | --- openlp/plugins/songs/lib/openlyricsxml.py 2017-10-10 02:29:56 +0000 |
800 | +++ openlp/plugins/songs/lib/openlyricsxml.py 2017-11-10 23:08:30 +0000 |
801 | @@ -281,7 +281,7 @@ |
802 | # Process the formatting tags. |
803 | # Have we any tags in song lyrics? |
804 | tags_element = None |
805 | - match = re.search('\{/?\w+\}', song.lyrics, re.UNICODE) |
806 | + match = re.search(r'\{/?\w+\}', song.lyrics) |
807 | if match: |
808 | # Named 'format_' - 'format' is built-in function in Python. |
809 | format_ = etree.SubElement(song_xml, 'format') |
810 | |
811 | === modified file 'openlp/plugins/songusage/forms/songusagedetailform.py' |
812 | --- openlp/plugins/songusage/forms/songusagedetailform.py 2017-10-23 22:09:57 +0000 |
813 | +++ openlp/plugins/songusage/forms/songusagedetailform.py 2017-11-10 23:08:30 +0000 |
814 | @@ -54,8 +54,14 @@ |
815 | """ |
816 | We need to set up the screen |
817 | """ |
818 | - self.from_date_calendar.setSelectedDate(Settings().value(self.plugin.settings_section + '/from date')) |
819 | - self.to_date_calendar.setSelectedDate(Settings().value(self.plugin.settings_section + '/to date')) |
820 | + to_date = Settings().value(self.plugin.settings_section + '/to date') |
821 | + if not (isinstance(to_date, QtCore.QDate) and to_date.isValid()): |
822 | + to_date = QtCore.QDate.currentDate() |
823 | + from_date = Settings().value(self.plugin.settings_section + '/from date') |
824 | + if not (isinstance(from_date, QtCore.QDate) and from_date.isValid()): |
825 | + from_date = to_date.addYears(-1) |
826 | + self.from_date_calendar.setSelectedDate(from_date) |
827 | + self.to_date_calendar.setSelectedDate(to_date) |
828 | self.report_path_edit.path = Settings().value(self.plugin.settings_section + '/last directory export') |
829 | |
830 | def on_report_path_edit_path_changed(self, file_path): |
831 | |
832 | === modified file 'openlp/plugins/songusage/songusageplugin.py' |
833 | --- openlp/plugins/songusage/songusageplugin.py 2017-10-07 07:05:07 +0000 |
834 | +++ openlp/plugins/songusage/songusageplugin.py 2017-11-10 23:08:30 +0000 |
835 | @@ -38,20 +38,17 @@ |
836 | |
837 | log = logging.getLogger(__name__) |
838 | |
839 | -YEAR = QtCore.QDate().currentDate().year() |
840 | -if QtCore.QDate().currentDate().month() < 9: |
841 | - YEAR -= 1 |
842 | - |
843 | +TODAY = QtCore.QDate.currentDate() |
844 | |
845 | __default_settings__ = { |
846 | 'songusage/db type': 'sqlite', |
847 | 'songusage/db username': '', |
848 | - 'songuasge/db password': '', |
849 | - 'songuasge/db hostname': '', |
850 | - 'songuasge/db database': '', |
851 | + 'songusage/db password': '', |
852 | + 'songusage/db hostname': '', |
853 | + 'songusage/db database': '', |
854 | 'songusage/active': False, |
855 | - 'songusage/to date': QtCore.QDate(YEAR, 8, 31), |
856 | - 'songusage/from date': QtCore.QDate(YEAR - 1, 9, 1), |
857 | + 'songusage/to date': TODAY, |
858 | + 'songusage/from date': TODAY.addYears(-1), |
859 | 'songusage/last directory export': None |
860 | } |
861 | |
862 | |
863 | === modified file 'tests/functional/openlp_core/common/test_actions.py' |
864 | --- tests/functional/openlp_core/common/test_actions.py 2017-10-07 07:05:07 +0000 |
865 | +++ tests/functional/openlp_core/common/test_actions.py 2017-11-10 23:08:30 +0000 |
866 | @@ -153,6 +153,7 @@ |
867 | """ |
868 | Prepare the tests |
869 | """ |
870 | + self.setup_application() |
871 | self.action_list = ActionList.get_instance() |
872 | self.build_settings() |
873 | self.settings = Settings() |
874 | |
875 | === modified file 'tests/functional/openlp_core/common/test_httputils.py' |
876 | --- tests/functional/openlp_core/common/test_httputils.py 2017-09-25 20:34:05 +0000 |
877 | +++ tests/functional/openlp_core/common/test_httputils.py 2017-11-10 23:08:30 +0000 |
878 | @@ -233,7 +233,7 @@ |
879 | Test socket timeout gets caught |
880 | """ |
881 | # GIVEN: Mocked urlopen to fake a network disconnect in the middle of a download |
882 | - mocked_requests.get.side_effect = IOError |
883 | + mocked_requests.get.side_effect = OSError |
884 | |
885 | # WHEN: Attempt to retrieve a file |
886 | url_get_file(MagicMock(), url='http://localhost/test', file_path=Path(self.tempfile)) |
887 | |
888 | === modified file 'tests/functional/openlp_core/common/test_i18n.py' |
889 | --- tests/functional/openlp_core/common/test_i18n.py 2017-10-07 07:05:07 +0000 |
890 | +++ tests/functional/openlp_core/common/test_i18n.py 2017-11-10 23:08:30 +0000 |
891 | @@ -155,7 +155,7 @@ |
892 | assert first_instance is second_instance, 'Two UiStrings objects should be the same instance' |
893 | |
894 | |
895 | -def test_translate(self): |
896 | +def test_translate(): |
897 | """ |
898 | Test the translate() function |
899 | """ |
900 | |
901 | === modified file 'tests/functional/openlp_core/common/test_path.py' |
902 | --- tests/functional/openlp_core/common/test_path.py 2017-10-07 07:05:07 +0000 |
903 | +++ tests/functional/openlp_core/common/test_path.py 2017-11-10 23:08:30 +0000 |
904 | @@ -371,13 +371,13 @@ |
905 | @patch('openlp.core.common.path.log') |
906 | def test_create_paths_dir_io_error(self, mocked_logger): |
907 | """ |
908 | - Test the create_paths() when an IOError is raised |
909 | + Test the create_paths() when an OSError is raised |
910 | """ |
911 | # GIVEN: A `Path` to check with patched out mkdir and exists methods |
912 | mocked_path = MagicMock() |
913 | - mocked_path.exists.side_effect = IOError('Cannot make directory') |
914 | + mocked_path.exists.side_effect = OSError('Cannot make directory') |
915 | |
916 | - # WHEN: An IOError is raised when checking the if the path exists. |
917 | + # WHEN: An OSError is raised when checking the if the path exists. |
918 | create_paths(mocked_path) |
919 | |
920 | # THEN: The Error should have been logged |
921 | @@ -385,7 +385,7 @@ |
922 | |
923 | def test_create_paths_dir_value_error(self): |
924 | """ |
925 | - Test the create_paths() when an error other than IOError is raised |
926 | + Test the create_paths() when an error other than OSError is raised |
927 | """ |
928 | # GIVEN: A `Path` to check with patched out mkdir and exists methods |
929 | mocked_path = MagicMock() |
930 | |
931 | === modified file 'tests/functional/openlp_core/lib/test_lib.py' |
932 | --- tests/functional/openlp_core/lib/test_lib.py 2017-10-10 07:08:44 +0000 |
933 | +++ tests/functional/openlp_core/lib/test_lib.py 2017-11-10 23:08:30 +0000 |
934 | @@ -168,7 +168,7 @@ |
935 | patch.object(Path, 'open'): |
936 | file_path = Path('testfile.txt') |
937 | file_path.is_file.return_value = True |
938 | - file_path.open.side_effect = IOError() |
939 | + file_path.open.side_effect = OSError() |
940 | |
941 | # WHEN: get_text_file_string is called |
942 | result = get_text_file_string(file_path) |
943 | |
944 | === modified file 'tests/functional/openlp_core/ui/test_first_time.py' |
945 | --- tests/functional/openlp_core/ui/test_first_time.py 2017-09-20 16:55:21 +0000 |
946 | +++ tests/functional/openlp_core/ui/test_first_time.py 2017-11-10 23:08:30 +0000 |
947 | @@ -40,7 +40,7 @@ |
948 | Test get_web_page will attempt CONNECTION_RETRIES+1 connections - bug 1409031 |
949 | """ |
950 | # GIVEN: Initial settings and mocks |
951 | - mocked_requests.get.side_effect = IOError('Unable to connect') |
952 | + mocked_requests.get.side_effect = OSError('Unable to connect') |
953 | |
954 | # WHEN: A webpage is requested |
955 | try: |
956 | |
957 | === modified file 'tests/functional/openlp_core/widgets/test_views.py' |
958 | --- tests/functional/openlp_core/widgets/test_views.py 2017-10-23 22:09:57 +0000 |
959 | +++ tests/functional/openlp_core/widgets/test_views.py 2017-11-10 23:08:30 +0000 |
960 | @@ -627,4 +627,3 @@ |
961 | assert widget.allow_internal_dnd is False |
962 | assert widget.indentation() == 0 |
963 | assert widget.isAnimated() is True |
964 | - |
965 | |
966 | === modified file 'tests/functional/openlp_plugins/presentations/test_presentationcontroller.py' |
967 | --- tests/functional/openlp_plugins/presentations/test_presentationcontroller.py 2017-10-07 07:05:07 +0000 |
968 | +++ tests/functional/openlp_plugins/presentations/test_presentationcontroller.py 2017-11-10 23:08:30 +0000 |
969 | @@ -144,7 +144,7 @@ |
970 | # GIVEN: A mocked open, get_thumbnail_folder and exists |
971 | with patch('openlp.plugins.presentations.lib.presentationcontroller.Path.read_text') as mocked_read_text, \ |
972 | patch(FOLDER_TO_PATCH) as mocked_get_thumbnail_folder: |
973 | - mocked_read_text.side_effect = IOError() |
974 | + mocked_read_text.side_effect = OSError() |
975 | mocked_get_thumbnail_folder.return_value = Path('test') |
976 | |
977 | # WHEN: calling get_titles_and_notes |
978 | |
979 | === modified file 'tests/interfaces/openlp_core/ui/test_projectormanager.py' |
980 | --- tests/interfaces/openlp_core/ui/test_projectormanager.py 2017-10-07 07:05:07 +0000 |
981 | +++ tests/interfaces/openlp_core/ui/test_projectormanager.py 2017-11-10 23:08:30 +0000 |
982 | @@ -42,8 +42,8 @@ |
983 | """ |
984 | Create the UI and setup necessary options |
985 | """ |
986 | + self.setup_application() |
987 | self.build_settings() |
988 | - self.setup_application() |
989 | Registry.create() |
990 | with patch('openlp.core.lib.projector.db.init_url') as mocked_init_url: |
991 | if os.path.exists(TEST_DB): |
992 | |
993 | === modified file 'tests/interfaces/openlp_core/ui/test_projectorsourceform.py' |
994 | --- tests/interfaces/openlp_core/ui/test_projectorsourceform.py 2017-10-07 07:05:07 +0000 |
995 | +++ tests/interfaces/openlp_core/ui/test_projectorsourceform.py 2017-11-10 23:08:30 +0000 |
996 | @@ -64,8 +64,8 @@ |
997 | Set up anything necessary for all tests |
998 | """ |
999 | mocked_init_url.return_value = 'sqlite:///{}'.format(TEST_DB) |
1000 | + self.setup_application() |
1001 | self.build_settings() |
1002 | - self.setup_application() |
1003 | Registry.create() |
1004 | # Do not try to recreate if we've already been created from a previous test |
1005 | if not hasattr(self, 'projectordb'): |
1006 | |
1007 | === modified file 'tests/interfaces/openlp_core/ui/test_thememanager.py' |
1008 | --- tests/interfaces/openlp_core/ui/test_thememanager.py 2017-10-10 01:08:09 +0000 |
1009 | +++ tests/interfaces/openlp_core/ui/test_thememanager.py 2017-11-10 23:08:30 +0000 |
1010 | @@ -41,8 +41,8 @@ |
1011 | """ |
1012 | Create the UI |
1013 | """ |
1014 | + self.setup_application() |
1015 | self.build_settings() |
1016 | - self.setup_application() |
1017 | Registry.create() |
1018 | self.theme_manager = ThemeManager() |
1019 | |
1020 | |
1021 | === modified file 'tests/utils/__init__.py' |
1022 | --- tests/utils/__init__.py 2016-12-31 11:01:36 +0000 |
1023 | +++ tests/utils/__init__.py 2017-11-10 23:08:30 +0000 |
1024 | @@ -36,7 +36,7 @@ |
1025 | try: |
1026 | items = json.load(open_file) |
1027 | first_line = items[row] |
1028 | - except IOError: |
1029 | + except OSError: |
1030 | first_line = '' |
1031 | finally: |
1032 | open_file.close() |
1033 | |
1034 | === modified file 'tests/utils/test_pylint.py' |
1035 | --- tests/utils/test_pylint.py 2016-12-31 11:01:36 +0000 |
1036 | +++ tests/utils/test_pylint.py 2017-11-10 23:08:30 +0000 |
1037 | @@ -58,17 +58,21 @@ |
1038 | # GIVEN: Some checks to disable and enable, and the pylint script |
1039 | disabled_checks = 'import-error,no-member' |
1040 | enabled_checks = 'missing-format-argument-key,unused-format-string-argument,bad-format-string' |
1041 | - if is_win() or 'arch' in platform.dist()[0].lower(): |
1042 | - pylint_script = 'pylint' |
1043 | - else: |
1044 | - pylint_script = 'pylint3' |
1045 | + pylint_kwargs = { |
1046 | + 'return_std': True |
1047 | + } |
1048 | + if version < '1.7.0': |
1049 | + if is_win() or 'arch' in platform.dist()[0].lower(): |
1050 | + pylint_kwargs.update({'script': 'pylint'}) |
1051 | + else: |
1052 | + pylint_kwargs.update({'script': 'pylint3'}) |
1053 | |
1054 | # WHEN: Running pylint |
1055 | (pylint_stdout, pylint_stderr) = \ |
1056 | lint.py_run('openlp --errors-only --disable={disabled} --enable={enabled} ' |
1057 | '--reports=no --output-format=parseable'.format(disabled=disabled_checks, |
1058 | enabled=enabled_checks), |
1059 | - return_std=True, script=pylint_script) |
1060 | + **pylint_kwargs) |
1061 | stdout = pylint_stdout.read() |
1062 | stderr = pylint_stderr.read() |
1063 | filtered_stdout = self._filter_tolerated_errors(stdout) |
Looks good.