gcp_directory 0.1.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 +7 -0
- data/.gitignore +15 -0
- data/.rspec +2 -0
- data/.travis.yml +5 -0
- data/Gemfile +6 -0
- data/Gemfile.lock +119 -0
- data/LICENSE.txt +21 -0
- data/README.md +55 -0
- data/Rakefile +6 -0
- data/bin/console +11 -0
- data/bin/setup +8 -0
- data/exe/gcp_fetch_token +10 -0
- data/exe/gcp_listen +12 -0
- data/gcp_directory.gemspec +33 -0
- data/google_api_console.png +0 -0
- data/lib/gcp_directory/listener.rb +48 -0
- data/lib/gcp_directory/printer.rb +41 -0
- data/lib/gcp_directory/version.rb +3 -0
- data/lib/gcp_directory.rb +118 -0
- data/oauth_example.ru +74 -0
- metadata +191 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA1:
|
|
3
|
+
metadata.gz: a4f187d03c42f511e3f0bb076dab0468ea38b4a1
|
|
4
|
+
data.tar.gz: dee1130a879c71ae58e9b627fe1dd989cc1978a6
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: f56487af955d5b25492ec2a5371bfa4bb37fa14b32b852f32ef66d560eb3e22e89198f9552df301041c24a865325ea735c29e705b85334d670ae2b25bfab7c73
|
|
7
|
+
data.tar.gz: dd83bb1cc382b0a061478cac485213dff488ec591e487239a8b242ba9ce1eeafec1804bb1b3bf61eff8038a39ed08a55bdd4f15e787cf68e08f01520abb1b8aa
|
data/.gitignore
ADDED
data/.rspec
ADDED
data/.travis.yml
ADDED
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
PATH
|
|
2
|
+
remote: .
|
|
3
|
+
specs:
|
|
4
|
+
gcp_directory (0.1.0)
|
|
5
|
+
activesupport
|
|
6
|
+
google-api-client (~> 0.11)
|
|
7
|
+
httparty
|
|
8
|
+
listen (~> 3.0)
|
|
9
|
+
semantic_logger
|
|
10
|
+
|
|
11
|
+
GEM
|
|
12
|
+
remote: https://rubygems.org/
|
|
13
|
+
specs:
|
|
14
|
+
activesupport (5.0.3)
|
|
15
|
+
concurrent-ruby (~> 1.0, >= 1.0.2)
|
|
16
|
+
i18n (~> 0.7)
|
|
17
|
+
minitest (~> 5.1)
|
|
18
|
+
tzinfo (~> 1.1)
|
|
19
|
+
addressable (2.5.1)
|
|
20
|
+
public_suffix (~> 2.0, >= 2.0.2)
|
|
21
|
+
coderay (1.1.1)
|
|
22
|
+
concurrent-ruby (1.0.5)
|
|
23
|
+
declarative (0.0.9)
|
|
24
|
+
declarative-option (0.1.0)
|
|
25
|
+
diff-lcs (1.3)
|
|
26
|
+
faraday (0.12.1)
|
|
27
|
+
multipart-post (>= 1.2, < 3)
|
|
28
|
+
ffi (1.9.18)
|
|
29
|
+
google-api-client (0.11.2)
|
|
30
|
+
addressable (>= 2.5.1)
|
|
31
|
+
googleauth (~> 0.5)
|
|
32
|
+
httpclient (>= 2.8.1, < 3.0)
|
|
33
|
+
mime-types (>= 3.0)
|
|
34
|
+
representable (~> 3.0)
|
|
35
|
+
retriable (>= 2.0, < 4.0)
|
|
36
|
+
googleauth (0.5.1)
|
|
37
|
+
faraday (~> 0.9)
|
|
38
|
+
jwt (~> 1.4)
|
|
39
|
+
logging (~> 2.0)
|
|
40
|
+
memoist (~> 0.12)
|
|
41
|
+
multi_json (~> 1.11)
|
|
42
|
+
os (~> 0.9)
|
|
43
|
+
signet (~> 0.7)
|
|
44
|
+
httparty (0.14.0)
|
|
45
|
+
multi_xml (>= 0.5.2)
|
|
46
|
+
httpclient (2.8.3)
|
|
47
|
+
i18n (0.8.1)
|
|
48
|
+
jwt (1.5.6)
|
|
49
|
+
listen (3.1.5)
|
|
50
|
+
rb-fsevent (~> 0.9, >= 0.9.4)
|
|
51
|
+
rb-inotify (~> 0.9, >= 0.9.7)
|
|
52
|
+
ruby_dep (~> 1.2)
|
|
53
|
+
little-plugger (1.1.4)
|
|
54
|
+
logging (2.2.2)
|
|
55
|
+
little-plugger (~> 1.1)
|
|
56
|
+
multi_json (~> 1.10)
|
|
57
|
+
memoist (0.15.0)
|
|
58
|
+
method_source (0.8.2)
|
|
59
|
+
mime-types (3.1)
|
|
60
|
+
mime-types-data (~> 3.2015)
|
|
61
|
+
mime-types-data (3.2016.0521)
|
|
62
|
+
minitest (5.10.2)
|
|
63
|
+
multi_json (1.12.1)
|
|
64
|
+
multi_xml (0.6.0)
|
|
65
|
+
multipart-post (2.0.0)
|
|
66
|
+
os (0.9.6)
|
|
67
|
+
pry (0.10.4)
|
|
68
|
+
coderay (~> 1.1.0)
|
|
69
|
+
method_source (~> 0.8.1)
|
|
70
|
+
slop (~> 3.4)
|
|
71
|
+
public_suffix (2.0.5)
|
|
72
|
+
rake (10.5.0)
|
|
73
|
+
rb-fsevent (0.9.8)
|
|
74
|
+
rb-inotify (0.9.8)
|
|
75
|
+
ffi (>= 0.5.0)
|
|
76
|
+
representable (3.0.4)
|
|
77
|
+
declarative (< 0.1.0)
|
|
78
|
+
declarative-option (< 0.2.0)
|
|
79
|
+
uber (< 0.2.0)
|
|
80
|
+
retriable (3.0.2)
|
|
81
|
+
rspec (3.6.0)
|
|
82
|
+
rspec-core (~> 3.6.0)
|
|
83
|
+
rspec-expectations (~> 3.6.0)
|
|
84
|
+
rspec-mocks (~> 3.6.0)
|
|
85
|
+
rspec-core (3.6.0)
|
|
86
|
+
rspec-support (~> 3.6.0)
|
|
87
|
+
rspec-expectations (3.6.0)
|
|
88
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
|
89
|
+
rspec-support (~> 3.6.0)
|
|
90
|
+
rspec-mocks (3.6.0)
|
|
91
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
|
92
|
+
rspec-support (~> 3.6.0)
|
|
93
|
+
rspec-support (3.6.0)
|
|
94
|
+
ruby_dep (1.3.1)
|
|
95
|
+
semantic_logger (3.4.1)
|
|
96
|
+
concurrent-ruby (~> 1.0)
|
|
97
|
+
signet (0.7.3)
|
|
98
|
+
addressable (~> 2.3)
|
|
99
|
+
faraday (~> 0.9)
|
|
100
|
+
jwt (~> 1.5)
|
|
101
|
+
multi_json (~> 1.10)
|
|
102
|
+
slop (3.6.0)
|
|
103
|
+
thread_safe (0.3.6)
|
|
104
|
+
tzinfo (1.2.3)
|
|
105
|
+
thread_safe (~> 0.1)
|
|
106
|
+
uber (0.1.0)
|
|
107
|
+
|
|
108
|
+
PLATFORMS
|
|
109
|
+
ruby
|
|
110
|
+
|
|
111
|
+
DEPENDENCIES
|
|
112
|
+
bundler (~> 1.14)
|
|
113
|
+
gcp_directory!
|
|
114
|
+
pry
|
|
115
|
+
rake (~> 10.0)
|
|
116
|
+
rspec (~> 3.0)
|
|
117
|
+
|
|
118
|
+
BUNDLED WITH
|
|
119
|
+
1.14.5
|
data/LICENSE.txt
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
The MIT License (MIT)
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2017 Scott Pierce
|
|
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,55 @@
|
|
|
1
|
+
# Google Cloud Print Directory
|
|
2
|
+
|
|
3
|
+
Listen to a directory for new files and send files to Google Cloud Print.
|
|
4
|
+
|
|
5
|
+
## Usage
|
|
6
|
+
|
|
7
|
+
1. Pick a directory to watch for changes.
|
|
8
|
+
2. Create a config.yml file in the directory. Format specified below.
|
|
9
|
+
3. `gcp_listen PATH_TO_DIRECTORY`
|
|
10
|
+
|
|
11
|
+
### Setup OAUTH
|
|
12
|
+
|
|
13
|
+
1. Get secrets from from Google API Console website: https://console.developers.google.com
|
|
14
|
+
2. <img src='google_api_console.png' />
|
|
15
|
+
3. Copy client secrets file to `.secrets.json` in listening directory.
|
|
16
|
+
4. run `gcp_fetch_token PATH_TO_DIRECTORY`
|
|
17
|
+
|
|
18
|
+
If you need to listen to multiple directories startup more than one program.
|
|
19
|
+
|
|
20
|
+
### config.yml
|
|
21
|
+
```yaml
|
|
22
|
+
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
## Installation
|
|
26
|
+
|
|
27
|
+
Add this line to your application's Gemfile:
|
|
28
|
+
|
|
29
|
+
```ruby
|
|
30
|
+
gem 'gcp_directory'
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
And then execute:
|
|
34
|
+
|
|
35
|
+
$ bundle
|
|
36
|
+
|
|
37
|
+
Or install it yourself as:
|
|
38
|
+
|
|
39
|
+
$ gem install gcp_directory
|
|
40
|
+
|
|
41
|
+
## Development
|
|
42
|
+
|
|
43
|
+
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
|
44
|
+
|
|
45
|
+
To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
|
|
46
|
+
|
|
47
|
+
## Contributing
|
|
48
|
+
|
|
49
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/ddrscott/gcp_directory.
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
## License
|
|
53
|
+
|
|
54
|
+
The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
|
|
55
|
+
|
data/Rakefile
ADDED
data/bin/console
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
|
|
3
|
+
require 'bundler/setup'
|
|
4
|
+
require 'gcp_directory'
|
|
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
|
+
GcpDirectory.directory = 'tmp'
|
|
10
|
+
require 'pry'
|
|
11
|
+
Pry.start
|
data/bin/setup
ADDED
data/exe/gcp_fetch_token
ADDED
data/exe/gcp_listen
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
|
|
3
|
+
require 'bundler/setup'
|
|
4
|
+
require 'gcp_directory'
|
|
5
|
+
|
|
6
|
+
GcpDirectory.directory = ARGV[0] || raise('first argument must by listening directory')
|
|
7
|
+
|
|
8
|
+
# always update token
|
|
9
|
+
GcpDirectory.refresh_token
|
|
10
|
+
|
|
11
|
+
# list for files
|
|
12
|
+
GcpDirectory::Listener.listen
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# coding: utf-8
|
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
|
4
|
+
require 'gcp_directory/version'
|
|
5
|
+
|
|
6
|
+
Gem::Specification.new do |spec|
|
|
7
|
+
spec.name = 'gcp_directory'
|
|
8
|
+
spec.version = GcpDirectory::VERSION
|
|
9
|
+
spec.authors = ['Scott Pierce']
|
|
10
|
+
spec.email = ['ddrscott@gmail.com']
|
|
11
|
+
|
|
12
|
+
spec.summary = 'Listen for changes to a directory and send documents to Google Cloud Print'
|
|
13
|
+
spec.homepage = 'https://github.com/ddrscott/gcp_directory'
|
|
14
|
+
spec.license = 'MIT'
|
|
15
|
+
|
|
16
|
+
spec.files = `git ls-files -z`.split("\x0").reject do |f|
|
|
17
|
+
f.match(%r{^(test|spec|features)/})
|
|
18
|
+
end
|
|
19
|
+
spec.bindir = 'exe'
|
|
20
|
+
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
|
21
|
+
spec.require_paths = ['lib']
|
|
22
|
+
|
|
23
|
+
spec.add_dependency 'google-api-client', '~> 0.11'
|
|
24
|
+
spec.add_dependency 'listen', '~>3.0'
|
|
25
|
+
spec.add_dependency 'wdm', '>= 0.1.0' if Gem.win_platform?
|
|
26
|
+
spec.add_dependency 'httparty'
|
|
27
|
+
spec.add_dependency 'semantic_logger'
|
|
28
|
+
spec.add_dependency 'activesupport'
|
|
29
|
+
spec.add_development_dependency 'pry'
|
|
30
|
+
spec.add_development_dependency 'bundler', '~> 1.14'
|
|
31
|
+
spec.add_development_dependency 'rake', '~> 10.0'
|
|
32
|
+
spec.add_development_dependency 'rspec', '~> 3.0'
|
|
33
|
+
end
|
|
Binary file
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
require 'fileutils'
|
|
2
|
+
|
|
3
|
+
module GcpDirectory
|
|
4
|
+
# Watch for changes and send to API
|
|
5
|
+
class Listener
|
|
6
|
+
|
|
7
|
+
def initialize(auth=GcpDirectory.token_client)
|
|
8
|
+
@api = Printer.new(auth)
|
|
9
|
+
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def logger
|
|
13
|
+
GcpDirectory.logger
|
|
14
|
+
end
|
|
15
|
+
def self.logger
|
|
16
|
+
GcpDirectory.logger
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def print(added)
|
|
20
|
+
return if added =~ /\.(done|error)$/
|
|
21
|
+
GcpDirectory.config[:printerid] || raise(ArgumentError, '`printerid` not defined in config!')
|
|
22
|
+
options = GcpDirectory.config.merge(
|
|
23
|
+
title: added,
|
|
24
|
+
content: File.read(added)
|
|
25
|
+
)
|
|
26
|
+
logger.info "submitting file: #{added}"
|
|
27
|
+
logger.info @api.submit(**options)
|
|
28
|
+
FileUtils.mv(added, "#{added}.done")
|
|
29
|
+
rescue => error
|
|
30
|
+
logger.error "could not process #{added}", error
|
|
31
|
+
FileUtils.mv(added, "#{added}.error")
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def self.listen
|
|
35
|
+
instance = GcpDirectory::Listener.new
|
|
36
|
+
|
|
37
|
+
listener = Listen.to(GcpDirectory.directory) do |modified, added, removed|
|
|
38
|
+
logger.debug "modified absolute path: #{modified}"
|
|
39
|
+
logger.debug "added absolute path: #{added}"
|
|
40
|
+
logger.debug "removed absolute path: #{removed}"
|
|
41
|
+
added.each { |file| instance.print(file) } if added
|
|
42
|
+
end
|
|
43
|
+
listener.start # not blocking
|
|
44
|
+
$stderr.puts 'Press <CTRL-C> to stop listening'
|
|
45
|
+
sleep
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
end
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
module GcpDirectory
|
|
2
|
+
# Maps to https://developers.google.com/cloud-print/docs/appInterfaces
|
|
3
|
+
class Printer
|
|
4
|
+
include HTTParty
|
|
5
|
+
base_uri 'https://www.google.com/cloudprint'
|
|
6
|
+
|
|
7
|
+
debug_output(GcpDirectory.logger)
|
|
8
|
+
|
|
9
|
+
def initialize(auth = GcpDirectory.auth_client(GcpDirectory.token_path))
|
|
10
|
+
auth.access_token || raise(ArgumentError, "`access_token` not set in #{auth}")
|
|
11
|
+
@auth = auth
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def jobs(**options)
|
|
15
|
+
self.class.post('/jobs', with_default_options(options))
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def submit(printerid:, title:, content:, ticket: default_ticket)
|
|
19
|
+
self.class.post('/submit', with_default_options(body: {
|
|
20
|
+
printerid: printerid,
|
|
21
|
+
title: title,
|
|
22
|
+
ticket: ticket.to_json
|
|
23
|
+
}))
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def default_ticket
|
|
27
|
+
{
|
|
28
|
+
version: '1.0',
|
|
29
|
+
print: {}
|
|
30
|
+
}
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def with_default_options(**options)
|
|
34
|
+
{
|
|
35
|
+
headers: {
|
|
36
|
+
'Authorization' => "OAuth #{@auth.access_token}"
|
|
37
|
+
}
|
|
38
|
+
}.merge(options)
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
# external libs
|
|
2
|
+
require 'active_support/all'
|
|
3
|
+
require 'google/api_client/client_secrets'
|
|
4
|
+
require 'json'
|
|
5
|
+
require 'httparty'
|
|
6
|
+
require 'semantic_logger'
|
|
7
|
+
require 'yaml'
|
|
8
|
+
require 'listen'
|
|
9
|
+
|
|
10
|
+
SemanticLogger.default_level = :trace
|
|
11
|
+
SemanticLogger.add_appender(file_name: 'listener.log', formatter: :color)
|
|
12
|
+
|
|
13
|
+
# Listen for changes in a directory and send to Google Cloud Print
|
|
14
|
+
module GcpDirectory
|
|
15
|
+
|
|
16
|
+
CALLBACK_URL = 'http://localhost:8000/callback'.freeze
|
|
17
|
+
|
|
18
|
+
def self.logger
|
|
19
|
+
SemanticLogger['Listener']
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def self.directory=(dir)
|
|
23
|
+
@directory = dir
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def self.directory
|
|
27
|
+
@directory ||= File.expand_path('.')
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def self.config
|
|
31
|
+
JSON.parse(File.read(File.join(directory, 'printer.json'))).symbolize_keys
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def self.secrets_path
|
|
35
|
+
File.join(directory, '.secrets.json')
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def self.token_path
|
|
39
|
+
File.join(directory, '.token.json')
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def self.token_client
|
|
43
|
+
auth_client(token_path)
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def self.auth_client(path)
|
|
47
|
+
# check secrets exist
|
|
48
|
+
File.file?(path) || raise("#{path} does not exist! Please download from https://console.developers.google.com/")
|
|
49
|
+
|
|
50
|
+
# load them
|
|
51
|
+
client_secrets = Google::APIClient::ClientSecrets.load(path)
|
|
52
|
+
|
|
53
|
+
auth = client_secrets.to_authorization
|
|
54
|
+
auth.update!(
|
|
55
|
+
scope: 'https://www.googleapis.com/auth/cloudprint',
|
|
56
|
+
redirect_uri: CALLBACK_URL,
|
|
57
|
+
access_type: 'offline',
|
|
58
|
+
response_type: 'code'
|
|
59
|
+
)
|
|
60
|
+
auth
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
def self.refresh_token
|
|
64
|
+
auth = auth_client(token_path)
|
|
65
|
+
auth.refresh!
|
|
66
|
+
write_token(auth)
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
def self.fetch_token
|
|
70
|
+
oauth_url = auth_client(secrets_path).authorization_uri.to_s
|
|
71
|
+
|
|
72
|
+
$stderr.puts "Opening the following URL in your default browser. If it doesn't open, please open the link on your own:\n#{oauth_url}"
|
|
73
|
+
|
|
74
|
+
if Gem.win_platform?
|
|
75
|
+
puts `start "" "#{oauth_url}"`
|
|
76
|
+
elsif RUBY_PLATFORM =~ /darwin/
|
|
77
|
+
puts `open "#{oauth_url}"`
|
|
78
|
+
else # linux
|
|
79
|
+
puts `xdg-open "#{oauth_url}"`
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
start_callback_thread.join
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
def self.start_callback_thread
|
|
86
|
+
server = WEBrick::HTTPServer.new Port: 8000, DocumentRoot: File.expand_path('.')
|
|
87
|
+
|
|
88
|
+
server.mount_proc '/callback' do |req, res|
|
|
89
|
+
auth = auth_client(secrets_path)
|
|
90
|
+
auth.code = req.query['code']
|
|
91
|
+
auth.fetch_access_token!
|
|
92
|
+
|
|
93
|
+
$stderr.puts "writing token to #{token_path}"
|
|
94
|
+
write_token(auth)
|
|
95
|
+
res.body = "Credentials written to #{token_path}. You may close this browser tab."
|
|
96
|
+
server.stop
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
$stderr.puts 'Server started in background to receive OAuth callback...'
|
|
100
|
+
Thread.new do
|
|
101
|
+
server.start
|
|
102
|
+
end
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
def self.write_token(auth)
|
|
106
|
+
File.open(token_path, 'w') { |f| f << %Q{{"installed":#{auth.to_json}}}}
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
def self.submit_job(*args)
|
|
110
|
+
|
|
111
|
+
https://www.google.com/cloudprint/submit
|
|
112
|
+
end
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
# internal libs
|
|
116
|
+
require 'gcp_directory/version'
|
|
117
|
+
require 'gcp_directory/printer'
|
|
118
|
+
require 'gcp_directory/listener'
|
data/oauth_example.ru
ADDED
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
# Example OAuth2 from https://developers.google.com/api-client-library/ruby/guide/aaa_oauth
|
|
2
|
+
require 'google/apis/calendar_v3'
|
|
3
|
+
require 'google/api_client/client_secrets'
|
|
4
|
+
require 'sinatra'
|
|
5
|
+
require 'logger'
|
|
6
|
+
|
|
7
|
+
enable :sessions
|
|
8
|
+
|
|
9
|
+
def logger; settings.logger end
|
|
10
|
+
|
|
11
|
+
def calendar; settings.calendar; end
|
|
12
|
+
|
|
13
|
+
def user_credentials
|
|
14
|
+
# Build a per-request oauth credential based on token stored in session
|
|
15
|
+
# which allows us to use a shared API client.
|
|
16
|
+
@authorization ||= (
|
|
17
|
+
auth = settings.authorization.dup
|
|
18
|
+
auth.redirect_uri = to('/oauth2callback')
|
|
19
|
+
auth.update_token!(session)
|
|
20
|
+
auth
|
|
21
|
+
)
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
configure do
|
|
25
|
+
log_file = File.open('calendar.log', 'a+')
|
|
26
|
+
log_file.sync = true
|
|
27
|
+
logger = Logger.new(log_file)
|
|
28
|
+
logger.level = Logger::DEBUG
|
|
29
|
+
|
|
30
|
+
Google::Apis::ClientOptions.default.application_name = 'Ruby Calendar sample'
|
|
31
|
+
Google::Apis::ClientOptions.default.application_version = '1.0.0'
|
|
32
|
+
calendar_api = Google::Apis::CalendarV3::CalendarService.new
|
|
33
|
+
|
|
34
|
+
client_secrets = Google::APIClient::ClientSecrets.load
|
|
35
|
+
authorization = client_secrets.to_authorization
|
|
36
|
+
authorization.scope = 'https://www.googleapis.com/auth/calendar'
|
|
37
|
+
|
|
38
|
+
set :authorization, authorization
|
|
39
|
+
set :logger, logger
|
|
40
|
+
set :calendar, calendar_api
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
before do
|
|
44
|
+
# Ensure user has authorized the app
|
|
45
|
+
unless user_credentials.access_token || request.path_info =~ /^\/oauth2/
|
|
46
|
+
redirect to('/oauth2authorize')
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
after do
|
|
51
|
+
# Serialize the access/refresh token to the session and credential store.
|
|
52
|
+
session[:access_token] = user_credentials.access_token
|
|
53
|
+
session[:refresh_token] = user_credentials.refresh_token
|
|
54
|
+
session[:expires_in] = user_credentials.expires_in
|
|
55
|
+
session[:issued_at] = user_credentials.issued_at
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
get '/oauth2authorize' do
|
|
59
|
+
# Request authorization
|
|
60
|
+
redirect user_credentials.authorization_uri.to_s, 303
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
get '/oauth2callback' do
|
|
64
|
+
# Exchange token
|
|
65
|
+
user_credentials.code = params[:code] if params[:code]
|
|
66
|
+
user_credentials.fetch_access_token!
|
|
67
|
+
redirect to('/')
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
get '/' do
|
|
71
|
+
# Fetch list of events on the user's default calandar
|
|
72
|
+
events = calendar.list_events('primary', options: { authorization: user_credentials })
|
|
73
|
+
[200, {'Content-Type' => 'application/json'}, events.to_h.to_json]
|
|
74
|
+
end
|
metadata
ADDED
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: gcp_directory
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 0.1.0
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- Scott Pierce
|
|
8
|
+
autorequire:
|
|
9
|
+
bindir: exe
|
|
10
|
+
cert_chain: []
|
|
11
|
+
date: 2017-05-24 00:00:00.000000000 Z
|
|
12
|
+
dependencies:
|
|
13
|
+
- !ruby/object:Gem::Dependency
|
|
14
|
+
name: google-api-client
|
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
|
16
|
+
requirements:
|
|
17
|
+
- - "~>"
|
|
18
|
+
- !ruby/object:Gem::Version
|
|
19
|
+
version: '0.11'
|
|
20
|
+
type: :runtime
|
|
21
|
+
prerelease: false
|
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
23
|
+
requirements:
|
|
24
|
+
- - "~>"
|
|
25
|
+
- !ruby/object:Gem::Version
|
|
26
|
+
version: '0.11'
|
|
27
|
+
- !ruby/object:Gem::Dependency
|
|
28
|
+
name: listen
|
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
|
30
|
+
requirements:
|
|
31
|
+
- - "~>"
|
|
32
|
+
- !ruby/object:Gem::Version
|
|
33
|
+
version: '3.0'
|
|
34
|
+
type: :runtime
|
|
35
|
+
prerelease: false
|
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
37
|
+
requirements:
|
|
38
|
+
- - "~>"
|
|
39
|
+
- !ruby/object:Gem::Version
|
|
40
|
+
version: '3.0'
|
|
41
|
+
- !ruby/object:Gem::Dependency
|
|
42
|
+
name: httparty
|
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
|
44
|
+
requirements:
|
|
45
|
+
- - ">="
|
|
46
|
+
- !ruby/object:Gem::Version
|
|
47
|
+
version: '0'
|
|
48
|
+
type: :runtime
|
|
49
|
+
prerelease: false
|
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
51
|
+
requirements:
|
|
52
|
+
- - ">="
|
|
53
|
+
- !ruby/object:Gem::Version
|
|
54
|
+
version: '0'
|
|
55
|
+
- !ruby/object:Gem::Dependency
|
|
56
|
+
name: semantic_logger
|
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
|
58
|
+
requirements:
|
|
59
|
+
- - ">="
|
|
60
|
+
- !ruby/object:Gem::Version
|
|
61
|
+
version: '0'
|
|
62
|
+
type: :runtime
|
|
63
|
+
prerelease: false
|
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
65
|
+
requirements:
|
|
66
|
+
- - ">="
|
|
67
|
+
- !ruby/object:Gem::Version
|
|
68
|
+
version: '0'
|
|
69
|
+
- !ruby/object:Gem::Dependency
|
|
70
|
+
name: activesupport
|
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
|
72
|
+
requirements:
|
|
73
|
+
- - ">="
|
|
74
|
+
- !ruby/object:Gem::Version
|
|
75
|
+
version: '0'
|
|
76
|
+
type: :runtime
|
|
77
|
+
prerelease: false
|
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
79
|
+
requirements:
|
|
80
|
+
- - ">="
|
|
81
|
+
- !ruby/object:Gem::Version
|
|
82
|
+
version: '0'
|
|
83
|
+
- !ruby/object:Gem::Dependency
|
|
84
|
+
name: pry
|
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
|
86
|
+
requirements:
|
|
87
|
+
- - ">="
|
|
88
|
+
- !ruby/object:Gem::Version
|
|
89
|
+
version: '0'
|
|
90
|
+
type: :development
|
|
91
|
+
prerelease: false
|
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
93
|
+
requirements:
|
|
94
|
+
- - ">="
|
|
95
|
+
- !ruby/object:Gem::Version
|
|
96
|
+
version: '0'
|
|
97
|
+
- !ruby/object:Gem::Dependency
|
|
98
|
+
name: bundler
|
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
|
100
|
+
requirements:
|
|
101
|
+
- - "~>"
|
|
102
|
+
- !ruby/object:Gem::Version
|
|
103
|
+
version: '1.14'
|
|
104
|
+
type: :development
|
|
105
|
+
prerelease: false
|
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
107
|
+
requirements:
|
|
108
|
+
- - "~>"
|
|
109
|
+
- !ruby/object:Gem::Version
|
|
110
|
+
version: '1.14'
|
|
111
|
+
- !ruby/object:Gem::Dependency
|
|
112
|
+
name: rake
|
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
|
114
|
+
requirements:
|
|
115
|
+
- - "~>"
|
|
116
|
+
- !ruby/object:Gem::Version
|
|
117
|
+
version: '10.0'
|
|
118
|
+
type: :development
|
|
119
|
+
prerelease: false
|
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
121
|
+
requirements:
|
|
122
|
+
- - "~>"
|
|
123
|
+
- !ruby/object:Gem::Version
|
|
124
|
+
version: '10.0'
|
|
125
|
+
- !ruby/object:Gem::Dependency
|
|
126
|
+
name: rspec
|
|
127
|
+
requirement: !ruby/object:Gem::Requirement
|
|
128
|
+
requirements:
|
|
129
|
+
- - "~>"
|
|
130
|
+
- !ruby/object:Gem::Version
|
|
131
|
+
version: '3.0'
|
|
132
|
+
type: :development
|
|
133
|
+
prerelease: false
|
|
134
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
135
|
+
requirements:
|
|
136
|
+
- - "~>"
|
|
137
|
+
- !ruby/object:Gem::Version
|
|
138
|
+
version: '3.0'
|
|
139
|
+
description:
|
|
140
|
+
email:
|
|
141
|
+
- ddrscott@gmail.com
|
|
142
|
+
executables:
|
|
143
|
+
- gcp_fetch_token
|
|
144
|
+
- gcp_listen
|
|
145
|
+
extensions: []
|
|
146
|
+
extra_rdoc_files: []
|
|
147
|
+
files:
|
|
148
|
+
- ".gitignore"
|
|
149
|
+
- ".rspec"
|
|
150
|
+
- ".travis.yml"
|
|
151
|
+
- Gemfile
|
|
152
|
+
- Gemfile.lock
|
|
153
|
+
- LICENSE.txt
|
|
154
|
+
- README.md
|
|
155
|
+
- Rakefile
|
|
156
|
+
- bin/console
|
|
157
|
+
- bin/setup
|
|
158
|
+
- exe/gcp_fetch_token
|
|
159
|
+
- exe/gcp_listen
|
|
160
|
+
- gcp_directory.gemspec
|
|
161
|
+
- google_api_console.png
|
|
162
|
+
- lib/gcp_directory.rb
|
|
163
|
+
- lib/gcp_directory/listener.rb
|
|
164
|
+
- lib/gcp_directory/printer.rb
|
|
165
|
+
- lib/gcp_directory/version.rb
|
|
166
|
+
- oauth_example.ru
|
|
167
|
+
homepage: https://github.com/ddrscott/gcp_directory
|
|
168
|
+
licenses:
|
|
169
|
+
- MIT
|
|
170
|
+
metadata: {}
|
|
171
|
+
post_install_message:
|
|
172
|
+
rdoc_options: []
|
|
173
|
+
require_paths:
|
|
174
|
+
- lib
|
|
175
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
176
|
+
requirements:
|
|
177
|
+
- - ">="
|
|
178
|
+
- !ruby/object:Gem::Version
|
|
179
|
+
version: '0'
|
|
180
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
181
|
+
requirements:
|
|
182
|
+
- - ">="
|
|
183
|
+
- !ruby/object:Gem::Version
|
|
184
|
+
version: '0'
|
|
185
|
+
requirements: []
|
|
186
|
+
rubyforge_project:
|
|
187
|
+
rubygems_version: 2.6.11
|
|
188
|
+
signing_key:
|
|
189
|
+
specification_version: 4
|
|
190
|
+
summary: Listen for changes to a directory and send documents to Google Cloud Print
|
|
191
|
+
test_files: []
|