tidings 0.2.0 → 0.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/ext/extconf.rb +2 -2
- data/ext/fs_event/fs_event.c +104 -0
- data/ext/inotify/inotify.c +103 -0
- data/lib/tidings/version.rb +3 -0
- data/lib/tidings/watcher.rb +29 -0
- data/lib/tidings.rb +23 -0
- metadata +8 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: acdbaca8aecfaa40103a8b5b9dbf7932322cccc0
|
4
|
+
data.tar.gz: 3906c9fff15182a42c9d472a69bb0190fb2b6ccf
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 752e52830262e1f14e2fe360621ad0e7fd34fa00e31e597a3bf822559c8650b043c5d702b71a4cc080754ccdb853f3db95b1467acbe4cddc207f7fca2c3b8d72
|
7
|
+
data.tar.gz: 1d445b0ad98e8b663a4b96d637f66bcafad891ec1a55cbc61f723f62f08451f6dcebb491de7ed57c0c4b2191dc6dc9b0f767441c64baba0ea93608a7274db85e
|
data/ext/extconf.rb
CHANGED
@@ -3,8 +3,8 @@ require 'mkmf'
|
|
3
3
|
case RUBY_PLATFORM
|
4
4
|
when /darwin/
|
5
5
|
with_ldflags("-framework CoreServices") do
|
6
|
-
create_makefile("fs_event
|
6
|
+
create_makefile("fs_event", "fs_event")
|
7
7
|
end
|
8
8
|
when /linux/
|
9
|
-
create_makefile("inotify
|
9
|
+
create_makefile("inotify", "inotify")
|
10
10
|
end
|
@@ -0,0 +1,104 @@
|
|
1
|
+
#include <stdio.h>
|
2
|
+
#include <ruby.h>
|
3
|
+
|
4
|
+
#include <CoreFoundation/CoreFoundation.h>
|
5
|
+
#include <CoreServices/CoreServices.h>
|
6
|
+
|
7
|
+
static VALUE processor;
|
8
|
+
|
9
|
+
VALUE fs_event_event_flags(const FSEventStreamEventFlags eventFlags)
|
10
|
+
{
|
11
|
+
VALUE event_flags = rb_ary_new();
|
12
|
+
|
13
|
+
if (eventFlags & kFSEventStreamEventFlagMustScanSubDirs)
|
14
|
+
rb_ary_push(event_flags, ID2SYM(rb_intern("must_scan")));
|
15
|
+
if (eventFlags & kFSEventStreamEventFlagItemCreated)
|
16
|
+
rb_ary_push(event_flags, ID2SYM(rb_intern("created")));
|
17
|
+
if (eventFlags & kFSEventStreamEventFlagItemRemoved)
|
18
|
+
rb_ary_push(event_flags, ID2SYM(rb_intern("removed")));
|
19
|
+
if (eventFlags & kFSEventStreamEventFlagItemRenamed)
|
20
|
+
rb_ary_push(event_flags, ID2SYM(rb_intern("renamed")));
|
21
|
+
if (eventFlags & kFSEventStreamEventFlagItemModified)
|
22
|
+
rb_ary_push(event_flags, ID2SYM(rb_intern("modified")));
|
23
|
+
if (eventFlags & kFSEventStreamEventFlagItemIsFile)
|
24
|
+
rb_ary_push(event_flags, ID2SYM(rb_intern("file")));
|
25
|
+
if (eventFlags & kFSEventStreamEventFlagItemIsDir)
|
26
|
+
rb_ary_push(event_flags, ID2SYM(rb_intern("dir")));
|
27
|
+
|
28
|
+
return event_flags;
|
29
|
+
}
|
30
|
+
|
31
|
+
void fs_event_callback(
|
32
|
+
ConstFSEventStreamRef streamRef,
|
33
|
+
void *userData,
|
34
|
+
size_t numberOfEvents,
|
35
|
+
void *eventPaths,
|
36
|
+
const FSEventStreamEventFlags eventFlags[],
|
37
|
+
const FSEventStreamEventId eventIds[]
|
38
|
+
)
|
39
|
+
{
|
40
|
+
char **paths = eventPaths;
|
41
|
+
size_t index;
|
42
|
+
|
43
|
+
for(index=0; index < numberOfEvents; index++) {
|
44
|
+
rb_funcall(processor, rb_intern("call"), 2,
|
45
|
+
rb_str_new2(paths[index]),
|
46
|
+
fs_event_event_flags(eventFlags[index])
|
47
|
+
);
|
48
|
+
}
|
49
|
+
}
|
50
|
+
|
51
|
+
/*
|
52
|
+
* call-seq:
|
53
|
+
* fs_event_watch(path, processor)
|
54
|
+
*
|
55
|
+
* Calls the block with the changed paths when something changes in the
|
56
|
+
* specified path. This method blocks the thread forever.
|
57
|
+
*
|
58
|
+
* FSEvent.watch('/tmp', Proc.new { |files| p files })
|
59
|
+
*/
|
60
|
+
static VALUE fs_event_watch(VALUE self, VALUE path, VALUE proc)
|
61
|
+
{
|
62
|
+
processor = proc;
|
63
|
+
|
64
|
+
CFStringRef cfPaths[1];
|
65
|
+
cfPaths[0] = CFStringCreateWithCString(
|
66
|
+
kCFAllocatorSystemDefault,
|
67
|
+
RSTRING_PTR(path),
|
68
|
+
kCFStringEncodingUTF8
|
69
|
+
);
|
70
|
+
CFArrayRef paths = CFArrayCreate(kCFAllocatorSystemDefault, (const void **)cfPaths, 1, NULL);
|
71
|
+
|
72
|
+
FSEventStreamRef streamRef = FSEventStreamCreate(
|
73
|
+
NULL,
|
74
|
+
&fs_event_callback,
|
75
|
+
NULL,
|
76
|
+
paths,
|
77
|
+
kFSEventStreamEventIdSinceNow,
|
78
|
+
(CFTimeInterval)0.5,
|
79
|
+
kFSEventStreamCreateFlagWatchRoot | kFSEventStreamCreateFlagFileEvents
|
80
|
+
);
|
81
|
+
|
82
|
+
#ifdef DEBUG
|
83
|
+
FSEventStreamShow(streamRef);
|
84
|
+
#endif
|
85
|
+
|
86
|
+
FSEventStreamScheduleWithRunLoop(streamRef, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode);
|
87
|
+
FSEventStreamStart(streamRef);
|
88
|
+
|
89
|
+
CFRunLoopRun();
|
90
|
+
|
91
|
+
FSEventStreamFlushSync(streamRef);
|
92
|
+
FSEventStreamStop(streamRef);
|
93
|
+
|
94
|
+
return Qnil;
|
95
|
+
}
|
96
|
+
|
97
|
+
void Init_fs_event()
|
98
|
+
{
|
99
|
+
VALUE mFSEvent;
|
100
|
+
|
101
|
+
mFSEvent = rb_define_module("FSEvent");
|
102
|
+
|
103
|
+
rb_define_module_function(mFSEvent, "watch", fs_event_watch, 2);
|
104
|
+
}
|
@@ -0,0 +1,103 @@
|
|
1
|
+
#include <stdio.h>
|
2
|
+
#include <stdlib.h>
|
3
|
+
#include <errno.h>
|
4
|
+
#include <sys/types.h>
|
5
|
+
#include <sys/inotify.h>
|
6
|
+
#include <unistd.h>
|
7
|
+
#include <ruby.h>
|
8
|
+
|
9
|
+
#define EVENT_SIZE ( sizeof (struct inotify_event) )
|
10
|
+
#define BUF_LEN ( 1024 * ( EVENT_SIZE + 16 ) )
|
11
|
+
|
12
|
+
VALUE inotify_event_flags(uint32_t mask)
|
13
|
+
{
|
14
|
+
VALUE event_flags = rb_ary_new();
|
15
|
+
|
16
|
+
if (mask & IN_ACCESS)
|
17
|
+
rb_ary_push(event_flags, ID2SYM(rb_intern("accessed")));
|
18
|
+
if (mask & IN_CREATE)
|
19
|
+
rb_ary_push(event_flags, ID2SYM(rb_intern("created")));
|
20
|
+
if (mask & IN_DELETE)
|
21
|
+
rb_ary_push(event_flags, ID2SYM(rb_intern("removed")));
|
22
|
+
if (mask & IN_MODIFY)
|
23
|
+
rb_ary_push(event_flags, ID2SYM(rb_intern("modified")));
|
24
|
+
if (mask & IN_ISDIR)
|
25
|
+
rb_ary_push(event_flags, ID2SYM(rb_intern("dir")));
|
26
|
+
else
|
27
|
+
rb_ary_push(event_flags, ID2SYM(rb_intern("file")));
|
28
|
+
|
29
|
+
return event_flags;
|
30
|
+
}
|
31
|
+
|
32
|
+
/*
|
33
|
+
* call-seq:
|
34
|
+
* inotify_watch(path, processor)
|
35
|
+
*
|
36
|
+
* Calls the block with the changed paths when something changes in the
|
37
|
+
* specified path. This method blocks the thread forever.
|
38
|
+
*
|
39
|
+
* Inotify.watch('/tmp', Proc.new { |files| p files })
|
40
|
+
*/
|
41
|
+
static VALUE inotify_watch(VALUE self, VALUE path, VALUE processor)
|
42
|
+
{
|
43
|
+
int length, i;
|
44
|
+
int notify;
|
45
|
+
int watch;
|
46
|
+
char buffer[BUF_LEN];
|
47
|
+
VALUE mFile = rb_const_get(rb_cObject, rb_intern("File"));
|
48
|
+
|
49
|
+
fd_set rfds;
|
50
|
+
struct timeval tv;
|
51
|
+
int retval;
|
52
|
+
|
53
|
+
notify = inotify_init();
|
54
|
+
|
55
|
+
if (notify < 0) perror("inotify_init");
|
56
|
+
|
57
|
+
watch = inotify_add_watch(notify, RSTRING_PTR(path), IN_MODIFY | IN_CREATE | IN_DELETE );
|
58
|
+
|
59
|
+
for (;;)
|
60
|
+
{
|
61
|
+
FD_ZERO(&rfds);
|
62
|
+
FD_SET(notify, &rfds);
|
63
|
+
|
64
|
+
tv.tv_sec = 0;
|
65
|
+
tv.tv_usec = 500;
|
66
|
+
|
67
|
+
retval = select(notify + 1, &rfds, NULL, NULL, &tv);
|
68
|
+
|
69
|
+
if (retval < 0) {
|
70
|
+
perror("select()");
|
71
|
+
return Qfalse;
|
72
|
+
} else if (FD_ISSET(notify, &rfds)) {
|
73
|
+
length = read(notify, buffer, BUF_LEN);
|
74
|
+
if (length < 0) perror("read");
|
75
|
+
|
76
|
+
i = 0;
|
77
|
+
while(i < length) {
|
78
|
+
struct inotify_event *event = (struct inotify_event *)&buffer[i];
|
79
|
+
if (event->len) {
|
80
|
+
rb_funcall(processor, rb_intern("call"), 2,
|
81
|
+
rb_funcall(mFile, rb_intern("join"), 2, path, rb_str_new2(event->name)),
|
82
|
+
inotify_event_flags(event->mask)
|
83
|
+
);
|
84
|
+
}
|
85
|
+
i += EVENT_SIZE + event->len;
|
86
|
+
}
|
87
|
+
}
|
88
|
+
}
|
89
|
+
|
90
|
+
inotify_rm_watch(notify, watch);
|
91
|
+
close(notify);
|
92
|
+
|
93
|
+
return Qnil;
|
94
|
+
}
|
95
|
+
|
96
|
+
void Init_inotify()
|
97
|
+
{
|
98
|
+
VALUE mInotify;
|
99
|
+
|
100
|
+
mInotify = rb_define_module("Inotify");
|
101
|
+
|
102
|
+
rb_define_module_function(mInotify, "watch", inotify_watch, 2);
|
103
|
+
}
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module Tidings
|
2
|
+
class Watcher
|
3
|
+
def initialize(path, processor)
|
4
|
+
@path, @processor, @pid = path, processor, nil
|
5
|
+
end
|
6
|
+
|
7
|
+
def start
|
8
|
+
Signal.trap("SIGINT") { stop }
|
9
|
+
@pid = fork { watch }
|
10
|
+
Tidings.log("Tidings running on PID: #{@pid}")
|
11
|
+
Process.wait
|
12
|
+
Tidings.log("Tidings stopped running")
|
13
|
+
end
|
14
|
+
|
15
|
+
def stop
|
16
|
+
Process.kill("KILL", @pid)
|
17
|
+
end
|
18
|
+
|
19
|
+
if const_defined?(:FSEvent)
|
20
|
+
def watch
|
21
|
+
FSEvent.watch(@path, @processor)
|
22
|
+
end
|
23
|
+
elsif const_defined?(:Inotify)
|
24
|
+
def watch
|
25
|
+
Inotify.watch(@path, @processor)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
data/lib/tidings.rb
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
case RUBY_PLATFORM
|
2
|
+
when /darwin/
|
3
|
+
require 'fs_event'
|
4
|
+
when /linux/
|
5
|
+
require 'inotify'
|
6
|
+
else
|
7
|
+
raise RuntimeError, "Your platform is currently not supported (#{RUBY_PLATFORM})"
|
8
|
+
end
|
9
|
+
|
10
|
+
module Tidings
|
11
|
+
autoload :VERSION, 'tidings/version'
|
12
|
+
autoload :Watcher, 'tidings/watcher'
|
13
|
+
|
14
|
+
def self.log(message)
|
15
|
+
$stderr.puts('Tidings: ' + message.to_s) if $DEBUG
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.watch(path, processor=nil, &block)
|
19
|
+
watcher = Tidings::Watcher.new(path, processor || block)
|
20
|
+
watcher.start
|
21
|
+
watcher
|
22
|
+
end
|
23
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: tidings
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
4
|
+
version: 0.2.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Manfred Stienstra
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2013-12-
|
11
|
+
date: 2013-12-02 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: peck
|
@@ -48,9 +48,14 @@ extra_rdoc_files:
|
|
48
48
|
- README.rdoc
|
49
49
|
- COPYING
|
50
50
|
files:
|
51
|
+
- lib/tidings/version.rb
|
52
|
+
- lib/tidings/watcher.rb
|
53
|
+
- lib/tidings.rb
|
54
|
+
- ext/extconf.rb
|
55
|
+
- ext/fs_event/fs_event.c
|
56
|
+
- ext/inotify/inotify.c
|
51
57
|
- README.rdoc
|
52
58
|
- COPYING
|
53
|
-
- ext/extconf.rb
|
54
59
|
homepage: http://github.com/Manfred/tidings
|
55
60
|
licenses: []
|
56
61
|
metadata: {}
|