コード例 #1
0
ファイル: webbuffer.py プロジェクト: voloyev/webmacs
 def url(self):
     if self.__delay_loading_url:
         return self.__delay_loading_url.url
     return QWebEnginePage.url(self)
コード例 #2
0
class Umbrella(QMainWindow, Ui_MainWindow):
    def __init__(self):
        super().__init__()

        self.init_my_location()
        self.setupUi(self)  # 초기화
        # self.url = "http://192.168.0.3:8080/umbrella"
        self.url = "http://localhost:8080/umbrella.html"
        self.webEngineView.load(QUrl(self.url))
        self.page = QWebEnginePage()
        self.page.setUrl(QUrl(self.url))
        self.page.setView(self.webEngineView)
        # self.webEngineView2.load(QUrl("http://ncov.mohw.go.kr/bdBoardList_Real.do?brdId=1&brdGubun=11&ncvContSeq=&contSeq=&board_id=&gubun="))

        self.appLoaded = False
        chrome_option = Options()
        chrome_option.add_argument("--headless")
        chrome_option.add_argument("--mute-audio")
        self.browser = webdriver.Chrome(
            chrome_options=chrome_option,
            executable_path="resources/chromedriver.exe")
        self.browser.get(self.url)
        self.user_uuid = uuid.uuid4()
        self.runner = Runner(self)
        self.dc = DataCollector(self)
        self.dm = DataManager(self)
        self.itemList = []
        self.rowList = []
        self.dataChecker = 0

        # self.webEngineView2.load(QUrl(self.dc.html_test()))

        self.initSignal()
        self.timeSeries = self.dc.get_timeseries()
        self.comboBox.addItem("-----")
        for i in sorted(self.timeSeries.keys()):
            self.comboBox.addItem(i)

        #테트리스
        # self.tboard = Board(self.page_3)
        # self.tboard.msg2Statusbar.connect(self.test_1)
        # self.tboard.start()
        # self.tboard.setStyleSheet("background-color:#ffffff")
        # self.tboard.setGeometry(460,0,460,820)

    def test_1(self, msg):
        if msg == "Game over":
            self.tboard.initBoard()
            self.tboard.start()

    def initSignal(self):
        #page 변환
        self.pushButton_3.clicked.connect(
            lambda: self.stackedWidget.setCurrentIndex(1))
        self.pushButton_4.clicked.connect(
            lambda: self.stackedWidget.setCurrentIndex(1))
        self.intro_button.clicked.connect(
            lambda: self.stackedWidget.setCurrentIndex(1))
        self.pushButton_5.clicked.connect(
            lambda: self.stackedWidget.setCurrentIndex(1))
        self.pushButton__image.clicked.connect(
            lambda: self.stackedWidget.setCurrentIndex(0))
        self.pushButton__image2.clicked.connect(
            lambda: self.stackedWidget.setCurrentIndex(0))
        self.pushButton.clicked.connect(self.runner.map_removeMarkers)
        #intro 데이터 입력
        self.lineEdit.returnPressed.connect(
            lambda: self.runner.search(self.lineEdit.text().strip()))
        self.pushButton.clicked.connect(
            lambda: self.runner.search(self.lineEdit.text().strip()))
        self.page.loadFinished.connect(lambda: self.runner.setMap(
            self.my_location_lat, self.my_location_lng))
        self.pushButton2.clicked.connect(self.mark_around)
        self.pushButton3.clicked.connect(lambda: self.runner.setMap(
            self.my_location_lat, self.my_location_lng))
        self.page.urlChanged.connect(self.setButton)
        self.listWidget.itemActivated.connect(self.activateRow)
        self.listWidget.itemClicked.connect(self.rowClicked)
        self.lineEdit.setText(
            self.runner.coord_to_address(self.my_location_lat,
                                         self.my_location_lng, 0))

        self.radio1.clicked.connect(lambda: self.setDataChecker(0))
        self.radio2.clicked.connect(lambda: self.setDataChecker(2))
        self.radio3.clicked.connect(lambda: self.setDataChecker(3))
        self.radio4.clicked.connect(lambda: self.setDataChecker(4))

        self.widget_1.pressed.connect(self.view_graph)
        self.widget_2.pressed.connect(self.view_graph)
        self.widget_3.pressed.connect(self.view_graph)
        self.widget_4.pressed.connect(self.view_graph)

        self.comboBox.currentTextChanged.connect(self.show_timeSeries)

    def show_timeSeries(self, nat):
        if nat in self.timeSeries.keys():
            self.dm.graph_timeseries(self.timeSeries.get(nat))

    def view_graph(self):
        self.stackedWidget.setCurrentIndex(2)

    def mark_around(self):
        print("markaround")
        self.remove_list()
        if not self.page.url().toString().strip().startswith(self.url):
            self.page.load(QUrl(self.url))
            return
        self.runner.map_removeMarkers()
        try:
            lat, lng = self.runner.map_getCenter()
        except:
            print("mark_arount exception")
            return
        data = self.dc.get_data_by_latlng(lat, lng, 1000)
        self.runner.marking(data)
        self.show_list(data)
        self.lineEdit.setText(self.runner.coord_to_address(lat, lng, 0))

    def setDataChecker(self, num):
        self.dataChecker = num

    #표지
    def intro(self):
        data = self.dc.A()
        #Text
        self.dm.show_intro_list(data)
        #그래프
        self.dm.intro_graph(data)

    def init_my_location(self):
        url = 'https://www.googleapis.com/geolocation/v1/geolocate?key=AIzaSyDQKxbTt0MrFNH85kTJXzickMD5s88UVaI'
        data = {
            'considerIp': True,
        }
        result = requests.post(url, data)
        my_location = json.loads(result.text)
        self.my_location_lat = str(my_location.get('location').get('lat'))
        self.my_location_lng = str(my_location.get('location').get('lng'))

    def setButton(self):
        if self.page.url().toString().strip().startswith(
                "http://localhost:8080/umbrella"):
            self.pushButton2.setText("판매처 탐색")
        else:
            self.pushButton2.setText("지도 새로고침")

    def show_list(self, data):
        remainP = [
            '100개 이상', '30개 이상 100개 미만', '2개 이상 30개 미만', '1개 이하', '판매중지'
        ]
        for i in range(len(data)):
            item = QListWidgetItem(self.listWidget)
            row = Item(data[i])
            rs = data[i].get('remain_stat')
            if rs == None:
                row.remain_stat.setStyleSheet('color:red')
            elif remainP.index(rs) <= 1:
                row.remain_stat.setStyleSheet('color:green')
            elif remainP.index(rs) == 2:
                row.remain_stat.setStyleSheet('color:orange')
            else:
                row.remain_stat.setStyleSheet('color:red')
            item.setWhatsThis(str(i))
            item.setSizeHint(row.sizeHint())
            self.listWidget.setItemWidget(item, row)
            self.listWidget.addItem(item)
            self.itemList.append(item)
            self.rowList.append(row)

    def remove_list(self):
        for i in range(len(self.itemList)):
            self.itemList[i].setHidden(True)
        self.itemList = []
        self.rowList = []

    def activateRow(self, row):
        self.runner.setMap(self.rowList[int(row.whatsThis())].lat,
                           self.rowList[int(row.whatsThis())].lng)
        self.runner.info_open(self.rowList[int(row.whatsThis())].code)

    def rowClicked(self, row):
        self.runner.info_close_all()
        self.runner.info_open(self.rowList[int(row.whatsThis())].code)
コード例 #3
0
class TeamtoolBrowser(QWidget, design.Ui_Form):
    def __init__(self, parent=None):
        super(TeamtoolBrowser, self).__init__(parent)
        self.setupUi(self)
        self.browser = QWebEngineView()
        self.profile = QWebEngineProfile("somestorage", self.browser)
        self.webpage = QWebEnginePage(self.profile, self.browser)
        self.browser.setPage(self.webpage)
        self.initUI()
        self.eventUI()

    def eventUI(self):
        self.btnRefresh.clicked.connect(lambda: self.browse(refresh=True))
        self.codeEdit.textChanged.connect(lambda: self.browse(offline=True))
        self.fileView.doubleClicked.connect(self.selectFile)
        self.urlBar.returnPressed.connect(lambda: self.browse())
        self.webpage.loadStarted.connect(lambda: self.startLoading())
        self.webpage.loadFinished.connect(lambda: self.onLoadFinished())
        self.btnPrev.clicked.connect(lambda: self.prev())
        self.btnNext.clicked.connect(lambda: self.next())

    def prev(self):
        ''' History: go back '''
        self.webpage.page().triggerAction(QWebEnginePage.Back)
        self.urlBar.setText(self.webpage.url().toString())

    def next(self):
        ''' History: move forward '''
        self.webpage.page().triggerAction(QWebEnginePage.Forward)
        self.urlBar.setText(self.webpage.url().toString())

    def startLoading(self):
        ''' When page starts to load '''
        self.loadingAnimation.start()
        self.labelLoading.setVisible(True)

    def onLoadFinished(self):
        ''' When page has finished to load '''
        self.loadingAnimation.stop()
        self.labelLoading.setVisible(False)

        if self.webpage.history().canGoBack():
            self.btnPrev.setEnabled(True)
        else:
            self.btnPrev.setEnabled(False)

        if self.webpage.history().canGoForward():
            self.btnNext.setEnabled(True)
        else:
            self.btnNext.setEnabled(False)
        self.urlBar.setText(self.webpage.url().toString())

    def browse(self, refresh=False, offline=False):
        ''' Browse to urlBar URL or render a text/html string '''

        # Offline mode, load plaintext html code
        if offline:
            self.webpage.setHtml(self.codeEdit.toPlainText())
            return
        # Online mode
        if refresh:
            url = self.browser.reload()
            return
        url = self.urlBar.text()
        if not re.match('http://|https://', url, re.I):
            url = f'http://{url}'
        # print('===============>', os.path.join('statics/button', 'lock-ssl.png'), QUrl(url).scheme())
        if QUrl(url).scheme() == 'https':
            print('HTTPS')
            self.httpsicon.setPixmap(self.pixmap_ssl)
        else:
            print('HTTP')
            self.httpsicon.setPixmap(self.pixmap_nossl)
        print(f'Browse to this URL: {url}')
        if isinstance(url, str) and url != '':
            self.webpage.setUrl(QUrl(url))

    def selectFile(self, index):
        ''' Select a file in file system '''
        if not self.fileModel.isDir(index) and index.data().lower().endswith(
            ('.html', '.txt')):
            with open(self.fileModel.fileInfo(index).absoluteFilePath(),
                      'r',
                      encoding='utf-8') as f:
                self.webpage.setHtml(f.read())
        else:
            print('Can not read this file...')

    def initUI(self):
        ''' Configuration of widgets '''
        self.gLayoutBrowser.addWidget(self.browser)
        self.loadingAnimation = QMovie('loading.gif')
        self.loadingAnimation.setScaledSize(QtCore.QSize(24, 24))
        self.labelLoading.setMovie(self.loadingAnimation)
        self.labelLoading.setVisible(False)

        self.fileModel = QFileSystemModel()
        self.fileModel.setRootPath(QtCore.QDir.currentPath())
        self.fileView.setModel(self.fileModel)
        self.fileModel.setNameFilters(('.html', '.txt'))
        self.fileView.setColumnWidth(0, 170)
        self.fileView.setColumnWidth(1, 50)
        self.fileView.setColumnWidth(2, 50)

        self.splitterMain.setStretchFactor(1, 3)
        self.splitterSidebar.setStretchFactor(0, 1)

        self.urlBar.setPlaceholderText('Tapez ici votre URL')
        self.loadPage(online=True)
        self.pixmap_ssl = QPixmap(os.path.join('static/button',
                                               'lock-ssl.png'))
        self.pixmap_nossl = QPixmap(
            os.path.join('static/button', 'lock-nossl.png'))
        print(f'w: {self.pixmap_ssl.width()} | h: {self.pixmap_ssl.height()}')
        self.httpsicon.setPixmap(self.pixmap_nossl)

        self.setGeometry(300, 300, 1280, 720)
        self.updateTitle()

        # self.codeEdit = TxtInput([QPushButton('Hello'), QPushButton('World')])
        # self.editor = CustomTextEditor(txtInput=self.codeEdit)
        self.codeEdit = QPlainTextEdit()
        self.splitterSidebar.addWidget(self.codeEdit)

        self.show()

    def loadPage(self, online=True):
        ''' Load home page '''
        if online:
            self.browser.setUrl(QUrl("https://www.google.com"))
            return
        with open('home.html', 'r') as f:
            html = f.read()
            self.browser.setHtml(html)

    def updateTitle(self):
        title = self.browser.page().title()
        self.setWindowTitle(f'{title}')
コード例 #4
0
class AuthWidget(QWebEngineView):

    def __init__(self, parent, config=None, credential_file=None, cookie_persistence=False, log_level=logging.INFO):
        super(AuthWidget, self).__init__(parent)

        self.parent = parent
        self.config = None
        self.config_file = DEFAULT_CONFIG_FILE
        self.credential = DEFAULT_CREDENTIAL
        self.credential_file = None
        self.cookie_file = None
        self.cookie_jar = None
        self.auth_url = None
        self.authn_session = None
        self.authn_session_page = None
        self.authn_cookie_name = None
        self.authn_expires = time.time()
        self._success_callback = None
        self._failure_callback = None
        self._session = requests.session()
        self.token = None
        self.default_profile = QWebEngineProfile("deriva-auth", self)
        self.private_profile = QWebEngineProfile(self)

        logging.getLogger().setLevel(log_level)
        info = "%s v%s [Python: %s (PyQt: %s), %s]" % (
            self.__class__.__name__, get_installed_version(VERSION),
            platform.python_version(), PYQT_VERSION_STR, platform.platform(aliased=True))
        logging.info("Initializing authorization provider: %s" % info)
        self.cookie_persistence = cookie_persistence
        self._timer = QTimer(self)
        self._timer.timeout.connect(self._onTimerFired)
        self.configure(config, credential_file)

    def configure(self, config, credential_file):
        self.config = config if config else read_config(self.config_file, create_default=True, default=DEFAULT_CONFIG)
        self.credential_file = credential_file
        host = self.config.get("host")
        if not host:
            self.set_current_html(ERROR_HTML % "Could not locate hostname parameter in configuration.")
            return
        self.auth_url = QUrl()
        self.auth_url.setScheme(config.get("protocol", "https"))
        self.auth_url.setHost(host)
        if config.get("port") is not None:
            self.auth_url.setPort(config["port"])
        self.authn_cookie_name = self.config.get("cookie_name", "webauthn")

        self.cookie_file = DEFAULT_SESSION_CONFIG.get("cookie_jar")
        self.cookie_jar = load_cookies_from_file(self.cookie_file)

        retries = Retry(connect=DEFAULT_SESSION_CONFIG['retry_connect'],
                        read=DEFAULT_SESSION_CONFIG['retry_read'],
                        backoff_factor=DEFAULT_SESSION_CONFIG['retry_backoff_factor'],
                        status_forcelist=DEFAULT_SESSION_CONFIG['retry_status_forcelist'])

        self._session.mount(self.auth_url.toString() + '/',
                            HTTPAdapter(max_retries=retries))

    def set_current_html(self, html):
        page = QWebEnginePage(self.parent)
        page.setHtml(html)
        self.setPage(page)
        self.update()
        qApp.processEvents()

    def authenticated(self):
        if self.authn_session is None:
            return False

        now = time.time()
        if now >= self.authn_expires:
            return False

        return True

    def login(self):
        if not (self.auth_url and (self.auth_url.host() and self.auth_url.scheme())):
            logging.error("Missing or invalid hostname parameter in configuration.")
            return
        logging.info("Authenticating with host: %s" % self.auth_url.toString())
        qApp.setOverrideCursor(Qt.WaitCursor)
        self._cleanup()
        self.authn_session_page = QWebEnginePage(self.private_profile, self.parent) \
            if not self.cookie_persistence else QWebEnginePage(self.default_profile, self.parent)
        self.authn_session_page.profile().setPersistentCookiesPolicy(
            QWebEngineProfile.ForcePersistentCookies if self.cookie_persistence else
            QWebEngineProfile.NoPersistentCookies)
        if self.cookie_persistence:
            logging.debug("QTWebEngine persistent storage located at: %s" %
                          self.authn_session_page.profile().persistentStoragePath())
        self.authn_session_page.profile().cookieStore().cookieAdded.connect(self._onCookieAdded)
        self.authn_session_page.profile().cookieStore().cookieRemoved.connect(self._onCookieRemoved)
        self.authn_session_page.loadProgress.connect(self._onLoadProgress)
        self.authn_session_page.loadFinished.connect(self._onLoadFinished)

        self.authn_session_page.setUrl(QUrl(self.auth_url.toString() + "/authn/preauth"))
        self.setPage(self.authn_session_page)

    def logout(self, delete_cookies=False):
        if not (self.auth_url and (self.auth_url.host() and self.auth_url.scheme())):
            return
        if self.authenticated():
            try:
                logging.info("Logging out of host: %s" % self.auth_url.toString())
                if delete_cookies and self.cookie_persistence:
                    self.authn_session_page.profile().cookieStore().deleteAllCookies()
                self._session.delete(self.auth_url.toString() + "/authn/session")
                if self.credential_file:
                    creds = read_credential(self.credential_file, create_default=True)
                    host = self.auth_url.host()
                    if creds.get(host):
                        del creds[host]
                    write_credential(self.credential_file, creds)
            except Exception as e:
                logging.warning("Logout error: %s" % format_exception(e))
        self._cleanup()

    def setSuccessCallback(self, callback=None):
        self._success_callback = callback

    def setFailureCallback(self, callback=None):
        self._failure_callback = callback

    def setStatus(self, message):
        if self.window().statusBar is not None:
            self.window().statusBar().showMessage(message)

    def _execSuccessCallback(self):
        if self._success_callback:
            self._success_callback(host=self.auth_url.host(), credential=self.credential)

    def _execFailureCallback(self, message):
        if self._failure_callback:
            self._failure_callback(host=self.auth_url.host(), message=message)

    def _onTimerFired(self):
        if not self.authenticated():
            self.authn_session = None
            return
        resp = self._session.put(self.auth_url.toString() + "/authn/session")
        seconds_remaining = self.authn_session['seconds_remaining']
        self.authn_expires = time.time() + seconds_remaining + 1
        if resp.ok:
            logging.trace("webauthn session:\n%s\n", resp.json())
            logging.info("Session refreshed for: %s" % self.auth_url.host())
        else:
            logging.warning(
                "Unable to refresh session for: %s. Server responded: %s" %
                (self.auth_url.host(),
                 str.format("%s %s: %s" % (resp.status_code, resp.reason, resp.content.decode()))))

    def _onSessionContent(self, content):
        try:
            qApp.restoreOverrideCursor()
            self.set_current_html(SUCCESS_HTML)
            try:
                self.authn_session = json.loads(content)
            except json.JSONDecodeError:
                raise RuntimeError("Unable to parse response from server: %s" % content)
            seconds_remaining = self.authn_session['seconds_remaining']
            if not self._timer.isActive():
                interval = seconds_remaining // 2
                logging.info("Authentication successful for [%s]: credential refresh in %d seconds." %
                             (self.auth_url.toString(), interval))
                self._timer.start(interval * 1000)
            self.authn_expires = time.time() + seconds_remaining + 1
            logging.trace("webauthn session:\n%s\n", json.dumps(self.authn_session, indent=2))
            QTimer.singleShot(100, self._execSuccessCallback)
        except (ValueError, Exception) as e:
            error = format_exception(e)
            logging.error(error)
            self.set_current_html(ERROR_HTML % content)
            self._execFailureCallback(error)

    def _onPreAuthContent(self, content):
        try:
            if not content:
                logging.debug("no preauth content")
                return
            preauth = json.loads(content)
            logging.trace("webauthn preauth:\n%s\n", json.dumps(preauth, indent=2))
            qApp.setOverrideCursor(Qt.WaitCursor)
            self.authn_session_page.setUrl(QUrl(preauth["redirect_url"]))
        except (ValueError, Exception) as e:
            logging.error(format_exception(e))
            self.set_current_html(ERROR_HTML % content)

    def _onLoadFinished(self, result):
        qApp.restoreOverrideCursor()
        qApp.processEvents()
        if not result:
            self.setPage(self.authn_session_page)
            logging.debug("Page load error: %s" % self.authn_session_page.url().toDisplayString())
            return
        self.set_current_html(DEFAULT_HTML % self.auth_url.host())
        path = self.authn_session_page.url().path()
        if path == "/authn/preauth":
            self.authn_session_page.toPlainText(self._onPreAuthContent)
        elif path == "/authn/session":
            self.authn_session_page.toPlainText(self._onSessionContent)
        else:
            if self.page() != self.authn_session_page:
                self.page().deleteLater()
                self.setPage(self.authn_session_page)

    def _onLoadProgress(self, progress):
        self.setStatus("Loading page: %s [%d%%]" % (self.page().url().host(), progress))

    def _onCookieAdded(self, cookie):
        cookie_str = str(cookie.toRawForm(QNetworkCookie.NameAndValueOnly), encoding='utf-8')
        cookie_name = str(cookie.name(), encoding='utf-8')
        cookie_val = str(cookie.value(), encoding='utf-8')
        if (cookie_name == self.authn_cookie_name) and (cookie.domain() == self.config.get("host")):
            logging.trace("%s cookie added:\n\n%s\n\n" % (self.authn_cookie_name, cookie_str))
            self.credential["cookie"] = "%s=%s" % (self.authn_cookie_name, cookie_val)
            host = self.auth_url.host()
            cred_entry = dict()
            cred_entry[host] = self.credential
            if self.credential_file:
                creds = read_credential(self.credential_file, create_default=True)
                creds.update(cred_entry)
                write_credential(self.credential_file, creds)
            self.token = cookie_val
            self._session.cookies.set(self.authn_cookie_name, cookie_val, domain=host, path='/')
            if self.cookie_jar is not None:
                self.cookie_jar.set_cookie(
                    create_cookie(self.authn_cookie_name,
                                  cookie_val,
                                  domain=host,
                                  path='/',
                                  expires=0,
                                  discard=False,
                                  secure=True))
                for path in self.config.get("cookie_jars", DEFAULT_CONFIG["cookie_jars"]):
                    path_dir = os.path.dirname(path)
                    if os.path.isdir(path_dir):
                        logging.debug("Saving cookie jar to: %s" % path)
                        self.cookie_jar.save(path, ignore_discard=True, ignore_expires=True)
                    else:
                        logging.debug("Cookie jar save path [%s] does not exist." % path_dir)

    def _onCookieRemoved(self, cookie):
        cookie_str = str(cookie.toRawForm(QNetworkCookie.NameAndValueOnly), encoding='utf-8')
        cookie_name = str(cookie.name(), encoding='utf-8')
        if cookie_name == self.authn_cookie_name and cookie.domain() == self.url().host():
            logging.trace("%s cookie removed:\n\n%s\n\n" % (self.authn_cookie_name, cookie_str))
            if self.cookie_jar:
                self.cookie_jar.clear(cookie_name, path=cookie.path(), domain=cookie.domain())

    def _cleanup(self):
        self._timer.stop()
        self.token = None
        self.authn_session = None
        self.authn_expires = time.time()
        if self.authn_session_page:
            self.authn_session_page.loadProgress.disconnect(self._onLoadProgress)
            self.authn_session_page.loadFinished.disconnect(self._onLoadFinished)
            self.authn_session_page.profile().cookieStore().cookieAdded.disconnect(self._onCookieAdded)
            self.authn_session_page.profile().cookieStore().cookieRemoved.disconnect(self._onCookieRemoved)
            self.authn_session_page.deleteLater()
            self.authn_session_page = None
コード例 #5
0
class Umbrella(QMainWindow, Ui_MainWindow) :
    #생성자
    def __init__(self) :
        super().__init__()
        self.init_my_location()
        self.setupUi(self)  # 초기화
        self.url = "http://localhost:8080/umbrella"
        # self.url = "http://localhost:8000/umbrella2.html"
        self.webEngineView.load(QUrl(self.url))
        self.page = QWebEnginePage()
        self.page.setUrl(QUrl(self.url))
        self.page.setView(self.webEngineView)
        self.appLoaded = False
        chrome_option = Options()
        chrome_option.add_argument("--headless")
        chrome_option.add_argument("--mute-audio")
        self.browser = webdriver.Chrome(chrome_options=chrome_option, executable_path="resources/chromedriver.exe")
        self.browser.get(self.url)

        self.runner = Runner(self)
        self.dc = DataCollector()
        # self.comboBox.addItem("키워드")
        # self.comboBox.addItem("주소")
        self.itemList = []
        self.rowList = []
        # self.page.featurePermissionRequested.connect(self.setPagePermission)

        #page 변환
        self.pushButton_3.clicked.connect(self.translate_ui)
        self.pushButton.clicked.connect(self.runner.map_removeMarkers)
        # self.pushButton.clicked.connect(self.map_removeMarkers)
        # self.pushButton.clicked.connect(self.runner.map_getLevel)
        # self.pushButton.clicked.connect(lambda: self.runner.map_setLevel(random.randrange(7)))
        # self.pushButton.clicked.connect(lambda: self.runner.coord_to_address(self.my_location_lat,self.my_location_lng, random.randrange(0,5)))
        # self.pushButton.clicked.connect(lambda: self.getDistance([33.450500,126.569968],[[33.450500,126.569968],[35.404195,126.886323],[39.668777,126.065913]]))
        # self.pushButton.clicked.connect(self.test_a)
        # self.pushButton.clicked.connect(self.search)
        self.lineEdit.returnPressed.connect(lambda: self.runner.search(self.lineEdit.text().strip()))
        self.pushButton.clicked.connect(lambda: self.runner.search(self.lineEdit.text().strip()))
        self.page.loadFinished.connect(lambda: self.runner.setMap(self.my_location_lat, self.my_location_lng))
        # self.setMap(self.my_location_lat, self.my_location_lng)

        self.pushButton2.clicked.connect(self.mark_around)
        self.pushButton3.clicked.connect(lambda: self.runner.setMap(self.my_location_lat,self.my_location_lng))
        self.page.urlChanged.connect(self.setButton)


        self.listWidget.itemActivated.connect(self.activateRow)
        # self.lineEdit.setText(self.runner.coord_to_address(self.my_location_lat,self.my_location_lng, 0))
        self.lineEdit.setText(self.runner.coord_to_address(self.my_location_lat,self.my_location_lng, 0))
    def translate_ui(self) :

        print('aaaaaaaa')
        self.stackedWidget.setCurrentIndex(1)


    def mark_around(self) :
        self.remove_list()
        if not self.page.url().toString().strip().startswith("http://localhost:8080/umbrella") :
            self.page.load(QUrl(self.url))
            return
        self.runner.map_removeMarkers()
        lat, lng = self.runner.map_getCenter()
        data = self.dc.get_data_by_latlng(lat, lng, 1000)
        self.runner.marking(data)
        self.show_list(data)
        self.lineEdit.setText(self.runner.coord_to_address(lat, lng, 0))



    def init_my_location(self) :
        url = 'https://www.googleapis.com/geolocation/v1/geolocate?key=AIzaSyDQKxbTt0MrFNH85kTJXzickMD5s88UVaI'
        data = {
            'considerIp': True,
        }

        result = requests.post(url, data)

        my_location = json.loads(result.text)
        # print(my_location)
        # print("lat : ",my_location.get('location').get('lat'))
        # print("lon : ",my_location.get('location').get('lng'))
        self.my_location_lat = str(my_location.get('location').get('lat'))
        self.my_location_lng = str(my_location.get('location').get('lng'))


    def setButton(self) :
        if self.page.url().toString().strip().startswith("http://localhost:8080/umbrella") :
            self.pushButton2.setText("판매처 탐색")
        else :
            self.pushButton2.setText("지도 새로고침")

    def show_list(self, data) :
        for i in range(len(data)) :
            item = QListWidgetItem(self.listWidget)
            row = Item(data[i])
            item.setWhatsThis(str(i))
            item.setSizeHint(row.sizeHint())
            self.listWidget.setItemWidget(item, row)
            self.listWidget.addItem(item)
            self.itemList.append(item)
            self.rowList.append(row)
    def remove_list(self) :
        for i in range(len(self.itemList)) :
            self.itemList[i].setHidden(True)
        self.itemList = []
        self.rowList = []

    def activateRow(self, row) :
        self.runner.setMap(self.rowList[int(row.whatsThis())].lat,self.rowList[int(row.whatsThis())].lng)
        self.runner.info_open(self.rowList[int(row.whatsThis())].code)
        # self.runner.map_setLevel(2)
        pass
コード例 #6
0
class Browser(QMainWindow):
    def __init__(self, mainWin, webview=None):
        super().__init__(mainWin)
        self.showFullScreen()
        self.mainWin = mainWin
        self.webview = webview
        self.initUI()

    def initUI(self):
        global CREATE_BROWER
        # print("initUI")
        # self.setWindowFlags(Qt.FramelessWindowHint)  # 去掉标题栏的代码
        # 设置窗口标题
        # self.setWindowTitle('LingBrowser')
        # 设置窗口图标
        self.setWindowIcon(QIcon(':/icons/logo.png'))
        self.page = QWebEnginePage()
        self.page.settings().setAttribute(QWebEngineSettings.PluginsEnabled, True)  # 支持视频播放
        self.page.settings().setAttribute(QWebEngineSettings.JavascriptEnabled, True)
        self.page.settings().setAttribute(QWebEngineSettings.FullScreenSupportEnabled, True)
        if self.webview == None:
            # 初始化一个 tab
            self.webview = WebView(self)  # self必须要有,是将主窗口作为参数,传给浏览器
            self.page.setUrl(QUrl(HOME_PAGE))
        self.page.windowCloseRequested.connect(self.on_windowCloseRequested)  # 页面关闭请求
        if CREATE_BROWER:
            CREATE_BROWER = False
            self.page.profile().downloadRequested.connect(self.on_downloadRequested)  # 页面下载请求

        self.t = WebEngineUrlRequestInterceptor()
        self.page.profile().setRequestInterceptor(self.t)
        self.webview.setPage(self.page)
        self.url = self.webview.page().url()
        self.initToolbar(self.webview)
        self.setCentralWidget(self.webview)
        self.center()

    def on_downloadRequested(self, downloadItem):
        # print("download..")
        # print(downloadItem.downloadFileName())
        # print('isFinished', downloadItem.isFinished())
        # print('isPaused', downloadItem.isPaused())
        # print('isSavePageDownload', downloadItem.isSavePageDownload())
        # print('path', downloadItem.path())
        # print('url', downloadItem.url())
        downloadFileName, ok2 = QFileDialog.getSaveFileName(self,
                                                            "文件保存",
                                                            downloadItem.path(),
                                                            "All Files (*)")
        print(downloadItem.path())
        downloadItem.setPath(downloadFileName)
        downloadItem.accept()
        downloadItem.finished.connect(self.on_downloadfinished)
        downloadItem.downloadProgress.connect(self.on_downloadProgress)

    def on_downloadfinished(self):
        print()

    def on_downloadProgress(self, int_1, int_2):
        rate = str(round(int_1 / int_2, 2) * 100).split(".")[0]
        self.mainWin.statusBarDownloadLabel.setText("文件下载 " + rate + "%")
        if int(rate) == 100:
            self.mainWin.statusBarDownloadLabel.setHidden(True)
            self.mainWin.statusBar.setHidden(True)
        else:
            self.mainWin.statusBarDownloadLabel.setHidden(False)
            self.mainWin.statusBar.setHidden(False)

    def on_windowCloseRequested(self):
        print("close tab")
        # self.webview.close()
        # del self.webview
        # sip.delete(self.webview)
        # self.webview
        # self.webview.page().profile().deleteLater()
        # self.deleteLater()
        pass

    def moreMenuShow(self):
        try:
            self.contextMenu = QMenu()
            self.contextMenu.setObjectName("moreMenu")
            self.contextMenu.setFont(fontawesome("far"))
            # self.actionA = self.contextMenu.addAction(self.zoom_in_action)
            # self.actionA = self.contextMenu.addAction(self.zoom_out_action)
            self.contextMenu.popup(
                QPoint(self.mainWin.x() + self.more_button.x() - 200, self.mainWin.y() + 75))  # 2菜单显示的位置 QCursor.pos()
            # print(self.more_button.x())
            # print(self.more_button.y())
            # print(self.frameGeometry())
            # print(self.mainWin.x())
            # print(self.mainWin.y())
            self.contextMenu.setContentsMargins(25,0,0,0)
            self.contextMenu.addMenu("打印")
            self.contextMenu.addSeparator()
            # 缩放组合
            sf_widget = QWidget(self)
            sf_widget.setProperty("class","qwidget")
            sf_widget.setObjectName("sf_widget")
            sf_widget.setContentsMargins(0,0,0,0)
            # sf_widget.setFixedHeight(20)
            sf_layout = QHBoxLayout()
            sf_layout.setContentsMargins(0,0,0,0)
            sf_widget.setLayout(sf_layout)
            sf_label = QLabel("缩放")
            sf_label.setObjectName("sf_item_label")
            sf_layout.addWidget(sf_label)
            sf_layout.addWidget(self.zoom_out_button)
            sf_layout.addWidget(self.sf_label_rate)
            sf_layout.addWidget(self.zoom_in_button)
            sf_layout.addWidget(self.full_screen_button)
            sf_action = QWidgetAction(self)
            sf_action.setDefaultWidget(sf_widget)
            self.actionA = self.contextMenu.addAction(sf_action)
            # self.actionA.triggered.connect(self.actionHandler)
            sf_layout.setSpacing(0)

            self.contextMenu.show()
        except Exception as e:
            print(e)

    def initToolbar(self, webview):
        pass
        ###使用QToolBar创建导航栏,并使用QAction创建按钮
        # 添加导航栏
        self.navigation_bar = QToolBar('Navigation')
        # 锁定导航栏
        self.navigation_bar.setMovable(False)
        # 设定图标的大小
        self.navigation_bar.setIconSize(QSize(2, 2))
        # 添加导航栏到窗口中
        self.addToolBar(self.navigation_bar)
        # 添加其它配置
        self.navigation_bar.setObjectName("navigation_bar")
        self.navigation_bar.setCursor(Qt.ArrowCursor)
        # QAction类提供了抽象的用户界面action,这些action可以被放置在窗口部件中
        # 添加前进、后退、停止加载和刷新的按钮
        self.reload_icon = unichr(0xf2f9)
        self.stop_icon = unichr(0xf00d)

        # 后退按钮
        self.back_action = QWidgetAction(self)
        self.back_button = QPushButton(unichr(0xf060), self,
                                       clicked=webview.back,
                                       font=fontawesome("far"),
                                       objectName='back_button')
        self.back_button.setToolTip("后退")
        self.back_button.setCursor(Qt.ArrowCursor)
        self.back_action.setDefaultWidget(self.back_button)

        # 前进按钮
        self.next_action = QWidgetAction(self)
        self.next_button = QPushButton(unichr(0xf061), self,
                                       clicked=webview.forward,
                                       font=fontawesome("far"),
                                       objectName='next_button')
        self.next_button.setToolTip("前进")
        self.next_button.setCursor(Qt.ArrowCursor)
        self.next_action.setDefaultWidget(self.next_button)

        # 刷新与停止按钮
        self.reload_action = QWidgetAction(self)

        self.reload_button = QPushButton(self.reload_icon, self,
                                         clicked=webview.reload,
                                         font=fontawesome("far"),
                                         objectName='reload_button')
        self.reload_button.setToolTip("刷新")
        self.reload_button.setCursor(Qt.ArrowCursor)
        self.reload_action.setDefaultWidget(self.reload_button)

        # 放大按钮
        self.zoom_in_button = QPushButton(unichr(0xf067), self,
                                          clicked=self.zoom_in_func,
                                          font=fontawesome("far"),
                                          objectName='zoom_in_btn')
        self.zoom_in_button.setToolTip("放大")
        self.zoom_in_button.setCursor(Qt.ArrowCursor)

        # 缩小按钮
        self.zoom_out_button = QPushButton(unichr(0xf068), self,
                                           clicked=self.zoom_out_func,
                                           font=fontawesome("far"),
                                           objectName='zoom_out_btn')
        self.zoom_out_button.setToolTip("缩小")
        self.zoom_out_button.setCursor(Qt.ArrowCursor)
        self.sf_label_rate = QLabel()
        self.sf_label_rate.setObjectName("sf_label_rate")
        self.sf_label_rate.setFixedWidth(30)
        self.sf_label_rate.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignVCenter)
        self.sf_label_rate.setProperty("class","qlabel")
        self.sf_label_rate.setText(str(int(self.webview.zoomFactor()*100))+"%")

        # 全屏按钮
        self.full_screen_button = QPushButton(unichr(0xe140), self,
                                           clicked=self.full_screen_func,
                                           font=fontawesome("boot"),
                                           objectName='full_screen_button')
        self.full_screen_button.setToolTip("全屏")
        self.full_screen_button.setCursor(Qt.ArrowCursor)

        # 其它按钮
        self.more_action = QWidgetAction(self)
        self.more_button = QPushButton(unichr(0xe235), self,
                                       clicked=self.moreMenuShow,
                                       font=fontawesome("boot"),
                                       objectName='more_button')
        self.more_button.setToolTip("页面控制及浏览器核心")
        self.more_button.setCursor(Qt.ArrowCursor)
        self.more_action.setDefaultWidget(self.more_button)

        # 首页按钮
        self.index_action = QWidgetAction(self)
        self.index_button = QPushButton(unichr(0xf015), self,
                                        # clicked=self.zoom_out_func,
                                        font=fontawesome("far"),
                                        objectName='index_button')
        self.index_button.setToolTip("主页")
        self.index_button.setCursor(Qt.ArrowCursor)
        self.index_action.setDefaultWidget(self.index_button)

        # self.back_button.triggered.connect(webview.back)
        # self.next_button.triggered.connect(webview.forward)
        # self.reload_button.triggered.connect(webview.reload)
        # self.zoom_in_btn.triggered.connect(self.zoom_in_func)
        # self.zoom_out_btn.triggered.connect(self.zoom_out_func)
        # 将按钮添加到导航栏上
        self.navigation_bar.addAction(self.back_action)
        self.navigation_bar.addAction(self.next_action)
        self.navigation_bar.addAction(self.reload_action)
        self.navigation_bar.addAction(self.index_action)
        # 添加URL地址栏
        self.urlbar = QLineEdit()
        # 让地址栏能响应回车按键信号
        self.urlbar.returnPressed.connect(self.navigate_to_url)
        # self.navigation_bar.addSeparator()
        self.navigation_bar.addWidget(self.urlbar)
        # self.navigation_bar.addSeparator()

        # self.navigation_bar.addAction(self.zoom_in_action)
        # self.navigation_bar.addAction(self.zoom_out_action)
        self.navigation_bar.addAction(self.more_action)
        # 让浏览器相应url地址的变化
        webview.urlChanged.connect(self.renew_urlbar)
        webview.loadProgress.connect(self.processLoad)
        webview.loadStarted.connect(self.loadPage)
        webview.loadFinished.connect(self.loadFinish)
        webview.titleChanged.connect(self.renew_title)
        webview.iconChanged.connect(self.renew_icon)
        self.webBind()
        webview.show()
        self.navigation_bar.setIconSize(QSize(20, 20))
        self.urlbar.setFont(QFont('SansSerif', 13))

    def zoom_in_func(self):
        self.webview.setZoomFactor(self.webview.zoomFactor() + 0.1)
        self.sf_label_rate.setText(str(int(self.webview.zoomFactor()*100))+"%")

    def zoom_out_func(self):
        self.webview.setZoomFactor(self.webview.zoomFactor() - 0.1)
        self.sf_label_rate.setText(str(int(self.webview.zoomFactor()*100))+"%")

    def full_screen_func(self):
        self.navigation_bar.setHidden(True)
        self.mainWin.titleBar.setHidden(True)
        self.mainWin.showFullScreen()

    def on_network_call(self, info):
        print(info)
        pass

    def loadPage(self):
        # print("loadPage")
        # print(self.webview.objectName())
        # self.renew_title("空页面")
        index = self.mainWin.tabWidget.currentIndex()
        self.mainWin.tabWidget.setTabIcon(index, QIcon(":icons/earth_128.png"))
        # self.reload_button.setDefaultWidget(self.stop_button_icon)
        self.reload_button.setText(self.stop_icon)
        self.reload_button.setToolTip("停止")

    def processLoad(self, rate):
        self.mainWin.statusBarLabelProgress.setValue(rate)
        self.mainWin.statusBarLabel.setText("网页加载")
        if rate == 0:
            self.mainWin.statusBarLabelProgress.setMaximum(0)
            self.mainWin.statusBarLabelProgress.setMinimum(0)
        else:
            self.mainWin.statusBarLabelProgress.setMaximum(0)
            self.mainWin.statusBarLabelProgress.setMinimum(100)
        if rate == 100:
            self.mainWin.statusBarLabelProgress.setHidden(True)
            self.mainWin.statusBarLabel.setHidden(True)
            self.mainWin.statusBar.setHidden(True)
        else:
            self.mainWin.statusBarLabelProgress.setHidden(False)
            self.mainWin.statusBarLabel.setHidden(False)
            self.mainWin.statusBar.setHidden(False)
        pass

    def loadFinish(self, isEnd):
        if isEnd:
            # print("load finished", isEnd)
            # self.reload_button.setDefaultWidget(self.reload_button_icon)
            self.reload_button.setText(self.reload_icon)
            self.reload_button.setToolTip("刷新")
        else:
            # print("load finished", isEnd)
            # print("load finished",isEnd)
            pass
        # index = self.webview.objectName()
        # title = self.page.title()
        # print("title", title)
        try:
            url = self.page.url().toString()
        except BaseException as base:
            url = self.webview.page().url().toString()
        # self.mainWin.tabWidget.setTabText(int(index), title if title else url)
        self.urlbar.setText(url)

    def webBind(self):
        # print("webBind")
        # self.back_button.disconnect()
        # self.next_button.disconnect()
        # self.stop_button.disconnect()
        # self.reload_button.disconnect()
        # self.add_button.disconnect()
        # self.back_button.triggered.connect(self.webview.back)
        # self.next_button.triggered.connect(self.webview.forward)
        # self.stop_button.triggered.connect(self.webview.stop)
        # self.reload_button.triggered.connect(self.webview.reload)
        # self.add_button.triggered.connect(self.mainWin.newTab)
        self.webview.urlChanged.connect(self.renew_urlbar)
        self.webview.titleChanged.connect(self.renew_title)
        self.webview.iconChanged.connect(self.renew_icon)

    def navigate_to_url(self):
        q = QUrl(self.urlbar.text())
        if q.scheme() == '':
            q.setScheme('http')
        self.webview.setUrl(q)

    def renew_urlbar(self, url):
        # 将当前网页的链接更新到地址栏
        # print("renew_urlbar")
        self.urlbar.setText(url.toString())
        self.urlbar.setCursorPosition(0)
        # print("url", url)f

    def renew_title(self, title):
        # 将当前网页的标题更新到标签栏
        index = self.webview.objectName()
        self.mainWin.tabWidget.setTabToolTip(int(index), title)
        title = " " + title[:11] + ".." if len(title) >= 12 else " " + title
        self.mainWin.tabWidget.setTabText(int(index), title)
        pass

    def renew_icon(self, icon):
        # 将当前网页的图标更新到标签栏
        # print("renew_icon")
        index = self.webview.objectName()
        self.mainWin.tabWidget.setTabIcon(int(index), icon)

    def center(self):
        # print("center")
        qr = self.frameGeometry()
        cp = QDesktopWidget().availableGeometry().center()
        qr.moveCenter(cp)
        self.move(qr.topLeft())

    # 创建tab
    def create_tab(self, webview):
        # print("create_tab")
        self.tab = QWidget()
        self.mainWin.tabWidget.addTab(self.tab, "新标签页")
        self.mainWin.tabWidget.setCurrentWidget(self.tab)
        index = self.mainWin.tabWidget.currentIndex()
        # self.mainWin.tabWidget.setTabIcon(index, ":icons/logo.png")
        #####
        self.Layout = QVBoxLayout(self.tab)
        self.Layout.setContentsMargins(0, 0, 0, 0)
        self.Layout.addWidget(Browser(self.mainWin, webview=webview))
        webview.setObjectName(str(index))
        self.mainWin.tab_[str(index)] = webview
        self.tab.setObjectName("tab_" + str(index))
コード例 #7
0
class MainWindow(QMainWindow):
    error = pyqtSignal(str)

    def __init__(self):
        super().__init__()
        self.ui = Ui_MainWindow()
        self.ui.setupUi(self)
        self.setWindowIcon(readIcon)
        # permalinks of comments we already notified the user of
        self.permalinks = []
        self.quitting = False
        self.error.connect(self.showError)
        # Logger
        self.fileHandler = None
        self.handler = Handler()
        self.handler.newMessage.connect(self.logMessage)
        s = QSettings(orgName, appName)
        level = s.value('misc/loglevel', defaultLevel, type=int)
        self.handler.setLevel(logLevels[level])
        self.handler.setFormatter(logging.Formatter(logFormat))
        logging.getLogger().addHandler(self.handler)
        self.updateLogger()
        # Auto search
        self.model = Model()
        self.model.statusMessage.connect(self.showStatusMessage)
        self.model.progress.connect(self.showProgress)
        self.updateAutoSearch()
        self.autoSearchPage = QWebEnginePage()
        self.autoSearchPage.loadFinished.connect(self.searchPageLoaded)
        self.progressBar = QProgressBar()
        self.progressBar.setTextVisible(False)
        self.progressBar.setMaximumWidth(100)
        self.progressBar.setMinimum(0)
        self.progressBar.setMaximum(99)
        self.statusBar().addPermanentWidget(self.progressBar)
        self.progressBar.hide()
        self.delegate = ItemDelegate()
        self.fontSize = 14
        self.ui.treeView.setHeaderHidden(True)
        self.ui.treeView.setIconSize(QSize(40, 40))
        self.ui.treeView.setStyleSheet("QTreeView {{font-size: {}pt;}}".format(
            self.fontSize))
        self.ui.treeView.setModel(self.model)
        self.ui.treeView.setItemDelegate(self.delegate)
        self.ui.treeView.hideColumn(1)
        self.ui.treeView.setContextMenuPolicy(Qt.CustomContextMenu)
        self.ui.treeView.customContextMenuRequested.connect(self.onCustomMenu)

        bookmarks = s.value('bookmarks/bookmarks_list', '')
        self.bookmarksList = [
            baseUrl(line) for line in bookmarks.split('\n') if baseUrl(line)
        ]
        self.bookmarksList = list(dict.fromkeys(self.bookmarksList))
        self.bookmarksModel = BookmarksModel(self.bookmarksList)
        self.bookmarksModel.setSourceModel(self.model)
        self.ui.bookmarksTreeView.setHeaderHidden(True)
        self.ui.bookmarksTreeView.setIconSize(QSize(40, 40))
        self.ui.bookmarksTreeView.setStyleSheet(
            "QTreeView {{font-size: {}pt;}}".format(self.fontSize))
        self.ui.bookmarksTreeView.setModel(self.bookmarksModel)
        self.ui.bookmarksTreeView.setItemDelegate(self.delegate)
        self.ui.bookmarksTreeView.hideColumn(1)
        self.ui.bookmarksTreeView.setContextMenuPolicy(Qt.CustomContextMenu)
        self.ui.bookmarksTreeView.customContextMenuRequested.connect(
            self.onCustomMenu)
        # Tray icon
        self.ui.prefsAction.triggered.connect(self.showPrefs)
        self.ui.refreshAction.triggered.connect(self.refresh)
        self.ui.quitAction.triggered.connect(self.quit)
        self.ui.zoomInAction.triggered.connect(self.zoomIn)
        self.ui.zoomOutAction.triggered.connect(self.zoomOut)
        minimizeAction = QAction("Mi&nimize", self)
        minimizeAction.triggered.connect(self.hide)
        restoreAction = QAction("&Restore", self)
        restoreAction.triggered.connect(self.show)
        trayMenu = QMenu(self)
        trayMenu.addAction(minimizeAction)
        trayMenu.addAction(restoreAction)
        trayMenu.addAction(self.ui.prefsAction)
        trayMenu.addAction(self.ui.refreshAction)
        trayMenu.addAction(self.ui.quitAction)
        self.trayIcon = QSystemTrayIcon()
        self.trayIcon.setContextMenu(trayMenu)
        self.trayIcon.activated.connect(self.iconActivated)
        self.trayIcon.setIcon(readIcon)
        self.trayIcon.setVisible(True)
        self.ui.webView.loadStarted.connect(
            lambda self=self: self.ui.urlLineEdit.setText(self.ui.webView.url(
            ).toString()))
        self.ui.webView.loadFinished.connect(self.loadFinished)
        self.ui.urlLineEdit.returnPressed.connect(
            lambda self=self: self.ui.webView.setUrl(
                QUrl(self.ui.urlLineEdit.text())))
        self.ui.webView.setUrl(stUrl)
        self.timer = QTimer()
        self.timer.timeout.connect(self.refresh)
        self.updateInterval(s.value('misc/interval', defaultInterval,
                                    type=int))
        self.timer.start()
        self.messagesPage = QWebEnginePage()
        self.messagesPage.loadFinished.connect(self.messagesPageLoaded)
        self.refresh()

    def zoomIn(self):
        currentIndex = self.ui.tabWidget.currentIndex()
        if currentIndex == 0:
            self.ui.webView.setZoomFactor(self.ui.webView.zoomFactor() + 0.25)
        elif currentIndex == 1 or currentIndex == 2:
            if self.fontSize >= 20:
                return
            self.fontSize += 1
            self.ui.treeView.setStyleSheet(
                "QTreeView {{font-size: {}pt;}}".format(self.fontSize))
            self.ui.bookmarksTreeView.setStyleSheet(
                "QTreeView {{font-size: {}pt;}}".format(self.fontSize))
        elif currentIndex == 3:
            self.ui.logTextEdit.zoomIn()

    def zoomOut(self):
        currentIndex = self.ui.tabWidget.currentIndex()
        if currentIndex == 0:
            self.ui.webView.setZoomFactor(self.ui.webView.zoomFactor() - 0.25)
        elif currentIndex == 1 or currentIndex == 2:
            if self.fontSize <= 8:
                return
            self.fontSize -= 1
            self.ui.treeView.setStyleSheet(
                "QTreeView {{font-size: {}pt;}}".format(self.fontSize))
            self.ui.bookmarksTreeView.setStyleSheet(
                "QTreeView {{font-size: {}pt;}}".format(self.fontSize))
        elif currentIndex == 3:
            self.ui.logTextEdit.zoomOut()

    def onCustomMenu(self, point):
        sender = self.sender()
        index = sender.indexAt(point)
        urlIndex = index.siblingAtColumn(1)
        url = str(sender.model().data(urlIndex, role=Qt.DisplayRole))
        url = baseUrl(url)
        if not url:
            return
        self.contextMenu = QMenu()
        action = QAction("Copy url", self.contextMenu)
        action.triggered.connect(
            lambda checked, arg=url: QApplication.clipboard().setText(arg))
        self.contextMenu.addAction(action)
        action = QAction("Open in browser", self.contextMenu)
        action.triggered.connect(
            lambda checked, self=self, url=url: self.toBrowser(url))
        self.contextMenu.addAction(action)
        action = QAction("Open in default browser", self.contextMenu)
        action.triggered.connect(lambda checked, arg=url: subprocess.call(
            [sys.executable, '-m', 'webbrowser', '-t', arg]))
        self.contextMenu.addAction(action)
        if url not in self.bookmarksList:
            enabled = True
            action = QAction("Add to bookmarks", self.contextMenu)
        else:
            enabled = False
            action = QAction("Remove from bookmarks", self.contextMenu)
        action.triggered.connect(lambda checked, self=self, url=url, enabled=
                                 enabled: self.setBookmarked(url, enabled))
        self.contextMenu.addAction(action)
        action = QAction("Check now", self.contextMenu)
        action.triggered.connect(
            lambda checked, self=self, url=url: self.model.checkNow(url))
        self.contextMenu.addAction(action)
        self.contextMenu.exec(sender.viewport().mapToGlobal(point))

    def setBookmarked(self, url, enabled):
        bookmarked = url in self.bookmarksList
        s = QSettings(orgName, appName)
        if bookmarked and not enabled:
            self.bookmarksList.remove(url)
        elif enabled and not bookmarked:
            self.bookmarksList.append(url)
        self.bookmarksModel.invalidate()
        s.setValue('bookmarks/bookmarks_list', '\n'.join(self.bookmarksList))

    def toBrowser(self, url):
        self.ui.webView.setUrl(QUrl(url))
        self.ui.tabWidget.setCurrentIndex(0)

    def logMessage(self, msg):
        self.ui.logTextEdit.appendPlainText(msg)

    def updateLogLevel(self, newLevel):
        logging.debug('setting log level ' + str(newLevel))
        logging.getLogger().setLevel(logLevels[newLevel])
        for h in logging.getLogger().handlers:
            h.setLevel(logLevels[newLevel])

    def updateLogger(self):
        logging.debug("updating logger handlers")
        s = QSettings(orgName, appName)
        if self.fileHandler:
            logging.getLogger().removeHandler(self.fileHandler)
            self.fileHandler = None
        if s.value('logfile/enable', False, type=bool):
            f = s.value('logfile/filename', defaultLogfile)
            if not os.path.isabs(f):
                f = os.path.join(baseDir, f)
            logging.debug('new file handler for ' + f)
            fileHandler = logging.FileHandler(f)
            level = s.value('misc/loglevel', defaultLevel, type=int)
            fileHandler.setLevel(logLevels[level])
            fileHandler.setFormatter(logging.Formatter(logFormat))
            self.fileHandler = fileHandler
            logging.getLogger().addHandler(self.fileHandler)

    def updateAutoSearch(self):
        s = QSettings(orgName, appName)
        self.autoSearchEnabled = s.value('autosearch/enable', False, type=bool)
        haveListStr = s.value('autosearch/have_list', '')
        haveList = [
            line.strip().lower() for line in haveListStr.split('\n')
            if line.strip()
        ]
        wantListStr = s.value('autosearch/want_list', '')
        wantList = [
            line.strip().lower() for line in wantListStr.split('\n')
            if line.strip()
        ]
        self.model.updateLists(haveList, wantList)

    def searchPageLoaded(self, ok):
        if not ok:
            logging.warning('Failed to load URL: ' + stUrl.toString())
            return
        self.autoSearchPage.toHtml(self.model.parseSearchResults)

    def refresh(self):
        self.messagesPage.setUrl(messagesUrl)
        if not self.autoSearchEnabled:
            return
        self.autoSearchPage.setUrl(stUrl)
        for url in self.bookmarksList:
            self.model.queueUrl(url, False)

    def updateInterval(self, newInterval):
        logging.info(
            'setting refresh interval: {} minutes'.format(newInterval))
        self.timer.setInterval(newInterval * 1000 * 60)

    def quit(self):
        self.trayIcon.setVisible(False)
        self.quitting = True
        self.model.cancelAll.emit()
        self.statusBar().showMessage('Waiting for worker threads...')
        QThreadPool.globalInstance().waitForDone()
        QApplication.setQuitOnLastWindowClosed(True)
        self.close()

    def loadFinished(self, ok):
        if not ok:
            logging.warning('failed to load URL: ' +
                            self.ui.webView.url().toString())
            return
        self.ui.urlLineEdit.setText(self.ui.webView.url().toString())
        self.ui.urlLineEdit.setCursorPosition(0)

        if not self.autoSearchEnabled:
            return
        url = self.ui.webView.url().toString()
        if url == stUrl.toString() or url.startswith(
                'https://www.steamtrades.com/trades/search'):
            self.ui.webView.page().toHtml(self.model.parseSearchResults)
        elif url.startswith('https://www.steamtrades.com/trade/'):
            self.model.queueUrl(url, False)

    def messagesPageLoaded(self, ok):
        if not ok:
            logging.warning('failed to load URL: ' +
                            self.messagesPage.url().toString())
            return
        self.messagesPage.toHtml(self.checkMessages)

    def closeEvent(self, event):
        if not self.quitting:
            self.hide()
            event.ignore()
        else:
            event.accept()

    def iconActivated(self, reason):
        if reason == QSystemTrayIcon.Context or reason == QSystemTrayIcon.Trigger:
            return
        if self.isVisible():
            self.hide()
        else:
            self.show()

    def showPrefs(self):
        d = PrefsDialog(self)
        d.intervalChanged.connect(self.updateInterval)
        d.loglevelChanged.connect(self.updateLogLevel)
        d.logfileChanged.connect(self.updateLogger)
        d.autoSearchChanged.connect(self.updateAutoSearch)
        d.exec_()

    def showError(self, message):
        self.trayIcon.showMessage('', message, QSystemTrayIcon.Warning)

    def showStatusMessage(self, message):
        self.statusBar().showMessage(message, 5000)

    def showProgress(self, percent):
        if percent >= 0 and percent <= 99:
            self.progressBar.setValue(percent)
            if self.progressBar.isHidden():
                self.progressBar.show()
        else:
            self.progressBar.hide()

    def onMailError(self, msg, permalink):
        self.showError(msg)
        if permalink in self.permalinks:
            self.permalinks.remove(permalink)

    def checkMessages(self, page):
        url = self.messagesPage.url()
        logging.info('loaded page ' + url.toString())
        soup = BeautifulSoup(page, 'html.parser')
        if url.host() == 'www.steamtrades.com' or url.host(
        ) == 'steamtrades.com':
            if '<span>Messages' not in page:
                logging.warning(
                    'log in to SteamTrades to receive message notifications')
                return
        if url != messagesUrl:
            return
        messageCount = soup.find('span', attrs={'class': 'message_count'})
        if not messageCount:
            self.trayIcon.setIcon(readIcon)
            self.setWindowIcon(readIcon)
            return

        logging.debug('message count:' + messageCount.text)

        self.trayIcon.setIcon(unreadIcon)
        self.setWindowIcon(unreadIcon)
        try:
            parsed = 0
            for comment in soup.find_all('div',
                                         attrs={'class': 'comment_inner'}):
                if parsed >= int(messageCount.text):
                    break
                if comment.find('div', attrs={'class':
                                              'comment_unread'}) == None:
                    continue
                parsed += 1
                author = comment.find('a', attrs={
                    'class': 'author_name'
                }).text.strip()
                message = comment.find('div',
                                       attrs={
                                           'class':
                                           'comment_body_default markdown'
                                       }).text.strip()
                permalink = comment.find_all('a')[-1]['href']
                if permalink not in self.permalinks:
                    logging.debug('unread comment: \n' + str(comment))
                    logging.debug('author: ' + author)
                    logging.debug('message: \n' + message)
                    logging.debug('permalink:' + permalink)
                    self.trayIcon.showMessage("New message from " + author,
                                              message)
                    s = QSettings(orgName, appName)
                    if s.value('email/notify', False, type=bool):
                        sender = s.value('email/sender')
                        recipient = s.value('email/recipient')
                        smtpServer = s.value('email/host')
                        smtpPort = s.value('email/port')
                        encryption = s.value(
                            'email/encryption_type') if s.value(
                                'email/encrypt', False, type=bool) else ''
                        username = s.value('email/username') if s.value(
                            'email/login', False, type=bool) else ''
                        password = ''
                        try:
                            if s.value('email/login', False, type=bool):
                                password = keyring.get_password(
                                    sysName, "email/password")
                        except Exception as e:
                            logging.warning(
                                'Cannot read password from keyring: ' + str(e))
                        mailSender = MailSender(sender, recipient, smtpServer, smtpPort, encryption, username, password,\
                        messageTemplate.format(sender = sender,  recipient = recipient, count = messageCount.text, author = author, message = message), permalink)
                        logging.info('sending email...')
                        mailSender.emitter.error.connect(self.onMailError)
                        QThreadPool.globalInstance().start(mailSender)
                    self.permalinks.append(permalink)
        except Exception as e:
            logging.error(str(e))
            self.error.emit(str(e))