gosign commited on
Commit
e9d377a
·
verified ·
1 Parent(s): 42b7a57

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +234 -0
app.py ADDED
@@ -0,0 +1,234 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import json
2
+ import os
3
+ import magic
4
+ from dotenv import load_dotenv
5
+ from docx import Document
6
+ from docx.shared import Inches
7
+ from docx.enum.text import WD_ALIGN_PARAGRAPH
8
+ from flask_cors import CORS
9
+ from flask import Flask, request, jsonify
10
+ from supabase import create_client, Client
11
+
12
+ # load_dotenv(dotenv_path='.env.local')
13
+ load_dotenv()
14
+
15
+ app = Flask(__name__)
16
+
17
+ CORS(app)
18
+
19
+ url: str = 'http://127.0.0.1:54321'
20
+ key: str = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZS1kZW1vIiwicm9sZSI6ImFub24iLCJleHAiOjE5ODM4MTI5OTZ9.CRXP1A7WOeoJeXxjNni43kdQwgnWNReilDMblYTn_I0'
21
+
22
+ supabase: Client = create_client(url, key)
23
+
24
+ def get_file_by_id(file_id):
25
+ try:
26
+ response = supabase.table("files").select("*").eq("id", file_id).single().execute()
27
+ file = response.data
28
+
29
+ if not file:
30
+ raise ValueError(response.error.message if response.error else "File not found.")
31
+
32
+ file_path = file.get("file_path")
33
+ file_name = file.get("name")
34
+
35
+ if not file_path:
36
+ raise ValueError("File path is missing in the metadata.")
37
+
38
+ # Fetch the actual file content from Supabase storage
39
+ file_data = supabase.storage.from_('files').download(file_path)
40
+
41
+ return file_name, file_data
42
+ except Exception as e:
43
+ print("Error fetching file:", e)
44
+ return jsonify({"error": str(e)}), 500
45
+
46
+ def get_file_type(file_path):
47
+ try:
48
+ # Use python-magic to detect the MIME type of the file
49
+ mime = magic.Magic(mime=True)
50
+ file_type = mime.from_file(file_path)
51
+ return file_type
52
+ except Exception as e:
53
+ print("Error fetching file:", e)
54
+ return jsonify({"error": str(e)}), 500
55
+
56
+ def insert_file_record(user_id, doc):
57
+ try:
58
+ file_type = get_file_type(doc)
59
+ file_record = {
60
+ "user_id": user_id,
61
+ "description": "",
62
+ "file_path": "",
63
+ "name": "letterhead-" + os.path.basename(doc),
64
+ "size": os.path.getsize(doc),
65
+ "tokens": 0,
66
+ "type": file_type,
67
+ }
68
+
69
+ response = supabase.table("files").insert(file_record).execute()
70
+
71
+ return response
72
+ except Exception as e:
73
+ print("Error fetching file:", e)
74
+ return jsonify({"error": str(e)}), 500
75
+
76
+ def upload_file_to_storage(file, metadata):
77
+ # Replace with the actual upload implementation
78
+ file_path = f"{metadata['user_id']}/{metadata['file_id']}"
79
+ # file_content = file.read() # Read the file content as bytes
80
+
81
+ file_type = get_file_type(file)
82
+ try:
83
+ with open(file, 'rb') as f:
84
+ response = supabase.storage.from_("files").upload(
85
+ file=f,
86
+ path=file_path,
87
+ file_options={"cache-control": "3600", "content-type": file_type, "upsert": "false"},
88
+ )
89
+
90
+ file_path = response.path
91
+ return file_path
92
+ except Exception as e:
93
+ print("Error uploading file:", e)
94
+ return jsonify({"error": str(e)}), 500
95
+
96
+
97
+
98
+ def update_file_record(file_id, updates):
99
+ try:
100
+ response = supabase.table("files").update(updates).eq("id", file_id).execute()
101
+ return response
102
+ except Exception as e:
103
+ print("Error while updating record:", e)
104
+ return jsonify({"error": str(e)}), 500
105
+
106
+ def insert_text_and_image_at_end(full_path, full_image_path, text_to_insert, include_signature, signature_position, letterhead_address):
107
+ try:
108
+ doc = Document(full_path)
109
+
110
+ # Replace placeholder <<SENDER_ADDRESS>> with the letterhead address
111
+ for paragraph in doc.paragraphs:
112
+ if ("<<SENDER_ADDRESS>>" in paragraph.text and letterhead_address):
113
+ for run in paragraph.runs:
114
+ run.text = run.text.replace("<<SENDER_ADDRESS>>", letterhead_address)
115
+
116
+ # Add the new text at the end of the document
117
+ doc.add_paragraph(text_to_insert)
118
+
119
+ # Add the image at the end of the document with position adjustment
120
+ if (include_signature and full_image_path):
121
+ image_paragraph = doc.add_paragraph()
122
+ run = image_paragraph.add_run()
123
+ run.add_picture(full_image_path, width=Inches(1), height=Inches(1))
124
+
125
+ # Adjust the alignment based on signature_position
126
+ if signature_position == 'left':
127
+ image_paragraph.alignment = WD_ALIGN_PARAGRAPH.LEFT
128
+ elif signature_position == 'right':
129
+ image_paragraph.alignment = WD_ALIGN_PARAGRAPH.RIGHT
130
+ elif signature_position == 'center':
131
+ image_paragraph.alignment = WD_ALIGN_PARAGRAPH.CENTER
132
+
133
+ # Save the document with the inserted text and image
134
+ doc.save(full_path)
135
+
136
+ return full_path
137
+ except Exception as e:
138
+ print("Error while inserting text:", e)
139
+ return jsonify({"error": str(e)}), 500
140
+
141
+
142
+ def fetch_image(bucket_name: str, image_path: str):
143
+ try:
144
+ # Download file from Supabase storage
145
+ file_data = supabase.storage.from_(bucket_name).download(image_path)
146
+
147
+ # Use python-magic to detect MIME type from the file data
148
+ mime_type = magic.Magic(mime=True).from_buffer(file_data)
149
+
150
+ current_directory = os.getcwd()
151
+
152
+ letterhead_image_path = image_path.split('/')[-1] + "." + mime_type.split('/')[-1]
153
+ full_letterhead_image_path = os.path.join(current_directory, "letterhead", letterhead_image_path)
154
+
155
+ with open(full_letterhead_image_path, 'wb') as f:
156
+ f.write(file_data)
157
+
158
+ return full_letterhead_image_path
159
+
160
+ except Exception as e:
161
+ print(f"Error: {e}")
162
+ return jsonify({"error": str(e)}), 500
163
+
164
+ def delete_all_files(directory):
165
+ keep_file = "WARNING-DO-NOT-DELETE.txt"
166
+ try:
167
+ # Loop through each file in the directory
168
+ for filename in os.listdir(directory):
169
+ file_path = os.path.join(directory, filename)
170
+
171
+ # Check if it's a file and not the one to keep
172
+ if os.path.isfile(file_path) and filename != keep_file:
173
+ os.remove(file_path)
174
+ except Exception as e:
175
+ print(f"An error occurred: {e}")
176
+ return jsonify({"error": str(e)}), 500
177
+
178
+ @app.route("/api/letterhead", methods=["POST"])
179
+ def letterhead():
180
+ data = request.get_json() # Get JSON data from the request (if provided)
181
+
182
+ # Extract data
183
+ chat_settings = data.get("chatSettings")
184
+ profile = data.get("profile")
185
+ letterhead_data = data.get("letterheadData")
186
+
187
+ try:
188
+ file_name, file_data = get_file_by_id(chat_settings["letterheadFileId"])
189
+ current_directory = os.getcwd()
190
+ full_letterhead_file_path = os.path.join(current_directory, "letterhead", file_name)
191
+
192
+ full_letterhead_signature_path = None
193
+ if (letterhead_data["includeSignature"] and (chat_settings["letterheadSignatureImagePath"])):
194
+ full_letterhead_signature_path = fetch_image("assistant_images", (chat_settings["letterheadSignatureImagePath"]))
195
+
196
+ text_to_insert = letterhead_data["letterheadContent"]
197
+ include_signature = letterhead_data["includeSignature"]
198
+ signature_position = letterhead_data["signaturePosition"]
199
+ letterhead_address = letterhead_data["letterheadAddress"]
200
+
201
+ with open(full_letterhead_file_path, "wb") as f:
202
+ if hasattr(file_data, "read"):
203
+ f.write(file_data.read())
204
+ else: # If it's raw bytes
205
+ f.write(file_data)
206
+
207
+ modified_doc = insert_text_and_image_at_end(full_letterhead_file_path, full_letterhead_signature_path, text_to_insert, include_signature,signature_position, letterhead_address)
208
+
209
+ created_file = insert_file_record(profile["user_id"], modified_doc)
210
+
211
+ file_data = created_file.json()
212
+ file_data_json = json.loads(file_data)
213
+
214
+ file_path = upload_file_to_storage(modified_doc, {
215
+ "name": file_data_json["data"][0]["name"],
216
+ "user_id": file_data_json["data"][0]["user_id"],
217
+ "file_id": file_data_json["data"][0]["id"],
218
+ })
219
+
220
+ update_file_record(file_data_json["data"][0]["id"], {"file_path": file_path})
221
+
222
+ current_directory = os.getcwd()
223
+ file_deleting_directory_path = os.path.join(current_directory, "letterhead")
224
+ delete_all_files(file_deleting_directory_path)
225
+
226
+ message = f"letterheadFileId:{file_data_json["data"][0]["id"]} Your letterhead is successfully created."
227
+ return jsonify({ "message": message }), 200
228
+ except ValueError as e:
229
+ return jsonify({"error": str(e)}), 404
230
+ except Exception as e:
231
+ return jsonify({"error": str(e)}), 500
232
+
233
+ if __name__ == '__main__':
234
+ app.run(debug=True)