From 3111bb32ec138a74cc4c7a7d25a55a280a21e7c0 Mon Sep 17 00:00:00 2001 From: Cole Munz Date: Tue, 14 Jul 2026 23:29:20 -0500 Subject: [PATCH] fix: read isDefault from the API for profile photos instead of image hashing profile_photo entries were classified as default/custom by downloading the image and comparing its perceptual hash to one hardcoded reference hash. That produces false results whenever Google serves a slightly different variant of the default avatar (#486). The API response already includes an isDefault field for photo entries, and the cover_photo branch right below already uses it. Read the same field for profile_photo instead of hashing the image, which also drops a network request and the unused imagehash/PIL dependency from this path. Removed the now-dead is_default_profile_pic / get_url_image_flathash helpers and the flathash field, since nothing else read them. Fixes #486 --- ghunt/helpers/utils.py | 20 -------------------- ghunt/parsers/people.py | 8 +++----- 2 files changed, 3 insertions(+), 25 deletions(-) diff --git a/ghunt/helpers/utils.py b/ghunt/helpers/utils.py index ce03d60b..8f635af4 100644 --- a/ghunt/helpers/utils.py +++ b/ghunt/helpers/utils.py @@ -1,5 +1,4 @@ from pathlib import Path -from PIL import Image import hashlib from typing import * from time import time @@ -11,8 +10,6 @@ from packaging.version import parse as parse_version import httpx -import imagehash -from io import BytesIO from ghunt import globals as gb from ghunt import version as current_version @@ -57,23 +54,6 @@ def is_headers_syntax_good(headers: Dict[str, str]) -> bool: except: return False -async def get_url_image_flathash(as_client: httpx.AsyncClient, image_url: str) -> str: - req = await as_client.get(image_url) - img = Image.open(BytesIO(req.content)) - flathash = imagehash.average_hash(img) - return str(flathash) - -async def is_default_profile_pic(as_client: httpx.AsyncClient, image_url: str) -> Tuple[bool, str]: - """ - Returns a boolean which indicates if the image_url - is a default profile picture, and the flathash of - the image. - """ - flathash = await get_url_image_flathash(as_client, image_url) - if imagehash.hex_to_flathash(flathash, 8) - imagehash.hex_to_flathash("000018183c3c0000", 8) < 10 : - return True, str(flathash) - return False, str(flathash) - def get_class_name(obj) -> str: return str(obj).strip("<>").split(" ")[0] diff --git a/ghunt/parsers/people.py b/ghunt/parsers/people.py index 43554121..8bbbed4d 100644 --- a/ghunt/parsers/people.py +++ b/ghunt/parsers/people.py @@ -2,11 +2,10 @@ from datetime import datetime from ghunt.errors import * -from ghunt.helpers.utils import is_default_profile_pic, unicode_patch +from ghunt.helpers.utils import unicode_patch from ghunt.objects.apis import Parser import httpx -import imagehash class PersonGplusExtendedData(Parser): @@ -51,14 +50,13 @@ class PersonPhoto(Parser): def __init__(self): self.url: str = "" self.isDefault: bool = False - self.flathash: str = None async def _scrape(self, as_client: httpx.AsyncClient, photo_data: Dict[str, any], photo_type: str): if photo_type == "profile_photo": self.url = photo_data.get("url") + if (isDefault := photo_data.get("isDefault")): + self.isDefault = isDefault - self.isDefault, self.flathash = await is_default_profile_pic(as_client, self.url) - elif photo_type == "cover_photo": self.url = '='.join(photo_data.get("imageUrl").split("=")[:-1]) if (isDefault := photo_data.get("isDefault")):