filetter 0.2.6

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.
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
+