Skip to content

Commit d9060f0

Browse files
committed
Add the ability to set channels as favorite
1 parent 6bf21af commit d9060f0

File tree

4 files changed

+67
-6
lines changed

4 files changed

+67
-6
lines changed

usr/bin/hypnotix

+3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
#!/bin/sh
22

3+
mkdir -p ~/.cache/hypnotix/favorites
4+
touch ~/.cache/hypnotix/favorites/list
5+
36
mkdir -p ~/.cache/hypnotix/yt-dlp
47
if [ $(gsettings get org.x.hypnotix use-local-ytdlp) = true ]
58
then

usr/lib/hypnotix/common.py

+20-2
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@
1515

1616
TV_GROUP, MOVIES_GROUP, SERIES_GROUP = range(3)
1717

18+
FAVORITES_PATH = os.path.join(GLib.get_user_cache_dir(), "hypnotix", "favorites", "list")
19+
1820
# Used as a decorator to run things in the background
1921
def async_function(func):
2022
def wrapper(*args, **kwargs):
@@ -122,8 +124,12 @@ def __init__(self, provider, info):
122124
break
123125
if ext == ".jpeg":
124126
ext = ".jpg"
125-
self.logo_path = os.path.join(PROVIDERS_PATH, "%s-%s%s" % (slugify(provider.name), slugify(self.name), ext))
126-
127+
if provider is None:
128+
# favorite channel, no provider
129+
provider_name = "favorites"
130+
else:
131+
provider_name = provider.name
132+
self.logo_path = os.path.join(PROVIDERS_PATH, "%s-%s%s" % (slugify(provider_name), slugify(self.name), ext))
127133

128134
class Manager:
129135
def __init__(self, settings):
@@ -284,3 +290,15 @@ def load_channels(self, provider):
284290
provider.movies.append(channel)
285291
else:
286292
provider.channels.append(channel)
293+
294+
def load_favorites(self):
295+
favorites = []
296+
with open(FAVORITES_PATH, 'r') as f:
297+
for line in f:
298+
favorites.append(line.strip())
299+
return favorites
300+
301+
def save_favorites(self, favorites):
302+
with open(FAVORITES_PATH, "w") as f:
303+
for fav in favorites:
304+
f.write(f"{fav}\n")

usr/lib/hypnotix/hypnotix.py

+42-2
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@
3030
from imdb import IMDb
3131
from unidecode import unidecode
3232

33-
from common import Manager, Provider, MOVIES_GROUP, PROVIDERS_PATH, SERIES_GROUP, TV_GROUP,\
33+
from common import Manager, Provider, Channel, MOVIES_GROUP, PROVIDERS_PATH, SERIES_GROUP, TV_GROUP,\
3434
async_function, idle_function
3535

3636

@@ -127,6 +127,7 @@ def __init__(self, application):
127127
self.icon_theme = Gtk.IconTheme.get_default()
128128
self.manager = Manager(self.settings)
129129
self.providers = []
130+
self.favorite_data = []
130131
self.active_provider = None
131132
self.active_group = None
132133
self.active_serie = None
@@ -140,6 +141,8 @@ def __init__(self, application):
140141
self.mpv = None
141142
self.ia = IMDb()
142143

144+
self.page_is_loading = False # used to ignore signals while we set widget states
145+
143146
self.video_properties = {}
144147
self.audio_properties = {}
145148

@@ -262,6 +265,7 @@ def __init__(self, application):
262265
"audio_properties_label",
263266
"layout_properties_box",
264267
"layout_properties_label",
268+
"favorite_button",
265269
]
266270

267271
for name in widget_names:
@@ -293,6 +297,7 @@ def __init__(self, application):
293297
self.tv_button.connect("clicked", self.show_groups, TV_GROUP)
294298
self.movies_button.connect("clicked", self.show_groups, MOVIES_GROUP)
295299
self.series_button.connect("clicked", self.show_groups, SERIES_GROUP)
300+
self.favorites_button.connect("clicked", self.show_favorites)
296301
self.providers_button.connect("clicked", self.open_providers)
297302
self.preferences_button.connect("clicked", self.open_preferences)
298303
self.go_back_button.connect("clicked", self.on_go_back_button)
@@ -317,6 +322,8 @@ def __init__(self, application):
317322

318323
self.channels_listbox.connect("row-activated", self.on_channel_activated)
319324

325+
self.favorite_button.connect("toggled", self.on_favorite_button_toggled)
326+
320327
# Settings widgets
321328
self.bind_setting_widget("user-agent", self.useragent_entry)
322329
self.bind_setting_widget("http-referer", self.referer_entry)
@@ -329,7 +336,7 @@ def __init__(self, application):
329336
if os.path.exists(os.path.expanduser("~/.cache/hypnotix/yt-dlp/yt-dlp")):
330337
self.ytdlp_local_version_label.set_text(subprocess.getoutput("~/.cache/hypnotix/yt-dlp/yt-dlp --version"))
331338
self.ytdlp_update_button.connect("clicked", self.update_ytdlp)
332-
339+
333340
# Dark mode manager
334341
# keep a reference to it (otherwise it gets randomly garbage collected)
335342
self.dark_mode_manager = XApp.DarkModeManager.new(prefer_dark_mode=True)
@@ -507,6 +514,15 @@ def on_category_button_clicked(self, widget, group):
507514
else:
508515
self.show_vod(self.active_provider.series)
509516

517+
def show_favorites(self, widget):
518+
channels = []
519+
for line in self.favorite_data:
520+
info, url = line.split(":::")
521+
channel = Channel(None, info)
522+
channel.url = url
523+
channels.append(channel)
524+
self.show_channels(channels)
525+
510526
def show_channels(self, channels):
511527
self.navigate_to("channels_page")
512528
if self.content_type == TV_GROUP:
@@ -835,6 +851,19 @@ def open_keyboard_shortcuts(self, widget):
835851
window.set_title(_("Hypnotix"))
836852
window.show()
837853

854+
def on_favorite_button_toggled(self, widget):
855+
if self.page_is_loading:
856+
return
857+
name = self.active_channel.name
858+
data = f"{self.active_channel.info}:::{self.active_channel.url}"
859+
if widget.get_active() and data not in self.favorite_data:
860+
print (f"Adding {name} to favorites")
861+
self.favorite_data.append(data)
862+
elif widget.get_active() == False and data in self.favorite_data:
863+
print (f"Removing {name} from favorites")
864+
self.favorite_data.remove(data)
865+
self.manager.save_favorites(self.favorite_data)
866+
838867
def on_channel_activated(self, box, widget):
839868
self.active_channel = widget.channel
840869
self.play_async(self.active_channel)
@@ -881,6 +910,16 @@ def before_play(self, channel):
881910
self.label_channel_name.set_text(channel.name)
882911
self.label_channel_url.set_text(channel.url)
883912

913+
self.page_is_loading = True
914+
data = f"{channel.info}:::{channel.url}"
915+
if data in self.favorite_data:
916+
self.favorite_button.set_active(True)
917+
self.favorite_button.set_tooltip_text(_("Remove from favorites"))
918+
else:
919+
self.favorite_button.set_active(False)
920+
self.favorite_button.set_tooltip_text(_("Add to favorites"))
921+
self.page_is_loading = False
922+
884923
@idle_function
885924
def after_play(self, channel):
886925
self.mpv_stack.set_visible_child_name("player_page")
@@ -1456,6 +1495,7 @@ def on_key_press_event(self, widget, event):
14561495

14571496
@async_function
14581497
def reload(self, page=None, refresh=False):
1498+
self.favorite_data = self.manager.load_favorites()
14591499
self.status(_("Loading providers..."))
14601500
self.providers = []
14611501
for provider_info in self.settings.get_strv("providers"):

usr/share/hypnotix/hypnotix.ui

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<?xml version="1.0" encoding="UTF-8"?>
2-
<!-- Generated with glade 3.40.0 -->
2+
<!-- Generated with glade 3.38.2 -->
33
<interface>
44
<requires lib="gtk+" version="3.20"/>
55
<requires lib="xapp" version="0.0"/>
@@ -488,7 +488,7 @@
488488
</packing>
489489
</child>
490490
<child>
491-
<object class="GtkToggleButton">
491+
<object class="GtkToggleButton" id="favorite_button">
492492
<property name="visible">True</property>
493493
<property name="can-focus">True</property>
494494
<property name="receives-default">True</property>

0 commit comments

Comments
 (0)