deemix-gui-pyweb/deemix-pyweb.py
RemixDev efc1a7c3e6 Added back dummy menu item View Source
It doesn't do anything, but it will show at least an item in the context 
menu

Related to https://codeberg.org/RemixDev/deemix-webui/issues/31
2020-08-24 12:32:48 +02:00

242 lines
7.9 KiB
Python

#!/usr/bin/env python3
from PyQt5.QtWidgets import QApplication, QMainWindow, QFileDialog, QDialog, QVBoxLayout
from PyQt5.QtWebEngineWidgets import QWebEngineView, QWebEnginePage, QWebEngineProfile
from PyQt5.QtCore import QUrl, pyqtSignal
from PyQt5.QtGui import QIcon
import json
import webbrowser
from threading import Thread, Lock, Semaphore
import sys
import os.path as path
from os import makedirs
from time import sleep
from server import run_server
from http.client import HTTPConnection
from deemix.utils.localpaths import getConfigFolder
server_lock = Lock()
if sys.platform == "win32":
import ctypes
myappid = 'RemixDev.deemix'
ctypes.windll.shell32.SetCurrentProcessExplicitAppUserModelID(myappid)
class LoginWindow(QDialog):
class CustomPage(QWebEnginePage):
def acceptNavigationRequest(self, url, type, main):
if url.toString() == "https://www.deezer.com/":
url = QUrl('https://www.deezer.com/ajax/gw-light.php?method=user.getArl&input=3&api_version=1.0&api_token=null')
self.setUrl(url)
return False
return super().acceptNavigationRequest(url, type, main)
def __init__(self, parent):
super().__init__(parent)
self.webview = QWebEngineView()
profile = QWebEngineProfile(self.webview)
profile.setPersistentCookiesPolicy(QWebEngineProfile.NoPersistentCookies)
self.page = self.CustomPage(profile, self.webview)
self.page.loadFinished.connect(self.checkURL)
self.webview.setPage(self.page)
self.webview.setUrl(QUrl("https://deezer.com/login"))
layout = QVBoxLayout()
layout.addWidget(self.webview)
self.setLayout(layout)
self.arl = None
self.exec_()
def checkURL(self, ok):
url = self.webview.url().toString()
if 'user.getArl' in url:
sleep(1)
self.webview.page().toPlainText(self.saveARL)
def saveARL(self, body):
if body.startswith("{"):
self.arl = json.loads(body)['results']
self.accept()
class MainWindow(QMainWindow):
selectDownloadFolder_trigger = pyqtSignal()
appLogin_trigger = pyqtSignal()
class MainWebpage(QWebEnginePage):
def __init__(self, parent):
super().__init__(parent)
actions = [
QWebEnginePage.Back,
QWebEnginePage.Forward,
QWebEnginePage.Stop,
QWebEnginePage.Reload,
QWebEnginePage.ReloadAndBypassCache,
QWebEnginePage.PasteAndMatchStyle,
QWebEnginePage.OpenLinkInThisWindow,
QWebEnginePage.OpenLinkInNewWindow,
QWebEnginePage.OpenLinkInNewTab,
QWebEnginePage.OpenLinkInNewBackgroundTab,
QWebEnginePage.DownloadLinkToDisk,
QWebEnginePage.DownloadImageToDisk,
QWebEnginePage.DownloadMediaToDisk,
QWebEnginePage.InspectElement,
QWebEnginePage.RequestClose,
QWebEnginePage.SavePage
]
for a in actions:
self.action(a).setVisible(False)
class ExternalWebpage(QWebEnginePage):
def __init__(self, parent):
super().__init__(parent)
self.urlChanged.connect(self.open_browser)
def open_browser(self, url):
page = self.sender()
webbrowser.open(url.toString(), 2, True)
page.deleteLater()
def createWindow(self, _type):
page = None
if _type == QWebEnginePage.WebBrowserTab:
page = self.ExternalWebpage(self)
return page
def __init__(self, title, url, x=None, y=None, w=800, h=600):
super().__init__()
self.resize(w, h)
self.setWindowTitle(title)
self.setWindowIcon(QIcon(path.join(appDir, 'icon.ico')))
self.setMinimumSize(800, 600)
self.webview = QWebEngineView()
self.page = self.MainWebpage(self.webview)
self.page.loadFinished.connect(self.finishLoading)
self.webview.setPage(self.page)
self.setCentralWidget(self.webview)
self.url = url
self.downloadFolder = None
self.selectDownloadFolder_trigger.connect(self.selectDownloadFolder)
self._selectDownloadFolder_semaphore = Semaphore(0)
self.arl = None
self.appLogin_trigger.connect(self.appLogin)
self._appLogin_semaphore = Semaphore(0)
if x is not None and y is not None:
self.move(x, y)
else:
center = QApplication.desktop().availableGeometry().center() - self.rect().center()
self.move(center.x(), center.y())
def showWindow(self):
self.webview.setUrl(QUrl(self.url))
self.show()
def selectDownloadFolder(self):
filename = QFileDialog.getExistingDirectory(self, "Select Download Folder", options=QFileDialog.ShowDirsOnly)
self.downloadFolder = filename
self._selectDownloadFolder_semaphore.release()
def appLogin(self):
loginWindow = LoginWindow(self)
self.arl = loginWindow.arl
self._appLogin_semaphore.release()
loginWindow.page.deleteLater()
loginWindow.webview.deleteLater()
loginWindow.deleteLater()
def closeEvent(self, event):
x = int(self.x())
y = int(self.y())
w = int(self.width())
h = int(self.height())
if x < 0: x = 0
if y < 0: y = 0
with open(path.join(configFolder, '.UIposition'), 'w') as f:
f.write("|".join([str(x),str(y),str(w),str(h)]))
event.accept()
def finishLoading(self, ok):
if ok: self.webview.page().runJavaScript("window.dispatchEvent(new Event('pywebviewready'))")
def url_ok(url, port):
try:
conn = HTTPConnection(url, port)
conn.request('GET', '/')
r = conn.getresponse()
return r.status == 200
except:
print("Server not started")
return False
def save_position():
window = webview.windows[0]
x = int(window.x)
y = int(window.y)
w = int(window.width)
h = int(window.height)
if x < 0: x = 0
if y < 0: y = 0
with open(path.join(configFolder, '.UIposition'), 'w') as f:
f.write("|".join([str(x),str(y),str(w),str(h)]))
def get_position():
if path.isfile(path.join(configFolder, '.UIposition')):
try:
with open(path.join(configFolder, '.UIposition'), 'r') as f:
(x,y,w,h) = f.read().strip().split("|")
x = int(x)
y = int(y)
w = int(w)
h = int(h)
if x < 0: x = 0
if y < 0: y = 0
except:
x = None
y = None
w = 800
h = 600
else:
x = None
y = None
w = 800
h = 600
return (x,y,w,h)
if __name__ == '__main__':
url = "127.0.0.1"
port = 6595
if len(sys.argv) >= 2:
try:
port = int(sys.argv[1])
except ValueError:
pass
portable = None
server = False
appDir = path.dirname(path.realpath(__file__))
if '--portable' in sys.argv:
portable = path.join(appDir, 'config')
if '--server' in sys.argv or '-s' in sys.argv:
server = True
if not server:
configFolder = portable or getConfigFolder()
x,y,w,h = get_position()
app = QApplication([])
window = MainWindow('deemix', 'http://'+url+':'+str(port), x,y,w,h)
t = Thread(target=run_server, args=(port, url, portable, window))
else:
t = Thread(target=run_server, args=(port, url, portable))
t.daemon = True
t.start()
if not server:
while not url_ok(url, port):
sleep(1)
window.showWindow()
app.exec_()
conn = HTTPConnection(url, port)
conn.request('GET', '/shutdown')
t.join()