fix timeout and other issues
This commit is contained in:
parent
2ba82c66c6
commit
73a358c959
10 changed files with 48 additions and 38 deletions
|
@ -23,7 +23,7 @@ environ.Env.read_env(os.path.join(BASE_DIR, "neodb.env"))
|
|||
# ====== List of user configuration variables ======
|
||||
env = environ.FileAwareEnv(
|
||||
# WARNING: do not run with debug mode turned on in production
|
||||
NEODB_DEBUG=(bool, True),
|
||||
NEODB_DEBUG=(bool, False),
|
||||
# WARNING: must use your own key and keep it secret
|
||||
NEODB_SECRET_KEY=(str),
|
||||
# Site information
|
||||
|
|
|
@ -51,13 +51,6 @@ class SearchResultItem:
|
|||
return False
|
||||
|
||||
|
||||
class ProxiedRequest:
|
||||
@classmethod
|
||||
def get(cls, url):
|
||||
u = f"http://api.scraperapi.com?api_key={settings.SCRAPERAPI_KEY}&url={quote_plus(url)}"
|
||||
return requests.get(u, timeout=10)
|
||||
|
||||
|
||||
class Goodreads:
|
||||
@classmethod
|
||||
def search(cls, q, page=1):
|
||||
|
@ -66,7 +59,7 @@ class Goodreads:
|
|||
search_url = (
|
||||
f"https://www.goodreads.com/search?page={page}&q={quote_plus(q)}"
|
||||
)
|
||||
r = requests.get(search_url)
|
||||
r = requests.get(search_url, timeout=2)
|
||||
if r.url.startswith("https://www.goodreads.com/book/show/"):
|
||||
# Goodreads will 302 if only one result matches ISBN
|
||||
site = SiteManager.get_site_by_url(r.url)
|
||||
|
@ -119,7 +112,7 @@ class GoogleBooks:
|
|||
results = []
|
||||
try:
|
||||
api_url = f"https://www.googleapis.com/books/v1/volumes?country=us&q={quote_plus(q)}&startIndex={SEARCH_PAGE_SIZE*(page-1)}&maxResults={SEARCH_PAGE_SIZE}&maxAllowedMaturityRating=MATURE"
|
||||
j = requests.get(api_url).json()
|
||||
j = requests.get(api_url, timeout=2).json()
|
||||
if "items" in j:
|
||||
for b in j["items"]:
|
||||
if "title" not in b["volumeInfo"]:
|
||||
|
@ -166,7 +159,7 @@ class TheMovieDatabase:
|
|||
results = []
|
||||
try:
|
||||
api_url = f"https://api.themoviedb.org/3/search/multi?query={quote_plus(q)}&page={page}&api_key={settings.TMDB_API3_KEY}&language=zh-CN&include_adult=true"
|
||||
j = requests.get(api_url).json()
|
||||
j = requests.get(api_url, timeout=2).json()
|
||||
for m in j["results"]:
|
||||
if m["media_type"] in ["tv", "movie"]:
|
||||
url = f"https://www.themoviedb.org/{m['media_type']}/{m['id']}"
|
||||
|
@ -204,7 +197,7 @@ class Spotify:
|
|||
try:
|
||||
api_url = f"https://api.spotify.com/v1/search?q={q}&type=album&limit={SEARCH_PAGE_SIZE}&offset={page*SEARCH_PAGE_SIZE}"
|
||||
headers = {"Authorization": f"Bearer {get_spotify_token()}"}
|
||||
j = requests.get(api_url, headers=headers).json()
|
||||
j = requests.get(api_url, headers=headers, timeout=2).json()
|
||||
for a in j["albums"]["items"]:
|
||||
title = a["name"]
|
||||
subtitle = a["release_date"]
|
||||
|
@ -234,7 +227,7 @@ class Bandcamp:
|
|||
results = []
|
||||
try:
|
||||
search_url = f"https://bandcamp.com/search?from=results&item_type=a&page={page}&q={quote_plus(q)}"
|
||||
r = requests.get(search_url)
|
||||
r = requests.get(search_url, timeout=2)
|
||||
h = html.fromstring(r.content.decode("utf-8"))
|
||||
albums = h.xpath('//li[@class="searchresult data-search"]')
|
||||
for c in albums: # type:ignore
|
||||
|
@ -268,7 +261,7 @@ class ApplePodcast:
|
|||
results = []
|
||||
try:
|
||||
search_url = f"https://itunes.apple.com/search?entity=podcast&limit={page*SEARCH_PAGE_SIZE}&term={quote_plus(q)}"
|
||||
r = requests.get(search_url).json()
|
||||
r = requests.get(search_url, timeout=2).json()
|
||||
for p in r["results"][(page - 1) * SEARCH_PAGE_SIZE :]:
|
||||
results.append(
|
||||
SearchResultItem(
|
||||
|
|
|
@ -13,7 +13,7 @@ from django.views.decorators.clickjacking import xframe_options_exempt
|
|||
from django.views.decorators.http import require_http_methods
|
||||
|
||||
from common.config import PAGE_LINK_NUMBER
|
||||
from common.utils import PageLinksGenerator, get_uuid_or_404
|
||||
from common.utils import PageLinksGenerator, get_uuid_or_404, user_identity_required
|
||||
from journal.models import (
|
||||
Comment,
|
||||
Mark,
|
||||
|
@ -65,6 +65,7 @@ def embed(request, item_path, item_uuid):
|
|||
)
|
||||
|
||||
|
||||
@user_identity_required
|
||||
def retrieve(request, item_path, item_uuid):
|
||||
# item = get_object_or_404(Item, uid=get_uuid_or_404(item_uuid))
|
||||
item = Item.get_by_url(item_uuid)
|
||||
|
|
|
@ -27,6 +27,23 @@ class HTTPResponseHXRedirect(HttpResponseRedirect):
|
|||
status_code = 200
|
||||
|
||||
|
||||
def user_identity_required(func): # TODO make this a middleware
|
||||
@functools.wraps(func)
|
||||
def wrapper(request, *args, **kwargs):
|
||||
from users.models import APIdentity
|
||||
|
||||
identity = None
|
||||
if request.user.is_authenticated:
|
||||
try:
|
||||
identity = APIdentity.objects.get(user=request.user)
|
||||
except APIdentity.DoesNotExist:
|
||||
return HttpResponseRedirect("/account/register")
|
||||
request.identity = identity
|
||||
return func(request, *args, **kwargs)
|
||||
|
||||
return wrapper
|
||||
|
||||
|
||||
def target_identity_required(func):
|
||||
@functools.wraps(func)
|
||||
def wrapper(request, user_name, *args, **kwargs):
|
||||
|
@ -38,14 +55,21 @@ def target_identity_required(func):
|
|||
except APIdentity.DoesNotExist:
|
||||
return render_user_not_found(request)
|
||||
target_user = target.user
|
||||
viewer = None
|
||||
if target_user and not target_user.is_active:
|
||||
return render_user_not_found(request)
|
||||
if not target.is_visible_to_user(request.user):
|
||||
return render_user_blocked(request)
|
||||
if request.user.is_authenticated:
|
||||
try:
|
||||
viewer = APIdentity.objects.get(user=request.user)
|
||||
except APIdentity.DoesNotExist:
|
||||
return HttpResponseRedirect("/account/register")
|
||||
if request.user != target_user:
|
||||
if target.is_blocking(viewer) or target.is_blocked_by(viewer):
|
||||
return render_user_blocked(request)
|
||||
else:
|
||||
viewer = None
|
||||
request.target_identity = target
|
||||
# request.identity = (
|
||||
# request.user.identity if request.user.is_authenticated else None
|
||||
# )
|
||||
request.identity = viewer
|
||||
return func(request, user_name, *args, **kwargs)
|
||||
|
||||
return wrapper
|
||||
|
|
|
@ -253,7 +253,7 @@ def get_related_acct_list(site, token, api):
|
|||
if li[1].strip() == 'rel="next"':
|
||||
url = li[0].strip().replace(">", "").replace("<", "")
|
||||
except Exception as e:
|
||||
logger.error("Error GET {url} : {e}")
|
||||
logger.warning(f"Error GET {url} : {e}")
|
||||
url = None
|
||||
return results
|
||||
|
||||
|
@ -270,16 +270,16 @@ def detect_server_info(login_domain) -> tuple[str, str, str]:
|
|||
try:
|
||||
response = get(url, headers={"User-Agent": USER_AGENT})
|
||||
except Exception as e:
|
||||
logger.error(f"Error connecting {login_domain}: {e}")
|
||||
logger.warning(f"Error connecting {login_domain}: {e}")
|
||||
raise Exception(f"无法连接 {login_domain}")
|
||||
if response.status_code != 200:
|
||||
logger.error(f"Error connecting {login_domain}: {response.status_code}")
|
||||
logger.warning(f"Error connecting {login_domain}: {response.status_code}")
|
||||
raise Exception(f"实例 {login_domain} 返回错误,代码: {response.status_code}")
|
||||
try:
|
||||
j = response.json()
|
||||
domain = j["uri"].lower().split("//")[-1].split("/")[0]
|
||||
except Exception as e:
|
||||
logger.error(f"Error connecting {login_domain}: {e}")
|
||||
logger.warning(f"Error connecting {login_domain}: {e}")
|
||||
raise Exception(f"实例 {login_domain} 返回信息无法识别")
|
||||
server_version = j["version"]
|
||||
api_domain = domain
|
||||
|
|
|
@ -434,7 +434,7 @@ class Takahe:
|
|||
collection.visibility, user.preference.mastodon_publish_public
|
||||
)
|
||||
if existing_post and visibility != existing_post.visibility:
|
||||
Takahe.delete_posts([existing_post])
|
||||
Takahe.delete_posts([existing_post.pk])
|
||||
existing_post = None
|
||||
data = {
|
||||
"object": {
|
||||
|
|
|
@ -323,7 +323,7 @@ def verify_email(request):
|
|||
try:
|
||||
s = TimestampSigner().unsign_object(request.GET.get("c"), max_age=60 * 15)
|
||||
except Exception as e:
|
||||
logger.error(e)
|
||||
logger.warning(f"login link invalid {e}")
|
||||
error = _("链接无效或已过期")
|
||||
return render(
|
||||
request, "users/verify_email.html", {"success": False, "error": error}
|
||||
|
|
|
@ -133,8 +133,8 @@ def reset_visibility(request):
|
|||
if request.method == "POST":
|
||||
visibility = int(request.POST.get("visibility"))
|
||||
visibility = visibility if visibility >= 0 and visibility <= 2 else 0
|
||||
reset_journal_visibility_for_user(request.user, visibility)
|
||||
reset_social_visibility_for_user(request.user, visibility)
|
||||
reset_journal_visibility_for_user(request.user.identity, visibility)
|
||||
reset_social_visibility_for_user(request.user.identity, visibility)
|
||||
messages.add_message(request, messages.INFO, _("已重置。"))
|
||||
return redirect(reverse("users:data"))
|
||||
|
||||
|
|
|
@ -212,16 +212,6 @@ class APIdentity(models.Model):
|
|||
def is_followed_by(self, target: "APIdentity"):
|
||||
return target.is_following(self)
|
||||
|
||||
def is_visible_to_user(self, viewing_user: User):
|
||||
return (
|
||||
(not viewing_user.is_authenticated)
|
||||
or viewing_user == self.user
|
||||
or (
|
||||
not self.is_blocking(viewing_user.identity)
|
||||
and not self.is_blocked_by(viewing_user.identity)
|
||||
)
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def get_by_handler(cls, handler: str) -> "APIdentity":
|
||||
"""
|
||||
|
|
|
@ -148,6 +148,7 @@
|
|||
</form>
|
||||
</details>
|
||||
</article>
|
||||
<!--
|
||||
<article>
|
||||
<details>
|
||||
<summary>{% trans '重置所有标记和短评可见性' %}</summary>
|
||||
|
@ -165,6 +166,7 @@
|
|||
</form>
|
||||
</details>
|
||||
</article>
|
||||
-->
|
||||
</div>
|
||||
{% include "_sidebar.html" with show_profile=1 identity=request.user.identity %}
|
||||
</main>
|
||||
|
|
Loading…
Add table
Reference in a new issue