from fabric.api import env, local, task from fabric.context_managers import lcd import fabric.operations as fabric_ops from fabric.contrib.files import exists import os import sys import pathlib ERRCODE_DJANGO_COVERAGE_NO_APPLICATION_PARAMETER_SET = -3 dir_parent = pathlib.Path(os.path.abspath(__file__)).parents[2] sys.path.append(str(dir_parent)) try: import customfabric.modules.utils as modules_utils from customfabric.modules.utils import virtualenv from customfabric.modules.utils import loggify, print_run, booleanize from customfabric.modules.utils import generate_template_build_path from customfabric.modules.utils import generate_template_files_path from customfabric.modules.utils import handle_flag_message from customfabric.modules.utils import prompt_continue except ImportError: raise # from modules.utils import virtualenv # from .utils import loggify, print_run, booleanize # from .utils import generate_template_build_path # from .utils import generate_template_files_path # from .utils import handle_flag_message # from .utils import prompt_continue # # import os def generate_secret_key(): """ helper to generate django secret key """ import random import string SECRET_KEY = ''.join([random.SystemRandom().choice( "{}{}{}".format( string.ascii_letters, string.digits, '!#$%()*+,-./:;<=>?@[\\]_{}~')) for i in range(50)]) return SECRET_KEY @task def test(args=None): """ the purpose of this method is just to use as a placeholder for any kind of testing of methods """ print("debug - testing checkapp(sorl.thumbnail): %s" % check_app("sorl.thumbnail")) @task def commandline(args="", workingdir=None): """ prints out what you need to run on the command line to invoke manage.py :parameter args: the arguments you would normally say the django.manage. defaults to empty string :type args: str :parameter workingdir: the working directory of the manage.py script. defaults to None, which means it uses the working directory that are given in the project settings :type workingdir: str """ configuration = env.config if workingdir: commandline = "{djangoroot}/manage.py {args} " \ "--pythonpath='{djangoroot}' " \ "--settings={djangosettings}".format( djangoroot=configuration.paths.django.root, args=args, djangosettings=configuration.imports.settings,) else: commandline = "{djangoroot}/manage.py {args} --pythonpath='"\ "{djangoroot}' --settings={djangosettings}".format( djangoroot=configuration.paths.django.root, args=args, djangosettings=configuration.imports.settings,) print(commandline) @task def manage(args="help", workingdir=None, prefix="", suffix=""): """ wrapper method for the django manage.py command, takes values given and runs it using the project settings. It automatically applies the correct virtualenvwrapper for this project, sets the correct python path, and locates the correct settings file :parameter args: usually the argument that manage.py will take. defaults to 'help' :type args: str :parameter workingdir: the working directory of the manage.py script. defaults to None, which means it uses the working directory that are given in the project settings :type workingdir: str :param prefix: any bash commands we'd want to place before manage.py :type prefix: str :param suffix: any bash commands we'd want to place after manage.py :type suffix: str """ configuration = env.config # changes the working directory to the djangoroot from fabric.context_managers import cd with virtualenv(): if workingdir: with cd(workingdir): fabcommand = "{prefix} {djangoroot}/manage.py {args} " \ "--pythonpath='{djangoroot}' " \ "--settings={djangosettings} {suffix}".format( prefix=prefix, djangoroot=configuration.paths.django.root, args=args, djangosettings=configuration.imports.settings, suffix=suffix ) if env.debug: print("fabcommand: %s" % fabcommand) print("workingdir: %s" % workingdir) else: output = fabric_ops.run( fabcommand, # MAKE SURE THIS IS ALWAYS HERE! shell='/bin/bash') else: with cd(configuration.paths.django.root): cmd = "{prefix} {djangoroot}/manage.py {args} " \ " --pythonpath='{djangoroot}' " \ "--settings={djangosettings} {suffix}".format( prefix=prefix, djangoroot=configuration.paths.django.root, args=args, djangosettings=configuration.imports.settings, suffix=suffix) if env.debug: print("command: with cd(%s)" % configuration.paths.django.root) print("command: fabric_ops.run(%s)" % cmd) else: output = fabric_ops.run( cmd, # MAKE SURE THIS IS ALWAYS HERE! shell='/bin/bash' ) # fabric.run has the ability to give me back the output return output # NOTE: # there was a major problem using fabric commands of "local" or "prefix" # to work on remote machines, the problem was that for whatever cracked # up reason, fabric would assume I'm using a /bin/sh shell, and /bin/sh # CANNOT run all the commends that /bin/bash can. SO YOU MUST SPECIFY # shell='/bin/bash' in all uses of local! def coverage_test(): """ helper method to determine if coverage config exists and if not print out an error message """ configuration = env.config if configuration.coverage is None: print("\n\nWARNING! There is no coverage file specified " "in the virtualenv settings for this branch!") print("\ncoverage file settings should resemble the following:\n") print("coverage:") print(" config: setup.cfg") print(" paths:") print(" root: share/coverage") print(" html: htmlcov") print("\nExiting.") import sys sys.exit() @task def coverage(application=None, args="test", workingdir=None, outputdir=None, coveragerc=True, report=True, html=True): """ Helper method that uses the coverage package :parameter application: the name of the installed application being tested. NOTE: this is required because currently I do not know how to run manage.py test on all installed applications. If no value is given, the program will give a message and exit. :type application: str :parameter args: the manage command that coverage is going to run. defaults to test :type args: str :parameter workingdir: the working directory that manage will run it's command under. defaults to None :type workingdir: str :parameter outputdir: the directory to which file results will be output to. defaults to None :type outputdir: str :parameter coveragerc: flags whether or not there is a coverage settings file which determines what coverage will or wont do. coveragerc file is located in share/coverage/setup.cfg you can modify this in the virtualenv settings for this branch. defaults to True :type coveragerc: bool :parameter report: flags whether or not coverage will be asked to generate a report. defaults to true. :type report: bool :parameter html: flags whether or not coverage will generate an html version of its report. defaults to true :type html: bool TODO: test if coverage is installed and if it isn't give an error explaining the problem TODO: currently, django.manage:test is not working properly because it does not find the tests on all installed applications. Instead, each application must be tested seperately. For this reason, I require this method to specifically ask for the applications being used """ # # make sure that the application parameter was set if application is None: modules_utils.printerr( message="\nThe application parameter for django.coverage" " was not set! Please make sure you have set application" " to the application you wish to have coverage applied to!" "\nExiting.", errcode=ERRCODE_DJANGO_COVERAGE_NO_APPLICATION_PARAMETER_SET) configuration = env.config coverage_test() prefix = "coverage run" suffix = "" if coveragerc: prefix += " --rcfile=%s" % configuration.coverage.config if report: suffix += " && coverage report" if html: suffix += " && coverage html" suffix += " -d %s" % configuration.coverage.paths.html if env.debug: print("args: %s" % args) print("workigindir: %s" % args) print("\nis report: %s" % report) print("is html: %s" % html) print("\nprefix: %s" % prefix) print("suffix: %s" % suffix) args = args + " %s" % application manage(args=args, workingdir=workingdir, prefix=prefix, suffix=suffix) @task def admin(args="help"): configuration = env.config from fabric.context_managers import cd with virtualenv(): with cd(configuration.paths.django.root): fabric_ops.run( "django-admin {args} --pythonpath='{djangoroot}' " "--settings={djangosettings}".format( djangoroot=configuration.paths.django.root, args=args, djangosettings=configuration.imports.settings, ), # MAKE SURE THIS IS ALWAYS HERE! shell='/bin/bash' ) @task def collectstatic(): """ makes sure the static media directories exist """ configuration = env.config exists(configuration.paths.server.media.static) exists(configuration.paths.server.media.dynamic) manage("collectstatic --noinput") @task def run(args=None): configuration = env.config command = "runserver {host}:{port}".format( host=configuration.server.django.host, port=configuration.server.django.port) output = manage(command) return output @task def startapp(appname='help'): """ wrapper for the django.startapp takes name of app and creates in in code/apps appname - name of app """ configuration = env.config msg_help = """ django.startapp takes one of two values: \thelp - this help message \tappname - the name of the app you want to start """ import sys if handle_flag_message(appname, msg_help, 'help'): sys.exit() command = "startapp {appname}".format( appname=appname) manage(command, workingdir=configuration.paths.django.apps) # with lcd(configuration.paths.django.apps): # manage(command) @task def installed_apps(): """ List the currently installed apps in the settings.py file for this project """ configuration = env.config printecho = "print('\\n')" printcommand = "print('\\n').join([ item for item" \ " in {settings}.INSTALLED_APPS])".format( settings=configuration.imports.settings) command = "python -c \"import {settings}; {printecho};" \ " {printcommand}; {printecho}\"".format( settings=configuration.imports.settings, printecho=printecho, printcommand=printcommand) with lcd(configuration.paths.django.root): local(command) @task def src(): """ locate the django source files in the site-packages directory """ command = """ python -c " import sys sys.path = sys.path[1:] import django print(django.__path__)" """ command = """ python -c "import sys; sys.path=sys.path[1:];""" \ """ import django; print(django.__path__)[0]" """ with virtualenv(): local(command) @task def create_project(): configuration = env.config logger = loggify("django", "create_project") project_path = configuration.paths.django.root project_base = configuration.paths.django.settings.base project_name = configuration.project.name import os full_project_path = os.path.join(project_path, project_base) django_cmd = \ "django-admin startproject {project_base} {project_path}".format( project_base=project_base, project_path=project_path) manage_path = "%s/manage.py" % project_path logger.debug("django_root : %s" % configuration.paths.django.root) logger.debug("project_path : %s" % project_path) logger.debug("project_base : %s" % project_base) logger.debug("project_name : %s" % project_name) # I accidentally deleted the code directory, this checks to see if the # project path exists, if not, create it. if not exists(project_path): fabric_ops.run("mkdir -p %s" % project_path) if exists(manage_path): fabric_ops.run("rm %s" % manage_path) if exists(full_project_path): # we need to make sure that # a. we back up the current settings for the project # b. that we don't override the OLD project backup settings # c. and that we give ourselves the option to NOT backup # # so if the system sees that we already have a backup of the main # folder, ie. projectname.old, then it will give us the option to # either overwrite the old backup (Y), or to stop the proecess and do # whatever needs to be done to clear things up project_path_old = "{project_path}/{project_base}.old".format( project_path=project_path, project_base=project_base) if exists(project_path_old): prompt_continue( message="found an already existing old " "version of {project_path}, do you want to ignore" " backing up the version or exit? Y/n ( Y to " "continue without backing up. N to exit )", default="n") fabric_ops.run("rm -Rf {project_path}/{project_base}".format( project_base=project_base, project_path=project_path)) else: # backup whatever is there fabric_ops.run("mv {project_path}/{project_base}" " {project_path}/{project_base}.old".format( project_base=project_base, project_path=project_path)) with virtualenv(): fabric_ops.run(django_cmd) django_path = "{project_path}/{project_base}".format( project_base=project_base, project_path=project_path) fabric_ops.run("mkdir %s/_settings" % django_path) fabric_ops.run("touch %s/_settings/__init__.py" % django_path) generate('settings', True) generate('local', True) generate('wsgi', True) def generate_scripts(template_name, make_copy=False): """ this is a function meant to generate django settings files There are a number of different types of django settings files so instead of generating all of them at the same time (sometimes I want the local, sometimes I want the main, etc), I decided to create a function that can look up the type of scripts I want and generate those. The function is meant to be wrapped up in another funciton that will call the type of script I want """ configuration = env.config # make sure to booleanize ALL boolean values! make_copy = booleanize(make_copy) if env.debug: logger = loggify("django", "generate_scripts") project_base = configuration.paths.django.settings.base project_branch = configuration.project.branch project_path = configuration.paths.django.root project_name = configuration.project.name secret_key = generate_secret_key() files_name = getattr(configuration.templates.django, template_name).src build_name = getattr(configuration.templates.django, template_name).dst build_path = generate_template_build_path('django', template_name) files_path = generate_template_files_path('django') context = dict() context['project_name'] = project_name context['project_base'] = project_base context['project_branch'] = project_branch context['secret_key'] = secret_key context['paths_tools_fabric'] = configuration.paths.tools.fabric copy_path = "{project_path}/{project_base}".format( project_path=project_path, project_base=project_base) if template_name == 'local': copy_path = "{project_path}/{project_base}/_settings".format( project_path=project_path, project_base=project_base) build_name = "%s.py" % project_branch # generate the local generate scripts generate('local.generated', make_copy) elif template_name == 'local.generated': copy_path = "{project_path}/{project_base}/_settings".format( project_path=project_path, project_base=project_base) build_name = "%s_generated.py" % project_branch # add extra local specfic context variables # NOTE: # if you change project settings, you MUST run generate context['paths_django_templates'] = \ configuration.paths.django.templates context['server_database_backend'] = \ configuration.server.database.backend context['server_database_name'] = configuration.server.database.name context['server_database_user'] = configuration.server.database.user context['server_database_password'] = \ configuration.server.database.password context['server_database_host'] = configuration.server.database.host context['server_database_port'] = configuration.server.database.port context['paths_server_media_static'] = \ configuration.paths.server.media.static context['paths_server_media_dynamic'] = \ configuration.paths.server.media.dynamic context['paths_project_root'] = configuration.paths.project.root context['project_django_allowedhosts'] = \ configuration.project.django.allowedhosts # convenience variable naming, otherwise it's too long to deal with file_log_handler = configuration.logging.django.handlers.file_log file_debug_handler = configuration.logging.django.handlers.file_debug context['file_log_handler__name_project'] = \ file_log_handler.name.project context['file_log_handler__path_project'] = \ file_log_handler.path.project context['file_debug_handler__name_project'] = \ file_debug_handler.name.project context['file_debug_handler__path_project'] = \ file_debug_handler.path.project context['file_debug_handler__name_server'] = \ file_debug_handler.name.server context['file_debug_handler__path_server'] = \ file_debug_handler.path.server copy_full_path = "{copy_path}/{build_name}".format( copy_path=copy_path, build_name=build_name) copy_cmd = "cp {build_path} {copy_full_path}".format( build_path=build_path, copy_full_path=copy_full_path) backup_cmd = "cp {copy_full_path} " \ "{copy_full_path}.bak".format(copy_full_path=copy_full_path) from .utils import upload_template as utils_upload_template if env.debug: logger.debug("template_name : %s" % template_name) logger.debug("project_branch : %s" % project_branch) logger.debug("project_base : %s" % project_base) logger.debug("build_path : %s" % build_path) logger.debug("files_path : %s" % files_path) logger.debug("files_name : %s" % files_name) logger.debug("copy_path : %s" % copy_path) logger.debug("copy_full_path : %s" % copy_full_path) logger.debug("build_name : %s" % build_name) upload_msg = utils_upload_template( filename=files_name, destination=build_path, context=context, use_jinja=True, use_sudo=False, backup=True, template_dir=files_path, debug=True) logger.debug("upload_msg : %s" % upload_msg) logger.debug("make_copy : %s" % make_copy) logger.debug("copy_cmd : %s" % copy_cmd) logger.debug("backup_cmd : %s" % backup_cmd) else: utils_upload_template( filename=files_name, destination=build_path, context=context, use_jinja=True, use_sudo=False, backup=True, template_dir=files_path, debug=False) if make_copy: if exists(copy_full_path): fabric_ops.run(backup_cmd) fabric_ops.run(copy_cmd) print("\n\n------------------------------") print("project_base : %s" % project_base) print("project_branch : %s" % project_branch) print("project_path : %s" % project_path) print("template_name : %s" % template_name) print("build_path : %s" % build_path) print("files_path : %s" % files_path) print("files_name : %s" % files_name) print("copy_path : %s" % copy_path) print("copy_full_path : %s" % copy_full_path) print("build_name : %s" % build_name) upload_msg = utils_upload_template( filename=files_name, destination=build_path, context=context, use_jinja=True, use_sudo=False, backup=True, template_dir=files_path, debug=True) print("upload_msg : %s" % upload_msg) print("make_copy : %s" % make_copy) print("copy_cmd : %s" % copy_cmd) print("backup_cmd : %s" % backup_cmd) print("------------------------------\n\n") @task def generate(param="help", make_copy=False): """ param can be one of settings, local, local.generated, wsgi make_copy must be set to True if you want it to actually do anthing """ SCRIPT_LIST = ['settings', 'local', 'local.generated', 'wsgi'] PARAM_LIST = list(SCRIPT_LIST) PARAM_LIST.append('gunicorn') make_copy = booleanize(make_copy) if param: err_msg = None if param == "help": err_msg = """ fab django.generate:param="help",make_copy=False param - file to be generated can be of type: %s make_copy - determines whether or generate copies the generated file into it's practical location (otherwise doesn't do anything) """ % PARAM_LIST elif param not in PARAM_LIST: err_msg = "You asked to generate %s, that value isn't available" \ " possible script values available: %s" % (param, PARAM_LIST) if err_msg: import sys sys.exit(err_msg) print("django:generate make_copy : %s\n" % make_copy) print("django:generate script : %s" % param) if env.debug: print("django:generate script : %s" % param) print("django:generate make_copy : %s\n" % make_copy) else: pass # env.debug does not block the rest of the commands because this # function acts primarily as a wrapper for the following cmomands, in # those fucntion env.debug will be used to decide if anything should # happen or not if not param: # this is where script=None, generate all scripts for scriptkey in SCRIPT_LIST: generate_scripts(scriptkey, make_copy) generate_gunicorn(make_link=make_copy) elif param == 'gunicorn': generate_gunicorn(make_link=make_copy) else: generate_scripts(param, make_copy) def generate_gunicorn(make_link=True): """ create the gunicorn configuration script put it in the build folder and link it to the scripts directory """ configuration = env.config make_link = booleanize(make_link) if env.debug: logger = loggify("django", "generate_gunicorn") files_path = os.path.join( configuration.templates.gunicorn.path.local, 'files') build_path = os.path.join( configuration.templates.gunicorn.path.remote, 'build', configuration.templates.gunicorn.conf.dst) link_path = os.path.join( configuration.paths.server.scripts, configuration.templates.gunicorn.conf.dst ) context = dict() context['host'] = configuration.server.django.host context['port'] = configuration.server.django.port context['user'] = configuration.project.user context['group'] = configuration.project.group context['settings_module'] = configuration.imports.settings context['extended_name'] = configuration.project.extendedname context['logging_access'] = configuration.logging.gunicorn.access context['logging_error'] = configuration.logging.gunicorn.error msg_link_gunicorn = "ln -sf {gunicorn_root} {link_gunicorn}".format( gunicorn_root=build_path, link_gunicorn=link_path) print_run(msg_link_gunicorn) if env.debug: logger.debug("\n") logger.debug("--- in gunicorn ---\n") for key in context.keys(): logger.debug("%s\t: %s" % (key, context[key])) logger.debug('build_path\t: %s' % build_path) logger.debug('files_path\t: %s' % files_path) logger.debug('files config src: %s' % configuration.templates.gunicorn.conf.src) logger.debug('\n%s' % print_run(msg_link_gunicorn)) from .utils import upload_template as utils_upload_template upload_msg = utils_upload_template( filename=configuration.templates.gunicorn.conf.src, destination=build_path, context=context, use_jinja=True, use_sudo=False, backup=True, template_dir=files_path, debug=True) logger.debug("upload_msg : %s" % upload_msg) else: from fabric.contrib.files import upload_template upload_template( filename=configuration.templates.gunicorn.conf.src, destination=build_path, context=context, use_jinja=True, backup=True, template_dir=files_path) if make_link: print("\nlinking the generating gunicorn file in conf to " "the server diretory\n") fabric_ops.run(msg_link_gunicorn) else: print("\nNOTE: not linking the generated gunicorn file" "to the server directory\n") @task def edit(param='help'): """ calls up mvim on the gunicorn and django conf file """ from .maintenance import edit as maintenance_edit configuration = env.config link_path = os.path.join( configuration.paths.server.scripts, configuration.templates.gunicorn.conf.dst ) build_path = os.path.join( configuration.templates.gunicorn.path.remote, 'build', configuration.templates.gunicorn.conf.dst) project_branch = configuration.project.branch project_path = configuration.paths.django.root project_settings_dir = configuration.paths.django.settings.base django_path = "{project_path}/{project_settings_dir}".format( project_path=project_path, project_settings_dir=project_settings_dir ) settings_path = "{django_path}/settings.py".format( django_path=django_path) settings_local_path = "{django_path}/_settings/{project_branch}.py".format( django_path=django_path, project_branch=project_branch) settings_generated_path = "{django_path}/_settings/" \ "{project_branch}_generated.py".format( django_path=django_path, project_branch=project_branch) file_debug_handler = configuration.logging.django.handlers.file_debug # locations = ['coverage', 'gunicorn', 'gunicorn_link', 'gunicorn_build', # 'settings', 'local'] locations = { 'gunicorn': { 'path': link_path, 'desc': 'gunicorn.conf file', }, 'gunicorn_build': { 'path': build_path, 'desc': "gunicorn.conf file in scripts/conf/gunicorn/build" }, 'gunicorn.log.error': { 'path': configuration.logging.gunicorn.error, 'desc': "gunicorn error log file", }, 'gunicorn.log.access': { 'path': configuration.logging.gunicorn.access, 'desc': "gunicorn error log file", }, 'settings': { 'path': settings_path, 'desc': 'main settings file for django project', }, 'local': { 'path': settings_local_path, 'desc': 'local settings file for django project', }, 'generated': { 'path': settings_generated_path, 'desc': 'generated settings file for django project', }, 'server_log': { 'path': file_debug_handler.path.server, 'desc': 'django server log - handler name: %s' % file_debug_handler.name.server, }, 'project_log': { 'path': file_debug_handler.path.project, 'desc': 'django project log - handler name: %s' % file_debug_handler.name.project, }, } # # set .coveragerc path and filename # and add a coverage entry to locations if param == 'coverage': coverage_test() locations['coverage'] = { 'path': configuration.coverage.config, 'desc': 'coveragerc config file', } if param in locations.keys(): remote_path = locations[param]['path'] maintenance_edit(remote_path=remote_path) else: # if param == 'help': print(""" "fab django.edit" automates editing files important to django whether locally or remotely to use this you must pass one of the editable locations in as a parameter currently editable locations are: """) for k_loc in locations.keys(): print("\t{0: <20} - {1}".format(k_loc, locations[k_loc]['desc'])) return @task def clearmigrations(appname="help"): if appname == "help": print(""" "fab django.clearmigration:{appname}" clears out all migrations for the specified appname if no appname is given, or if you pass the "help" appnameter in place of an appname then this help message will appear. Note: if your appname is actually "help" you might want to go into this function and change it up a bit! """) return configuration = env.config import os app_path = os.path.join( configuration.paths.django.apps, appname) path_migrations = os.path.join( app_path, 'migrations') path_migrations_old = os.path.join( app_path, 'migrations.old') import fabric if fabric.contrib.files.exists(path_migrations): # get rid of any old migration backups if fabric.contrib.files.exists(path_migrations_old): cmd_rm_migration_old = "rm -Rf %s" % path_migrations_old fabric.operations.run(cmd_rm_migration_old) # move the original migrations folder to migrations.old cmd_migration = "mv %s %s" % ( path_migrations, path_migrations_old) fabric.operations.run(cmd_migration) manage("makemigrations --empty %s" % appname) manage("makemigrations") manage("migrate --fake %s 0002" % appname) @task def makemigrations_empty(param="help"): if param == "help": print("print this help message") return manage("makemigrations --empty %s" % param) @task def fixtures(appname=None, backup=False): """ @appname django app name for this fixture @backup default False, store in server backup dir? """ configuration = env.config # booleanize the backup parameter backup = booleanize(backup) print("debug - appname: %s" % appname) # from fabric.api import * path_data = configuration.paths.django.fixtures path_backup = configuration.paths.server.backups.fixtures print("debug - path_backup: %s" % path_backup) if appname is not None: path_data = os.path.join(path_data, appname) path_backup = os.path.join(path_backup, appname) fixture_name = "%s.json" % appname else: fixture_name = "all.json" if backup: fix_split = os.path.splitext(fixture_name) fixture_name = fix_split[0] + "_backup" + fix_split[1] path_fixture = os.path.join(path_backup, fixture_name) else: path_fixture = os.path.join(path_data, fixture_name) print("debug - path_fixture: %s" % path_fixture) from .utils import ensure_dir ensure_dir(path_data) ensure_dir(path_backup) from fabric.context_managers import hide with hide('running', 'stdout', 'stderr'): # get rid of things like "localhost: out" output = manage('dumpdata %s --indent 2' % appname) # Now go through the output and ignore all the extra # information there. import re # first get rid of everything until the last time # "[localhost] out:" is printed if configuration.project.host == 'localhost': p = re.compile(r"\[localhost\] out:") for match in p.finditer(output): pass try: pos = match.end() output = output[pos:] except Exception: pass # now find the first occurence of [ on a newline, e.g. # [ # { # "model.auth": 40, # etc. # p = re.compile(r"\n\[") # m = p.search(output) # pos = m.end() - 1 # output = output[pos:] from io import StringIO fixture_iostring = StringIO(output) fabric_ops.put(fixture_iostring, path_fixture) @task def loaddata(param=None): """ loads fixture data to the specified app from extras/data """ configuration = env.config if param is None: print("you must specify an appname to load the fixture to") return else: appname = param path_data = configuration.paths.django.fixtures if appname is not None: path_data = os.path.join(path_data, appname) path_fixture = os.path.join(path_data, "%s.json" % appname) else: path_fixture = os.path.join(path_data, "all.json") manage("loaddata %s" % path_fixture) @task def check_app(appname): """ check if is installed in settings @appname: the name of the app being checked for returns True/False """ from fabric.context_managers import hide with hide('running', 'stderr'): output = manage('listapps') import re p = re.compile(appname) match = p.search(output) if match: return True else: return False