Python-EFL: implemented ecore.FileMonitor class
This commit is contained in:
parent
6e221b54c5
commit
39e16242a0
2
INSTALL
2
INSTALL
|
@ -9,7 +9,7 @@
|
|||
- Tested with Cython 0.17.1
|
||||
|
||||
* EFL core library
|
||||
- eo, evas, ecore, edje, elementary, edbus and emotion
|
||||
- eo, evas, ecore, edje, emotion and elementary
|
||||
|
||||
* pkg-config (http://www.freedesktop.org/wiki/Software/pkg-config)
|
||||
- Windows executable (and GLib dependency) can be downloaded from
|
||||
|
|
1
TODO
1
TODO
|
@ -20,7 +20,6 @@ TODO
|
|||
====
|
||||
|
||||
* ecore.Poller
|
||||
* ecore.FileMonitor
|
||||
* alert on signal and subprocess module usage (was in python-ecore/ecore/__init__.py)
|
||||
* evas.SmartObject
|
||||
* edje: complete the unit tests
|
||||
|
|
|
@ -190,11 +190,20 @@ ECORE_EXE_TERM_WITH_PARENT = enums.ECORE_EXE_TERM_WITH_PARENT
|
|||
|
||||
ECORE_EXE_PRIORITY_INHERIT = 9999
|
||||
|
||||
|
||||
# Ecore_File_Progress_Return:
|
||||
ECORE_FILE_PROGRESS_CONTINUE = 0
|
||||
ECORE_FILE_PROGRESS_ABORT = 1
|
||||
|
||||
# Ecore_File_Event
|
||||
ECORE_FILE_EVENT_NONE = enums.ECORE_FILE_EVENT_NONE
|
||||
ECORE_FILE_EVENT_CREATED_FILE = enums.ECORE_FILE_EVENT_CREATED_FILE
|
||||
ECORE_FILE_EVENT_CREATED_DIRECTORY = enums.ECORE_FILE_EVENT_CREATED_DIRECTORY
|
||||
ECORE_FILE_EVENT_DELETED_FILE = enums.ECORE_FILE_EVENT_DELETED_FILE
|
||||
ECORE_FILE_EVENT_DELETED_DIRECTORY = enums.ECORE_FILE_EVENT_DELETED_DIRECTORY
|
||||
ECORE_FILE_EVENT_DELETED_SELF = enums.ECORE_FILE_EVENT_DELETED_SELF
|
||||
ECORE_FILE_EVENT_MODIFIED = enums.ECORE_FILE_EVENT_MODIFIED
|
||||
ECORE_FILE_EVENT_CLOSED = enums.ECORE_FILE_EVENT_CLOSED
|
||||
|
||||
|
||||
cdef Eina_Bool _ecore_task_cb(void *data) with gil:
|
||||
cdef Eo obj = <Eo>data
|
||||
|
@ -281,5 +290,6 @@ include "efl.ecore_fd_handler.pxi"
|
|||
include "efl.ecore_events.pxi"
|
||||
include "efl.ecore_exe.pxi"
|
||||
include "efl.ecore_file_download.pxi"
|
||||
include "efl.ecore_file_monitor.pxi"
|
||||
|
||||
init()
|
||||
|
|
|
@ -0,0 +1,81 @@
|
|||
# Copyright (C) 2007-2013 various contributors (see AUTHORS)
|
||||
#
|
||||
# This file is part of Python-EFL.
|
||||
#
|
||||
# Python-EFL is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU Lesser General Public
|
||||
# License as published by the Free Software Foundation; either
|
||||
# version 2.1 of the License, or (at your option) any later version.
|
||||
#
|
||||
# Python-EFL is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
# Lesser General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with this Python-EFL. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
from cpython cimport PyUnicode_AsUTF8String
|
||||
|
||||
|
||||
cdef void _file_monitor_cb(void *data, Ecore_File_Monitor *em, Ecore_File_Event event, const_char *path) with gil:
|
||||
obj = <FileMonitor>data
|
||||
try:
|
||||
obj._exec_monitor(event, path)
|
||||
except Exception, e:
|
||||
traceback.print_exc()
|
||||
|
||||
|
||||
cdef class FileMonitor(object):
|
||||
""" TODOC """
|
||||
def __init__(self, path, monitor_cb, *args, **kargs):
|
||||
|
||||
if not callable(monitor_cb):
|
||||
raise TypeError("Parameter 'monitor_cb' must be callable")
|
||||
|
||||
self.monitor_cb = monitor_cb
|
||||
self.args = args
|
||||
self.kargs = kargs
|
||||
|
||||
if isinstance(path, unicode): path = PyUnicode_AsUTF8String(path)
|
||||
self.mon = ecore_file_monitor_add(
|
||||
<const_char *>path if path is not None else NULL,
|
||||
_file_monitor_cb, <void *>self)
|
||||
if not self.mon:
|
||||
raise SystemError("could not monitor '%s'" % (path))
|
||||
|
||||
Py_INCREF(self)
|
||||
|
||||
def __dealloc__(self):
|
||||
if self.mon != NULL:
|
||||
ecore_file_monitor_del(self.mon)
|
||||
self.mon = NULL
|
||||
self.monitor_cb = None
|
||||
self.args = None
|
||||
self.kargs = None
|
||||
|
||||
def __str__(self):
|
||||
return "%s(monitor_cb=%s, args=%s, kargs=%s)" % \
|
||||
(self.__class__.__name__, self.monitor_cb, self.args, self.kargs)
|
||||
|
||||
def __repr__(self):
|
||||
return ("%s(%#x, monitor_cb=%s, args=%s, kargs=%s, refcount=%d)") % \
|
||||
(self.__class__.__name__, <unsigned long><void *>self,
|
||||
self.monitor_cb, self.args, self.kargs, PY_REFCOUNT(self))
|
||||
|
||||
cdef object _exec_monitor(self, Ecore_File_Event event, const_char *path):
|
||||
if self.monitor_cb:
|
||||
return self.monitor_cb(event, _ctouni(path), *self.args, **self.kargs)
|
||||
return 0
|
||||
|
||||
def delete(self):
|
||||
""" TODOC """
|
||||
if self.mon != NULL:
|
||||
ecore_file_monitor_del(self.mon)
|
||||
self.mon = NULL
|
||||
Py_DECREF(self)
|
||||
|
||||
property path:
|
||||
""" TODOC """
|
||||
def __get__(self):
|
||||
return _ctouni(ecore_file_monitor_path_get(self.mon))
|
|
@ -52,3 +52,15 @@ cdef extern from "Ecore.h":
|
|||
ctypedef enum Ecore_Animator_Source:
|
||||
ECORE_ANIMATOR_SOURCE_TIMER
|
||||
ECORE_ANIMATOR_SOURCE_CUSTOM
|
||||
|
||||
|
||||
cdef extern from "Ecore_File.h":
|
||||
ctypedef enum Ecore_File_Event:
|
||||
ECORE_FILE_EVENT_NONE
|
||||
ECORE_FILE_EVENT_CREATED_FILE
|
||||
ECORE_FILE_EVENT_CREATED_DIRECTORY
|
||||
ECORE_FILE_EVENT_DELETED_FILE
|
||||
ECORE_FILE_EVENT_DELETED_DIRECTORY
|
||||
ECORE_FILE_EVENT_DELETED_SELF
|
||||
ECORE_FILE_EVENT_MODIFIED
|
||||
ECORE_FILE_EVENT_CLOSED
|
||||
|
|
|
@ -18,7 +18,8 @@
|
|||
from efl cimport *
|
||||
from efl.c_eo cimport Eo as cEo
|
||||
from efl.eo cimport Eo
|
||||
from efl.ecore.enums cimport Ecore_Fd_Handler_Flags, Ecore_Exe_Flags
|
||||
from efl.ecore.enums cimport Ecore_Fd_Handler_Flags, Ecore_Exe_Flags, \
|
||||
Ecore_File_Event
|
||||
|
||||
|
||||
cdef extern from "Ecore.h":
|
||||
|
@ -165,9 +166,12 @@ cdef extern from "Ecore.h":
|
|||
cdef extern from "Ecore_File.h":
|
||||
|
||||
ctypedef struct Ecore_File_Download_Job
|
||||
ctypedef struct Ecore_File_Monitor
|
||||
|
||||
ctypedef void (*Ecore_File_Download_Completion_Cb)(void *data, const_char *file, int status)
|
||||
ctypedef int (*Ecore_File_Download_Progress_Cb)(void *data, const_char *file, long int dltotal, long int dlnow, long int ultotal, long int ulnow)
|
||||
ctypedef void (*Ecore_File_Monitor_Cb)(void *data, Ecore_File_Monitor *em, Ecore_File_Event event, const_char *path)
|
||||
|
||||
|
||||
int ecore_file_init()
|
||||
int ecore_file_shutdown()
|
||||
|
@ -180,6 +184,10 @@ cdef extern from "Ecore_File.h":
|
|||
void *data,
|
||||
Ecore_File_Download_Job **job_ret)
|
||||
|
||||
Ecore_File_Monitor *ecore_file_monitor_add(const_char *path, Ecore_File_Monitor_Cb func, void *data)
|
||||
void ecore_file_monitor_del(Ecore_File_Monitor *ecore_file_monitor)
|
||||
const_char *ecore_file_monitor_path_get(Ecore_File_Monitor *ecore_file_monitor)
|
||||
|
||||
|
||||
####################################################################
|
||||
# Python classes
|
||||
|
@ -316,3 +324,11 @@ cdef class FileDownload:
|
|||
long int dltotal, long int dlnow,
|
||||
long int ultotal, long int ulnow)
|
||||
|
||||
|
||||
cdef class FileMonitor:
|
||||
cdef Ecore_File_Monitor *mon
|
||||
cdef readonly object monitor_cb
|
||||
cdef readonly object args
|
||||
cdef readonly object kargs
|
||||
|
||||
cdef object _exec_monitor(self, Ecore_File_Event event, const_char *path)
|
||||
|
|
|
@ -0,0 +1,85 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
from efl import ecore
|
||||
import unittest
|
||||
import os
|
||||
import tempfile
|
||||
|
||||
|
||||
counters = [0, 0, 0, 0, 0, 0 , 0, 0]
|
||||
|
||||
def monitor_cb(event, path, tmp_path):
|
||||
""" for reference:
|
||||
if event == ecore.ECORE_FILE_EVENT_MODIFIED:
|
||||
print("EVENT_MODIFIED: '%s'" % path)
|
||||
elif event == ecore.ECORE_FILE_EVENT_CLOSED:
|
||||
print("EVENT_CLOSED: '%s'" % path)
|
||||
elif event == ecore.ECORE_FILE_EVENT_CREATED_FILE:
|
||||
print("ECORE_FILE_EVENT_CREATED_FILE: '%s'" % path)
|
||||
elif event == ecore.ECORE_FILE_EVENT_CREATED_DIRECTORY:
|
||||
print("ECORE_FILE_EVENT_CREATED_DIRECTORY: '%s'" % path)
|
||||
elif event == ecore.ECORE_FILE_EVENT_DELETED_FILE:
|
||||
print("ECORE_FILE_EVENT_DELETED_FILE: '%s'" % path)
|
||||
elif event == ecore.ECORE_FILE_EVENT_DELETED_DIRECTORY:
|
||||
print("ECORE_FILE_EVENT_DELETED_DIRECTORY: '%s'" % path)
|
||||
elif event == ecore.ECORE_FILE_EVENT_DELETED_SELF:
|
||||
print("ECORE_FILE_EVENT_DELETED_SELF: '%s'" % path)
|
||||
"""
|
||||
counters[event] += 1
|
||||
|
||||
def do_stuff(tmp_path, fm):
|
||||
folder1 = os.path.join(tmp_path, "folder1")
|
||||
folder2 = os.path.join(tmp_path, "folder2")
|
||||
file1 = os.path.join(tmp_path, "file1")
|
||||
file2 = os.path.join(tmp_path, "file2")
|
||||
|
||||
# this should trigger two ECORE_FILE_EVENT_CREATED_DIRECTORY
|
||||
os.mkdir(folder1)
|
||||
os.mkdir(folder2)
|
||||
|
||||
# this should trigger two ECORE_FILE_EVENT_DELETED_DIRECTORY
|
||||
os.rmdir(folder1)
|
||||
os.rmdir(folder2)
|
||||
|
||||
# this should trigger two ECORE_FILE_EVENT_CREATED_FILE
|
||||
fp1 = open(file1, 'a')
|
||||
fp2 = open(file2, 'a')
|
||||
|
||||
# this should trigger two ECORE_FILE_EVENT_MODIFIED
|
||||
fp1.write("nothing to say")
|
||||
fp2.write("nothing to say")
|
||||
|
||||
# this should trigger two ECORE_FILE_EVENT_CLOSED
|
||||
fp1.close()
|
||||
fp2.close()
|
||||
|
||||
# this should trigger two ECORE_FILE_EVENT_DELETED_FILE
|
||||
os.remove(file1)
|
||||
os.remove(file2)
|
||||
|
||||
# this should trigger one ECORE_FILE_EVENT_DELETED_SELF !!! we get two
|
||||
os.rmdir(tmp_path)
|
||||
|
||||
|
||||
class TestFileMonitor(unittest.TestCase):
|
||||
def testInit(self):
|
||||
path = tempfile.mkdtemp()
|
||||
fm = ecore.FileMonitor(path, monitor_cb, path)
|
||||
self.assertIsInstance(fm, ecore.FileMonitor)
|
||||
self.assertEqual(fm.path, path)
|
||||
|
||||
ecore.Timer(0.1, do_stuff, path, fm)
|
||||
ecore.Timer(1.0, lambda: ecore.main_loop_quit())
|
||||
|
||||
ecore.main_loop_begin()
|
||||
self.assertEqual(fm.path, path)
|
||||
fm.delete()
|
||||
|
||||
# FIXME: we receive two ECORE_FILE_EVENT_DELETED_SELF, it's wrong
|
||||
# should be [0, 2, 2, 2, 2, 1, 2, 2]
|
||||
self.assertEqual(counters, [0, 2, 2, 2, 2, 2, 2, 2])
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main(verbosity=2)
|
||||
ecore.shutdown()
|
Loading…
Reference in New Issue