from flask import Flask, request, jsonify, render_template_string from google.oauth2.service_account import Credentials from googleapiclient.discovery import build from googleapiclient.http import MediaIoBaseUpload import os import io import datetime import json app = Flask(__name__) SPREADSHEET_ID = '1rcIJflbC1VIc70F6dnASLFvGQ90TXHhCx0iyxsXR7Ww' FOLDER_ID = '1brmLNqOMCvRS0TDY6ECHvIBmlRx8pcPz' # Create service account credentials from environment variable CREDS_JSON = os.environ.get('GOOGLE_CREDENTIALS') if CREDS_JSON: CREDS_INFO = json.loads(CREDS_JSON) CREDENTIALS = Credentials.from_service_account_info( CREDS_INFO, scopes=['https://www.googleapis.com/auth/spreadsheets', 'https://www.googleapis.com/auth/drive.file'] ) def get_sheet_names(): try: service = build('sheets', 'v4', credentials=CREDENTIALS) spreadsheet = service.spreadsheets().get(spreadsheetId=SPREADSHEET_ID).execute() return [sheet['properties']['title'] for sheet in spreadsheet['sheets']] except Exception as e: print(f"Error getting sheet names: {str(e)}") return ['Sheet1'] def ensure_headers(sheet_name): try: sheets_service = build('sheets', 'v4', credentials=CREDENTIALS) headers = [ ['項目 Item', '總金額 Total Cost', '發票檔案 Receipt File', '時間 Timestamp', 'IP位址 IP', '付款明細 Payment Details'] ] sheets_service.spreadsheets().values().update( spreadsheetId=SPREADSHEET_ID, range=f'{sheet_name}!A1:F1', valueInputOption='RAW', body={'values': headers} ).execute() requests = [{ 'repeatCell': { 'range': { 'sheetId': 0, 'startRowIndex': 0, 'endRowIndex': 1 }, 'cell': { 'userEnteredFormat': { 'horizontalAlignment': 'CENTER', 'textFormat': { 'bold': True } } }, 'fields': 'userEnteredFormat(horizontalAlignment,textFormat)' } }] sheets_service.spreadsheets().batchUpdate( spreadsheetId=SPREADSHEET_ID, body={'requests': requests} ).execute() except Exception as e: print(f"Error setting headers: {str(e)}") HTML_TEMPLATE = ''' Purchase Record Form

購買記錄表單 Purchase Record Form

總金額 Total Cost: 0
''' @app.route('/') def index(): sheet_names = get_sheet_names() return render_template_string(HTML_TEMPLATE, sheet_names=sheet_names) @app.route('/submit', methods=['POST']) def submit(): try: sheet_name = request.form['sheetName'] product = request.form['product'] file = request.files['receipt'] names = request.form.getlist('names[]') student_ids = request.form.getlist('studentIds[]') costs = request.form.getlist('costs[]') # Calculate total total_cost = sum(float(cost) for cost in costs) # Create payment details string payment_details = [] for name, student_id, cost in zip(names, student_ids, costs): payment_details.append(f"{name}({student_id}): ${cost}") payment_details_str = " | ".join(payment_details) # Initialize Drive service drive_service = build('drive', 'v3', credentials=CREDENTIALS) # Check if subfolder exists, if not create it subfolder_name = sheet_name subfolder_query = f"name = '{subfolder_name}' and '{FOLDER_ID}' in parents and mimeType = 'application/vnd.google-apps.folder' and trashed = false" results = drive_service.files().list(q=subfolder_query).execute() items = results.get('files', []) if not items: # Create new subfolder folder_metadata = { 'name': subfolder_name, 'mimeType': 'application/vnd.google-apps.folder', 'parents': [FOLDER_ID] } subfolder = drive_service.files().create( body=folder_metadata, fields='id' ).execute() subfolder_id = subfolder.get('id') else: subfolder_id = items[0]['id'] # Upload file to the subfolder file_metadata = { 'name': f"{datetime.datetime.now().strftime('%Y%m%d_%H%M%S')}_{file.filename}", 'parents': [subfolder_id] # Use subfolder ID instead of main folder ID } media = MediaIoBaseUpload( io.BytesIO(file.read()), mimetype=file.content_type, resumable=True ) uploaded_file = drive_service.files().create( body=file_metadata, media_body=media, fields='id,webViewLink' ).execute() file_url = uploaded_file.get('webViewLink', '') # Ensure headers exist ensure_headers(sheet_name) # Update Google Sheet sheets_service = build('sheets', 'v4', credentials=CREDENTIALS) timestamp = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S') ip_address = request.remote_addr # Create single row entry values = [[ product, total_cost, file_url, timestamp, ip_address, payment_details_str ]] body = {'values': values} sheets_service.spreadsheets().values().append( spreadsheetId=SPREADSHEET_ID, range=f'{sheet_name}!A:F', valueInputOption='USER_ENTERED', body=body ).execute() return jsonify({'success': True, 'message': 'Data submitted successfully!'}) except Exception as e: return jsonify({'success': False, 'message': f'Error: {str(e)}'}) if __name__ == '__main__': app.run(host='0.0.0.0', port=7860)