diff --git a/paramecio2/config.py.sample b/paramecio2/config.py.sample new file mode 100644 index 0000000..bd1ae5b --- /dev/null +++ b/paramecio2/config.py.sample @@ -0,0 +1,33 @@ +from paramecio2.libraries.db.webmodel import WebModel + +secret_key="im smoking fool" + +static_folder='/media/default' + +static_url_path='/media/default' + +# The second parameter is the prefix if you want use more applications. + +apps={'welcome': ['paramecio2.modules.welcome', 'welcome_app', '/']} + +default_module='welcome' + +theme="default" + +reloader=True + +application_root='/' + +yes_static=True + +domain_url='http://127.0.0.1:5000' + +#media_folder='/media/' + +media_url='/media/' + +portal_email="no-reply@example.com" + +#Db configuration + + diff --git a/paramecio2/console.py b/paramecio2/console.py new file mode 100644 index 0000000..70bdd35 --- /dev/null +++ b/paramecio2/console.py @@ -0,0 +1,433 @@ +#!/usr/bin/env python3 + +import argparse +import os +import shutil +import getpass +import re +from pathlib import Path +from base64 import b64encode +from paramecio2.libraries.db.webmodel import WebModel +from paramecio2.modules.admin.models.admin import UserAdmin +from subprocess import call +from urllib.parse import urlparse + +def start(): + + parser=argparse.ArgumentParser(prog='paramecio2', description='A tool for create new paramecio2 sites') + + parser.add_argument('--path', help='The path where the paramecio site is located', required=True) + + parser.add_argument('--modules', help='A list separated by commas with the git repos for download modules for this site', required=False) + + parser.add_argument('--symlink', help='Set if create direct symlink to paramecio in new site', action='store_true') + + parser.add_argument('--tests', help='Create a symlink to tests for check into paramecio site', action='store_true') + + # Options for deploy + + parser.add_argument('--url', help='The http/https base url of the real proxy server. Example: https://www.exampledomain.com, default is http://localhost:8080', required=False) + + parser.add_argument('--folder', help='If you deploy in a subdirectory, set it, without beggining and ending slashes', required=False) + + parser.add_argument('--host', help='The host ip or domain where the app is binded', required=False) + + parser.add_argument('--port', help='Change the default port 8080 to other number. Use 80 is not recommended, use 80 for the proxy server how nginx or apache', required=False) + + args=parser.parse_args() + + #print(args) + #exit(0) + + workdir=os.path.dirname(os.path.abspath(__file__)) + + # Create directory + + path=Path(args.path) + + try: + path.mkdir(0o755, True) + + except: + + print('Error: cannot create the directory. Check if exists and if you have permissions') + exit() + # Create folder settings and copy index.py, admin.py + + path_settings=args.path+'/settings' + + try: + + os.mkdir(path_settings, 0o755) + except: + print('Error: cannot create the directory. Check if exists and if you have permissions') + + # Copy the files. Need optimization, use an array for save the filenames and a simple for loop. + + try: + + shutil.copy(workdir+'/config.py.sample', path_settings+'/config.py') + + except: + + print('Error: cannot copy the file config.py. Check if exists and if you have permissions for this task') + + try: + + shutil.copy(workdir+'/frontend/index.py', args.path+'/app.py') + + except: + + print('Error: cannot copy the file index.py to app.py. Check if exists and if you have permissions for this task') + + """ + try: + + shutil.copy(workdir+'/frontend/padmin.py', args.path+'/padmin.py') + + except: + + print('Error: cannot copy the file padmin.py. Check if exists and if you have permissions for this task') + + try: + + shutil.copy(workdir+'/frontend/i18nadmin.py', args.path+'/i18nadmin.py') + + except: + + print('Error: cannot copy the file i18nadmin.py. Check if exists and if you have permissions for this task') + + try: + + shutil.copy(workdir+'/frontend/regenerate.py', args.path+'/regenerate.py') + + except: + + print('Error: cannot copy the file regenerate.py. Check if exists and if you have permissions for this task') + + try: + + shutil.copy(workdir+'/frontend/create_module.py', args.path+'/create_module.py') + + except: + + print('Error: cannot copy the file create_module.py. Check if exists and if you have permissions for this task') + + + try: + + shutil.copy(workdir+'/settings/modules.py', path_settings+'/modules.py') + + except: + + print('Error: cannot copy the file modules.py. Check if exists and if you have permissions for this task') + + """ + if args.symlink==True: + try: + os.symlink(workdir, args.path+'/paramecio2', True) + + except: + print('Error: cannot symlink paramecio in new site') + + if args.tests==True: + try: + os.symlink(workdir, args.path+'/paramecio2/', True) + + except: + print('Error: cannot symlink paramecio in new site') + + with open(path_settings+'/config.py', 'r') as f: + conf=f.read() + + random_bytes = os.urandom(24) + #secret_key_session = b64encode(random_bytes).decode('utf-8').strip() + + conf=conf.replace('"im smoking fool"', random_bytes) + + #domain='localhost' + + #conf=conf.replace("domain='localhost'", "domain='"+args.url+"'") + """ + if args.host==None: + args.host='localhost' + + conf=conf.replace("host='localhost'", "host='"+args.host+"'") + + if args.port==None: + args.port='8080' + + + conf=conf.replace("port=8080", "port="+args.port) + """ + + base_url='/' + + if args.folder==None: + args.folder='' + else: + #args.folder='/'+args.folder + base_url='/'+args.folder+'/' + + conf=conf.replace("application_root='/'", "application_root='"+base_url+"'") + + if args.url==None: + args.url='http://127.0.0.1:5000' + + domain_url=args.url + + conf=conf.replace("domain_url='http://127.0.0.1:5000'", "domain_url='"+domain_url+"'") + + #domain_url='http://localhost:8080' + + with open(path_settings+'/config.py', 'w') as f: + f.write(conf) + + # Question about mysql configuration? If yes, install configuration + + s=input('Do you want use paramecio with MySQL database? y/n: ') + + if s=='y' or s=='Y': + + host_db=input('MySQL database server host, by default localhost: ').strip() + + db=input('MySQL database name, by default paramecio_db: ').strip() + + user_db=input('MySQL database user, by default root: ').strip() + + pass_db=getpass.getpass('MySQL database password, by default "": ').strip() + + if host_db=='': + + host_db='localhost' + + if user_db=='': + + user_db='root' + + #user=UserAdmin() + + #Create db + + if db=="": + db='paramecio_db' + + WebModel.connections={'default': {'name': 'default', 'host': host_db, 'user': user_db, 'password': pass_db, 'db': '', 'charset': 'utf8mb4', 'set_connection': False, 'db_type': 'pymysql'} } + + connection_code="WebModel.connections={'default': {'name': 'default', 'host': '"+host_db+"', 'user': '"+user_db+"', 'password': '"+pass_db+"', 'db': '"+db+"', 'charset': 'utf8mb4', 'set_connection': False, 'db_type': 'pymysql'} }" + + with open(path_settings+'/config.py', 'a') as f: + f.write("\n\n"+connection_code) + f.close() + + sql='create database '+db + + conn=WebModel.connection() + + useradmin=UserAdmin(conn) + + # Check if db exists + + c=0 + + with useradmin.query('SHOW DATABASES LIKE "%s"' % db) as cur: + c=cur.rowcount + + if c==0: + useradmin.query(sql) + #print('Error: cannot create database or db doesn\'t exists, check database permissions for this user') + + #if not useradmin.query(sql): + #print('Error: cannot create database, check the data of database') + + + #else: + + useradmin.query('use '+db) + + admin=input('Do you want create admin site? y/n: ') + + if admin=='y' or admin=='Y': + + try: + + #shutil.copy(workdir+'/settings/modules.py.admin', path_settings+'/modules.py') + + #shutil.copy(workdir+'/settings/config_admin.py.sample', path_settings+'/config_admin.py') + + sql=useradmin.create_table() + + if not useradmin.query(sql): + print('Error: cannot create table admin, you can create this table with padmin.py') + else: + + # Add admin module to config + with open(path_settings+'/config.py', 'r') as f: + + config_text=f.read() + + f.close() + + #apps={'welcome': ['paramecio2.modules.welcome', 'welcome_app', '/'], 'admin': ['paramecio2.modules.admin', 'admin_app', '/']} + + config_text=config_text.replace("apps={'welcome': ['paramecio2.modules.welcome', 'welcome_app', '/']}", "apps={'welcome': ['paramecio2.modules.welcome', 'welcome_app', '/'], 'admin': ['paramecio2.modules.admin', 'admin_app', '/']}") + + with open(path_settings+'/config.py', 'w') as f: + + f.write(config_text) + + f.close() + + """ + try: + + shutil.copy(workdir+'/settings/modules.py.admin', path_settings+'/modules.py') + + except: + + print('Error: cannot copy the file modules.py. Check if exists and if you have permissions for this task') + """ + + print('Created admin site...') + + except: + + print('Error: cannot create the database. Check if tables exists in it and if you have permissions for this task') + exit(1) + + pass + + # Install modules + """ + if args.modules!=None: + + if args.modules.strip()!='': + + arr_modules=args.modules.split(',') + + final_modules=[] + + final_modules_models=[] + + if len(arr_modules)>0: + + for k, module in enumerate(arr_modules): + + module=module.strip() + + try: + + u=urlparse(module) + + module_path=os.path.basename(u.path) + + except: + print('Error: not valid url for repository') + exit(1) + + + if call("git clone %s %s/modules/%s" % (module, path, module_path), shell=True) > 0: + print('Error, cannot install the module %s' % module_path) + exit(1) + else: + print('Added module %s' % module_path) + + final_modules.append(("modules/%s" % (module_path)).replace('/', '.')) + final_modules_models.append("modules/%s" % (module_path)) + + + + # Edit config.py + + with open(path_settings+'/config.py') as f: + + modules_final='\''+'\', \''.join(final_modules)+'\'' + + p=re.compile(r"^modules=\[(.*)\]$") + + #config_file=p.sub(r"modules=[\1, "+modules_final+"]", "modules=['paramecio.modules.welcome', 'paramecio.modules.admin', 'paramecio.modules.lang', 'modules.pastafari', 'modules.monit', 'modules.example']") + + final_config='' + + for line in f: + if p.match(line): + line=p.sub(r"modules=[\1, "+modules_final+"]", line) + final_config+=line + + with open(path_settings+'/config.py', 'w') as f: + + f.write(final_config) + + print('Updated configuration for add new modules...') + + #Change workdir + + real_dir=os.getcwd() + + os.chdir(args.path) + + #Regenerating modules.py + + regenerate='regenerate.py' + + os.chmod(regenerate, 0o755) + + if call('./regenerate.py', shell=True) > 0: + print('Error, cannot regenerate the modules.py script') + exit(1) + else: + print('Regeneration of modules.py finished') + + # Installing models + + padmin='padmin.py' + + os.chmod(padmin, 0o755) + + for mod_path in final_modules_models: + + models_path=mod_path+'/models' + + if os.path.isdir(models_path): + + models_files=os.listdir(models_path) + + m=re.compile(".*\.py$") + + underscore=re.compile("^__.*") + + for f in models_files: + + if m.match(f) and not underscore.match(f): + + if call('./padmin.py --model '+models_path+'/'+f, shell=True) > 0: + print('Error, cannot create the modules of '+models_path+'/'+f) + else: + print('Models from '+models_path+'/'+f+' created') + + # Execute two times the loop because i can need good installed models for postscript script + + # Execute postscript + + print('Executing postscripts') + + for mod_path in final_modules_models: + + postscript=mod_path+"/install/postinstall.py" + + os.chmod(padmin, 0o755) + + if os.path.isfile(postscript): + + os.chmod(postscript, 0o755) + + if call('./'+postscript, shell=True) > 0: + print('Error, cannot execute the postinstall script') + exit(1) + else: + print('Postinstall script finished') + """ + conn.close() + +if __name__=="__main__": + start() diff --git a/paramecio2/index.py b/paramecio2/index.py new file mode 100644 index 0000000..a967bba --- /dev/null +++ b/paramecio2/index.py @@ -0,0 +1,3 @@ +from paramecio2.app import start_app + +app=start_app() diff --git a/setup.py b/setup.py index ae3b045..ee74a0d 100644 --- a/setup.py +++ b/setup.py @@ -6,7 +6,7 @@ from setuptools import setup, find_packages if sys.version_info < (3, 5): - raise NotImplementedError("Sorry, you need at least Python 3.5 for use paramecio.") + raise NotImplementedError("Sorry, you need at least Python 3.5 for use paramecio2.") #import paramecio # Pillow should be installed after if you need ImageField @@ -18,12 +18,12 @@ setup(name='paramecio', long_description='This framework is a simple framework used for create web apps. Paramecio is modular and fast. By default have a module called admin that can be used for create admin sites', author='Antonio de la Rosa Caballero', author_email='antonio.delarosa@coesinfo.com', - url='https://github.com/paramecio/paramecio2fm/', - packages=['paramecio', 'paramecio.i18n', 'paramecio.settings'], + url='https://bitbucket.org/paramecio/paramecio2fm/', + packages=['paramecio2'], include_package_data=True, - install_requires=['bottle', 'flask', 'pymysql', 'sqlalchemy', 'colorama'], + install_requires=['flask', 'pymysql', 'sqlalchemy', 'colorama'], entry_points={'console_scripts': [ - 'paramecio = paramecio.console:start', + 'paramecio2 = paramecio2.console:start', ]}, license='GPLV3', platforms = 'any', @@ -37,11 +37,9 @@ setup(name='paramecio', 'Topic :: Internet :: WWW/HTTP :: WSGI :: Server', 'Topic :: Software Development :: Libraries :: Application Frameworks', 'Programming Language :: Python :: 3', - 'Programming Language :: Python :: 3.3', - 'Programming Language :: Python :: 3.4', 'Programming Language :: Python :: 3.5', 'Programming Language :: Python :: 3.6', 'Programming Language :: Python :: 3.7', - 'Programming Language :: Python :: 3.8' + 'Programming Language :: Python :: 3.6' ], )