from flask import Flask, request, jsonify, render_template_string, redirect, session from google_auth_oauthlib.flow import Flow from google.oauth2.credentials import Credentials from googleapiclient.discovery import build from googleapiclient.http import MediaIoBaseUpload import os import io import datetime app = Flask(__name__) app.secret_key = os.environ.get('FLASK_SECRET_KEY') SCOPES = ['https://www.googleapis.com/auth/spreadsheets', 'https://www.googleapis.com/auth/drive.file'] SPREADSHEET_ID = '1rcIJflbC1VIc70F6dnASLFvGQ90TXHhCx0iyxsXR7Ww' FOLDER_ID = '1brmLNqOMCvRS0TDY6ECHvIBmlRx8pcPz' # OAuth configuration client_config = { "web": { "client_id": os.environ.get('GOOGLE_CLIENT_ID'), "client_secret": os.environ.get('GOOGLE_CLIENT_SECRET'), "auth_uri": "https://accounts.google.com/o/oauth2/auth", "token_uri": "https://oauth2.googleapis.com/token", "redirect_uris": ["https://euler314-purchase-record.hf.space/oauth2callback"] } } def credentials_to_dict(credentials): return { 'token': credentials.token, 'refresh_token': credentials.refresh_token, 'token_uri': credentials.token_uri, 'client_id': credentials.client_id, 'client_secret': credentials.client_secret, 'scopes': credentials.scopes } def get_credentials(): if 'credentials' not in session: return None return Credentials(**session['credentials']) @app.route('/authorize') def authorize(): flow = Flow.from_client_config( client_config, scopes=SCOPES, redirect_uri=client_config['web']['redirect_uris'][0] ) authorization_url, state = flow.authorization_url( access_type='offline', include_granted_scopes='true' ) session['state'] = state return redirect(authorization_url) @app.route('/oauth2callback') def oauth2callback(): state = session['state'] flow = Flow.from_client_config( client_config, scopes=SCOPES, state=state, redirect_uri=client_config['web']['redirect_uris'][0] ) authorization_response = request.url flow.fetch_token(authorization_response=authorization_response) credentials = flow.credentials session['credentials'] = credentials_to_dict(credentials) return redirect('/') @app.route('/') def index(): if not get_credentials(): return redirect('/authorize') return render_template_string(HTML_TEMPLATE) HTML_TEMPLATE = ''' Purchase Record Form

購買記錄表單 Purchase Record Form

''' @app.route('/') def index(): return render_template_string(HTML_TEMPLATE) @app.route('/submit', methods=['POST']) def submit(): try: name = request.form['name'] student_id = request.form['studentId'] product = request.form['product'] cost = request.form['cost'] file = request.files['receipt'] credentials = Credentials.from_authorized_user_info(CREDENTIALS) # Upload file to Drive drive_service = build('drive', 'v3', credentials=credentials) file_metadata = { 'name': f"{student_id}_{datetime.datetime.now().strftime('%Y%m%d_%H%M%S')}_{file.filename}", 'parents': [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', '') # 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 values = [[name, student_id, product, cost, file_url, timestamp, ip_address]] body = {'values': values} sheets_service.spreadsheets().values().append( spreadsheetId=SPREADSHEET_ID, range='Sheet1!A:G', 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)