feedbook 0.9.0
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.
- 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 [](https://travis-ci.org/pinoss/feedbook) [](https://codeclimate.com/github/pinoss/feedbook) [](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'
|