imperialwool commited on
Commit
367be45
1 Parent(s): 74924ab

removing signature and supporting only post

Browse files
app.py CHANGED
@@ -1,29 +1,16 @@
1
  import os
2
  from flask import *
3
- from flask_limiter import Limiter
4
- from flask_limiter.util import get_remote_address
5
 
6
- from routes.helpers import checkSignature, configFile
7
  from routes import *
8
 
9
- from random import randint
10
- from transformers import AutoTokenizer, AutoModelForSequenceClassification, AutoModelForSeq2SeqLM
11
 
12
  #initing
13
  app = Flask(__name__)
14
- VERSION = '1.0 build117'
15
  app.config['JSON_AS_ASCII'] = False
16
- limiter = Limiter(app=app, key_func=get_remote_address, default_limits=["5/minute"], storage_uri="memory://",)
17
-
18
- #limiter
19
- @limiter.request_filter
20
- def ip_whitelist():
21
- #try:
22
- # if request.method == 'POST': signature = request.form['signature']
23
- # else: signature = request.args['signature']
24
- # return checkSignature(signature)
25
- #except: return False
26
- return bool(randint(0,1))
27
  #error pages
28
  @app.errorhandler(429)
29
  def ratelimit_handler(e): return render_template('ratelimit.html')
@@ -37,68 +24,57 @@ def ratelimit_handler(e): return render_template('intervalservererror.html')
37
  def ratelimit_handler(e): return render_template('badgateway.html')
38
 
39
  #empty routes
40
- @app.route('/yt/api/v1', methods=['GET', 'POST'])
41
- @app.route('/recognize/api/v1', methods=['GET', 'POST'])
42
- @app.route('/osu/api/v1', methods=['GET', 'POST'])
43
  def emptyPath(): return {}
44
 
45
- @app.route('/yt/api/v1/<path:path>', 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
53
  def favicon(): return send_from_directory(os.path.join(app.root_path, 'static'), 'favicon.ico', mimetype='image/vnd.microsoft.icon')
54
 
55
  ###############
56
  #SITE ROUTES
57
  @app.route('/')
58
- @limiter.exempt
59
  def index(): return render_template('index.html')
60
- @app.route('/signatures/api/v1/get', methods=['GET', 'POST'])
61
- @limiter.exempt
62
- def signatureGen(): return siteRoutes.signatureGen(request)
63
- @app.route('/system-info/api/v1/get', methods=['GET', 'POST'])
64
- @limiter.exempt
65
  def systemInfo(): return siteRoutes.systemInfo()
66
-
67
- ###############
68
- #RECOGNIZE API
69
- @app.route('/recognize/api/v1/voice', methods=['GET', 'POST'])
70
- def recognizeVoice(): return recognizeApi.recognizeVoice(request)
71
 
72
  ###############
73
  #YT SOUND API
74
- @app.route('/yt/api/v1/search', methods=['GET', 'POST'])
75
  def search(): return ytApi.search(request)
76
- @app.route('/yt/api/v1/get-full', methods=['GET', 'POST'])
77
  def getFull(): return ytApi.getFull(request)
78
- @app.route('/yt/api/v1/get-preview', methods=['GET', 'POST'])
79
  def getPreview(): return ytApi.getPreview(request)
80
 
81
  ###############
82
  #OSU API
83
- @app.route('/osu/api/v1/find-song', methods=['GET', 'POST'])
84
  def findSong(): return osuApi.findSong(request)
85
- @app.route('/osu/api/v1/get-beatmap', methods=['GET', 'POST'])
86
  def getBeatmap(): return osuApi.getBeatmap(request)
87
- @app.route('/osu/api/v1/get-preview', methods=['GET', 'POST'])
88
  def getBMPreview(): return osuApi.getPreview(request)
89
- @app.route('/osu/api/v1/get-full', methods=['GET', 'POST'])
90
  def getBMFull(): return osuApi.getFull(request)
91
 
92
  ###############
93
  # LOAD MODELS
94
  sa_t, sa_m = AutoTokenizer.from_pretrained("cardiffnlp/twitter-xlm-roberta-base-sentiment"), AutoModelForSequenceClassification.from_pretrained("cardiffnlp/twitter-xlm-roberta-base-sentiment")
95
  tc_t, tc_m = AutoTokenizer.from_pretrained("EIStakovskii/xlm_roberta_base_multilingual_toxicity_classifier_plus"), AutoModelForSequenceClassification.from_pretrained("EIStakovskii/xlm_roberta_base_multilingual_toxicity_classifier_plus")
96
- chct_t, chct_m = AutoTokenizer.from_pretrained("cointegrated/rut5-small-chitchat"), AutoModelForSeq2SeqLM.from_pretrained("cointegrated/rut5-small-chitchat")
97
 
98
  ##############
99
  # ANALYZE DATA API
100
  # to understand which text is negative, positive or neutral
101
- @app.route('/analyzeText/api/v1/sentiment', methods=['GET', 'POST'])
102
  def sentimentAnalys():
103
  try:
104
  text = request.form.get('text') or request.args.get('text') or request.values.get('text') or ""
@@ -110,7 +86,6 @@ def sentimentAnalys():
110
 
111
  inputs = sa_t(text, return_tensors="pt")
112
 
113
- # Предсказание тональности текста
114
  outputs = sa_m(**inputs)
115
  logits = outputs.logits
116
  predicted_sentiment_index = logits.argmax(dim=1).item()
@@ -118,7 +93,7 @@ def sentimentAnalys():
118
 
119
  return {"status": "pass", "predicted_sentiment": predicted_sentiment}
120
  except Exception as e: return {"status": "error", "details": { "error_code": 123, "error_details": str(e).replace("\n", " | ") }}
121
- @app.route('/analyzeText/api/v1/toxicity', methods=['GET', 'POST'])
122
  def toxicityAnalys():
123
  try:
124
  text = request.form.get('text') or request.args.get('text') or request.values.get('text') or ""
@@ -130,7 +105,6 @@ def toxicityAnalys():
130
 
131
  inputs = tc_t(text, return_tensors="pt")
132
 
133
- # Предсказание тональности текста
134
  outputs = tc_m(**inputs)
135
  logits = outputs.logits
136
  predicted_class = logits.argmax(dim=1).item()
@@ -138,26 +112,6 @@ def toxicityAnalys():
138
 
139
  return {"status": "pass", "toxicity": predicted_sentiment}
140
  except Exception as e: return {"status": "error", "details": { "error_code": 123, "error_details": str(e).replace("\n", " | ") }} , 400
141
- @app.route('/analyzeText/api/v1/chitchat', methods=['POST'])
142
- def chitchatRu():
143
- try:
144
- text = request.form.get('text') or request.args.get('text') or request.values.get('text') or ""
145
- if text == "":
146
- try: text = request.json.get('text') or ""
147
- except: pass
148
-
149
- if text == "":
150
- return {"status": "error", "details": {"error_code": 101, "error_details": "No text provided"}}, 400
151
-
152
- inputs = chct_t.encode(text, padding=True, truncation=True, return_tensors="pt")
153
- generated_ids = chct_m.generate(
154
- input_ids=inputs,
155
- use_cache=False
156
- )
157
- answer = chct_t.decode(generated_ids[0], skip_special_tokens=True)
158
- return {"status": "pass", "answer": answer}, 200
159
- except Exception as e:
160
- return {"status": "error", "details": {"error_code": 123, "error_details": str(e).replace("\n", " | ")}}, 400
161
 
162
  if __name__ == "__main__":
163
  config = configFile()
 
1
  import os
2
  from flask import *
 
 
3
 
4
+ from routes.helpers import configFile
5
  from routes import *
6
 
7
+ from transformers import AutoTokenizer, AutoModelForSequenceClassification
 
8
 
9
  #initing
10
  app = Flask(__name__)
11
+ VERSION = '1.0 build120'
12
  app.config['JSON_AS_ASCII'] = False
13
+
 
 
 
 
 
 
 
 
 
 
14
  #error pages
15
  @app.errorhandler(429)
16
  def ratelimit_handler(e): return render_template('ratelimit.html')
 
24
  def ratelimit_handler(e): return render_template('badgateway.html')
25
 
26
  #empty routes
27
+ @app.route('/yt/api/v1', methods=['POST'])
28
+ @app.route('/recognize/api/v1', methods=['POST'])
29
+ @app.route('/osu/api/v1', methods=['POST'])
30
  def emptyPath(): return {}
31
 
32
+ @app.route('/yt/api/v1/<path:path>', methods=['POST'])
33
+ @app.route('/recognize/api/v1/<path:path>', methods=['POST'])
34
+ @app.route('/osu/api/v1/<path:path>', methods=['POST'])
35
  def emptyApiWA(path): return {"status": "error", "error_code": 100, "error_details": "No method like that found"}
36
 
37
  #icon
38
  @app.route('/favicon.ico')
39
+
40
  def favicon(): return send_from_directory(os.path.join(app.root_path, 'static'), 'favicon.ico', mimetype='image/vnd.microsoft.icon')
41
 
42
  ###############
43
  #SITE ROUTES
44
  @app.route('/')
 
45
  def index(): return render_template('index.html')
46
+ @app.route('/signatures/api/v1/get', methods=['POST'])
 
 
 
 
47
  def systemInfo(): return siteRoutes.systemInfo()
 
 
 
 
 
48
 
49
  ###############
50
  #YT SOUND API
51
+ @app.route('/yt/api/v1/search', methods=['POST'])
52
  def search(): return ytApi.search(request)
53
+ @app.route('/yt/api/v1/get-full', methods=['POST'])
54
  def getFull(): return ytApi.getFull(request)
55
+ @app.route('/yt/api/v1/get-preview', methods=['POST'])
56
  def getPreview(): return ytApi.getPreview(request)
57
 
58
  ###############
59
  #OSU API
60
+ @app.route('/osu/api/v1/find-song', methods=['POST'])
61
  def findSong(): return osuApi.findSong(request)
62
+ @app.route('/osu/api/v1/get-beatmap', methods=['POST'])
63
  def getBeatmap(): return osuApi.getBeatmap(request)
64
+ @app.route('/osu/api/v1/get-preview', methods=['POST'])
65
  def getBMPreview(): return osuApi.getPreview(request)
66
+ @app.route('/osu/api/v1/get-full', methods=['POST'])
67
  def getBMFull(): return osuApi.getFull(request)
68
 
69
  ###############
70
  # LOAD MODELS
71
  sa_t, sa_m = AutoTokenizer.from_pretrained("cardiffnlp/twitter-xlm-roberta-base-sentiment"), AutoModelForSequenceClassification.from_pretrained("cardiffnlp/twitter-xlm-roberta-base-sentiment")
72
  tc_t, tc_m = AutoTokenizer.from_pretrained("EIStakovskii/xlm_roberta_base_multilingual_toxicity_classifier_plus"), AutoModelForSequenceClassification.from_pretrained("EIStakovskii/xlm_roberta_base_multilingual_toxicity_classifier_plus")
 
73
 
74
  ##############
75
  # ANALYZE DATA API
76
  # to understand which text is negative, positive or neutral
77
+ @app.route('/analyzeText/api/v1/sentiment', methods=['POST'])
78
  def sentimentAnalys():
79
  try:
80
  text = request.form.get('text') or request.args.get('text') or request.values.get('text') or ""
 
86
 
87
  inputs = sa_t(text, return_tensors="pt")
88
 
 
89
  outputs = sa_m(**inputs)
90
  logits = outputs.logits
91
  predicted_sentiment_index = logits.argmax(dim=1).item()
 
93
 
94
  return {"status": "pass", "predicted_sentiment": predicted_sentiment}
95
  except Exception as e: return {"status": "error", "details": { "error_code": 123, "error_details": str(e).replace("\n", " | ") }}
96
+ @app.route('/analyzeText/api/v1/toxicity', methods=['POST'])
97
  def toxicityAnalys():
98
  try:
99
  text = request.form.get('text') or request.args.get('text') or request.values.get('text') or ""
 
105
 
106
  inputs = tc_t(text, return_tensors="pt")
107
 
 
108
  outputs = tc_m(**inputs)
109
  logits = outputs.logits
110
  predicted_class = logits.argmax(dim=1).item()
 
112
 
113
  return {"status": "pass", "toxicity": predicted_sentiment}
114
  except Exception as e: return {"status": "error", "details": { "error_code": 123, "error_details": str(e).replace("\n", " | ") }} , 400
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
115
 
116
  if __name__ == "__main__":
117
  config = configFile()
requirements.txt CHANGED
@@ -8,7 +8,6 @@ requests
8
  py-cpuinfo
9
  transformers
10
  ffmpeg-python
11
- flask_limiter
12
  sentencepiece
13
  tensorflow-cpu
14
  SpeechRecognition
 
8
  py-cpuinfo
9
  transformers
10
  ffmpeg-python
 
11
  sentencepiece
12
  tensorflow-cpu
13
  SpeechRecognition
routes/__pycache__/__init__.cpython-310.pyc DELETED
Binary file (250 Bytes)
 
routes/__pycache__/__init__.cpython-311.pyc DELETED
Binary file (345 Bytes)
 
routes/__pycache__/helpers.cpython-310.pyc DELETED
Binary file (4.62 kB)
 
routes/config.json CHANGED
@@ -9,7 +9,5 @@
9
  "config-path": "/app/routes/config.json",
10
  "openapi-yaml-path": "/app/static/api.yaml",
11
 
12
- "signatures-db": "/app/signatures.db",
13
-
14
  "buildVersion": "1.0 build63"
15
  }
 
9
  "config-path": "/app/routes/config.json",
10
  "openapi-yaml-path": "/app/static/api.yaml",
11
 
 
 
12
  "buildVersion": "1.0 build63"
13
  }
routes/helpers.py CHANGED
@@ -1,33 +1,7 @@
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):
@@ -40,19 +14,6 @@ def configFile():
40
  config = json.loads(file.read())
41
  return config
42
 
43
- # Signatures check!!! Wow!!!
44
- def checkSignature(signature: str):
45
- config = configFile()
46
- db = EazySQLite3(config['signatures-db'])
47
- query = db.query(f"SELECT * FROM `table` WHERE (`key` LIKE \"{signature}\" OR `key`=\"{signature}\") AND `endtime`>{time.time()}")
48
- #if len(query['details']) == 0: return False
49
- for row in query['details']:
50
- if signature == row[0]:
51
- newTTL = round(time.time())+86400
52
- if newTTL > row[1]: db.query(f"UPDATE `table` SET `endtime`={newTTL} WHERE `key`=\"{signature}\"")
53
- return True
54
- return False
55
-
56
  # Hook for yt-dlp
57
  def thisIsHook(d):
58
  try:
@@ -63,72 +24,7 @@ def thisIsHook(d):
63
 
64
  # Get variable from request
65
  def getFromRequest(request, thing: str):
66
- try:
67
- if request.method == 'POST': reqthing = request.form[thing]
68
- else: reqthing = request.args[thing]
69
- return reqthing
70
- except: return None
71
-
72
- # Recognizing things
73
- def req(access_token, meth, path, params, **kwargs):
74
- full_url = "https://api.wit.ai" + path
75
- headers = {
76
- "authorization": "Bearer " + access_token,
77
- "accept": "application/vnd.wit." + "20221114" + "+json",
78
- }
79
- headers.update(kwargs.pop("headers", {}))
80
- rsp = requests.request(meth, full_url, headers=headers, params=params, **kwargs)
81
- if rsp.status_code > 200:
82
- raise Exception(
83
- str(rsp.status_code)
84
- + " ("
85
- + rsp.reason
86
- + ")"
87
- )
88
- try: r = rsp.json()
89
- except: r = rsp.text
90
- if "error" in r:
91
- raise Exception(json["error"])
92
 
93
- return r
94
- def dictation(access_token, audio_file, headers=None, verbose=None):
95
- params = {}
96
- headers = headers or {}
97
- if verbose:
98
- params["verbose"] = True
99
- resp = req(
100
- access_token,
101
- "POST",
102
- "/dictation",
103
- params,
104
- data=audio_file,
105
- headers=headers,
106
- )
107
- return resp
108
- def clean(text):
109
- if text not in ['', None]:
110
- return text.replace('?', '').replace('!', '').replace(';', '').replace('.', '').replace(',', '')
111
- def delivering(text):
112
- result = []
113
- temp = None
114
- toPush = None
115
- tempLength = 0
116
- for dirtLine in text.split('\n'):
117
- if '"text"' in dirtLine:
118
- line = dirtLine[11:-1]
119
- if temp == None: temp = line
120
- else:
121
- if temp in line: toPush = line
122
- else:
123
- temp = line
124
- result.append(toPush)
125
- return ' '.join(result)
126
- def devRaw(text):
127
- result = []
128
- for line in text.split('\n'): #line[11:-1]
129
- if '"text"' in line:
130
- result.append(line[11:-1])
131
- return result
132
-
133
  def randString(len: int = 16):
134
  return ''.join(random.SystemRandom().choice(string.ascii_uppercase + string.ascii_lowercase + string.digits) for _ in range(len))
 
1
  import os
 
2
  import json
3
  import random
4
  import string
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5
 
6
  # Deleting audio
7
  def deleteAudio(path: str, waitInSeconds: int = 0):
 
14
  config = json.loads(file.read())
15
  return config
16
 
 
 
 
 
 
 
 
 
 
 
 
 
 
17
  # Hook for yt-dlp
18
  def thisIsHook(d):
19
  try:
 
24
 
25
  # Get variable from request
26
  def getFromRequest(request, thing: str):
27
+ return request.json.get(thing) if request.is_json else request.form.get(thing)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
28
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
29
  def randString(len: int = 16):
30
  return ''.join(random.SystemRandom().choice(string.ascii_uppercase + string.ascii_lowercase + string.digits) for _ in range(len))
routes/osuApi/__pycache__/__init__.cpython-310.pyc DELETED
Binary file (244 Bytes)
 
routes/osuApi/__pycache__/findSong.cpython-310.pyc DELETED
Binary file (1.3 kB)
 
routes/osuApi/__pycache__/getBeatmap.cpython-310.pyc DELETED
Binary file (380 Bytes)
 
routes/osuApi/__pycache__/getFull.cpython-310.pyc DELETED
Binary file (2.13 kB)
 
routes/osuApi/__pycache__/getPreview.cpython-310.pyc DELETED
Binary file (1.39 kB)
 
routes/osuApi/findSong.py CHANGED
@@ -1,19 +1,9 @@
1
- import json
2
  from .. import helpers
3
  from requests import get
4
  from random import randint as rand
5
  def findSong(request):
6
- try:
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']
14
- else: query = request.args['query']
15
- if query.strip() in ['', None]: raise Exception()
16
- except: return {"status": "error", "details": { "error_code": 133, "error_details": "No query" }}
17
 
18
  tryment = get("https://api.chimu.moe/v1/search", params={"query": query})
19
  if int(tryment.status_code) not in [404, 403]:
@@ -32,4 +22,4 @@ def findSong(request):
32
  if counter >= rand(3,7): break
33
  return {"status": "pass", "details": {"code": int(tryment.status_code), "result": res}}
34
  else:
35
- return {"status": "error", "details": {"code": int(tryment.status_code), "answer": tryment.text}}
 
 
1
  from .. import helpers
2
  from requests import get
3
  from random import randint as rand
4
  def findSong(request):
5
+ query = helpers.getFromRequest(request, "query")
6
+ if not query: return {"status": "error", "details": { "error_code": 133, "error_details": "No query" }}, 400
 
 
 
 
 
 
 
 
 
7
 
8
  tryment = get("https://api.chimu.moe/v1/search", params={"query": query})
9
  if int(tryment.status_code) not in [404, 403]:
 
22
  if counter >= rand(3,7): break
23
  return {"status": "pass", "details": {"code": int(tryment.status_code), "result": res}}
24
  else:
25
+ return {"status": "error", "details": {"code": int(tryment.status_code), "answer": tryment.text}}, 400
routes/osuApi/getFull.py CHANGED
@@ -5,27 +5,8 @@ from .findSong import *
5
  from requests import get
6
  from random import randint as rand
7
  def getFull(request):
8
- try:
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']
16
- else: beatmapId = request.args['beatmapId']
17
- if beatmapId.strip() in ['', None]:
18
- raise Exception()
19
- except: beatmapId = None
20
-
21
- try:
22
- if request.method == 'POST': query = request.form['query']
23
- else: query = request.args['query']
24
- if query.strip() in ['', None]:
25
- raise Exception()
26
- except:
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:
@@ -40,8 +21,8 @@ def getFull(request):
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'])-1)]['beatmapId']
@@ -56,5 +37,5 @@ def getFull(request):
56
  helpers.deleteAudio(f"temp/{beatmapId}.ogg")
57
  return {"status": "pass", "details": {"code": int(tryment.status_code), "name": f"{beatmapId}.ogg", "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 {}
 
5
  from requests import get
6
  from random import randint as rand
7
  def getFull(request):
8
+ beatmapId = helpers.getFromRequest(request, "beatmapId")
9
+ query = helpers.getFromRequest(request, "query")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
10
 
11
  config = helpers.configFile()
12
  if beatmapId != None:
 
21
  helpers.deleteAudio(f"temp/{beatmapId}.ogg")
22
  return {"status": "pass", "details": {"code": int(tryment.status_code), "result": f"{config['url']}/static/full/{beatmapId}.ogg"}}
23
  else:
24
+ return {"status": "error", "details": {"code": int(tryment.status_code), "answer": tryment.text}}, 400
25
+ elif query != None:
26
  fffff = findSong(request)
27
  if fffff['status'] == "error": return fffff
28
  beatmapId = fffff['details']['result'][rand(0,len(fffff['details']['result'])-1)]['beatmapId']
 
37
  helpers.deleteAudio(f"temp/{beatmapId}.ogg")
38
  return {"status": "pass", "details": {"code": int(tryment.status_code), "name": f"{beatmapId}.ogg", "result": f"{config['url']}/static/full/{beatmapId}.ogg"}}
39
  else:
40
+ return {"status": "error", "details": {"code": int(tryment.status_code), "answer": tryment.text}}, 400
41
+ return {"status": "error", "details": { "error_code": 133, "error_details": "No details for finding preview" }}, 400
routes/osuApi/getPreview.py CHANGED
@@ -3,37 +3,18 @@ from .findSong import *
3
  from requests import get
4
  from random import randint as rand
5
  def getPreview(request):
6
- try:
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']
14
- else: beatmapId = request.args['beatmapId']
15
- if beatmapId.strip() in ['', None]:
16
- raise Exception()
17
- except: beatmapId = None
18
-
19
- try:
20
- if request.method == 'POST': query = request.form['query']
21
- else: query = request.args['query']
22
- if query.strip() in ['', None]:
23
- raise Exception()
24
- except:
25
- if beatmapId == None: return {"status": "error", "details": { "error_code": 133, "error_details": "No details for finding preview" }}
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:
35
  fffff = findSong(request)
36
- if fffff['status'] == "error": return fffff
37
  rBId = fffff['details']['result'][rand(0,len(fffff['details']['result'])-1)]['beatmapId']
38
  return {"status": "pass", "details": {"code": fffff['details']['code'], "name": "{rBId}.mp3", "result": f"https://b.ppy.sh/preview/{rBId}.mp3"}}
39
- return {}
 
3
  from requests import get
4
  from random import randint as rand
5
  def getPreview(request):
6
+ beatmapId = helpers.getFromRequest(request, "beatmapId")
7
+ query = helpers.getFromRequest(request, "query")
8
+
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
9
  if beatmapId != None:
10
  tryment = get(f"https://b.ppy.sh/preview/{beatmapId}.mp3")
11
  if int(tryment.status_code) not in [404, 403]:
12
  return {"status": "pass", "details": {"code": int(tryment.status_code), "result": f"https://b.ppy.sh/preview/{beatmapId}.mp3"}}
13
  else:
14
+ return {"status": "error", "details": {"code": int(tryment.status_code), "answer": tryment.text}}, 400
15
+ elif query != None:
16
  fffff = findSong(request)
17
+ if fffff['status'] == "error": return fffff, 400
18
  rBId = fffff['details']['result'][rand(0,len(fffff['details']['result'])-1)]['beatmapId']
19
  return {"status": "pass", "details": {"code": fffff['details']['code'], "name": "{rBId}.mp3", "result": f"https://b.ppy.sh/preview/{rBId}.mp3"}}
20
+ return {"status": "error", "details": { "error_code": 133, "error_details": "No details for finding preview" }}, 400
routes/recognizeApi/__init__.py DELETED
@@ -1 +0,0 @@
1
- from .recognizeVoice import *
 
 
routes/recognizeApi/__pycache__/__init__.cpython-310.pyc DELETED
Binary file (189 Bytes)
 
routes/recognizeApi/__pycache__/recognizeVoice.cpython-310.pyc DELETED
Binary file (1.98 kB)
 
routes/recognizeApi/recognizeVoice.py DELETED
@@ -1,58 +0,0 @@
1
- import wget
2
- import random
3
- import string
4
- import ffmpeg
5
- from .. import helpers
6
- import speech_recognition as sr
7
-
8
- def recognizeVoice(request):
9
- try:
10
- if request.method == 'POST': url = request.form['url']
11
- else: url = request.args['url']
12
- if url.strip() in ['', None]: raise Exception()
13
- except: return {"status": "error", "details": { "error_code": 101, "error_details": "No link provided" }}
14
- try:
15
- if request.method == 'POST': signature = request.form['signature']
16
- else: signature = request.args['signature']
17
- except: return {"status": "error", "details": { "error_code": 103, "error_details": "No signature" }}
18
- if not helpers.checkSignature(signature): return {"status": "error", "details": { "error_code": 105, "error_details": "Invalid signature" }}
19
- try:
20
- if request.method == 'POST': lang = request.form['lang']
21
- else: lang = request.args['lang']
22
- if lang.lower() in ['en','en-us']: lang = 'en-US'
23
- elif lang.lower() in ['ru','ru-ru']: lang = 'ru-RU'
24
- except: lang = "en-US"
25
-
26
- fileId = ''.join(random.SystemRandom().choice(string.ascii_uppercase + string.ascii_lowercase + string.digits) for _ in range(16))
27
- fileExt = url[url.rfind('.'):url.rfind('.')+4]
28
- if fileExt in [".wav",".mp3",".ogg",'.aac']: pass
29
- else: return {"status": "error", "details": { "error_code": 111, "error_details": "Wrong file format (only ogg, wav, mp3)" }}
30
-
31
- r = sr.Recognizer()
32
-
33
- config = helpers.configFile()
34
-
35
- wget.download(url, f"{config['temp-path']}/{fileId}{fileExt}")
36
- if fileExt != ".wav":
37
- audio_input = ffmpeg.input(f"{config['temp-path']}/{fileId}{fileExt}")
38
- oldFE = fileExt
39
- fileExt = ".wav"
40
- audio_output = ffmpeg.output(audio_input.audio, f"{config['temp-path']}/{fileId}{fileExt}")
41
- ffmpeg.run(audio_output)
42
- helpers.deleteAudio(f"temp/{fileId}.{oldFE}")
43
-
44
- rawSource = sr.AudioFile(f"{config['temp-path']}/{fileId}{fileExt}")
45
- with rawSource as source:
46
- r.adjust_for_ambient_noise(source)
47
- audio = r.record(source)
48
-
49
- try: googleText = r.recognize_google(audio, language=lang)
50
- except: googleText = ""
51
-
52
- # at now here's no keys :(
53
- #try: houndifyText = r.recognize_houndify(audio)
54
- #except: houndifyText = ""
55
-
56
- helpers.deleteAudio(f"temp/{fileId}{fileExt}")
57
-
58
- return {"status": "pass", "result": {"google": googleText, "houndify": "NOT-WORKING"}}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
routes/signatures.db DELETED
Binary file (16.4 kB)
 
routes/siteRoutes/__init__.py CHANGED
@@ -1,2 +1 @@
1
- from .sigGen import *
2
  from .systemInfo import *
 
 
1
  from .systemInfo import *
routes/siteRoutes/__pycache__/__init__.cpython-310.pyc DELETED
Binary file (205 Bytes)
 
routes/siteRoutes/__pycache__/sigGen.cpython-310.pyc DELETED
Binary file (1.23 kB)
 
routes/siteRoutes/__pycache__/systemInfo.cpython-310.pyc DELETED
Binary file (1.09 kB)
 
routes/siteRoutes/sigGen.py DELETED
@@ -1,29 +0,0 @@
1
- import time
2
- import random
3
- import hashlib
4
- from .. import helpers
5
-
6
- def signatureGen(request):
7
- endtime = round(time.time())+3600
8
-
9
- uK = helpers.getFromRequest(request, "key")
10
- if uK == None: return {"status": "error", "details": {"error_code": -1, "error_details": "No key to generate signature"}}
11
-
12
- userKey = hashlib.md5(uK.encode()).hexdigest()
13
- text = f"--START SIGNATURE-- {userKey}{endtime} --END SIGNATURE--"
14
- salt = hashlib.md5("funapi-salt".encode()).hexdigest()[0:16]
15
-
16
- creatorKey = hashlib.md5(f"HOST-IP:{request.remote_addr};USERKEY={userKey};DATE={time.strftime('%Y-%m-%d')};".encode()).hexdigest()
17
-
18
- key = hashlib.blake2b(text.encode(), key=userKey.encode(), salt=salt.encode()).hexdigest().upper()
19
-
20
- config = helpers.configFile()
21
- db = helpers.EazySQLite3(config['signatures-db'])
22
-
23
- query = db.query(f"INSERT INTO `table` (`key`, `endtime`, `creatorKey`) VALUES (\"{key}\", \"{endtime}\", \"{creatorKey}\")")
24
-
25
- if query['status']:
26
- return {"status": "pass", "result": key, "endtime": endtime}
27
- else:
28
- return {"status": "error", "details": {"error_code": -1, "error_details": "This key already got signature"}}
29
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
routes/ytApi/get.py CHANGED
@@ -3,33 +3,18 @@ import yt_dlp
3
  from .. import helpers
4
 
5
  def get(request, check = "huh"):
6
- try:
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']
14
- else: url = request.args['url']
15
- if url.strip() in ['', None]:
16
- raise Exception()
17
- except: return {"status": "error", "details": { "error_code": 101, "error_details": "No link provided" }}
18
 
19
- try:
20
- if request.method == 'POST': bitrate = str(request.form['bitrate'])
21
- else: bitrate = str(request.args['bitrate'])
22
- except: bitrate = "64k"
23
- try:
24
- if request.method == 'POST': quality = request.form['quality']
25
- else: quality = request.args['quality']
26
- if quality.lower() not in ['best', 'worst']: raise Exception()
27
- except: quality = 'worst'
28
 
29
- urlcode = None
30
- try: urlcode = url.partition('?v=')[2]
31
- except: urlcode = helpers.randString()
32
- if urlcode in ['', None]: urlcode = helpers.randString()
33
 
34
  config = helpers.configFile()
35
 
@@ -48,5 +33,5 @@ def get(request, check = "huh"):
48
  try:
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}
 
3
  from .. import helpers
4
 
5
  def get(request, check = "huh"):
6
+ url = helpers.getFromRequest(request, "url")
7
+ if not url: return {"status": "error", "details": { "error_code": 101, "error_details": "No link provided" }}, 400
 
 
 
 
 
 
 
 
 
 
8
 
9
+ bitrate = helpers.getFromRequest(request, "bitrate")
10
+ if not bitrate: bitrate = "64k"
11
+
12
+ quality = helpers.getFromRequest(request, "quality").lower()
13
+ if quality.lower() not in ['best', 'worst']: quality = 'worst'
14
+ else: bitrate = str(bitrate)
 
 
 
15
 
16
+ urlcode = url.partition('?v=')[2]
17
+ if not urlcode: urlcode = "NPRNRQh2fAo"
 
 
18
 
19
  config = helpers.configFile()
20
 
 
33
  try:
34
  with yt_dlp.YoutubeDL(ydl_opts) as ydl:
35
  error_code = ydl.download(url)
36
+ except Exception as e: return {"status": "error", "details": {"error_code": 102, "error_details": str(e)}}, 400
37
  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
@@ -8,7 +8,7 @@ def getFull(request):
8
  if answer['status'] == "error": return answer
9
  if answer['error']: return answer
10
  except KeyError: pass
11
- except Exception as e: return {"status": "error", "details": { "error_code": 123, "error_details": e }}
12
  urlcode = answer['urlcode']
13
  bitrate = answer['bitrate']
14
  quality = answer['quality']
@@ -23,6 +23,6 @@ def getFull(request):
23
  audio_output = ffmpeg.output(audio_input.audio, f"{config['full-path']}/{urlcode}.ogg", audio_bitrate=bitrate)
24
  ffmpeg.run(audio_output)
25
  helpers.deleteAudio(f"temp/{urlcode}.ogg")
26
- except Exception as e: return {"status": "error", "details": {"error_code": 102, "error_details": str(e), "result": f"{config['url']}/static/temp/{urlcode}.ogg"}}
27
  return {"status": "pass", "details": {"code": error_code, "name":"{}.ogg".format(urlcode), "result": f"{config['url']}/static/full/{urlcode}.ogg"}}
28
 
 
8
  if answer['status'] == "error": return answer
9
  if answer['error']: return answer
10
  except KeyError: pass
11
+ except Exception as e: return {"status": "error", "details": { "error_code": 123, "error_details": e }}, 400
12
  urlcode = answer['urlcode']
13
  bitrate = answer['bitrate']
14
  quality = answer['quality']
 
23
  audio_output = ffmpeg.output(audio_input.audio, f"{config['full-path']}/{urlcode}.ogg", audio_bitrate=bitrate)
24
  ffmpeg.run(audio_output)
25
  helpers.deleteAudio(f"temp/{urlcode}.ogg")
26
+ except Exception as e: return {"status": "error", "details": {"error_code": 102, "error_details": str(e), "result": f"{config['url']}/static/temp/{urlcode}.ogg"}}, 400
27
  return {"status": "pass", "details": {"code": error_code, "name":"{}.ogg".format(urlcode), "result": f"{config['url']}/static/full/{urlcode}.ogg"}}
28
 
routes/ytApi/getPreview.py CHANGED
@@ -9,24 +9,17 @@ def getPreview(request):
9
  if answer['status'] == "error": return answer
10
  if answer['error']: return answer
11
  except KeyError: pass
12
- except Exception as e: return {"status": "error", "details": { "error_code": 123, "error_details": e }}
13
  urlcode = answer['urlcode']
14
  bitrate = answer['bitrate']
15
- quality = answer['quality']
16
  error_code = answer['ytdlp-code']
17
 
18
- try:
19
- if request.method == 'POST': duration = int(request.form['duration'])
20
- else: duration = int(request.args['duration'])
21
- if duration >= 60: duration = 60
22
- except Exception as e:
23
- print(e)
24
- duration = 30
25
 
26
- try:
27
- if request.method == 'POST': extension = request.form['extension']
28
- else: extension = request.args['extension']
29
- except: extension = "ogg"
30
 
31
  config = helpers.configFile()
32
  if answer['done-or-not']:
@@ -41,6 +34,6 @@ def getPreview(request):
41
  audio_output = ffmpeg.output(audio_cut, f"{config['previews-path']}/{urlcode}.{extension}", audio_bitrate=bitrate)
42
  ffmpeg.run(audio_output)
43
  helpers.deleteAudio(f"temp/{urlcode}.{extension}")
44
- except Exception as e: return {"status": "error", "details": {"error_code": 102, "error_details": str(e), "result": f"{config['url']}/static/temp/{urlcode}.{extension}"}}
45
  return {"status": "pass", "details": {"code": error_code, "name":f"{urlcode}.{extension}", "result": f"{config['url']}/static/previews/{urlcode}.{extension}"}}
46
 
 
9
  if answer['status'] == "error": return answer
10
  if answer['error']: return answer
11
  except KeyError: pass
12
+ except Exception as e: return {"status": "error", "details": { "error_code": 123, "error_details": e }}, 400
13
  urlcode = answer['urlcode']
14
  bitrate = answer['bitrate']
 
15
  error_code = answer['ytdlp-code']
16
 
17
+ duration = helpers.getFromRequest(request, "duration")
18
+ try: duration = int(duration) if duration.isnumeric() and int(duration) <= 90 else 45
19
+ except: duration = 45
 
 
 
 
20
 
21
+ extension = helpers.getFromRequest(request, "extension")
22
+ if not extension: extension = "ogg"
 
 
23
 
24
  config = helpers.configFile()
25
  if answer['done-or-not']:
 
34
  audio_output = ffmpeg.output(audio_cut, f"{config['previews-path']}/{urlcode}.{extension}", audio_bitrate=bitrate)
35
  ffmpeg.run(audio_output)
36
  helpers.deleteAudio(f"temp/{urlcode}.{extension}")
37
+ except Exception as e: return {"status": "error", "details": {"error_code": 102, "error_details": str(e), "result": f"{config['url']}/static/temp/{urlcode}.{extension}"}}, 400
38
  return {"status": "pass", "details": {"code": error_code, "name":f"{urlcode}.{extension}", "result": f"{config['url']}/static/previews/{urlcode}.{extension}"}}
39
 
routes/ytApi/search.py CHANGED
@@ -3,20 +3,14 @@ import re
3
  from .. import helpers
4
 
5
  def search(request):
 
 
6
  try:
7
- if request.method == 'POST': searchQuery = request.form['query']
8
- else: searchQuery = request.args['query']
9
- if searchQuery.strip() in ['', None]:
10
- raise Exception()
11
- except: searchQuery = "rickroll"
12
- try:
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": "Invalid 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()
20
- for i in range(len(videoList)):
21
- videoIds.update({i: videoList[i]})
22
- return {"status": "pass", "query": searchQuery, "videoIds": videoIds}
 
3
  from .. import helpers
4
 
5
  def search(request):
6
+ searchQuery = helpers.getFromRequest(request, "query")
7
+ if not searchQuery: searchQuery = "rickroll"
8
  try:
9
+ html = urllib.request.urlopen("https://www.youtube.com/results?search_query={}".format(urllib.parse.quote_plus(searchQuery)))
10
+ videoList = re.findall(r"watch\?v=(\S{11})", html.read().decode())
11
+ videoIds = dict()
12
+ for i in range(len(videoList)): videoIds.update({i: videoList[i]})
13
+ return {"status": "pass", "query": searchQuery, "videoIds": videoIds}
14
+ except Exception as e:
15
+ print(e)
16
+ return {"status": "error", "details": { "error_code": 666, "error_details": "Something went wrong..." }}, 500
 
 
 
 
 
 
 
 
static/api.yaml CHANGED
@@ -5,33 +5,9 @@ info:
5
  version: $VERSION_VARIABLE$
6
  servers:
7
  - url: 'https://imperialwool-funapi.hf.space/'
8
- description: 'You are here! ^з^'
9
  paths:
10
  /signatures/api/v1/get:
11
- get:
12
- tags:
13
- - "Authentication"
14
- parameters:
15
- - name: 'key'
16
- description: Key to generate signature.
17
- in: 'query'
18
- schema:
19
- type: 'string'
20
- example: rickroll
21
- summary: "Generating auth key with small TTL."
22
- responses:
23
- 200:
24
- description: OK
25
- content:
26
- application/json:
27
- schema:
28
- $ref: "#/components/schemas/AuthSuccessObject"
29
- 400:
30
- description: Bad Request
31
- content:
32
- application/json:
33
- schema:
34
- $ref: "#/components/schemas/AuthErrorObject"
35
  post:
36
  tags:
37
  - "Authentication"
@@ -57,36 +33,6 @@ paths:
57
  schema:
58
  $ref: "#/components/schemas/AuthErrorObject"
59
  /osu/api/v1/find-song:
60
- get:
61
- tags:
62
- - "osu! API"
63
- parameters:
64
- - name: 'query'
65
- description: Query to find beatmap.
66
- in: 'query'
67
- schema:
68
- type: 'string'
69
- example: rickroll
70
- - name: 'signature'
71
- description: Special access key.
72
- in: 'query'
73
- schema:
74
- type: 'string'
75
- example: 'B46AAB1A3F1E33625C1B6BD9507453B928DE69BA638E7098DB533A2184ED288EFB899D563EF8AB5487DACBCAD909A801E4C81FD6D34B639F6591295CD1D10A5B'
76
- summary: "Finding beatmap by query."
77
- responses:
78
- 200:
79
- description: OK
80
- content:
81
- application/json:
82
- schema:
83
- $ref: "#/components/schemas/FindBeatmapsObject"
84
- 400:
85
- description: Bad Request
86
- content:
87
- application/json:
88
- schema:
89
- $ref: "#/components/schemas/ErrorObject"
90
  post:
91
  tags:
92
  - "osu! API"
@@ -97,12 +43,6 @@ paths:
97
  schema:
98
  type: 'string'
99
  example: rickroll
100
- - name: 'signature'
101
- description: Special access key.
102
- in: 'query'
103
- schema:
104
- type: 'string'
105
- example: 'B46AAB1A3F1E33625C1B6BD9507453B928DE69BA638E7098DB533A2184ED288EFB899D563EF8AB5487DACBCAD909A801E4C81FD6D34B639F6591295CD1D10A5B'
106
  summary: "Finding beatmap by query."
107
  responses:
108
  200:
@@ -118,42 +58,6 @@ paths:
118
  schema:
119
  $ref: "#/components/schemas/ErrorObject"
120
  /osu/api/v1/get-full:
121
- get:
122
- tags:
123
- - "osu! API"
124
- parameters:
125
- - name: 'query'
126
- description: Query to find beatmap and download full song.
127
- in: 'query'
128
- schema:
129
- type: 'string'
130
- example: rickroll
131
- - name: 'beatmapId'
132
- description: Beatset id. Not map, set.
133
- in: 'query'
134
- schema:
135
- type: 'integer'
136
- example: 1
137
- - name: 'signature'
138
- description: Special access key.
139
- in: 'query'
140
- schema:
141
- type: 'string'
142
- example: 'B46AAB1A3F1E33625C1B6BD9507453B928DE69BA638E7098DB533A2184ED288EFB899D563EF8AB5487DACBCAD909A801E4C81FD6D34B639F6591295CD1D10A5B'
143
- summary: "Get beatmap's full song."
144
- responses:
145
- 200:
146
- description: OK
147
- content:
148
- application/json:
149
- schema:
150
- $ref: "#/components/schemas/SongFullObject"
151
- 400:
152
- description: Bad Request
153
- content:
154
- application/json:
155
- schema:
156
- $ref: "#/components/schemas/ErrorObject"
157
  post:
158
  tags:
159
  - "osu! API"
@@ -170,12 +74,6 @@ paths:
170
  schema:
171
  type: 'integer'
172
  example: 1
173
- - name: 'signature'
174
- description: Special access key.
175
- in: 'query'
176
- schema:
177
- type: 'string'
178
- example: 'B46AAB1A3F1E33625C1B6BD9507453B928DE69BA638E7098DB533A2184ED288EFB899D563EF8AB5487DACBCAD909A801E4C81FD6D34B639F6591295CD1D10A5B'
179
  summary: "Get beatmap's full song."
180
  responses:
181
  200:
@@ -191,42 +89,6 @@ paths:
191
  schema:
192
  $ref: "#/components/schemas/ErrorObject"
193
  /osu/api/v1/get-preview:
194
- get:
195
- tags:
196
- - "osu! API"
197
- parameters:
198
- - name: 'query'
199
- description: Query to find beatmap and download full song.
200
- in: 'query'
201
- schema:
202
- type: 'string'
203
- example: rickroll
204
- - name: 'beatmapId'
205
- description: Beatset id. Not map, set.
206
- in: 'query'
207
- schema:
208
- type: 'integer'
209
- example: 1
210
- - name: 'signature'
211
- description: Special access key.
212
- in: 'query'
213
- schema:
214
- type: 'string'
215
- example: 'B46AAB1A3F1E33625C1B6BD9507453B928DE69BA638E7098DB533A2184ED288EFB899D563EF8AB5487DACBCAD909A801E4C81FD6D34B639F6591295CD1D10A5B'
216
- summary: "Get beatmap's song preview."
217
- responses:
218
- 200:
219
- description: OK
220
- content:
221
- application/json:
222
- schema:
223
- $ref: "#/components/schemas/SongPreviewObject"
224
- 400:
225
- description: Bad Request
226
- content:
227
- application/json:
228
- schema:
229
- $ref: "#/components/schemas/ErrorObject"
230
  post:
231
  tags:
232
  - "osu! API"
@@ -243,12 +105,6 @@ paths:
243
  schema:
244
  type: 'integer'
245
  example: 1
246
- - name: 'signature'
247
- description: Special access key.
248
- in: 'query'
249
- schema:
250
- type: 'string'
251
- example: 'B46AAB1A3F1E33625C1B6BD9507453B928DE69BA638E7098DB533A2184ED288EFB899D563EF8AB5487DACBCAD909A801E4C81FD6D34B639F6591295CD1D10A5B'
252
  summary: "Get beatmap's song preview."
253
  responses:
254
  200:
@@ -263,104 +119,7 @@ paths:
263
  application/json:
264
  schema:
265
  $ref: "#/components/schemas/ErrorObject"
266
- /recognize/api/v1/voice:
267
- get:
268
- tags:
269
- - Recognize API
270
- parameters:
271
- - name: 'url'
272
- description: URL-link to voice message. Should be mp3, ogg or wav.
273
- in: 'query'
274
- schema:
275
- type: 'string'
276
- example: https://cdn-102.anonfiles.com/q8v0o5O5y8/3d62dac1-1671893935/j4893hg894g4.mp3
277
- - name: 'extendInfo'
278
- description: Provide additional information or not.
279
- in: 'query'
280
- schema:
281
- type: 'string'
282
- default: False
283
- example: False
284
- - name: 'signature'
285
- description: Special access key.
286
- in: 'query'
287
- schema:
288
- type: 'string'
289
- example: 'B46AAB1A3F1E33625C1B6BD9507453B928DE69BA638E7098DB533A2184ED288EFB899D563EF8AB5487DACBCAD909A801E4C81FD6D34B639F6591295CD1D10A5B'
290
- summary: "This method can help with converting voice into the text."
291
- responses:
292
- 200:
293
- description: OK
294
- content:
295
- application/json:
296
- schema:
297
- $ref: "#/components/schemas/RecognizeObject"
298
- 400:
299
- description: Bad Request
300
- content:
301
- application/json:
302
- schema:
303
- $ref: "#/components/schemas/ErrorObject"
304
- post:
305
- tags:
306
- - Recognize API
307
- parameters:
308
- - name: 'url'
309
- description: URL-link to voice message. Should be mp3, ogg or wav.
310
- in: 'query'
311
- schema:
312
- type: 'string'
313
- example: https://cdn-102.anonfiles.com/q8v0o5O5y8/3d62dac1-1671893935/j4893hg894g4.mp3
314
- - name: 'file'
315
- description: Upload file to recognize voice. **NOT SUPPORTED NOW**
316
- in: 'query'
317
- schema:
318
- type: 'string'
319
- - name: 'extendInfo'
320
- description: Provide additional information or not.
321
- in: 'query'
322
- schema:
323
- type: 'string'
324
- default: False
325
- example: False
326
- - name: 'signature'
327
- description: Special access key.
328
- in: 'query'
329
- schema:
330
- type: 'string'
331
- example: 'B46AAB1A3F1E33625C1B6BD9507453B928DE69BA638E7098DB533A2184ED288EFB899D563EF8AB5487DACBCAD909A801E4C81FD6D34B639F6591295CD1D10A5B'
332
- summary: "This method can help with converting voice into the text."
333
- responses:
334
- 200:
335
- description: OK
336
- content:
337
- application/json:
338
- schema:
339
- $ref: "#/components/schemas/RecognizeObject"
340
- 400:
341
- description: Bad Request
342
- content:
343
- application/json:
344
- schema:
345
- $ref: "#/components/schemas/ErrorObject"
346
  /system-info/api/v1/get:
347
- get:
348
- tags:
349
- - "System information"
350
- summary: "Information about server."
351
- responses:
352
- 200:
353
- description: OK
354
- content:
355
- application/json:
356
- schema:
357
- $ref: "#/components/schemas/SysinfoObject"
358
- 400:
359
- description: Bad Request
360
- content:
361
- application/json:
362
- schema:
363
- $ref: "#/components/schemas/ErrorObject"
364
  post:
365
  tags:
366
  - "System information"
@@ -379,36 +138,6 @@ paths:
379
  schema:
380
  $ref: "#/components/schemas/ErrorObject"
381
  /yt/api/v1/search:
382
- get:
383
- tags:
384
- - "Youtube: Becoming Music Platform"
385
- parameters:
386
- - name: 'query'
387
- description: Query for YouTube to find videos.
388
- in: 'query'
389
- schema:
390
- type: 'string'
391
- example: never gonna give you up
392
- - name: 'signature'
393
- description: Special access key.
394
- in: 'query'
395
- schema:
396
- type: 'string'
397
- example: 'B46AAB1A3F1E33625C1B6BD9507453B928DE69BA638E7098DB533A2184ED288EFB899D563EF8AB5487DACBCAD909A801E4C81FD6D34B639F6591295CD1D10A5B'
398
- summary: "This method can help with searching videos on YouTube."
399
- responses:
400
- 200:
401
- description: OK
402
- content:
403
- application/json:
404
- schema:
405
- $ref: "#/components/schemas/YTSearchObject"
406
- 400:
407
- description: Bad Request
408
- content:
409
- application/json:
410
- schema:
411
- $ref: "#/components/schemas/ErrorObject"
412
  post:
413
  tags:
414
  - "Youtube: Becoming Music Platform"
@@ -419,12 +148,7 @@ paths:
419
  schema:
420
  type: 'string'
421
  example: never gonna give you up
422
- - name: 'signature'
423
- description: Special access key.
424
- in: 'query'
425
- schema:
426
- type: 'string'
427
- example: 'B46AAB1A3F1E33625C1B6BD9507453B928DE69BA638E7098DB533A2184ED288EFB899D563EF8AB5487DACBCAD909A801E4C81FD6D34B639F6591295CD1D10A5B'
428
  summary: "This method can help with searching videos on YouTube."
429
  responses:
430
  200:
@@ -440,47 +164,6 @@ paths:
440
  schema:
441
  $ref: "#/components/schemas/ErrorObject"
442
  /yt/api/v1/get-full:
443
- get:
444
- tags:
445
- - "Youtube: Becoming Music Platform"
446
- parameters:
447
- - name: 'url'
448
- description: Url to video from YouTube. (TikTok also works sometimes.)
449
- in: 'query'
450
- schema:
451
- type: 'string'
452
- - name: 'bitrate'
453
- description: Bitrate of final audio.
454
- in: 'query'
455
- schema:
456
- type: 'string'
457
- example: "64k"
458
- - name: 'quality'
459
- description: Quality of final audio. Only 'worst' or 'best'.
460
- in: 'query'
461
- schema:
462
- type: 'string'
463
- example: "worst"
464
- - name: 'signature'
465
- description: Special access key.
466
- in: 'query'
467
- schema:
468
- type: 'string'
469
- example: 'B46AAB1A3F1E33625C1B6BD9507453B928DE69BA638E7098DB533A2184ED288EFB899D563EF8AB5487DACBCAD909A801E4C81FD6D34B639F6591295CD1D10A5B'
470
- summary: "Download video as audio and providing link for you."
471
- responses:
472
- 200:
473
- description: OK
474
- content:
475
- application/json:
476
- schema:
477
- $ref: "#/components/schemas/YTFullObject"
478
- 400:
479
- description: Bad Request
480
- content:
481
- application/json:
482
- schema:
483
- $ref: "#/components/schemas/ErrorObject"
484
  post:
485
  tags:
486
  - "Youtube: Becoming Music Platform"
@@ -502,12 +185,7 @@ paths:
502
  schema:
503
  type: 'string'
504
  example: "worst"
505
- - name: 'signature'
506
- description: Special access key.
507
- in: 'query'
508
- schema:
509
- type: 'string'
510
- example: 'B46AAB1A3F1E33625C1B6BD9507453B928DE69BA638E7098DB533A2184ED288EFB899D563EF8AB5487DACBCAD909A801E4C81FD6D34B639F6591295CD1D10A5B'
511
  summary: "Download video as audio and providing link for you."
512
  responses:
513
  200:
@@ -523,53 +201,6 @@ paths:
523
  schema:
524
  $ref: "#/components/schemas/ErrorObject"
525
  /yt/api/v1/get-preview:
526
- get:
527
- tags:
528
- - "Youtube: Becoming Music Platform"
529
- parameters:
530
- - name: 'url'
531
- description: Url to video from YouTube. (TikTok also works sometimes.)
532
- in: 'query'
533
- schema:
534
- type: 'string'
535
- - name: 'bitrate'
536
- description: Bitrate of final audio.
537
- in: 'query'
538
- schema:
539
- type: 'string'
540
- example: "64k"
541
- - name: 'quality'
542
- description: Quality of final audio. Only 'worst' or 'best'.
543
- in: 'query'
544
- schema:
545
- type: 'string'
546
- example: "worst"
547
- - name: 'duration'
548
- description: Duration of preview. Maximum 60 seconds.
549
- in: 'query'
550
- schema:
551
- type: 'integer'
552
- example: 30
553
- - name: 'signature'
554
- description: Special access key.
555
- in: 'query'
556
- schema:
557
- type: 'string'
558
- example: 'B46AAB1A3F1E33625C1B6BD9507453B928DE69BA638E7098DB533A2184ED288EFB899D563EF8AB5487DACBCAD909A801E4C81FD6D34B639F6591295CD1D10A5B'
559
- summary: "Download video as cutted audio and providing link for you."
560
- responses:
561
- 200:
562
- description: OK
563
- content:
564
- application/json:
565
- schema:
566
- $ref: "#/components/schemas/YTPreviewResult"
567
- 400:
568
- description: Bad Request
569
- content:
570
- application/json:
571
- schema:
572
- $ref: "#/components/schemas/ErrorObject"
573
  post:
574
  tags:
575
  - "Youtube: Becoming Music Platform"
@@ -597,12 +228,6 @@ paths:
597
  schema:
598
  type: 'integer'
599
  example: 30
600
- - name: 'signature'
601
- description: Special access key.
602
- in: 'query'
603
- schema:
604
- type: 'string'
605
- example: 'B46AAB1A3F1E33625C1B6BD9507453B928DE69BA638E7098DB533A2184ED288EFB899D563EF8AB5487DACBCAD909A801E4C81FD6D34B639F6591295CD1D10A5B'
606
  summary: "Download video as cutted audio and providing link for you."
607
  responses:
608
  200:
 
5
  version: $VERSION_VARIABLE$
6
  servers:
7
  - url: 'https://imperialwool-funapi.hf.space/'
8
+ description: 'You are here! ^�^'
9
  paths:
10
  /signatures/api/v1/get:
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
11
  post:
12
  tags:
13
  - "Authentication"
 
33
  schema:
34
  $ref: "#/components/schemas/AuthErrorObject"
35
  /osu/api/v1/find-song:
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
36
  post:
37
  tags:
38
  - "osu! API"
 
43
  schema:
44
  type: 'string'
45
  example: rickroll
 
 
 
 
 
 
46
  summary: "Finding beatmap by query."
47
  responses:
48
  200:
 
58
  schema:
59
  $ref: "#/components/schemas/ErrorObject"
60
  /osu/api/v1/get-full:
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
61
  post:
62
  tags:
63
  - "osu! API"
 
74
  schema:
75
  type: 'integer'
76
  example: 1
 
 
 
 
 
 
77
  summary: "Get beatmap's full song."
78
  responses:
79
  200:
 
89
  schema:
90
  $ref: "#/components/schemas/ErrorObject"
91
  /osu/api/v1/get-preview:
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
92
  post:
93
  tags:
94
  - "osu! API"
 
105
  schema:
106
  type: 'integer'
107
  example: 1
 
 
 
 
 
 
108
  summary: "Get beatmap's song preview."
109
  responses:
110
  200:
 
119
  application/json:
120
  schema:
121
  $ref: "#/components/schemas/ErrorObject"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
122
  /system-info/api/v1/get:
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
123
  post:
124
  tags:
125
  - "System information"
 
138
  schema:
139
  $ref: "#/components/schemas/ErrorObject"
140
  /yt/api/v1/search:
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
141
  post:
142
  tags:
143
  - "Youtube: Becoming Music Platform"
 
148
  schema:
149
  type: 'string'
150
  example: never gonna give you up
151
+
 
 
 
 
 
152
  summary: "This method can help with searching videos on YouTube."
153
  responses:
154
  200:
 
164
  schema:
165
  $ref: "#/components/schemas/ErrorObject"
166
  /yt/api/v1/get-full:
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
167
  post:
168
  tags:
169
  - "Youtube: Becoming Music Platform"
 
185
  schema:
186
  type: 'string'
187
  example: "worst"
188
+
 
 
 
 
 
189
  summary: "Download video as audio and providing link for you."
190
  responses:
191
  200:
 
201
  schema:
202
  $ref: "#/components/schemas/ErrorObject"
203
  /yt/api/v1/get-preview:
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
204
  post:
205
  tags:
206
  - "Youtube: Becoming Music Platform"
 
228
  schema:
229
  type: 'integer'
230
  example: 30
 
 
 
 
 
 
231
  summary: "Download video as cutted audio and providing link for you."
232
  responses:
233
  200: