# Path: tidings/compat.py
# def iteritems(d, **kw):
# def iterkeys(d, **kw):
# 
# Path: tidings/models.py
# class Watch(ModelBase):
#     """The registration of a user's interest in a certain event
# 
#     At minimum, specifies an event_type and thereby an
#     :class:`~tidings.events.Event` subclass. May also specify a content type
#     and/or object ID and, indirectly, any number of
#     :class:`WatchFilters <WatchFilter>`.
# 
#     """
#     #: Key used by an Event to find watches it manages:
#     event_type = models.CharField(max_length=30, db_index=True)
# 
#     #: Optional reference to a content type:
#     content_type = models.ForeignKey(ContentType, null=True, blank=True,
#                                      on_delete=models.CASCADE)
#     object_id = models.PositiveIntegerField(db_index=True, null=True)
#     content_object = GenericForeignKey('content_type', 'object_id')
# 
#     user = models.ForeignKey(settings.AUTH_USER_MODEL, null=True, blank=True,
#                              on_delete=models.CASCADE)
# 
#     #: Email stored only in the case of anonymous users:
#     email = models.EmailField(db_index=True, null=True, blank=True)
# 
#     #: Secret for activating anonymous watch email addresses.
#     secret = models.CharField(max_length=10, null=True, blank=True)
#     #: Active watches receive notifications, inactive watches don't.
#     is_active = models.BooleanField(default=False, db_index=True)
# 
#     def __unicode__(self):
#         # TODO: Trace event_type back to find the Event subclass, and ask it
#         # how to describe me in English.
#         rest = self.content_object or self.content_type or self.object_id
#         return u'id=%s, type=%s, content_object=%s' % (self.pk,
#                                                        self.event_type,
#                                                        text_type(rest))
# 
#     def activate(self):
#         """Enable this watch so it actually fires.
# 
#         Return ``self`` to support method chaining.
# 
#         """
#         self.is_active = True
#         return self
# 
#     def unsubscribe_url(self):
#         """Return the absolute URL to visit to delete me."""
#         server_relative = ('%s?s=%s' % (reverse('tidings.unsubscribe',
#                                                 args=[self.pk]),
#                                         self.secret))
#         return 'https://%s%s' % (Site.objects.get_current().domain,
#                                  server_relative)
# 
# class WatchFilter(ModelBase):
#     """Additional key/value pairs that pare down the scope of a watch"""
# 
#     watch = models.ForeignKey(Watch, related_name='filters',
#                               on_delete=models.CASCADE)
#     name = models.CharField(max_length=20)
# 
#     #: Either an int or the hash of an item in a reasonably small set, which is
#     #: indicated by the name field. See comments by
#     #: :func:`~tidings.utils.hash_to_unsigned()` for more on what is reasonably
#     #: small.
#     value = models.PositiveIntegerField()
# 
#     class Meta(object):
#         # There's no particular reason we couldn't allow multiple values for
#         # one name to be ORed together, but the API needs a little work
#         # (accepting lists passed to notify()) to support that.
#         #
#         # This ordering makes the index usable for lookups by name.
#         unique_together = ('name', 'watch')
# 
#     def __unicode__(self):
#         return u'WatchFilter %s: %s=%s' % (self.pk, self.name, self.value)


import random
from string import ascii_letters
from django.contrib.auth import get_user_model
from tidings.compat import range
from tidings.models import Watch, WatchFilter
def user(save=False, **kwargs):
    defaults = {'password':
                'sha1$d0fcb$661bd5197214051ed4de6da4ecdabe17f5549c7c'}
    if 'username' not in kwargs:
        defaults['username'] = ''.join(random.choice(ascii_letters)
                                       for x in range(15))
    defaults.update(kwargs)
    u = get_user_model()(**defaults)
    if save:
        u.save()
    return u


def watch(save=False, **kwargs):
    # TODO: better defaults, when there are events available.
    defaults = {'user': kwargs.get('user') or user(save=True),
                'is_active': True,
                'secret': 'abcdefghjk'}
    defaults.update(kwargs)
    w = Watch.objects.create(**defaults)
    if save:
        w.save()
    return w


def watch_filter(save=False, **kwargs):
    defaults = {'watch': kwargs.get('watch') or watch(save=True),
                'name': 'test',
                'value': 1234}
    defaults.update(kwargs)

# Path: tidings/compat.py
# def iteritems(d, **kw):
# def iterkeys(d, **kw):
# 
# Path: tidings/models.py
# class Watch(ModelBase):
#     """The registration of a user's interest in a certain event
# 
#     At minimum, specifies an event_type and thereby an
#     :class:`~tidings.events.Event` subclass. May also specify a content type
#     and/or object ID and, indirectly, any number of
#     :class:`WatchFilters <WatchFilter>`.
# 
#     """
#     #: Key used by an Event to find watches it manages:
#     event_type = models.CharField(max_length=30, db_index=True)
# 
#     #: Optional reference to a content type:
#     content_type = models.ForeignKey(ContentType, null=True, blank=True,
#                                      on_delete=models.CASCADE)
#     object_id = models.PositiveIntegerField(db_index=True, null=True)
#     content_object = GenericForeignKey('content_type', 'object_id')
# 
#     user = models.ForeignKey(settings.AUTH_USER_MODEL, null=True, blank=True,
#                              on_delete=models.CASCADE)
# 
#     #: Email stored only in the case of anonymous users:
#     email = models.EmailField(db_index=True, null=True, blank=True)
# 
#     #: Secret for activating anonymous watch email addresses.
#     secret = models.CharField(max_length=10, null=True, blank=True)
#     #: Active watches receive notifications, inactive watches don't.
#     is_active = models.BooleanField(default=False, db_index=True)
# 
#     def __unicode__(self):
#         # TODO: Trace event_type back to find the Event subclass, and ask it
#         # how to describe me in English.
#         rest = self.content_object or self.content_type or self.object_id
#         return u'id=%s, type=%s, content_object=%s' % (self.pk,
#                                                        self.event_type,
#                                                        text_type(rest))
# 
#     def activate(self):
#         """Enable this watch so it actually fires.
# 
#         Return ``self`` to support method chaining.
# 
#         """
#         self.is_active = True
#         return self
# 
#     def unsubscribe_url(self):
#         """Return the absolute URL to visit to delete me."""
#         server_relative = ('%s?s=%s' % (reverse('tidings.unsubscribe',
#                                                 args=[self.pk]),
#                                         self.secret))
#         return 'https://%s%s' % (Site.objects.get_current().domain,
#                                  server_relative)
# 
# class WatchFilter(ModelBase):
#     """Additional key/value pairs that pare down the scope of a watch"""
# 
#     watch = models.ForeignKey(Watch, related_name='filters',
#                               on_delete=models.CASCADE)
#     name = models.CharField(max_length=20)
# 
#     #: Either an int or the hash of an item in a reasonably small set, which is
#     #: indicated by the name field. See comments by
#     #: :func:`~tidings.utils.hash_to_unsigned()` for more on what is reasonably
#     #: small.
#     value = models.PositiveIntegerField()
# 
#     class Meta(object):
#         # There's no particular reason we couldn't allow multiple values for
#         # one name to be ORed together, but the API needs a little work
#         # (accepting lists passed to notify()) to support that.
#         #
#         # This ordering makes the index usable for lookups by name.
#         unique_together = ('name', 'watch')
# 
#     def __unicode__(self):
#         return u'WatchFilter %s: %s=%s' % (self.pk, self.name, self.value)


# Path: tests/base.py
import random
from string import ascii_letters
from django.contrib.auth import get_user_model
from tidings.compat import range
from tidings.models import Watch, WatchFilter

def user(save=False, **kwargs):
    defaults = {'password':
                'sha1$d0fcb$661bd5197214051ed4de6da4ecdabe17f5549c7c'}
    if 'username' not in kwargs:
        defaults['username'] = ''.join(random.choice(ascii_letters)
                                       for x in range(15))
    defaults.update(kwargs)
    u = get_user_model()(**defaults)
    if save:
        u.save()
    return u


def watch(save=False, **kwargs):
    # TODO: better defaults, when there are events available.
    defaults = {'user': kwargs.get('user') or user(save=True),
                'is_active': True,
                'secret': 'abcdefghjk'}
    defaults.update(kwargs)
    w = Watch.objects.create(**defaults)
    if save:
        w.save()
    return w


def watch_filter(save=False, **kwargs):
    defaults = {'watch': kwargs.get('watch') or watch(save=True),
                'name': 'test',
                'value': 1234}
    defaults.update(kwargs)

    f = WatchFilter.objects.create(**defaults)