diff --git a/server.py b/server.py
new file mode 100755
index 0000000..7f5bff3
--- /dev/null
+++ b/server.py
@@ -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 ('\n
\n\t' + title + '\n' + '''\t''' + '\n')
+
+
+def html_title (text):
+ return ('\n\t' + text + '
')
+
+
+def html_iframe (src, height = '150', width = '300', name = None, style = 'border:none;'):
+ r = ''
+ return (r)
+
+
+def html_paragraph (text):
+ return ('\n\t' + text + '
')
+
+
+def html_list (lst):
+ t = '\n\t'
+ for line in lst:
+ t += '\n\t\t- ' + line + '
'
+ t += '\n\t
'
+ return (t)
+
+
+def html_link (url, text = None, target = '_self'):
+ if text is None:
+ text = url
+ return ('' + text + '')
+
+
+def html_table (body, table_style = None, cell_style = None):
+ t = '\n\t'
+ for line in body:
+ t += '\n\t\t'
+ for cell in line:
+ t += '\n\t\t\t' + cell + ' | '
+ t += '\n\t\t
'
+ t += '\n\t
'
+ return (t)
+
+
+def html_message (msg, sent, time, name, avatar = None):
+ r = '\n\t\n\t\t
\n\t\t
' + msg.replace ('\n', '
') + '
\n\t\t
' + time + '\n\t '
+ return (r)
+
+
+def html_form (body, url, post = True):
+ return ('\n\t')
+
+
+def html_form_text (id, value = '', textarea = False):
+ if textarea:
+ return ('\n\t')
+ return ('\n\t')
+
+
+def html_form_hidden (id, value):
+ return ('\n\t')
+
+
+def html_form_submit (label):
+ return ('\n\t')
+
+
+def html_footer ():
+ return ('\n\n')
+
+
+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 ((
+ ''
+ ).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 ((
+ ''
+ ).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)
\ No newline at end of file
diff --git a/sms.py b/sms.py
old mode 100755
new mode 100644
index 2bd8821..9762b50
--- a/sms.py
+++ b/sms.py
@@ -2,167 +2,23 @@
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 threading import Thread
from time import sleep
-from cgi import FieldStorage
-from os import kill, getpid
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'
-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 ('\n\n\t' + title + '\n' + '''\t''' + '\n')
-
-
-def html_title (text):
- return ('\n\t' + text + '
')
-
-
-def html_iframe (src, height = '150', width = '300', name = None, style = 'border:none;'):
- r = ''
- return (r)
-
-
-def html_paragraph (text):
- return ('\n\t' + text + '
')
-
-
-def html_list (lst):
- t = '\n\t'
- for line in lst:
- t += '\n\t\t- ' + line + '
'
- t += '\n\t
'
- return (t)
-
-
-def html_link (url, text = None, target = '_self'):
- if text is None:
- text = url
- return ('' + text + '')
-
-
-def html_table (body, table_style = None, cell_style = None):
- t = '\n\t'
- for line in body:
- t += '\n\t\t'
- for cell in line:
- t += '\n\t\t\t' + cell + ' | '
- t += '\n\t\t
'
- t += '\n\t
'
- return (t)
-
-
-def html_message (msg, sent, time, name, avatar = None):
- r = '\n\t\n\t\t
\n\t\t
' + msg.replace ('\n', '
') + '
\n\t\t
' + time + '\n\t '
- return (r)
-
-
-def html_form (body, url, post = True):
- return ('\n\t')
-
-
-def html_form_text (id, value = '', textarea = False):
- if textarea:
- return ('\n\t')
- return ('\n\t')
-
-
-def html_form_hidden (id, value):
- return ('\n\t')
-
-
-def html_form_submit (label):
- return ('\n\t')
-
-
-def html_footer ():
- return ('\n\n')
class SMS_Service (Thread):
- def __init__ (self):
+ def __init__ (self, sms_list = None):
Thread.__init__ (self)
- self.sms_list = []
+ if type (sms_list) == list:
+ self.sms_list = sms_list
+ else:
+ self.sms_list = []
- def run (self):
+ def build_database (self):
limit_fast_get = 1000000
- limit_normal_get = 20
offset = 0
while True:
msgs = self.get_sms (limit = limit_fast_get, offset = offset)
@@ -173,20 +29,27 @@ class SMS_Service (Thread):
offset += limit_fast_get
for msg in self.sms_list:
del (msg ['read'])
+
+ def update_database (self):
+ limit_normal_get = 20
+ getting_new = True
+ offset = 0
+ while getting_new:
+ msgs = self.get_sms (limit = limit_normal_get, offset = offset)
+ getting_new = False
+ for msg in msgs:
+ del (msg ['read'])
+ for msg in msgs:
+ if msg not in self.sms_list:
+ getting_new = True
+ self.sms_list.append (msg)
+ offset += limit_normal_get
+
+ def run (self):
+ self.build_database ()
while True:
sleep (5)
- getting_new = True
- offset = 0
- while getting_new:
- msgs = self.get_sms (limit = limit_normal_get, offset = offset)
- getting_new = False
- for msg in msgs:
- del (msg ['read'])
- for msg in msgs:
- if msg not in self.sms_list:
- getting_new = True
- self.sms_list.append (msg)
- offset += limit_normal_get
+ self.update_database ()
def get_sms (self, limit = 10, offset = 0):
while True:
@@ -239,263 +102,4 @@ class SMS_Service (Thread):
number = i ['number']
if 'sender' in i:
name = i ['sender']
- 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 ()
- 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 ((
- ''
- ).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 ((
- ''
- ).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)
\ No newline at end of file
+ return (number, name, sorted (l, key = lambda item: item [0]))
\ No newline at end of file
diff --git a/update.py b/update.py
new file mode 100644
index 0000000..f1c2840
--- /dev/null
+++ b/update.py
@@ -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 ()))
\ No newline at end of file