-
Notifications
You must be signed in to change notification settings - Fork 0
/
server.py
152 lines (126 loc) · 5.29 KB
/
server.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
import flask
import logging
from flask import Flask, send_from_directory, render_template, jsonify, url_for, request, redirect
from dirToPod import RssGenerator
from reverse_proxied import ReverseProxied
from eyed3 import id3
from random import random
from logging.handlers import RotatingFileHandler
import shutil
import os
import subprocess
app = Flask(__name__)
app.wsgi_app = ReverseProxied(app.wsgi_app)
SERVER_ROOT = '/var/www/books'
AUDIOBOOK_DIRECTORY = '/data/audiobooks'
LOGSIZE = 1000000 # 1MB
# Setup simple logging
log = logging.Logger('appLog')
log.addHandler(RotatingFileHandler('/tmp/dirToPod.log', maxBytes=LOGSIZE, backupCount=1))
@app.route("/")
def index():
pageText = ''
for item in sorted(os.listdir(AUDIOBOOK_DIRECTORY)):
if not item.startswith('.'):
pageText += '<p><a href="%s">%s</a></p>' % (url_for('getRss', path=item.replace(' ', '_')), item)
return pageText
@app.route("/audiobook/<path:path>")
def getRss(path):
# if not os.path.exists("%s/%s.xml" % (SERVER_ROOT, path)):
RssGenerator('http://{0}{1}'.format(request.host, url_for('index')[:-1]), "%s/%s" % (AUDIOBOOK_DIRECTORY, path.replace('_',' ')), path)
return send_from_directory(SERVER_ROOT, "%s.xml" % path)
#return redirect("http://%s/%s.xml" % (request.headers['Host'], path))
@app.route("/files")
def files():
return render_template('files.html')
@app.route("/api/joinFiles", methods=['POST'])
def joinFiles():
newName = request.json['newName']
fileList = request.json['fileList']
newName = newName + '.mp3' if not newName.endswith('.mp3') else newName
cwd = fileList[0] if os.path.isdir(fileList[0]) else os.path.dirname(fileList[0])
filesToJoin = [aFile for aFile in fileList if aFile.endswith('.mp3')]
map(lambda aFile: id3.tag.Tag.remove(aFile), filesToJoin)
filesToJoin = sorted([os.path.relpath(aFile, cwd) for aFile in filesToJoin])
args = ['/usr/bin/ffmpeg', '-i', 'concat:%s' % '|'.join(filesToJoin), '-y', '-acodec', 'copy', newName]
runProcess(args, cwd)
args = ['/usr/bin/vbrfix', '-always', newName, newName]
runProcess(args, cwd)
# cleanup crap leftover from vbrfix
leftoverCrap = [os.path.join(cwd, crapFile) for crapFile in ['vbrfix.log', 'vbrfix.tmp'] if os.path.isfile(os.path.join(cwd, crapFile))]
map(lambda crap: os.remove(crap), leftoverCrap)
return ""
@app.route("/api/hierarchy", methods=['GET'])
def getHierarchy():
def addEntries(entryList, icon):
for entry in entryList:
data.append({ 'id' : os.path.join(root, entry), 'text' : entry, 'parent' : root, 'icon' : icon})
data = [{'id' : AUDIOBOOK_DIRECTORY, 'text' : 'audiobooks', 'parent' : '#'}]
for root,dirs,files in os.walk(AUDIOBOOK_DIRECTORY):
files = [f for f in files if not f[0] == '.']
dirs[:] = [d for d in dirs if not d[0] == '.']
addEntries(dirs, 'jstree-folder')
addEntries(files, 'jstree-file')
return jsonify(data=data)
@app.route('/api/delete', methods=['POST'])
def delete():
if request.json.has_key('nodeList'):
nodeList = request.json['nodeList']
else:
nodeList = []
nodeList.append(request.json['node'])
for node in nodeList:
if os.path.isdir(node):
shutil.rmtree(node)
elif os.path.isfile(node):
os.remove(node)
#If its not a file or directory, we either already deleted it by deleting the directory, or we've got a symlink, which we ideally wanna keep around
return ''
@app.route('/api/rename', methods=['POST'])
def rename():
oldPath = request.json['oldPath']
newPath = os.path.join(os.path.dirname(oldPath), request.json['newNode'])
if os.path.exists(newPath):
raise OSError('Path already exists!')
os.rename(oldPath, newPath)
return ''
@app.route('/api/move', methods=['POST'])
def move():
oldPath = request.json['oldPath']
dropTo = request.json['dropTo']
if os.path.isdir(dropTo):
newPath = dropTo
elif os.path.isfile(dropTo):
newPath = os.path.dirname(dropTo)
else:
log.debug('Trying to drop on file that is neither directory or file...what is it?')
newPath = newPath + os.path.sep + os.path.basename(oldPath)
if os.path.exists(newPath):
raise OSError('Path already exists!')
shutil.move(oldPath, newPath)
return ''
@app.route('/api/reencode', methods=['POST'])
def reencode():
fileList = request.json['fileList']
for aFile in fileList:
if aFile.endswith('.mp3'):
fileDir = os.path.dirname(aFile)
filename = os.path.basename(aFile)
oldDir = os.path.join(fileDir, 'old')
if not os.path.isdir(oldDir):
os.mkdir(oldDir)
os.rename(aFile, os.path.join(oldDir, filename))
args = ['/usr/bin/ffmpeg', '-i', os.path.join(oldDir, filename), '-ab', '96k', aFile]
runProcess(args, fileDir)
return ''
def runProcess(args, cwd):
log.debug(args)
stdout = '/tmp/stdout%s' % str(random()).split('.')[1]
with open(stdout, 'w') as out:
pobj = subprocess.Popen(args, stdout=out, stderr=subprocess.STDOUT, cwd=cwd)
ret = pobj.wait()
with open(stdout, 'r') as out:
log.debug(out.read())
os.remove(stdout)
if __name__ == "__main__":
app.run('0.0.0.0', port=8881, debug=True)