Compare commits

...

10 Commits

Author SHA1 Message Date
3be5af77c6 Termux API update 2022-01-01 20:55:24 +01:00
87ffd22d35 Code splitting for specific usages
Also add a script to update a file containing SMSdb.
2021-12-14 18:35:02 +01:00
076610caf6 I forgot important piece of code 2021-09-06 14:56:10 +02:00
aece55c786 Autorefresh for people
*I know* I can use AJAX, but I don't have the skills yet, I will do the job waiting for AJAX refresh.
Pages are light, that's not a big deal.
2021-09-05 19:04:26 +02:00
f25cc7aa03 Add logos for sent and received messages
Oh my God, there are images now!
2021-09-05 18:51:18 +02:00
44255d6bc2 Add iframes
Trying more fluid experience with iframes.
2021-09-05 13:42:00 +02:00
3dc6d4323b Nicer conversation appearance
I added some style to display messages more nicely.
2021-09-05 11:07:28 +02:00
84d8c8bcc8 Ignore read flag
This modification is to avoid duplicate messages when some of them is read on the phone.
2021-09-04 10:57:15 +02:00
f86fa0d6a7 Suicide at keyboard interrupt
That's a bug, the program does not close at keyboard interruption because of threads, I pu a suicide function at the end, but suicide is never the solution.
2021-09-02 12:51:38 +02:00
867c6daca5 Note on security 2021-09-02 12:41:56 +02:00
4 changed files with 472 additions and 288 deletions

View File

@@ -15,3 +15,9 @@ These libraries are under GNU GPL v3. See [license](LICENSE) for more details.
This program requires Python interpretator and access to Android API. Access to Android API is provided by the API addon and the termux-api package. This program requires Python interpretator and access to Android API. Access to Android API is provided by the API addon and the termux-api package.
Once installed, just run the sms.py script with the python interpretator and connect a browser to phone, on port 8080. Once installed, just run the sms.py script with the python interpretator and connect a browser to phone, on port 8080.
# Note on security
This webserver listen on HTTP, so the traffic between phone and browser is in plain text.
The webserver will only serve the first IP (v4 ou v6) that connect to it, all the other will recieve a 403 error. The server log will show that the server locks on a specific IP when the first client will connect.

412
server.py Executable file
View File

@@ -0,0 +1,412 @@
#!/data/data/com.termux/files/usr/bin/python3
from subprocess import Popen, DEVNULL, PIPE
from json import loads as read_json
from http.server import BaseHTTPRequestHandler, ThreadingHTTPServer as http4_server_do_not_use
from urllib.parse import quote, unquote
from socket import AF_INET6
from cgi import FieldStorage
from os import kill, getpid
from sms import SMS_Service
contacts_list_program = '/data/data/com.termux/files/usr/bin/termux-contact-list'
class HTTPServer (http4_server_do_not_use):
'''
This block is just to have a IPv6 web server
This is not IPv6 only, the server also accepts IPv4 clients
'''
address_family = AF_INET6
def html_header (title = 'No title'):
return ('<html>\n<head>\n\t<title>' + title + '</title>\n' + '''\t<style>
body {
margin: 0 auto;
max-width: 100%;
padding: 0 20px;
}
.message {
border: 2px solid #dedede;
background-color: #f1f1f1;
border-radius: 5px;
padding: 10px;
margin: 10px 0;
}
.darker {
border-color: #ccc;
background-color: #ddd;
}
.message::after {
content: "";
clear: both;
display: table;
}
.message img {
float: left;
max-width: 60px;
width: 100%;
margin-right: 20px;
border-radius: 50%;
}
.message img.right {
float: right;
margin-left: 20px;
margin-right:0;
}
.time-right {
float: right;
color: #aaa;
}
.time-left {
float: left;
color: #999;
}
</style>''' + '<head>\n<body>')
def html_title (text):
return ('\n\t<h1>' + text + '</h1>')
def html_iframe (src, height = '150', width = '300', name = None, style = 'border:none;'):
r = '<iframe src="' + src + '" width="' + width + '" height="' + height + '" style="' + style + '"'
if name is not None:
r += ' name="' + name + '"'
r += '></iframe>'
return (r)
def html_paragraph (text):
return ('\n\t<p>' + text + '</p>')
def html_list (lst):
t = '\n\t<ul>'
for line in lst:
t += '\n\t\t<li>' + line + '</li>'
t += '\n\t</ul>'
return (t)
def html_link (url, text = None, target = '_self'):
if text is None:
text = url
return ('<a href="' + url + '" target="' + target + '">' + text + '</a>')
def html_table (body, table_style = None, cell_style = None):
t = '\n\t<table' + ((' style="' + table_style + '"') if table_style is not None else '') + '>'
for line in body:
t += '\n\t\t<tr>'
for cell in line:
t += '\n\t\t\t<td' + ((' style="' + cell_style + '"') if cell_style is not None else '') + '>' + cell + '</td>'
t += '\n\t\t</tr>'
t += '\n\t</table>'
return (t)
def html_message (msg, sent, time, name, avatar = None):
r = '\n\t<div class="message'
if sent:
r += ' darker'
r += '">\n\t\t<img src="' + str (avatar) + '" alt="' + name + '"'
if sent:
r += ' class="right"'
r += 'style"width:100%;">\n\t\t<p>' + msg.replace ('\n', '<br />') + '</p>\n\t\t<spam class="time-'
if sent:
r += 'left'
else:
r += 'right'
r += '">' + time + '</span>\n\t</div>'
return (r)
def html_form (body, url, post = True):
return ('\n\t<form action="' + url + '"' + (' method="post"' if post else '') + '>' + body + '\n\t</form>')
def html_form_text (id, value = '', textarea = False):
if textarea:
return ('\n\t<textarea name="' + id + '" rows="8" cols="100">' + value + '</textarea>')
return ('\n\t<input type="text" name="' + id + '" value="' + value + '" />')
def html_form_hidden (id, value):
return ('\n\t<input type="hidden" name="' + id + '" value="' + value + '" />')
def html_form_submit (label):
return ('\n\t<input type="submit" value="' + label + '" />')
def html_footer ():
return ('\n</body>\n</html>')
def contact_list ():
p = Popen (
[contacts_list_program, ],
stdin = DEVNULL,
stdout = PIPE
)
return (read_json (p.communicate () [0]))
class Web_Service (BaseHTTPRequestHandler):
def do_GET (self):
global locked_client
client = self.client_address [0]
if locked_client is None:
locked_client = client
print ('Locking on ' + str (client) + '')
if locked_client == client:
global sms
if self.path == '/':
self.send_response (200)
self.send_header ('Content-type', 'text/html; charset=UTF-8')
self.end_headers ()
self.wfile.write ((
html_header (title = 'Termux WebSMS') +
html_iframe ('/list', height = '100%', width = '30%', name = 'list') + html_iframe ('about:blank', height = '100%', width = '70%', name = 'thread') +
html_footer ()
).encode ('utf-8'))
elif self.path == '/up.svg':
self.send_response (200)
self.send_header ('Content-type', 'image/svg+xml; charset=UTF-8')
self.end_headers ()
self.wfile.write ((
'<svg xmlns="http://www.w3.org/2000/svg" width="128" height="128">\n' +
'\t<g>\n' +
'\t\t<path\n' +
'\t\t\tstyle="fill:#000000;stroke:#000000;stroke-width:0.264583"\n' +
'\t\t\td="M 42,128 86,128 86,64 128,64 64,0 0,64 42,64 Z"\n' +
'\t\t/>\n' +
'\t</g>\n' +
'</svg>'
).encode ('utf-8'))
elif self.path == '/down.svg':
self.send_response (200)
self.send_header ('Content-type', 'image/svg+xml; charset=UTF-8')
self.end_headers ()
self.wfile.write ((
'<svg xmlns="http://www.w3.org/2000/svg" width="128" height="128">\n' +
'\t<g>\n' +
'\t\t<path\n' +
'\t\t\tstyle="fill:#000000;stroke:#000000;stroke-width:0.264583"\n' +
'\t\t\td="M 42,0 86,0 86,64 128,64 64,128 0,64 42,64 Z"\n' +
'\t\t/>\n' +
'\t</g>\n' +
'</svg>'
).encode ('utf-8'))
elif self.path == '/list':
self.send_response (200)
self.send_header ('Content-type', 'text/html; charset=UTF-8')
self.send_header ('Refresh', '20')
self.end_headers ()
ls = sms.thread_list ()
lst = []
for i in sorted (ls, key = lambda item: ls [item] [1], reverse = True):
s = ls [i] [0] + ' (' + str (ls [i] [3]) + ')'
if len (ls [i]) == 5:
s = ls [i] [4] + ' (' + str (ls [i] [3]) + ')'
lst.append (html_link ('/?thread=' + str (i), text = s, target = 'thread'))
self.wfile.write ((
html_header (title = 'Conversations list') +
html_title ('Conversation') +
html_paragraph (html_link ('/new', text = 'New conversation', target = 'thread')) +
html_paragraph (html_link ('/list', text = 'Refresh list')) +
html_paragraph ('List of conversations follows:') +
html_list (lst) +
html_footer ()
).encode ('utf-8'))
elif self.path == '/new':
self.send_response (200)
self.send_header ('Content-type', 'text/html; charset=UTF-8')
self.end_headers ()
ls = contact_list ()
lst = []
for i in sorted (ls, key = lambda item: item ['name']):
lst.append (html_link ('/new?num=' + quote (i ['number']), text = i ['name'] + ' (' + i ['number'] + ')'))
self.wfile.write ((
html_header (title = 'New conversation') +
html_title ('Create a new conversation') +
html_paragraph ('Put number here:') +
html_form (
html_form_text ('num') +
html_form_submit ('Validate'),
'/new',
post = False
) +
html_paragraph ('List of contacts follows:') +
html_list (lst) +
html_footer ()
).encode ('utf-8'))
elif self.path [0:9] == '/new?num=':
self.send_response (200)
self.send_header ('Content-type', 'text/html; charset=UTF-8')
self.end_headers ()
number = self.path [9:]
self.wfile.write ((
html_header (title = 'New conversation') +
html_paragraph (html_link ('/new', text = '← Back to new message')) +
html_title ('Create a new conversation with ' + unquote (number)) +
html_paragraph ('Message:') +
html_form (
html_form_text ('msg', textarea = True) +
html_form_hidden ('number', unquote (number)) +
html_form_submit ('Send'),
'/send'
) +
html_footer ()
).encode ('utf-8'))
elif self.path [0:9] == '/?thread=':
try:
id = self.path [9:]
number, name, conv = sms.get_thread (id)
if number is None:
raise (IndexError)
except (ValueError, IndexError):
self.send_response (404)
self.send_header ('Content-type', 'text/html')
self.end_headers ()
self.wfile.write ((
html_header (title = 'Page not found') +
html_title ('Not found') +
html_paragraph ('This page does not exist. You cas return to the ' + html_link ('/', text = 'home') + '.') +
html_footer ()
).encode ('utf-8'))
return ()
if name is None:
name = number
else:
name = name + ' (' + number + ')'
self.send_response (200)
self.send_header ('Content-type', 'text/html; charset=UTF-8')
self.end_headers ()
self.wfile.write ((
html_header (title = 'Conversation with ' + name) +
html_title (name) +
html_form (
html_form_text ('msg', textarea = True) +
html_form_hidden ('number', number) +
html_form_submit ('Send'),
'/send'
) +
html_iframe ('/messages?thread=' + str (id), height = '80%', width = '100%', name = 'messages') +
html_footer ()
).encode ('utf-8'))
elif self.path [0:17] == '/messages?thread=':
try:
id = self.path [17:]
number, name, conv = sms.get_thread (id)
if number is None:
raise (IndexError)
except (ValueError, IndexError):
self.send_response (404)
self.send_header ('Content-type', 'text/html')
self.end_headers ()
self.wfile.write ((
html_header (title = 'Page not found') +
html_title ('Not found') +
html_paragraph ('This page does not exist. You cas return to the ' + html_link ('/', text = 'home') + '.') +
html_footer ()
).encode ('utf-8'))
return ()
self.send_response (200)
self.send_header ('Content-type', 'text/html; charset=UTF-8')
self.send_header ('Refresh', '10')
self.end_headers ()
msgs = ''
for i in sorted (conv, key = lambda item: item [0], reverse = True) [0:2000]:
msgs += html_message (i [2], not i [1], i [0], '' if i [1] else '', avatar = 'down.svg' if i [1] else 'up.svg')
if name is None:
name = number
else:
name = name + ' (' + number + ')'
self.wfile.write ((
html_header (title = 'Conversation with ' + name) +
html_link (self.path, text = 'Refresh') +
msgs +
html_footer ()
).encode ('utf-8'))
else:
self.send_response (404)
self.send_header ('Content-type', 'text/html')
self.end_headers ()
self.wfile.write ((
html_header (title = 'Page not found') +
html_title ('Not found') +
html_paragraph ('This page does not exist. You cas return to the ' + html_link ('/', text = 'home') + '.') +
html_footer ()
).encode ('utf-8'))
else:
self.send_response (403)
self.send_header ('Content-type', 'text/html')
self.end_headers ()
self.wfile.write ((
html_header (title = 'Access denied') +
html_title ('Access denied') +
html_paragraph ('Access have allready been granted to another host.') +
html_footer ()
).encode ('utf-8'))
def do_POST (self):
global locked_client
client = self.client_address [0]
if locked_client is None:
locked_client = client
print ('Locking on ' + str (client) + '')
if locked_client == client:
global sms
if self.path == '/send':
post_data = FieldStorage (fp = self.rfile, headers = self.headers, environ = {'REQUEST_METHOD': 'POST'})
sms.send_sms (post_data.getvalue ('number'), post_data.getvalue ('msg'))
self.send_response (301)
self.send_header ('Location', self.headers.get ('Referer'))
self.end_headers ()
else:
self.send_response (404)
self.send_header ('Content-type', 'text/html')
self.end_headers ()
self.wfile.write ((
html_header (title = 'Page not found') +
html_title ('Not found') +
html_paragraph ('This page does not exist. You cas return to the ' + html_link ('/', text = 'home') + '.') +
html_footer ()
).encode ('utf-8'))
else:
self.send_response (403)
self.send_header ('Content-type', 'text/html')
self.end_headers ()
self.wfile.write ((
html_header (title = 'Access denied') +
html_title ('Access denied') +
html_paragraph ('Access have allready been granted to another host.') +
html_footer ()
).encode ('utf-8'))
if __name__ == '__main__':
sms = SMS_Service ()
server = HTTPServer (('::', 8080), Web_Service)
locked_client = None
print ('Started!')
try:
sms.start ()
server.serve_forever ()
except KeyboardInterrupt:
print ('Interrupt received, closing process…')
server.server_close ()
# BUG: the program must kill itself to end or the user must send Ctrl+C several time to close
# TODO: find another way to close the program in one action, suicide is never the solution
kill (getpid (), 15)

297
sms.py Executable file → Normal file
View File

@@ -2,94 +2,23 @@
from subprocess import Popen, DEVNULL, PIPE from subprocess import Popen, DEVNULL, PIPE
from json import loads as read_json from json import loads as read_json
from http.server import BaseHTTPRequestHandler, ThreadingHTTPServer as http4_server_do_not_use
from urllib.parse import quote, unquote
from socket import AF_INET6
from threading import Thread from threading import Thread
from time import sleep from time import sleep
from cgi import FieldStorage
from sys import exit
sms_list_program = '/data/data/com.termux/files/usr/bin/termux-sms-list' sms_list_program = '/data/data/com.termux/files/usr/bin/termux-sms-list'
sms_send_program = '/data/data/com.termux/files/usr/bin/termux-sms-send' sms_send_program = '/data/data/com.termux/files/usr/bin/termux-sms-send'
contacts_list_program = '/data/data/com.termux/files/usr/bin/termux-contact-list'
class HTTPServer (http4_server_do_not_use):
'''
This block is just to have a IPv6 web server
This is not IPv6 only, the server also accepts IPv4 clients
'''
address_family = AF_INET6
def html_header (title = 'No title'):
return ('<html>\n<head>\n\t<title>' + title + '</title>\n<head>\n<body>')
def html_title (text):
return ('\n\t<h1>' + text + '</h1>')
def html_paragraph (text):
return ('\n\t<p>' + text + '</p>')
def html_list (lst):
t = '\n\t<ul>'
for line in lst:
t += '\n\t\t<li>' + line + '</li>'
t += '\n\t</ul>'
return (t)
def html_link (url, text = None):
if text is None:
text = url
return ('<a href="' + url + '">' + text + '</a>')
def html_table (body, table_style = None, cell_style = None):
t = '\n\t<table' + ((' style="' + table_style + '"') if table_style is not None else '') + '>'
for line in body:
t += '\n\t\t<tr>'
for cell in line:
t += '\n\t\t\t<td' + ((' style="' + cell_style + '"') if cell_style is not None else '') + '>' + cell + '</td>'
t += '\n\t\t</tr>'
t += '\n\t</table>'
return (t)
def html_form (body, url, post = True):
return ('\n\t<form action="' + url + '"' + (' method="post"' if post else '') + '>' + body + '\n\t</form>')
def html_form_text (id, value = '', textarea = False):
if textarea:
return ('\n\t<textarea name="' + id + '" rows="8" cols="100">' + value + '</textarea>')
return ('\n\t<input type="text" name="' + id + '" value="' + value + '" />')
def html_form_hidden (id, value):
return ('\n\t<input type="hidden" name="' + id + '" value="' + value + '" />')
def html_form_submit (label):
return ('\n\t<input type="submit" value="' + label + '" />')
def html_footer ():
return ('\n</body>\n</html>')
class SMS_Service (Thread): class SMS_Service (Thread):
def __init__ (self): def __init__ (self, sms_list = None):
Thread.__init__ (self) Thread.__init__ (self)
if type (sms_list) == list:
self.sms_list = sms_list
else:
self.sms_list = [] self.sms_list = []
def run (self): def build_database (self):
limit_fast_get = 1000000 limit_fast_get = 1000000
limit_normal_get = 20
offset = 0 offset = 0
while True: while True:
msgs = self.get_sms (limit = limit_fast_get, offset = offset) msgs = self.get_sms (limit = limit_fast_get, offset = offset)
@@ -98,19 +27,30 @@ class SMS_Service (Thread):
if len (msgs) < limit_fast_get: if len (msgs) < limit_fast_get:
break break
offset += limit_fast_get offset += limit_fast_get
while True: for msg in self.sms_list:
sleep (10) del (msg ['read'])
def update_database (self):
limit_normal_get = 20
getting_new = True getting_new = True
offset = 0 offset = 0
while getting_new: while getting_new:
msgs = self.get_sms (limit = limit_normal_get, offset = offset) msgs = self.get_sms (limit = limit_normal_get, offset = offset)
getting_new = False getting_new = False
for msg in msgs:
del (msg ['read'])
for msg in msgs: for msg in msgs:
if msg not in self.sms_list: if msg not in self.sms_list:
getting_new = True getting_new = True
self.sms_list.append (msg) self.sms_list.append (msg)
offset += limit_normal_get offset += limit_normal_get
def run (self):
self.build_database ()
while True:
sleep (5)
self.update_database ()
def get_sms (self, limit = 10, offset = 0): def get_sms (self, limit = 10, offset = 0):
while True: while True:
try: try:
@@ -144,8 +84,10 @@ class SMS_Service (Thread):
l [i ['threadid']] [1] = i ['received'] l [i ['threadid']] [1] = i ['received']
l [i ['threadid']] [2] = i ['body'] l [i ['threadid']] [2] = i ['body']
l [i ['threadid']] [3] += 1 l [i ['threadid']] [3] += 1
if len (l [i ['threadid']]) == 4 and 'sender' in i and i ['type'] == 'inbox':
l [i ['threadid']].append (i ['sender'])
else: else:
if 'sender' in i: if 'sender' in i and i ['type'] == 'inbox':
l [i ['threadid']] = [i ['number'], i ['received'], i ['body'], 1, i ['sender']] l [i ['threadid']] = [i ['number'], i ['received'], i ['body'], 1, i ['sender']]
else: else:
l [i ['threadid']] = [i ['number'], i ['received'], i ['body'], 1] l [i ['threadid']] = [i ['number'], i ['received'], i ['body'], 1]
@@ -160,201 +102,6 @@ class SMS_Service (Thread):
l.append ((i ['received'], True if i ['type'] == 'inbox' else False, i ['body'])) l.append ((i ['received'], True if i ['type'] == 'inbox' else False, i ['body']))
if number is None: if number is None:
number = i ['number'] number = i ['number']
if 'sender' in i: if name is None and i ['type'] == 'inbox' and 'sender' in i:
name = i ['sender'] name = i ['sender']
return (number, name, sorted (l, key = lambda item: item [0])) return (number, name, sorted (l, key = lambda item: item [0]))
def contact_list ():
p = Popen (
[contacts_list_program, ],
stdin = DEVNULL,
stdout = PIPE
)
return (read_json (p.communicate () [0]))
class Web_Service (BaseHTTPRequestHandler):
def do_GET (self):
global locked_client
client = self.client_address [0]
if locked_client is None:
locked_client = client
print ('Locking on ' + str (client) + '')
if locked_client == client:
global sms
if self.path == '/':
self.send_response (200)
self.send_header ('Content-type', 'text/html; charset=UTF-8')
self.end_headers ()
ls = sms.thread_list ()
lst = []
for i in sorted (ls, key = lambda item: ls [item] [1], reverse = True):
s = ls [i] [0] + ' (' + str (ls [i] [3]) + ')'
if len (ls [i]) == 5:
s = ls [i] [4] + ' (' + str (ls [i] [3]) + ')'
lst.append ([html_link ('/?thread=' + str (i), text = s), ls [i] [1], ls [i] [2] [0:50]])
self.wfile.write ((
html_header (title = 'Conversations list') +
html_title ('Conversation') +
html_paragraph (html_link ('/new', text = 'New conversation')) +
html_paragraph (html_link ('/', text = 'Refresh list')) +
html_paragraph ('List of conversations follows:') +
html_table (lst) +
html_footer ()
).encode ('utf-8'))
elif self.path == '/new':
self.send_response (200)
self.send_header ('Content-type', 'text/html; charset=UTF-8')
self.end_headers ()
ls = contact_list ()
lst = []
for i in sorted (ls, key = lambda item: item ['name']):
lst.append (html_link ('/new?num=' + quote (i ['number']), text = i ['name'] + ' (' + i ['number'] + ')'))
self.wfile.write ((
html_header (title = 'New conversation') +
html_paragraph (html_link ('/', text = '← Back to list')) +
html_title ('Create a new conversation') +
html_paragraph ('Put number here:') +
html_form (
html_form_text ('num') +
html_form_submit ('Validate'),
'/new',
post = False
) +
html_paragraph ('List of contacts follows:') +
html_list (lst) +
html_footer ()
).encode ('utf-8'))
elif self.path [0:9] == '/new?num=':
self.send_response (200)
self.send_header ('Content-type', 'text/html; charset=UTF-8')
self.end_headers ()
number = self.path [9:]
self.wfile.write ((
html_header (title = 'New conversation') +
html_paragraph (html_link ('/', text = '← Back to list')) +
html_paragraph (html_link ('/new', text = '← Back to new message')) +
html_title ('Create a new conversation with ' + unquote (number)) +
html_paragraph ('Message:') +
html_form (
html_form_text ('msg', textarea = True) +
html_form_hidden ('number', unquote (number)) +
html_form_submit ('Send'),
'/send'
) +
html_footer ()
).encode ('utf-8'))
elif self.path [0:9] == '/?thread=':
try:
id = self.path [9:]
number, name, conv = sms.get_thread (id)
if number is None:
raise (IndexError)
except (ValueError, IndexError):
self.send_response (404)
self.send_header ('Content-type', 'text/html')
self.end_headers ()
self.wfile.write ((
html_header (title = 'Page not found') +
html_title ('Not found') +
html_paragraph ('This page does not exist. You cas return to the ' + html_link ('/', text = 'home') + '.') +
html_footer ()
).encode ('utf-8'))
return ()
self.send_response (200)
self.send_header ('Content-type', 'text/html; charset=UTF-8')
self.end_headers ()
t = []
for i in sorted (conv, key = lambda item: item [0], reverse = True) [0:5000]:
if i [1]:
t.append ([i [2], '' + i [0]])
else:
t.append (['' + i [0], i [2]])
if name is None:
name = number
else:
name = name + ' (' + number + ')'
self.wfile.write ((
html_header (title = 'Conversation with ' + name) +
html_paragraph (html_link ('/', text = '← Back to list')) +
html_title (name) +
html_form (
html_form_text ('msg', textarea = True) +
html_form_hidden ('number', number) +
html_form_submit ('Send'),
'/send'
) +
html_link (self.path, text = 'Refresh') +
html_table (t, table_style = 'table-layout: fixed; border: 1px solid black', cell_style = 'width: 500px; border: 1px solid black') +
html_footer ()
).encode ('utf-8'))
else:
self.send_response (404)
self.send_header ('Content-type', 'text/html')
self.end_headers ()
self.wfile.write ((
html_header (title = 'Page not found') +
html_title ('Not found') +
html_paragraph ('This page does not exist. You cas return to the ' + html_link ('/', text = 'home') + '.') +
html_footer ()
).encode ('utf-8'))
else:
self.send_response (403)
self.send_header ('Content-type', 'text/html')
self.end_headers ()
self.wfile.write ((
html_header (title = 'Access denied') +
html_title ('Access denied') +
html_paragraph ('Access have allready been granted to another host.') +
html_footer ()
).encode ('utf-8'))
def do_POST (self):
global locked_client
client = self.client_address [0]
if locked_client is None:
locked_client = client
print ('Locking on ' + str (client) + '')
if locked_client == client:
global sms
if self.path == '/send':
post_data = FieldStorage (fp = self.rfile, headers = self.headers, environ = {'REQUEST_METHOD': 'POST'})
sms.send_sms (post_data.getvalue ('number'), post_data.getvalue ('msg'))
self.send_response (301)
self.send_header ('Location', self.headers.get ('Referer'))
self.end_headers ()
else:
self.send_response (404)
self.send_header ('Content-type', 'text/html')
self.end_headers ()
self.wfile.write ((
html_header (title = 'Page not found') +
html_title ('Not found') +
html_paragraph ('This page does not exist. You cas return to the ' + html_link ('/', text = 'home') + '.') +
html_footer ()
).encode ('utf-8'))
else:
self.send_response (403)
self.send_header ('Content-type', 'text/html')
self.end_headers ()
self.wfile.write ((
html_header (title = 'Access denied') +
html_title ('Access denied') +
html_paragraph ('Access have allready been granted to another host.') +
html_footer ()
).encode ('utf-8'))
if __name__ == '__main__':
sms = SMS_Service ()
server = HTTPServer (('::', 8080), Web_Service)
locked_client = None
print ('Started!')
try:
sms.start ()
server.serve_forever ()
except KeyboardInterrupt:
print ('Interrupt received, closing process…')
server.server_close ()
exit (0)

19
update.py Normal file
View File

@@ -0,0 +1,19 @@
#!/data/data/com.termux/files/usr/bin/python3
from json import loads as json_read, dumps as json_write
from sys import argv
from os.path import isfile
from sms import SMS_Service
output = argv [1]
if isfile (output):
database = json_read (open (output).read ())
s = SMS_Service (sms_list = database)
s.update_database ()
open (output, 'w').write (json_write (s.sorted_list ()))
else:
s = SMS_Service ()
s.build_database ()
open (output, 'w').write (json_write (s.sorted_list ()))