From 7ba8d5525280a9a62e9b844f8dd660a03d485241 Mon Sep 17 00:00:00 2001 From: Shikiryu Date: Fri, 13 Sep 2024 00:59:04 +0200 Subject: [PATCH 1/2] =?UTF-8?q?=F0=9F=9A=A7=20Add=20Quickposes=20model=20d?= =?UTF-8?q?ownload?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- requirements.txt | 3 ++- src/window/app.py | 43 +++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 43 insertions(+), 3 deletions(-) diff --git a/requirements.txt b/requirements.txt index 2fcfc81..c0f2b03 100644 --- a/requirements.txt +++ b/requirements.txt @@ -3,4 +3,5 @@ pyinstaller==5.13.1 pygame~=2.4.0 customtkinter~=5.1.3 configparser~=5.3.0 -CTkToolTip~=0.4 \ No newline at end of file +CTkToolTip~=0.4 +requests~=2.32.3 \ No newline at end of file diff --git a/src/window/app.py b/src/window/app.py index eb95851..50752e7 100644 --- a/src/window/app.py +++ b/src/window/app.py @@ -1,8 +1,16 @@ +import io +import os +import tempfile import tkinter from pathlib import Path from tkinter import * from tkinter import filedialog + +from datetime import datetime import customtkinter +import requests +from PIL import Image + from src.entity.config import Config from src.util import Util from src.window.image import ImageWindow @@ -25,6 +33,10 @@ class App: self.title = customtkinter.CTkLabel(root, text="Drawing Training") self.title.pack() + self.download_from_reference = customtkinter.CTkButton(root, text="Download 3 images from sketch daily", + command=self.download_from_reference) + self.download_from_reference.pack() + self.folder_selector = customtkinter.CTkButton(root, text="Select a folder", command=self.select_folder) self.folder_selector.pack() @@ -49,7 +61,8 @@ class App: self.buttons = [] for i, timer in enumerate(timers): - new_button = customtkinter.CTkButton(self.button_frame, width=10, text=timer, command=lambda t=timer: self.set_timer_in_seconds(t)) + new_button = customtkinter.CTkButton(self.button_frame, width=10, text=timer, + command=lambda t=timer: self.set_timer_in_seconds(t)) new_button.pack(side=tkinter.LEFT, fill=X, expand=True) self.buttons.append(new_button) @@ -83,6 +96,31 @@ class App: self.find_images_in_folder() self.check_lets_draw() + def download_from_reference(self): + dt = datetime.now() + ts = int(datetime.timestamp(dt)) + url = 'https://quickposes.com/ajax/getPosesForSlider/Chiaroscuro?_=' + str(ts) + + resp_json = requests.get(url=url) + if resp_json.status_code == 200: + data = resp_json.json() + c = 0 + for src in data: + if c >= 3: + break + buffer = tempfile.SpooledTemporaryFile(max_size=1e9) + r = requests.get('https://quickposes.com/assets/poses/' + src['src'], stream=True) + if r.status_code == 200: + downloaded = 0 + for chunk in r.iter_content(chunk_size=1024): + downloaded += len(chunk) + buffer.write(chunk) + buffer.seek(0) + i = Image.open(io.BytesIO(buffer.read())) + i.save(os.path.join(self.selected_folder, src['src']), quality=85) + buffer.close() + c += 1 + def find_images_in_folder(self): if Path(self.selected_folder).exists(): self.found_images = list( @@ -99,7 +137,8 @@ class App: def set_timer_in_seconds(self, user_data): # resetting buttons states for button in self.buttons: - button.configure(fg_color=(Util.get_default_button_color() if user_data != button.cget("text") else Util.get_default_active_button_color())) + button.configure(fg_color=(Util.get_default_button_color() if user_data != button.cget( + "text") else Util.get_default_active_button_color())) self.custom = False if user_data == "Custom": -- 2.30.2 From 312f481eb3f05a3110bbaa128bd33e8687746e5a Mon Sep 17 00:00:00 2001 From: Clement Desmidt Date: Fri, 13 Sep 2024 17:51:58 +0200 Subject: [PATCH 2/2] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20Refactor=20generators?= =?UTF-8?q?=20and=20add=20an=20about=20window?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- requirements.txt | 3 ++- src/entity/generator.py | 41 ++++++++++++++++++++++++++++++ src/window/about.py | 30 ++++++++++++++++++++++ src/window/app.py | 56 +++++++++++++++-------------------------- 4 files changed, 93 insertions(+), 37 deletions(-) create mode 100644 src/entity/generator.py create mode 100644 src/window/about.py diff --git a/requirements.txt b/requirements.txt index c0f2b03..46ce4e2 100644 --- a/requirements.txt +++ b/requirements.txt @@ -4,4 +4,5 @@ pygame~=2.4.0 customtkinter~=5.1.3 configparser~=5.3.0 CTkToolTip~=0.4 -requests~=2.32.3 \ No newline at end of file +requests~=2.32.3 +CTkMenuBar~=0.8 \ No newline at end of file diff --git a/src/entity/generator.py b/src/entity/generator.py new file mode 100644 index 0000000..d57afed --- /dev/null +++ b/src/entity/generator.py @@ -0,0 +1,41 @@ +from datetime import datetime +import os +import io +import tempfile +import requests +from PIL import Image + + +class Generator(object): + + def __init__(self, generator=None, folder=None): + self.selected_folder = folder + if generator == 'poses': + self.generate_poses() + + def generate_poses(self): + dt = datetime.now() + ts = int(datetime.timestamp(dt)) + url = 'https://quickposes.com/ajax/getPosesForSlider/Chiaroscuro?_=' + str(ts) + + resp_json = requests.get(url=url) + if resp_json.status_code == 200: + data = resp_json.json() + c = 0 + for src in data: + if os.path.exists(os.path.join(self.selected_folder, src['src'])): + continue + if c >= 3: + break + buffer = tempfile.SpooledTemporaryFile(max_size=1e9) + r = requests.get('https://quickposes.com/assets/poses/' + src['src'], stream=True) + if r.status_code == 200: + downloaded = 0 + for chunk in r.iter_content(chunk_size=1024): + downloaded += len(chunk) + buffer.write(chunk) + buffer.seek(0) + i = Image.open(io.BytesIO(buffer.read())) + i.save(os.path.join(self.selected_folder, src['src']), quality=85) + buffer.close() + c += 1 diff --git a/src/window/about.py b/src/window/about.py new file mode 100644 index 0000000..f1ab016 --- /dev/null +++ b/src/window/about.py @@ -0,0 +1,30 @@ +import webbrowser + +import customtkinter +from customtkinter import CTkToplevel + + +class AboutWindow: + def __init__(self, app): + self.app = app + + self.window = CTkToplevel(app.root) + self.window.title("À propos") + self.window.geometry("600x300") + self.window.protocol("WM_DELETE_WINDOW", self.on_closing) + + link_gesture_drawing = customtkinter.CTkLabel(self.window, text="Open Source alternative to GestureDrawing!") + link_gesture_drawing.pack() + link_gesture_drawing.bind("", + lambda e: self.open_link("https://cubebrush.co/advanches/products/d9q6yq/gesturedrawing")) + + link_shikiryu = customtkinter.CTkLabel(self.window, text="by Shikiryu") + link_shikiryu.pack() + link_shikiryu.bind("", lambda e: self.open_link("https://shikiryu.com")) + + @staticmethod + def open_link(url): + webbrowser.open_new(url) + + def on_closing(self): + self.window.destroy() diff --git a/src/window/app.py b/src/window/app.py index 50752e7..8d4d270 100644 --- a/src/window/app.py +++ b/src/window/app.py @@ -1,20 +1,15 @@ -import io -import os -import tempfile import tkinter from pathlib import Path from tkinter import * from tkinter import filedialog - -from datetime import datetime import customtkinter -import requests -from PIL import Image - from src.entity.config import Config +from src.entity.generator import Generator from src.util import Util +from src.window.about import AboutWindow from src.window.image import ImageWindow from src.window.session import SessionWindow +from CTkMenuBar import * class App: @@ -30,13 +25,20 @@ class App: self.selected_folder = "" self.found_images = [] self.timer = 0 + + menu = CTkMenuBar(master=root) + generate_button = menu.add_cascade("Generate") + help_button = menu.add_cascade("Help") + + dropdown = CustomDropdownMenu(widget=generate_button) + dropdown.add_option(option="Poses", command=lambda:self.download_poses('poses')) + + about = CustomDropdownMenu(widget=help_button) + about.add_option(option="À propos", command=self.show_help) + self.title = customtkinter.CTkLabel(root, text="Drawing Training") self.title.pack() - self.download_from_reference = customtkinter.CTkButton(root, text="Download 3 images from sketch daily", - command=self.download_from_reference) - self.download_from_reference.pack() - self.folder_selector = customtkinter.CTkButton(root, text="Select a folder", command=self.select_folder) self.folder_selector.pack() @@ -79,6 +81,9 @@ class App: except Exception: pass + def show_help(self): + AboutWindow(self) + def lets_draw(self): self.image_window = ImageWindow(self) self.image_window.lets_draw(self.found_images.copy(), self.timer) @@ -96,30 +101,9 @@ class App: self.find_images_in_folder() self.check_lets_draw() - def download_from_reference(self): - dt = datetime.now() - ts = int(datetime.timestamp(dt)) - url = 'https://quickposes.com/ajax/getPosesForSlider/Chiaroscuro?_=' + str(ts) - - resp_json = requests.get(url=url) - if resp_json.status_code == 200: - data = resp_json.json() - c = 0 - for src in data: - if c >= 3: - break - buffer = tempfile.SpooledTemporaryFile(max_size=1e9) - r = requests.get('https://quickposes.com/assets/poses/' + src['src'], stream=True) - if r.status_code == 200: - downloaded = 0 - for chunk in r.iter_content(chunk_size=1024): - downloaded += len(chunk) - buffer.write(chunk) - buffer.seek(0) - i = Image.open(io.BytesIO(buffer.read())) - i.save(os.path.join(self.selected_folder, src['src']), quality=85) - buffer.close() - c += 1 + def download_poses(self, generator=None): + Generator(generator=generator, folder=self.selected_folder) + self.find_images_in_folder() def find_images_in_folder(self): if Path(self.selected_folder).exists(): -- 2.30.2