Exemplo n.º 1
0
 def quit(cls):
     """退出线程
     :param cls:
     """
     if hasattr(cls, '_thread'):
         cls._thread.quit()
         AppLog.info('login thread quit')
Exemplo n.º 2
0
    def listSubDir(self, pitem, path):
        """遍历子目录
        :param item:    上级Item
        :param path:    目录
        """
        paths = os.listdir(path)
        files = []
        for name in paths:
            spath = os.path.join(path, name)
            if not os.path.isfile(spath):
                continue
            spath = os.path.splitext(spath)
            if len(spath) == 0:
                continue
            if spath[1] == '.py' and spath[0].endswith('__init__') == False:
                files.append(name)

        # 已经存在的item
        existsItems = [pitem.child(i).text() for i in range(pitem.rowCount())]

        for name in files:
            if name in existsItems:
                continue
            file = os.path.join(path, name).replace('\\', '/')
            item = QStandardItem(name)
            # 添加自定义的数据
            item.setData(False, Constants.RoleRoot)       # 不是根目录
            item.setData(file, Constants.RolePath)
            try:
                item.setData(open(file, 'rb').read().decode(
                    errors='ignore'), Constants.RoleCode)
            except Exception as e:
                AppLog.warn(
                    'read file({}) code error: {}'.format(file, str(e)))
            pitem.appendRow(item)
Exemplo n.º 3
0
    def run(self):
        try:
            req = requests.get(
                UrlGetAppsByCategory.format(category=self.category,
                                            pageno=1,
                                            count=20,
                                            time=time()))
            content = req.json()
            errno = content.get('errno', 0)
            AppLog.debug('errno: %s', errno)
            AppLog.debug('msg: %s', content.get('msg', ''))
            if errno != 0:
                return

            content = content.get('data', {})
            AppLog.debug('total_count: %s', content.get('total_count', ''))
            AppLog.debug('total_page: %s', content.get('total_page', ''))
            items = content.get('list', [])

            for i, item in enumerate(items):
                title = item.get('title', '')
                url = item.get('image', None)
                if not url:
                    continue
                self.download(i, title, url)
                QThread.msleep(200)
                QThread.yieldCurrentThread()
        except Exception as e:
            AppLog.exception(e)
        Signals.pictureDownFinished.emit(self.widget)
Exemplo n.º 4
0
 def loadCursor(cls, widget, name='default.png'):
     # 加载光标
     path = cls.cursorPath(name)
     AppLog.info('cursorPath: {}'.format(path))
     if os.path.exists(path):
         # 设置自定义鼠标样式,并以0,0为原点
         widget.setCursor(QCursor(QPixmap(path), 0, 0))
Exemplo n.º 5
0
    def loadColourfulTheme(cls, color, widget=None, replaces={}):
        """基于当前设置主题颜色
        :param cls:
        :param color:        背景颜色
        :param widget:        指定控件
        """
        # 加载主题取样式
        path = cls.stylePath('Default')
        AppLog.info('stylePath: {}'.format(path))
        try:
            styleSheet = open(path, 'rb').read().decode(
                'utf-8', errors='ignore')
            # 需要替换部分样式
            colorstr = GradientUtils.styleSheetCode(color)
            if isinstance(color, QLinearGradient) or isinstance(color, QRadialGradient) or isinstance(color, QConicalGradient):
                color = color.stops()[0][1]
            # 替换name
            templates = StyleGradientTemplate
            for name, value in replaces.items():
                templates = templates.replace(name, value)

            styleSheet += templates.format(
                color.red(), color.green(), color.blue(), colorstr)
            widget = widget or QApplication.instance()
            widget.setStyleSheet(styleSheet)
        except Exception as e:
            AppLog.exception(e)
Exemplo n.º 6
0
 def renderReadme(self, path=''):
     """加载README.md并显示
     """
     path = path.replace('\\', '/')
     if not path:
         path = os.path.join(Constants.DirProjects, 'README.md')
         Constants.CurrentReadme = ''
     elif path.count('/') == 0:
         path = os.path.join(Constants.DirCurrent, path, 'README.md')
         Constants.CurrentReadme = path
     elif not path.endswith('README.md'):
         path = path + '/README.md'
         Constants.CurrentReadme = path
     if not os.path.exists(path):
         AppLog.debug('{} not exists'.format(path))
         self._runJs('updateText("");')
         return
     if not os.path.isfile(path):
         AppLog.warn('file {} not exists'.format(path))
         return
     Constants.DirCurrent = os.path.dirname(path).replace('\\', '/')
     AppLog.debug('DirCurrent change to: {}'.format(Constants.DirCurrent))
     AppLog.debug('render: {}'.format(path))
     Constants.CurrentReadme = path      # 记录打开的路径防止重复加载
     AppLog.debug('readme dir: {}'.format(Constants.DirCurrent))
     content = repr(open(path, 'rb').read().decode())
     self._runJs("updateText({});".format(content))
Exemplo n.º 7
0
 def _showWebMenu(self, pos):
     """显示网页右键菜单
     :param pos:            点击位置
     """
     hit = self.webViewContent.page().currentFrame().hitTestContent(pos)
     url = hit.linkUrl()
     if url.isValid():
         path = url.toLocalFile().strip().replace('\\', '/')
         names = path.split('Markdown/')
         if len(names) == 1:
             return
         path = os.path.abspath(os.path.join(
             Constants.DirCurrent, names[1]))
         AppLog.debug('path: {}'.format(path))
         AppLog.debug('isdir: {}'.format(os.path.isdir(path)))
         self._webviewactRun.setData(path)
         self._webviewactView.setData(path)
         self._webviewactFolder.setData(path)
         if os.path.exists(path) and os.path.isdir(path):
             self._webviewactRun.setVisible(False)
             self._webviewactView.setVisible(False)
             self._webviewactFolder.setVisible(True)
         elif os.path.exists(path) and os.path.isfile(path):
             self._webviewactRun.setVisible(True)
             self._webviewactView.setVisible(True)
             self._webviewactFolder.setVisible(True)
         self._webviewMenu.exec_(QCursor.pos())
Exemplo n.º 8
0
 def initCatalog(self):
     """初始化本地仓库结构树
     """
     AppLog.debug('')
     if not os.path.exists(Constants.DirProjects):
         return
     pitem = self._dmodel.invisibleRootItem()
     # 只遍历根目录
     for name in os.listdir(Constants.DirProjects):
         file = os.path.join(Constants.DirProjects, name).replace('\\', '/')
         if os.path.isfile(file):  # 跳过文件
             continue
         if name.startswith(
                 '.') or name == 'Donate' or name == 'Test':  # 不显示.开头的文件夹
             continue
         items = self.findItems(name)
         if items:
             item = items[0]
         else:
             item = QStandardItem(name)
             # 添加自定义的数据
             # 用于绘制进度条的item标识
             item.setData(True, Constants.RoleRoot)
             # 目录或者文件的绝对路径
             item.setData(
                 os.path.abspath(os.path.join(Constants.DirProjects, name)),
                 Constants.RolePath)
             pitem.appendRow(item)
         # 遍历子目录
         self.listSubDir(item, file)
     # 排序
     self._fmodel.sort(0, Qt.AscendingOrder)
Exemplo n.º 9
0
 def onLoginErrored(self, message):
     AppLog.debug('onLoginErrored')
     self._isLogin = False
     self.buttonLogin.showWaiting(False)
     self.setEnabled(True)
     AppLog.error(message)
     if message:
         self.labelNotice.setText(message)
Exemplo n.º 10
0
    def run(self):
        AppLog.info('start get all colourful')
        # 午夜巴黎
        mcolor = QLinearGradient(0, 0, self.width, self.height)
        mcolor.ex = 1
        mcolor.ey = 1
        mcolor.startColor = QColor(20, 179, 255, 255)
        mcolor.endColor = QColor(226, 14, 255, 255)
        mcolor.setColorAt(0, mcolor.startColor)
        mcolor.setColorAt(1, mcolor.endColor)
        # 樱草青葱
        pcolor = QLinearGradient(0, 0, self.width, self.height)
        pcolor.ex = 1
        pcolor.ey = 1
        pcolor.startColor = QColor(0, 173, 246, 255)
        pcolor.endColor = QColor(0, 234, 155, 255)
        pcolor.setColorAt(0, pcolor.startColor)
        pcolor.setColorAt(1, pcolor.endColor)
        # 秋日暖阳
        acolor = QLinearGradient(0, 0, self.width, self.height)
        acolor.ex = 1
        acolor.ey = 1
        acolor.startColor = QColor(255, 128, 27, 255)
        acolor.endColor = QColor(255, 0, 14, 255)
        acolor.setColorAt(0, acolor.startColor)
        acolor.setColorAt(1, acolor.endColor)

        defaults = splistList(
            [
                [self.tr('MidnightParis'), mcolor],  # 午夜巴黎
                [self.tr('PrimroseGreenOnion'), pcolor],  # 樱草青葱
                [self.tr('AutumnSun'), acolor],  # 秋日暖阳
                [self.tr('LightGray'),
                 QColor(236, 236, 236)],  # 淡灰色
                [self.tr('DarkBlack'),
                 QColor(33, 33, 33)],  # 深黑色
                [self.tr('BlueGreen'),
                 QColor(0, 190, 172)],  # 蓝绿色
                [self.tr('Orange'), QColor(255, 152, 0)],  # 橙色
                [self.tr('Brown'), QColor(140, 100, 80)],  # 咖啡色
                [self.tr('Green'), QColor(121, 190, 60)],  # 绿色
                [self.tr('Pink'), QColor(236, 98, 161)],  # 粉色
                [self.tr('Purple'), QColor(103, 58, 183)],  # 紫色
                [self.tr('Blue'), QColor(0, 188, 212)],  # 蓝色
                [self.tr('GreyBlue'),
                 QColor(80, 126, 164)],  # 蓝灰色
                [self.tr('Red'), QColor(244, 94, 99)],  # 红色
            ],
            5)

        for row, default in enumerate(defaults):
            for col, (name, color) in enumerate(default):
                Signals.colourfulItemAdded.emit(row, col, name, color)
                QThread.msleep(100)
                QThread.yieldCurrentThread()

        Signals.colourfulItemAddFinished.emit()
        AppLog.info('colourful thread end')
Exemplo n.º 11
0
 def _initLanguage(self):
     """加载国际化翻译
     """
     if QLocale.system().language() in (QLocale.China, QLocale.Chinese, QLocale.Taiwan, QLocale.HongKong):
         # 加载中文
         translator = QTranslator(self)
         translator.load('Resources/pyqtclient_zh_CN.qm')
         QApplication.instance().installTranslator(translator)
         AppLog.info('install local language')
Exemplo n.º 12
0
 def loadFont(cls):
     """加载字体
     """
     ThemeManager.ThemeName = Setting.value('theme', 'Default', str)
     # 加载主题中的字体
     path = cls.fontPath()
     AppLog.info('fontPath: {}'.format(path))
     if os.path.isfile(path):
         QFontDatabase.addApplicationFont(path)
Exemplo n.º 13
0
 def _doActView(self):
     """右键菜单查看代码
     """
     path = self.sender().data()
     try:
         code = open(path, 'rb').read().decode(errors='ignore')
         Signals.showCoded.emit(code)
     except Exception as e:
         AppLog.warn(str(e))
Exemplo n.º 14
0
 def onReadChannelFinished(self):
     process = self.sender()
     message = process.readAllStandardError().data().decode()
     if process.exitCode() != 0 and len(message.strip()) > 0:
         file = str(process.property('file'))
         reqfile = os.path.abspath(os.path.join(
             os.path.dirname(file), 'requirements.txt'))
         AppLog.debug('reqfile: {}'.format(reqfile))
         dialog = ErrorDialog(message, self, reqfile=reqfile)
         dialog.exec_()
Exemplo n.º 15
0
    def createRequest(self, op, originalReq, outgoingData):
        """创建请求
        :param op:           操作类型见http://doc.qt.io/qt-5/qnetworkaccessmanager.html#Operation-enum
        :param originalReq:  原始请求
        :param outgoingData: 输出数据
        """
        url = originalReq.url()
        surl = url.toString()
        AppLog.debug('access url: {}'.format(surl))

        if surl.endswith('Donate'):
            # 点击了打赏
            originalReq.setUrl(QUrl())
            return super(NetworkAccessManager,
                         self).createRequest(op, originalReq, outgoingData)
        elif surl.endswith('k=5QVVEdF'):
            # 点击了QQ群链接
            webbrowser.open(Constants.UrlGroup)
            originalReq.setUrl(QUrl())
            return super(NetworkAccessManager,
                         self).createRequest(op, originalReq, outgoingData)

        if url.scheme() == 'tencent':
            # 调用tx的app
            webbrowser.open(surl)
            originalReq.setUrl(QUrl())
        elif url.scheme() == 'file':
            # 本地文件,比如一些图片文件等
            names = surl.split('Markdown/')
            if len(names) > 1:
                rname = names[1]
                path = os.path.join(Constants.DirCurrent,
                                    rname).replace('\\', '/')
                if os.path.exists(path) and os.path.isfile(path):
                    if rname[-3:] == '.py':
                        originalReq.setUrl(QUrl())
                        # 运行py文件
                        Signals.runExampled.emit(path)
                    else:
                        originalReq.setUrl(QUrl.fromLocalFile(path))
                elif os.path.exists(path) and os.path.isdir(path):
                    if rname.count('/') == 0:
                        # 跳转到左侧目录树
                        originalReq.setUrl(QUrl())
                        Signals.itemJumped.emit(rname)
        else:
            # 只加载文件,不加载其它网页
            if not mimetypes.guess_type(url.fileName())[0]:
                originalReq.setUrl(QUrl())
                # 调用系统打开网页
                webbrowser.open_new_tab(surl)

        return super(NetworkAccessManager,
                     self).createRequest(op, originalReq, outgoingData)
Exemplo n.º 16
0
 def onDoubleClicked(self, modelIndex):
     """Item双击
     :param modelIndex:        此处是代理模型中的QModelIndex, 并不是真实的
     """
     root = modelIndex.data(Constants.RoleRoot)
     path = modelIndex.data(Constants.RolePath)
     AppLog.debug('is root: {}'.format(root))
     AppLog.debug('path: {}'.format(path))
     if not root and os.path.isfile(path):
         # 运行代码
         Signals.runExampled.emit(path)
Exemplo n.º 17
0
 def start(cls, parent=None):
     """启动自动更新线程
     :param cls:
     """
     cls._thread = QThread(parent)
     cls._worker = UpgradeThread()
     cls._worker.moveToThread(cls._thread)
     cls._thread.started.connect(cls._worker.run)
     cls._thread.finished.connect(cls._worker.deleteLater)
     cls._thread.start()
     AppLog.info('update thread started')
Exemplo n.º 18
0
 def loadCursor(cls, widget, name='default.png'):
     # 加载光标
     path = cls.cursorPath(name)
     if path in ThemeManager.Cursors:
         widget.setCursor(ThemeManager.Cursors[path])
         return
     AppLog.info('cursorPath: {}'.format(path))
     if os.path.exists(path):
         # 设置自定义鼠标样式,并以0,0为原点
         cur = QCursor(QPixmap(path), 0, 0)
         ThemeManager.Cursors[path] = cur
         widget.setCursor(cur)
Exemplo n.º 19
0
 def start(cls, account, password, parent=None):
     """启动登录线程
     :param cls:
     :param account:        账号
     :param password:       密码
     """
     cls._thread = QThread(parent)
     cls._worker = LoginThread(account, password)
     cls._worker.moveToThread(cls._thread)
     cls._thread.started.connect(cls._worker.run)
     cls._thread.finished.connect(cls._worker.deleteLater)
     cls._thread.start()
     AppLog.info('login thread started')
Exemplo n.º 20
0
 def run(self):
     show = True
     try:
         req = requests.get(self.Url)
         AppLog.info(req.text)
         if req.status_code != 200:
             AppLog.info('update thread end')
             UpgradeThread.quit()
             return
         content = req.json()
         for version, text in content:
             if Version.version < version:
                 if show:
                     Signals.updateDialogShowed.emit()
                     QThread.msleep(1000)
                 show = False
                 Signals.updateTextChanged.emit(
                     str(Version.version), str(version), text)
                 self.download(Constants.UpgradeFile.format(
                     version), self.ZipUrl.format(version))
         Signals.updateFinished.emit(self.tr('update completed'))
     except Exception as e:
         Signals.updateFinished.emit(
             self.tr('update failed: {}').format(str(e)))
         AppLog.exception(e)
     AppLog.info('update thread end')
     UpgradeThread.quit()
Exemplo n.º 21
0
 def start(cls, width, height, parent=None):
     """启动线程
     :param cls:
     :param width:
     :param height:
     :param parent:
     """
     cls._thread = QThread(parent)
     cls._worker = ColourfulThread(width, height)
     cls._worker.moveToThread(cls._thread)
     cls._thread.started.connect(cls._worker.run)
     cls._thread.finished.connect(cls._worker.deleteLater)
     cls._thread.start()
     AppLog.info('colourful thread started')
Exemplo n.º 22
0
 def download(self, index, title, url):
     try:
         dirPath = os.path.join(DirWallpaper, self.category)
         os.makedirs(dirPath, exist_ok=True)
         path = os.path.join(dirPath, os.path.basename(url))
         if os.path.exists(path) and os.path.isfile(path):
             Signals.pictureItemAdded.emit(self.widget, index, title, path)
             return
         req = requests.get(url, headers=Headers)
         if req.status_code == 200:
             with open(path, 'wb') as fp:
                 fp.write(req.content)
             Signals.pictureItemAdded.emit(self.widget, index, title, path)
     except Exception as e:
         AppLog.exception(e)
Exemplo n.º 23
0
    def run(self):
        AppLog.info('start get all theme')

        defaults = [[p.parent.name, str(p)]
                    for p in Path(DirThemes).rglob('style.qss')]

        defaults = splistList(defaults, 5)

        for row, default in enumerate(defaults):
            for col, (name, path) in enumerate(default):
                Signals.themeItemAdded.emit(row, col, name, path)
                QThread.msleep(100)
                QThread.yieldCurrentThread()

        Signals.themeItemAddFinished.emit()
        AppLog.info('theme thread end')
Exemplo n.º 24
0
 def on_lineEditAccount_textChanged(self, account):
     """输入框编辑完成信号,寻找头像文件是否存在
     """
     if account not in self._accounts:  # 不存在
         return
     # 填充密码
     try:
         self.lineEditPassword.setText(base64.b85decode(
             self._accounts[account][1].encode()).decode())
     except Exception as e:
         self.lineEditPassword.setText('')
         AppLog.exception(e)
     # 更新头像
     path = os.path.join(Constants.ImageDir, self._accounts[account][0]).replace(
         '\\', '/') + '.jpg'
     if os.path.exists(path) and self.buttonHead.image != path:
         # 更换头像
         self.buttonHead.image = path
Exemplo n.º 25
0
 def _initUi(self):
     """初始UI"""
     self.setupUi(self)
     # 隐藏还原按钮
     self.buttonNormal.setVisible(False)
     # 隐藏目录树的滑动条
     self.treeViewCatalogs.verticalScrollBar().setVisible(False)
     # 加载鼠标样式
     ThemeManager.loadCursor(self.widgetMain)
     ThemeManager.setPointerCursors([
         self.buttonHead,            # 主界面头像
         self.buttonClear,           # 主界面清空按钮
         self.buttonGithub,          # Github按钮
         self.buttonQQ,              # QQ按钮
         self.buttonGroup,           # 群按钮
         self.buttonBackToUp,        # 返回顶部按钮
         self.buttonHome             # 显示主页readme
     ])
     # 安装事件过滤器用于还原鼠标样式
     self.widgetMain.installEventFilter(self)
     # 绑定返回顶部提示框
     ToolTip.bind(self.buttonBackToUp)
     ToolTip.bind(self.buttonHome)
     # 头像提示控件
     ToolTip.bind(self.buttonHead)
     # 加载主题
     colourful = Setting.value('colourful')
     picture = Setting.value('picture', '', str)
     AppLog.debug('colourful: %s', str(colourful))
     AppLog.debug('picture: %s', picture)
     if picture:
         ThemeManager.loadFont()
         ThemeManager.loadPictureTheme(picture)
     elif colourful:
         ThemeManager.loadFont()
         if isinstance(picture, QColor):
             ThemeManager.loadColourfulTheme(colourful)
         else:
             # json数据转渐变
             ThemeManager.loadColourfulTheme(
                 GradientUtils.toGradient(colourful))
     else:
         ThemeManager.loadTheme()
Exemplo n.º 26
0
 def onClicked(self, modelIndex):
     """Item单击
     :param modelIndex:        此处是代理模型中的QModelIndex, 并不是真实的
     """
     root = modelIndex.data(Constants.RoleRoot)
     path = modelIndex.data(Constants.RolePath)
     code = modelIndex.data(Constants.RoleCode)
     AppLog.debug('is root: {}'.format(root))
     AppLog.debug('path: {}'.format(path))
     if not root and os.path.isfile(path) and code:
         # 右侧显示代码
         Signals.showCoded.emit(code)
     if root and os.path.isdir(path):
         if self.isExpanded(modelIndex):
             self.collapse(modelIndex)
         else:
             self.expand(modelIndex)
         # 显示readme
         Signals.showReadmed.emit(os.path.join(path, 'README.md'))
Exemplo n.º 27
0
 def onLoginSuccessed(self, uid, name):
     AppLog.debug('onLoginSuccessed')
     self._isLogin = False
     self.buttonLogin.showWaiting(False)
     self.setEnabled(True)
     # 用账号密码实例化github访问对象
     account = self.lineEditAccount.text().strip()
     password = self.lineEditPassword.text().strip()
     Constants._Account = account
     Constants._Password = password
     Constants._Username = name
     # 储存账号密码
     Setting.setValue('account', account)
     if account not in self._accounts:
         # 更新账号数组
         self._accounts[account] = [
             uid, base64.b85encode(password.encode()).decode()]
         Setting.setValue('accounts', self._accounts)
     self.accept()
Exemplo n.º 28
0
    def loadPictureTheme(cls, image=None, widget=None, replaces={}):
        """设置图片背景的主题
        :param cls:
        :param image:         背景图片
        :param widget:        指定控件
        """
        # 加载主题取样式
        path = cls.stylePath('Default')
        AppLog.info('stylePath: {}'.format(path))
        try:
            styleSheet = open(path, 'rb').read().decode(
                'utf-8', errors='ignore')
            # 需要替换部分样式
            if image and os.path.isfile(image):
                # 获取图片主色调
                color_thief = ColorThief(image)
                color = color_thief.get_color()
                AppLog.info('dominant color: {}'.format(str(color)))

                # 替换name
                templates = StylePictureTemplate
                for name, value in replaces.items():
                    templates = templates.replace(name, value)

                styleSheet += templates.format(os.path.abspath(
                    image).replace('\\', '/')) + StyleColorTemplate.format(*color)
            widget = widget or QApplication.instance()
            widget.setStyleSheet(styleSheet)
        except Exception as e:
            AppLog.exception(e)
Exemplo n.º 29
0
 def loadTheme(cls):
     """根据配置加载主题
     :param cls:
     :param parent:
     """
     cls.ThemeName = Setting.value('theme', 'Default', str)
     # 加载主题中的字体
     path = cls.fontPath()
     AppLog.info('fontPath: {}'.format(path))
     if os.path.exists(path):
         QFontDatabase.addApplicationFont(path)
     # 加载主题取样式
     path = cls.stylePath()
     AppLog.info('stylePath: {}'.format(path))
     try:
         QApplication.instance().setStyleSheet(
             open(path, 'rb').read().decode('utf-8', errors='ignore'))
     except Exception as e:
         AppLog.error(str(e))
Exemplo n.º 30
0
 def download(self, file, url):
     AppLog.debug('start download {}'.format(url))
     with closing(requests.get(url, stream=True)) as response:
         # 单次请求最大值
         chunk_size = 1024
         # 内容体总大小
         content_size = int(response.headers['content-length'])
         data_count = 0
         Signals.updateProgressChanged.emit(0, 0, content_size)
         AppLog.debug('content_size: {}'.format(content_size))
         with open(file, 'wb') as fp:
             for data in response.iter_content(chunk_size=chunk_size):
                 fp.write(data)
                 data_count = data_count + len(data)
                 if content_size > 0:
                     Signals.updateProgressChanged.emit(
                         data_count, 0, content_size)
         # 解压
         self.unzip(file)
     AppLog.debug('download {} end'.format(file))