Spaces:
Runtime error
Runtime error
Upload 5 files
#2
by
geraldlu
- opened
README.md
CHANGED
@@ -1,12 +1,9 @@
|
|
1 |
-
|
2 |
-
|
3 |
-
|
4 |
-
|
5 |
-
|
6 |
-
|
7 |
-
|
8 |
-
|
9 |
-
pinned: false
|
10 |
-
---
|
11 |
|
12 |
-
Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
|
|
|
1 |
+
# r3sell
|
2 |
+
AI Atlanta Hackathon project to enable the resale economy
|
3 |
+
|
4 |
+
|
5 |
+
# To Run:
|
6 |
+
```
|
7 |
+
python3 -m streamlit run app.py
|
8 |
+
```
|
|
|
|
|
9 |
|
|
app.py
CHANGED
@@ -1,42 +1,112 @@
|
|
1 |
import streamlit as st
|
2 |
from transformers import pipeline
|
3 |
from PIL import Image
|
4 |
-
import
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
5 |
|
6 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
7 |
|
8 |
# Set the title and text color to dark green
|
9 |
st.markdown('<h1 style="color:darkgreen;">R3SELL</h1>', unsafe_allow_html=True)
|
10 |
|
11 |
# Create a file input option for uploading an image
|
12 |
-
file_name = st.file_uploader("Upload an image file (JPEG, PNG, etc.)")
|
13 |
|
14 |
# Create a camera input widget to capture images from the webcam
|
15 |
image = st.camera_input("Capture an image from your webcam")
|
16 |
|
17 |
# Add a text bar to add a title
|
18 |
-
image_title = st.text_input("Image Title"
|
|
|
|
|
|
|
|
|
|
|
|
|
19 |
|
20 |
# Add a text bar to add a description
|
21 |
-
|
22 |
|
23 |
if file_name is not None or image is not None:
|
24 |
# Check if the image is a webcam image
|
|
|
25 |
if file_name == 'webcam_image.jpg':
|
26 |
# Use the Base64 encoded image
|
27 |
image = Image.open('data:image/jpeg;base64,' + img_encoded)
|
28 |
else:
|
29 |
# Open the uploaded image
|
30 |
image = Image.open(file_name)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
31 |
|
32 |
-
# Pass the captured image to the pipeline function
|
33 |
-
predictions = pipeline(image)
|
34 |
|
35 |
-
col1, col2 = st.columns(2)
|
36 |
|
37 |
|
38 |
-
|
39 |
|
40 |
-
|
41 |
-
|
42 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
import streamlit as st
|
2 |
from transformers import pipeline
|
3 |
from PIL import Image
|
4 |
+
from rembg import remove
|
5 |
+
from io import BytesIO
|
6 |
+
from ebay import search_ebay_sold_items
|
7 |
+
from llava import get_quality
|
8 |
+
from os.path import abspath
|
9 |
+
import os
|
10 |
+
from anthropic import Anthropic, HUMAN_PROMPT, AI_PROMPT
|
11 |
+
import re
|
12 |
+
def convert_string_to_dict(data_string):
|
13 |
+
pairs = re.findall(r'"([^"]+)"\s*:\s*"([^"]*)"', data_string)
|
14 |
+
data_dictionary = dict(pairs)
|
15 |
+
return data_dictionary
|
16 |
|
17 |
+
def improving_picture(file_name):
|
18 |
+
image = file_name.getvalue()
|
19 |
+
new_image = remove(image, alpha_matting=True)
|
20 |
+
return new_image
|
21 |
+
def add_white_background_to_image_bytes(modified_image_bytes):
|
22 |
+
# Convert bytes to PIL Image
|
23 |
+
modified_image = Image.open(BytesIO(modified_image_bytes))
|
24 |
+
|
25 |
+
# Create a new image with a white background of the same size as the modified image
|
26 |
+
new_image = Image.new("RGB", modified_image.size, "white")
|
27 |
+
|
28 |
+
# Paste the modified image onto the white background
|
29 |
+
new_image.paste(modified_image, (0, 0), modified_image)
|
30 |
+
|
31 |
+
# Convert the new image to bytes
|
32 |
+
output_image_bytes = BytesIO()
|
33 |
+
new_image.save(output_image_bytes, format='PNG') # Change format if needed
|
34 |
+
|
35 |
+
return output_image_bytes.getvalue()
|
36 |
+
def find_brackets_indices(s):
|
37 |
+
first_open_bracket = s.find("{")
|
38 |
+
|
39 |
+
if first_open_bracket != -1:
|
40 |
+
second_last_close_bracket = s.rfind("}", first_open_bracket + 1, len(s) - 1)
|
41 |
+
return first_open_bracket, second_last_close_bracket
|
42 |
+
else:
|
43 |
+
return -1, -1 # Return -1 if "{" is not found
|
44 |
+
#pipeline = pipeline(task="image-classification", model="julien-c/hotdog-not-hotdog")
|
45 |
|
46 |
# Set the title and text color to dark green
|
47 |
st.markdown('<h1 style="color:darkgreen;">R3SELL</h1>', unsafe_allow_html=True)
|
48 |
|
49 |
# Create a file input option for uploading an image
|
50 |
+
file_name = st.file_uploader("Upload an image file (JPEG, PNG, etc.)", type=["png", "jpg", "jpeg"])
|
51 |
|
52 |
# Create a camera input widget to capture images from the webcam
|
53 |
image = st.camera_input("Capture an image from your webcam")
|
54 |
|
55 |
# Add a text bar to add a title
|
56 |
+
image_title = st.text_input("Image Title")
|
57 |
+
price = 'Prices: '
|
58 |
+
if image_title != '':
|
59 |
+
price = 'Prices: ' + str(search_ebay_sold_items(image_title))
|
60 |
+
st.write(price)
|
61 |
+
else:
|
62 |
+
st.write(price)
|
63 |
|
64 |
# Add a text bar to add a description
|
65 |
+
#mage_description = st.text_input("Image Description", value="(Optional)")
|
66 |
|
67 |
if file_name is not None or image is not None:
|
68 |
# Check if the image is a webcam image
|
69 |
+
|
70 |
if file_name == 'webcam_image.jpg':
|
71 |
# Use the Base64 encoded image
|
72 |
image = Image.open('data:image/jpeg;base64,' + img_encoded)
|
73 |
else:
|
74 |
# Open the uploaded image
|
75 |
image = Image.open(file_name)
|
76 |
+
|
77 |
+
nameFile = file_name.name
|
78 |
+
def save_uploaded_image_locally(uploaded_file):
|
79 |
+
if uploaded_file is not None:
|
80 |
+
file_path = os.path.join(".", uploaded_file.name)
|
81 |
+
with open(file_path, "wb") as f:
|
82 |
+
f.write(uploaded_file.getbuffer())
|
83 |
+
save_uploaded_image_locally(file_name)
|
84 |
+
st.write('Description: ' + get_quality(abspath(nameFile))[5:])
|
85 |
+
st.write('')
|
86 |
+
st.write('<span style="font-size: 36px;">Modified Image with White Background </span>', unsafe_allow_html=True)
|
87 |
+
image_rem = add_white_background_to_image_bytes(improving_picture(file_name))
|
88 |
|
|
|
|
|
89 |
|
|
|
90 |
|
91 |
|
92 |
+
st.image(image_rem, use_column_width=True)
|
93 |
|
94 |
+
anthropic = Anthropic(
|
95 |
+
api_key="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",
|
96 |
+
)
|
97 |
+
name = str(image_title)
|
98 |
+
description = "get_quality(abspath(nameFile))[5:]"
|
99 |
+
output_price = str(price)
|
100 |
+
s = "Name of Product is "+ name +". Min, 1st quartile, median, 3rd quartile, and max of used prices are "+ price +". Assume max is best used quality and min in worst used quality. Color and defects(consider in price and description) - "+description+"(sub color with official colorname). Generate a price given previous which ends in .99. Feel free to search the web. Video should be a product/review video make sure video is real. Generate a product description and the relevant information for an ebay listing. Search the web for additional help and it should be good for the ebay algorithms. Give it as a JSON with these categories Product Name, Price, Condition, Brand, Type, Color, Description, Specifications, Size, Video, Department. Generate Facebook and Instagram ads with hashtags and other stuff to boost algorithm. "
|
101 |
+
promp = "\n\nHuman ${userQuestion}\n\nAssistant:"
|
102 |
+
completion = anthropic.completions.create(
|
103 |
+
model="claude-2",
|
104 |
+
max_tokens_to_sample=1000,
|
105 |
+
prompt=f"{HUMAN_PROMPT} "+s+f" {AI_PROMPT}",
|
106 |
+
)
|
107 |
+
first_index, second_to_last_index = find_brackets_indices(completion.completion)
|
108 |
+
string_data = completion.completion[first_index:second_to_last_index + 1]
|
109 |
+
print(list(convert_string_to_dict(string_data).values()))
|
110 |
+
for key, value in convert_string_to_dict(string_data).items():
|
111 |
+
st.write(f'{key}: {value}')
|
112 |
+
st.write(completion.completion[second_to_last_index + 1:])
|
ebay.py
ADDED
@@ -0,0 +1,64 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import requests
|
2 |
+
from bs4 import BeautifulSoup
|
3 |
+
import pandas as pd
|
4 |
+
import numpy as np
|
5 |
+
|
6 |
+
def get_item_description(item_url):
|
7 |
+
response = requests.get(item_url)
|
8 |
+
soup = BeautifulSoup(response.text, 'html.parser')
|
9 |
+
|
10 |
+
iframe = soup.find(id='desc_ifr')
|
11 |
+
if iframe:
|
12 |
+
iframe_src = iframe['src']
|
13 |
+
iframe_response = requests.get(iframe_src)
|
14 |
+
iframe_soup = BeautifulSoup(iframe_response.text, 'html.parser')
|
15 |
+
return iframe_soup.get_text(strip=True)
|
16 |
+
else:
|
17 |
+
return 'No Description'
|
18 |
+
|
19 |
+
|
20 |
+
def search_ebay_sold_items(search_query):
|
21 |
+
# Replace spaces in the search query with '+'
|
22 |
+
query = search_query.replace(' ', '+')
|
23 |
+
counter = 0
|
24 |
+
|
25 |
+
prices = []
|
26 |
+
img_urls = []
|
27 |
+
for pgn in range(2):
|
28 |
+
|
29 |
+
if (counter == 100):
|
30 |
+
break
|
31 |
+
counter += 1
|
32 |
+
# eBay URL for sold listings
|
33 |
+
url = f"https://www.ebay.com/sch/i.html?_nkw={query}&_sop=12&LH_Sold=1&LH_Complete=1&rt=nc&LH_ItemCondition=3000&_pgn={pgn}"
|
34 |
+
|
35 |
+
# Send a request to the eBay URL
|
36 |
+
response = requests.get(url)
|
37 |
+
|
38 |
+
# Parse the response using BeautifulSoup
|
39 |
+
soup = BeautifulSoup(response.text, 'html.parser')
|
40 |
+
|
41 |
+
# Find listings - Adjust the selector as needed
|
42 |
+
listings = soup.find_all('li', class_='s-item')
|
43 |
+
|
44 |
+
|
45 |
+
# Extract and print details from each listing
|
46 |
+
for item in listings[1:]:
|
47 |
+
price = item.find('span', class_='s-item__price').text if item.find('span', class_='s-item__price') else 'No Price'
|
48 |
+
|
49 |
+
img_div = item.find('div', class_='s-item__image-wrapper')
|
50 |
+
img_url = img_div.find('img')['src'] if img_div and img_div.find('img') else 'No Image URL'
|
51 |
+
try:
|
52 |
+
prices.append(float(price.replace("$","").replace(",",'')))
|
53 |
+
except:
|
54 |
+
pass
|
55 |
+
img_urls.append(img_url)
|
56 |
+
|
57 |
+
prices = np.array(prices)
|
58 |
+
stats = min(prices), np.percentile(prices, 25), np.percentile(prices, 50), np.percentile(prices, 75), max(prices)
|
59 |
+
|
60 |
+
return stats
|
61 |
+
|
62 |
+
|
63 |
+
|
64 |
+
|
llava.py
ADDED
@@ -0,0 +1,49 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from selenium import webdriver
|
2 |
+
from selenium.webdriver.common.by import By
|
3 |
+
from selenium.webdriver.common.keys import Keys
|
4 |
+
import time
|
5 |
+
from selenium.webdriver.common.by import By
|
6 |
+
|
7 |
+
|
8 |
+
driver = webdriver.Chrome()
|
9 |
+
|
10 |
+
# Navigate to the website
|
11 |
+
driver.get("https://llava-vl.github.io/")
|
12 |
+
element = driver.find_element(By.CSS_SELECTOR,'gradio-app')
|
13 |
+
|
14 |
+
driver.execute_script("arguments[0].scrollIntoView();", element)
|
15 |
+
|
16 |
+
# Wait for the page to load (adjust the time as needed)
|
17 |
+
time.sleep(2)
|
18 |
+
|
19 |
+
# Uploading an image
|
20 |
+
|
21 |
+
def get_quality(image_path):
|
22 |
+
|
23 |
+
# Replace '/path/to/your/image.jpg' with the path to your image
|
24 |
+
file_input = driver.find_element(By.CSS_SELECTOR, 'input[type="file"]')
|
25 |
+
file_input.send_keys(image_path)
|
26 |
+
|
27 |
+
# Wait for the upload to complete (adjust time as needed)
|
28 |
+
time.sleep(5)
|
29 |
+
|
30 |
+
# Locate the textarea element
|
31 |
+
textarea = driver.find_element(By.CSS_SELECTOR, 'textarea.svelte-4xt1ch')
|
32 |
+
|
33 |
+
# Type your message
|
34 |
+
message = "I am planning to resell this product. Please identify any defects or issues or seems worn out or any scratches. Also, what is the color of product. Start your response with the word ANS"
|
35 |
+
textarea.send_keys(message)
|
36 |
+
|
37 |
+
textarea.send_keys(Keys.ENTER)
|
38 |
+
|
39 |
+
# Wait for the action to complete (adjust time as needed)
|
40 |
+
time.sleep(30)
|
41 |
+
|
42 |
+
# Close the browser (optional)
|
43 |
+
element = driver.find_elements(By.XPATH, "//*[contains(text(), 'ANS')]")[1]
|
44 |
+
|
45 |
+
|
46 |
+
ans = element.text
|
47 |
+
|
48 |
+
|
49 |
+
return ans
|
main.py
ADDED
@@ -0,0 +1,8 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from ebay import search_ebay_sold_items
|
2 |
+
|
3 |
+
from llava import get_quality
|
4 |
+
from os.path import abspath
|
5 |
+
|
6 |
+
name = "miles morales jordan 1"
|
7 |
+
print(search_ebay_sold_items(name))
|
8 |
+
print(get_quality(abspath('shoes.jpeg')))
|