def question_apply(self): """ Show confirm question message box before applying hosts file. :return: A flag indicating whether user has accepted to continue the operations or not. ====== ========= return Operation ====== ========= True Continue False Cancel ====== ========= :rtype: bool """ msg_title = unicode(_translate("Util", "Notice", None)) msg = unicode(_translate("Util", "Are you sure you want to apply changes \n" "to the hosts file on your system?\n\n" "This operation could not be reverted if \n" "you have not made a backup of your \n" "current hosts file.", None)) choice = QtGui.QMessageBox.question( self, msg_title, msg, QtGui.QMessageBox.Yes | QtGui.QMessageBox.No, QtGui.QMessageBox.No ) if choice == QtGui.QMessageBox.Yes: return True else: return False
def info_complete(self): """ Draw operation complete message box. """ QtGui.QMessageBox.information( self, _translate("Util", "Complete", None), _translate("Util", "Operation completed", None))
def finish_make(self, time, count): """ Start operations after making new hosts file. .. note:: This method is the slot responses to the fina_trigger signal values :attr:`time`, :attr:`count` from an instance of :class:`~gui._make.QSubMakeHosts` class while making operations are finished. :param time: Total time uesd while generating the new hosts file. :type time: str :param count: Total number of hosts entries inserted into the new hosts file. :type count: int .. seealso:: :attr:`fina_trigger` in :class:`~gui._make.QSubMakeHosts` class. """ self.set_make_finish_btns() RetrieveData.connect_db() msg = unicode( _translate("Util", "Notice: %i hosts entries has " "\n been applied in %ssecs.", None))\ % (count, time) self.set_make_message(msg) self.set_down_progress(100, unicode( _translate("Util", "Operation Completed Successfully!", None)))
def set_make_progress(self, mod_name, mod_num): """ Start operations to show progress while making hosts file. .. note:: This method is the slot responses to the info_trigger signal :attr:`mod_name`, :attr:`mod_num` from an instance of :class:`~gui._make.QSubMakeHosts` class while making operations are proceeding. :param mod_name: Tag of a specified hosts module in current progress. :type mod_name: str :param mod_num: Number of current module in the operation sequence. :type mod_num: int .. seealso:: :attr:`info_trigger` in :class:`~gui._make.QSubMakeHosts` class. """ total_mods_num = self._funcs[self._ipv_id].count(1) + 1 prog = 100 * mod_num / total_mods_num self.ui.Prog.setProperty("value", prog) module = unicode(_translate("Util", mod_name, None)) message = unicode(_translate( "Util", "Applying module: %s(%s/%s)", None) ) % (module, mod_num, total_mods_num) self.ui.Prog.setFormat(message) self.set_make_message(message)
def move_hosts(self): """ Move hosts file to the system path after making. .. note:: This method is the slot responses to the move_trigger signal from an instance of :class:`~gui._make.QSubMakeHosts` class while making operations are finished. .. seealso:: :attr:`move_trigger` in :class:`~gui._make.QSubMakeHosts`. """ filepath = "hosts" msg = unicode( _translate("Util", "Copying new hosts file to\n" "%s", None)) % self.hosts_path self.set_make_message(msg) try: shutil.copy2(filepath, self.hosts_path) except IOError: self.warning_permission() os.remove(filepath) return except OSError: pass msg = unicode(_translate("Util", "Remove temporary file", None)) self.set_make_message(msg) os.remove(filepath) msg = unicode(_translate("Util", "Operation completed", None)) self.set_make_message(msg) self.info_complete()
def move_hosts(self): """ Move hosts file to the system path after making. .. note:: This method is the slot responses to the move_trigger signal from an instance of :class:`~gui._make.QSubMakeHosts` class while making operations are finished. .. seealso:: :attr:`move_trigger` in :class:`~gui._make.QSubMakeHosts`. """ filepath = "hosts" msg = unicode( _translate("Util", "Copying new hosts file to\n" "%s", None)) % self.hosts_path self.set_make_message(msg) try: shutil.copy2(filepath, self.hosts_path) except IOError: self.warning_permission() os.remove(filepath) return except OSError: pass msg = unicode( _translate("Util", "Remove temporary file", None)) self.set_make_message(msg) os.remove(filepath) msg = unicode( _translate("Util", "Operation completed", None)) self.set_make_message(msg) self.info_complete()
def info_uptodate(self): """ Draw data file is up-to-date message box. """ QtGui.QMessageBox.information( self, _translate("Util", "Notice", None), _translate("Util", "Data file is up-to-date.", None))
def finish_make(self, time, count): """ Start operations after making new hosts file. .. note:: This method is the slot responses to the fina_trigger signal values :attr:`time`, :attr:`count` from an instance of :class:`~gui._make.QSubMakeHosts` class while making operations are finished. :param time: Total time uesd while generating the new hosts file. :type time: str :param count: Total number of hosts entries inserted into the new hosts file. :type count: int .. seealso:: :attr:`fina_trigger` in :class:`~gui._make.QSubMakeHosts` class. """ self.set_make_finish_btns() RetrieveData.connect_db() msg = unicode( _translate("Util", "Notice: %i hosts entries has " "\n been applied in %ssecs.", None))\ % (count, time) self.set_make_message(msg) self.set_down_progress( 100, unicode( _translate("Util", "Operation Completed Successfully!", None)))
def warning_download(self): """ Show download error warning message box. """ QtGui.QMessageBox.warning( self, _translate("Util", "Warning", None), _translate("Util", "Error retrieving data from the server.\n" "Please try another server.", None))
def warning_permission(self): """ Show permission error warning message box. """ QtGui.QMessageBox.warning( self, _translate("Util", "Warning", None), _translate("Util", "You do not have permissions to change the \n" "hosts file.\n" "Please run this program as Administrator/root\n" "so it can modify your hosts file." , None))
def export_hosts(self): """ Display the export dialog and get the path to save the exported hosts file. :return: Path to export a hosts file. :rtype: str """ filename = "hosts" if self.platform == "OS X": filename = "/Users/" + filename filepath = QtGui.QFileDialog.getSaveFileName( self, _translate("Util", "Export hosts", None), QtCore.QString(filename), _translate("Util", "hosts File", None)) return filepath
def set_make_message(self, message, start=0): """ List message for the current operating progress while making the new hosts file in function list. :param message: Message to be displayed in the function list. :type message: unicode :param start: A flag indicating whether the message is the first one in the making progress or not. Default value is `0`. ===== ============== start Status ===== ============== 0 Not the first. 1 First. ===== ============== :type start: int """ if start: self.ui.FunctionsBox.setTitle(_translate( "Util", "Progress", None)) self.ui.Functionlist.clear() item = QtGui.QListWidgetItem() item.setText("- " + message) item.setFlags(QtCore.Qt.ItemIsEnabled) self.ui.Functionlist.addItem(item)
def run(self): """ Start operations to retrieve the new hosts data file. """ self.prog_trigger.emit(0, unicode(_translate( "Util", "Connecting...", None))) self.fetch_file()
def finish_update(self, update): """ Start operations after checking update. .. note:: This method is the slot responses to the trigger signal value :attr:`update` from an instance of :class:`~gui._checkupdate.QSubChkUpdate` class while checking operations are finished. :param update: Metadata of the latest hosts data file on the server. :type update: dict .. seealso:: :attr:`trigger` in :class:`~gui._checkupdate.QSubChkUpdate` class. """ self._update = update self.set_label_text(self.ui.labelLatestData, update["version"]) if self._update["version"] == \ unicode(_translate("Util", "[Error]", None)): self.set_conn_status(0) else: self.set_conn_status(1) if self._down_flag: self.fetch_update_after_check() else: self.set_update_finish_btns()
def run(self): """ Start operations to retrieve the new hosts data file. """ self.prog_trigger.emit( 0, unicode(_translate("Util", "Connecting...", None))) self.fetch_file()
def set_mirrors(self): """ Set optional server list. """ for i, mirror in enumerate(self.mirrors): self.ui.SelectMirror.addItem(_fromUtf8("")) self.ui.SelectMirror.setItemText( i, _translate("Util", mirror["tag"], None)) self.set_platform_label()
def set_conn_status(self, status): """ Set the information of connection status to the current server selected. """ if status == -1: self.set_label_color(self.ui.labelConnStat, "BLACK") self.set_label_text(self.ui.labelConnStat, unicode( _translate("Util", "Checking...", None))) elif status in [0, 1]: if status: color, stat = "GREEN", unicode(_translate( "Util", "[OK]", None)) else: color, stat = "RED", unicode(_translate( "Util", "[Failed]", None)) self.set_label_color(self.ui.labelConnStat, color) self.set_label_text(self.ui.labelConnStat, stat)
def set_label_text(self, label, text): """ Set the :attr:`text` of a :attr:`label`. :param label: Label on the main dialog. :type: :class:`PyQt4.QtGui.QLabel` :param text: Message to be set on the label. :type text: unicode """ label.setText(_translate("Util", text, None))
def on_Backup_clicked(self): """ Backup the hosts file of current operating system. .. note:: This method is the slot responses to the signal from ButtonBackup widget while the button is clicked. """ l_time = time.localtime(time.time()) backtime = time.strftime("%Y-%m-%d-%H%M%S", l_time) filename = "hosts_" + backtime + ".bak" if self.platform == "OS X": filename = "/Users/" + filename filepath = QtGui.QFileDialog.getSaveFileName( self, _translate("Util", "Backup hosts", None), QtCore.QString(filename), _translate("Util", "Backup File(*.bak)", None)) if unicode(filepath) != u'': shutil.copy2(self.hosts_path, unicode(filepath)) self.info_complete()
def finish_fetch(self, refresh=1, error=0): """ Start operations after downloading data file. .. note:: This method is the slot responses to the finish_trigger signal :attr:`refresh`, :attr:`error` from an instance of :class:`~gui._update.QSubFetchUpdate` class while downloading is finished. :param refresh: An flag indicating whether the downloading progress is successfully finished or not. Default by 1. :type refresh: int. :param error: An flag indicating whether the downloading progress is successfully finished or not. Default by 0. :type error: int .. seealso:: :attr:`finish_trigger` in :class:`~gui._update.QSubFetchUpdate` class. """ self._down_flag = 0 if error: # Error occurred while downloading self.set_down_progress(0, unicode(_translate("Util", "Error", None))) try: os.remove(self.filename) except: pass self.warning_download() msg_title = "Warning" msg = unicode( _translate( "Util", "Incorrect Data file!\n" "Please use the \"Download\" key to \n" "fetch a new data file.", None)) self.set_message(msg_title, msg) self.set_conn_status(0) else: # Data file retrieved successfully self.set_down_progress( 100, unicode(_translate("Util", "Download Complete", None))) self.refresh_info(refresh) self.set_fetch_finish_btns(error)
def check_update(self): """ Retrieve the metadata of the latest data file from a server. """ self.set_update_start_btns() self.set_label_text(self.ui.labelLatestData, unicode(_translate("Util", "Checking...", None))) thread = QSubChkUpdate(self) thread.trigger.connect(self.finish_update) thread.start()
def check_update(self): """ Retrieve the metadata of the latest data file from a server. """ self.set_update_start_btns() self.set_label_text(self.ui.labelLatestData, unicode( _translate("Util", "Checking...", None))) thread = QSubChkUpdate(self) thread.trigger.connect(self.finish_update) thread.start()
def finish_fetch(self, refresh=1, error=0): """ Start operations after downloading data file. .. note:: This method is the slot responses to the finish_trigger signal :attr:`refresh`, :attr:`error` from an instance of :class:`~gui._update.QSubFetchUpdate` class while downloading is finished. :param refresh: An flag indicating whether the downloading progress is successfully finished or not. Default by 1. :type refresh: int. :param error: An flag indicating whether the downloading progress is successfully finished or not. Default by 0. :type error: int .. seealso:: :attr:`finish_trigger` in :class:`~gui._update.QSubFetchUpdate` class. """ self._down_flag = 0 if error: # Error occurred while downloading self.set_down_progress(0, unicode( _translate("Util", "Error", None))) try: os.remove(self.filename) except: pass self.warning_download() msg_title = "Warning" msg = unicode( _translate("Util", "Incorrect Data file!\n" "Please use the \"Download\" key to \n" "fetch a new data file.", None)) self.set_message(msg_title, msg) self.set_conn_status(0) else: # Data file retrieved successfully self.set_down_progress(100, unicode( _translate("Util", "Download Complete", None))) self.refresh_info(refresh) self.set_fetch_finish_btns(error)
def fetch_update_after_check(self): """ Decide whether to retrieve a new data file from server or not after checking update information from a mirror. """ if self._update["version"] == \ unicode(_translate("Util", "[Error]", None)): self.finish_fetch(error=1) elif self.new_version(): self.fetch_update() else: self.info_uptodate() self.finish_fetch()
def warning_no_datafile(self): """ Show no data file warning message box. """ msg_title = "Warning" msg = unicode(_translate("Util", "Data file not found!\n" "Please use the \"Download\" key to \n" "fetch a new data file.", None)) self.set_message(unicode(msg_title), msg) self.ui.ButtonApply.setEnabled(False) self.ui.ButtonANSI.setEnabled(False) self.ui.ButtonUTF.setEnabled(False)
def on_CheckUpdate_clicked(self): """ Retrieve update information (metadata) of the latest data file from a specified server. .. note:: This method is the slot responses to the signal from ButtonCheck widget while the button is clicked. """ if self.choice != [[], []]: self.refresh_func_list() self.set_update_click_btns() if self._update == {} or self._update["version"] == \ unicode(_translate("Util", "[Error]", None)): self.check_update()
def set_message(self, title, message): """ Show a message box with a :attr:`message` and a :attr:`title`. :param title: Title of the message box to be displayed. :type title: unicode :param message: Message in the message box. :type message: unicode """ self.ui.FunctionsBox.setTitle(_translate("Util", title, None)) self.ui.Functionlist.clear() item = QtGui.QListWidgetItem() item.setText(message) item.setFlags(QtCore.Qt.ItemIsEnabled) self.ui.Functionlist.addItem(item)
def run(self): """ Start operations to retrieve the metadata of the latest hosts data file. """ try: socket.setdefaulttimeout(5) urlobj = urllib.urlopen(self.url) j_str = urlobj.read() urlobj.close() info = json.loads(j_str) self.trigger.emit(info) except: info = {"version": unicode(_translate("Util", "[Error]", None))} self.trigger.emit(info)
def on_Restore_clicked(self): """ Restore a previously backed up hosts file. .. note:: This method is the slot responses to the signal from ButtonRestore widget while the button is clicked. This method would call .. note:: No operations would be called if current session does not have the privileges to change the hosts file. """ if not self._writable: self.warning_permission() return filename = '' if self.platform == "OS X": filename = "/Users/" + filename filepath = QtGui.QFileDialog.getOpenFileName( self, _translate("Util", "Restore hosts", None), QtCore.QString(filename), _translate("Util", "Backup File(*.bak)", None)) if unicode(filepath) != u'': shutil.copy2(unicode(filepath), self.hosts_path) self.info_complete()
def refresh_func_list(self): """ Refresh the items in the function list by user settings. """ ip_flag = self._ipv_id self.ui.Functionlist.clear() for f_id, func in enumerate(self.choice[self._ipv_id]): item = QtGui.QListWidgetItem() if self._funcs[ip_flag][f_id] == 1: check = QtCore.Qt.Checked else: check = QtCore.Qt.Unchecked item.setCheckState(check) item.setText(_translate("Util", func[3], None)) self.ui.Functionlist.addItem(item)
def set_progress(self, done, block, total): """ Send message to the main dialog to set the progress bar. :param done: Block count of packaged retrieved. :type done: int :param block: Block size of the data pack retrieved. :type block: int :param total: Total size of the hosts data file. :type total: int """ done = done * block if total <= 0: total = self.filesize prog = 100 * done / total done = CommonUtil.convert_size(done) total = CommonUtil.convert_size(total) text = unicode(_translate("Util", "Downloading: %s / %s", None)) % (done, total) self.prog_trigger.emit(prog, text)
def set_progress(self, done, block, total): """ Send message to the main dialog to set the progress bar. :param done: Block count of packaged retrieved. :type done: int :param block: Block size of the data pack retrieved. :type block: int :param total: Total size of the hosts data file. :type total: int """ done = done * block if total <= 0: total = self.filesize prog = 100 * done / total done = CommonUtil.convert_size(done) total = CommonUtil.convert_size(total) text = unicode(_translate( "Util", "Downloading: %s / %s", None)) % (done, total) self.prog_trigger.emit(prog, text)
def make_hosts(self, mode="system"): """ Make a new hosts file for current system. :param mode: Operation mode for making hosts file. The valid value could be one of `system`, `ansi`, and `utf-8`. Default by `system`. :type mode: str """ self.set_make_start_btns() self.set_make_message(unicode(_translate( "Util", "Building hosts file...", None)), 1) # Avoid conflict while making hosts file RetrieveData.disconnect_db() self.make_mode = mode self.set_config_bytes(mode) thread = QSubMakeHosts(self) thread.info_trigger.connect(self.set_make_progress) thread.fina_trigger.connect(self.finish_make) thread.move_trigger.connect(self.move_hosts) thread.start()
def make_hosts(self, mode="system"): """ Make a new hosts file for current system. :param mode: Operation mode for making hosts file. The valid value could be one of `system`, `ansi`, and `utf-8`. Default by `system`. :type mode: str """ self.set_make_start_btns() self.set_make_message( unicode(_translate("Util", "Building hosts file...", None)), 1) # Avoid conflict while making hosts file RetrieveData.disconnect_db() self.make_mode = mode self.set_config_bytes(mode) thread = QSubMakeHosts(self) thread.info_trigger.connect(self.set_make_progress) thread.fina_trigger.connect(self.finish_make) thread.move_trigger.connect(self.move_hosts) thread.start()
def set_func_list(self, new=0): """ Draw the function list and decide whether to load the default selection configuration or not. :param new: A flag indicating whether to load the default selection configuration or not. Default value is `0`. === =================== new Operation === =================== 0 Use user config. 1 Use default config. === =================== :type new: int """ self.ui.Functionlist.clear() self.ui.FunctionsBox.setTitle(_translate( "Util", "Functions", None)) if new: for ip in range(2): choice, defaults, slices = RetrieveData.get_choice(ip) if self.custom is None: # fix bug that "self.custom" is None self.custom = "custom.hosts" # as above if os.path.isfile(self.custom): choice.insert(0, [4, 1, 0, "customize"]) defaults[0x04] = [1] for i in range(len(slices)): slices[i] += 1 slices.insert(0, 0) self.choice[ip] = choice self.slices[ip] = slices funcs = [] for func in choice: if func[1] in defaults[func[0]]: funcs.append(1) else: funcs.append(0) self._funcs[ip] = funcs
def set_func_list(self, new=0): """ Draw the function list and decide whether to load the default selection configuration or not. :param new: A flag indicating whether to load the default selection configuration or not. Default value is `0`. === =================== new Operation === =================== 0 Use user config. 1 Use default config. === =================== :type new: int """ self.ui.Functionlist.clear() self.ui.FunctionsBox.setTitle(_translate( "Util", "Functions", None)) if new: for ip in range(2): choice, defaults, slices = RetrieveData.get_choice(ip) if os.path.isfile(self.custom): choice.insert(0, [4, 1, 0, "customize"]) defaults[0x04] = [1] for i in range(len(slices)): slices[i] += 1 slices.insert(0, 0) self.choice[ip] = choice self.slices[ip] = slices funcs = [] for func in choice: if func[1] in defaults[func[0]]: funcs.append(1) else: funcs.append(0) self._funcs[ip] = funcs
def on_FetchUpdate_clicked(self): """ Retrieve the latest hosts data file. .. note:: This method is the slot responses to the signal from ButtonUpdate widget while the button is clicked. This method would call operations to .. note:: Method :meth:`~gui.qdialog_slots.on_CheckUpdate_clicked` would be called if no update information has been set, .. note:: If the current data is up-to-date, no data file would be retrieved. """ self.set_fetch_click_btns() self._down_flag = 1 if self._update == {} or self._update["version"] == \ unicode(_translate("Util", "[Error]", None)): self.check_update() elif self.new_version(): self.fetch_update() else: self.info_uptodate() self.finish_fetch()
# this program. If not, see <http://www.gnu.org/licenses/>. # # This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING # THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR # PURPOSE. # ===================================================================== __author__ = "huhamhire <*****@*****.**>" from util_ui import _translate # Name of items from the function list to be localized # __list_trans (list): A list containing names of function list items # for translator to translate. __list_trans = [ _translate("Util", "customize", None), _translate("Util", "google", None), _translate("Util", "google-apis", None), _translate("Util", "google(cn)", None), _translate("Util", "google(hk)", None), _translate("Util", "google(us)", None), _translate("Util", "google-apis(cn)", None), _translate("Util", "google-apis(us)", None), _translate("Util", "activation-helper", None), _translate("Util", "facebook", None), _translate("Util", "twitter", None), _translate("Util", "youtube", None), _translate("Util", "wikipedia", None), _translate("Util", "institutions", None), _translate("Util", "steam", None), _translate("Util", "github", None),