Merge branch 'develop' of github.com:martini/zammad into develop

This commit is contained in:
Martin Edenhofer 2015-05-01 15:08:56 +02:00
commit d071d595ae
32 changed files with 104 additions and 92 deletions

28
Gemfile
View file

@ -63,24 +63,24 @@ gem 'em-websocket'
group :development, :test do group :development, :test do
gem 'test-unit' gem 'test-unit'
gem 'spring' gem 'spring'
gem 'sqlite3' gem 'sqlite3'
# code coverage # code coverage
gem 'simplecov' gem 'simplecov'
gem 'simplecov-rcov' gem 'simplecov-rcov'
# UI tests w/ Selenium # UI tests w/ Selenium
gem 'selenium-webdriver' gem 'selenium-webdriver'
# livereload on template changes (html, js, css) # livereload on template changes (html, js, css)
gem 'guard', '>= 2.2.2', require: false gem 'guard', '>= 2.2.2', require: false
gem 'guard-livereload', require: false gem 'guard-livereload', require: false
gem 'rack-livereload' gem 'rack-livereload'
gem 'rb-fsevent', require: false gem 'rb-fsevent', require: false
# code QA # code QA
gem 'rubocop' gem 'rubocop'
end end
gem 'puma' gem 'puma'

View file

@ -76,7 +76,7 @@ curl http://localhost/api/v1/getting_started -v -u #{login}:#{password}
# validate url # validate url
messages = {} messages = {}
if !Setting.get('system_online_service') if !Setting.get('system_online_service')
if !params[:url] || params[:url] !~ /^(http|https):\/\/.+?$/ if !params[:url] || params[:url] !~ %r{^(http|https)://.+?$}
messages[:url] = 'A URL looks like http://zammad.example.com' messages[:url] = 'A URL looks like http://zammad.example.com'
end end
end end
@ -107,7 +107,7 @@ curl http://localhost/api/v1/getting_started -v -u #{login}:#{password}
# split url in http_type and fqdn # split url in http_type and fqdn
settings = {} settings = {}
if !Setting.get('system_online_service') if !Setting.get('system_online_service')
if params[:url] =~ /^(http|https):\/\/(.+?)$/ if params[:url] =~ %r{/^(http|https)://(.+?)$}
Setting.set('http_type', $1) Setting.set('http_type', $1)
settings[:http_type] = $1 settings[:http_type] = $1
Setting.set('fqdn', $2) Setting.set('fqdn', $2)

View file

@ -6,7 +6,7 @@ class ImportOtrsController < ApplicationController
return if setup_done_response return if setup_done_response
# validate # validate
if !params[:url] || params[:url] !~ /^(http|https):\/\/.+?$/ if !params[:url] || params[:url] !~ %r{^(http|https)://.+?$}
render json: { render json: {
result: 'invalid', result: 'invalid',
message: 'Invalid!', message: 'Invalid!',
@ -44,7 +44,7 @@ class ImportOtrsController < ApplicationController
suffixes.each {|suffix| suffixes.each {|suffix|
url = params[:url] + suffix + '?Action=ZammadMigrator' url = params[:url] + suffix + '?Action=ZammadMigrator'
# strip multible / in url # strip multible / in url
url.gsub!(/([^:])(\/+\/)/, '\\1/') url.gsub!(%r{([^:])(/+/)}, '\\1/')
response = UserAgent.request( url ) response = UserAgent.request( url )
#Setting.set('import_mode', true) #Setting.set('import_mode', true)
@ -65,7 +65,7 @@ class ImportOtrsController < ApplicationController
# return result # return result
render json: { render json: {
result: 'invalid', result: 'invalid',
message_human: message_human, message_human: message_human,
} }
end end

View file

@ -55,14 +55,14 @@ class SessionsController < ApplicationController
end end
# return new session data # return new session data
render json: { render status: :created,
session: user, json: {
models: models, session: user,
collections: collections, models: models,
assets: assets, collections: collections,
logon_session: logon_session_key, assets: assets,
}, logon_session: logon_session_key,
status: :created }
end end
def show def show

View file

@ -99,12 +99,12 @@ return all activity entries of an user
return [] if role_ids.include?(customer_role.id) return [] if role_ids.include?(customer_role.id)
if group_ids.empty? if group_ids.empty?
stream = ActivityStream.where('(role_id IN (?) AND group_id is NULL)', role_ids ) stream = ActivityStream.where('(role_id IN (?) AND group_id is NULL)', role_ids )
.order( 'created_at DESC, id DESC' ) .order( 'created_at DESC, id DESC' )
.limit( limit ) .limit( limit )
else else
stream = ActivityStream.where('(role_id IN (?) AND group_id is NULL) OR ( role_id IN (?) AND group_id IN (?) ) OR ( role_id is NULL AND group_id IN (?) )', role_ids, role_ids, group_ids, group_ids ) stream = ActivityStream.where('(role_id IN (?) AND group_id is NULL) OR ( role_id IN (?) AND group_id IN (?) ) OR ( role_id is NULL AND group_id IN (?) )', role_ids, role_ids, group_ids, group_ids )
.order( 'created_at DESC, id DESC' ) .order( 'created_at DESC, id DESC' )
.limit( limit ) .limit( limit )
end end
list = [] list = []
stream.each do |item| stream.each do |item|

View file

@ -606,8 +606,8 @@ class OwnModel < ApplicationModel
class_name = self.class.name class_name = self.class.name
class_name.gsub!(/::/, '') class_name.gsub!(/::/, '')
Sessions.broadcast( Sessions.broadcast(
:event => class_name + ':touch', event: class_name + ':touch',
:data => { :id => self.id, :updated_at => self.updated_at } data: { id: self.id, updated_at: self.updated_at }
) )
end end

View file

@ -81,7 +81,7 @@ returns
attributes attributes
end end
private private
=begin =begin

View file

@ -110,7 +110,7 @@ add a avatar
# twitter workaround to get bigger avatar images # twitter workaround to get bigger avatar images
# see also https://dev.twitter.com/overview/general/user-profile-images-and-banners # see also https://dev.twitter.com/overview/general/user-profile-images-and-banners
if data[:url] =~ /\/\/pbs.twimg.com\//i if data[:url] =~ %r{//pbs.twimg.com/}i
data[:url].sub!(/normal\.png$/, 'bigger.png') data[:url].sub!(/normal\.png$/, 'bigger.png')
end end

View file

@ -103,7 +103,7 @@ class Channel::EmailParser
data[:from_local] = Mail::Address.new( from ).local data[:from_local] = Mail::Address.new( from ).local
data[:from_domain] = Mail::Address.new( from ).domain data[:from_domain] = Mail::Address.new( from ).domain
data[:from_display_name] = Mail::Address.new( from ).display_name || data[:from_display_name] = Mail::Address.new( from ).display_name ||
( Mail::Address.new( from ).comments && Mail::Address.new( from ).comments[0] ) ( Mail::Address.new( from ).comments && Mail::Address.new( from ).comments[0] )
rescue rescue
data[:from_email] = from data[:from_email] = from
data[:from_local] = from data[:from_local] = from

View file

@ -151,8 +151,8 @@ returns
if !related_history_object if !related_history_object
history_object = self.object_lookup( requested_object ) history_object = self.object_lookup( requested_object )
history = History.where( history_object_id: history_object.id ) history = History.where( history_object_id: history_object.id )
.where( o_id: requested_object_id ) .where( o_id: requested_object_id )
.order('created_at ASC, id ASC') .order('created_at ASC, id ASC')
else else
history_object_requested = self.object_lookup( requested_object ) history_object_requested = self.object_lookup( requested_object )
history_object_related = self.object_lookup( related_history_object ) history_object_related = self.object_lookup( related_history_object )

View file

@ -43,8 +43,8 @@ class Job < ApplicationModel
# find tickets to change # find tickets to change
tickets = Ticket.where( job.condition.permit! ) tickets = Ticket.where( job.condition.permit! )
.order( '`tickets`.`created_at` DESC' ) .order( '`tickets`.`created_at` DESC' )
.limit( 1_000 ) .limit( 1_000 )
job.processed = tickets.count job.processed = tickets.count
tickets.each do |ticket| tickets.each do |ticket|
#puts "CHANGE #{job.execute.inspect}" #puts "CHANGE #{job.execute.inspect}"

View file

@ -152,6 +152,7 @@ class Link < ApplicationModel
end end
private private
def self.link_type_get(data) def self.link_type_get(data)
linktype = Link::Type.where( name: data[:name] ).first linktype = Link::Type.where( name: data[:name] ).first
if !linktype if !linktype

View file

@ -12,6 +12,7 @@ class Observer::Ticket::CloseTime < ActiveRecord::Observer
end end
private private
def _check(record) def _check(record)
# puts 'check close time' # puts 'check close time'

View file

@ -18,8 +18,10 @@ class Observer::Ticket::LastContact < ActiveRecord::Observer
# check if last communication is done by agent, else do not set last_contact_customer # check if last communication is done by agent, else do not set last_contact_customer
if record.ticket.last_contact_customer == nil || if record.ticket.last_contact_customer == nil ||
record.ticket.last_contact_agent == nil || record.ticket.last_contact_agent == nil ||
record.ticket.last_contact_agent.to_i > record.ticket.last_contact_customer.to_i record.ticket.last_contact_agent.to_i > record.ticket.last_contact_customer.to_i
# set last_contact customer
record.ticket.last_contact_customer = record.created_at record.ticket.last_contact_customer = record.created_at
# set last_contact # set last_contact

View file

@ -70,7 +70,7 @@ class Observer::Ticket::Notification::BackgroundJob
object: 'Ticket', object: 'Ticket',
o_id: ticket.id, o_id: ticket.id,
seen: seen, seen: seen,
created_by_id: ticket.updated_by_id ||  1, created_by_id: ticket.updated_by_id || 1,
user_id: user.id, user_id: user.id,
) )
@ -135,7 +135,7 @@ class Observer::Ticket::Notification::BackgroundJob
history_type: 'notification', history_type: 'notification',
history_object: 'Ticket', history_object: 'Ticket',
value_to: recipient_list, value_to: recipient_list,
created_by_id: ticket.updated_by_id ||  1 created_by_id: ticket.updated_by_id || 1
) )
end end

View file

@ -12,6 +12,7 @@ class Observer::Ticket::OnlineNotificationSeen < ActiveRecord::Observer
end end
private private
def _check(record) def _check(record)
# return if we run import mode # return if we run import mode

View file

@ -57,8 +57,8 @@ mark online notification as seen
def self.seen(data) def self.seen(data)
notification = OnlineNotification.find(data[:id]) notification = OnlineNotification.find(data[:id])
notification.seen = true notification.seen = true
notification.save notification.save
end end
=begin =begin
@ -88,8 +88,8 @@ return all online notifications of an user
def self.list(user, limit) def self.list(user, limit)
notifications = OnlineNotification.where(user_id: user.id) notifications = OnlineNotification.where(user_id: user.id)
.order( 'created_at DESC, id DESC' ) .order( 'created_at DESC, id DESC' )
.limit( limit ) .limit( limit )
list = [] list = []
notifications.each do |item| notifications.each do |item|
data = item.attributes data = item.attributes
@ -116,8 +116,9 @@ return all online notifications of an object
object_lookup_id: object_id, object_lookup_id: object_id,
o_id: o_id, o_id: o_id,
) )
.order( 'created_at DESC, id DESC' ) .order( 'created_at DESC, id DESC' )
.limit( 10_000 ) .limit( 10_000 )
list = [] list = []
notifications.each do |item| notifications.each do |item|
data = item.attributes data = item.attributes

View file

@ -47,7 +47,7 @@ class Package < ApplicationModel
# install all packages located under auto_install/*.zpm # install all packages located under auto_install/*.zpm
def self.auto_install def self.auto_install
path = @@root + '/auto_install/' path = @@root + '/auto_install/'
return if ! File.exist?( path ) return if !File.exist?( path )
data = [] data = []
Dir.foreach( path ) do |entry| Dir.foreach( path ) do |entry|
if entry =~ /\.zpm/ && entry !~ /^\./ if entry =~ /\.zpm/ && entry !~ /^\./
@ -82,7 +82,7 @@ class Package < ApplicationModel
def self._package_base_dir?(package_base_dir) def self._package_base_dir?(package_base_dir)
package = false package = false
Dir.glob( package_base_dir + '/*.szpm') do |entry| Dir.glob( package_base_dir + '/*.szpm') do |entry|
package = entry.sub( /^.*\/(.+?)\.szpm$/, '\1') package = entry.sub( %r{^.*/(.+?)\.szpm$}, '\1')
end end
if package == false if package == false
raise "Can't link package, '#{package_base_dir}' is no package source directory!" raise "Can't link package, '#{package_base_dir}' is no package source directory!"
@ -133,7 +133,7 @@ class Package < ApplicationModel
entry = entry.sub( '//', '/' ) entry = entry.sub( '//', '/' )
file = entry file = entry
file = file.sub( /#{package_base_dir.to_s}/, '' ) file = file.sub( /#{package_base_dir.to_s}/, '' )
file = file.sub( /^\//, '' ) file = file.sub( %r{^/}, '' )
# ignore files # ignore files
if file =~ /^README/ if file =~ /^README/

View file

@ -38,12 +38,12 @@ class RecentView < ApplicationModel
def self.list( user, limit = 10, type = nil ) def self.list( user, limit = 10, type = nil )
if !type if !type
recent_views = RecentView.where( created_by_id: user.id ) recent_views = RecentView.where( created_by_id: user.id )
.order('created_at DESC, id DESC') .order('created_at DESC, id DESC')
.limit(limit) .limit(limit)
else else
recent_views = RecentView.select('DISTINCT(o_id), recent_view_object_id').where( created_by_id: user.id, recent_view_object_id: ObjectLookup.by_name(type) ) recent_views = RecentView.select('DISTINCT(o_id), recent_view_object_id').where( created_by_id: user.id, recent_view_object_id: ObjectLookup.by_name(type) )
.order('created_at DESC, id DESC') .order('created_at DESC, id DESC')
.limit(limit) .limit(limit)
end end
list = [] list = []

View file

@ -51,6 +51,7 @@ class Setting < ApplicationModel
end end
private private
def delete_cache def delete_cache
@@current[:settings_config] = nil @@current[:settings_config] = nil
end end

View file

@ -10,6 +10,7 @@ class Sla < ApplicationModel
after_destroy :escalation_calculation_rebuild after_destroy :escalation_calculation_rebuild
private private
def escalation_calculation_rebuild def escalation_calculation_rebuild
Cache.delete( 'SLA::List::Active' ) Cache.delete( 'SLA::List::Active' )
Ticket::Escalation.rebuild_all Ticket::Escalation.rebuild_all

View file

@ -81,7 +81,7 @@ returns
# search # search
store_object_id = Store::Object.lookup( name: data[:object] ) store_object_id = Store::Object.lookup( name: data[:object] )
stores = Store.where( store_object_id: store_object_id, o_id: data[:o_id].to_i ) stores = Store.where( store_object_id: store_object_id, o_id: data[:o_id].to_i )
.order('created_at ASC, id ASC') .order('created_at ASC, id ASC')
stores stores
end end
@ -104,8 +104,8 @@ returns
# search # search
store_object_id = Store::Object.lookup( name: data[:object] ) store_object_id = Store::Object.lookup( name: data[:object] )
stores = Store.where( store_object_id: store_object_id ) stores = Store.where( store_object_id: store_object_id )
.where( o_id: data[:o_id] ) .where( o_id: data[:o_id] )
.order('created_at ASC, id ASC') .order('created_at ASC, id ASC')
stores.each do |store| stores.each do |store|
# check backend for references # check backend for references

View file

@ -24,8 +24,8 @@ class Store::Provider::File
# generate directory # generate directory
base = Rails.root.to_s + '/storage/fs/' base = Rails.root.to_s + '/storage/fs/'
parts = sha.scan(/.{1,4}/) parts = sha.scan(/.{1,4}/)
path = parts[ 1 .. 10 ].join('/') + '/' path = parts[ 1..10 ].join('/') + '/'
file = parts[ 11 .. parts.count ].join('') file = parts[ 11..parts.count ].join('')
location = "#{base}/#{path}" location = "#{base}/#{path}"
# create directory if not exists # create directory if not exists

View file

@ -7,6 +7,7 @@ class Taskbar < ApplicationModel
before_update :update_last_contact, :set_user before_update :update_last_contact, :set_user
private private
def update_last_contact def update_last_contact
self.last_contact = Time.now self.last_contact = Time.now
end end

View file

@ -95,9 +95,9 @@ returns
access_condition = [] access_condition = []
if user.is_role(Z_ROLENAME_AGENT) if user.is_role(Z_ROLENAME_AGENT)
group_ids = Group.select( 'groups.id' ).joins(:users) group_ids = Group.select( 'groups.id' ).joins(:users)
.where( 'groups_users.user_id = ?', user.id ) .where( 'groups_users.user_id = ?', user.id )
.where( 'groups.active = ?', true ) .where( 'groups.active = ?', true )
.map( &:id ) .map( &:id )
access_condition = [ 'group_id IN (?)', group_ids ] access_condition = [ 'group_id IN (?)', group_ids ]
else else
if !user.organization || ( !user.organization.shared || user.organization.shared == false ) if !user.organization || ( !user.organization.shared || user.organization.shared == false )

View file

@ -109,13 +109,13 @@ returns
# get only tickets with permissions # get only tickets with permissions
if data[:current_user].is_role('Customer') if data[:current_user].is_role('Customer')
group_ids = Group.select( 'groups.id' ) group_ids = Group.select( 'groups.id' )
.where( 'groups.active = ?', true ) .where( 'groups.active = ?', true )
.map( &:id ) .map( &:id )
else else
group_ids = Group.select( 'groups.id' ).joins(:users) group_ids = Group.select( 'groups.id' ).joins(:users)
.where( 'groups_users.user_id = ?', [ data[:current_user].id ] ) .where( 'groups_users.user_id = ?', [ data[:current_user].id ] )
.where( 'groups.active = ?', true ) .where( 'groups.active = ?', true )
.map( &:id ) .map( &:id )
end end
# overview meta for navbar # overview meta for navbar
@ -148,10 +148,10 @@ returns
order_by = overview_selected.group_by + '_id, ' + order_by order_by = overview_selected.group_by + '_id, ' + order_by
end end
tickets = Ticket.select( 'id' ) tickets = Ticket.select( 'id' )
.where( group_id: group_ids ) .where( group_id: group_ids )
.where( _condition( overview_selected.condition ) ) .where( _condition( overview_selected.condition ) )
.order( order_by ) .order( order_by )
.limit( 500 ) .limit( 500 )
ticket_ids = [] ticket_ids = []
tickets.each { |ticket| tickets.each { |ticket|
@ -159,8 +159,8 @@ returns
} }
tickets_count = Ticket.where( group_id: group_ids ) tickets_count = Ticket.where( group_id: group_ids )
.where( _condition( overview_selected.condition ) ) .where( _condition( overview_selected.condition ) )
.count() .count()
return { return {
ticket_ids: ticket_ids, ticket_ids: ticket_ids,
@ -172,14 +172,14 @@ returns
# get tickets for overview # get tickets for overview
data[:start_page] ||= 1 data[:start_page] ||= 1
tickets = Ticket.where( group_id: group_ids ) tickets = Ticket.where( group_id: group_ids )
.where( _condition( overview_selected.condition ) ) .where( _condition( overview_selected.condition ) )
.order( overview_selected[:order][:by].to_s + ' ' + overview_selected[:order][:direction].to_s )#. .order( overview_selected[:order][:by].to_s + ' ' + overview_selected[:order][:direction].to_s )
# limit( overview_selected.view[ data[:view_mode].to_sym ][:per_page] ). # .limit( overview_selected.view[ data[:view_mode].to_sym ][:per_page] )
# offset( overview_selected.view[ data[:view_mode].to_sym ][:per_page].to_i * ( data[:start_page].to_i - 1 ) ) # .offset( overview_selected.view[ data[:view_mode].to_sym ][:per_page].to_i * ( data[:start_page].to_i - 1 ) )
tickets_count = Ticket.where( group_id: group_ids ) tickets_count = Ticket.where( group_id: group_ids )
.where( _condition( overview_selected.condition ) ) .where( _condition( overview_selected.condition ) )
.count() .count()
{ {
tickets: tickets, tickets: tickets,

View file

@ -13,7 +13,7 @@ class Token < ActiveRecord::Base
# check if token is still valid # check if token is still valid
if !token.persistent && if !token.persistent &&
token.created_at < 1.day.ago token.created_at < 1.day.ago
# delete token # delete token
token.delete token.delete
@ -26,6 +26,7 @@ class Token < ActiveRecord::Base
end end
private private
def generate_token def generate_token
begin begin
self.name = SecureRandom.hex(20) self.name = SecureRandom.hex(20)

View file

@ -167,6 +167,7 @@ translate strings in ruby context, e. g. for notifications
end end
private private
def set_initial def set_initial
return if target_initial return if target_initial

View file

@ -83,10 +83,10 @@ class String
string.gsub!( /^\s*/m, '' ) string.gsub!( /^\s*/m, '' )
# pre/code handling 1/2 # pre/code handling 1/2
string.gsub!( /<pre>(.+?)<\/pre>/m ) { |placeholder| string.gsub!( %r{<pre>(.+?)</pre>}m ) { |placeholder|
placeholder = placeholder.gsub(/\n/, '###BR###') placeholder = placeholder.gsub(/\n/, '###BR###')
} }
string.gsub!( /<code>(.+?)<\/code>/m ) { |placeholder| string.gsub!( %r{<code>(.+?)</code>/}m ) { |placeholder|
placeholder = placeholder.gsub(/\n/, '###BR###') placeholder = placeholder.gsub(/\n/, '###BR###')
} }
@ -103,12 +103,12 @@ class String
string.gsub!(/<blockquote(| [^>]*)>/i, '> ') string.gsub!(/<blockquote(| [^>]*)>/i, '> ')
# add hr # add hr
string.gsub!(/<hr(|\/| [^>]*)>/i, "___\n") string.gsub!(%r{<hr(|/| [^>]*)>}i, "___\n")
# add new lines # add new lines
string.gsub!( /\<(br|table)(|\/| [^>]*)\>/i, "\n" ) string.gsub!( %r{\<(br|table)(|/| [^>]*)\>}i, "\n" )
string.gsub!( /\<\/(div|p|pre|blockquote|table|tr)(|\s.+?)\>/i, "\n" ) string.gsub!( %r{\</(div|p|pre|blockquote|table|tr)(|\s.+?)\>}i, "\n" )
string.gsub!( /\<\/td\>/i, ' ' ) string.gsub!( %r{/</td\>}i, ' ' )
# strip all other tags # strip all other tags
string.gsub!( /\<.+?\>/, '' ) string.gsub!( /\<.+?\>/, '' )

View file

@ -352,7 +352,7 @@ module Import::OTRS
if !user if !user
begin begin
display_name = Mail::Address.new( article_new[:from] ).display_name || display_name = Mail::Address.new( article_new[:from] ).display_name ||
( Mail::Address.new( article_new[:from] ).comments && Mail::Address.new( article_new[:from] ).comments[0] ) ( Mail::Address.new( article_new[:from] ).comments && Mail::Address.new( article_new[:from] ).comments[0] )
rescue rescue
display_name = article_new[:from] display_name = article_new[:from]
end end

View file

@ -1004,7 +1004,7 @@ module Import::OTRS2
if group_lookup['Name'] == 'admin' && permissions && permissions.include?('rw') if group_lookup['Name'] == 'admin' && permissions && permissions.include?('rw')
roles.push 'Admin' roles.push 'Admin'
end end
if group_lookup['Name'] =~ /^(stats|report)/ && permissions && ( permissions.include?('ro') ||  permissions.include?('rw') ) if group_lookup['Name'] =~ /^(stats|report)/ && permissions && ( permissions.include?('ro') || permissions.include?('rw') )
roles.push 'Report' roles.push 'Report'
end end
end end
@ -1296,7 +1296,7 @@ module Import::OTRS2
# unlock user # unlock user
locks[:User][ email ] = false locks[:User][ email ] = false
true true
end end

View file

@ -241,6 +241,7 @@ returns
end end
private private
def self.get_http(uri, options) def self.get_http(uri, options)
http = Net::HTTP.new(uri.host, uri.port) http = Net::HTTP.new(uri.host, uri.port)