Skip to content

Commit

Permalink
Icon update, config migrated to appdata, MacOS also works correctly.
Browse files Browse the repository at this point in the history
  • Loading branch information
ozankaraali committed May 26, 2024
1 parent 887c135 commit 7a4fc8e
Show file tree
Hide file tree
Showing 10 changed files with 158 additions and 159 deletions.
12 changes: 6 additions & 6 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -104,12 +104,12 @@ jobs:
run: |
pip install pyinstaller
pyinstaller qitv-macos.spec
- name: Rename the executable
run: mv dist/qitv.app/Contents/MacOS/qitv dist/qitv.app/Contents/MacOS/qitv_cli
- name: Create launcher script
run: |
printf '#!/bin/bash\nopen -n "$(dirname "$0")/qitv_cli"\n' > dist/qitv.app/Contents/MacOS/qitv
chmod +x dist/qitv.app/Contents/MacOS/qitv
# - name: Rename the executable
# run: mv dist/qitv.app/Contents/MacOS/qitv dist/qitv.app/Contents/MacOS/qitv_cli
# - name: Create launcher script
# run: |
# printf '#!/bin/bash\nopen -n "$(dirname "$0")/qitv_cli"\n' > dist/qitv.app/Contents/MacOS/qitv
# chmod +x dist/qitv.app/Contents/MacOS/qitv
- name: Ad-Hoc Sign the app
run: codesign --force --deep --sign - dist/qitv.app
- name: Zip macOS App
Expand Down
Binary file modified assets/qitv.icns
Binary file not shown.
Binary file modified assets/qitv.ico
Binary file not shown.
Binary file modified assets/qitv.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
86 changes: 11 additions & 75 deletions channel_list.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
QLineEdit,
QGridLayout,
)
from PyQt5.QtGui import QIcon
from urlobject import URLObject

from options import OptionsDialog
Expand All @@ -29,12 +30,16 @@
class ChannelList(QMainWindow):
channels_loaded = pyqtSignal(list)

def __init__(self, app, player):
def __init__(self, app, player, config_manager):
super().__init__()
self.app = app
self.player = player
self.link = None
self.config_manager = config_manager
self.config = self.config_manager.config
self.config_manager.apply_window_settings("channel_list", self)

self.setWindowTitle("QiTV Channel List")
self.setWindowIcon(QIcon("assets/qitv.png"))

self.container_widget = QWidget(self)
self.setCentralWidget(self.container_widget)
Expand All @@ -43,16 +48,13 @@ def __init__(self, app, player):
self.create_upper_panel()
self.create_left_panel()
self.create_media_controls()

self.load_config()
self.apply_window_settings()
self.load_channels()

def closeEvent(self, event):
self.player.close()
self.save_window_settings()
self.save_config()
self.app.quit()
self.player.close()
self.config_manager.save_window_settings(self.geometry(), "channel_list")
event.accept()

def create_upper_panel(self):
self.upper_layout = QWidget(self.container_widget)
Expand Down Expand Up @@ -146,74 +148,8 @@ def open_file(self):
if file_path:
self.player.play_video(file_path)

def load_config(self):
try:
with open("config.json", "r") as f:
self.config = json.load(f)
if self.config is None:
self.config = self.default_config()
except (FileNotFoundError, json.JSONDecodeError):
self.config = self.default_config()
self.save_config()

selected_config = self.config["data"][self.config["selected"]]
if "options" in selected_config:
self.options = selected_config["options"]
self.token = self.options["headers"]["Authorization"].split(" ")[1]
else:
self.options = {
"headers": {
"User-Agent": "Mozilla/5.0 (QtEmbedded; U; Linux; C) AppleWebKit/533.3 (KHTML, like Gecko) MAG200 stbapp ver: 2 rev: 250 Safari/533.3",
"Accept-Charset": "UTF-8,*;q=0.8",
"X-User-Agent": "Model: MAG200; Link: Ethernet",
"Content-Type": "application/json",
}
}

self.url = selected_config.get("url")
self.mac = selected_config.get("mac")

@staticmethod
def default_config():
return {
"selected": 0,
"data": [
{
"type": "M3UPLAYLIST",
"url": "https://iptv-org.github.io/iptv/index.m3u",
}
],
"window_positions": {
"channel_list": {"x": 1250, "y": 100, "width": 400, "height": 800},
"video_player": {"x": 50, "y": 100, "width": 1200, "height": 800},
},
}

def save_config(self):
with open("config.json", "w") as f:
json.dump(self.config, f)

def save_window_settings(self):
pos = self.geometry()
window_positions = self.config.get("window_positions", {})
window_positions["channel_list"] = {
"x": pos.x(),
"y": pos.y(),
"width": pos.width(),
"height": pos.height(),
}
self.config["window_positions"] = window_positions
self.save_config()

def apply_window_settings(self):
window_positions = self.config.get("window_positions", {})
channel_list_pos = window_positions.get("channel_list", {})
self.setGeometry(
channel_list_pos.get("x", 1250),
channel_list_pos.get("y", 100),
channel_list_pos.get("width", 400),
channel_list_pos.get("height", 800),
)
self.config_manager.save_config()

def load_channels(self):
selected_provider = self.config["data"][self.config["selected"]]
Expand Down
105 changes: 105 additions & 0 deletions config_manager.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
import json
import os
import platform
import shutil


class ConfigManager:
def __init__(self):
self.config = {}
self.options = {}
self.token = ""
self.url = ""
self.mac = ""
self.config_path = self._get_config_path()
self._migrate_old_config()
self.load_config()

def _get_config_path(self):
app_name = 'qitv'
if platform.system() == 'Linux':
config_dir = os.path.join(os.getenv('HOME', ''), f'.config/{app_name}')
elif platform.system() == 'Darwin': # macOS
config_dir = os.path.join(os.getenv('HOME', ''), f'Library/Application Support/{app_name}')
elif platform.system() == 'Windows':
config_dir = os.path.join(os.getenv('APPDATA', ''), app_name)
else:
raise RuntimeError("Unsupported operating system")

os.makedirs(config_dir, exist_ok=True)
return os.path.join(config_dir, 'config.json')

def _migrate_old_config(self):
try:
old_config_path = 'config.json'
if os.path.isfile(old_config_path) and not os.path.isfile(self.config_path):
shutil.copy(old_config_path, self.config_path)
os.remove(old_config_path)
except Exception as e:
print(f"Error during config migration: {e}")

def load_config(self):
try:
with open(self.config_path, "r") as f:
self.config = json.load(f)
if self.config is None:
self.config = self.default_config()
except (FileNotFoundError, json.JSONDecodeError):
self.config = self.default_config()
self.save_config()

try:
selected_config = self.config["data"][self.config["selected"]]
except IndexError:
self.config = self.default_config()
self.save_config()
selected_config = self.config["data"][self.config["selected"]]

if "options" in selected_config:
self.options = selected_config["options"]
self.token = self.options["headers"]["Authorization"].split(" ")[1]
else:
self.options = {
"headers": {
"User-Agent": "Mozilla/5.0 (QtEmbedded; U; Linux; C) AppleWebKit/533.3 (KHTML, like Gecko) MAG200 stbapp ver: 2 rev: 250 Safari/533.3",
"Accept-Charset": "UTF-8,*;q=0.8",
"X-User-Agent": "Model: MAG200; Link: Ethernet",
"Content-Type": "application/json",
}
}

self.url = selected_config.get("url")
self.mac = selected_config.get("mac")

@staticmethod
def default_config():
return {
"selected": 0,
"data": [
{
"type": "M3UPLAYLIST",
"url": "https://iptv-org.github.io/iptv/index.m3u",
}
],
"window_positions": {
"channel_list": {"x": 1250, "y": 100, "width": 400, "height": 800},
"video_player": {"x": 50, "y": 100, "width": 1200, "height": 800},
},
}

def save_window_settings(self, pos, window_name):
self.config["window_positions"][window_name] = {
"x": pos.x(),
"y": pos.y(),
"width": pos.width(),
"height": pos.height(),
}
self.save_config()

def apply_window_settings(self, window_name, window):
settings = self.config["window_positions"][window_name]
window.setGeometry(settings["x"], settings["y"], settings["width"], settings["height"])

def save_config(self):
with open(self.config_path, "w") as f:
json.dump(self.config, f, indent=4)
6 changes: 4 additions & 2 deletions main.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,13 @@

from video_player import VideoPlayer
from channel_list import ChannelList
from config_manager import ConfigManager

if __name__ == "__main__":
app = QApplication(sys.argv)
player = VideoPlayer()
channel_list = ChannelList(app, player)
config_manager = ConfigManager()
player = VideoPlayer(config_manager)
channel_list = ChannelList(app, player, config_manager)
qdarktheme.setup_theme("auto")
player.show()
channel_list.show()
Expand Down
7 changes: 2 additions & 5 deletions options.py
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ def add_new_provider(self):
self.load_providers()

def remove_provider(self):
if self.provider_combo.currentIndex() == -1:
if self.provider_combo.currentIndex() == 0:
return
del self.config["data"][self.provider_combo.currentIndex()]
self.selected_provider_index = max(0, self.provider_combo.currentIndex() - 1)
Expand All @@ -134,10 +134,7 @@ def save_settings(self):
else "M3UPLAYLIST" if self.type_M3UPLAYLIST.isChecked() else "M3USTREAM"
)
self.parent().save_config()
self.parent().do_handshake(
self.url_input.text(), self.mac_input.text(), load=True
)
# self.parent().load_channels()
self.parent().load_channels()
self.accept()

def load_file(self):
Expand Down
29 changes: 20 additions & 9 deletions qitv-macos.spec
Original file line number Diff line number Diff line change
Expand Up @@ -32,22 +32,33 @@ exe = EXE(
#a.binaries,
a.datas,
[],
name='qitv',
name='QiTV',
debug=False,
bootloader_ignore_signals=False,
strip=False,
upx=True,
upx_exclude=[],
runtime_tmpdir=None,
console=False,
disable_windowed_traceback=False,
argv_emulation=False,
target_arch=None,
codesign_identity=None,
entitlements_file=None,
icon='assets/qitv.icns',
)
app = BUNDLE(
exe,
name='qitv.app',
name='QiTV.app',
icon='assets/qitv.icns',
bundle_identifier=None,
)
bundle_identifier='com.ozankaraali.QiTV',
version='1.1.2',
info_plist={
'CFBundleDisplayName': 'QiTV',
'CFBundleExecutable': 'QiTV',
'CFBundleIdentifier': 'com.ozankaraali.QiTV',
'CFBundleInfoDictionaryVersion': '6.0',
'CFBundleName': 'QiTV',
'CFBundlePackageType': 'APPL',
'CFBundleShortVersionString': '1.0.0',
'CFBundleVersion': '1.0.0',
'LSApplicationCategoryType': 'public.app-category.video',
'NSHighResolutionCapable': True,
'NSPrincipalClass': 'NSApplication',
}
)
Loading

0 comments on commit 7a4fc8e

Please sign in to comment.