Updates code for linter

This commit is contained in:
Mouse Reeve 2021-06-18 14:12:56 -07:00
parent 20f74ba02b
commit 4479864008
21 changed files with 71 additions and 61 deletions

View file

@ -20,5 +20,5 @@ jobs:
pip install pylint
- name: Analysing the code with pylint
run: |
pylint bookwyrm/ --ignore=migrations --disable=E1101,E1136,R0903,R0901,W0707,W0511
pylint bookwyrm/ --ignore=migrations,__init__ --disable=E1101,E1135,E1136,R0903,R0901,R0902,W0707,W0511,W0406

View file

@ -37,6 +37,7 @@ class Mention(Link):
@dataclass
# pylint: disable=invalid-name
class Signature:
"""public key block"""
@ -56,11 +57,11 @@ def naive_parse(activity_objects, activity_json, serializer=None):
activity_type = activity_json.get("type")
try:
serializer = activity_objects[activity_type]
except KeyError as e:
except KeyError as err:
# we know this exists and that we can't handle it
if activity_type in ["Question"]:
return None
raise ActivitySerializerError(e)
raise ActivitySerializerError(err)
return serializer(activity_objects=activity_objects, **activity_json)

View file

@ -6,6 +6,7 @@ from .base_activity import ActivityObject
from .image import Document
# pylint: disable=invalid-name
@dataclass(init=False)
class BookData(ActivityObject):
"""shared fields for all book data and authors"""
@ -18,6 +19,7 @@ class BookData(ActivityObject):
lastEditedBy: str = None
# pylint: disable=invalid-name
@dataclass(init=False)
class Book(BookData):
"""serializes an edition or work, abstract"""
@ -40,6 +42,7 @@ class Book(BookData):
type: str = "Book"
# pylint: disable=invalid-name
@dataclass(init=False)
class Edition(Book):
"""Edition instance of a book object"""
@ -57,6 +60,7 @@ class Edition(Book):
type: str = "Edition"
# pylint: disable=invalid-name
@dataclass(init=False)
class Work(Book):
"""work instance of a book object"""
@ -66,6 +70,7 @@ class Work(Book):
type: str = "Work"
# pylint: disable=invalid-name
@dataclass(init=False)
class Author(BookData):
"""author of a book"""

View file

@ -22,6 +22,7 @@ class Verb(ActivityObject):
self.object.to_model()
# pylint: disable=invalid-name
@dataclass(init=False)
class Create(Verb):
"""Create activity"""
@ -32,6 +33,7 @@ class Create(Verb):
type: str = "Create"
# pylint: disable=invalid-name
@dataclass(init=False)
class Delete(Verb):
"""Create activity"""
@ -57,6 +59,7 @@ class Delete(Verb):
# if we can't find it, we don't need to delete it because we don't have it
# pylint: disable=invalid-name
@dataclass(init=False)
class Update(Verb):
"""Update activity"""
@ -192,6 +195,7 @@ class Like(Verb):
self.to_model()
# pylint: disable=invalid-name
@dataclass(init=False)
class Announce(Verb):
"""boosting a status"""

View file

@ -127,8 +127,8 @@ class AbstractConnector(AbstractMinimalConnector):
edition_data = data
try:
work_data = self.get_work_from_edition_data(data)
except (KeyError, ConnectorException) as e:
logger.exception(e)
except (KeyError, ConnectorException) as err:
logger.exception(err)
work_data = data
if not work_data or not edition_data:
@ -237,16 +237,16 @@ def get_data(url, params=None, timeout=10):
},
timeout=timeout,
)
except (RequestError, SSLError, ConnectionError) as e:
logger.exception(e)
except (RequestError, SSLError, ConnectionError) as err:
logger.exception(err)
raise ConnectorException()
if not resp.ok:
raise ConnectorException()
try:
data = resp.json()
except ValueError as e:
logger.exception(e)
except ValueError as err:
logger.exception(err)
raise ConnectorException()
return data
@ -262,8 +262,8 @@ def get_image(url, timeout=10):
},
timeout=timeout,
)
except (RequestError, SSLError) as e:
logger.exception(e)
except (RequestError, SSLError) as err:
logger.exception(err)
return None
if not resp.ok:
return None

View file

@ -74,7 +74,7 @@ class Connector(AbstractConnector):
**{k: data.get(k) for k in ["uri", "image", "labels", "sitelinks"]},
}
def search(self, query, min_confidence=None):
def search(self, query, min_confidence=None): # pylint: disable=arguments-differ
"""overrides default search function with confidence ranking"""
results = super().search(query)
if min_confidence:

View file

@ -22,6 +22,7 @@ class CustomForm(ModelForm):
css_classes["number"] = "input"
css_classes["checkbox"] = "checkbox"
css_classes["textarea"] = "textarea"
# pylint: disable=super-with-arguments
super(CustomForm, self).__init__(*args, **kwargs)
for visible in self.visible_fields():
if hasattr(visible.field.widget, "input_type"):

View file

@ -93,7 +93,8 @@ class ListItem(CollectionItemMixin, BookWyrmModel):
)
class Meta:
# A book may only be placed into a list once, and each order in the list may be used only
# once
"""A book may only be placed into a list once,
and each order in the list may be used only once"""
unique_together = (("book", "book_list"), ("order", "book_list"))
ordering = ("-created_date",)

View file

@ -232,7 +232,7 @@ class User(OrderedCollectionPageMixin, AbstractUser):
def save(self, *args, **kwargs):
"""populate fields for new local users"""
created = not bool(self.id)
if not self.local and not re.match(regex.full_username, self.username):
if not self.local and not re.match(regex.FULL_USERNAME, self.username):
# generate a username that uses the domain (webfinger format)
actor_parts = urlparse(self.remote_id)
self.username = "%s@%s" % (self.username, actor_parts.netloc)

View file

@ -73,6 +73,7 @@ class Signature:
self.headers = headers
self.signature = signature
# pylint: disable=invalid-name
@classmethod
def parse(cls, request):
"""extract and parse a signature from an http request"""

View file

@ -1,9 +1,12 @@
""" Makes the app aware of the users timezone """
import pytz
from django.utils import timezone
class TimezoneMiddleware:
"""Determine the timezone based on the request"""
def __init__(self, get_response):
self.get_response = get_response

View file

@ -7,8 +7,8 @@ from django.views.generic.base import TemplateView
from bookwyrm import settings, views
from bookwyrm.utils import regex
user_path = r"^user/(?P<username>%s)" % regex.username
local_user_path = r"^user/(?P<username>%s)" % regex.localname
USER_PATH = r"^user/(?P<username>%s)" % regex.username
LOCAL_USER_PATH = r"^user/(?P<username>%s)" % regex.localname
status_types = [
"status",
@ -19,9 +19,9 @@ status_types = [
"boost",
"generatednote",
]
status_path = r"%s/(%s)/(?P<status_id>\d+)" % (user_path, "|".join(status_types))
STATUS_PATH = r"%s/(%s)/(?P<status_id>\d+)" % (USER_PATH, "|".join(status_types))
book_path = r"^book/(?P<book_id>\d+)"
BOOK_PATH = r"^book/(?P<book_id>\d+)"
urlpatterns = [
path("admin/", admin.site.urls),
@ -31,8 +31,8 @@ urlpatterns = [
),
# federation endpoints
re_path(r"^inbox/?$", views.Inbox.as_view()),
re_path(r"%s/inbox/?$" % local_user_path, views.Inbox.as_view()),
re_path(r"%s/outbox/?$" % local_user_path, views.Outbox.as_view()),
re_path(r"%s/inbox/?$" % LOCAL_USER_PATH, views.Inbox.as_view()),
re_path(r"%s/outbox/?$" % LOCAL_USER_PATH, views.Outbox.as_view()),
re_path(r"^\.well-known/webfinger/?$", views.webfinger),
re_path(r"^\.well-known/nodeinfo/?$", views.nodeinfo_pointer),
re_path(r"^\.well-known/host-meta/?$", views.host_meta),
@ -192,21 +192,21 @@ urlpatterns = [
re_path(r"^import/?$", views.Import.as_view(), name="import"),
re_path(r"^import/(\d+)/?$", views.ImportStatus.as_view(), name="import-status"),
# users
re_path(r"%s/?$" % user_path, views.User.as_view(), name="user-feed"),
re_path(r"%s\.json$" % user_path, views.User.as_view()),
re_path(r"%s/rss" % user_path, views.rss_feed.RssFeed(), name="user-rss"),
re_path(r"%s/?$" % USER_PATH, views.User.as_view(), name="user-feed"),
re_path(r"%s\.json$" % USER_PATH, views.User.as_view()),
re_path(r"%s/rss" % USER_PATH, views.rss_feed.RssFeed(), name="user-rss"),
re_path(
r"%s/followers(.json)?/?$" % user_path,
r"%s/followers(.json)?/?$" % USER_PATH,
views.Followers.as_view(),
name="user-followers",
),
re_path(
r"%s/following(.json)?/?$" % user_path,
r"%s/following(.json)?/?$" % USER_PATH,
views.Following.as_view(),
name="user-following",
),
# lists
re_path(r"%s/lists/?$" % user_path, views.UserLists.as_view(), name="user-lists"),
re_path(r"%s/lists/?$" % USER_PATH, views.UserLists.as_view(), name="user-lists"),
re_path(r"^list/?$", views.Lists.as_view(), name="lists"),
re_path(r"^list/(?P<list_id>\d+)(.json)?/?$", views.List.as_view(), name="list"),
re_path(r"^list/add-book/?$", views.list.add_book, name="list-add-book"),
@ -224,14 +224,14 @@ urlpatterns = [
r"^list/(?P<list_id>\d+)/curate/?$", views.Curate.as_view(), name="list-curate"
),
# User books
re_path(r"%s/books/?$" % user_path, views.Shelf.as_view(), name="user-shelves"),
re_path(r"%s/books/?$" % USER_PATH, views.Shelf.as_view(), name="user-shelves"),
re_path(
r"^%s/(helf|books)/(?P<shelf_identifier>[\w-]+)(.json)?/?$" % user_path,
r"^%s/(helf|books)/(?P<shelf_identifier>[\w-]+)(.json)?/?$" % USER_PATH,
views.Shelf.as_view(),
name="shelf",
),
re_path(
r"^%s/(books|shelf)/(?P<shelf_identifier>[\w-]+)(.json)?/?$" % local_user_path,
r"^%s/(books|shelf)/(?P<shelf_identifier>[\w-]+)(.json)?/?$" % LOCAL_USER_PATH,
views.Shelf.as_view(),
name="shelf",
),
@ -241,7 +241,7 @@ urlpatterns = [
re_path(r"^unshelve/?$", views.unshelve),
# goals
re_path(
r"%s/goal/(?P<year>\d{4})/?$" % user_path,
r"%s/goal/(?P<year>\d{4})/?$" % USER_PATH,
views.Goal.as_view(),
name="user-goal",
),
@ -258,10 +258,10 @@ urlpatterns = [
re_path(r"^block/(?P<user_id>\d+)/?$", views.Block.as_view()),
re_path(r"^unblock/(?P<user_id>\d+)/?$", views.unblock),
# statuses
re_path(r"%s(.json)?/?$" % status_path, views.Status.as_view(), name="status"),
re_path(r"%s/activity/?$" % status_path, views.Status.as_view(), name="status"),
re_path(r"%s(.json)?/?$" % STATUS_PATH, views.Status.as_view(), name="status"),
re_path(r"%s/activity/?$" % STATUS_PATH, views.Status.as_view(), name="status"),
re_path(
r"%s/replies(.json)?/?$" % status_path, views.Replies.as_view(), name="replies"
r"%s/replies(.json)?/?$" % STATUS_PATH, views.Replies.as_view(), name="replies"
),
re_path(
r"^post/?$",
@ -289,17 +289,17 @@ urlpatterns = [
re_path(r"^boost/(?P<status_id>\d+)/?$", views.Boost.as_view()),
re_path(r"^unboost/(?P<status_id>\d+)/?$", views.Unboost.as_view()),
# books
re_path(r"%s(.json)?/?$" % book_path, views.Book.as_view(), name="book"),
re_path(r"%s(.json)?/?$" % BOOK_PATH, views.Book.as_view(), name="book"),
re_path(
r"%s/(?P<user_statuses>review|comment|quote)/?$" % book_path,
r"%s/(?P<user_statuses>review|comment|quote)/?$" % BOOK_PATH,
views.Book.as_view(),
name="book-user-statuses",
),
re_path(r"%s/edit/?$" % book_path, views.EditBook.as_view()),
re_path(r"%s/confirm/?$" % book_path, views.ConfirmEditBook.as_view()),
re_path(r"%s/edit/?$" % BOOK_PATH, views.EditBook.as_view()),
re_path(r"%s/confirm/?$" % BOOK_PATH, views.ConfirmEditBook.as_view()),
re_path(r"^create-book/?$", views.EditBook.as_view(), name="create-book"),
re_path(r"^create-book/confirm?$", views.ConfirmEditBook.as_view()),
re_path(r"%s/editions(.json)?/?$" % book_path, views.Editions.as_view()),
re_path(r"%s/editions(.json)?/?$" % BOOK_PATH, views.Editions.as_view()),
re_path(
r"^upload-cover/(?P<book_id>\d+)/?$", views.upload_cover, name="upload-cover"
),

View file

@ -1,10 +1,10 @@
""" defining regexes for regularly used concepts """
domain = r"[\w_\-\.]+\.[a-z]{2,}"
localname = r"@?[a-zA-Z_\-\.0-9]+"
strict_localname = r"@[a-zA-Z_\-\.0-9]+"
username = r"%s(@%s)?" % (localname, domain)
strict_username = r"\B%s(@%s)?\b" % (strict_localname, domain)
full_username = r"%s@%s\b" % (localname, domain)
DOMAIN = r"[\w_\-\.]+\.[a-z]{2,}"
LOCALNAME = r"@?[a-zA-Z_\-\.0-9]+"
STRICT_LOCALNAME = r"@[a-zA-Z_\-\.0-9]+"
USERNAME = r"%s(@%s)?" % (LOCALNAME, DOMAIN)
STRICT_USERNAME = r"\B%s(@%s)?\b" % (STRICT_LOCALNAME, DOMAIN)
FULL_USERNAME = r"%s@%s\b" % (LOCALNAME, DOMAIN)
# should match (BookWyrm/1.0.0; or (BookWyrm/99.1.2;
bookwyrm_user_agent = r"\(BookWyrm/[0-9]+\.[0-9]+\.[0-9]+;"
BOOKWYRM_USER_AGENT = r"\(BookWyrm/[0-9]+\.[0-9]+\.[0-9]+;"

View file

@ -38,7 +38,7 @@ def is_api_request(request):
def is_bookwyrm_request(request):
"""check if the request is coming from another bookwyrm instance"""
user_agent = request.headers.get("User-Agent")
if user_agent is None or re.search(regex.bookwyrm_user_agent, user_agent) is None:
if user_agent is None or re.search(regex.BOOKWYRM_USER_AGENT, user_agent) is None:
return False
return True

View file

@ -21,6 +21,7 @@ from bookwyrm.utils import regex
class Inbox(View):
"""requests sent by outside servers"""
# pylint: disable=too-many-return-statements
def post(self, request, username=None):
"""only works as POST request"""
# first check if this server is on our shitlist
@ -70,7 +71,7 @@ def is_blocked_user_agent(request):
user_agent = request.headers.get("User-Agent")
if not user_agent:
return False
url = re.search(r"https?://{:s}/?".format(regex.domain), user_agent)
url = re.search(r"https?://{:s}/?".format(regex.DOMAIN), user_agent)
if not url:
return False
url = url.group()

View file

@ -1,13 +1,8 @@
""" isbn search view """
from django.http import HttpResponseNotFound
from django.http import JsonResponse
from django.shortcuts import get_object_or_404, redirect
from django.template.response import TemplateResponse
from django.utils.decorators import method_decorator
from django.views import View
from django.views.decorators.http import require_POST
from bookwyrm import forms, models
from bookwyrm.connectors import connector_manager
from .helpers import is_api_request
@ -23,7 +18,6 @@ class Isbn(View):
return JsonResponse([r.json() for r in book_results], safe=False)
data = {
"title": "ISBN Search Results",
"results": book_results,
"query": isbn,
}

View file

@ -314,8 +314,7 @@ def set_book_position(request, list_item_id):
Max("order")
)["order__max"]
if int_position > order_max:
int_position = order_max
int_position = min(int_position, order_max)
if request.user not in (book_list.user, list_item.user):
return HttpResponseNotFound()

View file

@ -10,7 +10,7 @@ class RssFeed(Feed):
description_template = "rss/content.html"
title_template = "rss/title.html"
def get_object(self, request, username):
def get_object(self, request, username): # pylint: disable=arguments-differ
"""the user who's posts get serialized"""
return get_user_from_username(request.user, username)

View file

@ -83,7 +83,7 @@ def user_search(query, viewer, *_):
# use webfinger for mastodon style account@domain.com username to load the user if
# they don't exist locally (handle_remote_webfinger will check the db)
if re.match(regex.full_username, query):
if re.match(regex.FULL_USERNAME, query):
handle_remote_webfinger(query)
return (

View file

@ -17,7 +17,7 @@ from bookwyrm import forms, models
from bookwyrm.activitypub import ActivitypubResponse
from bookwyrm.settings import PAGE_LENGTH
from .helpers import is_api_request, get_edition, get_user_from_username
from .helpers import handle_reading_status, privacy_filter
from .helpers import privacy_filter
# pylint: disable=no-self-use

View file

@ -133,7 +133,7 @@ def find_mentions(content):
"""detect @mentions in raw status content"""
if not content:
return
for match in re.finditer(regex.strict_username, content):
for match in re.finditer(rhandle_reading_status, egex.STRICT_USERNAME, content):
username = match.group().strip().split("@")[1:]
if len(username) == 1:
# this looks like a local user (@user), fill in the domain
@ -150,7 +150,7 @@ def find_mentions(content):
def format_links(content):
"""detect and format links"""
return re.sub(
r'([^(href=")]|^|\()(https?:\/\/(%s([\w\.\-_\/+&\?=:;,])*))' % regex.domain,
r'([^(href=")]|^|\()(https?:\/\/(%s([\w\.\-_\/+&\?=:;,])*))' % regex.DOMAIN,
r'\g<1><a href="\g<2>">\g<3></a>',
content,
)