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 | 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 23:08:30 +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 23:08:30 +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 23:08:30 +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 23:08:30 +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 23:08:30 +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 23:08:30 +0000 | |||
148 | @@ -255,7 +255,10 @@ | |||
149 | 255 | ('core/logo file', 'core/logo file', [(str_to_path, None)]), | 255 | ('core/logo file', 'core/logo file', [(str_to_path, None)]), |
150 | 256 | ('presentations/last directory', 'presentations/last directory', [(str_to_path, None)]), | 256 | ('presentations/last directory', 'presentations/last directory', [(str_to_path, None)]), |
151 | 257 | ('images/last directory', 'images/last directory', [(str_to_path, None)]), | 257 | ('images/last directory', 'images/last directory', [(str_to_path, None)]), |
153 | 258 | ('media/last directory', 'media/last directory', [(str_to_path, None)]) | 258 | ('media/last directory', 'media/last directory', [(str_to_path, None)]), |
154 | 259 | ('songuasge/db password', 'songusage/db password', []), | ||
155 | 260 | ('songuasge/db hostname', 'songusage/db hostname', []), | ||
156 | 261 | ('songuasge/db database', 'songusage/db database', []) | ||
157 | 259 | ] | 262 | ] |
158 | 260 | 263 | ||
159 | 261 | @staticmethod | 264 | @staticmethod |
160 | 262 | 265 | ||
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 | 104 | # no BOM was found | 104 | # no BOM was found |
166 | 105 | file_handle.seek(0) | 105 | file_handle.seek(0) |
167 | 106 | content = file_handle.read() | 106 | content = file_handle.read() |
169 | 107 | except (IOError, UnicodeError): | 107 | except (OSError, UnicodeError): |
170 | 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)) |
171 | 109 | return content | 109 | return content |
172 | 110 | 110 | ||
173 | 111 | 111 | ||
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 | 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. |
179 | 93 | """ | 93 | """ |
180 | 94 | self.hide() | 94 | self.hide() |
182 | 95 | self.whitespace = re.compile(r'[\W_]+', re.UNICODE) | 95 | self.whitespace = re.compile(r'[\W_]+') |
183 | 96 | visible_title = self.plugin.get_string(StringContent.VisibleName) | 96 | visible_title = self.plugin.get_string(StringContent.VisibleName) |
184 | 97 | self.title = str(visible_title['title']) | 97 | self.title = str(visible_title['title']) |
185 | 98 | Registry().register(self.plugin.name, self) | 98 | Registry().register(self.plugin.name, self) |
186 | @@ -344,7 +344,9 @@ | |||
187 | 344 | else: | 344 | else: |
188 | 345 | new_files.append(file_name) | 345 | new_files.append(file_name) |
189 | 346 | if new_files: | 346 | if new_files: |
191 | 347 | self.validate_and_load(new_files, data['target']) | 347 | if 'target' in data: |
192 | 348 | self.validate_and_load(new_files, data['target']) | ||
193 | 349 | self.validate_and_load(new_files) | ||
194 | 348 | 350 | ||
195 | 349 | def dnd_move_internal(self, target): | 351 | def dnd_move_internal(self, target): |
196 | 350 | """ | 352 | """ |
197 | 351 | 353 | ||
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 | 155 | try: | 155 | try: |
203 | 156 | with file_path.open('w') as report_file: | 156 | with file_path.open('w') as report_file: |
204 | 157 | report_file.write(report_text) | 157 | report_file.write(report_text) |
206 | 158 | except IOError: | 158 | except OSError: |
207 | 159 | log.exception('Failed to write crash report') | 159 | log.exception('Failed to write crash report') |
208 | 160 | 160 | ||
209 | 161 | def on_send_report_button_clicked(self): | 161 | def on_send_report_button_clicked(self): |
210 | 162 | 162 | ||
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 | 43 | r'(?P<tag>[^\s/!\?>]+)(?:\s+[^\s=]+="[^"]*")*\s*(?P<empty>/)?' | 43 | r'(?P<tag>[^\s/!\?>]+)(?:\s+[^\s=]+="[^"]*")*\s*(?P<empty>/)?' |
216 | 44 | r'|(?P<cdata>!\[CDATA\[(?:(?!\]\]>).)*\]\])' | 44 | r'|(?P<cdata>!\[CDATA\[(?:(?!\]\]>).)*\]\])' |
217 | 45 | r'|(?P<procinst>\?(?:(?!\?>).)*\?)' | 45 | r'|(?P<procinst>\?(?:(?!\?>).)*\?)' |
219 | 46 | r'|(?P<comment>!--(?:(?!-->).)*--))>', re.UNICODE) | 46 | r'|(?P<comment>!--(?:(?!-->).)*--))>') |
220 | 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) |
221 | 48 | 48 | ||
222 | 49 | def pre_save(self): | 49 | def pre_save(self): |
223 | 50 | 50 | ||
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 | 180 | triggers=self.service_manager_contents.on_load_service_clicked) | 180 | triggers=self.service_manager_contents.on_load_service_clicked) |
230 | 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', |
231 | 182 | can_shortcuts=True, category=UiStrings().File, | 182 | can_shortcuts=True, category=UiStrings().File, |
233 | 183 | triggers=self.service_manager_contents.save_file) | 183 | triggers=self.service_manager_contents.decide_save_method) |
234 | 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, |
235 | 185 | category=UiStrings().File, | 185 | category=UiStrings().File, |
236 | 186 | triggers=self.service_manager_contents.save_file_as) | 186 | triggers=self.service_manager_contents.save_file_as) |
237 | @@ -1367,7 +1367,7 @@ | |||
238 | 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)) |
239 | 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)) |
240 | 1369 | log.info('Copy successful') | 1369 | log.info('Copy successful') |
242 | 1370 | except (IOError, os.error, DistutilsFileError) as why: | 1370 | except (OSError, DistutilsFileError) as why: |
243 | 1371 | self.application.set_normal_cursor() | 1371 | self.application.set_normal_cursor() |
244 | 1372 | log.exception('Data copy failed {err}'.format(err=str(why))) | 1372 | log.exception('Data copy failed {err}'.format(err=str(why))) |
245 | 1373 | err_text = translate('OpenLP.MainWindow', | 1373 | err_text = translate('OpenLP.MainWindow', |
246 | 1374 | 1374 | ||
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 | 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', |
252 | 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.'), |
253 | 195 | can_shortcuts=True, category=UiStrings().Service, triggers=self.on_service_end) | 195 | can_shortcuts=True, category=UiStrings().Service, triggers=self.on_service_end) |
254 | 196 | self.down_action = self.order_toolbar.add_toolbar_action( | ||
255 | 197 | 'down', | ||
256 | 198 | text=translate('OpenLP.ServiceManager', 'Move &down'), can_shortcuts=True, | ||
257 | 199 | tooltip=translate('OpenLP.ServiceManager', 'Moves the selection down the window.'), visible=False, | ||
258 | 200 | triggers=self.on_move_selection_down) | ||
259 | 201 | action_list.add_action(self.down_action) | ||
260 | 202 | self.up_action = self.order_toolbar.add_toolbar_action( | ||
261 | 203 | 'up', | ||
262 | 204 | text=translate('OpenLP.ServiceManager', 'Move up'), can_shortcuts=True, | ||
263 | 205 | tooltip=translate('OpenLP.ServiceManager', 'Moves the selection up the window.'), visible=False, | ||
264 | 206 | triggers=self.on_move_selection_up) | ||
265 | 207 | action_list.add_action(self.up_action) | ||
266 | 208 | self.order_toolbar.addSeparator() | 196 | self.order_toolbar.addSeparator() |
267 | 209 | self.delete_action = self.order_toolbar.add_toolbar_action( | 197 | self.delete_action = self.order_toolbar.add_toolbar_action( |
268 | 210 | 'delete', can_shortcuts=True, | 198 | 'delete', can_shortcuts=True, |
269 | @@ -300,8 +288,8 @@ | |||
270 | 300 | self.theme_menu = QtWidgets.QMenu(translate('OpenLP.ServiceManager', '&Change Item Theme')) | 288 | self.theme_menu = QtWidgets.QMenu(translate('OpenLP.ServiceManager', '&Change Item Theme')) |
271 | 301 | self.menu.addMenu(self.theme_menu) | 289 | self.menu.addMenu(self.theme_menu) |
272 | 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, |
275 | 303 | self.move_top_action, self.move_bottom_action, self.up_action, | 291 | self.move_top_action, self.move_bottom_action, self.expand_action, |
276 | 304 | self.down_action, self.expand_action, self.collapse_action]) | 292 | self.collapse_action]) |
277 | 305 | Registry().register_function('theme_update_list', self.update_theme_list) | 293 | Registry().register_function('theme_update_list', self.update_theme_list) |
278 | 306 | Registry().register_function('config_screen_changed', self.regenerate_service_items) | 294 | Registry().register_function('config_screen_changed', self.regenerate_service_items) |
279 | 307 | Registry().register_function('theme_update_global', self.theme_change) | 295 | Registry().register_function('theme_update_global', self.theme_change) |
280 | @@ -474,6 +462,12 @@ | |||
281 | 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. |
282 | 475 | :param field: | 463 | :param field: |
283 | 476 | """ | 464 | """ |
284 | 465 | if self.is_modified(): | ||
285 | 466 | result = self.save_modified_service() | ||
286 | 467 | if result == QtWidgets.QMessageBox.Cancel: | ||
287 | 468 | return False | ||
288 | 469 | elif result == QtWidgets.QMessageBox.Save: | ||
289 | 470 | self.decide_save_method() | ||
290 | 477 | sender = self.sender() | 471 | sender = self.sender() |
291 | 478 | self.load_file(sender.data()) | 472 | self.load_file(sender.data()) |
292 | 479 | 473 | ||
293 | @@ -603,7 +597,7 @@ | |||
294 | 603 | if not os.path.exists(save_file): | 597 | if not os.path.exists(save_file): |
295 | 604 | shutil.copy(audio_from, save_file) | 598 | shutil.copy(audio_from, save_file) |
296 | 605 | zip_file.write(audio_from, audio_to) | 599 | zip_file.write(audio_from, audio_to) |
298 | 606 | except IOError: | 600 | except OSError: |
299 | 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)) |
300 | 608 | self.main_window.error_message(translate('OpenLP.ServiceManager', 'Error Saving File'), | 602 | self.main_window.error_message(translate('OpenLP.ServiceManager', 'Error Saving File'), |
301 | 609 | translate('OpenLP.ServiceManager', 'There was an error saving your file.')) | 603 | translate('OpenLP.ServiceManager', 'There was an error saving your file.')) |
302 | @@ -664,7 +658,7 @@ | |||
303 | 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) |
304 | 665 | # First we add service contents. | 659 | # First we add service contents. |
305 | 666 | zip_file.writestr(service_file_name, service_content) | 660 | zip_file.writestr(service_file_name, service_content) |
307 | 667 | except IOError: | 661 | except OSError: |
308 | 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)) |
309 | 669 | self.main_window.error_message(translate('OpenLP.ServiceManager', 'Error Saving File'), | 663 | self.main_window.error_message(translate('OpenLP.ServiceManager', 'Error Saving File'), |
310 | 670 | translate('OpenLP.ServiceManager', 'There was an error saving your file.')) | 664 | translate('OpenLP.ServiceManager', 'There was an error saving your file.')) |
311 | @@ -712,18 +706,23 @@ | |||
312 | 712 | default_file_path = directory_path / default_file_path | 706 | default_file_path = directory_path / default_file_path |
313 | 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 |
314 | 714 | # the long term. | 708 | # the long term. |
315 | 709 | lite_filter = translate('OpenLP.ServiceManager', 'OpenLP Service Files - lite (*.oszl)') | ||
316 | 710 | packaged_filter = translate('OpenLP.ServiceManager', 'OpenLP Service Files (*.osz)') | ||
317 | 711 | |||
318 | 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: |
319 | 716 | file_path, filter_used = FileDialog.getSaveFileName( | 713 | file_path, filter_used = FileDialog.getSaveFileName( |
320 | 717 | self.main_window, UiStrings().SaveService, default_file_path, | 714 | self.main_window, UiStrings().SaveService, default_file_path, |
323 | 718 | translate('OpenLP.ServiceManager', | 715 | '{packaged};; {lite}'.format(packaged=packaged_filter, lite=lite_filter)) |
322 | 719 | 'OpenLP Service Files (*.osz);; OpenLP Service Files - lite (*.oszl)')) | ||
324 | 720 | else: | 716 | else: |
325 | 721 | file_path, filter_used = FileDialog.getSaveFileName( | 717 | file_path, filter_used = FileDialog.getSaveFileName( |
328 | 722 | self.main_window, UiStrings().SaveService, file_path, | 718 | self.main_window, UiStrings().SaveService, default_file_path, |
329 | 723 | translate('OpenLP.ServiceManager', 'OpenLP Service Files (*.osz);;')) | 719 | '{packaged};;'.format(packaged=packaged_filter)) |
330 | 724 | if not file_path: | 720 | if not file_path: |
331 | 725 | return False | 721 | return False |
333 | 726 | file_path.with_suffix('.osz') | 722 | if filter_used == lite_filter: |
334 | 723 | file_path = file_path.with_suffix('.oszl') | ||
335 | 724 | else: | ||
336 | 725 | file_path = file_path.with_suffix('.osz') | ||
337 | 727 | self.set_file_name(file_path) | 726 | self.set_file_name(file_path) |
338 | 728 | self.decide_save_method() | 727 | self.decide_save_method() |
339 | 729 | 728 | ||
340 | @@ -791,11 +790,11 @@ | |||
341 | 791 | else: | 790 | else: |
342 | 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.')) |
343 | 793 | self.log_error('File contains no service data') | 792 | self.log_error('File contains no service data') |
345 | 794 | except (IOError, NameError): | 793 | except (OSError, NameError): |
346 | 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)) |
347 | 796 | critical_error_message_box(message=translate('OpenLP.ServiceManager', | 795 | critical_error_message_box(message=translate('OpenLP.ServiceManager', |
348 | 797 | 'File could not be opened because it is corrupt.')) | 796 | 'File could not be opened because it is corrupt.')) |
350 | 798 | except zipfile.BadZipfile: | 797 | except zipfile.BadZipFile: |
351 | 799 | if os.path.getsize(file_name) == 0: | 798 | if os.path.getsize(file_name) == 0: |
352 | 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)) |
353 | 801 | QtWidgets.QMessageBox.information(self, translate('OpenLP.ServiceManager', 'Empty File'), | 800 | QtWidgets.QMessageBox.information(self, translate('OpenLP.ServiceManager', 'Empty File'), |
354 | @@ -1657,14 +1656,15 @@ | |||
355 | 1657 | if start_pos == -1: | 1656 | if start_pos == -1: |
356 | 1658 | return | 1657 | return |
357 | 1659 | if item is None: | 1658 | if item is None: |
359 | 1660 | end_pos = len(self.service_items) | 1659 | end_pos = len(self.service_items) - 1 |
360 | 1661 | else: | 1660 | else: |
361 | 1662 | end_pos = get_parent_item_data(item) - 1 | 1661 | end_pos = get_parent_item_data(item) - 1 |
362 | 1663 | service_item = self.service_items[start_pos] | 1662 | service_item = self.service_items[start_pos] |
367 | 1664 | self.service_items.remove(service_item) | 1663 | if start_pos != end_pos: |
368 | 1665 | self.service_items.insert(end_pos, service_item) | 1664 | self.service_items.remove(service_item) |
369 | 1666 | self.repaint_service_list(end_pos, child) | 1665 | self.service_items.insert(end_pos, service_item) |
370 | 1667 | self.set_modified() | 1666 | self.repaint_service_list(end_pos, child) |
371 | 1667 | self.set_modified() | ||
372 | 1668 | else: | 1668 | else: |
373 | 1669 | # we are not over anything so drop | 1669 | # we are not over anything so drop |
374 | 1670 | replace = False | 1670 | replace = False |
375 | 1671 | 1671 | ||
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 | 604 | else: | 604 | else: |
381 | 605 | with full_name.open('wb') as out_file: | 605 | with full_name.open('wb') as out_file: |
382 | 606 | out_file.write(theme_zip.read(zipped_file)) | 606 | out_file.write(theme_zip.read(zipped_file)) |
384 | 607 | except (IOError, zipfile.BadZipfile): | 607 | except (OSError, zipfile.BadZipFile): |
385 | 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)) |
386 | 609 | raise ValidationError | 609 | raise ValidationError |
387 | 610 | except ValidationError: | 610 | except ValidationError: |
388 | @@ -667,7 +667,7 @@ | |||
389 | 667 | theme_path = theme_dir / '{file_name}.json'.format(file_name=name) | 667 | theme_path = theme_dir / '{file_name}.json'.format(file_name=name) |
390 | 668 | try: | 668 | try: |
391 | 669 | theme_path.write_text(theme_pretty) | 669 | theme_path.write_text(theme_pretty) |
393 | 670 | except IOError: | 670 | except OSError: |
394 | 671 | self.log_exception('Saving theme to file failed') | 671 | self.log_exception('Saving theme to file failed') |
395 | 672 | if image_source_path and image_destination_path: | 672 | if image_source_path and image_destination_path: |
396 | 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: |
397 | @@ -675,7 +675,7 @@ | |||
398 | 675 | if image_source_path != image_destination_path: | 675 | if image_source_path != image_destination_path: |
399 | 676 | try: | 676 | try: |
400 | 677 | copyfile(image_source_path, image_destination_path) | 677 | copyfile(image_source_path, image_destination_path) |
402 | 678 | except IOError: | 678 | except OSError: |
403 | 679 | self.log_exception('Failed to save theme image') | 679 | self.log_exception('Failed to save theme image') |
404 | 680 | self.generate_and_save_image(name, theme) | 680 | self.generate_and_save_image(name, theme) |
405 | 681 | 681 | ||
406 | 682 | 682 | ||
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 | 96 | remote_version = response.text | 96 | remote_version = response.text |
412 | 97 | log.debug('New version found: %s', remote_version) | 97 | log.debug('New version found: %s', remote_version) |
413 | 98 | break | 98 | break |
415 | 99 | except IOError: | 99 | except OSError: |
416 | 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') |
417 | 101 | retries += 1 | 101 | retries += 1 |
418 | 102 | else: | 102 | else: |
419 | @@ -182,7 +182,7 @@ | |||
420 | 182 | try: | 182 | try: |
421 | 183 | version_file = open(file_path, 'r') | 183 | version_file = open(file_path, 'r') |
422 | 184 | full_version = str(version_file.read()).rstrip() | 184 | full_version = str(version_file.read()).rstrip() |
424 | 185 | except IOError: | 185 | except OSError: |
425 | 186 | log.exception('Error in version file.') | 186 | log.exception('Error in version file.') |
426 | 187 | full_version = '0.0.0-bzr000' | 187 | full_version = '0.0.0-bzr000' |
427 | 188 | finally: | 188 | finally: |
428 | 189 | 189 | ||
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 | 27 | 27 | ||
434 | 28 | from PyQt5 import QtCore, QtGui, QtWidgets | 28 | from PyQt5 import QtCore, QtGui, QtWidgets |
435 | 29 | 29 | ||
436 | 30 | from openlp.core.common import CONTROL_CHARS | ||
437 | 30 | from openlp.core.common.i18n import UiStrings, translate | 31 | from openlp.core.common.i18n import UiStrings, translate |
438 | 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 |
439 | 32 | from openlp.core.common.settings import Settings | 33 | from openlp.core.common.settings import Settings |
440 | @@ -241,7 +242,7 @@ | |||
441 | 241 | self.line_edit.editingFinished.connect(self.on_line_edit_editing_finished) | 242 | self.line_edit.editingFinished.connect(self.on_line_edit_editing_finished) |
442 | 242 | self.update_button_tool_tips() | 243 | self.update_button_tool_tips() |
443 | 243 | 244 | ||
445 | 244 | @property | 245 | @QtCore.pyqtProperty('QVariant') |
446 | 245 | def path(self): | 246 | def path(self): |
447 | 246 | """ | 247 | """ |
448 | 247 | A property getter method to return the selected path. | 248 | A property getter method to return the selected path. |
449 | @@ -349,7 +350,7 @@ | |||
450 | 349 | :rtype: None | 350 | :rtype: None |
451 | 350 | """ | 351 | """ |
452 | 351 | if self._path != path: | 352 | if self._path != path: |
454 | 352 | self.path = path | 353 | self._path = path |
455 | 353 | self.pathChanged.emit(path) | 354 | self.pathChanged.emit(path) |
456 | 354 | 355 | ||
457 | 355 | 356 | ||
458 | @@ -470,12 +471,21 @@ | |||
459 | 470 | cursor.insertText(html['start tag']) | 471 | cursor.insertText(html['start tag']) |
460 | 471 | cursor.insertText(html['end tag']) | 472 | cursor.insertText(html['end tag']) |
461 | 472 | 473 | ||
462 | 474 | def insertFromMimeData(self, source): | ||
463 | 475 | """ | ||
464 | 476 | Reimplement `insertFromMimeData` so that we can remove any control characters | ||
465 | 477 | |||
466 | 478 | :param QtCore.QMimeData source: The mime data to insert | ||
467 | 479 | :rtype: None | ||
468 | 480 | """ | ||
469 | 481 | self.insertPlainText(CONTROL_CHARS.sub('', source.text())) | ||
470 | 482 | |||
471 | 473 | 483 | ||
472 | 474 | class Highlighter(QtGui.QSyntaxHighlighter): | 484 | class Highlighter(QtGui.QSyntaxHighlighter): |
473 | 475 | """ | 485 | """ |
474 | 476 | Provides a text highlighter for pointing out spelling errors in text. | 486 | Provides a text highlighter for pointing out spelling errors in text. |
475 | 477 | """ | 487 | """ |
477 | 478 | WORDS = r'(?iu)[\w\']+' | 488 | WORDS = r'(?i)[\w\']+' |
478 | 479 | 489 | ||
479 | 480 | def __init__(self, *args): | 490 | def __init__(self, *args): |
480 | 481 | """ | 491 | """ |
481 | 482 | 492 | ||
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 | 336 | for file in listing: | 336 | for file in listing: |
487 | 337 | files.append(os.path.join(local_file, file)) | 337 | files.append(os.path.join(local_file, file)) |
488 | 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), |
490 | 339 | {'files': files, 'target': self.itemAt(event.pos())}) | 339 | {'files': files}) |
491 | 340 | else: | 340 | else: |
492 | 341 | event.ignore() | 341 | event.ignore() |
493 | 342 | 342 | ||
494 | 343 | 343 | ||
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 | 113 | cor_book = self.corresponding_combo_box.currentText() | 113 | cor_book = self.corresponding_combo_box.currentText() |
500 | 114 | for character in '\\.^$*+?{}[]()': | 114 | for character in '\\.^$*+?{}[]()': |
501 | 115 | cor_book = cor_book.replace(character, '\\' + character) | 115 | cor_book = cor_book.replace(character, '\\' + character) |
504 | 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]))] |
503 | 117 | re.UNICODE)] | ||
505 | 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] |
506 | 119 | if books: | 118 | if books: |
507 | 120 | self.book_id = books[0]['id'] | 119 | self.book_id = books[0]['id'] |
508 | 121 | 120 | ||
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 | 224 | range_regex = '(?:(?P<from_chapter>[0-9]+){sep_v})?' \ | 224 | range_regex = '(?:(?P<from_chapter>[0-9]+){sep_v})?' \ |
514 | 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>' \ |
515 | 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) |
518 | 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)) |
519 | 228 | REFERENCE_MATCHES['range_separator'] = re.compile(REFERENCE_SEPARATORS['sep_l'], re.UNICODE) | 228 | REFERENCE_MATCHES['range_separator'] = re.compile(REFERENCE_SEPARATORS['sep_l']) |
520 | 229 | # full reference match: <book>(<range>(,(?!$)|(?=$)))+ | 229 | # full reference match: <book>(<range>(,(?!$)|(?=$)))+ |
521 | 230 | REFERENCE_MATCHES['full'] = \ | 230 | REFERENCE_MATCHES['full'] = \ |
522 | 231 | re.compile(r'^\s*(?!\s)(?P<book>[\d]*[.]?[^\d\.]+)\.*(?<!\s)\s*' | 231 | re.compile(r'^\s*(?!\s)(?P<book>[\d]*[.]?[^\d\.]+)\.*(?<!\s)\s*' |
523 | 232 | r'(?P<ranges>(?:{range_regex}(?:{sep_l}(?!\s*$)|(?=\s*$)))+)\s*$'.format( | 232 | r'(?P<ranges>(?:{range_regex}(?:{sep_l}(?!\s*$)|(?=\s*$)))+)\s*$'.format( |
525 | 233 | range_regex=range_regex, sep_l=REFERENCE_SEPARATORS['sep_l']), re.UNICODE) | 233 | range_regex=range_regex, sep_l=REFERENCE_SEPARATORS['sep_l'])) |
526 | 234 | 234 | ||
527 | 235 | 235 | ||
528 | 236 | def get_reference_separator(separator_type): | 236 | def get_reference_separator(separator_type): |
529 | 237 | 237 | ||
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 | 307 | book_escaped = book | 307 | book_escaped = book |
535 | 308 | for character in RESERVED_CHARACTERS: | 308 | for character in RESERVED_CHARACTERS: |
536 | 309 | book_escaped = book_escaped.replace(character, '\\' + character) | 309 | book_escaped = book_escaped.replace(character, '\\' + character) |
539 | 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) |
538 | 311 | re.UNICODE | re.IGNORECASE) | ||
540 | 312 | if language_selection == LanguageSelection.Bible: | 311 | if language_selection == LanguageSelection.Bible: |
541 | 313 | db_book = self.get_book(book) | 312 | db_book = self.get_book(book) |
542 | 314 | if db_book: | 313 | if db_book: |
543 | 315 | 314 | ||
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 | 366 | if validate_thumb(image.file_path, thumbnail_path): | 366 | if validate_thumb(image.file_path, thumbnail_path): |
549 | 367 | icon = build_icon(thumbnail_path) | 367 | icon = build_icon(thumbnail_path) |
550 | 368 | else: | 368 | else: |
552 | 369 | icon = create_thumb(image.file_path, thumbnail_path) | 369 | icon = create_thumb(str(image.file_path), str(thumbnail_path)) |
553 | 370 | item_name = QtWidgets.QTreeWidgetItem([file_name]) | 370 | item_name = QtWidgets.QTreeWidgetItem([file_name]) |
554 | 371 | item_name.setText(0, file_name) | 371 | item_name.setText(0, file_name) |
555 | 372 | item_name.setIcon(0, icon) | 372 | item_name.setIcon(0, icon) |
556 | @@ -390,6 +390,7 @@ | |||
557 | 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 |
558 | 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 |
559 | 392 | """ | 392 | """ |
560 | 393 | file_paths = [Path(file) for file in file_paths] | ||
561 | 393 | self.application.set_normal_cursor() | 394 | self.application.set_normal_cursor() |
562 | 394 | self.load_list(file_paths, target_group) | 395 | self.load_list(file_paths, target_group) |
563 | 395 | last_dir = file_paths[0].parent | 396 | last_dir = file_paths[0].parent |
564 | 396 | 397 | ||
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 | 70 | try: | 70 | try: |
570 | 71 | self.start_process() | 71 | self.start_process() |
571 | 72 | return self.process.CheckInstalled() | 72 | return self.process.CheckInstalled() |
573 | 73 | except WindowsError: | 73 | except OSError: |
574 | 74 | return False | 74 | return False |
575 | 75 | 75 | ||
576 | 76 | def start_process(self): | 76 | def start_process(self): |
577 | 77 | 77 | ||
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 | 105 | self.topics_list_view.setSortingEnabled(False) | 105 | self.topics_list_view.setSortingEnabled(False) |
583 | 106 | self.topics_list_view.setAlternatingRowColors(True) | 106 | self.topics_list_view.setAlternatingRowColors(True) |
584 | 107 | self.audio_list_widget.setAlternatingRowColors(True) | 107 | self.audio_list_widget.setAlternatingRowColors(True) |
588 | 108 | self.find_verse_split = re.compile('---\[\]---\n', re.UNICODE) | 108 | self.find_verse_split = re.compile('---\[\]---\n') |
589 | 109 | self.whitespace = re.compile(r'\W+', re.UNICODE) | 109 | self.whitespace = re.compile(r'\W+') |
590 | 110 | self.find_tags = re.compile(u'\{/?\w+\}', re.UNICODE) | 110 | self.find_tags = re.compile(r'\{/?\w+\}') |
591 | 111 | 111 | ||
592 | 112 | def _load_objects(self, cls, combo, cache): | 112 | def _load_objects(self, cls, combo, cache): |
593 | 113 | """ | 113 | """ |
594 | 114 | 114 | ||
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 | 24 | """ | 24 | """ |
600 | 25 | 25 | ||
601 | 26 | import logging | 26 | import logging |
602 | 27 | import os | ||
603 | 28 | import re | 27 | import re |
604 | 29 | 28 | ||
605 | 30 | from PyQt5 import QtWidgets | 29 | from PyQt5 import QtWidgets |
606 | @@ -39,8 +38,8 @@ | |||
607 | 39 | 38 | ||
608 | 40 | log = logging.getLogger(__name__) | 39 | log = logging.getLogger(__name__) |
609 | 41 | 40 | ||
612 | 42 | WHITESPACE = re.compile(r'[\W_]+', re.UNICODE) | 41 | WHITESPACE = re.compile(r'[\W_]+') |
613 | 43 | APOSTROPHE = re.compile('[\'`’ʻ′]', re.UNICODE) | 42 | APOSTROPHE = re.compile(r'[\'`’ʻ′]') |
614 | 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: |
615 | 45 | # \controlword - optionally preceded by \*, optionally followed by a number | 44 | # \controlword - optionally preceded by \*, optionally followed by a number |
616 | 46 | # \'## - where ## is a pair of hex digits, representing a single character | 45 | # \'## - where ## is a pair of hex digits, representing a single character |
617 | 47 | 46 | ||
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 | 25 | 25 | ||
623 | 26 | from lxml import etree, objectify | 26 | from lxml import etree, objectify |
624 | 27 | 27 | ||
625 | 28 | from openlp.core.common import normalize_str | ||
626 | 28 | from openlp.plugins.songs.lib import VerseType | 29 | from openlp.plugins.songs.lib import VerseType |
627 | 29 | from openlp.plugins.songs.lib.importers.songimport import SongImport | 30 | from openlp.plugins.songs.lib.importers.songimport import SongImport |
628 | 30 | 31 | ||
629 | @@ -225,7 +226,7 @@ | |||
630 | 225 | verses[reg].setdefault(vt, {}) | 226 | verses[reg].setdefault(vt, {}) |
631 | 226 | verses[reg][vt].setdefault(vn, {}) | 227 | verses[reg][vt].setdefault(vn, {}) |
632 | 227 | verses[reg][vt][vn].setdefault(inst, []) | 228 | verses[reg][vt][vn].setdefault(inst, []) |
634 | 228 | verses[reg][vt][vn][inst].append(self.tidy_text(line)) | 229 | verses[reg][vt][vn][inst].append(normalize_str(line)) |
635 | 229 | # done parsing | 230 | # done parsing |
636 | 230 | versetags = [] | 231 | versetags = [] |
637 | 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 |
638 | 232 | 233 | ||
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 | 101 | self.song_book_name = song.SongID | 101 | self.song_book_name = song.SongID |
644 | 102 | for verse in verses: | 102 | for verse in verses: |
645 | 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' |
647 | 104 | self.add_verse(self.tidy_text(verse.Text), tag) | 104 | self.add_verse(verse.Text, tag) |
648 | 105 | for order in verse_order: | 105 | for order in verse_order: |
649 | 106 | if order.Type < len(VERSE_TAGS): | 106 | if order.Type < len(VERSE_TAGS): |
650 | 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)) |
651 | 108 | 108 | ||
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 | 24 | 24 | ||
657 | 25 | from PyQt5 import QtCore | 25 | from PyQt5 import QtCore |
658 | 26 | 26 | ||
660 | 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 |
661 | 28 | from openlp.core.common.i18n import translate | 28 | from openlp.core.common.i18n import translate |
662 | 29 | from .songimport import SongImport | 29 | from .songimport import SongImport |
663 | 30 | 30 | ||
664 | @@ -241,7 +241,7 @@ | |||
665 | 241 | 241 | ||
666 | 242 | :param text: The text. | 242 | :param text: The text. |
667 | 243 | """ | 243 | """ |
669 | 244 | song_texts = self.tidy_text(text).split('\f') | 244 | song_texts = normalize_str(text).split('\f') |
670 | 245 | self.set_defaults() | 245 | self.set_defaults() |
671 | 246 | for song_text in song_texts: | 246 | for song_text in song_texts: |
672 | 247 | if song_text.strip(): | 247 | if song_text.strip(): |
673 | 248 | 248 | ||
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 | 25 | from lxml import objectify | 25 | from lxml import objectify |
679 | 26 | from lxml.etree import Error, LxmlError | 26 | from lxml.etree import Error, LxmlError |
680 | 27 | 27 | ||
681 | 28 | from openlp.core.common import normalize_str | ||
682 | 28 | from openlp.core.common.i18n import translate | 29 | from openlp.core.common.i18n import translate |
683 | 29 | from openlp.core.common.settings import Settings | 30 | from openlp.core.common.settings import Settings |
684 | 30 | from openlp.plugins.songs.lib import VerseType | 31 | from openlp.plugins.songs.lib import VerseType |
685 | @@ -262,7 +263,7 @@ | |||
686 | 262 | post=this_line[offset + column:]) | 263 | post=this_line[offset + column:]) |
687 | 263 | offset += len(chord) + 2 | 264 | offset += len(chord) + 2 |
688 | 264 | # Tidy text and remove the ____s from extended words | 265 | # Tidy text and remove the ____s from extended words |
690 | 265 | this_line = self.tidy_text(this_line) | 266 | this_line = normalize_str(this_line) |
691 | 266 | this_line = this_line.replace('_', '') | 267 | this_line = this_line.replace('_', '') |
692 | 267 | this_line = this_line.replace('||', '\n[---]\n') | 268 | this_line = this_line.replace('||', '\n[---]\n') |
693 | 268 | this_line = this_line.strip() | 269 | this_line = this_line.strip() |
694 | 269 | 270 | ||
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 | 25 | 25 | ||
700 | 26 | from PyQt5 import QtCore | 26 | from PyQt5 import QtCore |
701 | 27 | 27 | ||
702 | 28 | from openlp.core.common import normalize_str | ||
703 | 28 | from openlp.core.common.applocation import AppLocation | 29 | from openlp.core.common.applocation import AppLocation |
704 | 29 | from openlp.core.common.i18n import translate | 30 | from openlp.core.common.i18n import translate |
705 | 30 | from openlp.core.common.path import copyfile, create_paths | 31 | from openlp.core.common.path import copyfile, create_paths |
706 | @@ -130,26 +131,6 @@ | |||
707 | 130 | def register(self, import_wizard): | 131 | def register(self, import_wizard): |
708 | 131 | self.import_wizard = import_wizard | 132 | self.import_wizard = import_wizard |
709 | 132 | 133 | ||
710 | 133 | def tidy_text(self, text): | ||
711 | 134 | """ | ||
712 | 135 | Get rid of some dodgy unicode and formatting characters we're not interested in. Some can be converted to ascii. | ||
713 | 136 | """ | ||
714 | 137 | text = text.replace('\u2018', '\'') | ||
715 | 138 | text = text.replace('\u2019', '\'') | ||
716 | 139 | text = text.replace('\u201c', '"') | ||
717 | 140 | text = text.replace('\u201d', '"') | ||
718 | 141 | text = text.replace('\u2026', '...') | ||
719 | 142 | text = text.replace('\u2013', '-') | ||
720 | 143 | text = text.replace('\u2014', '-') | ||
721 | 144 | # Replace vertical tab with 2 linebreaks | ||
722 | 145 | text = text.replace('\v', '\n\n') | ||
723 | 146 | # Replace form feed (page break) with 2 linebreaks | ||
724 | 147 | text = text.replace('\f', '\n\n') | ||
725 | 148 | # Remove surplus blank lines, spaces, trailing/leading spaces | ||
726 | 149 | text = re.sub(r'[ \t]+', ' ', text) | ||
727 | 150 | text = re.sub(r' ?(\r\n?|\n) ?', '\n', text) | ||
728 | 151 | return text | ||
729 | 152 | |||
730 | 153 | def process_song_text(self, text): | 134 | def process_song_text(self, text): |
731 | 154 | """ | 135 | """ |
732 | 155 | Process the song text from import | 136 | Process the song text from import |
733 | @@ -368,7 +349,7 @@ | |||
734 | 368 | verse_tag = VerseType.tags[VerseType.Other] | 349 | verse_tag = VerseType.tags[VerseType.Other] |
735 | 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)) |
736 | 370 | verse_def = new_verse_def | 351 | verse_def = new_verse_def |
738 | 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) |
739 | 372 | song.lyrics = str(sxml.extract_xml(), 'utf-8') | 353 | song.lyrics = str(sxml.extract_xml(), 'utf-8') |
740 | 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: |
741 | 374 | self.verse_order_list = self.verse_order_list_generated | 355 | self.verse_order_list = self.verse_order_list_generated |
742 | 375 | 356 | ||
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 | 194 | :param text_portion: A Piece of text | 194 | :param text_portion: A Piece of text |
748 | 195 | """ | 195 | """ |
749 | 196 | text = text_portion.getString() | 196 | text = text_portion.getString() |
750 | 197 | text = self.tidy_text(text) | ||
751 | 198 | if text.strip() == '': | 197 | if text.strip() == '': |
752 | 199 | return text | 198 | return text |
753 | 200 | if text_portion.CharWeight == BOLD: | 199 | if text_portion.CharWeight == BOLD: |
754 | 201 | 200 | ||
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 | 30 | 30 | ||
760 | 31 | log = logging.getLogger(__name__) | 31 | log = logging.getLogger(__name__) |
761 | 32 | 32 | ||
762 | 33 | # Used to strip control chars (except 10=LF, 13=CR) | ||
763 | 34 | CONTROL_CHARS_MAP = dict.fromkeys(list(range(10)) + [11, 12] + list(range(14, 32)) + [127]) | ||
764 | 35 | |||
765 | 36 | 33 | ||
766 | 37 | class ZionWorxImport(SongImport): | 34 | class ZionWorxImport(SongImport): |
767 | 38 | """ | 35 | """ |
768 | @@ -95,12 +92,12 @@ | |||
769 | 95 | return | 92 | return |
770 | 96 | self.set_defaults() | 93 | self.set_defaults() |
771 | 97 | try: | 94 | try: |
773 | 98 | self.title = self._decode(record['Title1']) | 95 | self.title = record['Title1'] |
774 | 99 | if record['Title2']: | 96 | if record['Title2']: |
779 | 100 | self.alternate_title = self._decode(record['Title2']) | 97 | self.alternate_title = record['Title2'] |
780 | 101 | self.parse_author(self._decode(record['Writer'])) | 98 | self.parse_author(record['Writer']) |
781 | 102 | self.add_copyright(self._decode(record['Copyright'])) | 99 | self.add_copyright(record['Copyright']) |
782 | 103 | lyrics = self._decode(record['Lyrics']) | 100 | lyrics = record['Lyrics'] |
783 | 104 | except UnicodeDecodeError as e: | 101 | except UnicodeDecodeError as e: |
784 | 105 | self.log_error(translate('SongsPlugin.ZionWorxImport', 'Record {index}').format(index=index), | 102 | self.log_error(translate('SongsPlugin.ZionWorxImport', 'Record {index}').format(index=index), |
785 | 106 | translate('SongsPlugin.ZionWorxImport', 'Decoding error: {error}').format(error=e)) | 103 | translate('SongsPlugin.ZionWorxImport', 'Decoding error: {error}').format(error=e)) |
786 | @@ -122,10 +119,3 @@ | |||
787 | 122 | if not self.finish(): | 119 | if not self.finish(): |
788 | 123 | self.log_error(translate('SongsPlugin.ZionWorxImport', 'Record %d') % index + | 120 | self.log_error(translate('SongsPlugin.ZionWorxImport', 'Record %d') % index + |
789 | 124 | (': "' + title + '"' if title else '')) | 121 | (': "' + title + '"' if title else '')) |
790 | 125 | |||
791 | 126 | def _decode(self, str): | ||
792 | 127 | """ | ||
793 | 128 | Strips all control characters (except new lines). | ||
794 | 129 | """ | ||
795 | 130 | # ZionWorx has no option for setting the encoding for its songs, so we assume encoding is always the same. | ||
796 | 131 | return str.translate(CONTROL_CHARS_MAP) | ||
797 | 132 | 122 | ||
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 | 281 | # Process the formatting tags. | 281 | # Process the formatting tags. |
803 | 282 | # Have we any tags in song lyrics? | 282 | # Have we any tags in song lyrics? |
804 | 283 | tags_element = None | 283 | tags_element = None |
806 | 284 | match = re.search('\{/?\w+\}', song.lyrics, re.UNICODE) | 284 | match = re.search(r'\{/?\w+\}', song.lyrics) |
807 | 285 | if match: | 285 | if match: |
808 | 286 | # Named 'format_' - 'format' is built-in function in Python. | 286 | # Named 'format_' - 'format' is built-in function in Python. |
809 | 287 | format_ = etree.SubElement(song_xml, 'format') | 287 | format_ = etree.SubElement(song_xml, 'format') |
810 | 288 | 288 | ||
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 | 54 | """ | 54 | """ |
816 | 55 | We need to set up the screen | 55 | We need to set up the screen |
817 | 56 | """ | 56 | """ |
820 | 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') |
821 | 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()): |
822 | 59 | to_date = QtCore.QDate.currentDate() | ||
823 | 60 | from_date = Settings().value(self.plugin.settings_section + '/from date') | ||
824 | 61 | if not (isinstance(from_date, QtCore.QDate) and from_date.isValid()): | ||
825 | 62 | from_date = to_date.addYears(-1) | ||
826 | 63 | self.from_date_calendar.setSelectedDate(from_date) | ||
827 | 64 | self.to_date_calendar.setSelectedDate(to_date) | ||
828 | 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') |
829 | 60 | 66 | ||
830 | 61 | def on_report_path_edit_path_changed(self, file_path): | 67 | def on_report_path_edit_path_changed(self, file_path): |
831 | 62 | 68 | ||
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 | 38 | 38 | ||
837 | 39 | log = logging.getLogger(__name__) | 39 | log = logging.getLogger(__name__) |
838 | 40 | 40 | ||
843 | 41 | YEAR = QtCore.QDate().currentDate().year() | 41 | TODAY = QtCore.QDate.currentDate() |
840 | 42 | if QtCore.QDate().currentDate().month() < 9: | ||
841 | 43 | YEAR -= 1 | ||
842 | 44 | |||
844 | 45 | 42 | ||
845 | 46 | __default_settings__ = { | 43 | __default_settings__ = { |
846 | 47 | 'songusage/db type': 'sqlite', | 44 | 'songusage/db type': 'sqlite', |
847 | 48 | 'songusage/db username': '', | 45 | 'songusage/db username': '', |
851 | 49 | 'songuasge/db password': '', | 46 | 'songusage/db password': '', |
852 | 50 | 'songuasge/db hostname': '', | 47 | 'songusage/db hostname': '', |
853 | 51 | 'songuasge/db database': '', | 48 | 'songusage/db database': '', |
854 | 52 | 'songusage/active': False, | 49 | 'songusage/active': False, |
857 | 53 | 'songusage/to date': QtCore.QDate(YEAR, 8, 31), | 50 | 'songusage/to date': TODAY, |
858 | 54 | 'songusage/from date': QtCore.QDate(YEAR - 1, 9, 1), | 51 | 'songusage/from date': TODAY.addYears(-1), |
859 | 55 | 'songusage/last directory export': None | 52 | 'songusage/last directory export': None |
860 | 56 | } | 53 | } |
861 | 57 | 54 | ||
862 | 58 | 55 | ||
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 | 153 | """ | 153 | """ |
868 | 154 | Prepare the tests | 154 | Prepare the tests |
869 | 155 | """ | 155 | """ |
870 | 156 | self.setup_application() | ||
871 | 156 | self.action_list = ActionList.get_instance() | 157 | self.action_list = ActionList.get_instance() |
872 | 157 | self.build_settings() | 158 | self.build_settings() |
873 | 158 | self.settings = Settings() | 159 | self.settings = Settings() |
874 | 159 | 160 | ||
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 | 233 | Test socket timeout gets caught | 233 | Test socket timeout gets caught |
880 | 234 | """ | 234 | """ |
881 | 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 |
883 | 236 | mocked_requests.get.side_effect = IOError | 236 | mocked_requests.get.side_effect = OSError |
884 | 237 | 237 | ||
885 | 238 | # WHEN: Attempt to retrieve a file | 238 | # WHEN: Attempt to retrieve a file |
886 | 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)) |
887 | 240 | 240 | ||
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 | 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' |
893 | 156 | 156 | ||
894 | 157 | 157 | ||
896 | 158 | def test_translate(self): | 158 | def test_translate(): |
897 | 159 | """ | 159 | """ |
898 | 160 | Test the translate() function | 160 | Test the translate() function |
899 | 161 | """ | 161 | """ |
900 | 162 | 162 | ||
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 | 371 | @patch('openlp.core.common.path.log') | 371 | @patch('openlp.core.common.path.log') |
906 | 372 | def test_create_paths_dir_io_error(self, mocked_logger): | 372 | def test_create_paths_dir_io_error(self, mocked_logger): |
907 | 373 | """ | 373 | """ |
909 | 374 | Test the create_paths() when an IOError is raised | 374 | Test the create_paths() when an OSError is raised |
910 | 375 | """ | 375 | """ |
911 | 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 |
912 | 377 | mocked_path = MagicMock() | 377 | mocked_path = MagicMock() |
914 | 378 | mocked_path.exists.side_effect = IOError('Cannot make directory') | 378 | mocked_path.exists.side_effect = OSError('Cannot make directory') |
915 | 379 | 379 | ||
917 | 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. |
918 | 381 | create_paths(mocked_path) | 381 | create_paths(mocked_path) |
919 | 382 | 382 | ||
920 | 383 | # THEN: The Error should have been logged | 383 | # THEN: The Error should have been logged |
921 | @@ -385,7 +385,7 @@ | |||
922 | 385 | 385 | ||
923 | 386 | def test_create_paths_dir_value_error(self): | 386 | def test_create_paths_dir_value_error(self): |
924 | 387 | """ | 387 | """ |
926 | 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 |
927 | 389 | """ | 389 | """ |
928 | 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 |
929 | 391 | mocked_path = MagicMock() | 391 | mocked_path = MagicMock() |
930 | 392 | 392 | ||
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 | 168 | patch.object(Path, 'open'): | 168 | patch.object(Path, 'open'): |
936 | 169 | file_path = Path('testfile.txt') | 169 | file_path = Path('testfile.txt') |
937 | 170 | file_path.is_file.return_value = True | 170 | file_path.is_file.return_value = True |
939 | 171 | file_path.open.side_effect = IOError() | 171 | file_path.open.side_effect = OSError() |
940 | 172 | 172 | ||
941 | 173 | # WHEN: get_text_file_string is called | 173 | # WHEN: get_text_file_string is called |
942 | 174 | result = get_text_file_string(file_path) | 174 | result = get_text_file_string(file_path) |
943 | 175 | 175 | ||
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 | 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 |
949 | 41 | """ | 41 | """ |
950 | 42 | # GIVEN: Initial settings and mocks | 42 | # GIVEN: Initial settings and mocks |
952 | 43 | mocked_requests.get.side_effect = IOError('Unable to connect') | 43 | mocked_requests.get.side_effect = OSError('Unable to connect') |
953 | 44 | 44 | ||
954 | 45 | # WHEN: A webpage is requested | 45 | # WHEN: A webpage is requested |
955 | 46 | try: | 46 | try: |
956 | 47 | 47 | ||
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 | 627 | assert widget.allow_internal_dnd is False | 627 | assert widget.allow_internal_dnd is False |
962 | 628 | assert widget.indentation() == 0 | 628 | assert widget.indentation() == 0 |
963 | 629 | assert widget.isAnimated() is True | 629 | assert widget.isAnimated() is True |
964 | 630 | |||
965 | 631 | 630 | ||
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 | 144 | # GIVEN: A mocked open, get_thumbnail_folder and exists | 144 | # GIVEN: A mocked open, get_thumbnail_folder and exists |
971 | 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, \ |
972 | 146 | patch(FOLDER_TO_PATCH) as mocked_get_thumbnail_folder: | 146 | patch(FOLDER_TO_PATCH) as mocked_get_thumbnail_folder: |
974 | 147 | mocked_read_text.side_effect = IOError() | 147 | mocked_read_text.side_effect = OSError() |
975 | 148 | mocked_get_thumbnail_folder.return_value = Path('test') | 148 | mocked_get_thumbnail_folder.return_value = Path('test') |
976 | 149 | 149 | ||
977 | 150 | # WHEN: calling get_titles_and_notes | 150 | # WHEN: calling get_titles_and_notes |
978 | 151 | 151 | ||
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 | 42 | """ | 42 | """ |
984 | 43 | Create the UI and setup necessary options | 43 | Create the UI and setup necessary options |
985 | 44 | """ | 44 | """ |
986 | 45 | self.setup_application() | ||
987 | 45 | self.build_settings() | 46 | self.build_settings() |
988 | 46 | self.setup_application() | ||
989 | 47 | Registry.create() | 47 | Registry.create() |
990 | 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: |
991 | 49 | if os.path.exists(TEST_DB): | 49 | if os.path.exists(TEST_DB): |
992 | 50 | 50 | ||
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 | 64 | Set up anything necessary for all tests | 64 | Set up anything necessary for all tests |
998 | 65 | """ | 65 | """ |
999 | 66 | mocked_init_url.return_value = 'sqlite:///{}'.format(TEST_DB) | 66 | mocked_init_url.return_value = 'sqlite:///{}'.format(TEST_DB) |
1000 | 67 | self.setup_application() | ||
1001 | 67 | self.build_settings() | 68 | self.build_settings() |
1002 | 68 | self.setup_application() | ||
1003 | 69 | Registry.create() | 69 | Registry.create() |
1004 | 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 |
1005 | 71 | if not hasattr(self, 'projectordb'): | 71 | if not hasattr(self, 'projectordb'): |
1006 | 72 | 72 | ||
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 | 41 | """ | 41 | """ |
1012 | 42 | Create the UI | 42 | Create the UI |
1013 | 43 | """ | 43 | """ |
1014 | 44 | self.setup_application() | ||
1015 | 44 | self.build_settings() | 45 | self.build_settings() |
1016 | 45 | self.setup_application() | ||
1017 | 46 | Registry.create() | 46 | Registry.create() |
1018 | 47 | self.theme_manager = ThemeManager() | 47 | self.theme_manager = ThemeManager() |
1019 | 48 | 48 | ||
1020 | 49 | 49 | ||
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 | 36 | try: | 36 | try: |
1026 | 37 | items = json.load(open_file) | 37 | items = json.load(open_file) |
1027 | 38 | first_line = items[row] | 38 | first_line = items[row] |
1029 | 39 | except IOError: | 39 | except OSError: |
1030 | 40 | first_line = '' | 40 | first_line = '' |
1031 | 41 | finally: | 41 | finally: |
1032 | 42 | open_file.close() | 42 | open_file.close() |
1033 | 43 | 43 | ||
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 | 58 | # GIVEN: Some checks to disable and enable, and the pylint script | 58 | # GIVEN: Some checks to disable and enable, and the pylint script |
1039 | 59 | disabled_checks = 'import-error,no-member' | 59 | disabled_checks = 'import-error,no-member' |
1040 | 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' |
1045 | 61 | if is_win() or 'arch' in platform.dist()[0].lower(): | 61 | pylint_kwargs = { |
1046 | 62 | pylint_script = 'pylint' | 62 | 'return_std': True |
1047 | 63 | else: | 63 | } |
1048 | 64 | pylint_script = 'pylint3' | 64 | if version < '1.7.0': |
1049 | 65 | if is_win() or 'arch' in platform.dist()[0].lower(): | ||
1050 | 66 | pylint_kwargs.update({'script': 'pylint'}) | ||
1051 | 67 | else: | ||
1052 | 68 | pylint_kwargs.update({'script': 'pylint3'}) | ||
1053 | 65 | 69 | ||
1054 | 66 | # WHEN: Running pylint | 70 | # WHEN: Running pylint |
1055 | 67 | (pylint_stdout, pylint_stderr) = \ | 71 | (pylint_stdout, pylint_stderr) = \ |
1056 | 68 | lint.py_run('openlp --errors-only --disable={disabled} --enable={enabled} ' | 72 | lint.py_run('openlp --errors-only --disable={disabled} --enable={enabled} ' |
1057 | 69 | '--reports=no --output-format=parseable'.format(disabled=disabled_checks, | 73 | '--reports=no --output-format=parseable'.format(disabled=disabled_checks, |
1058 | 70 | enabled=enabled_checks), | 74 | enabled=enabled_checks), |
1060 | 71 | return_std=True, script=pylint_script) | 75 | **pylint_kwargs) |
1061 | 72 | stdout = pylint_stdout.read() | 76 | stdout = pylint_stdout.read() |
1062 | 73 | stderr = pylint_stderr.read() | 77 | stderr = pylint_stderr.read() |
1063 | 74 | filtered_stdout = self._filter_tolerated_errors(stdout) | 78 | filtered_stdout = self._filter_tolerated_errors(stdout) |
Looks good.