diff --git a/ikinuki_client/__main__.py b/ikinuki_client/__main__.py index 8936830..d763fe1 100644 --- a/ikinuki_client/__main__.py +++ b/ikinuki_client/__main__.py @@ -1,4 +1,8 @@ from typing import Type + +import sys +from urllib import parse + from PyQt5.QtWidgets import QApplication from PyQt5.QtQml import qmlRegisterType, QQmlApplicationEngine from PyQt5.QtQuick import QQuickView @@ -6,24 +10,62 @@ from PyQt5.QtCore import QObject, QUrl, pyqtProperty from .qtmpv import MpvObject -import sys +import requests + + +class Show(QObject): + def __init__(self, name, parent=None): + super().__init__(parent) + self._name = name + + @pyqtProperty("QString") + def name(self): + return self._name + + +def getUrl(base: str, path: str) -> dict: + url: str = parse.urljoin(base, path) + r: requests.Response = requests.get(url) + return r.json() class Provider(QObject): - def __init__(self, name, parent=None): + def __init__(self, ip: str, port: int, parent=None): super().__init__(parent) - self.name = name - # self.ip = ip - # self.port = port + self.url: str = f"http://{ip}:{port}" + + describe: dict = getUrl(self.url, "describe") + self._name: str = describe["name"] + + shows: dict = getUrl(self.url, "shows") + self._shows: dict[int, dict] = {e["id"]: e for e in shows["data"]} + + recently_added: dict = getUrl(self.url, "recently_added") + self._recently_added: list[int] = recently_added["data"] + + in_progress: dict = getUrl(self.url, "in_progress") + self._in_progress: list[int] = in_progress["data"] @pyqtProperty("QString") - def Name(self): - return self.name + def name(self) -> str: + return self._name + + @pyqtProperty("QObject") + def getShow(self, id) -> dict: + return self._shows[id] + + @pyqtProperty(list) + def recentlyAdded(self) -> list[int]: + return self._recently_added + + @pyqtProperty(list) + def inProgress(self) -> list: + return self._in_progress class DataSource: def __init__(self, providers=[]): - self.providers = [Provider(name) for name in providers] + self.providers = [Provider(ip, port) for (ip, port) in providers] def DatabaseType(data_source) -> Type: @@ -43,7 +85,10 @@ def DatabaseType(data_source) -> Type: def main(): app = QApplication(sys.argv) - data_source = DataSource(["Anime", "TV", "Movies", "Settings"]) + # data_source = DataSource(["Anime", "TV", "Movies", "Settings"]) + data_source = DataSource( + [("127.0.0.1", "8080"), ("127.0.0.1", "8080"), ("127.0.0.1", "8080")] + ) qmlRegisterType(DatabaseType(data_source), "Ikinuki.Client", 1, 0, "Database") # qmlRegisterType(Provider, "Ikinuki.Client", 1, 0, "Provider") diff --git a/layouts/components/ContentView.qml b/layouts/components/ContentView.qml new file mode 100644 index 0000000..b52d4f6 --- /dev/null +++ b/layouts/components/ContentView.qml @@ -0,0 +1,42 @@ +import QtQuick 2.12 + +import Ikinuki.Client 1.0 + +Rectangle { + property var providers + //default property int selectedElement: 0 + //property var max_elements: providers.length + width: parent.width * 0.7 + height: parent.height + color: "#22282A" + Column { + Row { + height: parent.parent.height * 0. + } + } + // anchors.fill: parent + // // header + // SidebarHeader {} + // Repeater { + // model: providers + // SidebarElement { + // name: modelData.name + // selected: (index == selectedElement) ? true : false + // } + // } + + //} + //function mod(n, m) { + // return ((n % m) + m) % m; + //} + //Keys.onPressed: (event)=> { + // // Handle scrolling + // if (event.key == Qt.Key_Down) { + // selectedElement = mod(selectedElement + 1, max_elements); + // } + // else if (event.key == Qt.Key_Up) { + // selectedElement = mod(selectedElement - 1, max_elements); + // } + // event.accepted = true; + //} +} diff --git a/layouts/components/Sidebar.qml b/layouts/components/Sidebar.qml index e9e0b48..d08e3f0 100644 --- a/layouts/components/Sidebar.qml +++ b/layouts/components/Sidebar.qml @@ -4,7 +4,7 @@ import Ikinuki.Client 1.0 Rectangle { property var providers - default property int selectedElement: 2 + default property int selectedElement: 0 property var max_elements: providers.length width: parent.width * 0.3 height: parent.height @@ -16,7 +16,7 @@ Rectangle { Repeater { model: providers SidebarElement { - name: modelData.Name + name: modelData.name selected: (index == selectedElement) ? true : false } } @@ -26,13 +26,13 @@ Rectangle { return ((n % m) + m) % m; } Keys.onPressed: (event)=> { + // Handle scrolling if (event.key == Qt.Key_Down) { selectedElement = mod(selectedElement + 1, max_elements); } else if (event.key == Qt.Key_Up) { selectedElement = mod(selectedElement - 1, max_elements); } - console.log(selectedElement) event.accepted = true; } } diff --git a/layouts/ikinuki-default.qml b/layouts/ikinuki-default.qml index 7e3f254..46e15ba 100644 --- a/layouts/ikinuki-default.qml +++ b/layouts/ikinuki-default.qml @@ -17,24 +17,32 @@ ApplicationWindow { Database { id: database } - //Column { - // Repeater { - // model: database.Providers - // Text { - // text: modelData.Name - // //text: database.getString[0] - // } - // } - //} Row { anchors.fill: parent + focus: true + default property int selectedView: 0 Sidebar { + id: sidebar providers: database.Providers - focus: true } - Column { - width: parent.width * 0.7 - height: parent.height + ContentView { + id: view + providers: database.Providers + } + function mod(n, m) { + return ((n % m) + m) % m; + } + Keys.onPressed: (event)=> { + if (selectedView == 0) { + if (event.key == Qt.Key_Right) { + selectedView = 1; + } + sidebar.Keys.pressed(event); + event.accepted = true; + } else { + + } + event.accepted = true; } } } diff --git a/poetry.lock b/poetry.lock index 211db4a..c8e96f4 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1,3 +1,30 @@ +[[package]] +name = "certifi" +version = "2022.6.15" +description = "Python package for providing Mozilla's CA Bundle." +category = "main" +optional = false +python-versions = ">=3.6" + +[[package]] +name = "charset-normalizer" +version = "2.1.0" +description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." +category = "main" +optional = false +python-versions = ">=3.6.0" + +[package.extras] +unicode_backport = ["unicodedata2"] + +[[package]] +name = "idna" +version = "3.3" +description = "Internationalized Domain Names in Applications (IDNA)" +category = "main" +optional = false +python-versions = ">=3.5" + [[package]] name = "pyqt5" version = "5.15.6" @@ -37,12 +64,55 @@ python-versions = ">=3.5" [package.extras] screenshot_raw = ["pillow"] +[[package]] +name = "requests" +version = "2.28.1" +description = "Python HTTP for Humans." +category = "main" +optional = false +python-versions = ">=3.7, <4" + +[package.dependencies] +certifi = ">=2017.4.17" +charset-normalizer = ">=2,<3" +idna = ">=2.5,<4" +urllib3 = ">=1.21.1,<1.27" + +[package.extras] +socks = ["PySocks (>=1.5.6,!=1.5.7)"] +use_chardet_on_py3 = ["chardet (>=3.0.2,<6)"] + +[[package]] +name = "urllib3" +version = "1.26.11" +description = "HTTP library with thread-safe connection pooling, file post, and more." +category = "main" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*, <4" + +[package.extras] +brotli = ["brotlicffi (>=0.8.0)", "brotli (>=1.0.9)", "brotlipy (>=0.6.0)"] +secure = ["pyOpenSSL (>=0.14)", "cryptography (>=1.3.4)", "idna (>=2.0.0)", "certifi", "ipaddress"] +socks = ["PySocks (>=1.5.6,!=1.5.7,<2.0)"] + [metadata] lock-version = "1.1" python-versions = "^3.10" -content-hash = "78b366b3ef924bc35630263d1f60d58493b2c5eb494cafc5943285e443d42dc3" +content-hash = "7e77956c19bb0148f37be8283857fbd29805184149d6f2c1027daab624c66b80" [metadata.files] +certifi = [ + {file = "certifi-2022.6.15-py3-none-any.whl", hash = "sha256:fe86415d55e84719d75f8b69414f6438ac3547d2078ab91b67e779ef69378412"}, + {file = "certifi-2022.6.15.tar.gz", hash = "sha256:84c85a9078b11105f04f3036a9482ae10e4621616db313fe045dd24743a0820d"}, +] +charset-normalizer = [ + {file = "charset-normalizer-2.1.0.tar.gz", hash = "sha256:575e708016ff3a5e3681541cb9d79312c416835686d054a23accb873b254f413"}, + {file = "charset_normalizer-2.1.0-py3-none-any.whl", hash = "sha256:5189b6f22b01957427f35b6a08d9a0bc45b46d3788ef5a92e978433c7a35f8a5"}, +] +idna = [ + {file = "idna-3.3-py3-none-any.whl", hash = "sha256:84d9dd047ffa80596e0f246e2eab0b391788b0503584e8945f2368256d2735ff"}, + {file = "idna-3.3.tar.gz", hash = "sha256:9d643ff0a55b762d5cdb124b8eaa99c66322e2157b69160bc32796e824360e6d"}, +] pyqt5 = [ {file = "PyQt5-5.15.6-cp36-abi3-macosx_10_13_x86_64.whl", hash = "sha256:33ced1c876f6a26e7899615a5a4efef2167c263488837c7beed023a64cebd051"}, {file = "PyQt5-5.15.6-cp36-abi3-manylinux1_x86_64.whl", hash = "sha256:9d6efad0377aa78bf081a20ac752ce86096ded18f04c592d98f5b92dc879ad0a"}, @@ -78,3 +148,11 @@ pyqt5-sip = [ python-mpv = [ {file = "python-mpv-0.5.2.tar.gz", hash = "sha256:10c7ae61eff441602c7188595108391cdede153c15454772d8811c2bcb9e6823"}, ] +requests = [ + {file = "requests-2.28.1-py3-none-any.whl", hash = "sha256:8fefa2a1a1365bf5520aac41836fbee479da67864514bdb821f31ce07ce65349"}, + {file = "requests-2.28.1.tar.gz", hash = "sha256:7c5599b102feddaa661c826c56ab4fee28bfd17f5abca1ebbe3e7f19d7c97983"}, +] +urllib3 = [ + {file = "urllib3-1.26.11-py2.py3-none-any.whl", hash = "sha256:c33ccba33c819596124764c23a97d25f32b28433ba0dedeb77d873a38722c9bc"}, + {file = "urllib3-1.26.11.tar.gz", hash = "sha256:ea6e8fb210b19d950fab93b60c9009226c63a28808bc8386e05301e25883ac0a"}, +] diff --git a/pyproject.toml b/pyproject.toml index 6166aaa..95dd150 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -9,6 +9,7 @@ license = "GPLv3" python = "^3.10" python-mpv = "^0.5.2" PyQt5 = "^5.15.1" +requests = "^2.28.1" [tool.poetry.scripts]