remove torrent backend

This commit is contained in:
j 2023-07-10 14:31:15 +05:30
parent 9355ae691d
commit 83df2c0011
12 changed files with 29 additions and 142 deletions

View file

@ -1399,10 +1399,8 @@
corner of the screen corner of the screen
"resolutions": List of video resolutions. Supported values are 96, 144, "resolutions": List of video resolutions. Supported values are 96, 144,
240, 288, 360, 432, 480, 720 and 1080. 240, 288, 360, 432, 480, 720 and 1080.
"torrent": If true, video downloads are offered via BitTorrent
*/ */
"video": { "video": {
"torrent": false,
"formats": ["webm", "mp4"], "formats": ["webm", "mp4"],
// fixme: this should be named "ratio" or "defaultRatio", // fixme: this should be named "ratio" or "defaultRatio",
// as it also applies to clip lists (on load) // as it also applies to clip lists (on load)

View file

@ -1876,10 +1876,8 @@
corner of the screen corner of the screen
"resolutions": List of video resolutions. Supported values are 96, 144, "resolutions": List of video resolutions. Supported values are 96, 144,
240, 288, 360, 432, 480, 720 and 1080. 240, 288, 360, 432, 480, 720 and 1080.
"torrent": If true, video downloads are offered via BitTorrent
*/ */
"video": { "video": {
"torrent": false,
"formats": ["webm", "mp4"], "formats": ["webm", "mp4"],
"previewRatio": 1.375, "previewRatio": 1.375,
"resolutions": [240, 480] "resolutions": [240, 480]

View file

@ -1334,10 +1334,8 @@
corner of the screen corner of the screen
"resolutions": List of video resolutions. Supported values are 96, 144, "resolutions": List of video resolutions. Supported values are 96, 144,
240, 288, 360, 432, 480, 720 and 1080. 240, 288, 360, 432, 480, 720 and 1080.
"torrent": If true, video downloads are offered via BitTorrent
*/ */
"video": { "video": {
"torrent": true,
"formats": ["webm", "mp4"], "formats": ["webm", "mp4"],
"previewRatio": 1.3333333333, "previewRatio": 1.3333333333,
//supported resolutions are //supported resolutions are

View file

@ -1272,13 +1272,11 @@ examples (config.SITENAME.jsonc) that are part of this pan.do/ra distribution.
corner of the screen corner of the screen
"resolutions": List of video resolutions. Supported values are 96, 144, "resolutions": List of video resolutions. Supported values are 96, 144,
240, 288, 360, 432, 480, 720 and 1080. 240, 288, 360, 432, 480, 720 and 1080.
"torrent": If true, video downloads are offered via BitTorrent
*/ */
"video": { "video": {
"downloadFormat": "webm", "downloadFormat": "webm",
"formats": ["webm", "mp4"], "formats": ["webm", "mp4"],
"previewRatio": 1.3333333333, "previewRatio": 1.3333333333,
"resolutions": [240, 480], "resolutions": [240, 480]
"torrent": false
} }
} }

View file

@ -71,7 +71,7 @@ class Migration(migrations.Migration):
('poster_width', models.IntegerField(default=0)), ('poster_width', models.IntegerField(default=0)),
('poster_frame', models.FloatField(default=-1)), ('poster_frame', models.FloatField(default=-1)),
('icon', models.ImageField(blank=True, default=None, upload_to=item.models.get_icon_path)), ('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_info', oxdjango.fields.DictField(default={}, editable=False)),
('stream_aspect', models.FloatField(default=1.3333333333333333)), ('stream_aspect', models.FloatField(default=1.3333333333333333)),
], ],

View 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',
),
]

View file

@ -157,9 +157,6 @@ def get_icon_path(f, x):
def get_poster_path(f, x): def get_poster_path(f, x):
return get_path(f, 'poster.jpg') return get_path(f, 'poster.jpg')
def get_torrent_path(f, x):
return get_path(f, 'torrent.torrent')
class Item(models.Model): class Item(models.Model):
created = models.DateTimeField(auto_now_add=True) created = models.DateTimeField(auto_now_add=True)
modified = models.DateTimeField(auto_now=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) 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_info = JSONField(default=dict, editable=False)
# stream related fields # stream related fields
@ -1306,90 +1302,6 @@ class Item(models.Model):
self.files.filter(selected=True).update(selected=False) self.files.filter(selected=True).update(selected=False)
self.save() 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): def audio_tracks(self):
tracks = [f['language'] tracks = [f['language']
for f in self.files.filter(selected=True).filter(Q(is_video=True) | Q(is_audio=True)).values('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.select_frame()
self.make_poster() self.make_poster()
self.make_icon() self.make_icon()
self.make_torrent()
self.rendered = streams.count() > 0 self.rendered = streams.count() > 0
self.save() self.save()
if self.rendered: if self.rendered:

View file

@ -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<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), 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 #export
re_path(r'^(?P<id>[A-Z0-9].*)/json$', views.item_json), re_path(r'^(?P<id>[A-Z0-9].*)/json$', views.item_json),
re_path(r'^(?P<id>[A-Z0-9].*)/xml$', views.item_xml), re_path(r'^(?P<id>[A-Z0-9].*)/xml$', views.item_xml),

View file

@ -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')) response['Content-Disposition'] = "attachment; filename*=UTF-8''%s" % quote(filename.encode('utf-8'))
return response 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): def video(request, id, resolution, format, index=None, track=None):
resolution = int(resolution) resolution = int(resolution)
@ -1288,12 +1267,6 @@ def atom_xml(request):
el.text = "1:1" el.text = "1:1"
if has_capability(request.user, 'canDownloadVideo'): 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 # FIXME: loop over streams
# for s in item.streams().filter(resolution=max(settings.CONFIG['video']['resolutions'])): # for s in item.streams().filter(resolution=max(settings.CONFIG['video']['resolutions'])):
for s in item.streams().filter(source=None): for s in item.streams().filter(source=None):

View file

@ -232,9 +232,6 @@ XACCELREDIRECT = False
SITE_CONFIG = join(PROJECT_ROOT, 'config.jsonc') SITE_CONFIG = join(PROJECT_ROOT, 'config.jsonc')
DEFAULT_CONFIG = join(PROJECT_ROOT, 'config.pandora.jsonc') DEFAULT_CONFIG = join(PROJECT_ROOT, 'config.pandora.jsonc')
#used if CONFIG['canDownloadVideo'] is set
TRACKER_URL = "udp://tracker.openbittorrent.com:80"
DATA_SERVICE = '' DATA_SERVICE = ''
POSTER_PRECEDENCE = () POSTER_PRECEDENCE = ()
POSTER_ONLY_PORTRAIT = () POSTER_ONLY_PORTRAIT = ()

View file

@ -895,7 +895,12 @@ pandora.ui.infoView = function(data, isMixed) {
} else if (capability.name == 'canPlayVideo') { } else if (capability.name == 'canPlayVideo') {
pandora.UI.set({itemView: ui.videoView}); pandora.UI.set({itemView: ui.videoView});
} else if (capability.name == 'canDownloadVideo') { } 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();
} }
} }
} }

View file

@ -1399,14 +1399,8 @@ pandora.getCurrentFrameAnnotation = function(data) {
}()); }());
pandora.getDownloadLink = function(item, rightslevel) { pandora.getDownloadLink = function(item, rightslevel) {
var torrent = pandora.site.video.torrent, var url = '/' + item + '/download/';
url; if (pandora.site.video.downloadFormat) {
if (arguments.length == 2 && torrent &&
pandora.hasCapability('canSeeItem', 'guest') < rightslevel) {
torrent = false;
}
url = '/' + item + (torrent ? '/torrent/' : '/download/');
if (!torrent && pandora.site.video.downloadFormat) {
url += Ox.max(pandora.site.video.resolutions) + 'p.' + pandora.site.video.downloadFormat; url += Ox.max(pandora.site.video.resolutions) + 'p.' + pandora.site.video.downloadFormat;
} }
return url; return url;