Added webnotes.in_test check in too many writes check Conflicts: public/js/wn/form/control.js webnotes/utils/file_manager.py webnotes/webutils.py website/sitemap.py wnf.py
330 lines
No EOL
11 KiB
Python
Executable file
330 lines
No EOL
11 KiB
Python
Executable file
#!/usr/bin/env python
|
|
|
|
# Copyright (c) 2013, Web Notes Technologies Pvt. Ltd.
|
|
# MIT License. See license.txt
|
|
|
|
from __future__ import unicode_literals
|
|
import sys
|
|
|
|
if __name__=="__main__":
|
|
sys.path = [".", "lib", "app"] + sys.path
|
|
|
|
import webnotes
|
|
|
|
def main():
|
|
def run(args):
|
|
for fn, opts in args.items():
|
|
if (opts or isinstance(opts, list)) and globals().get(fn):
|
|
return globals().get(fn)(opts, args)
|
|
|
|
webnotes.destroy()
|
|
|
|
parsed_args = webnotes._dict(vars(setup_parser()))
|
|
if parsed_args.get("site")=="all":
|
|
for site in get_sites():
|
|
args = parsed_args.copy()
|
|
args["site"] = site
|
|
run(args)
|
|
else:
|
|
run(parsed_args)
|
|
|
|
def get_sites():
|
|
pass
|
|
|
|
def setup_parser():
|
|
import argparse
|
|
parser = argparse.ArgumentParser(description="Run webnotes utility functions")
|
|
|
|
setup_install(parser)
|
|
setup_utilities(parser)
|
|
setup_translation(parser)
|
|
setup_git(parser)
|
|
|
|
# common
|
|
parser.add_argument("-f", "--force", default=False, action="store_true",
|
|
help="Force execution where applicable (look for [-f] in help)")
|
|
parser.add_argument("--site", nargs="?", metavar="SITE-NAME or all",
|
|
help="Run for a particular site")
|
|
|
|
return parser.parse_args()
|
|
|
|
def setup_install(parser):
|
|
parser.add_argument("--install", metavar="DB-NAME", nargs=1,
|
|
help="Install a new app")
|
|
parser.add_argument("--reinstall", default=False, action="store_true",
|
|
help="Install a fresh app in db_name specified in conf.py")
|
|
parser.add_argument("--restore", metavar=("DB-NAME", "SQL-FILE"), nargs=2,
|
|
help="Restore from an sql file")
|
|
parser.add_argument("--install_fixtures", default=False, action="store_true",
|
|
help="(Re)Install install-fixtures from app/startup/install_fixtures")
|
|
parser.add_argument("--make_demo", default=False, action="store_true",
|
|
help="Install demo in demo_db_name specified in conf.py")
|
|
parser.add_argument("--make_demo_fresh", default=False, action="store_true",
|
|
help="(Re)Install demo in demo_db_name specified in conf.py")
|
|
|
|
def setup_utilities(parser):
|
|
# update
|
|
parser.add_argument("-u", "--update", nargs="*", metavar=("REMOTE", "BRANCH"),
|
|
help="Perform git pull, run patches, sync schema and rebuild files/translations")
|
|
parser.add_argument("--patch", nargs=1, metavar="PATCH-MODULE",
|
|
help="Run a particular patch [-f]")
|
|
parser.add_argument("-l", "--latest", default=False, action="store_true",
|
|
help="Run patches, sync schema and rebuild files/translations")
|
|
parser.add_argument("--sync_all", default=False, action="store_true",
|
|
help="Reload all doctypes, pages, etc. using txt files [-f]")
|
|
parser.add_argument("--reload_doc", nargs=3,
|
|
metavar=('"MODULE"', '"DOCTYPE"', '"DOCNAME"'))
|
|
|
|
# build
|
|
parser.add_argument("-b", "--build", default=False, action="store_true",
|
|
help="Minify + concatenate JS and CSS files, build translations")
|
|
parser.add_argument("-w", "--watch", default=False, action="store_true",
|
|
help="Watch and concatenate JS and CSS files as and when they change")
|
|
|
|
# misc
|
|
parser.add_argument("--backup", default=False, action="store_true",
|
|
help="Take backup of database in backup folder [--with_files]")
|
|
parser.add_argument("--with_files", default=False, action="store_true",
|
|
help="Also take backup of files")
|
|
parser.add_argument("--docs", default=False, action="store_true",
|
|
help="Build docs")
|
|
parser.add_argument("--domain", nargs="*",
|
|
help="Get or set domain in Website Settings")
|
|
parser.add_argument("--make_conf", nargs="*", metavar=("DB-NAME", "DB-PASSWORD"),
|
|
help="Create new conf.py file")
|
|
|
|
# clear
|
|
parser.add_argument("--clear_web", default=False, action="store_true",
|
|
help="Clear website cache")
|
|
parser.add_argument("--clear_cache", default=False, action="store_true",
|
|
help="Clear cache, doctype cache and defaults")
|
|
parser.add_argument("--reset_perms", default=False, action="store_true",
|
|
help="Reset permissions for all doctypes")
|
|
|
|
# scheduler
|
|
parser.add_argument("--scheduler", "--run_scheduler", default=False, action="store_true",
|
|
help="Trigger scheduler")
|
|
parser.add_argument("--scheduler_event", "--run_scheduler_event", nargs=1,
|
|
metavar="all | daily | weekly | monthly",
|
|
help="Run a scheduler event")
|
|
|
|
# replace
|
|
parser.add_argument("--replace", nargs=3,
|
|
metavar=("SEARCH-REGEX", "REPLACE-BY", "FILE-EXTN"),
|
|
help="Multi-file search-replace [-f]")
|
|
|
|
# import/export
|
|
parser.add_argument("--export_doc", nargs=2, metavar=('"DOCTYPE"', '"DOCNAME"'))
|
|
parser.add_argument("--export_doclist", nargs=3, metavar=("DOCTYPE", "NAME", "PATH"),
|
|
help="""Export doclist as json to the given path, use '-' as name for Singles.""")
|
|
parser.add_argument("--export_csv", nargs=2, metavar=("DOCTYPE", "PATH"),
|
|
help="""Dump DocType as csv""")
|
|
parser.add_argument("--import_doclist", nargs=1, metavar="PATH",
|
|
help="""Import (insert/update) doclist. If the argument is a directory, all files ending with .json are imported""")
|
|
|
|
def setup_git(parser):
|
|
parser.add_argument("--pull", nargs="*", metavar=("REMOTE", "BRANCH"),
|
|
help="Run git pull for both repositories")
|
|
parser.add_argument("-p", "--push", nargs="*", metavar=("REMOTE", "BRANCH"),
|
|
help="Run git push for both repositories")
|
|
parser.add_argument("--status", default=False, action="store_true",
|
|
help="Run git status for both repositories")
|
|
parser.add_argument("--checkout", nargs=1, metavar="BRANCH",
|
|
help="Run git checkout BRANCH for both repositories")
|
|
parser.add_argument("--git", nargs="*", metavar="OPTIONS",
|
|
help="Run git command for both repositories")
|
|
|
|
|
|
def setup_translation(parser):
|
|
parser.add_argument("--build_message_files", default=False, action="store_true",
|
|
help="Build message files for translation")
|
|
parser.add_argument("--export_messages", nargs=2, metavar=("LANG-CODE", "FILENAME"),
|
|
help="""Export all messages for a language to translation in a csv file.
|
|
Example, lib/wnf.py --export_messages hi hindi.csv""")
|
|
parser.add_argument("--import_messages", nargs=2, metavar=("LANG-CODE", "FILENAME"),
|
|
help="""Import messages for a language and make language files.
|
|
Example, lib/wnf.py --import_messages hi hindi.csv""")
|
|
parser.add_argument("--google_translate", nargs=3,
|
|
metavar=("LANG-CODE", "INFILE", "OUTFILE"),
|
|
help="Auto translate using Google Translate API")
|
|
parser.add_argument("--translate", nargs=1, metavar="LANG-CODE",
|
|
help="""Rebuild translation for the given langauge and
|
|
use Google Translate to tranlate untranslated messages. use "all" """)
|
|
|
|
# methods
|
|
|
|
# install
|
|
def _install(opts, args):
|
|
from webnotes.install_lib.install import Installer
|
|
inst = Installer('root', db_name=opts[0], site=args.site)
|
|
inst.install(*opts, verbose=1, force=args.force)
|
|
|
|
def install(opts, args):
|
|
_install(opts, args)
|
|
|
|
# install
|
|
def reinstall(opts, args):
|
|
webnotes.init(site=args.site)
|
|
_install([webnotes.conf.db_name], args)
|
|
|
|
def restore(opts, args):
|
|
_install(opts, args)
|
|
|
|
def install_fixtures(opts, args):
|
|
webnotes.init(site=args.site)
|
|
from webnotes.install_lib.install import install_fixtures
|
|
install_fixtures()
|
|
|
|
def make_demo(opts, args):
|
|
import utilities.demo.make_demo
|
|
webnotes.init(site=args.site)
|
|
utilities.demo.make_demo.make()
|
|
|
|
def make_demo_fresh(opts, args):
|
|
import utilities.demo.make_demo
|
|
webnotes.init(site=args.site)
|
|
utilities.demo.make_demo.make(reset=True)
|
|
|
|
# utilities
|
|
def update(opts, args):
|
|
pull(opts, args)
|
|
reload(webnotes)
|
|
latest(opts, args)
|
|
|
|
def latest(opts, args):
|
|
import webnotes.modules.patch_handler
|
|
import webnotes.model.sync
|
|
|
|
webnotes.connect(site=args.site)
|
|
|
|
# run patches
|
|
webnotes.modules.patch_handler.log_list = []
|
|
webnotes.modules.patch_handler.run_all()
|
|
print "\n".join(webnotes.modules.patch_handler.log_list)
|
|
|
|
# sync
|
|
webnotes.model.sync.sync_all()
|
|
|
|
# build
|
|
build(opts, args)
|
|
|
|
def sync_all(opts, args):
|
|
import webnotes.model.sync
|
|
webnotes.connect(site=args.site)
|
|
webnotes.model.sync.sync_all(force=args.force)
|
|
|
|
def patch(opts, args):
|
|
import webnotes.modules.patch_handler
|
|
webnotes.connect(site=args.site)
|
|
webnotes.modules.patch_handler.log_list = []
|
|
webnotes.modules.patch_handler.run_single(opts[0], force=args.force)
|
|
print "\n".join(webnotes.modules.patch_handler.log_list)
|
|
|
|
def reload_doc(opts, args):
|
|
webnotes.connect(site=args.site)
|
|
webnotes.reload_doc(opts[0], opts[1], opts[2], force=args.force)
|
|
|
|
def build(opts, args):
|
|
import webnotes.build
|
|
webnotes.build.bundle(False)
|
|
|
|
def watch(opts, args):
|
|
import webnotes.build
|
|
webnotes.build.watch(True)
|
|
|
|
def backup(opts, args):
|
|
from webnotes.utils.backups import scheduled_backup
|
|
webnotes.connect(site=args.site)
|
|
scheduled_backup(ignore_files=not args.with_files)
|
|
|
|
def docs(opts, args):
|
|
from core.doctype.documentation_tool.documentation_tool import write_static
|
|
write_static()
|
|
|
|
def domain(opts, args):
|
|
webnotes.connect(site=args.site)
|
|
if opts:
|
|
webnotes.conn.set_value("Website Settings", None, "subdomain", opts[0])
|
|
webnotes.conn.commit()
|
|
else:
|
|
print webnotes.conn.get_value("Website Settings", None, "subdomain")
|
|
|
|
def make_conf(opts, args):
|
|
from webnotes.install_lib.install import make_conf
|
|
make_conf(*opts, site=args.site)
|
|
|
|
# git
|
|
def git(opts, args=None):
|
|
cmd = opts
|
|
if isinstance(opts, (list, tuple)):
|
|
cmd = " ".join(opts)
|
|
import os
|
|
os.system("cd lib && git %s" % cmd)
|
|
os.system("cd app && git %s" % cmd)
|
|
|
|
def pull(opts, args=None):
|
|
if not opts:
|
|
webnotes.init(site=args.site)
|
|
opts = ("origin", webnotes.conf.branch or "master")
|
|
git(("pull", opts[0], opts[1]))
|
|
|
|
def push(opts, args=None):
|
|
if not opts:
|
|
webnotes.init(site=args.site)
|
|
opts = ("origin", webnotes.conf.branch or "master")
|
|
git(("push", opts[0], opts[1]))
|
|
|
|
def status(opts, args=None):
|
|
git("status")
|
|
|
|
def checkout(opts, args=None):
|
|
git(("checkout", opts[0]))
|
|
|
|
def replace_code(start, txt1, txt2, extn, search=None, force=False):
|
|
"""replace all txt1 by txt2 in files with extension (extn)"""
|
|
import webnotes.utils
|
|
import os, re
|
|
esc = webnotes.utils.make_esc('[]')
|
|
if not search: search = esc(txt1)
|
|
for wt in os.walk(start, followlinks=1):
|
|
for fn in wt[2]:
|
|
if fn.split('.')[-1]==extn:
|
|
fpath = os.path.join(wt[0], fn)
|
|
with open(fpath, 'r') as f:
|
|
content = f.read()
|
|
|
|
if re.search(search, content):
|
|
res = search_replace_with_prompt(fpath, txt1, txt2, force)
|
|
if res == 'skip':
|
|
return 'skip'
|
|
|
|
|
|
def search_replace_with_prompt(fpath, txt1, txt2, force=False):
|
|
""" Search and replace all txt1 by txt2 in the file with confirmation"""
|
|
from termcolor import colored
|
|
with open(fpath, 'r') as f:
|
|
content = f.readlines()
|
|
|
|
tmp = []
|
|
for c in content:
|
|
if c.find(txt1) != -1:
|
|
print fpath
|
|
print colored(txt1, 'red').join(c[:-1].split(txt1))
|
|
a = ''
|
|
if force:
|
|
c = c.replace(txt1, txt2)
|
|
else:
|
|
while a.lower() not in ['y', 'n', 'skip']:
|
|
a = raw_input('Do you want to Change [y/n/skip]?')
|
|
if a.lower() == 'y':
|
|
c = c.replace(txt1, txt2)
|
|
elif a.lower() == 'skip':
|
|
return 'skip'
|
|
tmp.append(c)
|
|
|
|
with open(fpath, 'w') as f:
|
|
f.write(''.join(tmp))
|
|
print colored('Updated', 'green')
|
|
|
|
if __name__=="__main__":
|
|
main() |