Check packages for broken links when submitting for approval

Half of #546
This commit is contained in:
rubenwardy
2024-07-04 21:29:56 +01:00
parent a38a650dc1
commit 3f62a41952
7 changed files with 91 additions and 6 deletions

View File

@@ -16,12 +16,15 @@
import datetime
import re
from typing import Optional
import requests
from sqlalchemy import or_, and_
from app.markdown import get_links, render_markdown
from app.models import Package, db, PackageState, AuditLogEntry
from app.tasks import celery
from app.utils import post_bot_message
from app.tasks import celery, TaskError
from app.utils import post_bot_message, post_to_approval_thread, get_system_user
@celery.task()
@@ -103,3 +106,59 @@ def clear_removed_packages(all_packages: bool):
db.session.commit()
return f"Deleted {count} soft deleted packages packages"
def _url_exists(url: str) -> bool:
try:
with requests.get(url, stream=True) as response:
try:
response.raise_for_status()
return True
except requests.exceptions.HTTPError:
return False
except requests.exceptions.ConnectionError:
return False
def check_for_dead_links(package: Package) -> set[str]:
links: list[Optional[str]] = [
package.repo,
package.website,
package.issueTracker,
package.forums_url,
package.video_url,
package.donate_url_actual,
package.translation_url,
]
if package.desc:
links.extend(get_links(render_markdown(package.desc), package.get_url("packages.view", absolute=True)))
bad_urls = set()
for link in links:
if link is None:
continue
if not _url_exists(link):
bad_urls.add(link)
return bad_urls
@celery.task()
def check_package_on_submit(package_id: int):
package = Package.query.get(package_id)
if package is None:
raise TaskError("No such package")
bad_urls = check_for_dead_links(package)
if len(bad_urls) > 0:
marked = f"Marked {package.title} as Changed Needed"
msg = "The following broken links were found on your package:\n\n" + "\n".join([f"- {x}" for x in bad_urls])
system_user = get_system_user()
post_to_approval_thread(package, system_user, marked, is_status_update=True, create_thread=True)
post_to_approval_thread(package, system_user, msg, is_status_update=False, create_thread=True)
package.state = PackageState.CHANGES_NEEDED
db.session.commit()