From 3b9f8fa03871ecc8dd1159f8a7caa8a21772761d Mon Sep 17 00:00:00 2001 From: bartool Date: Thu, 16 Oct 2025 16:42:08 +0200 Subject: [PATCH] DZIALA --- gsheet_api.py | 103 +++++++++++++++++++++++++----------------- info.txt | 37 +++++++++++++++ main.py | 123 ++++++++++++++++++++++++++------------------------ 3 files changed, 162 insertions(+), 101 deletions(-) create mode 100644 info.txt diff --git a/gsheet_api.py b/gsheet_api.py index e8df731..3ebeb24 100644 --- a/gsheet_api.py +++ b/gsheet_api.py @@ -6,54 +6,75 @@ SCOPES = [ "https://www.googleapis.com/auth/drive" ] -def connect(): - creds = Credentials.from_service_account_file("credentials.json", scopes=SCOPES) - client = gspread.authorize(creds) - return client +class GSheetAPI: + def __init__(self, credentials_file="credentials.json"): + """Inicjalizuje klienta API przy tworzeniu obiektu.""" + creds = Credentials.from_service_account_file(credentials_file, scopes=SCOPES) + self.client = gspread.authorize(creds) + print("✅ Połączono z Google Sheets API.") + def list_sheets(self, doc_name): + """Zwraca listę arkuszy w danym dokumencie.""" + spreadsheet = self.client.open(doc_name) + return [ws.title for ws in spreadsheet.worksheets()] -def list_sheets(doc_name): - client = connect() - spreadsheet = client.open(doc_name) - return [ws.title for ws in spreadsheet.worksheets()] + def get_sheet_data(self, doc_name, sheet_name): + """Pobiera wszystkie dane z danego arkusza.""" + sheet = self.client.open(doc_name).worksheet(sheet_name) + return sheet.get_all_values() + def ensure_worksheet(self, doc_name, sheet_name): + """ + Zwraca worksheet o danej nazwie. + Tworzy nowy, jeśli nie istnieje. + """ + spreadsheet = self.client.open(doc_name) + try: + ws = spreadsheet.worksheet(sheet_name) + except gspread.exceptions.WorksheetNotFound: + print(f"➕ Tworzę nowy arkusz: {sheet_name}") + ws = spreadsheet.add_worksheet(title=sheet_name, rows=100, cols=10) + ws.append_row(["#", "Link", "Nr zamówienia", "Model", "Wykończenie", "Kolor Top", "Kolor Body", "Kolor Neck", "Kolor Head", "Finish"]) + return ws -def get_sheet_data(doc_name, sheet_name): - client = connect() - sheet = client.open(doc_name).worksheet(sheet_name) - return sheet.get_all_values() + def batch_append_unique_rows(self, doc_name, sheet_name, rows_data): + """ + Dodaje wiele wierszy za jednym razem, pomijając te, + których nr zamówienia (kolumna 3) już istnieje. + """ + if not rows_data: + print("ℹ️ Brak danych do dodania.") + return + ws = self.ensure_worksheet(doc_name, sheet_name) -def ensure_worksheet(doc_name, sheet_name): - """ - Zwraca worksheet o danej nazwie. - Tworzy nowy, jeśli nie istnieje. - """ - client = connect() - spreadsheet = client.open(doc_name) - try: - ws = spreadsheet.worksheet(sheet_name) - except gspread.exceptions.WorksheetNotFound: - print(f"➕ Tworzę nowy arkusz: {sheet_name}") - ws = spreadsheet.add_worksheet(title=sheet_name, rows=100, cols=10) - ws.append_row(["#", "Link", "Nr zamówienia", "Model"]) - return ws + # 1. Pobierz wszystkie istniejące numery zamówień w JEDNYM zapytaniu + print("🔍 Sprawdzam istniejące numery zamówień w arkuszu docelowym...") + # existing_orders = set(ws.col_values(3)) + existing_orders = {str(x).strip() for x in ws.col_values(3)} + print(f"Znaleziono {len(existing_orders)} istniejących numerów.\n existing_orders: {existing_orders}") -def append_unique_row(doc_name, sheet_name, row_data): - """ - Dodaje wiersz tylko, jeśli dany nr zamówienia (kolumna 3) jeszcze nie istnieje. - """ - client = connect() - ws = ensure_worksheet(doc_name, sheet_name) + # 2. Filtruj nowe wiersze, aby znaleźć tylko te unikalne + unique_rows_to_add = [] + for row in rows_data: + order_number = str(row[2]).strip() + # print(f"order_number: '{order_number}'", end="") + if order_number not in existing_orders: + # print(f" not in existing_order!", end="") + unique_rows_to_add.append(row) + # Dodaj nowo dodany numer do seta, aby uniknąć duplikatów w ramach jednej paczki + existing_orders.add(order_number) + # print(" ") - existing = ws.col_values(3) # kolumna "Nr zamówienia" - order_number = str(row_data[2]).strip() + # 3. Dodaj wszystkie unikalne wiersze w JEDNYM zapytaniu + if unique_rows_to_add: + print(f"📝 Dodaję {len(unique_rows_to_add)} nowych unikalnych wierszy do arkusza {sheet_name}...") + ws.append_rows(unique_rows_to_add, value_input_option="USER_ENTERED") # type: ignore + print("✅ Zakończono dodawanie.") + else: + print("ℹ️ Nie znaleziono żadnych nowych wierszy do dodania.") - if order_number in existing: - print(f"⏭️ Pomijam – nr {order_number} już istnieje w arkuszu {sheet_name}") - return False - - ws.append_row(row_data, value_input_option="USER_ENTERED") - print(f"📝 Dodano do {sheet_name}: {row_data}") - return True + skipped_count = len(rows_data) - len(unique_rows_to_add) + if skipped_count > 0: + print(f"⏭️ Pominięto {skipped_count} wierszy, które już istniały w arkuszu.") \ No newline at end of file diff --git a/info.txt b/info.txt new file mode 100644 index 0000000..9fb27d0 --- /dev/null +++ b/info.txt @@ -0,0 +1,37 @@ + ori.html: + KOLOR - Korpus + - M-GUNGRY-MTL-M + KOLOR - Szyjka + - T-NAT-M + KOLOR - Główka + - T-NAT-M + KOLOR - Wykończenie [K/C] + - M + KOLOR - Wykończenie [S] + - M + +Aquila.html: + KOLOR - Top + - T-ANTIQUE-BLK-M + KOLOR - Korpus + - T-ANTIQUE-BLK-M + KOLOR - Szyjka + - T-ANTIQUE-BLK-M + KOLOR - Główka + - T-ANTIQUE-BLK-M + KOLOR - Wykończenie [K/C] + - M + KOLOR - Wykończenie [S] + - M + +regius.html: + KOLOR - Top + - T-BLU-SPR-G + KOLOR - Korpus + - T-CST-M + KOLOR - Szyjka + - T-CST-M + KOLOR - Główka + - T-BLU-SPR-G + KOLOR - Wykończenie [K/C] + - G+M \ No newline at end of file diff --git a/main.py b/main.py index 09df005..5da8401 100644 --- a/main.py +++ b/main.py @@ -1,4 +1,4 @@ -from gsheet_api import list_sheets, get_sheet_data, append_unique_row +from gsheet_api import GSheetAPI from mayo import MayoSession from dotenv import load_dotenv import os @@ -6,48 +6,29 @@ import re load_dotenv() -# --- konfiguracja ---pip list +# --- konfiguracja --- DOC_NAME = os.getenv("DOC_NAME") MAYO_URL = os.getenv("MAYO_URL") LOGIN = os.getenv("MAYO_LOGIN") PASSWORD = os.getenv("MAYO_PASSWORD") RESULT_DOC = "gitary 2025" - - def normalize(text): if not text: return "" - # usuwa spacje, niełamliwe spacje, nowe linie itp. return re.sub(r"\s+", "", text) def get_finish_type(row_data): - """ - Analizuje dane z listy wiersza, aby określić rodzaj wykończenia. - - Args: - row_data: Lista zawierająca dane zamówienia, gdzie: - - row_data[4] to 'color_top' - - row_data[5] to 'color_body' - - Returns: - Ciąg znaków: "GLOSS", "SATIN", "MIX", lub "MAT" na podstawie - ostatnich liter w kodach kolorów. Zwraca None, jeśli żaden - warunek nie jest spełniony. - """ try: color_top = row_data["color_top"].strip() color_body = row_data["color_body"].strip() - # Sprawdzenie, czy dane są dostępne if not color_top or not color_body: return None - # Pobranie ostatniej litery z kodów kolorów top_last_char = color_top[-1] body_last_char = color_body[-1] - # Warunki logiczne if top_last_char == 'G' and body_last_char == 'G': return "GLOSS" elif top_last_char == 'S' and body_last_char == 'S': @@ -56,29 +37,42 @@ def get_finish_type(row_data): return "MIX" elif top_last_char in ('M', 'R') and body_last_char in ('M', 'R'): return "MAT" - except: - return None # Zwraca None, jeśli żaden z powyższych warunków nie zostanie spełniony - - + except (KeyError, AttributeError): + return None + return None def main(): - print("📄 Pobieram listę arkuszy...") - sheets = list_sheets(DOC_NAME) - for i, name in enumerate(sheets): - print(f"{i+1}. {name}") + # Inicjalizuj API raz na początku + gsheet_api = GSheetAPI() + + print("📄 Pobieram listę arkuszy...") + try: + sheets = gsheet_api.list_sheets(DOC_NAME) + for i, name in enumerate(sheets): + print(f"{i+1}. {name}") + except Exception as e: + print(f"❌ Błąd podczas pobierania listy arkuszy: {e}") + return - # wybór arkusza (na razie manualny) sheet_name = input("\nWybierz arkusz do przetworzenia: ") print(f"📋 Pobieram dane z arkusza: {sheet_name}") - rows = get_sheet_data(DOC_NAME, sheet_name) + try: + rows = gsheet_api.get_sheet_data(DOC_NAME, sheet_name) + except Exception as e: + print(f"❌ Błąd podczas pobierania danych z arkusza: {e}") + return mayo = MayoSession(MAYO_URL, LOGIN, PASSWORD) mayo.login() + rows_to_process = [] counter = 1 # Zakładamy: kolumna B = link, kolumna C = nr zam. - for row in rows[1:]: # pomijamy nagłówek + for row in rows[1:]: + if len(row) < 3: + continue # Pomiń wiersze, które nie mają wystarczającej liczby kolumn + link = row[1] nr_zam = row[2] @@ -86,37 +80,46 @@ def main(): continue print(f"\n🔗 Sprawdzam: {link}") - info = mayo.get_order_info(link) - order_number = info["order_number"] - model = info["model"] + try: + info = mayo.get_order_info(link) + order_number = info["order_number"] + model = info["model"] - print(f"Nr z arkusza: {nr_zam}") - print(f"Nr ze strony: {info['order_number']}") - print(f"Model: {info['model']}") + print(f"Nr z arkusza: {nr_zam}") + print(f"Nr ze strony: {order_number}") + print(f"Model: {model}") - if normalize(info["order_number"]) == normalize(nr_zam): - print("✅ Numer się zgadza") - else: - print("⚠️ Numer NIE pasuje!") + if normalize(order_number) == normalize(nr_zam): + print("✅ Numer się zgadza") + else: + print("⚠️ Numer NIE pasuje!") - row_data = [ - counter, - link, - nr_zam, - model, - get_finish_type(info), - info["color_top"], - info["color_body"], - info["color_neck"], - info["color_head"], - info["finish"], - ] - - print(f"top: {info['color_top']}, body: {info['color_body']}, neck: {info['color_neck']}, head: {info['color_head']}, finish: {info["finish"]}") - print(f"WYKONCZENIE: {get_finish_type(info)}") - append_unique_row(RESULT_DOC, sheet_name, row_data) + row_data = [ + counter, + link, + nr_zam, + model, + get_finish_type(info), + info.get("color_top"), + info.get("color_body"), + info.get("color_neck"), + info.get("color_head"), + info.get("finish"), + ] + + rows_to_process.append(row_data) + counter += 1 - counter += 1 + except Exception as e: + print(f"❌ Błąd podczas przetwarzania linku {link}: {e}") + + # Po zakończeniu pętli, dodaj wszystkie zebrane wiersze za jednym razem + if rows_to_process: + print(f"\n\n--- Podsumowanie ---") + print(f"Zebrano {len(rows_to_process)} wierszy do przetworzenia.") + gsheet_api.batch_append_unique_rows(RESULT_DOC, sheet_name, rows_to_process) + else: + print("\nNie zebrano żadnych danych do przetworzenia.") if __name__ == "__main__": - main() + main() \ No newline at end of file