pipe 0.0.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.
- data/.gitignore +4 -0
- data/Gemfile +4 -0
- data/README.md +46 -0
- data/Rakefile +6 -0
- data/examples/hacker_news_gtalk_alert.rb +13 -0
- data/lib/pipe.rb +40 -0
- data/lib/pipe/filter/json_contains.rb +10 -0
- data/lib/pipe/input/hacker_news.rb +5 -0
- data/lib/pipe/output/gtalk.rb +5 -0
- data/lib/pipe/sink/android.rb +3 -0
- data/lib/pipe/sink/bookmark.rb +3 -0
- data/lib/pipe/sink/calendar.rb +3 -0
- data/lib/pipe/sink/email.rb +3 -0
- data/lib/pipe/sink/growl.rb +3 -0
- data/lib/pipe/sink/http_callback.rb +3 -0
- data/lib/pipe/sink/i_phone.rb +3 -0
- data/lib/pipe/sink/instant_message.rb +22 -0
- data/lib/pipe/sink/launchy.rb +3 -0
- data/lib/pipe/sink/text_message.rb +3 -0
- data/lib/pipe/sink/todo_list.rb +3 -0
- data/lib/pipe/sink/twitter.rb +3 -0
- data/lib/pipe/source/html_page.rb +3 -0
- data/lib/pipe/source/json_feed.rb +9 -0
- data/lib/pipe/source/twitter_feed.rb +3 -0
- data/lib/pipe/source/xml_feed.rb +3 -0
- data/lib/pipe/version.rb +3 -0
- data/pipe.gemspec +29 -0
- data/spec/filter/json_contains_spec.rb +17 -0
- data/spec/input/hacker_news_spec.rb +20 -0
- data/spec/output/gtalk_spec.rb +4 -0
- data/spec/pipe_spec.rb +33 -0
- data/spec/sink/instant_message_spec.rb +26 -0
- data/spec/source/json_feed_spec.rb +20 -0
- data/spec/spec_helper.rb +6 -0
- metadata +144 -0
data/.gitignore
ADDED
data/Gemfile
ADDED
data/README.md
ADDED
@@ -0,0 +1,46 @@
|
|
1
|
+
## pIpe
|
2
|
+
|
3
|
+
ifttt is awesome for popular channels like Twitter, Facebook, Email etc. But if you want to customize channels to use any json or xml feed it isn't of much help.
|
4
|
+
|
5
|
+
pIpe is ifttt for websites/webservices linked to webservices/smartphones/laptops with advanced filters.
|
6
|
+
|
7
|
+
It is the ultimate in web automation. See [Hacker News Gtalk Alert](https://github.com/sathish316/pIpe/blob/master/examples/hacker_news_gtalk_alert.rb) for example
|
8
|
+
|
9
|
+
To install:
|
10
|
+
|
11
|
+
```
|
12
|
+
gem install pipe
|
13
|
+
```
|
14
|
+
|
15
|
+
Add to Gemfile:
|
16
|
+
|
17
|
+
```
|
18
|
+
gem 'pipe'
|
19
|
+
```
|
20
|
+
|
21
|
+
### Source
|
22
|
+
|
23
|
+
Source can be:
|
24
|
+
|
25
|
+
1. Any json feed
|
26
|
+
2. Any xml/rss feed
|
27
|
+
3. Any website with changes detected from html
|
28
|
+
4. Twitter
|
29
|
+
|
30
|
+
### Sink
|
31
|
+
|
32
|
+
Events can be notified to:
|
33
|
+
|
34
|
+
1. Any webservice
|
35
|
+
2. Desktop notifications like Growl
|
36
|
+
3. iPhone / Android
|
37
|
+
4. Email, Instant Message, Text Message
|
38
|
+
5. Twitter, Google Calendar, Todo lists etc
|
39
|
+
|
40
|
+
### Filter
|
41
|
+
|
42
|
+
pIpe has advanced filters and is not limited to one input and output.
|
43
|
+
|
44
|
+
### Contribute
|
45
|
+
|
46
|
+
pIpe is still a work in progress. To contribute fork and check out unfinished Sources, Sinks, Inputs, Outputs
|
data/Rakefile
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# To execute with Gtalk outputs:
|
3
|
+
# $ PIPE_GTALK_USER=abc PIPE_GTALK_PASS=def ruby examples/hacker_news_gtalk_alert.rb
|
4
|
+
|
5
|
+
require 'rubygems'
|
6
|
+
require 'pipe'
|
7
|
+
# require_relative '../lib/pipe' # for development
|
8
|
+
|
9
|
+
hacker_news = Pipe::Input::HackerNews.new(url: 'http://apify.heroku.com/api/hacker_news.json')
|
10
|
+
apple_post = Pipe::Filter::JSONContains.new(attribute: 'title', contains: 'Apple')
|
11
|
+
gtalk_message = Pipe::Output::Gtalk.new(recipient: 'sathish316@gmail.com', message: 'Found Apple post in HackerNews')
|
12
|
+
pipe = Pipe::Pipe.new(hacker_news, apple_post, gtalk_message)
|
13
|
+
pipe.execute
|
data/lib/pipe.rb
ADDED
@@ -0,0 +1,40 @@
|
|
1
|
+
require "pipe/version"
|
2
|
+
require 'json'
|
3
|
+
require 'open-uri'
|
4
|
+
require 'active_support'
|
5
|
+
require 'net/http'
|
6
|
+
require 'xmpp4r'
|
7
|
+
# require 'xmpp4r-simple'
|
8
|
+
|
9
|
+
module Pipe
|
10
|
+
module Source
|
11
|
+
end
|
12
|
+
module Input
|
13
|
+
end
|
14
|
+
module Sink
|
15
|
+
end
|
16
|
+
module Output
|
17
|
+
end
|
18
|
+
module Filter
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
['source', 'input', 'sink', 'output', 'filter'].each do |dir|
|
23
|
+
Dir[File.dirname(__FILE__) + "/pipe/#{dir}/*.rb"].each do |path|
|
24
|
+
require "pipe/#{dir}/#{File.basename(path)}"
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
module Pipe
|
29
|
+
class Pipe
|
30
|
+
def initialize(input, filter, output)
|
31
|
+
@input, @filter, @output = input, filter, output
|
32
|
+
end
|
33
|
+
|
34
|
+
def execute
|
35
|
+
data = @input.get
|
36
|
+
notify = data.any? {|datum| @filter.match?(datum)}
|
37
|
+
@output.post if notify
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
class Pipe::Sink::InstantMessage
|
2
|
+
def initialize(options={})
|
3
|
+
@options = options
|
4
|
+
end
|
5
|
+
|
6
|
+
def post
|
7
|
+
connect
|
8
|
+
msg = ::Jabber::Message::new(@options[:recipient], @options[:message])
|
9
|
+
msg.type=:chat
|
10
|
+
@messenger.send(msg)
|
11
|
+
end
|
12
|
+
|
13
|
+
private
|
14
|
+
|
15
|
+
def connect
|
16
|
+
username = ::Jabber::JID::new(@options[:username])
|
17
|
+
@messenger = ::Jabber::Client.new(username)
|
18
|
+
@messenger.connect
|
19
|
+
@messenger.auth(@options[:password])
|
20
|
+
@messenger.send(::Jabber::Presence.new.set_type(:available))
|
21
|
+
end
|
22
|
+
end
|
data/lib/pipe/version.rb
ADDED
data/pipe.gemspec
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
3
|
+
require "pipe/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = "pipe"
|
7
|
+
s.version = Pipe::VERSION
|
8
|
+
s.authors = ["Sathish"]
|
9
|
+
s.email = ["sathish316@gmail.com"]
|
10
|
+
s.homepage = ""
|
11
|
+
s.summary = %q{pIpe is ifttt for websites/webservices linked to webservices/smartphones/laptops with sophisticated filters}
|
12
|
+
s.description = %q{pIpe is ifttt for websites/webservices linked to webservices/smartphones/laptops with sophisticated filters. pIpe is like *nix pipe operator for linking websites, webservices, smartphones and laptops}
|
13
|
+
|
14
|
+
s.rubyforge_project = "pipe"
|
15
|
+
|
16
|
+
s.files = `git ls-files`.split("\n")
|
17
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
18
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
19
|
+
s.require_paths = ["lib"]
|
20
|
+
|
21
|
+
# specify any dependencies here; for example:
|
22
|
+
s.add_runtime_dependency "active_support"
|
23
|
+
s.add_runtime_dependency "xmpp4r"
|
24
|
+
# s.add_runtime_dependency "xmpp4r-simple"
|
25
|
+
|
26
|
+
s.add_development_dependency "rspec"
|
27
|
+
s.add_development_dependency "fakeweb"
|
28
|
+
s.add_development_dependency "mocha"
|
29
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Pipe::Filter::JSONContains do
|
4
|
+
describe "#match?" do
|
5
|
+
it "should return true if object matches condition" do
|
6
|
+
filter = Pipe::Filter::JSONContains.new(attribute: 'title', contains: 'Clojure')
|
7
|
+
object = {'rank' => '1', 'title' => 'Clojure is awesome'}
|
8
|
+
filter.should be_match(object)
|
9
|
+
end
|
10
|
+
|
11
|
+
it "should return false if object does not match condition" do
|
12
|
+
filter = Pipe::Filter::JSONContains.new(attribute: 'title', contains: 'Clojure')
|
13
|
+
object = {'rank' => '1', 'title' => 'Haskell is awesome'}
|
14
|
+
filter.should_not be_match(object)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Pipe::Input::HackerNews do
|
4
|
+
describe "#get" do
|
5
|
+
before(:each) do
|
6
|
+
url = "http://apify.heroku.com/api/hacker_news.json"
|
7
|
+
@posts = [
|
8
|
+
{'rank' => '1', 'title' => "Haskell is awesome"},
|
9
|
+
{'rank' => '2', 'title' => "Clojure is awesome"},
|
10
|
+
{'rank' => '3', 'title' => "Make something people want"},
|
11
|
+
]
|
12
|
+
FakeWeb.register_uri :get, url, :body => @posts.to_json
|
13
|
+
end
|
14
|
+
|
15
|
+
it "should get data" do
|
16
|
+
feed = Pipe::Input::HackerNews.new
|
17
|
+
feed.get.should == @posts
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
data/spec/pipe_spec.rb
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Pipe::Pipe do
|
4
|
+
describe "#execute" do
|
5
|
+
it "should execute pipe if filter matched" do
|
6
|
+
input = Pipe::Input::HackerNews.new
|
7
|
+
filter = Pipe::Filter::JSONContains.new(title: 'Clojure')
|
8
|
+
output = Pipe::Output::Gtalk.new(username: 'test', password: 'pass', recipient: 'recipient@gmail.com', message: 'Found clojure post in HackerNews')
|
9
|
+
|
10
|
+
input.expects(:get).returns([
|
11
|
+
{'rank' => 1, 'title' => 'Clojure is awesome'}
|
12
|
+
])
|
13
|
+
output.expects(:post)
|
14
|
+
|
15
|
+
pipe = Pipe::Pipe.new(input, filter, output)
|
16
|
+
pipe.execute
|
17
|
+
end
|
18
|
+
|
19
|
+
it "should not execute pipe if filter does not match" do
|
20
|
+
input = Pipe::Input::HackerNews.new
|
21
|
+
filter = Pipe::Filter::JSONContains.new(title: 'Clojure')
|
22
|
+
output = Pipe::Output::Gtalk.new(username: 'test', password: 'pass', recipient: 'recipient@gmail.com', message: 'Found clojure post in HackerNews')
|
23
|
+
|
24
|
+
input.expects(:get).returns([
|
25
|
+
{'rank' => 1, 'title' => 'Haskell is awesome'}
|
26
|
+
])
|
27
|
+
output.expects(:post).never
|
28
|
+
|
29
|
+
pipe = Pipe::Pipe.new(input, filter, output)
|
30
|
+
pipe.execute
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Pipe::Sink::InstantMessage do
|
4
|
+
describe "#post" do
|
5
|
+
before(:each) do
|
6
|
+
pending
|
7
|
+
@username, @password = 'testuser', 'testpass'
|
8
|
+
::Jabber::JID.expects(:new).with(@username).returns(jabber_id = mock('jabber_id'))
|
9
|
+
::Jabber::Client.expects(:new).with(jabber_id).returns(@messenger = mock('messenger'))
|
10
|
+
@messenger.expects :connect
|
11
|
+
@messenger.expects(:auth).with(@password)
|
12
|
+
@messenger.expects(:send).with(::Jabber::Presence.new.set_type(:available))
|
13
|
+
end
|
14
|
+
|
15
|
+
it "should deliver message to recipient" do
|
16
|
+
pending
|
17
|
+
recipient, message = 'testrecipient', 'hello world'
|
18
|
+
::Jabber::Message.expects(:new).with(recipient, message).returns(msg = stub('msg'))
|
19
|
+
msg.expects(:type=).with(:chat)
|
20
|
+
@messenger.expects(:send).with(msg)
|
21
|
+
|
22
|
+
im = Pipe::Sink::InstantMessage.new(username: @username, password: @password)
|
23
|
+
im.post(recipient: recipient, message: message)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Pipe::Source::JSONFeed do
|
4
|
+
describe "#get" do
|
5
|
+
before(:each) do
|
6
|
+
@url = 'http://test.com/hackernews.json'
|
7
|
+
@posts = [
|
8
|
+
{'rank' => '1', 'title' => "Haskell is awesome"},
|
9
|
+
{'rank' => '2', 'title' => "Clojure is awesome"},
|
10
|
+
{'rank' => '3', 'title' => "Make something people want"},
|
11
|
+
]
|
12
|
+
FakeWeb.register_uri :get, @url, :body => @posts.to_json
|
13
|
+
end
|
14
|
+
|
15
|
+
it "should get data from Feed" do
|
16
|
+
feed = Pipe::Source::JSONFeed.new(url: @url)
|
17
|
+
feed.get.should == @posts
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
data/spec/spec_helper.rb
ADDED
metadata
ADDED
@@ -0,0 +1,144 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: pipe
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Sathish
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2012-07-06 00:00:00.000000000Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: active_support
|
16
|
+
requirement: &70299582821960 !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '0'
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: *70299582821960
|
25
|
+
- !ruby/object:Gem::Dependency
|
26
|
+
name: xmpp4r
|
27
|
+
requirement: &70299582820640 !ruby/object:Gem::Requirement
|
28
|
+
none: false
|
29
|
+
requirements:
|
30
|
+
- - ! '>='
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: '0'
|
33
|
+
type: :runtime
|
34
|
+
prerelease: false
|
35
|
+
version_requirements: *70299582820640
|
36
|
+
- !ruby/object:Gem::Dependency
|
37
|
+
name: rspec
|
38
|
+
requirement: &70299582819440 !ruby/object:Gem::Requirement
|
39
|
+
none: false
|
40
|
+
requirements:
|
41
|
+
- - ! '>='
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
version: '0'
|
44
|
+
type: :development
|
45
|
+
prerelease: false
|
46
|
+
version_requirements: *70299582819440
|
47
|
+
- !ruby/object:Gem::Dependency
|
48
|
+
name: fakeweb
|
49
|
+
requirement: &70299582818740 !ruby/object:Gem::Requirement
|
50
|
+
none: false
|
51
|
+
requirements:
|
52
|
+
- - ! '>='
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
type: :development
|
56
|
+
prerelease: false
|
57
|
+
version_requirements: *70299582818740
|
58
|
+
- !ruby/object:Gem::Dependency
|
59
|
+
name: mocha
|
60
|
+
requirement: &70299582818080 !ruby/object:Gem::Requirement
|
61
|
+
none: false
|
62
|
+
requirements:
|
63
|
+
- - ! '>='
|
64
|
+
- !ruby/object:Gem::Version
|
65
|
+
version: '0'
|
66
|
+
type: :development
|
67
|
+
prerelease: false
|
68
|
+
version_requirements: *70299582818080
|
69
|
+
description: pIpe is ifttt for websites/webservices linked to webservices/smartphones/laptops
|
70
|
+
with sophisticated filters. pIpe is like *nix pipe operator for linking websites,
|
71
|
+
webservices, smartphones and laptops
|
72
|
+
email:
|
73
|
+
- sathish316@gmail.com
|
74
|
+
executables: []
|
75
|
+
extensions: []
|
76
|
+
extra_rdoc_files: []
|
77
|
+
files:
|
78
|
+
- .gitignore
|
79
|
+
- Gemfile
|
80
|
+
- README.md
|
81
|
+
- Rakefile
|
82
|
+
- examples/hacker_news_gtalk_alert.rb
|
83
|
+
- lib/pipe.rb
|
84
|
+
- lib/pipe/filter/json_contains.rb
|
85
|
+
- lib/pipe/input/hacker_news.rb
|
86
|
+
- lib/pipe/output/gtalk.rb
|
87
|
+
- lib/pipe/sink/android.rb
|
88
|
+
- lib/pipe/sink/bookmark.rb
|
89
|
+
- lib/pipe/sink/calendar.rb
|
90
|
+
- lib/pipe/sink/email.rb
|
91
|
+
- lib/pipe/sink/growl.rb
|
92
|
+
- lib/pipe/sink/http_callback.rb
|
93
|
+
- lib/pipe/sink/i_phone.rb
|
94
|
+
- lib/pipe/sink/instant_message.rb
|
95
|
+
- lib/pipe/sink/launchy.rb
|
96
|
+
- lib/pipe/sink/text_message.rb
|
97
|
+
- lib/pipe/sink/todo_list.rb
|
98
|
+
- lib/pipe/sink/twitter.rb
|
99
|
+
- lib/pipe/source/html_page.rb
|
100
|
+
- lib/pipe/source/json_feed.rb
|
101
|
+
- lib/pipe/source/twitter_feed.rb
|
102
|
+
- lib/pipe/source/xml_feed.rb
|
103
|
+
- lib/pipe/version.rb
|
104
|
+
- pipe.gemspec
|
105
|
+
- spec/filter/json_contains_spec.rb
|
106
|
+
- spec/input/hacker_news_spec.rb
|
107
|
+
- spec/output/gtalk_spec.rb
|
108
|
+
- spec/pipe_spec.rb
|
109
|
+
- spec/sink/instant_message_spec.rb
|
110
|
+
- spec/source/json_feed_spec.rb
|
111
|
+
- spec/spec_helper.rb
|
112
|
+
homepage: ''
|
113
|
+
licenses: []
|
114
|
+
post_install_message:
|
115
|
+
rdoc_options: []
|
116
|
+
require_paths:
|
117
|
+
- lib
|
118
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
119
|
+
none: false
|
120
|
+
requirements:
|
121
|
+
- - ! '>='
|
122
|
+
- !ruby/object:Gem::Version
|
123
|
+
version: '0'
|
124
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
125
|
+
none: false
|
126
|
+
requirements:
|
127
|
+
- - ! '>='
|
128
|
+
- !ruby/object:Gem::Version
|
129
|
+
version: '0'
|
130
|
+
requirements: []
|
131
|
+
rubyforge_project: pipe
|
132
|
+
rubygems_version: 1.8.10
|
133
|
+
signing_key:
|
134
|
+
specification_version: 3
|
135
|
+
summary: pIpe is ifttt for websites/webservices linked to webservices/smartphones/laptops
|
136
|
+
with sophisticated filters
|
137
|
+
test_files:
|
138
|
+
- spec/filter/json_contains_spec.rb
|
139
|
+
- spec/input/hacker_news_spec.rb
|
140
|
+
- spec/output/gtalk_spec.rb
|
141
|
+
- spec/pipe_spec.rb
|
142
|
+
- spec/sink/instant_message_spec.rb
|
143
|
+
- spec/source/json_feed_spec.rb
|
144
|
+
- spec/spec_helper.rb
|