class BrowserWidget(QWebEngineView):
    def __init__(self, url, *args, **kwargs):
        QWebEngineView.__init__(self, *args, **kwargs)

        self._page = QWebEnginePage(get_profile())
        self.setPage(self._page)
        self.load(url)

        # Shortcut to manually reload
        self.reload_shortcut = QShortcut('CTRL+R', self)
        self.reload_shortcut.activated.connect(self.reload)

        # Check if pages is correctly loaded
        self.loadFinished.connect(self._load_finished)

        # Shortcut to close
        self.quit_shortcut = QShortcut('CTRL+ALT+DELETE', self)
        self.quit_shortcut.activated.connect(lambda: self.close())

        # Stretch the browser
        policy = QSizePolicy()
        policy.setVerticalStretch(1)
        policy.setHorizontalStretch(1)
        policy.setVerticalPolicy(QSizePolicy.Preferred)
        policy.setHorizontalPolicy(QSizePolicy.Preferred)
        self.setSizePolicy(policy)

    def load(self, url):
        self._page.setUrl(url)

    def _load_finished(self, success):
        if not success:
            QTimer.singleShot(5000, self.reload)
Exemple #2
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)

        chrome_option = Options()
        chrome_option.add_argument("--headless")
        chrome_option.add_argument("--mute-audio")
        self.browser = webdriver.Chrome(
            chrome_options=chrome_option,
            executable_path="webdriver/Chrome/chromedriver.exe")
        self.browser.get(self.url)

        self.runner = Runner(self.page, self.browser)
        self.comboBox.addItem("키워드")
        self.comboBox.addItem("주소")

        # self.page.featurePermissionRequested.connect(self.setPagePermission)

        # self.pushButton.clicked.connect(self.map_removeMarkers)

        # self.pushButton.clicked.connect(lambda: self.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(self.runner.search)
        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)

    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'))
Exemple #3
0
    async def _alogin(self):
        """async login method."""
        from PyQt5.QtWidgets import QApplication
        from PyQt5.QtWebEngineWidgets import QWebEngineView, QWebEngineProfile, QWebEnginePage
        from PyQt5.QtCore import QEventLoop, QUrl

        app = QApplication(sys.argv)
        browser = QWebEngineView()
        profile = QWebEngineProfile()
        page = QWebEnginePage(profile, browser)

        loop = asyncio.get_event_loop()
        browser_closed_event = asyncio.Event(loop=loop)
        page.windowCloseRequested.connect(
            lambda event: browser_closed_event.set())

        # whenever a page finishes loading, look for the login button
        page.loadFinished.connect(partial(self.__on_page_loaded, page))

        # keep track of cookies
        cookies = profile.cookieStore()
        self.__update_cookie_store(cookies)
        got_auth_event = asyncio.Event(loop=loop)
        cookies.cookieAdded.connect(
            partial(self.__on_cookie_added, got_auth_event))

        # navigate to the notebook and show the browser
        page.setUrl(QUrl(self.__notebook_url))
        browser.setPage(page)
        browser.show()

        # process Qt events until we've got the token or the browser is closed
        async def poll():
            future = asyncio.gather(got_auth_event.wait(),
                                    browser_closed_event.wait())
            while not got_auth_event.is_set(
            ) and not browser_closed_event.is_set():
                app.processEvents(QEventLoop.AllEvents, 300)
                await asyncio.wait([future], loop=loop, timeout=0)

        await poll()

        if not got_auth_event.is_set():
            raise AuthenticationError()

        return self.__cookies
Exemple #4
0
class TestForm(QMainWindow, Ui_MainWindow) :
    #생성자
    def __init__(self) :
        super().__init__()
        self.setupUi(self)  # 초기화
        self.url = QUrl("http://localhost:8080/umbrella")
        self.webEngineView.load(QUrl(self.url))
        self.page = QWebEnginePage()
        self.page.setUrl(self.url)
        self.page.setView(self.webEngineView)
        self.pushButton_3.clicked.connect(self.translate_ui)



    def translate_ui(self) :

        print('aaaaaaaa')
        self.stackedWidget.setCurrentIndex(1)
Exemple #5
0
    def __init__(self, parent=None):
        super().__init__(parent)
        layout = QVBoxLayout()
        self.setLayout(layout)
        self.profile = QWebEngineProfile()
        self.store = self.profile.cookieStore()
        self.brower = QWebEngineView()
        self.profile.cookieStore().cookieAdded.connect(self.onCookieAdd)
        page = QWebEnginePage(self.profile, self.brower)
        page.setUrl(QUrl("https://passport.csdn.net/login?code=public"))
        self.brower.setPage(page)
        self.title = QLabel()
        self.edit = QTextEdit()
        #self.edit=QCodeEditor()
        layout.addWidget(self.title)
        layout.addWidget(self.brower)
        layout.addWidget(self.edit)
        layout.setStretchFactor(self.title, 1)
        layout.setStretchFactor(self.brower, 10)
        layout.setStretchFactor(self.edit, 10)
        self.title.setHidden(True)
        self.edit.setHidden(True)

        #当edit的内容改动的时候,broswer的内容要同步进行刷新
        self.edit.textChanged.connect(self.refreshBrowser)

        #快捷查找
        self.contentSearch = QLineEdit(returnPressed=lambda: self.brower.
                                       findText(self.contentSearch.text()))
        self.contentSearch.setWindowTitle("搜索")
        self.contentSearch.hide()
        self.showSearch = QShortcut(
            "Ctrl+F",
            self,
            activated=lambda:
            (self.contentSearch.show(), self.contentSearch.setFocus()))
Exemple #6
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)
Exemple #7
0
ip = res.text.split(":")
port = ip[1]
ip = ip[0]

proxy = QtNetwork.QNetworkProxy()
# Http访问代理
proxy.setType(QtNetwork.QNetworkProxy.HttpProxy)
# 代理ip地址HttpProxy
proxy.setHostName(ip)
# 端口号
proxy.setPort(int(port))
QtNetwork.QNetworkProxy.setApplicationProxy(proxy)

interceptor = TwitchInterceptor()
profile = QWebEngineProfile()
profile.clearHttpCache()
profile.clearAllVisitedLinks()
pCookie = profile.cookieStore()
pCookie.deleteAllCookies()
pCookie.deleteSessionCookies()
profile.setRequestInterceptor(interceptor)

profile.setPersistentCookiesPolicy(QWebEngineProfile.ForcePersistentCookies)

page = QWebEnginePage(profile, view)
page.loadFinished.connect(on_done)
view.setPage(page)
page.setUrl(QUrl(twitch_url))
view.show()
sys.exit(app.exec_())
Exemple #8
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}')
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
Exemple #10
0
class TestForm(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)

        chrome_option = Options()
        #headless 모드
        chrome_option.add_argument("--headless")
        #사운드 뮤트
        chrome_option.add_argument("--mute-audio")

        # webdriver 설정(chrome) --headless
        self.browser = webdriver.Chrome(
            chrome_options=chrome_option,
            executable_path="webdriver/Chrome/chromedriver.exe")

        self.browser.get(self.url)

        self.runner = Runner(self.page, self.browser)
        self.comboBox.addItem("키워드")
        self.comboBox.addItem("주소")

        # self.page.featurePermissionRequested.connect(self.setPagePermission)

        # self.pushButton.clicked.connect(self.map_removeMarkers)

        # self.pushButton.clicked.connect(lambda: self.map_setLevel(random.randrange(7)))

        #현재위치
        #self.pushButton.clicked.connect(lambda: self.coord_to_address(37.62244036,127.072065, 0))
        #거리
        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(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(self.search)
        self.page.loadFinished.connect(
            lambda: self.setMap(self.my_location_lat, self.my_location_lng))
        # self.setMap(self.my_location_lat, self.my_location_lng)

    #아이피로 현재 위치 받아오기(google api 사용)
    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 = my_location.get('location').get('lat')
        self.my_location_lng = my_location.get('location').get('lng')

    def test_a(self):
        script = """
        return centerX.val()
        """
        centerX = self.run(script)
        print(centerX)

    #위치권한 요청이 왔을때 허용해줌
    def setPagePermission(self, url, feature):
        self.page.setFeaturePermission(url, feature,
                                       QWebEnginePage.PermissionGrantedByUser)

    def search(self):
        search_text = self.lineEdit.text().strip()

        if self.comboBox.currentIndex() == 0:
            script = """
            removeMarkers();
            // 주소-좌표 변환 객체를 생성합니다
            var geocoder = new kakao.maps.services.Geocoder();

            // 장소 검색 객체를 생성합니다
            var ps = new kakao.maps.services.Places();

            // 키워드로 장소를 검색합니다
            ps.keywordSearch('""" + search_text + """', placesSearchCB);

            function placesSearchCB (data, status, pagination) {
                if (status === kakao.maps.services.Status.OK) {

                    // 검색된 장소 위치를 기준으로 지도 범위를 재설정하기위해
                    // LatLngBounds 객체에 좌표를 추가합니다
                    var bounds = new kakao.maps.LatLngBounds();

                    for (var i=0; i<data.length; i++) {
                        displayMarker(data[i]);
                        bounds.extend(new kakao.maps.LatLng(data[i].y, data[i].x));
                    }

                    // 검색된 장소 위치를 기준으로 지도 범위를 재설정합니다
                    map.setBounds(bounds);
                }
            }


            """
        elif self.comboBox.currentIndex():
            script = """
            removeMarkers();
            // 주소-좌표 변환 객체를 생성합니다
            var geocoder = new kakao.maps.services.Geocoder();

            // 주소로 좌표를 검색합니다
            geocoder.addressSearch('""" + search_text + """', function(result, status) {

                // 정상적으로 검색이 완료됐으면
                 if (status === kakao.maps.services.Status.OK) {

                    var coords = new kakao.maps.LatLng(result[0].y, result[0].x);

                    // 결과값으로 받은 위치를 마커로 표시합니다
                    var marker = new kakao.maps.Marker({
                        map: map,
                        position: coords
                    });
                    //*** 마커 담기
                    markerList.push(marker)


                    // 인포윈도우로 장소에 대한 설명을 표시합니다

                    infowindow.open(map, marker);

                    // 지도의 중심을 결과값으로 받은 위치로 이동시킵니다
                    map.setCenter(coords);
                }
            });    """

        else:
            return
        self.run(script)

    #거리 계산하는 메소드
    # center에는 기준좌표 [lat, lng]
    # pointList에는 측정할 좌표 리스트 [ [lat,lng]  ,  [lat,lng] .......  ]
    #리턴값은 측정한 거리(int값) list  ex) [ [0], [218667], [691542] ]
    #단위는 m
    def getDistance(self, center, pointList):

        # center가 None일 경우
        # 기본값으로 '내위치'의 좌표
        center = center or [self.my_location_lat, self.my_location_lng]

        script = """
        var tmp_point_arr = """ + str(pointList) + """
        var tmp_center = """ + str(center) + """
        var tmp_div = $('#tmp_div');
        var result_arr = new Array();
        for(var i=0; i < tmp_point_arr.length; i++){
            const polyline = new window.daum.maps.Polyline({
                map : map,
                path : [
                    new window.daum.maps.LatLng(tmp_center[0], tmp_center[1]),
                    new window.daum.maps.LatLng(tmp_point_arr[i][0], tmp_point_arr[i][1])
                ],
                strokeWeight : 0
            });
            result_arr.push(polyline.getLength());
        }
        return '['+result_arr.toString()+']';
        """
        result = list(map(int, eval(self.run(script))))
        print(result)
        for i in result:
            print(f"거리 : {i}m, type : {type(i)}")

        return result

    #좌표로 주소 얻기 idx
    #0 : 지번주소
    #1 : 지번주소 - 시도단위
    #2 : 지번주소 - 구 단위
    #3 : 지번주소 - 동 단위
    #4 : 지번주소 - 우편번호(6자리)
    #없을경우 ""
    def coord_to_address(self, lat, lng, idx):
        if not idx in (0, 1, 2, 3, 4):
            idx = 0
        result = ""
        print(lat)
        print(lng)
        script = """
        go_py_result = '대기중'
        var coord = new kakao.maps.LatLng(""" + str(lat) + """, """ + str(
            lng) + """);
        var c2a = function(result, status) {
            tmp_div.append("result0 -"+result[0].address.address_name);
            //go_py_result = result[0].address.address_name;
            var idx = """ + str(idx) + """


            if(idx === 0){
                go_py_result = result[0].address.address_name;
            }else if(idx === 1){
                go_py_result = result[0].address.region_1depth_name;
            }else if(idx === 2){
                go_py_result = result[0].address.region_2depth_name;
            }else if(idx === 3){
                go_py_result = result[0].address.region_3depth_name;
            }else if(idx === 4){
                go_py_result = result[0].address.zip_code;
            }else{
                go_py_result = result[0].address.address_name;
            }

        };
        geocoder.coord2Address(coord.getLng(), coord.getLat(), c2a);
        """
        script2 = "return go_py_result;"
        self.run(script)
        for i in range(50):
            result = self.run(script2)
            if result != "대기중":
                print("idx : ", idx, "c 2 a : ", result)
                return result
                break
        print("idx : ", idx, "c 2 a : ", result)
        return ""

    #지도 확대 레벨 설정
    def map_setLevel(self, level):
        script = """
        map.setLevel(""" + str(level) + """)
        """
        self.run(script)

    #마커 다 지우는 메소드
    def map_removeMarkers(self):
        script = """
        removeMarkers();
        """
        self.run(script)

    #맵 이동
    def setMap(self, lat, lng):
        script = """
        var umbrella_location = new kakao.maps.LatLng(""" + str(
            lat) + """, """ + str(lng) + """);
        map.setCenter(umbrella_location);
        """
        self.run(script)

    #스크립트 실행
    def run(self, script):
        # print("run runJavaScript")
        self.page.runJavaScript(script)
        # print("run execute_Script")
        result = self.browser.execute_script(script)
        return result

    def marking(self, data):
        typeP = ["", "약국", "우체국", "농협"]
        for item in data:
            addr = item.get('addr')
            code = item.get('code')
            created_at = item.get('created_at')
            lat = item.get('lat')
            lng = item.get('lng')
            name = item.get('name')
            remain_stat = item.get('remain_stat')
            stock_at = item.get('stock_at')
            type = typeP[int(item.get('type'))]
            print(
                f"addr = {addr}\ncode = {code}\ncreated_at = {created_at}\nlat = {lat}\nlng = {lng}\nname = {name}\nremain_stat = {remain_stat}\nstock_at = {stock_at}\ntype = {type}"
            )

            script = """










            """
            self.run(script)
Exemple #11
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
Exemple #12
0
class TestForm(QMainWindow, Ui_MainWindow):
    #생성자
    def __init__(self):
        super().__init__()
        self.setupUi(self)  # 초기화
        self.url = QUrl("http://localhost:8080/umbrella")
        self.webEngineView.load(QUrl(self.url))
        self.page = QWebEnginePage()
        self.page.setUrl(self.url)
        self.page.setView(self.webEngineView)

        self.comboBox.addItem("키워드")
        self.comboBox.addItem("주소")

        # self.page.featurePermissionRequested.connect(self.setPagePermission)

        self.pushButton.clicked.connect(self.search)
        self.lineEdit.returnPressed.connect(self.search)
        self.init_my_location()
        self.page.loadFinished.connect(
            lambda: self.setMap(self.my_location_lat, self.my_location_lng))
        # self.setMap(self.my_location_lat, self.my_location_lng)

    #아이피로 현재 위치 받아오기(google api 사용)
    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 = my_location.get('location').get('lat')
        self.my_location_lng = my_location.get('location').get('lng')

    def setMap(self, lat, lng):
        script = """
        var umbrella_location = new kakao.maps.LatLng(""" + str(
            lat) + """, """ + str(lng) + """);
        map.setCenter(umbrella_location);
        """
        self.run(script)

    #위치권한 요청이 왔을때 허용해줌
    def setPagePermission(self, url, feature):
        self.page.setFeaturePermission(url, feature,
                                       QWebEnginePage.PermissionGrantedByUser)

    def search(self):

        search_text = self.lineEdit.text().strip()

        if self.comboBox.currentIndex() == 0:
            script = """
            removeMarkers();
            // 주소-좌표 변환 객체를 생성합니다
            var geocoder = new kakao.maps.services.Geocoder();

            // 장소 검색 객체를 생성합니다
            var ps = new kakao.maps.services.Places();

            // 키워드로 장소를 검색합니다
            ps.keywordSearch('""" + search_text + """', placesSearchCB);

            function placesSearchCB (data, status, pagination) {
                if (status === kakao.maps.services.Status.OK) {

                    // 검색된 장소 위치를 기준으로 지도 범위를 재설정하기위해
                    // LatLngBounds 객체에 좌표를 추가합니다
                    var bounds = new kakao.maps.LatLngBounds();

                    for (var i=0; i<data.length; i++) {
                        displayMarker(data[i]);
                        bounds.extend(new kakao.maps.LatLng(data[i].y, data[i].x));
                    }

                    // 검색된 장소 위치를 기준으로 지도 범위를 재설정합니다
                    map.setBounds(bounds);
                }
            }


            """
        elif self.comboBox.currentIndex():
            script = """

            removeMarkers();
            var positions = [];
            positions=Marker3.main3();
            for (var i=0; i<positions.length;i++){
                map:map,
                position:new kakao.maps.LatLng(positions[i].get('lat')+positions[i].get('lng'))
            }
            // 주소-좌표 변환 객체를 생성합니다
            var geocoder = new kakao.maps.services.Geocoder();

            // 주소로 좌표를 검색합니다
            geocoder.addressSearch('""" + search_text + """', function(result, status) {

                // 정상적으로 검색이 완료됐으면
                 if (status === kakao.maps.services.Status.OK) {

                    var coords = new kakao.maps.LatLng(result[0].y, result[0].x);

                    // 결과값으로 받은 위치를 마커로 표시합니다
                    var marker = new kakao.maps.Marker({
                        map: map,
                        position: coords
                    });



                    //*** 마커 담기
                    markerList.push(marker)


                    // 인포윈도우로 장소에 대한 설명을 표시합니다

                    infowindow.open(map, marker);

                    // 지도의 중심을 결과값으로 받은 위치로 이동시킵니다
                    map.setCenter(coords);
                }
            });    """

        else:

            return

        self.run(script)

    def run(self, script):
        self.page.runJavaScript(script)
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))
Exemple #14
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))
Exemple #15
0
class Worker(QRunnable):
    def __init__(self, url, haveList=[], wantList=[], id_=-1):
        super().__init__()
        self.url = url
        self.haveList = haveList
        self.wantList = wantList
        self.id_ = id_
        self.state = WorkerState.PENDING
        self.mutex = QMutex()
        self.emitter = Emitter()
        self.page = QWebEnginePage()
        self.html = ''
        self.page.loadFinished.connect(self.loadFinished)
        self.page.setUrl(QUrl(self.url))
        # Set timeout to 3 minutes
        QTimer.singleShot(3 * 60 * 1000, self.cancel)

    def changeState(self, new, old=None):
        mutexLocker = QMutexLocker(self.mutex)
        if not old or old == self.state:
            self.state = new
            return True

    def run(self):
        if not self.changeState(WorkerState.RUNNING, WorkerState.PENDING):
            return
        try:
            soup = BeautifulSoup(self.html, 'html.parser')
            closedTag = soup.find('div',
                                  attrs={'class': 'notification yellow'})
            if closedTag and closedTag.text.startswith('Closed'):
                title = 'Closed'
            else:
                title = soup.find('div', attrs={
                    'class': 'page_heading'
                }).find('h1').text
            style = soup.find('div', attrs={
                'class': 'comment_inner'
            }).find('a', attrs={'class': 'author_avatar'})['style']
            res = re.findall('url\((.*)\);', style)
            if len(res) == 1:
                iconUrl = res[0]
            else:
                iconUrl = ''
            self.emitter.updateName.emit(self.id_, title)
            self.emitter.updateIconUrl.emit(self.id_, iconUrl)

            h = soup.find('div', attrs={'class': 'have markdown'})
            if h:
                hls = h.text.split('\n')
                for g in self.wantList:
                    for hl in hls:
                        if g in hl.lower():
                            self.emitter.newNode.emit(self.id_, '[H] ' + hl,
                                                      NodeType.H_GAME)
            h = soup.find('div', attrs={'class': 'want markdown'})
            if h:
                hls = h.text.split('\n')
                for g in self.haveList:
                    for hl in hls:
                        if g in hl.lower():
                            self.emitter.newNode.emit(self.id_, '[W] ' + hl,
                                                      NodeType.W_GAME)
        except Exception as e:
            logging.error('Error parsing trade page: ' + str(e))
        self.changeState(WorkerState.FINISHED)
        self.emitter.finished.emit(self.id_)

    def loadFinished(self, ok):
        if not ok:
            logging.warning('Failed to load page: ' + self.url)
            self.changeState(WorkerState.FINISHED)
            self.emitter.loadError.emit(self.id_)
            self.emitter.finished.emit(self.id_)
            return
        self.page.toHtml(self.processPage)

    def processPage(self, html):
        self.html = html
        QThreadPool.globalInstance().start(self)

    def cancel(self):
        if not self.changeState(WorkerState.FINISHED, WorkerState.PENDING):
            return
        self.page.triggerAction(QWebEnginePage.Stop)
        logging.warning('Canceling ' + self.url)
        self.emitter.loadError.emit(self.id_)
        self.emitter.finished.emit(self.id_)