Source

python-bitbucket / api.py

Full commit
Kevin Veroneau 298102b 
Kevin Veroneau 382c1b7 




Kevin Veroneau fa0d7c0 



Kevin Veroneau fab8d21 

Kevin Veroneau fa0d7c0 



Kevin Veroneau fab8d21 

Kevin Veroneau fa0d7c0 


Kevin Veroneau fab8d21 












Kevin Veroneau fa0d7c0 

Kevin Veroneau fab8d21 
Kevin Veroneau fa0d7c0 





Kevin Veroneau fab8d21 
Kevin Veroneau fa0d7c0 


Kevin Veroneau 382c1b7 
Kevin Veroneau 298102b 
Kevin Veroneau 382c1b7 








Kevin Veroneau 298102b 
Kevin Veroneau 382c1b7 

Kevin Veroneau 298102b 











Kevin Veroneau 382c1b7 
Kevin Veroneau fb6b648 


Kevin Veroneau 382c1b7 











Kevin Veroneau 298102b 
Kevin Veroneau 382c1b7 

Kevin Veroneau 298102b 
Kevin Veroneau 382c1b7 
















Kevin Veroneau fab8d21 
Kevin Veroneau 298102b 


Kevin Veroneau 382c1b7 
Kevin Veroneau 298102b 
Kevin Veroneau 382c1b7 



Kevin Veroneau fab8d21 



Kevin Veroneau 382c1b7 
Kevin Veroneau 298102b 





Kevin Veroneau fab8d21 


Kevin Veroneau 382c1b7 
Kevin Veroneau 298102b 





Kevin Veroneau 382c1b7 


Kevin Veroneau fa0d7c0 




Kevin Veroneau fab8d21 
Kevin Veroneau fa0d7c0 



Kevin Veroneau fab8d21 


# -*- coding: utf-8 -*-
import cookielib
import urllib2
import base64
import json
from urllib import urlencode
import datetime

class BBFile(object):
    # Additional functionality will be added to this class in the future.  For now it is a placeholder class.
    def __init__(self, api, username, repository, rev, data):
        self.url = 'repositories/%s/%s/raw/%s/%s' % (username, repository, rev, data['file'])
        # Python variables "type" and "file" are reserved, and incompatible with the BB API ones.
        # Any suggestions on other names are welcome, but I believe "action" and "filename" suit it well.
        self.action = data['type']
        self.filename = data['file']
        self.api = api
        self._handler = None
    
    def __repr__(self):
        return "<BBFile: %s>" % self.filename
    
    def __getattr__(self, name):
        if name == 'handler':
	    if self._handler == None:
	        self._handler = self.api.get_raw(self.url)
	    return self._handler
	raise AttributeError

    def read(self, size=-1):
        return self.handler.read(size)
    
    def readline(self, size=-1):
        return self.handler.readline(size)

class Changeset(object):
    def __init__(self, api, username, repository, data):
        for i in data:
	    if i is not ['files', 'timestamp']:
	        setattr(self, i, data[i])
	self.timestamp = datetime.datetime.strptime(data['timestamp'], "%Y-%m-%d %H:%M:%S")
	self.files = []
	for f in data['files']:
	    self.files.append(BBFile(api, username, repository, data['node'], f))

    def __repr__(self):
        return "<Changeset: %s>" % self.node

class Issue(object):
    title = ""
    content = ""
    component = None
    milestone = None
    version = None
    responsible = None
    priority = "major"
    status = "new"
    kind = "bug"
    def __init__(self, api, username, repository, data=None):
        self.api = api
        self.responsible = username
        self.url = 'repositories/%s/%s/issues/' % (username, repository)
        if data:
	    self.url = 'repositories/%s/%s/issues/%s/' % (username, repository, data['local_id'])
	    self.title = data['title']
	    self.content = data['content']
	    self.component = data['metadata']['component']
	    self.milestone = data['metadata']['milestone']
	    self.version = data['metadata']['version']
	    self.responsible = data['responsible']['username']
	    self.priority = data['priority']
	    self.status = data['status']
	    self.kind = data['metadata']['kind']

    def __repr__(self):
        return "<Issue: %s>" % self.title

    def as_dict(self):
        data = {'title':self.title, 'content':self.content, 'priority':self.priority, 'status':self.status, 'kind':self.kind}
        data.update({'responsible':self.responsible})
        if self.component:
	    data.update({'component':self.component})
	if self.milestone:
	    data.update({'milestone':self.milestone})
	if self.version:
	    data.update({'version':self.version})
	return data

    def save(self):
        self.json = self.api.post(self.url, self.as_dict())
        return self.json

class API(object):
    api_url = 'https://api.bitbucket.org/1.0/'

    def __init__(self, username, password, proxy=None):
        encodedstring = base64.encodestring("%s:%s" % (username, password))[:-1]
        self._auth = "Basic %s" % encodedstring
        self._opener = self._create_opener(proxy)

    def _create_opener(self, proxy=None):
        cj = cookielib.LWPCookieJar()
        cookie_handler = urllib2.HTTPCookieProcessor(cj)
        if proxy:
            proxy_handler = urllib2.ProxyHandler(proxy)
            opener = urllib2.build_opener(cookie_handler, proxy_handler)
        else:
            opener = urllib2.build_opener(cookie_handler)
        return opener

    def _raw_request(self, url, data=None):
        query_url = self.api_url + url
        if data:
	  data = urlencode(data)
        try:
	    req = urllib2.Request(query_url, data, {"Authorization": self._auth })
	    handler = self._opener.open(req)
	except urllib2.HTTPError, e:
	    print e.headers
	    raise e
	return handler

    def _request(self, url, data=None):
	return json.load(self._raw_request(url, data))

    def post(self, url, data):
        return self._request(url, data)

    def get(self, url):
        return self._request(url, None)
    
    def get_raw(self, url):
        return self._raw_request(url, None)
    
    def get_issues(self, username, repository):
        json = self.get('repositories/%s/%s/issues/' % (username, repository))
        issues = []
        for i in json['issues']:
	    issue = Issue(self, username, repository, i)
	    issues.append(issue)
	return issues
        
    def new_issue(self, username, repository):
        return Issue(self, username, repository)
    
    def get_changesets(self, username, repository, limit=15):
        json = self.get('repositories/%s/%s/changesets?limit=%s' % (username, repository, limit))
        changesets = []
        for i in json['changesets']:
	    changesets.append(Changeset(self, username, repository, i))
	return changesets

    def get_changeset(self, username, repository, changeset):
        json = self.get('repositories/%s/%s/changesets/%s' % (username, repository, changeset))
        return Changeset(self, username, repository, json)

    def get_file(self, username, repository, filename, revision="tip"):
        return BBFile(self, username, repository, revision, {'type':'source', 'file':filename})