Justabot est un Bot écrit en python, il permet une présence sur les salons Jabber. https://www.devosi.org
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.

377 lines
12KB

  1. # -*- coding: utf-8 -*-
  2. # Copyright Crestetto Kévin, (Jun 2013)
  3. # checkpoint [at] singularity (dot) fr
  4. # Ce logiciel est un programme informatique
  5. # servant à discuter et executer des commandes sur un salon jabber/XMPP.
  6. # Ce logiciel est régi par la licence CeCILL soumise au droit français et
  7. # respectant les principes de diffusion des logiciels libres. Vous pouvez
  8. # utiliser, modifier et/ou redistribuer ce programme sous les conditions
  9. # de la licence CeCILL telle que diffusée par le CEA, le CNRS et l'INRIA
  10. # sur le site "http://www.cecill.info".
  11. # En contrepartie de l'accessibilité au code source et des droits de copie,
  12. # de modification et de redistribution accordés par cette licence, il n'est
  13. # offert aux utilisateurs qu'une garantie limitée. Pour les mêmes raisons,
  14. # seule une responsabilité restreinte pèse sur l'auteur du programme, le
  15. # titulaire des droits patrimoniaux et les concédants successifs.
  16. # A cet égard l'attention de l'utilisateur est attirée sur les risques
  17. # associés au chargement, à l'utilisation, à la modification et/ou au
  18. # développement et à la reproduction du logiciel par l'utilisateur étant
  19. # donné sa spécificité de logiciel libre, qui peut le rendre complexe à
  20. # manipuler et qui le réserve donc à des développeurs et des professionnels
  21. # avertis possédant des connaissances informatiques approfondies. Les
  22. # utilisateurs sont donc invités à charger et tester l'adéquation du
  23. # logiciel à leurs besoins dans des conditions permettant d'assurer la
  24. # sécurité de leurs systèmes et ou de leurs données et, plus généralement,
  25. # à l'utiliser et l'exploiter dans les mêmes conditions de sécurité.
  26. # Le fait que vous puissiez accéder à cet en-tête signifie que vous avez
  27. # pris connaissance de la licence CeCILL, et que vous en avez accepté les
  28. # termes.
  29. import sys
  30. import os
  31. import shutil
  32. def makethedir(target):
  33. if target[-1] == '/':
  34. target = target[:-1]
  35. if os.path.islink(target):
  36. os.mkdir(os.readlink(target))
  37. else:
  38. os.mkdir(target)
  39. def initconf():
  40. normalconf = 'config/'
  41. targetconf = 'config_user/'
  42. if os.path.islink(targetconf[:-1]):
  43. shutil.copytree(normalconf, targetconf + normalconf)
  44. initconfigpy()
  45. return
  46. if os.path.exists(targetconf):
  47. tmpconf = 'config_user_bak'
  48. if besure("Une configuration existe déjà, continuez quand même ? (y/n)"):
  49. if os.path.exists(tmpconf):
  50. raise SystemExit(tmpconf + "existe aussi")
  51. os.rename(targetconf, tmpconf)
  52. print(targetconf + "Enregistrer sous" + tmpconf)
  53. print("Veuillez supprimer manuellement" + tmpconf)
  54. else:
  55. raise SystemExit("user abort")
  56. makethedir(targetconf)
  57. shutil.copytree(normalconf, targetconf + normalconf)
  58. initconfigpy()
  59. def initconfigpy():
  60. normalconf = 'config/'
  61. targetconf = 'config_user/'
  62. if besure("Configurer maintenant ? (y/n)"):
  63. fileconf = targetconf + normalconf + 'config.py'
  64. allconf = []
  65. values = []
  66. autoserverport = True
  67. with open(fileconf, 'r') as f:
  68. allconf = f.readlines()
  69. if besure("Voulez-vous spécifier le port du serveur ? (no pour auto)"):
  70. autoserverport = False
  71. for line in allconf:
  72. if line.startswith("SERVER") and not autoserverport:
  73. print("Hostname du serveur (exemple.org)")
  74. l = "SERVER = '" + sys.stdin.readline()[:-1] + "'"
  75. elif line.startswith("SERVER") and not autoserverport:
  76. print("Port du serveur")
  77. l = "PORT = " + sys.stdin.readline()[:-1]
  78. elif line.startswith('PASS'):
  79. print("Mot de passe du compte à utiliser (password)")
  80. l = "PASS = '" + sys.stdin.readline()[:-1] + "'"
  81. elif line.startswith('JID'):
  82. print("Compte Jabber (myaccount@exemple.org)")
  83. l = "JID = '" + sys.stdin.readline()[:-1] + "'"
  84. elif line.startswith('ADMINS'):
  85. print("Ajouter un admin au bot.")
  86. alladmins = []
  87. while besure("Ajouter un admin ? (y/n)"):
  88. print('>')
  89. alladmins.append(sys.stdin.readline()[:-1])
  90. l = "ADMINS = ["
  91. for admin in alladmins:
  92. l += "'" + admin + "',"
  93. l += "]"
  94. elif line.startswith('CHANNELS'):
  95. print("Connecter le bot à un salon de discussion.")
  96. allchans = []
  97. while besure("Ajouter un salon ? (y/n)"):
  98. print('>')
  99. allchans.append(sys.stdin.readline()[:-1])
  100. l = "CHANNELS = ["
  101. for chan in allchans:
  102. l += "'" + chan + "',"
  103. l += "]"
  104. elif line.startswith("RECONNECT"):
  105. l = "RECONNECT = True"
  106. elif line.startswith("DOMAIN_FILTER"):
  107. print("Autoriser un nom de domaine externe.")
  108. print("Ajouter (*) pour tout accepter.")
  109. alldomains = []
  110. while besure("Ajouter un domaine. (y/n)"):
  111. print('>')
  112. alldomains.append(sys.stdin.readline()[:-1])
  113. l = "DOMAIN_FILTER = ["
  114. for domain in alldomains:
  115. l += "'" + domain + "',"
  116. l += "]"
  117. else:
  118. l = line[:-1]
  119. values.append(l)
  120. if not besure("Sauvegarder ma configuration ? (y/n)"):
  121. raise SystemExit(" Abandon de l'utilisateur...")
  122. with open(fileconf, 'w') as f:
  123. for line in values:
  124. f.write(line + "\n")
  125. print(fileconf + " Sauvegardé avec succès !")
  126. def besure(nota):
  127. print(nota)
  128. yes = ('y', 'Y', 'yes', 'YES', 'Yes')
  129. no = ('n', 'N', 'no', 'NO', 'No')
  130. answer = sys.stdin.readline()[:-1]
  131. while not (answer in yes or answer in no):
  132. print("y/n")
  133. answer = sys.stdin.readline()[:-1]
  134. if answer in no:
  135. return False
  136. elif answer in yes:
  137. return True
  138. sys.exit(1)
  139. if __name__ != '__main__':
  140. sys.exit(1)
  141. if sys.version_info[0] < 3:
  142. raise SystemExit('require python_3')
  143. if os.sep != '/' or os.linesep != "\n":
  144. raise SystemExit('system not supported')
  145. try:
  146. me = os.path.dirname(__file__)
  147. if me != '':
  148. os.chdir(me)
  149. except:
  150. raise SystemExit('cannot change current directory')
  151. if '-V' in sys.argv[1:]:
  152. from config.config import my_version
  153. print(my_version)
  154. sys.exit()
  155. elif '-e' in sys.argv[1:]:
  156. sleek_clone = os.getcwd() + '/sleekxmpp_clone/SleekXMPP'
  157. config_user = os.getcwd() + '/config_user'
  158. if not os.path.isdir(config_user + '/config'):
  159. initconf()
  160. if os.path.isdir(config_user + '/config'):
  161. sys.path.insert(0, config_user)
  162. from config.configvar import MYDIRS
  163. if not os.path.isdir(MYDIRS['tmp']):
  164. makethedir(MYDIRS['tmp'])
  165. if not os.path.isdir(MYDIRS['logs']):
  166. makethedir(MYDIRS['logs'])
  167. if '-R' in sys.argv[1:]:
  168. import config.config
  169. config.config.RECONNECT = True
  170. if os.path.isdir('sleekxmpp_clone/SleekXMPP'):
  171. sys.path.insert(1, sleek_clone)
  172. try:
  173. import sleekxmpp
  174. except:
  175. raise SystemExit("""Require sleekxmpp\n\
  176. please add 'sleekxmpp/' in your root justabot/""")
  177. from demibot import inout
  178. # run all !
  179. try:
  180. i = inout()
  181. i()
  182. except KeyboardInterrupt:
  183. sys.exit()
  184. elif '-c' in sys.argv[1:]:
  185. config_user = os.getcwd() + '/config_user'
  186. if os.path.isdir(config_user + '/config'):
  187. sys.path.insert(0, config_user)
  188. from config.configvar import MYDIRS
  189. thedirs = []
  190. thefiles = []
  191. to_add = ['config_user/', MYDIRS['tmp'], MYDIRS['logs'],
  192. 'diff_changes.txt', 'diff_config.txt', 'tmp/', 'logs/']
  193. if '-a' in sys.argv[1:]:
  194. to_add.extend(('sleekxmpp_clone/', '.git/'))
  195. for alldir in to_add:
  196. if os.path.isdir(alldir):
  197. for item in os.walk(alldir):
  198. thedirs.append(item[0])
  199. if item[2]:
  200. for f in item[2]:
  201. thefiles.append(item[0] + '/' + f)
  202. elif os.path.isfile(alldir):
  203. thefiles.append(alldir)
  204. for item in os.walk('.'):
  205. if item[0] == '__pycache__':
  206. thedirs.append(item[0])
  207. if item[2]:
  208. for f in item[2]:
  209. thefiles.append(item[0] + '/' + f)
  210. ex = ''
  211. for d in sorted(thedirs):
  212. if ex != d:
  213. ex = d
  214. print(d + '/')
  215. for f in sorted(thefiles):
  216. if ex != f:
  217. ex = f
  218. print(f)
  219. sys.exit(0)
  220. elif '-i' in sys.argv[1:]:
  221. if not os.path.isdir('config_user/config'):
  222. initconf()
  223. else:
  224. initconfigpy()
  225. elif '-s' in sys.argv[1:]:
  226. import tarfile
  227. targz = 'justabot_config.tar.gz'
  228. confuser = 'config_user/'
  229. if os.path.isfile(targz):
  230. raise SystemExit(targz + " already exist")
  231. if not os.path.isdir(confuser):
  232. raise SystemExit(confuser + " not found")
  233. if besure("save config ?"):
  234. tar = tarfile.open(targz, "w:gz")
  235. tar.add(confuser)
  236. tar.close()
  237. elif '-r' in sys.argv[1:]:
  238. import tarfile
  239. targz = 'justabot_config.tar.gz'
  240. if not os.path.isfile(targz):
  241. raise SystemExit("no archive found")
  242. tar = tarfile.open(targz, "r:gz")
  243. for tarinfo in tar:
  244. print(tarinfo.name, " => ", tarinfo.size, "bytes")
  245. tar.close()
  246. if besure("extract config ?"):
  247. tar = tarfile.open(targz)
  248. tar.extractall()
  249. tar.close()
  250. elif '-u' in sys.argv[1:]:
  251. if not os.path.isfile("demibot.py"):
  252. raise SystemExit("error, demibot.py not found here")
  253. if not os.path.isdir("config_user/config/"):
  254. print("config_user not found")
  255. if not besure("continue anyway ?"):
  256. raise SystemExit("user abort")
  257. if os.system("which git"):
  258. raise SystemExit("git require")
  259. if os.system("which rsync"):
  260. raise SystemExit("rsync require")
  261. if os.path.isdir(".git"):
  262. if os.system("git pull origin master"):
  263. if besure("force pull ?"):
  264. os.system("git reset --hard HEAD")
  265. os.system("git pull origin master")
  266. os.system("diff -r './config' 'config_user/config' > 'diff_config.txt'")
  267. count = 0
  268. with open('diff_config.txt') as f:
  269. count = len(f.readlines())
  270. if count > 0:
  271. os.system("less 'diff_config.txt'")
  272. if besure("add new config file ?"):
  273. os.system("rsync -rub 'config/' 'config_user/config/'")
  274. else:
  275. os.system("git clone git://gitorious.org/justabot/justabot.git")
  276. os.system("rsync -av 'justabot/' '.'")
  277. os.system("rm -R justabot/")
  278. lib_file="config_user/never_update_lib"
  279. if not os.path.isfile(lib_file):
  280. if not besure("update/add sleekxmpp ?"):
  281. if besure("never update ?"):
  282. with open(lib_file, 'w') as f:
  283. f.write('')
  284. else:
  285. if os.path.isdir("sleekxmpp_clone/SleekXMPP/sleekxmpp"):
  286. os.chdir('sleekxmpp_clone/SleekXMPP')
  287. os.system("git pull origin master")
  288. os.chdir("../..")
  289. else:
  290. os.mkdir('sleekxmpp_clone')
  291. os.chdir('sleekxmpp_clone/')
  292. os.system("git clone 'git://github.com/fritzy/SleekXMPP.git'")
  293. os.chdir('..')
  294. print('update done !')
  295. else:
  296. print("usage : " + sys.argv[0])
  297. print(" -i : init config_user/")
  298. print(" -e : exec")
  299. print(" -V : version")
  300. print(" -e -R : exec and reconnect")
  301. print(" -c [-a]: list files adds")
  302. print("testing only :")
  303. print(" -u : update")
  304. print(" -s : save config")
  305. print(" -r : restore config")