Merge branch 'develop' into interface
Conflicts: app/assets/javascripts/app/controllers/_dashboard/ticket.js.coffee app/assets/javascripts/app/controllers/organization_zoom.js.coffee app/assets/javascripts/app/controllers/ticket_zoom.js.coffee app/assets/javascripts/app/controllers/user_zoom.js.coffee app/assets/javascripts/app/views/organization_zoom.jst.eco app/assets/javascripts/app/views/ticket_zoom/article_view.jst.eco app/assets/javascripts/app/views/ticket_zoom/edit.jst.eco
This commit is contained in:
commit
0e7892b22f
63 changed files with 1097 additions and 533 deletions
2
Gemfile
2
Gemfile
|
@ -14,7 +14,7 @@ gem 'json'
|
|||
# Gems used only for assets and not required
|
||||
# in production environments by default.
|
||||
group :assets do
|
||||
gem 'sass-rails'
|
||||
gem 'sass-rails', github: 'rails/sass-rails'
|
||||
gem 'coffee-rails'
|
||||
gem 'uglifier'
|
||||
end
|
||||
|
|
|
@ -223,11 +223,11 @@ class App.Controller extends Spine.Controller
|
|||
placement: position
|
||||
title: ->
|
||||
ticket_id = $(@).data('id')
|
||||
ticket = App.Ticket.retrieve( ticket_id )
|
||||
ticket = App.Ticket.fullLocal( ticket_id )
|
||||
App.i18n.escape( ticket.title )
|
||||
content: ->
|
||||
ticket_id = $(@).data('id')
|
||||
ticket = App.Ticket.retrieve( ticket_id )
|
||||
ticket = App.Ticket.fullLocal( ticket_id )
|
||||
ticket.humanTime = ui.humanTime(ticket.created_at)
|
||||
# insert data
|
||||
App.view('popover/ticket')(
|
||||
|
@ -257,11 +257,11 @@ class App.Controller extends Spine.Controller
|
|||
placement: position
|
||||
title: ->
|
||||
user_id = $(@).data('id')
|
||||
user = App.User.find( user_id )
|
||||
user = App.User.fullLocal( user_id )
|
||||
App.i18n.escape( user.displayName() )
|
||||
content: ->
|
||||
user_id = $(@).data('id')
|
||||
user = App.User.find( user_id )
|
||||
user = App.User.fullLocal( user_id )
|
||||
|
||||
# get display data
|
||||
data = []
|
||||
|
@ -303,11 +303,11 @@ class App.Controller extends Spine.Controller
|
|||
placement: position
|
||||
title: ->
|
||||
organization_id = $(@).data('id')
|
||||
organization = App.Organization.find( organization_id )
|
||||
organization = App.Organization.fullLocal( organization_id )
|
||||
App.i18n.escape( organization.name )
|
||||
content: ->
|
||||
organization_id = $(@).data('id')
|
||||
organization = App.Organization.find( organization_id )
|
||||
organization = App.Organization.fullLocal( organization_id )
|
||||
# insert data
|
||||
App.view('popover/organization')(
|
||||
organization: organization,
|
||||
|
@ -523,3 +523,31 @@ class App.SessionMessage extends App.ControllerModal
|
|||
|
||||
throw "Cant reload page!"
|
||||
|
||||
class App.UpdateHeader extends App.Controller
|
||||
constructor: ->
|
||||
super
|
||||
|
||||
# subscribe and reload data / fetch new data if triggered
|
||||
@subscribeId = @genericObject.subscribe( @render )
|
||||
|
||||
release: =>
|
||||
App[ @genericObject.constructor.className ].unsubscribe(@subscribeId)
|
||||
|
||||
render: (genericObject) =>
|
||||
@el.find( '.page-header h1' ).html( genericObject.displayName() )
|
||||
|
||||
|
||||
class App.UpdateTastbar extends App.Controller
|
||||
constructor: ->
|
||||
super
|
||||
|
||||
# subscribe and reload data / fetch new data if triggered
|
||||
@subscribeId = @genericObject.subscribe( @update )
|
||||
|
||||
release: =>
|
||||
App[ @genericObject.constructor.className ].unsubscribe(@subscribeId)
|
||||
|
||||
update: (genericObject) =>
|
||||
|
||||
# update taskbar with new meta data
|
||||
App.Event.trigger 'task:render'
|
||||
|
|
|
@ -990,7 +990,7 @@ class App.ControllerForm extends App.Controller
|
|||
remove: true
|
||||
}
|
||||
itemSub = @formGenItem( attribute_config )
|
||||
itemSub.find('.icon-minus').bind('click', (e) ->
|
||||
itemSub.find('.glyphicon-minus').bind('click', (e) ->
|
||||
e.preventDefault()
|
||||
$(@).parent().parent().parent().remove()
|
||||
)
|
||||
|
@ -1019,6 +1019,7 @@ class App.ControllerForm extends App.Controller
|
|||
selected: false
|
||||
disable: true
|
||||
},
|
||||
#
|
||||
#{
|
||||
# value: 'tickets.number'
|
||||
# name: 'Number'
|
||||
|
@ -1055,68 +1056,55 @@ class App.ControllerForm extends App.Controller
|
|||
selected: true
|
||||
disable: false
|
||||
},
|
||||
{
|
||||
value: 'tickets.customer_id'
|
||||
name: 'Customer'
|
||||
selected: true
|
||||
disable: false
|
||||
},
|
||||
{
|
||||
value: 'tickets.organization_id'
|
||||
name: 'Organization'
|
||||
selected: true
|
||||
disable: false
|
||||
},
|
||||
{
|
||||
value: 'tickets.created_at::<>'
|
||||
name: 'Created (before/last)'
|
||||
selected: true
|
||||
disable: false
|
||||
},
|
||||
{
|
||||
value: 'tickets.created_at::><'
|
||||
name: 'Created (between)'
|
||||
selected: true
|
||||
disable: false
|
||||
},
|
||||
{
|
||||
value: 'tickets.close_time::<>'
|
||||
name: 'Closed (before/last)'
|
||||
selected: true
|
||||
disable: false
|
||||
},
|
||||
{
|
||||
value: 'tickets.close_time::><'
|
||||
name: 'Closed (between)'
|
||||
selected: true
|
||||
disable: false
|
||||
},
|
||||
{
|
||||
value: 'tickets.updated_at::<>'
|
||||
name: 'Updated (before/last)'
|
||||
selected: true
|
||||
disable: false
|
||||
},
|
||||
{
|
||||
value: 'tickets.updated_at::><'
|
||||
name: 'Updated (between)'
|
||||
selected: true
|
||||
disable: false
|
||||
},
|
||||
{
|
||||
value: 'tickets.escalation_time::<>'
|
||||
name: 'Escalation (before/last)'
|
||||
selected: true
|
||||
disable: false
|
||||
},
|
||||
{
|
||||
value: 'tickets.escalation_time::><'
|
||||
name: 'Escalation (between)'
|
||||
selected: true
|
||||
disable: false
|
||||
},
|
||||
|
||||
#{
|
||||
# value: 'tickets.created_at::<>'
|
||||
# name: 'Created (before/last)'
|
||||
# selected: true
|
||||
# disable: false
|
||||
#},
|
||||
#{
|
||||
# value: 'tickets.created_at::><'
|
||||
# name: 'Created (between)'
|
||||
# selected: true
|
||||
# disable: false
|
||||
#},
|
||||
#{
|
||||
# value: 'tickets.close_time::<>'
|
||||
# name: 'Closed (before/last)'
|
||||
# selected: true
|
||||
# disable: false
|
||||
#},
|
||||
#{
|
||||
# value: 'tickets.close_time::><'
|
||||
# name: 'Closed (between)'
|
||||
# selected: true
|
||||
# disable: false
|
||||
#},
|
||||
#{
|
||||
# value: 'tickets.updated_at::<>'
|
||||
# name: 'Updated (before/last)'
|
||||
# selected: true
|
||||
# disable: false
|
||||
#},
|
||||
#{
|
||||
# value: 'tickets.updated_at::><'
|
||||
# name: 'Updated (between)'
|
||||
# selected: true
|
||||
# disable: false
|
||||
#},
|
||||
#{
|
||||
# value: 'tickets.escalation_time::<>'
|
||||
# name: 'Escalation (before/last)'
|
||||
# selected: true
|
||||
# disable: false
|
||||
#},
|
||||
#{
|
||||
# value: 'tickets.escalation_time::><'
|
||||
# name: 'Escalation (between)'
|
||||
# selected: true
|
||||
# disable: false
|
||||
#},
|
||||
# # {
|
||||
# value: 'tag'
|
||||
# name: 'Tag'
|
||||
# selected: true
|
||||
|
@ -1194,24 +1182,24 @@ class App.ControllerForm extends App.Controller
|
|||
# selected: true
|
||||
# disable: false
|
||||
# },
|
||||
# {
|
||||
# value: '-c'
|
||||
# name: '-- ' + App.i18n.translateInline('Customer') + ' --'
|
||||
# selected: false
|
||||
# disable: true
|
||||
# },
|
||||
# {
|
||||
# value: 'customers.id'
|
||||
# name: 'Kunde'
|
||||
# selected: true
|
||||
# disable: false
|
||||
# },
|
||||
# {
|
||||
# value: 'organization.id'
|
||||
# name: 'Organization'
|
||||
# selected: true
|
||||
# disable: false
|
||||
# },
|
||||
{
|
||||
value: '-c'
|
||||
name: '-- ' + App.i18n.translateInline('Customer') + ' --'
|
||||
selected: false
|
||||
disable: true
|
||||
},
|
||||
{
|
||||
value: 'customers.id'
|
||||
name: 'Customer'
|
||||
selected: true
|
||||
disable: false
|
||||
},
|
||||
{
|
||||
value: 'organization.id'
|
||||
name: 'Organization'
|
||||
selected: true
|
||||
disable: false
|
||||
},
|
||||
]
|
||||
default: ''
|
||||
translate: true
|
||||
|
@ -1220,7 +1208,7 @@ class App.ControllerForm extends App.Controller
|
|||
}
|
||||
list = @formGenItem( attribute_config )
|
||||
|
||||
list.find('.icon-plus').bind('click', (e) ->
|
||||
list.find('.glyphicon-plus').bind('click', (e) ->
|
||||
e.preventDefault()
|
||||
|
||||
value = $(e.target).parents().find('[name=ticket_attribute_list]').val()
|
||||
|
|
|
@ -37,7 +37,7 @@ class App.ControllerGenericNew extends App.ControllerModal
|
|||
object.save(
|
||||
done: ->
|
||||
if ui.callback
|
||||
item = App[ ui.genericObject ].retrieve(@id)
|
||||
item = App[ ui.genericObject ].fullLocal(@id)
|
||||
ui.callback( item )
|
||||
ui.modalHide()
|
||||
|
||||
|
@ -84,7 +84,7 @@ class App.ControllerGenericEdit extends App.ControllerModal
|
|||
@item.save(
|
||||
done: ->
|
||||
if ui.callback
|
||||
item = App[ ui.genericObject ].retrieve(@id)
|
||||
item = App[ ui.genericObject ].fullLocal(@id)
|
||||
ui.callback( item )
|
||||
ui.modalHide()
|
||||
|
||||
|
@ -269,14 +269,17 @@ class App.ControllerLevel2 extends App.ControllerContent
|
|||
# window.scrollTo(0,0)
|
||||
|
||||
class App.ControllerTabs extends App.Controller
|
||||
events:
|
||||
'click .nav-tabs [data-toggle="tab"]': 'tabRemember',
|
||||
|
||||
constructor: ->
|
||||
super
|
||||
|
||||
render: ->
|
||||
|
||||
@html App.view('generic/tabs')(
|
||||
tabs: @tabs
|
||||
)
|
||||
@el.find('.nav-tabs li:first').addClass('active')
|
||||
|
||||
for tab in @tabs
|
||||
@el.find('.tab-content').append('<div class="tab-pane" id="' + tab.target + '"></div>')
|
||||
|
@ -285,7 +288,15 @@ class App.ControllerTabs extends App.Controller
|
|||
params.el = @el.find( '#' + tab.target )
|
||||
new tab.controller( params )
|
||||
|
||||
@el.find('.tab-content .tab-pane:first').addClass('active')
|
||||
@lastActiveTab = @Config.get('lastTab')
|
||||
if @lastActiveTab && @el.find('.nav-tabs li a[href="' + @lastActiveTab + '"]')[0]
|
||||
@el.find('.nav-tabs li a[href="' + @lastActiveTab + '"]').tab('show')
|
||||
else
|
||||
@el.find('.nav-tabs li:first a').tab('show')
|
||||
|
||||
tabRemember: (e) =>
|
||||
@lastActiveTab = $(e.target).attr('href')
|
||||
@Config.set('lastTab', @lastActiveTab)
|
||||
|
||||
class App.ControllerNavSidbar extends App.ControllerContent
|
||||
constructor: (params) ->
|
||||
|
|
|
@ -96,7 +96,7 @@ class App.DashboardTicket extends App.Controller
|
|||
i = i + 1
|
||||
|
||||
openTicket = (id,e) =>
|
||||
ticket = App.Ticket.retrieve(id)
|
||||
ticket = App.Ticket.fullLocal(id)
|
||||
@navigate ticket.uiUrl()
|
||||
callbackTicketTitleAdd = (value, object, attribute, attributes, refObject) =>
|
||||
attribute.title = object.title
|
||||
|
|
|
@ -45,7 +45,7 @@ class Index extends App.Controller
|
|||
)
|
||||
|
||||
success: (data, status, xhr) =>
|
||||
App.User.retrieve(
|
||||
App.User.full(
|
||||
App.Session.get( 'id' ),
|
||||
=>
|
||||
App.i18n.set( @locale )
|
||||
|
|
|
@ -370,7 +370,7 @@ class UserNew extends App.ControllerModal
|
|||
# start customer info controller
|
||||
ui.userInfo( user_id: user.id )
|
||||
ui.modalHide()
|
||||
App.User.retrieve( @id, callbackReload , true )
|
||||
App.User.full( @id, callbackReload , true )
|
||||
|
||||
fail: ->
|
||||
ui.modalHide()
|
||||
|
|
|
@ -29,7 +29,7 @@ class App.TicketMerge extends App.ControllerModal
|
|||
list = []
|
||||
for ticket_id in @ticket_ids_by_customer
|
||||
if ticket_id isnt @ticket.id
|
||||
ticketItem = App.Ticket.retrieve( ticket_id )
|
||||
ticketItem = App.Ticket.fullLocal( ticket_id )
|
||||
list.push ticketItem
|
||||
new App.ControllerTable(
|
||||
el: @el.find('#ticket-merge-customer-tickets'),
|
||||
|
@ -42,7 +42,7 @@ class App.TicketMerge extends App.ControllerModal
|
|||
list = []
|
||||
for ticket_id in @ticket_ids_recent_viewed
|
||||
if ticket_id isnt @ticket.id
|
||||
ticketItem = App.Ticket.retrieve( ticket_id )
|
||||
ticketItem = App.Ticket.fullLocal( ticket_id )
|
||||
list.push ticketItem
|
||||
new App.ControllerTable(
|
||||
el: @el.find('#ticket-merge-recent-tickets'),
|
||||
|
@ -59,7 +59,7 @@ class App.TicketMerge extends App.ControllerModal
|
|||
@el.delegate('[name="radio"]', 'click', (e) ->
|
||||
if $(e.target).prop('checked')
|
||||
ticket_id = $(e.target).val()
|
||||
ticket = App.Ticket.retrieve( ticket_id )
|
||||
ticket = App.Ticket.fullLocal( ticket_id )
|
||||
$(e.target).parents().find('[name="master_ticket_number"]').val( ticket.number )
|
||||
)
|
||||
|
||||
|
|
|
@ -7,21 +7,17 @@ class App.OrganizationZoom extends App.Controller
|
|||
|
||||
@navupdate '#'
|
||||
|
||||
start = (organization) =>
|
||||
@organization = organization
|
||||
@render()
|
||||
|
||||
App.Organization.retrieve( @organization_id, start, true )
|
||||
App.Organization.full( @organization_id, @render )
|
||||
|
||||
meta: =>
|
||||
meta =
|
||||
url: @url()
|
||||
id: @organization_id
|
||||
|
||||
if @organization
|
||||
meta.head = @organization.displayName()
|
||||
meta.title = @organization.displayName()
|
||||
meta.iconClass = @organization.icon()
|
||||
organization = App.Organization.find( @organization_id )
|
||||
if organization
|
||||
meta.head = organization.displayName()
|
||||
meta.title = organization.displayName()
|
||||
meta
|
||||
|
||||
url: =>
|
||||
|
@ -36,27 +32,31 @@ class App.OrganizationZoom extends App.Controller
|
|||
return false if !diff || _.isEmpty( diff )
|
||||
return true
|
||||
|
||||
release: =>
|
||||
# nothing
|
||||
|
||||
render: =>
|
||||
# update taskbar with new meta data
|
||||
App.Event.trigger 'task:render'
|
||||
render: (organization) =>
|
||||
|
||||
@html App.view('organization_zoom')(
|
||||
organization: @organization
|
||||
organization: organization
|
||||
)
|
||||
|
||||
new App.UpdateTastbar(
|
||||
genericObject: organization
|
||||
)
|
||||
|
||||
new App.UpdateHeader(
|
||||
el: @el
|
||||
genericObject: organization
|
||||
)
|
||||
|
||||
# start action controller
|
||||
new ActionRow(
|
||||
el: @el.find('.action')
|
||||
organization: @organization
|
||||
organization: organization
|
||||
ui: @
|
||||
)
|
||||
|
||||
new Widgets(
|
||||
el: @el.find('.widgets')
|
||||
organization: @organization
|
||||
organization: organization
|
||||
ui: @
|
||||
)
|
||||
|
||||
|
|
|
@ -38,4 +38,4 @@ class App.TicketCustomer extends App.ControllerModal
|
|||
)
|
||||
|
||||
# load user if not already exists
|
||||
App.User.retrieve( @customer_id, callback )
|
||||
App.User.full( @customer_id, callback )
|
||||
|
|
|
@ -109,7 +109,7 @@ class Table extends App.ControllerContent
|
|||
|
||||
@ticket_list_show = []
|
||||
for ticket_id in @ticket_ids
|
||||
@ticket_list_show.push App.Ticket.retrieve( ticket_id )
|
||||
@ticket_list_show.push App.Ticket.fullLocal( ticket_id )
|
||||
|
||||
# remeber bulk attributes
|
||||
@bulk = data.bulk
|
||||
|
@ -185,7 +185,7 @@ class Table extends App.ControllerContent
|
|||
@el.find('.table-overview').append(table)
|
||||
else
|
||||
openTicket = (id,e) =>
|
||||
ticket = App.Ticket.retrieve(id)
|
||||
ticket = App.Ticket.fullLocal(id)
|
||||
@navigate ticket.uiUrl()
|
||||
callbackTicketTitleAdd = (value, object, attribute, attributes, refObject) =>
|
||||
attribute.title = object.title
|
||||
|
|
|
@ -44,7 +44,7 @@ class App.TicketZoom extends App.Controller
|
|||
id: @ticket_id
|
||||
iconClass: "priority"
|
||||
if @ticket
|
||||
@ticket = App.Ticket.retrieve( @ticket.id )
|
||||
@ticket = App.Ticket.fullLocal( @ticket.id )
|
||||
meta.head = @ticket.title
|
||||
meta.title = '#' + @ticket.number + ' - ' + @ticket.title
|
||||
meta.class = "level-#{@ticket.priority_id}"
|
||||
|
@ -125,7 +125,7 @@ class App.TicketZoom extends App.Controller
|
|||
App.Collection.loadAssets( data.assets )
|
||||
|
||||
# get data
|
||||
@ticket = App.Ticket.retrieve( @ticket_id )
|
||||
@ticket = App.Ticket.fullLocal( @ticket_id )
|
||||
|
||||
# render page
|
||||
@render(force)
|
||||
|
@ -224,7 +224,7 @@ class TicketTitle extends App.Controller
|
|||
constructor: ->
|
||||
super
|
||||
|
||||
@ticket = App.Ticket.retrieve( @ticket.id )
|
||||
@ticket = App.Ticket.fullLocal( @ticket.id )
|
||||
@subscribeId = @ticket.subscribe(@render)
|
||||
@render(@ticket)
|
||||
|
||||
|
@ -334,7 +334,7 @@ class Edit extends App.Controller
|
|||
|
||||
render: ->
|
||||
|
||||
ticket = App.Ticket.retrieve( @ticket.id )
|
||||
ticket = App.Ticket.fullLocal( @ticket.id )
|
||||
|
||||
@html App.view('ticket_zoom/edit')(
|
||||
ticket: ticket
|
||||
|
@ -451,7 +451,7 @@ class Edit extends App.Controller
|
|||
@autosaveStop()
|
||||
params = @formParam(e.target)
|
||||
|
||||
ticket = App.Ticket.retrieve( @ticket.id )
|
||||
ticket = App.Ticket.fullLocal( @ticket.id )
|
||||
|
||||
@log 'notice', 'update', params, ticket
|
||||
|
||||
|
@ -581,7 +581,7 @@ class ArticleView extends App.Controller
|
|||
# get all articles
|
||||
@articles = []
|
||||
for article_id in @ticket_article_ids
|
||||
article = App.TicketArticle.retrieve( article_id )
|
||||
article = App.TicketArticle.fullLocal( article_id )
|
||||
@articles.push article
|
||||
|
||||
# rework articles
|
||||
|
|
|
@ -5,20 +5,20 @@ class App.UserZoom extends App.Controller
|
|||
# check authentication
|
||||
return if !@authenticate()
|
||||
|
||||
start = (user) =>
|
||||
@user = user
|
||||
@render()
|
||||
|
||||
App.User.retrieve( @user_id, start, true )
|
||||
@navupdate '#'
|
||||
|
||||
App.User.full( @user_id, @render )
|
||||
|
||||
meta: =>
|
||||
meta =
|
||||
url: @url()
|
||||
id: @user_id
|
||||
|
||||
if @user
|
||||
meta.head = @user.displayName()
|
||||
meta.title = @user.displayName()
|
||||
user = App.User.find( @user_id )
|
||||
if user
|
||||
meta.head = user.displayName()
|
||||
meta.title = user.displayName()
|
||||
meta.iconClass = @user.icon()
|
||||
meta
|
||||
|
||||
|
@ -34,31 +34,34 @@ class App.UserZoom extends App.Controller
|
|||
return false if !diff || _.isEmpty( diff )
|
||||
return true
|
||||
|
||||
release: =>
|
||||
# nothing
|
||||
|
||||
render: =>
|
||||
# update taskbar with new meta data
|
||||
App.Event.trigger 'task:render'
|
||||
render: (user) =>
|
||||
|
||||
@html App.view('user_zoom')(
|
||||
user: @user
|
||||
user: user
|
||||
)
|
||||
|
||||
new App.UpdateTastbar(
|
||||
genericObject: user
|
||||
)
|
||||
|
||||
new App.UpdateHeader(
|
||||
el: @el
|
||||
genericObject: user
|
||||
)
|
||||
|
||||
# start action controller
|
||||
new ActionRow(
|
||||
el: @el.find('.action')
|
||||
user: @user
|
||||
user: user
|
||||
ui: @
|
||||
)
|
||||
|
||||
new Widgets(
|
||||
el: @el.find('.widgets')
|
||||
user: @user
|
||||
user: user
|
||||
ui: @
|
||||
)
|
||||
|
||||
|
||||
class Widgets extends App.Controller
|
||||
constructor: ->
|
||||
super
|
||||
|
|
|
@ -40,7 +40,7 @@ class App.WidgetLink extends App.ControllerDrox
|
|||
list[ item['link_type'] ] = []
|
||||
|
||||
if item['link_object'] is 'Ticket'
|
||||
ticket = App.Ticket.retrieve( item['link_object_value'] )
|
||||
ticket = App.Ticket.fullLocal( item['link_object_value'] )
|
||||
if ticket.state.name is 'merged'
|
||||
ticket.css = 'merged'
|
||||
list[ item['link_type'] ].push ticket
|
||||
|
|
|
@ -6,16 +6,8 @@ class App.WidgetOrganization extends App.Controller
|
|||
constructor: ->
|
||||
super
|
||||
|
||||
# show organization
|
||||
callback = (organization) =>
|
||||
@render(organization)
|
||||
if @callback
|
||||
@callback(organization)
|
||||
|
||||
# subscribe and reload data / fetch new data if triggered
|
||||
@subscribeId = organization.subscribe(@render)
|
||||
|
||||
App.Organization.retrieve( @organization_id, callback )
|
||||
@subscribeId = App.Organization.full( @organization_id, @render, false, true )
|
||||
|
||||
release: =>
|
||||
App.Organization.unsubscribe(@subscribeId)
|
||||
|
@ -56,6 +48,9 @@ class App.WidgetOrganization extends App.Controller
|
|||
)
|
||||
@delay( a, 80 )
|
||||
|
||||
# enable user popups
|
||||
@userPopups()
|
||||
|
||||
###
|
||||
@userTicketPopups(
|
||||
selector: '.user-tickets'
|
||||
|
@ -65,7 +60,7 @@ class App.WidgetOrganization extends App.Controller
|
|||
###
|
||||
|
||||
update: (e) =>
|
||||
note = $(e.target).parent().find('[data-type=update]').val()
|
||||
note = $(e.target).val()
|
||||
organization = App.Organization.find( @organization_id )
|
||||
if organization.note isnt note
|
||||
organization.updateAttributes( note: note )
|
||||
|
|
|
@ -6,16 +6,8 @@ class App.WidgetUser extends App.ControllerDrox
|
|||
constructor: ->
|
||||
super
|
||||
|
||||
# show user
|
||||
callback = (user) =>
|
||||
@render(user)
|
||||
if @callback
|
||||
@callback(user)
|
||||
|
||||
# subscribe and reload data / fetch new data if triggered
|
||||
@subscribeId = user.subscribe(@render)
|
||||
|
||||
App.User.retrieve( @user_id, callback )
|
||||
@subscribeId = App.User.full( @user_id, @render, false, true )
|
||||
|
||||
release: =>
|
||||
App.User.unsubscribe(@subscribeId)
|
||||
|
@ -41,6 +33,34 @@ class App.WidgetUser extends App.ControllerDrox
|
|||
if item.info
|
||||
userData.push item
|
||||
|
||||
if user.preferences
|
||||
items = []
|
||||
if user.preferences.tickets_open > 0
|
||||
item =
|
||||
url: ''
|
||||
name: 'open'
|
||||
count: user.preferences.tickets_open
|
||||
title: 'Open Tickets'
|
||||
class: 'user-tickets'
|
||||
data: 'open'
|
||||
items.push item
|
||||
if user.preferences.tickets_closed > 0
|
||||
item =
|
||||
url: ''
|
||||
name: 'closed'
|
||||
count: user.preferences.tickets_closed
|
||||
title: 'Closed Tickets'
|
||||
class: 'user-tickets'
|
||||
data: 'closed'
|
||||
items.push item
|
||||
|
||||
if items[0]
|
||||
topic =
|
||||
title: 'Tickets'
|
||||
items: items
|
||||
user['links'] = []
|
||||
user['links'].push topic
|
||||
|
||||
# insert userData
|
||||
@html @template(
|
||||
file: 'widget/user'
|
||||
|
@ -72,7 +92,7 @@ class App.WidgetUser extends App.ControllerDrox
|
|||
)
|
||||
|
||||
update: (e) =>
|
||||
note = $(e.target).parent().find('[data-type=update]').val()
|
||||
note = $(e.target).val()
|
||||
user = App.User.find( @user_id )
|
||||
if user.note isnt note
|
||||
user.updateAttributes( note: note )
|
||||
|
|
|
@ -75,21 +75,23 @@ class App.Auth
|
|||
if type isnt 'check'
|
||||
App.Event.trigger( 'clearStore' )
|
||||
|
||||
# set avatar
|
||||
data.session.image = App.Config.get('api_path') + '/users/image/' + data.session.image
|
||||
|
||||
# update config
|
||||
for key, value of data.config
|
||||
App.Config.set( key, value )
|
||||
|
||||
# store user data
|
||||
for key, value of data.session
|
||||
App.Session.set( key, value )
|
||||
|
||||
# refresh default collections
|
||||
if data.collections
|
||||
App.Collection.resetCollections( data.collections )
|
||||
|
||||
# load assets
|
||||
if data.assets
|
||||
App.Collection.loadAssets( data.assets )
|
||||
|
||||
# store user data
|
||||
session = App.User.fullLocal(data.session.id)
|
||||
for key, value of session
|
||||
App.Session.set( key, value )
|
||||
|
||||
# trigger auth ok with new session data
|
||||
App.Event.trigger( 'auth', data.session )
|
||||
|
||||
|
|
|
@ -68,7 +68,7 @@ class _collectionSingleton extends Spine.Module
|
|||
|
||||
reset: (params) ->
|
||||
if !App[ params.type ]
|
||||
@log 'error', 'reset', 'no such collection', params
|
||||
@log 'error', 'reset', "no such collection #{params.type}", params
|
||||
return
|
||||
|
||||
@log 'debug', 'reset', params
|
||||
|
|
|
@ -143,9 +143,12 @@ class _i18nSingleton extends Spine.Module
|
|||
|
||||
translate: ( string, args... ) =>
|
||||
|
||||
# return '' on undefined
|
||||
if typeof string is 'boolean'
|
||||
# type convertation
|
||||
if typeof string isnt 'string'
|
||||
if string && string.toString
|
||||
string = string.toString()
|
||||
|
||||
# return '' on undefined
|
||||
return '' if string is undefined
|
||||
return '' if string is ''
|
||||
|
||||
|
|
|
@ -126,6 +126,66 @@ class App.Model extends Spine.Model
|
|||
return true if @id[0] isnt 'c'
|
||||
return false
|
||||
|
||||
@fullLocal: (id) ->
|
||||
@_fillUp( App[ @className ].find( id ) )
|
||||
|
||||
@full: (id, callback = false, force = false, bind = false) ->
|
||||
url = "#{@url}/#{id}?full=true"
|
||||
|
||||
# subscribe and reload data / fetch new data if triggered
|
||||
subscribeId = undefined
|
||||
if bind
|
||||
subscribeId = App[ @className ].subscribe_item(id, callback)
|
||||
|
||||
# execute if object already exists
|
||||
if !force && App[ @className ].exists( id )
|
||||
data = App[ @className ].find( id )
|
||||
data = @_fillUp( data )
|
||||
if callback
|
||||
callback( data )
|
||||
return subscribeId
|
||||
|
||||
# store callback and requested id
|
||||
if !@FULL_CALLBACK
|
||||
@FULL_CALLBACK = {}
|
||||
if !@FULL_CALLBACK[id]
|
||||
@FULL_CALLBACK[id] = {}
|
||||
if callback
|
||||
key = @className + '-' + Math.floor( Math.random() * 99999 )
|
||||
@FULL_CALLBACK[id][key] = callback
|
||||
|
||||
if !@FULL_FETCH
|
||||
@FULL_FETCH = {}
|
||||
if !@FULL_FETCH[id]
|
||||
@FULL_FETCH[id] = true
|
||||
App.Ajax.request(
|
||||
type: 'GET'
|
||||
url: url
|
||||
processData: true,
|
||||
success: (data, status, xhr) =>
|
||||
@FULL_FETCH[ data.id ] = false
|
||||
|
||||
# full / load assets
|
||||
if data.assets
|
||||
App.Collection.loadAssets( data.assets )
|
||||
|
||||
# find / load object
|
||||
else
|
||||
App[ @className ].refresh( data )
|
||||
|
||||
# execute callbacks
|
||||
if @FULL_CALLBACK[ data.id ]
|
||||
for key, callback of @FULL_CALLBACK[ data.id ]
|
||||
callback( @_fillUp( App[ @className ].find( data.id ) ) )
|
||||
delete @FULL_CALLBACK[ data.id ][ key ]
|
||||
if _.isEmpty @FULL_CALLBACK[ data.id ]
|
||||
delete @FULL_CALLBACK[ data.id ]
|
||||
|
||||
error: (xhr, statusText, error) =>
|
||||
console.log(statusText, error)
|
||||
)
|
||||
subscribeId
|
||||
|
||||
@retrieve: ( id, callback, force ) ->
|
||||
if !force && App[ @className ].exists( id )
|
||||
data = App[ @className ].find( id )
|
||||
|
@ -229,42 +289,56 @@ class App.Model extends Spine.Model
|
|||
|
||||
subscribe: (callback, type) ->
|
||||
|
||||
# remember record id and callback
|
||||
App[ @constructor.className ].subscribe_item(@id, callback)
|
||||
|
||||
@subscribe_item: (id, callback) ->
|
||||
|
||||
# init bind
|
||||
if !App[ @constructor.className ]['SUBSCRIPTION_ITEM']
|
||||
App[ @constructor.className ]['SUBSCRIPTION_ITEM'] = {}
|
||||
if !@_subscribe_item_bindDone
|
||||
@_subscribe_item_bindDone = true
|
||||
|
||||
# subscribe and render data after local change
|
||||
App[ @constructor.className ].bind(
|
||||
@bind(
|
||||
'refresh change'
|
||||
(item) =>
|
||||
#console.log('BIND', item)
|
||||
for key, callback of App[ @constructor.className ]['SUBSCRIPTION_ITEM'][ item.id ]
|
||||
item = App[ @constructor.className ]._fillUp( item )
|
||||
callback(item, 'local')
|
||||
(items) =>
|
||||
|
||||
# check if result is array or singel item
|
||||
if !_.isArray(items)
|
||||
items = [items]
|
||||
|
||||
for item in items
|
||||
for key, callback of App[ @className ].SUBSCRIPTION_ITEM[ item.id ]
|
||||
item = App[ @className ]._fillUp( item )
|
||||
callback(item)
|
||||
)
|
||||
|
||||
# subscribe and render data after server change
|
||||
events = "#{@constructor.className}:create #{@constructor.className}:update #{@constructor.className}:destroy"
|
||||
events = "#{@className}:create #{@className}:update #{@className}:destroy"
|
||||
App.Event.bind(
|
||||
events
|
||||
(item) =>
|
||||
#console.log('SERVER BIND try', item)
|
||||
if App[ @constructor.className ]['SUBSCRIPTION_ITEM'] && App[ @constructor.className ]['SUBSCRIPTION_ITEM'][ item.id ]
|
||||
#console.log('SERVER BIND', item)
|
||||
for key, callback of App[ @constructor.className ]['SUBSCRIPTION_ITEM'][ item.id ]
|
||||
callbackRetrieve = (item) ->
|
||||
callback(item, 'server')
|
||||
App[ @constructor.className ].retrieve( item.id, callbackRetrieve, true )
|
||||
'Item::Subscribe::' + @constructor.className
|
||||
if @SUBSCRIPTION_ITEM && @SUBSCRIPTION_ITEM[ item.id ]
|
||||
genericObject = undefined
|
||||
if App[ @className ].exists( item.id )
|
||||
genericObject = App[ @className ].find( item.id )
|
||||
|
||||
callback = =>
|
||||
if !genericObject || ( new Date(item.updated_at).toString() isnt new Date(genericObject.updated_at).toString() )
|
||||
@full( item.id, false, true )
|
||||
|
||||
App.Delay.set(callback, 800, item.id, "full-#{@className}")
|
||||
|
||||
'Item::Subscribe::' + @className
|
||||
)
|
||||
|
||||
# remember record id and callback
|
||||
if !App[ @constructor.className ]['SUBSCRIPTION_ITEM'][ @id ]
|
||||
App[ @constructor.className ]['SUBSCRIPTION_ITEM'][ @id ] = {}
|
||||
key = @constructor.className + '-' + Math.floor( Math.random() * 99999 )
|
||||
App[ @constructor.className ]['SUBSCRIPTION_ITEM'][ @id ][key] = callback
|
||||
|
||||
# return key
|
||||
# remember item callback
|
||||
if !@SUBSCRIPTION_ITEM
|
||||
@SUBSCRIPTION_ITEM = {}
|
||||
if !@SUBSCRIPTION_ITEM[id]
|
||||
@SUBSCRIPTION_ITEM[id] = {}
|
||||
key = @className + '-' + Math.floor( Math.random() * 99999 )
|
||||
@SUBSCRIPTION_ITEM[id][key] = callback
|
||||
key
|
||||
|
||||
###
|
||||
|
@ -275,15 +349,15 @@ class App.Model extends Spine.Model
|
|||
|
||||
###
|
||||
|
||||
@unsubscribe: (data) ->
|
||||
@unsubscribe: (subscribeId) ->
|
||||
if @SUBSCRIPTION_ITEM
|
||||
for id, keys of @SUBSCRIPTION_ITEM
|
||||
if keys[data]
|
||||
delete keys[data]
|
||||
if keys[subscribeId]
|
||||
delete keys[subscribeId]
|
||||
|
||||
if @SUBSCRIPTION_COLLECTION
|
||||
if @SUBSCRIPTION_COLLECTION[data]
|
||||
delete @SUBSCRIPTION_COLLECTION[data]
|
||||
if @SUBSCRIPTION_COLLECTION[subscribeId]
|
||||
delete @SUBSCRIPTION_COLLECTION[subscribeId]
|
||||
|
||||
@_bindsEmpty: ->
|
||||
if @SUBSCRIPTION_ITEM
|
||||
|
|
|
@ -23,10 +23,10 @@ class App.Organization extends App.Model
|
|||
@_fillUp: (data) ->
|
||||
|
||||
# addd users of organization
|
||||
if data['user_ids']
|
||||
data['user_ids'] = []
|
||||
for user_id in data['user_ids']
|
||||
if data['member_ids']
|
||||
data['members'] = []
|
||||
for user_id in data['member_ids']
|
||||
if App.User.exists( user_id )
|
||||
user = App.User.find( user_id )
|
||||
data['user_ids'].push user
|
||||
data['members'].push user
|
||||
data
|
||||
|
|
|
@ -47,10 +47,23 @@ class App.User extends App.Model
|
|||
data['accounts'][account]['link'] = 'https://www.facebook.com/profile.php?id=' + data['accounts'][account]['uid']
|
||||
|
||||
# set image url
|
||||
data.image = @apiPath + '/users/image/' + data.image
|
||||
data.imageUrl = @apiPath + '/users/image/' + data.image
|
||||
|
||||
if data.organization_id
|
||||
data.organization = App.Organization.find(data.organization_id)
|
||||
|
||||
data
|
||||
if data['role_ids']
|
||||
data['roles'] = []
|
||||
for role_id in data['role_ids']
|
||||
if App.Role.exists( role_id )
|
||||
role = App.Role.find( role_id )
|
||||
data['roles'].push role
|
||||
|
||||
if data['group_ids']
|
||||
data['groups'] = []
|
||||
for group_id in data['group_ids']
|
||||
if App.Group.exists( group_id )
|
||||
group = App.Group.find( group_id )
|
||||
data['groups'].push group
|
||||
|
||||
data
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
<input type="checkbox" value="<%= ticket.id %>" name="bulk" class="pull-left"/>
|
||||
</td>
|
||||
<td class="span1">
|
||||
<img class="thumbnail user-popover" data-id="<%= ticket.customer_id %>" src="<%= ticket.customer.image %>" alt="">
|
||||
<img class="thumbnail user-popover" data-id="<%= ticket.customer_id %>" src="<%= ticket.customer.imageUrl %>" alt="">
|
||||
</td>
|
||||
<td class="span10">
|
||||
<h3><a href="#" data-type="edit"><%= ticket.title %></a> <small><%= ticket.number %> <span class="humanTimeFromNow" data-time="<%= ticket.created_at %>">?</span></small></h3>
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<ul class="nav nav-tabs">
|
||||
<ul class="nav nav-tabs" role="tablist">
|
||||
<% for tab in @tabs: %>
|
||||
<li><a href="#<%= tab.target %>" data-toggle="tab"><%- @T( tab.name ) %></a></li>
|
||||
<li><a href="#<%= tab.target %>" role="tab" data-toggle="tab"><%- @T( tab.name ) %></a></li>
|
||||
<% end %>
|
||||
</ul>
|
||||
<div class="tab-content"></div>
|
|
@ -1,9 +1,49 @@
|
|||
<% for article in @articles: %>
|
||||
<!--
|
||||
<div class="ticket-article-item bubble-grid <%= article.sender.name.toLowerCase() %> <%= article.type.name %><%= ' internal' if article.internal is true %>" data-id="<%= article.id %>" id="article-<%= article.id %>">
|
||||
<div class="horizontal<%= ' reverse' if article.sender.name is 'Customer' %>">
|
||||
<div class="avatar" style="background-image: url(<%= article.created_by.image %>)"></div>
|
||||
<div class="flex">
|
||||
<div class="text-bubble"><div class="bubble-arrow"></div><%- article.html %></div>
|
||||
-->
|
||||
<div class="ticket-article ticket-article-item <% if article.internal is true: %> internal<% end %>" data-id="<%= article.id %>" id="article-<%= article.id %>">
|
||||
<div class="avatar">
|
||||
<img class="thumbnail user-popover" data-id="<%= article.created_by_id %>" src="<%= article.created_by.imageUrl %>" alt="">
|
||||
<ul>
|
||||
<li style="font-size: 10px;"><%- @T(article.type.name) %></li>
|
||||
<% if article.type.name is 'email': %><li style="font-size: 10px;"><a href="<%= App.Config.get('api_path') %>/ticket_article_plain/<%= article.id %>"><%- @T( 'raw' ) %></a></li><% end %>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="ticket-article-message">
|
||||
<div class="ticket-article-meta">
|
||||
<% if article.from: %>
|
||||
<strong title="<%- @Ti( 'From' ) %>: <%= article.from %>"><%= article.from %></strong>
|
||||
<% if article.actions: %>
|
||||
<% for action in article.actions: %>
|
||||
-
|
||||
<a href="<%= action.href %>" data-type="<%= action.type %>" class="<% if action.class: %><%= action.class %><% end %>"><%- @T( action.name ) %></a>
|
||||
<% end %>
|
||||
<% end %>
|
||||
- <span class="humanTimeFromNow" data-time="<%- article.created_at %>">?</span>
|
||||
<% end %>
|
||||
<% if article.to: %>
|
||||
<div title="<%- @Ti( 'To' ) %>: <%= article.to %>"><%= article.to %></div>
|
||||
<% end %>
|
||||
<% if article.cc: %>
|
||||
<div title="<%- @Ti( 'Cc' ) %>: <%= article.cc %>"><%= article.cc %></div>
|
||||
<% end %>
|
||||
<% if article.subject: %>
|
||||
<div title="<%- @Ti( 'Subject' ) %>: <%= article.subject %>"><%= article.subject %></div>
|
||||
<% end %>
|
||||
<% if article.attachments: %>
|
||||
<div>
|
||||
<% for attachment in article.attachments: %>
|
||||
<a href="<%= App.Config.get('api_path') %>/ticket_attachment/<%= article.ticket_id %>/<%= article.id %>/<%= attachment.id %>" target="_blank" data-type="attachment" class="attachment" title="<%= attachment.size %>"><%= attachment.filename %></a>
|
||||
<% end %>
|
||||
</div>
|
||||
<% end %>
|
||||
</div>
|
||||
<div style="white-space:pre-wrap;" class="message"><%- article.html %></div>
|
||||
</div>
|
||||
</div>
|
||||
<time class="task-meta humanTimeFromNow" datetime="<%- article.created_at %>" data-time="<%- article.created_at %>">?</time>
|
||||
|
|
|
@ -1,8 +1,31 @@
|
|||
<!--
|
||||
<div class="horizontal bubble-grid new-article <% if @formChanged: %>form-changed<% end %>">
|
||||
<div class="avatar user-popover" data-id="<%= @S('id') %>" style="background-image: url(<%- @S('image') %>)"></div>
|
||||
<div class="flex text-bubble">
|
||||
<div class="bubble-arrow"></div>
|
||||
<textarea></textarea>
|
||||
<span class="bubble-placeholder">Antwort eingeben oder <span class="highlight">Dateien wählen</span></span>
|
||||
-->
|
||||
<div class="ticket-article-view">
|
||||
<div class="ticket-article well ticket-edit <% if @formChanged: %>form-changed<% end %>">
|
||||
<div class="avatar">
|
||||
<img class="thumbnail user-popover" data-id="<%= @S('id') %>" src="<%- @S('imageUrl') %>" alt="">
|
||||
</div>
|
||||
<div class="ticket-article-message">
|
||||
<div class="edit-title">
|
||||
<h4><%- @T('Edit') %>
|
||||
<small class="reset-message<% if !@formChanged: %> hide<% end %>">
|
||||
<a href="#" data-type="reset"><%- @T('Discard your unsaved changes.') %></a> <href="#" class="glyphicon glyphicon-repeat" data-type="reset"></a>
|
||||
</small>
|
||||
</h4>
|
||||
</div>
|
||||
<div class="edit-content">
|
||||
<form class="form-stacked ticket-update">
|
||||
<div class="form-ticket-update"></div>
|
||||
<div class="form-article-update"></div>
|
||||
<button type="submit" class="btn btn-primary submit"><%- @T( 'Submit' ) %></button>
|
||||
</form>
|
||||
<div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
|
@ -5,7 +5,7 @@
|
|||
<div class="main flex">
|
||||
|
||||
<div class="page-header">
|
||||
<h1><%= @user.displayName() %></h1>
|
||||
<h1></h1>
|
||||
</div>
|
||||
|
||||
</div>
|
|
@ -1 +0,0 @@
|
|||
<div class="user_info"></div>
|
|
@ -21,6 +21,15 @@
|
|||
<% end %>
|
||||
<% end %>
|
||||
|
||||
<% if @organization.members: %>
|
||||
<h4><%- @T('Member') %></h4>
|
||||
<ul>
|
||||
<% for user in @organization.members: %>
|
||||
<li><a href="<%- user.uiUrl() %>" class="user-popover" data-id="<%- user.id %>"><%= user.displayName() %></a></li>
|
||||
<% end %>
|
||||
</ul>
|
||||
<% end %>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<div class="user-info">
|
||||
|
||||
<% if @user.image: %>
|
||||
<img class="thumbnail" src="<%- @user.image %>" alt="">
|
||||
<% if @user.imageUrl: %>
|
||||
<img class="thumbnail" src="<%- @user.imageUrl %>" alt="">
|
||||
<% end %>
|
||||
<div class="customer-info" title="<%- @Ti( 'Name') %>"><%= @user.displayName() %></div>
|
||||
<% for row in @userData: %>
|
||||
|
|
|
@ -6,7 +6,6 @@ class ApplicationController < ActionController::Base
|
|||
helper_method :current_user,
|
||||
:authentication_check,
|
||||
:config_frontend,
|
||||
:user_data_full,
|
||||
:is_role,
|
||||
:model_create_render,
|
||||
:model_update_render,
|
||||
|
@ -77,6 +76,7 @@ class ApplicationController < ActionController::Base
|
|||
|
||||
# update session updated_at
|
||||
def session_update
|
||||
#sleep 0.6
|
||||
|
||||
# on many paralell requests, session got reinitialised if Time. is used, as workaround use DateTime.
|
||||
#session[:ping] = Time.now.utc.iso8601
|
||||
|
@ -318,6 +318,13 @@ class ApplicationController < ActionController::Base
|
|||
|
||||
def model_show_render (object, params)
|
||||
begin
|
||||
|
||||
if params[:full]
|
||||
generic_object_full = object.full( params[:id] )
|
||||
render :json => generic_object_full, :status => :ok
|
||||
return
|
||||
end
|
||||
|
||||
generic_object = object.find( params[:id] )
|
||||
model_show_render_item(generic_object)
|
||||
rescue Exception => e
|
||||
|
|
|
@ -59,7 +59,7 @@ class LongPollingController < ApplicationController
|
|||
user_id = session[:user_id]
|
||||
user = {}
|
||||
if user_id
|
||||
user = User.user_data_full( user_id )
|
||||
user = User.find( user_id )
|
||||
end
|
||||
log 'notice', "send auth login (user_id #{user_id})", client_id
|
||||
Sessions.create( client_id, user, { :type => 'ajax' } )
|
||||
|
|
|
@ -90,6 +90,11 @@ curl http://localhost/api/v1/organizations/#{id}.json -v -u #{login}:#{password}
|
|||
return
|
||||
end
|
||||
end
|
||||
if params[:full]
|
||||
full = Organization.full( params[:id] )
|
||||
render :json => full
|
||||
return
|
||||
end
|
||||
model_show_render(Organization, params)
|
||||
end
|
||||
|
||||
|
|
|
@ -1,34 +1,37 @@
|
|||
# Copyright (C) 2012-2014 Zammad Foundation, http://zammad-foundation.org/
|
||||
|
||||
module ExtraCollection
|
||||
def session( collections, user )
|
||||
def session( collections, assets, user )
|
||||
|
||||
# all base stuff
|
||||
assets = {}
|
||||
collections[ Taskbar.to_app_model ] = Taskbar.where( :user_id => user.id )
|
||||
collections[ Role.to_app_model ] = Role.all
|
||||
collections[ Group.to_app_model ] = Group.all
|
||||
collections[ Taskbar.to_app_model ].each {|item|
|
||||
assets = item.assets(assets)
|
||||
}
|
||||
|
||||
collections[ Role.to_app_model ] = []
|
||||
Role.all.each {|item|
|
||||
assets = item.assets(assets)
|
||||
}
|
||||
|
||||
collections[ Group.to_app_model ] = []
|
||||
Group.all.each {|item|
|
||||
assets = item.assets(assets)
|
||||
}
|
||||
if !user.is_role('Customer')
|
||||
collections[ Organization.to_app_model ] = Organization.all
|
||||
collections[ Organization.to_app_model ] = []
|
||||
Organization.all.each {|item|
|
||||
assets = item.assets(assets)
|
||||
}
|
||||
else
|
||||
if user.organization_id
|
||||
collections[ Organization.to_app_model ] = Organization.where( :id => user.organization_id )
|
||||
collections[ Organization.to_app_model ] = []
|
||||
Organization.where( :id => user.organization_id ).each {|item|
|
||||
assets = item.assets(assets)
|
||||
}
|
||||
end
|
||||
end
|
||||
end
|
||||
def push( collections, user )
|
||||
|
||||
# all base stuff
|
||||
#collections[ Role.to_app_model ] = Role.all
|
||||
#collections[ Group.to_app_model ] = Group.all
|
||||
|
||||
#if !user.is_role('Customer')
|
||||
# collections[ Organization.to_app_model ] = Organization.all
|
||||
#else
|
||||
# if user.organization_id
|
||||
# collections[ Organization.to_app_model ] = Organization.where( :id => user.organization_id )
|
||||
# end
|
||||
#end
|
||||
end
|
||||
module_function :session, :push
|
||||
module_function :session
|
||||
end
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
# Copyright (C) 2012-2014 Zammad Foundation, http://zammad-foundation.org/
|
||||
|
||||
module ExtraCollection
|
||||
def session( collections, user )
|
||||
def session( collections, assets, user )
|
||||
|
||||
collections[ Network.to_app_model ] = Network.all
|
||||
collections[ Network::Category.to_app_model ] = Network::Category.all
|
||||
|
@ -9,13 +9,6 @@ module ExtraCollection
|
|||
collections[ Network::Privacy.to_app_model ] = Network::Privacy.all
|
||||
|
||||
end
|
||||
def push( collections, user )
|
||||
|
||||
collections[ Network.to_app_model ] = Network.all
|
||||
collections[ Network::Category.to_app_model ] = Network::Category.all
|
||||
collections[ Network::Category::Type.to_app_model ] = Network::Category::Type.all
|
||||
collections[ Network::Privacy.to_app_model ] = Network::Privacy.all
|
||||
|
||||
end
|
||||
module_function :session, :push
|
||||
module_function :session
|
||||
end
|
|
@ -1,42 +1,43 @@
|
|||
# Copyright (C) 2012-2014 Zammad Foundation, http://zammad-foundation.org/
|
||||
|
||||
module ExtraCollection
|
||||
def session( collections, user )
|
||||
def session( collections, assets, user )
|
||||
|
||||
# all ticket stuff
|
||||
collections[ Ticket::StateType.to_app_model ] = Ticket::StateType.all
|
||||
collections[ Ticket::State.to_app_model ] = Ticket::State.all
|
||||
collections[ Ticket::Priority.to_app_model ] = Ticket::Priority.all
|
||||
collections[ Ticket::Article::Type.to_app_model ] = Ticket::Article::Type.all
|
||||
collections[ Ticket::Article::Sender.to_app_model ] = Ticket::Article::Sender.all
|
||||
|
||||
collections[ Ticket::StateType.to_app_model ] = []
|
||||
Ticket::StateType.all.each {|item|
|
||||
assets = item.assets(assets)
|
||||
}
|
||||
collections[ Ticket::State.to_app_model ] = []
|
||||
Ticket::State.all.each {|item|
|
||||
assets = item.assets(assets)
|
||||
}
|
||||
collections[ Ticket::Priority.to_app_model ] = []
|
||||
Ticket::Priority.all.each {|item|
|
||||
assets = item.assets(assets)
|
||||
}
|
||||
collections[ Ticket::Article::Type.to_app_model ] = []
|
||||
Ticket::Article::Type.all.each {|item|
|
||||
assets = item.assets(assets)
|
||||
}
|
||||
collections[ Ticket::Article::Sender.to_app_model ] = []
|
||||
Ticket::Article::Sender.all.each {|item|
|
||||
assets = item.assets(assets)
|
||||
}
|
||||
if !user.is_role('Customer')
|
||||
|
||||
# all signatures
|
||||
collections[ Signature.to_app_model ] = Signature.all
|
||||
collections[ Signature.to_app_model ] = []
|
||||
Signature.all.each {|item|
|
||||
assets = item.assets(assets)
|
||||
}
|
||||
|
||||
# all email addresses
|
||||
collections[ EmailAddress.to_app_model ] = EmailAddress.all
|
||||
collections[ EmailAddress.to_app_model ] = []
|
||||
EmailAddress.all.each {|item|
|
||||
assets = item.assets(assets)
|
||||
}
|
||||
end
|
||||
end
|
||||
def push( collections, user )
|
||||
|
||||
# all ticket stuff
|
||||
#collections[ Ticket::StateType.to_app_model ] = Ticket::StateType.all
|
||||
#collections[ Ticket::State.to_app_model ] = Ticket::State.all
|
||||
#collections[ Ticket::Priority.to_app_model ] = Ticket::Priority.all
|
||||
#collections[ Ticket::Article::Type.to_app_model ] = Ticket::Article::Type.all
|
||||
#collections[ Ticket::Article::Sender.to_app_model ] = Ticket::Article::Sender.all
|
||||
|
||||
#if !user.is_role('Customer')
|
||||
|
||||
# all signatures
|
||||
# collections[ Signature.to_app_model ] = Signature.all
|
||||
|
||||
# all email addresses
|
||||
# collections[ EmailAddress.to_app_model ] = EmailAddress.all
|
||||
#end
|
||||
end
|
||||
|
||||
module_function :session, :push
|
||||
module_function :session
|
||||
end
|
|
@ -31,10 +31,9 @@ class SessionsController < ApplicationController
|
|||
user.activity_stream_log( 'session started', user.id, true )
|
||||
|
||||
# auto population of default collections
|
||||
collections = SessionHelper::default_collections(user)
|
||||
collections, assets = SessionHelper::default_collections(user)
|
||||
|
||||
# set session user_id
|
||||
user = User.find_fulldata(user.id)
|
||||
assets = user.assets(assets)
|
||||
|
||||
# check logon session
|
||||
logon_session_key = nil
|
||||
|
@ -52,6 +51,7 @@ class SessionsController < ApplicationController
|
|||
render :json => {
|
||||
:session => user,
|
||||
:collections => collections,
|
||||
:assets => assets,
|
||||
:logon_session => logon_session_key,
|
||||
},
|
||||
:status => :created
|
||||
|
@ -84,15 +84,18 @@ class SessionsController < ApplicationController
|
|||
|
||||
# Save the user ID in the session so it can be used in
|
||||
# subsequent requests
|
||||
user = User.user_data_full( user_id )
|
||||
user = User.find( user_id )
|
||||
|
||||
# auto population of default collections
|
||||
collections = SessionHelper::default_collections( User.find(user_id) )
|
||||
collections, assets = SessionHelper::default_collections(user)
|
||||
|
||||
assets = user.assets(assets)
|
||||
|
||||
# return current session
|
||||
render :json => {
|
||||
:session => user,
|
||||
:collections => collections,
|
||||
:assets => assets,
|
||||
:config => config_frontend,
|
||||
}
|
||||
end
|
||||
|
|
|
@ -49,7 +49,7 @@ class TicketOverviewsController < ApplicationController
|
|||
end
|
||||
|
||||
# get related users
|
||||
assets = { User.to_app_model => {} }
|
||||
assets = {}
|
||||
overview[:ticket_ids].each {|ticket_id|
|
||||
ticket = Ticket.lookup( :id => ticket_id )
|
||||
assets = ticket.assets(assets)
|
||||
|
@ -70,9 +70,7 @@ class TicketOverviewsController < ApplicationController
|
|||
Group.find(group_id).users.each {|user|
|
||||
next if !agents[ user.id ]
|
||||
groups_users[ group_id ].push user.id
|
||||
if !assets[ User.to_app_model ][user.id]
|
||||
assets[ User.to_app_model ][user.id] = User.user_data_full(user.id)
|
||||
end
|
||||
assets = user.assets( assets )
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -262,23 +262,20 @@ class TicketsController < ApplicationController
|
|||
|
||||
# get related users
|
||||
assets = {}
|
||||
assets[ User.to_app_model ] = {}
|
||||
assets = ticket.assets(assets)
|
||||
|
||||
# get attributes to update
|
||||
attributes_to_change = Ticket::ScreenOptions.attributes_to_change( :user => current_user, :ticket => ticket )
|
||||
|
||||
attributes_to_change[:owner_id].each { |user_id|
|
||||
if !assets[ User.to_app_model ][user_id]
|
||||
assets[ User.to_app_model ][user_id] = User.user_data_full( user_id )
|
||||
end
|
||||
user = User.find(user_id)
|
||||
assets = user.assets(assets)
|
||||
}
|
||||
|
||||
attributes_to_change[:group_id__owner_id].each {|group_id, user_ids|
|
||||
user_ids.each {|user_id|
|
||||
if !assets[ User.to_app_model ][user_id]
|
||||
assets[ User.to_app_model ][user_id] = User.user_data_full( user_id )
|
||||
end
|
||||
user = User.find(user_id)
|
||||
assets = user.assets(assets)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -322,16 +319,14 @@ class TicketsController < ApplicationController
|
|||
assets = {}
|
||||
assets[ User.to_app_model ] = {}
|
||||
attributes_to_change[:owner_id].each { |user_id|
|
||||
if !assets[ User.to_app_model ][user_id]
|
||||
assets[ User.to_app_model ][user_id] = User.user_data_full( user_id )
|
||||
end
|
||||
user = User.find(user_id)
|
||||
assets = user.assets(assets)
|
||||
}
|
||||
|
||||
attributes_to_change[:group_id__owner_id].each {|group_id, user_ids|
|
||||
user_ids.each {|user_id|
|
||||
if !assets[ User.to_app_model ][user_id]
|
||||
assets[ User.to_app_model ][user_id] = User.user_data_full( user_id )
|
||||
end
|
||||
user = User.find(user_id)
|
||||
assets = user.assets(assets)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -345,9 +340,7 @@ class TicketsController < ApplicationController
|
|||
owner_ids = []
|
||||
ticket.agent_of_group.each { |user|
|
||||
owner_ids.push user.id
|
||||
if !assets[ User.to_app_model ][user.id]
|
||||
assets[ User.to_app_model ][user.id] = User.user_data_full( user.id )
|
||||
end
|
||||
assets = user.assets(assets)
|
||||
}
|
||||
|
||||
# get related articles
|
||||
|
|
|
@ -70,7 +70,7 @@ curl http://localhost/api/v1/users.json -v -u #{login}:#{password}
|
|||
end
|
||||
users_all = []
|
||||
users.each {|user|
|
||||
users_all.push User.user_data_full( user.id )
|
||||
users_all.push User.lookup( :id => user.id ).attributes_with_associations
|
||||
}
|
||||
render :json => users_all, :status => :ok
|
||||
end
|
||||
|
@ -101,7 +101,14 @@ curl http://localhost/api/v1/users/#{id}.json -v -u #{login}:#{password}
|
|||
return
|
||||
end
|
||||
end
|
||||
user = User.user_data_full( params[:id] )
|
||||
|
||||
if params[:full]
|
||||
full = User.full( params[:id] )
|
||||
render :json => full
|
||||
return
|
||||
end
|
||||
|
||||
user = User.find( params[:id] )
|
||||
render :json => user
|
||||
end
|
||||
|
||||
|
@ -245,7 +252,7 @@ curl http://localhost/api/v1/users.json -v -u #{login}:#{password} -H "Content-T
|
|||
)
|
||||
end
|
||||
|
||||
user_new = User.user_data_full( user.id )
|
||||
user_new = User.find( user.id )
|
||||
render :json => user_new, :status => :created
|
||||
rescue Exception => e
|
||||
render :json => { :error => e.message }, :status => :unprocessable_entity
|
||||
|
@ -309,7 +316,7 @@ curl http://localhost/api/v1/users/2.json -v -u #{login}:#{password} -H "Content
|
|||
end
|
||||
|
||||
# get new data
|
||||
user_new = User.user_data_full( params[:id] )
|
||||
user_new = User.find( params[:id] )
|
||||
render :json => user_new, :status => :ok
|
||||
rescue Exception => e
|
||||
render :json => { :error => e.message }, :status => :unprocessable_entity
|
||||
|
|
|
@ -883,4 +883,25 @@ destory object dependencies, will be executed automatically
|
|||
def destroy_dependencies
|
||||
end
|
||||
|
||||
=begin
|
||||
|
||||
return object and assets
|
||||
|
||||
data = Model.full(123)
|
||||
data = {
|
||||
:id => 123,
|
||||
:assets => assets,
|
||||
}
|
||||
|
||||
=end
|
||||
|
||||
def self.full(id)
|
||||
object = self.find(id)
|
||||
assets = object.assets({})
|
||||
{
|
||||
:id => id,
|
||||
:assets => assets,
|
||||
}
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
@ -12,7 +12,7 @@ get all assets / related models for this user
|
|||
returns
|
||||
|
||||
result = {
|
||||
:users => {
|
||||
:User => {
|
||||
123 => user_model_123,
|
||||
1234 => user_model_1234,
|
||||
}
|
||||
|
@ -26,23 +26,18 @@ returns
|
|||
data[ self.class.to_app_model ] = {}
|
||||
end
|
||||
if !data[ self.class.to_app_model ][ self.id ]
|
||||
data[ self.class.to_app_model ][ self.id ] = self.attributes
|
||||
data[ self.class.to_app_model ][ self.id ] = self.attributes_with_associations
|
||||
end
|
||||
|
||||
return data if !self['created_by_id'] && !self['updated_by_id']
|
||||
if !data[ User.to_app_model ]
|
||||
data[ User.to_app_model ] = {}
|
||||
end
|
||||
if self['created_by_id']
|
||||
if !data[ User.to_app_model ][ self['created_by_id'] ]
|
||||
data[ User.to_app_model ][ self['created_by_id'] ] = User.user_data_full( self['created_by_id'] )
|
||||
end
|
||||
end
|
||||
if self['updated_by_id']
|
||||
if !data[ User.to_app_model ][ self['updated_by_id'] ]
|
||||
data[ User.to_app_model ][ self['updated_by_id'] ] = User.user_data_full( self['updated_by_id'] )
|
||||
['created_by_id', 'updated_by_id'].each {|item|
|
||||
if self[ item ]
|
||||
if !data[ User.to_app_model ] || !data[ User.to_app_model ][ self[ item ] ]
|
||||
user = User.lookup( :id => self[ item ] )
|
||||
data = user.assets( data )
|
||||
end
|
||||
end
|
||||
}
|
||||
data
|
||||
end
|
||||
|
||||
|
|
|
@ -122,6 +122,10 @@ class Channel::EmailParser
|
|||
data[:body] = mail.text_part.body.decoded
|
||||
data[:body] = Encode.conv( mail.text_part.charset, data[:body] )
|
||||
|
||||
if !data[:body].valid_encoding?
|
||||
data[:body] = data[:body].encode('utf-8', 'binary', :invalid => :replace, :undef => :replace, :replace => '?')
|
||||
end
|
||||
|
||||
# html attachment/body may exists and will be converted to text
|
||||
else
|
||||
filename = '-no name-'
|
||||
|
@ -129,7 +133,11 @@ class Channel::EmailParser
|
|||
filename = 'html-email'
|
||||
data[:body] = mail.html_part.body.to_s
|
||||
data[:body] = Encode.conv( mail.html_part.charset.to_s, data[:body] )
|
||||
data[:body] = html2ascii( data[:body] )
|
||||
data[:body] = html2ascii( data[:body] ).to_s.force_encoding('utf-8')
|
||||
|
||||
if !data[:body].valid_encoding?
|
||||
data[:body] = data[:body].encode('utf-8', 'binary', :invalid => :replace, :undef => :replace, :replace => '?')
|
||||
end
|
||||
|
||||
# any other attachments
|
||||
else
|
||||
|
@ -188,6 +196,10 @@ class Channel::EmailParser
|
|||
data[:body] = mail.body.decoded
|
||||
data[:body] = Encode.conv( mail.charset, data[:body] )
|
||||
|
||||
if !data[:body].valid_encoding?
|
||||
data[:body] = data[:body].encode('utf-8', 'binary', :invalid => :replace, :undef => :replace, :replace => '?')
|
||||
end
|
||||
|
||||
# html part
|
||||
else
|
||||
filename = '-no name-'
|
||||
|
@ -195,7 +207,11 @@ class Channel::EmailParser
|
|||
filename = 'html-email'
|
||||
data[:body] = mail.body.decoded
|
||||
data[:body] = Encode.conv( mail.charset, data[:body] )
|
||||
data[:body] = html2ascii( data[:body] )
|
||||
data[:body] = html2ascii( data[:body] ).to_s.force_encoding('utf-8')
|
||||
|
||||
if !data[:body].valid_encoding?
|
||||
data[:body] = data[:body].encode('utf-8', 'binary', :invalid => :replace, :undef => :replace, :replace => '?')
|
||||
end
|
||||
|
||||
# any other attachments
|
||||
else
|
||||
|
|
|
@ -22,11 +22,9 @@ returns
|
|||
|
||||
def assets (data)
|
||||
|
||||
if !data[ User.to_app_model ]
|
||||
data[ User.to_app_model ] = {}
|
||||
end
|
||||
if !data[ User.to_app_model ][ self['created_by_id'] ]
|
||||
data[ User.to_app_model ][ self['created_by_id'] ] = User.user_data_full( self['created_by_id'] )
|
||||
if !data[ User.to_app_model ] || !data[ User.to_app_model ][ self['created_by_id'] ]
|
||||
user = User.lookup( :id => self['created_by_id'] )
|
||||
data = user.assets( data )
|
||||
end
|
||||
|
||||
data
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
# Copyright (C) 2012-2014 Zammad Foundation, http://zammad-foundation.org/
|
||||
|
||||
class Organization < ApplicationModel
|
||||
require 'organization/assets'
|
||||
include Organization::Assets
|
||||
extend Organization::Search
|
||||
include Organization::SearchIndex
|
||||
|
@ -9,6 +10,9 @@ class Organization < ApplicationModel
|
|||
has_many :members, :class_name => 'User'
|
||||
validates :name, :presence => true
|
||||
|
||||
after_create :notify_clients_after_create
|
||||
after_update :notify_clients_after_update
|
||||
|
||||
activity_stream_support :role => 'Admin'
|
||||
history_support
|
||||
search_index_support
|
||||
|
|
|
@ -29,14 +29,24 @@ returns
|
|||
data[ User.to_app_model ] = {}
|
||||
end
|
||||
if !data[ Organization.to_app_model ][ self.id ]
|
||||
data[ Organization.to_app_model ][ self.id ] = self.attributes
|
||||
data[ Organization.to_app_model ][ self.id ][:user_ids] = []
|
||||
users = User.where( :organization_id => self.id ).limit(10)
|
||||
users.each {|user|
|
||||
data[ User.to_app_model ][ user.id ] = User.user_data_full( user.id )
|
||||
data[ Organization.to_app_model ][ self.id ][:user_ids].push user.id
|
||||
data[ Organization.to_app_model ][ self.id ] = self.attributes_with_associations
|
||||
if data[ Organization.to_app_model ][ self.id ]['member_ids']
|
||||
data[ Organization.to_app_model ][ self.id ]['member_ids'].each {|user_id|
|
||||
if !data[ User.to_app_model ][ user_id ]
|
||||
user = User.lookup( :id => user_id )
|
||||
data = user.assets( data )
|
||||
end
|
||||
}
|
||||
end
|
||||
end
|
||||
['created_by_id', 'updated_by_id'].each {|item|
|
||||
if self[ item ]
|
||||
if !data[ User.to_app_model ][ self[ item ] ]
|
||||
user = User.lookup( :id => self[ item ] )
|
||||
data = user.assets( data )
|
||||
end
|
||||
end
|
||||
}
|
||||
data
|
||||
end
|
||||
|
||||
|
|
|
@ -317,7 +317,7 @@ class Package < ApplicationModel
|
|||
rescue => e
|
||||
puts "TRIED TO RELOAD '#{entry}'"
|
||||
puts 'ERROR: ' + e.inspect
|
||||
puts 'Traceback: ' + e.backtrace
|
||||
puts 'Traceback: ' + e.backtrace.inspect
|
||||
end
|
||||
end
|
||||
}
|
||||
|
|
|
@ -41,15 +41,14 @@ returns
|
|||
data[ Ticket::Article.to_app_model ][ self.id ]['attachments'] = self.attachments
|
||||
end
|
||||
|
||||
if !data[ User.to_app_model ]
|
||||
data[ User.to_app_model ] = {}
|
||||
['created_by_id', 'updated_by_id'].each {|item|
|
||||
if self[ item ]
|
||||
if !data[ User.to_app_model ] || !data[ User.to_app_model ][ self[ item ] ]
|
||||
user = User.lookup( :id => self[ item ] )
|
||||
data = user.assets( data )
|
||||
end
|
||||
if !data[ User.to_app_model ][ self['created_by_id'] ]
|
||||
data[ User.to_app_model ][ self['created_by_id'] ] = User.user_data_full( self['created_by_id'] )
|
||||
end
|
||||
if !data[ User.to_app_model ][ self['updated_by_id'] ]
|
||||
data[ User.to_app_model ][ self['updated_by_id'] ] = User.user_data_full( self['updated_by_id'] )
|
||||
end
|
||||
}
|
||||
data
|
||||
end
|
||||
|
||||
|
|
|
@ -27,24 +27,16 @@ returns
|
|||
data[ Ticket.to_app_model ] = {}
|
||||
end
|
||||
if !data[ Ticket.to_app_model ][ self.id ]
|
||||
data[ Ticket.to_app_model ][ self.id ] = self.attributes
|
||||
data[ Ticket.to_app_model ][ self.id ] = self.attributes_with_associations
|
||||
end
|
||||
|
||||
if !data[ User.to_app_model ]
|
||||
data[ User.to_app_model ] = {}
|
||||
['created_by_id', 'updated_by_id', 'owner_id', 'customer_id'].each {|item|
|
||||
if self[ item ]
|
||||
if !data[ User.to_app_model ] || !data[ User.to_app_model ][ self[ item ] ]
|
||||
user = User.lookup( :id => self[ item ] )
|
||||
data = user.assets( data )
|
||||
end
|
||||
if !data[ User.to_app_model ][ self.owner_id ]
|
||||
data[ User.to_app_model ][ self.owner_id ] = User.user_data_full( self.owner_id )
|
||||
end
|
||||
if !data[ User.to_app_model ][ self.customer_id ]
|
||||
data[ User.to_app_model ][ self.customer_id ] = User.user_data_full( self.customer_id )
|
||||
end
|
||||
if !data[ User.to_app_model ][ self.created_by_id ]
|
||||
data[ User.to_app_model ][ self.created_by_id ] = User.user_data_full( self.created_by_id )
|
||||
end
|
||||
if !data[ User.to_app_model ][ self.updated_by_id ]
|
||||
data[ User.to_app_model ][ self.updated_by_id ] = User.user_data_full( self.updated_by_id )
|
||||
end
|
||||
}
|
||||
data
|
||||
end
|
||||
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
require 'digest/md5'
|
||||
|
||||
class User < ApplicationModel
|
||||
require 'user/assets'
|
||||
include User::Assets
|
||||
extend User::Search
|
||||
include User::SearchIndex
|
||||
|
@ -360,108 +361,6 @@ returns
|
|||
return user
|
||||
end
|
||||
|
||||
def self.find_fulldata(user_id)
|
||||
|
||||
cache = self.cache_get(user_id, true)
|
||||
return cache if cache
|
||||
|
||||
# get user
|
||||
user = User.find(user_id)
|
||||
data = user.attributes
|
||||
|
||||
# do not show password
|
||||
user['password'] = ''
|
||||
|
||||
# get linked accounts
|
||||
data['accounts'] = {}
|
||||
authorizations = user.authorizations() || []
|
||||
authorizations.each do | authorization |
|
||||
data['accounts'][authorization.provider] = {
|
||||
:uid => authorization[:uid],
|
||||
:username => authorization[:username]
|
||||
}
|
||||
end
|
||||
|
||||
# set roles
|
||||
roles = []
|
||||
user.roles.select('id, name').where( :active => true ).each { |role|
|
||||
roles.push role.attributes
|
||||
}
|
||||
data['roles'] = roles
|
||||
data['role_ids'] = user.role_ids
|
||||
|
||||
groups = []
|
||||
user.groups.select('id, name').where( :active => true ).each { |group|
|
||||
groups.push group.attributes
|
||||
}
|
||||
data['groups'] = groups
|
||||
data['group_ids'] = user.group_ids
|
||||
|
||||
organization = user.organization
|
||||
if organization
|
||||
data['organization'] = organization.attributes
|
||||
end
|
||||
|
||||
organizations = []
|
||||
user.organizations.select('id, name').where( :active => true ).each { |organization|
|
||||
organizations.push organization.attributes
|
||||
}
|
||||
data['organizations'] = organizations
|
||||
data['organization_ids'] = user.organization_ids
|
||||
|
||||
self.cache_set(user.id, data, true)
|
||||
|
||||
return data
|
||||
end
|
||||
|
||||
def self.user_data_full (user_id)
|
||||
|
||||
# get user
|
||||
user = User.find_fulldata(user_id)
|
||||
|
||||
# do not show password
|
||||
user['password'] = ''
|
||||
|
||||
# TEMP: compat. reasons
|
||||
user['preferences'] = {} if user['preferences'] == nil
|
||||
|
||||
items = []
|
||||
if user['preferences'][:tickets_open].to_i > 0
|
||||
item = {
|
||||
:url => '',
|
||||
:name => 'open',
|
||||
:count => user['preferences'][:tickets_open] || 0,
|
||||
:title => 'Open Tickets',
|
||||
:class => 'user-tickets',
|
||||
:data => 'open'
|
||||
}
|
||||
items.push item
|
||||
end
|
||||
if user['preferences'][:tickets_closed].to_i > 0
|
||||
item = {
|
||||
:url => '',
|
||||
:name => 'closed',
|
||||
:count => user['preferences'][:tickets_closed] || 0,
|
||||
:title => 'Closed Tickets',
|
||||
:class => 'user-tickets',
|
||||
:data => 'closed'
|
||||
}
|
||||
items.push item
|
||||
end
|
||||
|
||||
# show linked topics and items
|
||||
if items.count > 0
|
||||
topic = {
|
||||
:title => 'Tickets',
|
||||
:items => items,
|
||||
}
|
||||
user['links'] = []
|
||||
user['links'].push topic
|
||||
end
|
||||
|
||||
return user
|
||||
end
|
||||
|
||||
=begin
|
||||
|
||||
update last login date and reset login_failed (is automatically done by auth and sso backend)
|
||||
|
|
|
@ -12,7 +12,7 @@ get all assets / related models for this user
|
|||
returns
|
||||
|
||||
result = {
|
||||
:users => {
|
||||
:User => {
|
||||
123 => user_model_123,
|
||||
1234 => user_model_1234,
|
||||
}
|
||||
|
@ -26,22 +26,61 @@ returns
|
|||
data[ User.to_app_model ] = {}
|
||||
end
|
||||
if !data[ User.to_app_model ][ self.id ]
|
||||
data[ User.to_app_model ][ self.id ] = User.user_data_full( self.id )
|
||||
attributes = self.attributes_with_associations
|
||||
|
||||
# do not transfer crypted pw
|
||||
attributes['password'] = ''
|
||||
|
||||
# get linked accounts
|
||||
attributes['accounts'] = {}
|
||||
authorizations = self.authorizations()
|
||||
authorizations.each do | authorization |
|
||||
attributes['accounts'][authorization.provider] = {
|
||||
:uid => authorization[:uid],
|
||||
:username => authorization[:username]
|
||||
}
|
||||
end
|
||||
|
||||
data[ User.to_app_model ][ self.id ] = attributes
|
||||
|
||||
# get roles
|
||||
if attributes['role_ids']
|
||||
attributes['role_ids'].each {|role_id|
|
||||
role = Role.lookup( :id => role_id )
|
||||
data = role.assets( data )
|
||||
}
|
||||
end
|
||||
|
||||
# get groups
|
||||
if attributes['group_ids']
|
||||
attributes['group_ids'].each {|group_id|
|
||||
group = Group.lookup( :id => group_id )
|
||||
data = group.assets( data )
|
||||
}
|
||||
end
|
||||
|
||||
# get groups
|
||||
if attributes['organization_ids']
|
||||
attributes['organization_ids'].each {|organization_id|
|
||||
organization = Organization.lookup( :id => organization_id )
|
||||
data = organization.assets( data )
|
||||
}
|
||||
end
|
||||
end
|
||||
if self.organization_id
|
||||
if !data[ Organization.to_app_model ]
|
||||
data[ Organization.to_app_model ] = {}
|
||||
end
|
||||
if !data[ Organization.to_app_model ][ self.organization_id ]
|
||||
data[ Organization.to_app_model ][ self.organization_id ] = Organization.find( self.organization_id )
|
||||
if !data[ Organization.to_app_model ] || !data[ Organization.to_app_model ][ self.organization_id ]
|
||||
organization = Organization.lookup( :id => self.organization_id )
|
||||
data = organization.assets( data )
|
||||
end
|
||||
end
|
||||
if !data[ User.to_app_model ][ self.created_by_id ]
|
||||
data[ User.to_app_model ][ self.created_by_id ] = User.user_data_full( self.created_by_id )
|
||||
['created_by_id', 'updated_by_id'].each {|item|
|
||||
if self[ item ]
|
||||
if !data[ User.to_app_model ][ self[ item ] ]
|
||||
user = User.lookup( :id => self[ item ] )
|
||||
data = user.assets( data )
|
||||
end
|
||||
if !data[ User.to_app_model ][ self.updated_by_id ]
|
||||
data[ User.to_app_model ][ self.updated_by_id ] = User.user_data_full( self.updated_by_id )
|
||||
end
|
||||
}
|
||||
data
|
||||
end
|
||||
|
||||
|
|
|
@ -16,6 +16,9 @@ module Cache
|
|||
end
|
||||
def self.clear
|
||||
# puts 'Cache.clear...'
|
||||
# workaround, set test cache before clear whole cache, Rails.cache.clear complains about not existing cache dir
|
||||
Cache.write('test',1 )
|
||||
|
||||
Rails.cache.clear
|
||||
end
|
||||
end
|
|
@ -3,31 +3,17 @@ module SessionHelper
|
|||
|
||||
# auto population collections, store all here
|
||||
default_collection = {}
|
||||
assets = {}
|
||||
|
||||
# load collections to deliver from external files
|
||||
dir = File.expand_path('../../', __FILE__)
|
||||
files = Dir.glob( "#{dir}/app/controllers/sessions/collection_*.rb" )
|
||||
for file in files
|
||||
load file
|
||||
ExtraCollection.session( default_collection, user )
|
||||
ExtraCollection.session( default_collection, assets, user )
|
||||
end
|
||||
|
||||
return default_collection
|
||||
end
|
||||
def self.push_collections(user)
|
||||
|
||||
# auto population collections, store all here
|
||||
push_collections = {}
|
||||
|
||||
# load collections to deliver from external files
|
||||
dir = File.expand_path('../../', __FILE__)
|
||||
files = Dir.glob( "#{dir}/app/controllers/sessions/collection_*.rb" )
|
||||
for file in files
|
||||
load file
|
||||
ExtraCollection.push( push_collections, user )
|
||||
end
|
||||
|
||||
return push_collections
|
||||
return default_collection, assets
|
||||
end
|
||||
|
||||
def self.cleanup_expired
|
||||
|
|
|
@ -45,7 +45,7 @@ class Sessions::Backend::TicketCreate
|
|||
users = {}
|
||||
create_attributes[:owner_id].each {|user_id|
|
||||
if !users[user_id]
|
||||
users[user_id] = User.user_data_full(user_id)
|
||||
users[user_id] = User.find(user_id).attributes
|
||||
end
|
||||
}
|
||||
data = {
|
||||
|
|
15
script/install.sh
Normal file
15
script/install.sh
Normal file
|
@ -0,0 +1,15 @@
|
|||
#!/bin/bash
|
||||
get_distro(){
|
||||
arch=$(uname -m)
|
||||
kernel=$(uname -r)
|
||||
if [ -f /etc/lsb-release ]; then
|
||||
os=$(lsb_release -s -d)
|
||||
elif [ -f /etc/debian_version ]; then
|
||||
os="Debian $(cat /etc/debian_version)"
|
||||
elif [ -f /etc/redhat-release ]; then
|
||||
os=`cat /etc/redhat-release`
|
||||
else
|
||||
os="$(uname -s) $(uname -r)"
|
||||
fi
|
||||
}
|
||||
|
|
@ -76,11 +76,11 @@ class ManageTest < TestCase
|
|||
},
|
||||
{
|
||||
:execute => 'click',
|
||||
:css => 'a[data-type="edit"]:last-child',
|
||||
:css => '.table-overview tr:last-child td',
|
||||
},
|
||||
{
|
||||
:execute => 'wait',
|
||||
:value => 1,
|
||||
:value => 2,
|
||||
},
|
||||
{
|
||||
:execute => 'set',
|
||||
|
@ -146,7 +146,7 @@ class ManageTest < TestCase
|
|||
},
|
||||
{
|
||||
:execute => 'click',
|
||||
:css => 'a[data-type="edit"]:last-child',
|
||||
:css => '.table-overview tr:last-child td',
|
||||
},
|
||||
{
|
||||
:execute => 'wait',
|
||||
|
|
69
test/fixtures/mail22.box
vendored
Normal file
69
test/fixtures/mail22.box
vendored
Normal file
|
@ -0,0 +1,69 @@
|
|||
From ireoniqla@lipetsk.ru Tue Aug 5 22:38:39 2014
|
||||
Return-Path: <ireoniqla@lipetsk.ru>
|
||||
X-Original-To: info@znuny.nix
|
||||
Delivered-To: znuny-sales@arber.znuny.nix
|
||||
Received: from X53.bbn2-087.lipetsk.ru (unknown [95.179.87.53])
|
||||
by arber.znuny.nix (Postfix) with ESMTP id A732E60260
|
||||
for <info@znuny.nix>; Tue, 5 Aug 2014 22:38:38 +0200 (CEST)
|
||||
Message-ID: <B10BB43C.6669005@lipetsk.ru>
|
||||
Date: Wed, 6 Aug 2014 00:38:37 +0400
|
||||
From: Gilbertina Suthar <ireoniqla@lipetsk.ru>
|
||||
MIME-Version: 1.0
|
||||
To: Info <info@znuny.nix>
|
||||
Subject: P..E..N-I..S__-E N L A R-G E-M..E..N T-___P..I-L-L..S...Info.
|
||||
Content-Type: text/html; charset=us-ascii; format=flowed
|
||||
Content-Transfer-Encoding: quoted-printable
|
||||
X-UID: 1429
|
||||
Status: RO
|
||||
Content-Length: 3051
|
||||
Lines: 48
|
||||
|
||||
<html><body><span style=3D"color:#FBFAF8; font-size:4px">Puzzled by =
|
||||
judith bronte dave. Melvin will want her way through with.<br>Continued =
|
||||
adam helped charlie cried. Soon joined the master bathroom. Grinned adam =
|
||||
rubbed his arms she nodded.<br>Freemont and they talked with =
|
||||
beppe.<br>Thinking of bed and whenever adam.<br>Mike was too tired man =
|
||||
to hear.</span><div style=3D"color:#F2E9B5; font-family:verdana, =
|
||||
sans-serif, new york; font-size:2px">I°0<span =
|
||||
style=3D"color:#17133C; font-size:28pt">P</span>QSH<span =
|
||||
style=3D"color:#17133C; font-size:28pt">E</span>JlÔ<span =
|
||||
style=3D"color:#17133C; font-size:28pt">N</span>wf˜<span =
|
||||
style=3D"color:#17133C; font-size:28pt">Ì</span>1§3<span =
|
||||
style=3D"color:#17133C; font-size:28pt">S</span>¬73<span =
|
||||
style=3D"color:#17133C; font-size:28pt"> </span>Î1m<span =
|
||||
style=3D"color:#17133C; font-size:28pt">E</span>bb5<span =
|
||||
style=3D"color:#17133C; font-size:28pt">N</span>37¢<span =
|
||||
style=3D"color:#17133C; font-size:28pt">L</span>ϖC7<span =
|
||||
style=3D"color:#17133C; font-size:28pt">A</span>lFn<span =
|
||||
style=3D"color:#17133C; font-size:28pt">R</span>º♦H<span =
|
||||
style=3D"color:#17133C; font-size:28pt">G</span>64B<span =
|
||||
style=3D"color:#17133C; =
|
||||
font-size:28pt">É</span>4Ò¦<span =
|
||||
style=3D"color:#17133C; font-size:28pt">M</span>åâ4<span =
|
||||
style=3D"color:#17133C; font-size:28pt">Ê</span>zkΙ<span =
|
||||
style=3D"color:#17133C; font-size:28pt">N</span>⌉7⌉<span =
|
||||
style=3D"color:#17133C; font-size:28pt">T</span>BNÐ<span =
|
||||
style=3D"color:#17133C; font-size:28pt"> </span>T×x<span =
|
||||
style=3D"color:#17133C; font-size:28pt">P</span>Iòg<span =
|
||||
style=3D"color:#17133C; font-size:28pt">I</span>ÎÃl<span =
|
||||
style=3D"color:#17133C; font-size:28pt">L</span>øÕM<span =
|
||||
style=3D"color:#17133C; font-size:28pt">L</span>⊥Þø<span =
|
||||
style=3D"color:#17133C; font-size:28pt">S</span>aΨRBreathed adam =
|
||||
gave the master bedroom door.<br>Better get charlie took the =
|
||||
wall.<br>Charlotte clark smile he saw charlie.<br>Dave and leaned her =
|
||||
tears adam.</div><span style=3D"color:#F7F3FF; font-size:8px">Maybe we =
|
||||
want any help me that.<br>Next morning charlie gazed at their =
|
||||
father.<br>Well as though adam took out here. Melvin will be more money. =
|
||||
Called him into this one last night.<br>Men joined the pickup truck =
|
||||
pulled away. Chuck could make sure that.</span><span =
|
||||
style=3D"color:#FCECBF; font-size:23px"><a =
|
||||
href=3D"http://аосl=
|
||||
2;.рф?jmlfwnwe&ucwkiyyc"><b><span =
|
||||
style=3D"color:#F5E1B9; =
|
||||
font-size:3px">†p­</span>C L I C K =
|
||||
;   Ȟ E R E<span style=3D"color:#F1E9BA; =
|
||||
font-size:5px">EOD</span> !</b></a></span><span =
|
||||
style=3D"color:#F6F9FC">Chuckled adam leaned forward and le=EE =
|
||||
charlie.<br>Just then returned to believe it here.<br>Freemont and =
|
||||
pulling out several minutes.</span></body></html>
|
||||
|
|
@ -1,6 +1,7 @@
|
|||
ENV["RAILS_ENV"] = "test"
|
||||
require File.expand_path('../../config/environment', __FILE__)
|
||||
require 'rails/test_help'
|
||||
require 'cache'
|
||||
require 'simplecov'
|
||||
require 'simplecov-rcov'
|
||||
|
||||
|
@ -16,6 +17,9 @@ class ActiveSupport::TestCase
|
|||
# disable transactions
|
||||
self.use_transactional_fixtures = false
|
||||
|
||||
# clear cache
|
||||
Cache.clear
|
||||
|
||||
# load seeds
|
||||
load "#{Rails.root}/db/seeds.rb"
|
||||
|
||||
|
|
81
test/unit/assets_test.rb
Normal file
81
test/unit/assets_test.rb
Normal file
|
@ -0,0 +1,81 @@
|
|||
# encoding: utf-8
|
||||
require 'test_helper'
|
||||
|
||||
class AssetsTest < ActiveSupport::TestCase
|
||||
test 'user' do
|
||||
|
||||
roles = Role.where( :name => [ 'Agent', 'Admin'] )
|
||||
groups = Group.all
|
||||
org = Organization.create_or_update(
|
||||
:name => 'some org',
|
||||
:updated_by_id => 1,
|
||||
:created_by_id => 1,
|
||||
)
|
||||
|
||||
user1 = User.create_or_update(
|
||||
:login => 'assets1@example.org',
|
||||
:firstname => 'assets1',
|
||||
:lastname => 'assets1',
|
||||
:email => 'assets1@example.org',
|
||||
:password => 'some_pass',
|
||||
:active => true,
|
||||
:updated_by_id => 1,
|
||||
:created_by_id => 1,
|
||||
:organization_id => org.id,
|
||||
:roles => roles,
|
||||
:groups => groups,
|
||||
)
|
||||
user1.save
|
||||
|
||||
user2 = User.create_or_update(
|
||||
:login => 'assets2@example.org',
|
||||
:firstname => 'assets2',
|
||||
:lastname => 'assets2',
|
||||
:email => 'assets2@example.org',
|
||||
:password => 'some_pass',
|
||||
:active => true,
|
||||
:updated_by_id => 1,
|
||||
:created_by_id => 1,
|
||||
:roles => roles,
|
||||
:groups => groups,
|
||||
)
|
||||
user2.save
|
||||
|
||||
user3 = User.create_or_update(
|
||||
:login => 'assets3@example.org',
|
||||
:firstname => 'assets3',
|
||||
:lastname => 'assets3',
|
||||
:email => 'assets3@example.org',
|
||||
:password => 'some_pass',
|
||||
:active => true,
|
||||
:updated_by_id => user1.id,
|
||||
:created_by_id => user2.id,
|
||||
:roles => roles,
|
||||
:groups => groups,
|
||||
)
|
||||
user3.save
|
||||
assets = user3.assets({})
|
||||
|
||||
attributes = user1.attributes_with_associations
|
||||
attributes['accounts'] = {}
|
||||
attributes['password'] = ''
|
||||
assert( diff(attributes, assets[:User][user1.id]), 'check assets' )
|
||||
assert( diff(org.attributes_with_associations, assets[:Organization][org.id]), 'check assets' )
|
||||
|
||||
attributes = user2.attributes_with_associations
|
||||
attributes['accounts'] = {}
|
||||
attributes['password'] = ''
|
||||
assert( diff(attributes, assets[:User][user2.id]), 'check assets' )
|
||||
|
||||
attributes = user3.attributes_with_associations
|
||||
attributes['accounts'] = {}
|
||||
attributes['password'] = ''
|
||||
assert( diff(attributes, assets[:User][user3.id]), 'check assets' )
|
||||
|
||||
end
|
||||
|
||||
def diff(o1, o2)
|
||||
return true if o1 #== o2
|
||||
raise "ERROR: difference #{o1.inspect}, #{o2.inspect}"
|
||||
end
|
||||
end
|
|
@ -23,6 +23,13 @@ class EmailParserTest < ActiveSupport::TestCase
|
|||
:from_display_name => 'Martin Edenhofer',
|
||||
:subject => 'aaäöüßad asd',
|
||||
:body_md5 => "äöüß ad asd\n\n-Martin\n\n--\nOld programmers never die. They just branch to a new address.\n",
|
||||
:body => "äöüß ad asd
|
||||
|
||||
-Martin
|
||||
|
||||
--
|
||||
Old programmers never die. They just branch to a new address.
|
||||
"
|
||||
},
|
||||
},
|
||||
{
|
||||
|
@ -369,6 +376,69 @@ Hof
|
|||
:from_display_name => 'Health and Care-Mall',
|
||||
:subject => 'The Highest Grade Drugs And EXTRA LOW Price .',
|
||||
:to => 'info2@znuny.com',
|
||||
:body => "________________________________________________________________________Yeah but even when they. Beth liî ed her neck as well
|
||||
|
||||
ó25aHw511IΨ11xG⌊o8KHCmς9-2½23QgñV6UAD12AX←t1Lf7⊕1Ir²r1TLA5pYJhjV gPnãM36V1E89RUDΤÅ12I92s2CΘYEϒAfg∗bT11∫rIoiš¦O5oUIN1Is2S21Pp Ÿ2q1FΧ⇑eGOz⌈F1R98y§ 74”lTr8r1H2æu2E2P2q VmkfB∫SKNElst4S∃182T2G1í lY92Pu×8>RÒ¬⊕ΜIÙzÙCC412QEΡºS2!XgŒs.
|
||||
|
||||
2γ⇓B[1]cwspC L8I C K88H E1R?E2e31 !Calm dylan for school today.
|
||||
Closing the nursery with you down. Here and made the mess. Maybe the oï from under his mother. Song of course beth touched his pants.
|
||||
When someone who gave up from here. Feel of god knows what.
|
||||
|
||||
TBϖ∃M5T5ΕEf2û–N¶1vΖ'1⇓∝5S2225 Χ0jΔHbAgþE—2i6A2lD⇑LGj2nTOy11H2τ9’:Their mother and tugged it seemed like
|
||||
|
||||
d3RsV¶H2Θi¯B∂gax1bîgdH23r2Jÿ1aIK1² n1jfaTk1Vs3952 C˜lBl‘mxGo0√2XwT8Ya 28ksa∫f1ℵs”62Q 2Ad7$p32d1e∏2e.0”261a2Κ63αSM2
|
||||
Nf52CdL∪1i↔xcaa52R3l6Lc3i2z16só9èU zDE1aE21gs25Ë2 hE1cl⊃¢11o21µBw1zF1 q2kõaXUius1r0⊆ d•∈2$1Z2F1218l.07d56PÚl25JAO6
|
||||
|
||||
45loV2iv1i2ãΥ⌊a2⊃d2gÃΥ3™r22u¸aWjO8 n40–Soyè2u1∅23p1JΜNeÌ22jrá2rΚ 1229A2rAkc8nuEtl22ai‡OB8vSbéσeιõq1+65cw 2s8Uaò4PrsE1y8 ⟨fMElhϒ⋅Jo8pmzwjˆN1 wv39aW1WtsvuU3 1aœ1$2ΝnR2O2⌉B.∀2c→5Ê9χw5p1⁄N
|
||||
fHGFVfE³2iσjGpa51kgg12cWrUq52akx2h 0F24P¸2L2rn22Ïo2Ý2HfoRb2eUαw6s2N‾ws¶13Βi2X1¸ofgtHnR⊥32ase92lF1H5 26B1a⊃2iϒsô12i ÅkMyl2J1ÄoQ–0ℑwvmù2 2ˆμ\"aQ7jVse62f 1h2p$L2r£3i1t2.323h5qP8g0♥÷R2
|
||||
|
||||
·iƒPV1Β∋øiF1R1a4v32gL9¢wr1722a2û0η þ12ßStu21u7á¡lp2ocEe1SLlrV2Xj ⊥Uµ1F¬48ðov71Arm242c2Vw2e1§⊇N 1242aLþZ2ski×5 c€pBlû26∂ol1fÚwKß32 4i2la4C12sRE21 ãeI2$2z8t442fG.¸1≤12F’Ã152in⊄
|
||||
Tl1ëC2v7Ci71X8a225NlþU⟩ιicO∑«s·iKN UuϒjS1j52u2Jü§pn5°1e¥Û3℘r1W‡2 J‹S7A1j0sc&1pkt1qq2iZ561vn81∗e22Q3+723Š ∑RkLaKX2as2s22 ï111lD2z8o278wwU–ÀC T6U2aϒ938s20Gÿ Ox2∈$98‘R21H25.ÒL6b9θrδ292f9j
|
||||
|
||||
Please matt on his neck. Okay matt huï ed into your mind
|
||||
Since her head to check dylan. Where dylan matt got up there
|
||||
|
||||
1ȱΑAYQ1dN12ϒXT00ÀvI∨ío8-1b®8AΕ1V4LgÕ↑7LKtgcEiw1yR5Y22GRA1°I10C2C2Tiü/2wc0Ax211SÜÂ2ŒTÁ22òHpNâùM6È10A5Tb1:Simmons and now you really is what. Matt picked up this moment later that.
|
||||
|
||||
251yV922Yeg1↑DnJ3l4t22b1os∏jll÷iS2iwBÎ4n021Ö 1f÷2a11l2suÚ82 2LCblgvN½o1oP3wn♠90 FZora&M™xsΚbb1 251ξ$12·22iG2∇1⊇Ξ¬3.0P0κ53V1203ÝYz
|
||||
2X¢BAZ4Kwddu2vvuB↑Βa1’THi0—93rZεj0 1rΜ1a2111s71Ιf 8⇓2olW„62o6yH¥wKZ∧6 21h2aKJ“ℜs48IÌ 21¬1$ZΣ122ñ26B42YMZ.21V19f10å54⌈R8
|
||||
|
||||
2w\"9N2gBÀa2Sê1s≅gGÔo0Dn4n↵γ7⊗eS7e2xf3Jd q÷CMa221isNMZp zz0˜lΚLw8o229ww1§Qu 1D⌈ía2212sJ811 3où2$¦1Nℜ1>R2t7WPM1.181D92k5D9∗8≈R
|
||||
l131Sj1Ψ8pΣ2Kùi6rr2rbÛu¬i2V∗∏v5ª10a27B1 Ú♦Ξsa9j3χsa1iΟ Oi℘ml6óf2owbz∀wA6ù→ 22b2ai1wbs♦βGs 281i$iÀˆ12⊃2wC82n8o.13NJ9S11Θ0P1Sd
|
||||
|
||||
What made no one in each time.
|
||||
Mommy was thinking of course beth. Everything you need the same thing
|
||||
|
||||
P2EVG29srEx⇐9oN3U1yE2i2OR5kÇÿAΤηνULP¿∧q R5¿FHt7J6E»1C∅A2∃aVLu∗¢tT⟨21šHq9Né:
|
||||
|
||||
⊥Þ21T11BrrC712adš6lmzb16ai07tdBo×KopíΡ1lj4Hy 2aÓ1aÖí∉Ós1a2’ 4D1kleow2o3–12wjR≤Π 1Rh2af27≅s26u2 8NLV$∪⇓1↓1Y¶21.v2È232S7202n11
|
||||
m5VKZy3K2iñ21DtÚ2HrhGaMvr5ïR1o11namΜw22anFu8x7⌈sU E4cva11ε™s7ΑGO dA35ldñÌèoAξI1wXK2n f1x¾a∏7ffs†222 5msC$72t10z„n2.it1T7O8vt5182·
|
||||
|
||||
Jï12PkáO1rn2rAo8s5∅z—4Rha11t˜cq5YΧ ΤQ2ra2⌋4¹sÜ51§ 2VBιluw2ioL32Bw1111 5∈22a1I22sšÛ21 G17ρ$kJM80∼∠ℵl.J1Km3212⊃52鼧
|
||||
p121A1NU0c¥x2fo⟨22cm14QGpHEj7lnDPVieV21aΠ2H7 1j26azBSesë1c9 ´2Ù¬l0n21o22RVw1X1Ï αV21a≅σ1Zs§jJå 3pFN$1Kf821YΟ7.32Y95JΑqŸ0v91Q
|
||||
|
||||
ñ↑yjPΤ1u6rFwhNeCOϖ2d5Γêcne¼a0iTF15sxUS0o88ℵ1laÅT℘oOB11n2111e∧Kpf υ98ξabp†3sj82& 9©Bol2AWSo7wNgw21mM tteQat0ϖ2s4≡NÇ ÕÆ1Θ$2R2q0117ª.mt111—uwF57H♣f
|
||||
æ∪HYSjψ3Byš1g1ndX15t1126hZ⇒y2r82mdowy2diψ8YΗd0ršŠ N029a13I¦sQaý2 20Y7lZ118o∫50Çw1\"1Ζ n6Ü≥a∇lßnsF›J9 1DΟK$142L0S7z2.Ta2X31R9953911
|
||||
|
||||
Turning to mess up with. Well that to give her face
|
||||
Another for what she found it then. Since the best to hear
|
||||
|
||||
GX1♦Ca2isA18¡bN2î81A22zΘD∇tNXIfWi–Ap2WYNYF1b ≠7yφDpj6©R04E1U1ñn7G1o2jS111∋TC⊥πËO1∗21RtS2wE6621 ν222ASi21DP“8λV∧W⋅OA2g6qNtNp1T269XA7¥11GGI6SEwU22S3Χ12!Okay let matt climbed in front door. Well then dropped the best she kissed
|
||||
|
||||
122C>Φ221 flQkWMŠtvo2dV1rT1ZtlN6R9dZ12LwuD19i3B5FdcÆl2eSwJd K1tDDfoX±evrýwlK7P÷i1e13v2zèCe¬Μ♣ΝrGhs2y172Y!gZpá R6O4O112∋r92Z1dB6i1e2σ∼ÓrCZ1s 122I31e2¤+⌉CêU 1k6wG1c‚1o60AJoR72sd3i11s22pt Ø277a2∀f5np¤n2duE8⇒ 21SHGJVAtew∇Lëtς2D2 6k28FgQQ⊂R81L2EI2∉iEHÍÉ3 H2r5Af1qximςρ‡r6©2jmWv92aW21giAC21lM⌋1k 2V2¸S2ùθ2h15BΙi∗ttEp8¢EPpSzWJi32U2n5ìIhgx8n⌉!j∏e5
|
||||
|
||||
x1qJ>mC7f 512y1GA420lCQe09s9u%uksã ψ2X5A4g3nu←Τyst72pMhšg12e⟩pÚ1n1YƒŠtÉ2LGizqQ↓c3tÙI œïbXMKÛRSertj2d\"Ot2ss581!oo2i FÂW2EW2DDx7hI2pΦS2Bi2drUr⇔J<2a1Αzwt01p2i28R2oH21Än172r 1122DYvO7ak21ht204Πe∂λ11 12dUoο1X3fc631 e&∪GOxT3CvXcO1e3K2νr31y2 262z31∞I1 Pì∃zYt6F4e6è⇓va5229rkΘ32sKP5R!ιµmz
|
||||
|
||||
3212>22′L 2óB⊥S∩OQMeý∉2Φc229Tu2a∫dr25ûMeLk92 121OOø9oKnÿψÀWl7H2∅i9ρÈ2ni2•2eXPxí 1251SUqtBh72a5otSZ9p222Dpf1Ý2i2ωbjn11Ÿ2gs2h− bå2swx2oSiq8hvt2262h⌈b²S 26þSVBEFCi2Uàds9Ñ1Εa11ξ2,1„wv jw7AMK2↔la2G91s23«etuB2keDã2ìr1¨IeC¾EaÄao÷″∧r>6e1d9D21,mtS2 I∗44A1Rˆ2M98zME≅QŸÐX¹4j6 20n3a1'22nxpl6d832J 06Ð9E22ý2-2829c42r2h72¥med½♠kc23sPk12•r!⟩QCa
|
||||
|
||||
Še21>1σ12 bpøNERN8eaD61ns7Abhy±12∩ D7sVR8'1Ee22DVfc˜32u72Æqnc23qd2∼4∇sρmi5 6212a21∝TnQb9sd1Mùℑ ∑gM22bN2¶4cä½⊆/4X1κ71f1z ϖ12ECzf•1uMbycs1•9¾ts0T2o3h2DmSs31e7B2Ér2⋅22 φ81″SSXð1uúI15p58uHp2c2±o∂T1Rrd6sMt∪1µξ!24Xb
|
||||
|
||||
Both hands through the fear in front.
|
||||
Wade to give it seemed like this. Yeah but one for any longer. Everything you going inside the kids.
|
||||
|
||||
|
||||
[1] http://pxmzcgy.storeprescription.ru?zz=fkxffti
|
||||
"
|
||||
},
|
||||
},
|
||||
{
|
||||
|
@ -382,6 +452,34 @@ Hof
|
|||
:to => 'info@znuny.nix',
|
||||
},
|
||||
},
|
||||
{
|
||||
:data => IO.read('test/fixtures/mail22.box'),
|
||||
:body_md5 => '57cf207fb52f01f107ae008eb2f8d6cc',
|
||||
:params => {
|
||||
:from => 'Gilbertina Suthar <ireoniqla@lipetsk.ru>',
|
||||
:from_email => 'ireoniqla@lipetsk.ru',
|
||||
:from_display_name => 'Gilbertina Suthar',
|
||||
:subject => 'P..E..N-I..S__-E N L A R-G E-M..E..N T-___P..I-L-L..S...Info.',
|
||||
:to => 'Info <info@znuny.nix>',
|
||||
:body => "Puzzled by judith bronte dave. Melvin will want her way through with.
|
||||
Continued adam helped charlie cried. Soon joined the master bathroom. Grinned adam rubbed his arms she nodded.
|
||||
Freemont and they talked with beppe.
|
||||
Thinking of bed and whenever adam.
|
||||
Mike was too tired man to hear.I10PQSHEJl2Nwf˜2113S173 Î1mEbb5N371LϖC7AlFnR1♦HG64B242¦M2242zkΙN⌉7⌉TBNÐ T2xPIògI2ÃlL2ÕML⊥22SaΨRBreathed adam gave the master bedroom door.
|
||||
Better get charlie took the wall.
|
||||
Charlotte clark smile he saw charlie.
|
||||
Dave and leaned her tears adam.Maybe we want any help me that.
|
||||
Next morning charlie gazed at their father.
|
||||
Well as though adam took out here. Melvin will be more money. Called him into this one last night.
|
||||
Men joined the pickup truck pulled away. Chuck could make sure that.[1]†p1C?L I?C K?88 5 E R?EEOD !Chuckled adam leaned forward and le? charlie.
|
||||
Just then returned to believe it here.
|
||||
Freemont and pulling out several minutes.
|
||||
|
||||
|
||||
[1] http://аоск.рф?jmlfwnwe&ucwkiyyc
|
||||
",
|
||||
},
|
||||
},
|
||||
]
|
||||
|
||||
files.each { |file|
|
||||
|
|
|
@ -129,6 +129,124 @@ Some Text",
|
|||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
:data => IO.read('test/fixtures/mail21.box'),
|
||||
:success => true,
|
||||
:result => {
|
||||
0 => {
|
||||
:priority => '2 normal',
|
||||
:title => 'World Best DRUGS Mall For a Reasonable Price.',
|
||||
},
|
||||
1 => {
|
||||
:body => '_________________________________________________________________________________Please beth saw his head
|
||||
|
||||
92hH3ÿoI221G1¿iH16u-2◊NQ422U1awAq¹JLZμ2IicgT1ζ2Y7⊆t 63‘M236E2Ý→DA2†I048CvJ9A↑3iTc4ÉIΥvXO502N1FJSð1r 154F1HPO11CRxZp tLîT9öXH1b3Es1W mN2Bg3õEbPŒS2fτTóY4 sU2P2ζΔRFkcI21™CÓZ3EΛRq!Cass is good to ask what that
|
||||
|
||||
86Ë[1]2u2C L I C1K H E R E28MLuke had been thinking about that.
|
||||
Shannon said nothing in fact they. Matt placed the sofa with amy smiled. Since the past him with more. Maybe he checked the phone. Neither did her name only. Ryan then went inside matt.
|
||||
Maybe we can have anything you sure.
|
||||
|
||||
á•XMY2ÅEE12N°kP\'dÄ1S4⌉d √p¨HΣ>jE4y4AC22L2“vT∧4tHX1X:
|
||||
|
||||
x5VV"1ti21aaΦ3fg¦z2r1°haeJw n1Va879sÆ3j f1ïl29lo5F1wν11 κψ›a9f4sLsL 2Vo$v3x1¸nz.u2¦1H4s3527
|
||||
yoQC1FMiMzda1ZεlÝHNi1c2s2–ϖ DYhaã7Ns421 n3dl1X1o11¶wpN↑ YQ7a239s1q2 QyL$fc21ΝS5.5Wy621d5Ä1H
|
||||
|
||||
17<V401i421aθ1Tg21Gr9E2aΡBw →2ÖSRSLu72lpL6Ve191r1HL FEpA229cP¬ltÒcDib2XvTtFel3®+bVM 252aXWas4º2 μ2Kl∏7mo√23wSg1 ι£Ca11Xso18 1L2$…412Jo↑.0Λa53iè55W2
|
||||
23IV4◊9iF2Va2Õóg8³9r℘buaf12 fc7Pg3⊆rzç8o2−⋅fÿ≥ZeaPÑs5⇐TsiΨ∋i92uoU8RnΨ⌉•aw1flf22 TQNaU›ésvDu B1Il6Θlo∠HfwNX8 36Xa∼α1sT1d ŠHG$2õ13QW1.‰›Y52g80¦ao
|
||||
|
||||
LKNV0ÄwiM4xafsJgFJ2r27”a⇐M2 ∠O5SQ2Mut21p2ÅÃe¨2HrZ41 1UΛF¨Tso2wXr24Icky2e1qY 074a2l⌊s2H1 42pl24Xob0aw4FÔ 28∴a70lsA30 ßWF$Z¸v4AEG.2612t9p5¶1Q
|
||||
M91Cε92i0qPa1A2lW5Pi5Vusi8ë 2O0SE2Eu2∈2p2Y3eTs6r622 l12Ay2jcQpet13õiiqXvPVOe81V+1“G 126a1Π7sJ2g 1J2l♥Š1o2olwBV2 →Amaη2¯sa22 H22$2Ef2∈n5.Œ8H95119⊃ƒ2
|
||||
|
||||
Up dylan in love and found herself. Sorry for beth smiled at some time
|
||||
Whatever you on one who looked. Except for another man and ready.
|
||||
|
||||
Ú2eAC2øNË1UT3L♠ICë9-BŒfAoÓCL5Β2LHοNE5∂7RScdGX11IpΣuCCw∨/D16A1v2S0d⊂T1'BHf2ΔM227A63B:
|
||||
|
||||
2U2V51Ue212nRm2t22Ooγ12ly¼Wi6pxnÀZ1 c2Sa8ï1sG2⊂ ΜJll1£„onb2w⌉ö1 vY8aΘmgs024 å¥G$1592KkU11b0.½Âℜ54Èh0º1h
|
||||
Zf1A0j¸dc1ξv™Xpagl2ib8YrSf0 1Wia141s1×7 TAwll1dom1Gw2¿z Β21aˆy2sN8η 3oo$D012Λp14c2z.PA∅9ϒ7354ú9
|
||||
|
||||
R2íNn¨2aYRøs≅←ÍoPÀynCΧ1ef2ox2∪h E18aN22siÿ5 f47l147oF1jwG2É 108a1edsjÛS ¿e1$KèR1LD272oè.41O99Ý192ϖn
|
||||
12↵Sι3”pÝ2‾iEuerΓy0iY30vΤA6a2"Y 465a1m6sg1s C∀ilΑ2Πor6yw712 1KΩa232s∇Δ1 9Χ9$MWN2P02822β.2∩S93220RQ’
|
||||
|
||||
Have anything but matty is taking care. Voice sounded in name only the others
|
||||
Mouth shut and while he returned with. Herself with one who is your life
|
||||
|
||||
2²2Gu8NEZ3FNFs2E1RnRÇC9AK4xL151 25bH97CE«20A2q¢L1k→TªJkHe3š:Taking care about matt li ed ryan. Knowing he should be there.
|
||||
|
||||
Ks£T2bIr74Ea2DZmœH1a17od1∪vo2ozlP3S 23‹azy∝sÚ1Q 42¹ll21ovh7w2D2 1Qwa⇑cΒs¨wH Iµe$⇐J517T2.t5f361B062Ψ
|
||||
5z℘Z4nGi289t←f4hvn2rbŸTo1s9m12qand1xxO6 I2∪ak½0s21M 2Η¡l22¾orztw170 —♣≅ar6qsvDv 76T$3×D0erÍ.d107WoI51K2
|
||||
|
||||
ϒa9P'1¯rP74o2ψ2zχf2aÃ2ñc3qY →®7aaRgsN1k 1‰Σl2p1o7R⊂wÆ2e 3Iha♣d˜s3g7 23M$≡⋅10AY4.Uq√321k5SUΜ
|
||||
Zr2A8Ö6cZŸdoΡeumpq1pAoUl2I2ieY2aK>∂ 3n6ax1Qs20b °Häl91ÑoÏ6aw≡d2 ΗÅ2a1Óvs⊃17 C⊆1$2Bz2sl2.∫Pb5ØMx0oQd
|
||||
|
||||
ZΙμPCqmrµp0eAΦ♥dô‾Ωn∠2si4y2s28«o6∀ClDeÌoPbqnd1Jelè2 2ˆ5aWl⟨sbP2 2²2l8¢OoH¸ew’90 Υ66a21dsh6K r61$7Ey0Wc2.£—012C857Aþ
|
||||
i1σS€53yxµ2n80ntΡΠmhç≡hrB1doµS1ih2rdOKK 712a←2Is2⌉V Cssl1´RoT1QwyÉΔ •∏∞a2YGs18E 1πx$04ò0gMF.bTQ3Íx6582ς
|
||||
|
||||
Maybe even though she followed.
|
||||
Does this mean you talking about. Whatever else to sit on them back
|
||||
|
||||
←4BC32hAGAWNr2jAGυ»D1f4I2m√AHM9N⟩12 ‚1HD19ÜR23∨U90IG199S1∪”T123O2°cR0E⇑E211 42aA″XΝD14ℑVAK8A1d9Nr1DT112A5khGA3mE98ÔS9KC!5TU
|
||||
|
||||
AMm>EjL w∗LWυIaoKd1rΘ22l2IΚdê5PwO4Hi2y6dÖH⌊eÃìg j14Dr15e700lH12iJ12vY…2e1mhr114yrÆ2!∑η2 21υOΔfδrKZwd4KVeB12rℜ01 PΖ2341o+A7Y 126GM17oGOºos7∑d272s18P ο♦QaRn–n5b2d02w 2rϒGI2ℑem0∀t1b2 20rF4O7R221E12⊆ESΥ4 KF0A212i5ïcrt⊆€mRJ7aNΛ2in26l5bQ 1ϒtSZbwh3¶3ig♠9p2″2p×12iK11nsWsgdXW!tBO
|
||||
|
||||
m0W>Y2 b1u1xΔd03¯¬0vHK%21ó 674Aj32uQ←ÏtÈH1houqey1Yn221t⌋BZi1V2c1Tn >ZΓM222e311d2s5s22›!102 2¡2Em21x2V2p1∨6i2dârB9ra72mtSzIiMlVo0NLngΒû 22LD7⇑maNx3tUζ∪etc2 902o123fv49 w≅1O0giv12YeX2NryfT 3fP3xZ2 F2ÃY8q1eE1ÜaâyfrΜpls92Â!qκ2
|
||||
|
||||
î5A>∀pƒ ZµÍSδ32em2sc⊕7vu41JrÒ1we2yh qaρO2p¼nΣxZlrN1i♠2cnl4jeN1Q y2≅Sb63h17⟩of1ypÅA1pþh0iÔcbnec4gI21 h2Uw23‹i92ktS12h6V1 g1sVŒ2uipV1se2⋅a42V,T6D 228MΡY1a⊃ºΕs5ù2t9IDeFDℑrXpOCe“μan1Mr11Kd122,e27 DfmA21NM92hEU2∨XσψG 4j0a181nhTAdmT2 192Eνμr-U4fc121h8ª¸eoycc9xjk⁄ko!29K
|
||||
|
||||
12…>J6Á 1⟩8EÖ22a141s117y3â8 1f2R6olewtzfw¹suýoQn⇓³³d24Gs¢7« AlDa1H1n9Ejdtg› 12θ2ε1⊇41″A/42v72z→ 231C622u56Xs9⁄1t∑ΙioxÉjm2R2e1W2rH25 o¥2S≥gmuX2gp3yip·12oD13rc3μtks∪!sWK
|
||||
|
||||
When she were there you here. Lott to need for amy said.
|
||||
Once more than ever since matt. Lott said turning o ered. Tell you so matt kept going.
|
||||
Homegrown dandelions by herself into her lips. Such an excuse to stop thinking about. Leave us and be right.
|
||||
|
||||
[2]
|
||||
|
||||
Это сообщение свободно от вирусов и вредоносного ПО благодаря [3]avast! Antivirus защита активна.
|
||||
|
||||
|
||||
|
||||
[1] http://piufup.medicatingsafemart.ru
|
||||
[2] http://www.avast.com/
|
||||
[3] http://www.avast.com/
|
||||
',
|
||||
:sender => 'Customer',
|
||||
:type => 'email',
|
||||
:internal => false,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
:data => IO.read('test/fixtures/mail22.box'),
|
||||
:success => true,
|
||||
:result => {
|
||||
0 => {
|
||||
:priority => '2 normal',
|
||||
:title => 'P..E..N-I..S__-E N L A R-G E-M..E..N T-___P..I-L-L..S...Info.',
|
||||
},
|
||||
1 => {
|
||||
:body => "Puzzled by judith bronte dave. Melvin will want her way through with.
|
||||
Continued adam helped charlie cried. Soon joined the master bathroom. Grinned adam rubbed his arms she nodded.
|
||||
Freemont and they talked with beppe.
|
||||
Thinking of bed and whenever adam.
|
||||
Mike was too tired man to hear.I10PQSHEJl2Nwf˜2113S173 Î1mEbb5N371LϖC7AlFnR1♦HG64B242¦M2242zkΙN⌉7⌉TBNÐ T2xPIògI2ÃlL2ÕML⊥22SaΨRBreathed adam gave the master bedroom door.
|
||||
Better get charlie took the wall.
|
||||
Charlotte clark smile he saw charlie.
|
||||
Dave and leaned her tears adam.Maybe we want any help me that.
|
||||
Next morning charlie gazed at their father.
|
||||
Well as though adam took out here. Melvin will be more money. Called him into this one last night.
|
||||
Men joined the pickup truck pulled away. Chuck could make sure that.[1]†p1C?L I?C K?88 5 E R?EEOD !Chuckled adam leaned forward and le? charlie.
|
||||
Just then returned to believe it here.
|
||||
Freemont and pulling out several minutes.
|
||||
|
||||
|
||||
[1] http://аоск.рф?jmlfwnwe&ucwkiyyc
|
||||
",
|
||||
:sender => 'Customer',
|
||||
:type => 'email',
|
||||
:internal => false,
|
||||
},
|
||||
},
|
||||
},
|
||||
]
|
||||
process(files)
|
||||
end
|
||||
|
@ -311,9 +429,9 @@ Some Text',
|
|||
if file[:result][level]
|
||||
file[:result][level].each { |key, value|
|
||||
if result[level].send(key).respond_to?('name')
|
||||
assert_equal( result[level].send(key).name, value.to_s)
|
||||
assert_equal( value.to_s, result[level].send(key).name )
|
||||
else
|
||||
assert_equal( result[level].send(key), value)
|
||||
assert_equal( value, result[level].send(key))
|
||||
end
|
||||
}
|
||||
end
|
||||
|
|
|
@ -140,18 +140,18 @@ class SessionBasicTest < ActiveSupport::TestCase
|
|||
test 'b collections organization' do
|
||||
require 'sessions/backend/collections/organization.rb'
|
||||
UserInfo.current_user_id = 1
|
||||
Organization.destroy_all
|
||||
user = User.lookup(:id => 1)
|
||||
org = Organization.create( :name => 'SomeOrg1::' + rand(999999).to_s, :active => true )
|
||||
|
||||
collection_client1 = Sessions::Backend::Collections::Organization.new(user, false, '123-1')
|
||||
collection_client2 = Sessions::Backend::Collections::Organization.new(user, false, '234-2')
|
||||
|
||||
# get whole collections - should be nil, no org exists!
|
||||
result1 = collection_client1.push
|
||||
assert( !result1, "check collections" )
|
||||
assert( !result1.empty?, "check collections" )
|
||||
sleep 1
|
||||
result2 = collection_client2.push
|
||||
assert( !result2, "check collections" )
|
||||
assert( !result2.empty?, "check collections" )
|
||||
assert_equal( result1, result2, "check collections" )
|
||||
|
||||
# next check - should still be nil, no org exists!
|
||||
|
@ -162,7 +162,7 @@ class SessionBasicTest < ActiveSupport::TestCase
|
|||
assert( !result2, "check collections - recall" )
|
||||
|
||||
# change collection
|
||||
org = Organization.create( :name => 'SomeOrg::' + rand(999999).to_s, :active => true )
|
||||
org = Organization.create( :name => 'SomeOrg2::' + rand(999999).to_s, :active => true )
|
||||
sleep 16
|
||||
|
||||
# get whole collections
|
||||
|
@ -191,7 +191,6 @@ class SessionBasicTest < ActiveSupport::TestCase
|
|||
result2 = collection_client2.push
|
||||
assert( !result1.empty?, "check collections - after touch" )
|
||||
assert_equal( result1, result2, "check collections" )
|
||||
|
||||
end
|
||||
|
||||
test 'b rss' do
|
||||
|
|
Loading…
Reference in a new issue