Source code for shopyoapi.cmd

"""
commandline utilities functions
"""
import os
import re
import subprocess
import sys
import importlib

from shopyoapi.init import db
from shopyoapi.cmd_helper import tryrmcache
from shopyoapi.cmd_helper import tryrmfile
from shopyoapi.cmd_helper import tryrmtree
from shopyoapi.path import root_path
from shopyoapi.path import static_path
from shopyoapi.path import modules_path
from shopyoapi.file import trymkdir
from shopyoapi.file import trymkfile
from shopyoapi.file import get_folders
from shopyoapi.file import trycopytree


[docs]def clean(app): """ Deletes shopyo.db and migrations/ if present in current working directory. Deletes all __pycache__ folders starting from current working directory all the way to leaf directory. Parameters ---------- - app: flask app that that need to be cleaned Returns ------- None ... """ SEP_CHAR = "#" SEP_NUM = 23 print(SEP_CHAR * SEP_NUM, end="\n\n") print("Cleaning...") # getting app context creates the shopyo.db file even if it is not present with app.test_request_context(): db.drop_all() db.engine.execute("DROP TABLE IF EXISTS alembic_version;") print("[x] all tables dropped") tryrmcache(os.getcwd()) tryrmfile(os.path.join(os.getcwd(), "shopyo.db"), verbose=True) tryrmtree(os.path.join(os.getcwd(), "migrations"), verbose=True)
[docs]def initialise(): """ Create db, migrate, adds default users, add settings Parameters ---------- Returns ------- None """ SEP_CHAR = "#" SEP_NUM = 23 print("Creating Db") print(SEP_CHAR * SEP_NUM, end="\n\n") subprocess.run( [sys.executable, "manage.py", "db", "init"], stdout=subprocess.PIPE ) print("Migrating") print(SEP_CHAR * SEP_NUM, end="\n\n") subprocess.run( [sys.executable, "manage.py", "db", "migrate"], stdout=subprocess.PIPE ) subprocess.run( [sys.executable, "manage.py", "db", "upgrade"], stdout=subprocess.PIPE ) print("Collecting static") print(SEP_CHAR * SEP_NUM, end="\n\n") subprocess.run( [sys.executable, "manage.py", "collectstatic"], stdout=subprocess.PIPE ) # Uploads print("Uploads") print(SEP_CHAR * SEP_NUM, end="\n\n") for folder in os.listdir(os.path.join(root_path, "modules")): if folder.startswith("__"): # ignore __pycache__ continue if folder.startswith("box__"): # boxes for sub_folder in os.listdir( os.path.join(root_path, "modules", folder) ): if sub_folder.startswith("__"): # ignore __pycache__ continue elif sub_folder.endswith(".json"): # box_info.json continue try: upload = importlib.import_module( "modules.{}.{}.upload".format(folder, sub_folder) ) upload.upload() except ImportError as e: # print(e) pass else: # apps try: upload = importlib.import_module( "modules.{}.upload".format(folder) ) upload.upload() except ImportError as e: # print(e) pass print("Done!")
[docs]def create_module(modulename, base_path=None): """ creates module with the structure defined in the modules section in docs Parameters ---------- modulename: str name of module, in alphanumeric-underscore Returns ------- None """ if bool(re.match(r"^[A-Za-z0-9_]+$", modulename)) is False: print( "Error: modulename is not valid, please use alphanumeric\ and underscore only" ) sys.exit() print(f"creating module: {modulename}") if not base_path: base_path = f"modules/{modulename}" trymkdir(base_path) trymkdir(f"{base_path}/templates") trymkdir(f"{base_path}/templates/{modulename}") trymkdir(f"{base_path}/tests") trymkdir(f"{base_path}/static") test_func_content = """ Please add your functional tests to this file. """ test_model_content = """ Please add your models tests to this file. """ trymkfile( f"{base_path}/tests/test_{modulename}_functional.py", test_func_content ) trymkfile( f"{base_path}/tests/test_{modulename}_models.py", test_model_content ) view_content = """ from shopyo.api.module import ModuleHelp # from flask import render_template # from flask import url_for # from flask import redirect # from flask import flash # from flask import request # from shopyo.api.html import notify_success # from shopyo.api.forms import flash_errors mhelp = ModuleHelp(__file__, __name__) globals()[mhelp.blueprint_str] = mhelp.blueprint module_blueprint = globals()[mhelp.blueprint_str] @module_blueprint.route("/") def index(): return mhelp.info['display_string'] # If "dashboard": "/dashboard" is set in info.json # # @module_blueprint.route("/dashboard", methods=["GET"]) # def dashboard(): # context = mhelp.context() # context.update({ # }) # return mhelp.render('dashboard.html', **context) """ trymkfile(f"{base_path}/view.py", view_content) trymkfile(f"{base_path}/forms.py", "") trymkfile(f"{base_path}/models.py", "") info_json_content = """{{ "display_string": "{0}", "module_name":"{1}", "type": "show", "fa-icon": "fa fa-store", "url_prefix": "/{1}", "author": {{ "name":"", "website":"", "mail":"" }} }}""".format( modulename.capitalize(), modulename ) trymkfile(f"{base_path}/info.json", info_json_content) trymkdir(f"{base_path}/templates/{modulename}/blocks") trymkfile(f"{base_path}/templates/{modulename}/blocks/sidebar.html", "") dashboard_file_content = """ {% extends "base/module_base.html" %} {% set active_page = info['display_string']+' dashboard' %} {% block pagehead %} <title></title> <style> </style> {% endblock %} {% block sidebar %} {% include info['module_name']+'/blocks/sidebar.html' %} {% endblock %} {% block content %} <br> <div class="card"> <div class="card-body"> </div> </div> {% endblock %} """ trymkfile( f"{base_path}/templates/{modulename}/dashboard.html", dashboard_file_content, ) global_file_content = """ available_everywhere = { } """ trymkfile(f"{base_path}/global.py", global_file_content)
[docs]def create_box(name): """ creates box with box_info.json Parameters ---------- name: str name of box, in alphanumeric-underscore Returns ------- None """ base_path = f"modules/box__{name}" if os.path.exists(base_path): print(f"Box {base_path} exists!") else: trymkdir(base_path) info_json_content = """{{ "display_string": "{0}", "box_name":"{1}", "author": {{ "name":"", "website":"", "mail":"" }} }}""".format( name.capitalize(), name ) trymkfile(f"{base_path}/box_info.json", info_json_content)
[docs]def create_module_in_box(modulename, boxname): """ creates module with the structure defined in the modules section in docs in a box Parameters ---------- modulename: str name of module, in alphanumeric-underscore boxname: str name of box, in alphanumeric-underscore Returns ------- None """ box_path = os.path.join("modules", boxname) module_path = os.path.join("modules", boxname, modulename) if not boxname.startswith("box__"): print(f"Invalid box {boxname}. Boxes should start with box__") elif not os.path.exists(box_path): print(f"Box {box_path} does not exists!") available_boxes = "\n* ".join( [f for f in os.listdir("modules/") if f.startswith("box__")] ) print(f"Available boxes: \n* {available_boxes}") elif os.path.exists(module_path): print(f"Module {module_path} exists") else: print(f"Creating module {module_path}") create_module(modulename, base_path=module_path)
[docs]def collectstatic(target_module=None): """ Copies ``module/static`` into ``/static/modules/module``. In static it becomes like :: static/ modules/ box_something/ modulename modulename2 Parameters ---------- target_module: str name of module, in alphanumeric-underscore, supports ``module`` or ``box__name/module`` Returns ------- None """ modules_path_in_static = os.path.join(static_path, "modules") if target_module is None: # clear modules dir if exists. tryrmtree(modules_path_in_static) # look for static folders in all project for folder in get_folders(modules_path): if folder.startswith("box__"): box_path = os.path.join(modules_path, folder) for subfolder in get_folders(box_path): module_name = subfolder module_static_folder = os.path.join( box_path, subfolder, "static" ) if not os.path.exists(module_static_folder): continue module_in_static_dir = os.path.join( modules_path_in_static, folder, module_name ) trycopytree(module_static_folder, module_in_static_dir) else: module_name = folder module_static_folder = os.path.join( modules_path, folder, "static" ) if not os.path.exists(module_static_folder): continue module_in_static_dir = os.path.join( modules_path_in_static, module_name ) trycopytree(module_static_folder, module_in_static_dir) else: # copy only module's static folder module_static_folder = os.path.join( modules_path, target_module, "static" ) if os.path.exists(module_static_folder): if target_module.startswith("box__"): if "/" in target_module: module_name = target_module.split("/")[1] else: print("Could not understand module name") sys.exit() else: module_name = target_module module_in_static_dir = os.path.join( modules_path_in_static, module_name ) tryrmtree(module_in_static_dir) trycopytree(module_static_folder, module_in_static_dir) else: print("Module does not exist")