A Python robot that edits Wikipedia and interacts with people over IRC https://en.wikipedia.org/wiki/User:EarwigBot
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.

145 lines
4.8 KiB

  1. # -*- coding: utf-8 -*-
  2. """Commands to interface with the bot's git repository; use '!git help' for sub-command list."""
  3. import shlex, subprocess
  4. from config.irc_config import *
  5. actions, data = None, None
  6. def call(a, d):
  7. global actions, data
  8. actions, data = a, d
  9. if data.host not in ADMINS:
  10. actions.say(data.chan, "\x02%s\x0F: you must be a bot admin to use this command." % data.nick)
  11. return
  12. if not data.args:
  13. actions.say(data.chan, "\x02%s\x0F: no arguments provided." % data.nick)
  14. return
  15. if data.args[0] == "help":
  16. do_help()
  17. elif data.args[0] == "branch":
  18. do_branch()
  19. elif data.args[0] == "branches":
  20. do_branches()
  21. elif data.args[0] == "checkout":
  22. do_checkout()
  23. elif data.args[0] == "delete":
  24. do_delete()
  25. elif data.args[0] == "pull":
  26. do_pull()
  27. elif data.args[0] == "status":
  28. do_status()
  29. else: # they asked us to do something we don't know
  30. actions.say(data.chan, "\x02%s\x0F: unknown argument: \x0303%s\x0301." % (data.nick, data.args[0]))
  31. def exec_shell(command):
  32. """execute a shell command and get the output"""
  33. command = shlex.split(command)
  34. result = subprocess.check_output(command, stderr=subprocess.STDOUT)
  35. return result
  36. def do_help():
  37. """display all commands"""
  38. help_dict = {
  39. "branch": "get current branch",
  40. "branches": "get all branches",
  41. "checkout": "switch branches",
  42. "delete": "delete an old branch",
  43. "pull": "update everything from the remote server",
  44. "status": "check if we are out of date"
  45. }
  46. help = ""
  47. for key in help_dict.keys():
  48. help += "\x0303%s\x0301: (%s)," % (key, help_dict[key])
  49. help = help[:-1] # trim last comma
  50. actions.say(data.chan, "\x02%s\x0F: sub-commands are: %s." % (data.nick, help))
  51. def do_branch():
  52. """get our current branch"""
  53. branch = exec_shell("git name-rev --name-only HEAD")
  54. branch = branch[:-1] # strip newline
  55. actions.say(data.chan, "\x02%s\x0F: currently on branch \x0302%s\x0301." % (data.nick, branch))
  56. def do_branches():
  57. """get list of branches"""
  58. branches = exec_shell("git branch")
  59. branches = branches[:-1] # strip newline
  60. branches = branches.replace('\n* ', ', ') # cleanup extraneous characters
  61. branches = branches.replace('* ', ' ')
  62. branches = branches.replace('\n ', ', ')
  63. branches = branches.strip()
  64. actions.say(data.chan, "\x02%s\x0F: branches: \x0302%s\x0301." % (data.nick, branches))
  65. def do_checkout():
  66. """switch branches"""
  67. try:
  68. branch = data.args[1]
  69. except IndexError: # no branch name provided
  70. actions.say(data.chan, "\x02%s\x0F: switch to which branch?" % data.nick)
  71. return
  72. try:
  73. result = exec_shell("git checkout %s" % branch)
  74. if "Already on" in result:
  75. actions.say(data.chan, "\x02%s\x0F: already on \x0302%s\x0301!" % (data.nick, branch))
  76. else:
  77. actions.say(data.chan, "\x02%s\x0F: switched to branch \x0302%s\x0301." % (data.nick, branch))
  78. except subprocess.CalledProcessError: # git couldn't switch branches
  79. actions.say(data.chan, "\x02%s\x0F: branch \x0302%s\x0301 does not exist!" % (data.nick, branch))
  80. def do_delete():
  81. """delete a branch, while making sure that we are not on it"""
  82. try:
  83. delete_branch = data.args[1]
  84. except IndexError: # no branch name provided
  85. actions.say(data.chan, "\x02%s\x0F: delete which branch?" % data.nick)
  86. return
  87. current_branch = exec_shell("git name-rev --name-only HEAD")
  88. current_branch = current_branch[:-1] # strip newline
  89. if current_branch == delete_branch:
  90. actions.say(data.chan, "\x02%s\x0F: you're currently on this branch; please checkout to a different branch before deleting." % data.nick)
  91. return
  92. exec_shell("git branch -d %s" % delete_branch)
  93. actions.say(data.chan, "\x02%s\x0F: branch \x0302%s\x0301 has been deleted locally." % (data.nick, delete_branch))
  94. def do_pull():
  95. """pull from remote repository"""
  96. branch = exec_shell("git name-rev --name-only HEAD")
  97. branch = branch[:-1] # strip newline
  98. actions.say(data.chan, "\x02%s\x0F: pulling from remote (currently on \x0302%s\x0301)..." % (data.nick, branch))
  99. result = exec_shell("git pull")
  100. if "Already up-to-date." in result:
  101. actions.say(data.chan, "\x02%s\x0F: done; no new changes." % data.nick)
  102. else:
  103. actions.say(data.chan, "\x02%s\x0F: done; new changes merged." % data.nick)
  104. def do_status():
  105. """check whether we have anything to pull"""
  106. result = exec_shell("git fetch --dry-run")
  107. if not result:
  108. actions.say(data.chan, "\x02%s\x0F: local copy is up-to-date with remote." % data.nick)
  109. else:
  110. actions.say(data.chan, "\x02%s\x0F: remote is ahead of local copy." % (data.nick))