You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

11 vuotta sitten
11 vuotta sitten
11 vuotta sitten
11 vuotta sitten
11 vuotta sitten
11 vuotta sitten
11 vuotta sitten
11 vuotta sitten
11 vuotta sitten
11 vuotta sitten
11 vuotta sitten
11 vuotta sitten
11 vuotta sitten
11 vuotta sitten
11 vuotta sitten
11 vuotta sitten
11 vuotta sitten
11 vuotta sitten
11 vuotta sitten
11 vuotta sitten
11 vuotta sitten
11 vuotta sitten
11 vuotta sitten
11 vuotta sitten
11 vuotta sitten
11 vuotta sitten
11 vuotta sitten
11 vuotta sitten
11 vuotta sitten
11 vuotta sitten
11 vuotta sitten
11 vuotta sitten
11 vuotta sitten
11 vuotta sitten
11 vuotta sitten
11 vuotta sitten
11 vuotta sitten
11 vuotta sitten
11 vuotta sitten
11 vuotta sitten
11 vuotta sitten
13 vuotta sitten
11 vuotta sitten
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420
  1. #!/usr/bin/env python
  2. # Copyright (c) 2013, Web Notes Technologies Pvt. Ltd.
  3. # MIT License. See license.txt
  4. from __future__ import unicode_literals
  5. import sys
  6. if __name__=="__main__":
  7. sys.path = [".", "lib", "app"] + sys.path
  8. import webnotes
  9. def main():
  10. parsed_args = webnotes._dict(vars(setup_parser()))
  11. fn = get_function(parsed_args)
  12. if parsed_args.get("site")=="all":
  13. for site in get_sites():
  14. args = parsed_args.copy()
  15. args["site"] = site
  16. run(fn, args)
  17. else:
  18. run(fn, parsed_args)
  19. def run(fn, args):
  20. out = globals().get(fn)(args.get(fn), args)
  21. webnotes.destroy()
  22. return out
  23. def get_function(args):
  24. for fn, val in args.items():
  25. if (val or isinstance(val, list)) and globals().get(fn):
  26. return fn
  27. def get_sites():
  28. pass
  29. def setup_parser():
  30. import argparse
  31. parser = argparse.ArgumentParser(description="Run webnotes utility functions")
  32. setup_install(parser)
  33. setup_utilities(parser)
  34. setup_translation(parser)
  35. setup_git(parser)
  36. # common
  37. parser.add_argument("-f", "--force", default=False, action="store_true",
  38. help="Force execution where applicable (look for [-f] in help)")
  39. parser.add_argument("--site", nargs="?", metavar="SITE-NAME or all",
  40. help="Run for a particular site")
  41. return parser.parse_args()
  42. def setup_install(parser):
  43. parser.add_argument("--install", metavar="DB-NAME", nargs=1,
  44. help="Install a new app")
  45. parser.add_argument("--reinstall", default=False, action="store_true",
  46. help="Install a fresh app in db_name specified in conf.py")
  47. parser.add_argument("--restore", metavar=("DB-NAME", "SQL-FILE"), nargs=2,
  48. help="Restore from an sql file")
  49. parser.add_argument("--install_fixtures", default=False, action="store_true",
  50. help="(Re)Install install-fixtures from app/startup/install_fixtures")
  51. parser.add_argument("--make_demo", default=False, action="store_true",
  52. help="Install demo in demo_db_name specified in conf.py")
  53. parser.add_argument("--make_demo_fresh", default=False, action="store_true",
  54. help="(Re)Install demo in demo_db_name specified in conf.py")
  55. def setup_utilities(parser):
  56. # update
  57. parser.add_argument("-u", "--update", nargs="*", metavar=("REMOTE", "BRANCH"),
  58. help="Perform git pull, run patches, sync schema and rebuild files/translations")
  59. parser.add_argument("--patch", nargs=1, metavar="PATCH-MODULE",
  60. help="Run a particular patch [-f]")
  61. parser.add_argument("-l", "--latest", default=False, action="store_true",
  62. help="Run patches, sync schema and rebuild files/translations")
  63. parser.add_argument("--sync_all", default=False, action="store_true",
  64. help="Reload all doctypes, pages, etc. using txt files [-f]")
  65. parser.add_argument("--reload_doc", nargs=3,
  66. metavar=('"MODULE"', '"DOCTYPE"', '"DOCNAME"'))
  67. # build
  68. parser.add_argument("-b", "--build", default=False, action="store_true",
  69. help="Minify + concatenate JS and CSS files, build translations")
  70. parser.add_argument("-w", "--watch", default=False, action="store_true",
  71. help="Watch and concatenate JS and CSS files as and when they change")
  72. # misc
  73. parser.add_argument("--backup", default=False, action="store_true",
  74. help="Take backup of database in backup folder [--with_files]")
  75. parser.add_argument("--with_files", default=False, action="store_true",
  76. help="Also take backup of files")
  77. parser.add_argument("--docs", default=False, action="store_true",
  78. help="Build docs")
  79. parser.add_argument("--domain", nargs="*",
  80. help="Get or set domain in Website Settings")
  81. parser.add_argument("--make_conf", nargs="*", metavar=("DB-NAME", "DB-PASSWORD"),
  82. help="Create new conf.py file")
  83. # clear
  84. parser.add_argument("--clear_web", default=False, action="store_true",
  85. help="Clear website cache")
  86. parser.add_argument("--clear_cache", default=False, action="store_true",
  87. help="Clear cache, doctype cache and defaults")
  88. parser.add_argument("--reset_perms", default=False, action="store_true",
  89. help="Reset permissions for all doctypes")
  90. # scheduler
  91. parser.add_argument("--run_scheduler", default=False, action="store_true",
  92. help="Trigger scheduler")
  93. parser.add_argument("--run_scheduler_event", nargs=1,
  94. metavar="all | daily | weekly | monthly",
  95. help="Run a scheduler event")
  96. # replace
  97. parser.add_argument("--replace", nargs=3,
  98. metavar=("SEARCH-REGEX", "REPLACE-BY", "FILE-EXTN"),
  99. help="Multi-file search-replace [-f]")
  100. # import/export
  101. parser.add_argument("--export_doc", nargs=2, metavar=('"DOCTYPE"', '"DOCNAME"'))
  102. parser.add_argument("--export_doclist", nargs=3, metavar=("DOCTYPE", "NAME", "PATH"),
  103. help="""Export doclist as json to the given path, use '-' as name for Singles.""")
  104. parser.add_argument("--export_csv", nargs=2, metavar=("DOCTYPE", "PATH"),
  105. help="""Dump DocType as csv""")
  106. parser.add_argument("--import_doclist", nargs=1, metavar="PATH",
  107. help="""Import (insert/update) doclist. If the argument is a directory, all files ending with .json are imported""")
  108. def setup_git(parser):
  109. parser.add_argument("--pull", nargs="*", metavar=("REMOTE", "BRANCH"),
  110. help="Run git pull for both repositories")
  111. parser.add_argument("-p", "--push", nargs="*", metavar=("REMOTE", "BRANCH"),
  112. help="Run git push for both repositories")
  113. parser.add_argument("--status", default=False, action="store_true",
  114. help="Run git status for both repositories")
  115. parser.add_argument("--commit", nargs=1, metavar="COMMIT-MSG",
  116. help="Run git commit COMMIT-MSG for both repositories")
  117. parser.add_argument("--checkout", nargs=1, metavar="BRANCH",
  118. help="Run git checkout BRANCH for both repositories")
  119. parser.add_argument("--git", nargs="*", metavar="OPTIONS",
  120. help="Run git command for both repositories")
  121. def setup_translation(parser):
  122. parser.add_argument("--build_message_files", default=False, action="store_true",
  123. help="Build message files for translation")
  124. parser.add_argument("--export_messages", nargs=2, metavar=("LANG-CODE", "FILENAME"),
  125. help="""Export all messages for a language to translation in a csv file.
  126. Example, lib/wnf.py --export_messages hi hindi.csv""")
  127. parser.add_argument("--import_messages", nargs=2, metavar=("LANG-CODE", "FILENAME"),
  128. help="""Import messages for a language and make language files.
  129. Example, lib/wnf.py --import_messages hi hindi.csv""")
  130. parser.add_argument("--google_translate", nargs=3,
  131. metavar=("LANG-CODE", "INFILE", "OUTFILE"),
  132. help="Auto translate using Google Translate API")
  133. parser.add_argument("--translate", nargs=1, metavar="LANG-CODE",
  134. help="""Rebuild translation for the given langauge and
  135. use Google Translate to tranlate untranslated messages. use "all" """)
  136. # methods
  137. # install
  138. def _install(val, args):
  139. from webnotes.install_lib.install import Installer
  140. inst = Installer('root', db_name=val[0], site=args.site)
  141. inst.install(*val, verbose=1, force=args.force)
  142. def install(val, args):
  143. _install(val, args)
  144. # install
  145. def reinstall(val, args):
  146. webnotes.init(site=args.site)
  147. _install([webnotes.conf.db_name], args)
  148. def restore(val, args):
  149. _install(val, args)
  150. def install_fixtures(val, args):
  151. webnotes.init(site=args.site)
  152. from webnotes.install_lib.install import install_fixtures
  153. install_fixtures()
  154. def make_demo(val, args):
  155. import utilities.demo.make_demo
  156. webnotes.init(site=args.site)
  157. utilities.demo.make_demo.make()
  158. def make_demo_fresh(val, args):
  159. import utilities.demo.make_demo
  160. webnotes.init(site=args.site)
  161. utilities.demo.make_demo.make(reset=True)
  162. # utilities
  163. def update(val, args):
  164. pull(val, args)
  165. reload(webnotes)
  166. latest(val, args)
  167. def latest(val, args):
  168. import webnotes.modules.patch_handler
  169. import webnotes.model.sync
  170. webnotes.connect(site=args.site)
  171. # run patches
  172. webnotes.modules.patch_handler.log_list = []
  173. webnotes.modules.patch_handler.run_all()
  174. print "\n".join(webnotes.modules.patch_handler.log_list)
  175. # sync
  176. webnotes.model.sync.sync_all()
  177. # build
  178. build(val, args)
  179. def sync_all(val, args):
  180. import webnotes.model.sync
  181. webnotes.connect(site=args.site)
  182. webnotes.model.sync.sync_all(force=args.force)
  183. def patch(val, args):
  184. import webnotes.modules.patch_handler
  185. webnotes.connect(site=args.site)
  186. webnotes.modules.patch_handler.log_list = []
  187. webnotes.modules.patch_handler.run_single(val[0], force=args.force)
  188. print "\n".join(webnotes.modules.patch_handler.log_list)
  189. def reload_doc(val, args):
  190. webnotes.connect(site=args.site)
  191. webnotes.reload_doc(val[0], val[1], val[2], force=args.force)
  192. def build(val, args):
  193. import webnotes.build
  194. webnotes.build.bundle(False)
  195. def watch(val, args):
  196. import webnotes.build
  197. webnotes.build.watch(True)
  198. def backup(val, args):
  199. from webnotes.utils.backups import scheduled_backup
  200. webnotes.connect(site=args.site)
  201. scheduled_backup(ignore_files=not args.with_files)
  202. def docs(val, args):
  203. from core.doctype.documentation_tool.documentation_tool import write_static
  204. write_static()
  205. def domain(val, args):
  206. webnotes.connect(site=args.site)
  207. if val:
  208. webnotes.conn.set_value("Website Settings", None, "subdomain", val[0])
  209. webnotes.conn.commit()
  210. else:
  211. print webnotes.conn.get_value("Website Settings", None, "subdomain")
  212. def make_conf(val, args):
  213. from webnotes.install_lib.install import make_conf
  214. make_conf(*val, site=args.site)
  215. # clear
  216. def clear_cache(val, args):
  217. import webnotes.sessions
  218. webnotes.connect(site=args.site)
  219. webnotes.sessions.clear_cache()
  220. def clear_web(val, args):
  221. import webnotes.webutils
  222. webnotes.connect(site=args.site)
  223. webnotes.webutils.clear_cache()
  224. def reset_perms(val, args):
  225. webnotes.connect(site=args.site)
  226. for d in webnotes.conn.sql_list("""select name from `tabDocType`
  227. where ifnull(istable, 0)=0 and ifnull(custom, 0)=0"""):
  228. webnotes.clear_cache(doctype=d)
  229. webnotes.reset_perms(d)
  230. # scheduler
  231. def run_scheduler(val, args):
  232. import webnotes.utils.scheduler
  233. webnotes.connect(site=args.site)
  234. print webnotes.utils.scheduler.execute()
  235. def run_scheduler_event(val, args):
  236. import webnotes.utils.scheduler
  237. webnotes.connect(site=args.site)
  238. print webnotes.utils.scheduler.trigger("execute_" + val[0])
  239. # replace
  240. def replace(val, args):
  241. print val
  242. replace_code('.', *val, force=args.force)
  243. # import/export
  244. def export_doc(val, args):
  245. import webnotes.modules
  246. webnotes.connect(site=args.site)
  247. webnotes.modules.export_doc(*val)
  248. def export_doclist(val, args):
  249. from core.page.data_import_tool import data_import_tool
  250. webnotes.connect(site=args.site)
  251. data_import_tool.export_json(*val)
  252. def export_csv(val, args):
  253. from core.page.data_import_tool import data_import_tool
  254. webnotes.connect(site=args.site)
  255. data_import_tool.export_csv(*val)
  256. def import_doclist(val, args):
  257. from core.page.data_import_tool import data_import_tool
  258. webnotes.connect(site=args.site)
  259. data_import_tool.import_doclist(*val)
  260. # translation
  261. def build_message_files(val, args):
  262. import webnotes.translate
  263. webnotes.connect(site=args.site)
  264. webnotes.translate.build_message_files()
  265. def export_messages(val, args):
  266. import webnotes.translate
  267. webnotes.connect(site=args.site)
  268. webnotes.translate.export_messages(*val)
  269. def import_messages(val, args):
  270. import webnotes.translate
  271. webnotes.connect(site=args.site)
  272. webnotes.translate.import_messages(*val)
  273. def google_translate(val, args):
  274. import webnotes.translate
  275. webnotes.connect(site=args.site)
  276. webnotes.translate.google_translate(*val)
  277. def translate(val, args):
  278. import webnotes.translate
  279. webnotes.connect(site=args.site)
  280. webnotes.translate.translate(*val)
  281. # git
  282. def git(val, args=None):
  283. cmd = val
  284. if isinstance(val, (list, tuple)):
  285. cmd = " ".join(val)
  286. import os
  287. os.system("""cd lib && git %s""" % cmd)
  288. os.system("""cd app && git %s""" % cmd)
  289. def pull(val, args=None):
  290. if not val:
  291. webnotes.init(site=args.site)
  292. val = ("origin", webnotes.conf.branch or "master")
  293. git(("pull", val[0], val[1]))
  294. def push(val, args=None):
  295. if not val:
  296. webnotes.init(site=args.site)
  297. val = ("origin", webnotes.conf.branch or "master")
  298. git(("push", val[0], val[1]))
  299. def status(val, args=None):
  300. git("status")
  301. def commit(val, args=None):
  302. git("""commit -a -m "%s" """ % val[0].replace('"', '\"'))
  303. def checkout(val, args=None):
  304. git(("checkout", val[0]))
  305. def replace_code(start, txt1, txt2, extn, search=None, force=False):
  306. """replace all txt1 by txt2 in files with extension (extn)"""
  307. import webnotes.utils
  308. import os, re
  309. esc = webnotes.utils.make_esc('[]')
  310. if not search: search = esc(txt1)
  311. for wt in os.walk(start, followlinks=1):
  312. for fn in wt[2]:
  313. if fn.split('.')[-1]==extn:
  314. fpath = os.path.join(wt[0], fn)
  315. with open(fpath, 'r') as f:
  316. content = f.read()
  317. if re.search(search, content):
  318. res = search_replace_with_prompt(fpath, txt1, txt2, force)
  319. if res == 'skip':
  320. return 'skip'
  321. def search_replace_with_prompt(fpath, txt1, txt2, force=False):
  322. """ Search and replace all txt1 by txt2 in the file with confirmation"""
  323. from termcolor import colored
  324. with open(fpath, 'r') as f:
  325. content = f.readlines()
  326. tmp = []
  327. for c in content:
  328. if c.find(txt1) != -1:
  329. print fpath
  330. print colored(txt1, 'red').join(c[:-1].split(txt1))
  331. a = ''
  332. if force:
  333. c = c.replace(txt1, txt2)
  334. else:
  335. while a.lower() not in ['y', 'n', 'skip']:
  336. a = raw_input('Do you want to Change [y/n/skip]?')
  337. if a.lower() == 'y':
  338. c = c.replace(txt1, txt2)
  339. elif a.lower() == 'skip':
  340. return 'skip'
  341. tmp.append(c)
  342. with open(fpath, 'w') as f:
  343. f.write(''.join(tmp))
  344. print colored('Updated', 'green')
  345. if __name__=="__main__":
  346. main()