Skip to content

Commit

Permalink
Initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
clefebvre committed Oct 26, 2020
0 parents commit c0d65e1
Show file tree
Hide file tree
Showing 23 changed files with 3,200 additions and 0 deletions.
13 changes: 13 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
all: buildmo

buildmo:
@echo "Building the mo files"
# WARNING: the second sed below will only works correctly with the languages that don't contain "-"
for file in `ls po/*.po`; do \
lang=`echo $$file | sed 's@po/@@' | sed 's/\.po//' | sed 's/hypnotix-//'`; \
install -d usr/share/locale/$$lang/LC_MESSAGES/; \
msgfmt -o usr/share/locale/$$lang/LC_MESSAGES/hypnotix.mo $$file; \
done \

clean:
rm -rf usr/share/locale
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Hypnotix

An IPTV app.
6 changes: 6 additions & 0 deletions debian/changelog
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
hypnotix (1.0.0) ulyana; urgency=low

* Initial release

-- Clement Lefebvre <root@linuxmint.com> Tue, 26 Oct 2020 21:38:00 +0000

1 change: 1 addition & 0 deletions debian/compat
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
9
17 changes: 17 additions & 0 deletions debian/control
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
Source: hypnotix
Section: admin
Priority: optional
Maintainer: Linux Mint <root@linuxmint.com>
Build-Depends: debhelper (>= 9)
Standards-Version: 3.9.5

Package: hypnotix
Architecture: all
Depends: gir1.2-xapp-1.0,
python3,
python3-gi,
python3-setproctitle,
xapps-common,
${misc:Depends},
Description: IPTV Player
Watch TV by streaming from M3U sources.
20 changes: 20 additions & 0 deletions debian/copyright
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
Upstream-Name: hypnotix
Upstream-Contact: Linux Mint <root@linuxmint.com>
Source: https://github.com/linuxmint/hypnotix

Files: *
Copyright: 2020 Linux Mint <root@linuxmint.com>
License: GPL-3+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
.
On Debian systems, the complete text of the GNU General
Public License can be found in `/usr/share/common-licenses/GPL'
1 change: 1 addition & 0 deletions debian/install
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
usr
20 changes: 20 additions & 0 deletions debian/postinst
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#!/bin/sh
set -e

case "$1" in
configure)
if which glib-compile-schemas >/dev/null 2>&1
then
glib-compile-schemas /usr/share/glib-2.0/schemas
fi
;;

abort-upgrade|abort-remove|abort-deconfigure)

;;

*)
echo "postinst called with unknown argument \`$1'" >&2
exit 1
;;
esac
13 changes: 13 additions & 0 deletions debian/rules
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
#!/usr/bin/make -f

DEB_VERSION := $(shell dpkg-parsechangelog | egrep '^Version:' | cut -f 2 -d ' ')

%:
dh ${@}

# Inject version number in the code
override_dh_installdeb:
dh_installdeb
for pkg in $$(dh_listpackages -i); do \
find debian/$$pkg -type f -exec sed -i -e s/__DEB_VERSION__/$(DEB_VERSION)/g {} +; \
done
1 change: 1 addition & 0 deletions debian/source/format
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
3.0 (native)
24 changes: 24 additions & 0 deletions generate_desktop_files
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
#!/usr/bin/python3

DOMAIN = "hypnotix"
PATH = "/usr/share/locale"

import os
import gettext
from mintcommon import additionalfiles

os.environ['LANGUAGE'] = "en_US.UTF-8"
gettext.install(DOMAIN, PATH)

prefix = "[Desktop Entry]\n"

suffix = """Exec=hypnotix
Icon=hypnotix
Terminal=false
Type=Application
Encoding=UTF-8
Categories=AudioVideo;Video;Player;TV;
StartupNotify=false
"""

additionalfiles.generate(DOMAIN, PATH, "usr/share/applications/hypnotix.desktop", prefix, _("Hypnotix"), _("Watch TV"), suffix)
5 changes: 5 additions & 0 deletions makepot
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#!/bin/bash
intltool-extract --type=gettext/glade usr/share/hypnotix/hypnotix.ui
intltool-extract --type=gettext/glade usr/share/hypnotix/shortcuts.ui
xgettext --language=Python --keyword=_ --keyword=N_ --output=hypnotix.pot usr/lib/hypnotix/*.py generate_desktop_files usr/share/hypnotix/hypnotix.ui.h usr/share/hypnotix/shortcuts.ui.h
rm -f usr/share/hypnotix/*.ui.h
Empty file added po/hypnotix-fr.po
Empty file.
5 changes: 5 additions & 0 deletions test
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#!/bin/bash
sudo rm -rf /usr/lib/hypnotix
sudo rm -rf /usr/share/hypnotix
sudo cp -R usr /
hypnotix
2 changes: 2 additions & 0 deletions usr/bin/hypnotix
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
#!/bin/sh
/usr/lib/hypnotix/hypnotix.py &
132 changes: 132 additions & 0 deletions usr/lib/hypnotix/common.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
#!/usr/bin/python3
import configparser
import gi
import os
import requests
import shutil
import string
import threading
import re
from gi.repository import GObject
from random import choice

# M3U parsing regex
PARAMS = re.compile(r'(\S+)="(.*?)"')
EXTINF = re.compile(r'^#EXTINF:(?P<duration>-?\d+?) ?(?P<params>.*),(?P<title>.*?)$')
PROVIDERS_PATH = os.path.expanduser("~/.hypnotix/providers")

# Used as a decorator to run things in the background
def _async(func):
def wrapper(*args, **kwargs):
thread = threading.Thread(target=func, args=args, kwargs=kwargs)
thread.daemon = True
thread.start()
return thread
return wrapper

# Used as a decorator to run things in the main loop, from another thread
def idle(func):
def wrapper(*args):
GObject.idle_add(func, *args)
return wrapper

def slugify(string):
"""
Normalizes string, converts to lowercase, removes non-alpha characters,
and converts spaces to hyphens.
"""
return "".join(x.lower() for x in string if x.isalnum())

class Provider():
def __init__(self, name, url):
self.name = name
self.path = os.path.join(PROVIDERS_PATH, slugify(name))
self.url = url
self.groups = []
self.channels = []

class Group():
def __init__(self, name):
self.name = name
self.channels = []

class Channel():
def __init__(self, info):
self.info = info
self.id = None
self.name = None
self.logo = None
self.group_title = None
self.title = None
self.url = None
match = EXTINF.fullmatch(info)
if match != None:
res = match.groupdict()
if 'params' in res:
params = dict(PARAMS.findall(res['params']))
if "tvg-name" in params and params['tvg-name'].strip() != "":
self.name = params['tvg-name'].strip()
if "tvg-logo" in params and params['tvg-logo'].strip() != "":
self.logo = params['tvg-logo'].strip()
if "group-title" in params and params['group-title'].strip() != "":
self.group_title = params['group-title'].strip()
if 'title' in res:
self.title = res['title']

class Manager():

def __init__(self):
os.system("mkdir -p '%s'" % PROVIDERS_PATH)

def download_playlist(self, provider):
success = False
try:
response = requests.get(provider.url, timeout=10)
if response.status_code == 200:
print("Download success")
try:
source = response.content.decode("UTF-8")
except UnicodeDecodeError as e:
source = response.content.decode("latin1")
if (source.count("#EXTM3U") > 0 and source.count("#EXTINF") > 0):
print("Content looks legit")
with open(provider.path, "w") as file:
file.write(source)
success = True
except Exception as e:
print(e)
finally:
return success

def load_channels(self, provider):
with open(provider.path, "r") as file:
channel = None
group = None
groups = {}
for line in file:
line = line.strip()
if line.startswith("#EXTM3U"):
continue
if line.startswith("#EXTINF"):
channel = Channel(line)
continue
if "://" in line:
if channel == None:
continue
if channel.url != None:
# We already found the URL, skip the line
continue
if channel.name == None or "***" in channel.name:
continue
channel.url = line
provider.channels.append(channel)
if channel.group_title != None and channel.group_title.strip() != "":
if group == None or group.name != channel.group_title:
if channel.group_title in groups.keys():
group = groups[channel.group_title]
else:
group = Group(channel.group_title)
provider.groups.append(group)
groups[channel.group_title] = group
group.channels.append(channel)

Loading

0 comments on commit c0d65e1

Please sign in to comment.