forked from mirrors/bookwyrm
Updates code for linter
This commit is contained in:
parent
20f74ba02b
commit
4479864008
21 changed files with 71 additions and 61 deletions
2
.github/workflows/pylint.yml
vendored
2
.github/workflows/pylint.yml
vendored
|
@ -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
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
|
|
@ -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"""
|
||||
|
|
|
@ -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"""
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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"):
|
||||
|
|
|
@ -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",)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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"""
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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"
|
||||
),
|
||||
|
|
|
@ -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]+;"
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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,
|
||||
}
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
|
|
@ -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 (
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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,
|
||||
)
|
||||
|
|
Loading…
Reference in a new issue