123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108 |
- import logging
- import rd
- __version__ = '1.0'
- WEBFINGER_TYPE = 'application/jrd+json'
- LEGACY_WEBFINGER_TYPES = ['application/json']
- UNOFFICIAL_ENDPOINTS = {
- # 'facebook.com': 'facebook-webfinger.appspot.com',
- # 'twitter.com': 'twitter-webfinger.appspot.com',
- }
- logger = logging.getLogger("webfinger")
- class WebFingerException(Exception):
- pass
- class WebFingerClient(object):
- def __init__(self, timeout=None, official=False):
- self.official = official
- self.timeout = timeout
- def _parse_host(self, resource):
- (scheme, host, path) = rd.parse_uri_components(resource)
- if host in UNOFFICIAL_ENDPOINTS and not self.official:
- unofficial_host = UNOFFICIAL_ENDPOINTS[host]
- logger.debug('host %s is not supported, using unofficial endpoint %s' % (host, unofficial_host))
- host = unofficial_host
- return host
- def finger(self, resource, host=None, rel=None):
- import requests
- if not host:
- host = self._parse_host(resource)
- url = "https://%s/.well-known/webfinger" % host
- headers = {
- 'User-Agent': 'python-webfinger/%s' % __version__,
- 'Accept': ', '.join(rd.JRD_TYPES + rd.XRD_TYPES),
- }
- params = {'resource': resource}
- if rel:
- params['rel'] = rel
- resp = requests.get(url, params=params, headers=headers, timeout=self.timeout, verify=True)
- logger.debug('fetching RD from %s' % resp.url)
- content_type = resp.headers.get('Content-Type', '').split(';', 1)[0].strip()
- logger.debug('response content type: %s' % content_type)
- if content_type not in (rd.JRD_TYPES + rd.XRD_TYPES):
- raise WebFingerException('Invalid response type from server')
- ''' Returns an RD object '''
- return rd.loads(resp.content.decode(resp.encoding if resp.encoding else 'utf-8'), content_type)
- def finger(resource, rel=None):
- """ Convenience method for invoking WebFingerClient.
- """
- return WebFingerClient().finger(resource, rel=rel)
- if __name__ == '__main__':
- import argparse
- parser = argparse.ArgumentParser(description="Simple webfinger client.")
- parser.add_argument("acct", metavar="URI", help="account URI")
- parser.add_argument("-d", "--debug", dest="debug", action="store_true", help="print debug logging output to console")
- parser.add_argument("-r", "--rel", metavar="REL", dest="rel", help="desired relation")
- args = parser.parse_args()
- if args.debug:
- logging.basicConfig(level=logging.DEBUG)
- wf = finger(args.acct, rel=args.rel)
- print("--- %s ---" % wf.subject)
- if args.rel:
- link = wf.find_link(args.rel)
- if link is None:
- print("*** Link not found for rel=%s" % args.rel)
- else:
- print("%s:\n\t%s" % (args.rel, link))
- else:
- for rel in rd.KNOWN_RELS:
- link = getattr(wf, rel)
- if link:
- print('{}\t{}'.format(rel, link.href if link.href else link.template))
|