Skip to content

Commit

Permalink
2.2.3 Update
Browse files Browse the repository at this point in the history
  • Loading branch information
devhotteok committed Dec 5, 2022
1 parent 3d51bdf commit e180897
Show file tree
Hide file tree
Showing 58 changed files with 1,060 additions and 576 deletions.
2 changes: 2 additions & 0 deletions Core/Config.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,5 +29,7 @@ class Config(Meta):

SERVER_URL = _U(Meta.HOMEPAGE_URL, "server")

STATUS_UPDATE_INTERVAL = 60000

APP_SHUTDOWN_TIMEOUT = 60
SYSTEM_SHUTDOWN_TIMEOUT = 100
3 changes: 3 additions & 0 deletions Core/Launcher.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@ class SingleApplicationLauncher(QtWidgets.QApplication):

def __init__(self, guid, argv):
super(SingleApplicationLauncher, self).__init__(argv)
self.setApplicationName(Config.APP_NAME)
self.setApplicationVersion(Config.APP_VERSION)
self.setApplicationDisplayName("")
self.logger = Logger(fileName=f"{Config.APP_NAME}_{Logger.getFormattedTime()}#{uuid.uuid4()}.log")
self.logger.info(f"\n\n{Config.getProjectInfo()}\n")
self.logger.info(OSUtils.getOSInfo())
Expand Down
8 changes: 3 additions & 5 deletions Core/Meta.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,15 @@
class Meta:
APP_NAME = "TwitchLink"

VERSION = "2.2.2"
APP_VERSION = "2.2.3"

AUTHOR = "DevHotteok"

LICENSE = "MIT"

FIRST_VERSION_RELEASED = QtCore.QDate(2021, 2, 1)

class CONTACT:
DISCORD = ""
EMAIL = ""
CONTACT = {}

HOMEPAGE_URL = "https://twitchlink.github.io/"

Expand All @@ -24,4 +22,4 @@ def getCopyrightInfo(cls):

@classmethod
def getProjectInfo(cls):
return f"{cls.APP_NAME} {cls.VERSION}\n\n[Author]\n{cls.AUTHOR}\n\n[License]\n{cls.LICENSE} License\n\n{cls.getCopyrightInfo()}"
return f"{cls.APP_NAME} {cls.APP_VERSION}\n\n[Author]\n{cls.AUTHOR}\n\n[License]\n{cls.LICENSE} License\n\n{cls.getCopyrightInfo()}"
2 changes: 1 addition & 1 deletion Core/Qt/QtWebEngineWidgets/QWebEngineProfile.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ def __init__(self, parent=None):
self.setupProfile()

def setupProfile(self):
self.setHttpUserAgent(re.sub("QtWebEngine/\S* Chrome/\S*", f"{Config.APP_NAME}/{Config.VERSION}", self.httpUserAgent()))
self.setHttpUserAgent(re.sub("QtWebEngine/\S* Chrome/\S*", f"{Config.APP_NAME}/{Config.APP_VERSION}", self.httpUserAgent()))

@classmethod
def setup(cls):
Expand Down
125 changes: 74 additions & 51 deletions Core/Updater.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
from Core.Config import Config
from Services.NetworkRequests import Network
from Services.Utils.OSUtils import OSUtils
from Services.Utils.Utils import Utils
from Services.NotificationManager import NotificationManager
from Services.ContentManager import ContentManager
from Services.Translator.Translator import Translator
from Services.Document import DocumentData, DocumentButtonData

from PyQt5 import QtCore

Expand All @@ -17,6 +17,10 @@ class UnexpectedError(Exception):
def __str__(self):
return "Unexpected Error"

class SessionExpired(Exception):
def __str__(self):
return "Session Expired"

class Unavailable(Exception):
def __str__(self):
return "Unavailable"
Expand All @@ -33,82 +37,91 @@ def __str__(self):
class _Status:
CONNECTION_FAILURE = 0
UNEXPECTED_ERROR = 1
UNAVAILABLE = 2
UPDATE_REQUIRED = 3
UPDATE_FOUND = 4
AVAILABLE = 5

SESSION_EXPIRED = 2
UNAVAILABLE = 3
UPDATE_REQUIRED = 4
UPDATE_FOUND = 5
AVAILABLE = 6

class Version:
def __init__(self, data):
self.latestVersion = data.get("latestVersion")
self.updateRequired = not Config.VERSION in data.get("compatibleVersions", []) and self.latestVersion != Config.VERSION
self.updateRequired = not Config.APP_VERSION in data.get("compatibleVersions", []) and self.latestVersion != Config.APP_VERSION
updateNoteData = data.get("updateNote", {}).get(Translator.getLanguage(), {})
self.updateNote = updateNoteData.get("content")
self.updateNoteType = updateNoteData.get("contentType")
self.updateUrl = data.get("updateUrl", Config.HOMEPAGE_URL)

def __init__(self):
self.setStatus(self.UNAVAILABLE)
self.updateStatusData({})
self.updateNotifications({})
self.update({})

def updateStatusData(self, data):
def update(self, data):
self.session = data.get("session", None)
self.sessionStrict = data.get("sessionStrict", True)
self.operational = data.get("operational", False)
operationalInfoData = data.get("operationalInfo", {}).get(Translator.getLanguage(), {})
self.operationalInfo = operationalInfoData.get("content")
self.operationalInfoType = operationalInfoData.get("contentType")
self.operationalInfo = operationalInfoData.get("content", "")
self.operationalInfoType = operationalInfoData.get("contentType", "")
self.version = self.Version(data.get("version", {}))

def updateNotifications(self, data):
self.notifications = [
DocumentData(
contentId=notification.get("contentId", None),
contentVersion=notification.get("contentVersion", 0),
title=notification.get("title", ""),
content=notification.get("content", ""),
contentType=notification.get("contentType", ""),
modal=notification.get("modal", False),
blockExpiry=notification.get("blockExpiry", False),
buttons=[
DocumentButtonData(
text=button.get("text", ""),
action=button.get("action", None),
role=button.get("role", "accept"),
default=button.get("default", False)
) for button in notification.get("buttons", [])
]
) for notification in data.get(Translator.getLanguage(), []) if Config.VERSION in notification.get("targetVersion", [Config.VERSION])
]

def setStatus(self, appStatus):
self.appStatus = appStatus

def getStatus(self):
return self.appStatus

def isOperational(self):
return self.appStatus == self.UPDATE_FOUND or self.appStatus == self.AVAILABLE
return self.getStatus() == self.UPDATE_FOUND or self.getStatus() == self.AVAILABLE


class _Updater(QtCore.QObject):
updateProgress = QtCore.pyqtSignal(int)
updateComplete = QtCore.pyqtSignal()
statusUpdated = QtCore.pyqtSignal()
configUpdated = QtCore.pyqtSignal()

MAX_REDIRECT_COUNT = 10
TOTAL_TASK_COUNT = 4

def __init__(self, parent=None):
super(_Updater, self).__init__(parent=parent)
self.status = _Status()
self._autoUpdateEnabled = False
self._updateThread = Utils.WorkerThread(target=self._updateProcess, parent=self)
self._updateThread.finished.connect(self._updateCompleteHandler)
self._updateTimer = QtCore.QTimer(parent=self)
self._updateTimer.setSingleShot(True)
self._updateTimer.timeout.connect(self.update)
self.configUpdated.connect(self.configUpdateHandler)
self.configUpdateHandler()

def configUpdateHandler(self):
self._updateTimer.setInterval(Config.STATUS_UPDATE_INTERVAL)

def startAutoUpdate(self):
if not self._autoUpdateEnabled:
self._autoUpdateEnabled = True
self._updateTimer.start()

def stopAutoUpdate(self):
if self._autoUpdateEnabled:
self._autoUpdateEnabled = False
self._updateTimer.stop()

def update(self):
self._updateThread.start()

def _updateCompleteHandler(self):
if self._autoUpdateEnabled:
self._updateTimer.start()

def _updateProcess(self):
previousStatus = self.status.getStatus()
try:
self.updateProgress.emit(0)
try:
self.updateStatus()
except Exceptions.Unavailable:
self.status.setStatus(self.status.UNAVAILABLE)
except Exceptions.UpdateFound:
self.status.setStatus(self.status.UPDATE_FOUND)
else:
Expand All @@ -124,14 +137,20 @@ def update(self):
self.status.setStatus(self.status.CONNECTION_FAILURE)
except Exceptions.UnexpectedError:
self.status.setStatus(self.status.UNEXPECTED_ERROR)
except Exceptions.SessionExpired:
self.status.setStatus(self.status.SESSION_EXPIRED)
except Exceptions.Unavailable:
self.status.setStatus(self.status.UNAVAILABLE)
except:
self.status.setStatus(self.status.UPDATE_REQUIRED)
self.updateComplete.emit()
if self.status.getStatus() != previousStatus:
self.statusUpdated.emit()

def getData(self, url):
for requestCount in range(self.MAX_REDIRECT_COUNT + 1):
try:
response = Network.session.get(OSUtils.joinUrl(url, params={"version": Config.VERSION}))
response = Network.session.get(Utils.joinUrl(url, params={"version": Config.APP_VERSION}))
if response.status_code == 200:
if response.text.startswith("redirect:"):
url = response.text.split(":", 1)[1]
Expand All @@ -144,31 +163,34 @@ def getData(self, url):
raise Exceptions.ConnectionFailure

def updateStatus(self):
response = self.getData(OSUtils.joinUrl(Config.SERVER_URL, "status.json"))
response = self.getData(Utils.joinUrl(Config.SERVER_URL, "status.json"))
oldSessionKey = self.status.session
try:
data = response.json()
self.status.updateStatusData(data)
self.status.update(data)
except:
raise Exceptions.UpdateRequired
if self.status.operational:
if self.status.version.latestVersion != Config.VERSION:
if self.status.version.updateRequired:
raise Exceptions.UpdateRequired
else:
raise Exceptions.UpdateFound
else:
if self.status.sessionStrict:
if oldSessionKey != self.status.session and oldSessionKey != None and self.status.session != None:
raise Exceptions.SessionExpired
if not self.status.operational:
raise Exceptions.Unavailable
if self.status.version.latestVersion != Config.APP_VERSION:
if self.status.version.updateRequired:
raise Exceptions.UpdateRequired
else:
raise Exceptions.UpdateFound

def updateNotifications(self):
response = self.getData(OSUtils.joinUrl(Config.SERVER_URL, "notifications.json"))
response = self.getData(Utils.joinUrl(Config.SERVER_URL, "notifications.json"))
try:
data = response.json()
self.status.updateNotifications(data)
NotificationManager.updateNotifications(data)
except:
raise Exceptions.UnexpectedError

def updateConfig(self):
response = self.getData(OSUtils.joinUrl(Config.SERVER_URL, "config.json"))
response = self.getData(Utils.joinUrl(Config.SERVER_URL, "config.json"))
try:
from Core.Config import Config as CoreConfig
from Services.Image.Config import Config as ImageConfig
Expand Down Expand Up @@ -214,9 +236,10 @@ def updateConfig(self):
setattr(configTarget, configPath[-1], value)
except:
raise Exceptions.UnexpectedError
self.configUpdated.emit()

def updateRestrictions(self):
response = self.getData(OSUtils.joinUrl(Config.SERVER_URL, "restrictions.json"))
response = self.getData(Utils.joinUrl(Config.SERVER_URL, "restrictions.json"))
try:
data = response.json()
ContentManager.setRestrictions(data)
Expand Down
21 changes: 11 additions & 10 deletions Database/Database.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,28 +38,29 @@ def getTermsOfServiceAgreement(self):

class Account(Codable):
def __init__(self):
self._user = TwitchAccount()
self._account = TwitchAccount()

def login(self, username, token, expiry):
self._user.login(username, token, expiry)
self._account.login(username, token, expiry)

def logout(self):
self._user.logout()
self._account.logout()

def updateAccount(self):
self._user.updateAccount()
self._account.updateAccount()

def isUserLoggedIn(self):
return self._user.isConnected()
return self._account.isConnected()

def getAccountData(self):
return self._user.data
@property
def user(self):
return self._account.data

def checkAuthToken(self):
self._user.checkToken()
self._account.checkToken()

def getAuthToken(self):
return self._user.token
return self._account.token

class General(Codable):
def __init__(self):
Expand Down Expand Up @@ -245,7 +246,7 @@ def getDownloadSpeed(self):

class Database:
def __init__(self):
self.version = Config.VERSION
self.version = Config.APP_VERSION
self.reset()
App.aboutToQuit.connect(self.save)

Expand Down
18 changes: 15 additions & 3 deletions Database/Updater.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,19 @@ def Update_2_2_0(data):

@staticmethod
def Update_2_2_2(data):
data["temp"].pop("_downloadHistory", None)
data["temp"]["_downloadOptionHistory"]["stream"].pop("_optimizeFile", None)
if "temp" in data:
data["temp"].pop("_downloadHistory", None)
data["temp"]["_downloadOptionHistory"]["stream"].pop("_optimizeFile", None)
return data

@staticmethod
def Update_2_2_3(data):
if "account" in data:
if "_user" in data["account"]:
data["account"]["_account"] = data["account"].pop("_user")
if "temp" in data:
data["temp"].pop("_downloadHistory", None)
data["temp"]["_downloadOptionHistory"]["video"].pop("_optimizeFile", None)
return data

@classmethod
Expand All @@ -79,7 +90,8 @@ def getUpdaters(cls, versionFrom):
"2.1.0": None,
"2.2.0": cls.Update_2_2_0,
"2.2.1": None,
"2.2.2": cls.Update_2_2_2
"2.2.2": cls.Update_2_2_2,
"2.2.3": cls.Update_2_2_3
}
updaters = []
versionFound = False
Expand Down
Loading

0 comments on commit e180897

Please sign in to comment.