Spaces:
No application file
No application file
Commit ·
e7b60d6
1
Parent(s): 1a02be9
works with decathlon and latulippe
Browse files
README.md
CHANGED
|
@@ -5,7 +5,7 @@ colorFrom: yellow
|
|
| 5 |
colorTo: red
|
| 6 |
sdk: gradio
|
| 7 |
sdk_version: 4.1.1
|
| 8 |
-
app_file:
|
| 9 |
pinned: false
|
| 10 |
---
|
| 11 |
|
|
|
|
| 5 |
colorTo: red
|
| 6 |
sdk: gradio
|
| 7 |
sdk_version: 4.1.1
|
| 8 |
+
app_file: app_static.py
|
| 9 |
pinned: false
|
| 10 |
---
|
| 11 |
|
app.py
CHANGED
|
@@ -30,15 +30,28 @@ shop = None
|
|
| 30 |
shops = {
|
| 31 |
'Latulippe': {
|
| 32 |
'url': 'https://latulippe.com/fr/recherche/?keywords=',
|
| 33 |
-
'regex': r'N° (M\d+)'
|
|
|
|
| 34 |
},
|
| 35 |
'Decathlon': {
|
| 36 |
'url': 'https://www.decathlon.fr/search?Ntt=',
|
| 37 |
-
'regex': r'Réf\. ?: ?([\d, ]+)'
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 38 |
},
|
| 39 |
# Add more shops and their respective information here
|
| 40 |
}
|
| 41 |
|
|
|
|
|
|
|
|
|
|
| 42 |
def app(img, selected_shop):
|
| 43 |
if img is None:
|
| 44 |
raise gr.Error("No file uploaded. Please upload an image.")
|
|
@@ -100,10 +113,13 @@ with gr.Blocks() as demo:
|
|
| 100 |
texts = []
|
| 101 |
sku = []
|
| 102 |
|
| 103 |
-
print("selected_shop:", selected_shop)
|
| 104 |
search_url = shops[selected_shop]['url']
|
| 105 |
ref_number_regex = shops[selected_shop]['regex']
|
| 106 |
-
print("search_url:", search_url)
|
|
|
|
|
|
|
|
|
|
| 107 |
|
| 108 |
if mode == 'rbf':
|
| 109 |
predictions = get_yolo_predictions(img)
|
|
@@ -158,16 +174,62 @@ with gr.Blocks() as demo:
|
|
| 158 |
text = ocr(sub_image)
|
| 159 |
texts.append(text)
|
| 160 |
for object_number, text in enumerate(texts, start=1):
|
| 161 |
-
print("object", object_number)
|
| 162 |
-
print("text", text)
|
| 163 |
-
# ref_numbers = re.findall(ref_number_regex, text)
|
| 164 |
-
full_match = re.search(ref_number_regex, text)
|
| 165 |
ref_numbers = []
|
| 166 |
-
if
|
| 167 |
-
|
| 168 |
-
|
| 169 |
-
|
| 170 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 171 |
for ref in ref_numbers:
|
| 172 |
# print("SKU:", ref)
|
| 173 |
# append 'M' before the ref number
|
|
@@ -175,7 +237,7 @@ with gr.Blocks() as demo:
|
|
| 175 |
if ref not in sku:
|
| 176 |
sku.append(ref)
|
| 177 |
# if search_query not in hotspots_sku_links:
|
| 178 |
-
hotspots_sku_links.append(search_query)
|
| 179 |
hostpots.append(((int(coord[0]), int(coord[1]), int(coord[2]), int(coord[3])), str(ref)))
|
| 180 |
print("hotspots_sku_links: ", hotspots_sku_links)
|
| 181 |
print("skus: ", sku)
|
|
@@ -185,13 +247,24 @@ with gr.Blocks() as demo:
|
|
| 185 |
|
| 186 |
section_btn.click(section, [img_input, selected_shop], img_output)
|
| 187 |
|
|
|
|
| 188 |
# def select_section(evt: gr.SelectData):
|
| 189 |
-
#
|
|
|
|
|
|
|
| 190 |
|
| 191 |
def select_section(evt: gr.SelectData):
|
| 192 |
-
|
| 193 |
-
|
| 194 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 195 |
|
| 196 |
img_output.select(select_section, None, selected_section)
|
| 197 |
|
|
|
|
| 30 |
shops = {
|
| 31 |
'Latulippe': {
|
| 32 |
'url': 'https://latulippe.com/fr/recherche/?keywords=',
|
| 33 |
+
'regex': r'N° (M\d+)',
|
| 34 |
+
'multi_items': False,
|
| 35 |
},
|
| 36 |
'Decathlon': {
|
| 37 |
'url': 'https://www.decathlon.fr/search?Ntt=',
|
| 38 |
+
'regex': r'Réf\. ?: ?([\d, ]+)',
|
| 39 |
+
'multi_items': True,
|
| 40 |
+
'brands': [
|
| 41 |
+
"Allsix", "Aptonia", "Artengo", "Atorka", "B'Twin", "Caperlan", "Domyos", "Dreamscape",
|
| 42 |
+
"FLX", "Forclaz", "Fouganza", "Geologic", "Geonaute", "Inesis", "Imviso", "Inovik",
|
| 43 |
+
"Itiwit", "KOODZA", "KOROK", "Kalenji", "Kimjaly", "Kipsta", "Kuikma", "Nabaiji",
|
| 44 |
+
"Newfeel", "Offload", "Olaian", "Opfeel", "Orao", "Oroks", "Outshock", "Oxelo",
|
| 45 |
+
"Perfly", "Pongori", "Quechua", "Rockrider", "Sandever", "Simond", "Solognac",
|
| 46 |
+
"Subea", "Tarmak", "Triban", "Tribord", "Urball", "Van Rysel", "Wed'Ze", "Decathlon"
|
| 47 |
+
]
|
| 48 |
},
|
| 49 |
# Add more shops and their respective information here
|
| 50 |
}
|
| 51 |
|
| 52 |
+
regex_price = r'(\d+\.?\d*) ?([€$])|([€$]) ?(\d+\.?\d*)'
|
| 53 |
+
|
| 54 |
+
|
| 55 |
def app(img, selected_shop):
|
| 56 |
if img is None:
|
| 57 |
raise gr.Error("No file uploaded. Please upload an image.")
|
|
|
|
| 113 |
texts = []
|
| 114 |
sku = []
|
| 115 |
|
| 116 |
+
#print("selected_shop:", selected_shop)
|
| 117 |
search_url = shops[selected_shop]['url']
|
| 118 |
ref_number_regex = shops[selected_shop]['regex']
|
| 119 |
+
# print("search_url:", search_url)
|
| 120 |
+
brands = shops[selected_shop]['brands'] if 'brands' in shops[selected_shop] else None
|
| 121 |
+
if brands:
|
| 122 |
+
brands = [brand.upper() for brand in brands]
|
| 123 |
|
| 124 |
if mode == 'rbf':
|
| 125 |
predictions = get_yolo_predictions(img)
|
|
|
|
| 174 |
text = ocr(sub_image)
|
| 175 |
texts.append(text)
|
| 176 |
for object_number, text in enumerate(texts, start=1):
|
| 177 |
+
#print("object", object_number)
|
| 178 |
+
#print("text", text)
|
|
|
|
|
|
|
| 179 |
ref_numbers = []
|
| 180 |
+
if shops[selected_shop]['multi_items']:
|
| 181 |
+
full_match = re.search(ref_number_regex, text)
|
| 182 |
+
if full_match:
|
| 183 |
+
#print("FULL MATCH: ", full_match)
|
| 184 |
+
# Extracting all numbers from the captured sequence
|
| 185 |
+
numbers_string = full_match.group(1)
|
| 186 |
+
ref_numbers = re.findall(r'\d+', numbers_string)
|
| 187 |
+
else:
|
| 188 |
+
ref_numbers = re.findall(ref_number_regex, text)
|
| 189 |
+
|
| 190 |
+
#print("REF NUMBERS: ", ref_numbers)
|
| 191 |
+
|
| 192 |
+
matches = re.findall(regex_price, text)
|
| 193 |
+
prices = []
|
| 194 |
+
for match in matches:
|
| 195 |
+
if match[0]: # If the first group is not empty, the format is "price currency"
|
| 196 |
+
prices.append(match[0] + match[1])
|
| 197 |
+
else: # Otherwise, the format is "currency price"
|
| 198 |
+
prices.append(match[2] + match[3])
|
| 199 |
+
# price = prices[0] if len(prices) > 0 else ""
|
| 200 |
+
#print("PRICES: ", prices)
|
| 201 |
+
|
| 202 |
+
if brands:
|
| 203 |
+
print("BRANDS: yes")
|
| 204 |
+
# Extracting the product name
|
| 205 |
+
lines = text.split('\n')
|
| 206 |
+
product_name = ""
|
| 207 |
+
found_brand = False
|
| 208 |
+
name_started = False
|
| 209 |
+
for line in lines:
|
| 210 |
+
if any(brand in line for brand in brands):
|
| 211 |
+
found_brand = True
|
| 212 |
+
#print("FOUND BRAND", line)
|
| 213 |
+
continue
|
| 214 |
+
if found_brand:
|
| 215 |
+
#print('current line:', line)
|
| 216 |
+
if line.strip() == "": # Skip blank lines
|
| 217 |
+
continue
|
| 218 |
+
if name_started and (line[0].isupper() or any(char.isdigit() for char in line)):
|
| 219 |
+
break
|
| 220 |
+
product_name += line.strip() + " "
|
| 221 |
+
name_started = True
|
| 222 |
+
product_name = product_name.strip()
|
| 223 |
+
|
| 224 |
+
else:
|
| 225 |
+
# Regex to match sequences of uppercase letters
|
| 226 |
+
uppercase_words = re.findall(r'\b[A-Z]+\b', text)
|
| 227 |
+
|
| 228 |
+
# Joining the extracted words with a space
|
| 229 |
+
product_name = ' '.join(uppercase_words)
|
| 230 |
+
|
| 231 |
+
#print("PRODUCT NAME: ", product_name)
|
| 232 |
+
|
| 233 |
for ref in ref_numbers:
|
| 234 |
# print("SKU:", ref)
|
| 235 |
# append 'M' before the ref number
|
|
|
|
| 237 |
if ref not in sku:
|
| 238 |
sku.append(ref)
|
| 239 |
# if search_query not in hotspots_sku_links:
|
| 240 |
+
hotspots_sku_links.append([{'sku': ref, 'url': search_query, 'prices': prices, 'product_name': product_name}])
|
| 241 |
hostpots.append(((int(coord[0]), int(coord[1]), int(coord[2]), int(coord[3])), str(ref)))
|
| 242 |
print("hotspots_sku_links: ", hotspots_sku_links)
|
| 243 |
print("skus: ", sku)
|
|
|
|
| 247 |
|
| 248 |
section_btn.click(section, [img_input, selected_shop], img_output)
|
| 249 |
|
| 250 |
+
|
| 251 |
# def select_section(evt: gr.SelectData):
|
| 252 |
+
# # Format the URL as a Markdown link
|
| 253 |
+
# url = hotspots_sku_links[evt.index]
|
| 254 |
+
# return f"[Click here to visit the selected hotspot's link]({url})"
|
| 255 |
|
| 256 |
def select_section(evt: gr.SelectData):
|
| 257 |
+
hotspot_data = hotspots_sku_links[evt.index]
|
| 258 |
+
markdown_output = ""
|
| 259 |
+
for data in hotspot_data:
|
| 260 |
+
url = data['url']
|
| 261 |
+
price_str = ", ".join(data['prices']) if data['prices'] else "No price found"
|
| 262 |
+
product_name = data['product_name'] if data['product_name'] else "No product name found"
|
| 263 |
+
if product_name != "No product name found":
|
| 264 |
+
markdown_output += f"[{product_name}]({url}): {price_str}\n\n"
|
| 265 |
+
else:
|
| 266 |
+
markdown_output += f"[SKU: {data['sku']}]({url}): {price_str}\n\n"
|
| 267 |
+
return markdown_output
|
| 268 |
|
| 269 |
img_output.select(select_section, None, selected_section)
|
| 270 |
|
test.py
CHANGED
|
@@ -1,17 +1,15 @@
|
|
| 1 |
import re
|
| 2 |
|
| 3 |
-
text = "
|
|
|
|
|
|
|
|
|
|
|
|
|
| 4 |
|
| 5 |
-
# Regex to
|
| 6 |
-
|
| 7 |
|
| 8 |
-
#
|
| 9 |
-
|
| 10 |
|
| 11 |
-
|
| 12 |
-
if full_match:
|
| 13 |
-
# Extracting all numbers from the captured sequence
|
| 14 |
-
numbers_string = full_match.group(1)
|
| 15 |
-
ref_numbers = re.findall(r'\d+', numbers_string)
|
| 16 |
-
|
| 17 |
-
print(ref_numbers) # This will correctly print: ['8403098', '8403427']
|
|
|
|
| 1 |
import re
|
| 2 |
|
| 3 |
+
text = """
|
| 4 |
+
This is some SAMPLE text.
|
| 5 |
+
It INCLUDES some LINES
|
| 6 |
+
with UPPER CASE words.
|
| 7 |
+
"""
|
| 8 |
|
| 9 |
+
# Regex to match sequences of uppercase letters
|
| 10 |
+
uppercase_words = re.findall(r'\b[A-Z]+\b', text)
|
| 11 |
|
| 12 |
+
# Joining the extracted words with a space
|
| 13 |
+
result = ' '.join(uppercase_words)
|
| 14 |
|
| 15 |
+
print(result) # This will print: SAMPLE INCLUDES LINES UPPER CASE
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|