diff --git a/_build.py b/_build.py index f078ed4..fdb094d 100644 --- a/_build.py +++ b/_build.py @@ -20,9 +20,9 @@ import sys import shutil -from hostsutl import __version__ +from gui.hostsutil import __version__ -SCRIPT = "hostsutl.py" +SCRIPT = "hostsutil.py" SCRIPT_DIR = os.getcwd() + '/' RELEASE_DIR = "../release/" @@ -69,7 +69,7 @@ ] ), ("theme", [ - "theme/darkdefault.qss", + "theme/default.qss", ] ), "LICENSE", @@ -200,7 +200,7 @@ from setuptools import setup # Set working directories WORK_DIR = SCRIPT_DIR + "work/" - RES_DIR = SCRIPT_DIR + "mac_res/" + RES_DIR = SCRIPT_DIR + "res/" APP_NAME = "HostsUtl.app" APP_PATH = WORK_DIR + APP_NAME DIST_DIR = APP_PATH + "/Contents/" @@ -268,7 +268,7 @@ # Pack APP to DMG file VDMG_DIR = WORK_DIR + "package_vdmg/" DMG_TMP = WORK_DIR + "pack_tmp.dmg" - DMG_RES_DIR = RES_DIR + "dmg_resource/" + DMG_RES_DIR = RES_DIR + "dmg/" VOL_NAME = "HostsUtl" DMG_NAME = VOL_NAME + "-mac-gpl-" + VERSION + ".dmg" DMG_PATH = WORK_DIR + DMG_NAME diff --git a/gui/__init__.py b/gui/__init__.py new file mode 100644 index 0000000..92ff4ef --- /dev/null +++ b/gui/__init__.py @@ -0,0 +1,15 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# +# __init__.py: +# +# Copyleft (C) 2014 - huhamhire +# ===================================================================== +# Licensed under the GNU General Public License, version 3. You should +# have received a copy of the GNU General Public License along with +# this program. If not, see . +# ===================================================================== + +from hostsutil import HostsUtil + +__all__ = ["HostsUtil"] diff --git a/gui/__list_trans.py b/gui/__list_trans.py new file mode 100644 index 0000000..56689b1 --- /dev/null +++ b/gui/__list_trans.py @@ -0,0 +1,41 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# +# __list_trans.py : Name of items from the function list to be localized +# +# Copyleft (C) 2014 - huhamhire hosts team +# ===================================================================== +# Licensed under the GNU General Public License, version 3. You should +# have received a copy of the GNU General Public License along with +# this program. If not, see . +# +# 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", "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", "others", None), + _translate("Util", "adblock-hostsx", None), + _translate("Util", "adblock-mvps", None), + _translate("Util", "adblock-mwsl", None), + _translate("Util", "adblock-yoyo", None), ] diff --git a/gui/_checkconn.py b/gui/_checkconn.py new file mode 100644 index 0000000..025b594 --- /dev/null +++ b/gui/_checkconn.py @@ -0,0 +1,58 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# +# _checkconn.py: +# +# Copyleft (C) 2014 - huhamhire +# ===================================================================== +# Licensed under the GNU General Public License, version 3. You should +# have received a copy of the GNU General Public License along with +# this program. If not, see . +# ===================================================================== + +__author__ = "huhamhire " + +from PyQt4 import QtCore + +import sys +sys.path.append("..") +from util import CommonUtil + + +class QSubChkConnection(QtCore.QThread): + """A class to check connection with server + + QSubChkConnection is a subclasse of PyQt4.QtCore.QThread. This class + contains methods to check the network connection with a specified mirror. + + The instance of this class should be created in an individual thread. And + the object instance of HostsUtil class should be set as parent here. + + Attribute: + trigger (obj): A PyQt4.QtCore.pyqtSignal object to emit suatus signal + to the main dialog. The meaning of the signal arguments is listed + here: + -1 -> checking..., 0 -> Failed, 1 -> OK. + """ + trigger = QtCore.pyqtSignal(int) + + def __init__(self, parent=None): + """Initialize a new instance of this class - Private Method + + Get mirror settings from the main dialog to check the connection. + + Args: + parent (obj): An instance of HostsUtil object to get settings + from. + """ + super(QSubChkConnection, self).__init__(parent) + self.link = parent.mirrors[parent._mirr_id]["test_url"] + + def run(self): + """Check connection - Public Method + + Operations to check the network connection with a specified mirror. + """ + self.trigger.emit(-1) + status = CommonUtil.check_connection(self.link) + self.trigger.emit(status) \ No newline at end of file diff --git a/gui/_checkupdate.py b/gui/_checkupdate.py new file mode 100644 index 0000000..d5c8aaf --- /dev/null +++ b/gui/_checkupdate.py @@ -0,0 +1,67 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# +# _checkupdate.py: +# +# Copyleft (C) 2014 - huhamhire +# ===================================================================== +# Licensed under the GNU General Public License, version 3. You should +# have received a copy of the GNU General Public License along with +# this program. If not, see . +# ===================================================================== + +__author__ = "huhamhire " + +import json +import socket +import urllib +from PyQt4 import QtCore + +from util_ui import _translate + + +class QSubChkUpdate(QtCore.QThread): + """A class to check update info of the latest data file + + QSubChkConnection is a subclasse of PyQt4.QtCore.QThread. This class + contains methods to retrieve the metadata of the latest hosts data file. + + The instance of this class should be created in an individual thread. And + the object instance of HostsUtil class should be set as parent here. + + Attribute: + trigger (obj): A PyQt4.QtCore.pyqtSignal object to emit suatus signal + to the main dialog. The meaning of the signal is listed here: + (dict) -> (update_info) + update_info (dict): A dictionary containing metadata of the + latest hosts data file. + """ + trigger = QtCore.pyqtSignal(dict) + + def __init__(self, parent=None): + """Initialize a new instance of this class - Private Method + + Get mirror settings from the main dialog to check the connection. + + Args: + parent (obj): An instance of HostsUtil object to get settings + from. + """ + super(QSubChkUpdate, self).__init__(parent) + self.url = parent.mirrors[parent._mirr_id]["update"] + parent.infofile + + def run(self): + """Check update - Public Method + + 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) \ No newline at end of file diff --git a/gui/_make.py b/gui/_make.py new file mode 100644 index 0000000..aeab163 --- /dev/null +++ b/gui/_make.py @@ -0,0 +1,203 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# +# _make.py: +# +# Copyleft (C) 2014 - huhamhire +# ===================================================================== +# Licensed under the GNU General Public License, version 3. You should +# have received a copy of the GNU General Public License along with +# this program. If not, see . +# ===================================================================== + +__author__ = "huhamhire " + +import time +from PyQt4 import QtCore + +import sys +sys.path.append("..") +from util import RetrieveData + + +class QSubMakeHosts(QtCore.QThread): + """A class to make a new hosts file + + QSubMakeHosts is a subclasse of PyQt4.QtCore.QThread. This class contains + methods to make a new hosts file for client. + + The instance of this class should be created in an individual thread. And + the object instance of HostsUtil class should be set as parent here. + + Attributes: + info_trigger (obj): A PyQt4.QtCore.pyqtSignal object to emit message + signal to the main dialog indicating the current operation.The + meaning of the signal arguments is listed here: + (str, int) - (mod_name, mod_num) + mod_name (str): A string indicating the name of a specified hosts + module in current progress. + mod_num (int): An integer indicating the number of current module + in the operation sequence. + fina_trigger (obj): A PyQt4.QtCore.pyqtSignal object to emit message + signal to the main dialog indicating finish information. The + meaning of the signal arguments is listed here: + (str, int) - (time, count) + time (str): A string indicating the total time uesd to make the + new hosts file. + count (int): An integer indicating the total number of hosts + entries inserted into the new hosts file. + move_trigger (obj): A PyQt4.QtCore.pyqtSignal object to emit signal + to the main dialog while new hosts is being moved to specified + path on current system. This signal does not + count (int): An integer indicating id of the module being processed + currently. + mod_num (int): An integer indicating total number of modules being + operated while making hosts file. + make_cfg (dict): A dictionary containing the selection control bytes + to make a hosts file. + make_mode (str): A string indicating the operation mode for making + hosts file. + eol (str): A string indicating the End-Of-Line marker. + """ + info_trigger = QtCore.pyqtSignal(str, int) + fina_trigger = QtCore.pyqtSignal(str, int) + move_trigger = QtCore.pyqtSignal() + + count = 0 + mod_num = 0 + make_cfg = {} + make_mode = "" + eol = "" + + def __init__(self, parent=None): + """Initialize a new instance of this class - Private Method + + Fetch settings from the main dialog to make a new hosts file. + + Args: + parent (obj): An instance of HostsUtil object to get settings + from. + """ + super(QSubMakeHosts, self).__init__(parent) + self.count = 0 + self.make_cfg = parent._make_cfg + self.make_mode = parent._make_mode + make_path = parent._make_path + self.hostname = parent.hostname + if parent._make_mode == "system": + self.eol = parent._sys_eol + self.hosts_file = open("hosts", "wb") + elif parent._make_mode == "ansi": + self.eol = "\r\n" + self.hosts_file = open(unicode(make_path), "wb") + elif parent._make_mode == "utf-8": + self.eol = "\n" + self.hosts_file = open(unicode(make_path), "wb") + + def run(self): + """Make new hosts file - Public Method + + Operations to retrieve data from the data file and make the new hosts + file for current system. + """ + RetrieveData.connect_db() + start_time = time.time() + self.maketime = start_time + self.write_head() + self.write_info() + self.get_hosts(self.make_cfg) + self.hosts_file.close() + end_time = time.time() + total_time = "%.4f" % (end_time - start_time) + self.fina_trigger.emit(total_time, self.count) + if self.make_mode == "system": + self.move_trigger.emit() + RetrieveData.disconnect_db() + + def get_hosts(self, make_cfg): + """Make hosts by user config - Public Method + + Make the new hosts file by the configuration ({make_cfg}) from + function list on the main dialog. + + Args: + make_cfg (dict): A dictionary containing module settings in byte + word format. + """ + 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 + if part_id == 0x02: + self.write_localhost_mod(part_id, mod_id) + else: + self.write_common_mod(part_id, mod_id) + + def write_head(self): + """Write head section - Public Method + + Write the head part of new hosts file. + """ + for head_str in RetrieveData.get_head(): + self.hosts_file.write("%s%s" % (head_str[0], self.eol)) + + def write_info(self): + """Write info section - Public Method + + Write the information part of new hosts file. + """ + info = RetrieveData.get_info() + info_lines = ["#"] + info_lines.append("# %s: %s" % ("Version", info["Version"])) + info_lines.append("# %s: %s" % ("Buildtime", info["Buildtime"])) + info_lines.append("# %s: %s" % ("Applytime", int(self.maketime))) + info_lines.append("#") + for line in info_lines: + self.hosts_file.write("%s%s" % (line, self.eol)) + + def write_common_mod(self, part_id, mod_id): + """Write module section - Public Method + + Write hosts entries in a specified module ({mod_id}) from a specified + part ({part_id}) of the data file to the new hosts file. + + Args: + part_id (int): An integer indicating the index number of a part + in the data file. + mod_id (int): An integer indicating the index number of a module + in the data file. + """ + hosts, mod_name = RetrieveData.get_host(part_id, mod_id) + self.info_trigger.emit(mod_name, self.mod_num) + self.hosts_file.write( + "%s# Section Start: %s%s" % (self.eol, mod_name, self.eol)) + for host in hosts: + self.hosts_file.write("%s %s%s" % (host[0], host[1], self.eol)) + self.count += 1 + self.hosts_file.write("# Section End: %s%s" % (mod_name, self.eol)) + + def write_localhost_mod(self, part_id, mod_id): + """Write localhost section - Public Method + + Write hosts entries in a localhost module ({mod_id}) from a specified + part ({part_id}) of the data file to the new hosts file. + + Args: + part_id (int): An integer indicating the index number of a part + in the data file. + mod_id (int): An integer indicating the index number of a module + in the data file. + """ + hosts, mod_name = RetrieveData.get_host(part_id, mod_id) + self.info_trigger.emit(mod_name, self.mod_num) + self.hosts_file.write( + "%s# Section Start: Localhost%s" % (self.eol, self.eol)) + for host in hosts: + if "#Replace" in host[1]: + host = (host[0], self.hostname) + self.hosts_file.write("%s %s%s" % (host[0], host[1], self.eol)) + self.count += 1 + self.hosts_file.write("# Section End: Localhost%s" % (self.eol)) \ No newline at end of file diff --git a/gui/_update.py b/gui/_update.py new file mode 100644 index 0000000..5fc0aa6 --- /dev/null +++ b/gui/_update.py @@ -0,0 +1,130 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# +# _update.py: +# +# Copyleft (C) 2014 - huhamhire +# ===================================================================== +# Licensed under the GNU General Public License, version 3. You should +# have received a copy of the GNU General Public License along with +# this program. If not, see . +# ===================================================================== + +__author__ = "huhamhire " + +import os +import socket +import urllib +from PyQt4 import QtCore + +from util_ui import _translate + +import sys +sys.path.append("..") +from util import CommonUtil + + +class QSubFetchUpdate(QtCore.QThread): + """A class to fetch the latest data file + + QSubFetchUpdate is a subclasse of PyQt4.QtCore.QThread. This class + contains methods to retrieve the latest hosts data file. + + The instance of this class should be created in an individual thread. And + the object instance of HostsUtil class should be set as parent here. + + Attributes: + prog_trigger (obj): A PyQt4.QtCore.pyqtSignal object to emit progress + signal to the main dialog indicating the current download + progress. The meaning of the signal arguments is listed here: + (int, str) -> (progress, message) + progress (int): An integer indicating the current download + progress. + message (str): A string indicating the message to be shown to + users on the progress bar. + finish_trigger (obj): A PyQt4.QtCore.pyqtSignal object to emit finish + signal to the main dialog. The meaning of the signal arguments is + listed here: + (int, int) -> (refresh_flag, error_flag) + refresh_flag (int): An integer indicating whether to refresh + the funcion list or not. 1: refresh, 0: do not refresh. + error_flag (int): An integer indicating whether the + downloading is successfully finished or not. + 1: error, 0: success. + """ + prog_trigger = QtCore.pyqtSignal(int, str) + finish_trigger = QtCore.pyqtSignal(int, int) + + def __init__(self, parent=None): + """Initialize a new instance of this class - Private Method + + Get download settings from the main dialog to retrieve new hosts data + file. + + Args: + parent (obj): An instance of HostsUtil object to get settings + from. + """ + super(QSubFetchUpdate, self).__init__(parent) + self.url = parent.mirrors[parent._mirr_id]["update"] + parent.filename + self.path = "./" + parent.filename + self.tmp_path = self.path + ".download" + self.filesize = parent._update["size"] + + def run(self): + """Fetch data file - Public Method + + Operations to retrieve the new hosts data file. + """ + self.prog_trigger.emit(0, unicode(_translate( + "Util", "Connecting...", None))) + self.fetch_file() + + def fetch_file(self): + """Fetch the data file - Public Method + + Retrieve the latest data file to a specified path ({path}) by url + ({url}). + + Args: + url (str): A string indicating the url to fetch the latest data + file. + path (str): A string indicating the path to save the data file on + current machine. + """ + socket.setdefaulttimeout(10) + try: + urllib.urlretrieve(self.url, self.tmp_path, self.set_progress) + self.replace_old() + self.finish_trigger.emit(1, 0) + except: + self.finish_trigger.emit(1, 1) + + def set_progress(self, done, blocksize, total): + """Set progress bar in the main dialog - Public Method + + Send message to the main dialog to set the progress bar Prog. + + Args: + done (int): An integer indicating the number of data blocks have + been downloaded from the server. + blocksize (int): An integer indicating the size of a data block. + """ + done = done * blocksize + 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 replace_old(self): + """Replace the old data file - Public Method + + Overwrite the old hosts data file with the new one. + """ + if os.path.isfile(self.path): + os.remove(self.path) + os.rename(self.tmp_path, self.path) \ No newline at end of file diff --git a/gui/hostsutil.py b/gui/hostsutil.py new file mode 100644 index 0000000..fc7a7cb --- /dev/null +++ b/gui/hostsutil.py @@ -0,0 +1,118 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# +# hostsutil.py : Main parts of Hosts Setup Utility +# +# Copyleft (C) 2014 - huhamhire hosts team +# ===================================================================== +# Licensed under the GNU General Public License, version 3. You should +# have received a copy of the GNU General Public License along with +# this program. If not, see . +# +# This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING +# THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE. +# ===================================================================== + +__version__ = "1.9.8" +__revision__ = "$Id$" +__author__ = "huhamhire " + +import sys + +from PyQt4 import QtGui +from zipfile import BadZipfile + +from qdialog_slots import QDialogSlots +from util_ui import _translate, _fromUtf8 + +sys.path.append("..") +from util import RetrieveData, CommonUtil + +# Path to store language files +LANG_DIR = "./gui/lang/" + + +class HostsUtil(QDialogSlots): + """A class to manage the operations and UI of Hosts Setup Utility + + HostsUtil class is a subclass of PyQt4.QtGui.QDialog which is used to + make the main dialog of this hosts setup utility. + This class contains a set of tools used to manage the operations while + modifying the hosts file of current operating system. Including methods + to manage operations to update data file, download data file, configure + hosts, make hosts file, backup hosts file, and restore backup. + The HostsUtil class also provides QT slots to deal with the QT singles + emitted by the widgets on the main dialog operated by users. Extend + methods dealing with the user interface is also given by this class. + + Attributes: + initd (int): An integer indicating how many times has the main dialog + been initialized. This value would be referenced for translator + to set the language of the main dialog. + _mirr_id (int): An integer indicating current index number of mirrors. + mirrors (list): A dictionary containing tag, test url, and update url + of mirrors. + filename (str): A string indicating the filename of the data file + containing data to make a hosts file. + infofile (str): A string indicating the filename of the info file + containing metadata of the data file in JSON format. + """ + initd = 0 + # Mirror related configuration + _mirr_id = 0 + mirrors = [] + # Data file related configuration + filename = "hostslist.data" + infofile = "hostsinfo.json" + + def __init__(self): + self.app = QtGui.QApplication(sys.argv) + super(HostsUtil, self).__init__() + + def __del__(self): + # Clear up datafile + try: + RetrieveData.clear() + except: + pass + + def start(self): + if not self.initd: + self.init_main() + self.show() + sys.exit(self.app.exec_()) + + def init_main(self): + """Initialize the main dialog - Public Method + + Set up the elements on the main dialog. Check the environment of + current operating system and current session. + """ + self.Ui.SelectMirror.clear() + # Set mirrors + self.mirrors = CommonUtil.set_network("network.conf") + 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() + # 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.initd += 1 + + +if __name__ == "__main__": + HostsUtlMain = HostsUtil() + HostsUtlMain.start() diff --git a/lang/de_DE.ts b/gui/lang/de_DE.ts similarity index 69% rename from lang/de_DE.ts rename to gui/lang/de_DE.ts index 8114403..ec90df1 100644 --- a/lang/de_DE.ts +++ b/gui/lang/de_DE.ts @@ -1,208 +1,161 @@ - HostsUtlMain + Util - + google(cn) - + google(hk) - + google(us) - + google-apis(cn) - + google-apis(us) - + activation-helper - + facebook - + twitter - + youtube - + wikipedia - + institutions - + steam - + others - + adblock-hostsx - + adblock-mvps - + adblock-mwsl - + adblock-yoyo - + Backup hosts - + Backup File(*.bak) - + Restore hosts - + [Error] - + Checking... - - Export hosts - - - - - hosts File - - - - - Building hosts file... - - - - - Copying new hosts file to - %s - - - - - Remove temporary file + + Operation completed - - Operation completed + + Incorrect Data file! +Please use the "Download" key to +fetch a new data file. - + [OK] - + [Failed] - + Functions - + Applying module: %s(%s/%s) - + Progress - - Notice: %i hosts entries has - been applied in %ssecs. - - - - - Operation Completed Successfully! - - - - - Error - - - - - Incorrect Data file! -Please use the "Download" key to -fetch a new data file. - - - - - Download Complete - - - - + Warning - + You do not have permissions to change the hosts file. Please run this program as Administrator/root @@ -210,25 +163,25 @@ so it can modify your hosts file. - + Error retrieving data from the server. Please try another server. - + Data file not found! Please use the "Download" key to fetch a new data file. - + Notice - + Are you sure you want to apply changes to the hosts file on your system? @@ -238,169 +191,216 @@ current hosts file. - + Data file is up-to-date. - + Complete - - Connecting... - - - - - Downloading: %s / %s - - - - + Hosts Setup Utility - + Config - + Server - + IP Version - + Status - + Connection - + N/A - + OS - + Hosts Info - + Version - + Release - + Latest - + Backup the hosts file of current system. - + Download data file - + Download the latest data file. - + Restore backup - + Restore a previous backup of hosts file. - + Apply hosts - + Apply changes to the hosts file. - + Exit - + Close this tool. - + Check update / Refresh - + Check the latest version of hosts data file. - + Save with ANSI - + Export to hosts file encoding by ANSI. - + Save with UTF-8 - + Export to hosts file encoding by UTF-8. - + Copyleft (C) 2011-2014 <a href="https://hosts.huhamhire.com/"><span style="text-decoration: none;color: #b1b1b1;">huhamhire-hosts</span></a> - + Powered by PyQT + + + Connecting... + + + + + Downloading: %s / %s + + + + + Export hosts + + + + + hosts File + + + + + Building hosts file... + + + + + Copying new hosts file to +%s + + + + + Remove temporary file + + + + + Notice: %i hosts entries has + been applied in %ssecs. + + + + + Operation Completed Successfully! + + + + + Error + + + + + Download Complete + + diff --git a/gui/lang/en_US.qm b/gui/lang/en_US.qm new file mode 100644 index 0000000..b5adf82 Binary files /dev/null and b/gui/lang/en_US.qm differ diff --git a/lang/en_US.ts b/gui/lang/en_US.ts similarity index 65% rename from lang/en_US.ts rename to gui/lang/en_US.ts index 89d19d9..93a1b25 100644 --- a/lang/en_US.ts +++ b/gui/lang/en_US.ts @@ -1,406 +1,407 @@ - + + - HostsUtlMain + Util - - Backup hosts - + + google(cn) + Google Web Service (CN) - - Functions - + + google(hk) + Google Web Service (HK) - - Hosts Setup Utility - + + google(us) + Google Web Service (US) - - Config - + + google-apis(cn) + Google API Service (CN) - - Server - + + google-apis(us) + Google API Service (US) - - IP Version + + activation-helper - - Status - + + facebook + Facebook - - Connection - + + twitter + twitter - - N/A - + + youtube + YouTube - - OS - + + wikipedia + Wikipedia - - Backup the hosts file of current system. - + + institutions + Academy and Research institutions - - Download data file - + + steam + Steam - - Download the latest data file. - + + others + Other services - - Restore backup + + adblock-hostsx - - Restore a previous backup of hosts file. + + adblock-mvps - - Apply hosts + + adblock-mwsl - - Apply changes to the hosts file. + + adblock-yoyo - - Exit + + Backup hosts - - Close this tool. + + Backup File(*.bak) - - Check update / Refresh + + Restore hosts - - Check the latest version of hosts data file. + + [Error] - - Hosts Info + + Checking... - - Version + + Operation completed - - Release + + [OK] - - Latest + + [Failed] - - google(cn) - Google Web Service (CN) + + Functions + - - google(us) - Google Web Service (US) + + Applying module: %s(%s/%s) + - - activation-helper + + Progress - - others + + Warning - - adblock-hostsx + + Error retrieving data from the server. +Please try another server. - - adblock-mvps + + Notice - - adblock-mwsl + + Data file is up-to-date. - - adblock-yoyo + + Complete - - Building hosts file... + + Hosts Setup Utility - - Backup File(*.bak) + + Config - - Restore hosts + + Server - - [Error] + + IP Version - - Checking... + + Status - - Copying new hosts file to - %s + + Connection - - Remove temporary file + + N/A - - Operation completed + + OS - - [OK] + + Hosts Info - - [Failed] + + Version - - Applying module: %s(%s/%s) + + Release - - Progress + + Latest - - Notice: %i hosts entries has - been applied in %ssecs. + + Backup the hosts file of current system. - - Operation Completed Successfully! + + Download data file - - Error + + Download the latest data file. - - Incorrect Data file! -Please use the "Download" key to -fetch a new data file. + + Restore backup - - Download Complete + + Restore a previous backup of hosts file. - - Warning + + Apply hosts - - You do not have permissions to change the -hosts file. -Please run this program as Administrator/root -so it can modify your hosts file. + + Apply changes to the hosts file. - - Error retrieving data from the server. -Please try another server. + + Exit - - Data file not found! -Please use the "Download" key to -fetch a new data file. + + Close this tool. - - Notice + + Check update / Refresh - - Data file is up-to-date. + + Check the latest version of hosts data file. - - Complete + + Save with ANSI - - Connecting... + + Export to hosts file encoding by ANSI. - - Downloading: %s / %s + + Save with UTF-8 - - Are you sure you want to apply changes -to the hosts file on your system? - -This operation could not be reverted if -you have not made a backup of your -current hosts file. + + Export to hosts file encoding by UTF-8. - - Save with ANSI + + Copyleft (C) 2011-2014 <a href="https://hosts.huhamhire.com/"><span style="text-decoration: none;color: #b1b1b1;">huhamhire-hosts</span></a> - - Export to hosts file encoding by ANSI. + + Powered by PyQT - - Save with UTF-8 + + Connecting... - - Export to hosts file encoding by UTF-8. + + Downloading: %s / %s - - Export hosts + + Incorrect Data file! +Please use the "Download" key to +fetch a new data file. - - hosts File + + You do not have permissions to change the +hosts file. +Please run this program as Administrator/root +so it can modify your hosts file. - - google-apis(cn) - Google API Service (CN) + + Data file not found! +Please use the "Download" key to +fetch a new data file. + - - google-apis(us) - Google API Service (US) + + Are you sure you want to apply changes +to the hosts file on your system? + +This operation could not be reverted if +you have not made a backup of your +current hosts file. + - - wikipedia + + Export hosts - - steam + + hosts File - - Copyleft (C) 2011-2014 <a href="https://hosts.huhamhire.com/"><span style="text-decoration: none;color: #b1b1b1;">huhamhire-hosts</span></a> + + Building hosts file... - - Powered by PyQT + + Copying new hosts file to +%s - - google(hk) - Google Web Service (HK) + + Remove temporary file + - - facebook - Facebook + + Notice: %i hosts entries has + been applied in %ssecs. + - - twitter - twitter + + Operation Completed Successfully! + - - youtube - YouTube + + Error + - - institutions - Academy and Research institutions + + Download Complete + diff --git a/gui/lang/zh_CN.qm b/gui/lang/zh_CN.qm new file mode 100644 index 0000000..69fcbed Binary files /dev/null and b/gui/lang/zh_CN.qm differ diff --git a/lang/zh_CN.ts b/gui/lang/zh_CN.ts similarity index 71% rename from lang/zh_CN.ts rename to gui/lang/zh_CN.ts index 12407aa..8726349 100644 --- a/lang/zh_CN.ts +++ b/gui/lang/zh_CN.ts @@ -1,193 +1,164 @@ - + + - HostsUtlMain + Util - + google(cn) Google Web服务(北京) - + google(hk) Google Web服务(香港) - + google(us) Google Web服务(美国) - + google-apis(cn) Google 应用程序服务(北京) - + google-apis(us) Google 应用程序服务(美国) - + activation-helper 屏蔽部分破解软件激活服务器 - + facebook Facebook - + twitter twitter - + youtube YouTube - + wikipedia 维基百科 - + institutions 教育科研机构 - + steam Steam 游戏平台 - + others 其他墙外站点 - + adblock-hostsx 广告屏蔽-hostsx 列表 - + adblock-mvps 广告屏蔽-mvps 列表 - + adblock-mwsl 广告屏蔽-mwsl 列表 - + adblock-yoyo 广告屏蔽-yoyo 列表 - + Backup hosts 备份 hosts 文件 - + Backup File(*.bak) 备份文件(*.bak) - + Restore hosts 还原备份的 hosts 文件 - + [Error] [错误] - + Checking... 正在连接... - + Export hosts 导出 hosts 文件 - + hosts File hosts 文件 - - Building hosts file... - 正在生成 hosts 文件... - - - + Copying new hosts file to %s - 正在将新的 hosts 配置到目标路径 + 正在将新的 hosts 配置到目标路径 %s - + Remove temporary file 清理临时文件 - + Operation completed 操作完成 - - [OK] - [正常] - - - - [Failed] - [失败] - - - - Functions - 功能列表 - - - - Applying module: %s(%s/%s) - 应用选定的模块: %s(%s/%s) - - - - Progress - 操作进度 - - - + Notice: %i hosts entries has been applied in %ssecs. 注意:共有 %i 条 hosts 条目在 %s秒内被插入到 hosts 文件中。 - + Operation Completed Successfully! 操作成功完成! - + Error 错误 - + Incorrect Data file! Please use the "Download" key to fetch a new data file. @@ -196,17 +167,42 @@ fetch a new data file. 新的数据文件。 - + Download Complete 下载完成 - + + [OK] + [正常] + + + + [Failed] + [失败] + + + + Functions + 功能列表 + + + + Applying module: %s(%s/%s) + 应用选定的模块: %s(%s/%s) + + + + Progress + 操作进度 + + + Warning 警告 - + You do not have permissions to change the hosts file. Please run this program as Administrator/root @@ -217,14 +213,14 @@ so it can modify your hosts file. 工具。 - + Error retrieving data from the server. Please try another server. 在从服务器获取数据是发生错误。 请在更换服务器之后尝试先前的操作。 - + Data file not found! Please use the "Download" key to fetch a new data file. @@ -233,12 +229,12 @@ fetch a new data file. 新的数据文件。 - + Notice 注意 - + Are you sure you want to apply changes to the hosts file on your system? @@ -252,179 +248,184 @@ current hosts file. 不可逆转。 - + Data file is up-to-date. 数据文件已经是最新版本。 - + Complete 完成 - - Connecting... - 正在连接服务器... - - - - Downloading: %s / %s - 正在下载: %s / %s + + Building hosts file... + 正在生成 hosts 文件... - + Hosts Setup Utility hosts 文件配置工具 - + Config 设置 - + Server 服务器 - + IP Version IP 协议版本 - + Status 状态 - + Connection 连接 - + N/A 无状态 - + OS 操作系统 - + Hosts Info 数据文件信息 - + Version 当前版本 - + Release 发布日期 - + Latest 最新版本 - + Backup the hosts file of current system. 备份当前系统的 hosts 文件。 - + Download data file 下载数据文件 - + Download the latest data file. 下载最新数据文件。 - + Restore backup 还原备份 - + Restore a previous backup of hosts file. 还原先前备份的 hosts 文件。 - + Apply hosts 更改 hosts - + Apply changes to the hosts file. 对 hosts 文件进行修改。 - + Exit 退出 - + Close this tool. 关闭本工具。 - + Check update / Refresh 检查更新/刷新 - + Check the latest version of hosts data file. 在线检查数据文件的最新版本。 - + Save with ANSI 保存为 ANSI 格式 - + Export to hosts file encoding by ANSI. 以 ANSI 的编码方式导出 hosts 文件。 - + Save with UTF-8 保存为 UTF-8 格式 - + Export to hosts file encoding by UTF-8. 以 UTF-8 的编码方式导出 hosts 文件。 - + Copyleft (C) 2011-2014 <a href="https://hosts.huhamhire.com/"><span style="text-decoration: none;color: #b1b1b1;">huhamhire-hosts</span></a> 公共版权 (C) 2011-2014 <a href="https://hosts.huhamhire.com/"><span style="text-decoration: none;color: #b1b1b1;">huhamhire-hosts</span></a> - + Powered by PyQT - + + Connecting... + 正在连接服务器... + + + + Downloading: %s / %s + 正在下载: %s / %s + + + Notice: %i hosts entries has been applied in %ssecs. 注意:共有 %i 条 hosts 条目在 %s秒内被插入到 hosts 文件中。 - + Incorrect Data file! Please use the "Download" key to fetch a new data file. @@ -433,7 +434,7 @@ fetch a new data file. 新的数据文件。 - + You do not have permissions to change the hosts file. Please run this program as Administrator/root @@ -444,7 +445,7 @@ so it can modify your hosts file. 工具。 - + Data file not found! Please use the "Download" key to fetch a new data file. @@ -453,7 +454,7 @@ fetch a new data file. 新的数据文件。 - + Are you sure you want to apply changes to the hosts file on your system? @@ -466,5 +467,12 @@ current hosts file. 若先前未对 hosts 文件进行备份,该操作将 不可逆转。 + + + Copying new hosts file to +%s + 正在将新的 hosts 配置到目标路径 + %s + diff --git a/gui/lang/zh_TW.qm b/gui/lang/zh_TW.qm new file mode 100644 index 0000000..5ef8d6b Binary files /dev/null and b/gui/lang/zh_TW.qm differ diff --git a/lang/zh_TW.ts b/gui/lang/zh_TW.ts similarity index 62% rename from lang/zh_TW.ts rename to gui/lang/zh_TW.ts index 3c9adbf..ef3f111 100644 --- a/lang/zh_TW.ts +++ b/gui/lang/zh_TW.ts @@ -1,419 +1,476 @@ - + + - HostsUtlMain + Util - + google(cn) Google Web服務(大陸) - + + google(hk) + Google Web服務(香港) + + + google(us) Google Web服務(美國) - + + google-apis(cn) + Google API服務(大陸) + + + + google-apis(us) + Google API服務(美國) + + + activation-helper 遮罩部分破解軟體啟動伺服器 - + + facebook + Facebook + + + + twitter + twitter + + + + youtube + YouTube + + + + wikipedia + 維基百科 + + + + institutions + 教育科研機構 + + + + steam + Steam 遊戲平台 + + + others 其他網站 - + adblock-hostsx 廣告攔截-hostsx 清單 - + adblock-mvps 廣告攔截-mvps 清單 - + adblock-mwsl 廣告攔截-mwsl 清單 - + adblock-yoyo 廣告攔截-yoyo 清單 - - Building hosts file... - 正在創建 hosts 檔... - - - + Backup hosts 備份 hosts 檔 - + Backup File(*.bak) 備份檔(*.bak) - + Restore hosts 還原 hosts - + [Error] [錯誤] - + Checking... 正在連接伺服器... - + + Export hosts + 匯出 hosts 檔 + + + + hosts File + hosts 檔 + + + Copying new hosts file to %s - 將新的 hosts 檔案複製到 + 將新的 hosts 檔案複製到 %s - + Remove temporary file 刪除暫存檔案 - + Operation completed 作業完成 - - [OK] - [好] - - - - [Failed] - [失敗] - - - - Functions - 功能清單 - - - - Applying module: %s(%s/%s) - 應用選定的模組: %s(%s/%s) - - - - Progress - 作業進度 - - - - Notice: %i hosts entries has + + Notice: %i hosts entries has been applied in %ssecs. - 消息:共有 %i 条 hosts 条目在 + 消息:共有 %i 条 hosts 条目在 %s秒内被插入到 hosts 文件中。 - + Operation Completed Successfully! 作業已成功完成 ! - + Error 錯誤 - + Incorrect Data file! -Please use the "Download" key to +Please use the "Download" key to fetch a new data file. - 不正確的資料檔案 ! + 不正確的資料檔案 ! 請使用"下載"按鈕來獲得 一個新的資料檔案。 - + Download Complete 下載已完成 - + + [OK] + [好] + + + + [Failed] + [失敗] + + + + Functions + 功能清單 + + + + Applying module: %s(%s/%s) + 應用選定的模組: %s(%s/%s) + + + + Progress + 作業進度 + + + Warning 警告 - - You do not have permissions to change the + + You do not have permissions to change the hosts file. Please run this program as Administrator/root so it can modify your hosts file. - 您目前沒有許可權以更改 hosts 檔。 + 您目前沒有許可權以更改 hosts 檔。 請以管理員方式或者根使用者運行本 程式。 - + Error retrieving data from the server. Please try another server. 從伺服器中檢索資料時出錯。 請嘗試使用另一台伺服器。 - + Data file not found! -Please use the "Download" key to +Please use the "Download" key to fetch a new data file. - 找不到本地資料檔案! + 找不到本地資料檔案! 請使用"下載"按鈕來獲得 一個新的資料檔案。 - + Notice 消息 - + + Are you sure you want to apply changes +to the hosts file on your system? + +This operation could not be reverted if +you have not made a backup of your +current hosts file. + 您確認繼續執行當前操作以修改系統 hosts +檔嗎? + +若先前未對 hosts 檔進行備份,該操作將 +不可逆轉。 + + + Data file is up-to-date. 當前的資料檔案是最新的。 - + Complete 完成 - - Connecting... - 正在連接... - - - - Downloading: %s / %s - 正在下載: %s / %s + + Building hosts file... + 正在創建 hosts 檔... - + Hosts Setup Utility hosts 設置實用程式 - + Config 配置 - + Server 伺服器 - + IP Version IP 協定版本 - + Status 狀態 - + Connection 連接狀態 - + N/A 不適用 - + OS 作業系統 - + + Hosts Info + 資料檔案狀態 + + + + Version + 當前版本 + + + + Release + 發佈日期 + + + + Latest + 最新版本 + + + Backup the hosts file of current system. 備份當前系統的 hosts 檔。 - + Download data file 下載資料檔案 - + Download the latest data file. 下載最新的資料檔案。 - + Restore backup 還原備份 - + Restore a previous backup of hosts file. 還原以前的備份的 hosts 檔。 - + Apply hosts 更改 hosts 檔 - + Apply changes to the hosts file. 將更改應用到主 hosts 檔。 - + Exit 退出 - + Close this tool. 關閉此程式。 - + Check update / Refresh 檢查更新 / 刷新 - + Check the latest version of hosts data file. 檢查 hosts 檔案的最新版本。 - - Hosts Info - 資料檔案狀態 - - - - Version - 當前版本 - - - - Release - 發佈日期 - - - - Latest - 最新版本 - - - - Are you sure you want to apply changes -to the hosts file on your system? - -This operation could not be reverted if -you have not made a backup of your -current hosts file. - 您確認繼續執行當前操作以修改系統 hosts -檔嗎? - -若先前未對 hosts 檔進行備份,該操作將 -不可逆轉。 - - - + Save with ANSI 保存為 ANSI 格式 - + Export to hosts file encoding by ANSI. 匯出由 ANSI 編碼的 hosts 檔。 - + Save with UTF-8 保存為 UTF-8 格式 - + Export to hosts file encoding by UTF-8. 匯出由 UTF-8 編碼的 hosts 檔。 - - Export hosts - 匯出 hosts 檔 - - - - hosts File - hosts 檔 - - - - google-apis(cn) - Google API服務(大陸) - - - - google-apis(us) - Google API服務(美國) + + Copyleft (C) 2011-2014 <a href="https://hosts.huhamhire.com/"><span style="text-decoration: none;color: #b1b1b1;">huhamhire-hosts</span></a> + 公共版權 (C) 2011-2014 <a href="https://hosts.huhamhire.com/"><span style="text-decoration: none;color: #b1b1b1;">huhamhire-hosts</span></a> - - wikipedia - 維基百科 + + Powered by PyQT + - - steam - Steam 遊戲平台 + + Connecting... + 正在連接... - - Copyleft (C) 2011-2014 <a href="https://hosts.huhamhire.com/"><span style="text-decoration: none;color: #b1b1b1;">huhamhire-hosts</span></a> - 公共版權 (C) 2011-2014 <a href="https://hosts.huhamhire.com/"><span style="text-decoration: none;color: #b1b1b1;">huhamhire-hosts</span></a> + + Downloading: %s / %s + 正在下載: %s / %s - - Powered by PyQT - + + Notice: %i hosts entries has + been applied in %ssecs. + 消息:共有 %i 条 hosts 条目在 + %s秒内被插入到 hosts 文件中。 - - google(hk) - Google Web服務(香港) + + Incorrect Data file! +Please use the "Download" key to +fetch a new data file. + 不正確的資料檔案 ! +請使用"下載"按鈕來獲得 +一個新的資料檔案。 - - facebook - Facebook + + You do not have permissions to change the +hosts file. +Please run this program as Administrator/root +so it can modify your hosts file. + 您目前沒有許可權以更改 hosts 檔。 +請以管理員方式或者根使用者運行本 +程式。 - - twitter - twitter + + Data file not found! +Please use the "Download" key to +fetch a new data file. + 找不到本地資料檔案! +請使用"下載"按鈕來獲得 +一個新的資料檔案。 - - youtube - YouTube + + Are you sure you want to apply changes +to the hosts file on your system? + +This operation could not be reverted if +you have not made a backup of your +current hosts file. + 您確認繼續執行當前操作以修改系統 hosts +檔嗎? + +若先前未對 hosts 檔進行備份,該操作將 +不可逆轉。 - - institutions - 教育科研機構 + + Copying new hosts file to +%s + 將新的 hosts 檔案複製到 + %s diff --git a/util/language.py b/gui/language.py similarity index 100% rename from util/language.py rename to gui/language.py diff --git a/_pylupdate4.py b/gui/pyqt/_pylupdate4.py similarity index 87% rename from _pylupdate4.py rename to gui/pyqt/_pylupdate4.py index d52f674..cbab5e8 100644 --- a/_pylupdate4.py +++ b/gui/pyqt/_pylupdate4.py @@ -17,6 +17,6 @@ import os for root, dirs, files in os.walk('.'): - for file in files: - if file.endswith('.pro'): - os.system('pylupdate4 %s' % file) + for f in files: + if f.endswith('.pro'): + os.system('pylupdate4 %s' % f) diff --git a/_pyuic4.py b/gui/pyqt/_pyuic4.py similarity index 56% rename from _pyuic4.py rename to gui/pyqt/_pyuic4.py index 97d6cbf..fbcedca 100644 --- a/_pyuic4.py +++ b/gui/pyqt/_pyuic4.py @@ -15,11 +15,18 @@ # ===================================================================== import os -for root, dirs, files in os.walk('.'): - for file in files: - if file.endswith('.ui'): - os.system('pyuic4 -o %s.py -x %s' \ - % (file.rsplit('.', 1)[0], file)) - elif file.endswith('.qrc'): - os.system('pyrcc4 -o %s_rc.py %s' \ - % (file.rsplit('.', 1)[0], file)) + +PROJ_DIR = '../' + +for root, dirs, files in os.walk(PROJ_DIR): + for f in files: + file_path = os.path.join(root, f) + out_path = os.path.join(PROJ_DIR, f.rsplit('.', 1)[0]) + if f.endswith('.ui'): + os.system('pyuic4 -o %s.py -x %s' % (out_path, file_path)) + print("make: %s.py" % out_path) + elif f.endswith('.qrc'): + os.system('pyrcc4 -o %s_rc.py %s' % (out_path, file_path)) + print("make: %s_rc.py" % out_path) + else: + pass diff --git a/gui/pyqt/style.qrc b/gui/pyqt/style.qrc new file mode 100644 index 0000000..a21e688 --- /dev/null +++ b/gui/pyqt/style.qrc @@ -0,0 +1,6 @@ + + + ../../res/img/style/checkbox.png + ../../res/img/style/down_arrow.png + + diff --git a/gui/pyqt/util.pro b/gui/pyqt/util.pro new file mode 100644 index 0000000..870bf64 --- /dev/null +++ b/gui/pyqt/util.pro @@ -0,0 +1,19 @@ +SOURCES = ../hostsutil.py \ + ../__list_trans.py \ + ../_checkconn.py \ + ../_checkupdate.py \ + ../_make.py \ + ../_update.py \ + ../qdialog_ui.py \ + ../qdialog_d.py \ + ../qdialog_slots.py \ + ../util_ui.py +TRANSLATIONS = ../lang/de_DE.ts \ + ../lang/en_US.ts \ + ../lang/zh_CN.ts \ + ../lang/zh_TW.ts +INTERFACES = util_ui.ui +RESOURCES = util.qrc \ + style.qrc +CODECFORTR = UTF-8 +CODECFORSRC = UTF-8 diff --git a/gui/pyqt/util.qrc b/gui/pyqt/util.qrc new file mode 100644 index 0000000..cee83bb --- /dev/null +++ b/gui/pyqt/util.qrc @@ -0,0 +1,23 @@ + + + ../../res/img/buttons/button_ansi.png + ../../res/img/buttons/button_ansi_disabled.png + ../../res/img/buttons/button_apply.png + ../../res/img/buttons/button_apply_disabled.png + ../../res/img/buttons/button_backup.png + ../../res/img/buttons/button_backup_disabled.png + ../../res/img/buttons/button_download.png + ../../res/img/buttons/button_download_disabled.png + ../../res/img/buttons/button_exit.png + ../../res/img/buttons/button_exit_disabled.png + ../../res/img/buttons/button_restore.png + ../../res/img/buttons/button_restore_disabled.png + ../../res/img/buttons/button_update.png + ../../res/img/buttons/button_update_disabled.png + ../../res/img/buttons/button_utf8.png + ../../res/img/buttons/button_utf8_disabled.png + + + ../../res/img/icons/utl_icon@256x256.png + + diff --git a/qthostsui.ui b/gui/pyqt/util_ui.ui similarity index 88% rename from qthostsui.ui rename to gui/pyqt/util_ui.ui index 7c87faa..031c55c 100644 --- a/qthostsui.ui +++ b/gui/pyqt/util_ui.ui @@ -1,8 +1,8 @@ huhamhire - HostsUtlMain - + Util + true @@ -39,8 +39,8 @@ Hosts Setup Utility - - :/icon/img/icons/utl_icon@256x256.png:/icon/img/icons/utl_icon@256x256.png + + :/icon/res/img/icons/utl_icon@256x256.png:/icon/res/img/icons/utl_icon@256x256.png @@ -344,9 +344,9 @@ - - :/buttons/img/buttons/button_backup.png - :/buttons/img/buttons/button_backup_disabled.png:/buttons/img/buttons/button_backup.png + + :/buttons/res/img/buttons/button_backup.png + :/buttons/res/img/buttons/button_backup_disabled.png:/buttons/res/img/buttons/button_backup.png @@ -374,9 +374,9 @@ - - :/buttons/img/buttons/button_download.png - :/buttons/img/buttons/button_download_disabled.png:/buttons/img/buttons/button_download.png + + :/buttons/res/img/buttons/button_download.png + :/buttons/res/img/buttons/button_download_disabled.png:/buttons/res/img/buttons/button_download.png @@ -404,9 +404,9 @@ - - :/buttons/img/buttons/button_restore.png - :/buttons/img/buttons/button_restore_disabled.png:/buttons/img/buttons/button_restore.png + + :/buttons/res/img/buttons/button_restore.png + :/buttons/res/img/buttons/button_restore_disabled.png:/buttons/res/img/buttons/button_restore.png @@ -434,9 +434,9 @@ - - :/buttons/img/buttons/button_apply.png - :/buttons/img/buttons/button_apply_disabled.png:/buttons/img/buttons/button_apply.png + + :/buttons/res/img/buttons/button_apply.png + :/buttons/res/img/buttons/button_apply_disabled.png:/buttons/res/img/buttons/button_apply.png @@ -464,9 +464,9 @@ - - :/buttons/img/buttons/button_exit.png - :/buttons/img/buttons/button_exit_disabled.png:/buttons/img/buttons/button_exit.png + + :/buttons/res/img/buttons/button_exit.png + :/buttons/res/img/buttons/button_exit_disabled.png:/buttons/res/img/buttons/button_exit.png @@ -494,9 +494,9 @@ - - :/buttons/img/buttons/button_update.png - :/buttons/img/buttons/button_update_disabled.png:/buttons/img/buttons/button_update.png + + :/buttons/res/img/buttons/button_update.png + :/buttons/res/img/buttons/button_update_disabled.png:/buttons/res/img/buttons/button_update.png @@ -524,9 +524,9 @@ - - :/buttons/img/buttons/button_ansi.png - :/buttons/img/buttons/button_ansi_disabled.png:/buttons/img/buttons/button_ansi.png + + :/buttons/res/img/buttons/button_ansi.png + :/buttons/res/img/buttons/button_ansi_disabled.png:/buttons/res/img/buttons/button_ansi.png @@ -554,9 +554,9 @@ - - :/buttons/img/buttons/button_utf8.png - :/buttons/img/buttons/button_utf8_disabled.png:/buttons/img/buttons/button_utf8.png + + :/buttons/res/img/buttons/button_utf8.png + :/buttons/res/img/buttons/button_utf8_disabled.png:/buttons/res/img/buttons/button_utf8.png @@ -654,14 +654,14 @@ SelectLang - + ButtonExit clicked() - HostsUtlMain + Util close() @@ -677,7 +677,7 @@ SelectIP currentIndexChanged(int) - HostsUtlMain + Util on_IPVersion_changed(int) @@ -693,7 +693,7 @@ SelectMirror currentIndexChanged(int) - HostsUtlMain + Util on_Mirror_changed(int) @@ -709,7 +709,7 @@ Functionlist itemChanged(QListWidgetItem*) - HostsUtlMain + Util on_Selection_changed(QListWidgetItem*) @@ -725,7 +725,7 @@ ButtonApply clicked() - HostsUtlMain + Util on_MakeHosts_clicked() @@ -741,7 +741,7 @@ ButtonBackup clicked() - HostsUtlMain + Util on_Backup_clicked() @@ -757,7 +757,7 @@ ButtonRestore clicked() - HostsUtlMain + Util on_Restore_clicked() @@ -773,7 +773,7 @@ ButtonCheck clicked() - HostsUtlMain + Util on_CheckUpdate_clicked() @@ -789,7 +789,7 @@ ButtonUpdate clicked() - HostsUtlMain + Util on_FetchUpdate_clicked() @@ -805,7 +805,7 @@ SelectLang currentIndexChanged(QString) - HostsUtlMain + Util on_Lang_changed(QString) @@ -821,7 +821,7 @@ ButtonANSI clicked() - HostsUtlMain + Util on_MakeANSI_clicked() @@ -837,7 +837,7 @@ ButtonUTF clicked() - HostsUtlMain + Util on_MakeUTF8_clicked() @@ -853,7 +853,7 @@ Copyright linkActivated(QString) - HostsUtlMain + Util on_LinkActivated(QString) diff --git a/gui/qdialog_d.py b/gui/qdialog_d.py new file mode 100644 index 0000000..3ab29ed --- /dev/null +++ b/gui/qdialog_d.py @@ -0,0 +1,398 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# +# qdialog_d.py : +# +# Copyleft (C) 2014 - huhamhire hosts team +# ===================================================================== +# Licensed under the GNU General Public License, version 3. You should +# have received a copy of the GNU General Public License along with +# this program. If not, see . +# +# 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 " + +import os +import shutil + +from zipfile import BadZipfile +from PyQt4 import QtCore, QtGui + +from _checkconn import QSubChkConnection +from _checkupdate import QSubChkUpdate +from _make import QSubMakeHosts +from _update import QSubFetchUpdate +from qdialog_ui import QDialogUI +from util_ui import _translate + +import sys +sys.path.append("..") +from util import RetrieveData, CommonUtil + + +class QDialogDaemon(QDialogUI): + """ + Attributes: + _down_flag (int) An integer indicating the downloading status of + current session. 1 represents data file is being downloaded. + _funcs (list): A list containing two lists with the information of + function list for IPv4 and IPv6 environment. + _make_cfg (dict): A dictionary containing the selection control bytes + to make a hosts file. + _make_mode (str): A string indicating the operation mode for making + hosts file. + _sys_eol (str): A string indicating the End-Of-Line marker. + _update (dict): A dictionary containing the update information of the + current data file on server. + _writable (int): An integer indicating whether the program is run with + admin/root privileges. The value could be 1 or 0. + + choice (list): A list containing two lists with the selection of + functions for IPv4 and IPv6 environment. + slices (list): A list containing two lists with integers indicating + the number of function items from different parts listed in the + function list. + hostname (str): A string indicating the hostname of current operating + system. This attribute would be used for linux clients. + hosts_path (str): A string indicating the absolute path of the hosts + file on current operating system. + """ + + _down_flag = 0 + _funcs = [[], []] + _make_cfg = {} + _make_mode = "" + _sys_eol = "" + _update = {} + _writable = 0 + + choice = [[], []] + slices = [[], []] + hostname = '' + hosts_path = '' + + def __init__(self): + super(QDialogDaemon, self).__init__() + self.set_platform() + self.set_platform_label() + + def reject(self): + """Response to the reject signal - Public Method + + The slot response to the reject signal from an instance of the main + dialog. Close this program while the reject signal is emitted. + """ + self.close() + return QtGui.QDialog.reject(self) + + def close(self): + """Response to the close signal - Public Method + + The slot response to the close signal from an instance of the main + dialog. Close this program while the reject signal is emitted. + """ + try: + RetrieveData.clear() + except: + pass + super(QDialogDaemon, self).close() + + def check_writable(self): + """Check root privileges - Public Method + + Check if current session is ran with root privileges. + """ + writable = CommonUtil.check_privileges()[1] + self._writable = writable + if not writable: + self.warning_permission() + + def check_connection(self): + """Operations to check connection - Public Method + + Call operations to check the connection to current server. + """ + thread = QSubChkConnection(self) + thread.trigger.connect(self.set_conn_status) + thread.start() + + def check_update(self): + """Operations to check data file update - Public Method + + Call operations to 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 fetch_update(self): + """Operations to fetch new data file - Public Method + + Call operations to retrieve a new hosts data file from a server. + """ + self.set_fetch_start_btns() + thread = QSubFetchUpdate(self) + thread.prog_trigger.connect(self.set_down_progress) + thread.finish_trigger.connect(self.finish_fetch) + thread.start() + + def fetch_update_after_check(self): + """Check to fetch data file after check for update - Public Method + + 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 export_hosts(self): + """Draw export hosts dialog - Public Method + + Show the export dialog and get the path to save the exported hosts + file. + + Returns: + A string indicating the path to export a hosts file + """ + 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 make_hosts(self, mode="system"): + """Operations to make hosts file - Public Method + + Call operations to make a new hosts file for current system. + + Args: + mode (str): A string indicating the operation mode for making + hosts file. + """ + 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 move_hosts(self): + """Move hosts file to the system path after making - Public Method + + The slot response to the move_trigger signal from an instance of + QSubMakeHosts class while making operations are finished. + """ + 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 set_platform(self): + """Set OS info - Public Method + + Set the information of current operating system platform. + """ + system, hostname, path, encode, flag = CommonUtil.check_platform() + self.platform = system + self.hostname = hostname + self.hosts_path = path + self.plat_flag = flag + if encode == "win_ansi": + self._sys_eol = "\r\n" + else: + self._sys_eol = "\n" + + def set_config_bytes(self, mode): + """Set configuration byte words - Public Method + + Calculate the module configuration byte words by the selection from + function list on the main dialog. + + Args: + mode (str): A string indicating the operation mode for making + hosts file. + """ + ip_flag = self._ipv_id + selection = {} + if mode == "system": + localhost_word = { + "Windows": 0x0001, "Linux": 0x0002, + "Unix": 0x0002, "OS X": 0x0004}[self.platform] + else: + localhost_word = 0x0008 + selection[0x02] = localhost_word + ch_parts = (0x08, 0x20 if ip_flag else 0x10, 0x40) + slices = self.slices[ip_flag] + for i, part in enumerate(ch_parts): + part_cfg = self._funcs[ip_flag][slices[i]:slices[i + 1]] + part_word = 0 + for i, cfg in enumerate(part_cfg): + part_word += cfg << i + selection[part] = part_word + self._make_cfg = selection + + def refresh_info(self, refresh=0): + """Refresh data file information - Public Method + + 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. + + Arg: + refresh (int): A flag integer indicating whether the information + needs to be reloaded or not. 1: reload, 0: do not reload. + Default by 0. + """ + if refresh and RetrieveData.conn is 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 finish_make(self, time, count): + """Operations after making new hosts file - Public Method + + The slot response to the fina_trigger signal ({time}, {count}) from + an instance of QSubMakeHosts class while making operations are + finished. + + Args: + time (str): A string indicating the total time uesd to make the + new hosts file. + count (int): An integer indicating the total number of hosts + entries inserted into the new hosts file. + """ + 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_update(self, update): + """Operations after checking update - Public Method + + The slot response to the trigger signal ({update}) from an instance + of QSubChkUpdate class while checking operations are finished. + + Arg: + update (dict): A dictionary containing metadata of the latest + hosts file from the server. + """ + 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 finish_fetch(self, refresh=1, error=0): + """Operations after downloading data file - Public Method + + The slot response to the finish_trigger signal ({refresh}, {error}) + from an instance of QSubFetchUpdate class while downloading is + finished. + + Args: + refresh (int): A flag integer indicating whether a refresh for + function list is needed or not. 1: refresh, 0: no refresh. + Default by 1. + error (int): A flag integer indicating errors have occurred while + downloading new data file. 1: error, 0:success. Default by 0. + """ + 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 new_version(self): + """Compare version of data file - Public Method + + Compare version of local data file to the version from the server. + + Returns: + A flag integer indicating whether the local data file is + up-to-date or not. + 1 -> The version of data file on server is newer. + 0 -> The local data file is up-to-date. + """ + local_ver = self._cur_ver + server_ver = self._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 \ No newline at end of file diff --git a/gui/qdialog_slots.py b/gui/qdialog_slots.py new file mode 100644 index 0000000..179fea3 --- /dev/null +++ b/gui/qdialog_slots.py @@ -0,0 +1,282 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# +# qdialog_slots.py : +# +# Copyleft (C) 2014 - huhamhire hosts team +# ===================================================================== +# Licensed under the GNU General Public License, version 3. You should +# have received a copy of the GNU General Public License along with +# this program. If not, see . +# +# 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 " + +import shutil +import time + +from PyQt4 import QtCore, QtGui + +from language import LangUtil +from qdialog_d import QDialogDaemon +from util_ui import _translate + +import sys +sys.path.append("..") +from util import RetrieveData + + +class QDialogSlots(QDialogDaemon): + """ + Attributes: + _ipv_id (int): An integer indicating current IP version setting. The + value could be 1 or 0. 1 represents IPv6 while 1 represents IPv4. + _make_path (str): A string indicating the path to store the hosts file + in export mode. + """ + _ipv_id = 0 + _make_path = "./hosts" + + def __init__(self): + """Initialize a new instance of this class - Private Method + """ + super(QDialogSlots, self).__init__() + + def mouseMoveEvent(self, e): + """Set mouse drag event - Public Method + + Allow drag operations to set the new position for current dialog. + + Args: + e (QMouseEvent): A QMouseEvent object indicating current mouse + event. + """ + if e.buttons() & QtCore.Qt.LeftButton: + try: + self.move(e.globalPos() - self.dragPos) + except AttributeError: + pass + e.accept() + + def mousePressEvent(self, e): + """Set mouse press event - Public Method + + Allow drag operations to set the new position for current dialog. + + Args: + e (QMouseEvent): A QMouseEvent object indicating current mouse + event. + """ + if e.button() == QtCore.Qt.LeftButton: + self.dragPos = e.globalPos() - self.frameGeometry().topLeft() + e.accept() + + def on_Mirror_changed(self, mirr_id): + """Change the current mirror setting - Public Method + + The slot response to the signal ({mirr_id}) from SelectMirror widget + while the value is changed. + + Args: + mirr_id (int): An integer indicating current index number of + mirrors. + """ + self._mirr_id = mirr_id + self.check_connection() + + def on_IPVersion_changed(self, ipv_id): + """Change the current IP version setting - Public Method + + The slot response to the signal ({ipv_id}) from SelectIP widget while + the value is changed. + + Args: + ipv_id (int): An integer indicating current IP version setting. + The value could be 1 or 0. 1 represents IPv6 while 1 + represents IPv4. + """ + 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 on_Selection_changed(self, item): + """Change the function selection setting - Public Method + + The slot response to the signal ({item}) from Functionlist widget + while the selection of the items is changed. This method would change + the current selection of functions. + + Args: + item (int): An integer indicating the row number of the item + listed in Functionlist which is changed by user. + """ + ip_flag = self._ipv_id + func_id = item.listWidget().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 + item = self.Ui.Functionlist.item(c_id) + self.refresh_func_list() + + def on_Lang_changed(self, lang): + """Change the UI language setting - Public Method + + The slot response to the signal ({lang}) from SelectLang widget while + the value is changed. This method would change the language of the UI. + + Args: + lang (str): A string indicating the language which is selected by + user. + This string uses the for of IETF language tag. For example: + en_US, en_GB, etc. + """ + new_lang = LangUtil.get_locale_by_language(unicode(lang)) + trans = QtCore.QTranslator() + from hostsutil import LANG_DIR + trans.load(LANG_DIR + new_lang) + QtGui.QApplication.removeTranslator(self._trans) + QtGui.QApplication.installTranslator(trans) + self._trans = trans + self.Ui.retranslateUi(self) + self.init_main() + self.check_connection() + + def on_MakeHosts_clicked(self): + """Start making hosts file - Public Method + + The slot response to the signal from ButtonApply widget while the + button is clicked. This method would call operations to make a hosts + file. + 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 + if self.question_apply(): + self._make_path = "./hosts" + self.make_hosts("system") + else: + return + + def on_MakeANSI_clicked(self): + """Export hosts ANSI - Public Method + + The slot response to the signal from ButtonANSI widget while the + button is clicked. This method would call operations to export a hosts + file encoding in ANSI. + """ + self._make_path = self.export_hosts() + if unicode(self._make_path) != u'': + self.make_hosts("ansi") + + def on_MakeUTF8_clicked(self): + """Export hosts in UTF-8 - Public Method + + The slot response to the signal from ButtonUTF widget while the + button is clicked. This method would call operations to export a hosts + file encoding in UTF-8. + """ + self._make_path = self.export_hosts() + if unicode(self._make_path) != u'': + self.make_hosts("utf-8") + + def on_Backup_clicked(self): + """Backup system hosts file - Public Method + + The slot response to the signal from ButtonBackup widget while the + button is clicked. This method would call operations to backup the + hosts file of current operating system. + """ + 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 on_Restore_clicked(self): + """Restore hosts file - Public Method + + The slot response to the signal from ButtonRestore widget while the + button is clicked. This method would call operations to restore a + previously backed up hosts file. + 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 on_CheckUpdate_clicked(self): + """Check data file update - Public Method + + The slot response to the signal from ButtonCheck widget while the + button is clicked. This method would call operations to fetch update + information of the latest data file. + """ + 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 on_FetchUpdate_clicked(self): + """Fetch data file update - Public Method + + The slot response to the signal from ButtonUpdate widget while the + button is clicked. This method would call operations to fetch the + latest data file. + If no update information has been got from the server, the method to + check the update would be called. + 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() + + def on_LinkActivated(self, url): + """Open external link in browser - Public Method + + The slot response to the signal from Label widget while the text with + a hyperlink is clicked by user. + """ + QtGui.QDesktopServices.openUrl(QtCore.QUrl(url)) \ No newline at end of file diff --git a/gui/qdialog_ui.py b/gui/qdialog_ui.py new file mode 100644 index 0000000..c50a2a5 --- /dev/null +++ b/gui/qdialog_ui.py @@ -0,0 +1,506 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# +# qdialog_ui.py : +# +# Copyleft (C) 2014 - huhamhire hosts team +# ===================================================================== +# Licensed under the GNU General Public License, version 3. You should +# have received a copy of the GNU General Public License along with +# this program. If not, see . +# +# 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 " + +import os + +from PyQt4 import QtCore, QtGui + +from language import LangUtil +from util_ui import Ui_Util, _translate, _fromUtf8 + +import sys +sys.path.append("..") +from util import RetrieveData, CommonUtil + +# Path to store language files +LANG_DIR = "./gui/lang/" + + +class QDialogUI(QtGui.QDialog, object): + """ + Attributes: + _cur_ver (str): A string indicating the current version of hosts data + file. + _trans (obj): A QtCore.QTranslator object indicating the current UI + language setting. + platform (str): A string indicating the platform of current operating + system. The value could be "Windows", "Linux", "Unix", "OS X", and + of course "Unkown". + plat_flag (bool): A boolean flag indicating whether the current os is + supported or not. + Ui (str): A user interface object indicating the main dialog of this + program. + """ + _cur_ver = "" + _trans = None + + # OS related configuration + platform = '' + plat_flag = True + Ui = None + + def __init__(self): + """Initialize a new instance of this class - Private Method + + Set the UI object and current translator of the main dialog. + """ + super(QDialogUI, self).__init__() + self.Ui = Ui_Util() + self.Ui.setupUi(self) + self.set_style() + self.set_stylesheet() + # Set default UI language + trans = QtCore.QTranslator() + trans.load(LANG_DIR + "en_US") + self._trans = trans + QtGui.QApplication.installTranslator(trans) + self.set_languages() + + def set_stylesheet(self): + """Set Stylesheet for main frame - Public Method + + Define the style sheet of main dialog. + """ + app = QtGui.QApplication.instance() + with open("./gui/theme/default.qss", "r") as qss: + app.setStyleSheet(qss.read()) + + def set_style(self): + """Set window style - Public Method + + Set the main dialog with a window style depending on the os platform. + """ + self.setWindowFlags(QtCore.Qt.FramelessWindowHint) + system = self.platform + if system == "Windows": + pass + elif system == "Linux": + # Set window style for sudo users. + QtGui.QApplication.setStyle( + QtGui.QStyleFactory.create("Cleanlooks")) + elif system == "OS X": + pass + + def set_languages(self): + """Set items in SelectLang widget - Public Method + + Set optional language selection items in the SelectLang widget. + """ + self.Ui.SelectLang.clear() + langs = LangUtil.language + langs_not_found = [] + for locale in langs: + if not os.path.isfile(LANG_DIR + locale + ".qm"): + langs_not_found.append(locale) + for locale in langs_not_found: + langs.pop(locale) + LangUtil.language = langs + if len(langs) <= 1: + self.Ui.SelectLang.setEnabled(False) + # Block the signal while set the language selecions. + self.Ui.SelectLang.blockSignals(True) + sys_locale = LangUtil.get_locale() + if sys_locale not in langs.keys(): + sys_locale = "en_US" + for i, locale in enumerate(sorted(langs.keys())): + if sys_locale == locale: + select = i + lang = langs[locale] + self.Ui.SelectLang.addItem(_fromUtf8("")) + self.Ui.SelectLang.setItemText(i, lang) + self.Ui.SelectLang.blockSignals(False) + self.Ui.SelectLang.setCurrentIndex(select) + + def set_label_color(self, label, color): + """Set the color of a label - Public Method + + Set a specified label ({label}) to show with specified color + ({color}). + + Args: + label (obj): An instance of PyQt4.QtGui.QLabel class on the main + dialog. + color (str): A string indicating the color to be shown on the + lable. + """ + if color == "GREEN": + rgb = "#37b158" + elif color == "RED": + rgb = "#e27867" + elif color == "BLACK": + rgb = "#b1b1b1" + label.setStyleSheet("QLabel {color: %s}" % rgb) + + def set_label_text(self, label, text): + """Set the text of a label - Public Method + + Set a specified label ({label}) to show specified text ({text}). + + Args: + label (obj): An instance of PyQt4.QtGui.QLabel class on the main + dialog. + text (str): A string indicating the message to be shown on the + lable. + """ + label.setText(_translate("Util", text, None)) + + def set_conn_status(self, status): + """Set connection status info - Public Method + + 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_info(self): + """Set data file info - Public Method + + 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, build) + + def set_down_progress(self, prog, msg): + """Set progress bar - Public Method + + Set the progress bar to a specified progress position ({prog}) with a + specified message ({msg}). + + Args: + prog (int): An integer indicating the progress to be set on the + progress bar. + msg (str): A string indicating the message to be shown on the + progress bar. + """ + self.Ui.Prog.setProperty("value", prog) + self.set_conn_status(1) + self.Ui.Prog.setFormat(msg) + + def set_platform_label(self): + """Set label of OS info - Public Method + + Set the information of the label indicating current operating system + platform. + """ + color = "GREEN" if self.plat_flag else "RED" + self.set_label_color(self.Ui.labelOSStat, color) + self.set_label_text(self.Ui.labelOSStat, "[%s]" % self.platform) + + def set_func_list(self, new=0): + """Set the function list - Public Method + + Draw the function list and decide whether to load the default + selection configuration or not. + + Arg: + new (int): A flag integer indicating whether to load the default + selection configuration or not. 0 -> user user config, + 1 -> use default config. Default by 0. + """ + ip_flag = self._ipv_id + 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) + self.choice[ip] = choice + self.slices[ip] = slices + funcs = [] + for func in choice: + item = QtGui.QListWidgetItem() + if func[1] in defaults[func[0]]: + funcs.append(1) + else: + funcs.append(0) + self._funcs[ip] = funcs + + def set_list_item_unchecked(self, item_id): + """Set list item to be unchecked - Public Method + + Set a specified item ({item_id}) to become unchecked in the function + list. + + Arg: + item_id (int): An integer indicating the id number of a specified + item in the function list. + """ + self._funcs[self._ipv_id][item_id] = 0 + item = self.Ui.Functionlist.item(item_id) + item.setCheckState(QtCore.Qt.Unchecked) + + def refresh_func_list(self): + """Refresh the function list - Public Method + + 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_make_progress(self, mod_name, mod_num): + """Operations to show progress while making hosts file - Public Method + + The slot response to the info_trigger signal ({mod_name}, {mod_num}) + from an instance of QSubMakeHosts class while making operations are + proceeded. + + Args: + mod_name (str): A string indicating the name of a specified hosts + module in current progress. + mod_num (int): An integer indicating the number of current module + in the operation sequence. + """ + total_mods_num = self._funcs[self._ipv_id].count(1) + 1 + prog = 100 * mod_num / total_mods_num + self.Ui.Prog.setProperty("value", prog) + format = unicode(_translate( + "Util", "Applying module: %s(%s/%s)", None)) % ( + mod_name, mod_num, total_mods_num) + self.Ui.Prog.setFormat(format) + self.set_make_message(format) + + + def set_message(self, title, msg): + """Set a message box - Public Method + + Show a message box with a specified message ({msg}) with a specified + title ({title}). + + Args: + title (str): A string indicating the title of the message box. + msg (str): A string indicating the message to be shown in the + message box. + """ + self.Ui.FunctionsBox.setTitle(_translate("Util", title, None)) + self.Ui.Functionlist.clear() + item = QtGui.QListWidgetItem() + item.setText(msg) + item.setFlags(QtCore.Qt.ItemIsEnabled) + self.Ui.Functionlist.addItem(item) + + def set_make_message(self, msg, start=0): + """Operations to show making progress in function list - Public Method + + List message for the current operating progress while making the new + hosts file. + + Args: + msg (str): A string indicating the message to show in the function + list. + start (int): A flag integer indicating whether the message is the + first of the making progress or not. 1: first, 0: not the + first. Default by 0. + """ + if start: + self.Ui.FunctionsBox.setTitle(_translate( + "Util", "Progress", None)) + self.Ui.Functionlist.clear() + item = QtGui.QListWidgetItem() + item.setText("- " + msg) + item.setFlags(QtCore.Qt.ItemIsEnabled) + self.Ui.Functionlist.addItem(item) + + def warning_permission(self): + """Show permission error warning - Public Method + + Draw 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 warning_download(self): + """Show download error warning - Public Method + + Draw 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_incorrect_datafile(self): + """Show incorrect data file warning - Public Method + + Draw incorrect data file warning message box. + """ + 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.Ui.ButtonApply.setEnabled(False) + self.Ui.ButtonANSI.setEnabled(False) + self.Ui.ButtonUTF.setEnabled(False) + + def warning_no_datafile(self): + """Show no data file warning - Public Method + + Draw 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(msg_title, msg) + self.Ui.ButtonApply.setEnabled(False) + self.Ui.ButtonANSI.setEnabled(False) + self.Ui.ButtonUTF.setEnabled(False) + + def question_apply(self): + """Show confirm make question - Public Method + + Draw confirm make question message box. + + Returns: + A bool flag indicating whether user has accepted to continue the + operations or not. True: Continue, False: Cancel. + """ + 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_uptodate(self): + """Show up-to-date message - Public Method + + 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 info_complete(self): + """Show complete message - Public Method + + Draw operation complete message box. + """ + QtGui.QMessageBox.information( + self, _translate("Util", "Complete", None), + _translate("Util", "Operation completed", None)) + + + + def set_make_start_btns(self): + self.Ui.Functionlist.setEnabled(False) + self.Ui.SelectIP.setEnabled(False) + self.Ui.ButtonCheck.setEnabled(False) + self.Ui.ButtonUpdate.setEnabled(False) + self.Ui.ButtonApply.setEnabled(False) + self.Ui.ButtonANSI.setEnabled(False) + self.Ui.ButtonUTF.setEnabled(False) + self.Ui.ButtonExit.setEnabled(False) + + def set_make_finish_btns(self): + self.Ui.Functionlist.setEnabled(True) + self.Ui.SelectIP.setEnabled(True) + self.Ui.ButtonCheck.setEnabled(True) + self.Ui.ButtonUpdate.setEnabled(True) + self.Ui.ButtonApply.setEnabled(False) + self.Ui.ButtonANSI.setEnabled(False) + self.Ui.ButtonUTF.setEnabled(False) + self.Ui.ButtonExit.setEnabled(True) + + def set_update_click_btns(self): + self.Ui.ButtonApply.setEnabled(True) + self.Ui.ButtonANSI.setEnabled(True) + self.Ui.ButtonUTF.setEnabled(True) + + def set_update_start_btns(self): + self.Ui.SelectMirror.setEnabled(False) + self.Ui.ButtonCheck.setEnabled(False) + self.Ui.ButtonUpdate.setEnabled(False) + + def set_update_finish_btns(self): + self.Ui.SelectMirror.setEnabled(True) + self.Ui.ButtonCheck.setEnabled(True) + self.Ui.ButtonUpdate.setEnabled(True) + + def set_fetch_click_btns(self): + self.Ui.Functionlist.setEnabled(False) + self.Ui.ButtonApply.setEnabled(False) + self.Ui.ButtonANSI.setEnabled(False) + self.Ui.ButtonUTF.setEnabled(False) + + def set_fetch_start_btns(self): + self.Ui.SelectMirror.setEnabled(False) + self.Ui.ButtonCheck.setEnabled(False) + self.Ui.ButtonUpdate.setEnabled(False) + self.Ui.ButtonApply.setEnabled(False) + self.Ui.ButtonANSI.setEnabled(False) + self.Ui.ButtonUTF.setEnabled(False) + self.Ui.ButtonExit.setEnabled(False) + + def set_fetch_finish_btns(self, error=0): + if error: + self.Ui.ButtonApply.setEnabled(False) + self.Ui.ButtonANSI.setEnabled(False) + self.Ui.ButtonUTF.setEnabled(False) + else: + self.Ui.ButtonApply.setEnabled(True) + self.Ui.ButtonANSI.setEnabled(True) + self.Ui.ButtonUTF.setEnabled(True) + self.Ui.Functionlist.setEnabled(True) + self.Ui.SelectMirror.setEnabled(True) + self.Ui.ButtonCheck.setEnabled(True) + self.Ui.ButtonUpdate.setEnabled(True) + self.Ui.ButtonExit.setEnabled(True) diff --git a/style_rc.py b/gui/style_rc.py similarity index 95% rename from style_rc.py rename to gui/style_rc.py index c1a0e48..3569b69 100644 --- a/style_rc.py +++ b/gui/style_rc.py @@ -2,7 +2,7 @@ # Resource object code # -# Created: 周二 12月 3 15:25:34 2013 +# Created: 周一 12月 9 17:45:36 2013 # by: The Resource Compiler for PyQt (Qt v4.8.4) # # WARNING! All changes made in this file will be lost! @@ -107,6 +107,10 @@ \x00\x71\ \x00\x73\x00\x73\ \x00\x03\ +\x00\x00\x78\xc3\ +\x00\x72\ +\x00\x65\x00\x73\ +\x00\x03\ \x00\x00\x70\x37\ \x00\x69\ \x00\x6d\x00\x67\ @@ -128,9 +132,10 @@ \x00\x00\x00\x00\x00\x02\x00\x00\x00\x01\x00\x00\x00\x01\ \x00\x00\x00\x00\x00\x02\x00\x00\x00\x01\x00\x00\x00\x02\ \x00\x00\x00\x0c\x00\x02\x00\x00\x00\x01\x00\x00\x00\x03\ -\x00\x00\x00\x18\x00\x02\x00\x00\x00\x02\x00\x00\x00\x04\ -\x00\x00\x00\x28\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\ -\x00\x00\x00\x46\x00\x00\x00\x00\x00\x01\x00\x00\x01\x5b\ +\x00\x00\x00\x18\x00\x02\x00\x00\x00\x01\x00\x00\x00\x04\ +\x00\x00\x00\x24\x00\x02\x00\x00\x00\x02\x00\x00\x00\x05\ +\x00\x00\x00\x34\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\ +\x00\x00\x00\x52\x00\x00\x00\x00\x00\x01\x00\x00\x01\x5b\ " def qInitResources(): diff --git a/theme/darkdefault.qss b/gui/theme/default.qss similarity index 98% rename from theme/darkdefault.qss rename to gui/theme/default.qss index a1c4309..7d3a06d 100644 --- a/theme/darkdefault.qss +++ b/gui/theme/default.qss @@ -113,7 +113,7 @@ QComboBox::drop-down QComboBox::down-arrow { - image: url(:/qss/img/style/down_arrow.png); + image: url(:/qss/res/img/style/down_arrow.png); } QGroupBox { @@ -280,7 +280,7 @@ QCheckBox::indicator{ QCheckBox::indicator:checked { - image:url(:/qss/img/style/checkbox.png); + image:url(:/qss/res/img/style/checkbox.png); } QCheckBox::indicator:disabled, QRadioButton::indicator:disabled diff --git a/qthosts_rc.py b/gui/util_rc.py similarity index 99% rename from qthosts_rc.py rename to gui/util_rc.py index bff1f2b..8307540 100644 --- a/qthosts_rc.py +++ b/gui/util_rc.py @@ -2,7 +2,7 @@ # Resource object code # -# Created: 周二 12月 3 15:25:33 2013 +# Created: 周一 12月 9 17:45:36 2013 # by: The Resource Compiler for PyQt (Qt v4.8.4) # # WARNING! All changes made in this file will be lost! @@ -3444,6 +3444,10 @@ \x00\x62\ \x00\x75\x00\x74\x00\x74\x00\x6f\x00\x6e\x00\x73\ \x00\x03\ +\x00\x00\x78\xc3\ +\x00\x72\ +\x00\x65\x00\x73\ +\x00\x03\ \x00\x00\x70\x37\ \x00\x69\ \x00\x6d\x00\x67\ @@ -3536,29 +3540,31 @@ qt_resource_struct = "\ \x00\x00\x00\x00\x00\x02\x00\x00\x00\x02\x00\x00\x00\x01\ -\x00\x00\x00\x00\x00\x02\x00\x00\x00\x01\x00\x00\x00\x15\ +\x00\x00\x00\x00\x00\x02\x00\x00\x00\x01\x00\x00\x00\x16\ \x00\x00\x00\x0e\x00\x02\x00\x00\x00\x01\x00\x00\x00\x03\ \x00\x00\x00\x22\x00\x02\x00\x00\x00\x01\x00\x00\x00\x04\ -\x00\x00\x00\x0e\x00\x02\x00\x00\x00\x10\x00\x00\x00\x05\ -\x00\x00\x00\xb8\x00\x00\x00\x00\x00\x01\x00\x00\x12\x2c\ -\x00\x00\x02\xb6\x00\x00\x00\x00\x00\x01\x00\x00\x57\x58\ -\x00\x00\x02\x6a\x00\x00\x00\x00\x00\x01\x00\x00\x48\xda\ -\x00\x00\x03\x04\x00\x00\x00\x00\x00\x01\x00\x00\x62\xfc\ -\x00\x00\x02\x8e\x00\x00\x00\x00\x00\x01\x00\x00\x50\x67\ -\x00\x00\x01\xbe\x00\x00\x00\x00\x00\x01\x00\x00\x33\x9e\ -\x00\x00\x01\x64\x00\x00\x00\x00\x00\x01\x00\x00\x25\x54\ -\x00\x00\x00\x68\x00\x00\x00\x00\x00\x01\x00\x00\x04\xfc\ -\x00\x00\x00\xf0\x00\x00\x00\x00\x00\x01\x00\x00\x18\xef\ -\x00\x00\x01\x88\x00\x00\x00\x00\x00\x01\x00\x00\x2c\x15\ -\x00\x00\x01\x2e\x00\x00\x00\x00\x00\x01\x00\x00\x1e\x93\ -\x00\x00\x01\xfa\x00\x00\x00\x00\x00\x01\x00\x00\x3a\x5d\ -\x00\x00\x02\xdc\x00\x00\x00\x00\x00\x01\x00\x00\x5e\x00\ -\x00\x00\x00\x2e\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\ -\x00\x00\x02\x30\x00\x00\x00\x00\x00\x01\x00\x00\x41\xe9\ -\x00\x00\x00\x94\x00\x00\x00\x00\x00\x01\x00\x00\x0a\xa0\ -\x00\x00\x00\x22\x00\x02\x00\x00\x00\x01\x00\x00\x00\x16\ -\x00\x00\x03\x2e\x00\x02\x00\x00\x00\x01\x00\x00\x00\x17\ -\x00\x00\x03\x3e\x00\x00\x00\x00\x00\x01\x00\x00\x69\xb1\ +\x00\x00\x00\x2e\x00\x02\x00\x00\x00\x01\x00\x00\x00\x05\ +\x00\x00\x00\x0e\x00\x02\x00\x00\x00\x10\x00\x00\x00\x06\ +\x00\x00\x00\xc4\x00\x00\x00\x00\x00\x01\x00\x00\x12\x2c\ +\x00\x00\x02\xc2\x00\x00\x00\x00\x00\x01\x00\x00\x57\x58\ +\x00\x00\x02\x76\x00\x00\x00\x00\x00\x01\x00\x00\x48\xda\ +\x00\x00\x03\x10\x00\x00\x00\x00\x00\x01\x00\x00\x62\xfc\ +\x00\x00\x02\x9a\x00\x00\x00\x00\x00\x01\x00\x00\x50\x67\ +\x00\x00\x01\xca\x00\x00\x00\x00\x00\x01\x00\x00\x33\x9e\ +\x00\x00\x01\x70\x00\x00\x00\x00\x00\x01\x00\x00\x25\x54\ +\x00\x00\x00\x74\x00\x00\x00\x00\x00\x01\x00\x00\x04\xfc\ +\x00\x00\x00\xfc\x00\x00\x00\x00\x00\x01\x00\x00\x18\xef\ +\x00\x00\x01\x94\x00\x00\x00\x00\x00\x01\x00\x00\x2c\x15\ +\x00\x00\x01\x3a\x00\x00\x00\x00\x00\x01\x00\x00\x1e\x93\ +\x00\x00\x02\x06\x00\x00\x00\x00\x00\x01\x00\x00\x3a\x5d\ +\x00\x00\x02\xe8\x00\x00\x00\x00\x00\x01\x00\x00\x5e\x00\ +\x00\x00\x00\x3a\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\ +\x00\x00\x02\x3c\x00\x00\x00\x00\x00\x01\x00\x00\x41\xe9\ +\x00\x00\x00\xa0\x00\x00\x00\x00\x00\x01\x00\x00\x0a\xa0\ +\x00\x00\x00\x22\x00\x02\x00\x00\x00\x01\x00\x00\x00\x17\ +\x00\x00\x00\x2e\x00\x02\x00\x00\x00\x01\x00\x00\x00\x18\ +\x00\x00\x03\x3a\x00\x02\x00\x00\x00\x01\x00\x00\x00\x19\ +\x00\x00\x03\x4a\x00\x00\x00\x00\x00\x01\x00\x00\x69\xb1\ " def qInitResources(): diff --git a/qthostsui.py b/gui/util_ui.py similarity index 60% rename from qthostsui.py rename to gui/util_ui.py index f13bf31..ed04c33 100644 --- a/qthostsui.py +++ b/gui/util_ui.py @@ -1,8 +1,8 @@ # -*- coding: utf-8 -*- -# Form implementation generated from reading ui file 'qthostsui.ui' +# Form implementation generated from reading ui file '../pyqt\util_ui.ui' # -# Created: Tue Dec 03 15:25:34 2013 +# Created: Mon Dec 09 17:45:37 2013 # by: PyQt4 UI code generator 4.10.2 # # WARNING! All changes made in this file will be lost! @@ -23,26 +23,26 @@ def _translate(context, text, disambig): def _translate(context, text, disambig): return QtGui.QApplication.translate(context, text, disambig) -class Ui_HostsUtlMain(object): - def setupUi(self, HostsUtlMain): - HostsUtlMain.setObjectName(_fromUtf8("HostsUtlMain")) - HostsUtlMain.setEnabled(True) - HostsUtlMain.resize(640, 420) +class Ui_Util(object): + def setupUi(self, Util): + Util.setObjectName(_fromUtf8("Util")) + Util.setEnabled(True) + Util.resize(640, 420) sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Fixed) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(HostsUtlMain.sizePolicy().hasHeightForWidth()) - HostsUtlMain.setSizePolicy(sizePolicy) - HostsUtlMain.setMinimumSize(QtCore.QSize(640, 420)) - HostsUtlMain.setMaximumSize(QtCore.QSize(640, 420)) - HostsUtlMain.setContextMenuPolicy(QtCore.Qt.DefaultContextMenu) + sizePolicy.setHeightForWidth(Util.sizePolicy().hasHeightForWidth()) + Util.setSizePolicy(sizePolicy) + Util.setMinimumSize(QtCore.QSize(640, 420)) + Util.setMaximumSize(QtCore.QSize(640, 420)) + Util.setContextMenuPolicy(QtCore.Qt.DefaultContextMenu) icon = QtGui.QIcon() - icon.addPixmap(QtGui.QPixmap(_fromUtf8(":/icon/img/icons/utl_icon@256x256.png")), QtGui.QIcon.Normal, QtGui.QIcon.Off) - HostsUtlMain.setWindowIcon(icon) - HostsUtlMain.setLocale(QtCore.QLocale(QtCore.QLocale.English, QtCore.QLocale.UnitedStates)) - HostsUtlMain.setSizeGripEnabled(False) - HostsUtlMain.setModal(False) - self.mainFrame = QtGui.QFrame(HostsUtlMain) + icon.addPixmap(QtGui.QPixmap(_fromUtf8(":/icon/res/img/icons/utl_icon@256x256.png")), QtGui.QIcon.Normal, QtGui.QIcon.Off) + Util.setWindowIcon(icon) + Util.setLocale(QtCore.QLocale(QtCore.QLocale.English, QtCore.QLocale.UnitedStates)) + Util.setSizeGripEnabled(False) + Util.setModal(False) + self.mainFrame = QtGui.QFrame(Util) self.mainFrame.setGeometry(QtCore.QRect(0, 40, 640, 351)) self.mainFrame.setFrameShape(QtGui.QFrame.StyledPanel) self.mainFrame.setFrameShadow(QtGui.QFrame.Raised) @@ -164,8 +164,8 @@ def setupUi(self, HostsUtlMain): self.ButtonBackup.setGeometry(QtCore.QRect(0, 10, 48, 48)) self.ButtonBackup.setText(_fromUtf8("")) icon1 = QtGui.QIcon() - icon1.addPixmap(QtGui.QPixmap(_fromUtf8(":/buttons/img/buttons/button_backup.png")), QtGui.QIcon.Normal, QtGui.QIcon.Off) - icon1.addPixmap(QtGui.QPixmap(_fromUtf8(":/buttons/img/buttons/button_backup_disabled.png")), QtGui.QIcon.Disabled, QtGui.QIcon.Off) + icon1.addPixmap(QtGui.QPixmap(_fromUtf8(":/buttons/res/img/buttons/button_backup.png")), QtGui.QIcon.Normal, QtGui.QIcon.Off) + icon1.addPixmap(QtGui.QPixmap(_fromUtf8(":/buttons/res/img/buttons/button_backup_disabled.png")), QtGui.QIcon.Disabled, QtGui.QIcon.Off) self.ButtonBackup.setIcon(icon1) self.ButtonBackup.setIconSize(QtCore.QSize(32, 32)) self.ButtonBackup.setObjectName(_fromUtf8("ButtonBackup")) @@ -173,8 +173,8 @@ def setupUi(self, HostsUtlMain): self.ButtonUpdate.setGeometry(QtCore.QRect(60, 70, 48, 48)) self.ButtonUpdate.setText(_fromUtf8("")) icon2 = QtGui.QIcon() - icon2.addPixmap(QtGui.QPixmap(_fromUtf8(":/buttons/img/buttons/button_download.png")), QtGui.QIcon.Normal, QtGui.QIcon.Off) - icon2.addPixmap(QtGui.QPixmap(_fromUtf8(":/buttons/img/buttons/button_download_disabled.png")), QtGui.QIcon.Disabled, QtGui.QIcon.Off) + icon2.addPixmap(QtGui.QPixmap(_fromUtf8(":/buttons/res/img/buttons/button_download.png")), QtGui.QIcon.Normal, QtGui.QIcon.Off) + icon2.addPixmap(QtGui.QPixmap(_fromUtf8(":/buttons/res/img/buttons/button_download_disabled.png")), QtGui.QIcon.Disabled, QtGui.QIcon.Off) self.ButtonUpdate.setIcon(icon2) self.ButtonUpdate.setIconSize(QtCore.QSize(32, 32)) self.ButtonUpdate.setObjectName(_fromUtf8("ButtonUpdate")) @@ -182,8 +182,8 @@ def setupUi(self, HostsUtlMain): self.ButtonRestore.setGeometry(QtCore.QRect(60, 10, 48, 48)) self.ButtonRestore.setText(_fromUtf8("")) icon3 = QtGui.QIcon() - icon3.addPixmap(QtGui.QPixmap(_fromUtf8(":/buttons/img/buttons/button_restore.png")), QtGui.QIcon.Normal, QtGui.QIcon.Off) - icon3.addPixmap(QtGui.QPixmap(_fromUtf8(":/buttons/img/buttons/button_restore_disabled.png")), QtGui.QIcon.Disabled, QtGui.QIcon.Off) + icon3.addPixmap(QtGui.QPixmap(_fromUtf8(":/buttons/res/img/buttons/button_restore.png")), QtGui.QIcon.Normal, QtGui.QIcon.Off) + icon3.addPixmap(QtGui.QPixmap(_fromUtf8(":/buttons/res/img/buttons/button_restore_disabled.png")), QtGui.QIcon.Disabled, QtGui.QIcon.Off) self.ButtonRestore.setIcon(icon3) self.ButtonRestore.setIconSize(QtCore.QSize(32, 32)) self.ButtonRestore.setObjectName(_fromUtf8("ButtonRestore")) @@ -191,8 +191,8 @@ def setupUi(self, HostsUtlMain): self.ButtonApply.setGeometry(QtCore.QRect(0, 220, 48, 48)) self.ButtonApply.setText(_fromUtf8("")) icon4 = QtGui.QIcon() - icon4.addPixmap(QtGui.QPixmap(_fromUtf8(":/buttons/img/buttons/button_apply.png")), QtGui.QIcon.Normal, QtGui.QIcon.Off) - icon4.addPixmap(QtGui.QPixmap(_fromUtf8(":/buttons/img/buttons/button_apply_disabled.png")), QtGui.QIcon.Disabled, QtGui.QIcon.Off) + icon4.addPixmap(QtGui.QPixmap(_fromUtf8(":/buttons/res/img/buttons/button_apply.png")), QtGui.QIcon.Normal, QtGui.QIcon.Off) + icon4.addPixmap(QtGui.QPixmap(_fromUtf8(":/buttons/res/img/buttons/button_apply_disabled.png")), QtGui.QIcon.Disabled, QtGui.QIcon.Off) self.ButtonApply.setIcon(icon4) self.ButtonApply.setIconSize(QtCore.QSize(32, 32)) self.ButtonApply.setObjectName(_fromUtf8("ButtonApply")) @@ -200,8 +200,8 @@ def setupUi(self, HostsUtlMain): self.ButtonExit.setGeometry(QtCore.QRect(60, 220, 48, 48)) self.ButtonExit.setText(_fromUtf8("")) icon5 = QtGui.QIcon() - icon5.addPixmap(QtGui.QPixmap(_fromUtf8(":/buttons/img/buttons/button_exit.png")), QtGui.QIcon.Normal, QtGui.QIcon.Off) - icon5.addPixmap(QtGui.QPixmap(_fromUtf8(":/buttons/img/buttons/button_exit_disabled.png")), QtGui.QIcon.Disabled, QtGui.QIcon.Off) + icon5.addPixmap(QtGui.QPixmap(_fromUtf8(":/buttons/res/img/buttons/button_exit.png")), QtGui.QIcon.Normal, QtGui.QIcon.Off) + icon5.addPixmap(QtGui.QPixmap(_fromUtf8(":/buttons/res/img/buttons/button_exit_disabled.png")), QtGui.QIcon.Disabled, QtGui.QIcon.Off) self.ButtonExit.setIcon(icon5) self.ButtonExit.setIconSize(QtCore.QSize(32, 32)) self.ButtonExit.setObjectName(_fromUtf8("ButtonExit")) @@ -209,8 +209,8 @@ def setupUi(self, HostsUtlMain): self.ButtonCheck.setGeometry(QtCore.QRect(0, 70, 48, 48)) self.ButtonCheck.setText(_fromUtf8("")) icon6 = QtGui.QIcon() - icon6.addPixmap(QtGui.QPixmap(_fromUtf8(":/buttons/img/buttons/button_update.png")), QtGui.QIcon.Normal, QtGui.QIcon.Off) - icon6.addPixmap(QtGui.QPixmap(_fromUtf8(":/buttons/img/buttons/button_update_disabled.png")), QtGui.QIcon.Disabled, QtGui.QIcon.Off) + icon6.addPixmap(QtGui.QPixmap(_fromUtf8(":/buttons/res/img/buttons/button_update.png")), QtGui.QIcon.Normal, QtGui.QIcon.Off) + icon6.addPixmap(QtGui.QPixmap(_fromUtf8(":/buttons/res/img/buttons/button_update_disabled.png")), QtGui.QIcon.Disabled, QtGui.QIcon.Off) self.ButtonCheck.setIcon(icon6) self.ButtonCheck.setIconSize(QtCore.QSize(32, 32)) self.ButtonCheck.setObjectName(_fromUtf8("ButtonCheck")) @@ -218,8 +218,8 @@ def setupUi(self, HostsUtlMain): self.ButtonANSI.setGeometry(QtCore.QRect(0, 160, 48, 48)) self.ButtonANSI.setText(_fromUtf8("")) icon7 = QtGui.QIcon() - icon7.addPixmap(QtGui.QPixmap(_fromUtf8(":/buttons/img/buttons/button_ansi.png")), QtGui.QIcon.Normal, QtGui.QIcon.Off) - icon7.addPixmap(QtGui.QPixmap(_fromUtf8(":/buttons/img/buttons/button_ansi_disabled.png")), QtGui.QIcon.Disabled, QtGui.QIcon.Off) + icon7.addPixmap(QtGui.QPixmap(_fromUtf8(":/buttons/res/img/buttons/button_ansi.png")), QtGui.QIcon.Normal, QtGui.QIcon.Off) + icon7.addPixmap(QtGui.QPixmap(_fromUtf8(":/buttons/res/img/buttons/button_ansi_disabled.png")), QtGui.QIcon.Disabled, QtGui.QIcon.Off) self.ButtonANSI.setIcon(icon7) self.ButtonANSI.setIconSize(QtCore.QSize(32, 32)) self.ButtonANSI.setObjectName(_fromUtf8("ButtonANSI")) @@ -227,8 +227,8 @@ def setupUi(self, HostsUtlMain): self.ButtonUTF.setGeometry(QtCore.QRect(60, 160, 48, 48)) self.ButtonUTF.setText(_fromUtf8("")) icon8 = QtGui.QIcon() - icon8.addPixmap(QtGui.QPixmap(_fromUtf8(":/buttons/img/buttons/button_utf8.png")), QtGui.QIcon.Normal, QtGui.QIcon.Off) - icon8.addPixmap(QtGui.QPixmap(_fromUtf8(":/buttons/img/buttons/button_utf8_disabled.png")), QtGui.QIcon.Disabled, QtGui.QIcon.Off) + icon8.addPixmap(QtGui.QPixmap(_fromUtf8(":/buttons/res/img/buttons/button_utf8.png")), QtGui.QIcon.Normal, QtGui.QIcon.Off) + icon8.addPixmap(QtGui.QPixmap(_fromUtf8(":/buttons/res/img/buttons/button_utf8_disabled.png")), QtGui.QIcon.Disabled, QtGui.QIcon.Off) self.ButtonUTF.setIcon(icon8) self.ButtonUTF.setIconSize(QtCore.QSize(32, 32)) self.ButtonUTF.setObjectName(_fromUtf8("ButtonUTF")) @@ -241,93 +241,93 @@ def setupUi(self, HostsUtlMain): self.Prog.setTextVisible(True) self.Prog.setInvertedAppearance(False) self.Prog.setObjectName(_fromUtf8("Prog")) - self.TitleLabel = QtGui.QLabel(HostsUtlMain) + self.TitleLabel = QtGui.QLabel(Util) self.TitleLabel.setGeometry(QtCore.QRect(20, 20, 250, 25)) self.TitleLabel.setObjectName(_fromUtf8("TitleLabel")) - self.Copyright = QtGui.QLabel(HostsUtlMain) + self.Copyright = QtGui.QLabel(Util) self.Copyright.setGeometry(QtCore.QRect(330, 390, 300, 16)) self.Copyright.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter) self.Copyright.setObjectName(_fromUtf8("Copyright")) - self.label = QtGui.QLabel(HostsUtlMain) + self.label = QtGui.QLabel(Util) self.label.setGeometry(QtCore.QRect(10, 390, 150, 16)) self.label.setObjectName(_fromUtf8("label")) self.labelIP.setBuddy(self.SelectMirror) self.labelMirror.setBuddy(self.SelectIP) - self.retranslateUi(HostsUtlMain) - QtCore.QObject.connect(self.ButtonExit, QtCore.SIGNAL(_fromUtf8("clicked()")), HostsUtlMain.close) - QtCore.QObject.connect(self.SelectIP, QtCore.SIGNAL(_fromUtf8("currentIndexChanged(int)")), HostsUtlMain.on_IPVersion_changed) - QtCore.QObject.connect(self.SelectMirror, QtCore.SIGNAL(_fromUtf8("currentIndexChanged(int)")), HostsUtlMain.on_Mirror_changed) - QtCore.QObject.connect(self.Functionlist, QtCore.SIGNAL(_fromUtf8("itemChanged(QListWidgetItem*)")), HostsUtlMain.on_Selection_changed) - QtCore.QObject.connect(self.ButtonApply, QtCore.SIGNAL(_fromUtf8("clicked()")), HostsUtlMain.on_MakeHosts_clicked) - QtCore.QObject.connect(self.ButtonBackup, QtCore.SIGNAL(_fromUtf8("clicked()")), HostsUtlMain.on_Backup_clicked) - QtCore.QObject.connect(self.ButtonRestore, QtCore.SIGNAL(_fromUtf8("clicked()")), HostsUtlMain.on_Restore_clicked) - QtCore.QObject.connect(self.ButtonCheck, QtCore.SIGNAL(_fromUtf8("clicked()")), HostsUtlMain.on_CheckUpdate_clicked) - QtCore.QObject.connect(self.ButtonUpdate, QtCore.SIGNAL(_fromUtf8("clicked()")), HostsUtlMain.on_FetchUpdate_clicked) - QtCore.QObject.connect(self.SelectLang, QtCore.SIGNAL(_fromUtf8("currentIndexChanged(QString)")), HostsUtlMain.on_Lang_changed) - QtCore.QObject.connect(self.ButtonANSI, QtCore.SIGNAL(_fromUtf8("clicked()")), HostsUtlMain.on_MakeANSI_clicked) - QtCore.QObject.connect(self.ButtonUTF, QtCore.SIGNAL(_fromUtf8("clicked()")), HostsUtlMain.on_MakeUTF8_clicked) - QtCore.QObject.connect(self.Copyright, QtCore.SIGNAL(_fromUtf8("linkActivated(QString)")), HostsUtlMain.on_LinkActivated) - QtCore.QMetaObject.connectSlotsByName(HostsUtlMain) - HostsUtlMain.setTabOrder(self.SelectMirror, self.SelectIP) - HostsUtlMain.setTabOrder(self.SelectIP, self.Functionlist) - HostsUtlMain.setTabOrder(self.Functionlist, self.ButtonApply) - HostsUtlMain.setTabOrder(self.ButtonApply, self.ButtonExit) - HostsUtlMain.setTabOrder(self.ButtonExit, self.ButtonCheck) - HostsUtlMain.setTabOrder(self.ButtonCheck, self.ButtonUpdate) - HostsUtlMain.setTabOrder(self.ButtonUpdate, self.ButtonBackup) - HostsUtlMain.setTabOrder(self.ButtonBackup, self.ButtonRestore) - HostsUtlMain.setTabOrder(self.ButtonRestore, self.ButtonANSI) - HostsUtlMain.setTabOrder(self.ButtonANSI, self.ButtonUTF) - HostsUtlMain.setTabOrder(self.ButtonUTF, self.SelectLang) + self.retranslateUi(Util) + QtCore.QObject.connect(self.ButtonExit, QtCore.SIGNAL(_fromUtf8("clicked()")), Util.close) + QtCore.QObject.connect(self.SelectIP, QtCore.SIGNAL(_fromUtf8("currentIndexChanged(int)")), Util.on_IPVersion_changed) + QtCore.QObject.connect(self.SelectMirror, QtCore.SIGNAL(_fromUtf8("currentIndexChanged(int)")), Util.on_Mirror_changed) + QtCore.QObject.connect(self.Functionlist, QtCore.SIGNAL(_fromUtf8("itemChanged(QListWidgetItem*)")), Util.on_Selection_changed) + QtCore.QObject.connect(self.ButtonApply, QtCore.SIGNAL(_fromUtf8("clicked()")), Util.on_MakeHosts_clicked) + QtCore.QObject.connect(self.ButtonBackup, QtCore.SIGNAL(_fromUtf8("clicked()")), Util.on_Backup_clicked) + QtCore.QObject.connect(self.ButtonRestore, QtCore.SIGNAL(_fromUtf8("clicked()")), Util.on_Restore_clicked) + QtCore.QObject.connect(self.ButtonCheck, QtCore.SIGNAL(_fromUtf8("clicked()")), Util.on_CheckUpdate_clicked) + QtCore.QObject.connect(self.ButtonUpdate, QtCore.SIGNAL(_fromUtf8("clicked()")), Util.on_FetchUpdate_clicked) + QtCore.QObject.connect(self.SelectLang, QtCore.SIGNAL(_fromUtf8("currentIndexChanged(QString)")), Util.on_Lang_changed) + QtCore.QObject.connect(self.ButtonANSI, QtCore.SIGNAL(_fromUtf8("clicked()")), Util.on_MakeANSI_clicked) + QtCore.QObject.connect(self.ButtonUTF, QtCore.SIGNAL(_fromUtf8("clicked()")), Util.on_MakeUTF8_clicked) + QtCore.QObject.connect(self.Copyright, QtCore.SIGNAL(_fromUtf8("linkActivated(QString)")), Util.on_LinkActivated) + QtCore.QMetaObject.connectSlotsByName(Util) + Util.setTabOrder(self.SelectMirror, self.SelectIP) + Util.setTabOrder(self.SelectIP, self.Functionlist) + Util.setTabOrder(self.Functionlist, self.ButtonApply) + Util.setTabOrder(self.ButtonApply, self.ButtonExit) + Util.setTabOrder(self.ButtonExit, self.ButtonCheck) + Util.setTabOrder(self.ButtonCheck, self.ButtonUpdate) + Util.setTabOrder(self.ButtonUpdate, self.ButtonBackup) + Util.setTabOrder(self.ButtonBackup, self.ButtonRestore) + Util.setTabOrder(self.ButtonRestore, self.ButtonANSI) + Util.setTabOrder(self.ButtonANSI, self.ButtonUTF) + Util.setTabOrder(self.ButtonUTF, self.SelectLang) - def retranslateUi(self, HostsUtlMain): - HostsUtlMain.setWindowTitle(_translate("HostsUtlMain", "Hosts Setup Utility", None)) - self.ConfigBox.setTitle(_translate("HostsUtlMain", "Config", None)) - self.labelIP.setText(_translate("HostsUtlMain", "Server", None)) - self.labelMirror.setText(_translate("HostsUtlMain", "IP Version", None)) - self.StatusBox.setTitle(_translate("HostsUtlMain", "Status", None)) - self.labelConn.setText(_translate("HostsUtlMain", "Connection", None)) - self.labelConnStat.setText(_translate("HostsUtlMain", "N/A", None)) - self.labelOS.setText(_translate("HostsUtlMain", "OS", None)) - self.labelOSStat.setText(_translate("HostsUtlMain", "N/A", None)) - self.InfoBox.setTitle(_translate("HostsUtlMain", "Hosts Info", None)) - self.labelVersion.setText(_translate("HostsUtlMain", "Version", None)) - self.labelVersionData.setText(_translate("HostsUtlMain", "N/A", None)) - self.labelRelease.setText(_translate("HostsUtlMain", "Release", None)) - self.labelReleaseData.setText(_translate("HostsUtlMain", "N/A", None)) - self.labelLatest.setText(_translate("HostsUtlMain", "Latest", None)) - self.labelLatestData.setText(_translate("HostsUtlMain", "N/A", None)) - self.FunctionsBox.setTitle(_translate("HostsUtlMain", "Functions", None)) - self.ButtonBackup.setToolTip(_translate("HostsUtlMain", "Backup hosts", None)) - self.ButtonBackup.setWhatsThis(_translate("HostsUtlMain", "Backup the hosts file of current system.", None)) - self.ButtonUpdate.setToolTip(_translate("HostsUtlMain", "Download data file", None)) - self.ButtonUpdate.setWhatsThis(_translate("HostsUtlMain", "Download the latest data file.", None)) - self.ButtonRestore.setToolTip(_translate("HostsUtlMain", "Restore backup", None)) - self.ButtonRestore.setWhatsThis(_translate("HostsUtlMain", "Restore a previous backup of hosts file.", None)) - self.ButtonApply.setToolTip(_translate("HostsUtlMain", "Apply hosts", None)) - self.ButtonApply.setWhatsThis(_translate("HostsUtlMain", "Apply changes to the hosts file.", None)) - self.ButtonExit.setToolTip(_translate("HostsUtlMain", "Exit", None)) - self.ButtonExit.setWhatsThis(_translate("HostsUtlMain", "Close this tool.", None)) - self.ButtonCheck.setToolTip(_translate("HostsUtlMain", "Check update / Refresh", None)) - self.ButtonCheck.setWhatsThis(_translate("HostsUtlMain", "Check the latest version of hosts data file.", None)) - self.ButtonANSI.setToolTip(_translate("HostsUtlMain", "Save with ANSI", None)) - self.ButtonANSI.setWhatsThis(_translate("HostsUtlMain", "Export to hosts file encoding by ANSI.", None)) - self.ButtonUTF.setToolTip(_translate("HostsUtlMain", "Save with UTF-8", None)) - self.ButtonUTF.setWhatsThis(_translate("HostsUtlMain", "Export to hosts file encoding by UTF-8.", None)) - self.TitleLabel.setText(_translate("HostsUtlMain", "Hosts Setup Utility", None)) - self.Copyright.setText(_translate("HostsUtlMain", "Copyleft (C) 2011-2014 huhamhire-hosts", None)) - self.label.setText(_translate("HostsUtlMain", "Powered by PyQT", None)) + def retranslateUi(self, Util): + Util.setWindowTitle(_translate("Util", "Hosts Setup Utility", None)) + self.ConfigBox.setTitle(_translate("Util", "Config", None)) + self.labelIP.setText(_translate("Util", "Server", None)) + self.labelMirror.setText(_translate("Util", "IP Version", None)) + self.StatusBox.setTitle(_translate("Util", "Status", None)) + self.labelConn.setText(_translate("Util", "Connection", None)) + self.labelConnStat.setText(_translate("Util", "N/A", None)) + self.labelOS.setText(_translate("Util", "OS", None)) + self.labelOSStat.setText(_translate("Util", "N/A", None)) + self.InfoBox.setTitle(_translate("Util", "Hosts Info", None)) + self.labelVersion.setText(_translate("Util", "Version", None)) + self.labelVersionData.setText(_translate("Util", "N/A", None)) + self.labelRelease.setText(_translate("Util", "Release", None)) + self.labelReleaseData.setText(_translate("Util", "N/A", None)) + self.labelLatest.setText(_translate("Util", "Latest", None)) + self.labelLatestData.setText(_translate("Util", "N/A", None)) + self.FunctionsBox.setTitle(_translate("Util", "Functions", None)) + self.ButtonBackup.setToolTip(_translate("Util", "Backup hosts", None)) + self.ButtonBackup.setWhatsThis(_translate("Util", "Backup the hosts file of current system.", None)) + self.ButtonUpdate.setToolTip(_translate("Util", "Download data file", None)) + self.ButtonUpdate.setWhatsThis(_translate("Util", "Download the latest data file.", None)) + self.ButtonRestore.setToolTip(_translate("Util", "Restore backup", None)) + self.ButtonRestore.setWhatsThis(_translate("Util", "Restore a previous backup of hosts file.", None)) + self.ButtonApply.setToolTip(_translate("Util", "Apply hosts", None)) + self.ButtonApply.setWhatsThis(_translate("Util", "Apply changes to the hosts file.", None)) + self.ButtonExit.setToolTip(_translate("Util", "Exit", None)) + self.ButtonExit.setWhatsThis(_translate("Util", "Close this tool.", None)) + self.ButtonCheck.setToolTip(_translate("Util", "Check update / Refresh", None)) + self.ButtonCheck.setWhatsThis(_translate("Util", "Check the latest version of hosts data file.", None)) + self.ButtonANSI.setToolTip(_translate("Util", "Save with ANSI", None)) + self.ButtonANSI.setWhatsThis(_translate("Util", "Export to hosts file encoding by ANSI.", None)) + self.ButtonUTF.setToolTip(_translate("Util", "Save with UTF-8", None)) + self.ButtonUTF.setWhatsThis(_translate("Util", "Export to hosts file encoding by UTF-8.", None)) + self.TitleLabel.setText(_translate("Util", "Hosts Setup Utility", None)) + self.Copyright.setText(_translate("Util", "Copyleft (C) 2011-2014 huhamhire-hosts", None)) + self.label.setText(_translate("Util", "Powered by PyQT", None)) -import qthosts_rc +import util_rc import style_rc if __name__ == "__main__": import sys app = QtGui.QApplication(sys.argv) - HostsUtlMain = QtGui.QDialog() - ui = Ui_HostsUtlMain() - ui.setupUi(HostsUtlMain) - HostsUtlMain.show() + Util = QtGui.QDialog() + ui = Ui_Util() + ui.setupUi(Util) + Util.show() sys.exit(app.exec_()) diff --git a/guitest.py b/guitest.py new file mode 100644 index 0000000..497b749 --- /dev/null +++ b/guitest.py @@ -0,0 +1,8 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +import gui + +if __name__ == "__main__": + main = gui.HostsUtil() + main.start() \ No newline at end of file diff --git a/hostsutl.pro b/hostsutl.pro deleted file mode 100644 index 11f4793..0000000 --- a/hostsutl.pro +++ /dev/null @@ -1,10 +0,0 @@ -SOURCES = hostsutl.py \ - qthostsui.py -TRANSLATIONS = lang/de_DE.ts \ - lang/en_US.ts \ - lang/zh_CN.ts \ - lang/zh_TW.ts -INTERFACES = qthostsui.ui -RESOURCES = qthosts.qrc -CODECFORTR = UTF-8 -CODECFORSRC = UTF-8 diff --git a/hostsutl.py b/hostsutl.py deleted file mode 100644 index cfac165..0000000 --- a/hostsutl.py +++ /dev/null @@ -1,1562 +0,0 @@ -#!/usr/bin/env python -# -*- coding: utf-8 -*- -# -# hostsutl.py : Main parts of Hosts Setup Utility -# -# Copyleft (C) 2013 - huhamhire hosts team -# ===================================================================== -# Licensed under the GNU General Public License, version 3. You should -# have received a copy of the GNU General Public License along with -# this program. If not, see . -# -# This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING -# THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR -# PURPOSE. -# ===================================================================== - -__version__ = "1.9.7" -__revision__ = "$Id$" -__author__ = "huhamhire " - -__all__ = [ - "LANG_DIR", "MainDialog", "QSubChkConnection", "QSubFetchUpdate", - "QSubMakeHosts", "QSubChkUpdate",] - -import json -import os -import shutil -import socket -import sys -import time -import urllib -from zipfile import BadZipfile - -from PyQt4 import QtCore, QtGui - -from qthostsui import Ui_HostsUtlMain, _fromUtf8, _translate -from util.retrievedata import RetrieveData -from util import CommonUtil, LangUtil - - -# Path to store language files -LANG_DIR = "./lang/" - -class MainDialog(QtGui.QDialog): - """A class to manage the operations and UI of Hosts Setup Utility - - MainDialog class is a subclasse of PyQt4.QtGui.QDialog which is used to - make the main dialog of this hosts setup utility. - This class contains a set of tools used to manage the operations while - modifying the hosts file of current operating system. Including methods - to manage operations to update data file, download data file, configure - hosts, make hosts file, backup hosts file, and restore backup. - The MainDialog class also provides QT slots to deal with the QT singles - emitted by the widgets on the main dialog operated by users. Extend - methods dealing with the user interface is also given by this class. - - Attributes: - _cur_ver (str): A string indicating the current version of hosts data - file. - _ipv_id (int): An integer indicating current IP version setting. The - value could be 1 or 0. 1 represents IPv6 while 1 represents IPv4. - _is_root (int): An integer indicating whether the program is run with - admin/root privileges. The value could be 1 or 0. - _down_flag (int) An integer indicating the downloading status of - current session. 1 represents data file is being downloaded. - _funcs (list): A list containing two lists with the information of - function list for IPv4 and IPv6 environment. - _make_cfg (dict): A dictionary containing the selection control bytes - to make a hosts file. - _make_mode (str): A string indicating the operation mode for making - hosts file. - _make_path (str): A string indicating the path to store the hosts file - in export mode. - _sys_eol (str): A string indicating the End-Of-Line marker. - _update (dict): A dictionary containing the update information of the - current data file on server. - _trans (obj): A QtCore.QTranslator object indicating the current UI - language setting. - choice (list): A list containing two lists with the selection of - functions for IPv4 and IPv6 environment. - slices (list): A list containing two lists with integers indicating - the number of function items from different parts listed in the - function list. - initd (int): An integer indicating how many times has the main dialog - been initialized. This value would be referenced for translator - to set the language of the main dialog. - platform (str): A string indicating the platform of current operating - system. The value could be "Windows", "Linux", "Unix", "OS X", and - of course "Unkown". - plat_flag (bool): A boolean flag indicating whether the current os is - supported or not. - hostname (str): A string indicating the hostname of current operating - system. This attribute would be used for linux clients. - hostspath (str): A string indicating the absolute path of the hosts - file on current operating system. - Ui (str): A user interface object indicating the main dialog of this - program. - _mirr_id (int): An integer indicating current index number of mirrors. - mirrors (list): A dictionary containing tag, test url, and update url - of mirrors. - __list_trans (list): A list containing names of function list items - for translator to translate. - filename (str): A string indicating the filename of the data file - containing data to make a hosts file. - infofile (str): A string indicating the filename of the info file - containing metadata of the data file in JSON format. - """ - _cur_ver = "" - _ipv_id = 0 - _is_root = 0 - _down_flag = 0 - _funcs = [[], []] - _make_cfg = {} - _make_mode = "" - _make_path = "./hosts" - _sys_eol = "" - _update = {} - _trans = None - - choice = [[], []] - slices = [[], []] - - initd = 0 - - Ui = None - # OS related configuration - platform = '' - plat_flag = True - hostname = '' - hostspath = '' - # Mirror related configuration - _mirr_id = 0 - mirrors = [] - # Name of items from the function list to be localized - __list_trans = [ - _translate("HostsUtlMain", "google(cn)", None), - _translate("HostsUtlMain", "google(hk)", None), - _translate("HostsUtlMain", "google(us)", None), - _translate("HostsUtlMain", "google-apis(cn)", None), - _translate("HostsUtlMain", "google-apis(us)", None), - _translate("HostsUtlMain", "activation-helper", None), - _translate("HostsUtlMain", "facebook", None), - _translate("HostsUtlMain", "twitter", None), - _translate("HostsUtlMain", "youtube", None), - _translate("HostsUtlMain", "wikipedia", None), - _translate("HostsUtlMain", "institutions", None), - _translate("HostsUtlMain", "steam", None), - _translate("HostsUtlMain", "others", None), - _translate("HostsUtlMain", "adblock-hostsx", None), - _translate("HostsUtlMain", "adblock-mvps", None), - _translate("HostsUtlMain", "adblock-mwsl", None), - _translate("HostsUtlMain", "adblock-yoyo", None), - ] - # Data file related configuration - filename = "hostslist.data" - infofile = "hostsinfo.json" - - def __init__(self, Ui, trans): - """Initialize a new instance of this class - Private Method - - Set the UI object and current translator of the main dialog. - - Args: - Ui (obj): A user interface object indicating the main dialog of - this program. - trans (obj): A PyQt4.QtCore.QTranslator object indicating the - current UI language setting. - """ - super(MainDialog, self).__init__() - self.Ui = Ui - self._trans = trans - self.set_platform() - self.set_style() - self.set_stylesheet() - - def on_Mirror_changed(self, mirr_id): - """Change the current mirror setting - Public Method - - The slot response to the signal ({mirr_id}) from SelectMirror widget - while the value is changed. - - Args: - mirr_id (int): An integer indicating current index number of - mirrors. - """ - self._mirr_id = mirr_id - self.check_connection() - - def on_IPVersion_changed(self, ipv_id): - """Change the current IP version setting - Public Method - - The slot response to the signal ({ipv_id}) from SelectIP widget while - the value is changed. - - Args: - ipv_id (int): An integer indicating current IP version setting. - The value could be 1 or 0. 1 represents IPv6 while 1 - represents IPv4. - """ - 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 on_Selection_changed(self, item): - """Change the function selection setting - Public Method - - The slot response to the signal ({item}) from Functionlist widget - while the selection of the items is changed. This method would change - the current selection of functions. - - Args: - item (int): An integer indicating the row number of the item - listed in Functionlist which is changed by user. - """ - ip_flag = self._ipv_id - func_id = item.listWidget().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 - item = self.Ui.Functionlist.item(c_id) - self.refresh_func_list() - - def on_Lang_changed(self, lang): - """Change the UI language setting - Public Method - - The slot response to the signal ({lang}) from SelectLang widget while - the value is changed. This method would change the language of the UI. - - Args: - lang (str): A string indicating the language which is selected by - user. - This string uses the for of IETF language tag. For example: - en_US, en_GB, etc. - """ - new_lang = LangUtil.get_locale_by_language(unicode(lang)) - trans = QtCore.QTranslator() - global LANG_DIR - trans.load(LANG_DIR + new_lang) - QtGui.QApplication.removeTranslator(self._trans) - QtGui.QApplication.installTranslator(trans) - self._trans = trans - self.Ui.retranslateUi(self) - self.init_main() - self.check_connection() - - def on_MakeHosts_clicked(self): - """Start making hosts file - Public Method - - The slot response to the signal from ButtonApply widget while the - button is clicked. This method would call operations to make a hosts - file. - No operations would be called if current session does not have the - privileges to change the hosts file. - """ - if not self._is_root: - self.warning_permission() - return - if self.question_apply(): - self._make_path = "./hosts" - self.make_hosts("system") - else: - return - - def on_MakeANSI_clicked(self): - """Export hosts ANSI - Public Method - - The slot response to the signal from ButtonANSI widget while the - button is clicked. This method would call operations to export a hosts - file encoding in ANSI. - """ - self._make_path = self.export_hosts() - if unicode(self._make_path) != u'': - self.make_hosts("ansi") - - def on_MakeUTF8_clicked(self): - """Export hosts in UTF-8 - Public Method - - The slot response to the signal from ButtonUTF widget while the - button is clicked. This method would call operations to export a hosts - file encoding in UTF-8. - """ - self._make_path = self.export_hosts() - if unicode(self._make_path) != u'': - self.make_hosts("utf-8") - - def on_Backup_clicked(self): - """Backup system hosts file - Public Method - - The slot response to the signal from ButtonBackup widget while the - button is clicked. This method would call operations to backup the - hosts file of current operating system. - """ - 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("HostsUtlMain", "Backup hosts", None), - QtCore.QString(filename), - _translate("HostsUtlMain", "Backup File(*.bak)", None)) - if unicode(filepath) != u'': - shutil.copy2(self.hostspath, unicode(filepath)) - self.info_complete() - - def on_Restore_clicked(self): - """Restore hosts file - Public Method - - The slot response to the signal from ButtonRestore widget while the - button is clicked. This method would call operations to restore a - previously backed up hosts file. - No operations would be called if current session does not have the - privileges to change the hosts file. - """ - if not self._is_root: - self.warning_permission() - return - filename = '' - if self.platform == "OS X": - filename = "/Users/" + filename - filepath = QtGui.QFileDialog.getOpenFileName( - self, _translate("HostsUtlMain", "Restore hosts", None), - QtCore.QString(filename), - _translate("HostsUtlMain", "Backup File(*.bak)", None)) - if unicode(filepath) != u'': - shutil.copy2(unicode(filepath), self.hostspath) - self.info_complete() - - def on_CheckUpdate_clicked(self): - """Check data file update - Public Method - - The slot response to the signal from ButtonCheck widget while the - button is clicked. This method would call operations to fetch update - information of the latest data file. - """ - if self.choice != [[], []]: - self.refresh_func_list() - self.Ui.ButtonApply.setEnabled(True) - self.Ui.ButtonANSI.setEnabled(True) - self.Ui.ButtonUTF.setEnabled(True) - if self._update == {} or self._update["version"] == \ - unicode(_translate("HostsUtlMain", "[Error]", None)): - self.check_update() - - def on_FetchUpdate_clicked(self): - """Fetch data file update - Public Method - - The slot response to the signal from ButtonUpdate widget while the - button is clicked. This method would call operations to fetch the - latest data file. - If no update information has been got from the server, the method to - check the update would be called. - If the current data is up-to-date, no data file would be retrieved. - """ - self._down_flag = 1 - self.Ui.Functionlist.setEnabled(False) - self.Ui.ButtonApply.setEnabled(False) - self.Ui.ButtonANSI.setEnabled(False) - self.Ui.ButtonUTF.setEnabled(False) - if self._update == {} or self._update["version"] == \ - unicode(_translate("HostsUtlMain", "[Error]", None)): - self.check_update() - elif self.new_version(): - self.fetch_update() - else: - self.info_uptodate() - self.finish_fetch() - - def on_LinkActivated(self, url): - """Open external link in browser - Public Method - - The slot response to the signal from Label widget while the text with - a hyperlink is clicked by user. - """ - QtGui.QDesktopServices.openUrl(QtCore.QUrl(url)) - - def init_main(self): - """Initialize the main dialog - Public Method - - Set up the elements on the main dialog. Check the environment of - current operating system and current session. - """ - self.Ui.SelectMirror.clear() - # Set mirrors - self.mirrors = CommonUtil.set_network("network.conf") - for i, mirror in enumerate(self.mirrors): - self.Ui.SelectMirror.addItem(_fromUtf8("")) - self.Ui.SelectMirror.setItemText( - i, _translate("HostsUtlMain", mirror["tag"], None)) - self.set_platform_label() - # 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_root() - self.initd += 1 - - def reject(self): - """Response to the reject signal - Public Method - - The slot response to the reject signal from an instance of the main - dialog. Close this program while the reject signal is emitted. - """ - self.close() - return QtGui.QDialog.reject(self) - - def close(self): - """Response to the close signal - Public Method - - The slot response to the close signal from an instance of the main - dialog. Close this program while the reject signal is emitted. - """ - try: - RetrieveData.clear() - except: - pass - super(MainDialog, self).close() - - def check_root(self): - """Check root privileges - Public Method - - Check if current session is ran with root privileges. - """ - is_root = CommonUtil.check_privileges()[1] - self._is_root = is_root - if not is_root: - self.warning_permission() - - def check_connection(self): - """Operations to check connection - Public Method - - Call operations to check the connection to current server. - """ - thread = QSubChkConnection(self) - thread.trigger.connect(self.set_conn_status) - thread.start() - - def check_update(self): - """Operations to check data file update - Public Method - - Call operations to retrieve the metadata of the latest data file from - a server. - """ - self.Ui.SelectMirror.setEnabled(False) - self.Ui.ButtonCheck.setEnabled(False) - self.Ui.ButtonUpdate.setEnabled(False) - self.set_label_text(self.Ui.labelLatestData, unicode( - _translate("HostsUtlMain", "Checking...", None))) - thread = QSubChkUpdate(self) - thread.trigger.connect(self.finish_update) - thread.start() - - def fetch_update(self): - """Operations to fetch new data file - Public Method - - Call operations to retrieve a new hosts data file from a server. - """ - self.Ui.SelectMirror.setEnabled(False) - self.Ui.ButtonCheck.setEnabled(False) - self.Ui.ButtonUpdate.setEnabled(False) - self.Ui.ButtonApply.setEnabled(False) - self.Ui.ButtonANSI.setEnabled(False) - self.Ui.ButtonUTF.setEnabled(False) - self.Ui.ButtonExit.setEnabled(False) - thread = QSubFetchUpdate(self) - thread.prog_trigger.connect(self.set_downprogbar) - thread.finish_trigger.connect(self.finish_fetch) - thread.start() - - def fetch_update_aftercheck(self): - """Check to fetch data file after check for update - Public Method - - 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("HostsUtlMain", "[Error]", None)): - self.finish_fetch(error=1) - elif self.new_version(): - self.fetch_update() - else: - self.info_uptodate() - self.finish_fetch() - - def export_hosts(self): - """Draw export hosts dialog - Public Method - - Show the export dialog and get the path to save the exported hosts - file. - - Returns: - A string indicating the path to export a hosts file - """ - filename = "hosts" - if self.platform == "OS X": - filename = "/Users/" + filename - filepath = QtGui.QFileDialog.getSaveFileName( - self, _translate("HostsUtlMain", "Export hosts", None), - QtCore.QString(filename), - _translate("HostsUtlMain", "hosts File", None)) - return filepath - - def make_hosts(self, mode="system"): - """Operations to make hosts file - Public Method - - Call operations to make a new hosts file for current system. - - Args: - mode (str): A string indicating the operation mode for making - hosts file. - """ - self.Ui.Functionlist.setEnabled(False) - self.Ui.SelectIP.setEnabled(False) - self.Ui.ButtonCheck.setEnabled(False) - self.Ui.ButtonUpdate.setEnabled(False) - self.Ui.ButtonApply.setEnabled(False) - self.Ui.ButtonANSI.setEnabled(False) - self.Ui.ButtonUTF.setEnabled(False) - self.Ui.ButtonExit.setEnabled(False) - self.set_makemsg(unicode(_translate( - "HostsUtlMain", "Building hosts file...", None)), 1) - # Avoid conflict while making hosts file - RetrieveData.disconnect_db() - self._make_mode = mode - self.set_cfgbytes(mode) - thread = QSubMakeHosts(self) - thread.info_trigger.connect(self.set_makeprog) - thread.fina_trigger.connect(self.set_makefina) - thread.move_trigger.connect(self.move_hosts) - thread.start() - - def move_hosts(self): - """Move hosts file to the system path after making - Public Method - - The slot response to the move_trigger signal from an instance of - QSubMakeHosts class while making operations are finished. - """ - filepath = "hosts" - msg = unicode(_translate("HostsUtlMain", - "Copying new hosts file to\n" - " %s", None)) % self.hostspath - self.set_makemsg(msg) - try: - shutil.copy2(filepath, self.hostspath) - except IOError: - self.warning_permission() - os.remove(filepath) - return - except OSError: - pass - msg = unicode(_translate("HostsUtlMain", - "Remove temporary file", None)) - self.set_makemsg(msg) - os.remove(filepath) - msg = unicode(_translate("HostsUtlMain", - "Operation completed", None)) - self.set_makemsg(msg) - self.info_complete() - - def set_languages(self): - """Set items in SelectLang widget - Public Method - - Set optional language selection items in the SelectLang widget. - """ - self.Ui.SelectLang.clear() - langs = LangUtil.language - langs_not_found = [] - for locale in langs: - if not os.path.isfile(LANG_DIR + locale + ".qm"): - langs_not_found.append(locale) - for locale in langs_not_found: - langs.pop(locale) - LangUtil.language = langs - if len(langs) <= 1: - self.Ui.SelectLang.setEnabled(False) - # Block the signal while set the language selecions. - self.Ui.SelectLang.blockSignals(True) - sys_locale = LangUtil.get_locale() - if sys_locale not in langs.keys(): - sys_locale = "en_US" - for i, locale in enumerate(sorted(langs.keys())): - if sys_locale == locale: - select = i - lang = langs[locale] - self.Ui.SelectLang.addItem(_fromUtf8("")) - self.Ui.SelectLang.setItemText(i, lang) - self.Ui.SelectLang.blockSignals(False) - self.Ui.SelectLang.setCurrentIndex(select) - - def set_platform(self): - """Set OS info - Public Method - - Set the information of current operating system platform. - """ - system, hostname, path, encode, flag = CommonUtil.check_platform() - self.platform = system - self.hostname = hostname - self.hostspath = path - self.plat_flag = flag - if encode == "win_ansi": - self._sys_eol = "\r\n" - else: - self._sys_eol = "\n" - - def set_platform_label(self): - """Set label of OS info - Public Method - - Set the information of the label indicating current operating system - platform. - """ - color = "GREEN" if self.plat_flag else "RED" - self.set_label_color(self.Ui.labelOSStat, color) - self.set_label_text(self.Ui.labelOSStat, "[%s]" % self.platform) - - - def set_style(self): - """Set window style - Public Method - - Set the main dialog with a window style depending on the os platform. - """ - self.setWindowFlags(QtCore.Qt.FramelessWindowHint) - system = self.platform - if system == "Windows": - pass - elif system == "Linux": - # Set window style for sudo users. - QtGui.QApplication.setStyle( - QtGui.QStyleFactory.create("Cleanlooks")) - elif system == "OS X": - pass - - def set_stylesheet(self): - """Set Stylesheet for main frame - Public Method - - Define the style sheet of main dialog. - """ - app = QtGui.QApplication.instance() - with open("./theme/darkdefault.qss", "r") as qss: - app.setStyleSheet(qss.read()) - - def mouseMoveEvent(self, e): - """Set mouse drag event - Public Method - - Allow drag operations to set the new position for current dialog. - - Args: - e (QMouseEvent): A QMouseEvent object indicating current mouse - event. - """ - if e.buttons() & QtCore.Qt.LeftButton: - try: - self.move(e.globalPos() - self.dragPos) - except AttributeError: - pass - e.accept() - - def mousePressEvent(self, e): - """Set mouse press event - Public Method - - Allow drag operations to set the new position for current dialog. - - Args: - e (QMouseEvent): A QMouseEvent object indicating current mouse - event. - """ - if e.button() == QtCore.Qt.LeftButton: - self.dragPos = e.globalPos() - self.frameGeometry().topLeft() - e.accept() - - - def set_label_color(self, label, color): - """Set the color of a label - Public Method - - Set a specified label ({label}) to show with specified color - ({color}). - - Args: - label (obj): An instance of PyQt4.QtGui.QLabel class on the main - dialog. - color (str): A string indicating the color to be shown on the - lable. - """ - if color == "GREEN": - rgb = "#37b158" - elif color == "RED": - rgb = "#e27867" - elif color == "BLACK": - rgb = "#b1b1b1" - label.setStyleSheet("QLabel {color: %s}" % rgb) - - def set_label_text(self, label, text): - """Set the text of a label - Public Method - - Set a specified label ({label}) to show specified text ({text}). - - Args: - label (obj): An instance of PyQt4.QtGui.QLabel class on the main - dialog. - text (str): A string indicating the message to be shown on the - lable. - """ - label.setText(_translate("HostsUtlMain", text, None)) - - def set_conn_status(self, status): - """Set connection status info - Public Method - - 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("HostsUtlMain", "Checking...", None))) - elif status in [0, 1]: - if status: - color, stat = "GREEN", unicode(_translate( - "HostsUtlMain", "[OK]", None)) - else: - color, stat = "RED", unicode(_translate( - "HostsUtlMain", "[Failed]", None)) - self.set_label_color(self.Ui.labelConnStat, color) - self.set_label_text(self.Ui.labelConnStat, stat) - - def set_func_list(self, new=0): - """Set the function list - Public Method - - Draw the function list and decide whether to load the default - selection configuration or not. - - Arg: - new (int): A flag integer indicating whether to load the default - selection configuration or not. 0 -> user user config, - 1 -> use default config. Default by 0. - """ - ip_flag = self._ipv_id - self.Ui.Functionlist.clear() - self.Ui.FunctionsBox.setTitle(_translate( - "HostsUtlMain", "Functions", None)) - if new: - for ip in range(2): - choice, defaults, slices = RetrieveData.get_choice(ip) - self.choice[ip] = choice - self.slices[ip] = slices - funcs = [] - for func in choice: - item = QtGui.QListWidgetItem() - if func[1] in defaults[func[0]]: - funcs.append(1) - else: - funcs.append(0) - self._funcs[ip] = funcs - - def refresh_func_list(self): - """Refresh the function list - Public Method - - 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("HostsUtlMain", func[3], None)) - self.Ui.Functionlist.addItem(item) - - def set_message(self, title, msg): - """Set a message box - Public Method - - Show a message box with a specified message ({msg}) with a specified - title ({title}). - - Args: - title (str): A string indicating the title of the message box. - msg (str): A string indicating the message to be shown in the - message box. - """ - self.Ui.FunctionsBox.setTitle(_translate( - "HostsUtlMain", title, None)) - self.Ui.Functionlist.clear() - item = QtGui.QListWidgetItem() - item.setText(msg) - item.setFlags(QtCore.Qt.ItemIsEnabled) - self.Ui.Functionlist.addItem(item) - - def set_info(self): - """Set data file info - Public Method - - 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, build) - - def set_downprogbar(self, prog, msg): - """Set progress bar - Public Method - - Set the progress bar to a specified progress position ({prog}) with a - specified message ({msg}). - - Args: - prog (int): An integer indicating the progress to be set on the - progress bar. - msg (str): A string indicating the message to be shown on the - progress bar. - """ - self.Ui.Prog.setProperty("value", prog) - self.set_conn_status(1) - self.Ui.Prog.setFormat(msg) - - def set_listitemunchecked(self, item_id): - """Set list item to be unchecked - Public Method - - Set a specified item ({item_id}) to become unchecked in the function - list. - - Arg: - item_id (int): An integer indicating the id number of a specified - item in the function list. - """ - self._funcs[self._ipv_id][item_id] = 0 - item = self.Ui.Functionlist.item(item_id) - item.setCheckState(QtCore.Qt.Unchecked) - - def set_cfgbytes(self, mode): - """Set configuration byte words - Public Method - - Calculate the module configuration byte words by the selection from - function list on the main dialog. - - Args: - mode (str): A string indicating the operation mode for making - hosts file. - """ - ip_flag = self._ipv_id - selection = {} - if mode == "system": - localhost_word = { - "Windows": 0x0001, "Linux": 0x0002, - "Unix": 0x0002, "OS X": 0x0004}[self.platform] - else: - localhost_word = 0x0008 - selection[0x02] = localhost_word - ch_parts = (0x08, 0x20 if ip_flag else 0x10, 0x40) - slices = self.slices[ip_flag] - for i, part in enumerate(ch_parts): - part_cfg = self._funcs[ip_flag][slices[i]:slices[i + 1]] - part_word = 0 - for i, cfg in enumerate(part_cfg): - part_word += cfg << i - selection[part] = part_word - self._make_cfg = selection - - def refresh_info(self, refresh=0): - """Refresh data file information - Public Method - - 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. - - Arg: - refresh (int): A flag integer indicating whether the information - needs to be reloaded or not. 1: reload, 0: do not reload. - Default by 0. - """ - if refresh and RetrieveData._conn != 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 set_makeprog(self, mod_name, mod_num): - """Operations to show progress while making hosts file - Public Method - - The slot response to the info_trigger signal ({mod_name}, {mod_num}) - from an instance of QSubMakeHosts class while making operations are - proceeded. - - Args: - mod_name (str): A string indicating the name of a specified hosts - module in current progress. - mod_num (int): An integer indicating the number of current module - in the operation sequence. - """ - total_mods_num = self._funcs[self._ipv_id].count(1) + 1 - prog = 100 * mod_num / total_mods_num - self.Ui.Prog.setProperty("value", prog) - format = unicode(_translate( - "HostsUtlMain", "Applying module: %s(%s/%s)", None)) % ( - mod_name, mod_num, total_mods_num) - self.Ui.Prog.setFormat(format) - self.set_makemsg(format) - - def set_makemsg(self, msg, start=0): - """Operations to show making progress in function list - Public Method - - List message for the current operating progress while making the new - hosts file. - - Args: - msg (str): A string indicating the message to show in the function - list. - start (int): A flag integer indicating whether the message is the - first of the making progress or not. 1: first, 0: not the - first. Default by 0. - """ - if start: - self.Ui.FunctionsBox.setTitle(_translate( - "HostsUtlMain", "Progress", None)) - self.Ui.Functionlist.clear() - item = QtGui.QListWidgetItem() - item.setText("- " + msg) - item.setFlags(QtCore.Qt.ItemIsEnabled) - self.Ui.Functionlist.addItem(item) - - def set_makefina(self, time, count): - """Operations after making new hosts file - Public Method - - The slot response to the fina_trigger signal ({time}, {count}) from - an instance of QSubMakeHosts class while making operations are - finished. - - Args: - time (str): A string indicating the total time uesd to make the - new hosts file. - count (int): An integer indicating the total number of hosts - entries inserted into the new hosts file. - """ - self.Ui.Functionlist.setEnabled(True) - self.Ui.SelectIP.setEnabled(True) - self.Ui.ButtonCheck.setEnabled(True) - self.Ui.ButtonUpdate.setEnabled(True) - self.Ui.ButtonApply.setEnabled(False) - self.Ui.ButtonANSI.setEnabled(False) - self.Ui.ButtonUTF.setEnabled(False) - self.Ui.ButtonExit.setEnabled(True) - RetrieveData.connect_db() - msg = unicode(_translate("HostsUtlMain", - "Notice: %i hosts entries has " - "\n been applied in %ssecs.", None)) % (count, time) - self.set_makemsg(msg) - self.set_downprogbar(100, - unicode(_translate("HostsUtlMain", - "Operation Completed Successfully!", None))) - - def finish_update(self, update): - """Operations after checking update - Public Method - - The slot response to the trigger signal ({update}) from an instance - of QSubChkUpdate class while checking operations are finished. - - Arg: - update (dict): A dictionary containing metadata of the latest - hosts file from the server. - """ - self._update = update - self.set_label_text(self.Ui.labelLatestData, update["version"]) - if self._update["version"] == \ - unicode(_translate("HostsUtlMain", "[Error]", None)): - self.set_conn_status(0) - else: - self.set_conn_status(1) - if self._down_flag: - self.fetch_update_aftercheck() - else: - self.Ui.SelectMirror.setEnabled(True) - self.Ui.ButtonCheck.setEnabled(True) - self.Ui.ButtonUpdate.setEnabled(True) - - def finish_fetch(self, refresh=1, error=0): - """Operations after downloading data file - Public Method - - The slot response to the finish_trigger signal ({refresh}, {error}) - from an instance of QSubFetchUpdate class while downloading is - finished. - - Args: - refresh (int): A flag integer indicating whether a refresh for - function list is needed or not. 1: refresh, 0: no refresh. - Default by 1. - error (int): A flag integer indicating errors have occurred while - downloading new data file. 1: error, 0:success. Default by 0. - """ - self._down_flag = 0 - if error: - # Error occurred while downloading - self.set_downprogbar(0, - unicode(_translate("HostsUtlMain", - "Error", None))) - try: - os.remove(self.filename) - except: - pass - self.warning_download() - msg_title = "Warning" - msg = unicode(_translate("HostsUtlMain", - "Incorrect Data file!\n" - "Please use the \"Download\" key to \n" - "fetch a new data file.", None)) - self.set_message(msg_title, msg) - self.Ui.ButtonApply.setEnabled(False) - self.Ui.ButtonANSI.setEnabled(False) - self.Ui.ButtonUTF.setEnabled(False) - self.set_conn_status(0) - else: - # Data file retrieved successfully - self.set_downprogbar(100, - unicode(_translate("HostsUtlMain", - "Download Complete", None))) - self.refresh_info(refresh) - self.Ui.ButtonApply.setEnabled(True) - self.Ui.ButtonANSI.setEnabled(True) - self.Ui.ButtonUTF.setEnabled(True) - self.Ui.Functionlist.setEnabled(True) - self.Ui.SelectMirror.setEnabled(True) - self.Ui.ButtonCheck.setEnabled(True) - self.Ui.ButtonUpdate.setEnabled(True) - self.Ui.ButtonExit.setEnabled(True) - - def new_version(self): - """Compare version of data file - Public Method - - Compare version of local data file to the version from the server. - - Returns: - A flag integer indicating whether the local data file is - up-to-date or not. - 1 -> The version of data file on server is newer. - 0 -> The local data file is up-to-date. - """ - local_ver = self._cur_ver - server_ver = self._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 warning_permission(self): - """Show permission error warning - Public Method - - Draw permission error warning message box. - """ - QtGui.QMessageBox.warning( - self, _translate("HostsUtlMain", "Warning", None), - _translate("HostsUtlMain", - "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 warning_download(self): - """Show download error warning - Public Method - - Draw download error warning message box. - """ - QtGui.QMessageBox.warning( - self, _translate("HostsUtlMain", "Warning", None), - _translate("HostsUtlMain", - "Error retrieving data from the server.\n" - "Please try another server.", None)) - - def warning_incorrect_datafile(self): - """Show incorrect data file warning - Public Method - - Draw incorrect data file warning message box. - """ - msg_title = "Warning" - msg = unicode(_translate("HostsUtlMain", - "Incorrect Data file!\n" - "Please use the \"Download\" key to \n" - "fetch a new data file.", None)) - self.set_message(msg_title, msg) - self.Ui.ButtonApply.setEnabled(False) - self.Ui.ButtonANSI.setEnabled(False) - self.Ui.ButtonUTF.setEnabled(False) - - def warning_no_datafile(self): - """Show no data file warning - Public Method - - Draw no data file warning message box. - """ - msg_title = "Warning" - msg = unicode(_translate("HostsUtlMain", - "Data file not found!\n" - "Please use the \"Download\" key to \n" - "fetch a new data file.", None)) - self.set_message(msg_title, msg) - self.Ui.ButtonApply.setEnabled(False) - self.Ui.ButtonANSI.setEnabled(False) - self.Ui.ButtonUTF.setEnabled(False) - - def question_apply(self): - """Show confirm make question - Public Method - - Draw confirm make question message box. - - Returns: - A bool flag indicating whether user has accepted to continue the - operations or not. True: Continue, False: Cancel. - """ - msg_title = unicode(_translate("HostsUtlMain", "Notice", None)) - msg = unicode(_translate("HostsUtlMain", - "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_uptodate(self): - """Show up-to-date message - Public Method - - Draw data file is up-to-date message box. - """ - QtGui.QMessageBox.information( - self, _translate("HostsUtlMain", "Notice", None), - _translate("HostsUtlMain", "Data file is up-to-date.", None)) - - def info_complete(self): - """Show complete message - Public Method - - Draw operation complete message box. - """ - QtGui.QMessageBox.information( - self, _translate("HostsUtlMain", "Complete", None), - _translate("HostsUtlMain", "Operation completed", None)) - - -class QSubChkConnection(QtCore.QThread): - """A class to check connection with server - - QSubChkConnection is a subclasse of PyQt4.QtCore.QThread. This class - contains methods to check the network connection with a specified mirror. - - The instance of this class should be created in an individual thread. And - the object instance of MainDialog class should be set as parent here. - - Attribute: - trigger (obj): A PyQt4.QtCore.pyqtSignal object to emit suatus signal - to the main dialog. The meaning of the signal arguments is listed - here: - -1 -> checking..., 0 -> Failed, 1 -> OK. - """ - trigger = QtCore.pyqtSignal(int) - - def __init__(self, parent=None): - """Initialize a new instance of this class - Private Method - - Get mirror settings from the main dialog to check the connection. - - Args: - parent (obj): An instance of MainDialog object to get settings - from. - """ - super(QSubChkConnection, self).__init__(parent) - self.link = parent.mirrors[parent._mirr_id]["test_url"] - - def run(self): - """Check connection - Public Method - - Operations to check the network connection with a specified mirror. - """ - self.trigger.emit(-1) - status = CommonUtil.check_connection(self.link) - self.trigger.emit(status) - -class QSubFetchUpdate(QtCore.QThread): - """A class to fetch the latest data file - - QSubFetchUpdate is a subclasse of PyQt4.QtCore.QThread. This class - contains methods to retrieve the latest hosts data file. - - The instance of this class should be created in an individual thread. And - the object instance of MainDialog class should be set as parent here. - - Attributes: - prog_trigger (obj): A PyQt4.QtCore.pyqtSignal object to emit progress - signal to the main dialog indicating the current download - progress. The meaning of the signal arguments is listed here: - (int, str) -> (progress, message) - progress (int): An integer indicating the current download - progress. - message (str): A string indicating the message to be shown to - users on the progress bar. - finish_trigger (obj): A PyQt4.QtCore.pyqtSignal object to emit finish - signal to the main dialog. The meaning of the signal arguments is - listed here: - (int, int) -> (refresh_flag, error_flag) - refresh_flag (int): An integer indicating whether to refresh - the funcion list or not. 1: refresh, 0: do not refresh. - error_flag (int): An integer indicating whether the - downloading is successfully finished or not. - 1: error, 0: success. - """ - prog_trigger = QtCore.pyqtSignal(int, str) - finish_trigger = QtCore.pyqtSignal(int, int) - - def __init__(self, parent=None): - """Initialize a new instance of this class - Private Method - - Get download settings from the main dialog to retrieve new hosts data - file. - - Args: - parent (obj): An instance of MainDialog object to get settings - from. - """ - super(QSubFetchUpdate, self).__init__(parent) - self.url = parent.mirrors[parent._mirr_id]["update"] + parent.filename - self.path = "./" + parent.filename - self.tmp_path = self.path + ".download" - self.filesize = parent._update["size"] - - def run(self): - """Fetch data file - Public Method - - Operations to retrieve the new hosts data file. - """ - self.prog_trigger.emit(0, unicode(_translate( - "HostsUtlMain", "Connecting...", None))) - self.fetch_file() - - def fetch_file(self): - """Fetch the data file - Public Method - - Retrieve the latest data file to a specified path ({path}) by url - ({url}). - - Args: - url (str): A string indicating the url to fetch the latest data - file. - path (str): A string indicating the path to save the data file on - current machine. - """ - socket.setdefaulttimeout(10) - try: - urllib.urlretrieve(self.url, self.tmp_path, self.set_progress) - self.replace_old() - self.finish_trigger.emit(1, 0) - except: - self.finish_trigger.emit(1, 1) - - def set_progress(self, done, blocksize, total): - """Set progress bar in the main dialog - Public Method - - Send message to the main dialog to set the progress bar Prog. - - Args: - done (int): An integer indicating the number of data blocks have - been downloaded from the server. - blocksize (int): An integer indicating the size of a data block. - """ - done = done * blocksize - if total <= 0: - total = self.filesize - prog = 100 * done / total - done = CommonUtil.convert_size(done) - total = CommonUtil.convert_size(total) - text = unicode(_translate( - "HostsUtlMain", "Downloading: %s / %s", None)) % (done, total) - self.prog_trigger.emit(prog, text) - - def replace_old(self): - """Replace the old data file - Public Method - - Overwrite the old hosts data file with the new one. - """ - if os.path.isfile(self.path): - os.remove(self.path) - os.rename(self.tmp_path, self.path) - - -class QSubMakeHosts(QtCore.QThread): - """A class to make a new hosts file - - QSubMakeHosts is a subclasse of PyQt4.QtCore.QThread. This class contains - methods to make a new hosts file for client. - - The instance of this class should be created in an individual thread. And - the object instance of MainDialog class should be set as parent here. - - Attributes: - info_trigger (obj): A PyQt4.QtCore.pyqtSignal object to emit message - signal to the main dialog indicating the current operation.The - meaning of the signal arguments is listed here: - (str, int) - (mod_name, mod_num) - mod_name (str): A string indicating the name of a specified hosts - module in current progress. - mod_num (int): An integer indicating the number of current module - in the operation sequence. - fina_trigger (obj): A PyQt4.QtCore.pyqtSignal object to emit message - signal to the main dialog indicating finish information. The - meaning of the signal arguments is listed here: - (str, int) - (time, count) - time (str): A string indicating the total time uesd to make the - new hosts file. - count (int): An integer indicating the total number of hosts - entries inserted into the new hosts file. - move_trigger (obj): A PyQt4.QtCore.pyqtSignal object to emit signal - to the main dialog while new hosts is being moved to specified - path on current system. This signal does not - count (int): An integer indicating id of the module being processed - currently. - mod_num (int): An integer indicating total number of modules being - operated while making hosts file. - make_cfg (dict): A dictionary containing the selection control bytes - to make a hosts file. - make_mode (str): A string indicating the operation mode for making - hosts file. - eol (str): A string indicating the End-Of-Line marker. - """ - info_trigger = QtCore.pyqtSignal(str, int) - fina_trigger = QtCore.pyqtSignal(str, int) - move_trigger = QtCore.pyqtSignal() - - count = 0 - mod_num = 0 - make_cfg = {} - make_mode = "" - eol = "" - - def __init__(self, parent=None): - """Initialize a new instance of this class - Private Method - - Fetch settings from the main dialog to make a new hosts file. - - Args: - parent (obj): An instance of MainDialog object to get settings - from. - """ - super(QSubMakeHosts, self).__init__(parent) - self.count = 0 - self.make_cfg = parent._make_cfg - self.make_mode = parent._make_mode - make_path = parent._make_path - self.hostname = parent.hostname - if parent._make_mode == "system": - self.eol = parent._sys_eol - self.hosts_file = open("hosts", "wb") - elif parent._make_mode == "ansi": - self.eol = "\r\n" - self.hosts_file = open(unicode(make_path), "wb") - elif parent._make_mode == "utf-8": - self.eol = "\n" - self.hosts_file = open(unicode(make_path), "wb") - - def run(self): - """Make new hosts file - Public Method - - Operations to retrieve data from the data file and make the new hosts - file for current system. - """ - RetrieveData.connect_db() - start_time = time.time() - self.maketime = start_time - self.write_head() - self.write_info() - self.get_hosts(self.make_cfg) - self.hosts_file.close() - end_time = time.time() - total_time = "%.4f" % (end_time - start_time) - self.fina_trigger.emit(total_time, self.count) - if self.make_mode == "system": - self.move_trigger.emit() - RetrieveData.disconnect_db() - - def get_hosts(self, make_cfg): - """Make hosts by user config - Public Method - - Make the new hosts file by the configuration ({make_cfg}) from - function list on the main dialog. - - Args: - make_cfg (dict): A dictionary containing module settings in byte - word format. - """ - 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 - if part_id == 0x02: - self.write_localhost_mod(part_id, mod_id) - else: - self.write_common_mod(part_id, mod_id) - - def write_head(self): - """Write head section - Public Method - - Write the head part of new hosts file. - """ - for head_str in RetrieveData.get_head(): - self.hosts_file.write("%s%s" % (head_str[0], self.eol)) - - def write_info(self): - """Write info section - Public Method - - Write the information part of new hosts file. - """ - info = RetrieveData.get_info() - info_lines = ["#"] - info_lines.append("# %s: %s" % ("Version", info["Version"])) - info_lines.append("# %s: %s" % ("Buildtime", info["Buildtime"])) - info_lines.append("# %s: %s" % ("Applytime", int(self.maketime))) - info_lines.append("#") - for line in info_lines: - self.hosts_file.write("%s%s" % (line, self.eol)) - - def write_common_mod(self, part_id, mod_id): - """Write module section - Public Method - - Write hosts entries in a specified module ({mod_id}) from a specified - part ({part_id}) of the data file to the new hosts file. - - Args: - part_id (int): An integer indicating the index number of a part - in the data file. - mod_id (int): An integer indicating the index number of a module - in the data file. - """ - hosts, mod_name = RetrieveData.get_host(part_id, mod_id) - self.info_trigger.emit(mod_name, self.mod_num) - self.hosts_file.write( - "%s# Section Start: %s%s" % (self.eol, mod_name, self.eol)) - for host in hosts: - self.hosts_file.write("%s %s%s" % (host[0], host[1], self.eol)) - self.count += 1 - self.hosts_file.write("# Section End: %s%s" % (mod_name, self.eol)) - - def write_localhost_mod(self, part_id, mod_id): - """Write localhost section - Public Method - - Write hosts entries in a localhost module ({mod_id}) from a specified - part ({part_id}) of the data file to the new hosts file. - - Args: - part_id (int): An integer indicating the index number of a part - in the data file. - mod_id (int): An integer indicating the index number of a module - in the data file. - """ - hosts, mod_name = RetrieveData.get_host(part_id, mod_id) - self.info_trigger.emit(mod_name, self.mod_num) - self.hosts_file.write( - "%s# Section Start: Localhost%s" % (self.eol, self.eol)) - for host in hosts: - if "#Replace" in host[1]: - host = (host[0], self.hostname) - self.hosts_file.write("%s %s%s" % (host[0], host[1], self.eol)) - self.count += 1 - self.hosts_file.write("# Section End: Localhost%s" % (self.eol)) - - -class QSubChkUpdate(QtCore.QThread): - """A class to check update info of the latest data file - - QSubChkConnection is a subclasse of PyQt4.QtCore.QThread. This class - contains methods to retrieve the metadata of the latest hosts data file. - - The instance of this class should be created in an individual thread. And - the object instance of MainDialog class should be set as parent here. - - Attribute: - trigger (obj): A PyQt4.QtCore.pyqtSignal object to emit suatus signal - to the main dialog. The meaning of the signal is listed here: - (dict) -> (update_info) - update_info (dict): A dictionary containing metadata of the - latest hosts data file. - """ - trigger = QtCore.pyqtSignal(dict) - - def __init__(self, parent=None): - """Initialize a new instance of this class - Private Method - - Get mirror settings from the main dialog to check the connection. - - Args: - parent (obj): An instance of MainDialog object to get settings - from. - """ - super(QSubChkUpdate, self).__init__(parent) - self.url = parent.mirrors[parent._mirr_id]["update"] + parent.infofile - - def run(self): - """Check update - Public Method - - 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("HostsUtlMain", - "[Error]", None))} - self.trigger.emit(info) - - -def qt_main(): - """Load main dialog - - Start the main dialog of Hosts Setup Utility. - """ - trans = QtCore.QTranslator() - trans.load("lang/en_US") - app = QtGui.QApplication(sys.argv) - app.installTranslator(trans) - ui = Ui_HostsUtlMain() - HostsUtlMain = MainDialog(ui, trans) - ui.setupUi(HostsUtlMain) - HostsUtlMain.set_languages() - if not HostsUtlMain.initd: - HostsUtlMain.init_main() - HostsUtlMain.show() - sys.exit(app.exec_()) - -if __name__ == "__main__": - qt_main() diff --git a/lang/en_US.qm b/lang/en_US.qm deleted file mode 100644 index 6ea3657..0000000 Binary files a/lang/en_US.qm and /dev/null differ diff --git a/lang/zh_CN.qm b/lang/zh_CN.qm deleted file mode 100644 index d842be4..0000000 Binary files a/lang/zh_CN.qm and /dev/null differ diff --git a/lang/zh_TW.qm b/lang/zh_TW.qm deleted file mode 100644 index ca362e0..0000000 Binary files a/lang/zh_TW.qm and /dev/null differ diff --git a/mac_res/.DS_Store b/mac_res/.DS_Store deleted file mode 100644 index 54998dc..0000000 Binary files a/mac_res/.DS_Store and /dev/null differ diff --git a/qthosts.qrc b/qthosts.qrc deleted file mode 100644 index 3900723..0000000 --- a/qthosts.qrc +++ /dev/null @@ -1,23 +0,0 @@ - - - img/icons/utl_icon@256x256.png - - - img/buttons/button_ansi.png - img/buttons/button_ansi_disabled.png - img/buttons/button_apply.png - img/buttons/button_apply_disabled.png - img/buttons/button_backup.png - img/buttons/button_backup_disabled.png - img/buttons/button_download.png - img/buttons/button_download_disabled.png - img/buttons/button_exit.png - img/buttons/button_exit_disabled.png - img/buttons/button_restore.png - img/buttons/button_restore_disabled.png - img/buttons/button_update.png - img/buttons/button_update_disabled.png - img/buttons/button_utf8.png - img/buttons/button_utf8_disabled.png - - diff --git a/img/buttons/button_ansi.png b/res/img/buttons/button_ansi.png similarity index 100% rename from img/buttons/button_ansi.png rename to res/img/buttons/button_ansi.png diff --git a/img/buttons/button_ansi_disabled.png b/res/img/buttons/button_ansi_disabled.png similarity index 100% rename from img/buttons/button_ansi_disabled.png rename to res/img/buttons/button_ansi_disabled.png diff --git a/img/buttons/button_apply.png b/res/img/buttons/button_apply.png similarity index 100% rename from img/buttons/button_apply.png rename to res/img/buttons/button_apply.png diff --git a/img/buttons/button_apply_disabled.png b/res/img/buttons/button_apply_disabled.png similarity index 100% rename from img/buttons/button_apply_disabled.png rename to res/img/buttons/button_apply_disabled.png diff --git a/img/buttons/button_backup.png b/res/img/buttons/button_backup.png similarity index 100% rename from img/buttons/button_backup.png rename to res/img/buttons/button_backup.png diff --git a/img/buttons/button_backup_disabled.png b/res/img/buttons/button_backup_disabled.png similarity index 100% rename from img/buttons/button_backup_disabled.png rename to res/img/buttons/button_backup_disabled.png diff --git a/img/buttons/button_download.png b/res/img/buttons/button_download.png similarity index 100% rename from img/buttons/button_download.png rename to res/img/buttons/button_download.png diff --git a/img/buttons/button_download_disabled.png b/res/img/buttons/button_download_disabled.png similarity index 100% rename from img/buttons/button_download_disabled.png rename to res/img/buttons/button_download_disabled.png diff --git a/img/buttons/button_exit.png b/res/img/buttons/button_exit.png similarity index 100% rename from img/buttons/button_exit.png rename to res/img/buttons/button_exit.png diff --git a/img/buttons/button_exit_disabled.png b/res/img/buttons/button_exit_disabled.png similarity index 100% rename from img/buttons/button_exit_disabled.png rename to res/img/buttons/button_exit_disabled.png diff --git a/img/buttons/button_restore.png b/res/img/buttons/button_restore.png similarity index 100% rename from img/buttons/button_restore.png rename to res/img/buttons/button_restore.png diff --git a/img/buttons/button_restore_disabled.png b/res/img/buttons/button_restore_disabled.png similarity index 100% rename from img/buttons/button_restore_disabled.png rename to res/img/buttons/button_restore_disabled.png diff --git a/img/buttons/button_update.png b/res/img/buttons/button_update.png similarity index 100% rename from img/buttons/button_update.png rename to res/img/buttons/button_update.png diff --git a/img/buttons/button_update_disabled.png b/res/img/buttons/button_update_disabled.png similarity index 100% rename from img/buttons/button_update_disabled.png rename to res/img/buttons/button_update_disabled.png diff --git a/img/buttons/button_utf8.png b/res/img/buttons/button_utf8.png similarity index 100% rename from img/buttons/button_utf8.png rename to res/img/buttons/button_utf8.png diff --git a/img/buttons/button_utf8_disabled.png b/res/img/buttons/button_utf8_disabled.png similarity index 100% rename from img/buttons/button_utf8_disabled.png rename to res/img/buttons/button_utf8_disabled.png diff --git a/img/icons/hosts_utl.icns b/res/img/icons/hosts_utl.icns similarity index 100% rename from img/icons/hosts_utl.icns rename to res/img/icons/hosts_utl.icns diff --git a/img/icons/hosts_utl.ico b/res/img/icons/hosts_utl.ico similarity index 100% rename from img/icons/hosts_utl.ico rename to res/img/icons/hosts_utl.ico diff --git a/img/icons/utl_icon@256x256.png b/res/img/icons/utl_icon@256x256.png similarity index 100% rename from img/icons/utl_icon@256x256.png rename to res/img/icons/utl_icon@256x256.png diff --git a/img/icons/utl_icon@512x512.png b/res/img/icons/utl_icon@512x512.png similarity index 100% rename from img/icons/utl_icon@512x512.png rename to res/img/icons/utl_icon@512x512.png diff --git a/img/style/checkbox.png b/res/img/style/checkbox.png similarity index 100% rename from img/style/checkbox.png rename to res/img/style/checkbox.png diff --git a/img/style/down_arrow.png b/res/img/style/down_arrow.png similarity index 100% rename from img/style/down_arrow.png rename to res/img/style/down_arrow.png diff --git a/mac_res/HostsUtl.scpt b/res/mac/HostsUtl.scpt similarity index 100% rename from mac_res/HostsUtl.scpt rename to res/mac/HostsUtl.scpt diff --git a/mac_res/Info.plist b/res/mac/Info.plist similarity index 100% rename from mac_res/Info.plist rename to res/mac/Info.plist diff --git a/mac_res/dmg_resource/DS_Store_dmg b/res/mac/dmg/DS_Store_dmg similarity index 100% rename from mac_res/dmg_resource/DS_Store_dmg rename to res/mac/dmg/DS_Store_dmg diff --git a/mac_res/dmg_resource/background.png b/res/mac/dmg/background.png similarity index 100% rename from mac_res/dmg_resource/background.png rename to res/mac/dmg/background.png diff --git a/style.qrc b/style.qrc deleted file mode 100644 index 9c88d05..0000000 --- a/style.qrc +++ /dev/null @@ -1,6 +0,0 @@ - - - img/style/checkbox.png - img/style/down_arrow.png - - diff --git a/test.py b/test.py index 4abab8b..abdfbdd 100644 --- a/test.py +++ b/test.py @@ -5,4 +5,4 @@ if __name__ == "__main__": main = tui.HostsUtil() - main.startutil() \ No newline at end of file + main.start() \ No newline at end of file diff --git a/tui/make.py b/tui/_make.py similarity index 98% rename from tui/make.py rename to tui/_make.py index ae91fca..eb180fe 100644 --- a/tui/make.py +++ b/tui/_make.py @@ -1,7 +1,7 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- # -# make.py: +# _make.py: # # Copyleft (C) 2014 - huhamhire # ===================================================================== @@ -30,7 +30,7 @@ def __init__(self, parent=None): Fetch settings from the main dialog to make a new hosts file. Args: - parent (obj): An instance of MainDialog object to get settings + parent (obj): An instance of CursesDaemon object to get settings from. """ self.make_cfg = parent._make_cfg diff --git a/tui/update.py b/tui/_update.py similarity index 98% rename from tui/update.py rename to tui/_update.py index bfaff8b..f3c270e 100644 --- a/tui/update.py +++ b/tui/_update.py @@ -1,7 +1,7 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- # -# update.py: +# _update.py: # # Copyleft (C) 2013 - huhamhire # ===================================================================== diff --git a/tui/curses_d.py b/tui/curses_d.py index a74941e..609e35e 100644 --- a/tui/curses_d.py +++ b/tui/curses_d.py @@ -21,15 +21,14 @@ import sys from curses_ui import CursesUI -from make import MakeHosts -from update import FetchUpdate +from _make import MakeHosts +from _update import FetchUpdate sys.path.append("..") -from util.retrievedata import RetrieveData -from util import CommonUtil +from util import CommonUtil, RetrieveData -class CursesDeamon(CursesUI): +class CursesDaemon(CursesUI): """ Attributes: _make_cfg (dict): A dictionary containing the selection control bytes @@ -43,7 +42,7 @@ class CursesDeamon(CursesUI): of course "Unkown". hostname (str): A string indicating the hostname of current operating system. This attribute would be used for linux clients. - hostspath (str): A string indicating the absolute path of the hosts + hosts_path (str): A string indicating the absolute path of the hosts file on current operating system. """ _make_cfg = {} @@ -58,7 +57,7 @@ class CursesDeamon(CursesUI): _hot_keys = [curses.KEY_UP, curses.KEY_DOWN, 10, 32] def __init__(self): - super(CursesDeamon, self).__init__() + super(CursesDaemon, self).__init__() # Check if current session have root privileges self.check_writable() @@ -111,13 +110,14 @@ def session_daemon(self): msg = "Apply Changes to hosts file?" confirm = self.messagebox(msg, 2) if confirm: - self.set_cfgbytes() + self.set_config_bytes() maker = MakeHosts(self) maker.make() self.move_hosts() elif key_in == curses.KEY_F5: self._update = self.check_update() elif key_in == curses.KEY_F6: + # TODO Check if data file up-to-date if self._update == {}: self._update = self.check_update() self.fetch_update() @@ -240,7 +240,7 @@ def fetch_update(self): fetch_d = FetchUpdate(self) fetch_d.get_file() - def set_cfgbytes(self): + def set_config_bytes(self): """Set configuration byte words - Public Method Calculate the module configuration byte words by the selection from diff --git a/tui/curses_ui.py b/tui/curses_ui.py index 5720054..9fc4a36 100644 --- a/tui/curses_ui.py +++ b/tui/curses_ui.py @@ -17,8 +17,8 @@ import sys sys.path.append("..") -from util.common import CommonUtil -from hostsutl import __version__ +from util import CommonUtil +from gui.hostsutil import __version__ class CursesUI(object): diff --git a/tui/hostsutil.py b/tui/hostsutil.py index 7ed4a90..1c434ef 100644 --- a/tui/hostsutil.py +++ b/tui/hostsutil.py @@ -10,18 +10,20 @@ # this program. If not, see . # ===================================================================== +__version__ = "1.9.8" +__revision__ = "$Id$" __author__ = "huhamhire " from zipfile import BadZipfile +from curses_d import CursesDaemon + import sys sys.path.append("..") -from curses_d import CursesDeamon -from util.retrievedata import RetrieveData -from util import CommonUtil +from util import CommonUtil, RetrieveData -class HostsUtil(CursesDeamon): +class HostsUtil(CursesDaemon): _down_flag = 0 _hostsinfo = [] @@ -50,7 +52,7 @@ def __del__(self): except: pass - def startutil(self): + def start(self): while True: # Reload if self.session_daemon(): @@ -101,4 +103,4 @@ def set_info(self): if __name__ == "__main__": main = HostsUtil() - main.startutil() + main.start() diff --git a/util/__init__.py b/util/__init__.py index 820ffb4..73b0f56 100644 --- a/util/__init__.py +++ b/util/__init__.py @@ -11,7 +11,6 @@ # ===================================================================== from common import CommonUtil -from language import LangUtil from retrievedata import RetrieveData -__all__ = ["CommonUtil", "LangUtil", "RetrieveData"] \ No newline at end of file +__all__ = ["CommonUtil", "RetrieveData"] \ No newline at end of file diff --git a/util/retrievedata.py b/util/retrievedata.py index 72031a2..dac20c3 100644 --- a/util/retrievedata.py +++ b/util/retrievedata.py @@ -32,14 +32,14 @@ class RetrieveData(object): methods. Attributes: - _conn (obj): An instance of sqlite3.connect object to set the + conn (obj): An instance of sqlite3.connect object to set the connection with a SQLite database. _cur (obj): An instance of sqlite3.connect.cursor object to operate SQL queries in the database. _database (str): A string indicating the filename of a SQLite database file. """ - _conn = None + conn = None _cur = None _database = None @@ -68,8 +68,8 @@ def connect_db(cls, database=DATABASE): database (str): A string indicating the SQLite database file. "hostslist.s3db" by default. """ - cls._conn = sqlite3.connect(database) - cls._cur = cls._conn.cursor() + cls.conn = sqlite3.connect(database) + cls._cur = cls.conn.cursor() cls._database = database @classmethod @@ -78,7 +78,7 @@ def disconnect_db(cls): Close the connection with a SQLite database. """ - cls._conn.close() + cls.conn.close() @classmethod def get_info(cls): @@ -244,5 +244,5 @@ def clear(cls): Close the connection to the database and delete the database file. """ - cls._conn.close() + cls.conn.close() os.remove(cls._database)