karolkrusz commited on
Commit
be8708a
·
1 Parent(s): a3a9b2c

init prod test

Browse files
.idea/.gitignore ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ # Default ignored files
2
+ /shelf/
3
+ /workspace.xml
.idea/Siloshot-Generator.iml ADDED
@@ -0,0 +1,8 @@
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <module type="PYTHON_MODULE" version="4">
3
+ <component name="NewModuleRootManager">
4
+ <content url="file://$MODULE_DIR$" />
5
+ <orderEntry type="inheritedJdk" />
6
+ <orderEntry type="sourceFolder" forTests="false" />
7
+ </component>
8
+ </module>
.idea/inspectionProfiles/Project_Default.xml ADDED
@@ -0,0 +1,20 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <component name="InspectionProjectProfileManager">
2
+ <profile version="1.0">
3
+ <option name="myName" value="Project Default" />
4
+ <inspection_tool class="PyPackageRequirementsInspection" enabled="true" level="WARNING" enabled_by_default="true">
5
+ <option name="ignoredPackages">
6
+ <value>
7
+ <list size="7">
8
+ <item index="0" class="java.lang.String" itemvalue="huggingface_hub" />
9
+ <item index="1" class="java.lang.String" itemvalue="glob2" />
10
+ <item index="2" class="java.lang.String" itemvalue="playwright" />
11
+ <item index="3" class="java.lang.String" itemvalue="uvicorn" />
12
+ <item index="4" class="java.lang.String" itemvalue="fastapi" />
13
+ <item index="5" class="java.lang.String" itemvalue="pydantic" />
14
+ <item index="6" class="java.lang.String" itemvalue="matplotlib" />
15
+ </list>
16
+ </value>
17
+ </option>
18
+ </inspection_tool>
19
+ </profile>
20
+ </component>
.idea/inspectionProfiles/profiles_settings.xml ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
 
1
+ <component name="InspectionProjectProfileManager">
2
+ <settings>
3
+ <option name="USE_PROJECT_PROFILE" value="false" />
4
+ <version value="1.0" />
5
+ </settings>
6
+ </component>
.idea/misc.xml ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <project version="4">
3
+ <component name="Black">
4
+ <option name="sdkName" value="Python 3.12" />
5
+ </component>
6
+ <component name="ProjectRootManager" version="2" project-jdk-name="Python 3.12" project-jdk-type="Python SDK" />
7
+ </project>
.idea/modules.xml ADDED
@@ -0,0 +1,8 @@
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <project version="4">
3
+ <component name="ProjectModuleManager">
4
+ <modules>
5
+ <module fileurl="file://$PROJECT_DIR$/.idea/Siloshot-Generator.iml" filepath="$PROJECT_DIR$/.idea/Siloshot-Generator.iml" />
6
+ </modules>
7
+ </component>
8
+ </project>
.idea/vcs.xml ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
 
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <project version="4">
3
+ <component name="VcsDirectoryMappings">
4
+ <mapping directory="" vcs="Git" />
5
+ </component>
6
+ </project>
Dockerfile ADDED
@@ -0,0 +1,43 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ FROM python:3.9
2
+
3
+ # Install necessary dependencies
4
+ RUN apt-get update && apt-get install -y \
5
+ libnss3 \
6
+ libnspr4 \
7
+ libatk1.0-0 \
8
+ libatk-bridge2.0-0 \
9
+ libcups2 \
10
+ libatspi2.0-0 \
11
+ libxcomposite1 \
12
+ libxdamage1 \
13
+ libxrandr2 \
14
+ libgbm-dev \
15
+ libgtk-3-0 \
16
+ xdg-utils \
17
+ && rm -rf /var/lib/apt/lists/*
18
+
19
+ # Install Python dependencies
20
+ RUN pip install --upgrade pip
21
+ COPY requirements.txt .
22
+ RUN pip install -r requirements.txt
23
+
24
+ # Install Playwright and download the required browsers
25
+ RUN playwright install --with-deps
26
+
27
+ # Create and switch to a non-root user
28
+ RUN useradd -m -u 1000 user
29
+ USER user
30
+ ENV PATH="/home/user/.local/bin:$PATH"
31
+
32
+ # Ensure Playwright browsers are installed for the non-root user
33
+ RUN playwright install
34
+ RUN pip install python-multipart
35
+
36
+ # Set working directory
37
+ WORKDIR /app
38
+
39
+ # Copy application code
40
+ COPY --chown=user . /app
41
+
42
+ # Run the application
43
+ CMD ["uvicorn", "app:app", "--host", "0.0.0.0", "--port", "7860"]
app.py ADDED
@@ -0,0 +1,110 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import re
3
+ import io
4
+ import zipfile
5
+ import tempfile
6
+ import requests
7
+ from fastapi import FastAPI, HTTPException, Form
8
+ from fastapi.responses import StreamingResponse
9
+ from playwright.async_api import async_playwright
10
+ from bs4 import BeautifulSoup
11
+
12
+ app = FastAPI()
13
+
14
+ @app.get("/")
15
+ async def read_root():
16
+ return {"message": "Hello, World!"}
17
+
18
+
19
+ async def login(page, username, password):
20
+ await page.goto("https://portal.intiaro.com/login?configuratorVersion=2.5")
21
+ await page.fill('input[name="userName"]', username)
22
+ await page.fill('input[name="password"]', password)
23
+ await page.click('button[type=submit]')
24
+ await page.wait_for_timeout(2000) # Wait for navigation after login
25
+
26
+
27
+ async def siloshot_making(page):
28
+ await page.wait_for_timeout(5000) # Wait for the page to fully load
29
+ html = await page.content()
30
+ soup = BeautifulSoup(html, 'html.parser')
31
+ slider = soup.find('img', class_='slider-image')
32
+ img = slider.get('src')
33
+ return img
34
+
35
+
36
+ def generate_urls(img, start_angle=0, end_angle=360, step=10):
37
+ angle_pattern = re.compile(r'(angle/)(\d+)')
38
+ match = angle_pattern.search(img)
39
+ if match:
40
+ base_url = img[:match.start(2)] # Base URL up to the angle value
41
+
42
+ urls = []
43
+ for angle in range(start_angle, end_angle + 1, step):
44
+ new_url = re.sub(r'angle/\d+', f'angle/{angle}', img)
45
+ urls.append(new_url)
46
+ return urls
47
+
48
+
49
+ async def download_images(img_urls, product_name):
50
+ angle_pattern = re.compile(r'angle/(\d+)')
51
+ count_img_downloaded = 0
52
+ image_paths = []
53
+
54
+ with tempfile.TemporaryDirectory() as tmpdirname:
55
+ for img_url in img_urls:
56
+ try:
57
+ img_response = requests.get(img_url)
58
+ img_response.raise_for_status()
59
+ angle_match = angle_pattern.search(img_url)
60
+ if angle_match:
61
+ angle_value = angle_match.group(1)
62
+ img_name = f"{product_name}_{angle_value}.png"
63
+ else:
64
+ img_name = "product_unknown.jpg"
65
+ img_path = os.path.join(tmpdirname, img_name)
66
+ image_paths.append(img_path)
67
+ with open(img_path, 'wb') as file:
68
+ file.write(img_response.content)
69
+ count_img_downloaded += 1
70
+ except Exception as e:
71
+ print(f'Failed to download {img_url}: {e}')
72
+
73
+ zip_buffer = io.BytesIO()
74
+ with zipfile.ZipFile(zip_buffer, 'w') as zipf:
75
+ for img_path in image_paths:
76
+ zipf.write(img_path, os.path.basename(img_path))
77
+
78
+ zip_buffer.seek(0)
79
+ return zip_buffer
80
+
81
+
82
+ async def process_images(username, password, product_url, product_name):
83
+ async with async_playwright() as playwright:
84
+ browser = await playwright.chromium.launch(headless=True)
85
+ context = await browser.new_context()
86
+ page = await context.new_page()
87
+ await login(page, username, password)
88
+ await page.goto(product_url)
89
+ img = await siloshot_making(page)
90
+ img_urls = generate_urls(img, start_angle=0, end_angle=360, step=10)
91
+ zip_buffer = await download_images(img_urls, product_name)
92
+ await browser.close()
93
+ return zip_buffer
94
+
95
+
96
+ @app.post("/generate-images/")
97
+ async def generate_images(username: str = Form(...), password: str = Form(...), product_url: str = Form(...),
98
+ product_name: str = Form(...)):
99
+ if not (username and password and product_url and product_name):
100
+ raise HTTPException(status_code=400, detail="All input fields are required.")
101
+
102
+ zip_buffer = await process_images(username, password, product_url, product_name)
103
+ return StreamingResponse(zip_buffer, media_type="application/zip",
104
+ headers={"Content-Disposition": f"attachment; filename={product_name}_images.zip"})
105
+
106
+
107
+ if __name__ == "__main__":
108
+ import uvicorn
109
+
110
+ uvicorn.run(app, host="0.0.0.0", port=7860)
requirements.txt ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ aiofiles==23.2.1
2
+ beautifulsoup4==4.12.3
3
+ fastapi==0.95.2
4
+ packaging==24.1
5
+ pandas==2.2.2
6
+ playwright==1.39.0
7
+ pydantic==1.8.2
8
+ python-multipart==0.0.9
9
+ requests==2.32.3
10
+ urllib3==2.2.2
11
+ uvicorn==0.22.0
12
+ watchfiles==0.22.0
13
+ websockets==12.0
14
+ glob2==0.7