Commit 4d447ac0 authored by librebob's avatar librebob

Add logging when doing update/upgrade.

Add filtering by recent.
parent 3e996cbb
......@@ -85,7 +85,7 @@ Page {
}
MenuItem {
text: qsTr('Recent')
// onTriggered: Qt.quit()
onTriggered: window.filterRecent()
}
MenuSeparator { }
MenuItem {
......@@ -134,6 +134,10 @@ Page {
text: qsTr('Settings')
onTriggered: stackView.push(settingsView)
}
MenuItem {
text: qsTr('Check For Updates')
onTriggered: window.checkAll()
}
MenuItem {
text: qsTr('Update All')
onTriggered: window.updateAll()
......@@ -157,9 +161,10 @@ Page {
boundsBehavior: Flickable.StopAtBounds
keyNavigationEnabled: true
focus: true
Keys.onDownPressed: {
console.log(listView.currentIndex)
onCurrentItemChanged:{
window.indexUpdated(listView.currentIndex)
}
delegate: Component {
id: delegateComponent
Rectangle {
......@@ -172,8 +177,8 @@ Page {
MouseArea {
anchors.fill: parent
onClicked: {
window.indexUpdated(index)
listView.currentIndex = index
listView.forceActiveFocus()
}
id: itemMouseArea
hoverEnabled: true
......@@ -201,6 +206,7 @@ Page {
anchors.left: gameIcon.right
anchors.top: parent.top
anchors.bottom: parent.bottom
anchors.right: parent.right
text: name
anchors.topMargin: 5
anchors.rightMargin: 5
......@@ -208,12 +214,33 @@ Page {
verticalAlignment: Text.AlignVCenter
}
BusyIndicator {
visible: false
height: parent.height
width: parent.height
id: gameProcessing
anchors.right: parent.right
running: processing
}
Rectangle {
visible: false
height: parent.height
width: parent.height
anchors.right: parent.right
color: tr
Rectangle {
width: childrenRect.width
height: childrenRect.height
anchors.centerIn: parent
color: sel
radius: 3
Text {
text: qsTr('New')
font.pixelSize: 12
padding: 3
color: tc
}
}
}
}
}
}
......@@ -337,6 +364,22 @@ Page {
color: library.currentGame.playing ? 'lightgreen' : 'lightblue'
}
}
// Button {
// text: qsTr('Update')
// visible: library.currentGame.hasUpdates && library.currentGame.installed
// enabled: !library.currentGame.playing && !library.currentGame.processing
// icon.source: 'icons/refresh.svg'
// icon.height: 16
// icon.width: 16
// onClicked: {
// window.updateGame(library.currentGame.id)
// }
// background: Rectangle {
// implicitWidth: 40
// implicitHeight: 40
// color: dg
// }
// }
Button {
text: qsTr('Uninstall')
visible: library.currentGame.installed
......
......@@ -3,7 +3,7 @@ from datetime import datetime
from PyQt5.QtCore import QObject, pyqtProperty, pyqtSignal, QProcess
from PyQt5.QtQml import QQmlListProperty
from models import getGame, setGame
from models import setGame
class Url(QObject):
typeChanged = pyqtSignal()
......@@ -148,6 +148,7 @@ class Game(QObject):
refChanged = pyqtSignal()
installedChanged = pyqtSignal()
lastPlayedDateChanged = pyqtSignal()
playingChanged = pyqtSignal()
processingChanged = pyqtSignal()
......@@ -160,7 +161,7 @@ class Game(QObject):
iconSmall='',
iconLarge='',
license='',
developer_name='',
developerName='',
summary='',
description='',
screenshots=[],
......@@ -169,6 +170,7 @@ class Game(QObject):
urls=[],
ref='',
installed=False,
lastPlayedDate=None,
*args,
**kwargs):
super().__init__(*args, **kwargs)
......@@ -178,9 +180,8 @@ class Game(QObject):
self._iconSmall = iconSmall
self._iconLarge = iconLarge
self._license = license
self._developerName = developer_name
self._developerName = developerName
self._summary = summary
self._description = description
self._screenshots = screenshots
......@@ -191,6 +192,7 @@ class Game(QObject):
self._ref = ref
self._installed = installed
self._lastPlayedDate = lastPlayedDate
# Dynamic values
self._playing = False
......@@ -345,6 +347,15 @@ class Game(QObject):
self._installed = installed
self.installedChanged.emit()
@pyqtProperty(bool, notify=lastPlayedDateChanged)
def lastPlayedDate(self):
return self._lastPlayedDate
@lastPlayedDate.setter
def lastPlayedDate(self, lastPlayedDate):
self._lastPlayedDate = lastPlayedDate
self.lastPlayedDateChanged.emit()
@pyqtProperty(bool, notify=processingChanged)
def processing(self):
return self._processing
......@@ -370,6 +381,8 @@ class Game(QObject):
def stopGame(self):
self.playing = False
self.lastPlayedDate = datetime.now()
self.save()
print('stop game')
def startInstall(self):
......@@ -378,7 +391,7 @@ class Game(QObject):
def finishInstall(self, process):
self.processing = False
self.installed = True
setGame(id=self.id, installed=self.installed)
self.save()
self.appendLog(process, finished=True)
def startUninstall(self):
......@@ -387,7 +400,7 @@ class Game(QObject):
def finishUninstall(self, process):
self.processing = False
self.installed = False
setGame(id=self.id, installed=self.installed)
self.save()
self.appendLog(process, finished=True)
def startUpdate(self):
......@@ -410,3 +423,6 @@ class Game(QObject):
else:
self._log = self._log + log_data
self.logChanged.emit()
def save(self):
setGame(self)
from time import sleep
from functools import partial
from datetime import datetime, timedelta
import operator
from PyQt5.QtCore import QObject, pyqtProperty, pyqtSignal, QProcess
from PyQt5.QtQml import QQmlListProperty
from peewee import DoesNotExist
from models import GameRecord
from game import Game
import appstream
......@@ -149,6 +147,14 @@ class Library(QObject):
if game.installed:
self.appendFilter(game)
def filterRecent(self):
self.filter = []
now = datetime.now()
for game in self._games:
if game.lastPlayedDate:
if (game.lastPlayedDate + timedelta(days=3)) > now:
self.appendFilter(game)
def sortAZ(self):
self._filter.sort(key = lambda idx: operator.attrgetter('name')(idx).lower())
self.filterChanged.emit()
......
......@@ -13,6 +13,7 @@ class Loader(QObject):
stateChanged = pyqtSignal()
messageChanged = pyqtSignal()
errorChanged = pyqtSignal()
logChanged = pyqtSignal()
gameLoaded = pyqtSignal(Game)
arch = 'x86_64'
......@@ -27,7 +28,9 @@ class Loader(QObject):
'Constructing castles...',
'Collecting cow bells...',
'Summoning demons...',
'Building power plants...'
'Building power plants...',
'Planting mines...',
'Evolving...'
]
def __init__(self, *args, **kwargs):
......@@ -40,37 +43,56 @@ class Loader(QObject):
self._message = random.choice(self.messages)
self._appsteamPath = QStandardPaths.writableLocation(QStandardPaths.GenericDataLocation) + '/flatpak/appstream/{remote}/{arch}/active/appstream.xml.gz'
self._iconsPath = QStandardPaths.writableLocation(QStandardPaths.GenericDataLocation) + '/flatpak/appstream/{remote}/{arch}/active/icons'
self._log = ''
self._installed_list = ''
self._updates_list = ''
def load(self):
if getMeta(self.metaKey):
self.loadAppstream()
else:
self.runCommands()
self.runUpdateCommands()
def runCommands(self, proc_number=0):
def runUpdateCommands(self, proc_number=0):
commandProcess = QProcess()
commandProcess.finished.connect(partial(self._processes.remove, commandProcess))
commandProcess.errorOccurred.connect(self.handleError)
commandProcess.readyReadStandardOutput.connect(partial(self.appendLog, commandProcess))
if proc_number == 0:
commandProcess.started.connect(self.startLoading)
commandProcess.finished.connect(partial(self.runCommands, 1))
commandProcess.finished.connect(partial(self.runUpdateCommands, 1))
commandProcess.start('flatpak', ['remote-add', '--if-not-exists', '--user', self.flatHub['name'], self.flatHub['url']])
elif proc_number == 1:
commandProcess.finished.connect(partial(self.runCommands, 2))
commandProcess.start('flatpak', ['remote-ls', '--updates', '--user'])
elif proc_number == 2:
commandProcess.finished.connect(partial(self.runCommands, 3))
commandProcess.finished.connect(partial(self.runUpdateCommands, 2))
commandProcess.start('flatpak', ['update', '--appstream', '--user'])
elif proc_number == 3:
commandProcess.finished.connect(partial(self.runCommands, 4))
commandProcess.start('flatpak', ['update', '--user'])
elif proc_number == 4:
commandProcess.finished.connect(partial(self.loadAppstream, commandProcess))
elif proc_number == 2:
commandProcess.finished.connect(self.runListCommands)
commandProcess.start('flatpak', ['update', '--user', '-y'])
self._processes.append(commandProcess)
def runListCommands(self, proc_number=0):
commandProcess = QProcess()
commandProcess.finished.connect(partial(self._processes.remove, commandProcess))
commandProcess.errorOccurred.connect(self.handleError)
if proc_number == 0:
commandProcess.started.connect(self.startLoading)
commandProcess.finished.connect(partial(self.runListCommands, 1))
commandProcess.finished.connect(partial(self.loadListData, commandProcess, proc_number))
commandProcess.start('flatpak', ['list', '--user'])
if proc_number == 1:
commandProcess.finished.connect(partial(self.loadListData, commandProcess, proc_number))
commandProcess.start('flatpak', ['remote-ls', '--updates', '--user'])
self._processes.append(commandProcess)
def loadListData(self, process, proc_number):
if proc_number == 0:
self._installed_list = str(process.readAllStandardOutput(), 'utf-8')
if proc_number == 1:
self._updates_list = str(process.readAllStandardOutput(), 'utf-8')
self.loadAppstream(process=True)
def loadAppstream(self, process=None):
if process:
installed_list = str(process.readAllStandardOutput(), 'utf-8')
stream = appstream.Store()
stream.from_file(self._appsteamPath.format(remote=self.flatHub['name'], arch=self.arch))
......@@ -78,35 +100,40 @@ class Loader(QObject):
if component.project_license:
if not 'LicenseRef-proprietary' in component.project_license:
if not 'CC-BY-NC-SA' in component.project_license:
if 'Game' in component.categories or 'Games' in component.categories:
if 'Game' in component.categories:
installed = False
last_played_date = None
if process:
installed = component.bundle['value'][4:] in installed_list
setGame(component.id, installed)
name = component.bundle['value'][4:]
installed = name in self._installed_list
else:
gr = getGame(component.id)
if gr:
installed = gr.installed
else:
installed = False
self.gameLoaded.emit(
Game(
id=component.id,
name=component.name,
iconSmall=self.getIconSmall(component.icons),
iconLarge=self.getIconLarge(component.icons),
license=component.project_license,
developer_name=component.developer_name,
summary=component.summary,
description=component.description,
screenshots=self.getScreenshots(component.screenshots),
categories=component.categories,
releases=self.getReleases(component.releases),
urls=self.getUrls(component.urls),
ref=component.bundle['value'],
installed=installed
)
last_played_date = gr.last_played_date
game = Game(
id=component.id,
name=component.name,
iconSmall=self.getIconSmall(component.icons),
iconLarge=self.getIconLarge(component.icons),
license=component.project_license,
developerName=component.developer_name,
summary=component.summary,
description=component.description,
screenshots=self.getScreenshots(component.screenshots),
categories=component.categories,
releases=self.getReleases(component.releases),
urls=self.getUrls(component.urls),
ref=component.bundle['value'],
installed=installed,
lastPlayedDate=last_played_date
)
if process:
setGame(game=game)
self.gameLoaded.emit(game)
self.finishLoading()
def getIconSmall(self, icons):
......@@ -210,6 +237,16 @@ class Loader(QObject):
self._error = error
self.stateChanged.emit()
@pyqtProperty(str, notify=logChanged)
def log(self):
return self._log
@log.setter
def log(self, log):
if log != self._log:
self._log = log
self.logChanged.emit()
@pyqtProperty(str, notify=stateChanged)
def message(self):
return self._message
......@@ -233,6 +270,21 @@ class Loader(QObject):
self.loading = False
self.finished.emit()
def appendLog(self, process, finished=False):
log_data = str(process.readAllStandardOutput(), 'utf-8')
if finished:
pass
else:
if log_data[:1] == '\r':
rs = self._log.rsplit('\r', 1)
if len(rs) > 1:
self._log = rs[0] + log_data
else:
self._log = self._log.rsplit('\n', 1)[0] + log_data
else:
self._log = self._log + log_data
self.logChanged.emit()
def handleError(self, error):
self._timer.stop()
self.error = True
......
import signal
from sys import argv
import signal, os, sys
from PyQt5.QtGui import QGuiApplication
from PyQt5.QtCore import QTranslator, QLocale
......@@ -17,7 +16,7 @@ def main():
db.connect()
db.create_tables([GameRecord, MetaRecord, SettingsRecord], safe=True)
app = QGuiApplication(argv)
app = QGuiApplication(sys.argv)
app.setApplicationDisplayName('Athenaeum')
app.setQuitOnLastWindowClosed(True)
......@@ -30,8 +29,8 @@ def main():
qmlRegisterType(Library, 'Athenaeum', 1, 0, 'Library')
qmlRegisterType(Loader, 'Athenaeum', 1, 0, 'Loader')
loader = Loader()
library = Library()
loader = Loader(parent=app)
library = Library(parent=app)
loader.started.connect(library.reset)
loader.finished.connect(library.load)
......@@ -50,17 +49,19 @@ def main():
engine.rootObjects()[0].uninstallGame.connect(library.uninstallGame)
engine.rootObjects()[0].updateGame.connect(library.updateGame)
engine.rootObjects()[0].playGame.connect(library.playGame)
engine.rootObjects()[0].updateAll.connect(loader.runCommands)
engine.rootObjects()[0].updateAll.connect(loader.runUpdateCommands)
engine.rootObjects()[0].checkAll.connect(loader.runListCommands)
engine.rootObjects()[0].search.connect(library.search)
engine.rootObjects()[0].filterAll.connect(library.filterAll)
engine.rootObjects()[0].filterInstalled.connect(library.filterInstalled)
# engine.rootObjects()[0].filterFavourites.connect(library.filterFavourites)
# engine.rootObjects()[0].filterRecent.connect(library.filterRecent)
engine.rootObjects()[0].filterRecent.connect(library.filterRecent)
engine.rootObjects()[0].sortAZ.connect(library.sortAZ)
engine.rootObjects()[0].sortZA.connect(library.sortZA)
exit(app.exec_())
os._exit(app.exec())
if __name__ == '__main__':
main()
......@@ -12,10 +12,11 @@ ApplicationWindow {
signal playGame(string id)
signal search(string query)
signal updateAll()
signal checkAll()
signal filterAll()
signal filterInstalled()
// signal filterFavourites()
// signal filterRecent()
signal filterRecent()
signal sortAZ()
signal sortZA()
......@@ -58,6 +59,35 @@ ApplicationWindow {
topPadding: 10
horizontalAlignment: Text.AlignHCenter
}
/* Logs */
Rectangle {
anchors.left: parent.left
anchors.right: parent.right
anchors.rightMargin: 40
anchors.leftMargin: 40
anchors.bottom: parent.bottom
color: bg
height: 150
Flickable {
id: testFlick
anchors.fill: parent
clip: true
boundsBehavior: Flickable.StopAtBounds
TextArea {
id: ta
onContentHeightChanged: {
testFlick.contentY = (contentHeight <= 150 ? 0 : contentHeight - 150)
}
color: tc
readOnly: true
text: loader.log
}
}
}
}
}
......@@ -12,6 +12,7 @@ class GameRecord(BaseModel):
installed = BooleanField(default=False)
created_date = DateTimeField(default=datetime.datetime.now)
modified_date = DateTimeField()
last_played_date = DateTimeField(null=True)
class MetaRecord(BaseModel):
key = CharField(unique=True)
......@@ -36,9 +37,10 @@ def getGame(id):
except DoesNotExist:
return None
def setGame(id, installed):
def setGame(game):
GameRecord.replace(
id=id,
installed=installed,
id=game.id,
installed=game.installed,
last_played_date=game.lastPlayedDate,
modified_date=datetime.datetime.now()
).execute()
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment