feat: IMAP sync incremental + Account Setup Wizard + robust FETCH parser
- ImapSynchronizer::syncFolder(): detecta eliminados (UIDs locales no en servidor), fetch nuevos (sinceUid), actualiza flags (FLAGS batch) - fetchAllUids(): SELECT + SEARCH ALL para lista completa UIDs servidor - parseAndUpdateFlags(): FETCH FLAGS en lotes 100, update DB si cambió read/flagged - AccountSetupDialog: integra ConnectionWizard para IMAP/POP3 con test de conexión real - IMAP FETCH parser robusto: logging respuesta servidor + fallback UID-by-UID - Fix: FETCH failed logging muestra first/last UID + respuesta truncada
This commit is contained in:
@@ -0,0 +1,59 @@
|
||||
import sys
|
||||
import re
|
||||
|
||||
filename = sys.argv[1]
|
||||
with open(filename, 'r') as f:
|
||||
content = f.read()
|
||||
|
||||
# Helper to replace SELECT clause and add mapping after setBodyHtml
|
||||
def replace_select_and_add_mapping(content, func_name):
|
||||
# Pattern to find the function (simplistic but works for our file)
|
||||
# We'll replace the SELECT string inside the function.
|
||||
# Since each function has a unique SELECT, we can replace directly.
|
||||
if func_name == 'findById':
|
||||
# Replace SELECT line
|
||||
pattern = r'(query\.prepare\\(\s*"SELECT id, folderId, messageId, subject, sender, recipient, date, read, flagged, hasAttachment, size, fileId, uid, bodyHtml FROM MailCopy WHERE id = :id"\s*\\);)'
|
||||
replacement = '''query.prepare(
|
||||
"SELECT id, folderId, messageId, subject, sender, recipient, date, read, flagged, hasAttachment, size, fileId, uid, bodyHtml, toAddr, ccAddr, bccAddr FROM MailCopy WHERE id = :id"
|
||||
);'''
|
||||
content = re.sub(pattern, replacement, content)
|
||||
# Add mapping after setBodyHtml line
|
||||
# Find line with item.setBodyHtml(query.value(13).toString());
|
||||
pattern2 = r'(item\.setBodyHtml\(query\.value\(13\)\.toString\(\);\s*\n\s*)'
|
||||
replacement2 = r'\1 item.setTo(query.value(14).toString());\n item.setCc(query.value(15).toString());\n item.setBcc(query.value(16).toString());\n'
|
||||
content = re.sub(pattern2, replacement2, content)
|
||||
elif func_name == 'findAll':
|
||||
# SELECT line inside exec
|
||||
pattern = r'(query\.exec\(\s*"SELECT id, folderId, messageId, subject, sender, recipient, date, read, flagged, hasAttachment, size, fileId, uid, bodyHtml FROM MailCopy"\s*\)\s*)'
|
||||
# We need to replace the whole argument; easier: replace the string inside.
|
||||
# We'll replace the quoted string.
|
||||
pattern = r'"SELECT id, folderId, messageId, subject, sender, recipient, date, read, flagged, hasAttachment, size, fileId, uid, bodyHtml FROM MailCopy"'
|
||||
replacement = '"SELECT id, folderId, messageId, subject, sender, recipient, date, read, flagged, hasAttachment, size, fileId, uid, bodyHtml, toAddr, ccAddr, bccAddr FROM MailCopy"'
|
||||
content = re.sub(pattern, replacement, content)
|
||||
# Add mapping after setBodyHtml line in the while loop
|
||||
pattern2 = r'(item\.setBodyHtml\(query\.value\(13\)\.toString\(\);\s*\n\s*)'
|
||||
replacement2 = r'\1 item.setTo(query.value(14).toString());\n item.setCc(query.value(15).toString());\n item.setBcc(query.value(16).toString());\n'
|
||||
content = re.sub(pattern2, replacement2, content)
|
||||
elif func_name == 'findByFolderId':
|
||||
pattern = r'"SELECT id, folderId, messageId, subject, sender, recipient, date, read, flagged, hasAttachment, size, fileId, uid, bodyHtml FROM MailCopy WHERE folderId = :folderId"'
|
||||
replacement = '"SELECT id, folderId, messageId, subject, sender, recipient, date, read, flagged, hasAttachment, size, fileId, uid, bodyHtml, toAddr, ccAddr, bccAddr FROM MailCopy WHERE folderId = :folderId"'
|
||||
content = re.sub(pattern, replacement, content)
|
||||
pattern2 = r'(item\.setBodyHtml\(query\.value\(13\)\.toString\(\);\s*\n\s*)'
|
||||
replacement2 = r'\1 item.setTo(query.value(14).toString());\n item.setCc(query.value(15).toString());\n item.setBcc(query.value(16).toString());\n'
|
||||
content = re.sub(pattern2, replacement2, content)
|
||||
elif func_name == 'findByFolderIdSinceUid':
|
||||
pattern = r'"SELECT id, folderId, messageId, subject, sender, recipient, date, read, flagged, hasAttachment, size, fileId, uid, bodyHtml FROM MailCopy WHERE folderId = :folderId AND uid > :sinceUid"'
|
||||
replacement = '"SELECT id, folderId, messageId, subject, sender, recipient, date, read, flagged, hasAttachment, size, fileId, uid, bodyHtml, toAddr, ccAddr, bccAddr FROM MailCopy WHERE folderId = :folderId AND uid > :sinceUid"'
|
||||
content = re.sub(pattern, replacement, content)
|
||||
pattern2 = r'(item\.setBodyHtml\(query\.value\(13\)\.toString\(\);\s*\n\s*)'
|
||||
replacement2 = r'\1 item.setTo(query.value(14).toString());\n item.setCc(query.value(15).toString());\n item.setBcc(query.value(16).toString());\n'
|
||||
content = re.sub(pattern2, replacement2, content)
|
||||
return content
|
||||
|
||||
# Apply to each function
|
||||
for func in ['findById', 'findAll', 'findByFolderId', 'findByFolderIdSinceUid']:
|
||||
content = replace_select_and_add_mapping(content, func)
|
||||
|
||||
with open(filename, 'w') as f:
|
||||
f.write(content)
|
||||
print('Modified', filename)
|
||||
Reference in New Issue
Block a user