euler314 commited on
Commit
fa3a1a9
·
verified ·
1 Parent(s): c42f94c

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +157 -0
app.py ADDED
@@ -0,0 +1,157 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from flask import Flask, render_template, request, jsonify
2
+ import gspread
3
+ from google.oauth2.credentials import Credentials
4
+ from google.oauth2.service_account import Credentials
5
+ from oauth2client.service_account import ServiceAccountCredentials
6
+ import io
7
+ import datetime
8
+ from googleapiclient.discovery import build
9
+ from googleapiclient.http import MediaIoBaseUpload
10
+
11
+ app = Flask(__name__)
12
+
13
+ # Your Google Sheet and Drive settings
14
+ SPREADSHEET_ID = '1FfqnS2ThmTo8QDryimD86VHI1zGyET9c3vbaiRAcaPg'
15
+ FOLDER_ID = 'YOUR_FOLDER_ID' # Your Google Drive folder ID
16
+
17
+ # HTML template as a string
18
+ HTML_TEMPLATE = '''
19
+ <!DOCTYPE html>
20
+ <html>
21
+ <head>
22
+ <title>Purchase Record Form</title>
23
+ <style>
24
+ body { font-family: Arial, sans-serif; margin: 20px; max-width: 600px; margin: 0 auto; }
25
+ .form-group { margin-bottom: 15px; }
26
+ label { display: block; margin-bottom: 5px; }
27
+ input { width: 100%; padding: 8px; margin-bottom: 10px; border: 1px solid #ddd; border-radius: 4px; }
28
+ button { background-color: #4CAF50; color: white; padding: 10px 20px; border: none; border-radius: 4px; cursor: pointer; }
29
+ button:hover { background-color: #45a049; }
30
+ #status { margin-top: 20px; padding: 10px; display: none; }
31
+ .success { background-color: #dff0d8; color: #3c763d; }
32
+ .error { background-color: #f2dede; color: #a94442; }
33
+ </style>
34
+ </head>
35
+ <body>
36
+ <h2>Purchase Record Form</h2>
37
+ <form id="purchaseForm">
38
+ <div class="form-group">
39
+ <label for="name">Name:</label>
40
+ <input type="text" id="name" name="name" required>
41
+ </div>
42
+
43
+ <div class="form-group">
44
+ <label for="studentId">Student ID (學號):</label>
45
+ <input type="text" id="studentId" name="studentId" required>
46
+ </div>
47
+
48
+ <div class="form-group">
49
+ <label for="product">Product:</label>
50
+ <input type="text" id="product" name="product" required>
51
+ </div>
52
+
53
+ <div class="form-group">
54
+ <label for="cost">Cost:</label>
55
+ <input type="number" id="cost" name="cost" required>
56
+ </div>
57
+
58
+ <div class="form-group">
59
+ <label for="receipt">Receipt (發票):</label>
60
+ <input type="file" id="receipt" name="receipt" required>
61
+ </div>
62
+
63
+ <button type="submit">Submit</button>
64
+ </form>
65
+ <div id="status"></div>
66
+
67
+ <script>
68
+ document.getElementById('purchaseForm').addEventListener('submit', async (e) => {
69
+ e.preventDefault();
70
+
71
+ const status = document.getElementById('status');
72
+ status.style.display = 'block';
73
+ status.textContent = 'Submitting...';
74
+ status.className = '';
75
+
76
+ const formData = new FormData(e.target);
77
+
78
+ try {
79
+ const response = await fetch('/submit', {
80
+ method: 'POST',
81
+ body: formData
82
+ });
83
+
84
+ const result = await response.json();
85
+
86
+ if (result.success) {
87
+ status.className = 'success';
88
+ status.textContent = result.message;
89
+ e.target.reset();
90
+ } else {
91
+ status.className = 'error';
92
+ status.textContent = result.message;
93
+ }
94
+ } catch (error) {
95
+ status.className = 'error';
96
+ status.textContent = 'Error submitting form';
97
+ }
98
+ });
99
+ </script>
100
+ </body>
101
+ </html>
102
+ '''
103
+
104
+ @app.route('/')
105
+ def index():
106
+ return HTML_TEMPLATE
107
+
108
+ @app.route('/submit', methods=['POST'])
109
+ def submit():
110
+ try:
111
+ # Get form data
112
+ name = request.form['name']
113
+ student_id = request.form['studentId']
114
+ product = request.form['product']
115
+ cost = request.form['cost']
116
+ file = request.files['receipt']
117
+
118
+ # Initialize gspread client (using your credentials)
119
+ gc = gspread.service_account(filename='credentials.json')
120
+ sheet = gc.open_by_key(SPREADSHEET_ID).sheet1
121
+
122
+ # Upload file to Drive (using your credentials)
123
+ creds = ServiceAccountCredentials.from_json_keyfile_name('credentials.json')
124
+ drive_service = build('drive', 'v3', credentials=creds)
125
+
126
+ file_metadata = {
127
+ 'name': file.filename,
128
+ 'parents': [FOLDER_ID]
129
+ }
130
+
131
+ media = MediaIoBaseUpload(
132
+ io.BytesIO(file.read()),
133
+ mimetype=file.content_type,
134
+ resumable=True
135
+ )
136
+
137
+ uploaded_file = drive_service.files().create(
138
+ body=file_metadata,
139
+ media_body=media,
140
+ fields='id,webViewLink'
141
+ ).execute()
142
+
143
+ file_url = uploaded_file.get('webViewLink', '')
144
+
145
+ # Append to sheet
146
+ timestamp = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
147
+ ip_address = request.remote_addr
148
+
149
+ sheet.append_row([name, student_id, product, cost, file_url, timestamp, ip_address])
150
+
151
+ return jsonify({'success': True, 'message': 'Data submitted successfully!'})
152
+
153
+ except Exception as e:
154
+ return jsonify({'success': False, 'message': f'Error: {str(e)}'})
155
+
156
+ if __name__ == '__main__':
157
+ app.run(host='0.0.0.0', port=7860)