# Path: twobuntu/articles/models.py
# class Article(models.Model):
#     """
#     A post written in Markdown by an author.
#     """
# 
#     # Article status constants
#     DRAFT = 0
#     UNAPPROVED = 1
#     PUBLISHED = 2
# 
#     STATUS = (
#         (DRAFT, 'Draft'),
#         (UNAPPROVED, 'Unapproved'),
#         (PUBLISHED, 'Published'),
#     )
# 
#     author = models.ForeignKey(
#         User,
#         help_text="The user writing the article.",
#     )
#     category = models.ForeignKey(
#         Category,
#         help_text="The category of the article.",
#     )
#     title = models.CharField(
#         max_length=200,
#         help_text="The title of the article.",
#     )
#     body = models.TextField(help_text="The body of the article [in Markdown].")
#     image = models.ForeignKey(
#         Image,
#         blank=True,
#         null=True,
#         help_text="An image highlighting the contents of the article.",
#     )
#     status = models.PositiveSmallIntegerField(
#         choices=STATUS,
#         default=DRAFT,
#         help_text="The current status of the article.",
#     )
#     cc_license = models.BooleanField(
#         default=True,
#         help_text="Whether the article is released under the CC-BY-SA 4.0 license or not.",
#     )
#     date = models.DateTimeField()
# 
#     def __str__(self):
#         return '%s%s' % (
#             self.title,
#             ' [%s]' % self.get_status_display() if not self.status == self.PUBLISHED else '',
#         )
# 
#     @models.permalink
#     def get_absolute_url(self):
#         kwargs, slug = {'id': self.id}, slugify(self.title)
#         if slug:
#             kwargs['slug'] = slug
#         return ('articles:view', (), kwargs)
# 
#     def can_edit(self, request):
#         """
#         Determine if the article may be edited by the current user.
#         """
#         # The user must either be staff or have written the article and not published it yet
#         return request.user.is_staff or request.user == self.author and self.status == self.DRAFT
# 
#     def can_view(self, request):
#         """
#         Determine if the article may be viewed by the current user.
#         """
#         # The user must either be staff or have written the article or it must be published
#         return request.user.is_staff or request.user == self.author or self.status == self.PUBLISHED
# 
#     @property
#     def markdown_key(self):
#         """
#         Return the key used for caching markdown.
#         """
#         return 'article-%d-markdown' % self.id
# 
#     def related(self):
#         """
#         Returns a QuerySet of related articles.
#         """
#         return Article.objects.filter(~models.Q(id=self.id), status=self.PUBLISHED, category=self.category)
# 
#     def render(self):
#         """
#         Render the Markdown body.
#         """
#         md = cache.get(self.markdown_key)
#         if not md:
#             md = cmarkdown(self.body)
#             cache.set(self.markdown_key, md)
#         return md
# 
#     @classmethod
#     def apply_filter(cls, request, *args):
#         """
#         Return a QuerySet with the correct filter applied based on the request.
#         """
#         args = list(args)
#         if not request.user.is_staff:
#             args.append(models.Q(author=request.user.id) | models.Q(status=cls.PUBLISHED))
#         return cls.objects.filter(*args)
# 
#     class Meta:
#         ordering = ('status', '-date')
# 
# Path: twobuntu/categories/models.py
# class Category(models.Model):
#     """
#     A grouping for articles of a similar topic.
#     """
# 
#     name = models.CharField(
#         max_length=40,
#         help_text="The name of the category.",
#     )
#     image = models.ImageField(
#         upload_to='categories',
#         blank=True,
#         null=True,
#         help_text="A representative image.",
#     )
# 
#     def __str__(self):
#         return self.name
# 
#     @models.permalink
#     def get_absolute_url(self):
#         return ('categories:view', (), {
#             'id': self.id,
#             'slug': slugify(self.name),
#         })
# 
#     class Meta:
#         ordering = ('name',)
#         verbose_name_plural = 'Categories'
# 
# Path: twobuntu/decorators.py
# def canonical(model):
#     """
#     Enforce a canonical URL for a resource.
#     """
#     def outer(view):
#         def inner(request, id, slug=''):
#             instance = get_object_or_404(model, pk=id)
#             if not request.path == instance.get_absolute_url():
#                 return redirect(instance, permanent=True)
#             return view(request, instance)
#         return inner
#     return outer


from django.shortcuts import render
from twobuntu.articles.models import Article
from twobuntu.categories.models import Category
from twobuntu.decorators import canonical



@canonical(Category)
def view(request, category):
    """
    Display articles filed under the specified category.
    """
    return render(request, 'categories/view.html', {
        'title': category.name,
        'category': category,

# Path: twobuntu/articles/models.py
# class Article(models.Model):
#     """
#     A post written in Markdown by an author.
#     """
# 
#     # Article status constants
#     DRAFT = 0
#     UNAPPROVED = 1
#     PUBLISHED = 2
# 
#     STATUS = (
#         (DRAFT, 'Draft'),
#         (UNAPPROVED, 'Unapproved'),
#         (PUBLISHED, 'Published'),
#     )
# 
#     author = models.ForeignKey(
#         User,
#         help_text="The user writing the article.",
#     )
#     category = models.ForeignKey(
#         Category,
#         help_text="The category of the article.",
#     )
#     title = models.CharField(
#         max_length=200,
#         help_text="The title of the article.",
#     )
#     body = models.TextField(help_text="The body of the article [in Markdown].")
#     image = models.ForeignKey(
#         Image,
#         blank=True,
#         null=True,
#         help_text="An image highlighting the contents of the article.",
#     )
#     status = models.PositiveSmallIntegerField(
#         choices=STATUS,
#         default=DRAFT,
#         help_text="The current status of the article.",
#     )
#     cc_license = models.BooleanField(
#         default=True,
#         help_text="Whether the article is released under the CC-BY-SA 4.0 license or not.",
#     )
#     date = models.DateTimeField()
# 
#     def __str__(self):
#         return '%s%s' % (
#             self.title,
#             ' [%s]' % self.get_status_display() if not self.status == self.PUBLISHED else '',
#         )
# 
#     @models.permalink
#     def get_absolute_url(self):
#         kwargs, slug = {'id': self.id}, slugify(self.title)
#         if slug:
#             kwargs['slug'] = slug
#         return ('articles:view', (), kwargs)
# 
#     def can_edit(self, request):
#         """
#         Determine if the article may be edited by the current user.
#         """
#         # The user must either be staff or have written the article and not published it yet
#         return request.user.is_staff or request.user == self.author and self.status == self.DRAFT
# 
#     def can_view(self, request):
#         """
#         Determine if the article may be viewed by the current user.
#         """
#         # The user must either be staff or have written the article or it must be published
#         return request.user.is_staff or request.user == self.author or self.status == self.PUBLISHED
# 
#     @property
#     def markdown_key(self):
#         """
#         Return the key used for caching markdown.
#         """
#         return 'article-%d-markdown' % self.id
# 
#     def related(self):
#         """
#         Returns a QuerySet of related articles.
#         """
#         return Article.objects.filter(~models.Q(id=self.id), status=self.PUBLISHED, category=self.category)
# 
#     def render(self):
#         """
#         Render the Markdown body.
#         """
#         md = cache.get(self.markdown_key)
#         if not md:
#             md = cmarkdown(self.body)
#             cache.set(self.markdown_key, md)
#         return md
# 
#     @classmethod
#     def apply_filter(cls, request, *args):
#         """
#         Return a QuerySet with the correct filter applied based on the request.
#         """
#         args = list(args)
#         if not request.user.is_staff:
#             args.append(models.Q(author=request.user.id) | models.Q(status=cls.PUBLISHED))
#         return cls.objects.filter(*args)
# 
#     class Meta:
#         ordering = ('status', '-date')
# 
# Path: twobuntu/categories/models.py
# class Category(models.Model):
#     """
#     A grouping for articles of a similar topic.
#     """
# 
#     name = models.CharField(
#         max_length=40,
#         help_text="The name of the category.",
#     )
#     image = models.ImageField(
#         upload_to='categories',
#         blank=True,
#         null=True,
#         help_text="A representative image.",
#     )
# 
#     def __str__(self):
#         return self.name
# 
#     @models.permalink
#     def get_absolute_url(self):
#         return ('categories:view', (), {
#             'id': self.id,
#             'slug': slugify(self.name),
#         })
# 
#     class Meta:
#         ordering = ('name',)
#         verbose_name_plural = 'Categories'
# 
# Path: twobuntu/decorators.py
# def canonical(model):
#     """
#     Enforce a canonical URL for a resource.
#     """
#     def outer(view):
#         def inner(request, id, slug=''):
#             instance = get_object_or_404(model, pk=id)
#             if not request.path == instance.get_absolute_url():
#                 return redirect(instance, permanent=True)
#             return view(request, instance)
#         return inner
#     return outer


# Path: twobuntu/categories/views.py
from django.shortcuts import render
from twobuntu.articles.models import Article
from twobuntu.categories.models import Category
from twobuntu.decorators import canonical




@canonical(Category)
def view(request, category):
    """
    Display articles filed under the specified category.
    """
    return render(request, 'categories/view.html', {
        'title': category.name,
        'category': category,

        'articles': Article.objects.select_related('author','author__profile','category').filter(category=category, status=Article.PUBLISHED),