class IPtray(object):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        # self.Lock=threading.RLock()
        self.ip = "0.0.0.0"
        self.app = QApplication(sys.argv)
        self.wMain = QWidget()
        self.tray = QSystemTrayIcon(self.wMain)

    def Ui(self):
        self.sub_getIP()
        self.actExit = QAction("退出")
        self.actExit.triggered.connect(self.forceEx)
        self.tray.setIcon(QIcon(".\icon\ip.png"))
        self.tray.setVisible(True)
        self.trayMenu = QMenu()
        self.trayMenu.addAction(self.actExit)
        self.tray.setContextMenu(self.trayMenu)
        # print("showing message")
        self.tray.showMessage("IP", "你的IP是" + self.ip)
        self.sub_setToolTip()  #getIP运行比较慢, setToolTip放在后面.
        sys.exit(self.app.exec_())

    def forceEx(self):
        sys.exit(self.app.exec_())
        exit()

    def getIP(self):
        # self.Lock.acquire()
        while 1:
            try:
                s = socket(AF_INET, SOCK_DGRAM)
                s.connect(("114.114.114.114", 80))
                self.ip = s.getsockname()[0]
            finally:
                s.close()
                # print("exit getIP")
            sleep(5)
            # self.Lock.release()

    def setToolTip(self):
        while 1:
            self.tray.setToolTip(self.ip)
            # print("exit setToopTip")
            sleep(5)

    def sub_getIP(self):
        self.subThread_getIP = Thread(target=self.getIP, daemon=True)
        self.subThread_getIP.setName("sub_getIP")
        # self.subThread_getIP.setDaemon = True  # 设置为后台线程
        self.subThread_getIP.start()

    # 这个线程要一直运行
    def sub_setToolTip(self):
        self.subThread_setToolTip = Thread(target=self.setToolTip, daemon=True)
        self.subThread_setToolTip.setName("sub_setToolTip")
        # self.subThread_setToolTip.setDaemon(True)  # 设置为后台线程
        self.subThread_setToolTip.start()
Beispiel #2
0
    def Ui(self):
        app = QApplication(sys.argv)
        W = QWidget()

        #生成动作
        act_copy = QAction('复制到剪切板')
        act_about = QAction("关于: 0.1    FoxZno")
        act_exit = QAction("退出")
        act_copy.triggered.connect(self.copy)
        act_exit.triggered.connect(self.fouceEx)

        tray = QSystemTrayIcon(W)
        tray.setToolTip(self.ip)
        tray.setIcon(QIcon('.\icon\ip.png'))
        tray.setVisible(True)
        trayMenu = QMenu()

        #添加动作
        trayMenu.addAction(act_copy)
        trayMenu.addAction(act_about)
        trayMenu.addAction(act_exit)

        tray.setContextMenu(trayMenu)
        sys.exit(app.exec_())
Beispiel #3
0
        color = dialog.currentColor()
        clipboard.setText("rgb(%d, %d, %d)" %
                          (color.red(), color.green(), color.blue()))


def copy_color_hsv():
    if dialog.exec_():
        color = dialog.currentColor()
        clipboard.setText("hsv(%d, %d, %d)" %
                          (color.hue(), color.saturation(), color.value()))


# Create the tray
tray = QSystemTrayIcon()
tray.setIcon(icon)
tray.setVisible(True)

# Create the menu
menu = QMenu()
action1 = QAction("Hex")
action1.triggered.connect(copy_color_hex)
menu.addAction(action1)

action2 = QAction("RGB")
action2.triggered.connect(copy_color_rgb)
menu.addAction(action2)

action3 = QAction("HSV")
action3.triggered.connect(copy_color_hsv)
menu.addAction(action3)
class Indicator():
    APP_NAME = 'FortiVPN Quick Tray'

    def __init__(self):
        self.app = QApplication([])
        self.app.setQuitOnLastWindowClosed(False)
        self.indicator = QSystemTrayIcon()
        self.indicator.setIcon(QIcon(self._get_file('./icons/icon.png')))
        self.indicator.setContextMenu(self._build_menu())
        self.indicator.setVisible(True)
        self.indicator.setToolTip('OFF')

        self.indicator.activated.connect(self._click_indicator)

        self.logs_dialog = QTextEdit()
        self.logs_dialog.setWindowTitle(f'{self.APP_NAME} - Logs')
        self.logs_dialog.setFixedSize(440, 440)
        self.logs_dialog.setReadOnly(True)
        self.logs_dialog.setWindowIcon(
            QIcon(self._get_file('./icons/icon.png')))

        self.vpn_config = '/etc/openfortivpn/config'
        self.vpn_process = None
        self.vpn_logs_file = NamedTemporaryFile(delete=False)

        self.vpn_thread = VPNThread(self.vpn_logs_file)
        self.vpn_thread.status.connect(self._update_vpn_status)
        self.vpn_thread.log.connect(self.logs_dialog.append)

        self.app_update_thread = AppUpdateThread(self._get_file('./version'))
        self.app_update_thread.update_available.connect(
            self._show_update_notification)
        self.app_update_thread.start()

    def run(self):
        self.app.exec_()
        sys.exit()

    def _build_menu(self):
        menu = QMenu()

        self.connect_action = QAction('Connect')
        self.disconnect_action = QAction('Disconnect')
        self.config_action = QAction('Config')
        self.logs_action = QAction('Logs')
        self.exit_action = QAction('Exit')

        self.disconnect_action.setDisabled(True)

        self.connect_action.triggered.connect(self._click_connect)
        self.disconnect_action.triggered.connect(self._click_disconnect)
        self.config_action.triggered.connect(self._click_config)
        self.logs_action.triggered.connect(self._click_logs)
        self.exit_action.triggered.connect(self._click_exit)

        menu.addAction(self.connect_action)
        menu.addAction(self.disconnect_action)
        menu.addSeparator()
        menu.addAction(self.config_action)
        menu.addAction(self.logs_action)
        menu.addSeparator()
        menu.addAction(self.exit_action)

        return menu

    def _click_connect(self):
        self.indicator.setIcon(QIcon(self._get_file('./icons/try.png')))
        self.indicator.setToolTip('TRYING')

        self.connect_action.setDisabled(True)
        self.config_action.setDisabled(True)

        with open(self.vpn_logs_file.name, 'w+b') as f:
            try:
                self.vpn_process = Popen(split('pkexec openfortivpn -c ' +
                                               self.vpn_config),
                                         stdin=PIPE,
                                         stdout=f,
                                         stderr=f)
                self.vpn_process.communicate(timeout=1)
            except TimeoutExpired:
                pass

        self.vpn_thread.start()

    def _click_disconnect(self):
        try:
            run(split('pkexec kill ' + str(self.vpn_process.pid)))
        except ChildProcessError:
            pass

    def _click_config(self):
        config_file, _ = QFileDialog.getOpenFileName(
            caption='Select config file',
            dir='/',
            filter='All files (*)',
            options=QFileDialog.DontUseNativeDialog)

        if config_file:
            self.vpn_config = config_file

    def _click_logs(self):
        if not self.vpn_thread.isRunning():
            with open(self.vpn_logs_file.name) as logs:
                self.logs_dialog.setPlainText(logs.read())

        self.logs_dialog.show()

    def _click_exit(self):
        if self.indicator.toolTip() == 'ON':
            _ = QMessageBox.warning(
                None, self.APP_NAME,
                'VPN is still ON. Please Disconnect first before exiting')

            return

        if self.vpn_logs_file.name:
            remove_log_file(self.vpn_logs_file.name)

        self.app.quit()

    def _get_file(self, file_path):
        try:
            base = sys._MEIPASS
        except Exception:
            base = path.abspath('.')

        return path.join(base, file_path)

    def _click_indicator(self, event):
        if event == QSystemTrayIcon.ActivationReason.Trigger:
            self._click_logs()

    def _update_vpn_status(self, message):
        if message == 'ERR':
            self.indicator.setIcon(QIcon(self._get_file('./icons/err.png')))
            self.indicator.setToolTip('ERROR')
            self.connect_action.setDisabled(False)
            self.config_action.setDisabled(False)
            pass

        if message == 'ON':
            self.indicator.setIcon(QIcon(self._get_file('./icons/on.png')))
            self.indicator.setToolTip('ON')
            self.disconnect_action.setDisabled(False)
            pass

        if message == 'OFF':
            self.indicator.setIcon(QIcon(self._get_file('./icons/icon.png')))
            self.indicator.setToolTip('OFF')
            self.disconnect_action.setDisabled(True)
            self.connect_action.setDisabled(False)
            self.config_action.setDisabled(False)
            pass

    def _show_update_notification(self, flag):
        if flag and self.indicator.supportsMessages:
            self.indicator.showMessage(
                self.APP_NAME, 'There is a new update available',
                QIcon(self._get_file('./icons/icon.png')))
Beispiel #5
0
def gui(pid, url):
    from PySide2.QtGui import QIcon, QPixmap
    from PySide2.QtWidgets import QApplication, QSystemTrayIcon, QMenu, QAction
    xpm = b"""/* XPM */
static char * ecco_xpm[] = {
"64 54 188 2",
"  	c None",
". 	c #49CF23",
"+ 	c #40CE0E",
"@ 	c #44CE1C",
"# 	c #46CF1D",
"$ 	c #50D030",
"% 	c #40CE0D",
"& 	c #44CF1A",
"* 	c #3FCE08",
"= 	c #3FCE0B",
"- 	c #46CF1F",
"; 	c #42CE12",
"> 	c #49CF24",
", 	c #45CF1A",
"' 	c #41CE10",
") 	c #42CE13",
"! 	c #3FCE09",
"~ 	c #40CE0C",
"{ 	c #3FCE0C",
"] 	c #43CF13",
"^ 	c #40CE0F",
"/ 	c #4ED02E",
"( 	c #43CE17",
"_ 	c #4ACF27",
": 	c #61D00E",
"< 	c #C8DC0A",
"[ 	c #DFE108",
"} 	c #E1E108",
"| 	c #D3DE09",
"1 	c #8BD40D",
"2 	c #9BD60C",
"3 	c #A9D80B",
"4 	c #7CD20D",
"5 	c #47CF1D",
"6 	c #63D00D",
"7 	c #E8E208",
"8 	c #F5E507",
"9 	c #E4E208",
"0 	c #4BD028",
"a 	c #C9DD0A",
"b 	c #C4DC0A",
"c 	c #C0DB0A",
"d 	c #41CE0E",
"e 	c #93D50C",
"f 	c #CCDD0A",
"g 	c #F9F0A9",
"h 	c #FDFAE7",
"i 	c #FCF8DD",
"j 	c #F7EA72",
"k 	c #44CE19",
"l 	c #6ED10D",
"m 	c #ECE308",
"n 	c #F9F0AB",
"o 	c #FFFFFF",
"p 	c #FFFEFA",
"q 	c #F7EB85",
"r 	c #B0D90B",
"s 	c #72D10D",
"t 	c #FEFCF1",
"u 	c #F6E741",
"v 	c #EDE308",
"w 	c #5AD00E",
"x 	c #43CE16",
"y 	c #53CF0E",
"z 	c #FBF5CC",
"A 	c #4DD02C",
"B 	c #FEFBEE",
"C 	c #E0E108",
"D 	c #F8EE9A",
"E 	c #FBF6D0",
"F 	c #5DD00E",
"G 	c #42CF12",
"H 	c #ACD80B",
"I 	c #FCF6D2",
"J 	c #FEFEF8",
"K 	c #82D30D",
"L 	c #41CE13",
"M 	c #F5E63A",
"N 	c #FEFDF6",
"O 	c #F7EC86",
"P 	c #44CE18",
"Q 	c #A2D70C",
"R 	c #FAF3BC",
"S 	c #F9F0AE",
"T 	c #77D20D",
"U 	c #DCE009",
"V 	c #F7EB80",
"W 	c #A8D80B",
"X 	c #FAF1B5",
"Y 	c #BCDB0A",
"Z 	c #4BCF27",
"` 	c #F1E407",
" .	c #FBF5CB",
"..	c #F7EB7D",
"+.	c #CDDD0A",
"@.	c #F7EB82",
"#.	c #FCF8DC",
"$.	c #7BD76F",
"%.	c #FCF8DE",
"&.	c #F6E862",
"*.	c #D1EECE",
"=.	c #E6E208",
"-.	c #F5E626",
";.	c #F6E85B",
">.	c #E9E308",
",.	c #C9EBC6",
"'.	c #A5D70C",
").	c #ADD80B",
"!.	c #84D879",
"~.	c #55D03C",
"{.	c #C3E9BF",
"].	c #64D352",
"^.	c #68D456",
"/.	c #D6DF09",
"(.	c #D0DE09",
"_.	c #54D03B",
":.	c #C8EBC5",
"<.	c #AFE3AA",
"[.	c #C9EBC5",
"}.	c #A2E09B",
"|.	c #BAE7B5",
"1.	c #F8FCF7",
"2.	c #B1E4AB",
"3.	c #D9F1D6",
"4.	c #3FCE0A",
"5.	c #BBDA0B",
"6.	c #E7E208",
"7.	c #AFD90B",
"8.	c #44CE1A",
"9.	c #C0E8BB",
"0.	c #90DB87",
"a.	c #C7EBC4",
"b.	c #44CF15",
"c.	c #C4EAC0",
"d.	c #6AD458",
"e.	c #D4EFD2",
"f.	c #40CE0B",
"g.	c #97DD8F",
"h.	c #45CF1B",
"i.	c #A8E1A2",
"j.	c #99DD91",
"k.	c #A0DF99",
"l.	c #C7EBC3",
"m.	c #6FD55F",
"n.	c #7CD771",
"o.	c #C2E9BF",
"p.	c #B6E5B2",
"q.	c #66D355",
"r.	c #71D563",
"s.	c #7FD872",
"t.	c #44CF17",
"u.	c #7CD770",
"v.	c #BCE7B8",
"w.	c #62D24F",
"x.	c #D8F0D6",
"y.	c #8FDB84",
"z.	c #A8E1A3",
"A.	c #D6F0D3",
"B.	c #54D03C",
"C.	c #B6E6B1",
"D.	c #B0E3AB",
"E.	c #BDE7B9",
"F.	c #61D24D",
"G.	c #C8EBC4",
"H.	c #CEEDCC",
"I.	c #D8F0D5",
"J.	c #53D136",
"K.	c #7DD771",
"L.	c #70D561",
"M.	c #DFF3DD",
"N.	c #7CD76F",
"O.	c #54D03A",
"P.	c #4BCF28",
"Q.	c #C3E9C0",
"R.	c #CBECC8",
"S.	c #B9E6B4",
"T.	c #98DD91",
"U.	c #B6E5B1",
"V.	c #DAF1D8",
"W.	c #42CE14",
"X.	c #3DCE02",
"Y.	c #4DD02A",
"Z.	c #48CF22",
"`.	c #43CF14",
" +	c #4AD025",
".+	c #46CF1A",
"++	c #48CF20",
"@+	c #45CF19",
"                                                      . + @                                                                     ",
"                                                  # + + + + +                                                                   ",
"                                                  + + + + + + +                                                                 ",
"                                                $ + + + + + + +                                                                 ",
"                                                  + + + + + + + %                                                               ",
"                                                  + + + + + + + +                                                               ",
"                                                    + + + + + + +                                                               ",
"                                                    & + + + + + + *                                                             ",
"                                                      + + + + + + =                 = - ; + + + > ,                             ",
"                                                      % + + + + + +             ' + + + + + + + + + + +                         ",
"                                                        + + + + + '         ) + + + + + + + + + + + + + +                       ",
"                                                        + + + + + +     ' + + + + + + + + + + + + + + + + +                     ",
"                                                        ! + + + + + ~ * + + + + + + + + + + + + + + + + + + + {                 ",
"                                        ] ^ % + ; + /     + + + + + + + + + + + + + + + + + + + + + + + + + + + (               ",
"                                  ' _ + + + + + + + + %   + + + + + + + + + + : < [ } | 1 + : 2 3 3 4 + + + + + + + 5           ",
"                            + ^ + + + + + + + + + + + + + + + + + + + + + + 6 7 8 8 8 8 8 9 8 8 8 8 8 9 2 + + + + + + '         ",
"                        0 + + + + + + + + + + + + + + + + + + + + + + + + + a 8 8 8 8 8 8 8 8 8 8 8 8 8 8 b + + + + + +         ",
"                    ^ + + + + + + + + + + + + + + + + + + + + + + + + + + + [ 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 c + + + + + %       ",
"                  d + + + + + + + + + + + + + + + + + + + + + + + + + + + + [ 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 e + + + + + +     ",
"                + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + f 8 8 8 8 8 8 8 8 g h h i j 8 8 8 9 + + + + + k     ",
"              + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + l m 8 8 8 8 8 8 n o o o o p q 8 8 8 r + + + + +     ",
"            + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + s } 8 8 8 8 8 t o o o o o t u 8 8 v w + + + + x   ",
"          + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + y 9 8 8 8 8 o o o o o o o z 8 8 8 r + + + + +   ",
"        A + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + e 8 8 8 8 B o o o o o o o j 8 8 C + + + + +   ",
"      ) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 9 8 8 8 D o o o o o o o E 8 8 8 F + + + + G ",
"      + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + H 8 8 8 8 I o o o o o o J 8 8 8 K + + + + ^ ",
"    L + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + y v 8 8 8 M N o o o o o o O 8 8 K + + + + P ",
"    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Q 8 8 8 8 R o o o o o o S 8 8 T + + + + + ",
"    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + U 8 8 8 V o o o o o o z 8 v + + + + + + ",
"  ~ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + W 8 8 8 8 N o o o o o X 8 Y + + + + + Z ",
"  + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + y ` 8 8 8  .o o o o o ..} y + + + + + + ",
"  + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +.8 8 8 @.o o o o #.7 l + + + + + + ) ",
"  + + + + + + + + $.+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + e 8 8 8 8 g p o %.&.K + + + + + + +   ",
"  + + + + + + + + *.+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + =.8 8 8 8 -.;.8 >.+ + + + + + + +   ",
"^ + + + + + + + + ,.+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + '.8 8 8 8 8 8 8 ).+ + + + + + + =   ",
"+ + + + + + !.~.+ {.].^.+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + /.8 8 8 8 8 (.+ + + + + + + + +   ",
"+ + + + _.:.<.[.}.|.1.2.3.4.+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + y 5.7 8 6.7.+ + + + + + + + +     ",
"8.+ + + 9.].+ + :.{.0.a.,.+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + b.    ",
"4.+ + * c.+ + + d.e.+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +       ",
"  + + f.{.+ + + + g.+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + h.      ",
"  + + + i.j.+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +         ",
"  Z + + + k.l.m.+ + + n.o.,._.+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +         ",
"    + + + + _.p.[.i.q.e.r.s.o.+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + %           ",
"    t.+ + + + + + u.r.v.+ + w.+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +             ",
"      % + + + + + + + x.y.+ + z.A.0.+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +               ",
"        + + + + + + + B.C.*.D.E.+ + + F.G.H.I.r.+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +                 ",
"          J.+ + + + + + + + K.e.L.+ r.M.N.+ O.,.+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + P.                  ",
"              k + + + + + + + u.Q.R.2.S.+ + T.U.+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +                     ",
"                    + + + + + + + + + p.V.M.i.+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +                       ",
"                      W.+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + )                           ",
"                        X.+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ~                               ",
"                              ; - + + + + + + + Y.        Z.' + + + + + + + + + + + + + + + + +                                 ",
"                                    { `. +~                     ^ + + + + + + + + + + ) +                                       ",
"                                                                      .+- + + ++@++                                             "};
"""
    app = QApplication([])
    app.setQuitOnLastWindowClosed(False)

    def browse():
        webbrowser.open(url)

    menu = QMenu()
    action = QAction("Open in browser")
    action.triggered.connect(browse)

    def stop():
        os.kill(pid, signal.SIGINT)
        app.quit()

    menu.addAction(action)
    quit = QAction("Quit")
    quit.triggered.connect(stop)
    menu.addAction(quit)
    pix = QPixmap()
    pix.loadFromData(xpm)
    icon = QIcon(pix)
    tray = QSystemTrayIcon()
    tray.setIcon(icon)
    tray.setVisible(True)
    tray.setToolTip("ecco")
    tray.setContextMenu(menu)
    app.exec_()
Beispiel #6
0
class Window(QWidget):
    def __init__(self, parent=None):
        super(Window, self).__init__()
        self.path = None
        self.settings()
        self.create_widgets()
        self.create_layout()

    def settings(self):
        self.resize(300, 120)
        self.setWindowTitle('Mp3 Downloader')

    def create_widgets(self):
        self.edit_url = QLineEdit()
        self.edit_name = QLineEdit()
        self.btn_select_path = QPushButton('Select path', self)
        self.btn_select_path.clicked.connect(self.select_path)
        self.btn_download = QPushButton('Download mp3', self)
        self.btn_download.clicked.connect(self.download)

    def create_layout(self):
        self.layout = QFormLayout()
        self.layout.addRow('Nome:', self.edit_name)
        self.layout.addRow('Url:', self.edit_url)
        self.layout.addRow('Selecionar destino:', self.btn_select_path)
        self.layout.addRow(self.btn_download)
        self.setLayout(self.layout)

    def select_path(self):
        self.path = QFileDialog.getExistingDirectory(self, 'Selecionar Pasta')

    def download(self):
        if self.verify_fields():
            self.manage_interface(False)
            self.thread_qt()

    def verify_fields(self):
        if self.path is None:
            return False
        else:
            strings = [self.edit_url, self.edit_name.text(), self.path]
            regex_validate = QRegExp('*.mp3')
            regex_validate.setPatternSyntax(QRegExp.Wildcard)
            emptys = 0
            for string in strings:
                if len(string.split()) == 0:
                    emptys += 1
                if emptys == 0 and regex_validate.exactMatch(
                        self.edit_url.text()):
                    return True

    def thread_qt(self):
        url = self.edit_url.text()
        name = self.edit_name.text()
        path = self.edit_path.text()
        self.thre = DownloaderMusic()
        self.thre.finished.connect(self.downfin)
        self.thre.start()

    def manage_interface(self, state):
        self.btn_download.setEnabled(state)
        self.edit_name.setEnabled(state)
        self.edit_url.setEnabled(state)
        self.btn_select_path

    def downfin(self):
        self.notify_icon = QSystemTrayIcon()
        self.notify_icon.setVisible(True)
        self.notify_icon.showMessage(
            'Download Finalizado',
            u'O download da sua música foi realizado com sucesso.',
            QSystemTrayIcon.Information, 3000)
        self.manage_interface(True)
Beispiel #7
0
class UI:
    """
    WSL2 端口自动转发
    """
    def __init__(self, qt_application=None):
        self.qt_application = qt_application
        # 实例化配置管理类
        self.settings_manage = SettingsManage()
        self.__setting = self.settings_manage.get()

        # 实例化windows命令处理类
        self.wsl2 = WinCmd()

        # 初始化启动脚本
        if not isfile(self.wsl2.WSL_VBS_PATH):
            copyfile(self.wsl2.WSL_VBS_PATH_TEMP, self.wsl2.WSL_VBS_PATH)
        if not isfile(self.wsl2.WSL_BAT_PATH):
            self.settings_manage.save_file_content(
                self.wsl2.WSL_BAT_PATH,
                self.__setting.get('wsl_bat_content', ''))
        # 加载UI文件
        self.ui = QUiLoader().load(ResourcePath.resource_path('lib/wsl2.ui'))

        # 设置界面图标
        app_icon = QIcon(ResourcePath.resource_path("lib/logo.ico"))
        self.ui.setWindowIcon(app_icon)

        # 设置选中状态
        self.ui.auto_start_wsl.setChecked(
            self.__setting.get('auto_start_wsl', False))
        self.ui.fire_wall_open.setChecked(
            self.__setting.get('fire_wall_open', False))
        self.ui.fire_wall_close.setChecked(
            self.__setting.get('fire_wall_close', False))

        # 设置文本框的值
        self.ui.port_text.appendPlainText('\n'.join(
            self.__setting.get('ports', [])))
        self.ui.bat_text.appendPlainText(self.wsl2.get_bat_script())

        # 按钮监听
        self.ui.get_wsl2_ip.clicked.connect(self.__get_wsl2_ip)
        self.ui.port_add.clicked.connect(self.__port_add)
        self.ui.port_del.clicked.connect(self.__port_del)
        self.ui.port_info.clicked.connect(self.__port_info)
        self.ui.wsl_l_v.clicked.connect(self.__wsl_l_v)
        self.ui.port_reset.clicked.connect(self.__port_reset)
        self.ui.end_wsl.clicked.connect(self.__end_wsl)
        self.ui.start_wsl.clicked.connect(self.__start_wsl)
        self.ui.start_wsl_all.clicked.connect(self.start_wsl_all)
        self.ui.save_settings.clicked.connect(self.__save_settings)
        self.ui.save_settings_ports.clicked.connect(self.__save_settings)

        # 设置系统托盘图标的菜单
        tp_icon = QIcon(ResourcePath.resource_path("lib/logo.ico"))
        self.tp = QSystemTrayIcon(self.ui)
        self.tp.setIcon(tp_icon)

        self.ui_hide = QAction(icon=tp_icon,
                               text='隐藏(Hide)',
                               triggered=self.ui.hide)
        self.ui_show = QAction(icon=tp_icon,
                               text='显示(Show)',
                               triggered=self.ui.show)
        self.ui_exit = QAction(icon=tp_icon,
                               text='退出(Exit)',
                               triggered=self.__quit_app)
        self.tp_menu = QMenu()
        self.tp_menu.addAction(self.ui_hide)
        self.tp_menu.addAction(self.ui_show)
        self.tp_menu.addAction(self.ui_exit)
        self.tp.setContextMenu(self.tp_menu)
        self.tp.activated.connect(self.__tp_connect_action)
        self.tp.show()
        self.tp.showMessage('WSL2AutoPortForward', 'WSL2端口自动转发工具已启动',
                            QSystemTrayIcon.MessageIcon.Information)

    def __tp_connect_action(self, activation_reason):
        """
        监听托盘图标点击
        :param activation_reason: 点击类型
        :return:
        """
        if activation_reason == QSystemTrayIcon.ActivationReason.Trigger:
            # 左单击
            if self.ui.isHidden():
                self.ui.show()
            else:
                self.ui.hide()
        elif activation_reason == QSystemTrayIcon.ActivationReason.Context:
            # 右单击
            self.tp_menu.show()
        elif activation_reason == QSystemTrayIcon.ActivationReason.DoubleClick:
            # 双击
            self.ui.show()

    def __quit_app(self):
        """
        退出APP
        :return:
        """
        re = QMessageBox.question(self.ui, "提示", "退出系统",
                                  QMessageBox.Yes | QMessageBox.No,
                                  QMessageBox.No)
        if re == QMessageBox.Yes:
            # 关闭窗体程序
            self.qt_application.quit()
            # 在应用程序全部关闭后,TrayIcon其实还不会自动消失,
            # 直到你的鼠标移动到上面去后,才会消失,
            # 这是个问题,(如同你terminate一些带TrayIcon的应用程序时出现的状况),
            # 这种问题的解决我是通过在程序退出前将其setVisible(False)来完成的。
            self.tp.setVisible(False)

    def __wsl_l_v(self):
        """
        获取wsl信息
        :return:
        """
        wsl_l_v_txt = '  ' + self.wsl2.wsl_l_v(exec_run=True).replace(
            '\x00', '').strip()
        if not wsl_l_v_txt:
            # 未查询到wsl信息提示
            wsl_l_v_txt = '未查询到wsl信息!'
            QMessageBox.information(self.ui, '系统提示', wsl_l_v_txt)
        self.ui.wsl_l_v_text.setPlainText(wsl_l_v_txt)

    def __get_wsl2_ip(self):
        wsl2_ip_info = self.wsl2.get_wsl2_ip()
        if not wsl2_ip_info:
            # 未查询到端口转发信息提示
            QMessageBox.information(self.ui, '系统提示', '未查询到IP信息!')
        else:
            wsl2_ip_info = 'WSL2当前IP为:' + wsl2_ip_info
            self.ui.wsl_l_v_text.setPlainText(wsl2_ip_info)

    def __port_add(self):
        wsl2_ip_info = self.wsl2.get_wsl2_ip()
        if not wsl2_ip_info:
            # 未查询到端口转发信息提示
            QMessageBox.information(self.ui, '系统提示', '未查询到IP信息!')
        else:
            self.ui.result_text.clear()
            ports = self.ui.port_text.toPlainText()
            port_str = ''
            for port in ports.splitlines():
                if not port.strip():
                    continue
                self.__port_add_one(port, wsl2_ip_info)
                port_str += (',' + port if port_str else port)
            self.__fire_wall_rule_add(port_str)
            self.ui.result_text.appendPlainText('Succeed!')

    def __port_del(self, del_port=True, del_fire=True):
        self.ui.result_text.clear()
        ports = self.ui.port_text.toPlainText()
        if del_port:
            for port in ports.splitlines():
                if not port.strip():
                    continue
                self.__port_del_one(port)
        if del_fire:
            self.__fire_wall_rule_del()
        self.ui.result_text.appendPlainText('Succeed!')

    def __port_reset(self):
        port_info = self.wsl2.port_info()
        self.ui.result_text.clear()
        for port in port_info:
            self.__port_del_one(port['port'])
        self.__fire_wall_rule_del()
        self.ui.result_text.appendPlainText('Succeed!')

    def __port_info(self):
        """
        获取端口转发信息
        :return:
        """
        info_str = self.wsl2.port_info(True).strip()
        if not info_str:
            # 未查询到端口转发信息提示
            info_str = '未查询到端口转发信息!'
            QMessageBox.information(self.ui, '系统提示', info_str)
        self.ui.result_text.setPlainText(info_str)

    def __wsl2_auto_port_forward(self):
        """
        一键自动转发
        @return:
        """

        self.__port_del(del_port=False, del_fire=True)
        self.__port_add()

    def __end_wsl(self):
        """
        停止wsl
        :return:
        """
        self.start_qt_process(self.wsl2.end_wsl(exec_run=False))
        info_str = 'wsl 已全部停止'
        QMessageBox.information(self.ui, '系统提示', info_str)

    def __start_wsl(self):
        """
        启动wsl
        :return:
        """
        self.start_qt_process(self.wsl2.start_wsl(exec_run=False))

    def start_wsl_all(self):
        """
        启动wsl并转发端口
        :return:
        """
        self.__start_wsl()
        self.__wsl2_auto_port_forward()

    def __save_settings(self):
        """
        保存全部配置
        :return:
        """
        # 保存脚本
        self.__save_bat_script()

        # 保存配置信息
        self.settings_manage.set('fire_wall_open',
                                 self.ui.fire_wall_open.isChecked())
        self.settings_manage.set('fire_wall_close',
                                 self.ui.fire_wall_close.isChecked())
        self.settings_manage.set('auto_start_wsl',
                                 self.ui.auto_start_wsl.isChecked())
        self.settings_manage.set('ports',
                                 self.ui.port_text.toPlainText().splitlines())

        # 保存成功提示
        QMessageBox.information(self.ui, '系统提示', '配置保存成功!')

    def __save_bat_script(self):
        """
        保存启动脚本
        :return:
        """
        content = self.ui.bat_text.toPlainText()
        self.settings_manage.set('wsl_bat_content', content)
        self.wsl2.save_bat_script(content)

    def __fire_wall_rule_add(self, port):
        """
        添加防火墙
        :param port: 端口号,多个端口逗号隔开
        :return:
        """
        if self.ui.fire_wall_open.isChecked():
            self.start_qt_process(
                self.wsl2.fire_wall_rule_add(
                    wsl_port=port,
                    wall_type=self.wsl2.FireWallRuleIn,
                    exec_run=False))
            self.ui.result_text.appendPlainText('>>> 添加防火墙:【' +
                                                self.wsl2.FireWallRuleIn +
                                                '】...')
            self.start_qt_process(
                self.wsl2.fire_wall_rule_add(
                    wsl_port=port,
                    wall_type=self.wsl2.FireWallRuleOut,
                    exec_run=False))
            self.ui.result_text.appendPlainText('>>> 添加防火墙:【' +
                                                self.wsl2.FireWallRuleOut +
                                                '】...')

    def __fire_wall_rule_del(self):
        """
        删除防火墙
        :return:
        """
        if self.ui.fire_wall_close.isChecked():
            self.start_qt_process(
                self.wsl2.fire_wall_rule_del(
                    wall_type=self.wsl2.FireWallRuleIn, exec_run=False))
            self.ui.result_text.appendPlainText('>>> 删除防火墙:【' +
                                                self.wsl2.FireWallRuleIn +
                                                '】...')
            self.start_qt_process(
                self.wsl2.fire_wall_rule_del(
                    wall_type=self.wsl2.FireWallRuleOut, exec_run=False))
            self.ui.result_text.appendPlainText('>>> 删除防火墙:【' +
                                                self.wsl2.FireWallRuleOut +
                                                '】...')

    def __port_add_one(self, port, wsl2_ip_info):
        """
        添加单个端口
        :param port: 端口号
        :param wsl2_ip_info: 转发的IP
        :return:
        """
        self.start_qt_process(
            self.wsl2.port_add(wsl_ip=wsl2_ip_info,
                               wsl_port=port,
                               exec_run=False))
        self.ui.result_text.appendPlainText('>>> 添加端口:【' + port + '】...')

    def __port_del_one(self, port):
        """
        删除单个端口
        :param port: 端口号
        :return:
        """
        self.start_qt_process(self.wsl2.port_del(wsl_port=port,
                                                 exec_run=False))
        self.ui.result_text.appendPlainText('>>> 删除端口:【' + port + '】...')

    def start_qt_process(self, cmd):
        """
        启动子进程执行耗时命令
        :param cmd:
        :return:
        """
        process = QProcess(self.ui)
        process.start(cmd)
        result = process.waitForStarted()
        return result
Beispiel #8
0
class SystemTrayIcon(QObject):
    clicked = pyqtSignal()
    double_clicked = pyqtSignal()

    def __init__(self, parent, menu, is_logging=False):
        QObject.__init__(self)

        def getIcon(name):
            return QIcon(':/images/tray_icons/' + name + '.png')

        self._icons = {
            STATUS_INIT: getIcon("disconnected") if is_logging \
                else getIcon("sync"),
            STATUS_DISCONNECTED: getIcon("disconnected"),
            STATUS_WAIT: getIcon("default"),
            STATUS_PAUSE: getIcon("pause"),
            STATUS_IN_WORK: getIcon("sync"),
            STATUS_INDEXING: getIcon("sync"),
        }
        self._statuses = {
            STATUS_INIT: tr("Pvtbox"),
            STATUS_DISCONNECTED: tr("Pvtbox connecting..."),
            STATUS_WAIT: tr("Pvtbox"),
            STATUS_PAUSE: tr("Pvtbox paused"),
            STATUS_IN_WORK: tr("Pvtbox syncing..."),
            STATUS_INDEXING: tr("Pvtbox indexing...")
        }
        self._tray = QSystemTrayIcon(self._icons[STATUS_INIT], parent)
        self.set_tool_tip(self._statuses[STATUS_INIT])
        self._tray.setContextMenu(menu)
        menu.aboutToShow.connect(self.clicked.emit)

        self._tray.activated.connect(self._on_activated)
        self._tray.installEventFilter(self)
        self._tray.setVisible(True)
        self._tray.show()

        self._tray_show_timer = QTimer(self)
        self._tray_show_timer.setInterval(3000)
        self._tray_show_timer.setSingleShot(False)
        self._tray_show_timer.timeout.connect(self.show)

    def eventFilter(self, obj, ev):
        if ev.type() == QEvent.ToolTip:
            self.clicked.emit()
        return False

    def _on_activated(self, reason):
        '''
        Slot for system tray icon activated signal.
        See http://doc.qt.io/qt-5/qsystemtrayicon.html

        @param reason Tray activation reason
        '''

        if reason == QSystemTrayIcon.Trigger:
            # This is usually when left mouse button clicked on tray icon
            self.clicked.emit()
        elif reason == QSystemTrayIcon.DoubleClick:
            self.double_clicked.emit()

    @property
    def menu(self):
        return self._tray.contextMenu()

    def set_tool_tip(self, tip):
        self._tray.setToolTip(tip)

    def show_tray_notification(self, text, title=""):
        if not title:
            title = tr('Pvtbox')
        # Convert strings to unicode
        if type(text) in (str, str):
            text = ensure_unicode(text)
        if type(title) in (str, str):
            title = ensure_unicode(title)

        logger.info("show_tray_notification: %s, title: %s", text, title)
        if self._tray.supportsMessages():
            self._tray.showMessage(title, text)
        else:
            logger.warning("tray does not supports messages")

    def request_to_user(
            self, dialog_id, text, buttons=("Yes", "No"), title="",
            close_button_index=-1, close_button_off=False, parent=None,
            on_clicked_cb=None,
            details=''):

        msg_box = QMessageBox(parent)
        # msg_box = QMessageBox()
        if not title:
            title = tr('Pvtbox')
        msg_box.setWindowTitle(title)
        msg_box.setText(str(text))

        pvtboxIcon = QIcon(':/images/icon.png')
        msg_box.setWindowIcon(pvtboxIcon)

        if details:
            msg_box.setDetailedText(details)

        if close_button_off:
            if get_platform() == 'Darwin':
                msg_box.setWindowFlags(Qt.Tool)
            else:
                msg_box.setWindowFlags(Qt.Dialog |
                                       Qt.CustomizeWindowHint |
                                       Qt.WindowTitleHint)
        msg_box.setAttribute(Qt.WA_MacFrameworkScaled)
        msg_box.setModal(True)

        buttons = list(buttons)
        for button in buttons:
            msg_box.addButton(button, QMessageBox.ActionRole)
        msg_box.show()
        msg_box.raise_()
        msg_box.exec_()
        try:
            button_index = buttons.index(msg_box.clickedButton().text())
        except (ValueError, AttributeError):
            button_index = -1
           # message box was closed with close button
            if len(buttons) == 1 and close_button_index == -1:
                # if only one button then call callback
                close_button_index = 0

            if len(buttons) > close_button_index >= 0:
                button_index = close_button_index

        if button_index >= 0 and callable(on_clicked_cb):
            on_clicked_cb(dialog_id, button_index)

    def update_status_icon(self, new_status, new_substatus):
        icon = self._icons[STATUS_DISCONNECTED] if new_status == STATUS_INIT \
            else self._icons[new_status]
        self._tray.setIcon(icon)
        tool_tip = self._statuses[new_status]
        if new_status == STATUS_IN_WORK and new_substatus == SUBSTATUS_SHARE:
            tool_tip = tr("Pvtbox downloading share...")
        self.set_tool_tip(tool_tip)
        self.show()

    def show(self):
        self._tray.setVisible(True)
        self._tray.show()

    def hide(self):
        if self._tray_show_timer.isActive():
            self._tray_show_timer.stop()
        self._tray.hide()

    def __del__(self):
        self._tray.removeEventFilter(self)
        self._tray.activated.disconnect()
        self.hide()