smugsyncv2 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.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 50e94db133e4ea66d1c4e71702507664c3d54ecc
4
+ data.tar.gz: 589f36334f221a6574e819624f4a135838b70d8b
5
+ SHA512:
6
+ metadata.gz: 0906d160313ec369fca257d4f62c0b143d41e9427365e5e0db14834bad0ed7ec0646e515e59ce2fec1be2f4b4599899e94b7e141b80b97ddd62ef7c10a2b6798
7
+ data.tar.gz: 099a7af38a06b4858ff7ed69f26ad47246a00e0be8b11240204e7959b00ea2d27d11487e0d34c89077c3643119a5d12fe8772cf35f5da42710e25a8a73add313
data/.gitignore ADDED
@@ -0,0 +1,14 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /_yardoc/
4
+ /coverage/
5
+ /doc/
6
+ /pkg/
7
+ /spec/reports/
8
+ /tmp/
9
+ *.bundle
10
+ *.so
11
+ *.o
12
+ *.a
13
+ mkmf.log
14
+ .token_cache
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in smugsyncv2.gemspec
4
+ gemspec
data/Gemfile.lock ADDED
@@ -0,0 +1,32 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ smugsyncv2 (0.0.1)
5
+ deepopenstruct (~> 0.1.2)
6
+ faraday (~> 0.9.1)
7
+ faraday_middleware (~> 0.9.1)
8
+ oauth (~> 0.4.7)
9
+ simple_oauth (~> 0.3.1)
10
+ thor (~> 0.19.1)
11
+
12
+ GEM
13
+ remote: https://rubygems.org/
14
+ specs:
15
+ deepopenstruct (0.1.2)
16
+ faraday (0.9.1)
17
+ multipart-post (>= 1.2, < 3)
18
+ faraday_middleware (0.9.1)
19
+ faraday (>= 0.7.4, < 0.10)
20
+ multipart-post (2.0.0)
21
+ oauth (0.4.7)
22
+ rake (10.4.2)
23
+ simple_oauth (0.3.1)
24
+ thor (0.19.1)
25
+
26
+ PLATFORMS
27
+ ruby
28
+
29
+ DEPENDENCIES
30
+ bundler (~> 1.7)
31
+ rake (~> 10.0)
32
+ smugsyncv2!
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2015 Andrew Thompson
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,35 @@
1
+ # Smugsyncv2
2
+
3
+ API Client for the SmugMug v2 api
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ ```ruby
10
+ gem 'smugsyncv2'
11
+ ```
12
+
13
+ And then execute:
14
+
15
+ $ bundle
16
+
17
+ Or install it yourself as:
18
+
19
+ $ gem install smugsyncv2
20
+
21
+ ## Usage
22
+
23
+
24
+ ### Download images by tag
25
+ ```bash
26
+ smugsyncv2 download --key=smugmug_api_key --secret=smugmug_api_secret_key --tags=tag1 tag2 --dest=~/Downloads/myimages
27
+ ```
28
+
29
+ ## Contributing
30
+
31
+ 1. Fork it ( https://github.com/devkmsg/smugsyncv2/fork )
32
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
33
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
34
+ 4. Push to the branch (`git push origin my-new-feature`)
35
+ 5. Create a new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,2 @@
1
+ require "bundler/gem_tasks"
2
+
data/bin/smugsyncv2 ADDED
@@ -0,0 +1,55 @@
1
+ #!/usr/bin/env ruby
2
+ require 'smugsyncv2'
3
+ require 'fileutils'
4
+ require 'open-uri'
5
+ require 'tmpdir'
6
+ require 'thor'
7
+
8
+ class DownloadTaggedSmugmugPhotosHelper
9
+ def self.download(url, dest)
10
+ uri = URI.parse(url)
11
+ dest_file = File.basename(uri.path)
12
+ dest_path = File.join(dest, dest_file)
13
+ puts "Downloading #{dest_file}..."
14
+ File.open(dest_path, 'wb') do |saved_file|
15
+ # the following "open" is provided by open-uri
16
+ open(url, 'rb') do |read_file|
17
+ saved_file.write read_file.read
18
+ end
19
+ end
20
+ end
21
+ end
22
+
23
+ class DownloadTaggedSmugmugPhotos < Thor
24
+
25
+ desc 'download tagged images from SmugMug', 'download OPTIONS'
26
+ option :key, required: true, type: :string, banner: 'This is the SmugMug API key. Can be found at: https://secure.smugmug.com/settings/#section=api-keys'
27
+ option :secret, required: true, type: :string, banner: 'This is the SmugMug API secret key. Can be found at: https://secure.smugmug.com/settings/#section=api-keys'
28
+ option :tags, required: true, type: :array, banner: 'These are the tagged images you wish to download'
29
+ option :dest, required: false, type: :string, default: Dir.mktmpdir
30
+ option :logging, required: false, type: :boolean, default: false
31
+ def download
32
+ FileUtils.mkdir_p options[:dest] unless File.exist? options[:dest]
33
+ client = Smugsyncv2::Client.new(options[:key], options[:secret], options[:logging])
34
+ client.user
35
+ search = client.get_uri('UserImageSearch')
36
+ search_uri = search.Response.Uri
37
+ param_name = search.Options.Parameters.GET.find { |n| n.respond_to? :Name }.Name
38
+
39
+ puts "Downloading into #{options[:dest]}"
40
+ options[:tags].each do |tag|
41
+ params = { param_name => tag }
42
+ image_search_response = client.request(path: search_uri, params: params)
43
+ images = image_search_response.Response.Image
44
+ images.each do |image|
45
+ image_uri = image.Uris.LargestImage.Uri
46
+ image_response = client.request(path: image_uri)
47
+ image_download_url = image_response.Response.LargestImage.Url
48
+ DownloadTaggedSmugmugPhotosHelper.download(image_download_url, options[:dest])
49
+ end
50
+ puts "Downloaded #{images.length} images into #{options[:dest]}"
51
+ end
52
+ end
53
+ end
54
+
55
+ DownloadTaggedSmugmugPhotos.start(ARGV)
@@ -0,0 +1,118 @@
1
+ require 'oauth/request_proxy/base'
2
+
3
+ module Smugsyncv2
4
+ class Client
5
+ TOKEN_FILE = '.token_cache'
6
+
7
+ def initialize(key, secret, logger = false)
8
+ @uris = nil
9
+ @key = key
10
+ @secret = secret
11
+ @logger = logger
12
+ end
13
+
14
+ def oauth_opts
15
+ { site: OAUTH_ORIGIN,
16
+ request_token_path: REQUEST_TOKEN_PATH,
17
+ access_token_path: ACCESS_TOKEN_PATH,
18
+ authorize_path: AUTHORIZE_PATH
19
+ }
20
+ end
21
+
22
+ def login # rubocop:disable Metrics/MethodLength
23
+ @consumer = OAuth::Consumer.new(@key, @secret, oauth_opts)
24
+ return load_cached_token if File.exist?(TOKEN_FILE)
25
+ @request_token = @consumer.get_request_token
26
+ authorize_url = @request_token.authorize_url + '&Access=Full'
27
+ puts "Open a web browser and open: #{authorize_url}"
28
+ puts 'Enter the validation code: '
29
+ verification_code = Kernel.gets.chomp
30
+ @access_token = @request_token.get_access_token(
31
+ oauth_verifier: verification_code)
32
+ cache_token(@access_token)
33
+ @access_token
34
+ end
35
+
36
+ def access_token
37
+ @access_token ||= login
38
+ end
39
+
40
+ def consumer
41
+ if @consumer
42
+ @consumer
43
+ else
44
+ login
45
+ @consumer
46
+ end
47
+ end
48
+
49
+ def load_cached_token
50
+ Marshal.load(File.open(TOKEN_FILE, 'r'))
51
+ end
52
+
53
+ def cache_token(token)
54
+ File.open(TOKEN_FILE, 'w') do |file|
55
+ file.write Marshal.dump(token)
56
+ end
57
+ end
58
+
59
+ def adapter(url: BASE_URL)
60
+ @connection = Faraday.new(url: url) do |conn|
61
+ conn.request :json
62
+ conn.response :json
63
+ conn.adapter Faraday.default_adapter
64
+ conn.response :logger if @logger
65
+ end
66
+ end
67
+
68
+ def connection(**args)
69
+ @connection ||= adapter(**args)
70
+ end
71
+
72
+ def get_oauth_header(method, url, params)
73
+ SimpleOAuth::Header.new(
74
+ method, url,
75
+ params,
76
+ consumer_key: @key,
77
+ consumer_secret: @secret,
78
+ token: access_token.token,
79
+ token_secret: access_token.secret,
80
+ version: '1.0').to_s
81
+ end
82
+
83
+ def request(method: :get, path: nil, params: {}, body: {}, headers: {})
84
+ url = path.nil? ? BASE_URL : File.join(API_ORIGIN, path)
85
+ base_headers = { 'User-Agent' => USER_AGENT, 'Accept' => 'application/json' }
86
+ headers = base_headers.merge(headers || {})
87
+
88
+ adapter(url: url)
89
+ response = @connection.send(method) do |req|
90
+ oauth_header = get_oauth_header(method, url, params)
91
+ req.headers.merge!('Authorization' => oauth_header)
92
+
93
+ req.url url
94
+ req.headers.merge!(headers)
95
+ req.params.merge!(params)
96
+ req.body = body
97
+ end
98
+ @response = DeepOpenStruct.load(response.body)
99
+ end
100
+
101
+ def user
102
+ res = request
103
+ uri = res.Response.Uris.AuthUser.Uri
104
+ user = request(path: uri)
105
+ user = user.Response.User.Uris
106
+ @uris = user
107
+ end
108
+
109
+ def get_uri(name)
110
+ uri = @uris.send(name).Uri
111
+ request(path: uri)
112
+ if @response && @response.Response && @response.Response.send(name)
113
+ @uris = @response['Response'][name]['Uris']
114
+ end
115
+ @response
116
+ end
117
+ end
118
+ end
@@ -0,0 +1,3 @@
1
+ module Smugsyncv2
2
+ VERSION = "0.0.1"
3
+ end
data/lib/smugsyncv2.rb ADDED
@@ -0,0 +1,21 @@
1
+ require 'smugsyncv2/version'
2
+ require 'faraday_middleware'
3
+ require 'faraday'
4
+ require 'simple_oauth'
5
+ require 'deepopenstruct'
6
+ require 'oauth'
7
+ require 'json'
8
+ require 'pp'
9
+ require_relative './smugsyncv2/client.rb'
10
+
11
+ module Smugsyncv2
12
+ OAUTH_ORIGIN = 'https://secure.smugmug.com'
13
+ REQUEST_TOKEN_PATH = '/services/oauth/1.0a/getRequestToken'
14
+ ACCESS_TOKEN_PATH = '/services/oauth/1.0a/getAccessToken'
15
+ AUTHORIZE_PATH = '/services/oauth/1.0a/authorize'
16
+
17
+ API_ORIGIN = 'http://api.smugmug.com'
18
+ BASE_PATH = 'api/v2'
19
+ BASE_URL = File.join(API_ORIGIN, BASE_PATH)
20
+ USER_AGENT = "Ruby/#{RUBY_VERSION} (#{RUBY_PLATFORM}; #{RUBY_ENGINE}) Smugsyncv2/#{Smugsyncv2::VERSION} Faraday/#{Faraday::VERSION}".freeze
21
+ end
@@ -0,0 +1,29 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'smugsyncv2/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = 'smugsyncv2'
8
+ spec.version = Smugsyncv2::VERSION
9
+ spec.authors = ['Andrew Thompson']
10
+ spec.email = ['netengr2009@gmail.com']
11
+ spec.summary = %q{API Client for the SmugMug v2 api}
12
+ spec.homepage = ''
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_dependency 'oauth', '~> 0.4.7'
21
+ spec.add_dependency 'faraday', '~> 0.9.1'
22
+ spec.add_dependency 'faraday_middleware', '~> 0.9.1'
23
+ spec.add_dependency 'simple_oauth', '~> 0.3.1'
24
+ spec.add_dependency 'deepopenstruct', '~> 0.1.2'
25
+ spec.add_dependency 'thor', '~> 0.19.1'
26
+
27
+ spec.add_development_dependency 'bundler', '~> 1.7'
28
+ spec.add_development_dependency 'rake', '~> 10.0'
29
+ end
metadata ADDED
@@ -0,0 +1,168 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: smugsyncv2
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Andrew Thompson
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-03-04 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: oauth
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ~>
18
+ - !ruby/object:Gem::Version
19
+ version: 0.4.7
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ~>
25
+ - !ruby/object:Gem::Version
26
+ version: 0.4.7
27
+ - !ruby/object:Gem::Dependency
28
+ name: faraday
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ~>
32
+ - !ruby/object:Gem::Version
33
+ version: 0.9.1
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ~>
39
+ - !ruby/object:Gem::Version
40
+ version: 0.9.1
41
+ - !ruby/object:Gem::Dependency
42
+ name: faraday_middleware
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ~>
46
+ - !ruby/object:Gem::Version
47
+ version: 0.9.1
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ~>
53
+ - !ruby/object:Gem::Version
54
+ version: 0.9.1
55
+ - !ruby/object:Gem::Dependency
56
+ name: simple_oauth
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ~>
60
+ - !ruby/object:Gem::Version
61
+ version: 0.3.1
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ~>
67
+ - !ruby/object:Gem::Version
68
+ version: 0.3.1
69
+ - !ruby/object:Gem::Dependency
70
+ name: deepopenstruct
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ~>
74
+ - !ruby/object:Gem::Version
75
+ version: 0.1.2
76
+ type: :runtime
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ~>
81
+ - !ruby/object:Gem::Version
82
+ version: 0.1.2
83
+ - !ruby/object:Gem::Dependency
84
+ name: thor
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ~>
88
+ - !ruby/object:Gem::Version
89
+ version: 0.19.1
90
+ type: :runtime
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ~>
95
+ - !ruby/object:Gem::Version
96
+ version: 0.19.1
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.7'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ~>
109
+ - !ruby/object:Gem::Version
110
+ version: '1.7'
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
+ description:
126
+ email:
127
+ - netengr2009@gmail.com
128
+ executables:
129
+ - smugsyncv2
130
+ extensions: []
131
+ extra_rdoc_files: []
132
+ files:
133
+ - .gitignore
134
+ - Gemfile
135
+ - Gemfile.lock
136
+ - LICENSE.txt
137
+ - README.md
138
+ - Rakefile
139
+ - bin/smugsyncv2
140
+ - lib/smugsyncv2.rb
141
+ - lib/smugsyncv2/client.rb
142
+ - lib/smugsyncv2/version.rb
143
+ - smugsyncv2.gemspec
144
+ homepage: ''
145
+ licenses:
146
+ - MIT
147
+ metadata: {}
148
+ post_install_message:
149
+ rdoc_options: []
150
+ require_paths:
151
+ - lib
152
+ required_ruby_version: !ruby/object:Gem::Requirement
153
+ requirements:
154
+ - - '>='
155
+ - !ruby/object:Gem::Version
156
+ version: '0'
157
+ required_rubygems_version: !ruby/object:Gem::Requirement
158
+ requirements:
159
+ - - '>='
160
+ - !ruby/object:Gem::Version
161
+ version: '0'
162
+ requirements: []
163
+ rubyforge_project:
164
+ rubygems_version: 2.0.14
165
+ signing_key:
166
+ specification_version: 4
167
+ summary: API Client for the SmugMug v2 api
168
+ test_files: []