def main(argv): """ Use the arguments of the command line. """ # Use the arg parser args = docopt(full_docopt_text, argv=argv, version="generate-word-cloud.py v{}".format(version)) # printc("<magenta>Arguments: {} <reset>".format(args)) # DEBUG # Read the files printc("<green>Reading the files<reset>, from: <blue>{}<reset>.".format(args['INFILE'])) text = readfiles(args['INFILE']) # Decide where to save it outname = args['--outfile'] if args['--outfile'] else 'wordcloud.png' # Generate the wordcloud # print("Making a wordcloud from this text:\n", text) # DEBUG wordcloud = generate(text, max_words=args['--max'], width=args['--width'], height=args['--height'] ) # Finally, saving the image printc("<green>Making the image<reset> and saving it to <blue>{}<reset>.".format(outname)) makeimage(wordcloud, outname=outname, title=args['--title'], force=args['--force'], show=args['--show'] ) return 0
def loadEvents(fname): """ Reads a file that consists of first column of unix timestamps followed by arbitrary string, one per line. Outputs as dictionary. Also keeps track of min and max time seen in global mint,maxt """ events = [] try: try: # We have a bytes, as in Python2 with open(fname, "r") as f: ws = f.read().decode("utf-8").splitlines() except AttributeError: # We have a string, as in Python3 with open(fname, "r") as f: ws = f.read().splitlines() events = [] for w in ws: ix = w.find(" ") # find first space, that's where stamp ends stamp = int(w[:ix]) sstr = w[ix + 1:] events.append({"t": stamp, "s": sstr}) except Exception as e: printc( "The file '<black>%s<reset>' probably <red>does not exist<reset>, setting empty events list ..." % (fname, )) printc("<red>error was:<reset>") print(e) events = [] return events
def send_message(): try: twilio_cli = create_sms_instance() twilio_cli.messages.create(body="This is a test message from Kemal.", from_=twilio_number, to=my_number) printc(f"<green>Success: SMS send successfully to {my_number}.<white>") except Exception as exc: printc(f"<red>Error: Error occurred when to send an SMS. {exc}")
def readfiles(filenames): """ Return the content of each file, concatenated as one big string. - Path could be relative or absolute, but nothing fancy is done here. """ text = "" # Read the whole text for each file for filename in filenames: try: text += open(filename, 'r').read() text += r"\n" except Exception as e: printc("<ERROR>Error, exception: <reset>{}.".format(e)) printc("<red>Skipping file <black>'{}'<reset>...".format(filename)) # return "\n".join(open(filename, 'r').read() for filename in filenames) return text
def writenote(note, time_=None): """ From https://github.com/karpathy/ulogme/issues/48""" cmd = ["../scripts/note.sh"] if time_ is not None: cmd.append(str(time_)) process = subprocess.Popen(cmd, stdin=subprocess.PIPE) if not isinstance(note, bytes): note = note.encode('utf-8') # FIXED TypeError: 'str' does not support the buffer interface process.communicate(input=note) process.wait() notify( "<b>uLogMe</b> created a note, with content '<i>{}</i>' and time '<i>{!s}</i>'." .format(note, time_)) printc( "<green>uLogMe created a note<white>, with content '<black>{}<white>' and time '<magenta>{!s}<white>'." .format(note, time_))
def loadEvents(fname): """ Reads a file that consists of first column of unix timestamps followed by arbitrary string, one per line. Outputs as dictionary. Also keeps track of min and max time seen in global mint,maxt """ events = [] try: ws = [] try: # We have a bytes, as in Python2 with open(fname, "r") as f: # ws = f.read().decode("utf-8").splitlines() line = "first fake line" while line != "": try: line = f.readline().decode("utf-8")[:-1] except UnicodeDecodeError: line = "" if len(line) == 0: break ws.append(line) except AttributeError: # We have a string, as in Python3 with open(fname, "r") as f: ws = f.read().splitlines() events = [] for w in ws: # print("w =", w) # DEBUG ix = w.find(" ") # find first space, that's where stamp ends try: stamp = int(w[:ix]) sstr = w[ix + 1:] events.append({"t": stamp, "s": sstr}) except ValueError: printc( "<red>One line of the log file {} couldn't be read correctly<reset>: '{}' is probably not a valid integer. Skipping this line!" .format(fname, w[:ix])) except Exception as e: # WARNING printc( "The file '<black>%s<reset>' probably <red>does not exist<reset>, setting empty events list ..." % (fname, )) printc("<red>error was:<reset>") print(e) events = [] return events
def openSpecialFile(name, number=''): """ Open the hidden file '~/.smsapifreemobile_name.b64', read and decode (base64) and return its content. """ assert name in [ "number", "user", "password" ], "Error: unknown or incorrect value for 'name' for the function openSpecialFile(name) ..." printc( "<cyan>Opening the hidden file <white>'<u>~/.smsapifreemobile_{}.b64<U>'<cyan>, read and decode (base64) and return its content...<white>" .format(name)) try: with open( expanduser('~/') + ".smsapifreemobile_" + name + number + ".b64") as f: variable = base64.b64decode(f.readline()[:-1]) while variable[-1] == '\n': variable = variable[:-1] return variable except OSError: printc( "<red>Error: unable to read the file '~/.smsapifreemobile_{}.b64' ...<white>" .format(name)) printc( "<yellow>Please check that it is present, and if it not there, create it:<white>" ) if name == "number": print( "To create '~/.smsapifreemobile_number.b64', use your phone number (like '0612345678', not with +33), and execute this command line (in a terminal):" ) printc( "<black>echo '0612345678' | base64 > '~/.smsapifreemobile_number.b64'<white>" .format()) elif name == "user": print( "To create '~/.smsapifreemobile_user.b64', use your Free Mobile identifier (a 8 digit number, like '83123456'), and execute this command line (in a terminal):" ) printc( "<black>echo '83123456' | base64 > '~/.smsapifreemobile_user.b64'<white>" .format()) elif name == "password": print( "To create '~/.smsapifreemobile_password.b64', go to this webpage, https://mobile.free.fr/account/mes-options/notifications-sms (after logging to your Free Mobile account), and copy the API key (a 14-caracters string on [a-zA-Z0-9]*, like 'H6ahkTABEADz5Z'), and execute this command line (in a terminal):" ) printc( "<black>echo 'H6ahkTABEADz5Z' | base64 > '~/.smsapifreemobile_password.b64<white>' " .format())
def do_tree(self, args): """ Print the contents of the current directory in a format suitable for inclusion in some documentation. """ def colorize(path, fullpath): colors = ["blue", "cyan", "green", ""] color_tags = ["<" + color + ">>" if color else "" for color in colors] tag_index = -1 if os.path.islink(fullpath): tag_index = 1 elif os.path.isdir(fullpath): tag_index = 0 elif os.stat(fullpath).st_mode & stat.S_IXUSR: tag_index = 2 return color_tags[tag_index] + path + "<reset>>" files = all_paths(filtered_walk('.', depth=10, excluded_files=['*.pyc', '.gitignore'], excluded_dirs=[".*", ] ) ) l = list() for f in files: l.append(f) l.sort() previous = list() prev_depth = 0 for position, f in enumerate(l): current = f.split('/') if previous: i = 0 try: n = min(len(current), len(previous)) while i < n and current[i] == previous[i]: i += 1 except IndexError: print_exc() print("\nCurrent:\n") pprint(current) print("\nPrevious:\n") pprint(previous) TWIG = '── ' BRANCH = '├' + TWIG LEAF = '└' + TWIG TRUNK = '│' + ' ' l[position] = colorize(current[-1].strip(), f) if os.path.islink(f): target = os.readlink(f) l[position] += " -> " + colorize(target, target) if i: l[position] = BRANCH + l[position] if i > 1: l[position] = TRUNK * (i-1) + l[position] if i < prev_depth: l[position-1] = re.sub(BRANCH, LEAF, l[position-1]) prev_depth = i previous = current l[-1] = re.sub(BRANCH, LEAF, l[-1]) i = -1 while re.match(TRUNK, l[i]): l[i] = re.sub(TRUNK, INDENT, l[i]) i -= 1 l[i] = re.sub(BRANCH, LEAF, l[i]) printc ('\n'.join(l), right=">>")
def do_POST(self): form = cgi.FieldStorage(fp=self.rfile, headers=self.headers, environ={ "REQUEST_METHOD": "POST", "CONTENT_TYPE": self.headers["Content-Type"] }) result = "NOT_UNDERSTOOD" if self.path == "/refresh": # Recompute jsons. # We have to pop out to root from render directory temporarily. It's a little ugly refresh_time = int(form.getvalue("time")) if refresh_time > 0: printc( "<green>Refreshing the view of uLogMe<white>, for the day '<magenta>{}<white>' ..." .format(ppDay(refresh_time))) notify( "Refreshing the view of <b>uLogMe</b>, for the day '<i>{}</i>' ..." .format(ppDay(refresh_time))) else: printc( "<green>Refreshing the view of uLogMe<white>, for the overview page ..." ) notify( "Refreshing the view of <b>uLogMe</b>, for the overview page ..." ) # FIXME add a command line option to enable/disable the refresh notifications os.chdir(self.rootdir) # pop out updateEvents() # defined in export_events.py os.chdir(os.path.join("..", "render")) # pop back to render directory result = "OK" if self.path == "/addnote": # add note at specified time and refresh note = form.getvalue("note") note_time = form.getvalue("time") printc( "<green>Adding a note in uLogMe<white>, with content '<blue>{}<white>' and time '<magenta>{!s}<white>' ..." .format(note, ppTime(int(note_time)))) notify( "Adding a note in <b>uLogMe</b>, with content '<i>{}</i>' and time '<i>{!s}</i>' ..." .format(note, ppTime(int(note_time))), icon="note") os.chdir(self.rootdir) # pop out writenote(note, note_time) updateEvents() # defined in export_events.py os.chdir(os.path.join("..", "render")) # go back to render result = "OK" if self.path == "/blog": # add note at specified time and refresh post = form.getvalue("post") if post is None: post = "" post_time = int(form.getvalue("time")) printc( "<green>Adding a blog post in uLogMe<white>, with content '<blue>{}<white>' and time '<magenta>{!s}<white>' ..." .format(post, ppDay(int(post_time)))) notify( "Adding a blog post in <b>uLogMe</b>, with content '<i>{}</i>' and time '<i>{!s}</i>' ..." .format(post, ppDay(int(post_time))), icon="note") # DEBUG os.chdir(self.rootdir) # pop out trev = rewindTime(post_time) with open( os.path.join("..", "logs", "blog_%d.txt" % (post_time, )), "w") as f: f.write(post) updateEvents() # defined in export_events.py os.chdir(os.path.join("..", "render")) # go back to render result = "OK" # This part has to be done manually self.send_response(200) self.send_header("Content-type", "text/html") self.end_headers() try: # We have a bytes, as in Python2 self.wfile.write(result) except TypeError: # We have a string, as in Python3 self.wfile.write(bytes(result, "utf8"))
# Address settings if len(sys.argv) > 2: IP = str(sys.argv[2]) else: IP = "localhost" # IP address to use by default # Instead of "", more secure, thanks to https://github.com/karpathy/ulogme/issues/48 # Serve render/ folder, not current folder # rootdir = os.getcwd() # XXX Not used anymore os.chdir(os.path.join("..", "render")) try: httpd = socketserver.ThreadingTCPServer((IP, PORT), CustomHandler) printc( "<green>Serving uLogMe<white> on a HTTP server, see it locally on '<u><black>http://{}:{}<white><U>' ..." .format(IP, PORT)) notify( "Serving <b>uLogMe</b> on a <i>HTTP</i> server, see it locally on 'http://{}:{}' ..." .format(IP, PORT), icon="terminal") # DEBUG httpd.serve_forever() except socket.error as e: if e.errno == 98: printc("<red>The port {} was already used ...<white>".format(PORT)) printc( "Try again in some time (about 1 minute on Ubuntu), or launch the script again with another port: '<black>$ ulogme_serve.py {}<white>' ..." .format(PORT + 1)) else: printc( "<red>Error, ulogme_serve.py was interrupted, giving:<white>")
def updateEvents(): """ Goes down the list of .txt log files and writes all .json files that can be used by the frontend. """ logFiles = [] logFiles.extend(glob.glob(os.path.join("..", "logs", "keyfreq_*.txt"))) logFiles.extend(glob.glob(os.path.join("..", "logs", "window_*.txt"))) logFiles.extend(glob.glob(os.path.join("..", "logs", "notes_*.txt"))) logFiles = [f for f in logFiles if not os.path.islink(f)] # extract all times. all log files of form {type}_{stamp}.txt ts = [int(x[x.find("_") + 1:x.find(".txt")]) for x in logFiles] ts = list(set(ts)) ts.sort() mint = min(ts) # march from beginning to end, group events for each day and write json ROOT = "" RENDER_ROOT = os.path.join(ROOT, "..", "render") # DONE in a more Pythonic way if not os.path.isdir(RENDER_ROOT): os.makedirs(RENDER_ROOT) # FIXED Now the json/ path is created automatically, see https://github.com/Naereen/uLogMe/issues/30#issuecomment-430121035 render_json_path = os.path.join(RENDER_ROOT, "json") if not os.path.isdir(render_json_path): if os.path.exists(render_json_path): raise ValueError( "Error: the file '{}' already exists but it is not a directory, impossible to create it! Remove it or rename it manually please..." ) else: print( "The path '{}' did not exists but it is needed to export the list of events to a JSON file...\nCreating it..." ) os.mkdir(render_json_path) t = mint out_list = [] for t in ts: t0 = t t1 = t0 + 60 * 60 * 24 # 24 hrs later fout = os.path.join("json", "events_%d.json" % (t0, )) out_list.append({"t0": t0, "t1": t1, "fname": fout}) fwrite = os.path.join(RENDER_ROOT, fout) e1f = os.path.join("..", "logs", "window_%d.txt" % (t0, )) e2f = os.path.join("..", "logs", "keyfreq_%d.txt" % (t0, )) e3f = os.path.join("..", "logs", "notes_%d.txt" % (t0, )) e4f = os.path.join("..", "logs", "blog_%d.txt" % (t0, )) dowrite = False # output file already exists? # if the log files have not changed there is no need to regen if os.path.isfile(fwrite): tmod = mtime(fwrite) e1mod = mtime(e1f) e2mod = mtime(e2f) e3mod = mtime(e3f) e4mod = mtime(e4f) if e1mod > tmod or e2mod > tmod or e3mod > tmod or e4mod > tmod: dowrite = True # better update! printc( "<yellow>A log file has changed<reset>, so will update '<black>%s<reset>' ..." % (fwrite, )) else: # output file does not exist, so write. dowrite = True if dowrite: # okay lets do work e1 = loadEvents(e1f) e2 = loadEvents(e2f) e3 = loadEvents(e3f) for k in e2: k["s"] = int(k["s"]) # int convert e4 = "" if os.path.isfile(e4f): e4 = open(e4f, "r").read() eout = { "window_events": e1, "keyfreq_events": e2, "notes_events": e3, "blog": e4 } # print("eout =", eout) # DEBUG with open(fwrite, "w") as f: try: f.write(json.dumps(eout).encode("utf8")) except TypeError: f.write(json.dumps(eout)) assert os.path.exists( render_json_path ), "Error: the path '{}' do not exist but it should. Try again (or fill an issue, https://github.com/Naereen/uLogMe/issues/new)." # DEBUG fwrite = os.path.join(render_json_path, "export_list.json") with open(fwrite, "w") as f: try: # We have a bytes, as in Python2 f.write(json.dumps(out_list).encode("utf8")) except TypeError: # We have a string, as in Python3 f.write(json.dumps(out_list))
try: from ansicolortags import printc except ImportError: print("Optional dependency (ansicolortags) is not available, using regular print function.") print(" You can install it with : 'pip install ansicolortags' (or sudo pip)...") from ANSIColors import printc except ImportError: print("Optional dependency (ANSIColors) is not available, using regular print function.") print(" You can install it with : 'pip install ANSIColors-balises' (or sudo pip)...") def printc(*a, **kw): """ Print without colors. Install ansicolortags to have colors! """ print(*a, **kw) printc("<magenta>[LOG]<white> Using python, version {} on {}.".format(sys.version, sys.platform)) # If extensions (or modules to document with autodoc) are in another directory, # add these directories to sys.path here. If the directory is relative to the # documentation root, use os.path.abspath to make it absolute, like shown here. # sys.path.insert(0, os.path.abspath('.')) # -- General configuration ----------------------------------------------------- # If your documentation needs a minimal Sphinx version, state it here. needs_sphinx = '1.3' # Add any Sphinx extension module names here, as strings. They can be extensions # coming with Sphinx (named 'sphinx.ext.*') or your custom ones. extensions = [ 'sphinx.ext.todo',
def send_sms(text="Empty!", secured=True): """ Sens a free SMS to the user identified by [user], with [password]. :user: Free Mobile id (of the form [0-9]{8}), :password: Service password (of the form [a-zA-Z0-9]{14}), :text: The content of the message (a warning is displayed if the message is bigger than 480 caracters) :secured: True to use HTTPS, False to use HTTP. Returns a boolean and a status string. """ # DONE split the text into smaller pieces if length is too big (automatically, or propose to do it ?) if len(text) > MAX_SIZE: printc(errorcodes["toolong"]) nb_sub_messages = len(text) / MAX_SIZE printc( "\n<red>Warning<white>: message will be split in <red>{} piece{}<white> of size smaller than <black>{} characters<white>..." .format(nb_sub_messages + 1, 's' if nb_sub_messages > 0 else '', MAX_SIZE)) printc( " <magenta>Note that new lines and other information can be lost!<white>" ) for i, index in enumerate(range(0, len(text), MAX_SIZE)): answer = send_sms(text[index:index + MAX_SIZE]) printc( "For piece #{} of the message, the answer is:\n <magenta>{}<white>...\n" .format(i + 1, answer[1])) return answer # raise ValueError(errorcodes["toolong"]) # Read number, user, password #: Identification Number free mobile user = openSpecialFile("user") #: Password password = openSpecialFile("password") printc("\n<green>Your message is:<white>\n<yellow>" + text + "<white>") dictQuery = {"user": user, "pass": password, "msg": text} url = "https" if secured else "http" string_query = dumps(dictQuery, sort_keys=True, indent=4) string_query = string_query.replace(password, '*' * len(password)) printc( "\nThe web-based query to the Free Mobile API (<u>{}://smsapi.free-mobile.fr/sendmsg?query<U>) will be based on:\n{}." .format(url, string_query)) query = urlencode(dictQuery) url += "://smsapi.free-mobile.fr/sendmsg?{}".format(query) try: urlopen(url) return 0, errorcodes[1] except HTTPError as e: if hasattr(e, "code"): return e.code, errorcodes[e.code] else: print("Unknown error...") return 2, "Unknown error..."
def updateEvents(): """ Goes down the list of .txt log files and writes all .json files that can be used by the frontend. """ logFiles = [] logFiles.extend(glob.glob(os.path.join("..", "logs", "keyfreq_*.txt"))) logFiles.extend(glob.glob(os.path.join("..", "logs", "window_*.txt"))) logFiles.extend(glob.glob(os.path.join("..", "logs", "notes_*.txt"))) logFiles = [f for f in logFiles if not os.path.islink(f)] # XXX faster with? # logFiles = filter(lambda f: not(os.islink(f)), logFiles) # extract all times. all log files of form {type}_{stamp}.txt ts = [int(x[x.find("_") + 1:x.find(".txt")]) for x in logFiles] ts = list(set(ts)) ts.sort() mint = min(ts) # march from beginning to end, group events for each day and write json ROOT = "" RENDER_ROOT = os.path.join(ROOT, "..", "render") # DONE in a more Pythonic way if not os.path.isdir(RENDER_ROOT): os.makedirs(RENDER_ROOT) t = mint out_list = [] for t in ts: t0 = t t1 = t0 + 60 * 60 * 24 # 24 hrs later fout = os.path.join("json", "events_%d.json" % (t0, )) out_list.append({"t0": t0, "t1": t1, "fname": fout}) fwrite = os.path.join(RENDER_ROOT, fout) e1f = os.path.join("..", "logs", "window_%d.txt" % (t0, )) e2f = os.path.join("..", "logs", "keyfreq_%d.txt" % (t0, )) e3f = os.path.join("..", "logs", "notes_%d.txt" % (t0, )) e4f = os.path.join("..", "logs", "blog_%d.txt" % (t0, )) dowrite = False # output file already exists? # if the log files have not changed there is no need to regen if os.path.isfile(fwrite): tmod = mtime(fwrite) e1mod = mtime(e1f) e2mod = mtime(e2f) e3mod = mtime(e3f) e4mod = mtime(e4f) if e1mod > tmod or e2mod > tmod or e3mod > tmod or e4mod > tmod: dowrite = True # better update! printc( "<yellow>A log file has changed<white>, so will update '<black>%s<white>' ..." % (fwrite, )) else: # output file doesnt exist, so write. dowrite = True if dowrite: # okay lets do work e1 = loadEvents(e1f) e2 = loadEvents(e2f) e3 = loadEvents(e3f) for k in e2: k["s"] = int(k["s"]) # int convert e4 = "" if os.path.isfile(e4f): e4 = open(e4f, "r").read() eout = { "window_events": e1, "keyfreq_events": e2, "notes_events": e3, "blog": e4 } # print("eout =", eout) # DEBUG with open(fwrite, "w") as f: try: f.write(json.dumps(eout).encode("utf8")) except TypeError: f.write(json.dumps(eout)) fwrite = os.path.join(RENDER_ROOT, "json", "export_list.json") with open(fwrite, "w") as f: try: # We have a bytes, as in Python2 f.write(json.dumps(out_list).encode("utf8")) except TypeError: # We have a string, as in Python3 f.write(json.dumps(out_list))
def send_sms(text="Empty!", secured=True, sleep_duration=0): """ Sens a free SMS to the user identified by [user], with [password]. :user: Free Mobile id (of the form [0-9]{8}), :password: Service password (of the form [a-zA-Z0-9]{14}), :text: The content of the message (a warning is displayed if the message is bigger than 480 caracters) :secured: True to use HTTPS, False to use HTTP. Returns a boolean and a status string. """ # DONE split the text into smaller pieces if length is too big (automatically, or propose to do it ?) if len(text) > MAX_SIZE: printc(errorcodes["toolong"]) nb_sub_messages = len(text) / MAX_SIZE printc( "\n<red>Warning<white>: message will be split in <red>{} piece{}<white> of size smaller than <black>{} characters<white>..." .format(nb_sub_messages + 1, 's' if nb_sub_messages > 0 else '', MAX_SIZE)) printc( " <magenta>Note that new lines and other information can be lost!<white>" ) for i, index in enumerate(range(0, len(text), MAX_SIZE)): answer = send_sms(text[index:index + MAX_SIZE]) printc( "For piece #{} of the message, the answer is:\n <magenta>{}<white>...\n" .format(i + 1, answer[1])) return answer # raise ValueError(errorcodes["toolong"]) # Read user and password users = [] #: Identification Number free mobile user = openSpecialFile("user") users.append(user) if testSpecialFile("user", "2"): user2 = openSpecialFile("user", "2") users.append(user2) passwords = [] #: Password password = openSpecialFile("password") passwords.append(password) if testSpecialFile("password", "2"): password2 = openSpecialFile("password", "2") passwords.append(password2) printc("\n<green>Your message is:<white>\n<yellow>" + text + "<white>") url = "https" if secured else "http" # Sending to all the numbers results = [] for (user, password) in zip(users, passwords): dictQuery = {"user": user, "pass": password, "msg": text} string_query = json.dumps(dictQuery, sort_keys=True, indent=4) string_query = string_query.replace(password, '*' * len(password)) printc( "\nThe web-based query to the Free Mobile API (<u>{}://smsapi.free-mobile.fr/sendmsg?query<U>) will be based on:\n{}." .format(url, string_query)) if sleep_duration > 0: printc( "\nSleeping for <red>{}<reset><white> seconds before querying the API..." .format(sleep_duration)) try: time.sleep(sleep_duration) except KeyboardInterrupt as e: printc( "<red>You interrupted the process of sending this message, skipping to next one (or stopping now)...<reset><white>" ) else: printc( "\nDone sleeping for <red>{}<reset><white> seconds, it's time to query the API !" .format(sleep_duration)) query = urlencode(dictQuery) url += "://smsapi.free-mobile.fr/sendmsg?{}".format(query) try: urlopen(url) results.append((0, errorcodes[1])) except HTTPError as e: if hasattr(e, "code"): results.append((e.code, errorcodes[e.code])) else: print("Unknown error...") results.append((2, "Unknown error...")) # Now we return the list of results return results
def main(argv): """ Main function. Use the arguments of the command line (sys.argv). """ # TODO use docopt to handle the command line arguments! Cf. http://docopt.org/ # TODO can docopt handle a cli documentation with ansicolortags tags in it? Cf. http://ansicolortags.rtfd.io/ # Manual handing of the command line arguments if "-h" in argv or "--help" in argv: printc(""" <green>FreeSMS.py<white> --help|-h | -f file | [--sleep] body of the message A simple Python script to send a text message to a Free Mobile phone. The message should be smaller than 480 caracters. <u>Examples:<U> <black>$ FreeSMS.py --help<white> Print this help message! <black>$ FreeSMS.py -f MyMessageFile.txt<white> Try to send the content of the file MyMessageFile.txt. <black>$ FreeSMS.py "I like using Python to send me SMS from my laptop -- and it"s free thanks to Free !"<white> Will send a test message to your mobile phone. <black>$ FreeSMS.py --sleep 1 "This option makes the script sleep for one minute"<white> Sleep one minute. <magenta>Copyright 2014-20 Lilian Besson (License MIT)<white> <b>THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND.<reset><white> """) return 0 sleep = False sleep_duration = 15 # in seconds if "--sleep" in argv: sleep = True index = argv.index("--sleep") if index + 1 < len(argv): try: sleep_duration = int(argv[index + 1]) except: printc( "<red>Unable to get a sleep duration value from the command line argument ('{}' does not convert to an integer)." .format(argv[index + 1])) # DEBUG else: argv.pop(index) # remove sleep_duration argv.pop(index) # remove "--sleep" if "-f" in argv: try: with open(argv[argv.index("-f") + 1], 'r') as filename: text = "".join(filename.readlines())[:-1] except Exception as e: print(e) print( "Trying to use the rest of the arguments to send the text message..." ) text = " ".join(argv) else: if argv: # Text of the SMS if isinstance(argv, list): text = " ".join(argv) elif isinstance(argv, str): text = argv else: printc( "<Warning>argv seems to be of unknown type (not list, not str, but {}) ..." .format(type(argv))) text = argv text = text.replace("\\n", "\n") # Durty hack to have true new lines in the message else: text = """Test SMS sent from {machinename} with FreeSMS.py (the {date}). (a Python 2.7+ / 3.4+ script by Lilian Besson, open source, you can find the code at https://github.com/Naereen/FreeSMS.py or https://perso.crans.org/besson/bin/FreeSMS.py) For any issues, reach me by email at besson[at]crans[dot]org !""" # FIXED Check that this is working correctly! machinename = "jarvis" # Default name! try: machinename = open("/etc/hostname").readline()[:-1] except OSError: print( "Warning: unknown machine name (file '/etc/hostname' not readable?)..." ) machinename = "unknown machine" text = text.format(date=today, machinename=machinename) text = text.replace("[at]", "@").replace("[dot]", ".") answers = send_sms(text, sleep_duration=sleep_duration) return answers
def openWinSpecialFile(name, number=''): """ Open the hidden file '~/.smsapifreemobile_name.b64', read and decode (base64) and return its content. """ uname = os.getlogin( ) # gets the windows user name for adapted help messages assert name in [ "number", "user", "password" ], "Error: unknown or incorrect value for 'name' for the function openSpecialFile(name) ..." printc( "<cyan>Opening the hidden file <white>'<u>C:\\Users\\" + uname + "\\.smsapifreemobile_{}.b64<U>'<cyan>, read and decode (base64) and return its content...<white>" .format(name)) winuserpath = Path.home() # gets the home directory for windows platform try: with open( PurePath.joinpath( winuserpath, (".smsapifreemobile_" + name + number + ".b64"))) as f: variable = str(base64.b64decode(f.readline()[:-1])) variable = variable.replace( 'b\'', '') # Removes the b at the beginning of decoded string variable = variable.replace( '\'', '') # Removes the ' at the of decoded string while variable[-1] == '\n': variable = variable[:-1] return variable except OSError: printc("<red>Error: unable to read the file 'C:\\Users\\" + uname + "\\.smsapifreemobile_{}.b64' ...<white>".format(name)) printc( "<yellow>Please check that it is present, and if it not there, create it:<white>" ) if name == "number": print( "To create " + "C:\\Users\\" + uname + "\\.smsapifreemobile_number.b64, use your phone number (like '0612345678', not with +33), and execute this command line (in a powershell instance):" ) printc( "<black> [Convert]::ToBase64String([Text.Encoding]::UTF8.GetBytes( \"0612345678\")) | Out-File -FilePath .\\.smsapifreemobile_number.b64" ) elif name == "user": print( "To create " + "C:\\Users\\" + uname + "\\.smsapifreemobile_user.b64, use your Free Mobile identifier (a 8 digit number, like '83123456'), and execute this command line (in a powershell instance):" ) printc( "<black> [Convert]::ToBase64String([Text.Encoding]::UTF8.GetBytes( \"83123456\")) | Out-File -FilePath .\\.smsapifreemobile_user.b64" ) elif name == "password": print( "To create " + "C:\\Users\\" + uname + "\\.smsapifreemobile_password.b64, go to this webpage, https://mobile.free.fr/account/mes-options/notifications-sms (after logging to your Free Mobile account), and copy the API key (a 14-caracters string on [a-zA-Z0-9]*, like 'H6ahkTABEADz5Z'), and execute this command line (in a terminal):" ) printc( "<black> [Convert]::ToBase64String([Text.Encoding]::UTF8.GetBytes( \"H6ahkTABEADz5Z\")) | Out-File -FilePath .\\.smsapifreemobile_password.b64" )
def main(argv, to_language=TO_LANGUAGE, from_language=FROM_LANGUAGE): """ Main function. Use the arguments of the command line (sys.argv). """ # TODO use docopt to handle the command line arguments! Cf. http://docopt.org/ # TODO can docopt handle a cli documentation with ansicolortags tags in it? Cf. http://ansicolortags.rtfd.io/ # Manual handing of the command line arguments if "-h" in argv or "--help" in argv: printc(""" <green>deepl.py<white> --help|-h | -f file | [--from LANG] [--to LANG] text A simple Python script translate a text from a language to another language, using DeepL translator (https://www.deepl.com/translator). <u>Examples:<U> <black>$ deepl.py --help<white> Print this help message! <black>$ deepl.py -f test.txt<white> Translate this text file. <black>$ deepl.py "I like using command line to translate my text."<white> J'aime utiliser la ligne de commande pour traduire mon texte. <black>$ deepl.py --to ES "I like using command line to translate my text."<white> Me gusta usar la lĂnea de comandos para traducir mi texto. <magenta>Copyleft 2017 Lilian Besson (License MIT)<white> <b>THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND.<reset><white> """) return 0 if "--to" in argv: try: i = argv.index("--to") to_language = argv[i + 1] del argv[i], argv[i] # printc("<green>Using destination language {}<reset>...".format(to_language)) except Exception as e: print(e) printc( "<red>Ignored exception, using default destination language {}...<reset>" .format(to_language)) if "--from" in argv: try: i = argv.index("--from") from_language = argv[i + 1] del argv[i], argv[i] # printc("<green>Using destination language {}<reset>...".format(from_language)) except Exception as e: print(e) printc( "<red>Ignored exception, using default source language {}...<reset>" .format(from_language)) if "-f" in argv: try: with open(argv[argv.index("-f") + 1], 'r') as filename: text = "".join(filename.readlines())[:-1] except Exception as e: print(e) printc( "<red>Trying to use the rest of the arguments to send the text message...<white>" ) text = "".join(argv) else: if argv: # Text if isinstance(argv, list): text = "".join(argv) elif isinstance(argv, str): text = argv else: printc( "<Warning>argv seems to be of unknown type (not list, not str, but {}) ..." .format(type(argv))) text = argv text = text.replace("\\n", "\n") # Durty hack to have true new lines in the message else: text = "I like using command line to translate my text." # print("text = '{}'".format(text)) # DEBUG results = [] for t in text.splitlines(): if t.isspace() or len(t) == 0: results.append(t) else: results.append( translate(t, to_lang=to_language, from_lang=from_language)) result = "\n".join(results) print(result) return result
def makeimage(wordcloud, outname='wordcloud.png', title='Word cloud', show=False, force=False): """ Display or save the wordcloud as a image. """ # Display the generated image: try: # 2. the matplotlib way: plt.figure() plt.imshow(wordcloud) plt.axis("off") if title: printc("<magenta>Using title<reset> <blue>'{}'<reset>.".format(title)) plt.title(title) if show: printc("<green>Showing the generated image...<reset>") plt.show() else: printc("<green>Saving the generated image<reset> to <blue>'{}'<reset>...".format(outname)) if (not force) and path.exists(outname): erase = raw_input("The outfile '{}' already exists, should I erase it ? [y/N]".format(outname)) if erase == 'y': plt.savefig(outname) else: printc("<magenta>Not erasing it...<reset>") printc("<green>Showing the generated image...<reset>") plt.show() else: if force: printc("<WARNING> -f or --force has been used, overwriting the image '{}' <red>without<reset> asking you...".format(outname)) plt.savefig(outname) except Exception as e: printc("<ERROR> Error, exception<reset>: {}".format(e)) # 1. The pil way (if you don't have matplotlib) printc("<WARNING> Something went wrong with matplotlib, switching to PIL backend... (just showing the image, <red>not<reset> saving it!)") image = wordcloud.to_image() image.show() return True