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