feedbook 0.9.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +15 -0
- data/.gitignore +22 -0
- data/.rspec +3 -0
- data/.travis.yml +6 -0
- data/Gemfile +3 -0
- data/LICENSE.txt +22 -0
- data/README.md +129 -0
- data/Rakefile +7 -0
- data/bin/feedbook +73 -0
- data/feedbook.gemspec +35 -0
- data/lib/feedbook.rb +6 -0
- data/lib/feedbook/comparers/posts_comparer.rb +15 -0
- data/lib/feedbook/configuration.rb +47 -0
- data/lib/feedbook/errors.rb +10 -0
- data/lib/feedbook/errors/invalid_feed_url_error.rb +6 -0
- data/lib/feedbook/errors/invalid_interval_format_error.rb +6 -0
- data/lib/feedbook/errors/invalid_variables_format_error.rb +6 -0
- data/lib/feedbook/errors/no_configuration_file_error.rb +6 -0
- data/lib/feedbook/errors/notifier_configuration_error.rb +12 -0
- data/lib/feedbook/errors/notifier_notify_error.rb +12 -0
- data/lib/feedbook/errors/parse_feed_error.rb +11 -0
- data/lib/feedbook/errors/template_syntax_error.rb +6 -0
- data/lib/feedbook/errors/unsupported_notifier_error.rb +12 -0
- data/lib/feedbook/factories/notifiers_factory.rb +28 -0
- data/lib/feedbook/feed.rb +85 -0
- data/lib/feedbook/helpers/time_interval_parser.rb +38 -0
- data/lib/feedbook/listener.rb +122 -0
- data/lib/feedbook/notification.rb +62 -0
- data/lib/feedbook/notifiers.rb +5 -0
- data/lib/feedbook/notifiers/facebook_notifier.rb +44 -0
- data/lib/feedbook/notifiers/irc_notifier.rb +42 -0
- data/lib/feedbook/notifiers/mail_notifier.rb +52 -0
- data/lib/feedbook/notifiers/null_notifier.rb +25 -0
- data/lib/feedbook/notifiers/twitter_notifier.rb +49 -0
- data/lib/feedbook/post.rb +33 -0
- data/lib/feedbook/version.rb +3 -0
- data/spec/spec_helper.rb +30 -0
- data/spec/unit/lib/comparers/posts_comparer_spec.rb +13 -0
- data/spec/unit/lib/configuration_spec.rb +43 -0
- data/spec/unit/lib/factories/notifiers_factory_spec.rb +28 -0
- data/spec/unit/lib/feed_spec.rb +42 -0
- data/spec/unit/lib/helpers/time_interval_parser_spec.rb +26 -0
- data/spec/unit/lib/listener_spec.rb +29 -0
- data/spec/unit/lib/notification_spec.rb +44 -0
- data/spec/unit/lib/notifiers/facebook_notifier_spec.rb +34 -0
- data/spec/unit/lib/notifiers/irc_notifier_spec.rb +41 -0
- data/spec/unit/lib/notifiers/mail_notifier_spec.rb +39 -0
- data/spec/unit/lib/notifiers/null_notifier_spec.rb +19 -0
- data/spec/unit/lib/notifiers/twitter_notifier_spec.rb +36 -0
- data/spec/unit/lib/post_spec.rb +51 -0
- metadata +304 -0
checksums.yaml
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
---
|
2
|
+
!binary "U0hBMQ==":
|
3
|
+
metadata.gz: !binary |-
|
4
|
+
ZDkwNWM3OWZlM2RkOTliMzFmYjk5OTJmZTU4OGYwNTQzY2YzY2NkMA==
|
5
|
+
data.tar.gz: !binary |-
|
6
|
+
MWNiMmE5Njk1MDE1MDI1ZGJlNTBkMDRhM2M4NzM3Y2ZlMzZiOWU2OA==
|
7
|
+
SHA512:
|
8
|
+
metadata.gz: !binary |-
|
9
|
+
OTFjODk5MGIwNzhmZDlmM2RiMmIxMmYxNmZiZmVmNTViNTE0MjZhNDk0ZDkx
|
10
|
+
MDY2OWQ2YWY3N2UzODE0ZWYyNGExZWNiOWI1YzliNTNiNzc1ODE3MmVmNzA1
|
11
|
+
ZTk3OTlhMGRjYzE4MjQ2MmE2ODM2NTFmYjNkZmIwNGM5YjRjNDE=
|
12
|
+
data.tar.gz: !binary |-
|
13
|
+
NjJhZmU1YTMyOGVmZDQ1ZTUyY2U5Y2U0YzdhN2JkMTYwMGFhMWM1M2Q1MjM2
|
14
|
+
MDllNTdjMjViOWQ5MTUwNjdhZmQ2MDY4YTUzYzBlNjU5MDc1Zjg5OTQ1MDBi
|
15
|
+
OGIwYTBlZmUwMmYzMzkxMGQyZWFlMzY5ZWI0NzVmZDJlZDAyMjc=
|
data/.gitignore
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
*.gem
|
2
|
+
*.rbc
|
3
|
+
.bundle
|
4
|
+
.config
|
5
|
+
.yardoc
|
6
|
+
Gemfile.lock
|
7
|
+
InstalledFiles
|
8
|
+
_yardoc
|
9
|
+
coverage
|
10
|
+
doc/
|
11
|
+
lib/bundler/man
|
12
|
+
pkg
|
13
|
+
rdoc
|
14
|
+
spec/reports
|
15
|
+
test/tmp
|
16
|
+
test/version_tmp
|
17
|
+
tmp
|
18
|
+
*.bundle
|
19
|
+
*.so
|
20
|
+
*.o
|
21
|
+
*.a
|
22
|
+
mkmf.log
|
data/.rspec
ADDED
data/.travis.yml
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2014 Maciej Paruszewski
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,129 @@
|
|
1
|
+
# Feedbook [![Build Status](https://travis-ci.org/pinoss/feedbook.svg?branch=master)](https://travis-ci.org/pinoss/feedbook) [![Code Climate](https://codeclimate.com/github/pinoss/feedbook.png)](https://codeclimate.com/github/pinoss/feedbook) [![Coverage Status](https://coveralls.io/repos/pinoss/feedbook/badge.png)](https://coveralls.io/r/pinoss/feedbook)
|
2
|
+
|
3
|
+
Feedbook is a simple console application that allows to notify on IRC, mail and social media (like Twitter and Facebook) about RSS/Atom updates.
|
4
|
+
|
5
|
+
## Why?
|
6
|
+
|
7
|
+
> Automation isn’t about being lazy, it’s about being efficient.
|
8
|
+
> ~ Addy Osmani
|
9
|
+
|
10
|
+
* If you do something every day, why not to automate it?
|
11
|
+
* If you have a blog and want to notify your users on Twitter on Facebook that there is a new post, you can do it without opening your browser.
|
12
|
+
|
13
|
+
## Main Features
|
14
|
+
|
15
|
+
* Parse feeds and notifies about new posts.
|
16
|
+
* Easy to configure.
|
17
|
+
* Fire and forget - once you have valid configuration you do not need to think about feedbook again, everything will work automatically.
|
18
|
+
|
19
|
+
## Installation
|
20
|
+
|
21
|
+
Install gem with:
|
22
|
+
|
23
|
+
$ gem install feedbook
|
24
|
+
|
25
|
+
## Usage
|
26
|
+
|
27
|
+
Install gem into your system:
|
28
|
+
|
29
|
+
$ gem install feedbook
|
30
|
+
|
31
|
+
Create your configuration file or take a default file and modify it:
|
32
|
+
|
33
|
+
$ feedbook init
|
34
|
+
=> Created default feedbook configuration file: feedbook.yml
|
35
|
+
|
36
|
+
After you create or modify your configuration file, you need to start listening for RSS changes:
|
37
|
+
|
38
|
+
$ feedbook start
|
39
|
+
Loading configuration from file feedbook.yml... completed.
|
40
|
+
Loading notifiers...
|
41
|
+
Configuration loaded for TwitterNotifier
|
42
|
+
Configuration loaded for FacebookNotifier
|
43
|
+
completed.
|
44
|
+
Fetching feeds for the first use... completed.
|
45
|
+
Listener started...
|
46
|
+
Fetching feeds...
|
47
|
+
|
48
|
+
And Feedbook now will work and listen for changes.
|
49
|
+
|
50
|
+
## Configuration
|
51
|
+
|
52
|
+
|
53
|
+
```yaml
|
54
|
+
feeds:
|
55
|
+
- url: https://github.com/pinoss.atom # collection of urls (separated by space)
|
56
|
+
variables: # you can use variables defined here in your templates
|
57
|
+
default_header: Check out our new post
|
58
|
+
notifications: # notifications configuration, you need to specify type and template for each notification
|
59
|
+
- type: facebook
|
60
|
+
template: "{{ default_header }} {{ title }} by {{ author }}: {{ url }}"
|
61
|
+
- type: twitter
|
62
|
+
template: "{{ default_header }} on our blog {{ feed_url }}: {{ title }}/{{ url }}"
|
63
|
+
|
64
|
+
configuration:
|
65
|
+
interval: 5m
|
66
|
+
facebook: # Facebook OAuth token
|
67
|
+
token: SECRET_FACEBOOK_TOKEN
|
68
|
+
twitter: # Twitter token collection
|
69
|
+
consumer_key: SECRET_CONSUMER_KEY
|
70
|
+
consumer_secret: SECRET_TWITTER_CONSUMER_SECRET
|
71
|
+
access_token: SECRET_TWITTER_ACCESS_TOKEN
|
72
|
+
access_token_secret: SECRET_TWITTER_ACCESS_TOKEN_SECRET
|
73
|
+
irc: # IRC configuration
|
74
|
+
url: irc.freenode.net
|
75
|
+
port: 8001
|
76
|
+
ssl_enabled: true/false
|
77
|
+
channel: #channel
|
78
|
+
nick: feedbook_bot
|
79
|
+
mail: # Mail configuration
|
80
|
+
address: mparuszewski@feedbook.lo
|
81
|
+
port: 5870
|
82
|
+
domain: smtp.feedbook.lo
|
83
|
+
username: mparuszewski
|
84
|
+
password: your_password
|
85
|
+
authentication: plain
|
86
|
+
enable_starttls_auto: true/false
|
87
|
+
|
88
|
+
```
|
89
|
+
|
90
|
+
### Facebook
|
91
|
+
|
92
|
+
You need to generate your access token to use Facebook notifier, you can do that on [Graph API Explorer](https://developers.facebook.com/tools/explorer) page (click *Get access token* and select __user_status__).
|
93
|
+
|
94
|
+
### Twitter
|
95
|
+
|
96
|
+
You need to generate your keys here, you will need 4 keys, first two you will get on [Create an application](https://apps.twitter.com/app/new) page, after you create it, go to __API Keys__ tab and click __Create my access token__ at the bottom.
|
97
|
+
|
98
|
+
### Mail
|
99
|
+
|
100
|
+
Mail configuration is really simple, you need to specify few parameters and you will get mail notifications.
|
101
|
+
|
102
|
+
### IRC
|
103
|
+
|
104
|
+
IRC configuration is also very simple, I think it does not require any explanations.
|
105
|
+
|
106
|
+
## Templates
|
107
|
+
|
108
|
+
Feedbook uses Liquid for generating output. If you know Mustache it will not be a problem for you to write your template, it uses same syntax, but provides more features (like tags and helpers) - you can read about Liquid on [Liquid for Designers](https://github.com/Shopify/liquid/wiki/Liquid-for-Designers).
|
109
|
+
|
110
|
+
## Todo
|
111
|
+
|
112
|
+
Because Feedbook is still in development there is many to do:
|
113
|
+
|
114
|
+
* add Google+ Notifier
|
115
|
+
Unfortunately Google+ does not provides API with ability to push messages to streams. Because of that I need to find a tool that will provide that feature without use of Google+.
|
116
|
+
* add links shortener (bit.ly or goo.gl) as a Liquid tag/filter
|
117
|
+
Twitter limits Tweet length to 140 characters, why not to shorten links and rescue too long message.
|
118
|
+
* add ability to add own Notifier without forking Feedbook project
|
119
|
+
I would like to give ability to users to create own Notifier plugins without any special development to Feedbook.
|
120
|
+
* add more tests
|
121
|
+
I would like to add integration tests to make sure that all features work.
|
122
|
+
|
123
|
+
## Contributing
|
124
|
+
|
125
|
+
1. Fork it ( https://github.com/pinoss/feedbook/fork )
|
126
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
127
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
128
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
129
|
+
5. Create a new Pull Request
|
data/Rakefile
ADDED
data/bin/feedbook
ADDED
@@ -0,0 +1,73 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
$LOAD_PATH.unshift(File.dirname(__FILE__) + '/../lib')
|
3
|
+
|
4
|
+
require 'gli'
|
5
|
+
require 'box'
|
6
|
+
require 'feedbook'
|
7
|
+
require 'fileutils'
|
8
|
+
|
9
|
+
include GLI::App
|
10
|
+
|
11
|
+
program_desc 'Feedbook is a simple gem and application that notifies about new posts and Atom/RSS updates on your social media sites (like Facebook and Twitter), e-mail or IRC.'
|
12
|
+
|
13
|
+
flag [:c,:config], default_value: 'feedbook.yml', desc: 'Feedbook configuration file location'
|
14
|
+
|
15
|
+
desc 'Parses feedbook.yml file for feeds and configuration and listen for changes in RSS/Atom feeds to notify about updates on social media sites'
|
16
|
+
command :start do |c|
|
17
|
+
|
18
|
+
c.action do |global_options, _, _|
|
19
|
+
Feedbook::Listener.start(global_options[:config])
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
desc 'Creates basic feedbook config file'
|
24
|
+
command :init do |c|
|
25
|
+
c.action do |global_options, _, _|
|
26
|
+
abort 'There is already a feedbook configuration file' if File.exist?(global_options[:config])
|
27
|
+
File.open(global_options[:config], 'w') { |f| f.write(Box::FILES['feedbook']) }
|
28
|
+
puts "=> Created default feedbook configuration file: #{global_options[:config]}"
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
desc 'Outputs feedbook gem version'
|
33
|
+
command :version do |c|
|
34
|
+
c.action do |global_options, _, _|
|
35
|
+
puts "feedbook version: #{Feedbook::VERSION}"
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
on_error do |exception|
|
40
|
+
case exception
|
41
|
+
when SystemExit
|
42
|
+
else
|
43
|
+
STDERR.puts "Error: #{exception} (#{exception.class})"
|
44
|
+
STDERR.puts exception.backtrace.join("\n")
|
45
|
+
end
|
46
|
+
false
|
47
|
+
end
|
48
|
+
|
49
|
+
exit run(ARGV)
|
50
|
+
|
51
|
+
__END__
|
52
|
+
@@ feedbook
|
53
|
+
## Feedbook default config file, modify it!
|
54
|
+
|
55
|
+
feeds:
|
56
|
+
- url: https://github.com/pinoss.atom
|
57
|
+
variables:
|
58
|
+
default_header: Check out our new post
|
59
|
+
notifications:
|
60
|
+
- type: facebook
|
61
|
+
template: "{{ default_header }} {{ title }} by {{ author }}: {{ url }}"
|
62
|
+
- type: twitter
|
63
|
+
template: "{{ default_header }} on our blog {{ feed_url }}: {{ title }}/{{ url }}"
|
64
|
+
|
65
|
+
configuration:
|
66
|
+
interval: 5m
|
67
|
+
facebook:
|
68
|
+
token: SECRET_FACEBOOK_TOKEN
|
69
|
+
twitter:
|
70
|
+
consumer_key: SECRET_CONSUMER_KEY
|
71
|
+
consumer_secret: SECRET_TWITTER_CONSUMER_SECRET
|
72
|
+
access_token: SECRET_TWITTER_ACCESS_TOKEN
|
73
|
+
access_token_secret: SECRET_TWITTER_ACCESS_TOKEN_SECRET
|
data/feedbook.gemspec
ADDED
@@ -0,0 +1,35 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'feedbook/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = 'feedbook'
|
8
|
+
spec.version = Feedbook::VERSION
|
9
|
+
spec.authors = ['Maciej Paruszewski']
|
10
|
+
spec.email = ['maciek.paruszewski@gmail.com']
|
11
|
+
spec.summary = %q{Feedbook}
|
12
|
+
spec.homepage = "https://github.com/pinoss/feedbook"
|
13
|
+
spec.license = "MIT"
|
14
|
+
|
15
|
+
spec.files = `git ls-files -z`.split("\x0")
|
16
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
17
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
18
|
+
spec.require_paths = ['lib']
|
19
|
+
|
20
|
+
spec.add_runtime_dependency 'feedjira', '~> 1.3'
|
21
|
+
spec.add_runtime_dependency 'gli', '~> 2.1'
|
22
|
+
spec.add_runtime_dependency 'liquid', '~> 2.6'
|
23
|
+
spec.add_runtime_dependency 'timeloop', '~> 1.0'
|
24
|
+
spec.add_runtime_dependency 'koala', '~> 1.9'
|
25
|
+
spec.add_runtime_dependency 'box', '~> 0.1'
|
26
|
+
spec.add_runtime_dependency 'twitter', '~> 5.1'
|
27
|
+
spec.add_runtime_dependency 'mail', '~> 2.6'
|
28
|
+
spec.add_runtime_dependency 'irc-notify'
|
29
|
+
|
30
|
+
spec.add_development_dependency 'bundler', '~> 1.6'
|
31
|
+
spec.add_development_dependency 'rake', '~> 10.3'
|
32
|
+
spec.add_development_dependency 'rspec'
|
33
|
+
spec.add_development_dependency 'coveralls'
|
34
|
+
spec.add_development_dependency 'pry-debugger'
|
35
|
+
end
|
data/lib/feedbook.rb
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
module Feedbook
|
2
|
+
module Comparers
|
3
|
+
module PostsComparer
|
4
|
+
|
5
|
+
# Returns only posts from new posts list that does not exists in old posts list.
|
6
|
+
# @param old_posts [Array] list of old posts
|
7
|
+
# @param new_posts [Array] list of new posts
|
8
|
+
#
|
9
|
+
# @return [type] [description]
|
10
|
+
def self.get_new_posts(old_posts, new_posts)
|
11
|
+
new_posts.select { |post| old_posts.all? { |opost| opost.url != post.url } }
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
require 'feedbook/notifiers'
|
2
|
+
require 'feedbook/helpers/time_interval_parser'
|
3
|
+
|
4
|
+
module Feedbook
|
5
|
+
class Configuration
|
6
|
+
attr_reader :interval
|
7
|
+
|
8
|
+
INTERVAL_FORMAT = /\A(\d+)(s|m|h|d)\z/
|
9
|
+
|
10
|
+
# Initializes new Configuration object with configuration for program instance
|
11
|
+
# @param opts = {} [Hash] Hash with configuration of interval and suppliers
|
12
|
+
#
|
13
|
+
# @return [NilClass] nil
|
14
|
+
def initialize(opts = {})
|
15
|
+
@interval = Helpers::TimeIntervalParser.parse(opts.fetch(:interval, ''))
|
16
|
+
@twitter = opts.fetch(:twitter, nil)
|
17
|
+
@facebook = opts.fetch(:facebook, nil)
|
18
|
+
@irc = opts.fetch(:irc, nil)
|
19
|
+
@mail = opts.fetch(:mail, nil)
|
20
|
+
end
|
21
|
+
|
22
|
+
# Load notifiers configuration
|
23
|
+
#
|
24
|
+
# @return [NilClass] nil
|
25
|
+
def load_notifiers
|
26
|
+
unless twitter.nil?
|
27
|
+
Notifiers::TwitterNotifier.instance.load_configuration(twitter)
|
28
|
+
end
|
29
|
+
|
30
|
+
unless facebook.nil?
|
31
|
+
Notifiers::FacebookNotifier.instance.load_configuration(facebook)
|
32
|
+
end
|
33
|
+
|
34
|
+
unless irc.nil?
|
35
|
+
Notifiers::IRCNotifier.instance.load_configuration(irc)
|
36
|
+
end
|
37
|
+
|
38
|
+
unless mail.nil?
|
39
|
+
Notifiers::MailNotifier.instance.load_configuration(mail)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
private
|
44
|
+
attr_reader :twitter, :facebook, :irc, :mail
|
45
|
+
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,10 @@
|
|
1
|
+
require 'feedbook/errors/invalid_feed_url_error'
|
2
|
+
require 'feedbook/errors/invalid_interval_format_error'
|
3
|
+
require 'feedbook/errors/invalid_variables_format_error'
|
4
|
+
require 'feedbook/errors/no_configuration_file_error'
|
5
|
+
require 'feedbook/errors/parse_feed_error'
|
6
|
+
require 'feedbook/errors/no_configuration_file_error'
|
7
|
+
require 'feedbook/errors/template_syntax_error'
|
8
|
+
require 'feedbook/errors/unsupported_notifier_error'
|
9
|
+
require 'feedbook/errors/notifier_configuration_error'
|
10
|
+
require 'feedbook/errors/notifier_notify_error'
|