Nevar pievienot vairāk kā 25 tēmas Tēmai ir jāsākas ar burtu vai ciparu, tā var saturēt domu zīmes ('-') un var būt līdz 35 simboliem gara.

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