hallon 0.13.0 → 0.14.0
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG.md +43 -1
- data/Gemfile +0 -2
- data/LICENSE.txt +1 -1
- data/README.markdown +94 -44
- data/examples/playing_audio.rb +4 -5
- data/lib/hallon.rb +20 -0
- data/lib/hallon/album.rb +13 -12
- data/lib/hallon/album_browse.rb +1 -0
- data/lib/hallon/artist.rb +13 -12
- data/lib/hallon/artist_browse.rb +1 -0
- data/lib/hallon/base.rb +2 -0
- data/lib/hallon/image.rb +18 -10
- data/lib/hallon/loadable.rb +24 -0
- data/lib/hallon/observable.rb +1 -1
- data/lib/hallon/observable/playlist.rb +10 -16
- data/lib/hallon/observable/playlist_container.rb +12 -6
- data/lib/hallon/player.rb +3 -3
- data/lib/hallon/playlist.rb +34 -11
- data/lib/hallon/playlist_container.rb +10 -4
- data/lib/hallon/search.rb +1 -0
- data/lib/hallon/session.rb +2 -2
- data/lib/hallon/toplist.rb +17 -12
- data/lib/hallon/track.rb +1 -0
- data/lib/hallon/user.rb +48 -11
- data/lib/hallon/version.rb +1 -1
- data/spec/hallon/album_browse_spec.rb +2 -0
- data/spec/hallon/album_spec.rb +14 -7
- data/spec/hallon/artist_browse_spec.rb +2 -0
- data/spec/hallon/artist_spec.rb +14 -8
- data/spec/hallon/hallon_spec.rb +12 -0
- data/spec/hallon/image_spec.rb +18 -9
- data/spec/hallon/loadable_spec.rb +46 -0
- data/spec/hallon/observable/playlist_spec.rb +11 -5
- data/spec/hallon/observable_spec.rb +6 -0
- data/spec/hallon/playlist_container_spec.rb +6 -0
- data/spec/hallon/playlist_spec.rb +21 -4
- data/spec/hallon/search_spec.rb +2 -0
- data/spec/hallon/toplist_spec.rb +40 -23
- data/spec/hallon/track_spec.rb +2 -0
- data/spec/hallon/user_post_spec.rb +75 -0
- data/spec/hallon/user_spec.rb +7 -11
- data/spec/spec_helper.rb +2 -2
- metadata +20 -16
- data/examples/audio_driver.rb +0 -55
data/CHANGELOG.md
CHANGED
@@ -10,6 +10,47 @@ __Changed__
|
|
10
10
|
|
11
11
|
__Fixed__
|
12
12
|
|
13
|
+
[v0.14.0][]
|
14
|
+
------------------
|
15
|
+
This release brings a lot more meat added to the README, in addition to the following:
|
16
|
+
|
17
|
+
__Added__
|
18
|
+
|
19
|
+
- Add #load to all loadable objects [acb508a, d554fb9]
|
20
|
+
- Album
|
21
|
+
- AlbumBrowse
|
22
|
+
- Artist
|
23
|
+
- ArtistBrowse
|
24
|
+
- Image
|
25
|
+
- Playlist
|
26
|
+
- PlaylistContainer
|
27
|
+
- Search
|
28
|
+
- Toplist
|
29
|
+
- Track
|
30
|
+
- User
|
31
|
+
- Toplist#type [0ea8bac]
|
32
|
+
- Playlist.invalid_name? [a516cf0]
|
33
|
+
- User::Post#loaded? [373fd7]
|
34
|
+
- User::Post#message and User::Post#recipient_name [e31ff68]
|
35
|
+
- User::Post#recipient [4c6b71f]
|
36
|
+
- User::Post#tracks [1c407b6f]
|
37
|
+
|
38
|
+
__Changed__
|
39
|
+
|
40
|
+
- User::Post.create and User#post now accepts a single track [542f344]
|
41
|
+
- User::Post.new is now private, use User::Post.create instead [00ee6db]
|
42
|
+
- Toplist#artists/albums/tracks are now just Toplist#results [0ea8bac]
|
43
|
+
- Image#id(param) split up into Image#id and Image#raw_id [1bbd7def]
|
44
|
+
- Album#cover(param) split up into Album#cover and Album#cover_link [1bbd7def]
|
45
|
+
- Artist#portrait(param) split up into Artist#portrait and Artist#portrait_link [1bbd7def]
|
46
|
+
- Default cache_path and settings_path for Session#initialize are now both "tmp/hallon" [15573a7]
|
47
|
+
|
48
|
+
__Fixed__
|
49
|
+
|
50
|
+
- Playlist#remove accepting invalid parameters [91ccef6]
|
51
|
+
- Segfault in tracks_removed/tracks_moved playlist callbacks [46ac650]
|
52
|
+
- Observable#subscribe_for_callbacks subscribing to null pointers [f9cf72d]
|
53
|
+
|
13
54
|
[v0.13.0][]
|
14
55
|
------------------
|
15
56
|
|
@@ -259,4 +300,5 @@ easier to handle.
|
|
259
300
|
[v0.11.0]: https://github.com/Burgestrand/Hallon/compare/v0.10.1...v0.11.0
|
260
301
|
[v0.12.0]: https://github.com/Burgestrand/Hallon/compare/v0.11.0...v0.12.0
|
261
302
|
[v0.13.0]: https://github.com/Burgestrand/Hallon/compare/v0.12.0...v0.13.0
|
262
|
-
[
|
303
|
+
[v0.14.0]: https://github.com/Burgestrand/Hallon/compare/v0.13.0...v0.14.0
|
304
|
+
[HEAD]: https://github.com/Burgestrand/Hallon/compare/v0.14.0...HEAD
|
data/Gemfile
CHANGED
data/LICENSE.txt
CHANGED
data/README.markdown
CHANGED
@@ -1,32 +1,82 @@
|
|
1
1
|
[What is Hallon?][] [![Build Status][]](http://travis-ci.org/Burgestrand/Hallon)
|
2
2
|
===================
|
3
3
|
|
4
|
-
Hallon
|
5
|
-
|
6
|
-
Hallon would not have been possible if not for these people:
|
7
|
-
|
8
|
-
- Per Reimers, cracking synchronization bugs with me in the deep night (4 AM) and correcting me when I didn’t know better
|
9
|
-
- Spotify, providing a service worth attention (and my money!)
|
10
|
-
- Linus Oleander, originally inspiring me to write Hallon (for the radiofy.se project)
|
11
|
-
|
12
|
-
Also, these people are worthy of mention simply for their contribution:
|
13
|
-
|
14
|
-
- Jesper Särnesjö, unknowingly providing me a starting point with [Greenstripes][]
|
15
|
-
- Emil “@mrevilme” Palm, for his patience in helping me debug Hallon deadlock issues
|
4
|
+
Hallon (Swedish for “[Raspberry][]”) is _the_ ruby gem for interacting with the official Spotify C API. It is the only ruby gem for libspotify that is up-to-date and usable. My goal with Hallon is to make libspotify a joy to use.
|
16
5
|
|
17
6
|
Code samples can be found under the `examples/` directory. An explanation on how to run them can be found on the [Hallon wiki on GitHub](https://github.com/Burgestrand/Hallon/wiki).
|
18
7
|
|
19
8
|
Installation
|
20
9
|
------------
|
21
10
|
|
22
|
-
|
11
|
+
```bash
|
12
|
+
gem install hallon
|
13
|
+
```
|
23
14
|
|
24
15
|
If you want to play audio you’ll need to install an audio driver. As of current writing there is only one driver in existence. You can install it with:
|
25
16
|
|
26
|
-
|
17
|
+
```bash
|
18
|
+
gem install hallon-openal
|
19
|
+
```
|
27
20
|
|
28
21
|
For more information about audio support in Hallon, see the section "Audio support" below.
|
29
22
|
|
23
|
+
Hallon and Spotify objects
|
24
|
+
--------------------------
|
25
|
+
All objects from libspotify have a counterpart in Hallon, and just like in libspotify the objects are populated with information as it becomes available. All objects that behave in this way respond to `#loaded?`, which’ll return true if the object has been populated with data.
|
26
|
+
|
27
|
+
To ease loading objects, all loadable objects also respond to [#load][]. This method simply polls on the target object, repeatedly calling [Session#process_events][] until either a time limit is reached or the object has finished loading.
|
28
|
+
|
29
|
+
```ruby
|
30
|
+
user = Hallon::User.new("spotify:user:burgestrand").load
|
31
|
+
puts user.loaded? # => true
|
32
|
+
```
|
33
|
+
|
34
|
+
As far as usage of the library goes, what applies to libspotify also applies to Hallon, so I would suggest you also read [the libspotify library overview](http://developer.spotify.com/en/libspotify/docs/) and related documentation.
|
35
|
+
|
36
|
+
### Callbacks
|
37
|
+
Some objects may fire callbacks, most of the time as a direct result of [Session#process_events][]. In libspotify the callbacks are only fired once for every object, but in Hallon you may have more than one object attached to the same libspotify object. As a result, callbacks are handled individually for each Hallon object.
|
38
|
+
|
39
|
+
```ruby
|
40
|
+
imageA = Hallon::Image.new("spotify:image:548957670a3e9950e87ce61dc0c188debd22b0cb")
|
41
|
+
imageB = Hallon::Image.new("spotify:image:548957670a3e9950e87ce61dc0c188debd22b0cb")
|
42
|
+
|
43
|
+
imageA.pointer == imageB.pointer # => true, same spotify pointer
|
44
|
+
imageA.object_id == imageB.object_id # => false, different objects
|
45
|
+
|
46
|
+
imageA.on(:load) do
|
47
|
+
puts "imageA loaded!"
|
48
|
+
end
|
49
|
+
|
50
|
+
imageB.on(:load) do
|
51
|
+
puts "imageB loaded!"
|
52
|
+
end
|
53
|
+
|
54
|
+
imageA.load # might load imageB as well, we don’t know
|
55
|
+
imageB.load # but the callbacks will both fire on load
|
56
|
+
```
|
57
|
+
|
58
|
+
A list of all objects that may fire callbacks can be found on the [API page for Hallon::Observable][].
|
59
|
+
|
60
|
+
### Errors
|
61
|
+
On failed libspotify API calls, a [Hallon::Error][] will be raised with a message explaining the error. Methods that might fail in this way (e.g. [Session.initialize][]) should have this clearly stated in its’ documentation.
|
62
|
+
|
63
|
+
For a full list of possible errors, see [the official libspotify documentation on error handling](http://developer.spotify.com/en/libspotify/docs/group__error.html).
|
64
|
+
|
65
|
+
### Enumerators
|
66
|
+
Some methods (e.g. [Track#artists][]) return a [Hallon::Enumerator][] object. Enumerators are lazily loaded, which means that calling `track.artists` won’t create any artist objects until you try to retrieve one of the records out of the returned enumerator. If you want to load all artists for a track you should retrieve them all then load them in bulk.
|
67
|
+
|
68
|
+
```ruby
|
69
|
+
artists = track.artists.to_a # avoid laziness, instantiate all artist objects
|
70
|
+
artists.map(&:load)
|
71
|
+
```
|
72
|
+
|
73
|
+
An additional note is that the size of an enumerator may change, and its contents may move as libspotify updates its information.
|
74
|
+
|
75
|
+
For the API reference and existing subclasses, see [Hallon::Enumerator][].
|
76
|
+
|
77
|
+
### Garbage collection
|
78
|
+
Hallon makes use of Ruby’s own garbage collection to automatically release libspotify objects when they are no longer in use. There is no need to retain or release the spotify objects manually.
|
79
|
+
|
30
80
|
Audio support
|
31
81
|
-------------
|
32
82
|
Hallon supports streaming audio from Spotify via [Hallon::Player][]. When you create the player you give it your current session and an audio driver, which the player will then use for audio playback.
|
@@ -40,47 +90,38 @@ Available drivers are:
|
|
40
90
|
|
41
91
|
- [Hallon::OpenAL](https://rubygems.org/gems/hallon-openal)
|
42
92
|
|
43
|
-
|
44
|
-
|
45
|
-
For information on how to write your own audio driver, see [Hallon::ExampleAudioDriver].
|
46
|
-
|
47
|
-
You have any questions?
|
48
|
-
-----------------------
|
49
|
-
I can be reached at my [email (found on GitHub profile)](http://github.com/Burgestrand) or [@burgestrand on twitter](http://twitter.com/Burgestrand). I’d be extremely happy to discuss Hallon with
|
50
|
-
you if you have any feedback or thoughts.
|
51
|
-
|
52
|
-
For issues and feature requests, please use use [Hallons issue tracker](http://github.com/Burgestrand/Hallon/issues).
|
93
|
+
gem install hallon-openal
|
53
94
|
|
54
|
-
|
55
|
-
--------------------------------
|
56
|
-
Sweet! You contribute in more than one way!
|
57
|
-
|
58
|
-
### Write code!
|
59
|
-
[Fork](http://help.github.com/forking/) Hallon, [write tests for everything](http://relishapp.com/rspec) you do (so I don’t break your stuff during my own development) and send a pull request. If you modify existing files, please adhere to the coding standard surrounding your code!
|
60
|
-
|
61
|
-
### [Send me feedback and requests](http://github.com/Burgestrand/Hallon/issues)
|
62
|
-
Really, I ❤ feedback! Suggestions on how to improve the API, tell me what is delicious about Hallon, tell me what is yucky about Hallon… anything! All feedback is useful in one way or another.
|
95
|
+
For information on how to write your own audio driver, see [Hallon::ExampleAudioDriver][].
|
63
96
|
|
64
97
|
Finally, here are some important notes
|
65
98
|
--------------------------------------
|
66
99
|
|
67
|
-
###
|
68
|
-
|
100
|
+
### [Please tell me your feedback and requests!](https://github.com/Burgestrand/Hallon/issues/new)
|
101
|
+
Really, I ❤ feedback! Suggestions on how to improve the API, tell me what is delicious about Hallon, tell me what is yucky about Hallon… anything! All feedback is useful in one way or another. You have any issues with Hallon? Just ask, and I’ll answer if I can.
|
69
102
|
|
70
|
-
###
|
71
|
-
|
103
|
+
### Contributing to Hallon
|
104
|
+
[Fork](http://help.github.com/forking/) Hallon, write tests for everything you do (so I don’t break your stuff during my own development) and send a pull request. If you modify existing files, please adhere to the coding standard surrounding your code.
|
72
105
|
|
73
|
-
###
|
74
|
-
|
106
|
+
### Hallon uses [semantic versioning](http://semver.org) as of v0.0.0
|
107
|
+
As long as Hallon stays at major version 0, no guarantees of backwards-compatibility are made. `CHANGELOG.md` will be kept up to date with the different versions.
|
108
|
+
|
109
|
+
### Hallon only supports one session per process
|
110
|
+
You can only keep one session with Spotify alive at a time within the same process, due to a limitation of libspotify.
|
75
111
|
|
76
112
|
### When forking, you need to be extra careful
|
77
113
|
If you fork, you need to instantiate the session within the process you plan to use Hallon in. You want to use Hallon in the parent? Create the session in the parent. You want to use it in the child? Create the session in the child! This is a limitation of libspotify itself.
|
78
114
|
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
115
|
+
You have more questions?
|
116
|
+
------------------------
|
117
|
+
I can be reached at my [email (found on GitHub profile)](http://github.com/Burgestrand) or [@burgestrand on twitter](http://twitter.com/Burgestrand). I’d be extremely happy to discuss Hallon with you if you have any feedback or thoughts.
|
118
|
+
|
119
|
+
Credits
|
120
|
+
-------
|
121
|
+
- Per Reimers, cracking synchronization bugs with me deep in the night (4 AM), thanks. :)
|
122
|
+
- Jesper Särnesjö, unknowingly providing me a starting point with [Greenstripes][]
|
123
|
+
- Linus Oleander, originally inspiring me to write Hallon (for the radiofy.se project)
|
124
|
+
- Emil “@mrevilme” Palm, for his patience in helping me debug Hallon deadlock issues
|
84
125
|
|
85
126
|
License
|
86
127
|
-------
|
@@ -94,5 +135,14 @@ Hallon is licensed under a 2-clause (Simplified) BSD license. More information c
|
|
94
135
|
[What is Hallon?]: http://burgestrand.se/articles/hallon-delicious-ruby-bindings-to-libspotify.html
|
95
136
|
[Build Status]: https://secure.travis-ci.org/Burgestrand/Hallon.png
|
96
137
|
|
138
|
+
[API page for Hallon::Observable]: http://rubydoc.info/github/Burgestrand/Hallon/master/Hallon/Observable
|
139
|
+
|
140
|
+
[Hallon::Enumerator]: http://rubydoc.info/github/Burgestrand/Hallon/Hallon/Enumerator
|
141
|
+
[Hallon::Error]: http://rubydoc.info/github/Burgestrand/Hallon/Hallon/Error
|
97
142
|
[Hallon::Player]: http://rubydoc.info/github/Burgestrand/Hallon/Hallon/Player
|
98
143
|
[Hallon::ExampleAudioDriver]: http://rubydoc.info/github/Burgestrand/Hallon/Hallon/ExampleAudioDriver
|
144
|
+
|
145
|
+
[Session#process_events]: http://rubydoc.info/github/Burgestrand/Hallon/Hallon/Session:process_events
|
146
|
+
[Session.initialize]: http://rubydoc.info/github/Burgestrand/Hallon/Hallon/Session.initialize
|
147
|
+
[Track#artists]: http://rubydoc.info/github/Burgestrand/Hallon/Hallon/Track:artists
|
148
|
+
[#load]: http://rubydoc.info/github/Burgestrand/Hallon/Hallon/Loadable:load
|
data/examples/playing_audio.rb
CHANGED
@@ -2,13 +2,13 @@
|
|
2
2
|
|
3
3
|
$LOAD_PATH.unshift(File.expand_path('../lib', File.dirname(__FILE__)))
|
4
4
|
|
5
|
-
require 'bundler/setup'
|
6
5
|
require 'hallon'
|
7
6
|
|
8
7
|
begin
|
9
8
|
require 'hallon/openal'
|
10
|
-
rescue LoadError
|
11
|
-
|
9
|
+
rescue LoadError => e
|
10
|
+
puts e.message
|
11
|
+
abort "[ERROR] Could not load gem 'hallon-openal', please install with 'gem install hallon-openal'"
|
12
12
|
end
|
13
13
|
|
14
14
|
require_relative '../spec/support/config'
|
@@ -42,8 +42,7 @@ session = Hallon::Session.initialize IO.read(ENV['HALLON_APPKEY']) do
|
|
42
42
|
end
|
43
43
|
end
|
44
44
|
|
45
|
-
|
46
|
-
player = Hallon::Player.new(session, driver)
|
45
|
+
player = Hallon::Player.new(session, Hallon::OpenAL)
|
47
46
|
|
48
47
|
# Program flow.
|
49
48
|
|
data/lib/hallon.rb
CHANGED
@@ -5,6 +5,7 @@ require 'hallon/ext/ffi'
|
|
5
5
|
|
6
6
|
require 'hallon/observable'
|
7
7
|
require 'hallon/linkable'
|
8
|
+
require 'hallon/loadable'
|
8
9
|
|
9
10
|
require 'hallon/version'
|
10
11
|
require 'hallon/error'
|
@@ -64,4 +65,23 @@ module Hallon
|
|
64
65
|
|image:[a-fA-F0-9]{40}
|
65
66
|
))
|
66
67
|
/x
|
68
|
+
|
69
|
+
# Thrown by {Loadable#load} on failure.
|
70
|
+
TimeoutError = Class.new(Hallon::Error)
|
71
|
+
|
72
|
+
class << self
|
73
|
+
# @return [Numeric] default load timeout in seconds, used in {Loadable#load}.
|
74
|
+
attr_reader :load_timeout
|
75
|
+
|
76
|
+
# @param [Numeric] sets the default load_timeout in seconds for {Loadable#load}.
|
77
|
+
def load_timeout=(new_timeout)
|
78
|
+
if new_timeout < 0
|
79
|
+
raise ArgumentError, "timeout cannot be negative"
|
80
|
+
end
|
81
|
+
|
82
|
+
@load_timeout = new_timeout
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
self.load_timeout = 5 # seconds
|
67
87
|
end
|
data/lib/hallon/album.rb
CHANGED
@@ -24,6 +24,7 @@ module Hallon
|
|
24
24
|
end
|
25
25
|
|
26
26
|
extend Linkable
|
27
|
+
include Loadable
|
27
28
|
|
28
29
|
to_link :from_album
|
29
30
|
|
@@ -77,18 +78,18 @@ module Hallon
|
|
77
78
|
Artist.from(artist)
|
78
79
|
end
|
79
80
|
|
80
|
-
#
|
81
|
-
#
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
81
|
+
# @see cover_link
|
82
|
+
# @return [Image, nil] album cover as an Image.
|
83
|
+
def cover
|
84
|
+
cover = Spotify.album_cover(pointer)
|
85
|
+
Image.from(cover)
|
86
|
+
end
|
87
|
+
|
88
|
+
# @see cover
|
89
|
+
# @return [Link, nil] album cover as a spotify URI.
|
90
|
+
def cover_link
|
91
|
+
cover = Spotify.link_create_from_album_cover!(pointer)
|
92
|
+
Link.from(cover)
|
92
93
|
end
|
93
94
|
|
94
95
|
# Browse the Album by creating an {AlbumBrowse} instance from it.
|
data/lib/hallon/album_browse.rb
CHANGED
data/lib/hallon/artist.rb
CHANGED
@@ -12,6 +12,7 @@ module Hallon
|
|
12
12
|
# @see http://developer.spotify.com/en/libspotify/docs/group__artist.html
|
13
13
|
class Artist < Base
|
14
14
|
extend Linkable
|
15
|
+
include Loadable
|
15
16
|
|
16
17
|
from_link :as_artist
|
17
18
|
to_link :from_artist
|
@@ -42,18 +43,18 @@ module Hallon
|
|
42
43
|
Spotify.artist_is_loaded(pointer)
|
43
44
|
end
|
44
45
|
|
45
|
-
#
|
46
|
-
#
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
46
|
+
# @see portrait_link
|
47
|
+
# @return [Image, nil] artist portrait as an Image.
|
48
|
+
def portrait
|
49
|
+
portrait = Spotify.artist_portrait(pointer)
|
50
|
+
Image.from(portrait)
|
51
|
+
end
|
52
|
+
|
53
|
+
# @see portrait
|
54
|
+
# @return [Link, nil] artist portrait as a Link.
|
55
|
+
def portrait_link
|
56
|
+
portrait = Spotify.link_create_from_artist_portrait!(pointer)
|
57
|
+
Link.from(portrait)
|
57
58
|
end
|
58
59
|
|
59
60
|
# Browse the Artist, giving you the ability to explore its’
|
data/lib/hallon/artist_browse.rb
CHANGED
data/lib/hallon/base.rb
CHANGED
data/lib/hallon/image.rb
CHANGED
@@ -13,6 +13,7 @@ module Hallon
|
|
13
13
|
to_link :from_image
|
14
14
|
|
15
15
|
extend Observable::Image
|
16
|
+
include Loadable
|
16
17
|
|
17
18
|
# Create a new instance of an Image.
|
18
19
|
#
|
@@ -54,11 +55,16 @@ module Hallon
|
|
54
55
|
Spotify.image_format(pointer)
|
55
56
|
end
|
56
57
|
|
57
|
-
# @
|
58
|
-
# @return [String] image ID as a
|
59
|
-
def id
|
60
|
-
|
61
|
-
|
58
|
+
# @see raw_id
|
59
|
+
# @return [String] image ID as a sequence of hexadecimal digits.
|
60
|
+
def id
|
61
|
+
to_hex(raw_id)
|
62
|
+
end
|
63
|
+
|
64
|
+
# @see id
|
65
|
+
# @return [String] image ID as a binary string.
|
66
|
+
def raw_id
|
67
|
+
Spotify.image_image_id(pointer)
|
62
68
|
end
|
63
69
|
|
64
70
|
# @return [String] raw image data as a binary encoded string.
|
@@ -75,19 +81,21 @@ module Hallon
|
|
75
81
|
# @return [Boolean]
|
76
82
|
def ==(other)
|
77
83
|
super or if other.is_a?(Image)
|
78
|
-
|
84
|
+
raw_id == other.raw_id
|
79
85
|
end
|
80
86
|
end
|
81
87
|
|
82
88
|
protected
|
83
|
-
# @
|
84
|
-
# @
|
89
|
+
# @see to_id
|
90
|
+
# @param [String] id an image id as a binary string
|
91
|
+
# @return [String] image id as a hexadecimal string
|
85
92
|
def to_hex(id)
|
86
93
|
id.unpack('H40')[0]
|
87
94
|
end
|
88
95
|
|
89
|
-
# @
|
90
|
-
# @
|
96
|
+
# @see to_hex
|
97
|
+
# @param [String] hex an image id as a hexadecimal string
|
98
|
+
# @return [String] image id as a binary string
|
91
99
|
def to_id(hex)
|
92
100
|
[hex].pack('H40')
|
93
101
|
end
|