pick-pocket 0.0.3
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 +7 -0
- data/.gitignore +11 -0
- data/.rspec +2 -0
- data/.ruby-gemset +1 -0
- data/.ruby-version +1 -0
- data/.travis.yml +10 -0
- data/CODE_OF_CONDUCT.md +49 -0
- data/Gemfile +8 -0
- data/LICENSE.txt +21 -0
- data/README.md +47 -0
- data/Rakefile +6 -0
- data/bin/console +14 -0
- data/bin/pickpocket +36 -0
- data/bin/setup +8 -0
- data/lib/pickpocket/articles/api.rb +54 -0
- data/lib/pickpocket/articles/library.rb +58 -0
- data/lib/pickpocket/authentication/oauth.rb +43 -0
- data/lib/pickpocket/authentication/token_handler.rb +45 -0
- data/lib/pickpocket/configuration.rb +48 -0
- data/lib/pickpocket/logger.rb +20 -0
- data/lib/pickpocket/version.rb +3 -0
- data/lib/pickpocket.rb +12 -0
- data/pickpocket.gemspec +31 -0
- metadata +198 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA1:
|
|
3
|
+
metadata.gz: 1fa9a86328a7bbf01972683f1836a1441fee1028
|
|
4
|
+
data.tar.gz: 69524557c5b3d16aa0141e8adc1cf090b3ad945a
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: f8319e12ea91fa8e4714dd7be5a8347fe035ac3a0a19d214521f5baba696daafdce08040fee23bd66e0ba0ae5e920ea05bceb0786cca22bd019052933fe372cc
|
|
7
|
+
data.tar.gz: 5d59ae9cbe11bf3fc9239a5001931172a77eb5aaf9688a1b369fda34d6f57a12ed9d0883672aabad6fc180875c20a907d29671c110a2590243a15c507a806e26
|
data/.gitignore
ADDED
data/.rspec
ADDED
data/.ruby-gemset
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
pickpocket
|
data/.ruby-version
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
2.3.1
|
data/.travis.yml
ADDED
data/CODE_OF_CONDUCT.md
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
# Contributor Code of Conduct
|
|
2
|
+
|
|
3
|
+
As contributors and maintainers of this project, and in the interest of
|
|
4
|
+
fostering an open and welcoming community, we pledge to respect all people who
|
|
5
|
+
contribute through reporting issues, posting feature requests, updating
|
|
6
|
+
documentation, submitting pull requests or patches, and other activities.
|
|
7
|
+
|
|
8
|
+
We are committed to making participation in this project a harassment-free
|
|
9
|
+
experience for everyone, regardless of level of experience, gender, gender
|
|
10
|
+
identity and expression, sexual orientation, disability, personal appearance,
|
|
11
|
+
body size, race, ethnicity, age, religion, or nationality.
|
|
12
|
+
|
|
13
|
+
Examples of unacceptable behavior by participants include:
|
|
14
|
+
|
|
15
|
+
* The use of sexualized language or imagery
|
|
16
|
+
* Personal attacks
|
|
17
|
+
* Trolling or insulting/derogatory comments
|
|
18
|
+
* Public or private harassment
|
|
19
|
+
* Publishing other's private information, such as physical or electronic
|
|
20
|
+
addresses, without explicit permission
|
|
21
|
+
* Other unethical or unprofessional conduct
|
|
22
|
+
|
|
23
|
+
Project maintainers have the right and responsibility to remove, edit, or
|
|
24
|
+
reject comments, commits, code, wiki edits, issues, and other contributions
|
|
25
|
+
that are not aligned to this Code of Conduct, or to ban temporarily or
|
|
26
|
+
permanently any contributor for other behaviors that they deem inappropriate,
|
|
27
|
+
threatening, offensive, or harmful.
|
|
28
|
+
|
|
29
|
+
By adopting this Code of Conduct, project maintainers commit themselves to
|
|
30
|
+
fairly and consistently applying these principles to every aspect of managing
|
|
31
|
+
this project. Project maintainers who do not follow or enforce the Code of
|
|
32
|
+
Conduct may be permanently removed from the project team.
|
|
33
|
+
|
|
34
|
+
This code of conduct applies both within project spaces and in public spaces
|
|
35
|
+
when an individual is representing the project or its community.
|
|
36
|
+
|
|
37
|
+
Instances of abusive, harassing, or otherwise unacceptable behavior may be
|
|
38
|
+
reported by contacting a project maintainer at tiagopadrela@gmail.com. All
|
|
39
|
+
complaints will be reviewed and investigated and will result in a response that
|
|
40
|
+
is deemed necessary and appropriate to the circumstances. Maintainers are
|
|
41
|
+
obligated to maintain confidentiality with regard to the reporter of an
|
|
42
|
+
incident.
|
|
43
|
+
|
|
44
|
+
This Code of Conduct is adapted from the [Contributor Covenant][homepage],
|
|
45
|
+
version 1.3.0, available at
|
|
46
|
+
[http://contributor-covenant.org/version/1/3/0/][version]
|
|
47
|
+
|
|
48
|
+
[homepage]: http://contributor-covenant.org
|
|
49
|
+
[version]: http://contributor-covenant.org/version/1/3/0/
|
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
The MIT License (MIT)
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2016 Tiago Amaro
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
|
13
|
+
all copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
21
|
+
THE SOFTWARE.
|
data/README.md
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
# Pickpocket
|
|
2
|
+
|
|
3
|
+
[](https://travis-ci.org/tiagoamaro/pickpocket)
|
|
4
|
+
[](https://codeclimate.com/github/tiagoamaro/pickpocket)
|
|
5
|
+
[](https://codeclimate.com/github/tiagoamaro/pickpocket/coverage)
|
|
6
|
+
|
|
7
|
+
Pickpocket is a command line tool which will help you with your [Pocket](http://getpocket.com/) library. It selects a random article for you to read, opening your browser and marking it is deleted.
|
|
8
|
+
|
|
9
|
+
## Installation
|
|
10
|
+
|
|
11
|
+
Pickpocket is packaged as a Ruby gem.
|
|
12
|
+
|
|
13
|
+
Install it by running `gem install pick-pocket`
|
|
14
|
+
|
|
15
|
+
## Usage
|
|
16
|
+
|
|
17
|
+
### Authentication
|
|
18
|
+
|
|
19
|
+
To use Pickpocket, you first need to go through Pocket's OAuth authentication process.
|
|
20
|
+
|
|
21
|
+
1. Execute the `pickpocket oauth` command
|
|
22
|
+
1. This will open your web browser, asking you to approve Pickpocket's OAuth token
|
|
23
|
+
2. Execute the `pickpocket authorize` command
|
|
24
|
+
1. This will authorize your OAuth token against Pocket, creating an authorization token
|
|
25
|
+
|
|
26
|
+
### Usage
|
|
27
|
+
|
|
28
|
+
- `pickpocket pick`
|
|
29
|
+
- Selects a random article from your list, and open your browser with its resolved URL
|
|
30
|
+
- `pickpocket renew`
|
|
31
|
+
- This will synchronize your local library with your remote. Keep in mind: any article marked as read locally **WILL DELETED** from your remote library
|
|
32
|
+
|
|
33
|
+
## Don't Trust Me?
|
|
34
|
+
|
|
35
|
+
Pickpocket ships with its own consumer key, which will ask for access to modify/retrieve your articles.
|
|
36
|
+
|
|
37
|
+
If you don't like this idea, you can use your own consumer key, setting up the `POCKET_CONSUMER_KEY` environment variable before calling it.
|
|
38
|
+
|
|
39
|
+
Example:
|
|
40
|
+
|
|
41
|
+
`POCKET_CONSUMER_KEY="my-consumer-key" pickpocket oauth`
|
|
42
|
+
|
|
43
|
+
> To know more about consumer keys and how Pocket deals with third party applications, read more on [Pocket's Authentication API documentation](https://getpocket.com/developer/docs/authentication).
|
|
44
|
+
|
|
45
|
+
## License
|
|
46
|
+
|
|
47
|
+
MIT
|
data/Rakefile
ADDED
data/bin/console
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
|
|
3
|
+
require "bundler/setup"
|
|
4
|
+
require "pickpocket"
|
|
5
|
+
|
|
6
|
+
# You can add fixtures and/or initialization code here to make experimenting
|
|
7
|
+
# with your gem easier. You can also use a different console, if you like.
|
|
8
|
+
|
|
9
|
+
# (If you use this, don't forget to add pry to your Gemfile!)
|
|
10
|
+
# require "pry"
|
|
11
|
+
# Pry.start
|
|
12
|
+
|
|
13
|
+
require "irb"
|
|
14
|
+
IRB.start
|
data/bin/pickpocket
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
|
|
3
|
+
require 'bundler/setup'
|
|
4
|
+
require 'pickpocket'
|
|
5
|
+
|
|
6
|
+
require 'thor'
|
|
7
|
+
|
|
8
|
+
class PickpocketCLI < Thor
|
|
9
|
+
package_name 'Pickpocket'
|
|
10
|
+
|
|
11
|
+
desc 'oauth', '1st authorization step: ask Pocket to allow Pickpocket app'
|
|
12
|
+
def oauth
|
|
13
|
+
oauth = Pickpocket::Authentication::Oauth.new
|
|
14
|
+
oauth.request_authorization
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
desc 'authorize', '2nd authorization step: allow Pickpocket read/write access to your library'
|
|
18
|
+
def authorize
|
|
19
|
+
oauth = Pickpocket::Authentication::Oauth.new
|
|
20
|
+
oauth.authorize
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
desc 'pick', 'Picks a random article from your library (marking it as read)'
|
|
24
|
+
def pick
|
|
25
|
+
library = Pickpocket::Articles::Library.new
|
|
26
|
+
library.pick
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
desc 'renew', 'Syncs your local library with your Pocket. It will delete read articles and download new articles from your library'
|
|
30
|
+
def renew
|
|
31
|
+
library = Pickpocket::Articles::Library.new
|
|
32
|
+
library.renew
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
PickpocketCLI.start(ARGV)
|
data/bin/setup
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
require 'json'
|
|
2
|
+
|
|
3
|
+
module Pickpocket
|
|
4
|
+
module Articles
|
|
5
|
+
class API
|
|
6
|
+
ACTION_DELETE = 'delete'
|
|
7
|
+
STATE_UNREAD = 'unread'
|
|
8
|
+
|
|
9
|
+
attr_reader :token_handler
|
|
10
|
+
|
|
11
|
+
def initialize
|
|
12
|
+
@token_handler = Authentication::TokenHandler.new
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def retrieve
|
|
16
|
+
uri = URI(Pickpocket.config.pocket_retrieve_url)
|
|
17
|
+
response = Net::HTTP.post_form(uri, {
|
|
18
|
+
consumer_key: Pickpocket.config.consumer_key,
|
|
19
|
+
access_token: access_token,
|
|
20
|
+
state: STATE_UNREAD
|
|
21
|
+
})
|
|
22
|
+
|
|
23
|
+
# TODO: error handling (unauthorized, etc)
|
|
24
|
+
|
|
25
|
+
JSON.parse(response.body)
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def delete(article_ids = [])
|
|
29
|
+
return if article_ids.empty?
|
|
30
|
+
|
|
31
|
+
uri = URI(Pickpocket.config.pocket_send_url)
|
|
32
|
+
json_action = article_ids.each_with_object([]) do |article_id, array|
|
|
33
|
+
array << { action: ACTION_DELETE, item_id: article_id }
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
response = Net::HTTP.post_form(uri, {
|
|
37
|
+
consumer_key: Pickpocket.config.consumer_key,
|
|
38
|
+
access_token: access_token,
|
|
39
|
+
actions: JSON.dump(json_action)
|
|
40
|
+
})
|
|
41
|
+
|
|
42
|
+
# TODO: error handling (unauthorized, etc)
|
|
43
|
+
|
|
44
|
+
JSON.parse(response.body)
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
private
|
|
48
|
+
|
|
49
|
+
def access_token
|
|
50
|
+
token_handler.read_auth
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
end
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
require 'fileutils'
|
|
2
|
+
require 'yaml/store'
|
|
3
|
+
|
|
4
|
+
module Pickpocket
|
|
5
|
+
module Articles
|
|
6
|
+
class Library
|
|
7
|
+
attr_accessor :logger
|
|
8
|
+
attr_reader :store, :api
|
|
9
|
+
|
|
10
|
+
private def yaml_store
|
|
11
|
+
FileUtils.mkdir_p(File.dirname(Pickpocket.config.library_file))
|
|
12
|
+
YAML::Store.new(Pickpocket.config.library_file)
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def initialize
|
|
16
|
+
@api = API.new
|
|
17
|
+
@logger = Pickpocket::Logger
|
|
18
|
+
@store = yaml_store
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def guarantee_inventory
|
|
22
|
+
store.transaction do
|
|
23
|
+
store[:read] = {} if store[:read].nil?
|
|
24
|
+
store[:unread] = {} if store[:unread].nil?
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
# Select an unread article, put it to the read collection and return this article
|
|
29
|
+
def pick
|
|
30
|
+
guarantee_inventory
|
|
31
|
+
store.transaction do
|
|
32
|
+
unread = store[:unread]
|
|
33
|
+
random_key = unread.keys.sample
|
|
34
|
+
|
|
35
|
+
if (random_article = unread.delete(random_key))
|
|
36
|
+
store[:read].update({ random_key => random_article })
|
|
37
|
+
Launchy.open(random_article['resolved_url'])
|
|
38
|
+
else
|
|
39
|
+
logger.info 'You have read all articles!'
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
# Replace unread store with content from pocket
|
|
45
|
+
def renew
|
|
46
|
+
guarantee_inventory
|
|
47
|
+
store.transaction do
|
|
48
|
+
new_unread = api.retrieve['list']
|
|
49
|
+
already_read = store[:read]
|
|
50
|
+
|
|
51
|
+
api.delete(already_read.keys)
|
|
52
|
+
store[:unread] = new_unread
|
|
53
|
+
store[:read] = {}
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
end
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
require 'cgi'
|
|
2
|
+
require 'net/http'
|
|
3
|
+
require 'uri'
|
|
4
|
+
|
|
5
|
+
module Pickpocket
|
|
6
|
+
module Authentication
|
|
7
|
+
class Oauth
|
|
8
|
+
attr_reader :token_handler
|
|
9
|
+
|
|
10
|
+
def initialize
|
|
11
|
+
@token_handler = TokenHandler.new
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def request_authorization
|
|
15
|
+
uri = URI(Pickpocket.config.pocket_oauth_request_url)
|
|
16
|
+
response = Net::HTTP.post_form(uri, {
|
|
17
|
+
consumer_key: Pickpocket.config.consumer_key,
|
|
18
|
+
redirect_uri: Pickpocket.config.pocket_homepage
|
|
19
|
+
})
|
|
20
|
+
|
|
21
|
+
response_token = CGI::parse(response.body)['code'][0]
|
|
22
|
+
auth_url = URI(Pickpocket.config.pocket_user_authorize_url)
|
|
23
|
+
auth_url.query = "request_token=#{response_token}&redirect_uri=#{Pickpocket.config.pocket_homepage}"
|
|
24
|
+
|
|
25
|
+
Launchy.open(auth_url.to_s)
|
|
26
|
+
token_handler.save_oauth(response_token)
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def authorize
|
|
30
|
+
response_token = token_handler.read_oauth
|
|
31
|
+
uri = URI(Pickpocket.config.pocket_oauth_authorize_url)
|
|
32
|
+
|
|
33
|
+
response = Net::HTTP.post_form(uri, {
|
|
34
|
+
consumer_key: Pickpocket.config.consumer_key,
|
|
35
|
+
code: response_token
|
|
36
|
+
})
|
|
37
|
+
|
|
38
|
+
response_token = CGI::parse(response.body)['access_token'][0]
|
|
39
|
+
token_handler.save_auth(response_token)
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
module Pickpocket
|
|
2
|
+
module Authentication
|
|
3
|
+
class TokenHandler
|
|
4
|
+
attr_accessor :logger
|
|
5
|
+
|
|
6
|
+
def initialize
|
|
7
|
+
@logger = Pickpocket::Logger
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def save_oauth(token)
|
|
11
|
+
save_token(token: token, path: Pickpocket.config.oauth_token_file)
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def save_auth(token)
|
|
15
|
+
save_token(token: token, path: Pickpocket.config.authorization_token_file)
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def read_oauth
|
|
19
|
+
read_token(path: Pickpocket.config.oauth_token_file, error_message: 'OAuth Token file does not exist. Make sure you request authorization before proceeding.')
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def read_auth
|
|
23
|
+
read_token(path: Pickpocket.config.authorization_token_file, error_message: 'Authorization Token file does not exist. Make sure you request authorization before proceeding.')
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
private
|
|
27
|
+
|
|
28
|
+
def save_token(token:, path:)
|
|
29
|
+
FileUtils.mkdir_p(Pickpocket.config.home_folder)
|
|
30
|
+
|
|
31
|
+
file = File.new(path, 'w')
|
|
32
|
+
file.write(token)
|
|
33
|
+
file.close
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def read_token(path:, error_message:)
|
|
37
|
+
file = File.new(path, 'r')
|
|
38
|
+
file.read
|
|
39
|
+
rescue Errno::ENOENT => _
|
|
40
|
+
logger.warn(error_message)
|
|
41
|
+
:no_token
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
end
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
module Pickpocket
|
|
2
|
+
class Configuration
|
|
3
|
+
attr_accessor :home_folder,
|
|
4
|
+
:authorization_token_file,
|
|
5
|
+
:oauth_token_file,
|
|
6
|
+
:library_file,
|
|
7
|
+
:consumer_key,
|
|
8
|
+
:pocket_homepage,
|
|
9
|
+
:pocket_oauth_authorize_url,
|
|
10
|
+
:pocket_oauth_request_url,
|
|
11
|
+
:pocket_retrieve_url,
|
|
12
|
+
:pocket_send_url,
|
|
13
|
+
:pocket_user_authorize_url
|
|
14
|
+
|
|
15
|
+
def initialize
|
|
16
|
+
# Files
|
|
17
|
+
@home_folder = File.join(Dir.home, '.pickpocket')
|
|
18
|
+
@authorization_token_file = File.join(@home_folder, 'authorization_token')
|
|
19
|
+
@oauth_token_file = File.join(@home_folder, 'oauth_token')
|
|
20
|
+
@library_file = File.join(@home_folder, 'library_file')
|
|
21
|
+
|
|
22
|
+
# Pocket
|
|
23
|
+
@consumer_key = ENV.fetch('POCKET_CONSUMER_KEY', '58132-f824d5fbf935681e22e86a3c')
|
|
24
|
+
@pocket_homepage = 'https://getpocket.com'
|
|
25
|
+
@pocket_oauth_authorize_url = 'https://getpocket.com/v3/oauth/authorize'
|
|
26
|
+
@pocket_oauth_request_url = 'https://getpocket.com/v3/oauth/request'
|
|
27
|
+
@pocket_retrieve_url = 'https://getpocket.com/v3/get'
|
|
28
|
+
@pocket_send_url = 'https://getpocket.com/v3/send'
|
|
29
|
+
@pocket_user_authorize_url = 'https://getpocket.com/auth/authorize'
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
class << self
|
|
34
|
+
attr_writer :configuration
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def self.config
|
|
38
|
+
@configuration ||= Configuration.new
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def self.reset
|
|
42
|
+
@configuration = Configuration.new
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def self.configure
|
|
46
|
+
yield(config)
|
|
47
|
+
end
|
|
48
|
+
end
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
require 'logger'
|
|
2
|
+
require 'forwardable'
|
|
3
|
+
|
|
4
|
+
module Pickpocket
|
|
5
|
+
class Logger
|
|
6
|
+
extend SingleForwardable
|
|
7
|
+
|
|
8
|
+
@logger = ::Logger.new(STDOUT)
|
|
9
|
+
@logger.level = ::Logger::INFO
|
|
10
|
+
@logger.formatter = proc do |_severity, _datetime, _progname, msg|
|
|
11
|
+
%Q{[Pickpocket] #{msg}\n}
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def_delegators :@logger, :debug, :error, :info, :warn
|
|
15
|
+
|
|
16
|
+
def self.logger=(logger)
|
|
17
|
+
@logger = logger
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
data/lib/pickpocket.rb
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
require 'launchy'
|
|
2
|
+
require 'pickpocket/version'
|
|
3
|
+
|
|
4
|
+
require 'pickpocket/articles/api'
|
|
5
|
+
require 'pickpocket/articles/library'
|
|
6
|
+
require 'pickpocket/authentication/oauth'
|
|
7
|
+
require 'pickpocket/authentication/token_handler'
|
|
8
|
+
require 'pickpocket/configuration'
|
|
9
|
+
require 'pickpocket/logger'
|
|
10
|
+
|
|
11
|
+
module Pickpocket
|
|
12
|
+
end
|
data/pickpocket.gemspec
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# coding: utf-8
|
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
|
4
|
+
require 'pickpocket/version'
|
|
5
|
+
|
|
6
|
+
Gem::Specification.new do |spec|
|
|
7
|
+
spec.name = 'pick-pocket'
|
|
8
|
+
spec.version = Pickpocket::VERSION
|
|
9
|
+
spec.authors = ['Tiago Amaro']
|
|
10
|
+
spec.email = ['tiagopadrela@gmail.com']
|
|
11
|
+
|
|
12
|
+
spec.summary = %q{Pickpocket: selects a random article from your Pocket (former Read It Later)}
|
|
13
|
+
spec.description = %q{Pickpocket: selects a random article from your Pocket (former Read It Later)}
|
|
14
|
+
spec.homepage = 'https://github.com/tiagoamaro/pickpocket'
|
|
15
|
+
spec.license = 'MIT'
|
|
16
|
+
|
|
17
|
+
spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
|
18
|
+
spec.bindir = 'bin'
|
|
19
|
+
spec.executables = ['pickpocket']
|
|
20
|
+
spec.require_paths = ['lib']
|
|
21
|
+
|
|
22
|
+
spec.add_runtime_dependency 'launchy', '~> 2.4', '>= 2.4.3'
|
|
23
|
+
spec.add_runtime_dependency 'thor', '~> 0.19.1'
|
|
24
|
+
|
|
25
|
+
spec.add_development_dependency 'bundler', '~> 1.12'
|
|
26
|
+
spec.add_development_dependency 'rake', '~> 10.0'
|
|
27
|
+
spec.add_development_dependency 'rspec', '~> 3.0'
|
|
28
|
+
spec.add_development_dependency 'vcr', '~> 3.0', '>= 3.0.3'
|
|
29
|
+
spec.add_development_dependency 'codeclimate-test-reporter', "~> 0.6.0"
|
|
30
|
+
spec.add_development_dependency 'webmock', '~> 2.1', '>= 2.1.0'
|
|
31
|
+
end
|
metadata
ADDED
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: pick-pocket
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 0.0.3
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- Tiago Amaro
|
|
8
|
+
autorequire:
|
|
9
|
+
bindir: bin
|
|
10
|
+
cert_chain: []
|
|
11
|
+
date: 2016-10-02 00:00:00.000000000 Z
|
|
12
|
+
dependencies:
|
|
13
|
+
- !ruby/object:Gem::Dependency
|
|
14
|
+
name: launchy
|
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
|
16
|
+
requirements:
|
|
17
|
+
- - "~>"
|
|
18
|
+
- !ruby/object:Gem::Version
|
|
19
|
+
version: '2.4'
|
|
20
|
+
- - ">="
|
|
21
|
+
- !ruby/object:Gem::Version
|
|
22
|
+
version: 2.4.3
|
|
23
|
+
type: :runtime
|
|
24
|
+
prerelease: false
|
|
25
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
26
|
+
requirements:
|
|
27
|
+
- - "~>"
|
|
28
|
+
- !ruby/object:Gem::Version
|
|
29
|
+
version: '2.4'
|
|
30
|
+
- - ">="
|
|
31
|
+
- !ruby/object:Gem::Version
|
|
32
|
+
version: 2.4.3
|
|
33
|
+
- !ruby/object:Gem::Dependency
|
|
34
|
+
name: thor
|
|
35
|
+
requirement: !ruby/object:Gem::Requirement
|
|
36
|
+
requirements:
|
|
37
|
+
- - "~>"
|
|
38
|
+
- !ruby/object:Gem::Version
|
|
39
|
+
version: 0.19.1
|
|
40
|
+
type: :runtime
|
|
41
|
+
prerelease: false
|
|
42
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
43
|
+
requirements:
|
|
44
|
+
- - "~>"
|
|
45
|
+
- !ruby/object:Gem::Version
|
|
46
|
+
version: 0.19.1
|
|
47
|
+
- !ruby/object:Gem::Dependency
|
|
48
|
+
name: bundler
|
|
49
|
+
requirement: !ruby/object:Gem::Requirement
|
|
50
|
+
requirements:
|
|
51
|
+
- - "~>"
|
|
52
|
+
- !ruby/object:Gem::Version
|
|
53
|
+
version: '1.12'
|
|
54
|
+
type: :development
|
|
55
|
+
prerelease: false
|
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
57
|
+
requirements:
|
|
58
|
+
- - "~>"
|
|
59
|
+
- !ruby/object:Gem::Version
|
|
60
|
+
version: '1.12'
|
|
61
|
+
- !ruby/object:Gem::Dependency
|
|
62
|
+
name: rake
|
|
63
|
+
requirement: !ruby/object:Gem::Requirement
|
|
64
|
+
requirements:
|
|
65
|
+
- - "~>"
|
|
66
|
+
- !ruby/object:Gem::Version
|
|
67
|
+
version: '10.0'
|
|
68
|
+
type: :development
|
|
69
|
+
prerelease: false
|
|
70
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
71
|
+
requirements:
|
|
72
|
+
- - "~>"
|
|
73
|
+
- !ruby/object:Gem::Version
|
|
74
|
+
version: '10.0'
|
|
75
|
+
- !ruby/object:Gem::Dependency
|
|
76
|
+
name: rspec
|
|
77
|
+
requirement: !ruby/object:Gem::Requirement
|
|
78
|
+
requirements:
|
|
79
|
+
- - "~>"
|
|
80
|
+
- !ruby/object:Gem::Version
|
|
81
|
+
version: '3.0'
|
|
82
|
+
type: :development
|
|
83
|
+
prerelease: false
|
|
84
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
85
|
+
requirements:
|
|
86
|
+
- - "~>"
|
|
87
|
+
- !ruby/object:Gem::Version
|
|
88
|
+
version: '3.0'
|
|
89
|
+
- !ruby/object:Gem::Dependency
|
|
90
|
+
name: vcr
|
|
91
|
+
requirement: !ruby/object:Gem::Requirement
|
|
92
|
+
requirements:
|
|
93
|
+
- - "~>"
|
|
94
|
+
- !ruby/object:Gem::Version
|
|
95
|
+
version: '3.0'
|
|
96
|
+
- - ">="
|
|
97
|
+
- !ruby/object:Gem::Version
|
|
98
|
+
version: 3.0.3
|
|
99
|
+
type: :development
|
|
100
|
+
prerelease: false
|
|
101
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
102
|
+
requirements:
|
|
103
|
+
- - "~>"
|
|
104
|
+
- !ruby/object:Gem::Version
|
|
105
|
+
version: '3.0'
|
|
106
|
+
- - ">="
|
|
107
|
+
- !ruby/object:Gem::Version
|
|
108
|
+
version: 3.0.3
|
|
109
|
+
- !ruby/object:Gem::Dependency
|
|
110
|
+
name: codeclimate-test-reporter
|
|
111
|
+
requirement: !ruby/object:Gem::Requirement
|
|
112
|
+
requirements:
|
|
113
|
+
- - "~>"
|
|
114
|
+
- !ruby/object:Gem::Version
|
|
115
|
+
version: 0.6.0
|
|
116
|
+
type: :development
|
|
117
|
+
prerelease: false
|
|
118
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
119
|
+
requirements:
|
|
120
|
+
- - "~>"
|
|
121
|
+
- !ruby/object:Gem::Version
|
|
122
|
+
version: 0.6.0
|
|
123
|
+
- !ruby/object:Gem::Dependency
|
|
124
|
+
name: webmock
|
|
125
|
+
requirement: !ruby/object:Gem::Requirement
|
|
126
|
+
requirements:
|
|
127
|
+
- - "~>"
|
|
128
|
+
- !ruby/object:Gem::Version
|
|
129
|
+
version: '2.1'
|
|
130
|
+
- - ">="
|
|
131
|
+
- !ruby/object:Gem::Version
|
|
132
|
+
version: 2.1.0
|
|
133
|
+
type: :development
|
|
134
|
+
prerelease: false
|
|
135
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
136
|
+
requirements:
|
|
137
|
+
- - "~>"
|
|
138
|
+
- !ruby/object:Gem::Version
|
|
139
|
+
version: '2.1'
|
|
140
|
+
- - ">="
|
|
141
|
+
- !ruby/object:Gem::Version
|
|
142
|
+
version: 2.1.0
|
|
143
|
+
description: 'Pickpocket: selects a random article from your Pocket (former Read It
|
|
144
|
+
Later)'
|
|
145
|
+
email:
|
|
146
|
+
- tiagopadrela@gmail.com
|
|
147
|
+
executables:
|
|
148
|
+
- pickpocket
|
|
149
|
+
extensions: []
|
|
150
|
+
extra_rdoc_files: []
|
|
151
|
+
files:
|
|
152
|
+
- ".gitignore"
|
|
153
|
+
- ".rspec"
|
|
154
|
+
- ".ruby-gemset"
|
|
155
|
+
- ".ruby-version"
|
|
156
|
+
- ".travis.yml"
|
|
157
|
+
- CODE_OF_CONDUCT.md
|
|
158
|
+
- Gemfile
|
|
159
|
+
- LICENSE.txt
|
|
160
|
+
- README.md
|
|
161
|
+
- Rakefile
|
|
162
|
+
- bin/console
|
|
163
|
+
- bin/pickpocket
|
|
164
|
+
- bin/setup
|
|
165
|
+
- lib/pickpocket.rb
|
|
166
|
+
- lib/pickpocket/articles/api.rb
|
|
167
|
+
- lib/pickpocket/articles/library.rb
|
|
168
|
+
- lib/pickpocket/authentication/oauth.rb
|
|
169
|
+
- lib/pickpocket/authentication/token_handler.rb
|
|
170
|
+
- lib/pickpocket/configuration.rb
|
|
171
|
+
- lib/pickpocket/logger.rb
|
|
172
|
+
- lib/pickpocket/version.rb
|
|
173
|
+
- pickpocket.gemspec
|
|
174
|
+
homepage: https://github.com/tiagoamaro/pickpocket
|
|
175
|
+
licenses:
|
|
176
|
+
- MIT
|
|
177
|
+
metadata: {}
|
|
178
|
+
post_install_message:
|
|
179
|
+
rdoc_options: []
|
|
180
|
+
require_paths:
|
|
181
|
+
- lib
|
|
182
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
183
|
+
requirements:
|
|
184
|
+
- - ">="
|
|
185
|
+
- !ruby/object:Gem::Version
|
|
186
|
+
version: '0'
|
|
187
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
188
|
+
requirements:
|
|
189
|
+
- - ">="
|
|
190
|
+
- !ruby/object:Gem::Version
|
|
191
|
+
version: '0'
|
|
192
|
+
requirements: []
|
|
193
|
+
rubyforge_project:
|
|
194
|
+
rubygems_version: 2.5.1
|
|
195
|
+
signing_key:
|
|
196
|
+
specification_version: 4
|
|
197
|
+
summary: 'Pickpocket: selects a random article from your Pocket (former Read It Later)'
|
|
198
|
+
test_files: []
|