# Path: src/hydra/api.py
# class RedisProject(object):
#     """
#     A model layer representing a Project in Redis.
# 
#     It has an index of all existing projects, and then contains metadata about
#     projects including their existence, and a whitelist of URLs that you can
#     link to from them.
# 
#     Generally you create an instance by passing in a name, and a possible
#     whitelist. If you only pass in the name, the whitelist is populated from
#     the data store.
# 
#     The main methods you will call on an instance are save, delete, and exists.
#     There is a classmethod called all_projects that will return all projects.
# 
#     """
#     index_slug = "hydra:v1:projects"
# 
#     def __init__(self, name=None, whitelist=None, *args, **kwargs):
#         super(RedisProject, self).__init__(*args, **kwargs)
#         self.name = name
#         if whitelist:
#             self.whitelist = whitelist
#         else:
#             # We need to populate the whitelist here,
#             # so when we return the object, it will serialize with them
#             self.whitelist = self.get_whitelist()
# 
#     @classmethod
#     def all_projects(cls):
#         """
#         Return all projects. Classmethod because it doesn't need any data on
#         the instance.
#         """
#         ret_val = r.sort(cls.index_slug)
#         return ret_val
# 
#     @property
#     def redis_slug(self):
#         return "hydra:v1:projects:%s" % (self.name)
# 
#     def save_whitelist(self):
#         for redirect_url in self.whitelist:
#             r.sadd("%s:whitelist" % self.redis_slug, redirect_url)
# 
#     def save_project(self):
#         r.hset(self.redis_slug, "exists", "true")
#         r.sadd(self.index_slug, self.name)
# 
#     def save(self):
#         self.save_whitelist()
#         self.save_project()
# 
#     def delete(self):
#         r.delete(self.redis_slug)
#         r.delete("%s:whitelist" % self.redis_slug)
#         r.srem(self.index_slug, self.name)
# 
#     def exists(self):
#         return r.hget(self.redis_slug, "exists") == "true"
# 
#     def get_whitelist(self):
#         return r.smembers("%s:whitelist" % self.redis_slug)
# 
# class RedisRedirect(object):
#     """
#     A Redis Model for a Redirect
# 
#     This contains the basic information about how a projects redirects will
#     work.
# 
#     The set of (project, slug) is unique, and each contains a set of URLs that
#     might possibly be correct. We store these in a sorted set so that we can
#     keep score of clicks in the data model in Redis.
#     """
# 
#     def __init__(self, slug=None, project=None, urls=None, *args, **kwargs):
#         super(RedisRedirect, self).__init__(*args, **kwargs)
#         self.project = project
#         self.slug = slug
#         if urls:
#             self.urls = urls
#         else:
#             self.urls = self.get_urls()
# 
#     @property
#     def index_slug(self):
#         return "hydra:v1:projects:%s:slugs" % (self.project)
# 
#     @property
#     def redis_slug(self):
#         return "%s:%s" % (self.index_slug, self.slug)
# 
#     def all_slugs(self):
#         return r.sort(self.index_slug)
# 
#     def save_redirect(self):
#         r.sadd(self.index_slug, self.slug)
# 
#     def save_urls(self):
#         for obj in self.urls:
#             if hasattr(obj, 'get'):
#                 if obj.get('score', None):
#                     r.zadd(self.redis_slug, int(obj['score']), obj['url'])
#             else:
#                 r.zincrby(self.redis_slug, self.urls[0], 1)
# 
#     def save(self):
#         proj = RedisProject(name=self.project)
#         proj.save()
#         self.save_redirect()
#         self.save_urls()
#         return True
# 
#     def delete(self):
#         r.delete(self.redis_slug)
#         r.srem(self.index_slug, self.slug)
# 
#     def incr(self, url):
#         self.save_redirect()
#         r.zincrby(self.redis_slug, url, 1)
# 
#     def url_exists(self, url):
#         for url_obj in self.get_urls():
#             if url == url_obj['url']:
#                 return True
#         return False
# 
#     def exists(self):
#         return r.zcard(self.redis_slug)
# 
#     def get_urls(self):
#         urls = r.zrevrange(self.redis_slug, 0, -1, withscores=True)
#         ret_val = []
#         for obj in urls:
#             redirect_url, score = obj
#             ret_val.append({
#                 'score': score,
#                 'url': redirect_url
#             })
#         return ret_val
# 
# Path: src/hydra/forms.py
# class SlugForm(forms.Form):
#     project = forms.CharField(max_length=255)
#     slug = forms.CharField(max_length=255)
#     url = forms.URLField()
# 
#     def clean_url(self):
#         url = self.cleaned_data['url']
#         project = self.cleaned_data['project']
#         valid, msg = in_whitelist(project, url)
#         if not valid:
#             raise forms.ValidationError(msg)
#         return url


from django.core.urlresolvers import reverse
from django.conf import settings
from django.http import HttpResponseRedirect
from django.views.generic import RedirectView, TemplateView, FormView
from analytics.models import Visit
from .api import RedisProject, RedisRedirect
from .forms import SlugForm


THRESHOLD = getattr(settings, "THRESHOLD", 3)

class SlugLookupRedirectView(RedirectView):
    permanent = False

    def get_redirect_url(self, **kwargs):
        slug = kwargs.get('slug', '')
        project = kwargs.get('project', '')
        if slug == '':
            return reverse('home')

        redirect_url = ''

# Path: src/hydra/api.py
# class RedisProject(object):
#     """
#     A model layer representing a Project in Redis.
# 
#     It has an index of all existing projects, and then contains metadata about
#     projects including their existence, and a whitelist of URLs that you can
#     link to from them.
# 
#     Generally you create an instance by passing in a name, and a possible
#     whitelist. If you only pass in the name, the whitelist is populated from
#     the data store.
# 
#     The main methods you will call on an instance are save, delete, and exists.
#     There is a classmethod called all_projects that will return all projects.
# 
#     """
#     index_slug = "hydra:v1:projects"
# 
#     def __init__(self, name=None, whitelist=None, *args, **kwargs):
#         super(RedisProject, self).__init__(*args, **kwargs)
#         self.name = name
#         if whitelist:
#             self.whitelist = whitelist
#         else:
#             # We need to populate the whitelist here,
#             # so when we return the object, it will serialize with them
#             self.whitelist = self.get_whitelist()
# 
#     @classmethod
#     def all_projects(cls):
#         """
#         Return all projects. Classmethod because it doesn't need any data on
#         the instance.
#         """
#         ret_val = r.sort(cls.index_slug)
#         return ret_val
# 
#     @property
#     def redis_slug(self):
#         return "hydra:v1:projects:%s" % (self.name)
# 
#     def save_whitelist(self):
#         for redirect_url in self.whitelist:
#             r.sadd("%s:whitelist" % self.redis_slug, redirect_url)
# 
#     def save_project(self):
#         r.hset(self.redis_slug, "exists", "true")
#         r.sadd(self.index_slug, self.name)
# 
#     def save(self):
#         self.save_whitelist()
#         self.save_project()
# 
#     def delete(self):
#         r.delete(self.redis_slug)
#         r.delete("%s:whitelist" % self.redis_slug)
#         r.srem(self.index_slug, self.name)
# 
#     def exists(self):
#         return r.hget(self.redis_slug, "exists") == "true"
# 
#     def get_whitelist(self):
#         return r.smembers("%s:whitelist" % self.redis_slug)
# 
# class RedisRedirect(object):
#     """
#     A Redis Model for a Redirect
# 
#     This contains the basic information about how a projects redirects will
#     work.
# 
#     The set of (project, slug) is unique, and each contains a set of URLs that
#     might possibly be correct. We store these in a sorted set so that we can
#     keep score of clicks in the data model in Redis.
#     """
# 
#     def __init__(self, slug=None, project=None, urls=None, *args, **kwargs):
#         super(RedisRedirect, self).__init__(*args, **kwargs)
#         self.project = project
#         self.slug = slug
#         if urls:
#             self.urls = urls
#         else:
#             self.urls = self.get_urls()
# 
#     @property
#     def index_slug(self):
#         return "hydra:v1:projects:%s:slugs" % (self.project)
# 
#     @property
#     def redis_slug(self):
#         return "%s:%s" % (self.index_slug, self.slug)
# 
#     def all_slugs(self):
#         return r.sort(self.index_slug)
# 
#     def save_redirect(self):
#         r.sadd(self.index_slug, self.slug)
# 
#     def save_urls(self):
#         for obj in self.urls:
#             if hasattr(obj, 'get'):
#                 if obj.get('score', None):
#                     r.zadd(self.redis_slug, int(obj['score']), obj['url'])
#             else:
#                 r.zincrby(self.redis_slug, self.urls[0], 1)
# 
#     def save(self):
#         proj = RedisProject(name=self.project)
#         proj.save()
#         self.save_redirect()
#         self.save_urls()
#         return True
# 
#     def delete(self):
#         r.delete(self.redis_slug)
#         r.srem(self.index_slug, self.slug)
# 
#     def incr(self, url):
#         self.save_redirect()
#         r.zincrby(self.redis_slug, url, 1)
# 
#     def url_exists(self, url):
#         for url_obj in self.get_urls():
#             if url == url_obj['url']:
#                 return True
#         return False
# 
#     def exists(self):
#         return r.zcard(self.redis_slug)
# 
#     def get_urls(self):
#         urls = r.zrevrange(self.redis_slug, 0, -1, withscores=True)
#         ret_val = []
#         for obj in urls:
#             redirect_url, score = obj
#             ret_val.append({
#                 'score': score,
#                 'url': redirect_url
#             })
#         return ret_val
# 
# Path: src/hydra/forms.py
# class SlugForm(forms.Form):
#     project = forms.CharField(max_length=255)
#     slug = forms.CharField(max_length=255)
#     url = forms.URLField()
# 
#     def clean_url(self):
#         url = self.cleaned_data['url']
#         project = self.cleaned_data['project']
#         valid, msg = in_whitelist(project, url)
#         if not valid:
#             raise forms.ValidationError(msg)
#         return url


# Path: src/hydra/views.py
from django.core.urlresolvers import reverse
from django.conf import settings
from django.http import HttpResponseRedirect
from django.views.generic import RedirectView, TemplateView, FormView
from analytics.models import Visit
from .api import RedisProject, RedisRedirect
from .forms import SlugForm



THRESHOLD = getattr(settings, "THRESHOLD", 3)

class SlugLookupRedirectView(RedirectView):
    permanent = False

    def get_redirect_url(self, **kwargs):
        slug = kwargs.get('slug', '')
        project = kwargs.get('project', '')
        if slug == '':
            return reverse('home')

        redirect_url = ''

        proj_obj = RedisRedirect(slug=slug, project=project)