Skip to content

Commit

Permalink
Add support for getting artifacts (#40)
Browse files Browse the repository at this point in the history
  • Loading branch information
msabramo committed Aug 8, 2016
1 parent 681a8dc commit 0d1cbde
Show file tree
Hide file tree
Showing 4 changed files with 126 additions and 4 deletions.
105 changes: 105 additions & 0 deletions pyteamcity/future/artifact.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
import fnmatch
import os

from . import exceptions
from .core.utils import parse_date_string


class Artifact(object):
def __init__(self, build, path=''):
self.build = build
self.path = path
teamcity = self.build.build_query_set.teamcity
url = self.build.api_url + '/artifacts/metadata/' + self.path
res = teamcity.session.get(url)
res.raise_for_status()
self._data = res.json()

@property
def name(self):
return self._data['name']

def getsize(self):
return self._data.get('size')

@property
def size(self):
return self.getsize()

@property
def modification_time(self):
return parse_date_string(self._data['modificationTime'])

def splitext(self):
return os.path.splitext(self.name)

@property
def ext(self):
return self.splitext()[1]

def fnmatch(self, pattern):
return fnmatch.fnmatch(self.name, pattern)

@property
def content_href(self):
return self._data.get('content', {}).get('href')

def isdir(self):
return self.content_href is None

def isfile(self):
return self.content_href is not None

def __repr__(self):
return '<%s.%s: build.id=%r name=%r size=%r>' % (
self.__module__,
self.__class__.__name__,
self.build.id,
self.name,
self.size)

def content(self):
if not self.isfile():
raise exceptions.IllegalOperation(
'Calling the `content` method on a non-file artifact'
' (%r) is not allowed' % self)
teamcity = self.build.build_query_set.teamcity
url = teamcity.base_base_url + self.content_href
res = teamcity.session.get(url)
res.raise_for_status()
return res.content

def get_artifact_by_path(self, path):
artifact = self
for path_component in path.split('/'):
artifact = artifact.listdir(path_component)[0]
return artifact

def __div__(self, path):
return self.get_artifact_by_path(path)

def listdir(self, pattern=None):
teamcity = self.build.build_query_set.teamcity
url = self.build.api_url + '/artifacts/children/' + self.path
res = teamcity.session.get(url)
res.raise_for_status()
data = res.json()
if data.get('count', 0) == 0 or 'file' not in data:
return []
ret = []
for f in data['file']:
if pattern is None or fnmatch.fnmatch(f['name'], pattern):
path = self.path + '/' + f['name']
path = path.lstrip('/')
ret.append(Artifact(build=self.build, path=path))
return ret

def dirname(self):
path = os.path.dirname(self.path)
return Artifact(build=self.build, path=path)

def files(self, pattern=None):
return [x for x in self.listdir(pattern) if x.isfile()]

def dirs(self, pattern=None):
return [x for x in self.listdir(pattern) if x.isdir()]
12 changes: 12 additions & 0 deletions pyteamcity/future/build.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
from .core.utils import parse_date_string

from .agent import Agent
from .artifact import Artifact
from .build_type import BuildType, BuildTypeQuerySet
from .user import User

Expand Down Expand Up @@ -98,6 +99,17 @@ def parameters_dict(self):

return d

@property
def api_url(self):
teamcity = self.build_query_set.teamcity
base_url = teamcity.base_url
url = base_url + '/app/rest/builds/id:%s' % self.id
return url

@property
def artifacts(self):
return Artifact(build=self)


class BuildQuerySet(QuerySet):
uri = '/app/rest/builds/'
Expand Down
4 changes: 4 additions & 0 deletions pyteamcity/future/exceptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,10 @@ class InvalidLocatorDimension(Error):
pass


class IllegalOperation(Error):
pass


class HTTPError(Error):
def __init__(self, status_code, msg, text):
self.status_code = status_code
Expand Down
9 changes: 5 additions & 4 deletions pyteamcity/future/teamcity.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,13 +65,14 @@ def __init__(self,
teamcity=self,
query_set_factory=VCSRootQuerySet)

self.base_base_url = "%s://%s:%d" % (
self.protocol, self.server, self.port)

if self.username and self.password:
self.base_url = "%s://%s:%d/httpAuth" % (
self.protocol, self.server, self.port)
self.base_url = self.base_base_url + '/httpAuth'
self.auth = (self.username, self.password)
else:
self.base_url = "%s://%s:%d/guestAuth" % (
self.protocol, self.server, self.port)
self.base_url = self.base_base_url + '/guestAuth'
self.auth = None

@classmethod
Expand Down

0 comments on commit 0d1cbde

Please sign in to comment.