mirror of
https://github.com/fergalmoran/dss.api.git
synced 2025-12-22 09:18:13 +00:00
Feed working
This commit is contained in:
@@ -98,6 +98,17 @@ class LikeSerializer(serializers.ModelSerializer):
|
|||||||
display_name = serializers.ReadOnlyField(source='get_nice_name')
|
display_name = serializers.ReadOnlyField(source='get_nice_name')
|
||||||
|
|
||||||
|
|
||||||
|
class FavouriteSerializer(serializers.ModelSerializer):
|
||||||
|
class Meta:
|
||||||
|
model = UserProfile
|
||||||
|
fields = (
|
||||||
|
'display_name',
|
||||||
|
'slug',
|
||||||
|
)
|
||||||
|
|
||||||
|
display_name = serializers.ReadOnlyField(source='get_nice_name')
|
||||||
|
|
||||||
|
|
||||||
class GenreSerializer(serializers.ModelSerializer):
|
class GenreSerializer(serializers.ModelSerializer):
|
||||||
class Meta:
|
class Meta:
|
||||||
model = Genre
|
model = Genre
|
||||||
@@ -162,6 +173,7 @@ class MixSerializer(serializers.ModelSerializer):
|
|||||||
'plays',
|
'plays',
|
||||||
'downloads',
|
'downloads',
|
||||||
'is_liked',
|
'is_liked',
|
||||||
|
'is_favourited',
|
||||||
|
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -174,10 +186,11 @@ class MixSerializer(serializers.ModelSerializer):
|
|||||||
|
|
||||||
genres = GenreSerializer(many=True, required=False, read_only=True)
|
genres = GenreSerializer(many=True, required=False, read_only=True)
|
||||||
likes = LikeSerializer(many=True, required=False, read_only=True) # slug_field='slug', many=True, read_only=True)
|
likes = LikeSerializer(many=True, required=False, read_only=True) # slug_field='slug', many=True, read_only=True)
|
||||||
favourites = serializers.SlugRelatedField(slug_field='slug', many=True, read_only=True)
|
favourites = FavouriteSerializer(many=True, required=False, read_only=True) # slug_field='slug', many=True, read_only=True)
|
||||||
plays = InlineActivityPlaySerializer(many=True, read_only=True, source='activity_plays')
|
plays = InlineActivityPlaySerializer(many=True, read_only=True, source='activity_plays')
|
||||||
downloads = InlineActivityDownloadSerializer(read_only=True, source='activity_downloads')
|
downloads = InlineActivityDownloadSerializer(read_only=True, source='activity_downloads')
|
||||||
is_liked = serializers.SerializerMethodField(read_only=True)
|
is_liked = serializers.SerializerMethodField(read_only=True)
|
||||||
|
is_favourited = serializers.SerializerMethodField(read_only=True)
|
||||||
|
|
||||||
def update(self, instance, validated_data):
|
def update(self, instance, validated_data):
|
||||||
# all nested representations need to be serialized separately here
|
# all nested representations need to be serialized separately here
|
||||||
@@ -202,6 +215,25 @@ class MixSerializer(serializers.ModelSerializer):
|
|||||||
except UserProfile.DoesNotExist:
|
except UserProfile.DoesNotExist:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
favourites = self.initial_data['favourites']
|
||||||
|
unfavourited = instance.favourites.exclude(user__userprofile__slug__in=[f['slug'] for f in favourites])
|
||||||
|
for uf in unfavourited:
|
||||||
|
# check that the user removing the like is an instance of the current user
|
||||||
|
# for now, only the current user can like stuff
|
||||||
|
if uf == self.context['request'].user.userprofile:
|
||||||
|
instance.update_favourite(uf, False)
|
||||||
|
|
||||||
|
for favourite in favourites:
|
||||||
|
# check that the user adding the like is an instance of the current user
|
||||||
|
# for now, only the current user can like stuff
|
||||||
|
try:
|
||||||
|
user = UserProfile.objects.get(slug=favourite['slug'])
|
||||||
|
if user is not None and user == self.context['request'].user.userprofile:
|
||||||
|
instance.update_favourite(user, True)
|
||||||
|
|
||||||
|
except UserProfile.DoesNotExist:
|
||||||
|
pass
|
||||||
|
|
||||||
genres = self.initial_data['genres']
|
genres = self.initial_data['genres']
|
||||||
instance.genres.clear()
|
instance.genres.clear()
|
||||||
for genre in genres:
|
for genre in genres:
|
||||||
@@ -224,6 +256,8 @@ class MixSerializer(serializers.ModelSerializer):
|
|||||||
return super(MixSerializer, self).update(instance, validated_data)
|
return super(MixSerializer, self).update(instance, validated_data)
|
||||||
except MixUpdateException as ex:
|
except MixUpdateException as ex:
|
||||||
raise ex
|
raise ex
|
||||||
|
except Exception as ex:
|
||||||
|
raise ex
|
||||||
|
|
||||||
def is_valid(self, raise_exception=False):
|
def is_valid(self, raise_exception=False):
|
||||||
return super(MixSerializer, self).is_valid(raise_exception)
|
return super(MixSerializer, self).is_valid(raise_exception)
|
||||||
|
|||||||
@@ -123,13 +123,12 @@ INSTALLED_APPS = (
|
|||||||
'allauth.socialaccount.providers.twitter',
|
'allauth.socialaccount.providers.twitter',
|
||||||
|
|
||||||
'pipeline',
|
'pipeline',
|
||||||
'dbbackup',
|
'gunicorn',
|
||||||
|
|
||||||
'corsheaders',
|
'corsheaders',
|
||||||
'sorl.thumbnail',
|
'sorl.thumbnail',
|
||||||
'djcelery',
|
'djcelery',
|
||||||
'spa',
|
'spa',
|
||||||
'gunicorn',
|
|
||||||
'spa.signals',
|
'spa.signals',
|
||||||
'core',
|
'core',
|
||||||
'storages',
|
'storages',
|
||||||
@@ -254,7 +253,9 @@ SOCIAL_AUTH_AUTHENTICATION_BACKENDS = (
|
|||||||
'social.backends.yahoo.YahooOpenId'
|
'social.backends.yahoo.YahooOpenId'
|
||||||
)
|
)
|
||||||
|
|
||||||
|
"""
|
||||||
DBBACKUP_STORAGE = 'dbbackup.storage.dropbox_storage'
|
DBBACKUP_STORAGE = 'dbbackup.storage.dropbox_storage'
|
||||||
DBBACKUP_TOKENS_FILEPATH = '._dss_tokens'
|
DBBACKUP_TOKENS_FILEPATH = '._dss_tokens'
|
||||||
DBBACKUP_DROPBOX_APP_KEY = localsettings.DSS_DB_BACKUP_KEY
|
DBBACKUP_DROPBOX_APP_KEY = localsettings.DSS_DB_BACKUP_KEY
|
||||||
DBBACKUP_DROPBOX_APP_SECRET = localsettings.DSS_DB_BACKUP_SECRET
|
DBBACKUP_DROPBOX_APP_SECRET = localsettings.DSS_DB_BACKUP_SECRET
|
||||||
|
"""
|
||||||
@@ -14,6 +14,7 @@ urlpatterns = patterns(
|
|||||||
(r'^_embed/', include('spa.embedding.urls')),
|
(r'^_embed/', include('spa.embedding.urls')),
|
||||||
(r'^__redir/blog/', include('spa.blog.urls')),
|
(r'^__redir/blog/', include('spa.blog.urls')),
|
||||||
(r'^__redir/social/', include('spa.social.urls')),
|
(r'^__redir/social/', include('spa.social.urls')),
|
||||||
|
(r'^podcast/', include('spa.podcast.urls')),
|
||||||
url(r'', include('user_sessions.urls', 'user_sessions')),
|
url(r'', include('user_sessions.urls', 'user_sessions')),
|
||||||
url(r'^', include('api.urls')),
|
url(r'^', include('api.urls')),
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -22,7 +22,6 @@ google-api-python-client
|
|||||||
django-celery
|
django-celery
|
||||||
django-scheduler
|
django-scheduler
|
||||||
django-recurrence
|
django-recurrence
|
||||||
# django-dbbackup
|
|
||||||
|
|
||||||
azure
|
azure
|
||||||
|
|
||||||
|
|||||||
16
spa/management/commands/add_user_uid.py
Executable file
16
spa/management/commands/add_user_uid.py
Executable file
@@ -0,0 +1,16 @@
|
|||||||
|
import uuid
|
||||||
|
|
||||||
|
from django.core.management.base import NoArgsCommand
|
||||||
|
|
||||||
|
from spa.models import UserProfile
|
||||||
|
|
||||||
|
|
||||||
|
class Command(NoArgsCommand):
|
||||||
|
def handle_noargs(self, **options):
|
||||||
|
try:
|
||||||
|
users = UserProfile.objects.exclude(uid__isnull=False)
|
||||||
|
for user in users:
|
||||||
|
user.uid = uuid.uuid4()
|
||||||
|
user.save()
|
||||||
|
except Exception as ex:
|
||||||
|
print("Debug exception: %s" % ex)
|
||||||
19
spa/migrations/0026_userprofile_uid.py
Normal file
19
spa/migrations/0026_userprofile_uid.py
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
|
from django.db import models, migrations
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('spa', '0025_socialaccountlink_provider_data'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='userprofile',
|
||||||
|
name='uid',
|
||||||
|
field=models.UUIDField(editable=False, null=True),
|
||||||
|
),
|
||||||
|
]
|
||||||
@@ -238,7 +238,7 @@ class Mix(BaseModel):
|
|||||||
if user.user.is_authenticated():
|
if user.user.is_authenticated():
|
||||||
if value:
|
if value:
|
||||||
if self.favourites.filter(user=user.user).count() == 0:
|
if self.favourites.filter(user=user.user).count() == 0:
|
||||||
fav = ActivityFavourite(user=user) # , mix=self)
|
fav = ActivityFavourite(user=user, mix=self)
|
||||||
fav.save()
|
fav.save()
|
||||||
self.favourites.add(user)
|
self.favourites.add(user)
|
||||||
self.save()
|
self.save()
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ from django.contrib.auth.models import User
|
|||||||
from django.core.exceptions import SuspiciousOperation
|
from django.core.exceptions import SuspiciousOperation
|
||||||
from django.db import models
|
from django.db import models
|
||||||
from django.db.models import Count
|
from django.db.models import Count
|
||||||
|
import uuid
|
||||||
from django_gravatar.helpers import has_gravatar, get_gravatar_url
|
from django_gravatar.helpers import has_gravatar, get_gravatar_url
|
||||||
from sorl import thumbnail
|
from sorl import thumbnail
|
||||||
|
|
||||||
@@ -41,6 +42,8 @@ class UserProfile(BaseModel):
|
|||||||
ACTIVITY_SHARE_NETWORK_TWITTER = 2
|
ACTIVITY_SHARE_NETWORK_TWITTER = 2
|
||||||
|
|
||||||
user = models.OneToOneField(User, unique=True, related_name='userprofile')
|
user = models.OneToOneField(User, unique=True, related_name='userprofile')
|
||||||
|
uid = models.UUIDField(primary_key=False, editable=False, null=True)
|
||||||
|
|
||||||
avatar_type = models.CharField(max_length=15, default='social')
|
avatar_type = models.CharField(max_length=15, default='social')
|
||||||
avatar_image = models.ImageField(max_length=1024, blank=True, upload_to=avatar_name)
|
avatar_image = models.ImageField(max_length=1024, blank=True, upload_to=avatar_name)
|
||||||
display_name = models.CharField(blank=True, max_length=35)
|
display_name = models.CharField(blank=True, max_length=35)
|
||||||
|
|||||||
6
spa/podcast/urls.py
Normal file
6
spa/podcast/urls.py
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
from django.conf.urls import patterns, url
|
||||||
|
|
||||||
|
urlpatterns = patterns(
|
||||||
|
'',
|
||||||
|
url(r'^(?P<uid>[\w\d_.-]+)/favourites/?$', 'spa.podcast.views.favourites', name='podast_favourites_slug'),
|
||||||
|
)
|
||||||
35
spa/podcast/views.py
Normal file
35
spa/podcast/views.py
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
from django.http import Http404
|
||||||
|
from django.http import HttpResponse
|
||||||
|
from django.shortcuts import render_to_response
|
||||||
|
from django.template import RequestContext
|
||||||
|
|
||||||
|
from spa.models import UserProfile
|
||||||
|
|
||||||
|
|
||||||
|
def favourites(request, uid):
|
||||||
|
try:
|
||||||
|
user = UserProfile.objects.order_by('-id').get(uid=uid)
|
||||||
|
except UserProfile.DoesNotExist:
|
||||||
|
raise Http404("User does not exist")
|
||||||
|
|
||||||
|
fav_list = user.favourites.all()
|
||||||
|
return _render_podcast(request, user, fav_list)
|
||||||
|
|
||||||
|
|
||||||
|
def _render_podcast(request, user, list):
|
||||||
|
context = {
|
||||||
|
'title': 'DSS Favourites',
|
||||||
|
'description': 'All your favourites on Deep South Sounds',
|
||||||
|
'link': 'https://deepsouthsounds.com/',
|
||||||
|
'user': user.first_name,
|
||||||
|
'summary': 'Deep South Sounds is a collective of like minded house heads from Ireland"s Deep South',
|
||||||
|
'last_build_date': list[0].upload_date,
|
||||||
|
'objects': list,
|
||||||
|
}
|
||||||
|
response = render_to_response(
|
||||||
|
'podcast/feed.xml',
|
||||||
|
context=context,
|
||||||
|
context_instance=RequestContext(request),
|
||||||
|
content_type='application/rss+xml'
|
||||||
|
)
|
||||||
|
return response
|
||||||
0
spa/templatetags/__init__.py
Normal file
0
spa/templatetags/__init__.py
Normal file
33
spa/templatetags/dss_extras.py
Normal file
33
spa/templatetags/dss_extras.py
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
from django import template
|
||||||
|
import datetime
|
||||||
|
import time
|
||||||
|
from email import utils
|
||||||
|
|
||||||
|
register = template.Library()
|
||||||
|
|
||||||
|
|
||||||
|
@register.filter
|
||||||
|
def get_mix_url(obj):
|
||||||
|
return obj.get_full_url()
|
||||||
|
|
||||||
|
|
||||||
|
@register.filter
|
||||||
|
def get_mix_audio_url(obj):
|
||||||
|
return obj.get_download_url()
|
||||||
|
|
||||||
|
|
||||||
|
@register.filter
|
||||||
|
def seconds_to_hms(seconds):
|
||||||
|
try:
|
||||||
|
m, s = divmod(seconds, 60)
|
||||||
|
h, m = divmod(m, 60)
|
||||||
|
return "%d:%02d:%02d" % (h, m, s)
|
||||||
|
except Exception as ex:
|
||||||
|
return "00:00:09"
|
||||||
|
|
||||||
|
|
||||||
|
@register.filter
|
||||||
|
def date_to_rfc2822(date):
|
||||||
|
nowtuple = date.timetuple()
|
||||||
|
nowtimestamp = time.mktime(nowtuple)
|
||||||
|
return utils.formatdate(nowtimestamp)
|
||||||
BIN
static/img/podcast_logo.png
Normal file
BIN
static/img/podcast_logo.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 431 KiB |
52
templates/podcast/feed.xml
Normal file
52
templates/podcast/feed.xml
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<rss version="2.0" xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd">
|
||||||
|
<channel>
|
||||||
|
{% load dss_extras %}
|
||||||
|
|
||||||
|
<title>{{ title }}</title>
|
||||||
|
<description>{{ description }}</description>
|
||||||
|
<link>{{ link }}</link>
|
||||||
|
<language>en-ie</language>
|
||||||
|
<copyright>Copyright 2016</copyright>
|
||||||
|
<lastBuildDate>{{ last_build_date|date_to_rfc2822 }}</lastBuildDate>
|
||||||
|
<pubDate>{{ last_build_date|date_to_rfc2822 }}</pubDate>
|
||||||
|
<docs>http://blogs.law.harvard.edu/tech/rss</docs>
|
||||||
|
<webMaster>webmaster@deepsouthsounds.com</webMaster>
|
||||||
|
|
||||||
|
<itunes:author>{{ user }} @ deepsouthsounds</itunes:author>
|
||||||
|
<itunes:subtitle>{{ title }}</itunes:subtitle>
|
||||||
|
<itunes:summary>{{ summary }}</itunes:summary>
|
||||||
|
|
||||||
|
<itunes:owner>
|
||||||
|
<itunes:name>Fergal Moran</itunes:name>
|
||||||
|
<itunes:email>fergal@deepsouthsounds.com</itunes:email>
|
||||||
|
</itunes:owner>
|
||||||
|
|
||||||
|
<itunes:explicit>No</itunes:explicit>
|
||||||
|
|
||||||
|
<itunes:image href="https://dsscdn2.blob.core.windows.net/static/podcast_logo.png"/>
|
||||||
|
|
||||||
|
<itunes:category text="Technology">
|
||||||
|
<itunes:category text="Podcasting"/>
|
||||||
|
</itunes:category>
|
||||||
|
{% for item in objects %}
|
||||||
|
<item>
|
||||||
|
<title>{{ item.title }}</title>
|
||||||
|
<link>{{ item|get_mix_url }}</link>
|
||||||
|
<guid>{{ item|get_mix_url }}</guid>
|
||||||
|
<description>{{ item.description }}</description>
|
||||||
|
<enclosure url="{{ item|get_mix_audio_url }}" length="{{ item.duration }}" type="audio/mpeg"/>
|
||||||
|
<category>Podcasts</category>
|
||||||
|
<pubDate>{{ item.upload_date|date_to_rfc2822 }}</pubDate>
|
||||||
|
<itunes:author>{{ item.user.display_name }}</itunes:author>
|
||||||
|
<itunes:explicit>No</itunes:explicit>
|
||||||
|
<itunes:subtitle>{{ item.description }}</itunes:subtitle>
|
||||||
|
<itunes:summary>{{ item.description }}</itunes:summary>
|
||||||
|
<itunes:duration>{{ item.duration|seconds_to_hms }}</itunes:duration>
|
||||||
|
<itunes:keywords>deep south sounds, deep house, Cork, Fergal Moran, Ed Dunlea, {{ item.title }}, {{ item.user.display_name }}
|
||||||
|
</itunes:keywords>
|
||||||
|
</item>
|
||||||
|
{% endfor %}
|
||||||
|
</channel>
|
||||||
|
|
||||||
|
</rss>
|
||||||
57
templates/podcast/full.feed.html
Normal file
57
templates/podcast/full.feed.html
Normal file
@@ -0,0 +1,57 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<rss version="2.0" xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd">
|
||||||
|
<channel>
|
||||||
|
<title>{{ object.title }}</title>
|
||||||
|
<link>{{ object.link }}</link>
|
||||||
|
<description>{{ object.description|striptags }}</description>
|
||||||
|
{% if object.language %}<language>{{ object.language }}</language>{% endif %}
|
||||||
|
<copyright>℗ & © {% now "Y" %} {{ object.organization }}. {{ object.copyright }}.</copyright>
|
||||||
|
<managingEditor>{% for author in object.author.all %}{% if forloop.first %}{% else %}{% if forloop.last %} and {% else %}, {% endif %}{% endif %}{{ author.email }}{% endfor %}</managingEditor>
|
||||||
|
{% if object.author.email or object.webmaster.email %}<webMaster>{% if object.webmaster.email %}{{ object.webmaster.email }}{% else %}{% endif %}</webMaster>{% endif %}
|
||||||
|
<lastBuildDate>{{ object.list.0.date|date:"r" }}</lastBuildDate>
|
||||||
|
{% if object.category_show %}<category{% if object.domain %} domain="{{ object.domain }}"{% endif %}>{{ object.category_show }}</category>{% endif %}
|
||||||
|
<generator>Django Web Framework</generator>
|
||||||
|
<docs>http://blogs.law.harvard.edu/tech/rss</docs>
|
||||||
|
{% if object.ttl %}<ttl>{{ object.ttl }}</ttl>{% endif %}
|
||||||
|
{% if object.image %}<image>
|
||||||
|
<url>{{ object.image.url }}</url>
|
||||||
|
<title>{{ object.title }}</title>
|
||||||
|
<link>{{ object.link }}</link>
|
||||||
|
</image>{% endif %}
|
||||||
|
<itunes:author>{{ object.organization }}</itunes:author>
|
||||||
|
<itunes:owner>
|
||||||
|
<itunes:name>{% for author in object.author.all %}{% if forloop.first %}{% else %}{% if forloop.last %} and {% else %}, {% endif %}{% endif %}{% if author.first_name or author.last_name %}{% if author.first_name and author.last_name %}{{ author.first_name }} {{ author.last_name }}{% endif %}{% if author.first_name and not author.last_name %}{{ author.first_name }}{% endif %}{% if author.last_name and not author.first_name %}{{ author.last_name }}{% endif %}{% else %}{{ author.username }}{% endif %}{% endfor %}</itunes:name>
|
||||||
|
<itunes:email>{% for author in object.author.all %}{{ author.email }}{% if forloop.last %}{% else %}, {% endif %}{% endfor %}</itunes:email>
|
||||||
|
</itunes:owner>
|
||||||
|
{% if object.subtitle %}<itunes:subtitle>{{ object.subtitle }}</itunes:subtitle>{% endif %}
|
||||||
|
<itunes:summary>{% if object.summary %}{{ object.summary|striptags }}{% else %}{{ object.description|striptags }}{% endif %}</itunes:summary>
|
||||||
|
{% if object.image %}<itunes:image href="{{ object.image.url }}" />{% endif %}
|
||||||
|
{% if object.category.all %}{% for category in object.category.all %}{% if category.name %}<itunes:category text="{{ category.parent.name }}">
|
||||||
|
<itunes:category text="{{ category.name }}" />
|
||||||
|
</itunes:category>
|
||||||
|
{% else %}<itunes:category text="{{ category.parent.name }}" />
|
||||||
|
{% endif %}{% endfor %}{% endif %}
|
||||||
|
{% if object.explicit %}<itunes:explicit>{{ object.explicit|lower }}</itunes:explicit>{% endif %}
|
||||||
|
{% if object.block %}<itunes:block>yes</itunes:block>{% endif %}
|
||||||
|
{% if object.redirect %}<itunes:new-feed-url>{{ object.redirect }}</itunes:new-feed-url>{% endif %}
|
||||||
|
|
||||||
|
{% for episode in object.episode_set.published %}<item>
|
||||||
|
<title>{{ episode.title }}</title>
|
||||||
|
<link>{{ episode.enclosure_set.all.0.file.url }}</link>
|
||||||
|
<description>{{ episode.description|striptags }}</description>
|
||||||
|
<author>{% for author in object.author.all %}{{ author.email }}{% if forloop.last %}{% else %}, {% endif %}{% endfor %}</author>
|
||||||
|
{% if episode.category %}<category{% if episode.domain %} url="{{ episode.domain }}"{% endif %}>{{ episode.category }}</category>{% endif %}
|
||||||
|
<enclosure url="{{ episode.enclosure_set.all.0.file.url }}" length="{{ episode.enclosure_set.all.0.file.size }}" type="{{ episode.enclosure_set.all.0.mime }}" />
|
||||||
|
<guid isPermalink="true">{{ episode.enclosure_set.all.0.file.url }}</guid>
|
||||||
|
<pubDate>{{ episode.date|date:"r" }} GMT</pubDate>
|
||||||
|
<itunes:author>{% for author in episode.author.all %}{% if forloop.first %}{% else %}{% if forloop.last %} and {% else %}, {% endif %}{% endif %}{% if author.first_name or author.last_name %}{% if author.first_name and author.last_name %}{{ author.first_name }} {{ author.last_name }}{% endif %}{% if author.first_name and not author.last_name %}{{ author.first_name }}{% endif %}{% if author.last_name and not author.first_name %}{{ author.last_name }}{% endif %}{% else %}{{ author.username }}{% endif %}{% endfor %}</itunes:author>
|
||||||
|
{% if episode.subtitle %}<itunes:subtitle>{{ episode.subtitle }}</itunes:subtitle>{% endif %}
|
||||||
|
<itunes:summary>{% if episode.summary %}{{ episode.summary|striptags }}{% else %}{{ episode.description|striptags }}{% endif %}</itunes:summary>
|
||||||
|
{% if episode.minutes and episode.seconds %}<itunes:duration>{{ episode.minutes }}:{{ episode.seconds }}</itunes:duration>{% endif %}
|
||||||
|
{% if episode.keywords %}<itunes:keywords>{{ episode.keywords }}</itunes:keywords>{% endif %}
|
||||||
|
{% if episode.explicit %}<itunes:explicit>{{ episode.explicit|lower }}</itunes:explicit>{% endif %}
|
||||||
|
{% if episode.block %}<itunes:block>yes</itunes:block>{% endif %}
|
||||||
|
</item>
|
||||||
|
{% endfor %}
|
||||||
|
</channel>
|
||||||
|
</rss>
|
||||||
Reference in New Issue
Block a user