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
Пример #2
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
Пример #3
0
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
Пример #5
0
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_))
Пример #6
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:
        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
Пример #7
0
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())
Пример #8
0
    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=">>")
Пример #9
0
    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"))
Пример #10
0
    # 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>")
Пример #11
0
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))
Пример #12
0
    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',
Пример #13
0
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..."
Пример #14
0
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))
Пример #15
0
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
Пример #16
0
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
Пример #17
0
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"
            )
Пример #18
0
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