Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Relaxing channel name check in Xtream API #178

Merged
merged 27 commits into from
Dec 8, 2021
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
293963b
Added Initial XTream
superolmo May 28, 2021
a1dca48
Added XTream Series
superolmo Jun 2, 2021
d0be0a5
Added check for local logo_path
superolmo Jun 4, 2021
a84f7ce
Back to fixed path
superolmo Jun 4, 2021
b97598a
Added pyxtream choice
superolmo Jun 5, 2021
0530fc9
Replaced the test server
superolmo Jun 6, 2021
b56a6fb
Replaced the test server
superolmo Jun 6, 2021
ab11dfd
Fixed cache-path and added regex search
superolmo Jun 7, 2021
5d4a971
Merge branch 'master' of github.com:superolmo/hypnotix
superolmo Jun 7, 2021
2b8d127
Merge branch 'master' of https://github.com/linuxmint/hypnotix into l…
superolmo Jun 7, 2021
b38d61e
Changed osp back to os.path
superolmo Jun 7, 2021
7db1d62
Changed osp back to os.path
superolmo Jun 7, 2021
06517d6
Merge branch 'linuxmin-master'
superolmo Jun 7, 2021
2a45eb1
Fixed bug in the way it reload from cache
superolmo Jun 12, 2021
e79a848
Fixed missing provider when it doesn't load
superolmo Jun 18, 2021
dcbb6a1
Improved handling of missing keys
superolmo Jun 18, 2021
97b9e73
Fixed Categories and cleaned up the code
superolmo Jun 18, 2021
32af21f
Updated function names to follow PEP8
superolmo Jun 28, 2021
51e6d1d
Added check before authorizing
superolmo Sep 27, 2021
e6390d9
Merge remote-tracking branch 'upstream/master'
superolmo Sep 27, 2021
fca44f2
Scale down changes
superolmo Sep 27, 2021
0b41feb
Revert some more changes
superolmo Sep 27, 2021
215e191
Revert last changes
superolmo Sep 27, 2021
76bd0f2
Revert flag name
superolmo Sep 27, 2021
211db79
Discard streams w/o name, change live radio type to live stream
superolmo Nov 5, 2021
c8577a2
Rebase to upstream master
superolmo Nov 28, 2021
a7d447c
Fix subgroup name check
superolmo Dec 1, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
Added Initial XTream
  • Loading branch information
superolmo committed May 28, 2021
commit 293963b79a0bebc1610d585b358261d33309fde7
84 changes: 61 additions & 23 deletions usr/lib/hypnotix/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -131,33 +131,71 @@ def debug(self, *args):
if self.verbose:
print(args)

def get_playlist(self, provider, refresh=False):
try:
if "file:https://" in provider.url:
# local file
provider.path = provider.url.replace("file:https://", "")
elif ":https://" in provider.url:
# Other protocol, assume it's http
if refresh or not os.path.exists(provider.path):
headers = {
'User-Agent': self.settings.get_string("user-agent"),
'Referer': self.settings.get_string("http-referer")
}
response = requests.get(provider.url, headers=headers, timeout=10)
def get_playlist(self, provider, refresh=False) -> bool:
"""Get the playlist from the provided URL

Args:
provider ([type]): [description]
refresh (bool, optional): [description]. Defaults to False.

Returns:
bool: True for SUCCESS, False for ERROR
"""
ret_code = True

if "file:https://" in provider.url:
# local file
provider.path = provider.url.replace("file:https://", "")

elif ":https://" in provider.url:
# Other protocol, assume it's http
if refresh or not os.path.exists(provider.path):
# Assume it is not going to make it
ret_code = False

headers = {
'User-Agent': self.settings.get_string("user-agent"),
'Referer': self.settings.get_string("http-referer")
}
try:
response = requests.get(provider.url, headers=headers, timeout=(5,120), stream=True)

# If there is an answer from the remote server
if response.status_code == 200:
try:
source = response.content.decode("UTF-8")
except UnicodeDecodeError as e:
source = response.content.decode("latin1")
# Set downloaded size
downloaded_bytes = 0
# Get total playlist byte size
total_content_size = int(response.headers['content-length'])
# Set stream blocks
block_bytes = int(4*1024*1024) # 4 MB

response.encoding = response.apparent_encoding
#try:
# source = response.content.decode("UTF-8")
#except UnicodeDecodeError as e:
# source = response.content.decode("latin1")
with open(provider.path, "w") as file:
file.write(source)
# Grab data by block_bytes
for data in response.iter_content(block_bytes,decode_unicode=True):
downloaded_bytes += block_bytes
print("{} bytes".format(downloaded_bytes))
file.write(str(data))
if downloaded_bytes < total_content_size:
print("The file size is incorrect, deleting")
os.remove(provider.path)
else:
# Set the datatime when it was last retreived
# self.settings.set_
ret_code = True
else:
print("HTTP error %d while retrieving from %s!" % (response.status_code, provider.url))
else:
# No protocol, assume it's local
provider.path = provider.url
except Exception as e:
print(e)
except Exception as e:
print(e)
else:
# No protocol, assume it's local
provider.path = provider.url

return ret_code

def check_playlist(self, provider):
legit = False
Expand Down
109 changes: 89 additions & 20 deletions usr/lib/hypnotix/hypnotix.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
gettext.textdomain(APP)
_ = gettext.gettext

HYPNOTIX_HOME_PATH= os.path.abspath(os.path.join(os.path.dirname(os.path.realpath(__file__)),"../../../"))

PROVIDER_OBJ, PROVIDER_NAME = range(2)
PROVIDER_TYPE_ID, PROVIDER_TYPE_NAME = range(2)
Expand Down Expand Up @@ -105,8 +106,13 @@ def __init__(self, application):
self.x_pos = 0
self.y_pos = 0

# Used for redownloading timer
self.reload_timeout_sec = 60*5
self._timerid = -1

# Set the Glade file
gladefile = "/usr/share/hypnotix/hypnotix.ui"
gladefile = os.path.join(HYPNOTIX_HOME_PATH,"usr/share/hypnotix/hypnotix.ui")

self.builder = Gtk.Builder()
self.builder.set_translation_domain(APP)
self.builder.add_from_file(gladefile)
Expand All @@ -118,7 +124,8 @@ def __init__(self, application):
self.info_window = self.builder.get_object("stream_info_window")

provider = Gtk.CssProvider()
provider.load_from_path("/usr/share/hypnotix/hypnotix.css")
provider.load_from_path(os.path.join(HYPNOTIX_HOME_PATH,"usr/share/hypnotix/hypnotix.css"))

screen = Gdk.Display.get_default_screen(Gdk.Display.get_default())
# I was unable to found instrospected version of this
Gtk.StyleContext.add_provider_for_screen(
Expand All @@ -131,7 +138,12 @@ def __init__(self, application):
self.edit_mode = False

# Create variables to quickly access dynamic widgets
self.generic_channel_pixbuf = GdkPixbuf.Pixbuf.new_from_file_at_size("/usr/share/hypnotix/generic_tv_logo.png", 22, 22)
self.generic_channel_pixbuf = GdkPixbuf.Pixbuf.new_from_file_at_size(
os.path.join(HYPNOTIX_HOME_PATH,"usr/share/hypnotix/generic_tv_logo.png"),
22,
22
)

widget_names = ["headerbar", "status_label", "status_bar", "sidebar", "go_back_button", "channels_box", \
"provider_button", "preferences_button", \
"mpv_drawing_area", "stack", "fullscreen_button", \
Expand Down Expand Up @@ -264,14 +276,24 @@ def __init__(self, application):
self.provider_type_combo.set_active(0) # Select 1st type
self.provider_type_combo.connect("changed", self.on_provider_type_combo_changed)

self.tv_logo.set_from_pixbuf(GdkPixbuf.Pixbuf.new_from_file_at_size("/usr/share/hypnotix/pictures/tv.svg", 258, 258))
self.movies_logo.set_from_pixbuf(GdkPixbuf.Pixbuf.new_from_file_at_size("/usr/share/hypnotix/pictures/movies.svg", 258, 258))
self.series_logo.set_from_pixbuf(GdkPixbuf.Pixbuf.new_from_file_at_size("/usr/share/hypnotix/pictures/series.svg", 258, 258))
self.tv_logo.set_from_pixbuf(GdkPixbuf.Pixbuf.new_from_file_at_size(
os.path.join(HYPNOTIX_HOME_PATH,"/usr/share/hypnotix/pictures/tv.svg"),
258,
258))
self.movies_logo.set_from_pixbuf(GdkPixbuf.Pixbuf.new_from_file_at_size(
os.path.join(HYPNOTIX_HOME_PATH,"/usr/share/hypnotix/pictures/movies.svg"),
258,
258))
self.series_logo.set_from_pixbuf(GdkPixbuf.Pixbuf.new_from_file_at_size(
os.path.join(HYPNOTIX_HOME_PATH,"/usr/share/hypnotix/pictures/series.svg"),
258,
258))

self.reload(page="landing_page")

# Redownload playlists after a little while...
GLib.timeout_add_seconds(60 * 5, self.force_reload)
# Redownload playlists by default
# This is going to get readjusted
self._timerid = GLib.timeout_add_seconds(self.reload_timeout_sec, self.force_reload)

self.window.show()
self.playback_bar.hide()
Expand Down Expand Up @@ -303,7 +325,7 @@ def show_groups(self, widget, content_type):
box = Gtk.Box()
for word in group.name.split():
word = word.lower()
badge = "/usr/share/hypnotix/pictures/badges/%s.png" % word
badge = os.path.join(HYPNOTIX_HOME_PATH,"usr/share/hypnotix/pictures/badges/%s.png" % word)
if os.path.exists(badge):
try:
pixbuf = GdkPixbuf.Pixbuf.new_from_file_at_size(badge, -1, 16)
Expand All @@ -313,7 +335,7 @@ def show_groups(self, widget, content_type):
except:
print("Could not load badge", badge)
elif word in BADGES.keys():
badge = "/usr/share/hypnotix/pictures/badges/%s.png" % BADGES[word]
badge = os.path.join(HYPNOTIX_HOME_PATH,"usr/share/hypnotix/pictures/badges/%s.png" % BADGES[word])
try:
pixbuf = GdkPixbuf.Pixbuf.new_from_file_at_size(badge, -1, 16)
surface = Gdk.cairo_surface_create_from_pixbuf(pixbuf, self.window.get_scale_factor())
Expand Down Expand Up @@ -395,7 +417,12 @@ def show_vod(self, items):
label.set_max_width_chars(30)
label.set_ellipsize(Pango.EllipsizeMode.END)
box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
pixbuf = self.get_pixbuf(item.logo_path)
try:
pixbuf = self.get_pixbuf(item.logo_path)
except AttributeError as error:
print("Error loading logo_path")
print(error)
item.show()
surface = Gdk.cairo_surface_create_from_pixbuf(pixbuf, self.window.get_scale_factor())
image = Gtk.Image().new_from_surface(surface)
logos_to_refresh.append((item, image))
Expand Down Expand Up @@ -614,7 +641,7 @@ def navigate_to(self, page, name=""):
self.headerbar.set_subtitle(_("Reset providers"))

def open_keyboard_shortcuts(self, widget):
gladefile = "/usr/share/hypnotix/shortcuts.ui"
gladefile = os.path.join(HYPNOTIX_HOME_PATH,"usr/share/hypnotix/shortcuts.ui")
builder = Gtk.Builder()
builder.set_translation_domain(APP)
builder.add_from_file(gladefile)
Expand Down Expand Up @@ -1176,25 +1203,67 @@ def reload(self, page=None, refresh=False):
self.status("Loading providers...")
self.providers = []
for provider_info in self.settings.get_strv("providers"):

try:
provider = Provider(name=None, provider_info=provider_info)
if refresh:
self.status("Downloading playlist...", provider)
if provider.type_id != "xtream":
# Download M3U
if refresh:
self.status("Downloading playlist...", provider)
else:
self.status("Getting playlist...", provider)
ret = self.manager.get_playlist(provider, refresh=refresh)
if ret:
self.status("Checking playlist...", provider)
if (self.manager.check_playlist(provider)):
self.status("Loading channels...", provider)
self.manager.load_channels(provider)
self.providers.append(provider)
if provider.name == self.settings.get_string("active-provider"):
self.active_provider = provider
print(provider)
self.status(None)
print("Loaded {} channels".format(len(self.providers[0].channels)))
print("Loaded {} groups".format(len(self.providers[0].groups)))
print("Loaded {} series".format(len(self.providers[0].series)))
print("Loaded {} movies".format(len(self.providers[0].movies)))

# for g in self.providers[0].groups:
# print("{} [{}]".format(g.name,len(g.channels)))
# for c in g.channels:
# print("-> {}".format(c.name))
else:
self.status("Failed to Download playlist from {}".format(provider.name),provider)

else:
self.status("Getting playlist...", provider)
self.manager.get_playlist(provider, refresh=refresh)
self.status("Checking playlist...", provider)
if (self.manager.check_playlist(provider)):
self.status("Loading channels...", provider)
self.manager.load_channels(provider)

# Download via Xtream
from xtream import XTream
x = XTream(provider.url,provider.username,provider.password)
if x.authData != {}:
print("XTREAM Loading Channels")
x.load_iptv(provider)
else:
print("XTREAM Authentication Failed")

# Change redownload timeout
self.reload_timeout_sec = 60*60*2 # 2 hours
if self._timerid:
GLib.source_remove(self._timerid)
self._timerid = GLib.timeout_add_seconds(self.reload_timeout_sec, self.force_reload)

# If no errors, approve provider
self.providers.append(provider)
if provider.name == self.settings.get_string("active-provider"):
self.active_provider = provider
self.status(None)

except Exception as e:
print(e)
traceback.print_exc()
print("Couldn't parse provider info: ", provider_info)

# If there are more than 1 providers and no Active Provider, set to the first one
if len(self.providers) > 0 and self.active_provider == None:
self.active_provider = self.providers[0]

Expand Down
Loading