Added datables postdater filters.

This commit is contained in:
Martin Edenhofer 2012-10-11 13:55:51 +02:00
parent d2390521aa
commit f4fee25a62
9 changed files with 475 additions and 42 deletions

View file

@ -85,7 +85,6 @@ class App.ControllerForm extends App.Controller
### ###
formGenItem: (attribute_config, classname, form ) -> formGenItem: (attribute_config, classname, form ) ->
attribute = _.clone( attribute_config ) attribute = _.clone( attribute_config )
# create item id # create item id
@ -146,7 +145,6 @@ class App.ControllerForm extends App.Controller
# finde selected/checked item of list # finde selected/checked item of list
@_selectedOptions( attribute ) @_selectedOptions( attribute )
# boolean
if attribute.tag is 'boolean' if attribute.tag is 'boolean'
# build options list # build options list
@ -172,6 +170,96 @@ class App.ControllerForm extends App.Controller
else if attribute.tag is 'select' else if attribute.tag is 'select'
item = $( App.view('generic/select')( attribute: attribute ) ) item = $( App.view('generic/select')( attribute: attribute ) )
# select
else if attribute.tag is 'input_select'
item = $('<div class="input_select"></div>')
# 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 = $("<div class=" + itemClass + "></div>")
pearItem.append $( App.view('generic/select')( attribute: select ) )
pearItem.append $( App.view('generic/input')( attribute: input ) )
itemRemote = $('<a href="#" class="input_select_remove icon-minus"></a>')
itemRemote.bind('click', (e) ->
e.preventDefault()
$(@).parent().remove()
)
pearItem.append( itemRemote )
item.append( pearItem )
if key is ''
itemAdd = $('<div class="add"><a href="#" class="icon-plus"></a></div>')
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 # checkbox
else if attribute.tag is 'checkbox' else if attribute.tag is 'checkbox'
item = $( App.view('generic/checkbox')( attribute: attribute ) ) item = $( App.view('generic/checkbox')( attribute: attribute ) )
@ -224,10 +312,8 @@ class App.ControllerForm extends App.Controller
@log 'selected', event, ui @log 'selected', event, ui
b(event, ui.item.id) b(event, ui.item.id)
) )
@delay(a, 600) @delay(a, 600)
# input # input
else else
item = $( App.view('generic/input')( attribute: attribute ) ) item = $( App.view('generic/input')( attribute: attribute ) )
@ -439,7 +525,8 @@ class App.ControllerForm extends App.Controller
else else
console.log 'ERROR, no form found!', form console.log 'ERROR, no form found!', form
for key in form.serializeArray() array = form.serializeArray()
for key in array
if param[key.name] if param[key.name]
if typeof param[key.name] is 'string' if typeof param[key.name] is 'string'
param[key.name] = [ param[key.name], key.value] param[key.name] = [ param[key.name], key.value]
@ -448,16 +535,40 @@ class App.ControllerForm extends App.Controller
else else
# check boolean # check boolean
boolean = key.value.split '::' attributeType = key.value.split '::'
if boolean[0] is '{boolean}' if attributeType[0] is '{boolean}'
if boolean[1] is 'true' if attributeType[1] is 'true'
key.value = true key.value = true
else else
key.value = false key.value = false
# else if attributeType[0] is '{boolean}'
param[key.name] = key.value 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 return param

View file

@ -20,19 +20,20 @@ class App.ChannelEmail extends App.ControllerTabs
target: 'c-outbound', target: 'c-outbound',
controller: App.ChannelEmailOutbound, controller: App.ChannelEmailOutbound,
}, },
{
name: 'Sigantures',
target: 'c-signature',
controller: App.ChannelEmailSignature,
},
{ {
name: 'Adresses', name: 'Adresses',
target: 'c-address', target: 'c-address',
controller: App.ChannelEmailAddress, controller: App.ChannelEmailAddress,
}, },
{
name: 'Sigantures',
target: 'c-signature',
controller: App.ChannelEmailSignature,
},
{ {
name: 'Filter', name: 'Filter',
target: 'c-filter', target: 'c-filter',
controller: App.ChannelEmailFilter,
}, },
{ {
name: 'Settings', name: 'Settings',
@ -44,6 +45,97 @@ class App.ChannelEmail extends App.ControllerTabs
@render() @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 = $('<div></div>')
table = @table(
model: App.PostmasterFilter,
objects: data,
)
html.append( table )
html.append( '<a data-type="new" class="btn">' + T('New') + '</a>' )
@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 class App.ChannelEmailAddress extends App.Controller
events: events:
'click [data-type=new]': 'new' 'click [data-type=new]': 'new'

View file

@ -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'
]

View file

@ -22,7 +22,7 @@ Example:
=begin =begin
Resource: Resource:
GET /api/email_address.json GET /api/email_addresses.json
Response: Response:
[ [
@ -39,7 +39,7 @@ Response:
] ]
Test: Test:
curl http://localhost/api/email_address.json -v -u #{login}:#{password} curl http://localhost/api/email_addresses.json -v -u #{login}:#{password}
=end =end
@ -50,7 +50,7 @@ curl http://localhost/api/email_address.json -v -u #{login}:#{password}
=begin =begin
Resource: Resource:
GET /api/email_address/#{id}.json GET /api/email_addresses/#{id}.json
Response: Response:
{ {
@ -60,7 +60,7 @@ Response:
} }
Test: 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 =end
@ -71,7 +71,7 @@ curl http://localhost/api/email_address/#{id}.json -v -u #{login}:#{password}
=begin =begin
Resource: Resource:
POST /api/email_address.json POST /api/email_addresses.json
Payload: Payload:
{ {
@ -90,7 +90,7 @@ Response:
} }
Test: 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 =end
@ -101,7 +101,7 @@ curl http://localhost/api/email_address.json -v -u #{login}:#{password} -H "Cont
=begin =begin
Resource: Resource:
PUT /api/email_address/{id}.json PUT /api/email_addresses/{id}.json
Payload: Payload:
{ {
@ -120,7 +120,7 @@ Response:
} }
Test: 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 =end

View file

@ -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

View file

@ -4,25 +4,20 @@ module Channel::Filter::Database
def self.run( channel, mail ) def self.run( channel, mail )
# process postmaster filter # process postmaster filter
filters = [ filters = PostmasterFilter.where( :active => true, :channel => 'email' )
{
:name => 'some name',
:match => {
'from' => 'martin',
},
:set => {
'x-zammad-priority' => '3 high',
}
},
]
filters.each {|filter| filters.each {|filter|
puts " proccess filter #{filter.name} ..."
match = true match = true
loop = false
filter[:match].each {|key, value| filter[:match].each {|key, value|
loop = true
begin 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 match = true
else else
puts " is not matching #{ key.downcase }:'#{ mail[ key.downcase.to_sym ] }' on #{value}"
match = false match = false
end end
rescue Exception => e rescue Exception => e
@ -31,9 +26,10 @@ module Channel::Filter::Database
puts e.inspect puts e.inspect
end end
} }
if match if loop && match
filter[:set].each {|key, value| filter[:perform].each {|key, value|
mail[ key.to_sym ] = value puts " perform '#{ key.downcase }' = '#{value}'"
mail[ key.downcase.to_sym ] = value
} }
end end
} }

View file

@ -0,0 +1,4 @@
class PostmasterFilter < ApplicationModel
store :perform
store :match
end

View file

@ -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

View file

@ -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