internlm/SWE-Fixer-Train-110K huggingface dataset:
Repository: bookwyrm-social/bookwyrm

Issue:
User profile failing to load
**Describe the bug**
Attempting to access https://bookwyrm.social/user/jonathan.brodsky causes a
```
Server Error
Something went wrong! Sorry about that.
```

**To Reproduce**
Go to https://bookwyrm.social/user/jonathan.brodsky
It appears to apply to all urls within user/jonathan.brodsky - see https://bookwyrm.social/user/jonathan.brodsky/generatednote/1994

**Expected behavior**
A user profile page loads.

**Desktop (please complete the following information):**
 - OS: windows
 - Browser Chrome
 - Version 87.0.4280.66


Discussion:
I believe the simple fix is just to change
`username_regex = r'(?P<username>[\w\-_]+@[\w\-\_\.]+)'`
to `username_regex = r'(?P<username>[\w\.\-_]+@[\w\-\_\.]+)'` in urls.py

- but probably need to validate the username on signup too.



Resolving patch:
diff --git a/bookwyrm/urls.py b/bookwyrm/urls.py
--- a/bookwyrm/urls.py
+++ b/bookwyrm/urls.py
@@ -6,8 +6,8 @@
 from bookwyrm import incoming, outgoing, views, settings, wellknown
 from bookwyrm import view_actions as actions
 
-username_regex = r'(?P<username>[\w\-_]+@[\w\-\_\.]+)'
-localname_regex = r'(?P<username>[\w\-_]+)'
+username_regex = r'(?P<username>[\w\-_\.]+@[\w\-\_\.]+)'
+localname_regex = r'(?P<username>[\w\-_\.]+)'
 user_path = r'^user/%s' % username_regex
 local_user_path = r'^user/%s' % localname_regex
 
@@ -61,8 +61,8 @@
     # should return a ui view or activitypub json blob as requested
     # users
     re_path(r'%s/?$' % user_path, views.user_page),
-    re_path(r'%s/?$' % local_user_path, views.user_page),
     re_path(r'%s\.json$' % local_user_path, views.user_page),
+    re_path(r'%s/?$' % local_user_path, views.user_page),
     re_path(r'%s/shelves/?$' % local_user_path, views.user_shelves_page),
     re_path(r'%s/followers(.json)?/?$' % local_user_path, views.followers_page),
     re_path(r'%s/following(.json)?/?$' % local_user_path, views.following_page),


Test patch:
Repository: bookwyrm-social/bookwyrm

Issue:
A status and a boost of that status shouldn't both show up on a timeline
Instead, the query should only show the most recent version of the status


Discussion:

Resolving patch:
diff --git a/bookwyrm/views.py b/bookwyrm/views.py
--- a/bookwyrm/views.py
+++ b/bookwyrm/views.py
@@ -131,7 +131,7 @@ def get_activity_feed(user, filter_level, model=models.Status):
         activities = model.objects
 
     activities = activities.filter(
-        deleted=False
+        deleted=False,
     ).order_by(
         '-published_date'
     )
@@ -160,6 +160,11 @@ def get_activity_feed(user, filter_level, model=models.Status):
             Q(user__in=following, privacy='followers') | Q(privacy='public')
         )
 
+    try:
+        activities = activities.filter(~Q(boosters__in=activities))
+    except ValueError:
+        pass
+
     return activities
 
 


Test patch:
Repository: bookwyrm-social/bookwyrm

Issue:
Rate stars don't work
You should be able to click to give a star rating to a book on the book page, it doesn't do anything.


Discussion:

Resolving patch:
diff --git a/bookwyrm/activitypub/note.py b/bookwyrm/activitypub/note.py
--- a/bookwyrm/activitypub/note.py
+++ b/bookwyrm/activitypub/note.py
@@ -53,7 +53,7 @@ class Comment(Note):
 @dataclass(init=False)
 class Review(Comment):
     ''' a full book review '''
-    name: str
+    name: str = None
     rating: int = None
     type: str = 'Review'
 


Test patch:
Repository: bookwyrm-social/bookwyrm

Issue:
When Adding a Review, A Server Error is Shown (But the Review is Posted)
**Describe the bug**
When posting a review, Bookwyrm takes me to a page that says:
```
Server Error

Something went wrong! Sorry about that.
```

**To Reproduce**
Steps to reproduce the behavior:
1. Write a review
2. Click on 'Post Review'
3. See error
4. (Bonus) Check your feed and see the review posted

**Expected behavior**
The review is posted and no error is shown


**Desktop (please complete the following information):**
 - OS: macOS Big Sur
 - Browser Firefox
 - Version 85.0b4


Discussion:

Resolving patch:
diff --git a/bookwyrm/outgoing.py b/bookwyrm/outgoing.py
--- a/bookwyrm/outgoing.py
+++ b/bookwyrm/outgoing.py
@@ -41,6 +41,9 @@ def handle_remote_webfinger(query):
     user = None
 
     # usernames could be @user@domain or user@domain
+    if not query:
+        return None
+
     if query[0] == '@':
         query = query[1:]
 
@@ -218,7 +221,7 @@ def handle_status(user, form):
 
     # inspect the text for user tags
     matches = []
-    for match in re.finditer(regex.username, status.content):
+    for match in re.finditer(regex.strict_username, status.content):
         username = match.group().strip().split('@')[1:]
         if len(username) == 1:
             # this looks like a local user (@user), fill in the domain
diff --git a/bookwyrm/utils/regex.py b/bookwyrm/utils/regex.py
--- a/bookwyrm/utils/regex.py
+++ b/bookwyrm/utils/regex.py
@@ -2,5 +2,7 @@
 
 domain = r'[a-z-A-Z0-9_\-]+\.[a-z]+'
 localname = r'@?[a-zA-Z_\-\.0-9]+'
+strict_localname = r'@[a-zA-Z_\-\.0-9]+'
 username = r'%s(@%s)?' % (localname, domain)
+strict_username = r'%s(@%s)?' % (strict_localname, domain)
 full_username = r'%s@%s' % (localname, domain)
diff --git a/bookwyrm/view_actions.py b/bookwyrm/view_actions.py
--- a/bookwyrm/view_actions.py
+++ b/bookwyrm/view_actions.py
@@ -593,14 +593,14 @@ def tag(request):
 def untag(request):
     ''' untag a book '''
     name = request.POST.get('name')
-    tag = get_object_or_404(models.Tag, name=name)
+    tag_obj = get_object_or_404(models.Tag, name=name)
     book_id = request.POST.get('book')
     book = get_object_or_404(models.Edition, id=book_id)
 
-    tag = get_object_or_404(
-        models.UserTag, tag=tag, book=book, user=request.user)
-    tag_activity = tag.to_remove_activity(request.user)
-    tag.delete()
+    user_tag = get_object_or_404(
+        models.UserTag, tag=tag_obj, book=book, user=request.user)
+    tag_activity = user_tag.to_remove_activity(request.user)
+    user_tag.delete()
 
     broadcast(request.user, tag_activity)
     return redirect('/book/%s' % book_id)


Test patch:
Repository: bookwyrm-social/bookwyrm

Issue:
include logo, favicon in site settings



Discussion:

Resolving patch:
diff --git a/bookwyrm/migrations/0031_auto_20210104_2040.py b/bookwyrm/migrations/0031_auto_20210104_2040.py
new file mode 100644
--- /dev/null
+++ b/bookwyrm/migrations/0031_auto_20210104_2040.py
@@ -0,0 +1,28 @@
+# Generated by Django 3.0.7 on 2021-01-04 20:40
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('bookwyrm', '0030_auto_20201224_1939'),
+    ]
+
+    operations = [
+        migrations.AddField(
+            model_name='sitesettings',
+            name='favicon',
+            field=models.ImageField(blank=True, null=True, upload_to='logos/'),
+        ),
+        migrations.AddField(
+            model_name='sitesettings',
+            name='logo',
+            field=models.ImageField(blank=True, null=True, upload_to='logos/'),
+        ),
+        migrations.AddField(
+            model_name='sitesettings',
+            name='logo_small',
+            field=models.ImageField(blank=True, null=True, upload_to='logos/'),
+        ),
+    ]
diff --git a/bookwyrm/models/site.py b/bookwyrm/models/site.py
--- a/bookwyrm/models/site.py
+++ b/bookwyrm/models/site.py
@@ -17,6 +17,15 @@ class SiteSettings(models.Model):
     code_of_conduct = models.TextField(
         default="Add a code of conduct here.")
     allow_registration = models.BooleanField(default=True)
+    logo = models.ImageField(
+        upload_to='logos/', null=True, blank=True
+    )
+    logo_small = models.ImageField(
+        upload_to='logos/', null=True, blank=True
+    )
+    favicon = models.ImageField(
+        upload_to='logos/', null=True, blank=True
+    )
     support_link = models.CharField(max_length=255, null=True, blank=True)
     support_title = models.CharField(max_length=100, null=True, blank=True)
     admin_email = models.EmailField(max_length=255, null=True, blank=True)


Test patch:
Repository: bookwyrm-social/bookwyrm

Issue:
Seeing my own profile feed on other people's profiles
**Describe the bug**
When I go to someone else's profile, the feed that is rendered under "User Activity" is my own.

**To Reproduce**
Steps to reproduce the behavior:
1. Go to anyone else's profile page and observe the result
![image](https://user-images.githubusercontent.com/266454/103687958-f95ea800-4f45-11eb-9f7c-03aae7498997.png)

**Expected behavior**
I see the other user's public posts rather than my own.


Discussion:
wow yep you _sure_ are. I bet this is a really easy fix at least

Resolving patch:
diff --git a/bookwyrm/views.py b/bookwyrm/views.py
--- a/bookwyrm/views.py
+++ b/bookwyrm/views.py
@@ -467,9 +467,9 @@ def user_page(request, username):
 
     # user's posts
     activities = get_activity_feed(
-        user,
+        request.user,
         ['public', 'unlisted', 'followers'],
-        queryset=models.Status.objects.filter(user=request.user)
+        queryset=models.Status.objects.filter(user=user)
     )
     paginated = Paginator(activities, PAGE_LENGTH)
     activity_page = paginated.page(page)


Test patch:
Repository: bookwyrm-social/bookwyrm

Issue:
Invalid invite codes should produce a nice error page, not just a 403
right now, an invalid invite code just throws a 403. it should instead be a template, with nice things on it, and words


Discussion:

Resolving patch:
diff --git a/bookwyrm/view_actions.py b/bookwyrm/view_actions.py
--- a/bookwyrm/view_actions.py
+++ b/bookwyrm/view_actions.py
@@ -81,8 +81,12 @@ def register(request):
     if errors:
         data = {
             'login_form': forms.LoginForm(),
-            'register_form': form
+            'register_form': form,
+            'invite': invite,
+            'valid': invite.valid() if invite else True,
         }
+        if invite:
+            return TemplateResponse(request, 'invite.html', data)
         return TemplateResponse(request, 'login.html', data)
 
     username = '%s@%s' % (localname, DOMAIN)
diff --git a/bookwyrm/views.py b/bookwyrm/views.py
--- a/bookwyrm/views.py
+++ b/bookwyrm/views.py
@@ -377,17 +377,13 @@ def invite_page(request, code):
     ''' endpoint for sending invites '''
     if request.user.is_authenticated:
         return redirect('/')
-    try:
-        invite = models.SiteInvite.objects.get(code=code)
-        if not invite.valid():
-            raise PermissionDenied
-    except models.SiteInvite.DoesNotExist:
-        raise PermissionDenied
+    invite = get_object_or_404(models.SiteInvite, code=code)
 
     data = {
         'title': 'Join',
         'register_form': forms.RegisterForm(),
         'invite': invite,
+        'valid': invite.valid() if invite else True,
     }
     return TemplateResponse(request, 'invite.html', data)
 


Test patch:
Repository: bookwyrm-social/bookwyrm

Issue:
Shelf page json view has a server error
This is a quick fix, needs a unittest.


Discussion:

Resolving patch:
diff --git a/bookwyrm/models/shelf.py b/bookwyrm/models/shelf.py
--- a/bookwyrm/models/shelf.py
+++ b/bookwyrm/models/shelf.py
@@ -39,7 +39,7 @@ def save(self, *args, **kwargs):
     @property
     def collection_queryset(self):
         ''' list of books for this shelf, overrides OrderedCollectionMixin  '''
-        return self.books
+        return self.books.all()
 
     def get_remote_id(self):
         ''' shelf identifier instead of id '''


Test patch:
diff --git a/bookwyrm/tests/test_views.py b/bookwyrm/tests/test_views.py
--- a/bookwyrm/tests/test_views.py
+++ b/bookwyrm/tests/test_views.py
@@ -570,6 +570,16 @@ def test_shelf_page(self):
         self.assertEqual(result.status_code, 200)
 
 
+        request = self.factory.get('/?page=1')
+        request.user = self.local_user
+        with patch('bookwyrm.views.is_api_request') as is_api:
+            is_api.return_value = True
+            result = views.shelf_page(
+                request, self.local_user.username, shelf.identifier)
+        self.assertIsInstance(result, ActivitypubResponse)
+        self.assertEqual(result.status_code, 200)
+
+
     def test_is_bookwyrm_request(self):
         ''' checks if a request came from a bookwyrm instance '''
         request = self.factory.get('', {'q': 'Test Book'})
Repository: bookwyrm-social/bookwyrm

Issue:
urls in parens don't parse as links



Discussion:

Resolving patch:
diff --git a/bookwyrm/outgoing.py b/bookwyrm/outgoing.py
--- a/bookwyrm/outgoing.py
+++ b/bookwyrm/outgoing.py
@@ -296,7 +296,7 @@ def find_mentions(content):
 def format_links(content):
     ''' detect and format links '''
     return re.sub(
-        r'([^(href=")]|^)(https?:\/\/(%s([\w\.\-_\/+&\?=:;,])*))' % \
+        r'([^(href=")]|^|\()(https?:\/\/(%s([\w\.\-_\/+&\?=:;,])*))' % \
                 regex.domain,
         r'\g<1><a href="\g<2>">\g<3></a>',
         content)


Test patch:
diff --git a/bookwyrm/tests/test_outgoing.py b/bookwyrm/tests/test_outgoing.py
--- a/bookwyrm/tests/test_outgoing.py
+++ b/bookwyrm/tests/test_outgoing.py
@@ -497,6 +497,9 @@ def test_format_links(self):
         self.assertEqual(
             outgoing.format_links(url),
             '<a href="%s">www.fish.com/</a>' % url)
+        self.assertEqual(
+            outgoing.format_links('(%s)' % url),
+            '(<a href="%s">www.fish.com/</a>)' % url)
         url = 'https://archive.org/details/dli.granth.72113/page/n25/mode/2up'
         self.assertEqual(
             outgoing.format_links(url),
Repository: bookwyrm-social/bookwyrm

Issue:
shelve actions are always posted and always public



Discussion:

Resolving patch:
diff --git a/bookwyrm/view_actions.py b/bookwyrm/view_actions.py
--- a/bookwyrm/view_actions.py
+++ b/bookwyrm/view_actions.py
@@ -402,7 +402,7 @@ def shelve(request):
             request.user,
             desired_shelf,
             book,
-            privacy='public'
+            privacy=desired_shelf.privacy
         )
 
     return redirect('/')


Test patch:
Repository: bookwyrm-social/bookwyrm

Issue:
About page requires login
**Describe the bug**
Accessing the "About this server" link (https://bookwyrm.social/about) redirects to login

**To Reproduce**
Steps to reproduce the behavior:
1. Go to https://bookwyrm.social/about
2. redirected to login instead of seeing an about page (the URL is login/?next=/about)

**Expected behavior**
Access to information about this site / server

**Desktop (please complete the following information):**
 - OS: linux
 - Browser firefox
 - Version 85 (developer edition)



Discussion:

Resolving patch:
diff --git a/bookwyrm/views/landing.py b/bookwyrm/views/landing.py
--- a/bookwyrm/views/landing.py
+++ b/bookwyrm/views/landing.py
@@ -13,7 +13,6 @@
 
 
 # pylint: disable= no-self-use
-@method_decorator(login_required, name='dispatch')
 class About(View):
     ''' create invites '''
     def get(self, request):


Test patch:
Repository: bookwyrm-social/bookwyrm

Issue:
Feature request - block quote formatting in reviews
I published [a review](https://bookwyrm.social/user/darius/review/14497) just now with a markdown-style block quote in it. The second-to-last paragraph is formatted, at least when I wrote it in the dialog box, like this:

```
> "I was expecting to go to prison for the rest of my life," Ellsberg wryly said later, "and Ithiel wanted to know whether I understood that I'd never get another dollar from the federal government."
```

But it renders as regular text. I'm guessing a lot of reviewers will want to excerpt their books, so block quotes seem like a good thing to include!

I would expect it to render more like it does here on Github:

> "I was expecting to go to prison for the rest of my life," Ellsberg wryly said later, "and Ithiel wanted to know whether I understood that I'd never get another dollar from the federal government."


Discussion:

Resolving patch:
diff --git a/bookwyrm/sanitize_html.py b/bookwyrm/sanitize_html.py
--- a/bookwyrm/sanitize_html.py
+++ b/bookwyrm/sanitize_html.py
@@ -7,7 +7,7 @@ class InputHtmlParser(HTMLParser):#pylint: disable=abstract-method
     def __init__(self):
         HTMLParser.__init__(self)
         self.allowed_tags = [
-            'p', 'br',
+            'p', 'blockquote', 'br',
             'b', 'i', 'strong', 'em', 'pre',
             'a', 'span', 'ul', 'ol', 'li'
         ]


Test patch:
Repository: bookwyrm-social/bookwyrm

Issue:
Wrong baseurl in remote @-mention notification
When someone on a remote server @-mentions me on Bookwyrm, the "status" link in notifications has the wrong baseUrl.

Example:

![image](https://user-images.githubusercontent.com/266454/106845345-999c0f80-665f-11eb-8825-7415fb412497.png)

The url that the username `Flancian` links to is `https://bookwyrm.social/user/flancian@social.coop`. The url that `status` links to is `https://social.coop/users/flancian/status/14794`, which takes me to a 404 on the `social.coop` server. The correct url that status should be linking to is `https://bookwyrm.social/user/flancian@social.coop/status/14794`.

I've confirmed this happens for @-mentions from any remote server.


Discussion:

Resolving patch:
diff --git a/bookwyrm/models/base_model.py b/bookwyrm/models/base_model.py
--- a/bookwyrm/models/base_model.py
+++ b/bookwyrm/models/base_model.py
@@ -27,7 +27,7 @@ def get_remote_id(self):
         ''' generate a url that resolves to the local object '''
         base_path = 'https://%s' % DOMAIN
         if hasattr(self, 'user'):
-            base_path = self.user.remote_id
+            base_path = '%s%s' % (base_path, self.user.local_path)
         model_name = type(self).__name__.lower()
         return '%s/%s/%d' % (base_path, model_name, self.id)
 


Test patch:
Repository: bookwyrm-social/bookwyrm

Issue:
link formatting not working properly
I made a markdown link, but the "<a href" part was trimmed and garbled html remained


Discussion:

Resolving patch:
diff --git a/bookwyrm/views/status.py b/bookwyrm/views/status.py
--- a/bookwyrm/views/status.py
+++ b/bookwyrm/views/status.py
@@ -48,7 +48,6 @@ def post(self, request, status_type):
                 r'<a href="%s">%s</a>\g<1>' % \
                     (mention_user.remote_id, mention_text),
                 content)
-
         # add reply parent to mentions and notify
         if status.reply_parent:
             status.mention_users.add(status.reply_parent.user)
@@ -126,8 +125,8 @@ def format_links(content):
 
 def to_markdown(content):
     ''' catch links and convert to markdown '''
-    content = format_links(content)
     content = markdown(content)
+    content = format_links(content)
     # sanitize resulting html
     sanitizer = InputHtmlParser()
     sanitizer.feed(content)


Test patch:
diff --git a/bookwyrm/tests/views/test_status.py b/bookwyrm/tests/views/test_status.py
--- a/bookwyrm/tests/views/test_status.py
+++ b/bookwyrm/tests/views/test_status.py
@@ -217,6 +217,16 @@ def test_to_markdown(self):
                     'is rad</p>')
 
 
+    def test_to_markdown_link(self):
+        ''' this is mostly handled in other places, but nonetheless '''
+        text = '[hi](http://fish.com) is <marquee>rad</marquee>'
+        result = views.status.to_markdown(text)
+        self.assertEqual(
+            result,
+            '<p><a href="http://fish.com">hi</a> ' \
+                    'is rad</p>')
+
+
     def test_handle_delete_status(self):
         ''' marks a status as deleted '''
         view = views.DeleteStatus.as_view()
Repository: bookwyrm-social/bookwyrm

Issue:
Expand book data task is re-setting default editions
it should not.


Discussion:

Resolving patch:
diff --git a/bookwyrm/connectors/abstract_connector.py b/bookwyrm/connectors/abstract_connector.py
--- a/bookwyrm/connectors/abstract_connector.py
+++ b/bookwyrm/connectors/abstract_connector.py
@@ -145,8 +145,9 @@ def create_edition_from_data(self, work, edition_data):
         edition.connector = self.connector
         edition.save()
 
-        work.default_edition = edition
-        work.save()
+        if not work.default_edition:
+            work.default_edition = edition
+            work.save()
 
         for author in self.get_authors_from_data(edition_data):
             edition.authors.add(author)


Test patch:
Repository: bookwyrm-social/bookwyrm

Issue:
Reading goal status doesn't set plurals correctly
When someone is only planning to read 1 book, the status should say "1 book" not "1 books"


Discussion:
Thanks for accommodating us book-a-year types! 

Resolving patch:
diff --git a/bookwyrm/views/goal.py b/bookwyrm/views/goal.py
--- a/bookwyrm/views/goal.py
+++ b/bookwyrm/views/goal.py
@@ -2,6 +2,7 @@
 from django.contrib.auth.decorators import login_required
 from django.http import HttpResponseNotFound
 from django.shortcuts import redirect
+from django.template.loader import get_template
 from django.template.response import TemplateResponse
 from django.utils.decorators import method_decorator
 from django.views import View
@@ -62,9 +63,10 @@ def post(self, request, username, year):
 
         if request.POST.get('post-status'):
             # create status, if appropraite
+            template = get_template('snippets/generated_status/goal.html')
             create_generated_note(
                 request.user,
-                'set a goal to read %d books in %d' % (goal.goal, goal.year),
+                template.render({'goal': goal, 'user': request.user}).strip(),
                 privacy=goal.privacy
             )
 


Test patch:
Repository: bookwyrm-social/bookwyrm

Issue:
Still get notifications for follows from blocked user
**Describe the bug**
I blocked https://bookwyrm.social/user/followbot@search.fedi.app, but I'm still getting follow notifications from them. I also can still see them in my followers list

**To Reproduce**
1. Block user that currently follows you
2. View own follow list, see that they still follow you
3. Have that user (while blocked) refollow you
4. See notification for that follow

**Expected behavior**
I expect that a block would force a user to unfollow me. Even if this didn't happen, though, I'd like to no longer receive notifications from activity of users that I've blocked, including follow notifications


Discussion:
#594 and #609 should go a long way towards fixing this, but it needs a bit more looking-at before it's closeable

Resolving patch:
diff --git a/bookwyrm/models/relationship.py b/bookwyrm/models/relationship.py
--- a/bookwyrm/models/relationship.py
+++ b/bookwyrm/models/relationship.py
@@ -82,11 +82,16 @@ def save(self, *args, broadcast=True, **kwargs):
         try:
             UserFollows.objects.get(
                 user_subject=self.user_subject,
-                user_object=self.user_object
+                user_object=self.user_object,
             )
+            # blocking in either direction is a no-go
             UserBlocks.objects.get(
                 user_subject=self.user_subject,
-                user_object=self.user_object
+                user_object=self.user_object,
+            )
+            UserBlocks.objects.get(
+                user_subject=self.user_object,
+                user_object=self.user_subject,
             )
             return None
         except (UserFollows.DoesNotExist, UserBlocks.DoesNotExist):


Test patch: