mirror of
https://github.com/TrentSPalmer/trentpalmerdotorg.git
synced 2024-11-23 18:01:30 -08:00
switch to local file storage instead of object storage
This commit is contained in:
parent
45e8ef4dd9
commit
65e724c0aa
2
.gitignore
vendored
2
.gitignore
vendored
@ -11,3 +11,5 @@ audio/tests/__pycache__
|
|||||||
tp/__pycache__
|
tp/__pycache__
|
||||||
Mark Twain Taming The Bicycle.mp3
|
Mark Twain Taming The Bicycle.mp3
|
||||||
bicycle.jpg
|
bicycle.jpg
|
||||||
|
media/
|
||||||
|
static/
|
||||||
|
@ -49,7 +49,7 @@ class AudioRssFeed(RSSFeed):
|
|||||||
return f'{MP3_URL}{item.mp3}'
|
return f'{MP3_URL}{item.mp3}'
|
||||||
|
|
||||||
def item_enclosure_length(self, item):
|
def item_enclosure_length(self, item):
|
||||||
return item.image.size
|
return(item.mp3.size)
|
||||||
|
|
||||||
def item_enclosure_mime_type(self, item):
|
def item_enclosure_mime_type(self, item):
|
||||||
return "audio/mpeg"
|
return "audio/mpeg"
|
||||||
|
30
audio/migrations/0025_auto_20220218_1338.py
Normal file
30
audio/migrations/0025_auto_20220218_1338.py
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
# Generated by Django 3.2.10 on 2022-02-18 21:38
|
||||||
|
|
||||||
|
import audio.models
|
||||||
|
import django.core.files.storage
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('audio', '0024_auto_20211107_0710'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='episode',
|
||||||
|
name='image',
|
||||||
|
field=models.ImageField(blank=True, null=True, storage=django.core.files.storage.FileSystemStorage(location='/home/trent/trentpalmerdotorg/media/audio/images'), upload_to=audio.models.slugify_file_name),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='episode',
|
||||||
|
name='mp3',
|
||||||
|
field=models.FileField(blank=True, null=True, storage=django.core.files.storage.FileSystemStorage(location='/home/trent/trentpalmerdotorg/media/audio/mp3'), upload_to=audio.models.slugify_file_name),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='feed',
|
||||||
|
name='image',
|
||||||
|
field=models.ImageField(blank=True, null=True, storage=django.core.files.storage.FileSystemStorage(location='/home/trent/trentpalmerdotorg/media/audio/images'), upload_to=audio.models.slugify_file_name),
|
||||||
|
),
|
||||||
|
]
|
@ -3,9 +3,10 @@ from django.conf import settings
|
|||||||
from tp.models import UUIDAsIDModel
|
from tp.models import UUIDAsIDModel
|
||||||
from django.contrib.auth.models import User
|
from django.contrib.auth.models import User
|
||||||
from django.utils.text import slugify
|
from django.utils.text import slugify
|
||||||
from tp.storage_backends import PublicImageStorage, PublicMP3Storage
|
from django.core.files.storage import FileSystemStorage
|
||||||
from .choices import LICENSE_CHOICES, get_license_info
|
from .choices import LICENSE_CHOICES, get_license_info
|
||||||
import string, random
|
import string
|
||||||
|
import random
|
||||||
|
|
||||||
|
|
||||||
def rand_slug():
|
def rand_slug():
|
||||||
@ -15,7 +16,7 @@ def rand_slug():
|
|||||||
def slugify_file_name(instance, filename):
|
def slugify_file_name(instance, filename):
|
||||||
fname, dot, extension = filename.rpartition('.')
|
fname, dot, extension = filename.rpartition('.')
|
||||||
slug = slugify(fname)
|
slug = slugify(fname)
|
||||||
return f'{slug}.{extension}'
|
return f"{slug}.{extension}"
|
||||||
|
|
||||||
|
|
||||||
class EpisodeAndFeed(UUIDAsIDModel):
|
class EpisodeAndFeed(UUIDAsIDModel):
|
||||||
@ -27,7 +28,7 @@ class EpisodeAndFeed(UUIDAsIDModel):
|
|||||||
description = models.TextField(null=False)
|
description = models.TextField(null=False)
|
||||||
|
|
||||||
image = models.ImageField(
|
image = models.ImageField(
|
||||||
storage=PublicImageStorage(),
|
storage=FileSystemStorage(location=settings.IMAGE_ROOT),
|
||||||
upload_to=slugify_file_name,
|
upload_to=slugify_file_name,
|
||||||
null=True, blank=True)
|
null=True, blank=True)
|
||||||
|
|
||||||
@ -95,6 +96,6 @@ class Episode(EpisodeAndFeed):
|
|||||||
episode_number = models.IntegerField(null=True)
|
episode_number = models.IntegerField(null=True)
|
||||||
|
|
||||||
mp3 = models.FileField(
|
mp3 = models.FileField(
|
||||||
storage=PublicMP3Storage(),
|
storage=FileSystemStorage(location=settings.MP3_ROOT),
|
||||||
upload_to=slugify_file_name,
|
upload_to=slugify_file_name,
|
||||||
null=True, blank=True)
|
null=True, blank=True)
|
||||||
|
@ -263,7 +263,6 @@ class TestEditFeedViewTestCase(TestCase):
|
|||||||
self.assertEquals(feed_a.original_image_url, "https://commons.wikimedia.org/wiki/File:Ordinary_bicycle01.jpg")
|
self.assertEquals(feed_a.original_image_url, "https://commons.wikimedia.org/wiki/File:Ordinary_bicycle01.jpg")
|
||||||
self.assertEquals(feed_a.image_license, 1)
|
self.assertEquals(feed_a.image_license, 1)
|
||||||
self.assertEquals(feed_a.image_license_jurisdiction, "in the USA")
|
self.assertEquals(feed_a.image_license_jurisdiction, "in the USA")
|
||||||
self.assertEquals(feed_a.image, 'bicycle.jpg')
|
|
||||||
self.assertEquals(feed_a.image_license_url, "https://en.wikipedia.org/wiki/Public_domain")
|
self.assertEquals(feed_a.image_license_url, "https://en.wikipedia.org/wiki/Public_domain")
|
||||||
self.assertEquals(feed_a.image_license_name, 'Public Domain')
|
self.assertEquals(feed_a.image_license_name, 'Public Domain')
|
||||||
self.assertEquals(feed_a.license_url, "https://en.wikipedia.org/wiki/Public_domain")
|
self.assertEquals(feed_a.license_url, "https://en.wikipedia.org/wiki/Public_domain")
|
||||||
@ -320,7 +319,6 @@ class TestEditFeedViewTestCase(TestCase):
|
|||||||
self.assertEquals(feed_a.original_image_url, "https://commons.wikimedia.org/wiki/File:Ordinary_bicycle01.jpg")
|
self.assertEquals(feed_a.original_image_url, "https://commons.wikimedia.org/wiki/File:Ordinary_bicycle01.jpg")
|
||||||
self.assertEquals(feed_a.image_license, 1)
|
self.assertEquals(feed_a.image_license, 1)
|
||||||
self.assertEquals(feed_a.image_license_jurisdiction, "in the USA")
|
self.assertEquals(feed_a.image_license_jurisdiction, "in the USA")
|
||||||
self.assertEquals(feed_a.image, 'bicycle.jpg')
|
|
||||||
self.assertEquals(feed_a.image_license_url, "https://en.wikipedia.org/wiki/Public_domain")
|
self.assertEquals(feed_a.image_license_url, "https://en.wikipedia.org/wiki/Public_domain")
|
||||||
self.assertEquals(feed_a.image_license_name, 'Public Domain')
|
self.assertEquals(feed_a.image_license_name, 'Public Domain')
|
||||||
self.assertEquals(feed_a.license_url, "https://en.wikipedia.org/wiki/Public_domain")
|
self.assertEquals(feed_a.license_url, "https://en.wikipedia.org/wiki/Public_domain")
|
||||||
|
@ -131,7 +131,6 @@ class TestNewEpisodeViewTestCase(TestCase):
|
|||||||
self.assertEquals(str(episode_a.pub_date), pub_date)
|
self.assertEquals(str(episode_a.pub_date), pub_date)
|
||||||
self.assertEquals(episode_a.episode_number, 3)
|
self.assertEquals(episode_a.episode_number, 3)
|
||||||
self.assertEquals(episode_a.description, 'learn how to ride a bicycle')
|
self.assertEquals(episode_a.description, 'learn how to ride a bicycle')
|
||||||
self.assertEquals(episode_a.mp3, 'mark-twain-taming-the-bicycle.mp3')
|
|
||||||
self.assertEquals(episode_a.image_title, 'A Penny Farthing')
|
self.assertEquals(episode_a.image_title, 'A Penny Farthing')
|
||||||
self.assertEquals(episode_a.image_attribution, 'Agnieszka Kwiecień')
|
self.assertEquals(episode_a.image_attribution, 'Agnieszka Kwiecień')
|
||||||
self.assertEquals(
|
self.assertEquals(
|
||||||
@ -143,7 +142,6 @@ class TestNewEpisodeViewTestCase(TestCase):
|
|||||||
)
|
)
|
||||||
self.assertEquals(episode_a.image_license, 1)
|
self.assertEquals(episode_a.image_license, 1)
|
||||||
self.assertEquals(episode_a.image_license_jurisdiction, 'in the USA')
|
self.assertEquals(episode_a.image_license_jurisdiction, 'in the USA')
|
||||||
self.assertEquals(episode_a.image, 'bicycle.jpg')
|
|
||||||
self.assertEquals(episode_a.image_license_name, 'Public Domain')
|
self.assertEquals(episode_a.image_license_name, 'Public Domain')
|
||||||
self.assertEquals(
|
self.assertEquals(
|
||||||
episode_a.image_license_url, 'https://en.wikipedia.org/wiki/Public_domain'
|
episode_a.image_license_url, 'https://en.wikipedia.org/wiki/Public_domain'
|
||||||
|
@ -115,7 +115,6 @@ class TestNewFeedViewTestCase(TestCase):
|
|||||||
self.assertEquals(feed_a.original_image_url, "https://commons.wikimedia.org/wiki/File:Ordinary_bicycle01.jpg")
|
self.assertEquals(feed_a.original_image_url, "https://commons.wikimedia.org/wiki/File:Ordinary_bicycle01.jpg")
|
||||||
self.assertEquals(feed_a.image_license, 1)
|
self.assertEquals(feed_a.image_license, 1)
|
||||||
self.assertEquals(feed_a.image_license_jurisdiction, "in the USA")
|
self.assertEquals(feed_a.image_license_jurisdiction, "in the USA")
|
||||||
self.assertEquals(feed_a.image, 'bicycle.jpg')
|
|
||||||
self.assertEquals(feed_a.image_license_url, "https://en.wikipedia.org/wiki/Public_domain")
|
self.assertEquals(feed_a.image_license_url, "https://en.wikipedia.org/wiki/Public_domain")
|
||||||
self.assertEquals(feed_a.image_license_name, 'Public Domain')
|
self.assertEquals(feed_a.image_license_name, 'Public Domain')
|
||||||
self.assertEquals(feed_a.license_url, "https://en.wikipedia.org/wiki/Public_domain")
|
self.assertEquals(feed_a.license_url, "https://en.wikipedia.org/wiki/Public_domain")
|
||||||
|
@ -11,179 +11,182 @@ from .string_test_string import get_ep_description
|
|||||||
|
|
||||||
|
|
||||||
class TestRssTestCase(TestCase):
|
class TestRssTestCase(TestCase):
|
||||||
|
|
||||||
def test_rss(self):
|
def test_rss(self):
|
||||||
feed_a = Feed.objects.get(title='Caesar-Pompey Civil War')
|
feed_a = Feed.objects.get(title="Caesar-Pompey Civil War")
|
||||||
kw_args = {'slug': feed_a.slug}
|
kw_args = {"slug": feed_a.slug}
|
||||||
response = self.client.get(reverse('audio:rss', kwargs=kw_args))
|
response = self.client.get(reverse("audio:rss", kwargs=kw_args))
|
||||||
self.assertEquals(response.status_code, 200)
|
self.assertEquals(response.status_code, 200)
|
||||||
self.assertEquals(len(response.templates), 0)
|
self.assertEquals(len(response.templates), 0)
|
||||||
self.assertEquals(
|
self.assertEquals(response.request["PATH_INFO"], f"/rss/{feed_a.slug}.xml")
|
||||||
response.request['PATH_INFO'],
|
|
||||||
f'/rss/{feed_a.slug}.xml'
|
|
||||||
)
|
|
||||||
rss = ET.fromstring(response.content)
|
rss = ET.fromstring(response.content)
|
||||||
self.assertEquals(rss.attrib['version'], '2.0')
|
self.assertEquals(rss.attrib["version"], "2.0")
|
||||||
rss_children = [t.tag for t in rss.findall('*')]
|
rss_children = [t.tag for t in rss.findall("*")]
|
||||||
self.assertEquals(rss_children, ['channel'])
|
self.assertEquals(rss_children, ["channel"])
|
||||||
channel = rss.find('channel')
|
channel = rss.find("channel")
|
||||||
channel_children = [t.tag for t in channel.findall('*')]
|
channel_children = [t.tag for t in channel.findall("*")]
|
||||||
self.assertEquals(channel_children, [
|
self.assertEquals(
|
||||||
'title', 'link', 'description',
|
channel_children,
|
||||||
'{http://www.w3.org/2005/Atom}link',
|
[
|
||||||
'language', 'lastBuildDate', 'image',
|
"title",
|
||||||
'item', 'item'
|
"link",
|
||||||
])
|
"description",
|
||||||
channel_title = channel.find('title')
|
"{http://www.w3.org/2005/Atom}link",
|
||||||
self.assertEquals(channel_title.text, 'Caesar-Pompey Civil War')
|
"language",
|
||||||
cdt = channel.find('description').text
|
"lastBuildDate",
|
||||||
self.assertEquals(cdt, 'Civil War between Pompey and Caesar.')
|
"image",
|
||||||
channel_link = channel.find('link')
|
"item",
|
||||||
self.assertEquals(channel_link.text[-75:], reverse(
|
"item",
|
||||||
'audio:feed', kwargs={'pk': feed_a.pk, 'slug': feed_a.slug})
|
],
|
||||||
)
|
)
|
||||||
cdlang = channel.find('language').text
|
channel_title = channel.find("title")
|
||||||
self.assertEquals(cdlang, 'en-us')
|
self.assertEquals(channel_title.text, "Caesar-Pompey Civil War")
|
||||||
|
cdt = channel.find("description").text
|
||||||
|
self.assertEquals(cdt, "Civil War between Pompey and Caesar.")
|
||||||
|
channel_link = channel.find("link")
|
||||||
|
self.assertEquals(
|
||||||
|
channel_link.text[-75:],
|
||||||
|
reverse("audio:feed", kwargs={"pk": feed_a.pk, "slug": feed_a.slug}),
|
||||||
|
)
|
||||||
|
cdlang = channel.find("language").text
|
||||||
|
self.assertEquals(cdlang, "en-us")
|
||||||
latest_post = str(date.today() - timedelta(days=7))
|
latest_post = str(date.today() - timedelta(days=7))
|
||||||
cdlbd = parser.parse(channel.find('lastBuildDate').text)
|
cdlbd = parser.parse(channel.find("lastBuildDate").text)
|
||||||
cdlbd_string = cdlbd.strftime('%Y-%m-%d')
|
cdlbd_string = cdlbd.strftime("%Y-%m-%d")
|
||||||
self.assertEquals(latest_post, cdlbd_string)
|
self.assertEquals(latest_post, cdlbd_string)
|
||||||
f_image = channel.find('image')
|
f_image = channel.find("image")
|
||||||
f_image_children = [t.tag for t in f_image.findall('*')]
|
f_image_children = [t.tag for t in f_image.findall("*")]
|
||||||
self.assertEquals(f_image_children, [
|
self.assertEquals(f_image_children, ["url", "title", "link", "description"])
|
||||||
'url', 'title', 'link', 'description'
|
f_image_url = f_image.find("url").text
|
||||||
])
|
self.assertEquals(f_image_url, f"{IMAGES_URL}{feed_a.image}")
|
||||||
f_image_url = f_image.find('url').text
|
f_image_title = f_image.find("title").text
|
||||||
self.assertEquals(f_image_url, f'{IMAGES_URL}{feed_a.image}')
|
|
||||||
f_image_title = f_image.find('title').text
|
|
||||||
self.assertEquals(f_image_title, feed_a.title)
|
self.assertEquals(f_image_title, feed_a.title)
|
||||||
f_image_link = f_image.find('link').text
|
f_image_link = f_image.find("link").text
|
||||||
|
self.assertEquals(f_image_link, f"testserver/feed/{feed_a.pk}/{feed_a.slug}")
|
||||||
|
f_image_description = f_image.find("description").text
|
||||||
self.assertEquals(
|
self.assertEquals(
|
||||||
f_image_link,
|
f_image_description,
|
||||||
f'testserver/feed/{feed_a.pk}/{feed_a.slug}'
|
'<p>Photo <a href="https://commons.wikimedia.org/wiki/File:Ordinary_bicycle01.jpg">A Penny Farthing</a> by <a href="https://commons.wikimedia.org/wiki/User:Nova">Agnieszka Kwiecień</a> is licensed <a href="https://en.wikipedia.org/wiki/Public_domain">Public Domain</a> in the USA.</p>',
|
||||||
)
|
)
|
||||||
f_image_description = f_image.find('description').text
|
episodes = [t for t in channel.findall("item")]
|
||||||
self.assertEquals(
|
|
||||||
f_image_description, '<p>Photo <a href="https://commons.wikimedia.org/wiki/File:Ordinary_bicycle01.jpg">A Penny Farthing</a> by <a href="https://commons.wikimedia.org/wiki/User:Nova">Agnieszka Kwiecień</a> is licensed <a href="https://en.wikipedia.org/wiki/Public_domain">Public Domain</a> in the USA.</p>'
|
|
||||||
)
|
|
||||||
episodes = [t for t in channel.findall('item')]
|
|
||||||
for i, ep in enumerate(episodes):
|
for i, ep in enumerate(episodes):
|
||||||
ep_children = [t.tag for t in ep.findall('*')]
|
ep_children = [t.tag for t in ep.findall("*")]
|
||||||
self.assertEquals(ep_children, [
|
self.assertEquals(
|
||||||
'title', 'link', 'description',
|
ep_children,
|
||||||
'pubDate', 'guid', 'enclosure', 'image'
|
[
|
||||||
])
|
"title",
|
||||||
|
"link",
|
||||||
|
"description",
|
||||||
|
"pubDate",
|
||||||
|
"guid",
|
||||||
|
"enclosure",
|
||||||
|
"image",
|
||||||
|
],
|
||||||
|
)
|
||||||
episode = Episode.objects.get(feed=feed_a, episode_number=i + 1)
|
episode = Episode.objects.get(feed=feed_a, episode_number=i + 1)
|
||||||
ep_title = ep.find('title').text
|
ep_title = ep.find("title").text
|
||||||
self.assertEquals(ep_title, f'{episode.episode_number}: {episode.title}')
|
self.assertEquals(ep_title, f"{episode.episode_number}: {episode.title}")
|
||||||
ep_link = ep.find('link').text
|
ep_link = ep.find("link").text
|
||||||
self.assertEquals(
|
self.assertEquals(
|
||||||
ep_link,
|
ep_link, f"http://testserver/episode/{episode.pk}/{episode.slug}"
|
||||||
f'http://testserver/episode/{episode.pk}/{episode.slug}'
|
|
||||||
)
|
)
|
||||||
ep_desc = ep.find('description').text
|
ep_desc = ep.find("description").text
|
||||||
self.assertEquals(
|
self.assertEquals(ep_desc, get_ep_description(feed_a, episode))
|
||||||
ep_desc,
|
ep_pub_date = parser.parse(ep.find("pubDate").text).strftime("%Y-%m-%d")
|
||||||
get_ep_description(feed_a, episode)
|
|
||||||
)
|
|
||||||
ep_pub_date = parser.parse(ep.find('pubDate').text).strftime('%Y-%m-%d')
|
|
||||||
self.assertEquals(ep_pub_date, str(episode.pub_date))
|
self.assertEquals(ep_pub_date, str(episode.pub_date))
|
||||||
ep_guid = ep.find('guid').text
|
ep_guid = ep.find("guid").text
|
||||||
self.assertEquals(
|
self.assertEquals(
|
||||||
ep_guid,
|
ep_guid, f"http://testserver/episode/{episode.pk}/{episode.slug}"
|
||||||
f'http://testserver/episode/{episode.pk}/{episode.slug}'
|
|
||||||
)
|
)
|
||||||
ep_enclosure = ep.find('enclosure')
|
ep_enclosure = ep.find("enclosure")
|
||||||
self.assertEquals(ep_enclosure.keys(), ['length', 'type', 'url'])
|
self.assertEquals(ep_enclosure.keys(), ["length", "type", "url"])
|
||||||
self.assertEquals(
|
self.assertEquals(ep_enclosure.attrib["length"], str(episode.mp3.size))
|
||||||
ep_enclosure.attrib['length'], str(episode.image.size)
|
self.assertEquals(ep_enclosure.attrib["type"], "audio/mpeg")
|
||||||
)
|
self.assertEquals(ep_enclosure.attrib["url"], f"{MP3_URL}{episode.mp3}")
|
||||||
self.assertEquals(ep_enclosure.attrib['type'], 'audio/mpeg')
|
ep_image = ep.find("image")
|
||||||
self.assertEquals(
|
epim_children = [t.tag for t in ep_image.findall("*")]
|
||||||
ep_enclosure.attrib['url'], f'{MP3_URL}{episode.mp3}'
|
self.assertEquals(epim_children, ["url", "title", "link", "description"])
|
||||||
)
|
epim_url = ep_image.find("url").text
|
||||||
ep_image = ep.find('image')
|
self.assertEquals(epim_url, f"{IMAGES_URL}{episode.image.name}")
|
||||||
epim_children = [t.tag for t in ep_image.findall('*')]
|
epim_title = ep_image.find("title").text
|
||||||
self.assertEquals(
|
|
||||||
epim_children, ['url', 'title', 'link', 'description']
|
|
||||||
)
|
|
||||||
epim_url = ep_image.find('url').text
|
|
||||||
self.assertEquals(epim_url, f'{IMAGES_URL}{episode.image.name}')
|
|
||||||
epim_title = ep_image.find('title').text
|
|
||||||
self.assertEquals(epim_title, episode.title)
|
self.assertEquals(epim_title, episode.title)
|
||||||
epim_link = ep_image.find('link').text
|
epim_link = ep_image.find("link").text
|
||||||
self.assertEquals(
|
self.assertEquals(
|
||||||
epim_link,
|
epim_link, f"testserver/episode/{episode.pk}/{episode.slug}"
|
||||||
f'testserver/episode/{episode.pk}/{episode.slug}'
|
|
||||||
)
|
)
|
||||||
epim_desc = ep_image.find('description').text
|
epim_desc = ep_image.find("description").text
|
||||||
self.assertEquals(epim_desc, f'Image for: {episode.title}')
|
self.assertEquals(epim_desc, f"Image for: {episode.title}")
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
user_a = User.objects.create(username='user_a')
|
user_a = User.objects.create(username="user_a")
|
||||||
user_a.set_password('password_user_a')
|
user_a.set_password("password_user_a")
|
||||||
user_a.save()
|
user_a.save()
|
||||||
Account.objects.create(user=user_a)
|
Account.objects.create(user=user_a)
|
||||||
self.client.login(username='user_a', password='password_user_a')
|
self.client.login(username="user_a", password="password_user_a")
|
||||||
with open('bicycle.jpg', 'rb') as image_f:
|
with open("bicycle.jpg", "rb") as image_f:
|
||||||
self.client.post(reverse('audio:new_feed'), {
|
self.client.post(
|
||||||
'title': "Caesar-Pompey Civil War",
|
reverse("audio:new_feed"),
|
||||||
'author': "Gaius Julius Caesar",
|
{
|
||||||
'ebook_title': "Caesar's De Bello Gallico & Other Commentaries",
|
"title": "Caesar-Pompey Civil War",
|
||||||
'ebook_url': "https://gutenberg.org/ebooks/10657",
|
"author": "Gaius Julius Caesar",
|
||||||
'author_url': "https://gutenberg.org/ebooks/author/3621",
|
"ebook_title": "Caesar's De Bello Gallico & Other Commentaries",
|
||||||
'translator': 'McDevitte, W. A. (William Alexander)',
|
"ebook_url": "https://gutenberg.org/ebooks/10657",
|
||||||
'translator_url': 'https://gutenberg.org/ebooks/author/37952',
|
"author_url": "https://gutenberg.org/ebooks/author/3621",
|
||||||
'intro_author': 'De Quincey, Thomas',
|
"translator": "McDevitte, W. A. (William Alexander)",
|
||||||
'intro_author_url': 'https://gutenberg.org/ebooks/author/797',
|
"translator_url": "https://gutenberg.org/ebooks/author/37952",
|
||||||
'license': 1,
|
"intro_author": "De Quincey, Thomas",
|
||||||
'license_jurisdiction': 'in the USA',
|
"intro_author_url": "https://gutenberg.org/ebooks/author/797",
|
||||||
'description': "Civil War between Pompey and Caesar.",
|
"license": 1,
|
||||||
'image_title': 'A Penny Farthing',
|
"license_jurisdiction": "in the USA",
|
||||||
'image_attribution': 'Agnieszka Kwiecień',
|
"description": "Civil War between Pompey and Caesar.",
|
||||||
'image_attribution_url': 'https://commons.wikimedia.org/wiki/User:Nova',
|
"image_title": "A Penny Farthing",
|
||||||
'original_image_url': 'https://commons.wikimedia.org/wiki/File:Ordinary_bicycle01.jpg',
|
"image_attribution": "Agnieszka Kwiecień",
|
||||||
'image_license': 1,
|
"image_attribution_url": "https://commons.wikimedia.org/wiki/User:Nova",
|
||||||
'image_license_jurisdiction': 'in the USA',
|
"original_image_url": "https://commons.wikimedia.org/wiki/File:Ordinary_bicycle01.jpg",
|
||||||
'image': image_f,
|
"image_license": 1,
|
||||||
})
|
"image_license_jurisdiction": "in the USA",
|
||||||
feed_a = Feed.objects.get(title='Caesar-Pompey Civil War')
|
"image": image_f,
|
||||||
kw_args = {'feed_pk': feed_a.pk, 'feed_title_slug': feed_a.slug}
|
},
|
||||||
|
)
|
||||||
|
feed_a = Feed.objects.get(title="Caesar-Pompey Civil War")
|
||||||
|
kw_args = {"feed_pk": feed_a.pk, "feed_title_slug": feed_a.slug}
|
||||||
|
with (open("bicycle.jpg", "rb") as image_f, open("Mark Twain Taming The Bicycle.mp3", "rb") as mp3_f):
|
||||||
|
self.client.post(
|
||||||
|
reverse("audio:new_episode", kwargs=kw_args),
|
||||||
|
{
|
||||||
|
"title": "Caesar-Pompey Civil War Book I",
|
||||||
|
"author": "Gaius Julius Caesar",
|
||||||
|
"pub_date": str(date.today() - timedelta(days=8)),
|
||||||
|
"episode_number": 1,
|
||||||
|
"description": "Caesar confronts Afranius and Petreius",
|
||||||
|
"mp3": mp3_f,
|
||||||
|
"image_title": "A Penny Farthing",
|
||||||
|
"image_attribution": "Agnieszka Kwiecień",
|
||||||
|
"image_attribution_url": "https://commons.wikimedia.org/wiki/User:Nova",
|
||||||
|
"original_image_url": "https://commons.wikimedia.org/wiki/File:Ordinary_bicycle01.jpg",
|
||||||
|
"image_license": 1,
|
||||||
|
"image_license_jurisdiction": "in the USA",
|
||||||
|
"image": image_f,
|
||||||
|
},
|
||||||
|
)
|
||||||
with (
|
with (
|
||||||
open('bicycle.jpg', 'rb') as image_f,
|
open("bicycle.jpg", "rb") as image_f,
|
||||||
open('Mark Twain Taming The Bicycle.mp3', 'rb') as mp3_f
|
open("Mark Twain Taming The Bicycle.mp3", "rb") as mp3_f,
|
||||||
):
|
):
|
||||||
self.client.post(reverse('audio:new_episode', kwargs=kw_args), {
|
self.client.post(
|
||||||
'title': "Caesar-Pompey Civil War Book I",
|
reverse("audio:new_episode", kwargs=kw_args),
|
||||||
'author': "Gaius Julius Caesar",
|
{
|
||||||
'pub_date': str(date.today() - timedelta(days=8)),
|
"title": "Caesar-Pompey Civil War Book II",
|
||||||
'episode_number': 1,
|
"author": "Gaius Julius Caesar",
|
||||||
'description': 'Caesar confronts Afranius and Petreius',
|
"pub_date": str(date.today() - timedelta(days=7)),
|
||||||
'mp3': mp3_f,
|
"episode_number": 2,
|
||||||
'image_title': 'A Penny Farthing',
|
"description": "Trebonius confronts Domitius",
|
||||||
'image_attribution': 'Agnieszka Kwiecień',
|
"mp3": mp3_f,
|
||||||
'image_attribution_url': 'https://commons.wikimedia.org/wiki/User:Nova',
|
"image_title": "A Penny Farthing",
|
||||||
'original_image_url': 'https://commons.wikimedia.org/wiki/File:Ordinary_bicycle01.jpg',
|
"image_attribution": "Agnieszka Kwiecień",
|
||||||
'image_license': 1,
|
"image_attribution_url": "https://commons.wikimedia.org/wiki/User:Nova",
|
||||||
'image_license_jurisdiction': 'in the USA',
|
"original_image_url": "https://commons.wikimedia.org/wiki/File:Ordinary_bicycle01.jpg",
|
||||||
'image': image_f,
|
"image_license": 1,
|
||||||
})
|
"image_license_jurisdiction": "in the USA",
|
||||||
with (
|
"image": image_f,
|
||||||
open('bicycle.jpg', 'rb') as image_f,
|
},
|
||||||
open('Mark Twain Taming The Bicycle.mp3', 'rb') as mp3_f
|
)
|
||||||
):
|
|
||||||
self.client.post(reverse('audio:new_episode', kwargs=kw_args), {
|
|
||||||
'title': "Caesar-Pompey Civil War Book II",
|
|
||||||
'author': "Gaius Julius Caesar",
|
|
||||||
'pub_date': str(date.today() - timedelta(days=7)),
|
|
||||||
'episode_number': 2,
|
|
||||||
'description': 'Trebonius confronts Domitius',
|
|
||||||
'mp3': mp3_f,
|
|
||||||
'image_title': 'A Penny Farthing',
|
|
||||||
'image_attribution': 'Agnieszka Kwiecień',
|
|
||||||
'image_attribution_url': 'https://commons.wikimedia.org/wiki/User:Nova',
|
|
||||||
'original_image_url': 'https://commons.wikimedia.org/wiki/File:Ordinary_bicycle01.jpg',
|
|
||||||
'image_license': 1,
|
|
||||||
'image_license_jurisdiction': 'in the USA',
|
|
||||||
'image': image_f,
|
|
||||||
})
|
|
||||||
|
@ -4,24 +4,14 @@ import os
|
|||||||
from dotenv import load_dotenv
|
from dotenv import load_dotenv
|
||||||
load_dotenv()
|
load_dotenv()
|
||||||
|
|
||||||
# Build paths inside the project like this: BASE_DIR / 'subdir'.
|
|
||||||
BASE_DIR = Path(__file__).resolve().parent.parent
|
BASE_DIR = Path(__file__).resolve().parent.parent
|
||||||
|
|
||||||
|
|
||||||
# Quick-start development settings - unsuitable for production
|
|
||||||
# See https://docs.djangoproject.com/en/3.1/howto/deployment/checklist/
|
|
||||||
|
|
||||||
# SECURITY WARNING: keep the secret key used in production secret!
|
|
||||||
SECRET_KEY = str(os.getenv('SECRET_KEY'))
|
SECRET_KEY = str(os.getenv('SECRET_KEY'))
|
||||||
|
|
||||||
# SECURITY WARNING: don't run with debug turned on in production!
|
|
||||||
DEBUG = True if str(os.getenv('DEBUG')) == "True" else False
|
DEBUG = True if str(os.getenv('DEBUG')) == "True" else False
|
||||||
|
|
||||||
ALLOWED_HOSTS = [x for x in os.environ.get('ALLOWED_HOSTS').split(' ')]
|
ALLOWED_HOSTS = [x for x in os.environ.get('ALLOWED_HOSTS').split(' ')]
|
||||||
|
|
||||||
|
|
||||||
# Application definition
|
|
||||||
|
|
||||||
INSTALLED_APPS = [
|
INSTALLED_APPS = [
|
||||||
'django.contrib.admin',
|
'django.contrib.admin',
|
||||||
'django.contrib.auth',
|
'django.contrib.auth',
|
||||||
@ -34,7 +24,6 @@ INSTALLED_APPS = [
|
|||||||
'audio.apps.AudioConfig',
|
'audio.apps.AudioConfig',
|
||||||
'accounts.apps.AccountsConfig',
|
'accounts.apps.AccountsConfig',
|
||||||
'about.apps.AboutConfig',
|
'about.apps.AboutConfig',
|
||||||
'storages',
|
|
||||||
]
|
]
|
||||||
|
|
||||||
MIDDLEWARE = [
|
MIDDLEWARE = [
|
||||||
@ -58,6 +47,7 @@ TEMPLATES = [
|
|||||||
'context_processors': [
|
'context_processors': [
|
||||||
'django.template.context_processors.debug',
|
'django.template.context_processors.debug',
|
||||||
'django.template.context_processors.request',
|
'django.template.context_processors.request',
|
||||||
|
'django.template.context_processors.media',
|
||||||
'django.contrib.auth.context_processors.auth',
|
'django.contrib.auth.context_processors.auth',
|
||||||
'django.contrib.messages.context_processors.messages',
|
'django.contrib.messages.context_processors.messages',
|
||||||
],
|
],
|
||||||
@ -76,9 +66,6 @@ LOGGING_XMPP_CONFIG = {
|
|||||||
'LOGGING_XMPP_USE_TLS': str(os.getenv('LOGGING_XMPP_USE_TLS'))
|
'LOGGING_XMPP_USE_TLS': str(os.getenv('LOGGING_XMPP_USE_TLS'))
|
||||||
}
|
}
|
||||||
|
|
||||||
# Database
|
|
||||||
# https://docs.djangoproject.com/en/3.1/ref/settings/#databases
|
|
||||||
|
|
||||||
DATABASES = {
|
DATABASES = {
|
||||||
'default': {
|
'default': {
|
||||||
'ENGINE': 'django.db.backends.sqlite3',
|
'ENGINE': 'django.db.backends.sqlite3',
|
||||||
@ -88,10 +75,6 @@ DATABASES = {
|
|||||||
|
|
||||||
CRISPY_TEMPLATE_PACK = 'bootstrap4'
|
CRISPY_TEMPLATE_PACK = 'bootstrap4'
|
||||||
|
|
||||||
|
|
||||||
# Password validation
|
|
||||||
# https://docs.djangoproject.com/en/3.1/ref/settings/#auth-password-validators
|
|
||||||
|
|
||||||
AUTH_PASSWORD_VALIDATORS = [
|
AUTH_PASSWORD_VALIDATORS = [
|
||||||
{
|
{
|
||||||
'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
|
'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
|
||||||
@ -107,10 +90,6 @@ AUTH_PASSWORD_VALIDATORS = [
|
|||||||
},
|
},
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
# Internationalization
|
|
||||||
# https://docs.djangoproject.com/en/3.1/topics/i18n/
|
|
||||||
|
|
||||||
LANGUAGE_CODE = 'en-us'
|
LANGUAGE_CODE = 'en-us'
|
||||||
|
|
||||||
TIME_ZONE = 'America/Los_Angeles'
|
TIME_ZONE = 'America/Los_Angeles'
|
||||||
@ -121,34 +100,17 @@ USE_L10N = True
|
|||||||
|
|
||||||
USE_TZ = True
|
USE_TZ = True
|
||||||
|
|
||||||
|
STATIC_DOMAIN = os.getenv("STATIC_DOMAIN")
|
||||||
|
MP3_ROOT = os.path.join(BASE_DIR, 'media/audio/mp3')
|
||||||
|
IMAGE_ROOT = os.path.join(BASE_DIR, 'media/audio/images')
|
||||||
|
MEDIA_ROOT = os.path.join(BASE_DIR, 'media/audio')
|
||||||
|
|
||||||
# Static files (CSS, JavaScript, Images)
|
STATIC_URL = f"{STATIC_DOMAIN}/static/"
|
||||||
# https://docs.djangoproject.com/en/3.1/howto/static-files/
|
|
||||||
|
|
||||||
# STATIC_URL = '/static/'
|
|
||||||
|
|
||||||
# aws settings
|
|
||||||
AWS_ACCESS_KEY_ID = os.getenv('AWS_ACCESS_KEY_ID')
|
|
||||||
AWS_SECRET_ACCESS_KEY = os.getenv('AWS_SECRET_ACCESS_KEY')
|
|
||||||
AWS_STORAGE_BUCKET_NAME = os.getenv('AWS_STORAGE_BUCKET_NAME')
|
|
||||||
AWS_S3_ENDPOINT_URL = os.getenv('AWS_S3_ENDPOINT_URL')
|
|
||||||
AWS_DEFAULT_ACL = None
|
|
||||||
# AWS_S3_CUSTOM_DOMAIN = f'{AWS_STORAGE_BUCKET_NAME}.s3.amazonaws.com'
|
|
||||||
AWS_S3_CUSTOM_DOMAIN = os.getenv('AWS_S3_CUSTOM_DOMAIN')
|
|
||||||
AWS_S3_OBJECT_PARAMETERS = {'CacheControl': 'max-age=86400'}
|
|
||||||
# s3 static settings
|
|
||||||
STATIC_LOCATION = 'static'
|
|
||||||
STATIC_URL = f'https://{AWS_S3_CUSTOM_DOMAIN}/{STATIC_LOCATION}/'
|
|
||||||
STATICFILES_STORAGE = 'tp.storage_backends.StaticStorage'
|
|
||||||
# s3 public media settings
|
|
||||||
PUBLIC_MP3_LOCATION = 'mp3'
|
|
||||||
MP3_URL = f'https://{AWS_S3_CUSTOM_DOMAIN}/{PUBLIC_MP3_LOCATION}/'
|
|
||||||
MP3_FILE_STORAGE = 'tp.storage_backends.PublicMP3Storage'
|
|
||||||
PUBLIC_IMAGES_LOCATION = 'images'
|
|
||||||
IMAGES_URL = f'https://{AWS_S3_CUSTOM_DOMAIN}/{PUBLIC_IMAGES_LOCATION}/'
|
|
||||||
IMAGES_FILE_STORAGE = 'tp.storage_backends.PublicImageStorage'
|
|
||||||
|
|
||||||
STATICFILES_DIRS = (os.path.join(BASE_DIR, 'static'),)
|
STATICFILES_DIRS = (os.path.join(BASE_DIR, 'static'),)
|
||||||
|
MEDIA_URL = f"{STATIC_DOMAIN}/audio/"
|
||||||
|
IMAGES_URL = f"{MEDIA_URL}images/"
|
||||||
|
MP3_URL = f"{MEDIA_URL}mp3/"
|
||||||
|
|
||||||
LOGGING = init_logging_settings()
|
LOGGING = init_logging_settings()
|
||||||
|
|
||||||
EMAIL_BACKEND = os.getenv('EMAIL_BACKEND')
|
EMAIL_BACKEND = os.getenv('EMAIL_BACKEND')
|
||||||
|
15
tp/urls.py
15
tp/urls.py
@ -1,18 +1,3 @@
|
|||||||
"""tp URL Configuration
|
|
||||||
|
|
||||||
The `urlpatterns` list routes URLs to views. For more information please see:
|
|
||||||
https://docs.djangoproject.com/en/3.1/topics/http/urls/
|
|
||||||
Examples:
|
|
||||||
Function views
|
|
||||||
1. Add an import: from my_app import views
|
|
||||||
2. Add a URL to urlpatterns: path('', views.home, name='home')
|
|
||||||
Class-based views
|
|
||||||
1. Add an import: from other_app.views import Home
|
|
||||||
2. Add a URL to urlpatterns: path('', Home.as_view(), name='home')
|
|
||||||
Including another URLconf
|
|
||||||
1. Import the include() function: from django.urls import include, path
|
|
||||||
2. Add a URL to urlpatterns: path('blog/', include('blog.urls'))
|
|
||||||
"""
|
|
||||||
from django.contrib import admin
|
from django.contrib import admin
|
||||||
from django.urls import path, include
|
from django.urls import path, include
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user