Some checks failed
release / build-release (push) Has been cancelled
- IChannel: creators -> sub-channels -> video posts (public listing API, search mapped) - IRequiresMediaInfoCallback -> signed proxy URLs; stream controller rewrites HLS so the AES-128 key is fetched server-side with the session cookie, segments stay on the CDN - delivery/info cached per token lifetime and throttled (~2/min) - config page: paste sails.sid + validate, extra creators, quality, search test - scripts/package.sh -> plugin folder + zip + md5 + manifest.json; Gitea release workflow - research docs, HAR analysis (HAR itself gitignored), install-pi5.sh Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
95 lines
2.5 KiB
Python
95 lines
2.5 KiB
Python
#!/usr/bin/python
|
|
'''
|
|
plugin.video.floatplaneclub
|
|
Copyright (C) 2017 MrWolvetech
|
|
|
|
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.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
'''
|
|
|
|
from xbmcswift2 import Plugin
|
|
import resources.lib.scraper as scraper
|
|
|
|
plugin = Plugin()
|
|
|
|
|
|
@plugin.route('/')
|
|
def show_page1():
|
|
videos, has_next_page = scraper.get_videos()
|
|
items = [{
|
|
'label': video['title'],
|
|
'thumbnail': video['thumbnail'],
|
|
'info': {
|
|
'originaltitle': video['title']
|
|
},
|
|
'path': plugin.url_for(
|
|
endpoint='watch_video',
|
|
video_id=video['guid']
|
|
),
|
|
'is_playable': True,
|
|
} for video in videos]
|
|
if has_next_page:
|
|
next_page = str(2)
|
|
items.append({
|
|
'label': '>> Page %s >>' % (
|
|
next_page
|
|
),
|
|
'path': plugin.url_for(
|
|
endpoint='show_page',
|
|
page=next_page
|
|
),
|
|
})
|
|
return plugin.finish(items)
|
|
|
|
|
|
@plugin.route('/<page>/')
|
|
def show_page(page):
|
|
if page is 1:
|
|
return show_page1()
|
|
|
|
videos, has_next_page = scraper.get_videos(page)
|
|
items = [{
|
|
'label': video['title'],
|
|
'thumbnail': video['thumbnail'],
|
|
'info': {
|
|
'originaltitle': video['title']
|
|
},
|
|
'path': plugin.url_for(
|
|
endpoint='watch_video',
|
|
video_id=video['url']
|
|
),
|
|
'is_playable': True,
|
|
} for video in videos]
|
|
if has_next_page:
|
|
next_page = str(int(page) + 1)
|
|
items.append({
|
|
'label': '>> page %s >>' % (
|
|
next_page
|
|
),
|
|
'path': plugin.url_for(
|
|
endpoint='show_page',
|
|
page=next_page
|
|
),
|
|
})
|
|
return plugin.finish(items)
|
|
|
|
|
|
@plugin.route('/watch/<video_id>/')
|
|
def watch_video(video_id):
|
|
video_url = scraper.get_video_url(video_id)
|
|
return plugin.set_resolved_url(video_url)
|
|
|
|
|
|
if __name__ == '__main__':
|
|
plugin.run()
|