Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
165 changed files
with
4,018 additions
and
961 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,7 +1,6 @@ | ||
from django.contrib import admin | ||
|
||
from mimesis.models import Album, Photo | ||
from mimesis.models import Image, ImageAssociation | ||
|
||
|
||
admin.site.register(Album) | ||
admin.site.register(Photo) | ||
admin.site.register(Image) | ||
admin.site.register(ImageAssociation) |
This file was deleted.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
from django.db import models | ||
from django.contrib.contenttypes.models import ContentType | ||
from django.utils.encoding import force_unicode | ||
|
||
class MediaAssociationManager(models.Manager): | ||
|
||
def for_model(self, model, content_type=None): | ||
""" | ||
QuerySet for all media for a particular model (either an instance or | ||
a class). | ||
""" | ||
ct = content_type or ContentType.objects.get_for_model(model) | ||
qs = self.get_query_set().filter(content_type=ct) | ||
if isinstance(model, models.Model): | ||
qs = qs.filter(object_pk=force_unicode(model._get_pk_val())) | ||
return qs | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,72 +1,79 @@ | ||
from datetime import datetime | ||
import datetime | ||
|
||
from django.contrib.auth.models import User | ||
from django.db import models | ||
|
||
from django.contrib.auth.models import User | ||
from django.contrib.contenttypes.models import ContentType | ||
from django.contrib.contenttypes import generic | ||
|
||
from mimesis.managers import MediaAssociationManager | ||
from taggit.managers import TaggableManager | ||
|
||
|
||
class Album(models.Model): | ||
class MediaBase(models.Model): | ||
|
||
title = models.CharField(max_length=150) | ||
creator = models.ForeignKey(User) | ||
created = models.DateTimeField(default=datetime.datetime.now) | ||
|
||
owner = models.ForeignKey(User) | ||
name = models.CharField(max_length=150) | ||
description = models.TextField(null=True, blank=True) | ||
private = models.BooleanField(default=False) | ||
date_created = models.DateTimeField(default=datetime.now) | ||
tags = TaggableManager() | ||
|
||
class Meta: | ||
abstract = True | ||
|
||
def __unicode__(self): | ||
return u"%s" % self.name | ||
|
||
@property | ||
def key_photo(self): # @@@ This should likely be set by the user | ||
photo = None | ||
for photo in self.photo_set.all().order_by("-uploaded_on"): | ||
break | ||
return photo | ||
|
||
|
||
class Photo(models.Model): | ||
|
||
album = models.ForeignKey(Album, null=True, blank=True) | ||
photo = models.ImageField( | ||
upload_to="mimesis/%Y/%m/%d", | ||
height_field="height", | ||
width_field="width" | ||
) | ||
width = models.IntegerField(blank=True) | ||
height = models.IntegerField(blank=True) | ||
name = models.CharField(max_length=150, null=True, blank=True) | ||
description = models.TextField(null=True, blank=True) | ||
private = models.BooleanField(default=False) | ||
new_upload = models.BooleanField(default=True) | ||
uploaded_by = models.ForeignKey(User) | ||
uploaded_on = models.DateTimeField(default=datetime.now) | ||
return self.title | ||
|
||
|
||
class MediaAssociationBase(models.Model): | ||
|
||
tags = TaggableManager() | ||
content_type = models.ForeignKey(ContentType) | ||
object_pk = models.PositiveIntegerField() | ||
content_object = generic.GenericForeignKey("content_type", "object_pk") | ||
|
||
caption = models.TextField(blank=True) | ||
|
||
objects = MediaAssociationManager() | ||
|
||
class Meta: | ||
abstract = True | ||
|
||
|
||
class Image(MediaBase): | ||
|
||
image = models.ImageField(upload_to="mimesis/image/") | ||
|
||
|
||
class ImageAssociation(MediaAssociationBase): | ||
|
||
image = models.ForeignKey(Image) | ||
|
||
def get_absolute_url(self): | ||
return self.image.url | ||
|
||
|
||
class Audio(MediaBase): | ||
|
||
audio = models.FileField(upload_to="mimesis/audio/") | ||
|
||
|
||
class AudioAssociation(MediaAssociationBase): | ||
|
||
audio = models.ForeignKey(Audio) | ||
|
||
def get_absolute_url(self): | ||
return self.audio.url | ||
|
||
|
||
class Video(MediaBase): | ||
|
||
video = models.URLField(blank=True) | ||
|
||
|
||
class VideoAssociation(MediaAssociationBase): | ||
|
||
video = models.ForeignKey(Video) | ||
|
||
def next_or_prev(self, desc, **kwargs): | ||
order = "id" | ||
if desc: | ||
order = "-id" | ||
|
||
if self.album: | ||
p = self.album.photo_set.filter(**kwargs).order_by(order) | ||
if p: | ||
return p[0] | ||
p = self.album.photo_set.all().order_by(order) | ||
if p: | ||
return p[0] | ||
else: | ||
p = self.uploaded_by.photo_set.filter(**kwargs).order_by(order) | ||
if p: | ||
return p[0] | ||
p = self.uploaded_by.photo_set.all().order_by(order) | ||
if p: | ||
return p[0] | ||
|
||
def prev(self): | ||
return self.next_or_prev(desc=True, id__lt=self.id) | ||
|
||
def next(self): | ||
return self.next_or_prev(desc=False, id__gt=self.id) | ||
def get_absolute_url(self): | ||
return self.video | ||
|
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,116 @@ | ||
from django import template | ||
from django.contrib.contenttypes.models import ContentType | ||
from django.utils.encoding import smart_unicode | ||
|
||
from mimesis.models import ImageAssociation, AudioAssociation, VideoAssociation | ||
|
||
register = template.Library() | ||
|
||
|
||
class BaseMediaNode(template.Node): | ||
""" | ||
Base helper class (abstract) for handling the get_media_for template tags. | ||
""" | ||
|
||
@classmethod | ||
def handle_token(cls, parser, token, model): | ||
"""Class method to parse get_media_list and return a Node.""" | ||
|
||
tokens = token.contents.split() | ||
if tokens[1] != 'for': | ||
raise template.TemplateSyntaxError("Second argument in %r tag must be 'for'" % tokens[0]) | ||
|
||
# {% get_whatever for obj as varname %} | ||
if len(tokens) == 5: | ||
if tokens[3] != 'as': | ||
raise template.TemplateSyntaxError("Third argument in %r must be 'as'" % tokens[0]) | ||
return cls( | ||
object_expr = parser.compile_filter(tokens[2]), | ||
as_varname = tokens[4], | ||
model = model, | ||
) | ||
|
||
# {% get_whatever for app.model pk as varname %} | ||
elif len(tokens) == 6: | ||
if tokens[4] != 'as': | ||
raise template.TemplateSyntaxError("Fourth argument in %r must be 'as'" % tokens[0]) | ||
return cls( | ||
ctype = BaseMediaNode.lookup_content_type(tokens[2], tokens[0]), | ||
object_pk_expr = parser.compile_filter(tokens[3]), | ||
as_varname = tokens[5], | ||
model = model, | ||
) | ||
|
||
else: | ||
raise template.TemplateSyntaxError("%r tag requires 4 or 5 arguments" % tokens[0]) | ||
|
||
@staticmethod | ||
def lookup_content_type(token, tagname): | ||
try: | ||
app, model = token.split('.') | ||
return ContentType.objects.get(app_label=app, model=model) | ||
except ValueError: | ||
raise template.TemplateSyntaxError("Third argument in %r must be in the format 'app.model'" % tagname) | ||
except ContentType.DoesNotExist: | ||
raise template.TemplateSyntaxError("%r tag has non-existant content-type: '%s.%s'" % (tagname, app, model)) | ||
|
||
def __init__(self, ctype=None, object_pk_expr=None, object_expr=None, as_varname=None, model=None): | ||
if ctype is None and object_expr is None: | ||
raise template.TemplateSyntaxError("Media nodes must be given either a literal object or a ctype and object pk.") | ||
self.media_model = model | ||
self.as_varname = as_varname | ||
self.ctype = ctype | ||
self.object_pk_expr = object_pk_expr | ||
self.object_expr = object_expr | ||
|
||
def render(self, context): | ||
qs = self.get_query_set(context) | ||
context[self.as_varname] = self.get_context_value_from_queryset(context, qs) | ||
return "" | ||
|
||
def get_query_set(self, context): | ||
ctype, object_pk = self.get_target_ctype_pk(context) | ||
if not object_pk: | ||
return self.media_model.objects.none() | ||
|
||
qs = self.media_model.objects.filter( | ||
content_type = ctype, | ||
object_pk = smart_unicode(object_pk), | ||
) | ||
|
||
return qs | ||
|
||
def get_target_ctype_pk(self, context): | ||
if self.object_expr: | ||
try: | ||
obj = self.object_expr.resolve(context) | ||
except template.VariableDoesNotExist: | ||
return None, None | ||
return ContentType.objects.get_for_model(obj), obj.pk | ||
else: | ||
return self.ctype, self.object_pk_expr.resolve(context, ignore_failures=True) | ||
|
||
def get_context_value_from_queryset(self, context, qs): | ||
"""Subclasses should override this.""" | ||
raise NotImplementedError | ||
|
||
|
||
class MediaListNode(BaseMediaNode): | ||
"""Insert a list of media into the context.""" | ||
def get_context_value_from_queryset(self, context, qs): | ||
return list(qs) | ||
|
||
|
||
@register.tag | ||
def get_images_for(parser, token): | ||
return MediaListNode.handle_token(parser, token, ImageAssociation) | ||
|
||
|
||
@register.tag | ||
def get_audio_for(parser, token): | ||
return MediaListNode.handle_token(parser, token, AudioAssociation) | ||
|
||
|
||
@register.tag | ||
def get_videos_for(parser, token): | ||
return MediaListNode.handle_token(parser, token, VideoAssociation) |
This file was deleted.
Oops, something went wrong.
Oops, something went wrong.