Run Black over the whole codebase

This commit is contained in:
Danielle McLean 2023-08-10 16:52:37 +10:00
parent cd990e4e2f
commit 2e7d12b3e6
Signed by: 00dani
GPG key ID: 52C059C3B22A753E
109 changed files with 1539 additions and 1209 deletions

View file

@ -8,12 +8,10 @@ class SyndicationInline(admin.TabularInline):
class EntryAdmin(admin.ModelAdmin):
date_hierarchy = 'created'
list_display = ('title', 'id', 'kind', 'created')
list_filter = ('kind',)
inlines = (
SyndicationInline,
)
date_hierarchy = "created"
list_display = ("title", "id", "kind", "created")
list_filter = ("kind",)
inlines = (SyndicationInline,)
admin.site.register(Cat)

View file

@ -2,4 +2,4 @@ from django.apps import AppConfig
class EntriesConfig(AppConfig):
name = 'entries'
name = "entries"

View file

@ -11,24 +11,24 @@ from .models import Entry
def from_url(url: str) -> Entry:
domain = Site.objects.get_current().domain
if not url:
raise error.bad_req('url parameter required')
if '//' not in url:
url = '//' + url
parts = urlparse(url, scheme='https')
if parts.scheme not in ('http', 'https') or parts.netloc != domain:
raise error.bad_req('url does not point to this site')
raise error.bad_req("url parameter required")
if "//" not in url:
url = "//" + url
parts = urlparse(url, scheme="https")
if parts.scheme not in ("http", "https") or parts.netloc != domain:
raise error.bad_req("url does not point to this site")
try:
match = resolve(parts.path)
except Resolver404:
raise error.bad_req('url does not point to a valid page on this site')
raise error.bad_req("url does not point to a valid page on this site")
if match.view_name != 'entries:entry':
raise error.bad_req('url does not point to an entry on this site')
if match.view_name != "entries:entry":
raise error.bad_req("url does not point to an entry on this site")
try:
entry = Entry.objects.get(pk=match.kwargs['id'])
entry = Entry.objects.get(pk=match.kwargs["id"])
except Entry.DoesNotExist:
raise error.bad_req('url does not point to an existing entry')
raise error.bad_req("url does not point to an existing entry")
return entry

View file

@ -7,16 +7,19 @@ from ronkyuu import webmention
@job
def ping_hub(*urls):
for url in urls:
requests.post(settings.PUSH_HUB, data={
'hub.mode': 'publish',
'hub.url': url,
})
requests.post(
settings.PUSH_HUB,
data={
"hub.mode": "publish",
"hub.url": url,
},
)
@job
def send_mentions(source, targets=None):
if targets is None:
targets = webmention.findMentions(source)['refs']
targets = webmention.findMentions(source)["refs"]
for target in targets:
status, endpoint = webmention.discoverEndpoint(target)
if endpoint is not None and status == 200:

View file

@ -14,62 +14,62 @@ class Entry:
return self.index_page()
def index_page(self, page=0):
kwargs = {'kind': self}
kwargs = {"kind": self}
if page > 1:
kwargs['page'] = page
return reverse('entries:index', kwargs=kwargs)
kwargs["page"] = page
return reverse("entries:index", kwargs=kwargs)
@property
def entry(self):
return self.plural + '_entry'
return self.plural + "_entry"
@property
def atom(self):
return reverse('entries:atom_by_kind', kwargs={'kind': self})
return reverse("entries:atom_by_kind", kwargs={"kind": self})
@property
def rss(self):
return reverse('entries:rss_by_kind', kwargs={'kind': self})
return reverse("entries:rss_by_kind", kwargs={"kind": self})
Note = Entry(
id='note',
icon='fas fa-paper-plane',
plural='notes',
id="note",
icon="fas fa-paper-plane",
plural="notes",
)
Article = Entry(
id='article',
icon='fas fa-file-alt',
plural='articles',
id="article",
icon="fas fa-file-alt",
plural="articles",
slug=True,
)
Photo = Entry(
id='photo',
icon='fas fa-camera',
plural='photos',
id="photo",
icon="fas fa-camera",
plural="photos",
)
Reply = Entry(
id='reply',
icon='fas fa-comment',
plural='replies',
id="reply",
icon="fas fa-comment",
plural="replies",
on_home=False,
)
Like = Entry(
id='like',
icon='fas fa-heart',
plural='likes',
id="like",
icon="fas fa-heart",
plural="likes",
on_home=False,
)
Repost = Entry(
id='repost',
icon='fas fa-retweet',
plural='reposts',
id="repost",
icon="fas fa-retweet",
plural="reposts",
)
all = (Note, Article, Photo)
@ -79,7 +79,7 @@ from_plural = {k.plural: k for k in all}
class EntryKindConverter:
regex = '|'.join(k.plural for k in all)
regex = "|".join(k.plural for k in all)
def to_python(self, plural):
return from_plural[plural]

View file

@ -8,7 +8,6 @@ import django.db.models.deletion
class Migration(migrations.Migration):
initial = True
dependencies = [
@ -17,20 +16,41 @@ class Migration(migrations.Migration):
operations = [
migrations.CreateModel(
name='Entry',
name="Entry",
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('kind', models.CharField(choices=[('note', 'Note'), ('article', 'Article')], default='note', max_length=30)),
('name', models.CharField(blank=True, max_length=100)),
('summary', models.TextField(blank=True)),
('content', models.TextField()),
('published', models.DateTimeField()),
('updated', models.DateTimeField()),
('author', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
(
"id",
models.AutoField(
auto_created=True,
primary_key=True,
serialize=False,
verbose_name="ID",
),
),
(
"kind",
models.CharField(
choices=[("note", "Note"), ("article", "Article")],
default="note",
max_length=30,
),
),
("name", models.CharField(blank=True, max_length=100)),
("summary", models.TextField(blank=True)),
("content", models.TextField()),
("published", models.DateTimeField()),
("updated", models.DateTimeField()),
(
"author",
models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE,
to=settings.AUTH_USER_MODEL,
),
),
],
options={
'verbose_name_plural': 'entries',
'ordering': ['-published'],
"verbose_name_plural": "entries",
"ordering": ["-published"],
},
),
]

View file

@ -7,23 +7,42 @@ import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('users', '0005_auto_20171023_0158'),
('entries', '0001_initial'),
("users", "0005_auto_20171023_0158"),
("entries", "0001_initial"),
]
operations = [
migrations.CreateModel(
name='Syndication',
name="Syndication",
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('url', models.CharField(max_length=255)),
('entry', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='syndications', to='entries.Entry')),
('profile', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='users.Profile')),
(
"id",
models.AutoField(
auto_created=True,
primary_key=True,
serialize=False,
verbose_name="ID",
),
),
("url", models.CharField(max_length=255)),
(
"entry",
models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE,
related_name="syndications",
to="entries.Entry",
),
),
(
"profile",
models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE, to="users.Profile"
),
),
],
options={
'ordering': ['profile'],
"ordering": ["profile"],
},
),
]

View file

@ -6,14 +6,13 @@ from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('entries', '0002_syndication'),
("entries", "0002_syndication"),
]
operations = [
migrations.RemoveField(
model_name='entry',
name='summary',
model_name="entry",
name="summary",
),
]

View file

@ -8,20 +8,28 @@ import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('entries', '0003_remove_entry_summary'),
("entries", "0003_remove_entry_summary"),
]
operations = [
migrations.AlterField(
model_name='entry',
name='author',
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='entries', to=settings.AUTH_USER_MODEL),
model_name="entry",
name="author",
field=models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE,
related_name="entries",
to=settings.AUTH_USER_MODEL,
),
),
migrations.AlterField(
model_name='entry',
name='kind',
field=models.CharField(choices=[('note', 'note'), ('article', 'article')], db_index=True, default='note', max_length=30),
model_name="entry",
name="kind",
field=models.CharField(
choices=[("note", "note"), ("article", "article")],
db_index=True,
default="note",
max_length=30,
),
),
]

View file

@ -6,20 +6,24 @@ from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('entries', '0004_auto_20171027_0846'),
("entries", "0004_auto_20171027_0846"),
]
operations = [
migrations.AddField(
model_name='entry',
name='photo',
field=models.ImageField(blank=True, upload_to=''),
model_name="entry",
name="photo",
field=models.ImageField(blank=True, upload_to=""),
),
migrations.AlterField(
model_name='entry',
name='kind',
field=models.CharField(choices=[('note', 'note'), ('article', 'article'), ('photo', 'photo')], db_index=True, default='note', max_length=30),
model_name="entry",
name="kind",
field=models.CharField(
choices=[("note", "note"), ("article", "article"), ("photo", "photo")],
db_index=True,
default="note",
max_length=30,
),
),
]

View file

@ -8,34 +8,41 @@ import model_utils.fields
class Migration(migrations.Migration):
dependencies = [
('entries', '0005_auto_20171027_1557'),
("entries", "0005_auto_20171027_1557"),
]
operations = [
migrations.AlterModelOptions(
name='entry',
options={'ordering': ['-created'], 'verbose_name_plural': 'entries'},
name="entry",
options={"ordering": ["-created"], "verbose_name_plural": "entries"},
),
migrations.RenameField(
model_name='entry',
old_name='published',
new_name='created',
model_name="entry",
old_name="published",
new_name="created",
),
migrations.RenameField(
model_name='entry',
old_name='updated',
new_name='modified',
model_name="entry",
old_name="updated",
new_name="modified",
),
migrations.AlterField(
model_name='entry',
name='created',
field=model_utils.fields.AutoCreatedField(default=django.utils.timezone.now, editable=False, verbose_name='created'),
model_name="entry",
name="created",
field=model_utils.fields.AutoCreatedField(
default=django.utils.timezone.now,
editable=False,
verbose_name="created",
),
),
migrations.AlterField(
model_name='entry',
name='modified',
field=model_utils.fields.AutoLastModifiedField(default=django.utils.timezone.now, editable=False, verbose_name='modified'),
model_name="entry",
name="modified",
field=model_utils.fields.AutoLastModifiedField(
default=django.utils.timezone.now,
editable=False,
verbose_name="modified",
),
),
]

View file

@ -6,20 +6,31 @@ from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('entries', '0006_auto_20171102_1200'),
("entries", "0006_auto_20171102_1200"),
]
operations = [
migrations.AddField(
model_name='entry',
name='cite',
model_name="entry",
name="cite",
field=models.CharField(blank=True, max_length=255),
),
migrations.AlterField(
model_name='entry',
name='kind',
field=models.CharField(choices=[('note', 'note'), ('article', 'article'), ('photo', 'photo'), ('reply', 'reply'), ('like', 'like'), ('repost', 'repost')], db_index=True, default='note', max_length=30),
model_name="entry",
name="kind",
field=models.CharField(
choices=[
("note", "note"),
("article", "article"),
("photo", "photo"),
("reply", "reply"),
("like", "like"),
("repost", "repost"),
],
db_index=True,
default="note",
max_length=30,
),
),
]

View file

@ -6,25 +6,24 @@ from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('entries', '0007_auto_20171113_0841'),
("entries", "0007_auto_20171113_0841"),
]
operations = [
migrations.RenameField(
model_name='entry',
old_name='cite',
new_name='in_reply_to',
model_name="entry",
old_name="cite",
new_name="in_reply_to",
),
migrations.AddField(
model_name='entry',
name='like_of',
model_name="entry",
name="like_of",
field=models.CharField(blank=True, max_length=255),
),
migrations.AddField(
model_name='entry',
name='repost_of',
model_name="entry",
name="repost_of",
field=models.CharField(blank=True, max_length=255),
),
]

View file

@ -6,21 +6,28 @@ from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('entries', '0008_auto_20171116_2116'),
("entries", "0008_auto_20171116_2116"),
]
operations = [
migrations.CreateModel(
name='Tag',
name="Tag",
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('name', models.CharField(max_length=255, unique=True)),
('slug', models.CharField(max_length=255, unique=True)),
(
"id",
models.AutoField(
auto_created=True,
primary_key=True,
serialize=False,
verbose_name="ID",
),
),
("name", models.CharField(max_length=255, unique=True)),
("slug", models.CharField(max_length=255, unique=True)),
],
options={
'ordering': ('name',),
"ordering": ("name",),
},
),
]

View file

@ -6,15 +6,14 @@ from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('entries', '0009_tag'),
("entries", "0009_tag"),
]
operations = [
migrations.AddField(
model_name='entry',
name='tags',
field=models.ManyToManyField(related_name='entries', to='entries.Tag'),
model_name="entry",
name="tags",
field=models.ManyToManyField(related_name="entries", to="entries.Tag"),
),
]

View file

@ -9,17 +9,17 @@ class Migration(migrations.Migration):
atomic = False
dependencies = [
('entries', '0010_entry_tags'),
("entries", "0010_entry_tags"),
]
operations = [
migrations.RenameModel(
old_name='Tag',
new_name='Cat',
old_name="Tag",
new_name="Cat",
),
migrations.RenameField(
model_name='entry',
old_name='tags',
new_name='cats',
model_name="entry",
old_name="tags",
new_name="cats",
),
]

View file

@ -5,25 +5,25 @@ from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('entries', '0011_auto_20171120_1108'),
("entries", "0011_auto_20171120_1108"),
]
operations = [
migrations.AlterModelOptions(
name='syndication',
options={'ordering': ['domain']},
name="syndication",
options={"ordering": ["domain"]},
),
migrations.RemoveField(
model_name='syndication',
name='profile',
model_name="syndication",
name="profile",
),
migrations.AddField(
model_name='syndication',
name='domain',
model_name="syndication",
name="domain",
field=computed_property.fields.ComputedCharField(
compute_from='calc_domain', default='', editable=False, max_length=255),
compute_from="calc_domain", default="", editable=False, max_length=255
),
preserve_default=False,
),
]

View file

@ -4,24 +4,19 @@ from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('entries', '0012_auto_20180628_2044'),
("entries", "0012_auto_20180628_2044"),
]
operations = [
migrations.AlterField(
model_name='entry',
name='kind',
model_name="entry",
name="kind",
field=models.CharField(
choices=[
('note', 'note'),
('article', 'article'),
('photo', 'photo')
],
choices=[("note", "note"), ("article", "article"), ("photo", "photo")],
db_index=True,
default='note',
max_length=30
default="note",
max_length=30,
),
),
]

View file

@ -17,6 +17,7 @@ from users.models import Site
from . import kinds
from lemoncurry import requests, utils
ENTRY_KINDS = [(k.id, k.id) for k in kinds.all]
@ -32,38 +33,33 @@ class Cat(models.Model):
slug = models.CharField(max_length=255, unique=True)
def __str__(self):
return '#' + self.name
return "#" + self.name
@property
def url(self):
return reverse('entries:cat', args=(self.slug,))
return reverse("entries:cat", args=(self.slug,))
class Meta:
ordering = ('name',)
ordering = ("name",)
class EntryManager(models.Manager):
def get_queryset(self):
qs = super(EntryManager, self).get_queryset()
return (qs
.select_related('author')
.prefetch_related('cats', 'syndications'))
return qs.select_related("author").prefetch_related("cats", "syndications")
class Entry(ModelMeta, TimeStampedModel):
objects = EntryManager()
kind = models.CharField(
max_length=30,
choices=ENTRY_KINDS,
db_index=True,
default=ENTRY_KINDS[0][0]
max_length=30, choices=ENTRY_KINDS, db_index=True, default=ENTRY_KINDS[0][0]
)
name = models.CharField(max_length=100, blank=True)
photo = models.ImageField(blank=True)
content = models.TextField()
cats = models.ManyToManyField(Cat, related_name='entries')
cats = models.ManyToManyField(Cat, related_name="entries")
in_reply_to = models.CharField(max_length=255, blank=True)
like_of = models.CharField(max_length=255, blank=True)
@ -71,7 +67,7 @@ class Entry(ModelMeta, TimeStampedModel):
author = models.ForeignKey(
get_user_model(),
related_name='entries',
related_name="entries",
on_delete=models.CASCADE,
)
@ -79,10 +75,7 @@ class Entry(ModelMeta, TimeStampedModel):
def reply_context(self):
if not self.in_reply_to:
return None
return interpret(
requests.mf2(self.in_reply_to).to_dict(),
self.in_reply_to
)
return interpret(requests.mf2(self.in_reply_to).to_dict(), self.in_reply_to)
@property
def published(self):
@ -93,35 +86,29 @@ class Entry(ModelMeta, TimeStampedModel):
return self.modified
_metadata = {
'description': 'excerpt',
'image': 'image_url',
'twitter_creator': 'twitter_creator',
'og_profile_id': 'og_profile_id',
"description": "excerpt",
"image": "image_url",
"twitter_creator": "twitter_creator",
"og_profile_id": "og_profile_id",
}
@property
def title(self):
if self.name:
return self.name
return shorten(
utils.to_plain(self.paragraphs[0]),
width=100,
placeholder=''
)
return shorten(utils.to_plain(self.paragraphs[0]), width=100, placeholder="")
@property
def excerpt(self):
try:
return utils.to_plain(self.paragraphs[0 if self.name else 1])
except IndexError:
return ' '
return " "
@property
def paragraphs(self):
lines = self.content.splitlines()
return [
"\n".join(para) for k, para in groupby(lines, key=bool) if k
]
return ["\n".join(para) for k, para in groupby(lines, key=bool) if k]
@property
def twitter_creator(self):
@ -136,31 +123,31 @@ class Entry(ModelMeta, TimeStampedModel):
return self.photo.url if self.photo else self.author.avatar_url
def __str__(self):
return '{0} {1}: {2}'.format(self.kind, self.id, self.title)
return "{0} {1}: {2}".format(self.kind, self.id, self.title)
def get_absolute_url(self):
return self.absolute_url
@property
def absolute_url(self):
base = 'https://' + DjangoSite.objects.get_current().domain
base = "https://" + DjangoSite.objects.get_current().domain
return urljoin(base, self.url)
@property
def affected_urls(self):
base = 'https://' + DjangoSite.objects.get_current().domain
base = "https://" + DjangoSite.objects.get_current().domain
kind = kinds.from_id[self.kind]
urls = {
self.url,
reverse('entries:index', kwargs={'kind': kind}),
reverse('entries:atom_by_kind', kwargs={'kind': kind}),
reverse('entries:rss_by_kind', kwargs={'kind': kind}),
reverse("entries:index", kwargs={"kind": kind}),
reverse("entries:atom_by_kind", kwargs={"kind": kind}),
reverse("entries:rss_by_kind", kwargs={"kind": kind}),
} | {cat.url for cat in self.cats.all()}
if kind.on_home:
urls |= {
reverse('home:index'),
reverse('entries:atom'),
reverse('entries:rss')
reverse("home:index"),
reverse("entries:atom"),
reverse("entries:rss"),
}
return {urljoin(base, u) for u in urls}
@ -170,7 +157,7 @@ class Entry(ModelMeta, TimeStampedModel):
args = [kind, self.id]
if kind.slug:
args.append(self.slug)
return reverse('entries:entry', args=args)
return reverse("entries:entry", args=args)
@property
def short_url(self):
@ -182,49 +169,48 @@ class Entry(ModelMeta, TimeStampedModel):
@property
def json_ld(self):
base = 'https://' + DjangoSite.objects.get_current().domain
base = "https://" + DjangoSite.objects.get_current().domain
url = urljoin(base, self.url)
posting = {
'@context': 'http://schema.org',
'@type': 'BlogPosting',
'@id': url,
'url': url,
'mainEntityOfPage': url,
'author': {
'@type': 'Person',
'url': urljoin(base, self.author.url),
'name': self.author.name,
"@context": "http://schema.org",
"@type": "BlogPosting",
"@id": url,
"url": url,
"mainEntityOfPage": url,
"author": {
"@type": "Person",
"url": urljoin(base, self.author.url),
"name": self.author.name,
},
'headline': self.title,
'description': self.excerpt,
'datePublished': self.created.isoformat(),
'dateModified': self.modified.isoformat(),
"headline": self.title,
"description": self.excerpt,
"datePublished": self.created.isoformat(),
"dateModified": self.modified.isoformat(),
}
if self.photo:
posting['image'] = (urljoin(base, self.photo.url), )
posting["image"] = (urljoin(base, self.photo.url),)
return posting
class Meta:
verbose_name_plural = 'entries'
ordering = ['-created']
verbose_name_plural = "entries"
ordering = ["-created"]
class Syndication(models.Model):
entry = models.ForeignKey(
Entry,
related_name='syndications',
on_delete=models.CASCADE
Entry, related_name="syndications", on_delete=models.CASCADE
)
url = models.CharField(max_length=255)
domain = ComputedCharField(
compute_from='calc_domain', max_length=255,
compute_from="calc_domain",
max_length=255,
)
def calc_domain(self):
domain = urlparse(self.url).netloc
if domain.startswith('www.'):
if domain.startswith("www."):
domain = domain[4:]
return domain
@ -234,7 +220,7 @@ class Syndication(models.Model):
try:
return Site.objects.get(domain=d)
except Site.DoesNotExist:
return Site(name=d, domain=d, icon='fas fa-newspaper')
return Site(name=d, domain=d, icon="fas fa-newspaper")
class Meta:
ordering = ['domain']
ordering = ["domain"]

View file

@ -3,27 +3,27 @@ import pytest
@pytest.mark.django_db
def test_atom(client):
res = client.get('/atom')
res = client.get("/atom")
assert res.status_code == 200
assert res['Content-Type'] == 'application/atom+xml; charset=utf-8'
assert res["Content-Type"] == "application/atom+xml; charset=utf-8"
@pytest.mark.django_db
def test_rss(client):
res = client.get('/rss')
res = client.get("/rss")
assert res.status_code == 200
assert res['Content-Type'] == 'application/rss+xml; charset=utf-8'
assert res["Content-Type"] == "application/rss+xml; charset=utf-8"
@pytest.mark.django_db
def test_atom_by_kind(client):
res = client.get('/notes/atom')
res = client.get("/notes/atom")
assert res.status_code == 200
assert res['Content-Type'] == 'application/atom+xml; charset=utf-8'
assert res["Content-Type"] == "application/atom+xml; charset=utf-8"
@pytest.mark.django_db
def test_rss_by_kind(client):
res = client.get('/notes/rss')
res = client.get("/notes/rss")
assert res.status_code == 200
assert res['Content-Type'] == 'application/rss+xml; charset=utf-8'
assert res["Content-Type"] == "application/rss+xml; charset=utf-8"

View file

@ -3,47 +3,46 @@ from . import kinds
from .views import feeds, lists, perma
from lemoncurry import breadcrumbs as crumbs
register_converter(kinds.EntryKindConverter, 'kind')
register_converter(kinds.EntryKindConverter, "kind")
def to_pat(*args):
return '^{0}$'.format(''.join(args))
return "^{0}$".format("".join(args))
def prefix(route):
return app_name + ':' + route
return app_name + ":" + route
id = r'/(?P<id>\d+)'
kind = r'(?P<kind>{0})'.format('|'.join(k.plural for k in kinds.all))
page = r'(?:/page/(?P<page>\d+))?'
slug = r'/(?P<slug>[^/]+)'
id = r"/(?P<id>\d+)"
kind = r"(?P<kind>{0})".format("|".join(k.plural for k in kinds.all))
page = r"(?:/page/(?P<page>\d+))?"
slug = r"/(?P<slug>[^/]+)"
slug_opt = '(?:' + slug + ')?'
slug_opt = "(?:" + slug + ")?"
app_name = 'entries'
app_name = "entries"
urlpatterns = (
path('atom', feeds.AtomHomeEntries(), name='atom'),
path('rss', feeds.RssHomeEntries(), name='rss'),
path('cats/<slug:slug>', lists.by_cat, name='cat'),
path('cats/<slug:slug>/page/<int:page>', lists.by_cat, name='cat'),
path('<kind:kind>', lists.by_kind, name='index'),
path('<kind:kind>/page/<int:page>', lists.by_kind, name='index'),
path('<kind:kind>/atom', feeds.AtomByKind(), name='atom_by_kind'),
path('<kind:kind>/rss', feeds.RssByKind(), name='rss_by_kind'),
path('<kind:kind>/<int:id>', perma.entry, name='entry'),
path('<kind:kind>/<int:id>/<slug:slug>', perma.entry, name='entry'),
path("atom", feeds.AtomHomeEntries(), name="atom"),
path("rss", feeds.RssHomeEntries(), name="rss"),
path("cats/<slug:slug>", lists.by_cat, name="cat"),
path("cats/<slug:slug>/page/<int:page>", lists.by_cat, name="cat"),
path("<kind:kind>", lists.by_kind, name="index"),
path("<kind:kind>/page/<int:page>", lists.by_kind, name="index"),
path("<kind:kind>/atom", feeds.AtomByKind(), name="atom_by_kind"),
path("<kind:kind>/rss", feeds.RssByKind(), name="rss_by_kind"),
path("<kind:kind>/<int:id>", perma.entry, name="entry"),
path("<kind:kind>/<int:id>/<slug:slug>", perma.entry, name="entry"),
)
class IndexCrumb(crumbs.Crumb):
def __init__(self):
super().__init__(prefix('index'), parent='home:index')
super().__init__(prefix("index"), parent="home:index")
@property
def kind(self):
return self.match.kwargs['kind']
return self.match.kwargs["kind"]
@property
def label(self):
@ -51,9 +50,9 @@ class IndexCrumb(crumbs.Crumb):
@property
def url(self):
return reverse(prefix('index'), kwargs={'kind': self.kind})
return reverse(prefix("index"), kwargs={"kind": self.kind})
crumbs.add(prefix('cat'), parent='home:index')
crumbs.add(prefix("cat"), parent="home:index")
crumbs.add(IndexCrumb())
crumbs.add(prefix('entry'), parent=prefix('index'))
crumbs.add(prefix("entry"), parent=prefix("index"))

View file

@ -11,8 +11,8 @@ from ..models import Entry
class Atom1FeedWithHub(Atom1Feed):
def add_root_elements(self, handler):
super().add_root_elements(handler)
handler.startElement('link', {'rel': 'hub', 'href': settings.PUSH_HUB})
handler.endElement('link')
handler.startElement("link", {"rel": "hub", "href": settings.PUSH_HUB})
handler.endElement("link")
class EntriesFeed(Feed):
@ -79,7 +79,7 @@ class RssHomeEntries(EntriesFeed):
return Site.objects.get_current().name
def link(self):
return reverse('home:index')
return reverse("home:index")
def description(self):
return "content from {0}".format(

View file

@ -5,32 +5,32 @@ from ..models import Entry, Cat
from ..pagination import paginate
@render_to('entries/index.html')
@render_to("entries/index.html")
def by_kind(request, kind, page=None):
entries = Entry.objects.filter(kind=kind.id)
entries = paginate(queryset=entries, reverse=kind.index_page, page=page)
return {
'entries': entries,
'atom': kind.atom,
'rss': kind.rss,
'title': kind.plural,
"entries": entries,
"atom": kind.atom,
"rss": kind.rss,
"title": kind.plural,
}
@render_to('entries/index.html')
@render_to("entries/index.html")
def by_cat(request, slug, page=None):
def url(page):
kwargs = {'slug': slug}
kwargs = {"slug": slug}
if page > 1:
kwargs['page'] = page
return reverse('entries:cat', kwargs=kwargs)
kwargs["page"] = page
return reverse("entries:cat", kwargs=kwargs)
cat = get_object_or_404(Cat, slug=slug)
entries = cat.entries.all()
entries = paginate(queryset=entries, reverse=url, page=page)
return {
'entries': entries,
'title': '#' + cat.name,
"entries": entries,
"title": "#" + cat.name,
}

View file

@ -3,12 +3,12 @@ from django.shortcuts import redirect, get_object_or_404
from ..models import Entry
@render_to('entries/entry.html')
@render_to("entries/entry.html")
def entry(request, kind, id, slug=None):
entry = get_object_or_404(Entry, pk=id)
if request.path != entry.url:
return redirect(entry.url, permanent=True)
return {
'entry': entry,
'title': entry.title,
"entry": entry,
"title": entry.title,
}

View file

@ -1,5 +1,5 @@
import multiprocessing
proc_name = 'lemoncurry'
worker_class = 'gevent'
proc_name = "lemoncurry"
worker_class = "gevent"
workers = multiprocessing.cpu_count() * 2 + 1

View file

@ -3,10 +3,10 @@ from django.urls import reverse
class HomeSitemap(sitemaps.Sitemap):
changefreq = 'daily'
changefreq = "daily"
def items(self):
return ('home:index',)
return ("home:index",)
def location(self, item):
return reverse(item)

View file

@ -2,9 +2,9 @@ from django.urls import path
from . import views
app_name = 'home'
app_name = "home"
urlpatterns = [
path('', views.index, name='index'),
path('page/<int:page>', views.index, name='index'),
path('robots.txt', views.robots, name='robots.txt'),
path("", views.index, name="index"),
path("page/<int:page>", views.index, name="index"),
path("robots.txt", views.robots, name="robots.txt"),
]

View file

@ -8,34 +8,31 @@ from urllib.parse import urljoin
from entries import kinds, pagination
from lemoncurry import breadcrumbs, utils
breadcrumbs.add('home:index', 'home')
breadcrumbs.add("home:index", "home")
@render_to('home/index.html')
@render_to("home/index.html")
def index(request, page=None):
def url(page):
kwargs = {'page': page} if page != 1 else {}
return reverse('home:index', kwargs=kwargs)
kwargs = {"page": page} if page != 1 else {}
return reverse("home:index", kwargs=kwargs)
user = request.user
if not hasattr(user, 'entries'):
if not hasattr(user, "entries"):
user = get_object_or_404(User, pk=1)
entries = user.