@@ -0,0 +1,3097 @@
+import logging%0Aimport sys%0Aimport os%0Afrom textwrap import dedent%0A%0Aimport requests%0Afrom tambo import Transport%0A%0Aimport chacractl%0A%0Alogger = logging.getLogger(__name__)%0A%0A%0Aclass Project(object):%0A    _help = dedent(%22%22%22%0A    Handle projects on a remote chacra instance.%0A%0A    Creating a new project::%0A%0A        chacractl project create project%0A%0A    Options:%0A%0A    create        Creates a new project%0A    %22%22%22)%0A    help_menu = %22create projects%22%0A    options = %5B'create'%5D%0A%0A    def __init__(self, argv):%0A        self.argv = argv%0A%0A    @property%0A    def base_url(self):%0A        return os.path.join(%0A            chacractl.config%5B'url'%5D, 'binaries'%0A        )%0A%0A    def sanitize_url(self, url_part):%0A        # get rid of the leading slash to prevent issues when joining%0A        url = url_part.lstrip('/')%0A%0A        # and add a trailing slash so that the request is done at the correct%0A        # canonical url%0A        if not url.endswith('/'):%0A            url = %22%25s/%22 %25 url%0A        return url%0A%0A    def post(self, url):%0A        exists = requests.head(url)%0A%0A        if exists.status_code == 200:%0A            logger.warning('resource exists, will not upload')%0A            logger.warning('SKIP %25s', url)%0A            return%0A        elif exists.status_code == 404:%0A            logger.info('POSTing to project: %25s', url)%0A            response = requests.post(%0A                url,%0A                auth=chacractl.config%5B'credentials'%5D)%0A        if response.status_code %3E 201:%0A            logger.warning(%22%25s -%3E %25s%22, response.status_code, response.text)%0A            response.raise_for_status()%0A%0A    def delete(self, url):%0A        # XXX This exists here but it is not yet implemented, e.g. nothing%0A        # calls this method%0A        exists = requests.head(url)%0A        if exists.status_code == 404:%0A            logger.warning('project already deleted')%0A            logger.warning('SKIP %25s', url)%0A            return%0A        logger.info('DELETE project: %25s', url)%0A        response = requests.delete(%0A            url,%0A            auth=chacractl.config%5B'credentials'%5D)%0A        if response.status_code %3E 201:%0A            logger.warning(%22%25s -%3E %25s%22, response.status_code, response.text)%0A%0A    def main(self):%0A        self.parser = Transport(self.argv, options=self.options)%0A        self.parser.catch_help = self._help%0A        self.parser.parse_args()%0A%0A        # handle posting projects:%0A        if self.parser.has('create'):%0A            url_part = self.sanitize_url(self.parser.get('create'))%0A            if not sys.stdin.isatty():%0A                # read from stdin%0A                logger.info('reading input from stdin')%0A                for line in sys.stdin.readlines():%0A                    url = os.path.join(self.base_url, url_part)%0A                    self.post(url)%0A            else:%0A                url = os.path.join(self.base_url, url_part)%0A                self.post(url)%0A        # XXX this exists here but it not yet enabled from the CLI%0A        elif self.parser.has('delete'):%0A            url_part = self.sanitize_url(self.parser.get('delete'))%0A            url = os.path.join(self.base_url, url_part)%0A            self.delete(url)%0A

create a projects api support