Completed
Push — master ( 6965c0...6d2a19 )
by John
01:44 queued 54s
created

MultiAvatar.inflate_avatar_blob_png()   A

Complexity

Conditions 3

Size

Total Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
dl 0
loc 6
rs 9.4285
c 0
b 0
f 0
1
require 'avatarly'
2
require 'chunky_png'
3
require 'faraday'
4
require 'mime/types'
5
require 'ringcentral_sdk'
6
require 'ruby_identicon'
7
require 'tempfile'
8
9
module RingCentral
10
  module Avatars
11
    class Creator
0 ignored issues
show
Coding Style introduced by
This class should have a documentation comment as per coding style.
Loading history...
12
      DEFAULT_SIZE = 600
13
      DEFAULT_FORMAT = 'png'
14
      PNG_DEFAULT_METADATA = {
15
        'Description' => 'RingCentral Default Avatar'
16
      }
17
18
      attr_accessor :avatar_opts
19
      attr_accessor :avatars
20
      attr_accessor :client
21
      attr_accessor :extensions
22
      attr_accessor :png_metadata
23
24
      ##
25
      # Requires RingCentralSdk instance
26
      # `:avatar_opts` is optional to pass-through options for Avatarly
27
      def initialize(client, opts = {})
28
        @client = client
29
        if !opts.key?(:initials_opts) && opts.key?(:avatar_opts)
30
          opts[:initials_opts] = opts[:avatar_opts]
31
        end
32
        if opts.key(:png_metadata)
33
          opts[:png_metadata] = PNG_DEFAULT_METADATA.merge(opts[:png_metadata])
34
        else
35
          opts[:png_metadata] = PNG_DEFAULT_METADATA
36
        end
37
        @avatars = RingCentral::Avatars::MultiAvatar.new opts
38
        load_extensions
39
      end
40
41
      ##
42
      # Convenience method for creating default avatars for all extensions
43
      # Defaults to not overwriting existing avatars
44
      def create_defaults(opts = {})
45
        opts[:overwrite] = false
46
        create_all opts
47
      end
48
49
      ##
50
      # Convenience method for creating avatars for all extensions
51
      # Defaults to overwriting existing avatar
52
      def create_all(opts = {})
53
        opts[:overwrite] = true unless opts.key?(:overwrite)
54
        @extensions.extensions_hash.each do |ext_id, ext|
55
          create_avatar ext, opts
56
        end
57
        load_extensions
58
      end
59
60
      ##
61
      # Convenience method for creating avatar for authorized extension
62
      # Defaults to not overwriting existing avatar
63
      def create_mine(opts = {})
64
        res_ext = @client.http.get 'account/~/extension/~'
65
        res_av = create_avatar res_ext.body, opts
66
        load_extensions
67
        res_av
68
      end
69
70
      ##
71
      # Create the avatar for the extension.
72
      # Defaults to not overwriting existing avatar
73
      def create_avatar(ext, opts = {})
74
        opts[:overwrite] = false unless opts.key?(:overwrite)
75
        return if has_avatar(ext) && !opts[:overwrite]
76
        url = "account/~/extension/#{ext['id']}/profile-image"
77
        image = @avatars.avatar_faraday_uploadio ext['name']
78
        @client.http.put url, image: image
79
      end
80
81
      ##
82
      # Determines if extension has an existing avatar
83
      # Checks by looking for the presence of the `etag` property
84
      def has_avatar(ext)
0 ignored issues
show
Coding Style introduced by
Your coding style discourages the use of prefixes like is_ or has_ on predicates. Consider renaming has_avatar to avatar.
Loading history...
85
        ext['profileImage'].key?('etag') ? true : false
86
      end
87
88
      def load_extensions
89
        @extensions = RingCentralSdk::REST::Cache::Extensions.new client
90
        @extensions.retrieve_all
91
      end
92
93
      ##
94
      # Returns a list of avatar URLs which can be useful for testing purposes
95
      # Adding the current access token is optional
96
      def avatar_urls(opts = {})
97
        opts[:include_token] = false unless opts.key? :include_token
98
        urls = []
99
        @extensions.extensions_hash.keys.sort.each do |ext_id|
100
          ext = @extensions.extensions_hash[ext_id]
101
          urls.push avatar_url(ext, opts)
102
        end
103
        urls
104
      end
105
106
      def my_avatar_url(opts = {})
107
        opts[:include_token] = false unless opts.key? :include_token
108
        res = @client.http.get 'account/~/extension/~'
109
        avatar_url(res.body, opts)
110
      end
111
112
      def avatar_url(ext, opts = {})
113
        opts[:include_token] = false unless opts.key? :include_token
114
        token = @client.token.to_hash[:access_token]
115
        url = ext['profileImage']['uri']
116
        url += "?access_token=#{token}" if opts[:include_token]
117
        url
118
      end
119
    end
120
  end
121
end
122
123
module RingCentral
124
  module Avatars
125
    class MultiAvatar
0 ignored issues
show
Coding Style introduced by
This class should have a documentation comment as per coding style.
Loading history...
126
      DEFAULT_STYLE = 'initials'
127
      AVATARLY_DEFAULTS = {
128
        size: 600,
129
        format: 'png'
130
      }
131
      IDENTICON_DEFAULTS = {
132
        grid_size: 5,
133
        square_size: 70,
134
        background_color: 0xffffffff
135
      }
136
      IDENTICON_DEFAULT_FORMAT = 'png'
137
138
      def initialize(opts = {})
139
        @avatarly_opts =  inflate_avatarly_opts opts[:initials_opts]
140
        @identicon_opts = inflate_identicon_opts opts[:identicon_opts]
141
        @style = opts.key?(:style) ? opts[:style] : DEFAULT_STYLE
142
        @png_metadata = opts.key?(:png_metadata) ? opts[:png_metadata] : {}
143
      end
144
145
      def inflate_avatarly_opts(avatarly_opts = {})
146
        avatarly_opts = {} unless avatarly_opts.is_a? Hash
147
        AVATARLY_DEFAULTS.merge avatarly_opts
148
      end
149
150
      def inflate_identicon_opts(identicon_opts = {})
151
        identicon_opts = {} unless identicon_opts.is_a? Hash
152
        IDENTICON_DEFAULTS.merge identicon_opts
153
      end
154
155
      def avatar_blob(text, style = nil)
156
        style = @style if style.nil?
0 ignored issues
show
Unused Code introduced by
The assignment to the variable style has no effect on the outcome. Consider removing it.
Loading history...
157
        blob = @style == 'initials' \
0 ignored issues
show
Coding Style introduced by
Your coding style requires you to prefer if/unless over the ternary operator if the expression spans multiple lines.
Loading history...
158
          ? Avatarly.generate_avatar(text, @avatarly_opts) \
159
          : RubyIdenticon.create(text, @identicon_opts)
160
        inflate_avatar_blob_png blob
161
      end
162
163
      def inflate_avatar_blob_png(blob)
164
        return blob unless avatar_format == 'png' && @png_metadata
165
        img = ChunkyPNG::Image.from_blob blob
166
        img.metadata = @png_metadata
167
        img.to_blob
168
      end
169
170
      def avatar_temp_file(text, style = nil)
171
        blob = avatar_blob text, style
172
        file = Tempfile.new ['avatar', avatar_extension]
173
        file.binmode
174
        file.write blob
175
        file.flush
176
        file
177
      end
178
179
      def avatar_faraday_uploadio(text, style = nil)
180
        file = avatar_temp_file text, style
181
        image = Faraday::UploadIO.new file.path, avatar_mime_type
0 ignored issues
show
Unused Code introduced by
The assignment to the variable image has no effect on the outcome. Consider removing it.
Loading history...
182
      end
183
184
      def avatar_format
185
        @style == 'initials' ? @avatarly_opts[:format] : IDENTICON_DEFAULT_FORMAT
186
      end
187
188
      def avatar_mime_type
189
        types = MIME::Types.type_for avatar_format
190
        if types.length == 0
0 ignored issues
show
Coding Style introduced by
Consider using empty? instead of length == 0 to check for zero length.
Loading history...
191
          raise "Unknown avatar format: #{avatar_format}"
192
        end
193
        types[0].to_s
194
      end
195
196
      def avatar_extension
197
        ".#{avatar_format}"
198
      end
199
    end
200
  end
201
end