pipe 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,4 @@
1
+ *.gem
2
+ .bundle
3
+ Gemfile.lock
4
+ pkg/*
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in pipe.gemspec
4
+ gemspec
@@ -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
@@ -0,0 +1,6 @@
1
+ require "bundler/gem_tasks"
2
+ require 'rspec/core/rake_task'
3
+
4
+ RSpec::Core::RakeTask.new('spec')
5
+
6
+ task :default => :spec
@@ -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
@@ -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,10 @@
1
+ class Pipe::Filter::JSONContains
2
+ def initialize(options)
3
+ @options = options
4
+ end
5
+
6
+ def match?(object)
7
+ match = object[@options[:attribute]] =~ /#{@options[:contains]}/
8
+ match and match >= 0
9
+ end
10
+ end
@@ -0,0 +1,5 @@
1
+ class Pipe::Input::HackerNews < Pipe::Source::JSONFeed
2
+ def initialize(options={})
3
+ super(url: 'http://apify.heroku.com/api/hacker_news.json')
4
+ end
5
+ end
@@ -0,0 +1,5 @@
1
+ class Pipe::Output::Gtalk < Pipe::Sink::InstantMessage
2
+ def initialize(options={})
3
+ super(options.merge(username: ENV['PIPE_GTALK_USER'], password: ENV['PIPE_GTALK_PASS']))
4
+ end
5
+ end
@@ -0,0 +1,3 @@
1
+ class Pipe::Sink::Android
2
+
3
+ end
@@ -0,0 +1,3 @@
1
+ class Pipe::Sink::Bookmark
2
+
3
+ end
@@ -0,0 +1,3 @@
1
+ class Pipe::Sink::Calendar
2
+
3
+ end
@@ -0,0 +1,3 @@
1
+ class Pipe::Sink::Email
2
+
3
+ end
@@ -0,0 +1,3 @@
1
+ class Pipe::Sink::Growl
2
+
3
+ end
@@ -0,0 +1,3 @@
1
+ class Pipe::Sink::HTTPCallback
2
+
3
+ end
@@ -0,0 +1,3 @@
1
+ class Pipe::Sink::IPhone
2
+
3
+ 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
@@ -0,0 +1,3 @@
1
+ class Pipe::Sink::Launchy
2
+
3
+ end
@@ -0,0 +1,3 @@
1
+ class Pipe::Sink::TextMessage
2
+
3
+ end
@@ -0,0 +1,3 @@
1
+ class Pipe::Sink::TodoList
2
+
3
+ end
@@ -0,0 +1,3 @@
1
+ class Pipe::Sink::Twitter
2
+
3
+ end
@@ -0,0 +1,3 @@
1
+ class Pipe::Source::HTMLPage
2
+
3
+ end
@@ -0,0 +1,9 @@
1
+ class Pipe::Source::JSONFeed
2
+ def initialize(options={})
3
+ @options = options
4
+ end
5
+
6
+ def get
7
+ ActiveSupport::JSON.decode(open(@options[:url]).read)
8
+ end
9
+ end
@@ -0,0 +1,3 @@
1
+ class Pipe::Source::TwitterFeed
2
+
3
+ end
@@ -0,0 +1,3 @@
1
+ class Pipe::Source::XMLFeed
2
+
3
+ end
@@ -0,0 +1,3 @@
1
+ module Pipe
2
+ VERSION = "0.0.1"
3
+ end
@@ -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
@@ -0,0 +1,4 @@
1
+ require 'spec_helper'
2
+
3
+ describe Pipe::Output::Gtalk do
4
+ end
@@ -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
@@ -0,0 +1,6 @@
1
+ require 'rubygems'
2
+ require 'bundler/setup'
3
+ require 'fakeweb'
4
+ require 'mocha'
5
+
6
+ require 'pipe'
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