Merge branch 'main' into production

This commit is contained in:
Mouse Reeve 2020-10-30 15:23:26 -07:00
commit 7da705f87e
12 changed files with 68 additions and 46 deletions

View file

@ -5,6 +5,7 @@ from dateutil import parser
import pytz
import requests
from requests import HTTPError
from urllib3.exceptions import RequestError
from django.db import transaction
@ -298,7 +299,7 @@ def get_data(url):
'Accept': 'application/json; charset=utf-8',
},
)
except ConnectionError:
except RequestError:
raise ConnectorException()
if not resp.ok:
resp.raise_for_status()

View file

@ -204,7 +204,7 @@ def handle_follow_reject(activity):
def handle_create(activity):
''' someone did something, good on them '''
if activity['object'].get('type') not in \
['Note', 'Comment', 'Quotation', 'Review']:
['Note', 'Comment', 'Quotation', 'Review', 'GeneratedNote']:
# if it's an article or unknown type, ignore it
return

View file

@ -0,0 +1,17 @@
# Generated by Django 3.0.7 on 2020-10-30 21:57
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('bookwyrm', '0060_auto_20201030_2010'),
]
operations = [
migrations.RenameModel(
old_name='GeneratedStatus',
new_name='GeneratedNote',
),
]

View file

@ -6,7 +6,7 @@ from .book import Book, Work, Edition, Author
from .connector import Connector
from .relationship import UserFollows, UserFollowRequest, UserBlocks
from .shelf import Shelf, ShelfBook
from .status import Status, GeneratedStatus, Review, Comment, Quotation
from .status import Status, GeneratedNote, Review, Comment, Quotation
from .status import Favorite, Boost, Notification, ReadThrough
from .tag import Tag
from .user import User
@ -16,5 +16,5 @@ from .import_job import ImportJob, ImportItem
from .site import SiteSettings, SiteInvite, PasswordReset
cls_members = inspect.getmembers(sys.modules[__name__], inspect.isclass)
activity_models = {c[0]: c[1].activity_serializer for c in cls_members \
activity_models = {c[0]: c[1] for c in cls_members \
if hasattr(c[1], 'activity_serializer')}

View file

@ -1,4 +1,5 @@
''' base model with default fields '''
from datetime import datetime
from base64 import b64encode
from dataclasses import dataclass
from typing import Callable
@ -69,6 +70,8 @@ class ActivitypubMixin:
value = getattr(self, mapping.model_key)
if hasattr(value, 'remote_id'):
value = value.remote_id
if isinstance(value, datetime):
value = value.isoformat()
fields[mapping.activity_key] = mapping.activity_formatter(value)
if pure:

View file

@ -3,7 +3,6 @@ import re
from django.db import models
from django.utils import timezone
from django.utils.http import http_date
from model_utils.managers import InheritanceManager
from bookwyrm import activitypub
@ -63,16 +62,8 @@ class Book(ActivitypubMixin, BookWyrmModel):
ActivityMapping('id', 'remote_id'),
ActivityMapping('authors', 'ap_authors'),
ActivityMapping(
'first_published_date',
'first_published_date',
activity_formatter=lambda d: http_date(d.timestamp()) if d else None
),
ActivityMapping(
'published_date',
'published_date',
activity_formatter=lambda d: http_date(d.timestamp()) if d else None
),
ActivityMapping('first_published_date', 'first_published_date'),
ActivityMapping('published_date', 'published_date'),
ActivityMapping('title', 'title'),
ActivityMapping('sort_title', 'sort_title'),

View file

@ -1,6 +1,5 @@
''' models for storing different kinds of Activities '''
from django.utils import timezone
from django.utils.http import http_date
from django.core.validators import MaxValueValidator, MinValueValidator
from django.db import models
from model_utils.managers import InheritanceManager
@ -62,11 +61,7 @@ class Status(OrderedCollectionPageMixin, BookWyrmModel):
ActivityMapping('id', 'remote_id'),
ActivityMapping('url', 'remote_id'),
ActivityMapping('inReplyTo', 'reply_parent'),
ActivityMapping(
'published',
'published_date',
activity_formatter=lambda d: http_date(d.timestamp())
),
ActivityMapping('published', 'published_date'),
ActivityMapping('attributedTo', 'user'),
ActivityMapping('to', 'ap_to'),
ActivityMapping('cc', 'ap_cc'),
@ -116,13 +111,13 @@ class Status(OrderedCollectionPageMixin, BookWyrmModel):
return activitypub.Tombstone(
id=self.remote_id,
url=self.remote_id,
deleted=http_date(self.deleted_date.timestamp()),
published=http_date(self.deleted_date.timestamp()),
deleted=self.deleted_date.isoformat(),
published=self.deleted_date.isoformat()
).serialize()
return ActivitypubMixin.to_activity(self, **kwargs)
class GeneratedStatus(Status):
class GeneratedNote(Status):
''' these are app-generated messages about user activity '''
@property
def ap_pure_content(self):

View file

@ -21,7 +21,7 @@ def create_generated_note(user, content, mention_books=None):
parser.feed(content)
content = parser.get_output()
status = models.GeneratedStatus.objects.create(
status = models.GeneratedNote.objects.create(
user=user,
content=content,
)

View file

@ -1,19 +1,22 @@
{% extends 'layout.html' %}
{% load fr_display %}
{% block content %}
{% include 'user_header.html' with user=user %}
<div class="block">
<nav class="breadcrumb has-succeeds-separator" aria-label="breadcrumbs">
<div class="tabs">
<ul>
<li><a href="/user/{{ user.username }}">{% include 'snippets/username.html' with user=user %}</a></li>
<li><a href="/user/{{ user.username }}/shelves">Shelves</a></li>
<li class="is-active"><a href="#" aria-current="page">{{ shelf.name }}</a></li>
{% for shelf_tab in shelves %}
<li class="{% if shelf_tab.identifier == shelf.identifier %}is-active{% endif %}">
<a href="/user/{{ user | username }}/shelf/{{ shelf_tab.identifier }}">{{ shelf_tab.name }}</a>
</li>
{% endfor %}
</ul>
</nav>
</div>
</div>
<div class="block">
<div>
<h2 class="title">{{ shelf.name }}</h2>
{% include 'snippets/shelf.html' with shelf=shelf ratings=ratings %}
</div>
</div>

View file

@ -1,6 +1,6 @@
{% load humanize %}
{% load fr_display %}
{% if shelf.books %}
{% if shelf.books.all|length > 0 %}
<table class="table is-striped is-fullwidth">
<tr class="book-preview">

View file

@ -3,9 +3,20 @@
{% block content %}
{% include 'user_header.html' with user=user %}
<div class="block">
<div class="tabs">
<ul>
{% for shelf in shelves %}
<li class="{% if true %}is-active{% endif %}">
<a href="/user/{{ user | username }}/shelves/{{ shelf.identifier }}">{{ shelf.name }}</a>
</li>
{% endfor %}
</ul>
<h2 class="title">{{ shelf.name }}</h2>
</div>
{% for shelf in shelves %}
<div class="block">
<h2 class="title">{{ shelf.name }}</h2>
{% include 'snippets/shelf.html' with shelf=shelf ratings=ratings %}
</div>
{% endfor %}

View file

@ -299,7 +299,7 @@ def notifications_page(request):
return TemplateResponse(request, 'notifications.html', data)
@csrf_exempt
def user_page(request, username, subpage=None):
def user_page(request, username, subpage=None, shelf=None):
''' profile page for a user '''
try:
user = get_user_from_username(username)
@ -323,18 +323,22 @@ def user_page(request, username, subpage=None):
return TemplateResponse(request, 'following.html', data)
if subpage == 'shelves':
data['shelves'] = user.shelf_set.all()
return TemplateResponse(request, 'user_shelves.html', data)
if shelf:
data['shelf'] = user.shelf_set.get(identifier=shelf)
else:
data['shelf'] = user.shelf_set.first()
return TemplateResponse(request, 'shelf.html', data)
data['shelf_count'] = user.shelf_set.count()
shelves = []
for shelf in user.shelf_set.all():
if not shelf.books.count():
for user_shelf in user.shelf_set.all():
if not user_shelf.books.count():
continue
shelves.append({
'name': shelf.name,
'remote_id': shelf.remote_id,
'books': shelf.books.all()[:3],
'size': shelf.books.count(),
'name': user_shelf.name,
'remote_id': user_shelf.remote_id,
'books': user_shelf.books.all()[:3],
'size': user_shelf.books.count(),
})
if len(shelves) > 2:
break
@ -599,8 +603,5 @@ def shelf_page(request, username, shelf_identifier):
if is_api_request(request):
return JsonResponse(shelf.to_activity(**request.GET))
data = {
'shelf': shelf,
'user': user,
}
return TemplateResponse(request, 'shelf.html', data)
return user_page(
request, username, subpage='shelves', shelf=shelf_identifier)