120 lines
3.8 KiB
Python
Executable file
120 lines
3.8 KiB
Python
Executable file
#!/usr/bin/python3
|
|
import os
|
|
import json
|
|
import ox
|
|
import ox.web.auth
|
|
|
|
base_url = 'https://0xdb.org'
|
|
credentials = ox.web.auth.get('0xdb.org')
|
|
prefix = '/Cinema'
|
|
|
|
if os.path.exists('files.json'):
|
|
files = json.load(open('files.json'))
|
|
else:
|
|
files = {}
|
|
|
|
def get_info(api, oshash):
|
|
if oshash not in files:
|
|
r = api.findMedia({
|
|
'query': {
|
|
'conditions': [{'key': 'oshash', 'value': oshash}]
|
|
},
|
|
'keys': ['id', 'instances', 'resolution']
|
|
})['data']
|
|
files[oshash] = {
|
|
'path': os.path.join(prefix, r['items'][0]['instances'][0]['path']),
|
|
'resolution': r['items'][0]['resolution']
|
|
}
|
|
return files[oshash]
|
|
|
|
def normalize(name):
|
|
return name.replace(':', '_').replace('/', '_')
|
|
|
|
def sort_clips(edit, sort):
|
|
clips = edit['clips']
|
|
reverse = sort.startswith('-')
|
|
last = '' if reverse else 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'
|
|
sort = sort.lstrip('-')
|
|
if sort in [
|
|
'id', 'index', 'in', 'out', 'duration',
|
|
'title', 'director', 'year', 'videoRatio'
|
|
]:
|
|
s = sorted(clips, key=lambda c: (str(c.get(sort, last)), c['in'], c['out']))
|
|
if reverse:
|
|
s = reversed(s)
|
|
else:
|
|
ids = api.sortClips({
|
|
'edit': edit['id'],
|
|
'sort': [{'key': sort, 'operator': '-' if reverse else '+'}]
|
|
})['data']['clips']
|
|
print(set(c['id'] for c in clips) - set(ids))
|
|
print(set(ids) - set(c['id'] for c in clips))
|
|
|
|
s = sorted(clips, key=lambda c: ids.index(c['id']) if c['id'] in ids else -1)
|
|
return s
|
|
|
|
|
|
if __name__ == '__main__':
|
|
import sys
|
|
edit_id = sys.argv[1]
|
|
if len(sys.argv) > 2:
|
|
sort_by = sys.argv[2]
|
|
else:
|
|
sort_by = 'year'
|
|
|
|
api = ox.API(base_url + '/api/')
|
|
api.signin(**credentials)
|
|
edit = api.getEdit(id=edit_id)['data']
|
|
videos = []
|
|
subtitles = []
|
|
position = 0
|
|
for clip in sort_clips(edit, sort_by):
|
|
|
|
part_pos = 0
|
|
for i, duration in enumerate(clip['durations']):
|
|
if part_pos + duration < clip['in']:
|
|
part_pos += duration
|
|
elif part_pos <= clip['in']:
|
|
stream_in = clip['in'] - part_pos
|
|
stream_out = min(clip['out'] - part_pos, duration)
|
|
part_pos += duration
|
|
info = get_info(api, clip['streams'][i])
|
|
videos.append({
|
|
'oshash': clip['streams'][i],
|
|
'path': os.path.join(prefix, info['path']),
|
|
'resolution': info['resolution'],
|
|
'in': stream_in,
|
|
'out': stream_out
|
|
})
|
|
elif clip['out'] > part_pos:
|
|
stream_in = part_pos
|
|
stream_out = min(clip['out'] - part_pos, duration)
|
|
part_pos += duration
|
|
info = get_info(api, clip['streams'][i])
|
|
videos.append({
|
|
'oshash': clip['streams'][i],
|
|
'path': info['path'],
|
|
'resolution': info['resolution'],
|
|
'in': stream_in,
|
|
'out': stream_out
|
|
})
|
|
|
|
for sub in clip['layers']['subtitles']:
|
|
subtitles.append({
|
|
'in': position,
|
|
'out': position + (sub['out'] - sub['in']),
|
|
'value': sub['value'].replace('<br/>', '\n').replace('<br>', '\n').replace('\n\n', '\n'),
|
|
})
|
|
|
|
position += clip['duration']
|
|
|
|
name = normalize(edit_id)
|
|
if sort_by != 'year':
|
|
name += '_' + sort_by
|
|
with open('%s.srt' % name, 'wb') as fd:
|
|
fd.write(ox.srt.encode(subtitles))
|
|
with open('%s.json' % name, 'w') as fd:
|
|
json.dump(videos, fd, indent=4, ensure_ascii=False)
|
|
|
|
with open('files.json', 'w') as fd:
|
|
json.dump(files, fd, indent=4, ensure_ascii=False)
|