forked from 0x2620/pandora
remove torrent backend
This commit is contained in:
parent
9355ae691d
commit
83df2c0011
12 changed files with 29 additions and 142 deletions
|
@ -1399,10 +1399,8 @@
|
|||
corner of the screen
|
||||
"resolutions": List of video resolutions. Supported values are 96, 144,
|
||||
240, 288, 360, 432, 480, 720 and 1080.
|
||||
"torrent": If true, video downloads are offered via BitTorrent
|
||||
*/
|
||||
"video": {
|
||||
"torrent": false,
|
||||
"formats": ["webm", "mp4"],
|
||||
// fixme: this should be named "ratio" or "defaultRatio",
|
||||
// as it also applies to clip lists (on load)
|
||||
|
|
|
@ -1876,10 +1876,8 @@
|
|||
corner of the screen
|
||||
"resolutions": List of video resolutions. Supported values are 96, 144,
|
||||
240, 288, 360, 432, 480, 720 and 1080.
|
||||
"torrent": If true, video downloads are offered via BitTorrent
|
||||
*/
|
||||
"video": {
|
||||
"torrent": false,
|
||||
"formats": ["webm", "mp4"],
|
||||
"previewRatio": 1.375,
|
||||
"resolutions": [240, 480]
|
||||
|
|
|
@ -1334,10 +1334,8 @@
|
|||
corner of the screen
|
||||
"resolutions": List of video resolutions. Supported values are 96, 144,
|
||||
240, 288, 360, 432, 480, 720 and 1080.
|
||||
"torrent": If true, video downloads are offered via BitTorrent
|
||||
*/
|
||||
"video": {
|
||||
"torrent": true,
|
||||
"formats": ["webm", "mp4"],
|
||||
"previewRatio": 1.3333333333,
|
||||
//supported resolutions are
|
||||
|
|
|
@ -1272,13 +1272,11 @@ examples (config.SITENAME.jsonc) that are part of this pan.do/ra distribution.
|
|||
corner of the screen
|
||||
"resolutions": List of video resolutions. Supported values are 96, 144,
|
||||
240, 288, 360, 432, 480, 720 and 1080.
|
||||
"torrent": If true, video downloads are offered via BitTorrent
|
||||
*/
|
||||
"video": {
|
||||
"downloadFormat": "webm",
|
||||
"formats": ["webm", "mp4"],
|
||||
"previewRatio": 1.3333333333,
|
||||
"resolutions": [240, 480],
|
||||
"torrent": false
|
||||
"resolutions": [240, 480]
|
||||
}
|
||||
}
|
||||
|
|
|
@ -71,7 +71,7 @@ class Migration(migrations.Migration):
|
|||
('poster_width', models.IntegerField(default=0)),
|
||||
('poster_frame', models.FloatField(default=-1)),
|
||||
('icon', models.ImageField(blank=True, default=None, upload_to=item.models.get_icon_path)),
|
||||
('torrent', models.FileField(blank=True, default=None, max_length=1000, upload_to=item.models.get_torrent_path)),
|
||||
('torrent', models.FileField(blank=True, default=None, max_length=1000)),
|
||||
('stream_info', oxdjango.fields.DictField(default={}, editable=False)),
|
||||
('stream_aspect', models.FloatField(default=1.3333333333333333)),
|
||||
],
|
||||
|
|
19
pandora/item/migrations/0005_auto_20230710_0852.py
Normal file
19
pandora/item/migrations/0005_auto_20230710_0852.py
Normal file
|
@ -0,0 +1,19 @@
|
|||
# Generated by Django 3.0.10 on 2023-07-10 08:52
|
||||
|
||||
import django.core.serializers.json
|
||||
from django.db import migrations, models
|
||||
import oxdjango.fields
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('item', '0004_json_cache'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.RemoveField(
|
||||
model_name='item',
|
||||
name='torrent',
|
||||
),
|
||||
]
|
|
@ -157,9 +157,6 @@ def get_icon_path(f, x):
|
|||
def get_poster_path(f, x):
|
||||
return get_path(f, 'poster.jpg')
|
||||
|
||||
def get_torrent_path(f, x):
|
||||
return get_path(f, 'torrent.torrent')
|
||||
|
||||
class Item(models.Model):
|
||||
created = models.DateTimeField(auto_now_add=True)
|
||||
modified = models.DateTimeField(auto_now=True)
|
||||
|
@ -185,7 +182,6 @@ class Item(models.Model):
|
|||
|
||||
icon = models.ImageField(default=None, blank=True, upload_to=get_icon_path)
|
||||
|
||||
torrent = models.FileField(default=None, blank=True, max_length=1000, upload_to=get_torrent_path)
|
||||
stream_info = JSONField(default=dict, editable=False)
|
||||
|
||||
# stream related fields
|
||||
|
@ -1306,90 +1302,6 @@ class Item(models.Model):
|
|||
self.files.filter(selected=True).update(selected=False)
|
||||
self.save()
|
||||
|
||||
def get_torrent(self, request):
|
||||
if self.torrent:
|
||||
self.torrent.seek(0)
|
||||
data = ox.torrent.bdecode(self.torrent.read())
|
||||
url = request.build_absolute_uri("%s/torrent/" % self.get_absolute_url())
|
||||
if url.startswith('https://'):
|
||||
url = 'http' + url[5:]
|
||||
data['url-list'] = ['%s%s' % (url, u.split('torrent/')[1]) for u in data['url-list']]
|
||||
return ox.torrent.bencode(data)
|
||||
|
||||
def make_torrent(self):
|
||||
if not settings.CONFIG['video'].get('torrent'):
|
||||
return
|
||||
streams = self.streams()
|
||||
if streams.count() == 0:
|
||||
return
|
||||
base = self.path('torrent')
|
||||
base = os.path.abspath(os.path.join(settings.MEDIA_ROOT, base))
|
||||
if not isinstance(base, bytes):
|
||||
base = base.encode('utf-8')
|
||||
if os.path.exists(base):
|
||||
shutil.rmtree(base)
|
||||
ox.makedirs(base)
|
||||
|
||||
filename = utils.safe_filename(ox.decode_html(self.get('title')))
|
||||
base = self.path('torrent/%s' % filename)
|
||||
base = os.path.abspath(os.path.join(settings.MEDIA_ROOT, base))
|
||||
size = 0
|
||||
duration = 0.0
|
||||
if streams.count() == 1:
|
||||
v = streams[0]
|
||||
media_path = v.media.path
|
||||
extension = media_path.split('.')[-1]
|
||||
url = "%s/torrent/%s.%s" % (self.get_absolute_url(),
|
||||
quote(filename.encode('utf-8')),
|
||||
extension)
|
||||
video = "%s.%s" % (base, extension)
|
||||
if not isinstance(media_path, bytes):
|
||||
media_path = media_path.encode('utf-8')
|
||||
if not isinstance(video, bytes):
|
||||
video = video.encode('utf-8')
|
||||
media_path = os.path.relpath(media_path, os.path.dirname(video))
|
||||
os.symlink(media_path, video)
|
||||
size = v.media.size
|
||||
duration = v.duration
|
||||
else:
|
||||
url = "%s/torrent/" % self.get_absolute_url()
|
||||
part = 1
|
||||
ox.makedirs(base)
|
||||
for v in streams:
|
||||
media_path = v.media.path
|
||||
extension = media_path.split('.')[-1]
|
||||
video = "%s/%s.Part %d.%s" % (base, filename, part, extension)
|
||||
part += 1
|
||||
if not isinstance(media_path, bytes):
|
||||
media_path = media_path.encode('utf-8')
|
||||
if not isinstance(video, bytes):
|
||||
video = video.encode('utf-8')
|
||||
media_path = os.path.relpath(media_path, os.path.dirname(video))
|
||||
os.symlink(media_path, video)
|
||||
size += v.media.size
|
||||
duration += v.duration
|
||||
video = base
|
||||
|
||||
torrent = '%s.torrent' % base
|
||||
url = "http://%s%s" % (settings.CONFIG['site']['url'], url)
|
||||
meta = {
|
||||
'filesystem_encoding': 'utf-8',
|
||||
'target': torrent,
|
||||
'url-list': url,
|
||||
}
|
||||
if duration:
|
||||
meta['playtime'] = ox.format_duration(duration*1000)[:-4]
|
||||
|
||||
# slightly bigger torrent file but better for streaming
|
||||
piece_size_pow2 = 15 # 1 mbps -> 32KB pieces
|
||||
if size / duration >= 1000000:
|
||||
piece_size_pow2 = 16 # 2 mbps -> 64KB pieces
|
||||
meta['piece_size_pow2'] = piece_size_pow2
|
||||
|
||||
ox.torrent.create_torrent(video, settings.TRACKER_URL, meta)
|
||||
self.torrent.name = torrent[len(settings.MEDIA_ROOT)+1:]
|
||||
self.save()
|
||||
|
||||
def audio_tracks(self):
|
||||
tracks = [f['language']
|
||||
for f in self.files.filter(selected=True).filter(Q(is_video=True) | Q(is_audio=True)).values('language')
|
||||
|
@ -1440,7 +1352,6 @@ class Item(models.Model):
|
|||
self.select_frame()
|
||||
self.make_poster()
|
||||
self.make_icon()
|
||||
self.make_torrent()
|
||||
self.rendered = streams.count() > 0
|
||||
self.save()
|
||||
if self.rendered:
|
||||
|
|
|
@ -24,10 +24,6 @@ urls = [
|
|||
re_path(r'^(?P<id>[A-Z0-9].*)/(?P<resolution>\d+)p(?P<index>\d*)\.(?P<format>webm|ogv|mp4)$', views.video),
|
||||
re_path(r'^(?P<id>[A-Z0-9].*)/(?P<resolution>\d+)p(?P<index>\d*)\.(?P<track>.+)\.(?P<format>webm|ogv|mp4)$', views.video),
|
||||
|
||||
#torrent
|
||||
re_path(r'^(?P<id>[A-Z0-9].*)/torrent$', views.torrent),
|
||||
re_path(r'^(?P<id>[A-Z0-9].*)/torrent/(?P<filename>.*?)$', views.torrent),
|
||||
|
||||
#export
|
||||
re_path(r'^(?P<id>[A-Z0-9].*)/json$', views.item_json),
|
||||
re_path(r'^(?P<id>[A-Z0-9].*)/xml$', views.item_xml),
|
||||
|
|
|
@ -1046,27 +1046,6 @@ def download(request, id, resolution=None, format='webm', part=None):
|
|||
response['Content-Disposition'] = "attachment; filename*=UTF-8''%s" % quote(filename.encode('utf-8'))
|
||||
return response
|
||||
|
||||
def torrent(request, id, filename=None):
|
||||
item = get_object_or_404(models.Item, public_id=id)
|
||||
if not item.access(request.user):
|
||||
return HttpResponseForbidden()
|
||||
if not item.torrent:
|
||||
raise Http404
|
||||
if not filename or filename.endswith('.torrent'):
|
||||
response = HttpResponse(item.get_torrent(request),
|
||||
content_type='application/x-bittorrent')
|
||||
filename = utils.safe_filename("%s.torrent" % item.get('title'))
|
||||
response['Content-Disposition'] = "attachment; filename*=UTF-8''%s" % quote(filename.encode('utf-8'))
|
||||
return response
|
||||
while filename.startswith('/'):
|
||||
filename = filename[1:]
|
||||
filename = filename.replace('/../', '/')
|
||||
filename = item.path('torrent/%s' % filename)
|
||||
filename = os.path.abspath(os.path.join(settings.MEDIA_ROOT, filename))
|
||||
response = HttpFileResponse(filename)
|
||||
response['Content-Disposition'] = "attachment; filename*=UTF-8''%s" % \
|
||||
quote(os.path.basename(filename.encode('utf-8')))
|
||||
return response
|
||||
|
||||
def video(request, id, resolution, format, index=None, track=None):
|
||||
resolution = int(resolution)
|
||||
|
@ -1288,12 +1267,6 @@ def atom_xml(request):
|
|||
el.text = "1:1"
|
||||
|
||||
if has_capability(request.user, 'canDownloadVideo'):
|
||||
if item.torrent:
|
||||
el = ET.SubElement(entry, "link")
|
||||
el.attrib['rel'] = 'enclosure'
|
||||
el.attrib['type'] = 'application/x-bittorrent'
|
||||
el.attrib['href'] = '%s/torrent/' % page_link
|
||||
el.attrib['length'] = '%s' % ox.get_torrent_size(item.torrent.path)
|
||||
# FIXME: loop over streams
|
||||
# for s in item.streams().filter(resolution=max(settings.CONFIG['video']['resolutions'])):
|
||||
for s in item.streams().filter(source=None):
|
||||
|
|
|
@ -232,9 +232,6 @@ XACCELREDIRECT = False
|
|||
SITE_CONFIG = join(PROJECT_ROOT, 'config.jsonc')
|
||||
DEFAULT_CONFIG = join(PROJECT_ROOT, 'config.pandora.jsonc')
|
||||
|
||||
#used if CONFIG['canDownloadVideo'] is set
|
||||
TRACKER_URL = "udp://tracker.openbittorrent.com:80"
|
||||
|
||||
DATA_SERVICE = ''
|
||||
POSTER_PRECEDENCE = ()
|
||||
POSTER_ONLY_PORTRAIT = ()
|
||||
|
|
|
@ -895,7 +895,12 @@ pandora.ui.infoView = function(data, isMixed) {
|
|||
} else if (capability.name == 'canPlayVideo') {
|
||||
pandora.UI.set({itemView: ui.videoView});
|
||||
} else if (capability.name == 'canDownloadVideo') {
|
||||
document.location.href = '/' + ui.item + '/torrent/';
|
||||
pandora.ui.downloadVideoDialog({
|
||||
item: ui.item,
|
||||
rightsLevel: data.rightsLevel,
|
||||
title: data.title,
|
||||
video: data.video
|
||||
}).open();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1399,14 +1399,8 @@ pandora.getCurrentFrameAnnotation = function(data) {
|
|||
}());
|
||||
|
||||
pandora.getDownloadLink = function(item, rightslevel) {
|
||||
var torrent = pandora.site.video.torrent,
|
||||
url;
|
||||
if (arguments.length == 2 && torrent &&
|
||||
pandora.hasCapability('canSeeItem', 'guest') < rightslevel) {
|
||||
torrent = false;
|
||||
}
|
||||
url = '/' + item + (torrent ? '/torrent/' : '/download/');
|
||||
if (!torrent && pandora.site.video.downloadFormat) {
|
||||
var url = '/' + item + '/download/';
|
||||
if (pandora.site.video.downloadFormat) {
|
||||
url += Ox.max(pandora.site.video.resolutions) + 'p.' + pandora.site.video.downloadFormat;
|
||||
}
|
||||
return url;
|
||||
|
|
Loading…
Reference in a new issue