New branch: Bottle
This commit is contained in:
		
							parent
							
								
									5125ad3eba
								
							
						
					
					
						commit
						db5bbc6405
					
				
							
								
								
									
										2
									
								
								config/database.py
									
									
									
									
									
										
										
										Executable file → Normal file
									
								
							
							
						
						
									
										2
									
								
								config/database.py
									
									
									
									
									
										
										
										Executable file → Normal file
									
								
							@ -1,4 +1,4 @@
 | 
			
		||||
main_db = {
 | 
			
		||||
db_main = {
 | 
			
		||||
    'host'       : 'localhost',
 | 
			
		||||
    'user'       : 'root',
 | 
			
		||||
    'password'   : '',
 | 
			
		||||
 | 
			
		||||
@ -1,30 +1,13 @@
 | 
			
		||||
import os
 | 
			
		||||
from core import templatestaticdir
 | 
			
		||||
from core import template
 | 
			
		||||
 | 
			
		||||
# pages directory
 | 
			
		||||
page = {
 | 
			
		||||
    'public'    :'page/public'  ,
 | 
			
		||||
    'error'     :'page/error' # Non-template
 | 
			
		||||
    'public'    :'pages/public'
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
# public staticdir
 | 
			
		||||
dirconfig = {
 | 
			
		||||
    '/' :
 | 
			
		||||
static = [
 | 
			
		||||
    {
 | 
			
		||||
        'tools.sessions.on'     : True ,
 | 
			
		||||
        'tools.staticdir.root'  : os.path.abspath(os.getcwd()) ,
 | 
			
		||||
    },
 | 
			
		||||
    '/css' :
 | 
			
		||||
    {
 | 
			
		||||
        'tools.staticdir.on'    : True ,
 | 
			
		||||
        'tools.staticdir.dir'   : './static/css' ,
 | 
			
		||||
    },
 | 
			
		||||
    '/js' :
 | 
			
		||||
    {
 | 
			
		||||
        'tools.staticdir.on'    : True ,
 | 
			
		||||
        'tools.staticdir.dir'   : './static/js' ,
 | 
			
		||||
    },
 | 
			
		||||
        "route" :"/css/<filepath:re:.*\.(css|sass|css.map)>",
 | 
			
		||||
        "root"  :"./static/css"
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
# template staticdir: dirconfig  dirtemplate
 | 
			
		||||
templatestaticdir.add(dirconfig, "templates")
 | 
			
		||||
]
 | 
			
		||||
template.add(static, "templates")
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										6
									
								
								config/globalvar.py
									
									
									
									
									
										
										
										Executable file → Normal file
									
								
							
							
						
						
									
										6
									
								
								config/globalvar.py
									
									
									
									
									
										
										
										Executable file → Normal file
									
								
							@ -1,4 +1,4 @@
 | 
			
		||||
baseurl = "http://localhost:81"
 | 
			
		||||
baseurl = "http://127.0.0.1:15001"
 | 
			
		||||
title    = "CostaPy"
 | 
			
		||||
 | 
			
		||||
menu = {
 | 
			
		||||
@ -10,13 +10,13 @@ menu = {
 | 
			
		||||
                "roles":["guest"]
 | 
			
		||||
            },
 | 
			
		||||
            {
 | 
			
		||||
                "name":"About",
 | 
			
		||||
                "name":"Profile",
 | 
			
		||||
                "href":"#",
 | 
			
		||||
                "roles":["guest"]
 | 
			
		||||
            },
 | 
			
		||||
            {
 | 
			
		||||
                "name":"CostaPy Website",
 | 
			
		||||
                "href":"https://costapy.ditaajipratama.com",
 | 
			
		||||
                "href":"https://costapy.ditaajipratama.net",
 | 
			
		||||
                "roles":["guest"]
 | 
			
		||||
            }
 | 
			
		||||
        ]
 | 
			
		||||
 | 
			
		||||
@ -1,20 +1,16 @@
 | 
			
		||||
from config import directory
 | 
			
		||||
host        = "localhost"
 | 
			
		||||
port        = 15001
 | 
			
		||||
reloader    = False
 | 
			
		||||
debug       = False
 | 
			
		||||
server      = 'gunicorn' # default = 'wsgiref'
 | 
			
		||||
 | 
			
		||||
update = {
 | 
			
		||||
    'server.socket_host'                : "hostname"    ,
 | 
			
		||||
    'server.socket_port'                : "port"        ,
 | 
			
		||||
# cors
 | 
			
		||||
# session
 | 
			
		||||
 | 
			
		||||
    'cors.expose.on'                    : True          ,
 | 
			
		||||
    'tools.sessions.on'                 : True          ,
 | 
			
		||||
# error page 403
 | 
			
		||||
# error page 404
 | 
			
		||||
# error page 500
 | 
			
		||||
 | 
			
		||||
    'engine.autoreload.on'              : False         ,
 | 
			
		||||
    'request.show_tracebacks'           : False         ,
 | 
			
		||||
 | 
			
		||||
    'error_page.403'                    : f'{directory.page["error"]}/403.html' ,
 | 
			
		||||
    'error_page.404'                    : f'{directory.page["error"]}/404.html' ,
 | 
			
		||||
    'error_page.500'                    : f'{directory.page["error"]}/500.html' ,
 | 
			
		||||
 | 
			
		||||
    'server.max_request_body_size'      : 800 * 1024 * 1024 , # 800MB; Default 100MB
 | 
			
		||||
    'server.socket_timeout'             : 60                , # Default 10s
 | 
			
		||||
    'response.timeout'                  : 3600              , # Default 300s
 | 
			
		||||
}
 | 
			
		||||
# max_request_body_size   = 800 * 1024 * 1024 ,   # Multiply for 800MB result
 | 
			
		||||
# socket timeout = 60
 | 
			
		||||
# response timeout = 3600
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										9
									
								
								core/staticdir.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								core/staticdir.py
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,9 @@
 | 
			
		||||
from    bottle      import Bottle, get, static_file
 | 
			
		||||
from    config      import directory
 | 
			
		||||
 | 
			
		||||
app = Bottle()
 | 
			
		||||
 | 
			
		||||
for items in directory.static:
 | 
			
		||||
    @app.get(items['route'])
 | 
			
		||||
    def static_items(filepath):
 | 
			
		||||
        return static_file(filepath, root=items['root'])
 | 
			
		||||
@ -1,9 +1,8 @@
 | 
			
		||||
import os
 | 
			
		||||
 | 
			
		||||
def add(dirconfig, template_directory):
 | 
			
		||||
    template_directory  = "templates"
 | 
			
		||||
    template_list = [d for d in os.listdir(template_directory) if os.path.isdir(os.path.join(template_directory, d))]
 | 
			
		||||
    for template_name in template_list:
 | 
			
		||||
        template_module = __import__(f"{template_directory}.{template_name}.main", fromlist=["static"])
 | 
			
		||||
        for static in getattr(template_module, "static", []):
 | 
			
		||||
            dirconfig[ static['name'] ] = static['value']
 | 
			
		||||
            dirconfig.append(static)
 | 
			
		||||
@ -1,40 +0,0 @@
 | 
			
		||||
import  os
 | 
			
		||||
import  cherrypy
 | 
			
		||||
 | 
			
		||||
def main(file, rename, directory):
 | 
			
		||||
    try:
 | 
			
		||||
        os.makedirs(directory, exist_ok=True)
 | 
			
		||||
    except OSError as error:
 | 
			
		||||
        print(error)
 | 
			
		||||
    try:
 | 
			
		||||
        upload_path     = directory
 | 
			
		||||
        upload_filename = file.filename
 | 
			
		||||
        upload_rename   = rename
 | 
			
		||||
        upload_file     = os.path.normpath(os.path.join(upload_path, upload_rename))
 | 
			
		||||
        upload_size     = 0
 | 
			
		||||
 | 
			
		||||
        print("UPLOADING CORE: Directory: "+directory+"/"+rename)
 | 
			
		||||
        if (os.path.isfile(directory+"/"+rename)):
 | 
			
		||||
            print("UPLOADING CORE: Is exists! Removing!")
 | 
			
		||||
            try:
 | 
			
		||||
                os.remove(directory+"/"+rename)
 | 
			
		||||
            except Exception as e:
 | 
			
		||||
                print(f"UPLOADING CORE: removing failed: {e}")
 | 
			
		||||
        else:
 | 
			
		||||
            print("UPLOADING CORE: Is not exists! Removing skipped!")
 | 
			
		||||
        with open(upload_file, 'wb') as upload_result:
 | 
			
		||||
            while True:
 | 
			
		||||
                data = file.file.read(8192)
 | 
			
		||||
                if not data:
 | 
			
		||||
                    break
 | 
			
		||||
                upload_result.write(data)
 | 
			
		||||
                upload_size += len(data)
 | 
			
		||||
 | 
			
		||||
        print("UPLOAD PATH: " + str(upload_path))
 | 
			
		||||
        print("UPLOAD FILENAME: " + str(upload_filename))
 | 
			
		||||
        print("UPLOAD RENAME: " + str(upload_rename))
 | 
			
		||||
        print("UPLOAD FILE: " + str(upload_file))
 | 
			
		||||
        print("UPLOAD SIZE: " + str(upload_size))
 | 
			
		||||
 | 
			
		||||
    except Exception as e:
 | 
			
		||||
        print(f"ERROR CORE UPLOADING: {e}")
 | 
			
		||||
							
								
								
									
										31
									
								
								costa.py
									
									
									
									
									
								
							
							
						
						
									
										31
									
								
								costa.py
									
									
									
									
									
								
							@ -1,25 +1,20 @@
 | 
			
		||||
import  sys
 | 
			
		||||
import cherrypy
 | 
			
		||||
import cherrypy_cors
 | 
			
		||||
from    bottle      import Bottle, run
 | 
			
		||||
 | 
			
		||||
import  handler
 | 
			
		||||
 | 
			
		||||
from    core        import staticdir
 | 
			
		||||
from    config      import server
 | 
			
		||||
from config import directory
 | 
			
		||||
 | 
			
		||||
if __name__ == '__main__':
 | 
			
		||||
app = Bottle()
 | 
			
		||||
 | 
			
		||||
    dirconfig   = directory.dirconfig
 | 
			
		||||
    update      = server.update
 | 
			
		||||
app.merge(handler.app)
 | 
			
		||||
app.merge(staticdir.app)
 | 
			
		||||
 | 
			
		||||
    if len(sys.argv) >= 3:
 | 
			
		||||
 | 
			
		||||
        update["server.socket_host"]    = sys.argv[1]
 | 
			
		||||
        update["server.socket_port"]    = int(sys.argv[2])
 | 
			
		||||
 | 
			
		||||
        cherrypy_cors.install()
 | 
			
		||||
        cherrypy.config.update  ( update                                )
 | 
			
		||||
        cherrypy.quickstart     ( handler.handler(), config = dirconfig )
 | 
			
		||||
 | 
			
		||||
    else:
 | 
			
		||||
        print ("Usage   : python<ver>   costa.py    <ip_address>    <port>  <service_name>")
 | 
			
		||||
        print ("Example : python3       costa.py    localhost       81      CostaPySample")
 | 
			
		||||
run(app,
 | 
			
		||||
    host = server.host,
 | 
			
		||||
    port = server.port,
 | 
			
		||||
    reloader = server.reloader,
 | 
			
		||||
    server = server.server,
 | 
			
		||||
    debug = server.debug
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										23
									
								
								handler.py
									
									
									
									
									
										
										
										Executable file → Normal file
									
								
							
							
						
						
									
										23
									
								
								handler.py
									
									
									
									
									
										
										
										Executable file → Normal file
									
								
							@ -1,17 +1,16 @@
 | 
			
		||||
import cherrypy
 | 
			
		||||
import json
 | 
			
		||||
import config.directory		as directory
 | 
			
		||||
 | 
			
		||||
import templates.bare.main	as bare
 | 
			
		||||
from    bottle                  import Bottle, route
 | 
			
		||||
from    config                  import directory
 | 
			
		||||
 | 
			
		||||
import  templates.bare.main     as template_public
 | 
			
		||||
import  modules.public.home     as public_home
 | 
			
		||||
 | 
			
		||||
@cherrypy.tools.accept(media="application/json")
 | 
			
		||||
class handler():
 | 
			
		||||
app = Bottle()
 | 
			
		||||
 | 
			
		||||
    def index(self, **kwargs):
 | 
			
		||||
        kwargs["mako"] = {
 | 
			
		||||
            "website" : bare.main(directory.page["public"], "home")
 | 
			
		||||
@app.route('/')
 | 
			
		||||
def index():
 | 
			
		||||
    params = {
 | 
			
		||||
        "mako":{
 | 
			
		||||
            "website" : template_public.main(directory.page["public"], "home")
 | 
			
		||||
        }
 | 
			
		||||
        return public_home.main().html(kwargs)
 | 
			
		||||
    index.exposed = True
 | 
			
		||||
    }
 | 
			
		||||
    return public_home.main().html(params)
 | 
			
		||||
 | 
			
		||||
@ -1,8 +1,4 @@
 | 
			
		||||
sudo apt-get install -y python3-pip
 | 
			
		||||
pip install --upgrade pip
 | 
			
		||||
pip install cherrypy
 | 
			
		||||
pip install cherrypy-cors
 | 
			
		||||
pip install mako
 | 
			
		||||
pip install mysql-connector
 | 
			
		||||
pip install bcrypt
 | 
			
		||||
pip install pyjwt[crypto]
 | 
			
		||||
pip install bottle
 | 
			
		||||
pip install gunicorn
 | 
			
		||||
 | 
			
		||||
@ -1,5 +1,5 @@
 | 
			
		||||
from    mako.template      import Template
 | 
			
		||||
import	config.globalvar	as globalvar
 | 
			
		||||
from    config             import globalvar
 | 
			
		||||
 | 
			
		||||
class main:
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -1 +0,0 @@
 | 
			
		||||
403 Forbidden
 | 
			
		||||
@ -1 +0,0 @@
 | 
			
		||||
404 Not found
 | 
			
		||||
@ -1 +0,0 @@
 | 
			
		||||
500 Internal server error
 | 
			
		||||
@ -1,13 +0,0 @@
 | 
			
		||||
import cherrypy
 | 
			
		||||
import cherrypy_cors
 | 
			
		||||
import json
 | 
			
		||||
 | 
			
		||||
def body_json():
 | 
			
		||||
    result = None
 | 
			
		||||
    if cherrypy.request.method == 'OPTIONS':
 | 
			
		||||
        cherrypy_cors.preflight(allowed_methods=['GET', 'POST'])
 | 
			
		||||
    if cherrypy.request.method == 'POST':
 | 
			
		||||
        cherrypy.serving.response.headers['Content-Type'] = 'application/json'
 | 
			
		||||
        body_request = cherrypy.request.body.read()
 | 
			
		||||
        result = json.loads(body_request.decode())
 | 
			
		||||
    return result
 | 
			
		||||
@ -1,13 +0,0 @@
 | 
			
		||||
import datetime
 | 
			
		||||
 | 
			
		||||
def prcss(loc, msg):
 | 
			
		||||
    print(f"[loggorilla][{datetime.datetime.now()}][\033[32mprcss\033[39m][\033[95m{loc}\033[39m] {msg}")
 | 
			
		||||
 | 
			
		||||
def accss(loc, msg):
 | 
			
		||||
    print(f"[loggorilla][{datetime.datetime.now()}][\033[36maccss\033[39m][\033[95m{loc}\033[39m] {msg}")
 | 
			
		||||
 | 
			
		||||
def fyinf(loc, msg):
 | 
			
		||||
    print(f"[loggorilla][{datetime.datetime.now()}][\033[93mfyinf\033[39m][\033[95m{loc}\033[39m] {msg}")
 | 
			
		||||
 | 
			
		||||
def error(loc, msg):
 | 
			
		||||
    print(f"[loggorilla][{datetime.datetime.now()}][\033[31merror\033[39m][\033[95m{loc}\033[39m] {msg}")
 | 
			
		||||
@ -1,23 +0,0 @@
 | 
			
		||||
from    email.mime.multipart    import MIMEMultipart
 | 
			
		||||
from    email.mime.text         import MIMEText
 | 
			
		||||
import  smtplib
 | 
			
		||||
 | 
			
		||||
def smtp(config):
 | 
			
		||||
 | 
			
		||||
    msg = MIMEMultipart('alternative')
 | 
			
		||||
    msg['Subject'   ] = config['subject'    ]
 | 
			
		||||
    msg['From'      ] = config['from'       ]
 | 
			
		||||
    msg['To'        ] = config['to'         ]
 | 
			
		||||
 | 
			
		||||
    part1 = MIMEText(config['text'], 'plain')
 | 
			
		||||
    part2 = MIMEText(config['html'], 'html' )
 | 
			
		||||
 | 
			
		||||
    msg.attach(part1)
 | 
			
		||||
    msg.attach(part2)
 | 
			
		||||
 | 
			
		||||
    smtp_server = smtplib.SMTP(config['server']['host'], config['server']['port'])
 | 
			
		||||
    smtp_server.ehlo()
 | 
			
		||||
    smtp_server.starttls()
 | 
			
		||||
    smtp_server.login( config['login']['email'], config['login']['password'] )
 | 
			
		||||
    smtp_server.sendmail('&&&&&&', config['to'], msg.as_string() )
 | 
			
		||||
    smtp_server.quit()
 | 
			
		||||
@ -1,23 +0,0 @@
 | 
			
		||||
from cryptography.hazmat.primitives import serialization
 | 
			
		||||
import jwt
 | 
			
		||||
 | 
			
		||||
def encode(payload, id_rsa, passphrase):
 | 
			
		||||
    private_key = open(id_rsa, 'r').read()
 | 
			
		||||
    key         = serialization.load_ssh_private_key(private_key.encode(), password=passphrase)
 | 
			
		||||
    token       = jwt.encode(
 | 
			
		||||
        payload     = payload,
 | 
			
		||||
        key         = key,
 | 
			
		||||
        algorithm   = 'RS256'
 | 
			
		||||
    )
 | 
			
		||||
    return token
 | 
			
		||||
 | 
			
		||||
def decode(token, id_rsa):
 | 
			
		||||
    public_key  = open(id_rsa, 'r').read()
 | 
			
		||||
    key         = serialization.load_ssh_public_key(public_key.encode())
 | 
			
		||||
    header      = jwt.get_unverified_header(token)
 | 
			
		||||
    payload     = jwt.decode(
 | 
			
		||||
        jwt         = token,
 | 
			
		||||
        key         = key,
 | 
			
		||||
        algorithms  = [header['alg'], ]
 | 
			
		||||
    )
 | 
			
		||||
    return payload
 | 
			
		||||
@ -2,18 +2,8 @@ from core   import html
 | 
			
		||||
 | 
			
		||||
static = [
 | 
			
		||||
    {
 | 
			
		||||
        'name':'/bare/lib',
 | 
			
		||||
        'value':{
 | 
			
		||||
            'tools.staticdir.on'    : True ,
 | 
			
		||||
            'tools.staticdir.dir'   : './templates/bare/static/lib' ,
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
        'name':'/bare/css',
 | 
			
		||||
        'value':{
 | 
			
		||||
            'tools.staticdir.on'    : True ,
 | 
			
		||||
            'tools.staticdir.dir'   : './templates/bare/static/css' ,
 | 
			
		||||
        }
 | 
			
		||||
        "route" :"/bare/lib/<filepath:re:.*\.(css|sass|css.map|js|js.map)>",
 | 
			
		||||
        "root"  :"./templates/bare/static/lib"
 | 
			
		||||
    }
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -1 +0,0 @@
 | 
			
		||||
/* your style here */
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user