def get_hosts(self, make_cfg): """ Make the new hosts file by the configuration defined by `make_cfg` from function list on the main dialog. :param make_cfg: Module settings in byte word format. :type make_cfg: dict .. seealso:: :attr:`make_cfg` in :class:`~tui.curses_d.CursesDaemon` class. """ for part_id in sorted(make_cfg.keys()): mod_cfg = make_cfg[part_id] if not RetrieveData.chk_mutex(part_id, mod_cfg): return mods = RetrieveData.get_ids(mod_cfg) for mod_id in mods: self.mod_num += 1 hosts, mod_name = RetrieveData.get_host(part_id, mod_id) self.info_trigger.emit(mod_name, self.mod_num) if part_id == 0x02: self.write_localhost_mod(hosts) elif part_id == 0x04: self.write_customized() else: self.write_common_mod(hosts, mod_name)
def __init__(self): """ Initialize a new TUI session. * Load server list from a configuration file under working directory. * Try to load the hosts data file under working directory if it exists. .. note:: IF hosts data file does not exists correctly in current working directory, a warning message box would popup. And operations to change the hosts file on current system could be done only until a new data file has been downloaded. .. seealso:: :meth:`~tui.curses_d.CursesDaemon.session_daemon` method in :class:`~tui.curses_d.CursesDaemon`. .. seealso:: :meth:`~gui.hostsutil.HostsUtil.init_main` in :class:`~gui.hostsutil.HostsUtil` class. """ super(HostsUtil, self).__init__() # Set mirrors self.settings[0][2] = CommonUtil.set_network("network.conf") # Read data file and set function list try: self.set_platform() RetrieveData.unpack() RetrieveData.connect_db() self.set_info() self.set_func_list() except IOError: self.messagebox("No data file found! Press F6 to get data file " "first.", 1) except BadZipfile: self.messagebox("Incorrect Data file! Press F6 to get a new data " "file first.", 1)
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 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 __del__(self): """ Clear up the temporary data file while TUI session is finished. """ try: RetrieveData.clear() except: pass
def __del__(self): """ Reset the terminal and clear up the temporary data file while TUI session is finished. """ super(HostsUtil, self).__del__() try: RetrieveData.clear() except: pass
def close(self): """ Close this program while the close signal is emitted. .. note:: This method is the slot responses to the close signal from an instance of the main dialog. """ try: RetrieveData.clear() except: pass super(QDialogDaemon, self).close()
def on_IPVersion_changed(self, ipv_id): """ Change the current IP version setting. .. note:: This method is the slot responses to the signal argument :attr:`ipv_id` from SelectIP widget while the value is changed. :param ipv_id: An flag indicating current IP version setting. The value could be 1 or 0: ====== ========== ipv_id IP Version ====== ========== 1 IPv6 0 IPv4 ====== ========== :type ipv_id: int """ if self._ipv_id != ipv_id: self._ipv_id = ipv_id if not RetrieveData.db_exists(): self.warning_no_datafile() else: self.set_func_list(0) self.refresh_func_list()
def set_func_list(self): """ Set the function selection list in TUI session. """ 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) defaults[0x40].append(1) #adblocks-hostsx defaults[0x40].append(2) #adblock-mvp if 0x10 in defaults: #http://stackoverflow.com/questions/4915920/how-to-delete-an-item-in-a-list-if-it-exists-python try: defaults[0x10].remove(256) #no github defaults[0x10].remove(32) #no wiki except ValueError: pass 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_info(self): """ Set the information of the current local data file. """ info = RetrieveData.get_info() build = info["Buildtime"] self.hostsinfo["Version"] = info["Version"] self.hostsinfo["Release"] = CommonUtil.timestamp_to_date(build)
def set_info(cls): """ Set the information of the current local data file. Modified from tui.hostsutil.HostsUtil.set_info() """ info = RetrieveData.get_info() build = info["Buildtime"] cls.hostsinfo["Version"] = info["Version"] cls.hostsinfo["Release"] = CommonUtil.timestamp_to_date(build)
def set_info(self): """ Set the information of the current local data file. """ info = RetrieveData.get_info() ver = info["Version"] self._cur_ver = ver self.set_label_text(self.ui.labelVersionData, ver) build = info["Buildtime"] build = CommonUtil.timestamp_to_date(build) self.set_label_text(self.ui.labelReleaseData, unicode(build))
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 refresh_info(self, refresh=0): """ Reload the data file information and show them on the main dialog. The information here includes both metadata and hosts module info from the data file. :param refresh: A flag indicating whether the information on main dialog needs to be reloaded or not. The value could be `0` or `1`. ======= ============= refresh operation ======= ============= 0 Do NOT reload 1 Reload ======= ============= :type refresh: int """ if refresh and RetrieveData.conn is not None: RetrieveData.clear() try: RetrieveData.unpack() RetrieveData.connect_db() self.set_func_list(refresh) self.refresh_func_list() self.set_info() except (BadZipfile, IOError, OSError): self.warning_incorrect_datafile()
def init_main(self): """ Set up the elements on the main dialog. Check the environment of current operating system and current session. * Load server list from a configuration file under working directory. * Try to load the hosts data file under working directory if it exists. .. note:: IF hosts data file does not exists correctly in current working directory, a warning message box would popup. And operations to change the hosts file on current system could be done only until a new data file has been downloaded. .. seealso:: Method :meth:`~tui.hostsutil.HostsUtil.__init__` in :class:`~tui.hostsutil.HostsUtil` class. """ self.ui.SelectMirror.clear() self.set_version() # Set mirrors self.mirrors = CommonUtil.set_network("network.conf") self.set_mirrors() # Read data file and set function list try: RetrieveData.unpack() RetrieveData.connect_db() self.set_func_list(1) self.refresh_func_list() self.set_info() except IOError: self.warning_no_datafile() except BadZipfile: self.warning_incorrect_datafile() # Check if current session have root privileges self.check_writable() self.init_flag += 1
def start(cls,silent=0,mode='system'): cls.make_mode=mode #Possible values are 'utf-8', 'ansi' and 'system'. cls.silent=silent cls.set_platform() cls.check_connection() cls.update = cls.check_update() if cls.check_version(): cls.show_status("Update found!") cls.fetch_update() RetrieveData.unpack() RetrieveData.connect_db() cls.set_func_list() cls.select_all() cls.set_config_bytes() mk=MakeHosts(cls) mk.make() RetrieveData.clear() return 1 else: cls.show_status("No update!") RetrieveData.clear() return 0
def set_func_list(self): """ Set the function selection list in TUI session. """ 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 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(cls): """ Set the function selection list in TUI session. Modified from tui.hostsutil.HostsUtil.set_func_list() """ for ip in range(2): choice, defaults, slices = RetrieveData.get_choice(ip) if os.path.isfile(cls.custom): choice.insert(0, [4, 1, 0, "customize"]) defaults[0x04] = [1] for i in range(len(slices)): slices[i] += 1 slices.insert(0, 0) cls.choice[ip] = choice cls.slices[ip] = slices funcs = [] for func in choice: if func[1] in defaults[func[0]]: funcs.append(1) else: funcs.append(0) cls.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_Selection_changed(self, item): """ Change the current selection of modules to be applied to hosts file. .. note:: This method is the slot responses to the signal argument :attr:`item` from Functionlist widget while the item selection is changed. :param item: Row number of the item listed in Functionlist which is changed by user. :type item: int """ ip_flag = self._ipv_id func_id = self.ui.Functionlist.row(item) if self._funcs[ip_flag][func_id] == 0: self._funcs[ip_flag][func_id] = 1 else: self._funcs[ip_flag][func_id] = 0 mutex = RetrieveData.get_ids(self.choice[ip_flag][func_id][2]) for c_id, c in enumerate(self.choice[ip_flag]): if c[0] == self.choice[ip_flag][func_id][0]: if c[1] in mutex and self._funcs[ip_flag][c_id] == 1: self._funcs[ip_flag][c_id] = 0 self.refresh_func_list()
def check_version(cls): """ Compare version of local data file to the version from the server. Modified from tui.curses_d.CursesDaemon.new_version() """ if not os.path.isfile(cls.filename): return 1 RetrieveData.unpack() RetrieveData.connect_db() cls.set_info() RetrieveData.disconnect_db() local_ver = cls.hostsinfo["Version"] server_ver = cls.update["version"] local_ver = local_ver.split('.') server_ver = server_ver.split('.') for i, ver_num in enumerate(local_ver): if server_ver[i] > ver_num: return 1 return 0
def select_func(self, pos=None, key_in=None): """ Perform operations if `function selection list` is active, or just draw the `function selection list` with no items selected while it is inactive. .. note:: Whether the `function selection list` is inactive is decided by if :attr:`pos` is `None` or not. .. seealso:: :meth:`~tui.curses_d.CursesDaemon.configure_settings`. :param pos: Index of selected item in `function selection list`. The default value of `pos` is `None`. :type pos: int or None :param key_in: A flag indicating the key pressed by user. The default value of `key_in` is `None`. :type key_in: int or None :return: Index of selected item in `function selection list`. :rtype: int or None """ list_height = 15 ip = self.settings[1][1] # Key Press Operations item_len = len(self.choice[ip]) item_sup, item_inf = self._item_sup, self._item_inf if pos is not None: if item_len > list_height: if pos <= 1: item_sup = 0 item_inf = list_height - 1 elif pos >= item_len - 2: item_sup = item_len - list_height + 1 item_inf = item_len else: item_sup = 0 item_inf = item_len if key_in == curses.KEY_DOWN: pos += 1 if pos >= item_len: pos = 0 if pos not in range(item_sup, item_inf): item_sup += 2 if item_sup == 0 else 1 item_inf += 1 elif key_in == curses.KEY_UP: pos -= 1 if pos < 0: pos = item_len - 1 if pos not in range(item_sup, item_inf): item_inf -= 2 if item_inf == item_len else 1 item_sup -= 1 elif key_in in [10, 32]: self._funcs[ip][pos] = not self._funcs[ip][pos] mutex = RetrieveData.get_ids(self.choice[ip][pos][2]) for c_id, c in enumerate(self.choice[ip]): if c[0] == self.choice[ip][pos][0]: if c[1] in mutex and self._funcs[ip][c_id] == 1: self._funcs[ip][c_id] = 0 self.info(pos, 1) else: item_sup = 0 if item_len > list_height: item_inf = list_height - 1 else: item_inf = item_len self.show_funclist(pos, item_sup, item_inf) return pos