hallon 0.13.0 → 0.14.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (44) hide show
  1. data/CHANGELOG.md +43 -1
  2. data/Gemfile +0 -2
  3. data/LICENSE.txt +1 -1
  4. data/README.markdown +94 -44
  5. data/examples/playing_audio.rb +4 -5
  6. data/lib/hallon.rb +20 -0
  7. data/lib/hallon/album.rb +13 -12
  8. data/lib/hallon/album_browse.rb +1 -0
  9. data/lib/hallon/artist.rb +13 -12
  10. data/lib/hallon/artist_browse.rb +1 -0
  11. data/lib/hallon/base.rb +2 -0
  12. data/lib/hallon/image.rb +18 -10
  13. data/lib/hallon/loadable.rb +24 -0
  14. data/lib/hallon/observable.rb +1 -1
  15. data/lib/hallon/observable/playlist.rb +10 -16
  16. data/lib/hallon/observable/playlist_container.rb +12 -6
  17. data/lib/hallon/player.rb +3 -3
  18. data/lib/hallon/playlist.rb +34 -11
  19. data/lib/hallon/playlist_container.rb +10 -4
  20. data/lib/hallon/search.rb +1 -0
  21. data/lib/hallon/session.rb +2 -2
  22. data/lib/hallon/toplist.rb +17 -12
  23. data/lib/hallon/track.rb +1 -0
  24. data/lib/hallon/user.rb +48 -11
  25. data/lib/hallon/version.rb +1 -1
  26. data/spec/hallon/album_browse_spec.rb +2 -0
  27. data/spec/hallon/album_spec.rb +14 -7
  28. data/spec/hallon/artist_browse_spec.rb +2 -0
  29. data/spec/hallon/artist_spec.rb +14 -8
  30. data/spec/hallon/hallon_spec.rb +12 -0
  31. data/spec/hallon/image_spec.rb +18 -9
  32. data/spec/hallon/loadable_spec.rb +46 -0
  33. data/spec/hallon/observable/playlist_spec.rb +11 -5
  34. data/spec/hallon/observable_spec.rb +6 -0
  35. data/spec/hallon/playlist_container_spec.rb +6 -0
  36. data/spec/hallon/playlist_spec.rb +21 -4
  37. data/spec/hallon/search_spec.rb +2 -0
  38. data/spec/hallon/toplist_spec.rb +40 -23
  39. data/spec/hallon/track_spec.rb +2 -0
  40. data/spec/hallon/user_post_spec.rb +75 -0
  41. data/spec/hallon/user_spec.rb +7 -11
  42. data/spec/spec_helper.rb +2 -2
  43. metadata +20 -16
  44. 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
- [HEAD]: https://github.com/Burgestrand/Hallon/compare/v0.12.0...HEAD
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
@@ -4,6 +4,4 @@ gemspec
4
4
  gem 'ruby_parser'
5
5
  gem 'pry'
6
6
  gem 'cover_me', :platform => :ruby_19
7
- gem 'coreaudio', :platform => :ruby_19 if RUBY_PLATFORM =~ /darwin/i
8
- gem 'hallon-openal'
9
7
  gem 'rb-readline'
data/LICENSE.txt CHANGED
@@ -1,4 +1,4 @@
1
- Copyright 2011 Kim Burgestrand. All rights reserved.
1
+ Copyright 2012 Kim Burgestrand. All rights reserved.
2
2
 
3
3
  Redistribution and use in source and binary forms, with or without modification, are
4
4
  permitted provided that the following conditions are met:
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 — which is Swedish for “[Raspberry][]” is a ruby gem for interacting with the official Spotify C API. It is written on top of [Spotify for Ruby][], with the goal of making the experience of using `libspotify` as enjoyable as it can be.
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
- gem install hallon
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
- gem install hallon-openal
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
- gem install hallon-openal
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
- This is awesome! I want to help!
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
- ### Hallon is unstable
68
- The API is unstable, my code is likely unstable. Everything should be considered unstable!
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
- ### Hallon only supports one session per process
71
- You can only keep one session with Spotify alive at a time within the same process, due to a limitation of `libspotify`.
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
- ### You still have to worry about threads
74
- I have been doing my best at hiding the complexity in `libspotify`, but it’s still a work in progress. Despite my efforts, you’ll need to be familiar with concurrent programming to use Hallon properly.
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
- Versioning policy
80
- -----------------
81
- Hallon uses [semantic versioning](http://semver.org) as of v0.0.0. As long
82
- as Hallon stays at major version 0, no guarantees of backwards-compatibility
83
- are made. `CHANGELOG.md` will be kept up to date with the different versions.
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
@@ -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
- require_relative 'audio_driver'
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
- driver = defined?(Hallon::OpenAL) ? Hallon::OpenAL : Hallon::CoreAudio
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
- # Retrieves album cover art as an {Image} or a {Link}.
81
- #
82
- # @param [Boolean] as_image true if you want it as an {Image}.
83
- # @return [Image, Link, nil] album cover, the link to it, or nil.
84
- def cover(as_image = true)
85
- if as_image
86
- cover = Spotify.album_cover(pointer)
87
- Image.from(cover)
88
- else
89
- cover = Spotify.link_create_from_album_cover!(pointer)
90
- Link.from(cover)
91
- end
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.
@@ -26,6 +26,7 @@ module Hallon
26
26
  end
27
27
 
28
28
  extend Observable::AlbumBrowse
29
+ include Loadable
29
30
 
30
31
  # Creates an AlbumBrowse instance from an Album or an Album pointer.
31
32
  #
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
- # Retrieve artist portrait as an {Image} or a {Link}.
46
- #
47
- # @param [Boolean] as_image true if you want it as an Image
48
- # @return [Image, Link, nil] artist portrait, the link to it, or nil.
49
- def portrait(as_image = true)
50
- if as_image
51
- portrait = Spotify.artist_portrait(pointer)
52
- Image.from(portrait)
53
- else
54
- portrait = Spotify.link_create_from_artist_portrait!(pointer)
55
- Link.from(portrait)
56
- end
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’
@@ -56,6 +56,7 @@ module Hallon
56
56
  end
57
57
 
58
58
  extend Observable::ArtistBrowse
59
+ include Loadable
59
60
 
60
61
  # @return [Array<Symbol>] artist browsing types for use in {#initialize}
61
62
  def self.types
data/lib/hallon/base.rb CHANGED
@@ -1,4 +1,6 @@
1
1
  # coding: utf-8
2
+ require 'timeout'
3
+
2
4
  module Hallon
3
5
  # All objects in Hallon are mere representations of Spotify objects.
4
6
  # Hallon::Base covers basic functionality shared by all of these.
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
- # @param [Boolean] raw true if you want the image id as a hexadecimal string
58
- # @return [String] image ID as a string.
59
- def id(raw = false)
60
- id = Spotify.image_image_id(pointer)
61
- raw ? id : to_hex(id)
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
- id(true) == other.id(true)
84
+ raw_id == other.raw_id
79
85
  end
80
86
  end
81
87
 
82
88
  protected
83
- # @param [String]
84
- # @return [String]
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
- # @param [String]
90
- # @return [String]
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