from ..decorators import *
from .. import util
+# Setup logging
+log = logging.getLogger(__name__)
+
class ratelimit(object):
"""
A decorator class which limits how often a function can be called
if self.current_address:
return self.current_address.country_code
+ @property
+ def user_agent(self):
+ """
+ Returns the HTTP user agent
+ """
+ return self.request.headers.get("User-Agent", None)
+
+ @property
+ def referrer(self):
+ return self.request.headers.get("Referer", None)
+
def get_argument_int(self, *args, **kwargs):
arg = self.get_argument(*args, **kwargs)
return self.backend.releases
+class AnalyticsMixin(object):
+ def on_finish(self):
+ """
+ Collect some data about this request
+ """
+ # Log something
+ log.debug("Analytics for %s:" % self)
+ log.debug(" User-Agent: %s" % self.user_agent)
+ log.debug(" Referrer : %s" % self.referrer)
+
+ # Do nothing if this requst should be ignored
+ if self._ignore_analytics():
+ return
+
+ with self.db.transaction():
+ # Log unique visits
+ self.backend.analytics.log_unique_visit(
+ address=self.current_address,
+ referrer=self.referrer,
+ country_code=self.current_country_code,
+ user_agent=self.user_agent,
+ host=self.request.host,
+ uri=self.request.uri,
+
+ # UTMs
+ source=self.get_argument("utm_source", None),
+ medium=self.get_argument("utm_medium", None),
+ campaign=self.get_argument("utm_campaign", None),
+ content=self.get_argument("utm_content", None),
+ term=self.get_argument("utm_term", None),
+
+ # Search queries
+ q=self.get_argument("q", None),
+ )
+
+ def _ignore_analytics(self):
+ """
+ Checks if this request should be ignored
+ """
+ ignored_user_agents = (
+ "LWP::Simple",
+ "check_http",
+ )
+
+ # Only log GET requests
+ if not self.request.method == "GET":
+ return True
+
+ # Ignore everything from matching user agents
+ for ignored_user_agent in ignored_user_agents:
+ if self.user_agent.startswith(ignored_user_agent):
+ return True
+
+
class APIHandler(BaseHandler):
def check_xsrf_cookie(self):
"""