diff --git a/app/assets/javascripts/app/controllers/getting_started.js.coffee b/app/assets/javascripts/app/controllers/getting_started.js.coffee index 6cf1dd93b..5b74e861a 100644 --- a/app/assets/javascripts/app/controllers/getting_started.js.coffee +++ b/app/assets/javascripts/app/controllers/getting_started.js.coffee @@ -216,9 +216,13 @@ class Base extends App.ControllerContent else url = "#{http_type}://#{fqdn}" + logoFile = App.Config.get('product_logo') + logoUrl = App.Config.get('image_path') + "/#{logoFile}" + organization = App.Config.get('organization') @html App.view('getting_started/base')( url: url + logoUrl: logoUrl organization: organization ) @$("input, select").first().focus() @@ -237,7 +241,7 @@ class Base extends App.ControllerContent if !file return - maxSiteInMb = 3 + maxSiteInMb = 8 if file.size && file.size > 1024 * 1024 * maxSiteInMb @showAlert( 'logo', App.i18n.translateInline( 'File too big, max. %s MB allowed.', maxSiteInMb ) ) @logoPreview.attr( 'src', '' ) @@ -250,8 +254,15 @@ class Base extends App.ControllerContent # get params params = @formParam(e.target) + + # add logo params['logo'] = @logoPreview.attr('src') + # add resized image + if params['logo'] + resizeLogo = new App.ImageService( params['logo'] ) + params['logo_resize'] = resizeLogo.toDataURLForApp( @logoPreview.width(), @logoPreview.height() ) + @hideAlerts() @disable(e) diff --git a/app/assets/javascripts/app/controllers/login.js.coffee b/app/assets/javascripts/app/controllers/login.js.coffee index 86920ce6b..39572415c 100644 --- a/app/assets/javascripts/app/controllers/login.js.coffee +++ b/app/assets/javascripts/app/controllers/login.js.coffee @@ -50,11 +50,15 @@ class Index extends App.ControllerContent } auth_providers = [] for key, provider of auth_provider_all - if @Config.get( provider.config ) is true || @Config.get( provider.config ) is "true" + if @Config.get( provider.config ) is true || @Config.get( provider.config ) is 'true' auth_providers.push provider + logoFile = App.Config.get('product_logo') + logoUrl = App.Config.get('image_path') + "/#{logoFile}" + @html App.view('login')( item: data + logoUrl: logoUrl auth_providers: auth_providers ) diff --git a/app/assets/javascripts/app/lib/app_post/image_service.js.coffee b/app/assets/javascripts/app/lib/app_post/image_service.js.coffee new file mode 100644 index 000000000..ab20ee4d9 --- /dev/null +++ b/app/assets/javascripts/app/lib/app_post/image_service.js.coffee @@ -0,0 +1,46 @@ +class App.ImageService + constructor: (url) -> + @orgDataURL = url + + src: (url) => + @orgDataURL = url + + resize: ( x = 'auto', y = 'auto') => + @canvas = document.createElement('canvas') + context = @canvas.getContext('2d') + + # load image from data url + imageObject = new Image() + imageObject.src = @orgDataURL + imageWidth = imageObject.width + imageHeight = imageObject.height + + if y is 'auto' && x is 'auto' + x = imageWidth + y = imageHeight + + # get auto dimensions + if y is 'auto' + factor = imageWidth / x + y = imageHeight / factor + + if x is 'auto' + factor = imageWidth / y + x = imageHeight / factor + + console.log('BB', x, y) + # set canvas dimensions + @canvas.width = x + @canvas.height = y + + # draw image on canvas and set image dimensions + context.drawImage( imageObject, 0, 0, x, y ) + @canvas + + toDataURL: (type, quallity = 1) => + #@resize() + @canvas.toDataURL( type, quallity ) + + toDataURLForApp: ( x, y ) => + @resize( x * 2, y * 2 ) + @toDataURL( 'image/jpeg', 0.7 ) diff --git a/app/assets/javascripts/app/views/getting_started/base.jst.eco b/app/assets/javascripts/app/views/getting_started/base.jst.eco index cc70e48ff..24cf64be7 100644 --- a/app/assets/javascripts/app/views/getting_started/base.jst.eco +++ b/app/assets/javascripts/app/views/getting_started/base.jst.eco @@ -13,7 +13,7 @@
- +
<%- @T('Your Logo') %>
<%- @T('Upload') %>
diff --git a/app/assets/javascripts/app/views/login.jst.eco b/app/assets/javascripts/app/views/login.jst.eco index 9a4c802bc..1906a8898 100644 --- a/app/assets/javascripts/app/views/login.jst.eco +++ b/app/assets/javascripts/app/views/login.jst.eco @@ -3,7 +3,7 @@

<%- @T( 'Login with %s', @C( 'fqdn' ) ) %>

- +
diff --git a/app/controllers/getting_started_controller.rb b/app/controllers/getting_started_controller.rb index 7e10fe1ee..9a814ca51 100644 --- a/app/controllers/getting_started_controller.rb +++ b/app/controllers/getting_started_controller.rb @@ -106,27 +106,28 @@ curl http://localhost/api/v1/getting_started -v -u #{login}:#{password} # save image if params[:logo] && !params[:logo].empty? - content_type = nil - content = nil # data:image/png;base64 - if params[:logo] =~ /^data:(.+?);base64,(.+?)$/ - content_type = $1 - content = Base64.decode64($2) - end - Store.remove( :object => 'System::Logo', :o_id => 1 ) - Store.add( - :object => 'System::Logo', - :o_id => 1, - :data => content, - :filename => 'image', - :preferences => { - 'Content-Type' => content_type - }, -# :created_by_id => self.updated_by_id, - ) + file = StaticAssets.data_url_attributes( params[:logo] ) + + # store image 1:1 + StaticAssets.store_raw( file[:content], file[:content_type] ) end + if params[:logo_resize] && !params[:logo_resize].empty? + + # data:image/png;base64 + file = StaticAssets.data_url_attributes( params[:logo_resize] ) + + # store image 1:1 + settings[:product_logo] = StaticAssets.store( file[:content], file[:content_type] ) + end + + # set changed settings + settings.each {|key, value| + Setting.set(key, value) + } + render :json => { :result => 'ok', :settings => settings, diff --git a/app/controllers/sessions_controller.rb b/app/controllers/sessions_controller.rb index 9fef0f8fc..976cb584e 100644 --- a/app/controllers/sessions_controller.rb +++ b/app/controllers/sessions_controller.rb @@ -279,45 +279,4 @@ class SessionsController < ApplicationController render :json => {} end -=begin - -Resource: -GET /api/v1/sessions/logo - -Response: - - -Test: -curl http://localhost/api/v1/sessions/logo - -=end - - def logo - - # cache image - #response.headers['Expires'] = 1.year.from_now.httpdate - #response.headers["Cache-Control"] = "cache, store, max-age=31536000, must-revalidate" - #response.headers["Pragma"] = "cache" - - # find logo - list = Store.list( :object => 'System::Logo', :o_id => 2 ) - if list && list[0] - file = Store.find( list[0] ) - send_data( - file.content, - :filename => file.filename, - :type => file.preferences['Content-Type'], - :disposition => 'inline' - ) - return - end - - # serve default image - send_data( - '', - :filename => '', - :type => 'image/gif', - :disposition => 'inline' - ) - end -end +end \ No newline at end of file diff --git a/config/initializers/logo.rb b/config/initializers/logo.rb new file mode 100644 index 000000000..d1e9f38b1 --- /dev/null +++ b/config/initializers/logo.rb @@ -0,0 +1,2 @@ +# sync logo to fs +StaticAssets.sync \ No newline at end of file diff --git a/config/routes/auth.rb b/config/routes/auth.rb index a89ca2cf1..31b6717fd 100644 --- a/config/routes/auth.rb +++ b/config/routes/auth.rb @@ -15,7 +15,6 @@ Zammad::Application.routes.draw do match api_path + '/sessions/switch/:id', :to => 'sessions#switch_to_user', :via => :get match api_path + '/sessions/switch_back', :to => 'sessions#switch_back_to_user', :via => :get match api_path + '/sessions', :to => 'sessions#list', :via => :get - match api_path + '/sessions/logo', :to => 'sessions#logo', :via => :get match api_path + '/sessions/:id', :to => 'sessions#delete', :via => :delete end \ No newline at end of file diff --git a/db/migrate/20141119000001_update_setting2.rb b/db/migrate/20141119000001_update_setting2.rb new file mode 100644 index 000000000..2ddb41eb3 --- /dev/null +++ b/db/migrate/20141119000001_update_setting2.rb @@ -0,0 +1,25 @@ +class UpdateSetting2 < ActiveRecord::Migration + def up + Setting.create_if_not_exists( + :title => 'Logo', + :name => 'product_logo', + :area => 'System::CI', + :description => 'Defines the logo of the application, shown in the web interface.', + :options => { + :form => [ + { + :display => '', + :null => false, + :name => 'product_logo', + :tag => 'input', + }, + ], + }, + :state => 'logo.svg', + :frontend => true + ) + end + + def down + end +end \ No newline at end of file diff --git a/db/seeds.rb b/db/seeds.rb index b67f44ed5..0314b8533 100644 --- a/db/seeds.rb +++ b/db/seeds.rb @@ -33,6 +33,24 @@ Setting.create_if_not_exists( :state => 'Zammad', :frontend => true ) +Setting.create_if_not_exists( + :title => 'Logo', + :name => 'product_logo', + :area => 'System::CI', + :description => 'Defines the logo of the application, shown in the web interface.', + :options => { + :form => [ + { + :display => '', + :null => false, + :name => 'product_logo', + :tag => 'input', + }, + ], + }, + :state => 'logo.svg', + :frontend => true +) Setting.create_if_not_exists( :title => 'Organization', diff --git a/lib/static_assets.rb b/lib/static_assets.rb new file mode 100644 index 000000000..7be1464fc --- /dev/null +++ b/lib/static_assets.rb @@ -0,0 +1,75 @@ +module StaticAssets + + def self.data_url_attributes( data_url ) + data = {} + if data_url =~ /^data:(.+?);base64,(.+?)$/ + data[:content_type] = $1 + data[:content] = Base64.decode64($2) + return data + end + raise "Unable to parse data url: #{data_url.substr(0,100)}" + end + + # store image 1:1 + def self.store_raw( content, content_type ) + Store.remove( :object => 'System::Logo', :o_id => 1 ) + Store.add( + :object => 'System::Logo', + :o_id => 1, + :data => content, + :filename => 'image', + :preferences => { + 'Content-Type' => content_type + }, + ) + Digest::MD5.hexdigest( content ) + end + + # read raw 1:1 + def self.read_raw + list = Store.list( :object => 'System::Logo', :o_id => 1 ) + if list && list[0] + return Store.find( list[0] ) + end + raise "No such raw logo!" + end + + # store image in right size + def self.store( content, content_type ) + Store.remove( :object => 'System::Logo', :o_id => 2 ) + Store.add( + :object => 'System::Logo', + :o_id => 2, + :data => content, + :filename => 'image', + :preferences => { + 'Content-Type' => content_type + }, + ) + StaticAssets.sync + Digest::MD5.hexdigest( content ) + end + + # read image + def self.read + list = Store.list( :object => 'System::Logo', :o_id => 2 ) + if list && list[0] + file = Store.find( list[0] ) + hash = Digest::MD5.hexdigest( file.content ) + Setting.set('product_logo', hash) + return file + end + end + + # sync image to fs + def self.sync + file = read + return if !file + + hash = Digest::MD5.hexdigest( file.content ) + path = "#{Rails.root.to_s}/public/assets/#{hash}" + File.open( path, 'wb' ) do |f| + f.puts file.content + end + end +end \ No newline at end of file