Merge lp:~tomasgroth/openlp/pysword-import into lp:openlp
- pysword-import
- Merge into trunk
Status: | Merged |
---|---|
Merged at revision: | 2652 |
Proposed branch: | lp:~tomasgroth/openlp/pysword-import |
Merge into: | lp:openlp |
Diff against target: |
615 lines (+412/-7) 7 files modified
openlp/core/ui/lib/wizard.py (+2/-1) openlp/plugins/bibles/forms/bibleimportform.py (+176/-3) openlp/plugins/bibles/lib/manager.py (+8/-1) openlp/plugins/bibles/lib/sword.py (+100/-0) scripts/check_dependencies.py (+1/-0) tests/functional/openlp_plugins/bibles/test_swordimport.py (+109/-0) tests/interfaces/openlp_plugins/bibles/forms/test_bibleimportform.py (+16/-2) |
To merge this branch: | bzr merge lp:~tomasgroth/openlp/pysword-import |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Raoul Snyman | Approve | ||
Review via email: mp+292713@code.launchpad.net |
This proposal supersedes a proposal from 2016-04-20.
Commit message
Description of the change
Added support for importing SWORD bibles using PySword.
Tomas Groth (tomasgroth) wrote : Posted in a previous version of this proposal | # |
Raoul Snyman (raoul-snyman) wrote : Posted in a previous version of this proposal | # |
I tried to do an import from a SWORD Bible I already have, and I got this error as the import itself started.
Traceback (most recent call last):
File "/home/
self.
File "/home/
if importer.
TypeError: do_import() takes 1 positional argument but 2 were given
Tomas Groth (tomasgroth) wrote : | # |
Fixed traceback.
[SUCCESS] https:/
[SUCCESS] https:/
[SUCCESS] https:/
[SUCCESS] https:/
[SUCCESS] https:/
[SUCCESS] https:/
[SUCCESS] https:/
Raoul Snyman (raoul-snyman) wrote : | # |
I only have 1 SWORD Bible at the moment, so I'm not sure if it's pysword or the Bible itself, but it imported in a weird order. Nothing seemed to be wrong afterward, just had the new testament first and then the old. I figure it's probably just the order of things in the SWORD module itself.
- 2590. By Tomas Groth
-
merge trunk
- 2591. By Tomas Groth
-
fix merge issues
Preview Diff
1 | === modified file 'openlp/core/ui/lib/wizard.py' |
2 | --- openlp/core/ui/lib/wizard.py 2016-04-22 18:32:59 +0000 |
3 | +++ openlp/core/ui/lib/wizard.py 2016-04-26 19:04:37 +0000 |
4 | @@ -45,6 +45,7 @@ |
5 | OS = 'OpenSong' |
6 | OSIS = 'OSIS' |
7 | ZEF = 'Zefania' |
8 | + SWORD = 'Sword' |
9 | # These strings should need a good reason to be retranslated elsewhere. |
10 | FinishedImport = translate('OpenLP.Ui', 'Finished import.') |
11 | FormatLabel = translate('OpenLP.Ui', 'Format:') |
12 | @@ -113,7 +114,7 @@ |
13 | Set up the wizard UI. |
14 | :param image: path to start up image |
15 | """ |
16 | - self.setWindowIcon(build_icon(u':/icon/openlp-logo.svg')) |
17 | + self.setWindowIcon(build_icon(':/icon/openlp-logo.svg')) |
18 | self.setModal(True) |
19 | self.setOptions(QtWidgets.QWizard.IndependentPages | |
20 | QtWidgets.QWizard.NoBackButtonOnStartPage | QtWidgets.QWizard.NoBackButtonOnLastPage) |
21 | |
22 | === modified file 'openlp/plugins/bibles/forms/bibleimportform.py' |
23 | --- openlp/plugins/bibles/forms/bibleimportform.py 2016-04-22 18:25:57 +0000 |
24 | +++ openlp/plugins/bibles/forms/bibleimportform.py 2016-04-26 19:04:37 +0000 |
25 | @@ -27,6 +27,11 @@ |
26 | import urllib.error |
27 | |
28 | from PyQt5 import QtWidgets |
29 | +try: |
30 | + from pysword import modules |
31 | + PYSWORD_AVAILABLE = True |
32 | +except: |
33 | + PYSWORD_AVAILABLE = False |
34 | |
35 | from openlp.core.common import AppLocation, Settings, UiStrings, translate, clean_filename |
36 | from openlp.core.lib.db import delete_database |
37 | @@ -34,7 +39,7 @@ |
38 | from openlp.core.ui.lib.wizard import OpenLPWizard, WizardStrings |
39 | from openlp.core.common.languagemanager import get_locale_key |
40 | from openlp.plugins.bibles.lib.manager import BibleFormat |
41 | -from openlp.plugins.bibles.lib.db import BiblesResourcesDB, clean_filename |
42 | +from openlp.plugins.bibles.lib.db import clean_filename |
43 | from openlp.plugins.bibles.lib.http import CWExtract, BGExtract, BSExtract |
44 | |
45 | log = logging.getLogger(__name__) |
46 | @@ -94,6 +99,19 @@ |
47 | self.manager.set_process_dialog(self) |
48 | self.restart() |
49 | self.select_stack.setCurrentIndex(0) |
50 | + if PYSWORD_AVAILABLE: |
51 | + self.pysword_folder_modules = modules.SwordModules() |
52 | + try: |
53 | + self.pysword_folder_modules_json = self.pysword_folder_modules.parse_modules() |
54 | + except FileNotFoundError: |
55 | + log.debug('No installed SWORD modules found in the default location') |
56 | + self.sword_bible_combo_box.clear() |
57 | + return |
58 | + bible_keys = self.pysword_folder_modules_json.keys() |
59 | + for key in bible_keys: |
60 | + self.sword_bible_combo_box.addItem(self.pysword_folder_modules_json[key]['description'], key) |
61 | + else: |
62 | + self.sword_tab_widget.setDisabled(True) |
63 | |
64 | def custom_signals(self): |
65 | """ |
66 | @@ -106,6 +124,8 @@ |
67 | self.open_song_browse_button.clicked.connect(self.on_open_song_browse_button_clicked) |
68 | self.zefania_browse_button.clicked.connect(self.on_zefania_browse_button_clicked) |
69 | self.web_update_button.clicked.connect(self.on_web_update_button_clicked) |
70 | + self.sword_browse_button.clicked.connect(self.on_sword_browse_button_clicked) |
71 | + self.sword_zipbrowse_button.clicked.connect(self.on_sword_zipbrowse_button_clicked) |
72 | |
73 | def add_custom_pages(self): |
74 | """ |
75 | @@ -121,7 +141,7 @@ |
76 | self.format_label = QtWidgets.QLabel(self.select_page) |
77 | self.format_label.setObjectName('FormatLabel') |
78 | self.format_combo_box = QtWidgets.QComboBox(self.select_page) |
79 | - self.format_combo_box.addItems(['', '', '', '', '']) |
80 | + self.format_combo_box.addItems(['', '', '', '', '', '']) |
81 | self.format_combo_box.setObjectName('FormatComboBox') |
82 | self.format_layout.addRow(self.format_label, self.format_combo_box) |
83 | self.spacer = QtWidgets.QSpacerItem(10, 0, QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Minimum) |
84 | @@ -275,6 +295,64 @@ |
85 | self.zefania_layout.addRow(self.zefania_file_label, self.zefania_file_layout) |
86 | self.zefania_layout.setItem(5, QtWidgets.QFormLayout.LabelRole, self.spacer) |
87 | self.select_stack.addWidget(self.zefania_widget) |
88 | + self.sword_widget = QtWidgets.QWidget(self.select_page) |
89 | + self.sword_widget.setObjectName('SwordWidget') |
90 | + self.sword_layout = QtWidgets.QVBoxLayout(self.sword_widget) |
91 | + self.sword_layout.setObjectName('SwordLayout') |
92 | + self.sword_tab_widget = QtWidgets.QTabWidget(self.sword_widget) |
93 | + self.sword_tab_widget.setObjectName('SwordTabWidget') |
94 | + self.sword_folder_tab = QtWidgets.QWidget(self.sword_tab_widget) |
95 | + self.sword_folder_tab.setObjectName('SwordFolderTab') |
96 | + self.sword_folder_tab_layout = QtWidgets.QGridLayout(self.sword_folder_tab) |
97 | + self.sword_folder_tab_layout.setObjectName('SwordTabFolderLayout') |
98 | + self.sword_folder_label = QtWidgets.QLabel(self.sword_folder_tab) |
99 | + self.sword_folder_label.setObjectName('SwordSourceLabel') |
100 | + self.sword_folder_tab_layout.addWidget(self.sword_folder_label, 0, 0) |
101 | + self.sword_folder_label.setObjectName('SwordFolderLabel') |
102 | + self.sword_folder_edit = QtWidgets.QLineEdit(self.sword_folder_tab) |
103 | + self.sword_folder_edit.setObjectName('SwordFolderEdit') |
104 | + self.sword_browse_button = QtWidgets.QToolButton(self.sword_folder_tab) |
105 | + self.sword_browse_button.setIcon(self.open_icon) |
106 | + self.sword_browse_button.setObjectName('SwordBrowseButton') |
107 | + self.sword_folder_tab_layout.addWidget(self.sword_folder_edit, 0, 1) |
108 | + self.sword_folder_tab_layout.addWidget(self.sword_browse_button, 0, 2) |
109 | + self.sword_bible_label = QtWidgets.QLabel(self.sword_folder_tab) |
110 | + self.sword_bible_label.setObjectName('SwordBibleLabel') |
111 | + self.sword_folder_tab_layout.addWidget(self.sword_bible_label, 1, 0) |
112 | + self.sword_bible_combo_box = QtWidgets.QComboBox(self.sword_folder_tab) |
113 | + self.sword_bible_combo_box.setSizeAdjustPolicy(QtWidgets.QComboBox.AdjustToContents) |
114 | + self.sword_bible_combo_box.setInsertPolicy(QtWidgets.QComboBox.InsertAlphabetically) |
115 | + self.sword_bible_combo_box.setObjectName('SwordBibleComboBox') |
116 | + self.sword_folder_tab_layout.addWidget(self.sword_bible_combo_box, 1, 1) |
117 | + self.sword_tab_widget.addTab(self.sword_folder_tab, '') |
118 | + self.sword_zip_tab = QtWidgets.QWidget(self.sword_tab_widget) |
119 | + self.sword_zip_tab.setObjectName('SwordZipTab') |
120 | + self.sword_zip_layout = QtWidgets.QGridLayout(self.sword_zip_tab) |
121 | + self.sword_zip_layout.setObjectName('SwordZipLayout') |
122 | + self.sword_zipfile_label = QtWidgets.QLabel(self.sword_zip_tab) |
123 | + self.sword_zipfile_label.setObjectName('SwordZipFileLabel') |
124 | + self.sword_zipfile_edit = QtWidgets.QLineEdit(self.sword_zip_tab) |
125 | + self.sword_zipfile_edit.setObjectName('SwordZipFileEdit') |
126 | + self.sword_zipbrowse_button = QtWidgets.QToolButton(self.sword_zip_tab) |
127 | + self.sword_zipbrowse_button.setIcon(self.open_icon) |
128 | + self.sword_zipbrowse_button.setObjectName('SwordZipBrowseButton') |
129 | + self.sword_zipbible_label = QtWidgets.QLabel(self.sword_folder_tab) |
130 | + self.sword_zipbible_label.setObjectName('SwordZipBibleLabel') |
131 | + self.sword_zipbible_combo_box = QtWidgets.QComboBox(self.sword_zip_tab) |
132 | + self.sword_zipbible_combo_box.setSizeAdjustPolicy(QtWidgets.QComboBox.AdjustToContents) |
133 | + self.sword_zipbible_combo_box.setInsertPolicy(QtWidgets.QComboBox.InsertAlphabetically) |
134 | + self.sword_zipbible_combo_box.setObjectName('SwordZipBibleComboBox') |
135 | + self.sword_zip_layout.addWidget(self.sword_zipfile_label, 0, 0) |
136 | + self.sword_zip_layout.addWidget(self.sword_zipfile_edit, 0, 1) |
137 | + self.sword_zip_layout.addWidget(self.sword_zipbrowse_button, 0, 2) |
138 | + self.sword_zip_layout.addWidget(self.sword_zipbible_label, 1, 0) |
139 | + self.sword_zip_layout.addWidget(self.sword_zipbible_combo_box, 1, 1) |
140 | + self.sword_tab_widget.addTab(self.sword_zip_tab, '') |
141 | + self.sword_layout.addWidget(self.sword_tab_widget) |
142 | + self.sword_disabled_label = QtWidgets.QLabel(self.sword_widget) |
143 | + self.sword_disabled_label.setObjectName('SwordDisabledLabel') |
144 | + self.sword_layout.addWidget(self.sword_disabled_label) |
145 | + self.select_stack.addWidget(self.sword_widget) |
146 | self.select_page_layout.addLayout(self.select_stack) |
147 | self.addPage(self.select_page) |
148 | # License Page |
149 | @@ -323,6 +401,7 @@ |
150 | self.format_combo_box.setItemText(BibleFormat.WebDownload, translate('BiblesPlugin.ImportWizardForm', |
151 | 'Web Download')) |
152 | self.format_combo_box.setItemText(BibleFormat.Zefania, WizardStrings.ZEF) |
153 | + self.format_combo_box.setItemText(BibleFormat.SWORD, WizardStrings.SWORD) |
154 | self.osis_file_label.setText(translate('BiblesPlugin.ImportWizardForm', 'Bible file:')) |
155 | self.csv_books_label.setText(translate('BiblesPlugin.ImportWizardForm', 'Books file:')) |
156 | self.csv_verses_label.setText(translate('BiblesPlugin.ImportWizardForm', 'Verses file:')) |
157 | @@ -346,6 +425,22 @@ |
158 | self.web_tab_widget.setTabText( |
159 | self.web_tab_widget.indexOf(self.web_proxy_tab), translate('BiblesPlugin.ImportWizardForm', |
160 | 'Proxy Server (Optional)')) |
161 | + self.sword_bible_label.setText(translate('BiblesPlugin.ImportWizardForm', 'Bibles:')) |
162 | + self.sword_folder_label.setText(translate('BiblesPlugin.ImportWizardForm', 'SWORD data folder:')) |
163 | + self.sword_zipfile_label.setText(translate('BiblesPlugin.ImportWizardForm', 'SWORD zip-file:')) |
164 | + self.sword_folder_edit.setPlaceholderText(translate('BiblesPlugin.ImportWizardForm', |
165 | + 'Defaults to the standard SWORD data folder')) |
166 | + self.sword_zipbible_label.setText(translate('BiblesPlugin.ImportWizardForm', 'Bibles:')) |
167 | + self.sword_tab_widget.setTabText(self.sword_tab_widget.indexOf(self.sword_folder_tab), |
168 | + translate('BiblesPlugin.ImportWizardForm', 'Import from folder')) |
169 | + self.sword_tab_widget.setTabText(self.sword_tab_widget.indexOf(self.sword_zip_tab), |
170 | + translate('BiblesPlugin.ImportWizardForm', 'Import from Zip-file')) |
171 | + if PYSWORD_AVAILABLE: |
172 | + self.sword_disabled_label.setText('') |
173 | + else: |
174 | + self.sword_disabled_label.setText(translate('BiblesPlugin.ImportWizardForm', |
175 | + 'To import SWORD bibles the pysword python module must be ' |
176 | + 'installed. Please read the manual for instructions.')) |
177 | self.license_details_page.setTitle( |
178 | translate('BiblesPlugin.ImportWizardForm', 'License Details')) |
179 | self.license_details_page.setSubTitle(translate('BiblesPlugin.ImportWizardForm', |
180 | @@ -374,6 +469,9 @@ |
181 | if self.currentPage() == self.welcome_page: |
182 | return True |
183 | elif self.currentPage() == self.select_page: |
184 | + self.version_name_edit.clear() |
185 | + self.permissions_edit.clear() |
186 | + self.copyright_edit.clear() |
187 | if self.field('source_format') == BibleFormat.OSIS: |
188 | if not self.field('osis_location'): |
189 | critical_error_message_box(UiStrings().NFSs, WizardStrings.YouSpecifyFile % WizardStrings.OSIS) |
190 | @@ -410,6 +508,31 @@ |
191 | return False |
192 | else: |
193 | self.version_name_edit.setText(self.web_translation_combo_box.currentText()) |
194 | + elif self.field('source_format') == BibleFormat.SWORD: |
195 | + # Test the SWORD tab that is currently active |
196 | + if self.sword_tab_widget.currentIndex() == self.sword_tab_widget.indexOf(self.sword_folder_tab): |
197 | + if not self.field('sword_folder_path') and self.sword_bible_combo_box.count() == 0: |
198 | + critical_error_message_box(UiStrings().NFSs, |
199 | + WizardStrings.YouSpecifyFolder % WizardStrings.SWORD) |
200 | + self.sword_folder_edit.setFocus() |
201 | + return False |
202 | + key = self.sword_bible_combo_box.itemData(self.sword_bible_combo_box.currentIndex()) |
203 | + if 'description' in self.pysword_folder_modules_json[key]: |
204 | + self.version_name_edit.setText(self.pysword_folder_modules_json[key]['description']) |
205 | + if 'distributionlicense' in self.pysword_folder_modules_json[key]: |
206 | + self.permissions_edit.setText(self.pysword_folder_modules_json[key]['distributionlicense']) |
207 | + if 'copyright' in self.pysword_folder_modules_json[key]: |
208 | + self.copyright_edit.setText(self.pysword_folder_modules_json[key]['copyright']) |
209 | + elif self.sword_tab_widget.currentIndex() == self.sword_tab_widget.indexOf(self.sword_zip_tab): |
210 | + if not self.field('sword_zip_path'): |
211 | + critical_error_message_box(UiStrings().NFSs, WizardStrings.YouSpecifyFile % WizardStrings.SWORD) |
212 | + self.sword_zipfile_edit.setFocus() |
213 | + return False |
214 | + key = self.sword_zipbible_combo_box.itemData(self.sword_zipbible_combo_box.currentIndex()) |
215 | + if 'description' in self.pysword_zip_modules_json[key]: |
216 | + self.version_name_edit.setText(self.pysword_zip_modules_json[key]['description']) |
217 | + if 'distributionlicense' in self.pysword_zip_modules_json[key]: |
218 | + self.permissions_edit.setText(self.pysword_zip_modules_json[key]['distributionlicense']) |
219 | return True |
220 | elif self.currentPage() == self.license_details_page: |
221 | license_version = self.field('license_version') |
222 | @@ -531,6 +654,40 @@ |
223 | self.web_update_button.setEnabled(True) |
224 | self.web_progress_bar.setVisible(False) |
225 | |
226 | + def on_sword_browse_button_clicked(self): |
227 | + """ |
228 | + Show the file open dialog for the SWORD folder. |
229 | + """ |
230 | + self.get_folder(WizardStrings.OpenTypeFolder % WizardStrings.SWORD, self.sword_folder_edit, |
231 | + 'last directory import') |
232 | + if self.sword_folder_edit.text(): |
233 | + try: |
234 | + self.pysword_folder_modules = modules.SwordModules(self.sword_folder_edit.text()) |
235 | + self.pysword_folder_modules_json = self.pysword_folder_modules.parse_modules() |
236 | + bible_keys = self.pysword_folder_modules_json.keys() |
237 | + self.sword_bible_combo_box.clear() |
238 | + for key in bible_keys: |
239 | + self.sword_bible_combo_box.addItem(self.pysword_folder_modules_json[key]['description'], key) |
240 | + except: |
241 | + self.sword_bible_combo_box.clear() |
242 | + |
243 | + def on_sword_zipbrowse_button_clicked(self): |
244 | + """ |
245 | + Show the file open dialog for a SWORD zip-file. |
246 | + """ |
247 | + self.get_file_name(WizardStrings.OpenTypeFile % WizardStrings.SWORD, self.sword_zipfile_edit, |
248 | + 'last directory import') |
249 | + if self.sword_zipfile_edit.text(): |
250 | + try: |
251 | + self.pysword_zip_modules = modules.SwordModules(self.sword_zipfile_edit.text()) |
252 | + self.pysword_zip_modules_json = self.pysword_zip_modules.parse_modules() |
253 | + bible_keys = self.pysword_zip_modules_json.keys() |
254 | + self.sword_zipbible_combo_box.clear() |
255 | + for key in bible_keys: |
256 | + self.sword_zipbible_combo_box.addItem(self.pysword_zip_modules_json[key]['description'], key) |
257 | + except: |
258 | + self.sword_zipbible_combo_box.clear() |
259 | + |
260 | def register_fields(self): |
261 | """ |
262 | Register the bible import wizard fields. |
263 | @@ -543,6 +700,8 @@ |
264 | self.select_page.registerField('zefania_file', self.zefania_file_edit) |
265 | self.select_page.registerField('web_location', self.web_source_combo_box) |
266 | self.select_page.registerField('web_biblename', self.web_translation_combo_box) |
267 | + self.select_page.registerField('sword_folder_path', self.sword_folder_edit) |
268 | + self.select_page.registerField('sword_zip_path', self.sword_zipfile_edit) |
269 | self.select_page.registerField('proxy_server', self.web_server_edit) |
270 | self.select_page.registerField('proxy_username', self.web_user_edit) |
271 | self.select_page.registerField('proxy_password', self.web_password_edit) |
272 | @@ -565,6 +724,8 @@ |
273 | self.setField('csv_versefile', '') |
274 | self.setField('opensong_file', '') |
275 | self.setField('zefania_file', '') |
276 | + self.setField('sword_folder_path', '') |
277 | + self.setField('sword_zip_path', '') |
278 | self.setField('web_location', WebDownload.Crosswalk) |
279 | self.setField('web_biblename', self.web_translation_combo_box.currentIndex()) |
280 | self.setField('proxy_server', settings.value('proxy address')) |
281 | @@ -626,9 +787,21 @@ |
282 | language_id=language_id |
283 | ) |
284 | elif bible_type == BibleFormat.Zefania: |
285 | - # Import an Zefania bible. |
286 | + # Import a Zefania bible. |
287 | importer = self.manager.import_bible(BibleFormat.Zefania, name=license_version, |
288 | filename=self.field('zefania_file')) |
289 | + elif bible_type == BibleFormat.SWORD: |
290 | + # Import a SWORD bible. |
291 | + if self.sword_tab_widget.currentIndex() == self.sword_tab_widget.indexOf(self.sword_folder_tab): |
292 | + importer = self.manager.import_bible(BibleFormat.SWORD, name=license_version, |
293 | + sword_path=self.field('sword_folder_path'), |
294 | + sword_key=self.sword_bible_combo_box.itemData( |
295 | + self.sword_bible_combo_box.currentIndex())) |
296 | + else: |
297 | + importer = self.manager.import_bible(BibleFormat.SWORD, name=license_version, |
298 | + sword_path=self.field('sword_zip_path'), |
299 | + sword_key=self.sword_zipbible_combo_box.itemData( |
300 | + self.sword_zipbible_combo_box.currentIndex())) |
301 | if importer.do_import(license_version): |
302 | self.manager.save_meta_data(license_version, license_version, license_copyright, license_permissions) |
303 | self.manager.reload_bibles() |
304 | |
305 | === modified file 'openlp/plugins/bibles/lib/manager.py' |
306 | --- openlp/plugins/bibles/lib/manager.py 2016-04-05 17:10:51 +0000 |
307 | +++ openlp/plugins/bibles/lib/manager.py 2016-04-26 19:04:37 +0000 |
308 | @@ -31,7 +31,10 @@ |
309 | from .opensong import OpenSongBible |
310 | from .osis import OSISBible |
311 | from .zefania import ZefaniaBible |
312 | - |
313 | +try: |
314 | + from .sword import SwordBible |
315 | +except: |
316 | + pass |
317 | |
318 | log = logging.getLogger(__name__) |
319 | |
320 | @@ -46,6 +49,7 @@ |
321 | OpenSong = 2 |
322 | WebDownload = 3 |
323 | Zefania = 4 |
324 | + SWORD = 5 |
325 | |
326 | @staticmethod |
327 | def get_class(bible_format): |
328 | @@ -64,6 +68,8 @@ |
329 | return HTTPBible |
330 | elif bible_format == BibleFormat.Zefania: |
331 | return ZefaniaBible |
332 | + elif bible_format == BibleFormat.SWORD: |
333 | + return SwordBible |
334 | else: |
335 | return None |
336 | |
337 | @@ -78,6 +84,7 @@ |
338 | BibleFormat.OpenSong, |
339 | BibleFormat.WebDownload, |
340 | BibleFormat.Zefania, |
341 | + BibleFormat.SWORD |
342 | ] |
343 | |
344 | |
345 | |
346 | === added file 'openlp/plugins/bibles/lib/sword.py' |
347 | --- openlp/plugins/bibles/lib/sword.py 1970-01-01 00:00:00 +0000 |
348 | +++ openlp/plugins/bibles/lib/sword.py 2016-04-26 19:04:37 +0000 |
349 | @@ -0,0 +1,100 @@ |
350 | +# -*- coding: utf-8 -*- |
351 | +# vim: autoindent shiftwidth=4 expandtab textwidth=120 tabstop=4 softtabstop=4 |
352 | + |
353 | +############################################################################### |
354 | +# OpenLP - Open Source Lyrics Projection # |
355 | +# --------------------------------------------------------------------------- # |
356 | +# Copyright (c) 2008-2016 OpenLP Developers # |
357 | +# --------------------------------------------------------------------------- # |
358 | +# This program is free software; you can redistribute it and/or modify it # |
359 | +# under the terms of the GNU General Public License as published by the Free # |
360 | +# Software Foundation; version 2 of the License. # |
361 | +# # |
362 | +# This program is distributed in the hope that it will be useful, but WITHOUT # |
363 | +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or # |
364 | +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for # |
365 | +# more details. # |
366 | +# # |
367 | +# You should have received a copy of the GNU General Public License along # |
368 | +# with this program; if not, write to the Free Software Foundation, Inc., 59 # |
369 | +# Temple Place, Suite 330, Boston, MA 02111-1307 USA # |
370 | +############################################################################### |
371 | + |
372 | +import logging |
373 | +from pysword import modules |
374 | + |
375 | +from openlp.core.common import translate |
376 | +from openlp.core.lib.ui import critical_error_message_box |
377 | +from openlp.plugins.bibles.lib.db import BibleDB, BiblesResourcesDB |
378 | + |
379 | + |
380 | +log = logging.getLogger(__name__) |
381 | + |
382 | + |
383 | +class SwordBible(BibleDB): |
384 | + """ |
385 | + SWORD Bible format importer class. |
386 | + """ |
387 | + def __init__(self, parent, **kwargs): |
388 | + """ |
389 | + Constructor to create and set up an instance of the SwordBible class. This class is used to import Bibles |
390 | + from SWORD bible modules. |
391 | + """ |
392 | + log.debug(self.__class__.__name__) |
393 | + BibleDB.__init__(self, parent, **kwargs) |
394 | + self.sword_key = kwargs['sword_key'] |
395 | + self.sword_path = kwargs['sword_path'] |
396 | + if self.sword_path == '': |
397 | + self.sword_path = None |
398 | + |
399 | + def do_import(self, bible_name=None): |
400 | + """ |
401 | + Loads a Bible from SWORD module. |
402 | + """ |
403 | + log.debug('Starting SWORD import from "%s"' % self.sword_key) |
404 | + success = True |
405 | + try: |
406 | + pysword_modules = modules.SwordModules(self.sword_path) |
407 | + pysword_module_json = pysword_modules.parse_modules()[self.sword_key] |
408 | + bible = pysword_modules.get_bible_from_module(self.sword_key) |
409 | + language = pysword_module_json['lang'] |
410 | + language = language[language.find('.') + 1:] |
411 | + language_id = BiblesResourcesDB.get_language(language)['id'] |
412 | + self.save_meta('language_id', language_id) |
413 | + books = bible.get_structure().get_books() |
414 | + # Count number of books |
415 | + num_books = 0 |
416 | + if 'ot' in books: |
417 | + num_books += len(books['ot']) |
418 | + if 'nt' in books: |
419 | + num_books += len(books['nt']) |
420 | + self.wizard.progress_bar.setMaximum(num_books) |
421 | + # Import the bible |
422 | + for testament in books.keys(): |
423 | + for book in books[testament]: |
424 | + book_ref_id = self.get_book_ref_id_by_name(book.name, num_books, language_id) |
425 | + book_details = BiblesResourcesDB.get_book_by_id(book_ref_id) |
426 | + db_book = self.create_book(book_details['name'], book_ref_id, book_details['testament_id']) |
427 | + for chapter_number in range(1, book.num_chapters + 1): |
428 | + if self.stop_import_flag: |
429 | + break |
430 | + verses = bible.get_iter(book.name, chapter_number) |
431 | + verse_number = 0 |
432 | + for verse in verses: |
433 | + verse_number += 1 |
434 | + self.create_verse(db_book.id, chapter_number, verse_number, verse) |
435 | + self.wizard.increment_progress_bar( |
436 | + translate('BiblesPlugin.Sword', 'Importing %s...') % db_book.name) |
437 | + self.session.commit() |
438 | + self.application.process_events() |
439 | + except Exception as e: |
440 | + critical_error_message_box( |
441 | + message=translate('BiblesPlugin.SwordImport', 'An unexpected error happened while importing the SWORD ' |
442 | + 'bible, please report this to the OpenLP developers.\n' |
443 | + '%s' % e)) |
444 | + log.exception(str(e)) |
445 | + success = False |
446 | + if self.stop_import_flag: |
447 | + return False |
448 | + else: |
449 | + return success |
450 | |
451 | === modified file 'scripts/check_dependencies.py' |
452 | --- scripts/check_dependencies.py 2015-12-31 22:46:06 +0000 |
453 | +++ scripts/check_dependencies.py 2016-04-26 19:04:37 +0000 |
454 | @@ -102,6 +102,7 @@ |
455 | ('nose', '(testing framework)', True), |
456 | ('mock', '(testing module)', sys.version_info[1] < 3), |
457 | ('jenkins', '(access jenkins api - package name: jenkins-webapi)', True), |
458 | + ('pysword', '(import SWORD bibles)', True), |
459 | ] |
460 | |
461 | w = sys.stdout.write |
462 | |
463 | === added file 'tests/functional/openlp_plugins/bibles/test_swordimport.py' |
464 | --- tests/functional/openlp_plugins/bibles/test_swordimport.py 1970-01-01 00:00:00 +0000 |
465 | +++ tests/functional/openlp_plugins/bibles/test_swordimport.py 2016-04-26 19:04:37 +0000 |
466 | @@ -0,0 +1,109 @@ |
467 | +# -*- coding: utf-8 -*- |
468 | +# vim: autoindent shiftwidth=4 expandtab textwidth=120 tabstop=4 softtabstop=4 |
469 | + |
470 | +############################################################################### |
471 | +# OpenLP - Open Source Lyrics Projection # |
472 | +# --------------------------------------------------------------------------- # |
473 | +# Copyright (c) 2008-2016 OpenLP Developers # |
474 | +# --------------------------------------------------------------------------- # |
475 | +# This program is free software; you can redistribute it and/or modify it # |
476 | +# under the terms of the GNU General Public License as published by the Free # |
477 | +# Software Foundation; version 2 of the License. # |
478 | +# # |
479 | +# This program is distributed in the hope that it will be useful, but WITHOUT # |
480 | +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or # |
481 | +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for # |
482 | +# more details. # |
483 | +# # |
484 | +# You should have received a copy of the GNU General Public License along # |
485 | +# with this program; if not, write to the Free Software Foundation, Inc., 59 # |
486 | +# Temple Place, Suite 330, Boston, MA 02111-1307 USA # |
487 | +############################################################################### |
488 | +""" |
489 | +This module contains tests for the SWORD Bible importer. |
490 | +""" |
491 | + |
492 | +import os |
493 | +import json |
494 | +from unittest import TestCase, SkipTest |
495 | + |
496 | +from tests.functional import MagicMock, patch |
497 | +try: |
498 | + from openlp.plugins.bibles.lib.sword import SwordBible |
499 | +except ImportError: |
500 | + raise SkipTest('PySword is not installed, skipping SWORD test.') |
501 | +from openlp.plugins.bibles.lib.db import BibleDB |
502 | + |
503 | +TEST_PATH = os.path.abspath(os.path.join(os.path.dirname(__file__), |
504 | + '..', '..', '..', 'resources', 'bibles')) |
505 | + |
506 | + |
507 | +class TestSwordImport(TestCase): |
508 | + """ |
509 | + Test the functions in the :mod:`swordimport` module. |
510 | + """ |
511 | + |
512 | + def setUp(self): |
513 | + self.registry_patcher = patch('openlp.plugins.bibles.lib.db.Registry') |
514 | + self.registry_patcher.start() |
515 | + self.manager_patcher = patch('openlp.plugins.bibles.lib.db.Manager') |
516 | + self.manager_patcher.start() |
517 | + |
518 | + def tearDown(self): |
519 | + self.registry_patcher.stop() |
520 | + self.manager_patcher.stop() |
521 | + |
522 | + def create_importer_test(self): |
523 | + """ |
524 | + Test creating an instance of the Sword file importer |
525 | + """ |
526 | + # GIVEN: A mocked out "manager" |
527 | + mocked_manager = MagicMock() |
528 | + |
529 | + # WHEN: An importer object is created |
530 | + importer = SwordBible(mocked_manager, path='.', name='.', filename='', sword_key='', sword_path='') |
531 | + |
532 | + # THEN: The importer should be an instance of BibleDB |
533 | + self.assertIsInstance(importer, BibleDB) |
534 | + |
535 | + @patch('openlp.plugins.bibles.lib.sword.SwordBible.application') |
536 | + @patch('openlp.plugins.bibles.lib.sword.modules') |
537 | + @patch('openlp.plugins.bibles.lib.db.BiblesResourcesDB') |
538 | + def simple_import_test(self, mocked_bible_res_db, mocked_pysword_modules, mocked_application): |
539 | + """ |
540 | + Test that a simple SWORD import works |
541 | + """ |
542 | + # GIVEN: Test files with a mocked out "manager", "import_wizard", and mocked functions |
543 | + # get_book_ref_id_by_name, create_verse, create_book, session and get_language. |
544 | + # Also mocked pysword structures |
545 | + mocked_manager = MagicMock() |
546 | + mocked_import_wizard = MagicMock() |
547 | + importer = SwordBible(mocked_manager, path='.', name='.', filename='', sword_key='', sword_path='') |
548 | + result_file = open(os.path.join(TEST_PATH, 'dk1933.json'), 'rb') |
549 | + test_data = json.loads(result_file.read().decode()) |
550 | + importer.wizard = mocked_import_wizard |
551 | + importer.get_book_ref_id_by_name = MagicMock() |
552 | + importer.create_verse = MagicMock() |
553 | + importer.create_book = MagicMock() |
554 | + importer.session = MagicMock() |
555 | + mocked_bible_res_db.get_language.return_value = 'Danish' |
556 | + mocked_bible = MagicMock() |
557 | + mocked_genesis = MagicMock() |
558 | + mocked_genesis.name = 'Genesis' |
559 | + mocked_genesis.num_chapters = 1 |
560 | + books = {'ot': [mocked_genesis]} |
561 | + mocked_structure = MagicMock() |
562 | + mocked_structure.get_books.return_value = books |
563 | + mocked_bible.get_structure.return_value = mocked_structure |
564 | + mocked_bible.get_iter.return_value = [verse[1] for verse in test_data['verses']] |
565 | + mocked_module = MagicMock() |
566 | + mocked_module.get_bible_from_module.return_value = mocked_bible |
567 | + mocked_pysword_modules.SwordModules.return_value = mocked_module |
568 | + |
569 | + # WHEN: Importing bible file |
570 | + importer.do_import() |
571 | + |
572 | + # THEN: The create_verse() method should have been called with each verse in the file. |
573 | + self.assertTrue(importer.create_verse.called) |
574 | + for verse_tag, verse_text in test_data['verses']: |
575 | + importer.create_verse.assert_any_call(importer.create_book().id, 1, int(verse_tag), verse_text) |
576 | |
577 | === modified file 'tests/interfaces/openlp_plugins/bibles/forms/test_bibleimportform.py' |
578 | --- tests/interfaces/openlp_plugins/bibles/forms/test_bibleimportform.py 2015-12-31 22:46:06 +0000 |
579 | +++ tests/interfaces/openlp_plugins/bibles/forms/test_bibleimportform.py 2016-04-26 19:04:37 +0000 |
580 | @@ -27,7 +27,7 @@ |
581 | from PyQt5 import QtWidgets |
582 | |
583 | from openlp.core.common import Registry |
584 | -from openlp.plugins.bibles.forms.bibleimportform import BibleImportForm, WebDownload |
585 | +import openlp.plugins.bibles.forms.bibleimportform as bibleimportform |
586 | |
587 | from tests.helpers.testmixin import TestMixin |
588 | from tests.functional import MagicMock, patch |
589 | @@ -46,7 +46,8 @@ |
590 | self.setup_application() |
591 | self.main_window = QtWidgets.QMainWindow() |
592 | Registry().register('main_window', self.main_window) |
593 | - self.form = BibleImportForm(self.main_window, MagicMock(), MagicMock()) |
594 | + bibleimportform.PYSWORD_AVAILABLE = False |
595 | + self.form = bibleimportform.BibleImportForm(self.main_window, MagicMock(), MagicMock()) |
596 | |
597 | def tearDown(self): |
598 | """ |
599 | @@ -76,3 +77,16 @@ |
600 | |
601 | # THEN: The webbible list should still be empty |
602 | self.assertEqual(self.form.web_bible_list, {}, 'The webbible list should be empty') |
603 | + |
604 | + def custom_init_test(self): |
605 | + """ |
606 | + Test that custom_init works as expected if pysword is unavailable |
607 | + """ |
608 | + # GIVEN: A mocked sword_tab_widget |
609 | + self.form.sword_tab_widget = MagicMock() |
610 | + |
611 | + # WHEN: Running custom_init |
612 | + self.form.custom_init() |
613 | + |
614 | + # THEN: sword_tab_widget.setDisabled(True) should have been called |
615 | + self.form.sword_tab_widget.setDisabled.assert_called_with(True) |
lp:~tomasgroth/openlp/pysword-import (revision 2588) /ci.openlp. io/job/ Branch- 01-Pull/ 1468/ /ci.openlp. io/job/ Branch- 02-Functional- Tests/1384/ /ci.openlp. io/job/ Branch- 03-Interface- Tests/1322/ /ci.openlp. io/job/ Branch- 04a-Windows_ Functional_ Tests/1124/ /ci.openlp. io/job/ Branch- 04b-Windows_ Interface_ Tests/715/ /ci.openlp. io/job/ Branch- 05a-Code_ Analysis/ 782/ /ci.openlp. io/job/ Branch- 05b-Test_ Coverage/ 650/
[SUCCESS] https:/
[SUCCESS] https:/
[SUCCESS] https:/
[SUCCESS] https:/
[SUCCESS] https:/
[SUCCESS] https:/
[SUCCESS] https:/