Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
67 changes: 67 additions & 0 deletions user_scanner/user_scan/creative/blender_artists.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
import urllib.parse
from user_scanner.core.helpers import get_random_user_agent
from user_scanner.core.orchestrator import Result, generic_validate

def validate_blender_artists(user: str) -> Result:
encoded_user = urllib.parse.quote(user)
url = f"https://blenderartists.org/u/{encoded_user}.json"
show_url = f"https://blenderartists.org/u/{encoded_user}"

headers = {
"User-Agent": get_random_user_agent(),
"Accept": "application/json",
}

def process(response) -> Result:
if response.status_code == 404:
try:
data = response.json()
if (
data.get("error_type") == "not_found"
or any("not be found" in str(err).lower() for err in data.get("errors", []))
):
return Result.available(url=show_url)
except Exception:
pass
return Result.error("Discourse 404 response missing expected error payload")

if response.status_code == 200:
try:
data = response.json()
user_obj = data.get("user")
if user_obj and isinstance(user_obj, dict) and user_obj.get("username"):
extra: dict[str, str] = {}
media: dict[str, str] = {}

if user_obj.get("name"):
extra["name"] = str(user_obj["name"])
if user_obj.get("title"):
extra["title"] = str(user_obj["title"])
if user_obj.get("location"):
extra["location"] = str(user_obj["location"])
if user_obj.get("website_name") or user_obj.get("website"):
extra["website"] = str(user_obj.get("website") or user_obj.get("website_name"))
if user_obj.get("trust_level") is not None:
extra["trust_level"] = str(user_obj["trust_level"])
if user_obj.get("badge_count") is not None:
extra["badges"] = str(user_obj["badge_count"])
if user_obj.get("created_at"):
extra["joined"] = str(user_obj["created_at"])
if user_obj.get("bio_raw") or user_obj.get("bio_cooked"):
extra["bio"] = str(user_obj.get("bio_raw") or user_obj.get("bio_cooked"))

avatar_template = user_obj.get("avatar_template")
if avatar_template:
avatar_url = avatar_template.replace("{size}", "240")
if avatar_url.startswith("/"):
avatar_url = f"https://blenderartists.org{avatar_url}"
media["avatar"] = avatar_url

return Result.taken(url=show_url, extra=extra, media=media)
except Exception:
pass
return Result.error("Discourse 200 response missing valid user payload")

return Result.error(f"Unexpected status code: {response.status_code}")

return generic_validate(url, process, headers=headers, show_url=show_url, follow_redirects=True)
59 changes: 59 additions & 0 deletions user_scanner/user_scan/creative/myminifactory.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import re
import urllib.parse
from user_scanner.core.helpers import get_random_user_agent
from user_scanner.core.orchestrator import Result, generic_validate

def validate_myminifactory(user: str) -> Result:
encoded_user = urllib.parse.quote(user)
url = f"https://www.myminifactory.com/users/{encoded_user}"
show_url = f"https://www.myminifactory.com/users/{encoded_user}"

headers = {
"User-Agent": get_random_user_agent(),
"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
}

def process(response) -> Result:
if response.status_code == 404:
if "404 Not Found" in response.text or "404" in response.text:
return Result.available(url=show_url)
return Result.error("404 received without expected not-found markers")

if response.status_code == 200:
user_lower = user.lower()
text_lower = response.text.lower()

if f"@{user_lower}" in text_lower or f"myminifactory.com/users/{user_lower}" in text_lower:
extra: dict[str, str] = {}
media: dict[str, str] = {}

title_match = re.search(r'<title>(.+?)</title>', response.text)
if title_match:
raw_title = title_match.group(1).replace("- MyMiniFactory", "").strip()
extra["title"] = raw_title
# If title format is "NAME @HANDLE", extract name
if f"@{user.upper()}" in raw_title.upper():
name_candidate = re.sub(r'@\S+', '', raw_title).strip()
if name_candidate:
extra["name"] = name_candidate

desc_match = re.search(r'<meta name="description" content="([^"]+)"', response.text)
if desc_match:
bio = desc_match.group(1).strip()
if bio and bio != f"- {extra.get('name', '')} @{user.upper()}":
extra["bio"] = bio

img_match = re.search(r'<meta property="og:image" content="([^"]+)"', response.text)
if img_match:
media["avatar"] = img_match.group(1).strip()

return Result.taken(url=show_url, extra=extra, media=media)

if "404 Not Found" in response.text:
return Result.available(url=show_url)

return Result.error("Unable to verify MyMiniFactory profile structure")

return Result.error(f"Unexpected status code: {response.status_code}")

return generic_validate(url, process, headers=headers, show_url=show_url, follow_redirects=True)
67 changes: 67 additions & 0 deletions user_scanner/user_scan/dev/fedora.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
import urllib.parse
from user_scanner.core.helpers import get_random_user_agent
from user_scanner.core.orchestrator import Result, generic_validate

def validate_fedora(user: str) -> Result:
encoded_user = urllib.parse.quote(user)
url = f"https://discussion.fedoraproject.org/u/{encoded_user}.json"
show_url = f"https://discussion.fedoraproject.org/u/{encoded_user}"

headers = {
"User-Agent": get_random_user_agent(),
"Accept": "application/json",
}

def process(response) -> Result:
if response.status_code == 404:
try:
data = response.json()
if (
data.get("error_type") == "not_found"
or any("not be found" in str(err).lower() for err in data.get("errors", []))
):
return Result.available(url=show_url)
except Exception:
pass
return Result.error("Discourse 404 response missing expected error payload")

if response.status_code == 200:
try:
data = response.json()
user_obj = data.get("user")
if user_obj and isinstance(user_obj, dict) and user_obj.get("username"):
extra: dict[str, str] = {}
media: dict[str, str] = {}

if user_obj.get("name"):
extra["name"] = str(user_obj["name"])
if user_obj.get("title"):
extra["title"] = str(user_obj["title"])
if user_obj.get("location"):
extra["location"] = str(user_obj["location"])
if user_obj.get("website_name") or user_obj.get("website"):
extra["website"] = str(user_obj.get("website") or user_obj.get("website_name"))
if user_obj.get("trust_level") is not None:
extra["trust_level"] = str(user_obj["trust_level"])
if user_obj.get("badge_count") is not None:
extra["badges"] = str(user_obj["badge_count"])
if user_obj.get("created_at"):
extra["joined"] = str(user_obj["created_at"])
if user_obj.get("bio_raw") or user_obj.get("bio_cooked"):
extra["bio"] = str(user_obj.get("bio_raw") or user_obj.get("bio_cooked"))

avatar_template = user_obj.get("avatar_template")
if avatar_template:
avatar_url = avatar_template.replace("{size}", "240")
if avatar_url.startswith("/"):
avatar_url = f"https://discussion.fedoraproject.org{avatar_url}"
media["avatar"] = avatar_url

return Result.taken(url=show_url, extra=extra, media=media)
except Exception:
pass
return Result.error("Discourse 200 response missing valid user payload")

return Result.error(f"Unexpected status code: {response.status_code}")

return generic_validate(url, process, headers=headers, show_url=show_url, follow_redirects=True)
67 changes: 67 additions & 0 deletions user_scanner/user_scan/dev/gitlab_forum.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
import urllib.parse
from user_scanner.core.helpers import get_random_user_agent
from user_scanner.core.orchestrator import Result, generic_validate

def validate_gitlab_forum(user: str) -> Result:
encoded_user = urllib.parse.quote(user)
url = f"https://forum.gitlab.com/u/{encoded_user}.json"
show_url = f"https://forum.gitlab.com/u/{encoded_user}"

headers = {
"User-Agent": get_random_user_agent(),
"Accept": "application/json",
}

def process(response) -> Result:
if response.status_code == 404:
try:
data = response.json()
if (
data.get("error_type") == "not_found"
or any("not be found" in str(err).lower() for err in data.get("errors", []))
):
return Result.available(url=show_url)
except Exception:
pass
return Result.error("Discourse 404 response missing expected error payload")

if response.status_code == 200:
try:
data = response.json()
user_obj = data.get("user")
if user_obj and isinstance(user_obj, dict) and user_obj.get("username"):
extra: dict[str, str] = {}
media: dict[str, str] = {}

if user_obj.get("name"):
extra["name"] = str(user_obj["name"])
if user_obj.get("title"):
extra["title"] = str(user_obj["title"])
if user_obj.get("location"):
extra["location"] = str(user_obj["location"])
if user_obj.get("website_name") or user_obj.get("website"):
extra["website"] = str(user_obj.get("website") or user_obj.get("website_name"))
if user_obj.get("trust_level") is not None:
extra["trust_level"] = str(user_obj["trust_level"])
if user_obj.get("badge_count") is not None:
extra["badges"] = str(user_obj["badge_count"])
if user_obj.get("created_at"):
extra["joined"] = str(user_obj["created_at"])
if user_obj.get("bio_raw") or user_obj.get("bio_cooked"):
extra["bio"] = str(user_obj.get("bio_raw") or user_obj.get("bio_cooked"))

avatar_template = user_obj.get("avatar_template")
if avatar_template:
avatar_url = avatar_template.replace("{size}", "240")
if avatar_url.startswith("/"):
avatar_url = f"https://forum.gitlab.com{avatar_url}"
media["avatar"] = avatar_url

return Result.taken(url=show_url, extra=extra, media=media)
except Exception:
pass
return Result.error("Discourse 200 response missing valid user payload")

return Result.error(f"Unexpected status code: {response.status_code}")

return generic_validate(url, process, headers=headers, show_url=show_url, follow_redirects=True)
67 changes: 67 additions & 0 deletions user_scanner/user_scan/dev/huggingface_forum.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
import urllib.parse
from user_scanner.core.helpers import get_random_user_agent
from user_scanner.core.orchestrator import Result, generic_validate

def validate_huggingface_forum(user: str) -> Result:
encoded_user = urllib.parse.quote(user)
url = f"https://discuss.huggingface.co/u/{encoded_user}.json"
show_url = f"https://discuss.huggingface.co/u/{encoded_user}"

headers = {
"User-Agent": get_random_user_agent(),
"Accept": "application/json",
}

def process(response) -> Result:
if response.status_code == 404:
try:
data = response.json()
if (
data.get("error_type") == "not_found"
or any("not be found" in str(err).lower() for err in data.get("errors", []))
):
return Result.available(url=show_url)
except Exception:
pass
return Result.error("Discourse 404 response missing expected error payload")

if response.status_code == 200:
try:
data = response.json()
user_obj = data.get("user")
if user_obj and isinstance(user_obj, dict) and user_obj.get("username"):
extra: dict[str, str] = {}
media: dict[str, str] = {}

if user_obj.get("name"):
extra["name"] = str(user_obj["name"])
if user_obj.get("title"):
extra["title"] = str(user_obj["title"])
if user_obj.get("location"):
extra["location"] = str(user_obj["location"])
if user_obj.get("website_name") or user_obj.get("website"):
extra["website"] = str(user_obj.get("website") or user_obj.get("website_name"))
if user_obj.get("trust_level") is not None:
extra["trust_level"] = str(user_obj["trust_level"])
if user_obj.get("badge_count") is not None:
extra["badges"] = str(user_obj["badge_count"])
if user_obj.get("created_at"):
extra["joined"] = str(user_obj["created_at"])
if user_obj.get("bio_raw") or user_obj.get("bio_cooked"):
extra["bio"] = str(user_obj.get("bio_raw") or user_obj.get("bio_cooked"))

avatar_template = user_obj.get("avatar_template")
if avatar_template:
avatar_url = avatar_template.replace("{size}", "240")
if avatar_url.startswith("/"):
avatar_url = f"https://discuss.huggingface.co{avatar_url}"
media["avatar"] = avatar_url

return Result.taken(url=show_url, extra=extra, media=media)
except Exception:
pass
return Result.error("Discourse 200 response missing valid user payload")

return Result.error(f"Unexpected status code: {response.status_code}")

return generic_validate(url, process, headers=headers, show_url=show_url, follow_redirects=True)
67 changes: 67 additions & 0 deletions user_scanner/user_scan/dev/jenkins.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
import urllib.parse
from user_scanner.core.helpers import get_random_user_agent
from user_scanner.core.orchestrator import Result, generic_validate

def validate_jenkins(user: str) -> Result:
encoded_user = urllib.parse.quote(user)
url = f"https://community.jenkins.io/u/{encoded_user}.json"
show_url = f"https://community.jenkins.io/u/{encoded_user}"

headers = {
"User-Agent": get_random_user_agent(),
"Accept": "application/json",
}

def process(response) -> Result:
if response.status_code == 404:
try:
data = response.json()
if (
data.get("error_type") == "not_found"
or any("not be found" in str(err).lower() for err in data.get("errors", []))
):
return Result.available(url=show_url)
except Exception:
pass
return Result.error("Discourse 404 response missing expected error payload")

if response.status_code == 200:
try:
data = response.json()
user_obj = data.get("user")
if user_obj and isinstance(user_obj, dict) and user_obj.get("username"):
extra: dict[str, str] = {}
media: dict[str, str] = {}

if user_obj.get("name"):
extra["name"] = str(user_obj["name"])
if user_obj.get("title"):
extra["title"] = str(user_obj["title"])
if user_obj.get("location"):
extra["location"] = str(user_obj["location"])
if user_obj.get("website_name") or user_obj.get("website"):
extra["website"] = str(user_obj.get("website") or user_obj.get("website_name"))
if user_obj.get("trust_level") is not None:
extra["trust_level"] = str(user_obj["trust_level"])
if user_obj.get("badge_count") is not None:
extra["badges"] = str(user_obj["badge_count"])
if user_obj.get("created_at"):
extra["joined"] = str(user_obj["created_at"])
if user_obj.get("bio_raw") or user_obj.get("bio_cooked"):
extra["bio"] = str(user_obj.get("bio_raw") or user_obj.get("bio_cooked"))

avatar_template = user_obj.get("avatar_template")
if avatar_template:
avatar_url = avatar_template.replace("{size}", "240")
if avatar_url.startswith("/"):
avatar_url = f"https://community.jenkins.io{avatar_url}"
media["avatar"] = avatar_url

return Result.taken(url=show_url, extra=extra, media=media)
except Exception:
pass
return Result.error("Discourse 200 response missing valid user payload")

return Result.error(f"Unexpected status code: {response.status_code}")

return generic_validate(url, process, headers=headers, show_url=show_url, follow_redirects=True)
Loading
Loading