|
|
|
|
|
""" |
|
|
Contact database with 500 fake contacts covering all departments and divisions. |
|
|
Each contact has Arabic and English names for better search support. |
|
|
""" |
|
|
|
|
|
from typing import List, Dict |
|
|
from division_hierarchy import DIVISION_TO_DEPARTMENT |
|
|
import random |
|
|
|
|
|
|
|
|
ARABIC_FIRST_NAMES_MALE = [ |
|
|
"محمد", "أحمد", "عبدالله", "عمر", "خالد", "سعد", "فيصل", "سلطان", "ناصر", "طلال", |
|
|
"عبدالعزيز", "فهد", "تركي", "سلمان", "بندر", "مشعل", "ماجد", "يوسف", "حسن", "علي", |
|
|
"وليد", "زياد", "رامي", "كريم", "عادل", "راشد", "مازن", "طارق", "إبراهим", "عيسى", |
|
|
"نواف", "سامي", "بدر", "عاصم", "وسام", "هاني", "ثامر", "صالح", "ياسر", "جاسم", |
|
|
"هشام", "فواز", "معاذ", "عثمان", "أسامة", "باسل", "عمار", "نبيل", "توفيق", "جمال" |
|
|
] |
|
|
|
|
|
ARABIC_FIRST_NAMES_FEMALE = [ |
|
|
"فاطمة", "نورة", "سارة", "منى", "هند", "ريم", "لينا", "دانة", "شهد", "جود", |
|
|
"رهف", "غلا", "عبير", "أمل", "ندى", "رنا", "لمى", "ديمة", "بشرى", "سمية", |
|
|
"هيفاء", "ليلى", "زينب", "خلود", "شروق", "أريج", "جميلة", "رباب", "سلمى", "وفاء", |
|
|
"عائشة", "خديجة", "مريم", "رقية", "زهراء", "نجود", "حصة", "عزة", "صفية", "ملاك", |
|
|
"روان", "تالا", "جنى", "لين", "ريتاج", "أسماء", "سديم", "لمار", "بيان", "شيماء" |
|
|
] |
|
|
|
|
|
|
|
|
ARABIC_LAST_NAMES = [ |
|
|
"العتيبي", "الدوسري", "القحطاني", "الشهري", "الغامدي", "الزهراني", "العنزي", "الحربي", |
|
|
"المطيري", "العسيري", "السبيعي", "الشمري", "الجهني", "العمري", "البقمي", "الفهد", |
|
|
"السديري", "الثبيتي", "الصقري", "الأحمد", "الخالد", "السليمان", "العبدالله", "الفهيد", |
|
|
"الشايع", "الرشيد", "العجمي", "المالك", "الفريح", "الحمود", "الناصر", "الشريف", |
|
|
"البلوي", "اليامي", "الوادعي", "الفيفي", "الشهراني", "البكري", "العسكر", "الراشد", |
|
|
"الفايز", "الخليف", "المنيع", "العبيد", "السحيم", "الغنام", "السلمان", "الهاجري", |
|
|
"النهدي", "الرويلي", "المري", "السواط", "الربيعان", "الدغيثر", "الفضلي", "القرني", |
|
|
"الثنيان", "العريفي", "الهويدي", "الجريسي", "البدراني", "المهيدب", "السالم", "الحارثي", |
|
|
"العطوي", "الصخري", "الرحيلي", "السعيد", "الحافظ", "الوهيبي", "البراك", "الضويان" |
|
|
] |
|
|
|
|
|
|
|
|
JOB_TITLES = { |
|
|
"executive": [ |
|
|
("Chief Executive Officer", "المدير التنفيذي"), |
|
|
("Executive Director", "المدير التنفيذي"), |
|
|
("Vice President", "نائب الرئيس"), |
|
|
("Senior Vice President", "نائب الرئيس الأول"), |
|
|
], |
|
|
"management": [ |
|
|
("Director", "مدير"), |
|
|
("Senior Manager", "مدير أول"), |
|
|
("Manager", "مدير"), |
|
|
("Assistant Manager", "مساعد مدير"), |
|
|
("Team Leader", "قائد فريق"), |
|
|
("Supervisor", "مشرف"), |
|
|
], |
|
|
"specialist": [ |
|
|
("Senior Specialist", "أخصائي أول"), |
|
|
("Specialist", "أخصائي"), |
|
|
("Senior Analyst", "محلل أول"), |
|
|
("Analyst", "محلل"), |
|
|
("Senior Consultant", "مستشار أول"), |
|
|
("Consultant", "مستشار"), |
|
|
("Senior Officer", "موظف أول"), |
|
|
("Officer", "موظف"), |
|
|
], |
|
|
"technical": [ |
|
|
("Senior Engineer", "مهندس أول"), |
|
|
("Engineer", "مهندس"), |
|
|
("Technical Lead", "قائد تقني"), |
|
|
("Developer", "مطور"), |
|
|
("Architect", "مهندس معماري"), |
|
|
], |
|
|
"support": [ |
|
|
("Coordinator", "منسق"), |
|
|
("Administrator", "إداري"), |
|
|
("Assistant", "مساعد"), |
|
|
("Associate", "معاون"), |
|
|
] |
|
|
} |
|
|
|
|
|
|
|
|
def generate_extension() -> str: |
|
|
"""Generate a 4-digit phone extension""" |
|
|
return str(random.randint(1000, 9999)) |
|
|
|
|
|
|
|
|
def generate_email(first_name_en: str, last_name_en: str) -> str: |
|
|
"""Generate an email address""" |
|
|
|
|
|
first = first_name_en.lower().replace(" ", "").replace("-", "") |
|
|
last = last_name_en.lower().replace(" ", "").replace("-", "") |
|
|
return f"{first}.{last}@sidf.gov.sa" |
|
|
|
|
|
|
|
|
def transliterate_arabic_name(arabic_name: str) -> str: |
|
|
""" |
|
|
Simple transliteration of Arabic names to English. |
|
|
This is a basic mapping for common names. |
|
|
""" |
|
|
transliteration_map = { |
|
|
|
|
|
"محمد": "Mohammed", "أحمد": "Ahmed", "عبدالله": "Abdullah", "عمر": "Omar", "خالد": "Khalid", |
|
|
"سعد": "Saad", "فيصل": "Faisal", "سلطان": "Sultan", "ناصر": "Nasser", "طلال": "Talal", |
|
|
"عبدالعزيز": "Abdulaziz", "فهد": "Fahad", "تركي": "Turki", "سلمان": "Salman", "بندر": "Bandar", |
|
|
"مشعل": "Mishaal", "ماجد": "Majed", "يوسف": "Yousef", "حسن": "Hassan", "علي": "Ali", |
|
|
"وليد": "Waleed", "زياد": "Ziyad", "رامي": "Rami", "كريم": "Kareem", "عادل": "Adel", |
|
|
"راشد": "Rashed", "مازن": "Mazen", "طارق": "Tariq", "إبراهim": "Ibrahim", "عيسى": "Issa", |
|
|
"نواف": "Nawaf", "سامي": "Sami", "بدر": "Badr", "عاصم": "Asim", "وسام": "Wissam", |
|
|
"هاني": "Hani", "ثامر": "Thamer", "صالح": "Saleh", "ياسر": "Yasser", "جاسم": "Jasim", |
|
|
"هشام": "Hisham", "فواز": "Fawaz", "معاذ": "Muath", "عثمان": "Othman", "أسامة": "Osama", |
|
|
"باسل": "Basel", "عمار": "Ammar", "نبيل": "Nabil", "توفيق": "Tawfiq", "جمال": "Jamal", |
|
|
|
|
|
|
|
|
"فاطمة": "Fatima", "نورة": "Noura", "سارة": "Sarah", "منى": "Mona", "هند": "Hind", |
|
|
"ريم": "Reem", "لينا": "Lina", "دانة": "Dana", "شهد": "Shahad", "جود": "Joud", |
|
|
"رهف": "Rahaf", "غلا": "Ghala", "عبير": "Abeer", "أمل": "Amal", "ندى": "Nada", |
|
|
"رنا": "Rana", "لمى": "Lama", "ديمة": "Dima", "بشرى": "Bushra", "سمية": "Somaya", |
|
|
"هيفاء": "Haifa", "ليلى": "Layla", "زينب": "Zainab", "خلود": "Kholoud", "شروق": "Shorouq", |
|
|
"أريج": "Areej", "جميلة": "Jamila", "رباب": "Rabab", "سلمى": "Salma", "وفاء": "Wafa", |
|
|
"عائشة": "Aisha", "خديجة": "Khadija", "مريم": "Maryam", "رقية": "Ruqaya", "زهراء": "Zahra", |
|
|
"نجود": "Nujoud", "حصة": "Hessa", "عزة": "Azza", "صفية": "Safiya", "ملاك": "Malak", |
|
|
"روان": "Rawan", "تالا": "Tala", "جنى": "Jana", "لين": "Leen", "ريتاج": "Ritaj", |
|
|
"أسماء": "Asma", "سديم": "Sadeem", "لمار": "Lamar", "بيان": "Bayan", "شيماء": "Shaima", |
|
|
|
|
|
|
|
|
"العتيبي": "Al-Otaibi", "الدوسري": "Al-Dosari", "القحطاني": "Al-Qahtani", "الشهري": "Al-Shahri", |
|
|
"الغامدي": "Al-Ghamdi", "الزهراني": "Al-Zahrani", "العنزي": "Al-Anazi", "الحربي": "Al-Harbi", |
|
|
"المطيري": "Al-Mutairi", "العسيري": "Al-Asiri", "السبيعي": "Al-Subaie", "الشمري": "Al-Shammari", |
|
|
"الجهني": "Al-Juhani", "العمري": "Al-Omari", "البقمي": "Al-Buqami", "الفهد": "Al-Fahad", |
|
|
"السديري": "Al-Sudairi", "الثبيتي": "Al-Thubaiti", "الصقري": "Al-Saqri", "الأحمد": "Al-Ahmad", |
|
|
"الخالد": "Al-Khalid", "السليمان": "Al-Sulaiman", "العبدالله": "Al-Abdullah", "الفهيد": "Al-Fahaid", |
|
|
"الشايع": "Al-Shaya", "الرشيد": "Al-Rasheed", "العجمي": "Al-Ajmi", "المالك": "Al-Malek", |
|
|
"الفريح": "Al-Fraihi", "الحمود": "Al-Hamoud", "الناصر": "Al-Nasser", "الشريف": "Al-Shareef", |
|
|
"البلوي": "Al-Balawi", "اليامي": "Al-Yami", "الوادعي": "Al-Wadei", "الفيفي": "Al-Faifi", |
|
|
"الشهراني": "Al-Shahrani", "البكري": "Al-Bakri", "العسكر": "Al-Askar", "الراشد": "Al-Rashed", |
|
|
"الفايز": "Al-Fayez", "الخليف": "Al-Khleif", "المنيع": "Al-Manie", "العبيد": "Al-Obaid", |
|
|
"السحيم": "Al-Suhaim", "الغنام": "Al-Ghannam", "السلمان": "Al-Salman", "الهاجري": "Al-Hajri", |
|
|
"النهدي": "Al-Nahdi", "الرويلي": "Al-Ruwaili", "المري": "Al-Marri", "السواط": "Al-Sawat", |
|
|
"الربيعان": "Al-Rabian", "الدغيثر": "Al-Dughither", "الفضلي": "Al-Fadhli", "القرني": "Al-Qarni", |
|
|
"الثنيان": "Al-Thuniyan", "العريفي": "Al-Arifi", "الهويدي": "Al-Huwaidi", "الجريسي": "Al-Juraysi", |
|
|
"البدراني": "Al-Badrani", "المهيدب": "Al-Muhaidib", "السالم": "Al-Salem", "الحارثي": "Al-Harthi", |
|
|
"العطوي": "Al-Atawi", "الصخري": "Al-Sakhri", "الرحيلي": "Al-Rahili", "السعيد": "Al-Saeed", |
|
|
"الحافظ": "Al-Hafiz", "الوهيبي": "Al-Wahaibi", "البراك": "Al-Barrak", "الضويان": "Al-Dhuwayan", |
|
|
} |
|
|
return transliteration_map.get(arabic_name, arabic_name) |
|
|
|
|
|
|
|
|
def generate_contacts() -> List[Dict]: |
|
|
""" |
|
|
Generate 500 fake contacts distributed across all divisions. |
|
|
Returns a list of contact dictionaries. |
|
|
""" |
|
|
contacts = [] |
|
|
contact_id = 1000 |
|
|
|
|
|
|
|
|
divisions = list(DIVISION_TO_DEPARTMENT.keys()) |
|
|
|
|
|
|
|
|
contacts_per_division = 500 // len(divisions) |
|
|
extra_contacts = 500 % len(divisions) |
|
|
|
|
|
for div_index, division in enumerate(divisions): |
|
|
department_name, department_id = DIVISION_TO_DEPARTMENT[division] |
|
|
|
|
|
|
|
|
num_contacts = contacts_per_division |
|
|
if div_index < extra_contacts: |
|
|
num_contacts += 1 |
|
|
|
|
|
|
|
|
|
|
|
seniority_distribution = [] |
|
|
seniority_distribution.extend(["executive"] * max(1, int(num_contacts * 0.10))) |
|
|
seniority_distribution.extend(["management"] * max(1, int(num_contacts * 0.20))) |
|
|
seniority_distribution.extend(["specialist"] * max(1, int(num_contacts * 0.50))) |
|
|
seniority_distribution.extend(["technical"] * max(1, int(num_contacts * 0.15))) |
|
|
seniority_distribution.extend(["support"] * max(1, int(num_contacts * 0.05))) |
|
|
|
|
|
|
|
|
while len(seniority_distribution) < num_contacts: |
|
|
seniority_distribution.append("specialist") |
|
|
seniority_distribution = seniority_distribution[:num_contacts] |
|
|
|
|
|
random.shuffle(seniority_distribution) |
|
|
|
|
|
for i in range(num_contacts): |
|
|
|
|
|
is_male = random.random() < 0.6 |
|
|
|
|
|
if is_male: |
|
|
first_name_ar = random.choice(ARABIC_FIRST_NAMES_MALE) |
|
|
else: |
|
|
first_name_ar = random.choice(ARABIC_FIRST_NAMES_FEMALE) |
|
|
|
|
|
last_name_ar = random.choice(ARABIC_LAST_NAMES) |
|
|
|
|
|
|
|
|
first_name_en = transliterate_arabic_name(first_name_ar) |
|
|
last_name_en = transliterate_arabic_name(last_name_ar) |
|
|
|
|
|
|
|
|
full_name_ar = f"{first_name_ar} {last_name_ar}" |
|
|
full_name_en = f"{first_name_en} {last_name_en}" |
|
|
|
|
|
|
|
|
seniority = seniority_distribution[i] |
|
|
title_en, title_ar = random.choice(JOB_TITLES[seniority]) |
|
|
|
|
|
|
|
|
extension = generate_extension() |
|
|
email = generate_email(first_name_en, last_name_en) |
|
|
|
|
|
contact = { |
|
|
"id": contact_id, |
|
|
"first_name_ar": first_name_ar, |
|
|
"last_name_ar": last_name_ar, |
|
|
"full_name_ar": full_name_ar, |
|
|
"first_name_en": first_name_en, |
|
|
"last_name_en": last_name_en, |
|
|
"full_name_en": full_name_en, |
|
|
"title_en": title_en, |
|
|
"title_ar": title_ar, |
|
|
"division": division, |
|
|
"department": department_name, |
|
|
"department_id": department_id, |
|
|
"email": email, |
|
|
"extension": extension, |
|
|
"phone": f"+966-11-218-{extension}", |
|
|
} |
|
|
|
|
|
contacts.append(contact) |
|
|
contact_id += 1 |
|
|
|
|
|
return contacts |
|
|
|
|
|
|
|
|
|
|
|
CONTACTS_DATABASE = generate_contacts() |
|
|
|
|
|
|
|
|
CONTACTS_BY_NAME_AR = {contact["full_name_ar"]: contact for contact in CONTACTS_DATABASE} |
|
|
CONTACTS_BY_NAME_EN = {contact["full_name_en"]: contact for contact in CONTACTS_DATABASE} |
|
|
CONTACTS_BY_DIVISION = {} |
|
|
for contact in CONTACTS_DATABASE: |
|
|
division = contact["division"] |
|
|
if division not in CONTACTS_BY_DIVISION: |
|
|
CONTACTS_BY_DIVISION[division] = [] |
|
|
CONTACTS_BY_DIVISION[division].append(contact) |
|
|
|
|
|
|
|
|
def get_all_contacts() -> List[Dict]: |
|
|
"""Get all contacts""" |
|
|
return CONTACTS_DATABASE |
|
|
|
|
|
|
|
|
def get_contacts_by_division(division: str) -> List[Dict]: |
|
|
"""Get contacts for a specific division""" |
|
|
return CONTACTS_BY_DIVISION.get(division, []) |
|
|
|
|
|
|
|
|
def get_contact_by_name(name: str) -> Dict: |
|
|
"""Get contact by exact name (Arabic or English)""" |
|
|
|
|
|
contact = CONTACTS_BY_NAME_AR.get(name) |
|
|
if contact: |
|
|
return contact |
|
|
|
|
|
|
|
|
contact = CONTACTS_BY_NAME_EN.get(name) |
|
|
if contact: |
|
|
return contact |
|
|
|
|
|
return None |
|
|
|
|
|
|
|
|
if __name__ == "__main__": |
|
|
|
|
|
contacts = get_all_contacts() |
|
|
print(f"Generated {len(contacts)} contacts") |
|
|
print(f"\nSample contacts:") |
|
|
for i, contact in enumerate(contacts[:5]): |
|
|
print(f"{i+1}. {contact['full_name_en']} ({contact['full_name_ar']})") |
|
|
print(f" {contact['title_en']} - {contact['division']}") |
|
|
print(f" {contact['email']} | Ext: {contact['extension']}") |
|
|
print() |
|
|
|
|
|
|
|
|
from collections import Counter |
|
|
dept_counts = Counter(contact["department"] for contact in contacts) |
|
|
print("\nContacts by Department:") |
|
|
for dept, count in sorted(dept_counts.items(), key=lambda x: -x[1]): |
|
|
print(f" {dept}: {count}") |
|
|
|