-
Notifications
You must be signed in to change notification settings - Fork 11
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Signed-off-by: Jakub Koudelka <[email protected]>
- Loading branch information
Showing
6 changed files
with
207 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
# -*- coding: utf-8 -*- | ||
from kodiswift import Plugin | ||
from mall import MallApi | ||
|
||
plugin = Plugin() | ||
api = MallApi(plugin) | ||
|
||
@plugin.route('/category') | ||
def category_index(): | ||
return api.get_categories() | ||
|
||
@plugin.route('/category/<link>') | ||
def category(link): | ||
return api.get_category(link) | ||
|
||
@plugin.route('/show') | ||
def show_index(): | ||
return api.get_shows() | ||
|
||
@plugin.route('/show/<link>') | ||
def show(link): | ||
return api.get_show_videos(link) | ||
|
||
@plugin.route('/video/<link>') | ||
def video(link): | ||
url = api.get_video_url(link) | ||
plugin.set_resolved_url(url) | ||
|
||
@plugin.route('/') | ||
def index(): | ||
show = { | ||
'label': plugin.get_string(30002), | ||
'path': plugin.url_for(show_index) | ||
} | ||
category = { | ||
'label': plugin.get_string(30001), | ||
'path': plugin.url_for(category_index) | ||
} | ||
return [show, category] | ||
|
||
if __name__ == '__main__': | ||
plugin.run() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> | ||
<addon id="plugin.video.mall.tv" | ||
name="Mall.TV" | ||
version="0.0.1" | ||
provider-name="koudi"> | ||
<requires> | ||
<import addon="xbmc.python" version="2.1.0" /> | ||
<import addon="script.module.requests" /> | ||
<import addon="script.module.beautifulsoup4" /> | ||
<import addon="script.module.kodiswift" /> | ||
</requires> | ||
|
||
<extension point="xbmc.python.pluginsource" library="addon.py"> | ||
<provides>video</provides> | ||
</extension> | ||
|
||
<extension point="xbmc.addon.metadata"> | ||
<platform>all</platform> | ||
<summary>Mall.TV</summary> | ||
<summary lang="cs">Mall.TV</summary> | ||
<summary lang="en">Mall.TV</summary> | ||
<description> | ||
Plugin to play Mall.TV | ||
</description> | ||
<description lang="cs"> | ||
Plugin pro přehrávání Mall.TV | ||
</description> | ||
<source>https://github.com/koudi/plugin.video.mall.tv</source> | ||
</extension> | ||
</addon> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,125 @@ | ||
# -*- coding: utf-8 -*- | ||
|
||
from bs4 import BeautifulSoup | ||
import requests | ||
|
||
class MallApi(): | ||
|
||
BASE = 'https://www.mall.tv' | ||
|
||
def __init__(self, plugin): | ||
self.plugin = plugin | ||
|
||
def warn(self, *args, **kwargs): | ||
self.plugin.log.warning(*args, **kwargs) | ||
|
||
def url_for(self, *args, **kwargs): | ||
return self.plugin.url_for(*args, **kwargs) | ||
|
||
def get_page(self, url): | ||
r = requests.get(self.BASE + url) | ||
return BeautifulSoup(r.content, 'html.parser') | ||
|
||
def get_categories(self, ): | ||
result = [] | ||
|
||
page = self.get_page('/kategorie') | ||
|
||
category = page.find('section', {'class': 'isCategory'}) | ||
cards = category.find_all('div', {'class': 'video-card'}) | ||
|
||
self.warn(self.url_for('category', link='3')) | ||
|
||
for card in cards: | ||
a = card.find('a') | ||
result.append({ | ||
'path': self.url_for('category', link=a['href']), | ||
'thumbnail': a['data-src'], | ||
'label': card.find('h2').contents[0] | ||
}) | ||
|
||
badges = page.find_all('a', {'class': 'badge-kategory'}) | ||
for badge in badges: | ||
result.append({ | ||
'path': self.url_for('category', link=badge['href']), | ||
'label': badge.contents[0] | ||
}) | ||
|
||
return result | ||
|
||
def get_category(self, link): | ||
page = self.get_page(link) | ||
return self.extract_shows(page) | ||
|
||
def get_shows(self): | ||
index = 0 | ||
shows = [] | ||
|
||
while True: | ||
self.warn(index) | ||
page = self.get_page('/Serie/CategorySortedSeries?categoryId=0&sortType=1&page=' + str(index)) | ||
|
||
if not page: | ||
return shows | ||
|
||
slider_item = page.find('div', {'class': 'video-grid__body'}) | ||
|
||
if slider_item: | ||
count = int(slider_item['slider-total']) | ||
|
||
shows += self.extract_shows(page) | ||
|
||
if len(shows) >= count: | ||
break | ||
|
||
index += 1 | ||
|
||
return shows | ||
|
||
def get_show_videos(self, link): | ||
page = self.get_page(link) | ||
return self.extract_videos(page) | ||
|
||
def extract_shows(self, page): | ||
result = [] | ||
|
||
for item in page.select('.video-card__series figure'): | ||
result.append({ | ||
'label': item.find('h4').text, | ||
'path': self.url_for('show', link=item.find('a')['href']), | ||
'thumbnail': item.find('a', attrs={'data-src': True})['data-src'] | ||
}) | ||
|
||
return result | ||
|
||
def extract_videos(self, page): | ||
result = [] | ||
grid = page.find('section', {'class': ['video-grid', 'isVideo']}) | ||
|
||
for card in grid.find_all('div', {'class': 'video-card'}): | ||
link = card.select('.video-card__details a.video-card__details-link')[0] | ||
|
||
result.append({ | ||
'label': link.text, | ||
'thumbnail': card.find('div', {'class': ['video-card__thumbnail', 'lazy']})['data-src'], | ||
'path': self.url_for('video', link=link['href']), | ||
'info': { | ||
'duration': self.get_duration(card.find('span', {'class': 'badge__wrapper-video-duration'}).text) | ||
}, | ||
'is_playable': True | ||
}) | ||
|
||
return result | ||
|
||
def get_duration(self, val): | ||
count = 0 | ||
coef = [1, 60, 3600] | ||
|
||
for index, part in enumerate(reversed(val.split(':'))): | ||
count += int(part) * coef[index] | ||
|
||
return count | ||
|
||
def get_video_url(self, link): | ||
page = self.get_page(link) | ||
return page.find('source')['src'] + '.m3u8' |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
<?xml version="1.0" encoding="utf-8" standalone="yes"?> | ||
<strings> | ||
<string id="30001">Kategorie</string> | ||
<string id="30002">Seriály</string> | ||
</strings> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
<?xml version="1.0" encoding="utf-8" standalone="yes"?> | ||
<strings> | ||
<string id="30001">Categories</string> | ||
<string id="30002">TV Shows</string> | ||
</strings> |