DraconicDragon commited on
Commit
18120fc
·
verified ·
1 Parent(s): f246636

Update fetch_url_util.py

Browse files
Files changed (1) hide show
  1. fetch_url_util.py +44 -6
fetch_url_util.py CHANGED
@@ -1,4 +1,6 @@
1
  import io
 
 
2
  import urllib.parse
3
  from PIL import Image
4
  from curl_cffi import requests
@@ -8,10 +10,26 @@ try:
8
  except ImportError:
9
  pass
10
 
11
- # Max file size: 150MB
 
12
  MAX_SIZE = 150 * 1024 * 1024
13
  MAX_SIZE_MB = MAX_SIZE / (1024 * 1024)
14
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
15
  def fetch_image_from_url(url):
16
  if not url:
17
  return None
@@ -20,6 +38,23 @@ def fetch_image_from_url(url):
20
  if not url.startswith(("http://", "https://")):
21
  url = "https://" + url
22
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
23
  parsed_url = urllib.parse.urlparse(url)
24
  base_domain = f"{parsed_url.scheme}://{parsed_url.netloc}/"
25
 
@@ -44,25 +79,29 @@ def fetch_image_from_url(url):
44
 
45
  response.raise_for_status()
46
 
47
- # 1. Check Content-Length header
48
  cl = response.headers.get("Content-Length")
49
  if cl and int(cl) > MAX_SIZE:
50
  raise RuntimeError(f"File too large (limit: {MAX_SIZE_MB:.0f}MB)")
51
 
52
- # 2. Download in chunks
53
  downloaded_data = io.BytesIO()
54
  size = 0
55
- for chunk in response.iter_content(chunk_size=65536): # 64KB chunks
56
  size += len(chunk)
57
  if size > MAX_SIZE:
58
  raise RuntimeError(f"File exceeds {MAX_SIZE_MB:.0f}MB limit.")
59
  downloaded_data.write(chunk)
60
 
61
- # 3. Open and verify
62
  downloaded_data.seek(0)
63
  img = Image.open(downloaded_data)
64
  img.load()
65
 
 
 
 
 
 
 
 
66
  return img.convert("RGB")
67
 
68
  except Exception as e:
@@ -76,6 +115,5 @@ def fetch_image_from_url(url):
76
  raise RuntimeError(error_msg)
77
 
78
  finally:
79
- # Manually close the response since we used stream=True
80
  if response is not None:
81
  response.close()
 
1
  import io
2
+ import os
3
+ import hashlib
4
  import urllib.parse
5
  from PIL import Image
6
  from curl_cffi import requests
 
10
  except ImportError:
11
  pass
12
 
13
+ CACHE_DIR = "/tmp/image_fetch_cache"
14
+ MAX_CACHE_COUNT = 100
15
  MAX_SIZE = 150 * 1024 * 1024
16
  MAX_SIZE_MB = MAX_SIZE / (1024 * 1024)
17
 
18
+ # Ensure cache directory exists
19
+ os.makedirs(CACHE_DIR, exist_ok=True)
20
+
21
+ def _manage_cache_limit():
22
+ """Removes the oldest files if cache exceeds MAX_CACHE_COUNT."""
23
+ files = [os.path.join(CACHE_DIR, f) for f in os.listdir(CACHE_DIR)]
24
+ if len(files) > MAX_CACHE_COUNT:
25
+ # Sort by access time (oldest first)
26
+ files.sort(key=os.path.getatime)
27
+ for i in range(len(files) - MAX_CACHE_COUNT):
28
+ try:
29
+ os.remove(files[i])
30
+ except OSError:
31
+ pass
32
+
33
  def fetch_image_from_url(url):
34
  if not url:
35
  return None
 
38
  if not url.startswith(("http://", "https://")):
39
  url = "https://" + url
40
 
41
+ # Generate a unique filename based on the URL
42
+ url_hash = hashlib.sha256(url.encode()).hexdigest()
43
+ cache_path = os.path.join(CACHE_DIR, f"{url_hash}.png")
44
+
45
+ # 1. Check if image is in cache
46
+ if os.path.exists(cache_path):
47
+ try:
48
+ img = Image.open(cache_path)
49
+ img.load()
50
+ # Update access time so it's not cleared by cache manager
51
+ os.utime(cache_path, None)
52
+ return img.convert("RGB")
53
+ except Exception:
54
+ # If cached file is corrupt, remove it and proceed to fetch
55
+ os.remove(cache_path)
56
+
57
+ # 2. If not in cache, prepare to fetch
58
  parsed_url = urllib.parse.urlparse(url)
59
  base_domain = f"{parsed_url.scheme}://{parsed_url.netloc}/"
60
 
 
79
 
80
  response.raise_for_status()
81
 
 
82
  cl = response.headers.get("Content-Length")
83
  if cl and int(cl) > MAX_SIZE:
84
  raise RuntimeError(f"File too large (limit: {MAX_SIZE_MB:.0f}MB)")
85
 
 
86
  downloaded_data = io.BytesIO()
87
  size = 0
88
+ for chunk in response.iter_content(chunk_size=65536):
89
  size += len(chunk)
90
  if size > MAX_SIZE:
91
  raise RuntimeError(f"File exceeds {MAX_SIZE_MB:.0f}MB limit.")
92
  downloaded_data.write(chunk)
93
 
 
94
  downloaded_data.seek(0)
95
  img = Image.open(downloaded_data)
96
  img.load()
97
 
98
+ # 3. Save to cache
99
+ try:
100
+ img.save(cache_path, "PNG")
101
+ _manage_cache_limit()
102
+ except Exception as cache_err:
103
+ print(f"Cache write failed: {cache_err}")
104
+
105
  return img.convert("RGB")
106
 
107
  except Exception as e:
 
115
  raise RuntimeError(error_msg)
116
 
117
  finally:
 
118
  if response is not None:
119
  response.close()