mirror of
https://github.com/fastogt/fastocloud_admin.git
synced 2025-03-09 23:38:52 +00:00
Meta vods
This commit is contained in:
parent
7f75eaf40b
commit
7664ac4e0c
9 changed files with 154 additions and 29 deletions
|
@ -96,7 +96,7 @@ from app.provider.view import ProviderView
|
||||||
from app.stream.view import StreamView
|
from app.stream.view import StreamView
|
||||||
from app.service.view import ServiceView
|
from app.service.view import ServiceView
|
||||||
from app.subscriber.view import SubscriberView
|
from app.subscriber.view import SubscriberView
|
||||||
from app.autofill.view import M3uParseView
|
from app.autofill.view import M3uParseStreamsView
|
||||||
from app.epg.view import EpgView
|
from app.epg.view import EpgView
|
||||||
|
|
||||||
HomeView.register(app)
|
HomeView.register(app)
|
||||||
|
@ -104,5 +104,5 @@ ProviderView.register(app)
|
||||||
StreamView.register(app)
|
StreamView.register(app)
|
||||||
ServiceView.register(app)
|
ServiceView.register(app)
|
||||||
SubscriberView.register(app)
|
SubscriberView.register(app)
|
||||||
M3uParseView.register(app)
|
M3uParseStreamsView.register(app)
|
||||||
EpgView.register(app)
|
EpgView.register(app)
|
||||||
|
|
|
@ -3,13 +3,20 @@ from mongoengine import Document, StringField, ListField
|
||||||
import pyfastocloud_models.constants as constants
|
import pyfastocloud_models.constants as constants
|
||||||
|
|
||||||
|
|
||||||
class M3uParse(Document):
|
class M3uParseStreams(Document):
|
||||||
NAME_FIELD = 'name'
|
meta = {'allow_inheritance': False, 'collection': 'm3uparse_streams', 'auto_create_index': False}
|
||||||
|
|
||||||
meta = {'allow_inheritance': False, 'collection': 'm3uparse', 'auto_create_index': False}
|
|
||||||
name = StringField(unique=True, max_length=constants.MAX_STREAM_NAME_LENGTH,
|
name = StringField(unique=True, max_length=constants.MAX_STREAM_NAME_LENGTH,
|
||||||
min_length=constants.MIN_STREAM_NAME_LENGTH,
|
min_length=constants.MIN_STREAM_NAME_LENGTH,
|
||||||
required=True)
|
required=True)
|
||||||
tvg_id = ListField(StringField(unique=True), default=[])
|
tvg_id = ListField(StringField(unique=True), default=[])
|
||||||
tvg_logo = ListField(StringField(unique=True), default=[])
|
tvg_logo = ListField(StringField(unique=True), default=[])
|
||||||
group = ListField(StringField(unique=True), default=[])
|
group = ListField(StringField(unique=True), default=[])
|
||||||
|
|
||||||
|
|
||||||
|
class M3uParseVods(Document):
|
||||||
|
meta = {'allow_inheritance': False, 'collection': 'm3uparse_vods', 'auto_create_index': False}
|
||||||
|
name = StringField(unique=True, max_length=constants.MAX_STREAM_NAME_LENGTH,
|
||||||
|
min_length=constants.MIN_STREAM_NAME_LENGTH,
|
||||||
|
required=True)
|
||||||
|
tvg_logo = ListField(StringField(unique=True), default=[])
|
||||||
|
group = ListField(StringField(unique=True), default=[])
|
||||||
|
|
|
@ -5,27 +5,27 @@ from flask_login import login_required
|
||||||
from pyfastocloud_models.utils.m3u_parser import M3uParser
|
from pyfastocloud_models.utils.m3u_parser import M3uParser
|
||||||
from app.common.service.forms import UploadM3uForm
|
from app.common.service.forms import UploadM3uForm
|
||||||
import pyfastocloud_models.constants as constants
|
import pyfastocloud_models.constants as constants
|
||||||
from app.autofill.entry import M3uParse
|
from app.autofill.entry import M3uParseStreams, M3uParseVods
|
||||||
from pyfastocloud_models.utils.utils import is_valid_http_url
|
from pyfastocloud_models.utils.utils import is_valid_http_url
|
||||||
|
|
||||||
|
|
||||||
# routes
|
# routes
|
||||||
class M3uParseView(FlaskView):
|
class M3uParseStreamsView(FlaskView):
|
||||||
route_base = '/m3uparse/'
|
route_base = '/m3uparse_streams/'
|
||||||
|
|
||||||
@login_required
|
@login_required
|
||||||
def show(self):
|
def show(self):
|
||||||
m3u = M3uParse.objects()
|
m3u = M3uParseStreams.objects()
|
||||||
return render_template('autofill/show.html', m3u=m3u)
|
return render_template('autofill/show_streams.html', m3u=m3u)
|
||||||
|
|
||||||
@login_required
|
@login_required
|
||||||
def show_anonim(self):
|
def show_anonim(self):
|
||||||
m3u = M3uParse.objects()
|
m3u = M3uParseStreams.objects()
|
||||||
return render_template('autofill/show_anonim.html', m3u=m3u)
|
return render_template('autofill/show_streams_anonim.html', m3u=m3u)
|
||||||
|
|
||||||
@route('/search/<sid>', methods=['GET'])
|
@route('/search/<sid>', methods=['GET'])
|
||||||
def search(self, sid):
|
def search(self, sid):
|
||||||
lines = M3uParse.objects(id=sid)
|
lines = M3uParseStreams.objects(id=sid)
|
||||||
line = lines.first()
|
line = lines.first()
|
||||||
if line:
|
if line:
|
||||||
return jsonify(status='ok', line=line), 200
|
return jsonify(status='ok', line=line), 200
|
||||||
|
@ -49,9 +49,9 @@ class M3uParseView(FlaskView):
|
||||||
if len(title) > constants.MAX_STREAM_NAME_LENGTH:
|
if len(title) > constants.MAX_STREAM_NAME_LENGTH:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
line = M3uParse.objects(name=title).first()
|
line = M3uParseStreams.objects(name=title).first()
|
||||||
if not line:
|
if not line:
|
||||||
line = M3uParse(name=title)
|
line = M3uParseStreams(name=title)
|
||||||
|
|
||||||
tvg_id = file['tvg-id']
|
tvg_id = file['tvg-id']
|
||||||
if len(tvg_id) and len(tvg_id) < constants.MAX_STREAM_TVG_ID_LENGTH:
|
if len(tvg_id) and len(tvg_id) < constants.MAX_STREAM_TVG_ID_LENGTH:
|
||||||
|
@ -68,10 +68,74 @@ class M3uParseView(FlaskView):
|
||||||
|
|
||||||
line.save()
|
line.save()
|
||||||
|
|
||||||
return redirect(url_for('M3uParseView:show'))
|
return redirect(url_for('M3uParseStreamsView:show'))
|
||||||
|
|
||||||
@login_required
|
@login_required
|
||||||
@route('/upload_m3u', methods=['POST', 'GET'])
|
@route('/upload_m3u', methods=['POST', 'GET'])
|
||||||
def upload_m3u(self):
|
def upload_m3u(self):
|
||||||
form = UploadM3uForm()
|
form = UploadM3uForm()
|
||||||
return render_template('autofill/upload_m3u.html', form=form)
|
return render_template('autofill/upload_m3u_streams.html', form=form)
|
||||||
|
|
||||||
|
|
||||||
|
# routes
|
||||||
|
class M3uParseVodsView(FlaskView):
|
||||||
|
route_base = '/m3uparse_vods/'
|
||||||
|
|
||||||
|
@login_required
|
||||||
|
def show(self):
|
||||||
|
m3u = M3uParseVods.objects()
|
||||||
|
return render_template('autofill/show_vods.html', m3u=m3u)
|
||||||
|
|
||||||
|
@login_required
|
||||||
|
def show_anonim(self):
|
||||||
|
m3u = M3uParseVods.objects()
|
||||||
|
return render_template('autofill/show_vods_anonim.html', m3u=m3u)
|
||||||
|
|
||||||
|
@route('/search/<sid>', methods=['GET'])
|
||||||
|
def search(self, sid):
|
||||||
|
lines = M3uParseVods.objects(id=sid)
|
||||||
|
line = lines.first()
|
||||||
|
if line:
|
||||||
|
return jsonify(status='ok', line=line), 200
|
||||||
|
|
||||||
|
return jsonify(status='failed', error='Not found'), 404
|
||||||
|
|
||||||
|
@route('/upload_files', methods=['POST'])
|
||||||
|
@login_required
|
||||||
|
def upload_files(self):
|
||||||
|
form = UploadM3uForm()
|
||||||
|
if form.validate_on_submit():
|
||||||
|
files = request.files.getlist("files")
|
||||||
|
for file in files:
|
||||||
|
m3u_parser = M3uParser()
|
||||||
|
data = file.read().decode('utf-8')
|
||||||
|
m3u_parser.load_content(data)
|
||||||
|
m3u_parser.parse()
|
||||||
|
|
||||||
|
for file in m3u_parser.files:
|
||||||
|
title = file['title']
|
||||||
|
if len(title) > constants.MAX_STREAM_NAME_LENGTH:
|
||||||
|
continue
|
||||||
|
|
||||||
|
line = M3uParseVods.objects(name=title).first()
|
||||||
|
if not line:
|
||||||
|
line = M3uParseVods(name=title)
|
||||||
|
|
||||||
|
tvg_group = file['tvg-group']
|
||||||
|
if len(tvg_group) and len(tvg_group) < constants.MAX_STREAM_GROUP_TITLE_LENGTH:
|
||||||
|
line.group.append(tvg_group)
|
||||||
|
|
||||||
|
tvg_logo = file['tvg-logo']
|
||||||
|
if len(tvg_logo) and len(tvg_logo) < constants.MAX_URL_LENGTH:
|
||||||
|
if is_valid_http_url(tvg_logo, timeout=0.1):
|
||||||
|
line.tvg_logo.append(tvg_logo)
|
||||||
|
|
||||||
|
line.save()
|
||||||
|
|
||||||
|
return redirect(url_for('M3uParseVodsView:show'))
|
||||||
|
|
||||||
|
@login_required
|
||||||
|
@route('/upload_m3u', methods=['POST', 'GET'])
|
||||||
|
def upload_m3u(self):
|
||||||
|
form = UploadM3uForm()
|
||||||
|
return render_template('autofill/upload_m3u_vods.html', form=form)
|
||||||
|
|
|
@ -66,7 +66,7 @@ M3U | {{ config['PUBLIC_CONFIG'].site.title }}
|
||||||
<td>{{ loop.index }}</td>
|
<td>{{ loop.index }}</td>
|
||||||
<td>{{ line.name }}</td>
|
<td>{{ line.name }}</td>
|
||||||
<td>
|
<td>
|
||||||
<a href="{{ url_for('M3uParseView:search', sid=line.id) }}" role="button"
|
<a href="{{ url_for('M3uParseStreamsView:search', sid=line.id) }}" role="button"
|
||||||
target="_blank" class="btn btn-success btn-xs">
|
target="_blank" class="btn btn-success btn-xs">
|
||||||
Show
|
Show
|
||||||
</a>
|
</a>
|
||||||
|
@ -79,7 +79,7 @@ M3U | {{ config['PUBLIC_CONFIG'].site.title }}
|
||||||
</div>
|
</div>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-md-4">
|
<div class="col-md-4">
|
||||||
<a href="{{ url_for('M3uParseView:upload_m3u') }}" role="button" class="btn btn-success">
|
<a href="{{ url_for('M3uParseStreamsView:upload_m3u') }}" role="button" class="btn btn-success">
|
||||||
Upload urls
|
Upload urls
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
|
@ -49,7 +49,7 @@ M3U | {{ config['PUBLIC_CONFIG'].site.title }}
|
||||||
<td>{{ loop.index }}</td>
|
<td>{{ loop.index }}</td>
|
||||||
<td>{{ line.name }}</td>
|
<td>{{ line.name }}</td>
|
||||||
<td>
|
<td>
|
||||||
<a href="{{ url_for('M3uParseView:search', sid=line.id) }}" role="button"
|
<a href="{{ url_for('M3uParseStreamsView:search', sid=line.id) }}" role="button"
|
||||||
target="_blank" class="btn btn-success btn-xs">
|
target="_blank" class="btn btn-success btn-xs">
|
||||||
Show
|
Show
|
||||||
</a>
|
</a>
|
45
app/templates/autofill/upload_m3u_streams.html
Normal file
45
app/templates/autofill/upload_m3u_streams.html
Normal file
|
@ -0,0 +1,45 @@
|
||||||
|
{% extends 'layouts/layout_home.html' %}
|
||||||
|
{% block title %}
|
||||||
|
Upload m3u | {{ config['PUBLIC_CONFIG'].site.title }}
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
<div class="panel panel-default">
|
||||||
|
<div class="panel-heading">
|
||||||
|
<h1 class="panel-title">
|
||||||
|
<div class="col-md-11">
|
||||||
|
<a href="{{ url_for('HomeView:index') }}">{{ config['PUBLIC_CONFIG'].site.title }}</a>
|
||||||
|
</div>
|
||||||
|
<div>Version: {{ config['PUBLIC_CONFIG'].project.version }}</div>
|
||||||
|
</h1>
|
||||||
|
</div>
|
||||||
|
<div class="panel-body">
|
||||||
|
<div class="container-fluid">
|
||||||
|
<div class="row well">
|
||||||
|
<h3>Upload m3u files</h3>
|
||||||
|
<p>Note: Please upload m3u files for service.</p>
|
||||||
|
{{ util.flashed_messages(dismissible=True, container=False) }}
|
||||||
|
<form action="{{ url_for('M3uParseStreamsView:upload_files') }}" method="POST" class="form" role="form"
|
||||||
|
enctype="multipart/form-data">
|
||||||
|
{{ form.hidden_tag() }}
|
||||||
|
<div class="col-md-3">
|
||||||
|
{{ form.files }}
|
||||||
|
</div>
|
||||||
|
<div class="col-md-3">
|
||||||
|
Type: {{ form.type }}
|
||||||
|
</div>
|
||||||
|
<div class="col-md-3">
|
||||||
|
{{ form_field(form.upload, class="btn btn-success") }}
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<a href="{{ url_for('ProviderView:dashboard') }}" role="button" class="btn btn-info">
|
||||||
|
Dashboard
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{%- endblock %}
|
|
@ -20,7 +20,7 @@ Upload m3u | {{ config['PUBLIC_CONFIG'].site.title }}
|
||||||
<h3>Upload m3u files</h3>
|
<h3>Upload m3u files</h3>
|
||||||
<p>Note: Please upload m3u files for service.</p>
|
<p>Note: Please upload m3u files for service.</p>
|
||||||
{{ util.flashed_messages(dismissible=True, container=False) }}
|
{{ util.flashed_messages(dismissible=True, container=False) }}
|
||||||
<form action="{{ url_for('M3uParseView:upload_files') }}" method="POST" class="form" role="form"
|
<form action="{{ url_for('M3uParseVodsView:upload_files') }}" method="POST" class="form" role="form"
|
||||||
enctype="multipart/form-data">
|
enctype="multipart/form-data">
|
||||||
{{ form.hidden_tag() }}
|
{{ form.hidden_tag() }}
|
||||||
<div class="col-md-3">
|
<div class="col-md-3">
|
|
@ -13,14 +13,17 @@
|
||||||
<main>
|
<main>
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<div class="jumbotron text-center">
|
<div class="jumbotron text-center">
|
||||||
<div class="col-md-4">
|
<div class="col-md-3">
|
||||||
<a href={{ url_for('HomeView:signin') }} class="btn btn-warning">Sign In</a>
|
<a href={{ url_for('HomeView:signin') }} class="btn btn-warning">Sign In</a>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-md-4">
|
<div class="col-md-3">
|
||||||
<a href={{ url_for('HomeView:signup') }} class="btn btn-warning">Sign Up</a>
|
<a href={{ url_for('HomeView:signup') }} class="btn btn-warning">Sign Up</a>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-md-4">
|
<div class="col-md-3">
|
||||||
<a href={{ url_for('M3uParseView:show_anonim') }} class="btn btn-success">Meta</a>
|
<a href={{ url_for('M3uParseStreamsView:show_anonim') }} class="btn btn-success">Meta Streams</a>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-3">
|
||||||
|
<a href={{ url_for('M3uParseVodsView:show_anonim') }} class="btn btn-success">Meta VODs</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
|
|
|
@ -70,7 +70,7 @@ Dashboard | {{ config['PUBLIC_CONFIG'].site.title }}
|
||||||
<div class="col-md-1">
|
<div class="col-md-1">
|
||||||
<img width="64px" height="64px" src="{{ url_for('static', filename='images/logo.png') }}"/>
|
<img width="64px" height="64px" src="{{ url_for('static', filename='images/logo.png') }}"/>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-md-6">
|
<div class="col-md-5">
|
||||||
<p>Welcome {{ current_user.email }}</p>
|
<p>Welcome {{ current_user.email }}</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-md-1">
|
<div class="col-md-1">
|
||||||
|
@ -87,9 +87,15 @@ Dashboard | {{ config['PUBLIC_CONFIG'].site.title }}
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<div class="col-md-1">
|
<div class="col-md-1">
|
||||||
<a href="{{ url_for('M3uParseView:show') }}" class="btn btn-success"
|
<a href="{{ url_for('M3uParseStreamsView:show') }}" class="btn btn-success"
|
||||||
role="button">
|
role="button">
|
||||||
Meta
|
Meta Streams
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-1">
|
||||||
|
<a href="{{ url_for('M3uParseStreamsView:show') }}" class="btn btn-success"
|
||||||
|
role="button">
|
||||||
|
Meta VODs
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-md-1">
|
<div class="col-md-1">
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue