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 11 gadiem
pirms 11 gadiem
pirms 11 gadiem
pirms 11 gadiem
pirms 11 gadiem
pirms 11 gadiem
pirms 11 gadiem
pirms 11 gadiem
pirms 11 gadiem
pirms 11 gadiem
pirms 11 gadiem
pirms 11 gadiem
pirms 11 gadiem
pirms 11 gadiem
pirms 11 gadiem
pirms 11 gadiem
pirms 11 gadiem
pirms 11 gadiem
pirms 11 gadiem
pirms 11 gadiem
pirms 11 gadiem
pirms 11 gadiem
pirms 11 gadiem
pirms 11 gadiem
pirms 11 gadiem
pirms 11 gadiem
pirms 11 gadiem
pirms 11 gadiem
pirms 11 gadiem
pirms 11 gadiem
pirms 11 gadiem
pirms 11 gadiem
pirms 11 gadiem
pirms 11 gadiem
pirms 11 gadiem
pirms 11 gadiem
pirms 11 gadiem
pirms 13 gadiem
pirms 11 gadiem
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623
  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 cmd(fn):
  20. def new_fn(*args, **kwargs):
  21. import inspect
  22. fnargs, varargs, varkw, defaults = inspect.getargspec(fn)
  23. new_kwargs = {}
  24. for a in fnargs:
  25. if a in kwargs:
  26. new_kwargs[a] = kwargs.get(a)
  27. return fn(*args, **new_kwargs)
  28. return new_fn
  29. def run(fn, args):
  30. if isinstance(args.get(fn), (list, tuple)):
  31. out = globals().get(fn)(*args.get(fn), **args)
  32. else:
  33. out = globals().get(fn)(**args)
  34. return out
  35. def get_function(args):
  36. for fn, val in args.items():
  37. if (val or isinstance(val, list)) and globals().get(fn):
  38. return fn
  39. def get_sites():
  40. import os
  41. import conf
  42. return [site for site in os.listdir(conf.sites_dir)
  43. if not os.path.islink(os.path.join(conf.sites_dir, site))]
  44. def setup_parser():
  45. import argparse
  46. parser = argparse.ArgumentParser(description="Run webnotes utility functions")
  47. setup_install(parser)
  48. setup_utilities(parser)
  49. setup_translation(parser)
  50. setup_git(parser)
  51. # common
  52. parser.add_argument("-f", "--force", default=False, action="store_true",
  53. help="Force execution where applicable (look for [-f] in help)")
  54. parser.add_argument("--quiet", default=True, action="store_false", dest="verbose",
  55. help="Show verbose output where applicable")
  56. parser.add_argument("--site", nargs="?", metavar="SITE-NAME or all",
  57. help="Run for a particular site")
  58. return parser.parse_args()
  59. def setup_install(parser):
  60. parser.add_argument("--install", metavar="DB-NAME", nargs=1,
  61. help="Install a new app")
  62. parser.add_argument("--root-password", nargs=1,
  63. help="Root password for new app")
  64. parser.add_argument("--reinstall", default=False, action="store_true",
  65. help="Install a fresh app in db_name specified in conf.py")
  66. parser.add_argument("--restore", metavar=("DB-NAME", "SQL-FILE"), nargs=2,
  67. help="Restore from an sql file")
  68. parser.add_argument("--install_fixtures", default=False, action="store_true",
  69. help="(Re)Install install-fixtures from app/startup/install_fixtures")
  70. parser.add_argument("--make_demo", default=False, action="store_true",
  71. help="Install demo in demo_db_name specified in conf.py")
  72. parser.add_argument("--make_demo_fresh", default=False, action="store_true",
  73. help="(Re)Install demo in demo_db_name specified in conf.py")
  74. parser.add_argument("--add_system_manager", nargs="+",
  75. metavar=("EMAIL", "[FIRST-NAME] [LAST-NAME]"), help="Add a user with all roles")
  76. def setup_utilities(parser):
  77. # update
  78. parser.add_argument("-u", "--update", nargs="*", metavar=("REMOTE", "BRANCH"),
  79. help="Perform git pull, run patches, sync schema and rebuild files/translations")
  80. parser.add_argument("--patch", nargs=1, metavar="PATCH-MODULE",
  81. help="Run a particular patch [-f]")
  82. parser.add_argument("-l", "--latest", default=False, action="store_true",
  83. help="Run patches, sync schema and rebuild files/translations")
  84. parser.add_argument("--sync_all", default=False, action="store_true",
  85. help="Reload all doctypes, pages, etc. using txt files [-f]")
  86. parser.add_argument("--update_all_sites", nargs="*", metavar=("REMOTE", "BRANCH"),
  87. help="Perform git pull, run patches, sync schema and rebuild files/translations")
  88. parser.add_argument("--reload_doc", nargs=3,
  89. metavar=('"MODULE"', '"DOCTYPE"', '"DOCNAME"'))
  90. # build
  91. parser.add_argument("-b", "--build", default=False, action="store_true",
  92. help="Minify + concatenate JS and CSS files, build translations")
  93. parser.add_argument("-w", "--watch", default=False, action="store_true",
  94. help="Watch and concatenate JS and CSS files as and when they change")
  95. # misc
  96. parser.add_argument("--backup", default=False, action="store_true",
  97. help="Take backup of database in backup folder [--with_files]")
  98. parser.add_argument("--move", default=False, action="store_true",
  99. help="Move site to different directory defined by --dest_dir")
  100. parser.add_argument("--dest_dir", nargs=1, metavar="DEST-DIR",
  101. help="Move site to different directory")
  102. parser.add_argument("--with_files", default=False, action="store_true",
  103. help="Also take backup of files")
  104. parser.add_argument("--docs", default=False, action="store_true",
  105. help="Build docs")
  106. parser.add_argument("--domain", nargs="*",
  107. help="Get or set domain in Website Settings")
  108. parser.add_argument("--make_conf", nargs="*", metavar=("DB-NAME", "DB-PASSWORD"),
  109. help="Create new conf.py file")
  110. parser.add_argument("--make_custom_server_script", nargs=1, metavar="DOCTYPE",
  111. help="Create new conf.py file")
  112. parser.add_argument("--set_admin_password", metavar='ADMIN-PASSWORD', nargs=1,
  113. help="Set administrator password")
  114. parser.add_argument("--mysql", action="store_true", help="get mysql shell for a site")
  115. parser.add_argument("--serve", action="store_true", help="Run development server")
  116. parser.add_argument("--get_site_details", action="store_true", help="Get site details")
  117. parser.add_argument("--port", default=8000, type=int, help="port for development server")
  118. # clear
  119. parser.add_argument("--clear_web", default=False, action="store_true",
  120. help="Clear website cache")
  121. parser.add_argument("--clear_cache", default=False, action="store_true",
  122. help="Clear cache, doctype cache and defaults")
  123. parser.add_argument("--reset_perms", default=False, action="store_true",
  124. help="Reset permissions for all doctypes")
  125. # scheduler
  126. parser.add_argument("--run_scheduler", default=False, action="store_true",
  127. help="Trigger scheduler")
  128. parser.add_argument("--run_scheduler_event", nargs=1,
  129. metavar="all | daily | weekly | monthly",
  130. help="Run a scheduler event")
  131. # replace
  132. parser.add_argument("--replace", nargs=3,
  133. metavar=("SEARCH-REGEX", "REPLACE-BY", "FILE-EXTN"),
  134. help="Multi-file search-replace [-f]")
  135. # import/export
  136. parser.add_argument("--export_doc", nargs=2, metavar=('"DOCTYPE"', '"DOCNAME"'))
  137. parser.add_argument("--export_doclist", nargs=3, metavar=("DOCTYPE", "NAME", "PATH"),
  138. help="""Export doclist as json to the given path, use '-' as name for Singles.""")
  139. parser.add_argument("--export_csv", nargs=2, metavar=("DOCTYPE", "PATH"),
  140. help="""Dump DocType as csv""")
  141. parser.add_argument("--import_doclist", nargs=1, metavar="PATH",
  142. help="""Import (insert/update) doclist. If the argument is a directory, all files ending with .json are imported""")
  143. def setup_git(parser):
  144. parser.add_argument("--pull", nargs="*", metavar=("REMOTE", "BRANCH"),
  145. help="Run git pull for both repositories")
  146. parser.add_argument("-p", "--push", nargs="*", metavar=("REMOTE", "BRANCH"),
  147. help="Run git push for both repositories")
  148. parser.add_argument("--status", default=False, action="store_true",
  149. help="Run git status for both repositories")
  150. parser.add_argument("--commit", nargs=1, metavar="COMMIT-MSG",
  151. help="Run git commit COMMIT-MSG for both repositories")
  152. parser.add_argument("--checkout", nargs=1, metavar="BRANCH",
  153. help="Run git checkout BRANCH for both repositories")
  154. parser.add_argument("--git", nargs="*", metavar="OPTIONS",
  155. help="Run git command for both repositories")
  156. def setup_translation(parser):
  157. parser.add_argument("--build_message_files", default=False, action="store_true",
  158. help="Build message files for translation")
  159. parser.add_argument("--export_messages", nargs=2, metavar=("LANG-CODE", "FILENAME"),
  160. help="""Export all messages for a language to translation in a csv file.
  161. Example, lib/wnf.py --export_messages hi hindi.csv""")
  162. parser.add_argument("--import_messages", nargs=2, metavar=("LANG-CODE", "FILENAME"),
  163. help="""Import messages for a language and make language files.
  164. Example, lib/wnf.py --import_messages hi hindi.csv""")
  165. parser.add_argument("--google_translate", nargs=3,
  166. metavar=("LANG-CODE", "INFILE", "OUTFILE"),
  167. help="Auto translate using Google Translate API")
  168. parser.add_argument("--translate", nargs=1, metavar="LANG-CODE",
  169. help="""Rebuild translation for the given langauge and
  170. use Google Translate to tranlate untranslated messages. use "all" """)
  171. # methods
  172. # install
  173. @cmd
  174. def install(db_name, source_sql=None, site=None, verbose=True, force=False, root_password=None, site_config=None, admin_password='admin'):
  175. from webnotes.install_lib.install import Installer
  176. inst = Installer('root', db_name=db_name, site=site, root_password=root_password, site_config=site_config)
  177. inst.install(db_name, source_sql=source_sql, verbose=verbose, force=force, admin_password=admin_password)
  178. webnotes.destroy()
  179. @cmd
  180. def reinstall(site=None, verbose=True):
  181. webnotes.init(site=site)
  182. install(webnotes.conf.db_name, site=site, verbose=verbose, force=True)
  183. @cmd
  184. def restore(db_name, source_sql, site=None, verbose=True, force=False):
  185. install(db_name, source_sql, site=site, verbose=verbose, force=force)
  186. @cmd
  187. def install_fixtures(site=None):
  188. webnotes.init(site=site)
  189. from webnotes.install_lib.install import install_fixtures
  190. install_fixtures()
  191. webnotes.destroy()
  192. @cmd
  193. def add_system_manager(email, first_name=None, last_name=None, site=None):
  194. webnotes.connect(site=site)
  195. webnotes.profile.add_system_manager(email, first_name, last_name)
  196. webnotes.conn.commit()
  197. webnotes.destroy()
  198. @cmd
  199. def make_demo(site=None):
  200. import utilities.demo.make_demo
  201. webnotes.init(site=site)
  202. utilities.demo.make_demo.make()
  203. webnotes.destroy()
  204. @cmd
  205. def make_demo_fresh(site=None):
  206. import utilities.demo.make_demo
  207. webnotes.init(site=site)
  208. utilities.demo.make_demo.make(reset=True)
  209. webnotes.destroy()
  210. # utilities
  211. @cmd
  212. def update(remote=None, branch=None, site=None):
  213. pull(remote=remote, branch=branch, site=site)
  214. # maybe there are new framework changes, any consequences?
  215. reload(webnotes)
  216. latest(site=site)
  217. @cmd
  218. def latest(site=None, verbose=True):
  219. import webnotes.modules.patch_handler
  220. import webnotes.model.sync
  221. webnotes.connect(site=site)
  222. try:
  223. # run patches
  224. webnotes.local.patch_log_list = []
  225. webnotes.modules.patch_handler.run_all()
  226. if verbose:
  227. print "\n".join(webnotes.local.patch_log_list)
  228. # sync
  229. webnotes.model.sync.sync_all()
  230. except webnotes.modules.patch_handler.PatchError, e:
  231. print "\n".join(webnotes.local.patch_log_list)
  232. raise e
  233. finally:
  234. webnotes.destroy()
  235. @cmd
  236. def sync_all(site=None, force=False):
  237. import webnotes.model.sync
  238. webnotes.connect(site=site)
  239. webnotes.model.sync.sync_all(force=force)
  240. webnotes.destroy()
  241. @cmd
  242. def patch(patch_module, site=None, force=False):
  243. import webnotes.modules.patch_handler
  244. webnotes.connect(site=site)
  245. webnotes.local.patch_log_list = []
  246. webnotes.modules.patch_handler.run_single(patch_module, force=force)
  247. print "\n".join(webnotes.local.patch_log_list)
  248. webnotes.destroy()
  249. @cmd
  250. def update_all_sites(remote=None, branch=None, verbose=True):
  251. pull(remote, branch)
  252. build()
  253. for site in get_sites():
  254. latest(site=site, verbose=verbose)
  255. @cmd
  256. def reload_doc(module, doctype, docname, site=None, force=False):
  257. webnotes.connect(site=site)
  258. webnotes.reload_doc(module, doctype, docname, force=force)
  259. webnotes.destroy()
  260. @cmd
  261. def build():
  262. import webnotes.build
  263. webnotes.build.bundle(False)
  264. @cmd
  265. def watch():
  266. import webnotes.build
  267. webnotes.build.watch(True)
  268. @cmd
  269. def backup(site=None, with_files=False, verbose=True, backup_path_db=None, backup_path_files=None):
  270. from webnotes.utils.backups import scheduled_backup
  271. webnotes.connect(site=site)
  272. print backup_path_db
  273. odb = scheduled_backup(ignore_files=not with_files, backup_path_db=backup_path_db, backup_path_files=backup_path_files)
  274. if verbose:
  275. from webnotes.utils import now
  276. print "backup taken -", odb.backup_path_db, "- on", now()
  277. return odb
  278. @cmd
  279. def move(site=None, dest_dir=None):
  280. import os
  281. if not dest_dir:
  282. raise Exception, "--dest_dir is required for --move"
  283. dest_dir = dest_dir[0]
  284. if not os.path.isdir(dest_dir):
  285. raise Exception, "destination is not a directory or does not exist"
  286. webnotes.init(site=site)
  287. old_path = webnotes.utils.get_site_path()
  288. new_path = os.path.join(dest_dir, site)
  289. # check if site dump of same name already exists
  290. site_dump_exists = True
  291. count = 0
  292. while site_dump_exists:
  293. final_new_path = new_path + (count and str(count) or "")
  294. site_dump_exists = os.path.exists(final_new_path)
  295. count = int(count or 0) + 1
  296. os.rename(old_path, final_new_path)
  297. webnotes.destroy()
  298. return os.path.basename(final_new_path)
  299. @cmd
  300. def docs():
  301. from core.doctype.documentation_tool.documentation_tool import write_static
  302. write_static()
  303. @cmd
  304. def domain(host_url=None, site=None):
  305. webnotes.connect(site=site)
  306. if host_url:
  307. webnotes.conn.set_value("Website Settings", None, "subdomain", host_url)
  308. webnotes.conn.commit()
  309. else:
  310. print webnotes.conn.get_value("Website Settings", None, "subdomain")
  311. webnotes.destroy()
  312. @cmd
  313. def make_conf(db_name=None, db_password=None, site=None, site_config=None):
  314. from webnotes.install_lib.install import make_conf
  315. make_conf(db_name=db_name, db_password=db_password, site=site, site_config=site_config)
  316. @cmd
  317. def make_custom_server_script(doctype, site=None):
  318. from core.doctype.custom_script.custom_script import make_custom_server_script_file
  319. webnotes.connect(site=site)
  320. make_custom_server_script_file(doctype)
  321. webnotes.destroy()
  322. # clear
  323. @cmd
  324. def clear_cache(site=None):
  325. import webnotes.sessions
  326. webnotes.connect(site=site)
  327. webnotes.sessions.clear_cache()
  328. webnotes.destroy()
  329. @cmd
  330. def clear_web(site=None):
  331. import webnotes.webutils
  332. webnotes.connect(site=site)
  333. webnotes.webutils.clear_cache()
  334. webnotes.destroy()
  335. @cmd
  336. def reset_perms(site=None):
  337. webnotes.connect(site=site)
  338. for d in webnotes.conn.sql_list("""select name from `tabDocType`
  339. where ifnull(istable, 0)=0 and ifnull(custom, 0)=0"""):
  340. webnotes.clear_cache(doctype=d)
  341. webnotes.reset_perms(d)
  342. webnotes.destroy()
  343. # scheduler
  344. @cmd
  345. def run_scheduler(site=None):
  346. import webnotes.utils.scheduler
  347. webnotes.connect(site=site)
  348. print webnotes.utils.scheduler.execute()
  349. webnotes.destroy()
  350. @cmd
  351. def run_scheduler_event(event, site=None):
  352. import webnotes.utils.scheduler
  353. webnotes.connect(site=site)
  354. print webnotes.utils.scheduler.trigger("execute_" + event)
  355. webnotes.destroy()
  356. # replace
  357. @cmd
  358. def replace(search_regex, replacement, extn, force=False):
  359. print search_regex, replacement, extn
  360. replace_code('.', search_regex, replacement, extn, force=force)
  361. # import/export
  362. @cmd
  363. def export_doc(doctype, docname, site=None):
  364. import webnotes.modules
  365. webnotes.connect(site=site)
  366. webnotes.modules.export_doc(doctype, docname)
  367. webnotes.destroy()
  368. @cmd
  369. def export_doclist(doctype, name, path, site=None):
  370. from core.page.data_import_tool import data_import_tool
  371. webnotes.connect(site=site)
  372. data_import_tool.export_json(doctype, name, path)
  373. webnotes.destroy()
  374. @cmd
  375. def export_csv(doctype, path, site=None):
  376. from core.page.data_import_tool import data_import_tool
  377. webnotes.connect(site=site)
  378. data_import_tool.export_csv(doctype, path)
  379. webnotes.destroy()
  380. @cmd
  381. def import_doclist(path, site=None):
  382. from core.page.data_import_tool import data_import_tool
  383. webnotes.connect(site=site)
  384. data_import_tool.import_doclist(path)
  385. webnotes.destroy()
  386. # translation
  387. @cmd
  388. def build_message_files(site=None):
  389. import webnotes.translate
  390. webnotes.connect(site=site)
  391. webnotes.translate.build_message_files()
  392. webnotes.destroy()
  393. @cmd
  394. def export_messages(lang, outfile, site=None):
  395. import webnotes.translate
  396. webnotes.connect(site=site)
  397. webnotes.translate.export_messages(lang, outfile)
  398. webnotes.destroy()
  399. @cmd
  400. def import_messages(lang, infile, site=None):
  401. import webnotes.translate
  402. webnotes.connect(site=site)
  403. webnotes.translate.import_messages(lang, infile)
  404. webnotes.destroy()
  405. @cmd
  406. def google_translate(lang, infile, outfile, site=None):
  407. import webnotes.translate
  408. webnotes.connect(site=site)
  409. webnotes.translate.google_translate(lang, infile, outfile)
  410. webnotes.destroy()
  411. @cmd
  412. def translate(lang, site=None):
  413. import webnotes.translate
  414. webnotes.connect(site=site)
  415. webnotes.translate.translate(lang)
  416. webnotes.destroy()
  417. # git
  418. @cmd
  419. def git(param):
  420. if isinstance(param, (list, tuple)):
  421. param = " ".join(param)
  422. import os
  423. os.system("""cd lib && git %s""" % param)
  424. os.system("""cd app && git %s""" % param)
  425. def get_remote_and_branch(remote=None, branch=None):
  426. if not (remote and branch):
  427. webnotes.init()
  428. if not webnotes.conf.branch:
  429. raise Exception("Please specify remote and branch")
  430. remote = remote or "origin"
  431. branch = branch or webnotes.conf.branch
  432. webnotes.destroy()
  433. return remote, branch
  434. @cmd
  435. def pull(remote=None, branch=None):
  436. remote, branch = get_remote_and_branch(remote, branch)
  437. git(("pull", remote, branch))
  438. @cmd
  439. def push(remote=None, branch=None):
  440. remote, branch = get_remote_and_branch(remote, branch)
  441. git(("push", remote, branch))
  442. @cmd
  443. def status():
  444. git("status")
  445. @cmd
  446. def commit(message):
  447. git("""commit -a -m "%s" """ % message.replace('"', '\"'))
  448. @cmd
  449. def checkout(branch):
  450. git(("checkout", branch))
  451. @cmd
  452. def set_admin_password(admin_password, site=None):
  453. import webnotes
  454. webnotes.connect(site=site)
  455. webnotes.conn.sql("""update __Auth set `password`=password(%s)
  456. where user='Administrator'""", (admin_password,))
  457. webnotes.conn.commit()
  458. webnotes.destroy()
  459. @cmd
  460. def mysql(site=None):
  461. import webnotes
  462. import commands, os
  463. msq = commands.getoutput('which mysql')
  464. webnotes.init(site=site)
  465. os.execv(msq, [msq, '-u', webnotes.conf.db_name, '-p'+webnotes.conf.db_password, webnotes.conf.db_name])
  466. webnotes.destroy()
  467. @cmd
  468. def serve(port=8000):
  469. import webnotes.app
  470. webnotes.app.serve(port=port)
  471. def replace_code(start, txt1, txt2, extn, search=None, force=False):
  472. """replace all txt1 by txt2 in files with extension (extn)"""
  473. import webnotes.utils
  474. import os, re
  475. esc = webnotes.utils.make_esc('[]')
  476. if not search: search = esc(txt1)
  477. for wt in os.walk(start, followlinks=1):
  478. for fn in wt[2]:
  479. if fn.split('.')[-1]==extn:
  480. fpath = os.path.join(wt[0], fn)
  481. with open(fpath, 'r') as f:
  482. content = f.read()
  483. if re.search(search, content):
  484. res = search_replace_with_prompt(fpath, txt1, txt2, force)
  485. if res == 'skip':
  486. return 'skip'
  487. def search_replace_with_prompt(fpath, txt1, txt2, force=False):
  488. """ Search and replace all txt1 by txt2 in the file with confirmation"""
  489. from termcolor import colored
  490. with open(fpath, 'r') as f:
  491. content = f.readlines()
  492. tmp = []
  493. for c in content:
  494. if c.find(txt1) != -1:
  495. print fpath
  496. print colored(txt1, 'red').join(c[:-1].split(txt1))
  497. a = ''
  498. if force:
  499. c = c.replace(txt1, txt2)
  500. else:
  501. while a.lower() not in ['y', 'n', 'skip']:
  502. a = raw_input('Do you want to Change [y/n/skip]?')
  503. if a.lower() == 'y':
  504. c = c.replace(txt1, txt2)
  505. elif a.lower() == 'skip':
  506. return 'skip'
  507. tmp.append(c)
  508. with open(fpath, 'w') as f:
  509. f.write(''.join(tmp))
  510. print colored('Updated', 'green')
  511. @cmd
  512. def get_site_details(site=None, verbose=False):
  513. import webnotes
  514. from webnotes.profile import get_system_managers
  515. from core.doctype.profile.profile import get_total_users, get_active_users
  516. import json
  517. webnotes.connect(site=site)
  518. ret = {
  519. 'last_backup_on': webnotes.local.conf.last_backup_on,
  520. 'active_users': get_active_users(),
  521. 'total_users': get_total_users(),
  522. 'system_managers': get_system_managers()
  523. }
  524. webnotes.destroy()
  525. if verbose:
  526. print json.dumps(ret, indent=4)
  527. return ret
  528. if __name__=="__main__":
  529. main()