Completed
Push — master ( 33eb1a...ae01e8 )
by John
01:51 queued 50s
created

Creator.avatar_urls()   A

Complexity

Conditions 2

Size

Total Lines 9

Duplication

Lines 0
Ratio 0 %

Importance

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