94 lines
3.5 KiB
Python
94 lines
3.5 KiB
Python
# -*- coding: utf-8 -*-
|
|
env = env(user=1)
|
|
cr = env.cr
|
|
|
|
# Query to find all tables and character/text columns in the public schema
|
|
cr.execute("""
|
|
SELECT table_name, column_name
|
|
FROM information_schema.columns
|
|
WHERE table_schema = 'public'
|
|
AND data_type IN ('character varying', 'text')
|
|
AND table_name NOT LIKE 'pg_%'
|
|
AND table_name NOT LIKE 'sql_%'
|
|
""")
|
|
columns = cr.fetchall()
|
|
|
|
# Map of common broken words/phrases (ASCII-safe hex/unicode escape format)
|
|
replacements = {
|
|
'g\x3f\x3fn': 'g\u00fcn',
|
|
'\x3f\x3fnce': '\u00f6nce',
|
|
'onayland\x3f\x3f': 'onayland\u0131',
|
|
'Foto\x3f\x3fraflar\x3f\x3f': 'Foto\u011fraflar\u0131',
|
|
'y\x3f\x3fk\x3f\x3fnden': 'y\u00fck\u00fcnden',
|
|
'ar\x3f\x3fnd\x3f\x3fr\x3f\x3fld\x3f\x3f': 'ar\u0131nd\u0131r\u0131ld\u0131',
|
|
'S\x3f\x3fr\x3f\x3fc\x3f\x3f': 'S\u00fcr\u00fcc\u00fc',
|
|
'Y\x3f\x3flmaz': 'Y\u0131lmaz',
|
|
'Ara\x3f\x3f': 'Ara\u00e7',
|
|
'g\x3f\x3fnderildi': 'g\u00f6nderildi',
|
|
'G\x3f\x3fnderildi': 'G\u00f6nderildi',
|
|
'edildi\x3f\x3fi': 'edildi\u011fi',
|
|
'de\x3f\x3fer': 'de\u011fer',
|
|
'De\x3f\x3fer': 'De\u011fer',
|
|
'cezalar\x3f\x3f': 'cezalar\u0131',
|
|
'Cezalar\x3f\x3f': 'Cezalar\u0131',
|
|
'G\x3f\x3fvenlik': 'G\u00fcvenlik',
|
|
'g\x3f\x3fvenlik': 'g\u00fcvenlik',
|
|
'\x3f\x3fhlal': '\u0130hlal',
|
|
'\x3f\x3fhlalleri': '\u0130hlalleri',
|
|
'\x3f\x3frtak': 'Ortak',
|
|
'\x3f\x3fmit': '\u00dcmit',
|
|
'\x3f\x3fener': '\u015eener',
|
|
'\x3f\x3felik': '\u00c7elik',
|
|
'\x3f\x3fz': '\u00d6z',
|
|
'\x3f\x3fzcan': '\u00d6zcan',
|
|
'\x3f\x3fzt\x3f\x3frk': '\u00d6zt\u00fcrk',
|
|
'\x3f\x3fzkan': '\u00d6zkan',
|
|
# Specific missing ones from the log
|
|
'Ay\x3f\x3fe': 'Ay\u015fe',
|
|
's\x3f\x3f': 's\u00fc',
|
|
'S\x3f\x3fr\x3f\x3fc\x3fs\x3f\x3f': 'S\u00fcr\u00fcc\u00fcs\u00fc',
|
|
'S\x3f\x3fr\x3f\x3fc\x3f_X': 'S\u00fcr\u00fcc\u00fc_X',
|
|
'S\x3f\x3fr\x3f\x3fc\x3f_Yeni': 'S\u00fcr\u00fcc\u00fc_Yeni',
|
|
# Maintenance cost patterns
|
|
'Yak\x3f\x3ft': 'Yak\u0131t',
|
|
'Bak\x3f\x3fm': 'Bak\u0131m',
|
|
'Al\x3f\x3fm\x3f\x3f': 'Al\u0131m\u0131',
|
|
'Y\x3f\x3fksek': 'Y\u00fcksek',
|
|
'T\x3f\x3fketim': 'T\u00fcketim',
|
|
'Sim\x3f\x3flasyon': 'Sim\u00fclasyon',
|
|
'A\x3f\x3f\x3f\x3fr': 'A\u011f\u0131r',
|
|
}
|
|
|
|
fixed_count = 0
|
|
|
|
for table_name, column_name in columns:
|
|
if table_name.startswith(('ir_logging', 'ir_attachment', 'mail_message', 'mail_tracking', 'ir_model_data', 'ir_translation')):
|
|
continue
|
|
|
|
try:
|
|
cr.execute(f'SELECT id FROM "{table_name}" WHERE "{column_name}" LIKE \'%??%\'')
|
|
res = cr.fetchall()
|
|
if res:
|
|
record_ids = [r[0] for r in res]
|
|
|
|
for rec_id in record_ids:
|
|
cr.execute(f'SELECT "{column_name}" FROM "{table_name}" WHERE id = %s', (rec_id,))
|
|
val = cr.fetchone()[0]
|
|
if val:
|
|
fixed_val = val
|
|
for broken, fixed in replacements.items():
|
|
fixed_val = fixed_val.replace(broken, fixed)
|
|
|
|
if fixed_val != val:
|
|
cr.execute(f'UPDATE "{table_name}" SET "{column_name}" = %s WHERE id = %s', (fixed_val, rec_id))
|
|
print(f"Table: {table_name}, Column: {column_name}, ID: {rec_id} -> Fixed to: '{fixed_val}'")
|
|
fixed_count += 1
|
|
except Exception:
|
|
pass
|
|
|
|
if fixed_count > 0:
|
|
cr.commit()
|
|
print(f"SUCCESS: Fixed {fixed_count} columns across the database!")
|
|
else:
|
|
print("NO CORRUPTED DATA FOUND/FIXED IN DATABASE VIA SQL.")
|