Spaces:
Running
Running
Commit
·
f02b1de
1
Parent(s):
e49df2d
upd
Browse files- app.py +10 -4
- routes/__init__.py +3 -2
- routes/config.json +8 -0
- routes/helpers.py +46 -8
- routes/osuApi/findSong.py +1 -1
- routes/osuApi/getFull.py +18 -17
- routes/osuApi/getPreview.py +3 -3
- routes/siteRoutes/__init__.py +1 -0
- routes/siteRoutes/sigGen.py +27 -0
- routes/witaiApi/recognizeVoice.py +1 -0
- routes/ytApi/get.py +9 -7
- routes/ytApi/getFull.py +6 -5
- routes/ytApi/getPreview.py +6 -5
- routes/ytApi/search.py +1 -1
- signatures.db +0 -0
- static/api.yaml +5 -3
- templates/index.html +1 -1
app.py
CHANGED
@@ -3,11 +3,12 @@ from flask import *
|
|
3 |
from flask_limiter import Limiter
|
4 |
from flask_limiter.util import get_remote_address
|
5 |
|
|
|
6 |
from routes import *
|
7 |
|
8 |
app = Flask(__name__)
|
9 |
app.config['JSON_AS_ASCII'] = False
|
10 |
-
limiter = Limiter(app, default_limits=["5/minute"])
|
11 |
|
12 |
#limiter
|
13 |
@limiter.request_filter
|
@@ -15,7 +16,7 @@ def ip_whitelist():
|
|
15 |
try:
|
16 |
if request.method == 'POST': signature = request.form['signature']
|
17 |
else: signature = request.args['signature']
|
18 |
-
return
|
19 |
except: return False
|
20 |
#error pages
|
21 |
@app.errorhandler(429)
|
@@ -29,6 +30,11 @@ def ratelimit_handler(e): return render_template('notfound.html')
|
|
29 |
@app.route('/')
|
30 |
@limiter.exempt
|
31 |
def index(): return render_template('index.html')
|
|
|
|
|
|
|
|
|
|
|
32 |
|
33 |
#empty routes
|
34 |
@app.route('/yt/api/v1', methods=['GET', 'POST'])
|
@@ -40,7 +46,7 @@ def emptyPath(): return {}
|
|
40 |
@app.route('/recognize/api/v1/<path:path>', methods=['GET', 'POST'])
|
41 |
@app.route('/osu/api/v1/<path:path>', methods=['GET', 'POST'])
|
42 |
def emptyApiWA(path): return {"status": "error", "error_code": 100, "error_details": "No method like that found"}
|
43 |
-
|
44 |
#icon
|
45 |
@app.route('/favicon.ico')
|
46 |
@limiter.exempt
|
@@ -72,5 +78,5 @@ def getBMPreview(): return osuApi.getPreview(request)
|
|
72 |
def getBMFull(): return osuApi.getFull(request)
|
73 |
|
74 |
if __name__ == "__main__":
|
75 |
-
app.run(host="0.0.0.0", port=
|
76 |
|
|
|
3 |
from flask_limiter import Limiter
|
4 |
from flask_limiter.util import get_remote_address
|
5 |
|
6 |
+
from routes.helpers import checkSignature
|
7 |
from routes import *
|
8 |
|
9 |
app = Flask(__name__)
|
10 |
app.config['JSON_AS_ASCII'] = False
|
11 |
+
limiter = Limiter(app=app, key_func=get_remote_address, default_limits=["5/minute"], storage_uri="memory://",)
|
12 |
|
13 |
#limiter
|
14 |
@limiter.request_filter
|
|
|
16 |
try:
|
17 |
if request.method == 'POST': signature = request.form['signature']
|
18 |
else: signature = request.args['signature']
|
19 |
+
return checkSignature(request, signature)
|
20 |
except: return False
|
21 |
#error pages
|
22 |
@app.errorhandler(429)
|
|
|
30 |
@app.route('/')
|
31 |
@limiter.exempt
|
32 |
def index(): return render_template('index.html')
|
33 |
+
# sig gen
|
34 |
+
@app.route('/signatures/api/v1/get', methods=['GET', 'POST'])
|
35 |
+
@limiter.exempt
|
36 |
+
def signatureGen():
|
37 |
+
return siteRoutes.signatureGen(request)
|
38 |
|
39 |
#empty routes
|
40 |
@app.route('/yt/api/v1', methods=['GET', 'POST'])
|
|
|
46 |
@app.route('/recognize/api/v1/<path:path>', methods=['GET', 'POST'])
|
47 |
@app.route('/osu/api/v1/<path:path>', methods=['GET', 'POST'])
|
48 |
def emptyApiWA(path): return {"status": "error", "error_code": 100, "error_details": "No method like that found"}
|
49 |
+
|
50 |
#icon
|
51 |
@app.route('/favicon.ico')
|
52 |
@limiter.exempt
|
|
|
78 |
def getBMFull(): return osuApi.getFull(request)
|
79 |
|
80 |
if __name__ == "__main__":
|
81 |
+
app.run(host="0.0.0.0", port=80, debug=True)
|
82 |
|
routes/__init__.py
CHANGED
@@ -1,4 +1,5 @@
|
|
|
|
|
|
1 |
from .helpers import *
|
2 |
from .witaiApi import *
|
3 |
-
from .
|
4 |
-
from .osuApi import *
|
|
|
1 |
+
from .ytApi import *
|
2 |
+
from .osuApi import *
|
3 |
from .helpers import *
|
4 |
from .witaiApi import *
|
5 |
+
from .siteRoutes import *
|
|
routes/config.json
ADDED
@@ -0,0 +1,8 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
{
|
2 |
+
"url": "https://imperialwool-funapi.hf.space",
|
3 |
+
"full-path": "/app/static/full",
|
4 |
+
"temp-path": "/app/static/temp",
|
5 |
+
"static-path": "/app/static",
|
6 |
+
"previews-path": "/app/static/previews",
|
7 |
+
"signatures-db": "C:\\Users\\InspectorJoey\\Desktop\\api\\signatures.db"
|
8 |
+
}
|
routes/helpers.py
CHANGED
@@ -1,19 +1,57 @@
|
|
1 |
import os
|
|
|
|
|
2 |
import random
|
3 |
import string
|
|
|
|
|
4 |
import requests
|
5 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
6 |
# Deleting audio
|
7 |
def deleteAudio(path: str, waitInSeconds: int = 0):
|
8 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
9 |
|
10 |
-
# Signatures!!! Wow!!!
|
11 |
-
def checkSignature(signature: str):
|
12 |
-
|
13 |
-
|
14 |
-
|
15 |
-
]
|
16 |
-
|
|
|
|
|
|
|
|
|
|
|
17 |
|
18 |
# Hook for yt-dlp
|
19 |
def thisIsHook(d):
|
|
|
1 |
import os
|
2 |
+
import time
|
3 |
+
import json
|
4 |
import random
|
5 |
import string
|
6 |
+
import sqlite3
|
7 |
+
import hashlib
|
8 |
import requests
|
9 |
|
10 |
+
# SQLite3 class
|
11 |
+
class EazySQLite3():
|
12 |
+
def __init__(self, db: str = "sqlite.db"):
|
13 |
+
self.connection = sqlite3.connect(db)
|
14 |
+
#self.cursor = sqlite_connection.cursor()
|
15 |
+
def query(self, query: str = ""):
|
16 |
+
cursor = self.connection.cursor()
|
17 |
+
try:
|
18 |
+
cursor.execute(query)
|
19 |
+
self.connection.commit()
|
20 |
+
try:
|
21 |
+
record = cursor.fetchall()
|
22 |
+
cursor.close()
|
23 |
+
return {"status": True, "details": record}
|
24 |
+
except:
|
25 |
+
try: cursor.close()
|
26 |
+
except: pass
|
27 |
+
finally: return {"status": True, "details": None}
|
28 |
+
except Exception as e: return {"status": False, "details": str(e)}
|
29 |
+
def close(self):
|
30 |
+
self.connection.close()
|
31 |
+
|
32 |
# Deleting audio
|
33 |
def deleteAudio(path: str, waitInSeconds: int = 0):
|
34 |
+
config = configFile()
|
35 |
+
os.system("rm {}/{}".format(config['static-path'], path))
|
36 |
+
|
37 |
+
# Config file reading
|
38 |
+
def configFile():
|
39 |
+
with open("C:\\Users\\InspectorJoey\\Desktop\\api\\routes\\config.json", "r") as file:
|
40 |
+
config = json.loads(file.read())
|
41 |
+
return config
|
42 |
|
43 |
+
# Signatures check!!! Wow!!!
|
44 |
+
def checkSignature(request, signature: str):
|
45 |
+
config = configFile()
|
46 |
+
db = EazySQLite3(config['signatures-db'])
|
47 |
+
query = db.query(f"SELECT * FROM `table` WHERE `key`=\"{signature}\" AND `endtime`>{time.time()}")
|
48 |
+
if len(query['details']) == 0: return False
|
49 |
+
|
50 |
+
ip = hashlib.md5(request.remote_addr.encode()).hexdigest()
|
51 |
+
creatorKey = hashlib.md5(f"IP={ip};DATE={time.strftime('%Y-%m-%d')}".encode()).hexdigest()
|
52 |
+
for row in query['details']:
|
53 |
+
if creatorKey == row[2]: return True
|
54 |
+
return False
|
55 |
|
56 |
# Hook for yt-dlp
|
57 |
def thisIsHook(d):
|
routes/osuApi/findSong.py
CHANGED
@@ -7,7 +7,7 @@ def findSong(request):
|
|
7 |
if request.method == 'POST': signature = request.form['signature']
|
8 |
else: signature = request.args['signature']
|
9 |
except: return {"status": "error", "details": { "error_code": 103, "error_details": "No signature" }}
|
10 |
-
if not helpers.checkSignature(signature): return {"status": "error", "details": { "error_code": 105, "error_details": "Invalid signature" }}
|
11 |
|
12 |
try:
|
13 |
if request.method == 'POST': query = request.form['query']
|
|
|
7 |
if request.method == 'POST': signature = request.form['signature']
|
8 |
else: signature = request.args['signature']
|
9 |
except: return {"status": "error", "details": { "error_code": 103, "error_details": "No signature" }}
|
10 |
+
if not helpers.checkSignature(request, signature): return {"status": "error", "details": { "error_code": 105, "error_details": "Invalid signature" }}
|
11 |
|
12 |
try:
|
13 |
if request.method == 'POST': query = request.form['query']
|
routes/osuApi/getFull.py
CHANGED
@@ -9,7 +9,7 @@ def getFull(request):
|
|
9 |
if request.method == 'POST': signature = request.form['signature']
|
10 |
else: signature = request.args['signature']
|
11 |
except: return {"status": "error", "details": { "error_code": 103, "error_details": "No signature" }}
|
12 |
-
if not helpers.checkSignature(signature): return {"status": "error", "details": { "error_code": 105, "error_details": "Invalid signature" }}
|
13 |
|
14 |
try:
|
15 |
if request.method == 'POST': beatmapId = request.form['beatmapId']
|
@@ -27,33 +27,34 @@ def getFull(request):
|
|
27 |
if beatmapId == None: return {"status": "error", "details": { "error_code": 133, "error_details": "No details for finding preview" }}
|
28 |
else: query = None
|
29 |
|
|
|
30 |
if beatmapId != None:
|
31 |
-
if os.path.exists(f"
|
32 |
-
return {"status": "pass", "details": {"code": 200, "result": "
|
33 |
-
tryment = get("https://kitsu.moe/api/audio/{}"
|
34 |
if int(tryment.status_code) not in [404, 403, 429]:
|
35 |
-
open(f"
|
36 |
-
audio_input = ffmpeg.input(f"
|
37 |
-
audio_output = ffmpeg.output(audio_input, "
|
38 |
ffmpeg.run(audio_output)
|
39 |
-
helpers.deleteAudio("temp/{}.ogg"
|
40 |
-
return {"status": "pass", "details": {"code": int(tryment.status_code), "result": "
|
41 |
else:
|
42 |
return {"status": "error", "details": {"code": int(tryment.status_code), "answer": tryment.text}}
|
43 |
if query != None:
|
44 |
fffff = findSong(request)
|
45 |
if fffff['status'] == "error": return fffff
|
46 |
beatmapId = fffff['details']['result'][rand(0,len(fffff['details']['result']))]['beatmapId']
|
47 |
-
if os.path.exists(f"
|
48 |
-
return {"status": "pass", "details": {"code": 200, "result": "
|
49 |
-
tryment = get("https://kitsu.moe/api/audio/{}"
|
50 |
if int(tryment.status_code) not in [404, 403, 429]:
|
51 |
-
open(f"
|
52 |
-
audio_input = ffmpeg.input(f"
|
53 |
-
audio_output = ffmpeg.output(audio_input, "
|
54 |
ffmpeg.run(audio_output)
|
55 |
-
helpers.deleteAudio("temp/{}.ogg"
|
56 |
-
return {"status": "pass", "details": {"code": int(tryment.status_code), "result": "
|
57 |
else:
|
58 |
return {"status": "error", "details": {"code": int(tryment.status_code), "answer": tryment.text}}
|
59 |
return {}
|
|
|
9 |
if request.method == 'POST': signature = request.form['signature']
|
10 |
else: signature = request.args['signature']
|
11 |
except: return {"status": "error", "details": { "error_code": 103, "error_details": "No signature" }}
|
12 |
+
if not helpers.checkSignature(request, signature): return {"status": "error", "details": { "error_code": 105, "error_details": "Invalid signature" }}
|
13 |
|
14 |
try:
|
15 |
if request.method == 'POST': beatmapId = request.form['beatmapId']
|
|
|
27 |
if beatmapId == None: return {"status": "error", "details": { "error_code": 133, "error_details": "No details for finding preview" }}
|
28 |
else: query = None
|
29 |
|
30 |
+
config = helpers.configFile()
|
31 |
if beatmapId != None:
|
32 |
+
if os.path.exists(f"{config['full-path']}/{beatmapId}.ogg"):
|
33 |
+
return {"status": "pass", "details": {"code": 200, "result": f"{config['url']}/static/full/{beatmapId}.ogg"}}
|
34 |
+
tryment = get(f"https://kitsu.moe/api/audio/{beatmapId}", allow_redirects=True)
|
35 |
if int(tryment.status_code) not in [404, 403, 429]:
|
36 |
+
open(f"{config['temp-path']}/{beatmapId}.mp3", "wb").write(tryment.content)
|
37 |
+
audio_input = ffmpeg.input(f"{config['temp-path']}/{beatmapId}.mp3")
|
38 |
+
audio_output = ffmpeg.output(audio_input, f"{config['full-path']}/{beatmapId}.ogg", audio_bitrate="96K")
|
39 |
ffmpeg.run(audio_output)
|
40 |
+
helpers.deleteAudio(f"temp/{beatmapId}.ogg")
|
41 |
+
return {"status": "pass", "details": {"code": int(tryment.status_code), "result": f"{config['url']}/static/full/{beatmapId}.ogg"}}
|
42 |
else:
|
43 |
return {"status": "error", "details": {"code": int(tryment.status_code), "answer": tryment.text}}
|
44 |
if query != None:
|
45 |
fffff = findSong(request)
|
46 |
if fffff['status'] == "error": return fffff
|
47 |
beatmapId = fffff['details']['result'][rand(0,len(fffff['details']['result']))]['beatmapId']
|
48 |
+
if os.path.exists(f"{config['full-path']}/{beatmapId}.ogg"):
|
49 |
+
return {"status": "pass", "details": {"code": 200, "result": f"{config['url']}/static/full/{beatmapId}.ogg"}}
|
50 |
+
tryment = get(f"https://kitsu.moe/api/audio/{beatmapId}", allow_redirects=True)
|
51 |
if int(tryment.status_code) not in [404, 403, 429]:
|
52 |
+
open(f"{config['temp-path']}/{beatmapId}.mp3", "wb").write(tryment.content)
|
53 |
+
audio_input = ffmpeg.input(f"{config['temp-path']}/{beatmapId}.mp3")
|
54 |
+
audio_output = ffmpeg.output(audio_input, f"{config['full-path']}/{beatmapId}.ogg", audio_bitrate="96K")
|
55 |
ffmpeg.run(audio_output)
|
56 |
+
helpers.deleteAudio(f"temp/{beatmapId}.ogg")
|
57 |
+
return {"status": "pass", "details": {"code": int(tryment.status_code), "result": f"{config['url']}/static/full/{beatmapId}.ogg"}}
|
58 |
else:
|
59 |
return {"status": "error", "details": {"code": int(tryment.status_code), "answer": tryment.text}}
|
60 |
return {}
|
routes/osuApi/getPreview.py
CHANGED
@@ -7,7 +7,7 @@ def getPreview(request):
|
|
7 |
if request.method == 'POST': signature = request.form['signature']
|
8 |
else: signature = request.args['signature']
|
9 |
except: return {"status": "error", "details": { "error_code": 103, "error_details": "No signature" }}
|
10 |
-
if not helpers.checkSignature(signature): return {"status": "error", "details": { "error_code": 105, "error_details": "Invalid signature" }}
|
11 |
|
12 |
try:
|
13 |
if request.method == 'POST': beatmapId = request.form['beatmapId']
|
@@ -26,9 +26,9 @@ def getPreview(request):
|
|
26 |
else: query = None
|
27 |
|
28 |
if beatmapId != None:
|
29 |
-
tryment = get("https://b.ppy.sh/preview/{}.mp3"
|
30 |
if int(tryment.status_code) not in [404, 403]:
|
31 |
-
return {"status": "pass", "details": {"code": int(tryment.status_code), "result": "https://b.ppy.sh/preview/{}.mp3"
|
32 |
else:
|
33 |
return {"status": "error", "details": {"code": int(tryment.status_code), "answer": tryment.text}}
|
34 |
if query != None:
|
|
|
7 |
if request.method == 'POST': signature = request.form['signature']
|
8 |
else: signature = request.args['signature']
|
9 |
except: return {"status": "error", "details": { "error_code": 103, "error_details": "No signature" }}
|
10 |
+
if not helpers.checkSignature(request, signature): return {"status": "error", "details": { "error_code": 105, "error_details": "Invalid signature" }}
|
11 |
|
12 |
try:
|
13 |
if request.method == 'POST': beatmapId = request.form['beatmapId']
|
|
|
26 |
else: query = None
|
27 |
|
28 |
if beatmapId != None:
|
29 |
+
tryment = get(f"https://b.ppy.sh/preview/{beatmapId}.mp3")
|
30 |
if int(tryment.status_code) not in [404, 403]:
|
31 |
+
return {"status": "pass", "details": {"code": int(tryment.status_code), "result": f"https://b.ppy.sh/preview/{beatmapId}.mp3"}}
|
32 |
else:
|
33 |
return {"status": "error", "details": {"code": int(tryment.status_code), "answer": tryment.text}}
|
34 |
if query != None:
|
routes/siteRoutes/__init__.py
ADDED
@@ -0,0 +1 @@
|
|
|
|
|
1 |
+
from .sigGen import *
|
routes/siteRoutes/sigGen.py
ADDED
@@ -0,0 +1,27 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import time
|
2 |
+
import random
|
3 |
+
import hashlib
|
4 |
+
from .. import helpers
|
5 |
+
|
6 |
+
def signatureGen(request):
|
7 |
+
endtime = round(time.time())+604800
|
8 |
+
|
9 |
+
ip = hashlib.md5(request.remote_addr.encode()).hexdigest()
|
10 |
+
text = f"--START SIGNATURE-- {ip}{endtime} --END SIGNATURE--"
|
11 |
+
salt = "f u n a p i - s a l t".split(' ')
|
12 |
+
random.shuffle(salt)
|
13 |
+
salt = ''.join(salt)
|
14 |
+
|
15 |
+
creatorKey = hashlib.md5(f"IP={ip};DATE={time.strftime('%Y-%m-%d')}".encode()).hexdigest()
|
16 |
+
|
17 |
+
key = hashlib.blake2b(text.encode(), key=ip.encode(), salt=salt.encode()).hexdigest().upper()
|
18 |
+
|
19 |
+
db = helpers.EazySQLite3("C:\\Users\\InspectorJoey\\Desktop\\api\\signatures.db")
|
20 |
+
|
21 |
+
query = db.query(f"INSERT INTO `table` (`key`, `endtime`, `creatorKey`) VALUES (\"{key}\", \"{endtime}\", \"{creatorKey}\")")
|
22 |
+
|
23 |
+
if query['status']:
|
24 |
+
return {"status": "ok", "result": key, "endtime": endtime}
|
25 |
+
else:
|
26 |
+
return {"status": "error", "details": {"error_code": -1, "error_details": "You already got signature"}}
|
27 |
+
|
routes/witaiApi/recognizeVoice.py
CHANGED
@@ -13,6 +13,7 @@ def recognizeVoice(request):
|
|
13 |
if request.method == 'POST': signature = request.form['signature']
|
14 |
else: signature = request.args['signature']
|
15 |
except: return {"status": "error", "details": { "error_code": 103, "error_details": "No signature" }}
|
|
|
16 |
try:
|
17 |
if request.method == 'POST': extendInfo = request.form['extendInfo']
|
18 |
else: extendInfo = request.args['extendInfo']
|
|
|
13 |
if request.method == 'POST': signature = request.form['signature']
|
14 |
else: signature = request.args['signature']
|
15 |
except: return {"status": "error", "details": { "error_code": 103, "error_details": "No signature" }}
|
16 |
+
if not helpers.checkSignature(request, signature): return {"status": "error", "details": { "error_code": 105, "error_details": "Invalid signature" }}
|
17 |
try:
|
18 |
if request.method == 'POST': extendInfo = request.form['extendInfo']
|
19 |
else: extendInfo = request.args['extendInfo']
|
routes/ytApi/get.py
CHANGED
@@ -7,7 +7,7 @@ def get(request, check = "huh"):
|
|
7 |
if request.method == 'POST': signature = request.form['signature']
|
8 |
else: signature = request.args['signature']
|
9 |
except: return {"status": "error", "details": { "error_code": 103, "error_details": "No signature" }}
|
10 |
-
if not helpers.checkSignature(signature): return {"status": "error", "details": { "error_code": 105, "error_details": "Invalid signature" }}
|
11 |
|
12 |
try:
|
13 |
if request.method == 'POST': url = request.form['url']
|
@@ -31,15 +31,17 @@ def get(request, check = "huh"):
|
|
31 |
except: urlcode = helpers.randString()
|
32 |
if urlcode in ['', None]: urlcode = helpers.randString()
|
33 |
|
34 |
-
|
35 |
-
return {"status": "pass", 'done-or-not': True, 'ytdlp-code': 0, 'urlcode': urlcode, "path": "/home/ubuntu/api/static/{}/{}.ogg".format(check, urlcode), "quality": quality, "bitrate": bitrate}
|
36 |
|
37 |
-
if os.path.exists("
|
38 |
-
return {"status": "pass", 'done-or-not':
|
|
|
|
|
|
|
39 |
|
40 |
ydl_opts = {
|
41 |
'format': f'ogg/{quality}audio/{quality}',
|
42 |
-
'outtmpl': "
|
43 |
'progress_hooks': [helpers.thisIsHook],
|
44 |
}
|
45 |
|
@@ -47,4 +49,4 @@ def get(request, check = "huh"):
|
|
47 |
with yt_dlp.YoutubeDL(ydl_opts) as ydl:
|
48 |
error_code = ydl.download(url)
|
49 |
except Exception as e: return {"status": "error", "details": {"error_code": 102, "error_details": str(e)}}
|
50 |
-
return {"status": "pass", 'done-or-not': False, 'ytdlp-code': error_code, 'urlcode': urlcode, "path": "
|
|
|
7 |
if request.method == 'POST': signature = request.form['signature']
|
8 |
else: signature = request.args['signature']
|
9 |
except: return {"status": "error", "details": { "error_code": 103, "error_details": "No signature" }}
|
10 |
+
if not helpers.checkSignature(request, signature): return {"status": "error", "details": { "error_code": 105, "error_details": "Invalid signature" }}
|
11 |
|
12 |
try:
|
13 |
if request.method == 'POST': url = request.form['url']
|
|
|
31 |
except: urlcode = helpers.randString()
|
32 |
if urlcode in ['', None]: urlcode = helpers.randString()
|
33 |
|
34 |
+
config = helpers.configFile()
|
|
|
35 |
|
36 |
+
if os.path.exists(f"{config['static-path']}/{check}/{urlcode}.ogg"):
|
37 |
+
return {"status": "pass", 'done-or-not': True, 'ytdlp-code': 0, 'urlcode': urlcode, "path": f"{config['static-path']}/{check}/{urlcode}.ogg", "quality": quality, "bitrate": bitrate}
|
38 |
+
|
39 |
+
if os.path.exists(f"{config['temp-path']}/{urlcode}.ogg"):
|
40 |
+
return {"status": "pass", 'done-or-not': False, 'ytdlp-code': 0, 'urlcode': urlcode, "path": f"{config['temp-path']}/{urlcode}.ogg", "quality": quality, "bitrate": bitrate}
|
41 |
|
42 |
ydl_opts = {
|
43 |
'format': f'ogg/{quality}audio/{quality}',
|
44 |
+
'outtmpl': f"{config['temp-path']}/{urlcode}.ogg",
|
45 |
'progress_hooks': [helpers.thisIsHook],
|
46 |
}
|
47 |
|
|
|
49 |
with yt_dlp.YoutubeDL(ydl_opts) as ydl:
|
50 |
error_code = ydl.download(url)
|
51 |
except Exception as e: return {"status": "error", "details": {"error_code": 102, "error_details": str(e)}}
|
52 |
+
return {"status": "pass", 'done-or-not': False, 'ytdlp-code': error_code, 'urlcode': urlcode, "path": f"{config['temp-path']}/{urlcode}.ogg", "quality": quality, "bitrate": bitrate}
|
routes/ytApi/getFull.py
CHANGED
@@ -13,14 +13,15 @@ def getFull(request):
|
|
13 |
quality = answer['quality']
|
14 |
error_code = answer['ytdlp-code']
|
15 |
|
|
|
16 |
if answer['done-or-not']:
|
17 |
-
return {"status": "pass", "details": {"code": error_code, "name":"{}.ogg".format(urlcode), "result": "
|
18 |
|
19 |
try:
|
20 |
audio_input = ffmpeg.input(answer['path'])
|
21 |
-
audio_output = ffmpeg.output(audio_input.audio, "
|
22 |
ffmpeg.run(audio_output)
|
23 |
-
helpers.deleteAudio("temp/{}.ogg"
|
24 |
-
except Exception as e: return {"status": "error", "details": {"error_code": 102, "error_details": str(e), "result": "
|
25 |
-
return {"status": "pass", "details": {"code": error_code, "name":"{}.ogg".format(urlcode), "result": "
|
26 |
|
|
|
13 |
quality = answer['quality']
|
14 |
error_code = answer['ytdlp-code']
|
15 |
|
16 |
+
config = helpers.configFile()
|
17 |
if answer['done-or-not']:
|
18 |
+
return {"status": "pass", "details": {"code": error_code, "name":"{}.ogg".format(urlcode), "result": f"{config['url']}/static/full/{urlcode}.ogg"}}
|
19 |
|
20 |
try:
|
21 |
audio_input = ffmpeg.input(answer['path'])
|
22 |
+
audio_output = ffmpeg.output(audio_input.audio, f"{config['full-path']}/{urlcode}.ogg", audio_bitrate=bitrate)
|
23 |
ffmpeg.run(audio_output)
|
24 |
+
helpers.deleteAudio(f"temp/{urlcode}.ogg")
|
25 |
+
except Exception as e: return {"status": "error", "details": {"error_code": 102, "error_details": str(e), "result": f"{config['url']}/static/temp/{urlcode}.ogg"}}
|
26 |
+
return {"status": "pass", "details": {"code": error_code, "name":"{}.ogg".format(urlcode), "result": f"{config['url']}/static/full/{urlcode}.ogg"}}
|
27 |
|
routes/ytApi/getPreview.py
CHANGED
@@ -19,15 +19,16 @@ def getPreview(request):
|
|
19 |
if duration > 60: duration = 60
|
20 |
except: duration = 30
|
21 |
|
|
|
22 |
if answer['done-or-not']:
|
23 |
-
return {"status": "pass", "details": {"code": error_code, "name":"{}.ogg"
|
24 |
|
25 |
try:
|
26 |
audio_input = ffmpeg.input(answer['path'])
|
27 |
audio_cut = audio_input.audio.filter('atrim', duration=duration)
|
28 |
-
audio_output = ffmpeg.output(audio_cut, "
|
29 |
ffmpeg.run(audio_output)
|
30 |
-
helpers.deleteAudio("temp/{}.ogg"
|
31 |
-
except Exception as e: return {"status": "error", "details": {"error_code": 102, "error_details": str(e), "result": "
|
32 |
-
return {"status": "pass", "details": {"code": error_code, "name":"{}.ogg"
|
33 |
|
|
|
19 |
if duration > 60: duration = 60
|
20 |
except: duration = 30
|
21 |
|
22 |
+
config = helpers.configFile()
|
23 |
if answer['done-or-not']:
|
24 |
+
return {"status": "pass", "details": {"code": error_code, "name":f"{urlcode}.ogg", "result": f"{config['url']}/static/previews/{urlcode}.ogg"}}
|
25 |
|
26 |
try:
|
27 |
audio_input = ffmpeg.input(answer['path'])
|
28 |
audio_cut = audio_input.audio.filter('atrim', duration=duration)
|
29 |
+
audio_output = ffmpeg.output(audio_cut, f"{config['previews-path']}/{urlcode}.ogg", audio_bitrate=bitrate)
|
30 |
ffmpeg.run(audio_output)
|
31 |
+
helpers.deleteAudio(f"temp/{urlcode}.ogg")
|
32 |
+
except Exception as e: return {"status": "error", "details": {"error_code": 102, "error_details": str(e), "result": f"{config['url']}/static/temp/{urlcode}.ogg"}}
|
33 |
+
return {"status": "pass", "details": {"code": error_code, "name":f"{urlcode}.ogg", "result": f"{config['url']}/static/previews/{urlcode}.ogg"}}
|
34 |
|
routes/ytApi/search.py
CHANGED
@@ -13,7 +13,7 @@ def search(request):
|
|
13 |
if request.method == 'POST': signature = request.form['signature']
|
14 |
else: signature = request.args['signature']
|
15 |
except: return {"status": "error", "details": { "error_code": 103, "error_details": "No signature" }}
|
16 |
-
if not helpers.checkSignature(signature): return {"status": "error", "details": { "error_code": 105, "error_details": " signature" }}
|
17 |
html = urllib.request.urlopen("https://www.youtube.com/results?search_query={}".format(urllib.parse.quote_plus(searchQuery)))
|
18 |
videoList = re.findall(r"watch\?v=(\S{11})", html.read().decode())
|
19 |
videoIds = dict()
|
|
|
13 |
if request.method == 'POST': signature = request.form['signature']
|
14 |
else: signature = request.args['signature']
|
15 |
except: return {"status": "error", "details": { "error_code": 103, "error_details": "No signature" }}
|
16 |
+
if not helpers.checkSignature(request, signature): return {"status": "error", "details": { "error_code": 105, "error_details": " signature" }}
|
17 |
html = urllib.request.urlopen("https://www.youtube.com/results?search_query={}".format(urllib.parse.quote_plus(searchQuery)))
|
18 |
videoList = re.findall(r"watch\?v=(\S{11})", html.read().decode())
|
19 |
videoIds = dict()
|
signatures.db
ADDED
Binary file (16.4 kB). View file
|
|
static/api.yaml
CHANGED
@@ -1,11 +1,13 @@
|
|
1 |
openapi: 3.0.0
|
2 |
info:
|
3 |
-
title:
|
4 |
-
description: Collection of APIs for bots or just fun by @
|
5 |
version: 0.1.103
|
6 |
servers:
|
|
|
|
|
7 |
- url: 'https://funapi.dnszilla.bar/'
|
8 |
-
description:
|
9 |
paths:
|
10 |
/recognize/api/v1/voice:
|
11 |
get:
|
|
|
1 |
openapi: 3.0.0
|
2 |
info:
|
3 |
+
title: woolbot's FunAPI
|
4 |
+
description: Collection of APIs for bots or just fun by @podvaljoey.
|
5 |
version: 0.1.103
|
6 |
servers:
|
7 |
+
- url: 'https://imperialwool-funapi.hf.space/'
|
8 |
+
description: First path, public.
|
9 |
- url: 'https://funapi.dnszilla.bar/'
|
10 |
+
description: Second path, private.
|
11 |
paths:
|
12 |
/recognize/api/v1/voice:
|
13 |
get:
|
templates/index.html
CHANGED
@@ -1,7 +1,7 @@
|
|
1 |
<!doctype html> <!-- Important: must specify -->
|
2 |
<html>
|
3 |
<head>
|
4 |
-
<title>
|
5 |
<style> body {background-color:#14191f;} </style>
|
6 |
<meta charset="utf-8">
|
7 |
<meta name="viewport" content="width=device-width, minimum-scale=1, initial-scale=1, user-scalable=yes">
|
|
|
1 |
<!doctype html> <!-- Important: must specify -->
|
2 |
<html>
|
3 |
<head>
|
4 |
+
<title>woolbot's FunAPI</title>
|
5 |
<style> body {background-color:#14191f;} </style>
|
6 |
<meta charset="utf-8">
|
7 |
<meta name="viewport" content="width=device-width, minimum-scale=1, initial-scale=1, user-scalable=yes">
|