filetter 0.2.6

Sign up to get free protection for your applications and to get access to all the features.
data/History.txt ADDED
File without changes
data/README.rdoc ADDED
@@ -0,0 +1,62 @@
1
+ = filetter
2
+
3
+ http://github.com/jugyo/filetter
4
+
5
+ == DESCRIPTION:
6
+
7
+ Filetter is a pluggable tool for file system.
8
+
9
+ == FEATURES/PROBLEMS:
10
+
11
+ Available modes:
12
+
13
+ - mozrepl mode
14
+ - twitter mode
15
+ - flickr mode
16
+
17
+ In the future:
18
+
19
+ - rspec
20
+ - backup
21
+ - blog
22
+ - tumblr
23
+ - mail
24
+ ...
25
+
26
+ == SYNOPSIS:
27
+
28
+ Show help:
29
+
30
+ filetter --help
31
+
32
+ Run:
33
+
34
+ filetter -m MODE
35
+
36
+ or (for development)
37
+
38
+ ./bin/debug -m MODE
39
+
40
+ Example:
41
+
42
+ Run as 'mozrepl' mode for files named '*.css':
43
+
44
+ filetter -m mozrepl -p './**/*.css'
45
+
46
+ To load your file:
47
+
48
+ filetter -f your_file
49
+
50
+ Default file to load is '.filetter' in the current directory if exist.
51
+
52
+ == REQUIREMENTS:
53
+
54
+ - configatron
55
+ - highline
56
+ - rubytter
57
+ - rflickr
58
+
59
+ == INSTALL:
60
+
61
+ gem source -a http://gems.github.com
62
+ sudo gem install jugyo-filetter
data/Rakefile ADDED
@@ -0,0 +1,47 @@
1
+ # -*- coding: utf-8 -*-
2
+ $:.unshift File.dirname(__FILE__) + '/lib/'
3
+ require 'filetter'
4
+ require 'spec/rake/spectask'
5
+
6
+ desc 'run all specs'
7
+ Spec::Rake::SpecTask.new do |t|
8
+ t.spec_files = FileList['spec/**/*_spec.rb']
9
+ t.spec_opts = ['-c']
10
+ end
11
+
12
+ desc 'Generate gemspec'
13
+ task :gemspec do |t|
14
+ open('filetter.gemspec', "wb" ) do |file|
15
+ file << <<-EOS
16
+ Gem::Specification.new do |s|
17
+ s.name = 'filetter'
18
+ s.version = '#{Filetter::VERSION}'
19
+ s.summary = "Filetter is a pluggable tool for file system."
20
+ s.description = "Filetter is a pluggable tool for file system."
21
+ s.files = %w( #{Dir['lib/**/*.rb'].join(' ')}
22
+ #{Dir['spec/**/*.rb'].join(' ')}
23
+ README.rdoc
24
+ History.txt
25
+ Rakefile )
26
+ s.executables = ["filetter"]
27
+ s.add_dependency("configatron", ">= 2.2.2")
28
+ s.add_dependency("rubytter", ">= 0.4.5")
29
+ s.add_dependency("rflickr", ">= 2006.02.01")
30
+ s.add_dependency("highline", ">= 1.5.0")
31
+ s.author = 'jugyo'
32
+ s.email = 'jugyo.org@gmail.com'
33
+ s.homepage = 'http://github.com/jugyo/filetter'
34
+ s.rubyforge_project = 'filetter'
35
+ s.has_rdoc = true
36
+ s.rdoc_options = ["--main", "README.rdoc", "--exclude", "spec"]
37
+ s.extra_rdoc_files = ["README.rdoc", "History.txt"]
38
+ end
39
+ EOS
40
+ end
41
+ puts "Generate gemspec"
42
+ end
43
+
44
+ desc 'Generate gem'
45
+ task :gem => :gemspec do |t|
46
+ system 'gem', 'build', 'filetter.gemspec'
47
+ end
data/bin/filetter ADDED
@@ -0,0 +1,7 @@
1
+ #!/usr/bin/env ruby
2
+ # -*- coding: utf-8 -*-
3
+
4
+ $KCODE="u" unless Object.const_defined? :Encoding
5
+
6
+ require 'filetter'
7
+ Filetter.run
@@ -0,0 +1,34 @@
1
+ # -*- coding: utf-8 -*-
2
+ module Filetter
3
+ class FileInfo
4
+
5
+ attr_reader :pathname, :changes
6
+
7
+ def initialize(pathname, observe_targets = [:mtime])
8
+ @changes = []
9
+ @pathname = pathname
10
+ @targets = {}
11
+ @observe_targets = observe_targets
12
+ update_status()
13
+ end
14
+
15
+ def check_modified
16
+ old = @targets.dup
17
+ update_status()
18
+ @changes = []
19
+ @targets.each do |k, v|
20
+ @changes << k unless old[k] == v
21
+ end
22
+ end
23
+
24
+ private
25
+
26
+ def update_status
27
+ return unless @pathname.exist?
28
+ @observe_targets.each do |target|
29
+ @targets[target] = @pathname.__send__(target)
30
+ end
31
+ end
32
+ end
33
+ end
34
+
@@ -0,0 +1,178 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ require 'pathname'
4
+ require 'readline'
5
+ require 'singleton'
6
+
7
+ module Filetter
8
+ class Observer
9
+ include Singleton
10
+
11
+ # deplecated
12
+ def self.add_hook(*args, &block)
13
+ instance.add_hook(*args, &block)
14
+ end
15
+
16
+ def self.run(options = {})
17
+ instance.run(options)
18
+ end
19
+
20
+ attr_accessor :pattern, :interval, :debug, :prompt
21
+
22
+ def initialize
23
+ @pattern = './**/*'
24
+ @interval = 1
25
+ @work = true
26
+ @file_infos = {}
27
+ @hooks = {}
28
+ @prompt = '> '
29
+ end
30
+
31
+ def run(options = {})
32
+ options.each do |k, v|
33
+ self.__send__("#{k.to_s}=".to_sym, v) if self.respond_to?(k)
34
+ end
35
+
36
+ puts "=> initializing..."
37
+ collect_files
38
+
39
+ @input_thread = Thread.new do
40
+ Readline.completion_proc = lambda {|input|
41
+ self.methods.map{|i|i.to_s}.grep(/^#{Regexp.quote(input)}/)
42
+ }
43
+ puts '=> Enter "exit" to exit.'
44
+ while @work && line = Readline.readline(@prompt, true)
45
+ begin
46
+ eval(line) unless line.empty?
47
+ rescue => e
48
+ handle_error(e)
49
+ end
50
+ end
51
+ end
52
+
53
+ sleep @interval
54
+
55
+ @observe_thread = Thread.new do
56
+ while @work
57
+ begin
58
+ puts 'checking files...' if debug
59
+ check_files
60
+ rescue => e
61
+ handle_error(e)
62
+ ensure
63
+ sleep @interval
64
+ end
65
+ end
66
+ end
67
+
68
+ @observe_thread.join
69
+ @input_thread.join
70
+ end
71
+
72
+ def exit
73
+ puts 'exiting...'
74
+ @work = false
75
+ end
76
+
77
+ def add_hook(*args, &block)
78
+ unless args.empty?
79
+ args.each do |arg|
80
+ hook_name = normalize_as_hook_name(arg)
81
+ @hooks[hook_name] ||= []
82
+ @hooks[hook_name] << block
83
+ end
84
+ else
85
+ @hooks[:any] ||= []
86
+ @hooks[:any] << block
87
+ end
88
+ end
89
+
90
+ private
91
+
92
+ def collect_files
93
+ real_files = Pathname.glob(@pattern).map do |i|
94
+ if debug
95
+ print "\e[1K\e[0G#{i.basename.to_s}"
96
+ $stdout.flush
97
+ end
98
+ i.realpath
99
+ end
100
+
101
+ if debug
102
+ print "\e[1K\e[0G"
103
+ $stdout.flush
104
+ end
105
+
106
+ current_files = @file_infos.keys
107
+ created_files = real_files - current_files
108
+ deleted_files = current_files - real_files
109
+
110
+ @file_infos.delete_if do |k, v|
111
+ deleted_files.include?(k)
112
+ end
113
+
114
+ created_files.map!{|i|i.realpath}
115
+ created_files.each do |pathname|
116
+ @file_infos[pathname] = FileInfo.new(pathname)
117
+ end
118
+
119
+ [created_files, deleted_files]
120
+ end
121
+
122
+ def check_files
123
+ check_exists
124
+ check_modifies
125
+ end
126
+
127
+ def check_exists
128
+ created_files, deleted_files = collect_files
129
+ call_hooks(:created, created_files) unless created_files.empty?
130
+ call_hooks(:deleted, deleted_files) unless deleted_files.empty?
131
+ end
132
+
133
+ def check_modifies
134
+ @file_infos.values.each{|i| i.check_modified}
135
+ modifies = @file_infos.values.select{|i| !i.changes.empty?}
136
+ call_hooks(:modified, modifies.map{|i| i.pathname}) unless modifies.empty?
137
+ end
138
+
139
+ def call_hooks(name, pathnames = [])
140
+ if @hooks.has_key?(name) && !pathnames.empty?
141
+ @hooks[name].each do |i|
142
+ begin
143
+ i.call(pathnames.map{|i| i.to_s}, name)
144
+ rescue => e
145
+ handle_error(e)
146
+ end
147
+ end
148
+ end
149
+ if @hooks.has_key?(:any)
150
+ @hooks[:any].each do |i|
151
+ begin
152
+ i.call(pathnames.map{|i| i.to_s }, name)
153
+ rescue => e
154
+ handle_error(e)
155
+ end
156
+ end
157
+ end
158
+ end
159
+
160
+ def handle_error(e)
161
+ if debug
162
+ puts "Error: #{e}"
163
+ puts e.backtrace.join("\n")
164
+ end
165
+ end
166
+
167
+ def normalize_as_hook_name(name)
168
+ case name.to_s
169
+ when /^created?$/
170
+ :created
171
+ when /^(modif(y|ied)|updated?)$/
172
+ :modified
173
+ when /(deleted?|removed?)/
174
+ :deleted
175
+ end
176
+ end
177
+ end
178
+ end
@@ -0,0 +1,4 @@
1
+ # -*- coding: utf-8 -*-
2
+ module Filetter
3
+ VERSION = '0.2.6'
4
+ end
data/lib/filetter.rb ADDED
@@ -0,0 +1,79 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ require 'optparse'
4
+ require 'rubygems'
5
+ require 'configatron'
6
+ def config; configatron; end
7
+
8
+ require 'filetter/version'
9
+ require 'filetter/file_info'
10
+ require 'filetter/observer'
11
+
12
+ Thread.abort_on_exception = true
13
+
14
+ module Filetter
15
+ class << self
16
+ def run(options = {})
17
+ pattern = './**/*'
18
+ interval = 2
19
+ debug = false
20
+ mode = nil
21
+ load_file = '.filetter'
22
+ work_dir = nil
23
+ help = nil
24
+ list = false
25
+
26
+ OptionParser.new do |opt|
27
+ opt.version = VERSION
28
+ opt.program_name = self.to_s
29
+ opt.on('-m', '--mode=mode', 'Run mode' ) {|v| mode = v }
30
+ opt.on('-f', '--loadfile=file', 'File to load' ) {|v| load_file = v }
31
+ opt.on('-c', '--cd=directory', 'cd to directory' ) {|v| work_dir = v }
32
+ opt.on('-p', '--pattern=pattern', 'Pattern of target files' ) {|v| pattern = v }
33
+ opt.on('-i', '--interval=interval', 'Interval of check files', Integer ) {|v| interval = v }
34
+ opt.on('-d', '--debug', 'Enable debug mode' ) {|v| debug = true }
35
+ opt.on('-l', '--list', 'List up available modes' ) {|v| list = true }
36
+ opt.parse!(ARGV)
37
+ help = opt.help
38
+ end
39
+
40
+ if work_dir
41
+ Dir.chdir(work_dir)
42
+ puts "=> cd to #{work_dir}"
43
+ end
44
+
45
+ begin
46
+ if mode.nil? && !File.exist?(load_file)
47
+ if list
48
+ puts Dir[File.dirname(__FILE__) + '/modes/*.rb'].map{|f|File.basename(f).gsub(/\.rb$/, '')}
49
+ exit
50
+ else
51
+ puts help
52
+ exit!
53
+ end
54
+ else
55
+ puts "=> load \"#{load_file}\""
56
+ load load_file
57
+ if mode
58
+ puts "=> Run as \"#{mode}\" mode"
59
+ require "modes/#{mode}"
60
+ end
61
+ end
62
+ rescue LoadError => e
63
+ puts e
64
+ raise if debug
65
+ exit!
66
+ rescue => e
67
+ puts e
68
+ raise if debug
69
+ exit!
70
+ end
71
+
72
+ Observer.run({:pattern => pattern, :interval => interval, :debug => debug}.merge(options))
73
+ end
74
+
75
+ def add_hook(*args, &block)
76
+ Observer.instance.add_hook(*args, &block)
77
+ end
78
+ end
79
+ end
@@ -0,0 +1,63 @@
1
+ # -*- coding: utf-8 -*-
2
+ require 'flickr'
3
+ require 'highline/import'
4
+ HighLine.track_eof = false
5
+
6
+ module Filetter
7
+
8
+ def self.open_brawser(url)
9
+ case RUBY_PLATFORM
10
+ when /linux/
11
+ system 'firefox', url
12
+ when /mswin(?!ce)|mingw|bccwin/
13
+ system 'explorer', url
14
+ else
15
+ system 'open', url
16
+ end
17
+ end
18
+
19
+ flickr_api_key = '83f3811287387fa8c604bf3bdcec2c9f'
20
+ flickr_secret = '7c180f792cf64ca9'
21
+ flickr = Flickr.new('./flickr_token', flickr_api_key, flickr_secret)
22
+
23
+ unless flickr.auth.token
24
+ puts 'Please allow to access to your Flickr account.'
25
+ open_brawser flickr.auth.login_link('write')
26
+
27
+ a = ask("Did you have allowed? [Y/n] ") {|q| q.validate = /^(y|yes|n|no)$/i }
28
+ case a
29
+ when /^y/i
30
+ flickr.auth.getToken
31
+ flickr.auth.cache_token
32
+ when /^n/i
33
+ puts 'No token for Flickr authentication!'
34
+ exit!
35
+ end
36
+ end
37
+
38
+ Dir.mkdir('done') unless File.exist?('done')
39
+
40
+ config.flickr.set_default(:title, nil)
41
+ config.flickr.set_default(:description, nil)
42
+ config.flickr.set_default(:public, false)
43
+ config.flickr.set_default(:friend, false)
44
+ config.flickr.set_default(:family, false)
45
+
46
+ add_hook :create do |files, event|
47
+ files.each do |file|
48
+ if File.file?(file) && Pathname.new(file).dirname == Pathname.pwd
49
+ puts "=> Upload '#{file}' to flickr."
50
+ flickr.photos.upload.upload_file(
51
+ file,
52
+ config.flickr.title,
53
+ config.flickr.description,
54
+ config.flickr.public,
55
+ config.flickr.friend,
56
+ config.flickr.family
57
+ )
58
+ rename_to = 'done/' + File.basename(file)
59
+ File.rename(file, rename_to)
60
+ end
61
+ end
62
+ end
63
+ end
@@ -0,0 +1,18 @@
1
+ require 'net/telnet'
2
+
3
+ config.mozrepl.set_default(:host, 'localhost')
4
+ config.mozrepl.set_default(:port, 4242)
5
+ config.mozrepl.set_default(:commands, ['content.location.reload(true)'])
6
+
7
+ Filetter.add_hook do |files, event|
8
+ telnet = Net::Telnet.new( "Host" => config.mozrepl.host,
9
+ "Port" => config.mozrepl.port ) {|c| print c }
10
+ begin
11
+ config.mozrepl.commands.each do |cmd|
12
+ puts "> #{cmd}"
13
+ telnet.puts(cmd)
14
+ end
15
+ ensure
16
+ telnet.close
17
+ end
18
+ end
@@ -0,0 +1,14 @@
1
+ # -*- coding: utf-8 -*-
2
+ module Filetter
3
+ add_hook :modified do |files, event|
4
+ puts "#{event}: #{files.inspect}"
5
+ end
6
+
7
+ add_hook :created do |files, event|
8
+ puts "#{event}: #{files.inspect}"
9
+ end
10
+
11
+ add_hook :deleted do |files, event|
12
+ puts "#{event}: #{files.inspect}"
13
+ end
14
+ end
@@ -0,0 +1,19 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ require 'rubytter'
4
+
5
+ if config.twitter.login.empty? || config.twitter.password.empty?
6
+ puts "Config not found! => [config.twitter.login, config.twitter.password]"
7
+ exit!
8
+ end
9
+
10
+ module Filetter
11
+ rubytter = Rubytter.new(config.twitter.login, config.twitter.password)
12
+ add_hook :create do |files, event|
13
+ files.each do |file|
14
+ file_name = File.basename(file)
15
+ rubytter.update(file_name)
16
+ puts "=> Post to twitter '#{file_name}'"
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,27 @@
1
+ # -*- coding: utf-8 -*-
2
+ require File.dirname(__FILE__) + '/../spec_helper'
3
+
4
+ module Filetter
5
+ class Observer
6
+ describe Observer do
7
+ before do
8
+ @observer = Observer.instance
9
+ end
10
+
11
+ it 'should normalize hook name' do
12
+ [:created, :create].each do |name|
13
+ @observer.instance_eval{ normalize_as_hook_name(name).should == :created }
14
+ end
15
+ [:update, :updated, :modify, :modified].each do |name|
16
+ @observer.instance_eval{ normalize_as_hook_name(name).should == :modified }
17
+ end
18
+ [:delete, :deleted, :remove, :removed].each do |name|
19
+ @observer.instance_eval{ normalize_as_hook_name(name).should == :deleted }
20
+ end
21
+ [:createx, :creat, :modifi, :modifie, :modifeed, :updat, :updatedd].each do |name|
22
+ @observer.instance_eval{ normalize_as_hook_name(name).should == nil }
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,3 @@
1
+ # -*- coding: utf-8 -*-
2
+ $:.unshift(File.dirname(__FILE__) + '/../lib')
3
+ require 'filetter'
metadata ADDED
@@ -0,0 +1,108 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: filetter
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.2.6
5
+ platform: ruby
6
+ authors:
7
+ - jugyo
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2009-02-22 00:00:00 +09:00
13
+ default_executable:
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: configatron
17
+ type: :runtime
18
+ version_requirement:
19
+ version_requirements: !ruby/object:Gem::Requirement
20
+ requirements:
21
+ - - ">="
22
+ - !ruby/object:Gem::Version
23
+ version: 2.2.2
24
+ version:
25
+ - !ruby/object:Gem::Dependency
26
+ name: rubytter
27
+ type: :runtime
28
+ version_requirement:
29
+ version_requirements: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: 0.4.5
34
+ version:
35
+ - !ruby/object:Gem::Dependency
36
+ name: rflickr
37
+ type: :runtime
38
+ version_requirement:
39
+ version_requirements: !ruby/object:Gem::Requirement
40
+ requirements:
41
+ - - ">="
42
+ - !ruby/object:Gem::Version
43
+ version: 2006.02.01
44
+ version:
45
+ - !ruby/object:Gem::Dependency
46
+ name: highline
47
+ type: :runtime
48
+ version_requirement:
49
+ version_requirements: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - ">="
52
+ - !ruby/object:Gem::Version
53
+ version: 1.5.0
54
+ version:
55
+ description: Filetter is a pluggable tool for file system.
56
+ email: jugyo.org@gmail.com
57
+ executables:
58
+ - filetter
59
+ extensions: []
60
+
61
+ extra_rdoc_files:
62
+ - README.rdoc
63
+ - History.txt
64
+ files:
65
+ - lib/filetter/file_info.rb
66
+ - lib/filetter/observer.rb
67
+ - lib/filetter/version.rb
68
+ - lib/filetter.rb
69
+ - lib/modes/flickr.rb
70
+ - lib/modes/mozrepl.rb
71
+ - lib/modes/sample.rb
72
+ - lib/modes/twitter.rb
73
+ - spec/filetter/observer_spec.rb
74
+ - spec/spec_helper.rb
75
+ - README.rdoc
76
+ - History.txt
77
+ - Rakefile
78
+ has_rdoc: true
79
+ homepage: http://github.com/jugyo/filetter
80
+ post_install_message:
81
+ rdoc_options:
82
+ - --main
83
+ - README.rdoc
84
+ - --exclude
85
+ - spec
86
+ require_paths:
87
+ - lib
88
+ required_ruby_version: !ruby/object:Gem::Requirement
89
+ requirements:
90
+ - - ">="
91
+ - !ruby/object:Gem::Version
92
+ version: "0"
93
+ version:
94
+ required_rubygems_version: !ruby/object:Gem::Requirement
95
+ requirements:
96
+ - - ">="
97
+ - !ruby/object:Gem::Version
98
+ version: "0"
99
+ version:
100
+ requirements: []
101
+
102
+ rubyforge_project: filetter
103
+ rubygems_version: 1.3.1
104
+ signing_key:
105
+ specification_version: 2
106
+ summary: Filetter is a pluggable tool for file system.
107
+ test_files: []
108
+