Example #1
0
 def __call__(self, *credential, **payload):
     """Perform the RPC call while following CCP's caching guidelines."""
     
     if len(credential) > 1:
         raise Exception("The only positional parameter allowed is the credentials object.")
     
     now = datetime.utcnow()
     uri = self.uri(self.name)
     
     # Define the keyID/vCode API key arguments, if we have credentials.
     if credential:
         payload['keyID'] = credential[0].key
         payload['vCode'] = credential[0].code
     
     # Hash the arguments in a reliable way by converting to text in a way which sorts the keys.
     payload_hash = sha256(EnhancedBencode().encode(payload)).hexdigest()
     
     # Examine the cache.
     cv = CachedAPIValue.objects(
             key = payload.get('keyID', None),
             name = self.name,
             arguments = payload_hash,
             expires__gte = now
         ).first()
     
     if cv and cv.current:
         log.info("Returning cached result of %s for key ID %d.", self.name, payload.get('keyID', -1))
         return bunchify_lite(cv.result)
     
     log.info("Making query to %s for key ID %d.", self.name, payload.get('keyID', -1))
     
     # Actually perform the query if a cached version could not be found.
     response = requests.post(uri, data=payload or None)
     response.raise_for_status()
     
     # We don't want the initial XML prefix.  We should still check it, though.
     prefix, _, data = response.text.partition('\n')
     
     if prefix.strip() != "<?xml version='1.0' encoding='UTF-8'?>":
         raise Exception("Data returned doesn't seem to be XML!")
     
     data = xml(data)['eveapi']
     result = bunchify(data['result'], 'result')
     data = Bunch(data)
     
     if len(result) == 1:
         result = getattr(result, result.keys()[0])
     
     # Upsert (update if exists, create if it doesn't) the cache value.
     CachedAPIValue.objects(
             key = payload.get('keyID', None),
             name = self.name,
             arguments = payload_hash
         ).update_one(
             upsert = True,
             set__expires = datetime.strptime(data.cachedUntil, "%Y-%m-%d %H:%M:%S"),
             set__result = result
         )
     
     return result
Example #2
0
 def convert(self, content, conversion):
     """Convert content to Python data structures."""
     if not conversion:
         data = content
     elif self.format == 'json':
         data = json.loads(content)
     elif self.format == 'xml':
         content = xml(content)
         first = content.keys()[0]
         data = content[first]
     else:
         data = content
     return data
Example #3
0
 def convert(self, content, conversion):
     """Convert content to Python data structures."""
     if not conversion:
         data = content
     elif self.format == 'json':
         data = json.loads(content)
     elif self.format == 'xml':
         content = xml(content)
         first = content.keys()[0]
         data = content[first]
     else:
         data = content
     return data
Example #4
0
    def get(self, call, **kwargs):
        from newauth.models import APIKey, db
        cache_key = hash((self.base, call, frozenset(kwargs)))
        cached_data = redis.get(cache_key)
        if cached_data:
            cached_data = cPickle.loads(cached_data)
            if arrow.utcnow() < cached_data[0]:
                return cached_data[1]
        try:
            req = self.session.get(self.base + call + '.xml.aspx',
                                   params=kwargs)
            req.raise_for_status()
        except requests.exceptions.RequestException as e:
            raise e
        if req.status_code != 200:
            if req.status_code == requests.codes['not_found']:
                raise Exception(
                    "{} is not available on the API server (404)".format(
                        call.value))
            elif req.status_code == requests.codes['forbidden']:
                if self.api_key and self.api_key.id:
                    self.api_key.disabled = True
                    db.session.add(self.api_key)
                    db.session.commit()
                raise AuthenticationException(self.key_id)
            else:
                raise Exception("Eve API server exception.")
        request_data = req.text

        prefix, _, data = req.text.partition('\n')
        if prefix.strip() != "<?xml version='1.0' encoding='UTF-8'?>":
            raise Exception("Data returned doesn't seem to be XML!")

        if isinstance(data, unicode):
            data = data.encode('UTF-8')

        data = xml(data)['eveapi']
        result = bunchify(data['result'], 'result')
        data = Bunch(data)

        if len(result) == 1:
            result = getattr(result, result.keys())[0]
        redis.set(cache_key,
                  cPickle.dumps((arrow.get(data.cachedUntil), result), -1))
        return result
Example #5
0
def home():
    """Render website's home page."""
    if request.method == 'POST':
        files = request.form.items()
        try:
            # Not sure why Flask is splitting them apart?
            data = '='.join(files[0])
        except:
            return 'No file received.'
        try:
            content = xml(data)
        except Exception as error:
            content = {"error": str(error)}
        json = dumps(content)
        if 'X-callback' in request.headers:
            callback = request.headers['X-callback']
            req.post(callback, data=json)
        return json
    return render_template('home.html')
Example #6
0
    def get(self, call, **kwargs):
        from newauth.models import APIKey, db
        cache_key = hash((self.base, call, frozenset(kwargs)))
        cached_data = redis.get(cache_key)
        if cached_data:
            cached_data = cPickle.loads(cached_data)
            if arrow.utcnow() < cached_data[0]:
                return cached_data[1]
        try:
            req = self.session.get(self.base + call + '.xml.aspx', params=kwargs)
            req.raise_for_status()
        except requests.exceptions.RequestException as e:
            raise e
        if req.status_code != 200:
            if req.status_code == requests.codes['not_found']:
                raise Exception("{} is not available on the API server (404)".format(call.value))
            elif req.status_code == requests.codes['forbidden']:
                if self.api_key and self.api_key.id:
                    self.api_key.disabled = True
                    db.session.add(self.api_key)
                    db.session.commit()
                raise AuthenticationException(self.key_id)
            else:
                raise Exception("Eve API server exception.")
        request_data = req.text

        prefix, _, data = req.text.partition('\n')
        if prefix.strip() != "<?xml version='1.0' encoding='UTF-8'?>":
            raise Exception("Data returned doesn't seem to be XML!")

        if isinstance(data, unicode):
            data = data.encode('UTF-8')

        data = xml(data)['eveapi']
        result = bunchify(data['result'], 'result')
        data = Bunch(data)

        if len(result) == 1:
            result = getattr(result, result.keys())[0]
        redis.set(cache_key, cPickle.dumps((arrow.get(data.cachedUntil), result), -1))
        return result
Example #7
0
    def discovery(self, url=None):
        """
        Retrieve the standard discovery file that provides routing
        information.

        >>> Three().discovery()
        {'discovery': 'data'}
        """
        if url:
            data = self.session.get(url).content
        elif self.discovery_url:
            response = self.session.get(self.discovery_url)
            if self.format == 'xml':
                # Because, SF doesn't follow the spec.
                data = xml(response.text)
            else:
                # Spec calls for discovery always allowing JSON.
                data = response.json()
        else:
            data = self.get('discovery')
        return data
Example #8
0
    def discovery(self, url=None):
        """
        Retrieve the standard discovery file that provides routing
        information.

        >>> Three().discovery()
        {'discovery': 'data'}
        """
        if url:
            data = requests.get(url).content
        elif self.discovery_url:
            response = requests.get(self.discovery_url)
            if self.format == 'xml':
                # Because, SF doesn't follow the spec.
                data = xml(response.text)
            else:
                # Spec calls for discovery always allowing JSON.
                data = response.json()
        else:
            data = self.get('discovery')
        return data
Example #9
0
from relaxml import xml
import requests as req
url='http:export.yandex.ru/weather-ng/forecasts/26686.xml'
content = req.get(url).text
print content
print xml(content)
Example #10
0
 def _output(self, content):
     """Return the output from a given GET request."""
     if self.xml:
         return content
     return xml(content)