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