پروژه vcard editor

( نسخهء جدیدتر این برنامه: http://hamidreza-mz2.tk/?p=1241 )

این رئیس ما توی گوشیش بیش از هزار نفر شماره تلفن (contact) داشت بعد خیلی از اینا چپرچلاق هم بودن مثلا اسمشون رو غلط زده بود یا ناقص، contact های تکراری داشت (بعضا با اسامی کم و بیش متفاوت)، شمارهای مختلف توی فیلدهای رندوم زده بود، بعضی فیلدها چندتا شماره داشت (ظاهرا بعضی گوشی های قدیمی مثل مال خودم ساپورت نمیکنن)، خلاصه بهم ریخته و زیاد.
گفتش میخوام اینو بریزیم توی سیستم و اونجا ویرایشش کنیم منظم و اصلاح کنیم تکراری هاش رو هم شناسایی و حذف کنیم.

رئیس ما فکر میکرد کار راحتیه همینطور میریزی توی کامپیوتر و سه سوت میاد روی صفحه آمارش و درست میکنی و سه سوت هم برمیگردونی توی گوشی. ولی اینطوری نبود!
خب ما بلوتوث کردیم روی سیستم یه فایل با پسوند vcf بهمون داد با بیش از هزار contact.
توی فایل رو نگاه کردم دیدم اسمها هم انکد شدن، ولی سریع فرمتش رو شناختم (توی PHP تابعش هست) که Quoted-printable بودش.
از اون موقع توی فکر افتادم که یه برنامه خودم بنویسم که فرمت vcard رو بخونه. ولی گفتم بذار اول مقداری سرچ و تست کنم ببینم اگر برنامه آماده هست و امکانات لازم رو داره خب از اون استفاده کنم.
ولی با چند مورد سرچ و تست که بنده انجام دادم متوجه شدم که در این زمینه خیلی هم برنامه های زیاد و بی نقصی موجود نیست. با MS outlook هم تست کردم که جواب نداد و با این contact های زیاد ما مشکل داشت یکی اینکه فقط چند ده تا از هزار و خورده ای contact رو ایمپورت میکرد و دیگر اینکه اصلا بعدا نمیدونم چرا با انکدینگ و فارسی هم مشکل پیدا کرد و عجق وجق نشون میداد!
حتی یک سرویس آنلاین برای تبدیل vcard به فایل اکسل رو هم تست کردم (گفتم میبرم توی اکسل اونجا منظم و اصلاح میکنم و بعد دوباره از اکسل به vcard تبدیل میکنم) که اونم همین مشکل رو داشت. فکر کنم یکی دو برنامهء رایگان رو هم تست کردم که اونا هم ویژگیهای لازم رو نداشتن. من یه برنامه میخواستم که هم بتونه تعداد اینقدر زیاد contact در یک فایل vcf رو هندل کنه و هم با فارسی مشکلی نداشته باشه و هم امکانات و ویژگیهای لازم برای نظم دادن و ویرایش اونا رو داشته باشه، یعنی مثلا بتونم همزمان تمام contact ها رو بر اساس هر ستون مرتب و مقدارهای تکراری رو شناسایی کنم و راحت هم حذف و ویرایش کنم و اینا!
آهان راستی ناگفته نماند که برنامهء خود گوشی هم روی سیستم نصب نمیشد بخاطر قدیمی بودن سیستم و ویندوزش
کی حال داشت این سیستم قدیمی و هارد پر شده با کلی دیتا و برنامه رو پاک کنه و دوباره ویندوز و تشکیلات نصب کنه، تازه کلی وقت هم میخواست.
خلاصه بعد از این جریانات گفتم مثل اینکه این یکی از پروژه هایی هست که تاحالا دست توش زیاد نبوده و برنامه های زیاد و با امکانات کامل و همه کاره ای نداره و بنابراین بهتره خودم برم روی کارش ببینم چه میکنم بالاخره یه تمرین برنامه نویسی هم هست که هرچند وقت یک بار انجام بدم خوبه.
اول فکر کردم کار چندان سخت و زمانبری نیست چون فرمت vcard متنی و ساده بنظر میامد، و فکر کردم مقداری وقت گذاشتن در آخر هفته که فرصت میکنم برای درست کردن برنامش کافیه، اما بعدا متوجه شدم که کار چند برابر سخت تر از اینه و به چندتا آخر هفته نیاز داره!
بهرحال بنده این برنامه رو درست کردم، هرچند به دلایلی آخرش ازش استفادهء نهایی صورت نگرفت!! ولی بهرحال تجربهء خوبی بود و در آینده ممکنه به درد خودم یا دیگران بخوره. هرچند این برنامه رو الان نمیتونم بگم کامل و همه کاره است، چون فقط برای یک کار خاص و با عجله و مهندسی معکوس و تست محدود رو contact های رئیسم درستش کردم، و همه جور امکاناتی نداره و تست و تضمین کافی نشده که به مشکلی نخوره، اما فکر کنم بازم ارزشش رو داشته باشه که منتشرش کنم، یکیش بخاطر اینکه بوده برنامه ها و کدهایی که خودم یه زمانی نوشته بودم و در گذر زمان گم یا نابود شدن و دیگه حتی خودمم دستم بهشون نرسیده!

دانلود برنامه: دانلود

خب حالا بریم سر توضیحات فنیش.
من یه فایل vcf نمونه درست کردم همراه برنامه گذاشتم.
برنامه از این فایل contact ها رو میخونه و روی همین فایل هم save میکنه.
آهان یه نکته یادم نره همینجا بگم که اگر contact های شما مثل مال ما خیلی زیاد باشه، نیاز میشه تا مقدار max_input_vars رو در php.ini تغییر بدید و به عددی مثل 5000 هزار افزایش بدید.
توضیحات دیگر اینکه این برنامه یکسری فیلدهای از پیش تعریف شده رو نمایش میده که همشون (بجز فیلد عکس) قابل ویرایش هستن. بجز نام، بقیهء فیلدها (که فیلدهای شماره تلفن هستن) بصورت textarea تعریف شدن که شما بتونید در یک فیلد بیش از یک شماره تلفن هم وارد کنید (هر شماره رو در یک خط جداگانه وارد کنید).
شما یکسری فیلدهایی رو خواهید دید که دورشون یک خط رنگی (border) هست. اینا معنای خاصی دارن. فیلدهایی که دورشون خط قرمز زده نشون میده که در سطر قبلی در همون فیلد، یعنی درست در فیلد بالای سرش در سطر/contact قبلی، اون شماره موجوده. اینطوری میتونید شماره های تکراری رو خیلی راحتتر در بین این همه contact با یک نگاه شناسایی کنید. البته باید توجه داشت که پیدا شدن شماره های تکراری به این شکل به اینکه سطرها در برنامه بر اساس چه ستونی مرتب شده باشن هم بستگی داره (باید یک بار بر اساس نام مرتب کنید تا اسمهای تکراری رو پیدا کنید، یک بار بر اساس فیلد tel-cell، و همینطور بر اساس فیلدهای شماره دیگر).
فیلدهایی که دورشون border نارنجی میزنه به این معناست که اون شماره در سطر قبل هم دیده شده، ولی درست بالای سرش، یعنی در فیلد یکسانی نبوده. بنابراین باید در سطر قبلی نگاه کنید که اون شماره در کدوم فیلد اومده.
راستی محتویات فیلدهای شماره ای که بیش از یک شماره در اونا درج شده با رنگ قرمز به نمایش در میان که تشخیص اونا ساده تر بشه. علتش اینه که من ابتدا فکر میکردم که درج بیش از یک شماره در یک فیلد احتمالا غیراستاندارده و ممکنه در گوشی همهء این شماره ها در دسترس قرار نگیرن (البته در گوشی رئیسم ظاهرا اینطور نیست ولی مال خودم که بعدا تست کردم این محدودیت رو داشت و فقط یک شماره رو نشون میداد).
لیست متغییرهای کانفیگ برنامه:
$file='vcards.vcf';
$sort_field='no';
$sort_dir=SORT_ASC;
$aggregate_cell_numbers=false;
$kaaf8yeh='fa';
$preserve_photos=true;

متغییر file فایل ورودی و خروجی contact ها رو مشخص میکنه. توجه کنید که تمام تغییرات بعد از فشردن دکمهء save contacts، در همین فایل ذخیره میشن و این عملیات قابل برگشت نیست. بنابراین از فایل اولیه خودتون حتما یک نسخهء بکاپ داشته باشید.
متغییر sort_field فیلدی رو که مرتب سازی بر اساس اون صورت میگیره مشخص میکنه. مقدار این متغییر میتونه یکی از مقادیر موجود در آرایهء fields باشه؛ مثلا: name, tel-cell, tel-home و غیره. البته مرتب سازی پس از این فیلد، بر اساس نام هم همیشه اعمال میشه.
این متغییر دو مقدار خاص هم داره، یکی no و دیگری rand. با دادن مقدار no، برای برنامه مشخص میکنید که نمیخواید هیچگونه مرتب سازی روی contact های شما صورت بگیره. با تعیین مقدار rand مشخص میکنید که برنامه خودش ترتیب contact ها رو بصورت رندوم بهم بریزه (این گزینه برای توسعه و تست میتونه کاربرد داشته باشه).
متغییر sort_dir صعودی یا نزولی بودن مرتب سازی رو مشخص میکنه.
متغییر aggregate_cell_numbers اگر true باشه باعث میشه که شماره های موبایل که در فیلدهای دیگری غیر از tel-cell پیدا میکنه به فیلد tel-cell منتقل کنه تا تمام شماره های موبایل تحت یک فیلد در هر contact قرار بگیرن. ضمنا ستون شماره ردیف سطرهایی که اینطور شماره هایی داشتن و این عمل انتقال شماره روشون انجام شده با رنگ زمینهء آبی مشخص میشن تا شما بفهمید که اون سطر چنین شماره ای داشته و عمل انتقال شماره روش صورت گرفته. البته توجه داشته باشید که تا زمانی که شما این تغییرات رو بوسیلهء کلید save contacts سابمیت نکردید، هیچ چیزی در فایل ذخیره نمیشه و این عمل فقط در نمایش contact ها وجود داره.
متغییر kaaf8yeh مشخص میکنه که شما میخواید بطور خودکار عمل تبدیل به حروف ک و ی فارسی یا عربی در اسمها صورت بگیره (فکر کردم ممکنه نیاز بشه و از گوشی به گوشی هم تفاوت داشته باشه). دو مقدار fa و ar رو میتونید بهش بدید.
preserve_photos اگر false بشه باعث میشه که موقع save کردن contact ها، عکسهای اونا ذخیره نشن (و به این شکل تمامی عکسهایی که در contact ها داشتید از بین میرن/پاک میشن).

راستی یک فایل بنام show_all_fields.php هم همراه این برنامه هست که کاربردش برای موقع توسعه برنامه است که باهاش میتونید تمام فیلدهای رو که در یک فایل vcf وجود دارن شناسایی کنید. مثلا فایل vcf ما چون تعداد خیلی زیادی contact داشت نمیشد به راحتی با نگاه کردن مطمئن شد که چند نوع فیلد درش هست، بخاطر همین بنده این کد رو نوشتم که تمام انواع فیلدهایی رو که در این همه contact وجود دارن لیست کنه تا بتونم دامنهء کارم رو به اون فیلدها محدود کنم (احتمالا فرمت رسمی/استاندارد vcard فیلدهای تعریف شده بیشتری داره).

ضمنا این برنامه برای کار با فرمت vcard نسخهء 2.1 طراحی شده (چون فرمت فایل ما این بود). البته ظاهرا این نسخه متداول ترین نسخهء استفاده شده فرمت vcard درحال حاضر است.

یه چیزی که یادم رفت اینکه، متاسفانه این برنامه امکان اضافه کردن contact جدید رو نداره، چون همونطور که گفتم این برنامه رو برای کاربرد و هدف مقطعی خاص محیط کاری خودم نوشتم که اضافه کردن contact جزو نیازهاش نبود. ولی اضافه کردن چنین امکانی بهش، اصلا فکر نکنم کار سختی باشه!

فعلا این برنامه و کد رو منتشر کردم تا از بین نره و بتونه نمونه و الگو و احتمالا بیس برای کارهای بعدی خودم یا دیگران باشه. شاید نیاز کسی بشه. ضمنا مبتدی ها میتونن ازش چیزهای مهمی رو یاد بگیرن. یکی اینکه رگولار اکسپرشن در بعضی کاربردها چقدر مهم و کارا و اساسیه. در این پروژه چند جا رگولار اکسپرشن بکار رفته که اساسی بوده و بدون اون انجام این پروژه خیلی دشوارتر و حجیم تر میشد.
راستی مرتب سازی بر اساس چند فیلد در آرایه های چند بعدی (بوسیلهء تابع array_multisort) هم چیزی بود که خودم در این پروژه نیاز پیدا کردم و تازه یاد گرفتم! (البته شایدم قبلا در فرنس خونده بودم، ولی یادم نبود).
یکی دیگر از مسائلی که از ابتدا باید درموردش در این پروژه تصمیم میگرفتم بهینه سازی بود. مثلا چون تعداد contact ها زیاد بود (هر contact هم که خودش کلی اطلاعات داره و ممکنه عکس هم داشته باشه) اگر تمام اونا رو یکجا میخوندیم و در حافظه در مثلا یک آرایه ذخیره میکردیم، طبیعتا RAM قابل توجهی رو اشغال میکرد؛ هرچند این مقدار برای رایانه های امروزی عدد بزرگی بحساب نمیاد! و اون وسوسه و وسواس معروف بهینه سازی پیش از موعد (یا بر اساس تصورات آزمون نشده و بدون شواهد و نیاز عینی/عملی)، به سراغ منم اومد. با خودم گفتم اوه یعنی الان من این همه دیتا رو یکجا توی آرایه بریزم بخاطر یکسری عملیات ساده و کوچک؟ اونوقت این یک روش برنامه نویسی ناشیانه نخواهد بود؟ آیا بعدها به رایانه ها و سرورها فشار نخواهد آمد و مشکل ایجاد نخواهد شد؟ … ولی دست آخر به این نتیجه رسیدم که این همون مصداق وسواس در بهینه سازی و بهینه سازی زودهنگام است که بزرگی میگه ریشهء تمام بدی هاست! گفتم بیخیال همه رو یکجا میریزم توی رم خیالم هم نیست بذار به کامپیوتر یخورده فشار بیاریم تازه این که چیزی نیست مگه میخوام حالا آمازون و فیسبوک درست کنم یا دارم به چند هزار نفر سرویس میدم! گفتم وقت و انرژی من دانشمند ارزشمندتر از اونه که مدام بخوام بخاطر آسایش کامپیوتر هدرش بدم. گفتم امروزه یک اولویت مهم در برنامه نویسی، سرعت و راحتی و امنیت هرچه بیشتر در فرایند کدنویسی و به نتیجه نهایی رساندن برنامه است، نه انجام همه چیز با صرف کمترین پردازش و منابع سخت افزار! نه بهینه سازیهای جزیی و هوشمندبازی و نابغه بازی درآوردن های سطحی. من اگر میخواستم/واقعا لازم بود یا بعدا نیاز بشه میتونستم روشهای بهینه تری رو طراحی و پیاده سازی کنم، ولی الان که نیاز و توجیه و دلیل قانع کننده کافی وجود نداره و هدف خودنمایی یا تمرین و یادگیری بهینه سازی هم ندارم!

پاسخ دهید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *

*

شما می‌توانید از این دستورات HTML استفاده کنید: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>