Example #1
0
    def __init__(self,
                 local_search_paths=None,
                 url_search_prefixes=None,
                 auth=None,
                 uri_search_template=None):
        """Instantiates a ComponentStore including the specified locations.
        
        Args:

            local_search_paths: A list of local directories to include in the search.
            url_seach_prefixes: A list of URL prefixes to include in the search.
            auth: Auth object for the requests library. See https://requests.readthedocs.io/en/master/user/authentication/
            uri_search_template: A URI template for components, which may include {name}, {digest} and {tag} variables.
        """
        self.local_search_paths = local_search_paths or ['.']
        if uri_search_template:
            self.uri_search_template = URITemplate(uri_search_template)
        self.url_search_prefixes = url_search_prefixes or []
        self._auth = auth

        self._component_file_name = 'component.yaml'
        self._digests_subpath = 'versions/sha256'
        self._tags_subpath = 'versions/tags'

        cache_base_dir = Path(tempfile.gettempdir()) / '.kfp_components'
        self._git_blob_hash_to_data_db = KeyValueStore(
            cache_dir=cache_base_dir / 'git_blob_hash_to_data')
        self._url_to_info_db = KeyValueStore(cache_dir=cache_base_dir /
                                             'url_to_info')
Example #2
0
 def test_default_value(self):
     uri = 'https://api.github.com/user{/user=sigmavirus24}'
     t = URITemplate(uri)
     self.assertEqual(t.expand(),
                      'https://api.github.com/user/sigmavirus24')
     self.assertEqual(t.expand(user='******'),
                      'https://api.github.com/user/lukasa')
Example #3
0
    def get_sentences(self, request):
        expansions = {
            'count': request.get('count', None),
            'max-words': request.get('max_words', None)
        }

        if request.get('feature', None) is not None:
            template = '/sentence{/feature}{?count,max-words}'
            expansions.update(feature=request['feature'])

        elif request.get('word', None) is not None:
            if request.get('pos', None) is not None:
                template = '/sentence/word{/word}/pos{/pos}{?count,max-words}'
                expansions.update(word=request['word'], pos=request['pos'])

            else:
                template = '/sentence/word{/word}{?count,max-words}'
                expansions.update(word=request['word'])

        else:
            raise NotImplementedError()

        endpoint = URITemplate(self._api_path + template)
        url = endpoint.expand(expansions)
        return self.client.get(url, headers=self.headers)
Example #4
0
def send(req):
    criteria = []

    for key, value in iteritems(req.get('criteria', {})):
        criteria.append(key)
        criteria.append(value)

    url_tmpl = URITemplate('{protocol}://{host}/api{/series}{/season}{/round}'
                           '{/criteria*}{/resource}{/id}.json{?limit,offset}')

    url = url_tmpl.expand(req, criteria=criteria)
    res = requests.get(url)

    res.raise_for_status()

    res_data = res.json()

    # TODO: Format responses to target relevant data, and coerce numeric values to numbers
    # something like:
    # {limit, offset, total, url, result: []}
    # Remove all the ['MRData']['XXXXTable']['Races'][0] nonsense
    #
    # Might want a raw=True flag or something to be able to get around the formatting
    # if you want the full response for any reason.
    #
    # return Formatter(res_data, req.get('resource'))
    # return res_data
    return formatter(res_data, req)
def test_resource_class_create():
    rec_type = RecordTypeFactory("ResourceTest", RecordSchema)

    assert rec_type.resource_cls
    assert rec_type.resource_config_cls

    assert rec_type.resource_cls.__name__ == "ResourceTestResource"
    assert (
        rec_type.resource_config_cls.__name__ == "ResourceTestResourceConfig")

    assert rec_type.resource_config_cls.list_route == "/resourcetests"
    assert (rec_type.resource_config_cls.item_route ==
            "/resourcetests/<pid_value>")

    links_schema_class = rec_type.resource_config_cls.links_config["record"]
    search_links_schema_class = rec_type.resource_config_cls.links_config[
        "search"]

    assert links_schema_class.__name__ == "ResourceTestLinksSchema"
    assert (
        search_links_schema_class.__name__ == "ResourceTestSearchLinksSchema")

    assert hasattr(links_schema_class, "self")
    assert hasattr(search_links_schema_class, "self")
    assert hasattr(search_links_schema_class, "prev")
    assert hasattr(search_links_schema_class, "next")

    assert (links_schema_class.self.template.uri == URITemplate(
        "/api/resourcetests/{pid_value}").uri)
    assert (search_links_schema_class.self.template.uri == URITemplate(
        "/api/resourcetests/{?params*}").uri)

    assert rec_type.resource_cls.default_config == rec_type.resource_config_cls
Example #6
0
    def __init__(self, user, session=None):
        super(User, self).__init__(user, session)
        if not self.type:
            self.type = 'User'

        #: ID of the user's image on Gravatar
        self.gravatar_id = user.get('gravatar_id', '')
        #: True -- for hire, False -- not for hire
        self.hireable = user.get('hireable', False)

        ## The number of public_gists
        #: Number of public gists
        self.public_gists = user.get('public_gists', 0)

        # Private information
        #: How much disk consumed by the user
        self.disk_usage = user.get('disk_usage', 0)

        #: Number of private repos owned by this user
        self.owned_private_repos = user.get('owned_private_repos', 0)
        #: Number of private gists owned by this user
        self.total_private_gists = user.get('total_private_gists', 0)
        #: Total number of private repos
        self.total_private_repos = user.get('total_private_repos', 0)

        #: Which plan this user is on
        self.plan = Plan(user.get('plan', {}))

        events_url = user.get('events_url', '')
        #: Events URL Template. Expands with ``privacy``
        self.events_urlt = URITemplate(events_url) if events_url else None

        #: Followers URL (not a template)
        self.followers_url = user.get('followers_url', '')

        furl = user.get('following_url', '')
        #: Following URL Template. Expands with ``other_user``
        self.following_urlt = URITemplate(furl) if furl else None

        gists_url = user.get('gists_url', '')
        #: Gists URL Template. Expands with ``gist_id``
        self.gists_urlt = URITemplate(gists_url) if gists_url else None

        #: Organizations URL (not a template)
        self.organizations_url = user.get('organizations_url', '')

        #: Received Events URL (not a template)
        self.received_events_url = user.get('received_events_url', '')

        #: Repostories URL (not a template)
        self.repos_url = user.get('repos_url', '')

        starred_url = user.get('starred_url', '')
        #: Starred URL Template. Expands with ``owner`` and ``repo``
        self.starred_urlt = URITemplate(starred_url) if starred_url else None

        #: Subscriptions URL (not a template)
        self.subscriptions_url = user.get('subscriptions_url', '')

        self._uniq = user.get('id', None)
 def test_default_value(self):
     uri = 'https://api.github.com/user{/user=sigmavirus24}'
     t = URITemplate(uri)
     self.assertEqual(t.expand(),
                      'https://api.github.com/user/sigmavirus24')
     self.assertEqual(t.expand(user='******'),
                      'https://api.github.com/user/lukasa')
Example #8
0
 def __init__(self, release, session=None):
     super(Release, self).__init__(release, session)
     self._api = release.get('url')
     #: List of :class:`Asset <Asset>` objects for this release
     self.assets = [Asset(i, self) for i in release.get('assets', [])]
     #: URL for uploaded assets
     self.assets_url = release.get('assets_url')
     #: Body of the release (the description)
     self.body = release.get('body')
     #: Date the release was created
     self.created_at = self._strptime(release.get('created_at'))
     #: Boolean whether value is True or False
     self.draft = release.get('draft')
     #: HTML URL of the release
     self.html_url = release.get('html_url')
     #: GitHub id
     self.id = release.get('id')
     #: Name given to the release
     self.name = release.get('name')
     #; Boolean whether release is a prerelease
     self.prerelease = release.get('prerelease')
     #: Date the release was published
     self.published_at = self._strptime(release.get('published_at'))
     #: Name of the tag
     self.tag_name = release.get('tag_name')
     #: "Commit" that this release targets
     self.target_commitish = release.get('target_commitish')
     upload_url = release.get('upload_url')
     #: URITemplate to upload an asset with
     self.upload_urlt = URITemplate(upload_url) if upload_url else None
Example #9
0
def _make_package(args):  # pragma: no cover
    """Prepare transcriptiondata from the transcription sources."""
    from lingpy.sequence.sound_classes import token2class
    from lingpy.data import Model

    columns = ['LATEX', 'FEATURES', 'SOUND', 'IMAGE', 'COUNT', 'NOTE']
    bipa = TranscriptionSystem('bipa')
    for src, rows in args.repos.iter_sources(type='td'):
        args.log.info('TranscriptionData {0} ...'.format(src['NAME']))
        uritemplate = URITemplate(
            src['URITEMPLATE']) if src['URITEMPLATE'] else None
        out = [[
            'BIPA_GRAPHEME', 'CLTS_NAME', 'GENERATED', 'EXPLICIT', 'GRAPHEME',
            'URL'
        ] + columns]
        graphemes = set()
        for row in rows:
            if row['GRAPHEME'] in graphemes:
                args.log.warn('skipping duplicate grapheme: {0}'.format(
                    row['GRAPHEME']))
                continue
            graphemes.add(row['GRAPHEME'])
            if not row['BIPA']:
                bipa_sound = bipa[row['GRAPHEME']]
                explicit = ''
            else:
                bipa_sound = bipa[row['BIPA']]
                explicit = '+'
            generated = '+' if bipa_sound.generated else ''
            if is_valid_sound(bipa_sound, bipa):
                bipa_grapheme = bipa_sound.s
                bipa_name = bipa_sound.name
            else:
                bipa_grapheme, bipa_name = '<NA>', '<NA>'
            url = uritemplate.expand(
                **row) if uritemplate else row.get('URL', '')
            out.append([
                bipa_grapheme, bipa_name, generated, explicit, row['GRAPHEME'],
                url
            ] + [row.get(c, '') for c in columns])
        found = len([o for o in out if o[0] != '<NA>'])
        args.log.info('... {0} of {1} graphemes found ({2:.0f}%)'.format(
            found, len(out), found / len(out) * 100))
        with UnicodeWriter(pkg_path('transcriptiondata',
                                    '{0}.tsv'.format(src['NAME'])),
                           delimiter='\t') as writer:
            writer.writerows(out)

    count = 0
    with UnicodeWriter(pkg_path('soundclasses', 'lingpy.tsv'),
                       delimiter='\t') as writer:
        writer.writerow(['CLTS_NAME', 'BIPA_GRAPHEME'] + SOUNDCLASS_SYSTEMS)
        for grapheme, sound in sorted(bipa.sounds.items()):
            if not sound.alias:
                writer.writerow([sound.name, grapheme] + [
                    token2class(grapheme, Model(cls))
                    for cls in SOUNDCLASS_SYSTEMS
                ])
                count += 1
    args.log.info('SoundClasses: {0} written to file.'.format(count))
Example #10
0
    def __new__(mcs, attrs, record_type_name, endpoint_route):
        """Object creation."""
        # TODO better template building ?
        url_template = f"/api{endpoint_route}" + "/{?params*}"

        mcs.name = f"{record_type_name}SearchLinksSchema"

        attrs.update(
            {
                "self": Link(
                    template=URITemplate(url_template),
                    permission="search",
                    params=search_link_params(0),
                ),
                "prev": Link(
                    template=URITemplate(url_template),
                    permission="search",
                    params=search_link_params(-1),
                    when=search_link_when(-1),
                ),
                "next": Link(
                    template=URITemplate(url_template),
                    permission="search",
                    params=search_link_params(+1),
                    when=search_link_when(+1),
                ),
            }
        )
        return super().__new__(mcs, mcs.name, (), attrs)
class FileLinksSchema(Schema):
    """Schema for a record's links."""

    self_ = Link(
        template=URITemplate("/api/mocks/{pid_value}/files/{key}"),
        permission="read",
        params=lambda record_file: {
            'pid_value': record_file.record.pid.pid_value,
            'key': record_file.key,
        },
        data_key="self"  # To avoid using self since is python reserved key
    )

    content = Link(
        template=URITemplate("/api/mocks/{pid_value}/files/{key}/content"),
        permission="read",
        params=lambda record_file: {
            'pid_value': record_file.record.pid.pid_value,
            'key': record_file.key,
        },
    )

    commit = Link(
        template=URITemplate("/api/mocks/{pid_value}/files/{key}/commit"),
        permission="read",
        params=lambda record_file: {
            'pid_value': record_file.record.pid.pid_value,
            'key': record_file.key,
        },
    )
class FileLinksSchema(Schema):
    """Schema for a record file's links."""

    self_ = Link(
        template=URITemplate("/api/records/{pid_value}/files/{key}"),
        permission="read",
        params=lambda record_file: {
            'pid_value': record_file.record.pid.pid_value,
            'key': record_file.key,
        },
        data_key="self"  # To avoid using self since is python reserved key
    )

    # TODO: Explore how to expose also the HTTP method
    # commit = {
    #   "href": URITemplate("/api/records/{pid_value}/files/{key}/commit"),
    #   "method": "POST",
    # }
    content = Link(
        template=URITemplate("/api/records/{pid_value}/files/{key}/content"),
        permission="read",
        params=lambda record_file: {
            'pid_value': record_file.record.pid.pid_value,
            'key': record_file.key,
        },
    )

    commit = Link(
        template=URITemplate("/api/records/{pid_value}/files/{key}/commit"),
        permission="read",
        params=lambda record_file: {
            'pid_value': record_file.record.pid.pid_value,
            'key': record_file.key,
        },
    )
Example #13
0
 def test_unacceptable_route(self):
     # TODO decide whether failing all routes because one route has
     # failed is intended.
     with self.assertRaises(ValueError):
         URITemplateRouter([
             URITemplate('{target}'),
             URITemplate('/{target}'),
         ])
Example #14
0
    def test_no_slash_leading_fail(self):
        with self.assertRaises(ValueError):
            check_template_leading_slash(URITemplate('{}'))

        with self.assertRaises(ValueError):
            check_template_leading_slash(URITemplate('{count}'))

        check_template_leading_slash(URITemplate('/{count}'))
Example #15
0
 def test_no_variables_in_uri(self):
     """
     This test ensures that if there are no variables present, the
     template evaluates to itself.
     """
     uri = 'https://api.github.com/users'
     t = URITemplate(uri)
     self.assertEqual(t.expand(), uri)
     self.assertEqual(t.expand(users='foo'), uri)
Example #16
0
    def __init__(self, client, url: URITemplate):
        self.client = client

        self.info_url = url.partial(info='info', resource=self.resource_name)

        # Setting a URIVariable to None doesn't remove it using .partial,
        # so reconstruct the URITemplate
        submit_url = url.expand(info=None, resource=self.resource_name)
        self.submit_url = URITemplate(submit_url + '{/id}')
 def test_no_variables_in_uri(self):
     """
     This test ensures that if there are no variables present, the
     template evaluates to itself.
     """
     uri = 'https://api.github.com/users'
     t = URITemplate(uri)
     self.assertEqual(t.expand(), uri)
     self.assertEqual(t.expand(users='foo'), uri)
def main():
    print("Creating release...")

    # PARSE MODPACK YAML
    print("* Parsing modpack file")
    modpack = parseModpackDefinitions(MODPACK_FILE)

    headers = {
        'Authorization': 'token ' + os.environ['GITHUB_TOKEN'],
        'Content-type': 'application/json'
    }

    # POST /repos/:owner/:repo/releases
    print("* Creating release")

    with open('release.json', 'r') as f:
        releaseJson = f.read()

    if releaseJson == "":
        print("ERROR: releaseJson empty")
    else:
        print("releaseJson:")
        print(releaseJson)
        
    # payload = {
    #     "tag_name": modpack['version'],
    #     "name": "Release {}".format(modpack['version']),
    #     "draft": False,
    #     "prerelease": False,
    #     "body": releaseJson
    # }
    createResult = requests.post('https://api.github.com/repos/soapiestwaffles/minecraft-modpack/releases', headers=headers, data=releaseJson)
    print("   === HTTP {}".format(createResult.status_code))
    if createResult.status_code != 201:
        print("!!! Error creating release")
        print(createResult.json())
        os._exit(1)

    createResult = createResult.json()

    print("* Uploading release asset")
    zipFilename = "soapiestwaffles-modpack.zip"
    template = URITemplate(createResult['upload_url'])
    uploadUrl = template.expand(name=zipFilename)
    headers = {
        'Authorization': 'token ' + os.environ['GITHUB_TOKEN'],
        'Content-type': 'application/octet-stream',
        'Accept': 'application/json'
    }
    with open(os.path.join(OUTDIR, zipFilename), 'rb') as f:
        assetResult = requests.post(uploadUrl, data=f, headers=headers)
    print("   === HTTP {}".format(assetResult.status_code))
    if assetResult.status_code != 201:
        print("!!! Error uploading release asset")
        print(assetResult.json())
        os._exit(1)
Example #19
0
    def test_basic_creation_from_template(self):
        m = Map([
            URITemplateRule(URITemplate('/'), endpoint='root'),
            URITemplateRule(URITemplate('/somewhere'), endpoint='elsewhere'),
        ]).bind('example.com')
        self.assertEqual(('root', {}), m.match('/'))
        self.assertEqual(('elsewhere', {}), m.match('/somewhere'))

        with self.assertRaises(NotFound):
            m.match('/nowhere')
class DraftLinksSchema(Schema):
    """Schema for a draft's links."""

    self = Link(template=URITemplate("/api/mocks/{pid_value}/draft"),
                permission="read",
                params=lambda draft: {'pid_value': draft.pid.pid_value})
    publish = Link(
        template=URITemplate("/api/mocks/{pid_value}/draft/actions/publish"),
        permission="publish",
        params=lambda draft: {'pid_value': draft.pid.pid_value})
Example #21
0
async def get_schema(subject_name, httpsession, host):
    headers = {
        'Accept': 'application/vnd.schemaregistry.v1+json'
    }
    uri_temp = URITemplate(host + '/subjects{/subject}/versions{/version}')
    uri = uri_temp.expand(subject=subject_name, version='latest')
    r = await httpsession.get(uri, headers=headers)
    data = await r.json()
    schema = json.loads(data['schema'])
    schema_id = data['id']
    return schema, schema_id
Example #22
0
async def consume_for_simple_topics(*, loop, httpsession, consumer_settings,
                                    schema_registry_url, topic_name):
    consumer_settings.update({
        'group_id': topic_name,
        'client_id': f'{topic_name}-0'  # always only one consumer per topic
    })
    logger = structlog.get_logger(__name__).bind(
        role='consumer',
        group=consumer_settings['group_id'],
        client_id=consumer_settings['client_id'])
    logger.info(f'Getting schemas for topic {topic_name}')

    registry_headers = {'Accept': 'application/vnd.schemaregistry.v1+json'}
    schema_uri = URITemplate(schema_registry_url +
                             '/subjects{/subject}/versions/latest')

    # Get schemas
    r = await httpsession.get(schema_uri.expand(subject=f'{topic_name}-key'),
                              headers=registry_headers)
    data = await r.json()

    r = await httpsession.get(schema_uri.expand(subject=f'{topic_name}-value'),
                              headers=registry_headers)
    data = await r.json()
    value_schema = fastavro.parse_schema(json.loads(data['schema']))

    # Start up the Kafka consumer
    consumer = aiokafka.AIOKafkaConsumer(loop=loop, **consumer_settings)

    # Main loop for consuming messages
    try:
        await consumer.start()

        # Subscribe to all topics in the experiment
        consumer.subscribe([topic_name])

        logger.info(f'Started consumer for topic {topic_name}')
        while True:
            async for message in consumer:
                value_fh = BytesIO(message.value)
                value_fh.seek(0)
                value = fastavro.schemaless_reader(value_fh, value_schema)
                now = datetime.datetime.now(datetime.timezone.utc)
                latency = now - value['timestamp']
                latency_millisec = \
                    latency.seconds * 1000 + latency.microseconds / 1000
                CONSUMED.inc()  # increment prometheus consumption counter
                LATENCY.observe(latency_millisec / 1000)
                LATENCY_SUMMARY.observe(latency_millisec / 1000)
                logger.debug('latency',
                             latency_millisec=latency_millisec,
                             topic=message.topic)
    finally:
        consumer.stop()
Example #23
0
async def produce_for_simple_topic(*, loop, httpsession, producer_settings,
                                   schema_registry_url, topic_name, period):
    logger = structlog.get_logger(__name__).bind(
        role='producer',
        topic=topic_name,
    )

    logger.info('Getting schemas')
    schema_uri = URITemplate(schema_registry_url +
                             '/subjects{/subject}/versions/latest')
    headers = {'Accept': 'application/vnd.schemaregistry.v1+json'}

    # Get key schema
    r = await httpsession.get(schema_uri.expand(subject=topic_name + '-key'),
                              headers=headers)
    data = await r.json()
    key_schema = fastavro.parse_schema(json.loads(data['schema']))

    # Get value schema
    r = await httpsession.get(schema_uri.expand(subject=topic_name + '-value'),
                              headers=headers)
    data = await r.json()
    value_schema = fastavro.parse_schema(json.loads(data['schema']))

    default_key_fh = BytesIO()
    fastavro.schemaless_writer(default_key_fh, key_schema, {})
    default_key_fh.seek(0)
    default_key = default_key_fh.read()

    # Set up producer
    producer = aiokafka.AIOKafkaProducer(loop=loop, **producer_settings)
    await producer.start()
    logger.info(f'Started producer')

    try:
        while True:
            message_fh = BytesIO()
            fastavro.schemaless_writer(
                message_fh, value_schema,
                {'timestamp': datetime.datetime.now(datetime.timezone.utc)})
            message_fh.seek(0)
            # May want to adjust this control batching latency
            await producer.send_and_wait(topic_name,
                                         key=default_key,
                                         value=message_fh.read())
            PRODUCED.inc()  # increment prometheus production counter
            logger.debug('Sent message')
            # naieve message period; need to correct for production time
            await asyncio.sleep(period)
    finally:
        await producer.stop()
def buildKeyMapUrl(config_data):
    """
    Formats the KVM Keymap url for us using the config data.
    """

    t = URITemplate('https://{hostname}/{version}/organizations/{org}/environments/{env_name}/keyvaluemaps/{map_name}/entries/{entry_name}')
    return t.expand(
        hostname    = config_data['hostname'],
        version     = config_data['version'],
        org         = config_data['org'],
        env_name    = config_data['env_name'],
        map_name    = config_data['map_name'],
        entry_name  = config_data['entry_name']
    )
class BibliographicUserRecordsSearchLinksSchemaV1(SearchLinksSchema):
    """User Record Links schema."""

    self = Link(template=URITemplate("/api/user/records{?params*}"),
                permission="search",
                params=search_link_params(0))
    prev = Link(template=URITemplate("/api/user/records{?params*}"),
                permission="search",
                params=search_link_params(-1),
                when=search_link_when(-1))
    next = Link(template=URITemplate("/api/user/records{?params*}"),
                permission="search",
                params=search_link_params(+1),
                when=search_link_when(+1))
Example #26
0
class BibliographicRecordLinksSchemaV1(RecordLinksSchema):
    """Record Links schema."""

    # WARNING: It was intentionally decided that if
    #          config.py::RECORDS_UI_ENDPOINTS is changed by the instance,
    #          the instance also needs to overwrite this Schema (in the
    #          links_config)
    self_html = Link(template=URITemplate("/records/{pid_value}"),
                     permission="read",
                     params=lambda record: {'pid_value': record.pid.pid_value})

    files = Link(template=URITemplate("/api/records/{pid_value}/files"),
                 permission="read",
                 params=lambda record: {'pid_value': record.pid.pid_value})
    def test_expand(self):
        """
        This test ensures that expansion works as expected.
        """
        # Single
        t = URITemplate("https://api.github.com/users{/user}")
        expanded = "https://api.github.com/users/sigmavirus24"
        self.assertEqual(t.expand(user="******"), expanded)
        v = t.variables[0]
        self.assertEqual(v.expand({"user": None}), {"/user": ""})

        # Multiple
        t = URITemplate("https://api.github.com/users{/user}{/repo}")
        expanded = "https://api.github.com/users/sigmavirus24/github3.py"
        self.assertEqual(t.expand({"repo": "github3.py"}, user="******"), expanded)
Example #28
0
 def test_multi_path_matcher(self):
     template = URITemplate('{/path*}')
     url = '/one%2Ctwo%2Cthree/some/path'
     result = match(template, url)
     self.assertEqual({
         'path': ['one%2Ctwo%2Cthree', 'some', 'path'],
     }, result)
Example #29
0
 def _update_attributes(self, issue):
     self._api = issue["url"]
     self.assignee = issue["assignee"]
     if self.assignee:
         self.assignee = users.ShortUser(self.assignee, self)
     self.assignees = issue["assignees"]
     if self.assignees:
         self.assignees = [
             users.ShortUser(assignee, self) for assignee in self.assignees
         ]
     self.body = issue["body"]
     self.closed_at = self._strptime(issue["closed_at"])
     self.comments_count = issue["comments"]
     self.comments_url = issue["comments_url"]
     self.created_at = self._strptime(issue["created_at"])
     self.events_url = issue["events_url"]
     self.html_url = issue["html_url"]
     self.id = issue["id"]
     self.labels_urlt = URITemplate(issue["labels_url"])
     self.locked = issue["locked"]
     self.milestone = issue["milestone"]
     if self.milestone:
         self.milestone = milestone.Milestone(self.milestone, self)
     self.number = issue["number"]
     self.original_labels = issue["labels"]
     if self.original_labels:
         self.original_labels = [
             label.ShortLabel(lbl, self) for lbl in self.original_labels
         ]
     self.pull_request_urls = issue.get("pull_request")
     self.state = issue["state"]
     self.title = issue["title"]
     self.updated_at = self._strptime(issue["updated_at"])
     self.user = users.ShortUser(issue["user"], self)
class RecordLinksSchema(Schema):
    """Schema for a record's links."""

    # NOTE:
    #   - /api prefix is needed here because above are mounted on /api
    self_ = Link(
        template=URITemplate("/api/mocks/{pid_value}"),
        permission="read",
        params=lambda record: {'pid_value': record.pid.pid_value},
        data_key="self"  # To avoid using self since is python reserved key
    )
    files = Link(
        template=URITemplate("/api/mocks/{pid_value}/files"),
        permission="read",
        params=lambda record: {'pid_value': record.pid.pid_value},
    )
Example #31
0
 def test_single_path_matcher(self):
     template = URITemplate('{/count}')
     url = '/root/foo/bar'
     result = match(template, url)
     # nothing because additional path segment separator which does
     # not match.
     self.assertIsNone(result)
Example #32
0
    def reverse(self, lon=None, lat=None, types=None):
        """Returns a Requests response object that contains a GeoJSON
        collection of places near the given longitude and latitude.

        `response.geojson()` returns the geocoding result as GeoJSON.
        `response.status_code` returns the HTTP API status code.

        See: https://www.mapbox.com/api-documentation/#retrieve-places-near-a-location."""
        uri = URITemplate(self.baseuri + '/{dataset}/{lon},{lat}.json').expand(
            dataset=self.name,
            lon=str(round(float(lon), self.precision.get('reverse', 5))),
            lat=str(round(float(lat), self.precision.get('reverse', 5))))
        params = {}
        if types:
            params.update(self._validate_place_types(types))
        resp = self.session.get(uri, params=params)
        self.handle_http_error(resp)

        # for consistency with other services
        def geojson():
            return resp.json()

        resp.geojson = geojson

        return resp
Example #33
0
 def test_str_repr(self):
     uri = 'https://api.github.com{/endpoint}'
     t = URITemplate(uri)
     self.assertEqual(str(t), uri)
     self.assertEqual(str(t.variables[0]), '/endpoint')
     self.assertEqual(repr(t), 'URITemplate("%s")' % uri)
     self.assertEqual(repr(t.variables[0]), 'URIVariable(/endpoint)')
Example #34
0
 def __init__(self, release, session=None):
     super(Release, self).__init__(release, session)
     self._api = release.get('url')
     #: List of :class:`Asset <Asset>` objects for this release
     self.assets = [Asset(i, self) for i in release.get('assets', [])]
     #: URL for uploaded assets
     self.assets_url = release.get('assets_url')
     #: Body of the release (the description)
     self.body = release.get('body')
     #: Date the release was created
     self.created_at = self._strptime(release.get('created_at'))
     #: Boolean whether value is True or False
     self.draft = release.get('draft')
     #: HTML URL of the release
     self.html_url = release.get('html_url')
     #: GitHub id
     self.id = release.get('id')
     #: Name given to the release
     self.name = release.get('name')
     #; Boolean whether release is a prerelease
     self.prerelease = release.get('prerelease')
     #: Date the release was published
     self.published_at = self._strptime(release.get('published_at'))
     #: Name of the tag
     self.tag_name = release.get('tag_name')
     #: "Commit" that this release targets
     self.target_commitish = release.get('target_commitish')
     upload_url = release.get('upload_url')
     #: URITemplate to upload an asset with
     self.upload_urlt = URITemplate(upload_url) if upload_url else None
Example #35
0
class Link:
    """Utility class for keeping track of and resolve links."""

    def __init__(self, uritemplate, when=None, vars=None):
        """Constructor."""
        self._uritemplate = URITemplate(uritemplate)
        self._when_func = when
        self._vars_func = vars

    def should_render(self, obj, ctx):
        """Determine if the link should be rendered."""
        if self._when_func:
            return bool(self._when_func(obj, ctx))
        return True

    @staticmethod
    def vars(obj, vars):
        """Subclasses can overwrite this method."""
        pass

    def expand(self, obj, context):
        """Expand the URI Template."""
        vars = {}
        vars.update(deepcopy(context))
        self.vars(obj, vars)
        if self._vars_func:
            self._vars_func(obj, vars)
        vars = preprocess_vars(vars)
        return self._uritemplate.expand(**vars)
    def test_expand(self):
        """
        This test ensures that expansion works as expected.
        """
        # Single
        t = URITemplate('https://api.github.com/users{/user}')
        expanded = 'https://api.github.com/users/sigmavirus24'
        self.assertEqual(t.expand(user='******'), expanded)
        v = t.variables[0]
        self.assertEqual(v.expand({'user': None}), {'/user': ''})

        # Multiple
        t = URITemplate('https://api.github.com/users{/user}{/repo}')
        expanded = 'https://api.github.com/users/sigmavirus24/github3.py'
        self.assertEqual(
            t.expand({'repo': 'github3.py'}, user='******'),
            expanded
        )
Example #37
0
 def _update_attributes(self, user):
     self.avatar_url = user["avatar_url"]
     self.events_urlt = URITemplate(user["events_url"])
     self.followers_url = user["followers_url"]
     self.following_urlt = URITemplate(user["following_url"])
     self.gists_urlt = URITemplate(user["gists_url"])
     self.gravatar_id = user["gravatar_id"]
     self.html_url = user["html_url"]
     self.id = user["id"]
     self.login = user["login"]
     self.organizations_url = user["organizations_url"]
     self.received_events_url = user["received_events_url"]
     self.repos_url = user["repos_url"]
     self.site_admin = user.get("site_admin")
     self.starred_urlt = URITemplate(user["starred_url"])
     self.subscriptions_url = user["subscriptions_url"]
     self.type = user["type"]
     self.url = self._api = user["url"]
     self._uniq = self.id
Example #38
0
 def _update_attributes(self, release):
     self._api = self.url = release["url"]
     self.original_assets = [Asset(i, self) for i in release["assets"]]
     self.assets_url = release["assets_url"]
     self.author = users.ShortUser(release["author"], self)
     self.body = release["body"]
     self.created_at = self._strptime(release["created_at"])
     self.draft = release["draft"]
     self.html_url = release["html_url"]
     self.id = release["id"]
     self.name = release["name"]
     self.prerelease = release["prerelease"]
     self.published_at = self._strptime(release["published_at"])
     self.tag_name = release["tag_name"]
     self.tarball_url = release["tarball_url"]
     self.target_commitish = release["target_commitish"]
     self.upload_urlt = URITemplate(release["upload_url"])
     self.zipball_url = release["zipball_url"]
Example #39
0
class PriceURL:
    """ PriceURl implements an easily readible, funcational, and modifiable URL for retreiving prices
    :param item_type:
    :param item_number:
    :param  =color_id:
    
    Usage:
        url_template = PriceURL()
        uri = url_template.expand(item_type=itemtypeID, item_number=itemID, color_id=itemColorID)
        'https://www.bricklink.com/catalogPG.asp?P=3004&colorID=8'
    """

    url = ('https://www.bricklink.com/catalogPG.asp?'
           '{item_type} = {item_number} &'
           'colorID = {color_id}'
           )

    def __init__(self):
        self.raw_url = PriceURL.url.replace(" ", "")  # Spaces improved readability
        self.url_template = URITemplate(self.raw_url)

    def expand(self, itemtypeID, itemID, itemColorID):
        self.url = self.url_template.expand(item_type=itemtypeID, item_number=itemID, color_id=itemColorID)
        return self.url
Example #40
0
class User(BaseAccount):

    """The :class:`User <User>` object. This handles and structures information
    in the `User section <http://developer.github.com/v3/users/>`_.

    Two user instances can be checked like so::

        u1 == u2
        u1 != u2

    And is equivalent to::

        u1.id == u2.id
        u1.id != u2.id

    """

    def __init__(self, user, session=None):
        super(User, self).__init__(user, session)
        if not self.type:
            self.type = 'User'

        #: ID of the user's image on Gravatar
        self.gravatar_id = user.get('gravatar_id', '')
        #: True -- for hire, False -- not for hire
        self.hireable = user.get('hireable', False)

        ## The number of public_gists
        #: Number of public gists
        self.public_gists = user.get('public_gists', 0)

        # Private information
        #: How much disk consumed by the user
        self.disk_usage = user.get('disk_usage', 0)

        #: Number of private repos owned by this user
        self.owned_private_repos = user.get('owned_private_repos', 0)
        #: Number of private gists owned by this user
        self.total_private_gists = user.get('total_private_gists', 0)
        #: Total number of private repos
        self.total_private_repos = user.get('total_private_repos', 0)

        #: Which plan this user is on
        self.plan = Plan(user.get('plan', {}))

        events_url = user.get('events_url', '')
        #: Events URL Template. Expands with ``privacy``
        self.events_urlt = URITemplate(events_url) if events_url else None

        #: Followers URL (not a template)
        self.followers_url = user.get('followers_url', '')

        furl = user.get('following_url', '')
        #: Following URL Template. Expands with ``other_user``
        self.following_urlt = URITemplate(furl) if furl else None

        gists_url = user.get('gists_url', '')
        #: Gists URL Template. Expands with ``gist_id``
        self.gists_urlt = URITemplate(gists_url) if gists_url else None

        #: Organizations URL (not a template)
        self.organizations_url = user.get('organizations_url', '')

        #: Received Events URL (not a template)
        self.received_events_url = user.get('received_events_url', '')

        #: Repostories URL (not a template)
        self.repos_url = user.get('repos_url', '')

        starred_url = user.get('starred_url', '')
        #: Starred URL Template. Expands with ``owner`` and ``repo``
        self.starred_urlt = URITemplate(starred_url) if starred_url else None

        #: Subscriptions URL (not a template)
        self.subscriptions_url = user.get('subscriptions_url', '')

    def __str__(self):
        return self.login

    def _update_(self, user):
        self.__init__(user, self._session)

    @requires_auth
    def add_email_address(self, address):
        """Add the single email address to the authenticated user's
        account.

        :param str address: (required), email address to add
        :returns: list of email addresses
        """
        return self.add_email_addresses([address])

    @requires_auth
    def add_email_addresses(self, addresses=[]):
        """Add the email addresses in ``addresses`` to the authenticated
        user's account.

        :param list addresses: (optional), email addresses to be added
        :returns: list of email addresses
        """
        json = []
        if addresses:
            url = self._build_url('user', 'emails')
            json = self._json(self._post(url, data=addresses), 201)
        return json

    @requires_auth
    def delete_email_address(self, address):
        """Delete the email address from the user's account.

        :param str address: (required), email address to delete
        :returns: bool
        """
        return self.delete_email_addresses([address])

    @requires_auth
    def delete_email_addresses(self, addresses=[]):
        """Delete the email addresses in ``addresses`` from the
        authenticated user's account.

        :param list addresses: (optional), email addresses to be removed
        :returns: bool
        """
        url = self._build_url('user', 'emails')
        return self._boolean(self._delete(url, data=dumps(addresses)),
                             204, 404)

    def is_assignee_on(self, login, repository):
        """Checks if this user can be assigned to issues on login/repository.

        :returns: :class:`bool`
        """
        url = self._build_url('repos', login, repository, 'assignees',
                              self.login)
        return self._boolean(self._get(url), 204, 404)

    def is_following(self, login):
        """Checks if this user is following ``login``.

        :param str login: (required)
        :returns: bool

        """
        url = self.following_urlt.expand(other_user=login)
        return self._boolean(self._get(url), 204, 404)

    def iter_events(self, public=False, number=-1, etag=None):
        """Iterate over events performed by this user.

        :param bool public: (optional), only list public events for the
            authenticated user
        :param int number: (optional), number of events to return. Default: -1
            returns all available events.
        :param str etag: (optional), ETag from a previous request to the same
            endpoint
        :returns: list of :class:`Event <github3.events.Event>`\ s
        """
        path = ['events']
        if public:
            path.append('public')
        url = self._build_url(*path, base_url=self._api)
        return self._iter(int(number), url, Event, etag=etag)

    def iter_followers(self, number=-1, etag=None):
        """Iterate over the followers of this user.

        :param int number: (optional), number of followers to return. Default:
            -1 returns all available
        :param str etag: (optional), ETag from a previous request to the same
            endpoint
        :returns: generator of :class:`User <User>`\ s
        """
        url = self._build_url('followers', base_url=self._api)
        return self._iter(int(number), url, User, etag=etag)

    def iter_following(self, number=-1, etag=None):
        """Iterate over the users being followed by this user.

        :param int number: (optional), number of users to return. Default: -1
            returns all available users
        :param str etag: (optional), ETag from a previous request to the same
            endpoint
        :returns: generator of :class:`User <User>`\ s
        """
        url = self._build_url('following', base_url=self._api)
        return self._iter(int(number), url, User, etag=etag)

    def iter_keys(self, number=-1, etag=None):
        """Iterate over the public keys of this user.

        .. versionadded:: 0.5

        :param int number: (optional), number of keys to return. Default: -1
            returns all available keys
        :param str etag: (optional), ETag from a previous request to the same
            endpoint
        :returns: generator of :class:`Key <Key>`\ s
        """
        url = self._build_url('keys', base_url=self._api)
        return self._iter(int(number), url, Key, etag=etag)

    def iter_org_events(self, org, number=-1, etag=None):
        """Iterate over events as they appear on the user's organization
        dashboard. You must be authenticated to view this.

        :param str org: (required), name of the organization
        :param int number: (optional), number of events to return. Default: -1
            returns all available events
        :param str etag: (optional), ETag from a previous request to the same
            endpoint
        :returns: list of :class:`Event <github3.events.Event>`\ s
        """
        url = ''
        if org:
            url = self._build_url('events', 'orgs', org, base_url=self._api)
        return self._iter(int(number), url, Event, etag=etag)

    def iter_received_events(self, public=False, number=-1, etag=None):
        """Iterate over events that the user has received. If the user is the
        authenticated user, you will see private and public events, otherwise
        you will only see public events.

        :param bool public: (optional), determines if the authenticated user
            sees both private and public or just public
        :param int number: (optional), number of events to return. Default: -1
            returns all events available
        :param str etag: (optional), ETag from a previous request to the same
            endpoint
        :returns: generator of :class:`Event <github3.events.Event>`\ s
        """
        path = ['received_events']
        if public:
            path.append('public')
        url = self._build_url(*path, base_url=self._api)
        return self._iter(int(number), url, Event, etag=etag)

    def iter_starred(self, sort=None, direction=None, number=-1, etag=None):
        """Iterate over repositories starred by this user.

        .. versionchanged:: 0.5
           Added sort and direction parameters (optional) as per the change in
           GitHub's API.

        :param int number: (optional), number of starred repos to return.
            Default: -1, returns all available repos
        :param str sort: (optional), either 'created' (when the star was
            created) or 'updated' (when the repository was last pushed to)
        :param str direction: (optional), either 'asc' or 'desc'. Default:
            'desc'
        :param str etag: (optional), ETag from a previous request to the same
            endpoint
        :returns: generator of :class:`Repository <github3.repos.Repository>`
        """
        from github3.repos import Repository

        params = {'sort': sort, 'direction': direction}
        self._remove_none(params)
        url = self.starred_urlt.expand(owner=None, repo=None)
        return self._iter(int(number), url, Repository, params, etag)

    def iter_subscriptions(self, number=-1, etag=None):
        """Iterate over repositories subscribed to by this user.

        :param int number: (optional), number of subscriptions to return.
            Default: -1, returns all available
        :param str etag: (optional), ETag from a previous request to the same
            endpoint
        :returns: generator of :class:`Repository <github3.repos.Repository>`
        """
        from github3.repos import Repository
        url = self._build_url('subscriptions', base_url=self._api)
        return self._iter(int(number), url, Repository, etag=etag)

    @requires_auth
    def update(self, name=None, email=None, blog=None, company=None,
               location=None, hireable=False, bio=None):
        """If authenticated as this user, update the information with
        the information provided in the parameters.

        :param str name: e.g., 'John Smith', not login name
        :param str email: e.g., '*****@*****.**'
        :param str blog: e.g., 'http://www.example.com/jsmith/blog'
        :param str company:
        :param str location:
        :param bool hireable: defaults to False
        :param str bio: GitHub flavored markdown
        :returns: bool
        """
        user = {'name': name, 'email': email, 'blog': blog,
                'company': company, 'location': location,
                'hireable': hireable, 'bio': bio}
        self._remove_none(user)
        url = self._build_url('user')
        json = self._json(self._patch(url, data=dumps(user)), 200)
        if json:
            self._update_(json)
            return True
        return False
Example #41
0
 def __init__(self):
     self.raw_url = PriceURL.url.replace(" ", "")  # Spaces improved readability
     self.url_template = URITemplate(self.raw_url)
Example #42
0
class Release(GitHubCore):

    """The :class:`Release <Release>` object.

    It holds the information GitHub returns about a release from a
    :class:`Repository <github3.repos.repo.Repository>`.

    """

    CUSTOM_HEADERS = {'Accept': 'application/vnd.github.manifold-preview'}

    def _update_attributes(self, release):
        self._api = release.get('url')
        #: List of :class:`Asset <Asset>` objects for this release
        self.original_assets = [
            Asset(i, self) for i in release.get('assets', [])
        ]
        #: URL for uploaded assets
        self.assets_url = release.get('assets_url')
        #: Body of the release (the description)
        self.body = release.get('body')
        #: Date the release was created
        self.created_at = self._strptime(release.get('created_at'))
        #: Boolean whether value is True or False
        self.draft = release.get('draft')
        #: HTML URL of the release
        self.html_url = release.get('html_url')
        #: GitHub id
        self.id = release.get('id')
        #: Name given to the release
        self.name = release.get('name')
        #: Boolean whether release is a prerelease
        self.prerelease = release.get('prerelease')
        #: Date the release was published
        self.published_at = self._strptime(release.get('published_at'))
        #: Name of the tag
        self.tag_name = release.get('tag_name')
        #: URL to download a tarball of the release
        self.tarball_url = release.get('tarball_url')
        #: "Commit" that this release targets
        self.target_commitish = release.get('target_commitish')
        upload_url = release.get('upload_url')
        #: URITemplate to upload an asset with
        self.upload_urlt = URITemplate(upload_url) if upload_url else None
        #: URL to download a zipball of the release
        self.zipball_url = release.get('zipball_url')

    def _repr(self):
        return '<Release [{0}]>'.format(self.name)

    def archive(self, format, path=''):
        """Get the tarball or zipball archive for this release.

        :param str format: (required), accepted values: ('tarball',
            'zipball')
        :param path: (optional), path where the file should be saved
            to, default is the filename provided in the headers and will be
            written in the current directory.
            it can take a file-like object as well
        :type path: str, file
        :returns: bool -- True if successful, False otherwise

        """
        resp = None
        if format in ('tarball', 'zipball'):
            repo_url = self._api[:self._api.rfind('/releases')]
            url = self._build_url(format, self.tag_name, base_url=repo_url)
            resp = self._get(url, allow_redirects=True, stream=True)

        if resp and self._boolean(resp, 200, 404):
            utils.stream_response_to_file(resp, path)
            return True
        return False

    def asset(self, asset_id):
        """Retrieve the asset from this release with ``asset_id``.

        :param int asset_id: ID of the Asset to retrieve
        :returns: :class:`~github3.repos.release.Asset`
        """
        json = None
        if int(asset_id) > 0:
            i = self._api.rfind('/')
            url = self._build_url('assets', str(asset_id),
                                  base_url=self._api[:i])
            json = self._json(self._get(url), 200)
        return self._instance_or_null(Asset, json)

    def assets(self, number=-1, etag=None):
        """Iterate over the assets available for this release.

        :param int number: (optional), Number of assets to return
        :param str etag: (optional), last ETag header sent
        :returns: generator of :class:`Asset <Asset>` objects
        """
        url = self._build_url('assets', base_url=self._api)
        return self._iter(number, url, Asset, etag=etag)

    @requires_auth
    def delete(self):
        """Users with push access to the repository can delete a release.

        :returns: True if successful; False if not successful
        """
        url = self._api
        return self._boolean(
            self._delete(url, headers=Release.CUSTOM_HEADERS),
            204,
            404
        )

    @requires_auth
    def edit(self, tag_name=None, target_commitish=None, name=None, body=None,
             draft=None, prerelease=None):
        """Users with push access to the repository can edit a release.

        If the edit is successful, this object will update itself.

        :param str tag_name: (optional), Name of the tag to use
        :param str target_commitish: (optional), The "commitish" value that
            determines where the Git tag is created from. Defaults to the
            repository's default branch.
        :param str name: (optional), Name of the release
        :param str body: (optional), Description of the release
        :param boolean draft: (optional), True => Release is a draft
        :param boolean prerelease: (optional), True => Release is a prerelease
        :returns: True if successful; False if not successful
        """
        url = self._api
        data = {
            'tag_name': tag_name,
            'target_commitish': target_commitish,
            'name': name,
            'body': body,
            'draft': draft,
            'prerelease': prerelease,
        }
        self._remove_none(data)

        r = self.session.patch(
            url, data=json.dumps(data), headers=Release.CUSTOM_HEADERS
        )

        successful = self._boolean(r, 200, 404)
        if successful:
            # If the edit was successful, let's update the object.
            self._update_attributes(r.json())

        return successful

    @requires_auth
    def upload_asset(self, content_type, name, asset, label=None):
        """Upload an asset to this release.

        All parameters are required.

        :param str content_type: The content type of the asset. Wikipedia has
            a list of common media types
        :param str name: The name of the file
        :param asset: The file or bytes object to upload.
        :param label: (optional), An alternate short description of the asset.
        :returns: :class:`Asset <Asset>`
        """
        headers = {'Content-Type': content_type}
        params = {'name': name, 'label': label}
        self._remove_none(params)
        url = self.upload_urlt.expand(params)
        r = self._post(url, data=asset, json=False, headers=headers)
        if r.status_code in (201, 202):
            return Asset(r.json(), self)
        raise error_for(r)
Example #43
0
def main(argv):
    try:
        parser = argparse.ArgumentParser(description="Arma Automatic Publishing Script")
        parser.add_argument('manifest', type=argparse.FileType('r'), help='manifest json file')
        parser.add_argument('-r', '--release_target', type=str, help="the name of the release target in the manifest file.", default="release")
        parser.add_argument('-v', '--version', type=str, help="the version of the release archive.", default="")

        args = parser.parse_args()

        manifest_file = args.manifest
        release_target = args.release_target
        version = args.version.split(".")

        manifest = json.load(manifest_file)
        if version == "":
            version = get_project_version("..\\addons\\\main\\script_version.hpp")

        if(not "CBA_PUBLISH_CREDENTIALS_PATH" in os.environ):
            raise Exception("CBA_PUBLISH_CREDENTIALS_PATH is not set in the environment")

        credentials_path = os.environ["CBA_PUBLISH_CREDENTIALS_PATH"]


        for destination in manifest['publish'][release_target]['destinations']:

            if(destination["type"] == "steam"):
                cred_file = json.load(open(os.path.join(credentials_path, destination["cred_file"])))
                if("username" in cred_file and "password" in cred_file):
                    steam_username = cred_file["username"]
                    steam_password = cred_file["password"]

                    start_steam_with_user(steam_username, steam_password)
                else:
                    raise Exception("Credentials file did not specify a username and password for Steam login")
                if(not "project_id" in destination):
                    raise Exception("Steam Publish","No project ID defined in manifest for Steam publish")
                project_id = destination["project_id"]

                if(not "release_dir" in destination):
                    raise Exception("Steam Publish","No release directory defined in manifest for Steam publish")
                release_dir = destination["release_dir"]

                if(not "steam_changelog" in destination):
                    raise Exception("Steam Publish","No steam changelog defined in manifest for Steam publish")
                steam_changelog = destination["steam_changelog"]

                steam_publish_folder(release_dir, project_id, version, steam_changelog)
                close_steam()
            if(destination["type"] == "sftp"):
                cred_file = json.load(open(os.path.join(credentials_path, destination["cred_file"])))
                if("username" in cred_file and "password" in cred_file):
                    sftp_username = cred_file["username"]
                    sftp_password = cred_file["password"]
                else:
                    raise Exception("Credentials file did not specify a username and password for SFTP login")

                if(not "hostname" in destination):
                    raise Exception("SFTP Publish","No hostname was defined for the SFTP site.")
                hostname = destination["hostname"]

                if(not "local_path" in destination):
                    raise Exception("SFTP Publish","No local path was defined for the SFTP upload.")
                local_path = destination["local_path"]

                if(not "remote_path" in destination):
                    raise Exception("SFTP Publish","No remote path was defined for the SFTP upload.")
                remote_path = destination["remote_path"]


                cnopts = pysftp.CnOpts()
                cnopts.hostkeys = None
                sftp = pysftp.Connection(host=hostname, username=sftp_username, password=sftp_password, cnopts=cnopts)

                local_path = local_path.format(major=version[0], minor=version[1], patch=version[2], build=version[3])
                remote_path = remote_path.format(major=version[0], minor=version[1], patch=version[2], build=version[3])

                print("SFTP: Publishing {} to remote {}:{}".format(local_path, hostname, remote_path))

                sftp.put(local_path, remotepath=remote_path)
                print("SFTP: Upload Complete!")
            if(destination["type"] == "github"):

                account = destination["account"]
                tag_name = destination["tag_name"]
                branch = destination["branch"]
                name = destination["name"]
                body_file = destination["body_file"]
                local_path = destination["local_path"]
                prerelease = destination["prerelease"]
                asset_name = destination["asset_name"]

                tag_name = tag_name.format(major=version[0], minor=version[1], patch=version[2], build=version[3])
                name = name.format(major=version[0], minor=version[1], patch=version[2], build=version[3])
                asset_name = asset_name.format(major=version[0], minor=version[1], patch=version[2], build=version[3])
                local_path = local_path.format(major=version[0], minor=version[1], patch=version[2], build=version[3])

                release_text_file = open(body_file, mode='r')
                release_text = release_text_file.read()
                release_text_file.close()


                create_request = {
                    "tag_name": tag_name,
                    "target_commitish": branch,
                    "name": name,
                    "body": release_text,
                    "draft": False,
                    "prerelease": prerelease
                }

                github_token = os.environ["IDI_GITHUB_TOKEN"]

                release_string = json.dumps(create_request, separators=(',',':'))

                temp_dir = tempfile.mkdtemp()
                tmpname = os.path.join(temp_dir,"jsonpost")
                temp_file = open(tmpname, 'w')
                temp_file.write(release_string)
                temp_file.close()
                curl_string = ' '.join(["curl", '-s', '-H "Authorization: token {}"'.format(github_token), '-H "Content-Type: application/json"', "--request POST", "--data", '"@{}"'.format(tmpname).replace('\\','\\\\'), "https://api.github.com/repos/{}/releases".format(account)])

                print("Creating Github Release...")
                response = subprocess.check_output(curl_string)
                response_json = json.loads(response.decode("ascii"))
                shutil.rmtree(temp_dir)
                if("id" in response_json):
                    print("Github Release Created @ {}".format(response_json["url"]))
                    release_id = response_json["id"]
                    upload_url = response_json["upload_url"]

                    t = URITemplate(upload_url)
                    upload_url = t.expand(name=asset_name)


                    curl_string = ' '.join(["curl", '-s', '-H "Authorization: token {}"'.format(github_token),
                        '-H "Content-Type: application/zip"',
                        "--data-binary",
                        '"@{}"'.format(local_path),
                        upload_url])
                    print("Attaching Asset...")
                    response = subprocess.check_output(curl_string)
                    response_json = json.loads(response.decode("ascii"))
                    if("browser_download_url" in response_json):
                        print("Asset Attached @ {}".format(response_json["browser_download_url"]))
                    else:
                        print(response_json)
                        raise Exception("Github Publish","Failed to Attach Asset")

                else:
                    print(response_json)
                    raise Exception("Github Publish","Failed to Create Release")

    except Exception as e:
        print(e)
        sys.exit(1)
Example #44
0
class _User(models.GitHubCore):
    """The :class:`User <User>` object.

    This handles and structures information in the `User section`_.

    Two user instances can be checked like so::

        u1 == u2
        u1 != u2

    And is equivalent to::

        u1.id == u2.id
        u1.id != u2.id

    .. _User section:
        http://developer.github.com/v3/users/
    """

    class_name = "_User"

    def _update_attributes(self, user):
        self.avatar_url = user["avatar_url"]
        self.events_urlt = URITemplate(user["events_url"])
        self.followers_url = user["followers_url"]
        self.following_urlt = URITemplate(user["following_url"])
        self.gists_urlt = URITemplate(user["gists_url"])
        self.gravatar_id = user["gravatar_id"]
        self.html_url = user["html_url"]
        self.id = user["id"]
        self.login = user["login"]
        self.organizations_url = user["organizations_url"]
        self.received_events_url = user["received_events_url"]
        self.repos_url = user["repos_url"]
        self.site_admin = user.get("site_admin")
        self.starred_urlt = URITemplate(user["starred_url"])
        self.subscriptions_url = user["subscriptions_url"]
        self.type = user["type"]
        self.url = self._api = user["url"]
        self._uniq = self.id

    def __str__(self):
        return self.login

    def _repr(self):
        full_name = ""
        name = getattr(self, "name", None)
        if name is not None:
            full_name = ":{}".format(name)
        return "<{s.class_name} [{s.login}{full_name}]>".format(
            s=self, full_name=full_name
        )

    def is_assignee_on(self, username, repository):
        """Check if this user can be assigned to issues on username/repository.

        :param str username: owner's username of the repository
        :param str repository: name of the repository
        :returns: True if the use can be assigned, False otherwise
        :rtype: :class:`bool`
        """
        url = self._build_url(
            "repos", username, repository, "assignees", self.login
        )
        return self._boolean(self._get(url), 204, 404)

    def is_following(self, username):
        """Check if this user is following ``username``.

        :param str username: (required)
        :returns: bool

        """
        url = self.following_urlt.expand(other_user=username)
        return self._boolean(self._get(url), 204, 404)

    def events(self, public=False, number=-1, etag=None):
        r"""Iterate over events performed by this user.

        :param bool public: (optional), only list public events for the
            authenticated user
        :param int number: (optional), number of events to return. Default: -1
            returns all available events.
        :param str etag: (optional), ETag from a previous request to the same
            endpoint
        :returns: generator of :class:`Event <github3.events.Event>`\ s
        """
        path = ["events"]
        if public:
            path.append("public")
        url = self._build_url(*path, base_url=self._api)
        return self._iter(int(number), url, Event, etag=etag)

    def followers(self, number=-1, etag=None):
        r"""Iterate over the followers of this user.

        :param int number: (optional), number of followers to return. Default:
            -1 returns all available
        :param str etag: (optional), ETag from a previous request to the same
            endpoint
        :returns: generator of :class:`User <User>`\ s
        """
        url = self._build_url("followers", base_url=self._api)
        return self._iter(int(number), url, ShortUser, etag=etag)

    def following(self, number=-1, etag=None):
        r"""Iterate over the users being followed by this user.

        :param int number: (optional), number of users to return. Default: -1
            returns all available users
        :param str etag: (optional), ETag from a previous request to the same
            endpoint
        :returns: generator of :class:`User <User>`\ s
        """
        url = self._build_url("following", base_url=self._api)
        return self._iter(int(number), url, ShortUser, etag=etag)

    def gpg_keys(self, number=-1, etag=None):
        r"""Iterate over the GPG keys of this user.

        .. versionadded:: 1.2.0

        :param int number: (optional), number of GPG keys to return. Default:
            -1 returns all available GPG keys
        :param str etag: (optional), ETag from a previous request to the same
            endpoint
        :returns: generator of :class:`GPGKey <GPGKey>`\ s
        """
        url = self._build_url("gpg_keys", base_url=self._api)
        return self._iter(int(number), url, GPGKey, etag=etag)

    def keys(self, number=-1, etag=None):
        r"""Iterate over the public keys of this user.

        .. versionadded:: 0.5

        :param int number: (optional), number of keys to return. Default: -1
            returns all available keys
        :param str etag: (optional), ETag from a previous request to the same
            endpoint
        :returns: generator of :class:`Key <Key>`\ s
        """
        url = self._build_url("keys", base_url=self._api)
        return self._iter(int(number), url, Key, etag=etag)

    @requires_auth
    def organization_events(self, org, number=-1, etag=None):
        r"""Iterate over events from the user's organization dashboard.

        .. note:: You must be authenticated to view this.

        :param str org: (required), name of the organization
        :param int number: (optional), number of events to return. Default: -1
            returns all available events
        :param str etag: (optional), ETag from a previous request to the same
            endpoint
        :returns: generator of :class:`Event <github3.events.Event>`\ s
        """
        url = ""
        if org:
            url = self._build_url("events", "orgs", org, base_url=self._api)
        return self._iter(int(number), url, Event, etag=etag)

    def received_events(self, public=False, number=-1, etag=None):
        r"""Iterate over events that the user has received.

        If the user is the authenticated user, you will see private and public
        events, otherwise you will only see public events.

        :param bool public: (optional), determines if the authenticated user
            sees both private and public or just public
        :param int number: (optional), number of events to return. Default: -1
            returns all events available
        :param str etag: (optional), ETag from a previous request to the same
            endpoint
        :returns: generator of :class:`Event <github3.events.Event>`\ s
        """
        path = ["received_events"]
        if public:
            path.append("public")
        url = self._build_url(*path, base_url=self._api)
        return self._iter(int(number), url, Event, etag=etag)

    def organizations(self, number=-1, etag=None):
        r"""Iterate over organizations the user is member of.

        :param int number: (optional), number of organizations to return.
            Default: -1 returns all available organization
        :param str etag: (optional), ETag from a previous request to the same
            endpoint
        :returns: generator of
            :class:`ShortOrganization <github3.orgs.ShortOrganization>`\ s
        """
        # Import here, because a toplevel import causes an import loop
        from .orgs import ShortOrganization

        url = self._build_url("orgs", base_url=self._api)
        return self._iter(int(number), url, ShortOrganization, etag=etag)

    def starred_repositories(
        self, sort=None, direction=None, number=-1, etag=None
    ):
        """Iterate over repositories starred by this user.

        .. versionchanged:: 0.5
           Added sort and direction parameters (optional) as per the change in
           GitHub's API.

        :param int number: (optional), number of starred repos to return.
            Default: -1, returns all available repos
        :param str sort: (optional), either 'created' (when the star was
            created) or 'updated' (when the repository was last pushed to)
        :param str direction: (optional), either 'asc' or 'desc'. Default:
            'desc'
        :param str etag: (optional), ETag from a previous request to the same
            endpoint
        :returns: generator of :class:`~github3.repos.repo.StarredRepository`
        """
        from .repos import Repository, StarredRepository

        params = {"sort": sort, "direction": direction}
        self._remove_none(params)
        url = self.starred_urlt.expand(owner=None, repo=None)
        return self._iter(
            int(number),
            url,
            StarredRepository,
            params,
            etag,
            headers=Repository.STAR_HEADERS,
        )

    def subscriptions(self, number=-1, etag=None):
        """Iterate over repositories subscribed to by this user.

        :param int number: (optional), number of subscriptions to return.
            Default: -1, returns all available
        :param str etag: (optional), ETag from a previous request to the same
            endpoint
        :returns: generator of :class:`Repository <github3.repos.Repository>`
        """
        from .repos import ShortRepository

        url = self._build_url("subscriptions", base_url=self._api)
        return self._iter(int(number), url, ShortRepository, etag=etag)

    @requires_auth
    def rename(self, login):
        """Rename the user.

        .. note::

            This is only available for administrators of a GitHub Enterprise
            instance.

        :param str login: (required), new name of the user
        :returns: bool
        """
        url = self._build_url("admin", "users", self.login)
        payload = {"login": login}
        resp = self._boolean(self._patch(url, data=payload), 202, 403)
        return resp

    @requires_auth
    def impersonate(self, scopes=None):
        """Obtain an impersonation token for the user.

        The retrieved token will allow impersonation of the user.
        This is only available for admins of a GitHub Enterprise instance.

        :param list scopes: (optional), areas you want this token to apply to,
            i.e., 'gist', 'user'
        :returns: :class:`Authorization <Authorization>`
        """
        url = self._build_url("admin", "users", self.login, "authorizations")
        data = {}

        if scopes:
            data["scopes"] = scopes

        json = self._json(self._post(url, data=data), 201)

        return self._instance_or_null(Authorization, json)

    @requires_auth
    def revoke_impersonation(self):
        """Revoke all impersonation tokens for the current user.

        This is only available for admins of a GitHub Enterprise instance.

        :returns: bool -- True if successful, False otherwise
        """
        url = self._build_url("admin", "users", self.login, "authorizations")

        return self._boolean(self._delete(url), 204, 403)

    @requires_auth
    def promote(self):
        """Promote a user to site administrator.

        This is only available for admins of a GitHub Enterprise instance.

        :returns: bool -- True if successful, False otherwise
        """
        url = self._build_url("site_admin", base_url=self._api)

        return self._boolean(self._put(url), 204, 403)

    @requires_auth
    def demote(self):
        """Demote a site administrator to simple user.

        You can demote any user account except your own.

        This is only available for admins of a GitHub Enterprise instance.

        :returns: bool -- True if successful, False otherwise
        """
        url = self._build_url("site_admin", base_url=self._api)

        return self._boolean(self._delete(url), 204, 403)

    @requires_auth
    def suspend(self):
        """Suspend the user.

        This is only available for admins of a GitHub Enterprise instance.

        This API is disabled if you use LDAP, check the GitHub API dos for more
        information.

        :returns: bool -- True if successful, False otherwise
        """
        url = self._build_url("suspended", base_url=self._api)

        return self._boolean(self._put(url), 204, 403)

    @requires_auth
    def unsuspend(self):
        """Unsuspend the user.

        This is only available for admins of a GitHub Enterprise instance.

        This API is disabled if you use LDAP, check the GitHub API dos for more
        information.

        :returns: bool -- True if successful, False otherwise
        """
        url = self._build_url("suspended", base_url=self._api)

        return self._boolean(self._delete(url), 204, 403)

    @requires_auth
    def delete(self):
        """Delete the user.

        Per GitHub API documentation, it is often preferable to suspend the
        user.

        .. note::

            This is only available for admins of a GitHub Enterprise instance.

        :returns: bool -- True if successful, False otherwise
        """
        url = self._build_url("admin", "users", self.login)
        return self._boolean(self._delete(url), 204, 403)
Example #45
0
class Release(models.GitHubCore):
    """Representation of a GitHub release.

    It holds the information GitHub returns about a release from a
    :class:`Repository <github3.repos.repo.Repository>`.

    Please see GitHub's `Releases Documentation`_ for more information.

    This object has the following attributes:

    .. attribute:: original_assets

        A list of :class:`~github3.repos.release.Asset` objects representing
        the assets uploaded for this relesae.

    .. attribute:: assets_url

        The URL to retrieve the assets from the API.

    .. attribute:: author

        A :class:`~github3.users.ShortUser` representing the creator of this
        release.

    .. attribute:: body

        The description of this release as written by the release creator.

    .. attribute:: created_at

        A :class:`~datetime.datetime` object representing the date and time
        when this release was created.

    .. attribute:: draft

        A boolean attribute describing whether this release is a draft.

    .. attribute:: html_url

        The URL to view this release in a browser.

    .. attribute:: id

        The unique identifier of this release.

    .. attribute:: name

        The name given to this release by the :attr:`author`.

    .. attribute:: prerelease

        A boolean attribute indicating whether the release is a pre-release.

    .. attribute:: published_at

        A :class:`~datetime.datetime` object representing the date and time
        when this release was publisehd.

    .. attribute:: tag_name

        The name of the tag associated with this release.

    .. attribute:: tarball_url

        The URL to retrieve a GitHub generated tarball for this release from
        the API.

    .. attribute:: target_commitish

        The reference (usually a commit) that is targetted by this release.

    .. attribute:: upload_urlt

        A :class:`~uritemplate.URITemplate` object that expands to form the
        URL to upload assets to.

    .. attribute:: zipball_url

        The URL to retrieve a GitHub generated zipball for this release from
        the API.

    .. _Releases Documentation:
        https://developer.github.com/v3/repos/releases/
    """

    def _update_attributes(self, release):
        self._api = self.url = release["url"]
        self.original_assets = [Asset(i, self) for i in release["assets"]]
        self.assets_url = release["assets_url"]
        self.author = users.ShortUser(release["author"], self)
        self.body = release["body"]
        self.created_at = self._strptime(release["created_at"])
        self.draft = release["draft"]
        self.html_url = release["html_url"]
        self.id = release["id"]
        self.name = release["name"]
        self.prerelease = release["prerelease"]
        self.published_at = self._strptime(release["published_at"])
        self.tag_name = release["tag_name"]
        self.tarball_url = release["tarball_url"]
        self.target_commitish = release["target_commitish"]
        self.upload_urlt = URITemplate(release["upload_url"])
        self.zipball_url = release["zipball_url"]

    def _repr(self):
        return "<Release [{0}]>".format(self.name)

    def archive(self, format, path=""):
        """Get the tarball or zipball archive for this release.

        :param str format:
            (required), accepted values: ('tarball', 'zipball')
        :param path:
            (optional), path where the file should be saved to, default is the
            filename provided in the headers and will be written in the current
            directory. It can take a file-like object as well
        :type path:
            str, file
        :returns:
            True if successful, False otherwise
        :rtype:
            bool
        """
        resp = None
        if format in ("tarball", "zipball"):
            repo_url = self._api[: self._api.rfind("/releases")]
            url = self._build_url(format, self.tag_name, base_url=repo_url)
            resp = self._get(url, allow_redirects=True, stream=True)

        if resp and self._boolean(resp, 200, 404):
            utils.stream_response_to_file(resp, path)
            return True
        return False

    def asset(self, asset_id):
        """Retrieve the asset from this release with ``asset_id``.

        :param int asset_id:
            ID of the Asset to retrieve
        :returns:
            the specified asset, if it exists
        :rtype:
            :class:`~github3.repos.release.Asset`
        """
        json = None
        if int(asset_id) > 0:
            i = self._api.rfind("/")
            url = self._build_url(
                "assets", str(asset_id), base_url=self._api[:i]
            )
            json = self._json(self._get(url), 200)
        return self._instance_or_null(Asset, json)

    def assets(self, number=-1, etag=None):
        """Iterate over the assets available for this release.

        :param int number:
            (optional), Number of assets to return
        :param str etag:
            (optional), last ETag header sent
        :returns:
            generator of asset objects
        :rtype:
            :class:`~github3.repos.release.Asset`
        """
        url = self._build_url("assets", base_url=self._api)
        return self._iter(number, url, Asset, etag=etag)

    @requires_auth
    def delete(self):
        """Delete this release.

        Only users with push access to the repository can delete a release.

        :returns:
            True if successful; False if not successful
        :rtype:
            bool
        """
        url = self._api
        return self._boolean(self._delete(url), 204, 404)

    @requires_auth
    def edit(
        self,
        tag_name=None,
        target_commitish=None,
        name=None,
        body=None,
        draft=None,
        prerelease=None,
    ):
        """Edit this release.

        Only users with push access to the repository can edit a release.

        If the edit is successful, this object will update itself.

        :param str tag_name:
            (optional), Name of the tag to use
        :param str target_commitish:
            (optional), The "commitish" value that determines where the Git tag
            is created from. Defaults to the repository's default branch.
        :param str name:
            (optional), Name of the release
        :param str body:
            (optional), Description of the release
        :param boolean draft:
            (optional), True => Release is a draft
        :param boolean prerelease:
            (optional), True => Release is a prerelease
        :returns:
            True if successful; False if not successful
        :rtype:
            bool
        """
        url = self._api
        data = {
            "tag_name": tag_name,
            "target_commitish": target_commitish,
            "name": name,
            "body": body,
            "draft": draft,
            "prerelease": prerelease,
        }
        self._remove_none(data)

        r = self.session.patch(url, data=json.dumps(data))

        successful = self._boolean(r, 200, 404)
        if successful:
            # If the edit was successful, let's update the object.
            self._update_attributes(r.json())

        return successful

    @requires_auth
    def upload_asset(self, content_type, name, asset, label=None):
        """Upload an asset to this release.

        .. note:: All parameters are required.

        :param str content_type:
            The content type of the asset. Wikipedia has a list of common media
            types
        :param str name:
            The name of the file
        :param asset:
            The file or bytes object to upload.
        :param label:
            (optional), An alternate short description of the asset.
        :returns:
            the created asset
        :rtype:
            :class:`~github3.repos.release.Asset`
        """
        headers = {"Content-Type": content_type}
        params = {"name": name, "label": label}
        self._remove_none(params)
        url = self.upload_urlt.expand(params)
        r = self._post(url, data=asset, json=False, headers=headers)
        if r.status_code in (201, 202):
            return Asset(r.json(), self)
        raise error_for(r)
Example #46
0
    def _update_attributes(self, user):
        super(User, self)._update_attributes(user)
        if not self.type:
            self.type = 'User'

        #: ID of the user's image on Gravatar
        self.gravatar_id = user.get('gravatar_id', '')
        #: True -- for hire, False -- not for hire
        self.hireable = user.get('hireable', False)

        # The number of public_gists
        #: Number of public gists
        self.public_gists = user.get('public_gists', 0)

        # Private information
        #: How much disk consumed by the user
        self.disk_usage = user.get('disk_usage', 0)

        #: Number of private repos owned by this user
        self.owned_private_repos = user.get('owned_private_repos', 0)
        #: Number of private gists owned by this user
        self.total_private_gists = user.get('total_private_gists', 0)
        #: Total number of private repos
        self.total_private_repos = user.get('total_private_repos', 0)

        #: Which plan this user is on
        self.plan = Plan(user.get('plan', {}))

        events_url = user.get('events_url', '')
        #: Events URL Template. Expands with ``privacy``
        self.events_urlt = URITemplate(events_url) if events_url else None

        #: Followers URL (not a template)
        self.followers_url = user.get('followers_url', '')

        furl = user.get('following_url', '')
        #: Following URL Template. Expands with ``other_user``
        self.following_urlt = URITemplate(furl) if furl else None

        gists_url = user.get('gists_url', '')
        #: Gists URL Template. Expands with ``gist_id``
        self.gists_urlt = URITemplate(gists_url) if gists_url else None

        #: Organizations URL (not a template)
        self.organizations_url = user.get('organizations_url', '')

        #: Received Events URL (not a template)
        self.received_events_url = user.get('received_events_url', '')

        #: Repostories URL (not a template)
        self.repos_url = user.get('repos_url', '')

        starred_url = user.get('starred_url', '')
        #: Starred URL Template. Expands with ``owner`` and ``repo``
        self.starred_urlt = URITemplate(starred_url) if starred_url else None

        #: Subscriptions URL (not a template)
        self.subscriptions_url = user.get('subscriptions_url', '')

        #: Number of repo contributions. Only appears in ``repo.contributors``
        contributions = user.get('contributions')
        # The refresh method uses __init__ to replace the attributes on the
        # instance with what it receives from the /users/:username endpoint.
        # What that means is that contributions is no longer returned and as
        # such is changed because it doesn't exist. This guards against that.
        if contributions is not None:
            self.contributions = contributions

        self._uniq = user.get('id', None)
 def test_no_mutate(self):
     args = {}
     t = URITemplate('')
     t.expand(args, key=1)
     self.assertEqual(args, {})
Example #48
0
class User(BaseAccount):

    """The :class:`User <User>` object. This handles and structures information
    in the `User section <http://developer.github.com/v3/users/>`_.

    Two user instances can be checked like so::

        u1 == u2
        u1 != u2

    And is equivalent to::

        u1.id == u2.id
        u1.id != u2.id

    """

    def _update_attributes(self, user):
        super(User, self)._update_attributes(user)
        if not self.type:
            self.type = 'User'

        #: ID of the user's image on Gravatar
        self.gravatar_id = user.get('gravatar_id', '')
        #: True -- for hire, False -- not for hire
        self.hireable = user.get('hireable', False)

        # The number of public_gists
        #: Number of public gists
        self.public_gists = user.get('public_gists', 0)

        # Private information
        #: How much disk consumed by the user
        self.disk_usage = user.get('disk_usage', 0)

        #: Number of private repos owned by this user
        self.owned_private_repos = user.get('owned_private_repos', 0)
        #: Number of private gists owned by this user
        self.total_private_gists = user.get('total_private_gists', 0)
        #: Total number of private repos
        self.total_private_repos = user.get('total_private_repos', 0)

        #: Which plan this user is on
        self.plan = Plan(user.get('plan', {}))

        events_url = user.get('events_url', '')
        #: Events URL Template. Expands with ``privacy``
        self.events_urlt = URITemplate(events_url) if events_url else None

        #: Followers URL (not a template)
        self.followers_url = user.get('followers_url', '')

        furl = user.get('following_url', '')
        #: Following URL Template. Expands with ``other_user``
        self.following_urlt = URITemplate(furl) if furl else None

        gists_url = user.get('gists_url', '')
        #: Gists URL Template. Expands with ``gist_id``
        self.gists_urlt = URITemplate(gists_url) if gists_url else None

        #: Organizations URL (not a template)
        self.organizations_url = user.get('organizations_url', '')

        #: Received Events URL (not a template)
        self.received_events_url = user.get('received_events_url', '')

        #: Repostories URL (not a template)
        self.repos_url = user.get('repos_url', '')

        starred_url = user.get('starred_url', '')
        #: Starred URL Template. Expands with ``owner`` and ``repo``
        self.starred_urlt = URITemplate(starred_url) if starred_url else None

        #: Subscriptions URL (not a template)
        self.subscriptions_url = user.get('subscriptions_url', '')

        #: Number of repo contributions. Only appears in ``repo.contributors``
        contributions = user.get('contributions')
        # The refresh method uses __init__ to replace the attributes on the
        # instance with what it receives from the /users/:username endpoint.
        # What that means is that contributions is no longer returned and as
        # such is changed because it doesn't exist. This guards against that.
        if contributions is not None:
            self.contributions = contributions

        self._uniq = user.get('id', None)

    def __str__(self):
        return self.login

    @requires_auth
    def add_email_address(self, address):
        """Add the single email address to the authenticated user's
        account.

        :param str address: (required), email address to add
        :returns: list of email addresses
        """
        return self.add_email_addresses([address])

    @requires_auth
    def add_email_addresses(self, addresses=[]):
        """Add the email addresses in ``addresses`` to the authenticated
        user's account.

        :param list addresses: (optional), email addresses to be added
        :returns: list of email addresses
        """
        json = []
        if addresses:
            url = self._build_url('user', 'emails')
            json = self._json(self._post(url, data=addresses), 201)
        return json

    @requires_auth
    def delete_email_address(self, address):
        """Delete the email address from the user's account.

        :param str address: (required), email address to delete
        :returns: bool
        """
        return self.delete_email_addresses([address])

    @requires_auth
    def delete_email_addresses(self, addresses=[]):
        """Delete the email addresses in ``addresses`` from the
        authenticated user's account.

        :param list addresses: (optional), email addresses to be removed
        :returns: bool
        """
        url = self._build_url('user', 'emails')
        return self._boolean(self._delete(url, data=dumps(addresses)),
                             204, 404)

    def is_assignee_on(self, username, repository):
        """Check if this user can be assigned to issues on username/repository.

        :param str username: owner's username of the repository
        :param str repository: name of the repository
        :returns: True if the use can be assigned, False otherwise
        :rtype: :class:`bool`
        """
        url = self._build_url('repos', username, repository, 'assignees',
                              self.login)
        return self._boolean(self._get(url), 204, 404)

    def is_following(self, username):
        """Checks if this user is following ``username``.

        :param str username: (required)
        :returns: bool

        """
        url = self.following_urlt.expand(other_user=username)
        return self._boolean(self._get(url), 204, 404)

    def events(self, public=False, number=-1, etag=None):
        """Iterate over events performed by this user.

        :param bool public: (optional), only list public events for the
            authenticated user
        :param int number: (optional), number of events to return. Default: -1
            returns all available events.
        :param str etag: (optional), ETag from a previous request to the same
            endpoint
        :returns: generator of :class:`Event <github3.events.Event>`\ s
        """
        path = ['events']
        if public:
            path.append('public')
        url = self._build_url(*path, base_url=self._api)
        return self._iter(int(number), url, Event, etag=etag)

    def followers(self, number=-1, etag=None):
        """Iterate over the followers of this user.

        :param int number: (optional), number of followers to return. Default:
            -1 returns all available
        :param str etag: (optional), ETag from a previous request to the same
            endpoint
        :returns: generator of :class:`User <User>`\ s
        """
        url = self._build_url('followers', base_url=self._api)
        return self._iter(int(number), url, User, etag=etag)

    def following(self, number=-1, etag=None):
        """Iterate over the users being followed by this user.

        :param int number: (optional), number of users to return. Default: -1
            returns all available users
        :param str etag: (optional), ETag from a previous request to the same
            endpoint
        :returns: generator of :class:`User <User>`\ s
        """
        url = self._build_url('following', base_url=self._api)
        return self._iter(int(number), url, User, etag=etag)

    def keys(self, number=-1, etag=None):
        """Iterate over the public keys of this user.

        .. versionadded:: 0.5

        :param int number: (optional), number of keys to return. Default: -1
            returns all available keys
        :param str etag: (optional), ETag from a previous request to the same
            endpoint
        :returns: generator of :class:`Key <Key>`\ s
        """
        url = self._build_url('keys', base_url=self._api)
        return self._iter(int(number), url, Key, etag=etag)

    @requires_auth
    def organization_events(self, org, number=-1, etag=None):
        """Iterate over events as they appear on the user's organization
        dashboard. You must be authenticated to view this.

        :param str org: (required), name of the organization
        :param int number: (optional), number of events to return. Default: -1
            returns all available events
        :param str etag: (optional), ETag from a previous request to the same
            endpoint
        :returns: generator of :class:`Event <github3.events.Event>`\ s
        """
        url = ''
        if org:
            url = self._build_url('events', 'orgs', org, base_url=self._api)
        return self._iter(int(number), url, Event, etag=etag)

    def received_events(self, public=False, number=-1, etag=None):
        """Iterate over events that the user has received. If the user is the
        authenticated user, you will see private and public events, otherwise
        you will only see public events.

        :param bool public: (optional), determines if the authenticated user
            sees both private and public or just public
        :param int number: (optional), number of events to return. Default: -1
            returns all events available
        :param str etag: (optional), ETag from a previous request to the same
            endpoint
        :returns: generator of :class:`Event <github3.events.Event>`\ s
        """
        path = ['received_events']
        if public:
            path.append('public')
        url = self._build_url(*path, base_url=self._api)
        return self._iter(int(number), url, Event, etag=etag)

    def organizations(self, number=-1, etag=None):
        """Iterate over organizations the user is member of

        :param int number: (optional), number of organizations to return.
            Default: -1 returns all available organization
        :param str etag: (optional), ETag from a previous request to the same
            endpoint
        :returns: generator of :class:`Event <github3.orgs.Organization>`\ s
        """
        # Import here, because a toplevel import causes an import loop
        from .orgs import Organization
        url = self._build_url('orgs', base_url=self._api)
        return self._iter(int(number), url, Organization, etag=etag)

    def starred_repositories(self, sort=None, direction=None, number=-1,
                             etag=None):
        """Iterate over repositories starred by this user.

        .. versionchanged:: 0.5
           Added sort and direction parameters (optional) as per the change in
           GitHub's API.

        :param int number: (optional), number of starred repos to return.
            Default: -1, returns all available repos
        :param str sort: (optional), either 'created' (when the star was
            created) or 'updated' (when the repository was last pushed to)
        :param str direction: (optional), either 'asc' or 'desc'. Default:
            'desc'
        :param str etag: (optional), ETag from a previous request to the same
            endpoint
        :returns: generator of :class:`Repository <github3.repos.Repository>`
        """
        from .repos import Repository

        params = {'sort': sort, 'direction': direction}
        self._remove_none(params)
        url = self.starred_urlt.expand(owner=None, repo=None)
        return self._iter(int(number), url, Repository, params, etag)

    def subscriptions(self, number=-1, etag=None):
        """Iterate over repositories subscribed to by this user.

        :param int number: (optional), number of subscriptions to return.
            Default: -1, returns all available
        :param str etag: (optional), ETag from a previous request to the same
            endpoint
        :returns: generator of :class:`Repository <github3.repos.Repository>`
        """
        from .repos import Repository
        url = self._build_url('subscriptions', base_url=self._api)
        return self._iter(int(number), url, Repository, etag=etag)
Example #49
0
class Release(GitHubCore):

    """The :class:`Release <Release>` object.

    It holds the information GitHub returns about a release from a
    :class:`Repository <github3.repos.repo.Repository>`.

    """

    CUSTOM_HEADERS = {'Accept': 'application/vnd.github.manifold-preview'}

    def __init__(self, release, session=None):
        super(Release, self).__init__(release, session)
        self._api = release.get('url')
        #: List of :class:`Asset <Asset>` objects for this release
        self.assets = [Asset(i, self) for i in release.get('assets', [])]
        #: URL for uploaded assets
        self.assets_url = release.get('assets_url')
        #: Body of the release (the description)
        self.body = release.get('body')
        #: Date the release was created
        self.created_at = self._strptime(release.get('created_at'))
        #: Boolean whether value is True or False
        self.draft = release.get('draft')
        #: HTML URL of the release
        self.html_url = release.get('html_url')
        #: GitHub id
        self.id = release.get('id')
        #: Name given to the release
        self.name = release.get('name')
        #; Boolean whether release is a prerelease
        self.prerelease = release.get('prerelease')
        #: Date the release was published
        self.published_at = self._strptime(release.get('published_at'))
        #: Name of the tag
        self.tag_name = release.get('tag_name')
        #: "Commit" that this release targets
        self.target_commitish = release.get('target_commitish')
        upload_url = release.get('upload_url')
        #: URITemplate to upload an asset with
        self.upload_urlt = URITemplate(upload_url) if upload_url else None

    def _repr(self):
        return '<Release [{0}]>'.format(self.name)

    @requires_auth
    def delete(self):
        """Users with push access to the repository can delete a release.

        :returns: True if successful; False if not successful
        """
        url = self._api
        return self._boolean(
            self._delete(url, headers=Release.CUSTOM_HEADERS),
            204,
            404
        )

    @requires_auth
    def edit(self, tag_name=None, target_commitish=None, name=None, body=None,
             draft=None, prerelease=None):
        """Users with push access to the repository can edit a release.

        If the edit is successful, this object will update itself.

        :param str tag_name: (optional), Name of the tag to use
        :param str target_commitish: (optional), The "commitish" value that
            determines where the Git tag is created from. Defaults to the
            repository's default branch.
        :param str name: (optional), Name of the release
        :param str body: (optional), Description of the release
        :param boolean draft: (optional), True => Release is a draft
        :param boolean prerelease: (optional), True => Release is a prerelease
        :returns: True if successful; False if not successful
        """
        url = self._api
        data = {
            'tag_name': tag_name,
            'target_commitish': target_commitish,
            'name': name,
            'body': body,
            'draft': draft,
            'prerelease': prerelease,
        }
        self._remove_none(data)

        r = self._session.patch(
            url, data=json.dumps(data), headers=Release.CUSTOM_HEADERS
        )

        successful = self._boolean(r, 200, 404)
        if successful:
            # If the edit was successful, let's update the object.
            self.__init__(r.json(), self)

        return successful

    def iter_assets(self, number=-1, etag=None):
        """Iterate over the assets available for this release.

        :param int number: (optional), Number of assets to return
        :param str etag: (optional), last ETag header sent
        :returns: generator of :class:`Asset <Asset>` objects
        """
        url = self._build_url('assets', base_url=self._api)
        return self._iter(number, url, Asset, etag=etag)

    @requires_auth
    def upload_asset(self, content_type, name, asset):
        """Upload an asset to this release.

        All parameters are required.

        :param str content_type: The content type of the asset. Wikipedia has
            a list of common media types
        :param str name: The name of the file
        :param asset: The file or bytes object to upload.
        :returns: :class:`Asset <Asset>`
        """
        headers = Release.CUSTOM_HEADERS.copy()
        headers.update({'Content-Type': content_type})
        url = self.upload_urlt.expand({'name': name})
        r = self._post(url, data=asset, json=False, headers=headers,
                       verify=False)
        if r.status_code in (201, 202):
            return Asset(r.json(), self)
        raise GitHubError(r)
 def _test_(self):
     for k, v in d.items():
         t = URITemplate(k)
         self.assertEqual(t.expand(v['expansion']), v['expected'])
Example #51
0
	def __get_url(self, path, id):
		rootUrl = self.hal.get_root_url()
		template = URITemplate(rootUrl + path);

		return template.expand(id= str(id) if id is not None else "")
 def test_default_value(self):
     uri = "https://api.github.com/user{/user=sigmavirus24}"
     t = URITemplate(uri)
     self.assertEqual(t.expand(), "https://api.github.com/user/sigmavirus24")
     self.assertEqual(t.expand(user="******"), "https://api.github.com/user/lukasa")