Matteo Subet commited on
Commit
170c119
·
1 Parent(s): f665bea

Add application file

Browse files
Files changed (1) hide show
  1. app.py +256 -0
app.py ADDED
@@ -0,0 +1,256 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from pathlib import Path
2
+ import gradio as gr
3
+ import re
4
+ import pandas as pd
5
+ import email
6
+ from email import policy
7
+ from email.parser import BytesParser
8
+ import base64
9
+ import quopri
10
+ import xml.etree.ElementTree as ET
11
+ import csv
12
+ import os
13
+ import json
14
+ import gpxpy
15
+ import gpxpy.gpx
16
+ from icalendar import Calendar
17
+ import zipfile
18
+
19
+ def decode_email_content(content, content_transfer_encoding):
20
+ if content_transfer_encoding == 'base64':
21
+ return base64.b64decode(content)
22
+ elif content_transfer_encoding == 'quoted-printable':
23
+ return quopri.decodestring(content)
24
+ return content
25
+
26
+ def parse_email(raw_email):
27
+ # Parsing the raw email content
28
+ msg = BytesParser(policy=policy.default).parsebytes(raw_email)
29
+
30
+ # Extracting email details
31
+ email_details = {
32
+ "From": msg["From"],
33
+ "To": msg["To"],
34
+ "Date": msg["Date"],
35
+ "Subject": msg["Subject"],
36
+ "Body": ""
37
+ }
38
+
39
+ # Extracting the email body content
40
+ if msg.is_multipart():
41
+ for part in msg.iter_parts():
42
+ content_type = part.get_content_type()
43
+ content_disposition = part.get("Content-Disposition")
44
+ content_transfer_encoding = part.get("Content-Transfer-Encoding")
45
+ payload = part.get_payload(decode=False)
46
+
47
+ if content_type == "text/plain" and content_disposition is None:
48
+ body = decode_email_content(payload, content_transfer_encoding)
49
+ charset = part.get_content_charset() or 'utf-8'
50
+ if isinstance(body, bytes):
51
+ body = body.decode(charset)
52
+ email_details["Body"] += body.replace('\n', ' ').replace('\r', '')
53
+ else:
54
+ content_type = msg.get_content_type()
55
+ content_transfer_encoding = msg.get("Content-Transfer-Encoding")
56
+ payload = msg.get_payload(decode=False)
57
+ if content_type == "text/plain":
58
+ body = decode_email_content(payload, content_transfer_encoding)
59
+ charset = msg.get_content_charset() or 'utf-8'
60
+ if isinstance(body, bytes):
61
+ body = body.decode(charset)
62
+ email_details["Body"] = body.replace('\n', ' ').replace('\r', '')
63
+
64
+ return email_details
65
+
66
+ def dataManipulator(converter, filepath):
67
+ global output_file
68
+ output_file = filepath
69
+
70
+ if converter == "Email Converter":
71
+ records = []
72
+
73
+ with open(filepath, 'rb') as file:
74
+ raw_email_data = file.read()
75
+
76
+ email_entries = raw_email_data.split(b'\nFrom ')
77
+
78
+ for raw_email in email_entries:
79
+ if not raw_email.startswith(b'From '):
80
+ raw_email = b'From ' + raw_email
81
+
82
+ parsed_email = parse_email(raw_email)
83
+
84
+ record_data = {
85
+ "date and time": parsed_email["Date"],
86
+ "from": parsed_email["From"],
87
+ "to": parsed_email["To"],
88
+ "Cc": "", # Add Cc if needed, parse_email function does not extract it by default
89
+ "Subject": parsed_email["Subject"],
90
+ "Content": parsed_email["Body"]
91
+ }
92
+
93
+ records.append(record_data)
94
+
95
+ output_file = os.path.basename(os.path.splitext(filepath)[0]) + '_converted.csv'
96
+
97
+ columns = ["date and time", "from", "to", "Cc", "Subject", "Content"]
98
+
99
+ with open(output_file, 'w', newline='') as csvfile:
100
+ writer = csv.DictWriter(csvfile, fieldnames=columns)
101
+
102
+ writer.writeheader()
103
+ for record in records:
104
+ writer.writerow(record)
105
+
106
+ return gr.DownloadButton(label=f"Download {output_file}", value=output_file, interactive=True)
107
+ if converter == "Calendar Converter":
108
+ with open(filepath, 'rb') as file:
109
+ calendar = Calendar.from_ical(file.read())
110
+
111
+ records = []
112
+ for component in calendar.walk():
113
+ if component.name == "VEVENT":
114
+ records.append({
115
+ "summary": component.get('summary'),
116
+ "dtstart": component.get('dtstart').dt,
117
+ "dtend": component.get('dtend').dt,
118
+ "description": component.get('description'),
119
+ "location": component.get('location')
120
+ })
121
+
122
+ output_file = os.path.basename(os.path.splitext(filepath)[0]) + '_converted.csv'
123
+
124
+ with open(output_file, 'w', newline='') as csvfile:
125
+ fieldnames = ["summary", "dtstart", "dtend", "description", "location"]
126
+ writer = csv.DictWriter(csvfile, fieldnames=fieldnames)
127
+
128
+ writer.writeheader()
129
+ for record in records:
130
+ writer.writerow(record)
131
+
132
+ return gr.DownloadButton(label=f"Download {output_file}", value=output_file, interactive=True)
133
+ if converter == "AppleHealth Converter":
134
+ tree = ET.parse(filepath)
135
+ root = tree.getroot()
136
+ records = []
137
+
138
+ columns = ["startDate", "endDate", "device", "sourceName", "type", "unit", "value"]
139
+
140
+ for record in root.findall('Record'):
141
+ record_data = {key: record.attrib.get(key, '') for key in columns}
142
+ records.append(record_data)
143
+
144
+ output_file = os.path.basename(os.path.splitext(filepath)[0]) + '_converted.csv'
145
+
146
+ with open(output_file, 'w', newline='') as csvfile:
147
+ writer = csv.DictWriter(csvfile, fieldnames=columns)
148
+
149
+ writer.writeheader()
150
+ for record in records:
151
+ writer.writerow(record)
152
+
153
+ return gr.DownloadButton(label=f"Download {output_file}", value=output_file, interactive=True)
154
+ if converter == "AppleHealth GPS Converter":
155
+ with open(filepath, 'r') as filepath:
156
+ gpx = gpxpy.parse(filepath)
157
+
158
+ records = []
159
+ for track in gpx.tracks:
160
+ for segment in track.segments:
161
+ for point in segment.points:
162
+ records.append({
163
+ "latitude": point.latitude,
164
+ "longitude": point.longitude,
165
+ "elevation": point.elevation,
166
+ "time": point.time
167
+ })
168
+
169
+ output_file = os.path.basename(os.path.splitext(filepath.name)[0]) + '_converted.csv'
170
+
171
+ with open(output_file, 'w', newline='') as csvfile:
172
+ fieldnames = records[0].keys()
173
+ writer = csv.DictWriter(csvfile, fieldnames=fieldnames)
174
+
175
+ writer.writeheader()
176
+ for record in records:
177
+ writer.writerow(record)
178
+
179
+ return gr.DownloadButton(label=f"Download {output_file}", value=output_file, interactive=True)
180
+ if converter == "WhatsApp Converter":
181
+ with open(filepath, 'r', errors='ignore') as file:
182
+ lines = file.readlines()
183
+
184
+ records = []
185
+ for line in lines:
186
+ if ', ' in line and ': ' in line:
187
+ date_time, message = line.split(' - ', 1)
188
+ date, time = date_time.split(', ')
189
+ sender, message = message.split(': ', 1)
190
+ records.append({
191
+ "date": date,
192
+ "time": time,
193
+ "sender": sender,
194
+ "message": message
195
+ })
196
+
197
+ output_file = os.path.basename(os.path.splitext(filepath)[0]) + '_converted.csv'
198
+
199
+ with open(output_file, 'w', newline='') as csvfile:
200
+ fieldnames = ["date", "time", "sender", "message"]
201
+ writer = csv.DictWriter(csvfile, fieldnames=fieldnames)
202
+
203
+ writer.writeheader()
204
+ for record in records:
205
+ writer.writerow(record)
206
+
207
+ return gr.DownloadButton(label=f"Download {output_file}", value=output_file, interactive=True)
208
+ if converter == "Google Foto Converter":
209
+ records = []
210
+ # Unzip the file
211
+ with zipfile.ZipFile(filepath, 'r') as zip_ref:
212
+ zip_ref.extractall('json_folder')
213
+
214
+ # Process the extracted files
215
+ records = []
216
+ for filename in os.listdir('json_folder'):
217
+ if filename.endswith('.json'):
218
+ with open(os.path.join('json_folder', filename), 'r') as json_file:
219
+ data = json.load(json_file)
220
+ records.append(data)
221
+
222
+ for filename in os.listdir('json_folder'):
223
+ if filename.endswith('.json'):
224
+ with open(os.path.join('json_folder', filename), 'r') as json_file:
225
+ data = json.load(json_file)
226
+ records.append(data)
227
+
228
+ output_file = 'googleFotoConverted.csv'
229
+
230
+ with open(output_file, 'w', newline='') as csvfile:
231
+ fieldnames = set()
232
+ for record in records:
233
+ fieldnames.update(record.keys())
234
+ writer = csv.DictWriter(csvfile, fieldnames=list(fieldnames))
235
+
236
+ writer.writeheader()
237
+ for record in records:
238
+ writer.writerow(record)
239
+
240
+ return gr.DownloadButton(label=f"Download {output_file}", value=output_file, interactive=True)
241
+ else:
242
+ return gr.DownloadButton(label="Download not ready", value="output_file", interactive=False)
243
+
244
+
245
+ demo = gr.Interface(
246
+ dataManipulator,
247
+ [
248
+ gr.Radio(["Email Converter", "Calendar Converter", "AppleHealth Converter", "AppleHealth GPS Converter", "WhatsApp Converter", "Google Foto Converter"], label="Select a converter:"),
249
+ gr.File(label="Upload a file"),
250
+ ],
251
+ outputs=gr.DownloadButton(label="Download not ready", value="output_file", interactive=False),
252
+ allow_flagging="never",
253
+ )
254
+
255
+ if __name__ == "__main__":
256
+ demo.launch()