piwigo-api 0.1.1 → 0.2.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 +4 -4
- data/.gitignore +1 -0
- data/.vscode/launch.json +1 -0
- data/CHANGELOG.md +3 -0
- data/Gemfile.lock +1 -1
- data/README.md +29 -4
- data/lib/piwigo/albums.rb +187 -0
- data/lib/piwigo/session.rb +79 -37
- data/lib/piwigo/version.rb +1 -1
- data/piwigo-api.gemspec +2 -2
- metadata +7 -5
- data/main.rb +0 -8
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5051a29ebbe23995bb4c2d6436d6534b197f1b3794f7f857e0678e612d544501
|
4
|
+
data.tar.gz: f0c5dc53eede301abf914eb04fecb42e3c607281786939ef51db3dc50a6c8e98
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0fa2225cd04231a474299be116ff723a7ecbc70f44ada895041adfa2e47131663d08f60b399dd2ca98eb5e8f24ebf403195f2ff8aaf929d2e17e63bb7345c7cb
|
7
|
+
data.tar.gz: 4dfb369883eadfe868eaa6853a9c3c70661fef1ad9fd01b57011cf6e30454c5c56caf559f855465939ec9a2c9ab11f7c21a01eb99d6c0c063129441cdef340c1
|
data/.gitignore
CHANGED
data/.vscode/launch.json
CHANGED
data/CHANGELOG.md
CHANGED
@@ -6,6 +6,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
6
6
|
|
7
7
|
## [Unreleased]
|
8
8
|
|
9
|
+
0.2.0 - 2019-11-17
|
10
|
+
- Refactored the Session to make iteasier to use
|
11
|
+
- Support adding/deleting & listing albums
|
9
12
|
|
10
13
|
0.1.1 - 2019-11-16
|
11
14
|
- Initial Version, supports login/logout against a piwigo server
|
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
@@ -1,8 +1,8 @@
|
|
1
1
|
# Piwigo-API
|
2
2
|
|
3
|
-
|
3
|
+
Piwigo is open source web application to manage your collection of photos, and other medias. Piwigo provides an API for interacting with it.
|
4
4
|
|
5
|
-
|
5
|
+
This is a ruby-based client for interacting with a Piwigo instance using the Piwigo API.
|
6
6
|
|
7
7
|
## Installation
|
8
8
|
|
@@ -22,7 +22,32 @@ Or install it yourself as:
|
|
22
22
|
|
23
23
|
## Usage
|
24
24
|
|
25
|
-
|
25
|
+
Just include 'piwigo/session' and the related classes, then querying Piwigo is fairly quick and straightforward.
|
26
|
+
|
27
|
+
# Get the second album and all of it's children
|
28
|
+
|
29
|
+
|
30
|
+
```
|
31
|
+
require 'piwigo/session'
|
32
|
+
require 'piwigo/albums'
|
33
|
+
|
34
|
+
session = Piwigo::Session.login('mypiwigo.fqdn', 'Adrian', 'mypassword', https: false)
|
35
|
+
unless session.nil?
|
36
|
+
albums = Piwigo::Albums.list(session, album_id: 2, recursive: true)
|
37
|
+
albums.each { |album| p "#{album.id}, #{album.name} - # of photos: #{album.total_nb_images}" }
|
38
|
+
end
|
39
|
+
```
|
40
|
+
|
41
|
+
# Add a new album
|
42
|
+
```
|
43
|
+
session = Piwigo::Session.login('10.100.230.78', 'Adrian', 'secret', https: false)
|
44
|
+
unless session.nil?
|
45
|
+
album = Piwigo::Albums::Album.new
|
46
|
+
album.name = "My First Album"
|
47
|
+
album = Piwigo::Albums.add(session, album)
|
48
|
+
end
|
49
|
+
```
|
50
|
+
|
26
51
|
|
27
52
|
## Development
|
28
53
|
|
@@ -32,7 +57,7 @@ To install this gem onto your local machine, run `bundle exec rake install`. To
|
|
32
57
|
|
33
58
|
## Contributing
|
34
59
|
|
35
|
-
Bug reports and pull requests are welcome on GitHub at https://github.com/kkdad/piwigo.
|
60
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/kkdad/piwigo-ruby.
|
36
61
|
|
37
62
|
## License
|
38
63
|
|
@@ -0,0 +1,187 @@
|
|
1
|
+
require 'net/http'
|
2
|
+
require 'uri'
|
3
|
+
require 'json'
|
4
|
+
require 'logger'
|
5
|
+
|
6
|
+
# Piwigo organizes images by albums. The album tree has unlimted depth and each photo can belong to multiple albums. The Piwigo API
|
7
|
+
# refers to a Album as a Category.
|
8
|
+
module Piwigo
|
9
|
+
class Albums
|
10
|
+
class Album
|
11
|
+
# @return [Number] Album ID
|
12
|
+
attr_accessor :id
|
13
|
+
|
14
|
+
# @return [String] Name of the Album
|
15
|
+
attr_accessor :name
|
16
|
+
|
17
|
+
# @return [String] Album Description
|
18
|
+
attr_accessor :comment
|
19
|
+
|
20
|
+
# ???
|
21
|
+
attr_accessor :permalink
|
22
|
+
|
23
|
+
# @return [String] public or private
|
24
|
+
attr_accessor :status
|
25
|
+
|
26
|
+
# ???
|
27
|
+
attr_accessor :uppercats
|
28
|
+
|
29
|
+
# The rank of an album
|
30
|
+
attr_accessor :global_rank
|
31
|
+
|
32
|
+
# @return [Number] ID of the parent album, nil of this is a top-level album (Aka ParentID)
|
33
|
+
attr_accessor :id_uppercat
|
34
|
+
|
35
|
+
# @return [Number] Number of the Newest photos, excluding child albums
|
36
|
+
attr_accessor :nb_images
|
37
|
+
|
38
|
+
# @return [Number] Number of the Newest photos, including child albums
|
39
|
+
attr_accessor :total_nb_images
|
40
|
+
|
41
|
+
# ID of the representative photo for an album. This photo doesn't have to belong to the album.
|
42
|
+
attr_accessor :representative_picture_id
|
43
|
+
|
44
|
+
# @return [DateTime] Date of the Newest photos, excluding child albums
|
45
|
+
attr_accessor :date_last
|
46
|
+
|
47
|
+
# @return [DateTime] Date of the Newest photos, including child albums
|
48
|
+
attr_accessor :max_date_last
|
49
|
+
|
50
|
+
# @return [Number] Number of child albums inside this album
|
51
|
+
attr_accessor :nb_categories
|
52
|
+
|
53
|
+
# @return [Atring] Album URL
|
54
|
+
attr_accessor :url
|
55
|
+
|
56
|
+
# @return [String] Thumbnail URL
|
57
|
+
attr_accessor :tn_url
|
58
|
+
|
59
|
+
def initialize(hash: nil)
|
60
|
+
hash.each { |key, value| send("#{key}=", value) } unless hash.nil?
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
|
65
|
+
# Returns a list of albums
|
66
|
+
#
|
67
|
+
# @param [Session] session - Session
|
68
|
+
# @param [Number] album_id - Album to fetch, Optional
|
69
|
+
# @param [Boolean] recursive - Include subalbums, Optional
|
70
|
+
# @param [Boolean] public - Only include public albums, Optional
|
71
|
+
# @param [Boolean] fullname - ???, Optional
|
72
|
+
# @param [String] thumbnail_size - Size of thumbname to return, One of: square, thumb, 2small, xsmall, small, medium, large, xlarge, xxlarge. Optional
|
73
|
+
# @param [Logger] logger logger to output debug messages to (Optional)
|
74
|
+
#
|
75
|
+
# @return [Array<Album>] All albums that match the criteria, or nil there were no matches
|
76
|
+
#
|
77
|
+
def self.list(session, album_id: nil, recursive: false, public: false, fullname: false, thumbnail_size: 'thumb', logger: nil)
|
78
|
+
raise "Invalid session" if session.uri.nil?
|
79
|
+
logger = logger || Logger.new(STDOUT)
|
80
|
+
|
81
|
+
|
82
|
+
begin
|
83
|
+
http = Net::HTTP.new(session.uri.host, session.uri.port)
|
84
|
+
request = Net::HTTP::Post.new(session.uri.request_uri)
|
85
|
+
request.body = "method=pwg.categories.getList&cat_id=#{album_id}&recursive=#{recursive}&public=#{public}&fullname=#{fullname}&thumbnail_size=#{thumbnail_size}"
|
86
|
+
request['Cookie'] = [session.id]
|
87
|
+
|
88
|
+
# Send the request
|
89
|
+
response = http.request(request)
|
90
|
+
if response.code == '200'
|
91
|
+
data = JSON.parse(response.body)
|
92
|
+
albums = data['result']['categories'].map{ |hash| Album.new(hash: hash) }
|
93
|
+
logger.info "Album List succeeded: #{albums.size} albums retrieved."
|
94
|
+
albums
|
95
|
+
else
|
96
|
+
nil
|
97
|
+
end
|
98
|
+
rescue Timeout::Error, Errno::EINVAL, Errno::ECONNRESET, EOFError, Net::HTTPBadResponse, Net::HTTPHeaderSyntaxError, Net::ProtocolError => e
|
99
|
+
logger.error "Album List failed: #{e.messages}"
|
100
|
+
nil
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
|
105
|
+
# Adds an album.
|
106
|
+
#
|
107
|
+
# @param [Session] session to interact with Piwigo
|
108
|
+
# @param [Album] album album to create
|
109
|
+
# @param [Logger] logger logger to output debug messages to (Optional)
|
110
|
+
#
|
111
|
+
# @return [Album] newly created album
|
112
|
+
def self.add(session, album, logger: nil)
|
113
|
+
raise "Invalid session" if session.uri.nil?
|
114
|
+
raise "Invalid album" if album.nil?
|
115
|
+
|
116
|
+
logger = logger || Logger.new(STDOUT)
|
117
|
+
|
118
|
+
begin
|
119
|
+
http = Net::HTTP.new(session.uri.host, session.uri.port)
|
120
|
+
request = Net::HTTP::Post.new(session.uri.request_uri)
|
121
|
+
request.body = "method=pwg.categories.add&name=#{album.name}"
|
122
|
+
request.body.concat "&parent=#{album.id_uppercat}" unless album.id_uppercat.nil?
|
123
|
+
request.body.concat "&comment=#{album.comment}" unless album.comment.nil?
|
124
|
+
request.body.concat "&status=#{album.status}" unless album.status.nil?
|
125
|
+
request['Cookie'] = [session.id]
|
126
|
+
|
127
|
+
# Send the request
|
128
|
+
response = http.request(request)
|
129
|
+
if response.code == '200'
|
130
|
+
data = JSON.parse(response.body)
|
131
|
+
album.id = albums = data['result']['id']
|
132
|
+
logger.info "Album Add succeeded: #{album.id} created."
|
133
|
+
album
|
134
|
+
else
|
135
|
+
nil
|
136
|
+
|
137
|
+
end
|
138
|
+
rescue Timeout::Error, Errno::EINVAL, Errno::ECONNRESET, EOFError, Net::HTTPBadResponse, Net::HTTPHeaderSyntaxError, Net::ProtocolError => e
|
139
|
+
logger.error "Album Add failed: #{e.messages}"
|
140
|
+
nil
|
141
|
+
end
|
142
|
+
end
|
143
|
+
|
144
|
+
|
145
|
+
# Deletes album(s).
|
146
|
+
#
|
147
|
+
# @param [Session] piwigo session
|
148
|
+
# @param [Number] id of the album to remove
|
149
|
+
# @param [String] photo_deletion_mode can be "no_delete" (may create orphan photos), "delete_orphans" (default mode, only deletes photos linked to no other album)
|
150
|
+
# or "force_delete" (delete all photos, even those linked to other albums)
|
151
|
+
# @param [Logger] logger logger to output debug messages to (Optional)
|
152
|
+
#
|
153
|
+
# @return [Boolean] true if album was deleted
|
154
|
+
def self.delete(session, id, photo_deletion_mode: nil, logger: nil)
|
155
|
+
raise "Invalid session" if session.uri.nil?
|
156
|
+
|
157
|
+
logger = logger || Logger.new(STDOUT)
|
158
|
+
|
159
|
+
begin
|
160
|
+
http = Net::HTTP.new(session.uri.host, session.uri.port)
|
161
|
+
request = Net::HTTP::Post.new(session.uri.request_uri)
|
162
|
+
request.body = "method=pwg.categories.delete&category_id=#{id}"
|
163
|
+
request.body.concat "&photo_deletion_mode=#{photo_deletion_mode}" unless photo_deletion_mode.nil?
|
164
|
+
request.body.concat "&pwg_token=#{session.pwg_token}"
|
165
|
+
request['Cookie'] = [session.id]
|
166
|
+
|
167
|
+
# Send the request
|
168
|
+
response = http.request(request)
|
169
|
+
if response.code == '200'
|
170
|
+
data = JSON.parse(response.body)
|
171
|
+
logger.info "Album Delete succeeded."
|
172
|
+
true
|
173
|
+
else
|
174
|
+
p response.code
|
175
|
+
p response.body
|
176
|
+
false
|
177
|
+
|
178
|
+
end
|
179
|
+
rescue Timeout::Error, Errno::EINVAL, Errno::ECONNRESET, EOFError, Net::HTTPBadResponse, Net::HTTPHeaderSyntaxError, Net::ProtocolError => e
|
180
|
+
logger.error "Album delete: #{e.messages}"
|
181
|
+
false
|
182
|
+
end
|
183
|
+
end
|
184
|
+
|
185
|
+
|
186
|
+
end
|
187
|
+
end
|
data/lib/piwigo/session.rb
CHANGED
@@ -7,70 +7,112 @@ module Piwigo
|
|
7
7
|
# Class to hold the Piwigo session the rest of the API needs to pass in order to access the API
|
8
8
|
class Session
|
9
9
|
|
10
|
-
|
11
|
-
|
10
|
+
# @return [String] Piwigo session cookie
|
11
|
+
attr_accessor :id
|
12
|
+
|
13
|
+
# @return [URI::HTTP] Piwigo host associated with this session
|
14
|
+
attr_accessor :uri
|
15
|
+
|
16
|
+
# @return [String] token required for admin methods
|
17
|
+
attr_accessor :pwg_token
|
18
|
+
|
19
|
+
# @return [String] token required for admin methods
|
20
|
+
attr_accessor :username
|
21
|
+
|
22
|
+
|
23
|
+
def initialize(id, uri)
|
24
|
+
self.id = id
|
25
|
+
self.uri = uri
|
26
|
+
|
27
|
+
status
|
12
28
|
end
|
29
|
+
|
30
|
+
# Gets information about the current session. Also provides a token useable with admin methods.
|
31
|
+
# {"stat":"ok","result":{"username":"Adrian","status":"webmaster","theme":"modus","language":"en_GB","pwg_token":"9edde6a1ae535934cca6a2423f9bcbe7","charset":"utf-8","current_datetime":"2019-11-17 21:57:58","version":"2.10.1","available_sizes":["square","thumb","2small","xsmall","small","medium","large","xlarge","xxlarge"],"upload_file_types":"jpg,jpeg,png,gif","upload_form_chunk_size":500}}
|
32
|
+
# @return [<Type>] <description>
|
33
|
+
def status
|
34
|
+
logger = logger || Logger.new(STDOUT)
|
35
|
+
|
36
|
+
begin
|
37
|
+
# Create the HTTP objects
|
38
|
+
http = Net::HTTP.new(uri.host, uri.port)
|
39
|
+
request = Net::HTTP::Post.new(uri.request_uri)
|
40
|
+
request.body = "method=pwg.session.getStatus"
|
41
|
+
request['Cookie'] = self.id
|
42
|
+
|
43
|
+
# Send the request
|
44
|
+
response = http.request(request)
|
45
|
+
|
46
|
+
if response.code == '200'
|
47
|
+
logger.info "Status succeeded"
|
48
|
+
data = JSON.parse(response.body)
|
49
|
+
self.pwg_token = data['result']['pwg_token']
|
50
|
+
self.username = data['result']['username']
|
51
|
+
end
|
52
|
+
|
53
|
+
rescue Timeout::Error, Errno::EINVAL, Errno::ECONNRESET, EOFError, Net::HTTPBadResponse, Net::HTTPHeaderSyntaxError, Net::ProtocolError => e
|
54
|
+
logger.error "Unexpected failed: #{e.messages}"
|
55
|
+
end
|
56
|
+
nil
|
13
57
|
|
14
|
-
# Instantion a new Session object
|
15
|
-
# @param [Logger] logger logger to output debug messages to (Optional)
|
16
|
-
def initialize(logger: nil)
|
17
|
-
@session_id=nil
|
18
|
-
@uri=nil
|
19
|
-
@logger = logger || Logger.new(STDOUT)
|
20
58
|
end
|
59
|
+
|
60
|
+
# Logout of the current session
|
61
|
+
# @param [Logger] logger logger to output debug messages to (Optional)
|
62
|
+
def logout(logger: nil)
|
63
|
+
raise "This session has already been logged out" if uri.nil?
|
64
|
+
logger = logger || Logger.new(STDOUT)
|
21
65
|
|
66
|
+
# Create the HTTP objects
|
67
|
+
http = Net::HTTP.new(self.uri.host, self.uri.port)
|
68
|
+
request = Net::HTTP::Get.new(self.uri.request_uri + "&method=pwg.session.logout")
|
69
|
+
request['Cookie'] = self.id
|
70
|
+
|
71
|
+
# Send the request
|
72
|
+
response = http.request(request)
|
73
|
+
logger.info "Logout succeeded: #{response.body}" if response.code == '200'
|
74
|
+
self.id = nil
|
75
|
+
self.uri = nil
|
76
|
+
end
|
77
|
+
|
78
|
+
|
22
79
|
# Log into the piwigo API and grab the session id for subsequent calls.
|
23
80
|
# @param [string] piwigo - host to connect to. Can be fqdn or ip.
|
24
81
|
# @param [string] username - user to connect as
|
25
82
|
# @param [string] password - password for user
|
26
83
|
# @param [boolean] https - Use HTTPS?
|
27
|
-
|
84
|
+
# @param [Logger] logger logger to output debug messages to (Optional)
|
85
|
+
def self.login(host, username, password, https: true, logger: nil)
|
28
86
|
|
29
87
|
raise "host should not be nil" if host.nil?
|
30
88
|
raise "username should not be nil" if username.nil?
|
89
|
+
logger = logger || Logger.new(STDOUT)
|
31
90
|
|
32
91
|
begin
|
33
92
|
|
34
|
-
|
35
|
-
|
93
|
+
uri = https ? URI::HTTPS.build(host: host, path: "/ws.php", query: "format=json") :
|
94
|
+
URI::HTTP.build(host: host, path: "/ws.php", query: "format=json")
|
36
95
|
|
37
96
|
# Create the HTTP objects
|
38
|
-
http = Net::HTTP.new(
|
39
|
-
request = Net::HTTP::Post.new(
|
97
|
+
http = Net::HTTP.new(uri.host, uri.port)
|
98
|
+
request = Net::HTTP::Post.new(uri.request_uri)
|
40
99
|
request.body = "method=pwg.session.login&username=#{username}&password=#{password}"
|
41
100
|
|
42
101
|
# Send the request
|
43
102
|
response = http.request(request)
|
44
103
|
|
45
104
|
if response.code == '200'
|
46
|
-
|
47
|
-
|
48
|
-
return
|
105
|
+
logger.info "Login succeeded: #{response.body}"
|
106
|
+
pwg_id = response.response['set-cookie'].split(';').select { |i| i.strip.start_with? "pwg_id" }.first
|
107
|
+
return Session.new(pwg_id, uri)
|
49
108
|
else
|
50
|
-
|
51
|
-
@session_id = nil
|
52
|
-
@uri = nil
|
109
|
+
logger.error "Login failed: #{response.body}"
|
53
110
|
end
|
54
111
|
|
55
112
|
rescue Timeout::Error, Errno::EINVAL, Errno::ECONNRESET, EOFError, Net::HTTPBadResponse, Net::HTTPHeaderSyntaxError, Net::ProtocolError => e
|
56
|
-
|
113
|
+
logger.error "Login failed: #{e.messages}"
|
57
114
|
end
|
58
|
-
|
59
|
-
end
|
60
|
-
|
61
|
-
def logout
|
62
|
-
raise "login must be successfully called before logout" if @uri.nil?
|
63
|
-
|
64
|
-
# Create the HTTP objects
|
65
|
-
http = Net::HTTP.new(@uri.host, @uri.port)
|
66
|
-
request = Net::HTTP::Get.new(@uri.request_uri + "&method=pwg.session.logout")
|
67
|
-
request['Cookie'] = @session_id
|
68
|
-
|
69
|
-
# Send the request
|
70
|
-
response = http.request(request)
|
71
|
-
@logger.info "Logout succeeded: #{response.body}" if response.code == '200'
|
72
|
-
@session_id = nil
|
73
|
-
@uri = nil
|
74
|
-
end
|
115
|
+
nil
|
116
|
+
end
|
75
117
|
end
|
76
118
|
end
|
data/lib/piwigo/version.rb
CHANGED
data/piwigo-api.gemspec
CHANGED
@@ -8,8 +8,8 @@ Gem::Specification.new do |spec|
|
|
8
8
|
spec.authors = ["Adrian Gilbert"]
|
9
9
|
spec.email = ["adrian@gilbert.ca"]
|
10
10
|
|
11
|
-
spec.summary = %q{
|
12
|
-
spec.description = %q{
|
11
|
+
spec.summary = %q{Gem to interact with the Piwigo API}
|
12
|
+
spec.description = %q{Piwigo is open source web application to manage your collection of photos, and other medias. Piwigo provides an API for interacting with it. This is a ruby-based client for interacting with a Piwigo instance using the Piwigo API.}
|
13
13
|
spec.homepage = "https://github.com/kkdad/piwigo-api"
|
14
14
|
spec.license = "MIT"
|
15
15
|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: piwigo-api
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Adrian Gilbert
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2019-11-
|
11
|
+
date: 2019-11-17 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -80,7 +80,9 @@ dependencies:
|
|
80
80
|
- - "~>"
|
81
81
|
- !ruby/object:Gem::Version
|
82
82
|
version: '4.2'
|
83
|
-
description:
|
83
|
+
description: Piwigo is open source web application to manage your collection of photos,
|
84
|
+
and other medias. Piwigo provides an API for interacting with it. This is a ruby-based
|
85
|
+
client for interacting with a Piwigo instance using the Piwigo API.
|
84
86
|
email:
|
85
87
|
- adrian@gilbert.ca
|
86
88
|
executables: []
|
@@ -100,9 +102,9 @@ files:
|
|
100
102
|
- bin/console
|
101
103
|
- bin/setup
|
102
104
|
- lib/piwigo.rb
|
105
|
+
- lib/piwigo/albums.rb
|
103
106
|
- lib/piwigo/session.rb
|
104
107
|
- lib/piwigo/version.rb
|
105
|
-
- main.rb
|
106
108
|
- piwigo-api.gemspec
|
107
109
|
homepage: https://github.com/kkdad/piwigo-api
|
108
110
|
licenses:
|
@@ -129,5 +131,5 @@ requirements: []
|
|
129
131
|
rubygems_version: 3.0.3
|
130
132
|
signing_key:
|
131
133
|
specification_version: 4
|
132
|
-
summary:
|
134
|
+
summary: Gem to interact with the Piwigo API
|
133
135
|
test_files: []
|