ftp_deploy.utils.repo: 227 total statements, 81.8% covered

Generated: Sun 2014-03-16 19:26 GMT

Source file: /var/www/service.dev/service/ftp_deploy/utils/repo.py

Stats: 180 executed, 40 missed, 7 excluded, 93 ignored

  1. import pycurl
  2. import json
  3. import re
  4. import core
  5. from .curl import curl_connection
  6. from .decorators import check
  7. from ftp_deploy.conf import *
  8. class repository_parser(object):
  9. def __init__(self, data, service):
  10. self.service = service
  11. self.data = data
  12. self.service_repo = service.repo_source
  13. def credentials(self):
  14. """return login details"""
  15. if self.service_repo == 'bb':
  16. return BITBUCKET_SETTINGS['username'], BITBUCKET_SETTINGS['password']
  17. elif self.service_repo == 'gh':
  18. return GITHUB_SETTINGS['username'], GITHUB_SETTINGS['password']
  19. def check_branch(self):
  20. """check if payload branch match set branch"""
  21. if self.service_repo == 'bb':
  22. last_commit = len(self.data['commits']) - 1
  23. if self.data['commits'][last_commit]['branch'] == self.service.repo_branch:
  24. return True
  25. elif self.service_repo == 'gh':
  26. ref = self.data['ref'].split('/')
  27. if ref[2] == self.service.repo_branch:
  28. return True
  29. return False
  30. def deploy_email(self):
  31. """return email of deploy user"""
  32. if self.service_repo == 'bb':
  33. if self.data['user'] == 'Restore':
  34. return []
  35. try:
  36. curl = curl_connection(BITBUCKET_SETTINGS['username'], BITBUCKET_SETTINGS['password'])
  37. curl.authenticate()
  38. url = 'https://bitbucket.org/api/1.0/users/%s/emails' % self.data['user']
  39. context = json.loads(curl.perform(url))
  40. return [context[0]['email']]
  41. except Exception, e:
  42. return []
  43. elif self.service_repo == 'gh':
  44. if self.data['pusher']['name'] == 'Restore':
  45. return []
  46. return self.data['pusher']['email']
  47. def deploy_name(self):
  48. """ return username of deploy user"""
  49. if self.service_repo == 'bb':
  50. return self.data['user']
  51. elif self.service_repo == 'gh':
  52. return self.data['pusher']['name']
  53. class repository_api(object):
  54. def __init__(self, service_repo):
  55. self.service_repo = service_repo
  56. self.curl_init()
  57. def curl_init(self):
  58. if self.service_repo == 'bb':
  59. self.username = BITBUCKET_SETTINGS['username']
  60. self.password = BITBUCKET_SETTINGS['password']
  61. elif self.service_repo == 'gh':
  62. self.username = GITHUB_SETTINGS['username']
  63. self.password = GITHUB_SETTINGS['password']
  64. self.curl = curl_connection(self.username, self.password)
  65. self.curl.authenticate()
  66. def repositories(self):
  67. """Load list of repositories from repository account"""
  68. if(self.service_repo == 'bb'):
  69. url = 'https://bitbucket.org/api/1.0/user/repositories'
  70. elif(self.service_repo == 'gh'):
  71. url = 'https://api.github.com/user/repos'
  72. context = self.curl.perform(url)
  73. return context
  74. def add_hook(self, service, request):
  75. """Add hook and change repo_hook flag for service"""
  76. if(self.service_repo == 'bb'):
  77. url = 'https://api.bitbucket.org/1.0/repositories/%s/%s/services/ ' % (self.username, service.repo_slug_name)
  78. post = 'type=POST&URL=%s%s' % (core.absolute_url(request).build(), service.hook_url())
  79. elif(self.service_repo == 'gh'):
  80. url = 'https://api.github.com/repos/%s/%s/hooks' % (self.username, service.repo_slug_name)
  81. data = {
  82. "name": 'web',
  83. "active": True,
  84. "config": {
  85. "url": '%s%s' % (core.absolute_url(request).build(), service.hook_url()),
  86. "content_type": "json"
  87. }
  88. }
  89. post = json.dumps(data)
  90. service.repo_hook = True
  91. service.save()
  92. context = self.curl.perform_post(url, post)
  93. return context
  94. class commits_parser(object):
  95. """Commit parser for list of commits. Take commits dictionary captured from payload"""
  96. def __init__(self, commits, service_repo):
  97. self.commits = commits
  98. self.service_repo = service_repo
  99. def commits_info(self):
  100. """Return commits details list in format [message,author,raw_node]"""
  101. output = list()
  102. if self.service_repo == 'bb':
  103. [output.append([commit['message'], commit['author'], commit['raw_node']]) for commit in reversed(self.commits)]
  104. elif self.service_repo == 'gh':
  105. [output.append([commit['message'], commit['author']['name'], commit['id']]) for commit in reversed(self.commits)]
  106. return output
  107. def email_list(self):
  108. """Return email list from raw_author, limited to unique emails"""
  109. output = list()
  110. if self.service_repo == 'bb':
  111. for commit in self.commits:
  112. email = re.search('%s(.*)%s' % ('<', '>'), commit['raw_author']).group(1)
  113. output.append(email) if email not in output else False
  114. elif self.service_repo == 'gh':
  115. for commit in self.commits:
  116. email = commit['author']['email']
  117. output.append(email) if email not in output else False
  118. return output
  119. def file_diff(self):
  120. """Return files list grouped by added, modified and removed. Respect order of commits"""
  121. added, removed, modified = list(), list(), list()
  122. if self.service_repo == 'bb':
  123. for commit in self.commits:
  124. for file in commit['files']:
  125. if file['type'] == 'added':
  126. added.append(file['file']) if file['file'] not in added else False
  127. removed.remove(file['file']) if file['file'] in removed else False
  128. elif file['type'] == 'modified':
  129. modified.append(file['file']) if file['file'] not in modified and file['file'] not in added else False
  130. elif file['type'] == 'removed':
  131. removed.append(file['file']) if file['file'] not in removed + added else False
  132. added.remove(file['file']) if file['file'] in added else False
  133. modified.remove(file['file']) if file['file'] in modified else False
  134. elif self.service_repo == 'gh':
  135. for commit in self.commits:
  136. for file in commit['added']:
  137. added.append(file) if file not in added else False
  138. removed.remove(file) if file in removed else False
  139. for file in commit['modified']:
  140. modified.append(file) if file not in modified and file not in added else False
  141. for file in commit['removed']:
  142. removed.append(file) if file not in removed + added else False
  143. added.remove(file) if file in added else False
  144. modified.remove(file) if file in modified else False
  145. return added, modified, removed
  146. def files_count(self):
  147. count = 0
  148. if self.service_repo == 'bb':
  149. for commit in self.commits:
  150. count += len(commit['files'])
  151. elif self.service_repo == 'gh':
  152. for commit in self.commits:
  153. count += len(commit['added']) + len(commit['modified']) + len(commit['removed'])
  154. return count
  155. class bitbucket_check(curl_connection):
  156. """Bitbucket check class contain all checking points for bitbucket repository, return True if fail"""
  157. def __init__(self, username, password, service):
  158. super(bitbucket_check, self).__init__(username, password)
  159. self.service = service
  160. @check('Bitbucket')
  161. def check_authentication(self):
  162. self.authenticate()
  163. self.perform('https://bitbucket.org/api/1.0/user/repositories')
  164. if self.curl.getinfo(pycurl.HTTP_CODE) != 200:
  165. raise Exception("Login Fail")
  166. @check('Bitbucket')
  167. def check_repo_exist(self):
  168. self.authenticate()
  169. repos = json.loads(self.perform('https://bitbucket.org/api/1.0/user/repositories'))
  170. for repo in repos:
  171. if repo['slug'] == self.service.repo_slug_name:
  172. return False, ''
  173. raise Exception("Repository %s doesn't exist" % self.service.repo_slug_name)
  174. @check('Bitbucket')
  175. def check_branch_exist(self):
  176. self.authenticate()
  177. url = 'https://bitbucket.org/api/1.0/repositories/%s/%s/branches' % (self.username, self.service.repo_slug_name)
  178. branches = json.loads(self.perform(url))
  179. try:
  180. branches[self.service.repo_branch]
  181. except KeyError, e:
  182. raise Exception("Branch %s doesn't exist" % self.service.repo_branch)
  183. @check('Bitbucket')
  184. def check_hook_exist(self):
  185. self.authenticate()
  186. url = 'https://bitbucket.org/api/1.0/repositories/%s/%s/services' % (self.username, self.service.repo_slug_name)
  187. hooks = json.loads(self.perform(url))
  188. if type(hooks) == list:
  189. for hook in hooks:
  190. if len(hook['service']['fields']) > 0:
  191. value = hook['service']['fields'][0]['value']
  192. if value.find(str(self.service.hook_url())) != -1 and hook['service']['type'] == 'POST':
  193. return False, ''
  194. raise Exception("Hook is not set up")
  195. def check_all(self):
  196. status = self.check_authentication()
  197. if status[0] == True:
  198. return status
  199. status = self.check_repo_exist()
  200. if status[0] == True:
  201. return status
  202. status = self.check_branch_exist()
  203. if status[0] == True:
  204. return status
  205. return False, ''
  206. class github_check(curl_connection):
  207. """Bitbucket check class contain all checking points for bitbucket repository, return True if fail"""
  208. def __init__(self, username, password, service):
  209. super(github_check, self).__init__(username, password)
  210. self.service = service
  211. @check('Github')
  212. def check_authentication(self):
  213. self.authenticate()
  214. self.perform('https://api.github.com/user/repos')
  215. if self.curl.getinfo(pycurl.HTTP_CODE) != 200:
  216. raise Exception("Login Fail")
  217. @check('Github')
  218. def check_repo_exist(self):
  219. self.authenticate()
  220. repos = json.loads(self.perform('https://api.github.com/user/repos'))
  221. for repo in repos:
  222. if repo['name'] == self.service.repo_slug_name:
  223. return False, ''
  224. raise Exception("Repository %s doesn't exist" % self.service.repo_slug_name)
  225. @check('Github')
  226. def check_branch_exist(self):
  227. self.authenticate()
  228. url = 'https://api.github.com/repos/%s/%s/branches' % (self.username, self.service.repo_slug_name)
  229. branches = json.loads(self.perform(url))
  230. for branch in branches:
  231. if branch['name'] == self.service.repo_branch:
  232. return False, ''
  233. raise Exception("Branch %s doesn't exist" % self.service.repo_branch)
  234. @check('Github')
  235. def check_hook_exist(self):
  236. self.authenticate()
  237. url = 'https://api.github.com/repos/%s/%s/hooks' % (self.username, self.service.repo_slug_name)
  238. hooks = json.loads(self.perform(url))
  239. if type(hooks) == list:
  240. for hook in hooks:
  241. if hook['name'] == "web" and hook['config']['url'] == self.service.hook_url():
  242. return False, ''
  243. raise Exception("Hook is not set up")
  244. def check_all(self):
  245. status = self.check_authentication()
  246. if status[0] == True:
  247. return status
  248. status = self.check_repo_exist()
  249. if status[0] == True:
  250. return status
  251. status = self.check_branch_exist()
  252. if status[0] == True:
  253. return status
  254. return False, ''