PyInotify
لينكس بيقدم انترفيس inotify لمراقبة الأحداث الخاصة بالملفات مثل النقل، الحذف، الإنشاء وغيرها. على سبيل لدينا تطبيق مدير ملفات او برنامج للنسخ الإحتياطى او
Real-Time indexer هل منطقى ان نجبر البرنامج كل شوية انه يقرا المحتوى عشان نشوف الملفات الجديدة ؟ او اللى تم حذفها او غيره ؟ الكرنل ب "يدفع" الأحداث والبرنامج يعالج الأحداث اللى تهمه
ال Watches .. بعد تجهيز inotify بيتم تجهيز ال watches وهى بتعبر عن مسار ما ب mask "يحدد الأحداث المهتمين بمعالجتها"
هنستخدم pyinotify فى الكلام.. يمكن اذا ربنا ادانا العمر نتكلم عن inotify مباشرة
تقدر توصل للأحداث هنا
http://seb.dbzteam.org/swp/pages/pyinotify...entsCodes_Classاللى يهمنا منهم هو IN_CREATE و IN_DELETE و IN_MOVED_FROM و IN_MOVED_TO
عند الإنشاء والحذف وبدأ النقل "من مسار ما" وعند انتهاء النقل "الى مسار ما"
*منطقى اننا عايزين نراقب الأحداث على المجلد وكل المجلدات بداخله فهنستخدم rec=True اختصار ل recursive =True
نبدأ المتطلبات
لاحظ المفروض تستخدم pyinotify.WatchManger وهكذا بدل من استيراد الكل من pyinotify
بننشئ ال WatchManager ليدير كل العناصر المراقبة
mask بنحدد فيه الأحداث اللى مهتمين فيها
wm=WatchManager()
mask=IN_DELETE | IN_CREATE | IN_MOVED_FROM | IN_MOVED_TO #to watch..
ثم بننشئ ال inotify (بمدير العناصر المراقبة و كائن من صف خاص بمعالجة الأحداث اللتى نريدها )ونضيف المسار المطلوب مراقبة الأحداث عليه ونحدد ال mask ونجعل rec=True لمراقبة الأحداث بما فى اسفله
p=PDir()
notifier=Notifier(wm, p)
#add a watch..
watch=wm.add_watch("/home/striky/Desktop", mask, rec=True)
ونبدأ حلقة المعالجة
لاحظ اننا مش عارفين ايه PDir دا اصلا؟
بإختصار هو صف عرفنا فيه معالجات خاصة بالأحداث دى بيورث pyinotify.ProcessEvent
class PDir(ProcessEvent):
def my_init(self, **kwargs):
self.mv_cookies={} # {cookie: src}
def process_IN_DELETE(self, event):
print "Remove: %s"%event.pathname
def process_IN_CREATE(self, event):
print "Create: %s"%event.pathname
def process_IN_MOVED_FROM(self, event):
print "Moving FROM: %s"%event.pathname
self.mv_cookies[event.cookie]=event.pathname
def process_IN_MOVED_TO(self, event):
print "Moving TO: %s"%event.pathname
print " WAS MOVED FROM: ", self.mv_cookies[event.cookie]
الصف مباشر جدا.. ملحوظة ال event فى اى من معالجات الحدث هو كائن من الصف Event وله صفات منها
wd => وهى رقم مميز ( Watch Descriptor ) للعنصر المراقب
name => وهى اسم العنصر اللذى حدث عليه الحدث
pathname => مساره الكامل
dir => بتعبر عما اذا كان مجلد
mask => بتعبر عن ال bitmask للأحداث المراقبة فى ال wd
cookie => قيمة مميزة تستخدم لربط حدثين معا مثل IN_MOVED_FROM و IN_MOVED_TO
لأن كل منهم بيمثل نصف عملية النقل وهما الإتنين بيعبرو عن العملية. وهنا استخدمنا ال dict المسمى mv_cookies للربط بينهم
المثال كامل
import os
from pyinotify import *
wm=WatchManager()
mask=IN_DELETE | IN_CREATE | IN_MOVED_FROM | IN_MOVED_TO #to watch..
#no need.. use .pathname instead..
def fullname(event):
return os.path.join(event.path, event.name)
class PDir(ProcessEvent):
def my_init(self, **kwargs):
self.mv_cookies={} # {cookie: src}
def process_IN_DELETE(self, event):
print "Remove: %s"%event.pathname
def process_IN_CREATE(self, event):
print "Create: %s"%event.pathname
def process_IN_MOVED_FROM(self, event):
print "Moving FROM: %s"%event.pathname
self.mv_cookies[event.cookie]=event.pathname
def process_IN_MOVED_TO(self, event):
print "Moving TO: %s"%event.pathname
print " WAS MOVED FROM: ", self.mv_cookies[event.cookie] #same unique number
#notifier
p=PDir()
notifier=Notifier(wm, p)
#add a watch..
watch=wm.add_watch("/home/striky/Desktop", mask, rec=True)
notifier.loop()
دا كان المختصر المفيد للمزيد حول pyinotify تقدر تراجع
http://seb.dbzteam.org/swp/pages/pyinotify.html