@@ -96,19 +96,22 @@ def thumbnails_generate():
9696
9797 Body (JSON):
9898 {
99- "file_path": "posters/<env>/<uid>/filename.pdf", // required; also accepts "pdf_path" for backwards compat
99+ "file_path": "posters/<env>/<uid>[/version-<sequence>-<id>]/filename.pdf",
100+ // required; also accepts "pdf_path" for backwards compatibility
100101 "poster_id": 123 // optional — updates Poster.imageUrl
101102 }
102103
103104 Returns:
104105 { "thumbnail_path": "thumbnails/<env>/<uid>/image.jpeg" }
105106 """
106- # posters/<env>/<uid>/<filename>.<ext>
107+ # posters/<env>/<uid>[/version-<sequence>-<id>] /<filename>.<ext>
107108 # <env> — lowercase letters only (e.g. "p", "staging", "production")
108109 # <uid> — alphanumeric + hyphens/underscores, 8-40 chars
109- # <filename> — no path traversal; must end in .pdf, .jpg, .jpeg, or .png
110+ # <filename> — no path traversal; must use a supported poster extension
110111 _FILE_PATH_RE = re .compile (
111- r"^posters/[a-z]+/[a-zA-Z0-9_-]{8,40}/[^/]+\.(pdf|jpg|jpeg|png)$"
112+ r"^posters/[a-z]+/[a-zA-Z0-9_-]{8,40}/"
113+ r"(?:version-\d+-[a-zA-Z0-9_-]{8,40}/)?"
114+ r"[^/]+\.(pdf|jpg|jpeg|png)$"
112115 )
113116
114117 print ("[status] api: POST /thumbnails/generate" )
@@ -117,7 +120,12 @@ def thumbnails_generate():
117120 if not file_path :
118121 return jsonify ({"error" : "file_path is required" }), 400
119122 if not _FILE_PATH_RE .match (file_path ):
120- return jsonify ({"error" : "file_path must match posters/<env>/<uid>/<filename>.(pdf|jpg|jpeg|png)" }), 400
123+ message = (
124+ "file_path must match posters/<env>/<uid>"
125+ "[/version-<sequence>-<id>]/<filename>."
126+ "(pdf|jpg|jpeg|png)"
127+ )
128+ return jsonify ({"error" : message }), 400
121129
122130 poster_id = body .get ("poster_id" )
123131
0 commit comments