From f4fee25a62c2b0304a32fb4cd45e0fad4cdf3a8d Mon Sep 17 00:00:00 2001 From: Martin Edenhofer Date: Thu, 11 Oct 2012 13:55:51 +0200 Subject: [PATCH] Added datables postdater filters. --- .../_application_controller_form.js.coffee | 133 +++++++++++-- .../app/controllers/_channel/email.js.coffee | 106 ++++++++++- .../app/models/postmaster_filter.js.coffee | 17 ++ app/controllers/email_addresses_controller.rb | 16 +- .../postmaster_filters_controller.rb | 178 ++++++++++++++++++ app/models/channel/filter/database.rb | 28 ++- app/models/postmaster_filter.rb | 4 + config/routes/postmaster_filter.rb | 13 ++ ...20121008081936_postmaster_filter_create.rb | 22 +++ 9 files changed, 475 insertions(+), 42 deletions(-) create mode 100644 app/assets/javascripts/app/models/postmaster_filter.js.coffee create mode 100644 app/controllers/postmaster_filters_controller.rb create mode 100644 app/models/postmaster_filter.rb create mode 100644 config/routes/postmaster_filter.rb create mode 100644 db/migrate/20121008081936_postmaster_filter_create.rb diff --git a/app/assets/javascripts/app/controllers/_application_controller_form.js.coffee b/app/assets/javascripts/app/controllers/_application_controller_form.js.coffee index 0b7abd923..f309f537d 100644 --- a/app/assets/javascripts/app/controllers/_application_controller_form.js.coffee +++ b/app/assets/javascripts/app/controllers/_application_controller_form.js.coffee @@ -85,7 +85,6 @@ class App.ControllerForm extends App.Controller ### formGenItem: (attribute_config, classname, form ) -> - attribute = _.clone( attribute_config ) # create item id @@ -146,9 +145,8 @@ class App.ControllerForm extends App.Controller # finde selected/checked item of list @_selectedOptions( attribute ) - # boolean if attribute.tag is 'boolean' - + # build options list if _.isEmpty(attribute.options) attribute.options = [ @@ -172,6 +170,96 @@ class App.ControllerForm extends App.Controller else if attribute.tag is 'select' item = $( App.view('generic/select')( attribute: attribute ) ) + # select + else if attribute.tag is 'input_select' + item = $('
') + + # select shown attributes + loopData = {} + if @params && @params[ attribute.name ] + loopData = @params[ attribute.name ] + loopData[''] = '' + + # show each attribote + counter = 0 + for key of loopData + counter =+ 1 + @log 'kkk', key, loopData[ key ] + + # clone to keep it untouched for next loop + select = _.clone( attribute ) + input = _.clone( attribute ) + + # set field ids - not needed in this case + select.id = '' + input.id = '' + + # rename to be able to identify this option later + select.name = '{input_select}::' + select.name + input.name = '{input_select}::' + input.name + + # set sub attributes + for keysub of attribute.select + select[keysub] = attribute.select[keysub] + for keysub of attribute.input + input[keysub] = attribute.input[keysub] + + # set hide for + options + itemClass = '' + if key is '' + itemClass = 'hide' + select['nulloption'] = true + + # set selected value + select.value = key + input.value = loopData[ key ] + + # build options list based on config + @_getConfigOptionList( select ) + + # build options list based on relation + @_getRelationOptionList( select ) + + # add null selection if needed + @_addNullOption( select ) + + # sort attribute.options + @_sortOptions( select ) + + # finde selected/checked item of list + @_selectedOptions( select ) + + pearItem = $("
") + pearItem.append $( App.view('generic/select')( attribute: select ) ) + pearItem.append $( App.view('generic/input')( attribute: input ) ) + itemRemote = $('') + itemRemote.bind('click', (e) -> + e.preventDefault() + $(@).parent().remove() + ) + pearItem.append( itemRemote ) + item.append( pearItem ) + + if key is '' + itemAdd = $('
') + itemAdd.bind('click', (e) -> + e.preventDefault() + + # copy + newElement = $(@).prev().clone() + newElement.removeClass('hide') + + # bind on remove + newElement.find('.input_select_remove').bind('click', (e) -> + e.preventDefault() + $(@).parent().remove() + ) + + # prepend + $(@).parent().find('.add').before( newElement ) + ) + item.append( itemAdd ) + # checkbox else if attribute.tag is 'checkbox' item = $( App.view('generic/checkbox')( attribute: attribute ) ) @@ -192,7 +280,7 @@ class App.ControllerForm extends App.Controller @local_attribute = '#' + attribute.id @local_attribute_full = '#' + attribute.id + '_autocompletion' @callback = attribute.callback - + b = (event, key) => # set html form attribute @@ -224,10 +312,8 @@ class App.ControllerForm extends App.Controller @log 'selected', event, ui b(event, ui.item.id) ) - @delay(a, 600) - # input else item = $( App.view('generic/input')( attribute: attribute ) ) @@ -439,7 +525,8 @@ class App.ControllerForm extends App.Controller else console.log 'ERROR, no form found!', form - for key in form.serializeArray() + array = form.serializeArray() + for key in array if param[key.name] if typeof param[key.name] is 'string' param[key.name] = [ param[key.name], key.value] @@ -448,16 +535,40 @@ class App.ControllerForm extends App.Controller else # check boolean - boolean = key.value.split '::' - if boolean[0] is '{boolean}' - if boolean[1] is 'true' + attributeType = key.value.split '::' + if attributeType[0] is '{boolean}' + if attributeType[1] is 'true' key.value = true else key.value = false +# else if attributeType[0] is '{boolean}' param[key.name] = key.value -# console.log 'formParam', form, param + # check {input_select} + inputSelectObject = {} + for key of param + attributeType = key.split '::' + name = attributeType[1] + console.log 'split', key, attributeType, param[ name ] + if attributeType[0] is '{input_select}' && !param[ name ] + + # array need to be converted + inputSelectData = param[ key ] + inputSelectObject[ name ] = {} + for x in [0..inputSelectData.length] by 2 + console.log 'for by 111', x, inputSelectData, inputSelectData[x], inputSelectData[ x + 1 ] + if inputSelectData[ x ] + inputSelectObject[ name ][ inputSelectData[x] ] = inputSelectData[ x + 1 ] + + # remove {input_select} items + delete param[ key ] + + # set new {input_select} items + for key of inputSelectObject + param[ key ] = inputSelectObject[ key ] + + console.log 'formParam', form, param return param diff --git a/app/assets/javascripts/app/controllers/_channel/email.js.coffee b/app/assets/javascripts/app/controllers/_channel/email.js.coffee index f6808b236..8bda184ad 100644 --- a/app/assets/javascripts/app/controllers/_channel/email.js.coffee +++ b/app/assets/javascripts/app/controllers/_channel/email.js.coffee @@ -20,19 +20,20 @@ class App.ChannelEmail extends App.ControllerTabs target: 'c-outbound', controller: App.ChannelEmailOutbound, }, - { - name: 'Sigantures', - target: 'c-signature', - controller: App.ChannelEmailSignature, - }, { name: 'Adresses', target: 'c-address', controller: App.ChannelEmailAddress, }, { - name: 'Filter', - target: 'c-filter', + name: 'Sigantures', + target: 'c-signature', + controller: App.ChannelEmailSignature, + }, + { + name: 'Filter', + target: 'c-filter', + controller: App.ChannelEmailFilter, }, { name: 'Settings', @@ -44,6 +45,97 @@ class App.ChannelEmail extends App.ControllerTabs @render() +class App.ChannelEmailFilter extends App.Controller + events: + 'click [data-type=new]': 'new' + 'click [data-type=edit]': 'edit' + + constructor: -> + super + + App.PostmasterFilter.bind 'refresh change', @render + App.PostmasterFilter.fetch() + + render: => + data = App.PostmasterFilter.all() + + html = $('
') + + table = @table( + model: App.PostmasterFilter, + objects: data, + ) + + html.append( table ) + html.append( '' + T('New') + '' ) + @html html + + new: (e) => + e.preventDefault() + new App.ChannelEmailFilterEdit() + + edit: (e) => + e.preventDefault() + item = $(e.target).item( App.PostmasterFilter ) + new App.ChannelEmailFilterEdit( object: item ) + +class App.ChannelEmailFilterEdit extends App.ControllerModal + constructor: -> + super + @render(@object) + + render: (data = {}) -> + if @object + @html App.view('generic/admin/edit')( + head: 'Postmaster Filter' + ) + @form = new App.ControllerForm( + el: @el.find('#object_edit'), + model: App.PostmasterFilter, + params: @object, + autofocus: true, + ) + else + @html App.view('generic/admin/new')( + head: 'Postmaster Filter' + ) + @form = new App.ControllerForm( + el: @el.find('#object_new'), + model: App.PostmasterFilter, + autofocus: true, + ) + @modalShow() + + submit: (e) => + e.preventDefault() + + # get params + params = @formParam(e.target) + params['channel'] = 'email' + + object = @object || new App.PostmasterFilter + object.load(params) + + # validate form + errors = @form.validate( params ) + @log '11111', params, errors +# return false + # show errors in form + if errors + @log 'error new', errors + @formValidate( form: e.target, errors: errors ) + return false + + # save object + object.save( + success: => + @modalHide() + error: => + @log 'errors' + @modalHide() + ) + + class App.ChannelEmailAddress extends App.Controller events: 'click [data-type=new]': 'new' diff --git a/app/assets/javascripts/app/models/postmaster_filter.js.coffee b/app/assets/javascripts/app/models/postmaster_filter.js.coffee new file mode 100644 index 000000000..39f3f0667 --- /dev/null +++ b/app/assets/javascripts/app/models/postmaster_filter.js.coffee @@ -0,0 +1,17 @@ +class App.PostmasterFilter extends App.Model + @configure 'PostmasterFilter', 'name', 'channel', 'match', 'perform', 'note', 'active' + @extend Spine.Model.Ajax + @url: '/api/postmaster_filters' + + @configure_attributes = [ + { name: 'name', display: 'Name', tag: 'input', type: 'text', limit: 250, 'null': false, 'class': 'span4' }, + { name: 'channel', display: 'Channel', type: 'input', readonly: 1 }, + { name: 'match', display: 'Match all of the following', tag: 'input_select', select: { 'class': 'span2', options: { from: 'From', to: 'To', cc: 'Cc', subject: 'Subject', body: 'Body' }, multiple: false }, input: { limit: 250, type: 'text', 'class': 'span3' }, count_min: 2, count_max: 88, multiple: true, 'null': false, 'class': 'span4' }, + { name: 'perform', display: 'Perform action of the following', tag: 'input_select', select: { 'class': 'span2', options: { from: 'From', to: 'To', cc: 'Cc', subject: 'Subject', body: 'Body' }, multiple: false }, input: { limit: 250, type: 'text', 'class': 'span3' }, count_min: 2, count_max: 88, multiple: true, 'null': false, 'class': 'span4' }, + { name: 'note', display: 'Note', tag: 'textarea', note: 'Notes are visible to agents only, never to customers.', limit: 250, 'null': true, 'class': 'span4' }, + { name: 'updated_at', display: 'Updated', type: 'time', readonly: 1 }, + { name: 'active', display: 'Active', tag: 'boolean', type: 'boolean', 'default': true, 'null': false, 'class': 'span4' }, + ] + @configure_overview = [ + 'name', 'active' + ] diff --git a/app/controllers/email_addresses_controller.rb b/app/controllers/email_addresses_controller.rb index 1d2e304f1..fb8545bfa 100644 --- a/app/controllers/email_addresses_controller.rb +++ b/app/controllers/email_addresses_controller.rb @@ -22,7 +22,7 @@ Example: =begin Resource: -GET /api/email_address.json +GET /api/email_addresses.json Response: [ @@ -39,7 +39,7 @@ Response: ] Test: -curl http://localhost/api/email_address.json -v -u #{login}:#{password} +curl http://localhost/api/email_addresses.json -v -u #{login}:#{password} =end @@ -50,7 +50,7 @@ curl http://localhost/api/email_address.json -v -u #{login}:#{password} =begin Resource: -GET /api/email_address/#{id}.json +GET /api/email_addresses/#{id}.json Response: { @@ -60,7 +60,7 @@ Response: } Test: -curl http://localhost/api/email_address/#{id}.json -v -u #{login}:#{password} +curl http://localhost/api/email_addresses/#{id}.json -v -u #{login}:#{password} =end @@ -71,7 +71,7 @@ curl http://localhost/api/email_address/#{id}.json -v -u #{login}:#{password} =begin Resource: -POST /api/email_address.json +POST /api/email_addresses.json Payload: { @@ -90,7 +90,7 @@ Response: } Test: -curl http://localhost/api/email_address.json -v -u #{login}:#{password} -H "Content-Type: application/json" -X POST -d '{"name": "some_name","active": true, "note": "some note"}' +curl http://localhost/api/email_addresses.json -v -u #{login}:#{password} -H "Content-Type: application/json" -X POST -d '{"name": "some_name","active": true, "note": "some note"}' =end @@ -101,7 +101,7 @@ curl http://localhost/api/email_address.json -v -u #{login}:#{password} -H "Cont =begin Resource: -PUT /api/email_address/{id}.json +PUT /api/email_addresses/{id}.json Payload: { @@ -120,7 +120,7 @@ Response: } Test: -curl http://localhost/api/email_address.json -v -u #{login}:#{password} -H "Content-Type: application/json" -X PUT -d '{"name": "some_name","active": true, "note": "some note"}' +curl http://localhost/api/email_addresses.json -v -u #{login}:#{password} -H "Content-Type: application/json" -X PUT -d '{"name": "some_name","active": true, "note": "some note"}' =end diff --git a/app/controllers/postmaster_filters_controller.rb b/app/controllers/postmaster_filters_controller.rb new file mode 100644 index 000000000..0be921dcd --- /dev/null +++ b/app/controllers/postmaster_filters_controller.rb @@ -0,0 +1,178 @@ +class PostmasterFiltersController < ApplicationController + before_filter :authentication_check + +=begin + +Format: +JSON + +Example: +{ + "id":1, + "name":"some name", + "type":"email", + "match":{ + "From":"some@example.com" + }, + "perform":{ + "x-zammad-priority":"3 high" + }, + "note":"", + "active":true, + "updated_at":"2012-09-14T17:51:53Z", + "created_at":"2012-09-14T17:51:53Z", + "updated_by_id":2, + "created_by_id":2, +} + +=end + +=begin + +Resource: +GET /api/postmaster_filters.json + +Response: +[ + { + "id": 1, + "name":"some name", + ... + }, + { + "id": 2, + "name":"some name", + ... + } +] + +Test: +curl http://localhost/api/postmaster_filters.json -v -u #{login}:#{password} + +=end + + def index + model_index_render(PostmasterFilter, params) + end + +=begin + +Resource: +GET /api/postmaster_filters/#{id}.json + +Response: +{ + "id": 1, + "name": "name_1", + ... +} + +Test: +curl http://localhost/api/postmaster_filters/#{id}.json -v -u #{login}:#{password} + +=end + + def show + model_show_render(PostmasterFilter, params) + end + +=begin + +Resource: +POST /api/postmaster_filters.json + +Payload: +{ + "name":"some name", + "type":"email", + "match":{ + "From":"some@example.com" + }, + "perform":{ + "x-zammad-priority":"3 high" + }, + "note":"", + "active":true, +} + +Response: +{ + "id": 1, + "name":"some name", + "type":"email", + "match":{ + "From":"some@example.com" + }, + "perform":{ + "x-zammad-priority":"3 high" + }, + "note": "", + "active":true, + ... +} + +Test: +curl http://localhost/api/postmaster_filters.json -v -u #{login}:#{password} -H "Content-Type: application/json" -X POST -d '{"name": "some_name","active": true, "note": "some note"}' + +=end + + def create + model_create_render(PostmasterFilter, params) + end + +=begin + +Resource: +PUT /api/postmaster_filters/{id}.json + +Payload: +{ + "name":"some name", + "match":{ + "From":"some@example.com" + }, + "perform":{ + "x-zammad-priority":"3 high" + }, + "note":"", + "active":true, +} + +Response: +{ + "id": 1, + "name":"some name", + "match":{ + "From":"some@example.com" + }, + "perform":{ + "x-zammad-priority":"3 high" + }, + "note":"", + "active":true, + ... +} + +Test: +curl http://localhost/api/postmaster_filters.json -v -u #{login}:#{password} -H "Content-Type: application/json" -X PUT -d '{"name": "some_name","active": true, "note": "some note"}' + +=end + + def update + model_update_render(PostmasterFilter, params) + end + +=begin + +Resource: + +Response: + +Test: + +=end + + def destroy + model_destory_render(PostmasterFilter, params) + end +end diff --git a/app/models/channel/filter/database.rb b/app/models/channel/filter/database.rb index c41631383..f5e4ca265 100644 --- a/app/models/channel/filter/database.rb +++ b/app/models/channel/filter/database.rb @@ -4,25 +4,20 @@ module Channel::Filter::Database def self.run( channel, mail ) # process postmaster filter - filters = [ - { - :name => 'some name', - :match => { - 'from' => 'martin', - }, - :set => { - 'x-zammad-priority' => '3 high', - } - }, - ] - + filters = PostmasterFilter.where( :active => true, :channel => 'email' ) filters.each {|filter| + puts " proccess filter #{filter.name} ..." match = true + loop = false filter[:match].each {|key, value| + loop = true begin - if match && mail[ key.to_sym ].scan(/#{value}/i) + scan = mail[ key.downcase.to_sym ].scan(/#{value}/i) + if match && scan[0] + puts " matching #{ key.downcase }:'#{ mail[ key.downcase.to_sym ] }' on #{value}" match = true else + puts " is not matching #{ key.downcase }:'#{ mail[ key.downcase.to_sym ] }' on #{value}" match = false end rescue Exception => e @@ -31,9 +26,10 @@ module Channel::Filter::Database puts e.inspect end } - if match - filter[:set].each {|key, value| - mail[ key.to_sym ] = value + if loop && match + filter[:perform].each {|key, value| + puts " perform '#{ key.downcase }' = '#{value}'" + mail[ key.downcase.to_sym ] = value } end } diff --git a/app/models/postmaster_filter.rb b/app/models/postmaster_filter.rb new file mode 100644 index 000000000..09fe4d72e --- /dev/null +++ b/app/models/postmaster_filter.rb @@ -0,0 +1,4 @@ +class PostmasterFilter < ApplicationModel + store :perform + store :match +end diff --git a/config/routes/postmaster_filter.rb b/config/routes/postmaster_filter.rb new file mode 100644 index 000000000..1eb7ba850 --- /dev/null +++ b/config/routes/postmaster_filter.rb @@ -0,0 +1,13 @@ +module ExtraRoutes + def add(map) + + # postmaster_filters + map.match '/api/postmaster_filters', :to => 'postmaster_filters#index', :via => :get + map.match '/api/postmaster_filters/:id', :to => 'postmaster_filters#show', :via => :get + map.match '/api/postmaster_filters', :to => 'postmaster_filters#create', :via => :post + map.match '/api/postmaster_filters/:id', :to => 'postmaster_filters#update', :via => :put + map.match '/api/postmaster_filters/:id', :to => 'postmaster_filters#destroy', :via => :delete + + end + module_function :add +end \ No newline at end of file diff --git a/db/migrate/20121008081936_postmaster_filter_create.rb b/db/migrate/20121008081936_postmaster_filter_create.rb new file mode 100644 index 000000000..cdb7ec9aa --- /dev/null +++ b/db/migrate/20121008081936_postmaster_filter_create.rb @@ -0,0 +1,22 @@ +class PostmasterFilterCreate < ActiveRecord::Migration + def up + create_table :postmaster_filters do |t| + t.column :name, :string, :limit => 250, :null => false + t.column :channel, :string, :limit => 250, :null => false + t.column :match, :string, :limit => 5000, :null => false + t.column :perform, :string, :limit => 5000, :null => false + t.column :active, :boolean, :null => false, :default => true + t.column :note, :string, :limit => 250, :null => true + t.column :updated_by_id, :integer, :null => false + t.column :created_by_id, :integer, :null => false + t.timestamps + end + add_index :postmaster_filters, [:channel] + +# add_column :groups, :email_address_id, :integer, :null => true + + end + + def down + end +end