# Path: narwhal/core/profile/models.py
# class Profile(Model):
#     user = AutoOneToOneField(User, related_name='profile')
#     key = CharField(max_length=32, default=lambda: md5(os.urandom(40)).hexdigest())
#     
#     avatar = ImageField(upload_to='profiles/avatar/', blank=True, null=True)
#     uploaded = BigIntegerField(default=0)
#     downloaded = BigIntegerField(default=0)
#     
#     # extra_data should only be used for data that should not be 
#     # searched upon, such as chat protocol addresses
#     data = JSONField(default=lambda: {})
#     
#     #def __getattr__(self, name):
#     #    try: return self.extra_data[name]
#     #    except KeyError, e: raise AttributeError, e
#     #def __setattr__(self, name, value):
#     #    self.extra_data[name] = value
#     
#     def __unicode__(self):
#         return self.user.username
#     
#     @permalink
#     def get_absolute_url(self):
#         return ('profile:profile', (), {'username': self.user.username} )
#     
#     def gravatar(self):
#         if self.user.email:
#             return "http://www.gravatar.com/avatar/%s.png?d=%s" % (
#                 md5(self.user.email.lower().strip()).hexdigest(),
#                 settings.PROFILE_GRAVATAR_STANDIN )
#         
#     def ratio(self):
#         return "%.2f"% (self.total_uploaded / float(self.total_downloaded))
# 
# Path: narwhal/core/torrent/models.py
# class Torrent(Model):
#     class Meta:
#         ordering = ('-added',)
#         app_label = 'torrent'
#         verbose_name =_('torrent')
#         verbose_name_plural =_('torrents')
# 
#     category = ForeignKey(Category, related_name='torrents')
#     title = CharField(_('Title'), max_length=80)
#     slug = SlugField(_('Slug'))
#     user = ForeignKey('auth.User', blank=True, null=True, verbose_name=_('Author'))
#     image = ImageField(_('Image'), upload_to='img/torrents', blank=True, null=True)
#     description = TextField(_('Description'))
#     added = DateTimeField(_('Added'), auto_now_add=True, editable=False)
#     
#     torrent = FileField(upload_to='torrent/')
#     data = JSONField(editable=False, default=lambda: {})
#     info_hash = CharField(_('Info hash'), unique=True, max_length=40, db_index=True, editable=False)
#     seeders = PositiveIntegerField(editable=False, default=0)
#     leechers = PositiveIntegerField(editable=False, default=0)
#     downloaded = PositiveIntegerField(editable=False, default=0)
#     comments_enabled = BooleanField(_('comments enabled'), default=True)
#     
#     tags = TaggableManager()
#     
#     def single_file(self):
#         print self.data
#         return 'length' in self.data['info'].keys()
#     single_file.boolean = True
# 
#     def files(self):
#         if self.single_file():
#             return [ self.data['info']['name'] ]
#         else:
#             return [ ( "/".join(f['path']), f['length']) for f in self.data['info']['files'] ]
# 
#     def num_files(self):
#         if self.single_file():
#             return 1
#         else:
#             return len(self.data['info']['files'])
# 
#     def size(self):
#         if 'length' in self.data['info'].keys():
#             return self.data['info']['length']
#         elif 'files' in self.data['info'].keys():
#             return reduce(lambda a,b:a+b, (length for file, length in self.data['info']['files'].items()) )
# 
#     def __unicode__(self):
#         return smart_unicode(self.title)
# 
#     def validate(self):
#         fkeys = self.data['info'].keys()
#         if not 'length' in fkeys and  not 'files' in fkeys:
#             raise ValidationError(_('Torrent File is not valid: does not contain any files.'))
#         #extra validation performed by subclasses
# 
#     def save(self, **kwargs):
#         #from markdown import Markdown
#         #md = Markdown(extensions=['footnotes'], safe_mode=True)
#         #self.html = md.convert(self.text)
#         if not self.slug:
#             self.slug = slugify(self.title)[:self._meta.get_field_by_name('slug')[0].max_length]
#         super(Torrent, self).save(**kwargs)
# 
# Path: narwhal/core/tracker/models.py



from urlparse import parse_qsl
from django.conf import settings
from django.http import HttpResponse, Http404
from django.utils.datastructures import MultiValueDictKeyError
from django.core.cache import cache
from django.contrib.auth.models import User
from annoying.decorators import render_to
from bencode import bencode, bdecode
from narwhal.core.profile.models import Profile
from narwhal.core.torrent.models import Torrent
from narwhal.core.tracker.models import Peer
                cache.set("tracker-peers-iphandout-"+info_hash, peers, settings.TRACKER_ANNOUNCE_INTERVAL)
            response['peers'] = peers[:min(numwant, 100)]
            
    except MultiValueDictKeyError:
        response['failure reason'] = 'invalid request, duplicate GET keys.'
    except Torrent.DoesNotExist:
        response['failure reason'] = 'torrent not available'
    except ValueError as e:
        response['failure reason'] = e.message
    
    finally:
        if response.get('failure reason'): response['interval']=ERROR_INTERVAL
        return HttpResponse(bencode(response), content_type='text/plain')

def scrape(request):
    response = {}
    try:
        info_hash = request.GET.get('info_hash')
        if info_hash:
            info = cache.get('tracker-scrape-byhash-'+info_hash)
            if not info:
                t = Torrent.objects.only('seeders', 'leechers', 'downloaded').get(info_hash=info_hash)
                file = {'info_hash':info_hash, 'complete': t.seeders, 
                        'incomplete': t.leechers, 'downloaded': t.downloaded}
                cache.set('tracker-scrape-byhash-'+info_hash, file, settings.TRACKER_SCRAPE_INTERVAL)
            response['files'] = [file]
        
        else:
            files = cache.get('tracker-scrape')
            if not info:

# Path: narwhal/core/profile/models.py
# class Profile(Model):
#     user = AutoOneToOneField(User, related_name='profile')
#     key = CharField(max_length=32, default=lambda: md5(os.urandom(40)).hexdigest())
#     
#     avatar = ImageField(upload_to='profiles/avatar/', blank=True, null=True)
#     uploaded = BigIntegerField(default=0)
#     downloaded = BigIntegerField(default=0)
#     
#     # extra_data should only be used for data that should not be 
#     # searched upon, such as chat protocol addresses
#     data = JSONField(default=lambda: {})
#     
#     #def __getattr__(self, name):
#     #    try: return self.extra_data[name]
#     #    except KeyError, e: raise AttributeError, e
#     #def __setattr__(self, name, value):
#     #    self.extra_data[name] = value
#     
#     def __unicode__(self):
#         return self.user.username
#     
#     @permalink
#     def get_absolute_url(self):
#         return ('profile:profile', (), {'username': self.user.username} )
#     
#     def gravatar(self):
#         if self.user.email:
#             return "http://www.gravatar.com/avatar/%s.png?d=%s" % (
#                 md5(self.user.email.lower().strip()).hexdigest(),
#                 settings.PROFILE_GRAVATAR_STANDIN )
#         
#     def ratio(self):
#         return "%.2f"% (self.total_uploaded / float(self.total_downloaded))
# 
# Path: narwhal/core/torrent/models.py
# class Torrent(Model):
#     class Meta:
#         ordering = ('-added',)
#         app_label = 'torrent'
#         verbose_name =_('torrent')
#         verbose_name_plural =_('torrents')
# 
#     category = ForeignKey(Category, related_name='torrents')
#     title = CharField(_('Title'), max_length=80)
#     slug = SlugField(_('Slug'))
#     user = ForeignKey('auth.User', blank=True, null=True, verbose_name=_('Author'))
#     image = ImageField(_('Image'), upload_to='img/torrents', blank=True, null=True)
#     description = TextField(_('Description'))
#     added = DateTimeField(_('Added'), auto_now_add=True, editable=False)
#     
#     torrent = FileField(upload_to='torrent/')
#     data = JSONField(editable=False, default=lambda: {})
#     info_hash = CharField(_('Info hash'), unique=True, max_length=40, db_index=True, editable=False)
#     seeders = PositiveIntegerField(editable=False, default=0)
#     leechers = PositiveIntegerField(editable=False, default=0)
#     downloaded = PositiveIntegerField(editable=False, default=0)
#     comments_enabled = BooleanField(_('comments enabled'), default=True)
#     
#     tags = TaggableManager()
#     
#     def single_file(self):
#         print self.data
#         return 'length' in self.data['info'].keys()
#     single_file.boolean = True
# 
#     def files(self):
#         if self.single_file():
#             return [ self.data['info']['name'] ]
#         else:
#             return [ ( "/".join(f['path']), f['length']) for f in self.data['info']['files'] ]
# 
#     def num_files(self):
#         if self.single_file():
#             return 1
#         else:
#             return len(self.data['info']['files'])
# 
#     def size(self):
#         if 'length' in self.data['info'].keys():
#             return self.data['info']['length']
#         elif 'files' in self.data['info'].keys():
#             return reduce(lambda a,b:a+b, (length for file, length in self.data['info']['files'].items()) )
# 
#     def __unicode__(self):
#         return smart_unicode(self.title)
# 
#     def validate(self):
#         fkeys = self.data['info'].keys()
#         if not 'length' in fkeys and  not 'files' in fkeys:
#             raise ValidationError(_('Torrent File is not valid: does not contain any files.'))
#         #extra validation performed by subclasses
# 
#     def save(self, **kwargs):
#         #from markdown import Markdown
#         #md = Markdown(extensions=['footnotes'], safe_mode=True)
#         #self.html = md.convert(self.text)
#         if not self.slug:
#             self.slug = slugify(self.title)[:self._meta.get_field_by_name('slug')[0].max_length]
#         super(Torrent, self).save(**kwargs)
# 
# Path: narwhal/core/tracker/models.py



# Path: narwhal/core/tracker/views.py
from urlparse import parse_qsl
from django.conf import settings
from django.http import HttpResponse, Http404
from django.utils.datastructures import MultiValueDictKeyError
from django.core.cache import cache
from django.contrib.auth.models import User
from annoying.decorators import render_to
from bencode import bencode, bdecode
from narwhal.core.profile.models import Profile
from narwhal.core.torrent.models import Torrent
from narwhal.core.tracker.models import Peer

                cache.set("tracker-peers-iphandout-"+info_hash, peers, settings.TRACKER_ANNOUNCE_INTERVAL)
            response['peers'] = peers[:min(numwant, 100)]
            
    except MultiValueDictKeyError:
        response['failure reason'] = 'invalid request, duplicate GET keys.'
    except Torrent.DoesNotExist:
        response['failure reason'] = 'torrent not available'
    except ValueError as e:
        response['failure reason'] = e.message
    
    finally:
        if response.get('failure reason'): response['interval']=ERROR_INTERVAL
        return HttpResponse(bencode(response), content_type='text/plain')

def scrape(request):
    response = {}
    try:
        info_hash = request.GET.get('info_hash')
        if info_hash:
            info = cache.get('tracker-scrape-byhash-'+info_hash)
            if not info:
                t = Torrent.objects.only('seeders', 'leechers', 'downloaded').get(info_hash=info_hash)
                file = {'info_hash':info_hash, 'complete': t.seeders, 
                        'incomplete': t.leechers, 'downloaded': t.downloaded}
                cache.set('tracker-scrape-byhash-'+info_hash, file, settings.TRACKER_SCRAPE_INTERVAL)
            response['files'] = [file]
        
        else:
            files = cache.get('tracker-scrape')
            if not info:

                files = (Torrent.objects.filter(seeders__gt=0).order_by('-added')