๐Ÿ“ฆ pmdevita / WebModules

๐Ÿ“„ main.py ยท 138 lines
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138from venv_manager import venv
v = venv("int-flask", ["flask", "watchdog", "apscheduler"])

from flask import Flask, redirect, request
import os
import sys
import importlib
from pathlib import Path
from watchdog.observers import Observer
from watchdog.events import FileSystemEventHandler

DEBUG = False

module_path = "modules"
template_path = "templates"

modules = {} # route: module object
module_filenames = {} # filename: route

app = Flask(__name__,  template_folder=template_path)
sys.path.append(module_path)


def _load_module(filename):
    print("Loading {}... ".format(filename), end="")
    try:
        imp_module = importlib.import_module(filename).Module
        temp_module = imp_module()
    except Exception as e:
        print("Error\n{} {}"
              .format(type(e), e))
        return
    if not modules.get(temp_module.route, None):
        if temp_module.route:
            modules[temp_module.route] = temp_module
            module_filenames[filename] = temp_module.route
            print("Done")
        else:
            print("Empty module?")
    else:
        print("Duplicate route!")


def _reload_module(filename):
    print("Reloading {}... ".format(filename), end="")
    try:
        pimp_module = importlib.import_module(filename)
        imp_module = importlib.reload(pimp_module).Module
        temp_module = imp_module()
    except Exception as e:
        print("Error\n{} {}"
              .format(type(e), e))
        _remove_module(filename)
        return

    if temp_module.route:
        # if route previously exists and has changed then unregister old one
        if filename in module_filenames:
            if module_filenames.get(filename, None) != temp_module.route:
                modules.pop(module_filenames[filename])
                module_filenames[filename] = temp_module.route
        else:
            module_filenames[filename] = temp_module.route
        modules[temp_module.route] = temp_module
        print("Done")
    else:
        print("Empty module?")

def _remove_module(filename):
    print("Removing {}...".format(filename), end="")
    name = module_filenames.pop(filename)
    modules.pop(name)
    print("Done")


class Update(FileSystemEventHandler):
    def on_created(self, event):
        p = Path(event.src_path).parts[1]
        if p[-3:] == ".py":
            # print(event.src_path, "Created!", p)
            _load_module(p[:-3])

    def on_modified(self, event):
        p = Path(event.src_path).parts[1]
        if p[-3:] == ".py":
            # print(event.src_path, "Modified!", p)
            _reload_module(p[:-3])

    def on_deleted(self, event):
        p = Path(event.src_path).parts[1]
        if p[-3:] == ".py":
            # print(event.src_path, "Deleted!", p)
            _remove_module(p[:-3])

# setup scanner
handler = Update()
observer = Observer()
observer.schedule(handler, "modules")

@app.route("/")
def mainpage():
    page = ""
    for module in modules:
        page = page + str(modules[module])
    return page

@app.route("/<path:route>")
def routing(route):
    if request.method == "GET":
        args = request.args
    elif request.method == "POST":
        args = request.form
    path = route.split("/")
    module = modules.get(path[0], None)
    if module:
        try:
            return module.run(path, request.method, args)
        except Exception as e:
            print("Module {} could not be run due to error\n{} {}"
                  .format(i[:-3], type(e), e))

    return redirect("/")


if os.environ.get("WERKZEUG_RUN_MAIN") == "true" or DEBUG == False:
    observer.start()
    modules = {}
    for i in os.listdir("modules"):
        if i[-3:] == ".py":
            _load_module(i[:-3])

if __name__ == "__main__":
    app.debug = DEBUG
    app.run()
    observer.stop()
else:
    application = app