diff --git a/bookwyrm/forms.py b/bookwyrm/forms.py index 7b18a2ffa..0c3b19ba4 100644 --- a/bookwyrm/forms.py +++ b/bookwyrm/forms.py @@ -52,47 +52,31 @@ class RegisterForm(CustomForm): class RatingForm(CustomForm): class Meta: model = models.Review - fields = ['rating'] + fields = ['user', 'book', 'content', 'rating', 'privacy'] class ReviewForm(CustomForm): class Meta: model = models.Review - fields = ['name', 'content'] - help_texts = {f: None for f in fields} - labels = { - 'name': 'Title', - 'content': 'Review', - } + fields = ['user', 'book', 'name', 'content', 'rating', 'privacy'] class CommentForm(CustomForm): class Meta: model = models.Comment - fields = ['content'] - help_texts = {f: None for f in fields} - labels = { - 'content': 'Comment', - } + fields = ['user', 'book', 'content', 'privacy'] class QuotationForm(CustomForm): class Meta: model = models.Quotation - fields = ['quote', 'content'] - help_texts = {f: None for f in fields} - labels = { - 'quote': 'Quote', - 'content': 'Comment', - } + fields = ['user', 'book', 'quote', 'content', 'privacy'] class ReplyForm(CustomForm): class Meta: model = models.Status - fields = ['content'] - help_texts = {f: None for f in fields} - labels = {'content': 'Comment'} + fields = ['user', 'content', 'reply_parent', 'privacy'] class EditUserForm(CustomForm): diff --git a/bookwyrm/migrations/0057_auto_20201026_2131.py b/bookwyrm/migrations/0057_auto_20201026_2131.py new file mode 100644 index 000000000..cc414e98c --- /dev/null +++ b/bookwyrm/migrations/0057_auto_20201026_2131.py @@ -0,0 +1,18 @@ +# Generated by Django 3.0.7 on 2020-10-26 21:31 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('bookwyrm', '0056_auto_20201021_0150'), + ] + + operations = [ + migrations.AlterField( + model_name='status', + name='privacy', + field=models.CharField(choices=[('public', 'Public'), ('unlisted', 'Unlisted'), ('followers', 'Followers'), ('direct', 'Direct')], default='public', max_length=255), + ), + ] diff --git a/bookwyrm/models/status.py b/bookwyrm/models/status.py index 61e9c5005..b1283c9dc 100644 --- a/bookwyrm/models/status.py +++ b/bookwyrm/models/status.py @@ -10,6 +10,13 @@ from .base_model import ActivitypubMixin, OrderedCollectionPageMixin from .base_model import ActivityMapping, BookWyrmModel +PrivacyLevels = models.TextChoices('Privacy', [ + 'public', + 'unlisted', + 'followers', + 'direct' +]) + class Status(OrderedCollectionPageMixin, BookWyrmModel): ''' any post, like a reply to a review, etc ''' user = models.ForeignKey('User', on_delete=models.PROTECT) @@ -18,7 +25,11 @@ class Status(OrderedCollectionPageMixin, BookWyrmModel): mention_books = models.ManyToManyField( 'Edition', related_name='mention_book') local = models.BooleanField(default=True) - privacy = models.CharField(max_length=255, default='public') + privacy = models.CharField( + max_length=255, + default='public', + choices=PrivacyLevels.choices + ) sensitive = models.BooleanField(default=False) # the created date can't be this, because of receiving federated posts published_date = models.DateTimeField(default=timezone.now) @@ -181,9 +192,14 @@ class Review(Status): @property def ap_pure_name(self): ''' clarify review names for mastodon serialization ''' - return 'Review of "%s" (%d stars): %s' % ( + if self.rating: + return 'Review of "%s" (%d stars): %s' % ( + self.book.title, + self.rating, + self.name + ) + return 'Review of "%s": %s' % ( self.book.title, - self.rating, self.name ) diff --git a/bookwyrm/outgoing.py b/bookwyrm/outgoing.py index f496a2110..4681a6705 100644 --- a/bookwyrm/outgoing.py +++ b/bookwyrm/outgoing.py @@ -9,9 +9,7 @@ import requests from bookwyrm import activitypub from bookwyrm import models from bookwyrm.broadcast import broadcast -from bookwyrm.status import create_review, create_status -from bookwyrm.status import create_quotation, create_comment -from bookwyrm.status import create_tag, create_notification, create_rating +from bookwyrm.status import create_tag, create_notification from bookwyrm.status import create_generated_note from bookwyrm.status import delete_status from bookwyrm.remote_user import get_or_create_remote_user @@ -178,15 +176,16 @@ def handle_import_books(user, items): broadcast(user, activity) if item.rating or item.review: - review_title = "Review of {!r} on Goodreads".format( + review_title = 'Review of {!r} on Goodreads'.format( item.book.title, - ) if item.review else "" - handle_review( - user, - item.book, - review_title, - item.review, - item.rating, + ) if item.review else '' + + models.Review.objects.create( + user=user, + book=item.book, + name=review_title, + content=item.review, + rating=item.rating, ) for read in item.reads: read.book = item.book @@ -209,44 +208,25 @@ def handle_delete_status(user, status): broadcast(user, status.to_activity()) -def handle_rate(user, book, rating): - ''' a review that's just a rating ''' - builder = create_rating - handle_status(user, book, builder, rating) - - -def handle_review(user, book, name, content, rating): - ''' post a review ''' - # validated and saves the review in the database so it has an id - builder = create_review - handle_status(user, book, builder, name, content, rating) - - -def handle_quotation(user, book, content, quote): - ''' post a review ''' - # validated and saves the review in the database so it has an id - builder = create_quotation - handle_status(user, book, builder, content, quote) - - -def handle_comment(user, book, content): - ''' post a comment ''' - # validated and saves the review in the database so it has an id - builder = create_comment - handle_status(user, book, builder, content) - - -def handle_status(user, book_id, builder, *args): +def handle_status(user, form): ''' generic handler for statuses ''' - book = models.Edition.objects.get(id=book_id) - status = builder(user, book, *args) + status = form.save() + + # notify reply parent or (TODO) tagged users + if status.reply_parent and status.reply_parent.user.local: + create_notification( + status.reply_parent.user, + 'REPLY', + related_user=user, + related_status=status + ) broadcast(user, status.to_create_activity(user), software='bookwyrm') # re-format the activity for non-bookwyrm servers - remote_activity = status.to_create_activity(user, pure=True) - - broadcast(user, remote_activity, software='other') + if hasattr(status, 'pure_activity_serializer'): + remote_activity = status.to_create_activity(user, pure=True) + broadcast(user, remote_activity, software='other') def handle_tag(user, book, name): @@ -265,21 +245,6 @@ def handle_untag(user, book, name): broadcast(user, tag_activity) -def handle_reply(user, review, content): - ''' respond to a review or status ''' - # validated and saves the comment in the database so it has an id - reply = create_status(user, content, reply_parent=review) - if reply.reply_parent: - create_notification( - reply.reply_parent.user, - 'REPLY', - related_user=user, - related_status=reply, - ) - - broadcast(user, reply.to_create_activity(user)) - - def handle_favorite(user, status): ''' a user likes a status ''' try: diff --git a/bookwyrm/static/css/fonts/icomoon.eot b/bookwyrm/static/css/fonts/icomoon.eot index 5568c0ad4..99a90268a 100644 Binary files a/bookwyrm/static/css/fonts/icomoon.eot and b/bookwyrm/static/css/fonts/icomoon.eot differ diff --git a/bookwyrm/static/css/fonts/icomoon.svg b/bookwyrm/static/css/fonts/icomoon.svg index 4324502bb..28612eee4 100644 --- a/bookwyrm/static/css/fonts/icomoon.svg +++ b/bookwyrm/static/css/fonts/icomoon.svg @@ -7,27 +7,28 @@ <font-face units-per-em="1024" ascent="960" descent="-64" /> <missing-glyph horiz-adv-x="1024" /> <glyph unicode=" " horiz-adv-x="512" d="" /> -<glyph unicode="" glyph-name="arrow-right" d="M426 212.667v428l214-214z" /> -<glyph unicode="" glyph-name="bell" d="M521.143-18.286c0 5.143-4 9.143-9.143 9.143-45.143 0-82.286 37.143-82.286 82.286 0 5.143-4 9.143-9.143 9.143s-9.143-4-9.143-9.143c0-55.429 45.143-100.571 100.571-100.571 5.143 0 9.143 4 9.143 9.143zM987.429 146.286c0-40-33.143-73.143-73.143-73.143h-256c0-80.571-65.714-146.286-146.286-146.286s-146.286 65.714-146.286 146.286h-256c-40 0-73.143 33.143-73.143 73.143 84.571 71.429 182.857 199.429 182.857 475.429 0 109.714 90.857 229.714 242.286 252-2.857 6.857-4.571 14.286-4.571 22.286 0 30.286 24.571 54.857 54.857 54.857s54.857-24.571 54.857-54.857c0-8-1.714-15.429-4.571-22.286 151.429-22.286 242.286-142.286 242.286-252 0-276 98.286-404 182.857-475.429z" /> -<glyph unicode="" glyph-name="x, cancel, close" d="M960 179.264l-268.992 268.736 268.992 268.736-179.264 179.264-268.736-268.864-268.864 268.864-179.136-179.264 268.736-268.736-268.736-268.736 179.136-179.264 268.864 268.864 268.736-268.864z" /> -<glyph unicode="" glyph-name="quote-close" horiz-adv-x="951" d="M438.857 768v-402.286c0-161.143-131.429-292.571-292.571-292.571h-36.571c-20 0-36.571 16.571-36.571 36.571v73.143c0 20 16.571 36.571 36.571 36.571h36.571c80.571 0 146.286 65.714 146.286 146.286v18.286c0 30.286-24.571 54.857-54.857 54.857h-128c-60.571 0-109.714 49.143-109.714 109.714v219.429c0 60.571 49.143 109.714 109.714 109.714h219.429c60.571 0 109.714-49.143 109.714-109.714zM950.857 768v-402.286c0-161.143-131.429-292.571-292.571-292.571h-36.571c-20 0-36.571 16.571-36.571 36.571v73.143c0 20 16.571 36.571 36.571 36.571h36.571c80.571 0 146.286 65.714 146.286 146.286v18.286c0 30.286-24.571 54.857-54.857 54.857h-128c-60.571 0-109.714 49.143-109.714 109.714v219.429c0 60.571 49.143 109.714 109.714 109.714h219.429c60.571 0 109.714-49.143 109.714-109.714z" /> -<glyph unicode="" glyph-name="quote-open" horiz-adv-x="951" d="M438.857 402.286v-219.429c0-60.571-49.143-109.714-109.714-109.714h-219.429c-60.571 0-109.714 49.143-109.714 109.714v402.286c0 161.143 131.429 292.571 292.571 292.571h36.571c20 0 36.571-16.571 36.571-36.571v-73.143c0-20-16.571-36.571-36.571-36.571h-36.571c-80.571 0-146.286-65.714-146.286-146.286v-18.286c0-30.286 24.571-54.857 54.857-54.857h128c60.571 0 109.714-49.143 109.714-109.714zM950.857 402.286v-219.429c0-60.571-49.143-109.714-109.714-109.714h-219.429c-60.571 0-109.714 49.143-109.714 109.714v402.286c0 161.143 131.429 292.571 292.571 292.571h36.571c20 0 36.571-16.571 36.571-36.571v-73.143c0-20-16.571-36.571-36.571-36.571h-36.571c-80.571 0-146.286-65.714-146.286-146.286v-18.286c0-30.286 24.571-54.857 54.857-54.857h128c60.571 0 109.714-49.143 109.714-109.714z" /> -<glyph unicode="" glyph-name="image, photo, picture-o" horiz-adv-x="1097" d="M365.714 621.714c0-60.571-49.143-109.714-109.714-109.714s-109.714 49.143-109.714 109.714 49.143 109.714 109.714 109.714 109.714-49.143 109.714-109.714zM950.857 402.286v-256h-804.571v109.714l182.857 182.857 91.429-91.429 292.571 292.571zM1005.714 804.571h-914.286c-9.714 0-18.286-8.571-18.286-18.286v-694.857c0-9.714 8.571-18.286 18.286-18.286h914.286c9.714 0 18.286 8.571 18.286 18.286v694.857c0 9.714-8.571 18.286-18.286 18.286zM1097.143 786.286v-694.857c0-50.286-41.143-91.429-91.429-91.429h-914.286c-50.286 0-91.429 41.143-91.429 91.429v694.857c0 50.286 41.143 91.429 91.429 91.429h914.286c50.286 0 91.429-41.143 91.429-91.429z" /> -<glyph unicode="" glyph-name="pencil" horiz-adv-x="866" d="M207.429 73.143l52 52-134.286 134.286-52-52v-61.143h73.143v-73.143h61.143zM506.286 603.428c0 7.429-5.143 12.571-12.571 12.571-3.429 0-6.857-1.143-9.714-4l-309.714-309.714c-2.857-2.857-4-6.286-4-9.714 0-7.429 5.143-12.571 12.571-12.571 3.429 0 6.857 1.143 9.714 4l309.714 309.714c2.857 2.857 4 6.286 4 9.714zM475.429 713.143l237.714-237.714-475.429-475.429h-237.714v237.714zM865.714 658.286c0-19.429-8-38.286-21.143-51.429l-94.857-94.857-237.714 237.714 94.857 94.286c13.143 13.714 32 21.714 51.429 21.714s38.286-8 52-21.714l134.286-133.714c13.143-13.714 21.143-32.571 21.143-52z" /> -<glyph unicode="" glyph-name="list" d="M219.429 146.286c0-60.571-49.143-109.714-109.714-109.714s-109.714 49.143-109.714 109.714 49.143 109.714 109.714 109.714 109.714-49.143 109.714-109.714zM219.429 438.857c0-60.571-49.143-109.714-109.714-109.714s-109.714 49.143-109.714 109.714 49.143 109.714 109.714 109.714 109.714-49.143 109.714-109.714zM1024 201.143v-109.714c0-9.714-8.571-18.286-18.286-18.286h-694.857c-9.714 0-18.286 8.571-18.286 18.286v109.714c0 9.714 8.571 18.286 18.286 18.286h694.857c9.714 0 18.286-8.571 18.286-18.286zM219.429 731.428c0-60.571-49.143-109.714-109.714-109.714s-109.714 49.143-109.714 109.714 49.143 109.714 109.714 109.714 109.714-49.143 109.714-109.714zM1024 493.714v-109.714c0-9.714-8.571-18.286-18.286-18.286h-694.857c-9.714 0-18.286 8.571-18.286 18.286v109.714c0 9.714 8.571 18.286 18.286 18.286h694.857c9.714 0 18.286-8.571 18.286-18.286zM1024 786.286v-109.714c0-9.714-8.571-18.286-18.286-18.286h-694.857c-9.714 0-18.286 8.571-18.286 18.286v109.714c0 9.714 8.571 18.286 18.286 18.286h694.857c9.714 0 18.286-8.571 18.286-18.286z" /> -<glyph unicode="" glyph-name="unlock, unlisted" horiz-adv-x="951" d="M950.857 621.714v-146.286c0-20-16.571-36.571-36.571-36.571h-36.571c-20 0-36.571 16.571-36.571 36.571v146.286c0 80.571-65.714 146.286-146.286 146.286s-146.286-65.714-146.286-146.286v-109.714h54.857c30.286 0 54.857-24.571 54.857-54.857v-329.143c0-30.286-24.571-54.857-54.857-54.857h-548.571c-30.286 0-54.857 24.571-54.857 54.857v329.143c0 30.286 24.571 54.857 54.857 54.857h384v109.714c0 141.143 114.857 256 256 256s256-114.857 256-256z" /> -<glyph unicode="" glyph-name="globe, global, federated, public" horiz-adv-x="878" d="M438.857 877.714c242.286 0 438.857-196.571 438.857-438.857s-196.571-438.857-438.857-438.857-438.857 196.571-438.857 438.857 196.571 438.857 438.857 438.857zM595.429 580c-4.571-3.429-7.429-9.714-13.143-10.857 2.857 0.571 5.714 10.857 7.429 13.143 3.429 4 8 6.286 12.571 8.571 9.714 4 19.429 5.143 29.714 6.857 9.714 2.286 21.714 2.286 29.143-6.286-1.714 1.714 12 13.714 13.714 14.286 5.143 2.857 13.714 1.714 17.143 6.857 1.143 1.714 1.143 12.571 1.143 12.571-9.714-1.143-13.143 8-13.714 16 0-0.571-1.143-2.286-3.429-4.571 0.571 8.571-10.286 2.286-14.286 3.429-13.143 3.429-11.429 12.571-15.429 22.286-2.286 5.143-8.571 6.857-10.857 12-2.286 3.429-3.429 10.857-8.571 11.429-3.429 0.571-9.714-12-10.857-11.429-5.143 2.857-7.429-1.143-11.429-3.429-3.429-2.286-6.286-1.143-9.714-2.857 10.286 3.429-4.571 9.143-9.714 8 8 2.286 4 10.857-0.571 14.857h2.857c-1.143 5.143-17.143 9.714-22.286 13.143s-32.571 9.143-38.286 5.714c-6.857-4 1.714-15.429 1.714-21.143 0.571-6.857-6.857-8.571-6.857-14.286 0-9.714 18.286-8 13.714-21.143-2.857-8-13.714-9.714-18.286-16-4.571-5.714 0.571-16 5.143-20 4.571-3.429-8-9.143-9.714-10.286-9.714-4.571-17.143 9.714-19.429 18.286-1.714 6.286-2.286 13.714-9.143 17.143-3.429 1.143-14.286 2.857-16.571-0.571-3.429 8.571-15.429 12-23.429 14.857-11.429 4-21.143 4-33.143 2.286 4 0.571-1.143 18.286-10.857 15.429 2.857 5.714 1.714 12 2.857 17.714 1.143 4.571 3.429 9.143 6.857 13.143 1.143 2.286 13.714 15.429 9.714 16 9.714-1.143 20.571-1.714 28.571 6.286 5.143 5.143 7.429 13.714 12.571 19.429 7.429 8.571 16.571-2.286 24.571-2.857 11.429-0.571 10.857 12 4.571 17.714 7.429-0.571 1.143 13.143-2.857 14.857-5.143 1.714-24.571-3.429-14.286-7.429-2.286 1.143-16-27.429-24-13.143-2.286 2.857-3.429 14.857-8.571 15.429-4.571 0-7.429-5.143-9.143-8.571 2.857 7.429-16 12.571-20 13.143 8.571 5.714 1.714 12-4.571 15.429-4.571 2.857-18.857 5.143-22.857 0.571-10.857-13.143 11.429-14.857 17.143-18.286 1.714-1.143 8.571-5.143 4.571-8-3.429-1.714-13.714-4.571-14.857-6.857-3.429-5.143 4-10.857-1.143-16-5.143 5.143-5.143 13.714-9.143 19.429 5.143-6.286-20.571-2.857-20-2.857-8.571 0-22.286-5.714-28.571 2.857-1.143 2.286-1.143 15.429 2.286 12.571-5.143 4-8.571 8-12 10.286-18.857-6.286-36.571-14.286-53.714-23.429 2.286-0.571 4-0.571 6.857 0.571 4.571 1.714 8.571 4.571 13.143 6.857 5.714 2.286 17.714 9.143 24 4 0.571 1.143 2.286 2.286 2.857 2.857 4-4.571 8-9.143 11.429-14.286-4.571 2.286-12 1.143-17.143 0.571-4-1.143-10.857-2.286-12.571-6.857 1.714-2.857 4-7.429 2.857-10.286-7.429 5.143-13.143 13.714-23.429 14.857-4.571 0-9.143 0-12.571-0.571-54.857-30.286-101.143-74.286-134.286-126.857 2.286-2.286 4.571-4 6.857-4.571 5.714-1.714 0-18.286 10.857-9.714 3.429-2.857 4-6.857 1.714-10.857 0.571 0.571 23.429-14.286 25.143-15.429 4-3.429 10.286-7.429 12-12 1.143-4-2.286-8.571-5.714-10.286-0.571 1.143-9.143 9.714-10.286 7.429-1.714-2.857 0-18.286 6.286-17.714-9.143-0.571-5.143-36-7.429-42.857 0-0.571 1.143-0.571 1.143-0.571-1.714-6.857 4-33.714 15.429-30.857-7.429-1.714 13.143-28 16-29.714 7.429-5.143 16-8.571 21.143-16 5.714-8 5.714-20 13.714-26.286-2.286-6.857 12-14.857 11.429-24.571-1.143-0.571-1.714-0.571-2.857-1.143 2.857-8 13.714-8 17.714-15.429 2.286-4.571 0-15.429 7.429-13.143 1.143 12.571-7.429 25.143-13.714 35.429-3.429 5.714-6.857 10.857-9.714 16.571-2.857 5.143-3.429 11.429-5.714 17.143 2.286-0.571 14.857-5.143 13.714-6.857-4.571-11.429 18.286-31.429 24.571-38.857 1.714-1.714 14.857-18.857 8-18.857 7.429 0 17.714-11.429 21.143-17.143 5.143-8.571 4-19.429 7.429-28.571 3.429-11.429 19.429-16.571 28.571-21.714 8-4 14.857-9.714 22.857-12.571 12-4.571 14.857-0.571 25.143 1.143 14.857 2.286 16.571-14.286 28.571-20.571 7.429-4 23.429-9.714 31.429-6.286-3.429-1.143 12-24.571 13.143-26.286 5.143-6.857 14.857-10.286 20.571-17.143 1.714 1.143 3.429 2.857 4 5.143-2.286-6.286 8.571-18.286 14.286-17.143 6.286 1.143 8 13.714 8 18.286-11.429-5.714-21.714-1.143-28 10.286-1.143 2.857-10.286 18.857-2.286 18.857 10.857 0 3.429 8.571 2.286 16.571s-9.143 13.143-13.143 20c-3.429-6.857-14.857-5.143-18.286 0.571 0-1.714-1.714-4.571-1.714-6.857-2.857 0-5.714-0.571-8.571 0.571 1.143 6.857 1.714 15.429 3.429 22.857 2.857 10.286 21.714 30.286-2.857 29.143-8.571-0.571-12-4-14.857-11.429-2.857-6.857-1.714-13.143-9.714-16.571-5.143-2.286-22.286-1.143-27.429 1.714-10.857 6.286-18.286 26.286-18.286 37.714-0.571 15.429 7.429 29.143 0 43.429 3.429 2.857 6.857 8.571 10.857 11.429 3.429 2.286 7.429-1.714 9.143 5.143-1.714 1.143-4 3.429-4.571 3.429 8.571-4 24.571 5.714 32 0 4.571-3.429 9.714-4.571 12.571 1.143 0.571 1.714-4 8.571-1.714 13.143 1.714-9.714 8-11.429 16.571-5.143 3.429-3.429 12.571-2.286 18.857-5.714 6.286-4 7.429-10.286 14.857-1.714 4.571-6.857 5.143-6.857 6.857-13.714 1.714-6.286 5.143-22.286 10.857-25.143 12-7.429 9.143 12.571 8 19.429-0.571 0.571-0.571 19.429-1.143 19.429-18.286 4-11.429 18.286-1.143 28 1.714 1.143 14.857 5.714 20.571 10.286 5.143 4.571 11.429 12.571 8.571 20 2.857 0 5.143 2.286 6.286 5.143-1.714 0.571-8.571 6.286-9.714 5.714 4 2.286 3.429 5.714 1.143 9.143 5.714 3.429 2.857 9.714 8.571 12 6.286-8.571 18.857 1.143 12.571 8 5.714 8 18.857 4 22.286 11.429 8.571-2.286 2.286 8.571 6.857 14.857 4 5.143 10.857 5.143 16 8 0-0.571 14.286 8 9.714 8.571 9.714-1.143 29.143 9.143 14.286 17.714 2.286 5.143-5.143 7.429-10.286 8.571 4 1.143 9.143-1.143 12.571 1.143 7.429 5.143 2.286 7.429-4 9.143-8 2.286-18.286-2.857-24.571-6.857zM502.286 78.857c78.286 13.714 148 52.571 200.571 108-3.429 3.429-9.714 2.286-14.286 4.571-4.571 1.714-8 3.429-13.714 4.571 1.143 11.429-11.429 15.429-19.429 21.143-7.429 5.714-12 12-22.857 9.714-1.143-0.571-12.571-4.571-10.286-6.857-7.429 6.286-10.857 9.714-20.571 12.571-9.143 2.857-15.429 14.286-24.571 4-4.571-4.571-2.286-11.429-4.571-16-7.429 6.286 6.857 13.714 1.143 20.571-6.857 8-18.857-5.143-24.571-8.571-3.429-2.857-7.429-4-9.714-7.429-2.857-4-4-9.143-6.286-13.143-1.714 4.571-11.429 3.429-12 6.857 2.286-13.714 2.286-28 5.143-41.714 1.714-8 0-21.143-6.857-27.429s-15.429-13.143-16.571-22.857c-1.143-6.857 0.571-13.143 6.857-14.857 0.571-8.571-9.143-14.857-8.571-24 0-0.571 0.571-6.286 1.143-9.143z" /> -<glyph unicode="" glyph-name="lock, private" horiz-adv-x="658" d="M182.857 512h292.571v109.714c0 80.571-65.714 146.286-146.286 146.286s-146.286-65.714-146.286-146.286v-109.714zM658.286 457.143v-329.143c0-30.286-24.571-54.857-54.857-54.857h-548.571c-30.286 0-54.857 24.571-54.857 54.857v329.143c0 30.286 24.571 54.857 54.857 54.857h18.286v109.714c0 140.571 115.429 256 256 256s256-115.429 256-256v-109.714h18.286c30.286 0 54.857-24.571 54.857-54.857z" /> -<glyph unicode="" glyph-name="chain-broken, unlink" horiz-adv-x="951" d="M250.857 224.571l-146.286-146.286c-4-3.429-8.571-5.143-13.143-5.143s-9.143 1.714-13.143 5.143c-6.857 7.429-6.857 18.857 0 26.286l146.286 146.286c7.429 6.857 18.857 6.857 26.286 0 6.857-7.429 6.857-18.857 0-26.286zM347.429 201.143v-182.857c0-10.286-8-18.286-18.286-18.286s-18.286 8-18.286 18.286v182.857c0 10.286 8 18.286 18.286 18.286s18.286-8 18.286-18.286zM219.429 329.143c0-10.286-8-18.286-18.286-18.286h-182.857c-10.286 0-18.286 8-18.286 18.286s8 18.286 18.286 18.286h182.857c10.286 0 18.286-8 18.286-18.286zM941.714 256c0-44-17.143-85.143-48.571-116l-84-83.429c-30.857-30.857-72-47.429-116-47.429s-85.714 17.143-116.571 48.571l-190.857 191.429c-9.714 9.714-17.143 20.571-24 32l136.571 10.286 156-156.571c20.571-20.571 57.143-21.143 77.714-0.571l84 83.429c10.286 10.286 16 24 16 38.286 0 14.857-5.714 28.571-16 38.857l-156.571 157.143 10.286 136.571c11.429-6.857 22.286-14.286 32-24l192-192c30.857-31.429 48-72.571 48-116.571zM589.143 669.714l-136.571-10.286-156 156.571c-10.286 10.286-24 16-38.857 16s-28.571-5.714-38.857-15.429l-84-83.429c-10.286-10.286-16-24-16-38.286 0-14.857 5.714-28.571 16-38.857l156.571-156.571-10.286-137.143c-11.429 6.857-22.286 14.286-32 24l-192 192c-30.857 31.429-48 72.571-48 116.571s17.143 85.143 48.571 116l84 83.429c30.857 30.857 72 47.429 116 47.429s85.714-17.143 116.571-48.571l190.857-191.429c9.714-9.714 17.143-20.571 24-32zM950.857 621.714c0-10.286-8-18.286-18.286-18.286h-182.857c-10.286 0-18.286 8-18.286 18.286s8 18.286 18.286 18.286h182.857c10.286 0 18.286-8 18.286-18.286zM640 932.571v-182.857c0-10.286-8-18.286-18.286-18.286s-18.286 8-18.286 18.286v182.857c0 10.286 8 18.286 18.286 18.286s18.286-8 18.286-18.286zM872.571 846.286l-146.286-146.286c-4-3.429-8.571-5.143-13.143-5.143s-9.143 1.714-13.143 5.143c-6.857 7.429-6.857 18.857 0 26.286l146.286 146.286c7.429 6.857 18.857 6.857 26.286 0 6.857-7.429 6.857-18.857 0-26.286z" /> -<glyph unicode="" glyph-name="chain, link" horiz-adv-x="951" d="M832 256c0 14.857-5.714 28.571-16 38.857l-118.857 118.857c-10.286 10.286-24.571 16-38.857 16-16.571 0-29.714-6.286-41.143-18.286 18.857-18.857 41.143-34.857 41.143-64 0-30.286-24.571-54.857-54.857-54.857-29.143 0-45.143 22.286-64 41.143-12-11.429-18.857-24.571-18.857-41.714 0-14.286 5.714-28.571 16-38.857l117.714-118.286c10.286-10.286 24.571-15.429 38.857-15.429s28.571 5.143 38.857 14.857l84 83.429c10.286 10.286 16 24 16 38.286zM430.286 658.857c0 14.286-5.714 28.571-16 38.857l-117.714 118.286c-10.286 10.286-24.571 16-38.857 16s-28.571-5.714-38.857-15.429l-84-83.429c-10.286-10.286-16-24-16-38.286 0-14.857 5.714-28.571 16-38.857l118.857-118.857c10.286-10.286 24.571-15.429 38.857-15.429 16.571 0 29.714 5.714 41.143 17.714-18.857 18.857-41.143 34.857-41.143 64 0 30.286 24.571 54.857 54.857 54.857 29.143 0 45.143-22.286 64-41.143 12 11.429 18.857 24.571 18.857 41.714zM941.714 256c0-43.429-17.714-85.714-48.571-116l-84-83.429c-30.857-30.857-72.571-47.429-116-47.429-44 0-85.714 17.143-116.571 48.571l-117.714 118.286c-30.857 30.857-47.429 72.571-47.429 116 0 45.143 18.286 88 50.286 119.429l-50.286 50.286c-31.429-32-73.714-50.286-118.857-50.286-43.429 0-85.714 17.143-116.571 48l-118.857 118.857c-31.429 31.429-48 72.571-48 116.571 0 43.429 17.714 85.714 48.571 116l84 83.429c30.857 30.857 72.571 47.429 116 47.429 44 0 85.714-17.143 116.571-48.571l117.714-118.286c30.857-30.857 47.429-72.571 47.429-116 0-45.143-18.286-88-50.286-119.429l50.286-50.286c31.429 32 73.714 50.286 118.857 50.286 43.429 0 85.714-17.143 116.571-48l118.857-118.857c31.429-31.429 48-72.571 48-116.571z" /> -<glyph unicode="" glyph-name="comments" d="M804.571 512c0-161.714-180-292.571-402.286-292.571-34.857 0-68.571 3.429-100.571 9.143-47.429-33.714-101.143-58.286-158.857-73.143-15.429-4-32-6.857-49.143-9.143h-1.714c-8.571 0-16.571 6.857-18.286 16.571v0c-2.286 10.857 5.143 17.714 11.429 25.143 22.286 25.143 47.429 47.429 66.857 94.857-92.571 53.714-152 136.571-152 229.143 0 161.714 180 292.571 402.286 292.571s402.286-130.857 402.286-292.571zM1024 365.714c0-93.143-59.429-175.429-152-229.143 19.429-47.429 44.571-69.714 66.857-94.857 6.286-7.429 13.714-14.286 11.429-25.143v0c-2.286-10.286-10.857-17.714-20-16.571-17.143 2.286-33.714 5.143-49.143 9.143-57.714 14.857-111.429 39.429-158.857 73.143-32-5.714-65.714-9.143-100.571-9.143-103.429 0-198.286 28.571-269.714 75.429 16.571-1.143 33.714-2.286 50.286-2.286 122.857 0 238.857 35.429 327.429 99.429 95.429 69.714 148 164 148 266.286 0 29.714-4.571 58.857-13.143 86.857 96.571-53.143 159.429-137.714 159.429-233.143z" /> -<glyph unicode="" glyph-name="comment" d="M1024 438.857c0-202.286-229.143-365.714-512-365.714-28 0-56 1.714-82.857 4.571-74.857-66.286-164-113.143-262.857-138.286-20.571-5.714-42.857-9.714-65.143-12.571-12.571-1.143-24.571 8-27.429 21.714v0.571c-2.857 14.286 6.857 22.857 15.429 33.143 36 40.571 77.143 74.857 104 170.286-117.714 66.857-193.143 170.286-193.143 286.286 0 201.714 229.143 365.714 512 365.714s512-163.429 512-365.714z" /> -<glyph unicode="" glyph-name="boost" horiz-adv-x="1097" d="M731.429 91.428c0-9.714-8.571-18.286-18.286-18.286h-548.571c-21.143 0-18.286 22.286-18.286 36.571v329.143h-109.714c-20 0-36.571 16.571-36.571 36.571 0 8.571 2.857 17.143 8.571 23.429l182.857 219.429c6.857 8 17.143 12.571 28 12.571s21.143-4.571 28-12.571l182.857-219.429c5.714-6.286 8.571-14.857 8.571-23.429 0-20-16.571-36.571-36.571-36.571h-109.714v-219.429h329.143c5.143 0 10.857-2.286 14.286-6.286l91.429-109.714c2.286-3.429 4-8 4-12zM1097.143 329.143c0-8.571-2.857-17.143-8.571-23.429l-182.857-219.429c-6.857-8-17.143-13.143-28-13.143s-21.143 5.143-28 13.143l-182.857 219.429c-5.714 6.286-8.571 14.857-8.571 23.429 0 20 16.571 36.571 36.571 36.571h109.714v219.429h-329.143c-5.143 0-10.857 2.286-14.286 6.857l-91.429 109.714c-2.286 2.857-4 7.429-4 11.429 0 9.714 8.571 18.286 18.286 18.286h548.571c21.143 0 18.286-22.286 18.286-36.571v-329.143h109.714c20 0 36.571-16.571 36.571-36.571z" /> -<glyph unicode="" glyph-name="arrow-left" d="M598 640.667v-428l-214 214z" /> -<glyph unicode="" glyph-name="arrow-up" d="M298 340.667l214 214 214-214h-428z" /> -<glyph unicode="" glyph-name="arrow-down" d="M298 512.667h428l-214-214z" /> -<glyph unicode="" glyph-name="home" horiz-adv-x="951" d="M804.571 384v-274.286c0-20-16.571-36.571-36.571-36.571h-219.429v219.429h-146.286v-219.429h-219.429c-20 0-36.571 16.571-36.571 36.571v274.286c0 1.143 0.571 2.286 0.571 3.429l328.571 270.857 328.571-270.857c0.571-1.143 0.571-2.286 0.571-3.429zM932 423.428l-35.429-42.286c-2.857-3.429-7.429-5.714-12-6.286h-1.714c-4.571 0-8.571 1.143-12 4l-395.429 329.714-395.429-329.714c-4-2.857-8.571-4.571-13.714-4-4.571 0.571-9.143 2.857-12 6.286l-35.429 42.286c-6.286 7.429-5.143 19.429 2.286 25.714l410.857 342.286c24 20 62.857 20 86.857 0l139.429-116.571v111.429c0 10.286 8 18.286 18.286 18.286h109.714c10.286 0 18.286-8 18.286-18.286v-233.143l125.143-104c7.429-6.286 8.571-18.286 2.286-25.714z" /> -<glyph unicode="" glyph-name="local" horiz-adv-x="1097" d="M338.857 438.857c-59.429-1.714-113.143-27.429-151.429-73.143h-76.571c-57.143 0-110.857 27.429-110.857 90.857 0 46.286-1.714 201.714 70.857 201.714 12 0 71.429-48.571 148.571-48.571 26.286 0 51.429 4.571 76 13.143-1.714-12.571-2.857-25.143-2.857-37.714 0-52 16.571-103.429 46.286-146.286zM950.857 74.857c0-92.571-61.143-148-152.571-148h-499.429c-91.429 0-152.571 55.429-152.571 148 0 129.143 30.286 327.429 197.714 327.429 19.429 0 90.286-79.429 204.571-79.429s185.143 79.429 204.571 79.429c167.429 0 197.714-198.286 197.714-327.429zM365.714 804.571c0-80.571-65.714-146.286-146.286-146.286s-146.286 65.714-146.286 146.286 65.714 146.286 146.286 146.286 146.286-65.714 146.286-146.286zM768 585.143c0-121.143-98.286-219.429-219.429-219.429s-219.429 98.286-219.429 219.429 98.286 219.429 219.429 219.429 219.429-98.286 219.429-219.429zM1097.143 456.571c0-63.429-53.714-90.857-110.857-90.857h-76.571c-38.286 45.714-92 71.429-151.429 73.143 29.714 42.857 46.286 94.286 46.286 146.286 0 12.571-1.143 25.143-2.857 37.714 24.571-8.571 49.714-13.143 76-13.143 77.143 0 136.571 48.571 148.571 48.571 72.571 0 70.857-155.429 70.857-201.714zM1024 804.571c0-80.571-65.714-146.286-146.286-146.286s-146.286 65.714-146.286 146.286 65.714 146.286 146.286 146.286 146.286-65.714 146.286-146.286z" /> +<glyph unicode="" glyph-name="envelope" d="M921.6 870.4c56.554 0 102.4-45.846 102.4-102.4v0-614.4c0-56.554-45.846-102.4-102.4-102.4v0h-819.2c-56.554 0-102.4 45.846-102.4 102.4v0 614.4c0 56.32 46.080 102.4 102.4 102.4h819.2zM697.856 404.48l326.144-250.88v102.4l-262.144 199.68 262.144 209.92v102.4l-512-409.6-512 409.6v-102.4l262.144-209.92-262.144-199.68v-102.4l326.144 250.88 185.856-148.48 185.856 148.48z" /> +<glyph unicode="" glyph-name="arrow-right" d="M426 212.667v428l214-214z" /> +<glyph unicode="" glyph-name="bell" d="M521.143-18.286c0 5.143-4 9.143-9.143 9.143-45.143 0-82.286 37.143-82.286 82.286 0 5.143-4 9.143-9.143 9.143s-9.143-4-9.143-9.143c0-55.429 45.143-100.571 100.571-100.571 5.143 0 9.143 4 9.143 9.143zM987.429 146.286c0-40-33.143-73.143-73.143-73.143h-256c0-80.571-65.714-146.286-146.286-146.286s-146.286 65.714-146.286 146.286h-256c-40 0-73.143 33.143-73.143 73.143 84.571 71.429 182.857 199.429 182.857 475.429 0 109.714 90.857 229.714 242.286 252-2.857 6.857-4.571 14.286-4.571 22.286 0 30.286 24.571 54.857 54.857 54.857s54.857-24.571 54.857-54.857c0-8-1.714-15.429-4.571-22.286 151.429-22.286 242.286-142.286 242.286-252 0-276 98.286-404 182.857-475.429z" /> +<glyph unicode="" glyph-name="x" d="M960 179.264l-268.992 268.736 268.992 268.736-179.264 179.264-268.736-268.864-268.864 268.864-179.136-179.264 268.736-268.736-268.736-268.736 179.136-179.264 268.864 268.864 268.736-268.864z" /> +<glyph unicode="" glyph-name="quote-close" horiz-adv-x="951" d="M438.857 768v-402.286c0-161.143-131.429-292.571-292.571-292.571h-36.571c-20 0-36.571 16.571-36.571 36.571v73.143c0 20 16.571 36.571 36.571 36.571h36.571c80.571 0 146.286 65.714 146.286 146.286v18.286c0 30.286-24.571 54.857-54.857 54.857h-128c-60.571 0-109.714 49.143-109.714 109.714v219.429c0 60.571 49.143 109.714 109.714 109.714h219.429c60.571 0 109.714-49.143 109.714-109.714zM950.857 768v-402.286c0-161.143-131.429-292.571-292.571-292.571h-36.571c-20 0-36.571 16.571-36.571 36.571v73.143c0 20 16.571 36.571 36.571 36.571h36.571c80.571 0 146.286 65.714 146.286 146.286v18.286c0 30.286-24.571 54.857-54.857 54.857h-128c-60.571 0-109.714 49.143-109.714 109.714v219.429c0 60.571 49.143 109.714 109.714 109.714h219.429c60.571 0 109.714-49.143 109.714-109.714z" /> +<glyph unicode="" glyph-name="quote-open" horiz-adv-x="951" d="M438.857 402.286v-219.429c0-60.571-49.143-109.714-109.714-109.714h-219.429c-60.571 0-109.714 49.143-109.714 109.714v402.286c0 161.143 131.429 292.571 292.571 292.571h36.571c20 0 36.571-16.571 36.571-36.571v-73.143c0-20-16.571-36.571-36.571-36.571h-36.571c-80.571 0-146.286-65.714-146.286-146.286v-18.286c0-30.286 24.571-54.857 54.857-54.857h128c60.571 0 109.714-49.143 109.714-109.714zM950.857 402.286v-219.429c0-60.571-49.143-109.714-109.714-109.714h-219.429c-60.571 0-109.714 49.143-109.714 109.714v402.286c0 161.143 131.429 292.571 292.571 292.571h36.571c20 0 36.571-16.571 36.571-36.571v-73.143c0-20-16.571-36.571-36.571-36.571h-36.571c-80.571 0-146.286-65.714-146.286-146.286v-18.286c0-30.286 24.571-54.857 54.857-54.857h128c60.571 0 109.714-49.143 109.714-109.714z" /> +<glyph unicode="" glyph-name="image" horiz-adv-x="1097" d="M365.714 621.714c0-60.571-49.143-109.714-109.714-109.714s-109.714 49.143-109.714 109.714 49.143 109.714 109.714 109.714 109.714-49.143 109.714-109.714zM950.857 402.286v-256h-804.571v109.714l182.857 182.857 91.429-91.429 292.571 292.571zM1005.714 804.571h-914.286c-9.714 0-18.286-8.571-18.286-18.286v-694.857c0-9.714 8.571-18.286 18.286-18.286h914.286c9.714 0 18.286 8.571 18.286 18.286v694.857c0 9.714-8.571 18.286-18.286 18.286zM1097.143 786.286v-694.857c0-50.286-41.143-91.429-91.429-91.429h-914.286c-50.286 0-91.429 41.143-91.429 91.429v694.857c0 50.286 41.143 91.429 91.429 91.429h914.286c50.286 0 91.429-41.143 91.429-91.429z" /> +<glyph unicode="" glyph-name="pencil" horiz-adv-x="866" d="M207.429 73.143l52 52-134.286 134.286-52-52v-61.143h73.143v-73.143h61.143zM506.286 603.428c0 7.429-5.143 12.571-12.571 12.571-3.429 0-6.857-1.143-9.714-4l-309.714-309.714c-2.857-2.857-4-6.286-4-9.714 0-7.429 5.143-12.571 12.571-12.571 3.429 0 6.857 1.143 9.714 4l309.714 309.714c2.857 2.857 4 6.286 4 9.714zM475.429 713.143l237.714-237.714-475.429-475.429h-237.714v237.714zM865.714 658.286c0-19.429-8-38.286-21.143-51.429l-94.857-94.857-237.714 237.714 94.857 94.286c13.143 13.714 32 21.714 51.429 21.714s38.286-8 52-21.714l134.286-133.714c13.143-13.714 21.143-32.571 21.143-52z" /> +<glyph unicode="" glyph-name="list" d="M219.429 146.286c0-60.571-49.143-109.714-109.714-109.714s-109.714 49.143-109.714 109.714 49.143 109.714 109.714 109.714 109.714-49.143 109.714-109.714zM219.429 438.857c0-60.571-49.143-109.714-109.714-109.714s-109.714 49.143-109.714 109.714 49.143 109.714 109.714 109.714 109.714-49.143 109.714-109.714zM1024 201.143v-109.714c0-9.714-8.571-18.286-18.286-18.286h-694.857c-9.714 0-18.286 8.571-18.286 18.286v109.714c0 9.714 8.571 18.286 18.286 18.286h694.857c9.714 0 18.286-8.571 18.286-18.286zM219.429 731.428c0-60.571-49.143-109.714-109.714-109.714s-109.714 49.143-109.714 109.714 49.143 109.714 109.714 109.714 109.714-49.143 109.714-109.714zM1024 493.714v-109.714c0-9.714-8.571-18.286-18.286-18.286h-694.857c-9.714 0-18.286 8.571-18.286 18.286v109.714c0 9.714 8.571 18.286 18.286 18.286h694.857c9.714 0 18.286-8.571 18.286-18.286zM1024 786.286v-109.714c0-9.714-8.571-18.286-18.286-18.286h-694.857c-9.714 0-18.286 8.571-18.286 18.286v109.714c0 9.714 8.571 18.286 18.286 18.286h694.857c9.714 0 18.286-8.571 18.286-18.286z" /> +<glyph unicode="" glyph-name="unlock" horiz-adv-x="951" d="M950.857 621.714v-146.286c0-20-16.571-36.571-36.571-36.571h-36.571c-20 0-36.571 16.571-36.571 36.571v146.286c0 80.571-65.714 146.286-146.286 146.286s-146.286-65.714-146.286-146.286v-109.714h54.857c30.286 0 54.857-24.571 54.857-54.857v-329.143c0-30.286-24.571-54.857-54.857-54.857h-548.571c-30.286 0-54.857 24.571-54.857 54.857v329.143c0 30.286 24.571 54.857 54.857 54.857h384v109.714c0 141.143 114.857 256 256 256s256-114.857 256-256z" /> +<glyph unicode="" glyph-name="globe" horiz-adv-x="878" d="M438.857 877.714c242.286 0 438.857-196.571 438.857-438.857s-196.571-438.857-438.857-438.857-438.857 196.571-438.857 438.857 196.571 438.857 438.857 438.857zM595.429 580c-4.571-3.429-7.429-9.714-13.143-10.857 2.857 0.571 5.714 10.857 7.429 13.143 3.429 4 8 6.286 12.571 8.571 9.714 4 19.429 5.143 29.714 6.857 9.714 2.286 21.714 2.286 29.143-6.286-1.714 1.714 12 13.714 13.714 14.286 5.143 2.857 13.714 1.714 17.143 6.857 1.143 1.714 1.143 12.571 1.143 12.571-9.714-1.143-13.143 8-13.714 16 0-0.571-1.143-2.286-3.429-4.571 0.571 8.571-10.286 2.286-14.286 3.429-13.143 3.429-11.429 12.571-15.429 22.286-2.286 5.143-8.571 6.857-10.857 12-2.286 3.429-3.429 10.857-8.571 11.429-3.429 0.571-9.714-12-10.857-11.429-5.143 2.857-7.429-1.143-11.429-3.429-3.429-2.286-6.286-1.143-9.714-2.857 10.286 3.429-4.571 9.143-9.714 8 8 2.286 4 10.857-0.571 14.857h2.857c-1.143 5.143-17.143 9.714-22.286 13.143s-32.571 9.143-38.286 5.714c-6.857-4 1.714-15.429 1.714-21.143 0.571-6.857-6.857-8.571-6.857-14.286 0-9.714 18.286-8 13.714-21.143-2.857-8-13.714-9.714-18.286-16-4.571-5.714 0.571-16 5.143-20 4.571-3.429-8-9.143-9.714-10.286-9.714-4.571-17.143 9.714-19.429 18.286-1.714 6.286-2.286 13.714-9.143 17.143-3.429 1.143-14.286 2.857-16.571-0.571-3.429 8.571-15.429 12-23.429 14.857-11.429 4-21.143 4-33.143 2.286 4 0.571-1.143 18.286-10.857 15.429 2.857 5.714 1.714 12 2.857 17.714 1.143 4.571 3.429 9.143 6.857 13.143 1.143 2.286 13.714 15.429 9.714 16 9.714-1.143 20.571-1.714 28.571 6.286 5.143 5.143 7.429 13.714 12.571 19.429 7.429 8.571 16.571-2.286 24.571-2.857 11.429-0.571 10.857 12 4.571 17.714 7.429-0.571 1.143 13.143-2.857 14.857-5.143 1.714-24.571-3.429-14.286-7.429-2.286 1.143-16-27.429-24-13.143-2.286 2.857-3.429 14.857-8.571 15.429-4.571 0-7.429-5.143-9.143-8.571 2.857 7.429-16 12.571-20 13.143 8.571 5.714 1.714 12-4.571 15.429-4.571 2.857-18.857 5.143-22.857 0.571-10.857-13.143 11.429-14.857 17.143-18.286 1.714-1.143 8.571-5.143 4.571-8-3.429-1.714-13.714-4.571-14.857-6.857-3.429-5.143 4-10.857-1.143-16-5.143 5.143-5.143 13.714-9.143 19.429 5.143-6.286-20.571-2.857-20-2.857-8.571 0-22.286-5.714-28.571 2.857-1.143 2.286-1.143 15.429 2.286 12.571-5.143 4-8.571 8-12 10.286-18.857-6.286-36.571-14.286-53.714-23.429 2.286-0.571 4-0.571 6.857 0.571 4.571 1.714 8.571 4.571 13.143 6.857 5.714 2.286 17.714 9.143 24 4 0.571 1.143 2.286 2.286 2.857 2.857 4-4.571 8-9.143 11.429-14.286-4.571 2.286-12 1.143-17.143 0.571-4-1.143-10.857-2.286-12.571-6.857 1.714-2.857 4-7.429 2.857-10.286-7.429 5.143-13.143 13.714-23.429 14.857-4.571 0-9.143 0-12.571-0.571-54.857-30.286-101.143-74.286-134.286-126.857 2.286-2.286 4.571-4 6.857-4.571 5.714-1.714 0-18.286 10.857-9.714 3.429-2.857 4-6.857 1.714-10.857 0.571 0.571 23.429-14.286 25.143-15.429 4-3.429 10.286-7.429 12-12 1.143-4-2.286-8.571-5.714-10.286-0.571 1.143-9.143 9.714-10.286 7.429-1.714-2.857 0-18.286 6.286-17.714-9.143-0.571-5.143-36-7.429-42.857 0-0.571 1.143-0.571 1.143-0.571-1.714-6.857 4-33.714 15.429-30.857-7.429-1.714 13.143-28 16-29.714 7.429-5.143 16-8.571 21.143-16 5.714-8 5.714-20 13.714-26.286-2.286-6.857 12-14.857 11.429-24.571-1.143-0.571-1.714-0.571-2.857-1.143 2.857-8 13.714-8 17.714-15.429 2.286-4.571 0-15.429 7.429-13.143 1.143 12.571-7.429 25.143-13.714 35.429-3.429 5.714-6.857 10.857-9.714 16.571-2.857 5.143-3.429 11.429-5.714 17.143 2.286-0.571 14.857-5.143 13.714-6.857-4.571-11.429 18.286-31.429 24.571-38.857 1.714-1.714 14.857-18.857 8-18.857 7.429 0 17.714-11.429 21.143-17.143 5.143-8.571 4-19.429 7.429-28.571 3.429-11.429 19.429-16.571 28.571-21.714 8-4 14.857-9.714 22.857-12.571 12-4.571 14.857-0.571 25.143 1.143 14.857 2.286 16.571-14.286 28.571-20.571 7.429-4 23.429-9.714 31.429-6.286-3.429-1.143 12-24.571 13.143-26.286 5.143-6.857 14.857-10.286 20.571-17.143 1.714 1.143 3.429 2.857 4 5.143-2.286-6.286 8.571-18.286 14.286-17.143 6.286 1.143 8 13.714 8 18.286-11.429-5.714-21.714-1.143-28 10.286-1.143 2.857-10.286 18.857-2.286 18.857 10.857 0 3.429 8.571 2.286 16.571s-9.143 13.143-13.143 20c-3.429-6.857-14.857-5.143-18.286 0.571 0-1.714-1.714-4.571-1.714-6.857-2.857 0-5.714-0.571-8.571 0.571 1.143 6.857 1.714 15.429 3.429 22.857 2.857 10.286 21.714 30.286-2.857 29.143-8.571-0.571-12-4-14.857-11.429-2.857-6.857-1.714-13.143-9.714-16.571-5.143-2.286-22.286-1.143-27.429 1.714-10.857 6.286-18.286 26.286-18.286 37.714-0.571 15.429 7.429 29.143 0 43.429 3.429 2.857 6.857 8.571 10.857 11.429 3.429 2.286 7.429-1.714 9.143 5.143-1.714 1.143-4 3.429-4.571 3.429 8.571-4 24.571 5.714 32 0 4.571-3.429 9.714-4.571 12.571 1.143 0.571 1.714-4 8.571-1.714 13.143 1.714-9.714 8-11.429 16.571-5.143 3.429-3.429 12.571-2.286 18.857-5.714 6.286-4 7.429-10.286 14.857-1.714 4.571-6.857 5.143-6.857 6.857-13.714 1.714-6.286 5.143-22.286 10.857-25.143 12-7.429 9.143 12.571 8 19.429-0.571 0.571-0.571 19.429-1.143 19.429-18.286 4-11.429 18.286-1.143 28 1.714 1.143 14.857 5.714 20.571 10.286 5.143 4.571 11.429 12.571 8.571 20 2.857 0 5.143 2.286 6.286 5.143-1.714 0.571-8.571 6.286-9.714 5.714 4 2.286 3.429 5.714 1.143 9.143 5.714 3.429 2.857 9.714 8.571 12 6.286-8.571 18.857 1.143 12.571 8 5.714 8 18.857 4 22.286 11.429 8.571-2.286 2.286 8.571 6.857 14.857 4 5.143 10.857 5.143 16 8 0-0.571 14.286 8 9.714 8.571 9.714-1.143 29.143 9.143 14.286 17.714 2.286 5.143-5.143 7.429-10.286 8.571 4 1.143 9.143-1.143 12.571 1.143 7.429 5.143 2.286 7.429-4 9.143-8 2.286-18.286-2.857-24.571-6.857zM502.286 78.857c78.286 13.714 148 52.571 200.571 108-3.429 3.429-9.714 2.286-14.286 4.571-4.571 1.714-8 3.429-13.714 4.571 1.143 11.429-11.429 15.429-19.429 21.143-7.429 5.714-12 12-22.857 9.714-1.143-0.571-12.571-4.571-10.286-6.857-7.429 6.286-10.857 9.714-20.571 12.571-9.143 2.857-15.429 14.286-24.571 4-4.571-4.571-2.286-11.429-4.571-16-7.429 6.286 6.857 13.714 1.143 20.571-6.857 8-18.857-5.143-24.571-8.571-3.429-2.857-7.429-4-9.714-7.429-2.857-4-4-9.143-6.286-13.143-1.714 4.571-11.429 3.429-12 6.857 2.286-13.714 2.286-28 5.143-41.714 1.714-8 0-21.143-6.857-27.429s-15.429-13.143-16.571-22.857c-1.143-6.857 0.571-13.143 6.857-14.857 0.571-8.571-9.143-14.857-8.571-24 0-0.571 0.571-6.286 1.143-9.143z" /> +<glyph unicode="" glyph-name="lock" horiz-adv-x="658" d="M182.857 512h292.571v109.714c0 80.571-65.714 146.286-146.286 146.286s-146.286-65.714-146.286-146.286v-109.714zM658.286 457.143v-329.143c0-30.286-24.571-54.857-54.857-54.857h-548.571c-30.286 0-54.857 24.571-54.857 54.857v329.143c0 30.286 24.571 54.857 54.857 54.857h18.286v109.714c0 140.571 115.429 256 256 256s256-115.429 256-256v-109.714h18.286c30.286 0 54.857-24.571 54.857-54.857z" /> +<glyph unicode="" glyph-name="chain-broken" horiz-adv-x="951" d="M250.857 224.571l-146.286-146.286c-4-3.429-8.571-5.143-13.143-5.143s-9.143 1.714-13.143 5.143c-6.857 7.429-6.857 18.857 0 26.286l146.286 146.286c7.429 6.857 18.857 6.857 26.286 0 6.857-7.429 6.857-18.857 0-26.286zM347.429 201.143v-182.857c0-10.286-8-18.286-18.286-18.286s-18.286 8-18.286 18.286v182.857c0 10.286 8 18.286 18.286 18.286s18.286-8 18.286-18.286zM219.429 329.143c0-10.286-8-18.286-18.286-18.286h-182.857c-10.286 0-18.286 8-18.286 18.286s8 18.286 18.286 18.286h182.857c10.286 0 18.286-8 18.286-18.286zM941.714 256c0-44-17.143-85.143-48.571-116l-84-83.429c-30.857-30.857-72-47.429-116-47.429s-85.714 17.143-116.571 48.571l-190.857 191.429c-9.714 9.714-17.143 20.571-24 32l136.571 10.286 156-156.571c20.571-20.571 57.143-21.143 77.714-0.571l84 83.429c10.286 10.286 16 24 16 38.286 0 14.857-5.714 28.571-16 38.857l-156.571 157.143 10.286 136.571c11.429-6.857 22.286-14.286 32-24l192-192c30.857-31.429 48-72.571 48-116.571zM589.143 669.714l-136.571-10.286-156 156.571c-10.286 10.286-24 16-38.857 16s-28.571-5.714-38.857-15.429l-84-83.429c-10.286-10.286-16-24-16-38.286 0-14.857 5.714-28.571 16-38.857l156.571-156.571-10.286-137.143c-11.429 6.857-22.286 14.286-32 24l-192 192c-30.857 31.429-48 72.571-48 116.571s17.143 85.143 48.571 116l84 83.429c30.857 30.857 72 47.429 116 47.429s85.714-17.143 116.571-48.571l190.857-191.429c9.714-9.714 17.143-20.571 24-32zM950.857 621.714c0-10.286-8-18.286-18.286-18.286h-182.857c-10.286 0-18.286 8-18.286 18.286s8 18.286 18.286 18.286h182.857c10.286 0 18.286-8 18.286-18.286zM640 932.571v-182.857c0-10.286-8-18.286-18.286-18.286s-18.286 8-18.286 18.286v182.857c0 10.286 8 18.286 18.286 18.286s18.286-8 18.286-18.286zM872.571 846.286l-146.286-146.286c-4-3.429-8.571-5.143-13.143-5.143s-9.143 1.714-13.143 5.143c-6.857 7.429-6.857 18.857 0 26.286l146.286 146.286c7.429 6.857 18.857 6.857 26.286 0 6.857-7.429 6.857-18.857 0-26.286z" /> +<glyph unicode="" glyph-name="chain" horiz-adv-x="951" d="M832 256c0 14.857-5.714 28.571-16 38.857l-118.857 118.857c-10.286 10.286-24.571 16-38.857 16-16.571 0-29.714-6.286-41.143-18.286 18.857-18.857 41.143-34.857 41.143-64 0-30.286-24.571-54.857-54.857-54.857-29.143 0-45.143 22.286-64 41.143-12-11.429-18.857-24.571-18.857-41.714 0-14.286 5.714-28.571 16-38.857l117.714-118.286c10.286-10.286 24.571-15.429 38.857-15.429s28.571 5.143 38.857 14.857l84 83.429c10.286 10.286 16 24 16 38.286zM430.286 658.857c0 14.286-5.714 28.571-16 38.857l-117.714 118.286c-10.286 10.286-24.571 16-38.857 16s-28.571-5.714-38.857-15.429l-84-83.429c-10.286-10.286-16-24-16-38.286 0-14.857 5.714-28.571 16-38.857l118.857-118.857c10.286-10.286 24.571-15.429 38.857-15.429 16.571 0 29.714 5.714 41.143 17.714-18.857 18.857-41.143 34.857-41.143 64 0 30.286 24.571 54.857 54.857 54.857 29.143 0 45.143-22.286 64-41.143 12 11.429 18.857 24.571 18.857 41.714zM941.714 256c0-43.429-17.714-85.714-48.571-116l-84-83.429c-30.857-30.857-72.571-47.429-116-47.429-44 0-85.714 17.143-116.571 48.571l-117.714 118.286c-30.857 30.857-47.429 72.571-47.429 116 0 45.143 18.286 88 50.286 119.429l-50.286 50.286c-31.429-32-73.714-50.286-118.857-50.286-43.429 0-85.714 17.143-116.571 48l-118.857 118.857c-31.429 31.429-48 72.571-48 116.571 0 43.429 17.714 85.714 48.571 116l84 83.429c30.857 30.857 72.571 47.429 116 47.429 44 0 85.714-17.143 116.571-48.571l117.714-118.286c30.857-30.857 47.429-72.571 47.429-116 0-45.143-18.286-88-50.286-119.429l50.286-50.286c31.429 32 73.714 50.286 118.857 50.286 43.429 0 85.714-17.143 116.571-48l118.857-118.857c31.429-31.429 48-72.571 48-116.571z" /> +<glyph unicode="" glyph-name="comments" d="M804.571 512c0-161.714-180-292.571-402.286-292.571-34.857 0-68.571 3.429-100.571 9.143-47.429-33.714-101.143-58.286-158.857-73.143-15.429-4-32-6.857-49.143-9.143h-1.714c-8.571 0-16.571 6.857-18.286 16.571v0c-2.286 10.857 5.143 17.714 11.429 25.143 22.286 25.143 47.429 47.429 66.857 94.857-92.571 53.714-152 136.571-152 229.143 0 161.714 180 292.571 402.286 292.571s402.286-130.857 402.286-292.571zM1024 365.714c0-93.143-59.429-175.429-152-229.143 19.429-47.429 44.571-69.714 66.857-94.857 6.286-7.429 13.714-14.286 11.429-25.143v0c-2.286-10.286-10.857-17.714-20-16.571-17.143 2.286-33.714 5.143-49.143 9.143-57.714 14.857-111.429 39.429-158.857 73.143-32-5.714-65.714-9.143-100.571-9.143-103.429 0-198.286 28.571-269.714 75.429 16.571-1.143 33.714-2.286 50.286-2.286 122.857 0 238.857 35.429 327.429 99.429 95.429 69.714 148 164 148 266.286 0 29.714-4.571 58.857-13.143 86.857 96.571-53.143 159.429-137.714 159.429-233.143z" /> +<glyph unicode="" glyph-name="comment" d="M1024 438.857c0-202.286-229.143-365.714-512-365.714-28 0-56 1.714-82.857 4.571-74.857-66.286-164-113.143-262.857-138.286-20.571-5.714-42.857-9.714-65.143-12.571-12.571-1.143-24.571 8-27.429 21.714v0.571c-2.857 14.286 6.857 22.857 15.429 33.143 36 40.571 77.143 74.857 104 170.286-117.714 66.857-193.143 170.286-193.143 286.286 0 201.714 229.143 365.714 512 365.714s512-163.429 512-365.714z" /> +<glyph unicode="" glyph-name="boost" horiz-adv-x="1097" d="M731.429 91.428c0-9.714-8.571-18.286-18.286-18.286h-548.571c-21.143 0-18.286 22.286-18.286 36.571v329.143h-109.714c-20 0-36.571 16.571-36.571 36.571 0 8.571 2.857 17.143 8.571 23.429l182.857 219.429c6.857 8 17.143 12.571 28 12.571s21.143-4.571 28-12.571l182.857-219.429c5.714-6.286 8.571-14.857 8.571-23.429 0-20-16.571-36.571-36.571-36.571h-109.714v-219.429h329.143c5.143 0 10.857-2.286 14.286-6.286l91.429-109.714c2.286-3.429 4-8 4-12zM1097.143 329.143c0-8.571-2.857-17.143-8.571-23.429l-182.857-219.429c-6.857-8-17.143-13.143-28-13.143s-21.143 5.143-28 13.143l-182.857 219.429c-5.714 6.286-8.571 14.857-8.571 23.429 0 20 16.571 36.571 36.571 36.571h109.714v219.429h-329.143c-5.143 0-10.857 2.286-14.286 6.857l-91.429 109.714c-2.286 2.857-4 7.429-4 11.429 0 9.714 8.571 18.286 18.286 18.286h548.571c21.143 0 18.286-22.286 18.286-36.571v-329.143h109.714c20 0 36.571-16.571 36.571-36.571z" /> +<glyph unicode="" glyph-name="arrow-left" d="M598 640.667v-428l-214 214z" /> +<glyph unicode="" glyph-name="arrow-up" d="M298 340.667l214 214 214-214h-428z" /> +<glyph unicode="" glyph-name="arrow-down" d="M298 512.667h428l-214-214z" /> +<glyph unicode="" glyph-name="home" horiz-adv-x="951" d="M804.571 384v-274.286c0-20-16.571-36.571-36.571-36.571h-219.429v219.429h-146.286v-219.429h-219.429c-20 0-36.571 16.571-36.571 36.571v274.286c0 1.143 0.571 2.286 0.571 3.429l328.571 270.857 328.571-270.857c0.571-1.143 0.571-2.286 0.571-3.429zM932 423.428l-35.429-42.286c-2.857-3.429-7.429-5.714-12-6.286h-1.714c-4.571 0-8.571 1.143-12 4l-395.429 329.714-395.429-329.714c-4-2.857-8.571-4.571-13.714-4-4.571 0.571-9.143 2.857-12 6.286l-35.429 42.286c-6.286 7.429-5.143 19.429 2.286 25.714l410.857 342.286c24 20 62.857 20 86.857 0l139.429-116.571v111.429c0 10.286 8 18.286 18.286 18.286h109.714c10.286 0 18.286-8 18.286-18.286v-233.143l125.143-104c7.429-6.286 8.571-18.286 2.286-25.714z" /> +<glyph unicode="" glyph-name="local" horiz-adv-x="1097" d="M338.857 438.857c-59.429-1.714-113.143-27.429-151.429-73.143h-76.571c-57.143 0-110.857 27.429-110.857 90.857 0 46.286-1.714 201.714 70.857 201.714 12 0 71.429-48.571 148.571-48.571 26.286 0 51.429 4.571 76 13.143-1.714-12.571-2.857-25.143-2.857-37.714 0-52 16.571-103.429 46.286-146.286zM950.857 74.857c0-92.571-61.143-148-152.571-148h-499.429c-91.429 0-152.571 55.429-152.571 148 0 129.143 30.286 327.429 197.714 327.429 19.429 0 90.286-79.429 204.571-79.429s185.143 79.429 204.571 79.429c167.429 0 197.714-198.286 197.714-327.429zM365.714 804.571c0-80.571-65.714-146.286-146.286-146.286s-146.286 65.714-146.286 146.286 65.714 146.286 146.286 146.286 146.286-65.714 146.286-146.286zM768 585.143c0-121.143-98.286-219.429-219.429-219.429s-219.429 98.286-219.429 219.429 98.286 219.429 219.429 219.429 219.429-98.286 219.429-219.429zM1097.143 456.571c0-63.429-53.714-90.857-110.857-90.857h-76.571c-38.286 45.714-92 71.429-151.429 73.143 29.714 42.857 46.286 94.286 46.286 146.286 0 12.571-1.143 25.143-2.857 37.714 24.571-8.571 49.714-13.143 76-13.143 77.143 0 136.571 48.571 148.571 48.571 72.571 0 70.857-155.429 70.857-201.714zM1024 804.571c0-80.571-65.714-146.286-146.286-146.286s-146.286 65.714-146.286 146.286 65.714 146.286 146.286 146.286 146.286-65.714 146.286-146.286z" /> <glyph unicode="" glyph-name="search" d="M992.262 88.604l-242.552 206.294c-25.074 22.566-51.89 32.926-73.552 31.926 57.256 67.068 91.842 154.078 91.842 249.176 0 212.078-171.922 384-384 384-212.076 0-384-171.922-384-384s171.922-384 384-384c95.098 0 182.108 34.586 249.176 91.844-1-21.662 9.36-48.478 31.926-73.552l206.294-242.552c35.322-39.246 93.022-42.554 128.22-7.356s31.892 92.898-7.354 128.22zM384 320c-141.384 0-256 114.616-256 256s114.616 256 256 256 256-114.616 256-256-114.614-256-256-256z" /> <glyph unicode="" glyph-name="star-empty" d="M1024 562.95l-353.78 51.408-158.22 320.582-158.216-320.582-353.784-51.408 256-249.538-60.432-352.352 316.432 166.358 316.432-166.358-60.434 352.352 256.002 249.538zM512 206.502l-223.462-117.48 42.676 248.83-180.786 176.222 249.84 36.304 111.732 226.396 111.736-226.396 249.836-36.304-180.788-176.222 42.678-248.83-223.462 117.48z" /> <glyph unicode="" glyph-name="star-half" d="M1024 562.95l-353.78 51.408-158.22 320.582-158.216-320.582-353.784-51.408 256-249.538-60.432-352.352 316.432 166.358 316.432-166.358-60.434 352.352 256.002 249.538zM512 206.502l-0.942-0.496 0.942 570.768 111.736-226.396 249.836-36.304-180.788-176.222 42.678-248.83-223.462 117.48z" /> diff --git a/bookwyrm/static/css/fonts/icomoon.ttf b/bookwyrm/static/css/fonts/icomoon.ttf index a61117da6..0f78404f5 100644 Binary files a/bookwyrm/static/css/fonts/icomoon.ttf and b/bookwyrm/static/css/fonts/icomoon.ttf differ diff --git a/bookwyrm/static/css/fonts/icomoon.woff b/bookwyrm/static/css/fonts/icomoon.woff index 1dccbcf96..dcb8dc751 100644 Binary files a/bookwyrm/static/css/fonts/icomoon.woff and b/bookwyrm/static/css/fonts/icomoon.woff differ diff --git a/bookwyrm/static/css/icons.css b/bookwyrm/static/css/icons.css index eabfb06e3..bf68b7d6a 100644 --- a/bookwyrm/static/css/icons.css +++ b/bookwyrm/static/css/icons.css @@ -1,10 +1,10 @@ @font-face { font-family: 'icomoon'; - src: url('fonts/icomoon.eot?v0wquk'); - src: url('fonts/icomoon.eot?v0wquk#iefix') format('embedded-opentype'), - url('fonts/icomoon.ttf?v0wquk') format('truetype'), - url('fonts/icomoon.woff?v0wquk') format('woff'), - url('fonts/icomoon.svg?v0wquk#icomoon') format('svg'); + src: url('fonts/icomoon.eot?7ifunb'); + src: url('fonts/icomoon.eot?7ifunb#iefix') format('embedded-opentype'), + url('fonts/icomoon.ttf?7ifunb') format('truetype'), + url('fonts/icomoon.woff?7ifunb') format('woff'), + url('fonts/icomoon.svg?7ifunb#icomoon') format('svg'); font-weight: normal; font-style: normal; font-display: block; @@ -13,7 +13,7 @@ [class^="icon-"], [class*=" icon-"] { /* use !important to prevent issues with browser extensions that change fonts */ font-family: 'icomoon' !important; - speak: none; + speak: never; font-style: normal; font-weight: normal; font-variant: normal; @@ -25,26 +25,71 @@ -moz-osx-font-smoothing: grayscale; } -.icon-arrow-right:before { +.icon-envelope:before { content: "\e900"; } -.icon-arrow-left:before { - content: "\e910"; +.icon-arrow-right:before { + content: "\e901"; } -.icon-arrow-up:before { - content: "\e911"; -} -.icon-arrow-down:before { - content: "\e912"; +.icon-bell:before { + content: "\e902"; } .icon-x:before { - content: "\e902"; + content: "\e903"; } -.icon-cancel:before { - content: "\e902"; +.icon-quote-close:before { + content: "\e904"; } -.icon-close:before { - content: "\e902"; +.icon-quote-open:before { + content: "\e905"; +} +.icon-image:before { + content: "\e906"; +} +.icon-pencil:before { + content: "\e907"; +} +.icon-list:before { + content: "\e908"; +} +.icon-unlock:before { + content: "\e909"; +} +.icon-globe:before { + content: "\e90a"; +} +.icon-lock:before { + content: "\e90b"; +} +.icon-chain-broken:before { + content: "\e90c"; +} +.icon-chain:before { + content: "\e90d"; +} +.icon-comments:before { + content: "\e90e"; +} +.icon-comment:before { + content: "\e90f"; +} +.icon-boost:before { + content: "\e910"; +} +.icon-arrow-left:before { + content: "\e911"; +} +.icon-arrow-up:before { + content: "\e912"; +} +.icon-arrow-down:before { + content: "\e913"; +} +.icon-home:before { + content: "\e914"; +} +.icon-local:before { + content: "\e915"; } .icon-search:before { content: "\e986"; @@ -61,78 +106,3 @@ .icon-heart:before { content: "\e9da"; } -.icon-local:before { - content: "\e914"; -} -.icon-home:before { - content: "\e913"; -} -.icon-quote-close:before { - content: "\e903"; -} -.icon-quote-open:before { - content: "\e904"; -} -.icon-image:before { - content: "\e905"; -} -.icon-photo:before { - content: "\e905"; -} -.icon-picture-o:before { - content: "\e905"; -} -.icon-pencil:before { - content: "\e906"; -} -.icon-list:before { - content: "\e907"; -} -.icon-unlock:before { - content: "\e908"; -} -.icon-unlisted:before { - content: "\e908"; -} -.icon-globe:before { - content: "\e909"; -} -.icon-global:before { - content: "\e909"; -} -.icon-federated:before { - content: "\e909"; -} -.icon-public:before { - content: "\e909"; -} -.icon-lock:before { - content: "\e90a"; -} -.icon-private:before { - content: "\e90a"; -} -.icon-chain-broken:before { - content: "\e90b"; -} -.icon-unlink:before { - content: "\e90b"; -} -.icon-chain:before { - content: "\e90c"; -} -.icon-link:before { - content: "\e90c"; -} -.icon-comments:before { - content: "\e90d"; -} -.icon-comment:before { - content: "\e90e"; -} -.icon-boost:before { - content: "\e90f"; -} -.icon-bell:before { - content: "\e901"; -} diff --git a/bookwyrm/status.py b/bookwyrm/status.py index 256198399..258734b39 100644 --- a/bookwyrm/status.py +++ b/bookwyrm/status.py @@ -13,100 +13,6 @@ def delete_status(status): status.deleted_date = datetime.now() status.save() -def create_rating(user, book, rating): - ''' a review that's just a rating ''' - if not rating or rating < 1 or rating > 5: - raise ValueError('Invalid rating') - return models.Review.objects.create( - user=user, - book=book, - rating=rating, - ) - - -def create_review(user, book, name, content, rating): - ''' a book review has been added ''' - name = sanitize(name) - content = sanitize(content) - - # no ratings outside of 0-5 - if rating: - rating = rating if 1 <= rating <= 5 else None - else: - rating = None - - return models.Review.objects.create( - user=user, - book=book, - name=name, - rating=rating, - content=content, - ) - - -def create_quotation_from_activity(author, activity): - ''' parse an activity json blob into a status ''' - book_id = activity['inReplyToBook'] - book = get_or_create_book(book_id) - quote = activity.get('quote') - content = activity.get('content') - published = activity.get('published') - remote_id = activity['id'] - - quotation = create_quotation(author, book, content, quote) - quotation.published_date = published - quotation.remote_id = remote_id - quotation.save() - return quotation - - -def create_quotation(user, book, content, quote): - ''' a quotation has been added ''' - # throws a value error if the book is not found - content = sanitize(content) - quote = sanitize(quote) - - return models.Quotation.objects.create( - user=user, - book=book, - content=content, - quote=quote, - ) - - -def create_comment_from_activity(author, activity): - ''' parse an activity json blob into a status ''' - book_id = activity['inReplyToBook'] - book = get_or_create_book(book_id) - content = activity.get('content') - published = activity.get('published') - remote_id = activity['id'] - - comment = create_comment(author, book, content) - comment.published_date = published - comment.remote_id = remote_id - comment.save() - return comment - - -def create_comment(user, book, content): - ''' a book comment has been added ''' - # throws a value error if the book is not found - content = sanitize(content) - - return models.Comment.objects.create( - user=user, - book=book, - content=content, - ) - - -def get_status(remote_id): - ''' find a status in the database ''' - return models.Status.objects.select_subclasses().filter( - remote_id=remote_id - ).first() - def create_generated_note(user, content, mention_books=None): ''' a note created by the app about user activity ''' @@ -127,28 +33,6 @@ def create_generated_note(user, content, mention_books=None): return status -def create_status(user, content, reply_parent=None, mention_books=None): - ''' a status update ''' - # TODO: handle @'ing users - - # sanitize input html - parser = InputHtmlParser() - parser.feed(content) - content = parser.get_output() - - status = models.Status.objects.create( - user=user, - content=content, - reply_parent=reply_parent, - ) - - if mention_books: - for book in mention_books: - status.mention_books.add(book) - - return status - - def create_tag(user, possible_book, name): ''' add a tag to a book ''' book = get_or_create_book(possible_book) @@ -174,10 +58,3 @@ def create_notification(user, notification_type, related_user=None, \ related_import=related_import, notification_type=notification_type, ) - - -def sanitize(content): - ''' remove invalid html from free text ''' - parser = InputHtmlParser() - parser.feed(content) - return parser.get_output() diff --git a/bookwyrm/templates/layout.html b/bookwyrm/templates/layout.html index f5f72e658..553806528 100644 --- a/bookwyrm/templates/layout.html +++ b/bookwyrm/templates/layout.html @@ -47,11 +47,11 @@ <div id="mainNav" class="navbar-menu toggle-content"> <div class="navbar-start"> {% if request.user.is_authenticated %} - <a href="" class="navbar-item"> - Lists + <a href="/user/{{ request.user.localname }}/shelves" class="navbar-item"> + Your shelves </a> - <a href="" class="navbar-item"> - Groups + <a href="/#feed" class="navbar-item"> + Feed </a> {% endif %} </div> diff --git a/bookwyrm/templates/snippets/create_status.html b/bookwyrm/templates/snippets/create_status.html index 88558df9c..28379f0e3 100644 --- a/bookwyrm/templates/snippets/create_status.html +++ b/bookwyrm/templates/snippets/create_status.html @@ -22,6 +22,7 @@ <form class="toggle-content hidden tab-option-{{ book.id }}" name="review" action="/review/" method="post" id="tab-review-{{ book.id }}"> {% csrf_token %} <input type="hidden" name="book" value="{{ book.id }}"> + <input type="hidden" name="user" value="{{ request.user.id }}"> <div class="control"> <label class="label" for="id_name_{{ book.id }}_review">Title:</label> <input type="text" name="name" maxlength="255" class="input" required="" id="id_name_{{ book.id }}_review" placeholder="My review of '{{ book.title }}'"> @@ -42,7 +43,17 @@ <textarea name="content" class="textarea" id="id_content_{{ book.id }}_review"></textarea> </div> - <button class="button is-primary" type="submit">post review</button> + <div class="control is-grouped"> + <div class="select"> + <select name="privacy"> + <option value="public" selected>Public</option> + <option value="unlisted">Unlisted</option> + <option value="followers">Followers only</option> + <option value="direct">Private</option> + </select> + </div> + <button class="button is-primary" type="submit">post review</button> + </div> </form> </div> @@ -51,11 +62,24 @@ <form class="toggle-content hidden tab-option-{{ book.id }}" name="comment" action="/comment/" method="post" id="tab-comment-{{ book.id }}"> {% csrf_token %} <input type="hidden" name="book" value="{{ book.id }}"> + <input type="hidden" name="book" value="{{ book.id }}"> + <input type="hidden" name="user" value="{{ request.user.id }}"> + <input type="hidden" name="privacy" value="public"> <div class="control"> <label class="label" for="id_content_{{ book.id }}_comment">Comment:</label> <textarea name="content" class="textarea" id="id_content_{{ book.id }}_comment" placeholder="Some thoughts on '{{ book.title }}'"></textarea> </div> - <button class="button is-primary" type="submit">post comment</button> + <div class="control is-grouped"> + <div class="select"> + <select name="privacy"> + <option value="public" selected>Public</option> + <option value="unlisted">Unlisted</option> + <option value="followers">Followers only</option> + <option value="direct">Private</option> + </select> + </div> + <button class="button is-primary" type="submit">post comment</button> + </div> </form> </div> @@ -64,6 +88,9 @@ <form class="toggle-content hidden tab-option-{{ book.id }}" name="quotation" action="/quotate/" method="post" id="tab-quotation-{{ book.id }}"> {% csrf_token %} <input type="hidden" name="book" value="{{ book.id }}"> + <input type="hidden" name="book" value="{{ book.id }}"> + <input type="hidden" name="user" value="{{ request.user.id }}"> + <input type="hidden" name="privacy" value="public"> <div class="control"> <label class="label" for="id_quote_{{ book.id }}_quote">Quote:</label> <textarea name="quote" class="textarea" required="" id="id_quote_{{ book.id }}_quote" placeholder="An except from '{{ book.title }}'"></textarea> @@ -72,7 +99,17 @@ <label class="label" for="id_content_{{ book.id }}_quote">Comment:</label> <textarea name="content" class="textarea is-small" id="id_content_{{ book.id }}_quote"></textarea> </div> - <button class="button is-primary" type="submit">post quote</button> + <div class="control is-grouped"> + <div class="select"> + <select name="privacy"> + <option value="public" selected>Public</option> + <option value="unlisted">Unlisted</option> + <option value="followers">Followers only</option> + <option value="direct">Private</option> + </select> + </div> + <button class="button is-primary" type="submit">post quote</button> + </div> </form> </div> </div> diff --git a/bookwyrm/templates/snippets/interaction.html b/bookwyrm/templates/snippets/interaction.html index 8680df8de..a48d8a7ca 100644 --- a/bookwyrm/templates/snippets/interaction.html +++ b/bookwyrm/templates/snippets/interaction.html @@ -4,7 +4,9 @@ <form name="reply" action="/reply" method="post" onsubmit="return reply(event)"> <div class="field is-grouped"> {% csrf_token %} - <input type="hidden" name="parent" value="{{ activity.id }}"> + <input type="hidden" name="reply_parent" value="{{ activity.id }}"> + <input type="hidden" name="user" value="{{ request.user.id }}"> + <input type="hidden" name="privacy" value="{{ activity.privacy }}"> <textarea name="content" placeholder="Leave a comment..." id="id_content_{{ activity.id }}" required="true"></textarea> <button class="button" type="submit"> <span class="icon icon-comment"> diff --git a/bookwyrm/templates/snippets/status.html b/bookwyrm/templates/snippets/status.html index 5c570e0d6..ebd9d4539 100644 --- a/bookwyrm/templates/snippets/status.html +++ b/bookwyrm/templates/snippets/status.html @@ -23,15 +23,29 @@ {% endif %} <div class="card-footer-item"> - <span class="icon icon-public"> + {% if status.privacy == 'public' %} + <span class="icon icon-globe"> <span class="is-sr-only">Public post</span> </span> + {% elif status.privacy == 'unlisted' %} + <span class="icon icon-unlock"> + <span class="is-sr-only">Unlisted post</span> + </span> + {% elif status.privacy == 'followers' %} + <span class="icon icon-lock"> + <span class="is-sr-only">Followers-only post</span> + </span> + {% else %} + <span class="icon icon-envelope"> + <span class="is-sr-only">Private post</span> + </span> + {% endif %} {% if status.user == request.user %} <form name="delete-{{status.id}}" action="/delete-status" method="post"> {% csrf_token %} <input type="hidden" name="status" value="{{ status.id }}"> <button type="submit"> - <span class="icon icon-cancel"> + <span class="icon icon-x"> <span class="is-sr-only">Delete post</span> </span> </button> diff --git a/bookwyrm/tests/status/__init__.py b/bookwyrm/tests/status/__init__.py deleted file mode 100644 index b6e690fd5..000000000 --- a/bookwyrm/tests/status/__init__.py +++ /dev/null @@ -1 +0,0 @@ -from . import * diff --git a/bookwyrm/tests/status/test_comment.py b/bookwyrm/tests/status/test_comment.py deleted file mode 100644 index be127d887..000000000 --- a/bookwyrm/tests/status/test_comment.py +++ /dev/null @@ -1,18 +0,0 @@ -from django.test import TestCase - -from bookwyrm import models -from bookwyrm import status as status_builder - - -class Comment(TestCase): - ''' we have hecka ways to create statuses ''' - def setUp(self): - self.user = models.User.objects.create_user( - 'mouse', 'mouse@mouse.mouse', 'mouseword') - self.book = models.Edition.objects.create(title='Example Edition') - - - def test_create_comment(self): - comment = status_builder.create_comment( - self.user, self.book, 'commentary') - self.assertEqual(comment.content, 'commentary') diff --git a/bookwyrm/tests/status/test_quotation.py b/bookwyrm/tests/status/test_quotation.py deleted file mode 100644 index 4892e21d3..000000000 --- a/bookwyrm/tests/status/test_quotation.py +++ /dev/null @@ -1,24 +0,0 @@ -from django.test import TestCase - -from bookwyrm import models -from bookwyrm import status as status_builder - - -class Quotation(TestCase): - ''' we have hecka ways to create statuses ''' - def setUp(self): - self.user = models.User.objects.create_user( - 'mouse', 'mouse@mouse.mouse', 'mouseword', - remote_id='https://example.com/user/mouse' - ) - self.book = models.Edition.objects.create( - title='Example Edition', - remote_id='https://example.com/book/1', - ) - - - def test_create_quotation(self): - quotation = status_builder.create_quotation( - self.user, self.book, 'commentary', 'a quote') - self.assertEqual(quotation.quote, 'a quote') - self.assertEqual(quotation.content, 'commentary') diff --git a/bookwyrm/tests/status/test_review.py b/bookwyrm/tests/status/test_review.py deleted file mode 100644 index 263fef974..000000000 --- a/bookwyrm/tests/status/test_review.py +++ /dev/null @@ -1,39 +0,0 @@ -from django.test import TestCase - -from bookwyrm import models -from bookwyrm import status as status_builder - - -class Review(TestCase): - ''' we have hecka ways to create statuses ''' - def setUp(self): - self.user = models.User.objects.create_user( - 'mouse', 'mouse@mouse.mouse', 'mouseword') - self.book = models.Edition.objects.create(title='Example Edition') - - - def test_create_review(self): - review = status_builder.create_review( - self.user, self.book, 'review name', 'content', 5) - self.assertEqual(review.name, 'review name') - self.assertEqual(review.content, 'content') - self.assertEqual(review.rating, 5) - - review = status_builder.create_review( - self.user, self.book, '<div>review</div> name', '<b>content', 5) - self.assertEqual(review.name, 'review name') - self.assertEqual(review.content, 'content') - self.assertEqual(review.rating, 5) - - def test_review_rating(self): - review = status_builder.create_review( - self.user, self.book, 'review name', 'content', -1) - self.assertEqual(review.name, 'review name') - self.assertEqual(review.content, 'content') - self.assertEqual(review.rating, None) - - review = status_builder.create_review( - self.user, self.book, 'review name', 'content', 6) - self.assertEqual(review.name, 'review name') - self.assertEqual(review.content, 'content') - self.assertEqual(review.rating, None) diff --git a/bookwyrm/tests/status/test_status.py b/bookwyrm/tests/status/test_status.py deleted file mode 100644 index cb49cb12d..000000000 --- a/bookwyrm/tests/status/test_status.py +++ /dev/null @@ -1,28 +0,0 @@ -from django.test import TestCase - -from bookwyrm import models -from bookwyrm import status as status_builder - - -class Status(TestCase): - ''' we have hecka ways to create statuses ''' - def setUp(self): - self.user = models.User.objects.create_user( - 'mouse', 'mouse@mouse.mouse', 'mouseword', - local=False, - inbox='https://example.com/user/mouse/inbox', - outbox='https://example.com/user/mouse/outbox', - remote_id='https://example.com/user/mouse' - ) - - - def test_create_status(self): - content = 'statuses are usually <i>replies</i>' - status = status_builder.create_status( - self.user, content) - self.assertEqual(status.content, content) - - reply = status_builder.create_status( - self.user, content, reply_parent=status) - self.assertEqual(reply.content, content) - self.assertEqual(reply.reply_parent, status) diff --git a/bookwyrm/view_actions.py b/bookwyrm/view_actions.py index 3d01e9ff4..e8c3e6f2a 100644 --- a/bookwyrm/view_actions.py +++ b/bookwyrm/view_actions.py @@ -289,68 +289,45 @@ def shelve(request): def rate(request): ''' just a star rating for a book ''' form = forms.RatingForm(request.POST) - book_id = request.POST.get('book') - # TODO: better failure behavior - if not form.is_valid(): - return redirect('/book/%s' % book_id) - - rating = form.cleaned_data.get('rating') - # throws a value error if the book is not found - - outgoing.handle_rate(request.user, book_id, rating) - return redirect('/book/%s' % book_id) + return handle_status(request, form) @login_required def review(request): ''' create a book review ''' form = forms.ReviewForm(request.POST) - book_id = request.POST.get('book') - if not form.is_valid(): - return redirect('/book/%s' % book_id) - - # TODO: validation, htmlification - name = form.cleaned_data.get('name') - content = form.cleaned_data.get('content') - rating = form.data.get('rating', None) - try: - rating = int(rating) - except ValueError: - rating = None - - outgoing.handle_review(request.user, book_id, name, content, rating) - return redirect('/book/%s' % book_id) + return handle_status(request, form) @login_required def quotate(request): ''' create a book quotation ''' form = forms.QuotationForm(request.POST) - book_id = request.POST.get('book') - if not form.is_valid(): - return redirect('/book/%s' % book_id) - - quote = form.cleaned_data.get('quote') - content = form.cleaned_data.get('content') - - outgoing.handle_quotation(request.user, book_id, content, quote) - return redirect('/book/%s' % book_id) + return handle_status(request, form) @login_required def comment(request): ''' create a book comment ''' form = forms.CommentForm(request.POST) + return handle_status(request, form) + + +@login_required +def reply(request): + ''' respond to a book review ''' + form = forms.ReplyForm(request.POST) + return handle_status(request, form) + + +def handle_status(request, form): + ''' all the "create a status" functions are the same ''' book_id = request.POST.get('book') - # TODO: better failure behavior if not form.is_valid(): - return redirect('/book/%s' % book_id) + return redirect(request.headers.get('Referer', '/')) - # TODO: validation, htmlification - content = form.data.get('content') - - outgoing.handle_comment(request.user, book_id, content) - return redirect('/book/%s' % book_id) + outgoing.handle_status(request.user, form) + return redirect(request.headers.get('Referer', '/')) @login_required @@ -376,19 +353,6 @@ def untag(request): return redirect('/book/%s' % book_id) -@login_required -def reply(request): - ''' respond to a book review ''' - form = forms.ReplyForm(request.POST) - # this is a bit of a formality, the form is just one text field - if not form.is_valid(): - return redirect('/') - parent_id = request.POST['parent'] - parent = models.Status.objects.get(id=parent_id) - outgoing.handle_reply(request.user, parent, form.data['content']) - return redirect('/') - - @login_required def favorite(request, status_id): ''' like a status ''' diff --git a/bookwyrm/views.py b/bookwyrm/views.py index 55957ff29..2422cd27c 100644 --- a/bookwyrm/views.py +++ b/bookwyrm/views.py @@ -130,17 +130,22 @@ def get_activity_feed(user, filter_level, model=models.Status): if filter_level in ['friends', 'home']: # people you follow and direct mentions activities = activities.filter( - Q(user__in=following, privacy='public') | \ - Q(mention_users=user) + Q(user__in=following, privacy__in=['public', 'unlisted', 'followers']) | \ + Q(mention_users=user) | Q(user=user) ) elif filter_level == 'self': activities = activities.filter(user=user, privacy='public') elif filter_level == 'local': - # everyone on this instance - activities = activities.filter(user__local=True, privacy='public') + # everyone on this instance except unlisted + activities = activities.filter( + Q(user__in=following, privacy='followers') | Q(privacy='public'), + user__local=True + ) else: # all activities from everyone you federate with - activities = activities.filter(privacy='public') + activities = activities.filter( + Q(user__in=following, privacy='followers') | Q(privacy='public') + ) return activities @@ -386,9 +391,14 @@ def status_page(request, username, status_id): except ValueError: return HttpResponseNotFound() + # the url should have the poster's username in it if user != status.user: return HttpResponseNotFound() + # make sure the user is authorized to see the status + if not status_visible_to_user(request.user, status): + return HttpResponseNotFound() + if is_api_request(request): return JsonResponse(status.to_activity(), encoder=ActivityEncoder) @@ -397,6 +407,19 @@ def status_page(request, username, status_id): } return TemplateResponse(request, 'status.html', data) +def status_visible_to_user(viewer, status): + ''' is a user authorized to view a status? ''' + if viewer == status.user or status.privacy in ['public', 'unlisted']: + return True + if status.privacy == 'followers' and \ + status.user.followers.filter(id=viewer.id).first(): + return True + if status.privacy == 'direct' and \ + status.mention_users.filter(id=viewer.id).first(): + return True + return False + + @csrf_exempt def replies_page(request, username, status_id):