jiyuu-מחשבות פתוחות

התפרצויות כתיבה

30/06/2008 08:12 ע"י כתריאל טראום

הרבה זמן כבר לא כתבתי כאן.
מודה, קצת היתה חסרה לי מוזה. אם אין לי מוזה, אני לא כותב. ככה זה גם כשאני כותב קוד, יש לי לפעמים "התפרצויות כתיבה" בהן אני מסוגל לכתוב אפליקציה שלמה, או לגמור איזה feature שרציתי להוסיף ל-Jiyuu במכה.

יצא לי היום לקרוא קצת את ה-Planet של המקור, וקפץ לעיני הפוסט של נדב על חוסר עדכון הבלוג שלו. קצת חרגתי משלושת שבועות שלו, אבל ניחא. Better late than never.

אז מה חדש… מערכת ההתקנה שכתבתי ב-Python פחות או יותר הושלמה, ועושה את המלאכה בצורה די טובה. שמחתי שיצא לי לכתוב אותה, למדתי הרבה על Python, דברים כמו שימוש במחלקות (Classes), שגיאות (Exceptions) ומודולים. כמובן שיש עוד המון ללמוד, והפרויקט הבא כבר בדרך.

הפרויקט הבא דווקא לא קשור ישירות ל-Python, אבל יש לי כוונה להשתמש בו למרות זאת. עלה צורך בעבודה לנתח מספר רב של קבצי tcpdump בפורמט pcap ולחלץ מהם קצת מידע וסטטיסטיקות. עם כל ההייפ לאחרונה סביב Cloud Computing, החלטתי גם לקפוץ על העגלה. הכוונה היא להשתמש ב-hadoop שרץ על כמה מכונות וירטואליות שמפוזרות על כמה מכונות פיזיות כדי לחלק ולבזר את פעולת הניתוח. איך Python קשור? למרות ש-hadoop כתוב ב-java ומספק API ל-java, יש אפשרות להתממשק אליו בעזרת streams. הכוונה היא לשלב את hadoop יחד עם Python ו-pylibpcap כדי לחלץ את המידע הרלווטי ולסכם אותו תוך שימוש במנגנון MapReduce.

קצת שאפתני, אני יודע. אבל אם לא שואפים גבוהה, לא לומדים.

זהו בנתיים. עדכונים ואולי איזה מדריכון על hadoop בקרוב.

SQLite ו-Full Text Search

15/05/2008 22:15 ע"י כתריאל טראום

כאשר הוספתי יכולות חיפוש ל-Jiyuu, החלטתי קודם לבדוק האם יש ל-SQLite יכולות של Full Text Searching. לשמחתי ולדאבוני, גיליתי כי יכולת כזו קיימת, אך רק כהרחבה, אשר אינה זמינה ברוב אם לא בכל ההפצות כיום. מסיבה זו החלטתי להשתמש בשאילתות סטנדרטיות עם LIKE.

כאשר בחנתי את הרחבת ה-Full Text Search גיליתי כי היא מעניינת ומלאת אפשרויות, ולכן החלטתי לחקור אותה קצת ולשתף אתכם עם המסקנות.

הקדמה קצרה

Full Text Search היא טכניקת חיפוש שמאפשרת חיפוש מהיר (בד"כ) בכמות גדולה של מסמכים או כל מקור טקסט אחר. כאשר כמות המסמכים שיש לחפש בהם היא קטנה, ביצע חיפוש רגיל (חיפוש סריאלי או סדרתי) בד"כ יספק תוצאות במהירות סבירה יחסית. אבל מה עושים כאשר יש מאות או אלפי מסמכים לחפש בהם?

Full Text Searching (או FTS) היא טכניקה אשר מחולקת ל-2 חלקים: יצירת Index וחיפוש:

  • יצירת Index הוא תהליך של מיפוי הטקסט או טקסטים ויצירת Index בר-חיפוש של הטקסט.
  • תהליך החיפוש הוא תהליך שליפת המידע. החיפוש עצמו לא ניגש לטקסטים אלא ל-Index שנוצר מבעוד מועד ומאפשר שליפה מהירה של הטקסט, בלי סריקה מלאה שלו.

דוגמה קלאסית מעולם הקוד הפתוח לאפליקציית Full Text Searching היא Beagle אשר משתמש במנוע Indexing בשם Lucene, ליצירת Index של מידע אישי ואחזור מהיר שלו (מסמכים\אימיילים ועוד).

FTS ו-SQLite

בעולם מסדי הנתונים, שימוש ב-FTS אינו קיים או מוגדר כתקן (ANSI SQL), ובד"כ אם יש אפשרות כזו, זו היא הרחבה של מסד הנתונים.

יש הטוענים, ובצדק, כי מסד נתונים הוא אינו המקום לאחסן כמויות או את סוג המידע שיצריך שימוש ב-FTS. לראיה, מספר הפרויקטים\מוצרים (פתוחים או לא) אשר מיישים FTS לאחזור מידע וטקסט (ואינם מסדי נתונים) הוא די גדול.

אבל אני טוען, כי בימינו, כמות המידע אשר נדחס לתוך מסדי נתונים הולך וגדל. עם העליה של כמות הבלוגים והתוכן בהם, כמות אתרי החדשות והתוכן בהם וכו', השימוש ב-FTS כבר לא כל כך מופרך במסדי נתונים.

SQLite, כמו מסדי נתונים אחרים, מיישם גם הוא FTS, כהרחבה, אשר לצערי עדיין אינה נכללת ברוב ההפצות. קימפול של sqlite עם FTS הוא יחסית פשוט ומוסבר בקישור הבא. שימו לב כי ההוראות הן לגבי fts1 אבל נכונות גם לגרסאות החדשות יותר fts2\fts3 אשר נכללות בגרסאות האחרונות של sqlite.

בניית טבלאת FTS

לאחר בנייה של sqlite עם fts3, ניתן להתחיל לצור טבלאות אשר יבנו Index של המידע שנוסף אליהן. כדי לבנות טבלה אשר תשתמש ב-FTS משתמשים בתחביר הבא:

create virtual table email using fts3(subject, content)

פקודה זו תצור טבלה אשר יבנה לה Index מסוג FTS, ותאפשר אחזור מידע בעזרת פקודות SQL מתאימות.

הכנסת מידע

הכנסת מידע לטבלה נעשית בצורה סטנדרטית, ללא צורך בשינוי התחביר הסטנדרטי של SQLite

INSERT INTO email (subject, content) VALUES \
('meeting summary','summary for tuesday 23rd meeting \
 about bugs in the soup');
INSERT INTO email (subject, content) VALUES \
('trip plans','trip plans for upcoming flight to europe');

אחזור מידע

באחזור המידע מתגלה הכח והגמישות של הרחבת ה-FTS של SQLite. ההרחבה מאפשרת שליפה לא רק מהירה יותר כאשר מדובר בכמות מסמכים גדולה, אלא גם גמישה. שליפה סטנדרטית היא בעזרת שימוש במילת הברירה MATCH:

sqlite> SELECT subject, content FROM email \
WHERE content MATCH 'soup';
meeting summary|summary for tuesday 23rd meeting about bugs in the soup

FTS מאפשר שליפות שונות נוספות, למשל שליפה עם שלילה של מילים:

sqlite> SELECT * FROM email WHERE content MATCH 'for -meeting';
trip plans|trip plans for upcoming flight to europe

מכיוון ששאילתות FTS יכולות להכיל רק MATCH אחד, ניתן גם להשתמש בשם העמודה בשאילתה:

sqlite> SELECT subject FROM email where email MATCH \
'subject:plans content:europe';

trip plans

מכיוון שכל המידע שנשמר בטבלאות FTS הוא מידע שעובר אינדוקס מלא, לפעמים נוטים לחלק את הטבלאות ל-2: טבלאות metadata וטבלאות FTS. ניתן לאחזר מידע ע"י שימוש ב-JOIN וכך לקבל את כל המידע בשאילתה אחת. למשל הרצף הבא יחזיר את כל כותרות האימיילים והשולח שלהם שמכילים את המילה "some":

sqlite> create virtual table email using fts3(subject, content);
sqlite> create table email_meta (sender text, date integer);
sqlite> insert into email_meta values ('abc@def.com', 1210878295);
sqlite> insert into email values ('email from me','with some content');
sqlite> select sender, subject from email_meta join email_body \
 on email_meta.rowid = email_body.rowid where content match 'some';

abc@def.com|email from me

אלו הן, על קצה המזלג, היכולות של הרחבת ה-FTS של SQLite. ניתן למצוא מידע נוסף בויקי של SQLite

שימוש ב-HTML_QuickForm בשילוב עם Smarty

08/05/2008 22:24 ע"י כתריאל טראום

מכיוון ששתי אלו "טכנולוגיות" שאני משתמש בהם ב-Jiyuu בכל מקרה, חשבתי אולי אכתוב איזה מדריכון על איך לשלב בין השתיים.

הקדמה

לדעתי, 2 מהדברים הכי מייגעים בבנית כל אפליקציית Web הוא כתיבת טפסים ועיצוב הפלט.

  • השילוש הקדוש של יצירה\עריכה\מחיקה הוא אחד מהדברים האחרונים שאני תמיד כותב.
  • עיצוב העמודים, אם יש משהו שאני לא אוהב זה המגושמות של שילוב של HTML בתוך PHP או להפך.

2 הפתרונות שמצאתי, אשר עוזרים ומקלים עלי הם HTML_QuickForm ו-Smarty. שניהם פתרונות שבנויים כ-Class אשר מאפשרים שימוש נוח ואפילו הרחבה בעת הצורך.

HTML_QuickForm

HTML_QuickForm היא הרחבת PEAR שמאפשרת בניית טפסים בצורה מונחת עצמים ונוחה. דוגמה קטנה:

require_once('HTML/QuickForm.php');
$form = new HTML_QuickForm('formName','post');

$form->addElement('text','name','Name');
$form->addElement('text','address','Address');
$form->addElement('text','email','E-Mail');
$form->addElement('submit','send','Send');

$form->addRule('name','Please enter name','required');

if ($form->validate()) {
  // save data
} else {
  $form->display();
}

קל לראות איך זה מקצר את העבודה המייגעת של בניית טפסים. יותר מזה, השימוש בפונקציה setDefaults מאפשרת הכנסת ערכים לשדות, לבניית טפסי עריכה בקלות:

$form->addElemnt('text','name','Name');
$form->addElement('text','address','Address');

//Fetch data from DB

foreach ($resultSet as $key => $val) {
 if ($form->elementExists($key)) {
  $form->setDefaults(array($key=>$val));
 }
}

הפלט שמייצר HTML_QuickForm נראה סביר, אבל משתמש בשיטות בניית HTML שקצת פסו מן העולם: טבלאות.

Smarty

ה"שנאה" השניה שלי היא בניית דפי HTML דרך שילוב PHP בתוך הדף או שליחת פלט HTML-י דרך קוד PHP. לאחר בחינת כמה חלופות, בחרתי ב-Smarty. המנוע מאפשר בניית דפי HTML ו"שתילת" משתנים ופונקציות שמוחלפות בזמן עיבוד ה-Template. שימוש ב-Smarty אולי לא נראה נחוץ ואפילו קצת Over-Kill באפליקציות קטנות כמו Jiyuu. אבל גם כאן, אני חושב שכל אפליקציה יכול להרוויח מההפרדה בין HTML ל-PHP. דוגמה לקוד שמשתמש ב-Smarty:

$smarty = new Smarty();

$smarty->assign('itemList',fetchItemList());
$smarty->register_function('formatTimeString','_formatTimeString');

$smarty->display('template.tpl');

והשבלונה אשר אותה מציג הקוד:

<ol>
{foreach from=$itemList item=$item}
 <li>{formatString param=$item}</li>
{/foreach}
</ol>

ההפרדה בין קוד ל-HTML אומנם תשרת טוב יותר מפתחי אפליקציות גדולות יותר בהן יש אנשים אשר אחראים על עיצוב התוכן ואחרים על פיתוח הלוגיקה. בכל זאת, אפילו באפליקציות קטנות כמו Jiyuu, היתרון הוא די ברור.

שילוב בין השתיים

כמו שכבר ציינתי, פלט ברירת המחדל של HTML_QuickForm הוא טבלאי ולא ממש גמיש. לשמחתי, ל-QuickForm יש תמיכה ב-Renderers שונים שמאפשרים לשנות את הפלט של הטופס, אחד מהם הוא SmartyArray. שימוש ב-SmartyArray מאפשר שיוך של Array ל-Template ושימוש באותו ה-Array, אשר מכיל את כל המידע של הטופס בתוך ה-Template. את הדוגמא הראשונה של בניית הטופס נצטרך לשנות מעט:

require_once('HTML/QuickForm.php');
require_once('HTML/QuickForm/Renderer/ArraySmarty.php');
$form = new HTML_QuickForm('formName','post');
$tpl = new Smarty();
$renderer =& new HTML_QuickForm_Renderer_ArraySmarty($tpl);

$form->addElement('text','name','Name');
$form->addElement('text','address','Address');
$form->addElement('text','email','E-Mail');
$form->addElement('submit','send','Send');

$form->addRule('name','Please enter name','required');

if ($form->validate()) {
 // save data
} else {
 $form->accept($renderer);
 $tpl->assign('form', $renderer->toArray());
 $tpl->display('form.tpl');
}

וה-Template יראה כך:

<form {$form.attributes}>
  {$form.hidden}
  {$form.name.label} {$form.name.html}<br />
  {$form.address.label} {$form.address.html}<br />
  {$form.email.label} {$form.email.html}<br />
  {$form.send.html}     
</form>

פלט לדוגמא של הטופס ניתן לראות בכתובת הבאה

קצת חידושים

24/04/2008 22:23 ע"י כתריאל טראום

אחרי כמה זמן בתנור, סוף סוף מצאתי את הזמן לסגור כמה באגים ולעדכן את הבלוג לגירסה חדשה, משוכתבת חלקית של jiyuu.

הגירסה החדשה כוללת כמה שיפורי מהירות, יציבות, הורדת סיבוכיות ופלונטרים שנכנסתי אליהם בזמן הכתיבה של Jiyuu.

קשה כמובן לפספס גם את החידוש במראה. הפכתי את הבלוג ליותר סטנדרטי, תוך שימוש בתגי HTML סטנדרטיים, במקום יצירת CSS Styles עבור כל שטות בבלוג.

אז מה יש לנו:

  • העברתי את כל ה-HTML לתוך תבניות Smarty
  • הפכתי את כל הטפסים בבלוג למבוססי HTML_QuickForm
  • הסכמה של sqlite עברה בחינה תחת "חוקי הנירמול" וקיבלה עוד כמה שיפורים בדמות Triggers אשר יעזרו לשמור על שפיות המידע
  • גירסת ה-xajax שודרגה

סה"כ, מרגיש יותר יציב בעבודה. מי שמעוניין, מוזמן לשלוח לי מייל ל katriel AT traum.org.il ולקבל עותק של jiyuu.

חג אביב שמח

20/04/2008 13:01 ע"י כתריאל טראום

פסח הגיע, זמן לאוורר את הבלוג ולכתוב איזה פוסט.

נתחיל באיחולי חג שמח לכל. פסח הוא אחד מהחגים האהובים עלי, זו תמיד תקופה של פריחה והתחדשות. בניגוד לשנים שעברו, שבהם ביליתי שעתיים על הכביש לפני הסדר, יצא לי השנה לעשות את הסדר די קרוב: אצל השכנה שגרה בדלת מולי, מרחק 10 צעדים.
נחמד לדעת שאחרי ארוחה גדולה, וכמה כוסות יין, כל מה שצריך לעשות זה ללכת כמה צעדים, להתארגן וליפול לשנת שיכורים ארוכה (וכך היה יש לציין).

לאחרונה כתבתי שהתחלתי ללמוד קצת Python. תמיד האמנתי כי שפה (בין עם תיכנות ובין אם דיבור\כתיבה), אי אפשר ללמוד כמו שצריך בלי להשתמש בה. אם רק לומדים אותה תאורטית, הלימוד לא יהיה שווה, וישכח במהרה. לכן התחלתי לחפש תירוץ טוב ליישם את מה שלמדתי ב-Python. המזל האיר פנים, ונפלה בחלקי הזדמנות לכתוב עבור פרויקט מסויים שקשור לעבודתי מערכת התקנה לאפליקציה מסחרית גדולה, שכמובן החלטתי ליישם ב-Python.

עד עכשיו, הרשמים שלי מפייתון הם רק טובים. גם כשפת סקריפטים פשוטה, וגם כשפה שמיישמת OO בצורה פשוטה ויעילה. אני לא מתכנת, אבל יש הרגשה שכאילו כתבו את השפה הזו היישר מתוך איזה ספר של Programming Best Practices. סתם דוגמה פשוטה, אבל שדי מסכמת את החויה.
כדי לכתוב קוד בשפה אחרת צריך להיות בתוך {} (למשל קוד שרץ תחת if), במקום לגבול את הקוד ב-{}, פשוט משתמשים ב-indentation כלשהו, tab או רווח יספיקו. התוצאה היא קוד שחובה לכתוב אותו בצורה קריאה וברורה, אחרת הוא פשוט לא קוד תקף. ישנן עוד המון דוגמאות כאלו, שבהחלט הפכו את Python לשפה החביבה עלי לאחרונה.

לא הרבה קורה

23/03/2008 22:14 ע"י כתריאל טראום

הכותרת אומרת הכל אני חושב…

שוב מילואים. בשונה מפעם שעברה, הפעם הם קצרים ומפוזרים על גבי כמה ימים. חוצ'מזה, עבודה, עבודה ועוד עבודה.

בין לבין, יוצא לי קצת לעבוד על jiyuu. הגעתי למסקה שאני קצת חוטא למטרה הראשונית שלי של jiyuu, והיא לשמור את המערכת פשוטה ונקיה. הקוד התחיל להתנפח ולהסתבך כל כך עד שהייתי צריך לעקוב ולרדוף אחרי שורת פלט אחת ב-3 קבצי PHP שונים. בהחלט לט מה שרציתי.
לכן החלטתי לשכתב קצת את jiyuu, גם לשמור את המערכת פשוטה יותר, וגם להשתמש ברכיבים סטנדרטיים. שימוש ברכיבים סטנדרטיים אמור להוריד את כמות הקוד הכתוב, ולעלות את כמות הרכיבים שניתן למחזר בקוד. בחרתי ב-2 כלים כדי לבצע את העבודה השחורה בשבילי:

  • smarty - מנוע שבלונות מצויין, ובנוסף מספק מנוע caching מצויין
  • HTML_QuickForm - הרחבת PEAR שמאפשרת בניה קלה ומהירה של טפסים, אשר תשמש ליצירת טפסי הוספה\עריכה של מידע ב-jiyuu.

בנושאי עבודה, יוצא לי לאחרונה לעבוד קצת עם Jython, שהוא יישום של מפענח לשפת Python שכתוב כולו ב-Java. אני משתמש בו דרך מוצר צד שלישי מסחרי כלשהוא.

השימוש הזה בטכנולוגיה בקוד פתוח ע"י חברה מסחרית, שוב העלה בי את המחשבה על איך וכמה קוד פתוח חילחל כבר לכל כך הרבה פינות, שאפילו חבריות מסחריות כבר לא "מתביישות" להשתמש (יש שיגידו לנצל) באותן טכנולוגיות פתוחות.

אם בעבר עבור חברה מסחרית שימוש בקוד פתוח היה "טאבו", או משהו אשר השתמשו בו רק כמוצר פנימי, הרי שבימינו, נראה שקניה של חברת קוד פתוח, והמשך פיתוח המוצר שלה ככזה, היא הדבר החם בשוק (ראו רכישת XenSource ו-MySQL). רבות כבר נידון על הנושאים האלו, אבל מבחינתי, זו היא סוף סוף ההכרה שמה שהרבה מאיתנו כבר יודעים מזה זמן רב (קוד פתוח=טוב יותר, כיף יותר, <דעתכם על קוד פתוח כאן>), יכול להיות מתורגם גם לעולם העיסקי.

מנהלי חבילות ב-Slackware

26/02/2008 20:47 ע"י כתריאל טראום

אחרי שעבדתי עם Slackware תקופה כ-VM, החלטתי שאולי הגיע הזמן לעבור לדבר האמיתי. הורדתי לי DVD של Slackware 12.0 בביטורנט, והתקנתי. אחרי כמה מהמורות קלות בזמן ההתקנה (לא יצר לי initrd), עלתה לי מערכת חדשה, קטנה וקומפקטית.

עכשיו צריך להתחיל ולהתקין חבילות נוספות. Slackware מגיע עם KDE כברירת מחדל, בעוד אני רציתי להשתמש ב-Gnome. בחיפוש מהיר מצאתי את Gnome SlackBuild: כל חבילות גנום 2.20 מקומפלות ומוכנות להתקנה. כל זה הוביל אותי לבעיה הבאה, איך אני מתקין עכשיו כמה עשרות של חבילות, בצורה ידנית. מה עושים? מחפשים מנהל חבילות.

אז נכון, קצת "התברגנתי" (נהייתי בורגני), לא ממש תואם את הרוח של Slackware (אבל עובדה שמצאתי כמה, סימן שאני לא לבד), אבל הפך להכרח ברגע שרציתי להתקין את גנום.

קצת נוסטלגיה

12/02/2008 17:04 ע"י כתריאל טראום

אחרי שראיתי וקראתי את הראיון עם Patrick Volkerding, יוצר ההפצה Slackware, החלה עולה בי תחושה בלתי ניתנת לעצירה של נוסטלגיה.

את ימי כלינוקסאי, התחלתי אי שם בשנות התשעים, עוד בבית הספר. המורה שלי לאסמבלר נתן לי CD עם משהו שנקרא "לינוקס", וביקש שאנסה את המערכת הפעלה, הוא חשב להכניס את המערכת לשימוש בבית הספר.

מאז אותו הרגע, התחילה מסכת ארוכה של נסיון וטעיה (שנמשכת עד היום יש לציין), עד שהיתה לי מערכת עובדת על ה-386 ה"חדש" שלי. מאוחר יותר עברתי ל-Red Hat (גירסה 5.2) אחרי שהמליצו לי על ההפצה ב-IRC.

לאורך השנים די נשארתי עם Red Hat/Fedora, למעט גיחות לעולם ה-BSD ואובונטו\ג'נטו\LFS. ושוב, אחרי שקראתי את הכתבה עם פטריק, צפה ועלתה לי אותה התקופה, על ההפצה, ששמה מסבר היה "Slackware".

בלי להשתהות, ניגשתי לעמוד הבית של Slackware והתחלתי לבלוש מעט. התרשמתי מ-Slack כי היא קצת "מאחרת", רק עברה לקרנל 2.16, רק לא מזמן הוסיפו תמיכה ב-HAL. כל אלו דברים שנמצאים בהפצות אחרות כבר מזמן. מכיוון שאני לא מהממהרים (נסו להגיד את זה הרבה ומהר, מהממהרים) להחליף Desktop, אמרתי לעצמי שאולי עדיף לנסות את Slackware בתור VM.

אצתי רצתי, והורדתי לי Image מוכן מ-Jailtime. הסבה מהירה, והוא עובד כבר מעל lguest.

זהו. כרגע רק התחלתי לעבוד עם המערכת וללמוד להשתמש בה. אני רוצה להתחיל בהעברה של הפיתוח של jiyuu ל-VM החדש, ומשם נראה.

עוד עדכונים בהמשך.