From ecc30163af2461e56e897b102ef047ef540264cd Mon Sep 17 00:00:00 2001 From: Tomas Groth Date: Tue, 24 Feb 2015 23:04:01 +0000 Subject: [PATCH] Reverted some things to decrease the changes. It is now working. --- .../plugins/bibles/forms/bibleimportform.py | 119 +++++++++--------- .../bibles/resources/bibles_resources.sqlite | Bin 112640 -> 104448 bytes 2 files changed, 57 insertions(+), 62 deletions(-) diff --git a/openlp/plugins/bibles/forms/bibleimportform.py b/openlp/plugins/bibles/forms/bibleimportform.py index ee4b01c35..ac80434ca 100644 --- a/openlp/plugins/bibles/forms/bibleimportform.py +++ b/openlp/plugins/bibles/forms/bibleimportform.py @@ -24,6 +24,7 @@ The bible import functions for OpenLP """ import logging import os +import urllib.error from PyQt4 import QtGui @@ -91,7 +92,6 @@ class BibleImportForm(OpenLPWizard): Perform any custom initialisation for bible importing. """ self.manager.set_process_dialog(self) - self.load_Web_Bibles() self.restart() self.select_stack.setCurrentIndex(0) @@ -99,7 +99,7 @@ class BibleImportForm(OpenLPWizard): """ Set up the signals used in the bible importer. """ - self.web_language_combo_box.currentIndexChanged.connect(self.on_web_language_combo_box_index_changed) + self.web_source_combo_box.currentIndexChanged.connect(self.on_web_source_combo_box_index_changed) self.osis_browse_button.clicked.connect(self.on_osis_browse_button_clicked) self.csv_books_button.clicked.connect(self.on_csv_books_browse_button_clicked) self.csv_verses_button.clicked.connect(self.on_csv_verses_browse_button_clicked) @@ -204,28 +204,33 @@ class BibleImportForm(OpenLPWizard): self.web_bible_tab.setObjectName('WebBibleTab') self.web_bible_layout = QtGui.QFormLayout(self.web_bible_tab) self.web_bible_layout.setObjectName('WebBibleLayout') - self.web_update_label = QtGui.QLabel(self.web_bible_tab) self.web_update_label.setObjectName('WebUpdateLabel') self.web_bible_layout.setWidget(0, QtGui.QFormLayout.LabelRole, self.web_update_label) self.web_update_button = QtGui.QPushButton(self.web_bible_tab) - self.web_update_button.setObjectName('WebUpdateLabel') + self.web_update_button.setObjectName('WebUpdateButton') self.web_bible_layout.setWidget(0, QtGui.QFormLayout.FieldRole, self.web_update_button) - self.web_source_label = QtGui.QLabel(self.web_bible_tab) self.web_source_label.setObjectName('WebSourceLabel') self.web_bible_layout.setWidget(1, QtGui.QFormLayout.LabelRole, self.web_source_label) - self.web_language_combo_box = QtGui.QComboBox(self.web_bible_tab) - self.web_language_combo_box.setObjectName('WebSourceComboBox') - self.web_language_combo_box.addItems(['', '', '']) - self.web_bible_layout.setWidget(1, QtGui.QFormLayout.FieldRole, self.web_language_combo_box) + self.web_source_combo_box = QtGui.QComboBox(self.web_bible_tab) + self.web_source_combo_box.setObjectName('WebSourceComboBox') + self.web_source_combo_box.addItems(['', '', '']) + self.web_source_combo_box.setEnabled(False) + self.web_bible_layout.setWidget(1, QtGui.QFormLayout.FieldRole, self.web_source_combo_box) self.web_translation_label = QtGui.QLabel(self.web_bible_tab) self.web_translation_label.setObjectName('web_translation_label') self.web_bible_layout.setWidget(2, QtGui.QFormLayout.LabelRole, self.web_translation_label) self.web_translation_combo_box = QtGui.QComboBox(self.web_bible_tab) self.web_translation_combo_box.setSizeAdjustPolicy(QtGui.QComboBox.AdjustToContents) self.web_translation_combo_box.setObjectName('WebTranslationComboBox') + self.web_translation_combo_box.setEnabled(False) self.web_bible_layout.setWidget(2, QtGui.QFormLayout.FieldRole, self.web_translation_combo_box) + self.web_progress_bar = QtGui.QProgressBar(self) + self.web_progress_bar.setRange(0, 3) + self.web_progress_bar.setObjectName('WebTranslationProgressBar') + self.web_progress_bar.setVisible(False) + self.web_bible_layout.setWidget(3, QtGui.QFormLayout.SpanningRole, self.web_progress_bar) self.web_tab_widget.addTab(self.web_bible_tab, '') self.web_proxy_tab = QtGui.QWidget() self.web_proxy_tab.setObjectName('WebProxyTab') @@ -326,7 +331,12 @@ class BibleImportForm(OpenLPWizard): self.zefania_file_label.setText(translate('BiblesPlugin.ImportWizardForm', 'Bible file:')) self.web_update_label.setText(translate('BiblesPlugin.ImportWizardForm', 'Click to fetch bible list')) self.web_update_button.setText(translate('BiblesPlugin.ImportWizardForm', 'Fetch list')) - #self.web_language_combo_box.setItemText(0, translate('BiblesPlugin.ImportWizardForm', 'Choose a language')) + self.web_source_combo_box.setItemText(WebDownload.Crosswalk, translate('BiblesPlugin.ImportWizardForm', + 'Crosswalk')) + self.web_source_combo_box.setItemText(WebDownload.BibleGateway, translate('BiblesPlugin.ImportWizardForm', + 'BibleGateway')) + self.web_source_combo_box.setItemText(WebDownload.Bibleserver, translate('BiblesPlugin.ImportWizardForm', + 'Bibleserver')) self.web_translation_label.setText(translate('BiblesPlugin.ImportWizardForm', 'Bible:')) self.web_tab_widget.setTabText(self.web_tab_widget.indexOf(self.web_bible_tab), translate('BiblesPlugin.ImportWizardForm', 'Download Options')) @@ -395,8 +405,11 @@ class BibleImportForm(OpenLPWizard): self.zefania_file_edit.setFocus() return False elif self.field('source_format') == BibleFormat.WebDownload: - self.version_name_edit.setText(self.web_translation_combo_box.currentText()) - return True + # If count is 0 the bible list has not yet been downloaded + if self.web_translation_combo_box.count() == 0: + return False + else: + self.version_name_edit.setText(self.web_translation_combo_box.currentText()) return True elif self.currentPage() == self.license_details_page: license_version = self.field('license_version') @@ -434,16 +447,17 @@ class BibleImportForm(OpenLPWizard): if self.currentPage() == self.progress_page: return True - def on_web_language_combo_box_index_changed(self, index): + def on_web_source_combo_box_index_changed(self, index): """ Setup the list of Bibles when you select a different source on the web download page. :param index: The index of the combo box. """ self.web_translation_combo_box.clear() - bibles = list(self.web_bible_list[index].keys()) - bibles.sort(key=get_locale_key) - self.web_translation_combo_box.addItems(bibles) + if self.web_bible_list: + bibles = list(self.web_bible_list[index].keys()) + bibles.sort(key=get_locale_key) + self.web_translation_combo_box.addItems(bibles) def on_osis_browse_button_clicked(self): """ @@ -484,29 +498,34 @@ class BibleImportForm(OpenLPWizard): def on_web_update_button_clicked(self): """ - Download list of bibles from Crosswalk, BibleServer and BibleGateway, and fill data in comboboxes + Download list of bibles from Crosswalk, BibleServer and BibleGateway. """ # Download from Crosswalk, BiblesGateway, BibleServer self.web_bible_list = {} - for (source, extractor) in ((WebDownload.Crosswalk, CWExtract()), (WebDownload.BibleGateway, BGExtract()), - (WebDownload.Bibleserver, BSExtract())): - bibles = extractor.get_bibles_from_http() + self.web_source_combo_box.setEnabled(False) + self.web_translation_combo_box.setEnabled(False) + self.web_progress_bar.setVisible(True) + self.web_progress_bar.setValue(0) + proxy_server = self.field('proxy_server') + for (download_type, extractor) in ((WebDownload.Crosswalk, CWExtract(proxy_server)), + (WebDownload.BibleGateway, BGExtract(proxy_server)), + (WebDownload.Bibleserver, BSExtract(proxy_server))): + try: + bibles = extractor.get_bibles_from_http() + except (urllib.error.URLError, ConnectionError) as err: + critical_error_message_box(translate('BiblesPlugin.ImportWizardForm', 'Error during download'), + translate('BiblesPlugin.ImportWizardForm', + 'An error occurred while downloading the list of bibles from %s.')) + self.web_bible_list[download_type] = {} for (bible_name, bible_key, language_code) in bibles: - if not language_code in self.web_bible_list: - self.web_bible_list[language_code] = {} - self.web_bible_list[language_code]['translations'] = [] - bible_language = BiblesResourcesDB.get_language(language_code) - if bible_language: - self.web_bible_list[language_code]['name'] = bible_language['name'] - self.web_bible_list[language_code]['native_name'] = bible_language['native_name'] - else: - self.web_bible_list[language_code]['name'] = language_code - self.web_bible_list[language_code]['native_name'] = language_code - self.web_bible_list[language_code]['translations'].append((source, bible_name, bible_key)) - # Update combo box - for key in self.web_bible_list.keys(): - self.web_language_combo_box.addItem(self.web_bible_list[key]['native_name'] + ' (' + - self.web_bible_list[key]['name'] + ')', userData=key) + self.web_bible_list[download_type][bible_name] = bible_key + self.web_progress_bar.setValue(download_type + 1) + # Update combo box if something got into the list + if self.web_bible_list: + self.on_web_source_combo_box_index_changed(0) + self.web_source_combo_box.setEnabled(True) + self.web_translation_combo_box.setEnabled(True) + self.web_progress_bar.setVisible(False) def register_fields(self): """ @@ -518,7 +537,7 @@ class BibleImportForm(OpenLPWizard): self.select_page.registerField('csv_versefile', self.csv_verses_edit) self.select_page.registerField('opensong_file', self.open_song_file_edit) self.select_page.registerField('zefania_file', self.zefania_file_edit) - self.select_page.registerField('web_language', self.web_language_combo_box) + self.select_page.registerField('web_location', self.web_source_combo_box) self.select_page.registerField('web_biblename', self.web_translation_combo_box) self.select_page.registerField('proxy_server', self.web_server_edit) self.select_page.registerField('proxy_username', self.web_user_edit) @@ -542,7 +561,7 @@ class BibleImportForm(OpenLPWizard): self.setField('csv_versefile', '') self.setField('opensong_file', '') self.setField('zefania_file', '') - self.setField('web_language', 0) + self.setField('web_location', WebDownload.Crosswalk) self.setField('web_biblename', self.web_translation_combo_box.currentIndex()) self.setField('proxy_server', settings.value('proxy address')) self.setField('proxy_username', settings.value('proxy username')) @@ -550,33 +569,9 @@ class BibleImportForm(OpenLPWizard): self.setField('license_version', self.version_name_edit.text()) self.setField('license_copyright', self.copyright_edit.text()) self.setField('license_permissions', self.permissions_edit.text()) - #self.on_web_language_combo_box_index_changed(WebDownload.Crosswalk) + self.on_web_source_combo_box_index_changed(WebDownload.Crosswalk) settings.endGroup() - def load_Web_Bibles(self): - """ - Load the lists of Crosswalk, BibleGateway and Bibleserver bibles. - """ - # Load Crosswalk Bibles. - self.load_Bible_Resource(WebDownload.Crosswalk) - # Load BibleGateway Bibles. - self.load_Bible_Resource(WebDownload.BibleGateway) - # Load and Bibleserver Bibles. - self.load_Bible_Resource(WebDownload.Bibleserver) - - def load_Bible_Resource(self, download_type): - """ - Loads a web bible from bible_resources.sqlite. - - :param download_type: The WebDownload type e.g. bibleserver. - """ - self.web_bible_list[download_type] = {} - bibles = BiblesResourcesDB.get_webbibles(WebDownload.Names[download_type]) - for bible in bibles: - version = bible['name'] - name = bible['abbreviation'] - self.web_bible_list[download_type][version] = name.strip() - def pre_wizard(self): """ Prepare the UI for the import. diff --git a/openlp/plugins/bibles/resources/bibles_resources.sqlite b/openlp/plugins/bibles/resources/bibles_resources.sqlite index 4b6686055f5de7a9382625806e1231266581ee74..8f1777124032ee11b547fd6e1897f7e9b8b717a9 100644 GIT binary patch delta 4349 zcmY*cYiv}<6+Uz4@_xiDcW>`5i?PARHnl0wmZXqiUd9-V!G;8yG_38lz1|n>+7M`( zNm@lJs#=1hq`#ty(l)B1v{9rqst9cm%8!Idq*BwWsE_ZPVGFh8 z-I;UFoacAWj8EU5e)`h%?=4zzQ$&XFSN&ObwsmdnrnG(JOasZ)x5!wb@959U5J&`>@&;f&8Tl{Q{Nh|ynbbcdZ4neGg0~X6~8i4 z8m*k$)m-^Q*Ys%vQjo#Q`CW}KB@&+X?-TmB`mTSUOfB&Kq$6v>8W7iJ@UgxFAI*)I zH@Zi<8zn3Hy1t?>>F4w*-LH4+H9F9abHn+a^Q!ZLGvVZ&gU)8B!I`T*R&T4<)Oj_b zM%6*JS+y!p{vp@ps$7=u%Y!hhvcMq4X!jAdJ2>Q83DB@ z{xU0_1}$$+ke-&BrLHW7bXrF7H-yii-jy~`lE_;TF{hwC1x`VNI&!vSKPH8RMh%Uo zu#GQqWp%Xj*{}VwUrS5d!5Bu&^lbzpd5J7`r9Qe1H5oHr<-zq5^mUu@-AWE(9a%)l zt#S(I=>Gt81aaElYCK9pgN=6t`yggH1+0;WGQ{Z>%jE}jWh+!LY#Yca?EEiSIu#}1 zhLulB+-DS9vCm0A%YD~O2K&0GE1RNQkl++f(AYT4RTJM2s_#*2c?%dt9I)ncI1pb* zwWMc}lO(v-`+n@a2s5w+G^VitH~X>n7f{s}$d!zHIh^Xp&a1J~X#`>Q^fR0Xtn>(T zTLyy#9z^>5`If=-(=f}?kF__?s!2lqF&s+acU=6rR+`ii$w0OU>7>-oapl2iyD5jI z5G>Y85>#(CwY4Kqx>+vbBZ*Bgi*;#-vJ&>yd{B8X({gN<=q#0u;EXrJs-h0Y%Tgj6 z)9F|{bX21zJtx65t0!yRysM`S1IHxpGUe?C`f0>Mm-5DuA*s=XJb6@3PTaB5{g9-I zQ+HjW6LpGpZx$<`mlmm$y*O8Z0|oOr4_)3ZFN^-0{#gHcYW{_P>8Yh|+;P+gQ%x^_ z5c6j_cSL`vf1`h{U(lf*((O9#+`+{9&{>`c0pHcJ1MuxAEaw3Ng1&%ykkSwW!tJri zhhA58<)tBTyD8RVAi*{wJ_(x=PK-c$5bGcWh+AS^(q!_--fJ>N9smm%Zi#in4xvKy zXJL`Mnh@ZP#r9y6!!JL*5U{N`B%(bn<(&BnLO_-VQpgtVeu|7_%q|fEx2t2jaGoj8 z!T^N|1}+1_L^aAG(Kq$m`ZeTYLT7cK-mF{AB)sjs@4Vq$be?mbb_Sh3%)(_(jk=?* zsb8s|sdK7+LiMVRs!`R*-{p$Dh%z05M*h@>XpHr-$=R={_>6`S{jfbc`S2^MZbog0 z9#|i%v|sb)5j7cE69WBD#43Ne=1u+r@?}2+@Ec>q*En-tXsFNHBeK0hPb9C*bkxq;Ml-14o$BtpAal+S}aLWj=4>@Km zWBB%tTXQKB0}D?SN5-u=du0?s8I0ngMNC{Gv6^w+OqUfN!>* ze~k2UFOrh_A2>>=hJTa{(%G9-&1{^IpuqTg;S#UO>Wx;y-p|_;c81v8@dEO445k+* z+0<4~LE>4Ku-CY9ybR;j8uGSbmo~@|N8iwI>R0vi`n2iN4LYG`I)8QEGd()tWbs!H_-Y{IfmI-r&v$=hof z&ICzom^E7n&xCpQ2$IfDGJQSUxzvd=Bv415*%he_|j3XeBl_>7wXOB`ZJ zCV&4E6|D0fqqjXUX2Hd42*`fa9;Jcm6N%St!$FhLXD%Y6kpnCeuhO(>Qw~nQkLUIx za|0$z45xr~yqAFO#=2;lWf)xY$o2NqgKjua-{=J!BeIX$yFsyYh{cZgP|F^iLB7lQ zqA=Cu@E6}(WoA*dq?w79hj(N*-QwlQkw<`}ai%DdJv2f(9U~2sW_MNAUVlVt4rk(B zRzF?j-7tCaf||QKva71WQgcXG(8+pID`^}VCCKNnO6+9f$zkmVO(4|>GIIGX*DWuV z9!Gzq-@^U+l0KtHb&uYt=R5y&t~J9Z{^&M4IkKE+SA;AOd*0_?2R(|--s&afaVcux~%5vJgvztpmRD2b= zJ8{rrhN+?q(G~d;L)i(6J;Tbhu4E)TVU+(BrI4cke>?H%lm@j08qo7?Zl_Vfrssg= zZ4tCGryZa$kG6m9^Thum11HDQnbBbwuU%mR?|wJFD$+uqI*e_;i8$B2X5yd&YYtBv gVM>A~nyH+=>cxWP)}pNxL#Gh_8J_yjyXxwH0gmNJFaQ7m delta 10724 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