-
Notifications
You must be signed in to change notification settings - Fork 0
/
main.py
169 lines (152 loc) · 6.21 KB
/
main.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
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
# coding=utf8
from flask import Flask
from flask import render_template
from flask import request
from flask import send_file
from flask import jsonify
import os
import sys
import base64
from youtube_transcript_api import YouTubeTranscriptApi
import speech_recognition as sr
app = Flask(__name__,
static_url_path='',
static_folder='static')
# Routes / to index.html (User interface)
@app.route("/")
def home():
return render_template('index.html')
# The translator function. Handles the entire translation process basically.
@app.route("/text/<text>", methods=["GET", "POST"])
def translateBraille(text):
outputBraille = ""
# Braille has no upper or lower case so we convert everything to lower.
text = text.lower()
# Dictionary of braille characters to english/ascii characters.
brailleDict = {
"a": "⠁", "b": "⠃", "c": "⠉", "d": "⠙",
"e": "⠑", "f": "⠋", "g": "⠛", "h": "⠓",
"i": "⠊", "j": "⠚", "k": "⠅", "l": "⠇",
"m": "⠍", "n": "⠝", "o": "⠕", "p": "⠏",
"q": "⠟", "r": "⠗", "s": "⠎", "t": "⠞",
"u": "⠥", "v": "⠧", "w": "⠺", "x": "⠭",
"y": "⠽", "z": "⠵", "0": "⠚", "1": "⠁",
"2": "⠃", "3": "⠉", "4": "⠙", "5": "⠑",
"6": "⠋", "7": "⠛", "8": "⠓", "9": "⠊",
",": "⠂", ";": "⠆", ":": "⠒", ".": "⠲",
"?": "⠦", "!": "⠖", "‘": "⠄", "“": "⠄⠶",
"“": "⠘⠦", "”": "⠘⠴", "‘": "⠄", "’": "⠄",
"(": "⠐⠣", ")": "⠐⠜", "/": "⠸⠌", "\\": "⠸⠡",
"-": "⠤", " ": " ", "%": "⠨⠴", "@": "⠈⠁", "$": "⠈⠎", "'": "⠄"
}
isNumber = False
quoteLocation = -1
try:
# Translate character by character.
for i in text:
# Handles next line characters.
if i == "\n":
outputBraille += "\n"
continue
# Quotations have special behaviour in braille. Single quote mark is different if it has a corresponding closing mark.
# This function handles replacing the quotation character based on the previously stored quoteLocation
if i == '"':
if quoteLocation == -1:
quoteLocation = len(outputBraille)
outputBraille += "⠠⠶"
else:
tempOutput = list(outputBraille)
tempOutput[quoteLocation] = ""
tempOutput[quoteLocation + 1] = "⠦"
tempOutput.append("⠴")
outputBraille = "".join(tempOutput)
continue
# Numbers have a special character to denote that it is a number.
if i.isdigit() and isNumber:
outputBraille += brailleDict[i]
elif i.isdigit():
isNumber = True
outputBraille += "⠼"
outputBraille += brailleDict[i]
elif isNumber:
isNumber = False
if i == " ":
outputBraille += " "
else:
outputBraille += "⠰"
outputBraille += brailleDict[i]
else:
if i in brailleDict:
outputBraille += brailleDict[i]
except Exception:
# In case anything fails or an unhandleable character is present, show an error message
return "Text contains character that is not recognised."
return outputBraille
# Speech Recogniser API to detect words from wav audio.
@app.route("/speech", methods=["GET", "POST"])
def speechToText():
try:
# Relatively straight forward don't think needs explanation
if request.method == 'POST':
f = request.files['file']
f.save(f.filename)
r = sr.Recognizer()
test = sr.AudioFile(f.filename)
with test as source:
audio = r.record(source)
text = r.recognize_google(audio)
res = { "braille": translateBraille(text), "text": text }
return jsonify(res)
except:
# Catch speech recogniser failure.
return jsonify({ "braille": "oh no something happened... maybe try that again?", "text": "" })
# Process uploaded file content to translate.
@app.route("/file", methods=["GET", "POST"])
def fileUpload():
if request.method == 'POST':
f = request.files['file']
return translateBraille(f.read().decode('utf8'))
# Gets the youtube video captions using the videoID.
@app.route("/getTranscript/<videoID>", methods=["GET", "POST"])
def getTranscript(videoID):
try:
# Query youtube for captions
transcription = YouTubeTranscriptApi.get_transcript(videoID, languages=["en"])
except:
return "Video Link Invalid"
output = ""
for i in transcription:
# Translate text to Braille
output += translateBraille(u'{}'.format(i["text"]))
output += "\n"
return output
# Retrieves base64 URI encoded youtube link from URL and converts to a normal link to retrieve youtube video ID.
@app.route("/youtube/<videoLink>", methods=["GET", "POST"])
def youtube(videoLink):
try:
# Links are base64 encoded in the url as characters such as /, :, & or % in URL conflict.
# We did it twice as base64 does it weirdly for some reason but twice seemed to work.
videoLink = decodeBase64(decodeBase64(videoLink))
videoID = videoLink.split("?v=")
videoID = videoID[1].split("&")[0]
return getTranscript(videoID)
except:
return "Video Link Invalid"
# Handles file downloads
@app.route("/downloadFile/<content>", methods=["GET", "POST"])
def downloadFile(content):
# Save translated content to file
f = open("./output.txt", "w")
f.write(content)
f.close()
# Send file as response to request.
return send_file("./output.txt", as_attachment=True),os.remove("./output.txt")
# Basic Base64 decode function
def decodeBase64(text):
base64_message = text
base64_bytes = base64_message.encode('utf8')
message_bytes = base64.b64decode(base64_bytes)
message = message_bytes.decode('utf8')
return message
if __name__ == "__main__":
app.run(debug=True)