summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore2
-rw-r--r--app/controllers/call_forwards_controller.rb48
-rw-r--r--app/controllers/calls_controller.rb17
-rw-r--r--app/controllers/conference_invitees_controller.rb2
-rw-r--r--app/controllers/groups_controller.rb2
-rw-r--r--app/controllers/gs_parameters_controller.rb12
-rw-r--r--app/controllers/intruders_controller.rb3
-rw-r--r--app/controllers/softkeys_controller.rb8
-rw-r--r--app/controllers/trigger_controller.rb2
-rw-r--r--app/models/backup_job.rb9
-rw-r--r--app/models/call_forward.rb2
-rw-r--r--app/models/fax_document.rb11
-rw-r--r--app/models/group.rb3
-rw-r--r--app/models/group_permission.rb2
-rw-r--r--app/models/intruder.rb86
-rw-r--r--app/models/softkey.rb37
-rw-r--r--app/views/config_polycom/idle_screen.xml.haml17
-rw-r--r--app/views/fax_documents/_index_core.html.haml17
-rw-r--r--app/views/group_memberships/_index_core.html.haml3
-rw-r--r--app/views/group_memberships/show.html.haml4
-rw-r--r--app/views/groups/_form_core.html.haml2
-rw-r--r--app/views/groups/_index_core.html.haml10
-rw-r--r--app/views/gs_parameters/index.html.haml48
-rw-r--r--app/views/gs_parameters/show.html.haml10
-rw-r--r--app/views/intruders/_form_core.html.haml4
-rw-r--r--app/views/intruders/_index_core.html.haml25
-rw-r--r--app/views/intruders/index.html.haml9
-rw-r--r--app/views/phone_book_entries/show.html.haml27
-rw-r--r--app/views/phones/_form_core.html.haml2
-rw-r--r--app/views/phones/show.html.haml11
-rw-r--r--app/views/softkeys/_form_core.html.haml4
-rw-r--r--app/views/tenants/_table_of_automatic_call_distributors.html.haml2
-rw-r--r--app/views/tenants/_table_of_hunt_groups.html.haml2
-rw-r--r--config/backup.rb29
-rw-r--r--config/locales/navigation.en.yml2
-rw-r--r--config/locales/views/phone_book_entries/de.yml2
-rw-r--r--config/locales/views/phone_book_entries/en.yml2
-rw-r--r--db/schema.rb1176
-rw-r--r--lib/tasks/backup.rake18
-rw-r--r--misc/freeswitch/scripts/common/call_forwarding.lua185
-rw-r--r--misc/freeswitch/scripts/common/database.lua2
-rw-r--r--misc/freeswitch/scripts/common/group.lua84
-rw-r--r--misc/freeswitch/scripts/common/log.lua16
-rw-r--r--misc/freeswitch/scripts/common/object.lua106
-rw-r--r--misc/freeswitch/scripts/common/sip_account.lua36
-rw-r--r--misc/freeswitch/scripts/dialplan/dialplan.lua166
-rw-r--r--misc/freeswitch/scripts/dialplan/functions.lua94
-rw-r--r--misc/freeswitch/scripts/dialplan/router.lua1
-rw-r--r--misc/freeswitch/scripts/dialplan_default.lua2
49 files changed, 847 insertions, 1517 deletions
diff --git a/.gitignore b/.gitignore
index 4d70e4a..5393c21 100644
--- a/.gitignore
+++ b/.gitignore
@@ -86,3 +86,5 @@ tmp/**/*
# Cache
/public/gemeinschaft_setups/*
+
+/db/schema.rb
diff --git a/app/controllers/call_forwards_controller.rb b/app/controllers/call_forwards_controller.rb
index 34fb77a..b30ee9e 100644
--- a/app/controllers/call_forwards_controller.rb
+++ b/app/controllers/call_forwards_controller.rb
@@ -1,7 +1,10 @@
class CallForwardsController < ApplicationController
load_resource :phone_number
load_resource :sip_account
- load_and_authorize_resource :call_forward, :through => [:phone_number, :sip_account]
+ load_resource :automatic_call_distributor
+ load_resource :hunt_group
+
+ load_and_authorize_resource :call_forward, :through => [:phone_number, :sip_account, :automatic_call_distributor, :hunt_group]
before_filter :set_and_authorize_parent
before_filter :spread_breadcrumbs
@@ -81,7 +84,7 @@ class CallForwardsController < ApplicationController
private
private
def set_and_authorize_parent
- @parent = @sip_account || @phone_number
+ @parent = @phone_number || @sip_account || @automatic_call_distributor || @hunt_group
authorize! :read, @parent
end
@@ -90,27 +93,30 @@ class CallForwardsController < ApplicationController
if @parent.class == PhoneNumber && @parent.phone_numberable_type == 'SipAccount'
@sip_account = @parent.phone_numberable
end
- if @sip_account.sip_accountable_type == 'User'
- @user = @sip_account.sip_accountable
- if @parent.class == PhoneNumber
- add_breadcrumb t("users.index.page_title"), tenant_users_path(@user.current_tenant)
- add_breadcrumb @user, tenant_users_path(@user.current_tenant, @user)
- add_breadcrumb t("sip_accounts.index.page_title"), user_sip_accounts_path(@user)
- add_breadcrumb @sip_account, user_sip_account_path(@user, @sip_account)
- add_breadcrumb t("phone_numbers.index.page_title"), sip_account_phone_numbers_path(@sip_account)
- add_breadcrumb @parent, sip_account_phone_number_path(@sip_account, @parent)
- elsif @parent.class == SipAccount
- add_breadcrumb t("users.index.page_title"), tenant_users_path(@user.current_tenant)
- add_breadcrumb @user, tenant_users_path(@user.current_tenant, @user)
- add_breadcrumb t("sip_accounts.index.page_title"), user_sip_accounts_path(@user)
+
+ if @sip_account
+ if @sip_account.sip_accountable_type == 'User'
+ @user = @sip_account.sip_accountable
+ if @parent.class == PhoneNumber
+ add_breadcrumb t("users.index.page_title"), tenant_users_path(@user.current_tenant)
+ add_breadcrumb @user, tenant_users_path(@user.current_tenant, @user)
+ add_breadcrumb t("sip_accounts.index.page_title"), user_sip_accounts_path(@user)
+ add_breadcrumb @sip_account, user_sip_account_path(@user, @sip_account)
+ add_breadcrumb t("phone_numbers.index.page_title"), sip_account_phone_numbers_path(@sip_account)
+ add_breadcrumb @parent, sip_account_phone_number_path(@sip_account, @parent)
+ elsif @parent.class == SipAccount
+ add_breadcrumb t("users.index.page_title"), tenant_users_path(@user.current_tenant)
+ add_breadcrumb @user, tenant_users_path(@user.current_tenant, @user)
+ add_breadcrumb t("sip_accounts.index.page_title"), user_sip_accounts_path(@user)
+ end
+ end
+ if @sip_account.sip_accountable_type == 'Tenant'
+ @tenant = @sip_account.sip_accountable
+ add_breadcrumb t("sip_accounts.index.page_title"), tenant_sip_accounts_path(@tenant)
+ add_breadcrumb @sip_account, tenant_sip_account_path(@tenant, @sip_account)
end
end
- if @sip_account.sip_accountable_type == 'Tenant'
- @tenant = @sip_account.sip_accountable
- add_breadcrumb t("sip_accounts.index.page_title"), tenant_sip_accounts_path(@tenant)
- add_breadcrumb @sip_account, tenant_sip_account_path(@tenant, @sip_account)
- end
-
+
m = method( :"#{@parent.class.name.underscore}_call_forwards_url" )
add_breadcrumb t("call_forwards.index.page_title"), m.(@parent)
if @call_forward && !@call_forward.new_record?
diff --git a/app/controllers/calls_controller.rb b/app/controllers/calls_controller.rb
index 5534b1b..22ff92d 100644
--- a/app/controllers/calls_controller.rb
+++ b/app/controllers/calls_controller.rb
@@ -3,6 +3,7 @@ class CallsController < ApplicationController
load_resource :call
before_filter :set_and_authorize_parent
+ before_filter :spread_breadcrumbs
def index
if @parent
@@ -55,4 +56,20 @@ class CallsController < ApplicationController
def set_and_authorize_parent
@parent = @sip_account
end
+
+ def spread_breadcrumbs
+ if @parent.class == SipAccount
+ if @sip_account.sip_accountable.class == User
+ add_breadcrumb t('users.name'), tenant_users_path(@sip_account.sip_accountable.current_tenant)
+ add_breadcrumb @sip_account.sip_accountable, tenant_user_path(@sip_account.sip_accountable.current_tenant, @sip_account.sip_accountable)
+ add_breadcrumb t('sip_accounts.index.page_title'), user_sip_accounts_path(@sip_account.sip_accountable)
+ add_breadcrumb @sip_account, user_sip_account_path(@sip_account.sip_accountable, @sip_account)
+ add_breadcrumb t('calls.index.page_title'), sip_account_calls_path(@sip_account)
+ elsif @sip_account.sip_accountable.class == Tenant
+ add_breadcrumb t('sip_accounts.index.page_title'), tenant_sip_accounts_path(@sip_account.sip_accountable)
+ add_breadcrumb @sip_account, tenant_sip_account_path(@sip_account.sip_accountable, @sip_account)
+ add_breadcrumb t('calls.index.page_title'), sip_account_calls_path(@sip_account)
+ end
+ end
+ end
end
diff --git a/app/controllers/conference_invitees_controller.rb b/app/controllers/conference_invitees_controller.rb
index ce55b5a..e891ebc 100644
--- a/app/controllers/conference_invitees_controller.rb
+++ b/app/controllers/conference_invitees_controller.rb
@@ -58,7 +58,7 @@ class ConferenceInviteesController < ApplicationController
def destroy
@conference_invitee.destroy
- redirect_to conference_invitees_url, :notice => t('conference_invitees.controller.successfuly_destroyed')
+ redirect_to conference_conference_invitees_url(@conference), :notice => t('conference_invitees.controller.successfuly_destroyed')
end
private
diff --git a/app/controllers/groups_controller.rb b/app/controllers/groups_controller.rb
index 74ad7c8..d48707c 100644
--- a/app/controllers/groups_controller.rb
+++ b/app/controllers/groups_controller.rb
@@ -11,7 +11,7 @@ class GroupsController < ApplicationController
end
def new
- @group = Group.new
+ @group.active = true;
end
def create
diff --git a/app/controllers/gs_parameters_controller.rb b/app/controllers/gs_parameters_controller.rb
index bd8b44b..106ce76 100644
--- a/app/controllers/gs_parameters_controller.rb
+++ b/app/controllers/gs_parameters_controller.rb
@@ -4,9 +4,15 @@ class GsParametersController < ApplicationController
before_filter :spread_breadcrumbs
def index
- @gs_parameters_unordered = GsParameter.scoped
- @gs_parameters = GsParameter.order([:section, :name])
- @sections = @gs_parameters.pluck(:section).uniq.sort
+ @gs_parameters = GsParameter.order([:entity, :section, :name])
+
+ @entities = Hash.new()
+ @gs_parameters.each do |parameter|
+ if !@entities[parameter.entity]
+ @entities[parameter.entity] = Hash.new()
+ end
+ @entities[parameter.entity][parameter.section] = true
+ end
end
def show
diff --git a/app/controllers/intruders_controller.rb b/app/controllers/intruders_controller.rb
index d3c767e..bdda230 100644
--- a/app/controllers/intruders_controller.rb
+++ b/app/controllers/intruders_controller.rb
@@ -2,7 +2,8 @@ class IntrudersController < ApplicationController
load_and_authorize_resource :intruder
def index
- @intruders = Intruder.order('list_type ASC, contact_last DESC').all
+ @intruders = Intruder.order('list_type ASC, contact_last DESC')
+ @list_types = @intruders.pluck(:list_type).uniq.sort
spread_breadcrumbs
end
diff --git a/app/controllers/softkeys_controller.rb b/app/controllers/softkeys_controller.rb
index c9e8c20..9179d8c 100644
--- a/app/controllers/softkeys_controller.rb
+++ b/app/controllers/softkeys_controller.rb
@@ -2,7 +2,7 @@ class SoftkeysController < ApplicationController
load_and_authorize_resource :sip_account, :except => [:sort]
load_and_authorize_resource :softkey, :through => [:sip_account], :except => [:sort]
- before_filter :set_available_call_forwards_and_softkey_functions, :only => [ :new, :edit, :update ]
+ before_filter :set_available_softkey_functions, :only => [ :new, :edit, :update ]
before_filter :spread_breadcrumbs, :except => [:sort]
def index
@@ -54,12 +54,8 @@ class SoftkeysController < ApplicationController
render nothing: true
end
-
private
-
- def set_available_call_forwards_and_softkey_functions
- @available_call_forwards = @softkey.possible_blf_call_forwards
-
+ def set_available_softkey_functions
@softkey_functions = []
SoftkeyFunction.accessible_by(current_ability, :read).each do |softkey_function|
if GuiFunction.display?("softkey_function_#{softkey_function.name.downcase}_field_in_softkey_form", current_user)
diff --git a/app/controllers/trigger_controller.rb b/app/controllers/trigger_controller.rb
index 64a5f91..8e70ef2 100644
--- a/app/controllers/trigger_controller.rb
+++ b/app/controllers/trigger_controller.rb
@@ -84,12 +84,12 @@ class TriggerController < ApplicationController
fax_document.state = 'successful'
if fax_document.save
+ Notifications.new_fax(fax_document).deliver
begin
File.delete(pdf_file)
rescue => e
logger.error "PDF fax file could not be deleted: #{pdf_file} => #{e.inspect}"
end
- fax_document.tiff = nil
fax_document.save
fax_document.render_thumbnails
else
diff --git a/app/models/backup_job.rb b/app/models/backup_job.rb
index a04f6c0..48dd27e 100644
--- a/app/models/backup_job.rb
+++ b/app/models/backup_job.rb
@@ -12,12 +12,17 @@ class BackupJob < ActiveRecord::Base
private
def set_state_to_queued
- self.state = 'queued'
+ self.state ||= 'queued'
self.started_at = Time.now
end
def initiate_backup
- self.delay.make_a_backup
+ if self.state == 'force now'
+ self.state = 'queued'
+ self.make_a_backup
+ else
+ self.delay.make_a_backup
+ end
end
def make_a_backup
diff --git a/app/models/call_forward.rb b/app/models/call_forward.rb
index a932e11..195ac36 100644
--- a/app/models/call_forward.rb
+++ b/app/models/call_forward.rb
@@ -177,7 +177,7 @@ class CallForward < ActiveRecord::Base
end
def deactivate_concurring_entries
- CallForward.where(:call_forwardable_id => self.call_forwardable_id, :call_forwardable_type => self.call_forwardable_type, :call_forward_case_id => self.call_forward_case_id, :active => true).each do |call_forwarding_entry|
+ CallForward.where(:call_forwardable_id => self.call_forwardable_id, :call_forwardable_type => self.call_forwardable_type, :call_forward_case_id => self.call_forward_case_id, :source => self.source, :active => true).each do |call_forwarding_entry|
if call_forwarding_entry.id != self.id
call_forwarding_entry.update_attributes(:active => false)
end
diff --git a/app/models/fax_document.rb b/app/models/fax_document.rb
index 5b27965..3cb92ea 100644
--- a/app/models/fax_document.rb
+++ b/app/models/fax_document.rb
@@ -96,9 +96,18 @@ class FaxDocument < ActiveRecord::Base
page_size_command = "<< /Policies << /PageSize 3 >> /InputAttributes currentpagedevice /InputAttributes get dup { pop 1 index exch undef } forall dup 0 << /PageSize [ #{page_size_a4} ] >> put >> setpagedevice"
working_path, file_name = File.split(self.document.to_s)
tiff_file = File.basename(file_name.to_s.downcase, File.extname(file_name)) + '.tiff'
- result = system "cd #{store_dir} && gs -q -r#{self.fax_resolution.resolution_value} -dNOPAUSE -dBATCH -dSAFER -sDEVICE=tiffg3 -sOutputFile=\"#{tiff_file}\" -c \"#{page_size_command}\" -- \"#{self.document.to_s}\""
+ result = system "cd #{store_dir} && gs -q -r#{self.fax_resolution.resolution_value} -dNOPAUSE -dBATCH -dSAFER -sDEVICE=tiffg3 -sOutputFile=\"#{store_dir}/#{tiff_file}\" -c \"#{page_size_command}\" -- \"#{self.document.to_s}\""
if !File.exists?("#{store_dir}/#{tiff_file}")
+ page_size = "1728x1078" or "1728x1186";
+ command = "cd #{store_dir} && convert -quiet -density #{self.fax_resolution.resolution_value} -units PixelsPerInch -resize #{page_size}\! -monochrome -compress Fax \"#{self.document.to_s}\" \"#{store_dir}/#{tiff_file}\""
+ result = system(command)
+ if result.nil?
+ logger.error "### FAX_DOCUMENT_TO_TIFF - error: #{$?}, command: #{command}"
+ end
+ end
+
+ if !File.exists?("#{store_dir}/#{tiff_file}")
return nil
end
diff --git a/app/models/group.rb b/app/models/group.rb
index e0cfaab..c459530 100644
--- a/app/models/group.rb
+++ b/app/models/group.rb
@@ -5,6 +5,9 @@ class Group < ActiveRecord::Base
has_many :group_permissions, :dependent => :destroy
has_many :permittances, :foreign_key => :target_group_id, :class_name => "GroupPermission", :dependent => :destroy
+ validates :name,
+ :presence => true
+
def to_s
self.name
end
diff --git a/app/models/group_permission.rb b/app/models/group_permission.rb
index fe988ba..c859f52 100644
--- a/app/models/group_permission.rb
+++ b/app/models/group_permission.rb
@@ -1,7 +1,7 @@
class GroupPermission < ActiveRecord::Base
attr_accessible :group_id, :permission, :target_group_id
- PERMISSION_TYPES = ['pickup']
+ PERMISSION_TYPES = ['pickup', 'presence']
belongs_to :group
belongs_to :target_group, :class_name => "Group"
diff --git a/app/models/intruder.rb b/app/models/intruder.rb
index 97e3773..9a1c39a 100644
--- a/app/models/intruder.rb
+++ b/app/models/intruder.rb
@@ -17,6 +17,10 @@ class Intruder < ActiveRecord::Base
before_validation :set_key_if_empty
+ after_create :check_if_new_entry_relevant
+ after_update :check_if_update_relevant
+ after_destroy :check_if_delete_relevant
+
def to_s
key
end
@@ -31,26 +35,6 @@ class Intruder < ActiveRecord::Base
end
end
- def self.write_firewall_blacklist
- firewall_blacklist_file = GsParameter.get('blacklist_file', 'perimeter', 'general')
- entry_template = GsParameter.get('blacklist_file_entry', 'perimeter', 'general')
- comment_template = GsParameter.get('blacklist_file_comment', 'perimeter', 'general')
- File.open(firewall_blacklist_file, 'w') do |file|
- Intruder.where(:list_type => 'blacklist').where('bans > 0').all.each do |entry|
- if ! comment_template.blank?
- file.write(self.expand_variables(comment_template, entry.to_hash) + "\n")
- end
- file.write(self.expand_variables(entry_template, entry.to_hash) + "\n")
- end
- end
- end
-
- def self.expand_variables(line, variables)
- return line.gsub(/\{([a-z_]+)\}/) do |m|
- variables[$1.to_sym]
- end
- end
-
def to_hash
return {
:key => self.key,
@@ -72,4 +56,66 @@ class Intruder < ActiveRecord::Base
self.key = self.contact_ip
end
end
+
+ def expand_variables(line, variables)
+ return line.gsub(/\{([a-z_]+)\}/) do |m|
+ variables[$1.to_sym]
+ end
+ end
+
+ def write_firewall_list
+ firewall_blacklist_file = GsParameter.get('blacklist_file', 'perimeter', 'general')
+ blacklist_entry_template = GsParameter.get('blacklist_file_entry', 'perimeter', 'general')
+ whitelist_entry_template = GsParameter.get('whitelist_file_entry', 'perimeter', 'general')
+ comment_template = GsParameter.get('blacklist_file_comment', 'perimeter', 'general')
+ File.open(firewall_blacklist_file, 'w') do |file|
+ Intruder.where(:list_type => ['whitelist', 'blacklist']).order('list_type DESC, contact_last ASC').all.each do |entry|
+ if !whitelist_entry_template.blank? && entry.list_type == 'whitelist'
+ if ! comment_template.blank?
+ file.write(expand_variables(comment_template, entry.to_hash) + "\n")
+ end
+ file.write(expand_variables(whitelist_entry_template, entry.to_hash) + "\n")
+ elsif !blacklist_entry_template.blank? && entry.list_type == 'blacklist' && entry.bans.to_i > 0
+ if ! comment_template.blank?
+ file.write(expand_variables(comment_template, entry.to_hash) + "\n")
+ end
+ file.write(expand_variables(blacklist_entry_template, entry.to_hash) + "\n")
+ end
+ end
+ end
+ end
+
+ def restart_firewall
+ command = GsParameter.get('ban_command', 'perimeter', 'general')
+ if !command.blank?
+ system expand_variables(command, self.to_hash)
+ end
+ end
+
+ def check_if_update_relevant
+ if key_changed? || contact_ip_changed? || list_type_changed? || bans_changed? || points_changed?
+ if !GsParameter.get("#{self.list_type}_file_entry", 'perimeter', 'general').blank?
+ write_firewall_list
+ restart_firewall
+ end
+ end
+ end
+
+ def check_if_new_entry_relevant
+ if !GsParameter.get("#{self.list_type}_file_entry", 'perimeter', 'general').blank?
+ if self.list_type != 'blacklist' || self.bans.to_i > 0
+ write_firewall_list
+ restart_firewall
+ end
+ end
+ end
+
+ def check_if_delete_relevant
+ if !GsParameter.get("#{self.list_type}_file_entry", 'perimeter', 'general').blank?
+ if self.list_type != 'blacklist' || self.bans.to_i > 0
+ write_firewall_list
+ restart_firewall
+ end
+ end
+ end
end
diff --git a/app/models/softkey.rb b/app/models/softkey.rb
index 8049456..470605c 100644
--- a/app/models/softkey.rb
+++ b/app/models/softkey.rb
@@ -22,29 +22,24 @@ class Softkey < ActiveRecord::Base
after_save :resync_phone
after_destroy :resync_phone
- def possible_blf_call_forwards
- if self.sip_account.phone_numbers.count == 0
- nil
- else
- if self.sip_account.callforward_rules_act_per_sip_account == true
- # We pick one phone_number and display the rules of it.
- #
- phone_number = self.sip_account.phone_numbers.order(:number).first
- call_forwards = self.sip_account.call_forwards.where(:call_forwardable_id => phone_number.id, :call_forwardable_type => 'PhoneNumber')
- else
- call_forwards = self.sip_account.call_forwards
- end
-
- phone_numbers_ids = self.sip_account.phone_number_ids
- phone_numbers = PhoneNumber.where(:id => phone_numbers_ids).pluck(:number)
+ def possible_call_forwards
+ call_forwards = self.sip_account.call_forwards
+ self.sip_account.phone_numbers.each do |phone_number|
+ call_forwards = call_forwards + phone_number.call_forwards
+ end
- hunt_group_ids = PhoneNumber.where(:phone_numberable_type => 'HuntGroupMember', :number => phone_numbers).
- map{ |phone_number| phone_number.phone_numberable.hunt_group.id }.
- uniq
- call_forwards + CallForward.where(:destinationable_type => 'HuntGroup', :destinationable_id => hunt_group_ids, :call_forwardable_type => 'PhoneNumber').
- where('call_forwardable_id NOT IN (?)', phone_numbers_ids)
- end
+ phone_numbers_ids = self.sip_account.phone_number_ids
+ phone_numbers = PhoneNumber.where(:id => phone_numbers_ids).pluck(:number)
+
+ hunt_group_ids = PhoneNumber.where(:phone_numberable_type => 'HuntGroupMember', :number => phone_numbers).
+ map{ |phone_number| phone_number.phone_numberable.hunt_group.id }.
+ uniq
+
+ call_forwards = call_forwards + CallForward.where(:destinationable_type => 'HuntGroup', :destinationable_id => hunt_group_ids, :call_forwardable_type => 'PhoneNumber').
+ where('call_forwardable_id NOT IN (?)', phone_numbers_ids)
+
+ return call_forwards
end
def to_s
diff --git a/app/views/config_polycom/idle_screen.xml.haml b/app/views/config_polycom/idle_screen.xml.haml
index fa52c4f..f6d8cf9 100644
--- a/app/views/config_polycom/idle_screen.xml.haml
+++ b/app/views/config_polycom/idle_screen.xml.haml
@@ -3,5 +3,18 @@
%head
%title= @sip_account.caller_name
%body
- - @sip_account.phone_numbers.each do |number|
- %br= number.number
+ - phone_numbers = @sip_account.phone_numbers.order(:position)
+ - if phone_numbers[0]
+ %strong= phone_numbers[0].number
+ - else
+ %strong= sip_account.to_s
+ - if phone_numbers[1]
+ %strong= phone_numbers[1].number
+ - if phone_numbers[2]
+ %strong= phone_numbers[2].number
+ - if phone_numbers[3]
+ %strong ...
+ - call = @sip_account.call_histories.where(:entry_type => 'missed').order('start_stamp DESC').first
+ %p
+ Missed:
+ %br= "#{call.start_stamp.strftime('%d.%m %H:%M')} #{call.display_name} #{call.display_number}"
diff --git a/app/views/fax_documents/_index_core.html.haml b/app/views/fax_documents/_index_core.html.haml
index 2f9b214..df1e2ac 100644
--- a/app/views/fax_documents/_index_core.html.haml
+++ b/app/views/fax_documents/_index_core.html.haml
@@ -25,9 +25,24 @@
%tr{:class => current_status}
%td
- case fax_document.state
+ - when 'received'
+ %i.icon-warning-sign
+ = l fax_document.sent_at, :format => :short
+ - when 'unsuccessful'
+ %i.icon-ban-circle
+ = t("fax_documents.states.#{fax_document.state}")
- when 'successful'
- = "#{fax_document.inbound ? '&#8680;' : '&#8678;'}".html_safe
+ - if fax_document.inbound
+ %i.icon-arrow-right
+ - else
+ %i.icon-arrow-left
= l fax_document.sent_at, :format => :short
+ - when 'queued_for_sending'
+ %i.icon-time
+ = t("fax_documents.states.#{fax_document.state}")
+ - when 'sending'
+ %i.icon-print
+ = t("fax_documents.states.#{fax_document.state}")
- else
= t("fax_documents.states.#{fax_document.state}")
%td
diff --git a/app/views/group_memberships/_index_core.html.haml b/app/views/group_memberships/_index_core.html.haml
index beeefc9..31a9050 100644
--- a/app/views/group_memberships/_index_core.html.haml
+++ b/app/views/group_memberships/_index_core.html.haml
@@ -2,10 +2,11 @@
%tr
%th= t('group_memberships.index.item_type')
%th= t('group_memberships.index.item_id')
-
+ %th= t('group_memberships.index.item')
- for group_membership in group_memberships
%tr
%td= group_membership.item_type
%td= group_membership.item_id
+ %td= group_membership.item
=render :partial => 'shared/index_view_edit_destroy_part', :locals => {:parent => group_membership.group, :child => group_membership}
diff --git a/app/views/group_memberships/show.html.haml b/app/views/group_memberships/show.html.haml
index 0875f0b..362b25f 100644
--- a/app/views/group_memberships/show.html.haml
+++ b/app/views/group_memberships/show.html.haml
@@ -7,4 +7,8 @@
%strong= t('group_memberships.show.item_id') + ":"
= @group_membership.item_id
+%p
+ %strong= t('group_memberships.show.item') + ":"
+ = @group_membership.item
+
= render :partial => 'shared/show_edit_destroy_part', :locals => { :parent => @group, :child => @group_membership }
diff --git a/app/views/groups/_form_core.html.haml b/app/views/groups/_form_core.html.haml
index 1f9a39f..02f296b 100644
--- a/app/views/groups/_form_core.html.haml
+++ b/app/views/groups/_form_core.html.haml
@@ -1,4 +1,4 @@
.inputs
= f.input :name, :label => t('groups.form.name.label'), :hint => conditional_hint('groups.form.name.hint')
- = f.input :active, :label => t('groups.form.active.label'), :hint => conditional_hint('groups.form.active.hint')
= f.input :comment, :label => t('groups.form.comment.label'), :hint => conditional_hint('groups.form.comment.hint')
+ = f.input :active, :label => t('groups.form.active.label'), :hint => conditional_hint('groups.form.active.hint')
diff --git a/app/views/groups/_index_core.html.haml b/app/views/groups/_index_core.html.haml
index 3a444bf..e67eb66 100644
--- a/app/views/groups/_index_core.html.haml
+++ b/app/views/groups/_index_core.html.haml
@@ -2,6 +2,8 @@
%tr
%th
%th= t('groups.index.name')
+ %th= t('groups.index.permissions')
+ %th= t('groups.index.memberships')
%th= t('groups.index.comment')
@@ -13,5 +15,11 @@
- else
%i.icon-ban-circle
%td= group.name
+ %td
+ - if group.group_permissions.count > 0 && group.group_permissions.count < 4
+ = group.group_permissions.pluck(:permission).uniq.join(' ')
+ - else
+ = group.group_permissions.count
+ %td= group.group_memberships.count
%td= group.comment
- =render :partial => 'shared/index_view_edit_destroy_part', :locals => {:child => group} \ No newline at end of file
+ =render :partial => 'shared/index_view_edit_destroy_part', :locals => {:child => group}
diff --git a/app/views/gs_parameters/index.html.haml b/app/views/gs_parameters/index.html.haml
index 8df2bb3..9d757a0 100644
--- a/app/views/gs_parameters/index.html.haml
+++ b/app/views/gs_parameters/index.html.haml
@@ -2,12 +2,42 @@
- cache(['gs_parameter_all_tables', I18n.locale, @gs_parameters.count, @gs_parameters.reorder(:updated_at).first, @gs_parameters.reorder(:updated_at).last]) do
- if @gs_parameters && @gs_parameters.count > 0
- - if @sections
- - @sections.each do |section|
- %h3= section
- %table.table.table-striped
- -# Template Dependency: gs_parameters/_index_core
- = render "index_core", :gs_parameters => @gs_parameters.where(:section => section)
- - else
- %table.table.table-striped
- = render "index_core", :gs_parameters => @gs_parameters
+ %table.table.table-striped
+ %thead
+ %tr
+ %th
+ %th
+ %th
+ %th
+
+ %tbody
+ - @entities.each do |entity_name, entity|
+ %tr.table.info
+ %td{:colspan => 5}
+ - if !entity_name.blank?
+ %strong= entity_name
+ - entity.each do |section_name, section|
+ %tr.table.success
+ %td
+ %td{:colspan => 4}
+ %strong= section_name
+ - gs_parameters = @gs_parameters.where(:entity => entity_name, :section => section_name)
+ - cache(['gs_parameter_sub_table', I18n.locale, gs_parameters.count, gs_parameters.reorder(:updated_at).first, gs_parameters.reorder(:updated_at).last]) do
+
+ - for gs_parameter in gs_parameters
+ - cache(['gs_parameters_table_single_row', I18n.locale, gs_parameter]) do
+ %tr
+ %td
+ %td
+ %td
+ %span.hidden-phone
+ = truncate(gs_parameter.name, :length => GsParameter.get('DESKTOP_MAX_STRING_LENGTH'))
+ %span.visible-phone
+ = truncate(gs_parameter.name, :length => GsParameter.get('MOBILE_MAX_STRING_LENGTH'))
+ %td
+ %span.hidden-phone
+ = truncate(gs_parameter.value, :length => GsParameter.get('DESKTOP_MAX_STRING_LENGTH'))
+ %span.visible-phone
+ = truncate(gs_parameter.value, :length => GsParameter.get('MOBILE_MAX_STRING_LENGTH'))
+ =render :partial => 'shared/index_view_edit_destroy_part', :locals => {:child => gs_parameter}
+
diff --git a/app/views/gs_parameters/show.html.haml b/app/views/gs_parameters/show.html.haml
index 706625f..85e9b98 100644
--- a/app/views/gs_parameters/show.html.haml
+++ b/app/views/gs_parameters/show.html.haml
@@ -4,10 +4,11 @@
%table.table.table-striped
%tbody
%tr
+ %tr
%td
- %strong= t('gs_parameters.show.name') + ":"
+ %strong= t('gs_parameters.show.entity') + ":"
%td
- = @gs_parameter.name
+ = @gs_parameter.entity
%tr
%td
%strong= t('gs_parameters.show.section') + ":"
@@ -15,6 +16,11 @@
= @gs_parameter.section
%tr
%td
+ %strong= t('gs_parameters.show.name') + ":"
+ %td
+ = @gs_parameter.name
+ %tr
+ %td
%strong= t('gs_parameters.show.value') + ":"
%td
= @gs_parameter.value
diff --git a/app/views/intruders/_form_core.html.haml b/app/views/intruders/_form_core.html.haml
index 780d8cd..a0c2eb0 100644
--- a/app/views/intruders/_form_core.html.haml
+++ b/app/views/intruders/_form_core.html.haml
@@ -1,5 +1,7 @@
.inputs
= f.input :list_type, :collection => Intruder::LIST_TYPES, :label => t('intruders.form.list_type.label'), :hint => conditional_hint('intruders.form.list_type.hint'), :include_blank => false
= f.input :contact_ip, :label => t('intruders.form.contact_ip.label'), :hint => conditional_hint('intruders.form.contact_ip.hint')
- = f.input :ban_end, :label => t('intruders.form.ban_end.label'), :hint => conditional_hint('intruders.form.ban_end.hint')
+ = f.input :points, :label => t('intruders.form.points.label'), :hint => conditional_hint('intruders.form.points.hint')
+ = f.input :bans, :label => t('intruders.form.bans.label'), :hint => conditional_hint('intruders.form.bans.hint'), as: :boolean
+
= f.input :comment, :label => t('intruders.form.comment.label'), :hint => conditional_hint('intruders.form.comment.hint')
diff --git a/app/views/intruders/_index_core.html.haml b/app/views/intruders/_index_core.html.haml
index 63f2253..1fca601 100644
--- a/app/views/intruders/_index_core.html.haml
+++ b/app/views/intruders/_index_core.html.haml
@@ -2,38 +2,39 @@
%tr
%th
%th= t('intruders.index.contact_ip')
- %th= t('intruders.index.contact_port')
%th= t('intruders.index.points')
- %th= t('intruders.index.bans')
%th= t('intruders.index.ban_last')
- %th= t('intruders.index.ban_end')
%th= t('intruders.index.contact_count')
%th= t('intruders.index.contact_last')
%th= t('intruders.index.contacts_per_second')
%th= t('intruders.index.user_agent')
%th= t('intruders.index.to_user')
+ %th
- for intruder in intruders
- %tr
+ - if intruder.list_type == 'whitelist'
+ - entry_class = 'success'
+ - elsif intruder.bans.to_i > 0
+ - entry_class = 'error'
+ - elsif intruder.points.to_i > 0
+ - entry_class = 'warn'
+ - else
+ - entry_class = ''
+ %tr{:class => "table #{entry_class}"}
%td
- - if intruder.list_type == 'whitelist'
+ - if entry_class == 'success'
%i.icon-ok
- - elsif intruder.bans > 0
+ - elsif entry_class == 'error'
%i.icon-fire
- - elsif intruder.points > 0
+ - elsif entry_class == 'warn'
%i.icon-warning-sign
%td= intruder.contact_ip
- %td= intruder.contact_port
%td= intruder.points
- %td= intruder.bans
%td
- if intruder.ban_last
= l intruder.ban_last, :format => :short
- %td
- - if intruder.ban_end
- = l intruder.ban_end, :format => :short
%td= intruder.contact_count
%td
diff --git a/app/views/intruders/index.html.haml b/app/views/intruders/index.html.haml
index 72b8882..79b4ceb 100644
--- a/app/views/intruders/index.html.haml
+++ b/app/views/intruders/index.html.haml
@@ -1,6 +1,9 @@
- content_for :title, t("intruders.index.page_title")
-- if @intruders && @intruders.count > 0
- = render "index_core", :intruders => @intruders
+- if @intruders && @intruders.count > 0 && @list_types && @list_types.count > 0
+ - @list_types.each do |list_type|
+ %h3= list_type
+ %table.table.table-striped
+ = render "index_core", :intruders => @intruders.where(:list_type => list_type)
-= render :partial => 'shared/create_link', :locals => {:child_class => Intruder} \ No newline at end of file
+= render :partial => 'shared/create_link', :locals => {:child_class => Intruder}
diff --git a/app/views/phone_book_entries/show.html.haml b/app/views/phone_book_entries/show.html.haml
index 7dd9bcb..1afb019 100644
--- a/app/views/phone_book_entries/show.html.haml
+++ b/app/views/phone_book_entries/show.html.haml
@@ -70,26 +70,39 @@
- case phone_number.name.to_s.downcase
- when /fax/
.fax
+ %i.icon-print
+ = phone_number.name
= link_to phone_number, call_phone_book_entry_phone_number_path(@phone_book_entry, phone_number), :method => :put, :title => t('phone_numbers.show.actions.call')
- %span= phone_number.name
- when /home/
.home
+ %i.icon-home
+ = phone_number.name
= link_to phone_number, call_phone_book_entry_phone_number_path(@phone_book_entry, phone_number), :method => :put, :title => t('phone_numbers.show.actions.call')
- %span
- when /mobile/
.cellphone
+ %i.icon-signal
+ = phone_number.name
= link_to phone_number, call_phone_book_entry_phone_number_path(@phone_book_entry, phone_number), :method => :put, :title => t('phone_numbers.show.actions.call')
- %span= phone_number.name
- when /office/
.office
+ %i.icon-briefcase
+ = phone_number.name
= link_to phone_number, call_phone_book_entry_phone_number_path(@phone_book_entry, phone_number), :method => :put, :title => t('phone_numbers.show.actions.call')
- %span= phone_number.name
- - else
+ - when /phone/
.phone
+ %i.icon-asterisk
+ = phone_number.name
+ = link_to phone_number, call_phone_book_entry_phone_number_path(@phone_book_entry, phone_number), :method => :put, :title => t('phone_numbers.show.actions.call')
+ - else
+ .phone_number
+ %i.icon-star
+ = phone_number.name
= link_to phone_number, call_phone_book_entry_phone_number_path(@phone_book_entry, phone_number), :method => :put, :title => t('phone_numbers.show.actions.call')
- %span= phone_number.name
- = link_to t('phone_book_entries.show.manage_phone_numbers'), phone_book_entry_phone_numbers_path(@phone_book_entry)
+ %p
+ %a.btn.btn-small.btn-default{ :href => phone_book_entry_phone_numbers_path(@phone_book_entry) }
+ %i.icon-edit
+ = t('phone_book_entries.show.manage_phone_numbers')
.widget.adresses
- @phone_book_entry.addresses.each do |address|
diff --git a/app/views/phones/_form_core.html.haml b/app/views/phones/_form_core.html.haml
index 31f3c24..e093899 100644
--- a/app/views/phones/_form_core.html.haml
+++ b/app/views/phones/_form_core.html.haml
@@ -11,5 +11,5 @@
- if defined? GsParameter.get('NIGHTLY_REBOOT_OF_PHONES') && GsParameter.get('NIGHTLY_REBOOT_OF_PHONES') == true
= f.input :nightly_reboot, :label => t('phones.form.nightly_reboot.label'), :hint => conditional_hint('phones.form.nightly_reboot.hint')
- - if GsParameter.get('PROVISIONING_KEY_LENGTH') == 0
+ - if @phone && @phone.provisioning_key_active
= f.input :provisioning_key_active, :label => t('phones.form.provisioning_key_active.label'), :hint => conditional_hint('phones.form.provisioning_key_active.hint')
diff --git a/app/views/phones/show.html.haml b/app/views/phones/show.html.haml
index e9b8b21..1996d48 100644
--- a/app/views/phones/show.html.haml
+++ b/app/views/phones/show.html.haml
@@ -34,12 +34,11 @@
%td
= @phone.nightly_reboot == true ? t('simple_form.yes') : t('simple_form.no')
- - if GsParameter.get('PROVISIONING_KEY_LENGTH') == 0
- %tr
- %td
- %strong= t('phones.show.provisioning_key_active') + ":"
- %td
- = @phone.provisioning_key_active == true ? t('simple_form.yes') : t('simple_form.no')
+ %tr
+ %td
+ %strong= t('phones.show.provisioning_key_active') + ":"
+ %td
+ = @phone.provisioning_key_active == true ? t('simple_form.yes') : t('simple_form.no')
%tr{:class => (@phone.ip_address.blank? ? 'warning' : '')}
%td
diff --git a/app/views/softkeys/_form_core.html.haml b/app/views/softkeys/_form_core.html.haml
index 2863d5c..7c1dd4a 100644
--- a/app/views/softkeys/_form_core.html.haml
+++ b/app/views/softkeys/_form_core.html.haml
@@ -6,7 +6,7 @@
.inputs
= f.input :softkey_function_id, :as => :select, :collection => @softkey_functions.map {|x| [I18n.t("softkeys.functions.#{x}"), x.id] }, :label => t('softkeys.form.function.label'), :hint => conditional_hint('softkeys.form.function.hint'), :include_blank => false
- - if @available_call_forwards && @available_call_forwards.count > 0
- = f.association :softkeyable, :collection => @available_call_forwards, :label => t('softkeys.form.call_forward.label'), :hint => conditional_hint('softkeys.form.call_forward.hint'), :include_blank => false
+ - if @softkey.possible_call_forwards && @softkey.possible_call_forwards.count > 0
+ = f.association :softkeyable, :collection => @softkey.possible_call_forwards, :label => t('softkeys.form.call_forward.label'), :hint => conditional_hint('softkeys.form.call_forward.hint'), :include_blank => false
= f.input :number, :label => t('softkeys.form.number.label'), :hint => conditional_hint('softkeys.form.number.hint')
= f.input :label, :label => t('softkeys.form.label.label'), :hint => conditional_hint('softkeys.form.label.hint')
diff --git a/app/views/tenants/_table_of_automatic_call_distributors.html.haml b/app/views/tenants/_table_of_automatic_call_distributors.html.haml
index 22796af..c3ab309 100644
--- a/app/views/tenants/_table_of_automatic_call_distributors.html.haml
+++ b/app/views/tenants/_table_of_automatic_call_distributors.html.haml
@@ -1,4 +1,4 @@
-- cache(['tenant_show_table_of_automatic_call_distributors', I18n.locale, tenant, tenant.automatic_call_distributors.count, tenant.automatic_call_distributors.reorder(:updated_at).last]) do
+- cache(['tenant_show_table_of_automatic_call_distributors', I18n.locale, tenant, tenant.automatic_call_distributors.count, tenant.automatic_call_distributors.reorder(:updated_at).last, PhoneNumber.where(:phone_numberable_type => 'AutomaticCallDistributor').order(:updated_at).last]) do
-# AutomaticCallDistributors
-#
- if (can?( :index, AutomaticCallDistributor ) && tenant.automatic_call_distributors.count > 0 ) || can?( :create, AutomaticCallDistributor )
diff --git a/app/views/tenants/_table_of_hunt_groups.html.haml b/app/views/tenants/_table_of_hunt_groups.html.haml
index aca570d..d93ebe6 100644
--- a/app/views/tenants/_table_of_hunt_groups.html.haml
+++ b/app/views/tenants/_table_of_hunt_groups.html.haml
@@ -1,4 +1,4 @@
-- cache(['table_of_pbx_features_hunt_groups_row', I18n.locale, tenant, tenant.hunt_groups.count, tenant.hunt_groups.reorder(:updated_at).last]) do
+- cache(['table_of_pbx_features_hunt_groups_row', I18n.locale, tenant, tenant.hunt_groups.count, tenant.hunt_groups.reorder(:updated_at).last, PhoneNumber.where(:phone_numberable_type => 'HuntGroup').order(:updated_at).last]) do
-# HuntGroups
-#
- if (can?( :index, HuntGroup ) && tenant.hunt_groups.count > 0 ) || can?( :create, HuntGroup )
diff --git a/config/backup.rb b/config/backup.rb
index 88edd94..2c2984b 100644
--- a/config/backup.rb
+++ b/config/backup.rb
@@ -32,23 +32,7 @@ Backup::Model.new(:GS5, 'GS5 backup') do
#
if File.exists?('/var/opt/gemeinschaft/fax')
archive :faxes do |archive|
- # Incoming faxes
- #
- Dir.glob("/var/opt/gemeinschaft/fax/in/**/*.pdf").each do |fax_file|
- archive.add(fax_file)
- end
- Dir.glob("/var/opt/gemeinschaft/fax/in/**/*.tiff").each do |fax_file|
- archive.add(fax_file)
- end
-
- # Outgoing faxes
- #
- Dir.glob("/var/opt/gemeinschaft/fax/out/**/*.pdf").each do |fax_file|
- archive.add(fax_file)
- end
- Dir.glob("/var/opt/gemeinschaft/fax/out/**/*.tiff").each do |fax_file|
- archive.add(fax_file)
- end
+ archive.add '/var/opt/gemeinschaft/fax'
end
end
@@ -62,6 +46,15 @@ Backup::Model.new(:GS5, 'GS5 backup') do
end
##
+ # Voicemails
+ #
+ if File.exists?('/var/opt/gemeinschaft/freeswitch/recordings')
+ archive :recordings do |archive|
+ archive.add '/var/opt/gemeinschaft/freeswitch/recordings'
+ end
+ end
+
+ ##
# Avatars
#
if File.exists?('/opt/gemeinschaft/public/uploads/user/image')
@@ -81,4 +74,4 @@ Backup::Model.new(:GS5, 'GS5 backup') do
# Gzip [Compressor]
#
compress_with Gzip
-end \ No newline at end of file
+end
diff --git a/config/locales/navigation.en.yml b/config/locales/navigation.en.yml
index 82e901b..015b783 100644
--- a/config/locales/navigation.en.yml
+++ b/config/locales/navigation.en.yml
@@ -1,3 +1,3 @@
en:
navigation:
- admin_docu: 'Admin-Docu' \ No newline at end of file
+ admin_docu: 'Admin-Doc'
diff --git a/config/locales/views/phone_book_entries/de.yml b/config/locales/views/phone_book_entries/de.yml
index bdd0d67..839df3b 100644
--- a/config/locales/views/phone_book_entries/de.yml
+++ b/config/locales/views/phone_book_entries/de.yml
@@ -67,7 +67,7 @@ de:
xing_account: 'Xing Konto'
linkedin_account: 'LinkedIn Konto'
mobileme_account: 'iCloud Konto'
- manage_phone_number: 'Telefonnummern verwalten.'
+ manage_phone_numbers: 'Telefonnummern verwalten.'
actions:
confirm_destroy: 'Sind Sie sicher, dass Sie diesen Telefonbucheintrag löschen möchten?'
destroy: 'Löschen'
diff --git a/config/locales/views/phone_book_entries/en.yml b/config/locales/views/phone_book_entries/en.yml
index abfbbb2..e733d85 100644
--- a/config/locales/views/phone_book_entries/en.yml
+++ b/config/locales/views/phone_book_entries/en.yml
@@ -67,7 +67,7 @@ en:
xing_account: 'Xing account'
linkedin_account: 'LinkedIn account'
mobileme_account: 'iCloud account'
- manage_phone_number: 'Manage phone number.'
+ manage_phone_numbers: 'Manage phone numbers.'
actions:
confirm_destroy: 'Are you sure you want to delete this phone book entry?'
destroy: 'Delete phone book entry'
diff --git a/db/schema.rb b/db/schema.rb
deleted file mode 100644
index 60bc7f5..0000000
--- a/db/schema.rb
+++ /dev/null
@@ -1,1176 +0,0 @@
-# encoding: UTF-8
-# This file is auto-generated from the current state of the database. Instead
-# of editing this file, please use the migrations feature of Active Record to
-# incrementally modify your database, and then regenerate this schema definition.
-#
-# Note that this schema.rb definition is the authoritative source for your
-# database schema. If you need to create the application database on another
-# system, you should be using db:schema:load, not running all the migrations
-# from scratch. The latter is a flawed and unsustainable approach (the more migrations
-# you'll amass, the slower it'll run and the greater likelihood for issues).
-#
-# It's strongly recommended to check this file into your version control system.
-
-ActiveRecord::Schema.define(:version => 20130225160423) do
-
- create_table "access_authorizations", :force => true do |t|
- t.string "access_authorizationable_type"
- t.integer "access_authorizationable_id"
- t.string "name"
- t.string "login"
- t.string "pin"
- t.integer "position"
- t.datetime "created_at", :null => false
- t.datetime "updated_at", :null => false
- t.integer "sip_account_id"
- t.string "uuid"
- end
-
- add_index "access_authorizations", ["uuid"], :name => "index_access_authorizations_on_uuid"
-
- create_table "acd_agents", :force => true do |t|
- t.string "uuid"
- t.string "name"
- t.string "status"
- t.integer "automatic_call_distributor_id"
- t.datetime "last_call"
- t.integer "calls_answered"
- t.string "destination_type"
- t.integer "destination_id"
- t.datetime "created_at", :null => false
- t.datetime "updated_at", :null => false
- end
-
- create_table "acd_callers", :force => true do |t|
- t.string "channel_uuid"
- t.integer "automatic_call_distributor_id"
- t.string "status"
- t.datetime "enter_time"
- t.datetime "agent_answer_time"
- t.string "callback_number"
- t.integer "callback_attempts"
- t.datetime "created_at", :null => false
- t.datetime "updated_at", :null => false
- end
-
- create_table "addresses", :force => true do |t|
- t.integer "phone_book_entry_id"
- t.string "line1"
- t.string "line2"
- t.string "street"
- t.string "zip_code"
- t.string "city"
- t.integer "country_id"
- t.integer "position"
- t.datetime "created_at", :null => false
- t.datetime "updated_at", :null => false
- t.string "uuid"
- end
-
- create_table "aliases", :id => false, :force => true do |t|
- t.integer "sticky"
- t.string "alias", :limit => 128
- t.string "command", :limit => 4096
- t.string "hostname", :limit => 256
- end
-
- add_index "aliases", ["alias"], :name => "alias1"
-
- create_table "api_rows", :force => true do |t|
- t.string "user_id"
- t.string "user_name"
- t.string "last_name"
- t.string "middle_name"
- t.string "first_name"
- t.string "office_phone_number"
- t.string "internal_extension"
- t.string "mobile_phone_number"
- t.string "fax_phone_number"
- t.string "email"
- t.string "pin"
- t.datetime "pin_updated_at"
- t.string "photo_file_name"
- t.datetime "created_at", :null => false
- t.datetime "updated_at", :null => false
- end
-
- create_table "area_codes", :force => true do |t|
- t.integer "country_id"
- t.string "name"
- t.string "area_code"
- t.datetime "created_at", :null => false
- t.datetime "updated_at", :null => false
- t.string "central_office_code"
- end
-
- create_table "automatic_call_distributors", :force => true do |t|
- t.string "uuid"
- t.string "name"
- t.string "strategy"
- t.string "automatic_call_distributorable_type"
- t.integer "automatic_call_distributorable_id"
- t.integer "max_callers"
- t.integer "agent_timeout"
- t.integer "retry_timeout"
- t.string "join"
- t.string "leave"
- t.integer "gs_node_id"
- t.datetime "created_at", :null => false
- t.datetime "updated_at", :null => false
- t.integer "announce_position"
- t.string "announce_call_agents"
- t.string "greeting"
- t.string "goodbye"
- t.string "music"
- end
-
- create_table "backup_jobs", :force => true do |t|
- t.datetime "started_at"
- t.datetime "finished_at"
- t.string "state"
- t.string "directory"
- t.datetime "created_at", :null => false
- t.datetime "updated_at", :null => false
- t.string "backup_file"
- end
-
- create_table "call_forward_cases", :force => true do |t|
- t.string "value"
- t.datetime "created_at", :null => false
- t.datetime "updated_at", :null => false
- end
-
- add_index "call_forward_cases", ["value"], :name => "call_forward_cases_value_index", :unique => true
-
- create_table "call_forwards", :force => true do |t|
- t.integer "call_forward_case_id"
- t.integer "timeout"
- t.string "destination"
- t.string "source"
- t.boolean "active"
- t.datetime "created_at", :null => false
- t.datetime "updated_at", :null => false
- t.integer "phone_number_id"
- t.integer "depth"
- t.string "call_forwardable_type"
- t.integer "call_forwardable_id"
- t.integer "position"
- t.string "uuid"
- end
-
- add_index "call_forwards", ["phone_number_id"], :name => "index_call_forwards_on_phone_number_id"
-
- create_table "call_histories", :force => true do |t|
- t.string "call_historyable_type"
- t.integer "call_historyable_id"
- t.string "entry_type"
- t.string "caller_account_type"
- t.integer "caller_account_id"
- t.string "caller_id_number"
- t.string "caller_id_name"
- t.string "caller_channel_uuid"
- t.string "callee_account_type"
- t.integer "callee_account_id"
- t.string "callee_id_number"
- t.string "callee_id_name"
- t.string "auth_account_type"
- t.integer "auth_account_id"
- t.string "forwarding_service"
- t.string "destination_number"
- t.datetime "start_stamp"
- t.integer "duration"
- t.string "result"
- t.boolean "read_flag"
- t.boolean "returned_flag"
- t.datetime "created_at", :null => false
- t.datetime "updated_at", :null => false
- end
-
- create_table "call_routes", :force => true do |t|
- t.string "routing_table"
- t.string "name"
- t.string "endpoint_type"
- t.integer "endpoint_id"
- t.integer "position"
- t.datetime "created_at", :null => false
- t.datetime "updated_at", :null => false
- end
-
- create_table "calls", :id => false, :force => true do |t|
- t.string "call_uuid"
- t.string "call_created", :limit => 128
- t.integer "call_created_epoch"
- t.string "function", :limit => 1024
- t.string "caller_cid_name", :limit => 1024
- t.string "caller_cid_num", :limit => 256
- t.string "caller_dest_num", :limit => 256
- t.string "caller_chan_name", :limit => 1024
- t.string "caller_uuid", :limit => 256
- t.string "callee_cid_name", :limit => 1024
- t.string "callee_cid_numcallee_dest_num", :limit => 256
- t.string "callee_chan_name", :limit => 1024
- t.string "callee_uuid", :limit => 256
- t.string "hostname", :limit => 256
- end
-
- add_index "calls", ["call_uuid", "hostname"], :name => "eeuuindex2"
- add_index "calls", ["callee_uuid", "hostname"], :name => "eeuuindex"
- add_index "calls", ["caller_uuid", "hostname"], :name => "eruuindex"
- add_index "calls", ["hostname"], :name => "calls1"
-
- create_table "callthroughs", :force => true do |t|
- t.integer "tenant_id"
- t.string "name"
- t.string "clip_no_screening"
- t.datetime "created_at", :null => false
- t.datetime "updated_at", :null => false
- t.string "uuid"
- end
-
- create_table "cdrs", :id => false, :force => true do |t|
- t.string "uuid", :limit => 256
- t.integer "account_id"
- t.string "account_type", :limit => 256
- t.string "bleg_uuid", :limit => 256
- t.integer "bleg_account_id"
- t.string "bleg_account_type", :limit => 256
- t.string "dialed_number", :limit => 256
- t.string "destination_number", :limit => 256
- t.string "caller_id_number", :limit => 256
- t.string "caller_id_name", :limit => 256
- t.string "callee_id_number", :limit => 256
- t.string "callee_id_name", :limit => 256
- t.datetime "start_stamp"
- t.datetime "answer_stamp"
- t.datetime "end_stamp"
- t.integer "duration"
- t.integer "billsec"
- t.string "hangup_cause", :limit => 256
- t.string "dialstatus", :limit => 256
- t.string "forwarding_number", :limit => 256
- t.integer "forwarding_account_id"
- t.string "forwarding_account_type", :limit => 256
- t.string "forwarding_service", :limit => 256
- t.datetime "bleg_read_time"
- t.datetime "forwarding_read_time"
- t.datetime "bridge_stamp"
- end
-
- create_table "channels", :id => false, :force => true do |t|
- t.string "uuid", :limit => 256
- t.string "direction", :limit => 32
- t.string "created", :limit => 128
- t.integer "created_epoch"
- t.string "name", :limit => 1024
- t.string "state", :limit => 64
- t.string "cid_name", :limit => 1024
- t.string "cid_num", :limit => 256
- t.string "ip_addr", :limit => 256
- t.string "dest", :limit => 1024
- t.string "application", :limit => 128
- t.string "application_data", :limit => 4096
- t.string "dialplan", :limit => 128
- t.string "context", :limit => 128
- t.string "read_codec", :limit => 128
- t.string "read_rate", :limit => 32
- t.string "read_bit_rate", :limit => 32
- t.string "write_codec", :limit => 128
- t.string "write_rate", :limit => 32
- t.string "write_bit_rate", :limit => 32
- t.string "secure", :limit => 32
- t.string "hostname", :limit => 256
- t.string "presence_id", :limit => 4096
- t.string "presence_data", :limit => 4096
- t.string "callstate", :limit => 64
- t.string "callee_name", :limit => 1024
- t.string "callee_num", :limit => 256
- t.string "callee_direction", :limit => 5
- t.string "call_uuid", :limit => 256
- end
-
- add_index "channels", ["call_uuid", "hostname"], :name => "uuindex2"
- add_index "channels", ["hostname"], :name => "channels1"
- add_index "channels", ["uuid", "hostname"], :name => "uuindex", :unique => true
-
- create_table "complete", :id => false, :force => true do |t|
- t.integer "sticky"
- t.string "a1", :limit => 128
- t.string "a2", :limit => 128
- t.string "a3", :limit => 128
- t.string "a4", :limit => 128
- t.string "a5", :limit => 128
- t.string "a6", :limit => 128
- t.string "a7", :limit => 128
- t.string "a8", :limit => 128
- t.string "a9", :limit => 128
- t.string "a10", :limit => 128
- t.string "hostname", :limit => 256
- end
-
- add_index "complete", ["a1", "a2", "a3", "a4", "a5", "a6", "a7", "a8", "a9", "a10", "hostname"], :name => "complete11"
- add_index "complete", ["a1", "hostname"], :name => "complete1"
- add_index "complete", ["a10", "hostname"], :name => "complete10"
- add_index "complete", ["a2", "hostname"], :name => "complete2"
- add_index "complete", ["a3", "hostname"], :name => "complete3"
- add_index "complete", ["a4", "hostname"], :name => "complete4"
- add_index "complete", ["a5", "hostname"], :name => "complete5"
- add_index "complete", ["a6", "hostname"], :name => "complete6"
- add_index "complete", ["a7", "hostname"], :name => "complete7"
- add_index "complete", ["a8", "hostname"], :name => "complete8"
- add_index "complete", ["a9", "hostname"], :name => "complete9"
-
- create_table "conference_invitees", :force => true do |t|
- t.integer "conference_id"
- t.integer "phone_book_entry_id"
- t.string "pin"
- t.boolean "speaker"
- t.boolean "moderator"
- t.datetime "created_at", :null => false
- t.datetime "updated_at", :null => false
- t.string "uuid"
- end
-
- create_table "conferences", :force => true do |t|
- t.string "name"
- t.datetime "start"
- t.datetime "end"
- t.text "description"
- t.string "pin"
- t.text "state"
- t.boolean "open_for_anybody"
- t.string "conferenceable_type"
- t.integer "conferenceable_id"
- t.datetime "created_at", :null => false
- t.datetime "updated_at", :null => false
- t.integer "max_members"
- t.boolean "announce_new_member_by_name"
- t.boolean "announce_left_member_by_name"
- t.string "uuid"
- end
-
- create_table "countries", :force => true do |t|
- t.string "name"
- t.string "country_code"
- t.string "international_call_prefix"
- t.string "trunk_prefix"
- t.datetime "created_at", :null => false
- t.datetime "updated_at", :null => false
- end
-
- create_table "delayed_jobs", :force => true do |t|
- t.integer "priority", :default => 0
- t.integer "attempts", :default => 0
- t.text "handler"
- t.text "last_error"
- t.datetime "run_at"
- t.datetime "locked_at"
- t.datetime "failed_at"
- t.string "locked_by"
- t.datetime "created_at", :null => false
- t.datetime "updated_at", :null => false
- t.string "queue"
- end
-
- add_index "delayed_jobs", ["priority", "run_at"], :name => "delayed_jobs_priority"
-
- create_table "fax_accounts", :force => true do |t|
- t.string "fax_accountable_type"
- t.integer "fax_accountable_id"
- t.string "name"
- t.string "email"
- t.datetime "created_at", :null => false
- t.datetime "updated_at", :null => false
- t.integer "tenant_id"
- t.string "station_id"
- t.integer "days_till_auto_delete"
- t.integer "retries"
- t.string "uuid"
- end
-
- create_table "fax_documents", :force => true do |t|
- t.boolean "inbound"
- t.string "state"
- t.integer "transmission_time"
- t.datetime "sent_at"
- t.integer "document_total_pages"
- t.integer "document_transferred_pages"
- t.boolean "ecm_requested"
- t.boolean "ecm_used"
- t.string "image_resolution"
- t.string "image_size"
- t.string "local_station_id"
- t.integer "result_code"
- t.string "remote_station_id"
- t.boolean "success"
- t.integer "transfer_rate"
- t.string "document"
- t.datetime "created_at", :null => false
- t.datetime "updated_at", :null => false
- t.integer "fax_account_id"
- t.string "caller_id_number"
- t.string "caller_id_name"
- t.integer "retry_counter"
- t.string "tiff"
- t.integer "fax_resolution_id"
- t.string "uuid"
- end
-
- create_table "fax_pages", :force => true do |t|
- t.integer "position"
- t.datetime "created_at", :null => false
- t.datetime "updated_at", :null => false
- t.string "fax_page"
- end
-
- create_table "fax_resolutions", :force => true do |t|
- t.string "name"
- t.string "resolution_value"
- t.integer "position"
- t.datetime "created_at", :null => false
- t.datetime "updated_at", :null => false
- end
-
- create_table "fax_thumbnails", :force => true do |t|
- t.integer "fax_document_id"
- t.integer "position"
- t.string "thumbnail"
- t.datetime "created_at", :null => false
- t.datetime "updated_at", :null => false
- end
-
- create_table "faxes", :force => true do |t|
- t.boolean "inbound"
- t.integer "faxable_id"
- t.string "faxable_type"
- t.string "state"
- t.integer "transmission_time"
- t.datetime "sent_at"
- t.datetime "created_at", :null => false
- t.datetime "updated_at", :null => false
- t.integer "document_total_pages"
- t.integer "document_transferred_pages"
- t.boolean "ecm_requested"
- t.boolean "ecm_used"
- t.string "image_resolution"
- t.string "image_size"
- t.string "local_station_id"
- t.integer "result_code"
- t.string "result_text"
- t.string "remote_station_id"
- t.boolean "success"
- t.integer "transfer_rate"
- t.string "t38_gateway_format"
- t.string "t38_peer"
- t.string "fax"
- end
-
- create_table "fifo_bridge", :id => false, :force => true do |t|
- t.string "fifo_name", :limit => 1024, :null => false
- t.string "caller_uuid", :null => false
- t.string "caller_caller_id_name", :null => false
- t.string "caller_caller_id_number", :null => false
- t.string "consumer_uuid", :null => false
- t.string "consumer_outgoing_uuid"
- t.integer "bridge_start"
- end
-
- create_table "fifo_callers", :id => false, :force => true do |t|
- t.string "fifo_name", :null => false
- t.string "uuid", :null => false
- t.string "caller_caller_id_name"
- t.string "caller_caller_id_number"
- t.integer "timestamp"
- end
-
- create_table "fifo_outbound", :id => false, :force => true do |t|
- t.string "uuid"
- t.string "fifo_name"
- t.string "originate_string"
- t.integer "simo_count"
- t.integer "use_count"
- t.integer "timeout"
- t.integer "lag"
- t.integer "next_avail", :default => 0, :null => false
- t.integer "expires", :default => 0, :null => false
- t.integer "static", :default => 0, :null => false
- t.integer "outbound_call_count", :default => 0, :null => false
- t.integer "outbound_fail_count", :default => 0, :null => false
- t.string "hostname"
- t.integer "taking_calls", :default => 1, :null => false
- t.string "status"
- t.integer "outbound_call_total_count", :default => 0, :null => false
- t.integer "outbound_fail_total_count", :default => 0, :null => false
- t.integer "active_time", :default => 0, :null => false
- t.integer "inactive_time", :default => 0, :null => false
- t.integer "manual_calls_out_count", :default => 0, :null => false
- t.integer "manual_calls_in_count", :default => 0, :null => false
- t.integer "manual_calls_out_total_count", :default => 0, :null => false
- t.integer "manual_calls_in_total_count", :default => 0, :null => false
- t.integer "ring_count", :default => 0, :null => false
- t.integer "start_time", :default => 0, :null => false
- t.integer "stop_time", :default => 0, :null => false
- end
-
- create_table "gateway_parameters", :force => true do |t|
- t.integer "gateway_id"
- t.string "name"
- t.string "value"
- t.string "class_type"
- t.string "description"
- t.datetime "created_at", :null => false
- t.datetime "updated_at", :null => false
- end
-
- create_table "gateway_settings", :force => true do |t|
- t.integer "gateway_id"
- t.string "name"
- t.string "value"
- t.string "class_type"
- t.string "description"
- t.datetime "created_at", :null => false
- t.datetime "updated_at", :null => false
- end
-
- create_table "gateways", :force => true do |t|
- t.string "name"
- t.string "technology"
- t.boolean "inbound"
- t.boolean "outbound"
- t.string "description"
- t.datetime "created_at", :null => false
- t.datetime "updated_at", :null => false
- end
-
- create_table "gemeinschaft_setups", :force => true do |t|
- t.integer "user_id"
- t.integer "sip_domain_id"
- t.integer "country_id"
- t.integer "language_id"
- t.datetime "created_at", :null => false
- t.datetime "updated_at", :null => false
- t.string "default_area_code"
- t.string "default_company_name"
- t.string "default_system_email"
- t.string "trunk_access_code"
- end
-
- create_table "group_memberships", :force => true do |t|
- t.integer "group_id"
- t.string "item_type"
- t.integer "item_id"
- t.datetime "created_at", :null => false
- t.datetime "updated_at", :null => false
- end
-
- create_table "group_permissions", :force => true do |t|
- t.integer "group_id"
- t.string "permission"
- t.integer "target_group_id"
- t.datetime "created_at", :null => false
- t.datetime "updated_at", :null => false
- end
-
- create_table "groups", :force => true do |t|
- t.string "name"
- t.boolean "active"
- t.string "comment"
- t.datetime "created_at", :null => false
- t.datetime "updated_at", :null => false
- end
-
- create_table "gs_cluster_sync_log_entries", :force => true do |t|
- t.integer "gs_node_id"
- t.string "class_name"
- t.string "action"
- t.text "content"
- t.string "status"
- t.string "history"
- t.datetime "created_at", :null => false
- t.datetime "updated_at", :null => false
- t.string "homebase_ip_address"
- t.boolean "waiting_to_be_synced"
- t.string "association_method"
- t.string "association_uuid"
- end
-
- create_table "gs_nodes", :force => true do |t|
- t.string "name"
- t.string "ip_address"
- t.boolean "push_updates_to"
- t.datetime "created_at", :null => false
- t.datetime "updated_at", :null => false
- t.string "site"
- t.string "element_name"
- t.boolean "accepts_updates_from"
- t.datetime "last_sync"
- end
-
- create_table "gs_parameters", :force => true do |t|
- t.string "name"
- t.string "section"
- t.text "value"
- t.string "class_type"
- t.string "description"
- t.datetime "created_at", :null => false
- t.datetime "updated_at", :null => false
- t.string "entity"
- end
-
- create_table "gui_function_memberships", :force => true do |t|
- t.integer "gui_function_id"
- t.integer "user_group_id"
- t.boolean "activated"
- t.string "output"
- t.datetime "created_at", :null => false
- t.datetime "updated_at", :null => false
- end
-
- create_table "gui_functions", :force => true do |t|
- t.string "category"
- t.string "name"
- t.string "description"
- t.datetime "created_at", :null => false
- t.datetime "updated_at", :null => false
- end
-
- create_table "hunt_group_members", :force => true do |t|
- t.integer "hunt_group_id"
- t.string "name"
- t.integer "position"
- t.boolean "active"
- t.boolean "can_switch_status_itself"
- t.datetime "created_at", :null => false
- t.datetime "updated_at", :null => false
- t.string "uuid"
- end
-
- add_index "hunt_group_members", ["uuid"], :name => "index_hunt_group_members_on_uuid"
-
- create_table "hunt_groups", :force => true do |t|
- t.integer "tenant_id"
- t.string "name"
- t.string "strategy"
- t.integer "seconds_between_jumps"
- t.datetime "created_at", :null => false
- t.datetime "updated_at", :null => false
- t.integer "gs_node_id"
- t.integer "gs_node_original_id"
- t.string "uuid"
- end
-
- add_index "hunt_groups", ["uuid"], :name => "index_hunt_groups_on_uuid"
-
- create_table "interfaces", :id => false, :force => true do |t|
- t.string "type", :limit => 128
- t.string "name", :limit => 1024
- t.string "description", :limit => 4096
- t.string "ikey", :limit => 1024
- t.string "filename", :limit => 4096
- t.string "syntax", :limit => 4096
- t.string "hostname", :limit => 256
- end
-
- create_table "intruders", :force => true do |t|
- t.string "list_type"
- t.string "key"
- t.integer "points"
- t.integer "bans"
- t.datetime "ban_last"
- t.datetime "ban_end"
- t.string "contact_ip"
- t.integer "contact_port"
- t.integer "contact_count"
- t.datetime "contact_last"
- t.float "contacts_per_second"
- t.float "contacts_per_second_max"
- t.string "user_agent"
- t.string "to_user"
- t.string "comment"
- t.datetime "created_at", :null => false
- t.datetime "updated_at", :null => false
- end
-
- add_index "intruders", ["key"], :name => "index_intruders_on_key", :unique => true
-
- create_table "languages", :force => true do |t|
- t.string "name"
- t.string "code"
- t.datetime "created_at", :null => false
- t.datetime "updated_at", :null => false
- end
-
- create_table "manufacturers", :force => true do |t|
- t.string "name"
- t.string "ieee_name"
- t.string "homepage_url"
- t.string "state"
- t.datetime "created_at", :null => false
- t.datetime "updated_at", :null => false
- end
-
- create_table "nat", :id => false, :force => true do |t|
- t.integer "sticky"
- t.integer "port"
- t.integer "proto"
- t.string "hostname", :limit => 256
- end
-
- add_index "nat", ["port", "proto", "hostname"], :name => "nat_map_port_proto"
-
- create_table "ouis", :force => true do |t|
- t.integer "manufacturer_id"
- t.string "value"
- t.string "state"
- t.datetime "created_at", :null => false
- t.datetime "updated_at", :null => false
- end
-
- create_table "parking_stalls", :force => true do |t|
- t.string "name"
- t.string "lot"
- t.integer "parking_stallable_id"
- t.string "parking_stallable_type"
- t.string "comment"
- t.datetime "created_at", :null => false
- t.datetime "updated_at", :null => false
- end
-
- create_table "phone_book_entries", :force => true do |t|
- t.integer "phone_book_id"
- t.string "first_name"
- t.string "middle_name"
- t.string "last_name"
- t.string "title"
- t.string "nickname"
- t.string "organization"
- t.boolean "is_organization"
- t.string "department"
- t.string "job_title"
- t.boolean "is_male"
- t.date "birthday"
- t.string "birth_name"
- t.string "state"
- t.text "description"
- t.integer "position"
- t.string "homepage_personal"
- t.string "homepage_organization"
- t.string "twitter_account"
- t.string "facebook_account"
- t.string "google_plus_account"
- t.string "xing_account"
- t.string "linkedin_account"
- t.string "mobileme_account"
- t.datetime "created_at", :null => false
- t.datetime "updated_at", :null => false
- t.string "image"
- t.string "first_name_phonetic"
- t.string "last_name_phonetic"
- t.string "organization_phonetic"
- t.string "value_of_to_s"
- t.string "uuid"
- end
-
- add_index "phone_book_entries", ["first_name"], :name => "index_phone_book_entries_on_first_name"
- add_index "phone_book_entries", ["first_name_phonetic"], :name => "index_phone_book_entries_on_first_name_phonetic"
- add_index "phone_book_entries", ["last_name"], :name => "index_phone_book_entries_on_last_name"
- add_index "phone_book_entries", ["last_name_phonetic"], :name => "index_phone_book_entries_on_last_name_phonetic"
- add_index "phone_book_entries", ["organization"], :name => "index_phone_book_entries_on_organization"
- add_index "phone_book_entries", ["organization_phonetic"], :name => "index_phone_book_entries_on_organization_phonetic"
- add_index "phone_book_entries", ["uuid"], :name => "index_phone_book_entries_on_uuid"
-
- create_table "phone_books", :force => true do |t|
- t.string "name"
- t.string "description"
- t.integer "phone_bookable_id"
- t.string "phone_bookable_type"
- t.string "state"
- t.datetime "created_at", :null => false
- t.datetime "updated_at", :null => false
- t.string "uuid"
- end
-
- create_table "phone_models", :force => true do |t|
- t.string "name"
- t.string "manufacturer_id"
- t.string "product_manual_homepage_url"
- t.string "product_homepage_url"
- t.datetime "created_at", :null => false
- t.datetime "updated_at", :null => false
- t.string "state"
- t.string "uuid"
- end
-
- create_table "phone_number_ranges", :force => true do |t|
- t.string "name"
- t.text "description"
- t.datetime "created_at", :null => false
- t.datetime "updated_at", :null => false
- t.string "phone_number_rangeable_type"
- t.integer "phone_number_rangeable_id"
- t.string "uuid"
- end
-
- add_index "phone_number_ranges", ["uuid"], :name => "index_phone_number_ranges_on_uuid"
-
- create_table "phone_numbers", :force => true do |t|
- t.string "name"
- t.string "number"
- t.string "country_code"
- t.string "area_code"
- t.string "subscriber_number"
- t.string "extension"
- t.integer "position"
- t.datetime "created_at", :null => false
- t.datetime "updated_at", :null => false
- t.string "central_office_code"
- t.string "phone_numberable_type"
- t.integer "phone_numberable_id"
- t.string "state"
- t.string "value_of_to_s"
- t.integer "gs_node_id"
- t.integer "gs_node_original_id"
- t.string "uuid"
- t.integer "access_authorization_user_id"
- t.boolean "is_native"
- end
-
- add_index "phone_numbers", ["uuid"], :name => "index_phone_numbers_on_uuid"
-
- create_table "phone_sip_accounts", :force => true do |t|
- t.integer "phone_id"
- t.integer "sip_account_id"
- t.integer "position"
- t.datetime "created_at", :null => false
- t.datetime "updated_at", :null => false
- end
-
- create_table "phones", :force => true do |t|
- t.string "mac_address"
- t.integer "phone_model_id"
- t.string "ip_address"
- t.string "last_ip_address"
- t.string "http_user"
- t.string "http_password"
- t.datetime "created_at", :null => false
- t.datetime "updated_at", :null => false
- t.string "state"
- t.string "phoneable_type"
- t.integer "phoneable_id"
- t.boolean "hot_deskable"
- t.boolean "nightly_reboot"
- t.string "provisioning_key"
- t.boolean "provisioning_key_active"
- t.integer "tenant_id"
- t.integer "fallback_sip_account_id"
- end
-
- create_table "registrations", :id => false, :force => true do |t|
- t.string "reg_user"
- t.string "realm", :limit => 256
- t.string "token", :limit => 256
- t.text "url"
- t.integer "expires"
- t.string "network_ip", :limit => 256
- t.string "network_port", :limit => 256
- t.string "network_proto", :limit => 256
- t.string "hostname", :limit => 256
- end
-
- add_index "registrations", ["reg_user", "realm", "hostname"], :name => "regindex1"
-
- create_table "restore_jobs", :force => true do |t|
- t.string "state"
- t.string "backup_file"
- t.datetime "created_at", :null => false
- t.datetime "updated_at", :null => false
- end
-
- create_table "ringtones", :force => true do |t|
- t.string "ringtoneable_type"
- t.integer "ringtoneable_id"
- t.string "audio"
- t.integer "bellcore_id"
- t.datetime "created_at", :null => false
- t.datetime "updated_at", :null => false
- end
-
- create_table "route_elements", :force => true do |t|
- t.integer "call_route_id"
- t.string "var_in"
- t.string "var_out"
- t.string "pattern"
- t.string "replacement"
- t.string "action"
- t.boolean "mandatory"
- t.integer "position"
- t.datetime "created_at", :null => false
- t.datetime "updated_at", :null => false
- end
-
- create_table "sessions", :force => true do |t|
- t.string "session_id", :null => false
- t.text "data"
- t.datetime "created_at", :null => false
- t.datetime "updated_at", :null => false
- end
-
- add_index "sessions", ["session_id"], :name => "index_sessions_on_session_id"
- add_index "sessions", ["updated_at"], :name => "index_sessions_on_updated_at"
-
- create_table "sim_card_providers", :force => true do |t|
- t.string "name"
- t.string "homepage_url"
- t.string "docu_url"
- t.string "api_server_url"
- t.string "api_username"
- t.string "api_password"
- t.string "ref"
- t.string "sip_server"
- t.boolean "include_order_card_function"
- t.datetime "created_at", :null => false
- t.datetime "updated_at", :null => false
- end
-
- create_table "sim_cards", :force => true do |t|
- t.integer "sim_card_provider_id"
- t.string "sim_number"
- t.boolean "auto_order_card"
- t.integer "sip_account_id"
- t.string "auth_key"
- t.string "state"
- t.text "log"
- t.datetime "created_at", :null => false
- t.datetime "updated_at", :null => false
- end
-
- create_table "sip_accounts", :force => true do |t|
- t.string "sip_accountable_type"
- t.integer "sip_accountable_id"
- t.string "auth_name"
- t.string "caller_name"
- t.string "password"
- t.string "voicemail_pin"
- t.datetime "created_at", :null => false
- t.datetime "updated_at", :null => false
- t.string "value_of_to_s"
- t.integer "tenant_id"
- t.integer "sip_domain_id"
- t.boolean "call_waiting"
- t.boolean "clir"
- t.string "clip_no_screening"
- t.boolean "clip"
- t.string "description"
- t.boolean "callforward_rules_act_per_sip_account"
- t.boolean "hotdeskable"
- t.integer "gs_node_id"
- t.integer "gs_node_original_id"
- t.string "uuid"
- t.boolean "is_native"
- t.string "language_code"
- end
-
- add_index "sip_accounts", ["uuid"], :name => "index_sip_accounts_on_uuid"
-
- create_table "sip_domains", :force => true do |t|
- t.string "host"
- t.string "realm"
- t.datetime "created_at", :null => false
- t.datetime "updated_at", :null => false
- end
-
- create_table "sip_registrations", :id => false, :force => true do |t|
- t.string "call_id"
- t.string "sip_user"
- t.string "sip_host"
- t.string "presence_hosts"
- t.string "contact", :limit => 1024
- t.string "status"
- t.string "rpid"
- t.integer "expires"
- t.string "user_agent"
- t.string "server_user"
- t.string "server_host"
- t.string "profile_name"
- t.string "hostname"
- t.string "network_ip"
- t.string "network_port", :limit => 6
- t.string "sip_username"
- t.string "sip_realm"
- t.string "mwi_user"
- t.string "mwi_host"
- t.string "orig_server_host"
- t.string "orig_hostname"
- t.string "sub_host"
- end
-
- add_index "sip_registrations", ["call_id"], :name => "sr_call_id"
- add_index "sip_registrations", ["contact"], :name => "sr_contact"
- add_index "sip_registrations", ["expires"], :name => "sr_expires"
- add_index "sip_registrations", ["hostname"], :name => "sr_hostname"
- add_index "sip_registrations", ["mwi_host"], :name => "sr_mwi_host"
- add_index "sip_registrations", ["mwi_user"], :name => "sr_mwi_user"
- add_index "sip_registrations", ["network_ip"], :name => "sr_network_ip"
- add_index "sip_registrations", ["network_port"], :name => "sr_network_port"
- add_index "sip_registrations", ["orig_hostname"], :name => "sr_orig_hostname"
- add_index "sip_registrations", ["orig_server_host"], :name => "sr_orig_server_host"
- add_index "sip_registrations", ["presence_hosts"], :name => "sr_presence_hosts"
- add_index "sip_registrations", ["profile_name"], :name => "sr_profile_name"
- add_index "sip_registrations", ["sip_host"], :name => "sr_sip_host"
- add_index "sip_registrations", ["sip_realm"], :name => "sr_sip_realm"
- add_index "sip_registrations", ["sip_user"], :name => "sr_sip_user"
- add_index "sip_registrations", ["sip_username"], :name => "sr_sip_username"
- add_index "sip_registrations", ["status"], :name => "sr_status"
- add_index "sip_registrations", ["sub_host"], :name => "sr_sub_host"
-
- create_table "softkey_functions", :force => true do |t|
- t.string "name"
- t.datetime "created_at", :null => false
- t.datetime "updated_at", :null => false
- t.integer "position"
- end
-
- add_index "softkey_functions", ["name"], :name => "index_softkey_functions_on_name"
- add_index "softkey_functions", ["position"], :name => "index_softkey_functions_on_position"
-
- create_table "softkeys", :force => true do |t|
- t.string "function"
- t.string "number"
- t.string "label"
- t.integer "position"
- t.datetime "created_at", :null => false
- t.datetime "updated_at", :null => false
- t.integer "sip_account_id"
- t.integer "softkey_function_id"
- t.string "uuid"
- t.string "softkeyable_type"
- t.integer "softkeyable_id"
- end
-
- create_table "tasks", :id => false, :force => true do |t|
- t.integer "task_id"
- t.string "task_desc", :limit => 4096
- t.string "task_group", :limit => 1024
- t.integer "task_sql_manager"
- t.string "hostname", :limit => 256
- end
-
- add_index "tasks", ["hostname", "task_id"], :name => "tasks1", :unique => true
-
- create_table "tenant_memberships", :force => true do |t|
- t.integer "tenant_id"
- t.integer "user_id"
- t.string "state"
- t.datetime "created_at", :null => false
- t.datetime "updated_at", :null => false
- end
-
- create_table "tenants", :force => true do |t|
- t.string "name"
- t.text "description"
- t.string "state"
- t.datetime "created_at", :null => false
- t.datetime "updated_at", :null => false
- t.integer "country_id"
- t.integer "sip_domain_id"
- t.integer "language_id"
- t.string "internal_extension_ranges"
- t.string "did_list"
- t.string "from_field_voicemail_email"
- t.string "from_field_pin_change_email"
- t.string "uuid"
- end
-
- create_table "user_group_memberships", :force => true do |t|
- t.integer "user_group_id"
- t.integer "user_id"
- t.string "state"
- t.datetime "created_at", :null => false
- t.datetime "updated_at", :null => false
- end
-
- create_table "user_groups", :force => true do |t|
- t.string "name"
- t.text "description"
- t.integer "tenant_id"
- t.integer "position"
- t.datetime "created_at", :null => false
- t.datetime "updated_at", :null => false
- end
-
- create_table "users", :force => true do |t|
- t.string "user_name"
- t.string "email"
- t.string "password_digest"
- t.string "first_name"
- t.string "middle_name"
- t.string "last_name"
- t.boolean "male"
- t.string "gemeinschaft_unique_id"
- t.datetime "created_at", :null => false
- t.datetime "updated_at", :null => false
- t.string "image"
- t.integer "current_tenant_id"
- t.string "pin_salt"
- t.string "pin_hash"
- t.integer "language_id"
- t.boolean "send_voicemail_as_email_attachment"
- t.string "importer_checksum"
- t.integer "gs_node_id"
- t.integer "gs_node_original_id"
- t.string "uuid"
- t.boolean "is_native"
- end
-
- add_index "users", ["uuid"], :name => "index_users_on_uuid"
-
- create_table "voicemail_msgs", :id => false, :force => true do |t|
- t.integer "created_epoch"
- t.integer "read_epoch"
- t.string "username"
- t.string "domain"
- t.string "uuid"
- t.string "cid_name"
- t.string "cid_number"
- t.string "in_folder"
- t.string "file_path"
- t.integer "message_len"
- t.string "flags"
- t.string "read_flags"
- t.string "forwarded_by"
- t.boolean "notification"
- end
-
- add_index "voicemail_msgs", ["created_epoch"], :name => "voicemail_msgs_idx1"
- add_index "voicemail_msgs", ["domain"], :name => "voicemail_msgs_idx3"
- add_index "voicemail_msgs", ["forwarded_by"], :name => "voicemail_msgs_idx7"
- add_index "voicemail_msgs", ["in_folder"], :name => "voicemail_msgs_idx5"
- add_index "voicemail_msgs", ["read_flags"], :name => "voicemail_msgs_idx6"
- add_index "voicemail_msgs", ["username"], :name => "voicemail_msgs_idx2"
- add_index "voicemail_msgs", ["uuid"], :name => "voicemail_msgs_idx4"
-
- create_table "voicemail_prefs", :id => false, :force => true do |t|
- t.string "username"
- t.string "domain"
- t.string "name_path"
- t.string "greeting_path"
- t.string "password"
- t.boolean "notify"
- t.boolean "attachment"
- t.boolean "mark_read"
- t.boolean "purge"
- end
-
- add_index "voicemail_prefs", ["domain"], :name => "voicemail_prefs_idx2"
- add_index "voicemail_prefs", ["username"], :name => "voicemail_prefs_idx1"
-
- create_table "whitelists", :force => true do |t|
- t.string "name"
- t.string "whitelistable_type"
- t.integer "whitelistable_id"
- t.integer "position"
- t.datetime "created_at", :null => false
- t.datetime "updated_at", :null => false
- t.string "uuid"
- end
-
-end
diff --git a/lib/tasks/backup.rake b/lib/tasks/backup.rake
index 55369b6..ad4d41d 100644
--- a/lib/tasks/backup.rake
+++ b/lib/tasks/backup.rake
@@ -4,6 +4,18 @@ namespace :backup do
# This would be the daily backup.
end
+ desc "Do a backup."
+ task :queue_a_new_backup => :environment do
+ backup_job = BackupJob.create
+ echo "BackupJob ID: #{backup_job.id}"
+ end
+
+ desc "Do a backup. Now!"
+ task :force_now => :environment do
+ backup_job = BackupJob.create(:state => 'force now')
+ echo "BackupJob ID: #{backup_job.id}"
+ end
+
desc "Restore the system"
task :restore => :environment do
# This task takes the first RestoreJob to restore the system.
@@ -29,6 +41,12 @@ namespace :backup do
system "cd / && sudo /bin/tar xzfP #{restore_directory}/GS5/archives/voicemails.tar.gz"
end
+ # Restore recordings
+ #
+ if File.exists?("#{restore_directory}/GS5/archives/recordings.tar.gz")
+ system "cd / && sudo /bin/tar xzfP #{restore_directory}/GS5/archives/recordings.tar.gz"
+ end
+
# Restore avatars
#
if File.exists?("#{restore_directory}/GS5/archives/avatars.tar.gz")
diff --git a/misc/freeswitch/scripts/common/call_forwarding.lua b/misc/freeswitch/scripts/common/call_forwarding.lua
index 192c694..3429dc9 100644
--- a/misc/freeswitch/scripts/common/call_forwarding.lua
+++ b/misc/freeswitch/scripts/common/call_forwarding.lua
@@ -16,6 +16,7 @@ function CallForwarding.new(self, arg, object)
self.database = arg.database;
self.record = arg.record;
self.domain = arg.domain;
+ self.parent = arg.parent;
return object;
end
@@ -92,11 +93,191 @@ function CallForwarding.list_by_owner(self, call_forwardable_id, call_forwardabl
end
-function CallForwarding.presence_set(self, presence_state)
+function CallForwarding.presence_set(self, presence_state, id)
+ id = id or self.record.id;
+
+ if not id or not presence_state then
+ return;
+ end
+
require 'dialplan.presence'
local presence = dialplan.presence.Presence:new();
- presence:init{log = self.log, accounts = { 'f-cftg-' .. tostring(self.record.id) }, domain = self.domain, uuid = 'call_forwarding_' .. tostring(self.record.id)};
+ presence:init{log = self.log, accounts = { 'f-cftg-' .. id }, domain = self.domain, uuid = 'call_forwarding_' .. id};
return presence:set(presence_state);
end
+
+
+function CallForwarding.service_id_by_name(self, service_name)
+ local service_id = nil;
+ sql_query = 'SELECT `id` FROM `call_forward_cases` WHERE `value` = ' .. self.database:escape(service_name, '"');
+ self.database:query(sql_query, function(record)
+ service_id = tonumber(record.id);
+ end);
+
+ return service_id;
+end
+
+
+function CallForwarding.camelize_type(self, account_type)
+ ACCOUNT_TYPES = {
+ sipaccount = 'SipAccount',
+ conference = 'Conference',
+ faxaccount = 'FaxAccount',
+ callthrough = 'Callthrough',
+ huntgroup = 'HuntGroup',
+ automaticcalldistributor = 'AutomaticCallDistributor',
+ }
+
+ return ACCOUNT_TYPES[account_type] or account_type;
+end
+
+function CallForwarding.call_forwarding_on(self, service, destination, destination_type, timeout, source)
+ require 'common.str'
+
+ if source then
+ sql_query = 'SELECT `id`, `destination`, `destinationable_type`, `destinationable_id`, `call_forward_case_id`, `position`, `timeout` FROM `call_forwards` \
+ WHERE `call_forwardable_id` = ' .. self.parent.id .. ' \
+ AND `call_forwardable_type` = "' .. self.parent.class .. '" \
+ AND `call_forward_case_id` IN (SELECT `id` FROM `call_forward_cases` WHERE `value` = "' .. service .. '") \
+ AND `source` = "' .. source .. '" ORDER BY `active` DESC LIMIT 1';
+ else
+ sql_query = 'SELECT `id`, `destination`, `destinationable_type`, `destinationable_id`, `call_forward_case_id`, `position`, `timeout` FROM `call_forwards` \
+ WHERE `call_forwardable_id` = ' .. self.parent.id .. ' \
+ AND `call_forwardable_type` = "' .. self.parent.class .. '" \
+ AND `call_forward_case_id` IN (SELECT `id` FROM `call_forward_cases` WHERE `value` = "' .. service .. '") \
+ AND (`source` = "" OR `source` IS NULL) ORDER BY `active` DESC LIMIT 1';
+ end
+
+ destination_type = destination_type or 'PhoneNumber';
+ local destination_id = nil;
+ destination = destination or '';
+ local service_id = nil;
+ local entry_id = nil;
+
+ self.database:query(sql_query, function(record)
+ entry_id = tonumber(record.id);
+ service_id = record.call_forward_case_id;
+ timeout = tonumber(timeout) or tonumber(record.timeout);
+ if common.str.blank(destination) then
+ if not common.str.blank(record.destinationable_type) then
+ destination_type = common.str.downcase(record.destinationable_type);
+ end
+ if not common.str.blank(record.destination) then
+ destination = record.destination;
+ end
+ destination_id = tonumber(record.destinationable_id);
+ end
+ end)
+
+ if service == 'noanswer' then
+ timeout = tonumber(timeout) or '30';
+ else
+ timeout = nil;
+ end
+
+ if destination == '' and not estination_id and destination_type:lower() ~= 'voicemail' then
+ self.log:notice('CALL_FORWARDING_ON ', service, ' - for: ', self.parent.class, '=', self.parent.id, '/', self.parent.uuid,' - destination not specified: ', destination_type, '=', destination_id);
+ return false;
+ end
+
+ if not tonumber(service_id) then
+ service_id = self:service_id_by_name(service);
+ end
+
+ local call_forwarding_record = {
+ id = entry_id,
+ active = true,
+ uuid = { 'UUID()', raw = true },
+ updated_at = { 'NOW()', raw = true },
+ created_at = { 'NOW()', raw = true },
+ call_forwardable_id = self.parent.id,
+ call_forwardable_type = self:camelize_type(self.parent.class),
+ call_forward_case_id = service_id,
+ destination = destination,
+ destinationable_type = self:camelize_type(destination_type),
+ destinationable_id = destination_id,
+ timeout = timeout,
+ position = 1,
+ };
+
+ local result = self.database:insert_or_update('call_forwards', call_forwarding_record, { created_at = false, position = false });
+
+ if not result then
+ self.log:notice('CALL_FORWARDING_ON ', service, ' - could not be activated for: ', self.parent.class, '=', self.parent.id, '/', self.parent.uuid,' - destination: ', destination_type, '=', destination_id, '|', destination);
+ return false;
+ end
+
+ entry_id = entry_id or self.database:last_insert_id();
+
+ self.log:info('CALL_FORWARDING_ON ', service, ' - callforwarding=', entry_id, ', for: ', self.parent.class, '=', self.parent.id, '/', self.parent.uuid, ', destination: ', destination_type, '=', destination_id, '|', destination, ', timeout: ', timeout);
+
+ if tonumber(entry_id) then
+ if destination_type:lower() == 'voicemail' then
+ self:presence_set('early', entry_id);
+ else
+ self:presence_set('confirmed', entry_id);
+ end
+ end
+
+ return result;
+end
+
+
+function CallForwarding.call_forwarding_off(self, service, source, delete)
+ local conditions = {}
+ table.insert(conditions, '`call_forwardable_id` = ' .. self.parent.id);
+ table.insert(conditions, '`call_forwardable_type` = "' .. self.parent.class .. '"');
+
+ if source then
+ table.insert(conditions, '`source` = "' .. source);
+ else
+ table.insert(conditions, '(`source` = "" OR `source` IS NULL)');
+ end
+
+ if service then
+ table.insert(conditions, '`call_forward_case_id` IN (SELECT `id` FROM `call_forward_cases` WHERE `value` = "' .. service .. '")');
+ end
+
+ local call_forwarding_ids = {}
+ local sql_query = 'SELECT `id` FROM `call_forwards` WHERE ' .. table.concat(conditions, ' AND ');
+ self.database:query(sql_query, function(record)
+ table.insert(call_forwarding_ids, record.id);
+ end)
+
+ -- set call forwarding entry inactive
+ local sql_query = 'UPDATE `call_forwards` SET `active` = FALSE, `updated_at` = NOW() WHERE ' .. table.concat(conditions, ' AND ');
+ local call_forwards = {};
+
+ -- or delete call forwarding entry
+ if delete then
+ sql_query = 'SELECT * FROM `call_forwards` WHERE ' .. table.concat(conditions, ' AND ');
+ self.database:query(sql_query, function(forwarding_entry)
+ table.insert(call_forwards, forwarding_entry)
+ end)
+ sql_query = 'DELETE FROM `call_forwards` WHERE ' .. table.concat(conditions, ' AND ');
+ end
+
+ if not self.database:query(sql_query) then
+ self.log:notice('CALL_FORWARDING_OFF ', (service or 'any'), ' - could not be deactivated for: ', self.parent.class, '=', self.parent.id, '/', self.parent.uuid);
+ return false;
+ end
+
+ if delete then
+ require 'common.sync_log'
+ local sync_log_class = common.sync_log.SyncLog:new{ log = self.log, database = self.database, homebase_ip_address = '' }
+
+ for index, call_forward in ipairs(call_forwards) do
+ sync_log_class:insert('CallForward', call_forward, 'destroy', nil);
+ end
+ end
+
+ for index, entry_id in ipairs(call_forwarding_ids) do
+ if tonumber(entry_id) then
+ self:presence_set('terminated', entry_id);
+ end
+ end
+
+ return true;
+end
diff --git a/misc/freeswitch/scripts/common/database.lua b/misc/freeswitch/scripts/common/database.lua
index 345f69d..8aed1ac 100644
--- a/misc/freeswitch/scripts/common/database.lua
+++ b/misc/freeswitch/scripts/common/database.lua
@@ -72,7 +72,7 @@ function Database.last_insert_id(self)
end
-function Database.insert_or_update(self, db_table, record, use_on_update)
+function Database.insert_or_update(self, db_table, record, ignore_on_update)
ignore_on_update = ignore_on_update or self.ignore_on_update;
local record_sql_create = {};
local record_sql_update = {};
diff --git a/misc/freeswitch/scripts/common/group.lua b/misc/freeswitch/scripts/common/group.lua
index c4125bc..b9cae61 100644
--- a/misc/freeswitch/scripts/common/group.lua
+++ b/misc/freeswitch/scripts/common/group.lua
@@ -86,3 +86,87 @@ function Group.name_id_by_member(self, member_id, member_type)
return group_names, group_ids;
end
+
+
+function Group.permission_targets(self, group_ids, permission)
+ if not group_ids or #group_ids == 0 or not permission then
+ return {};
+ end
+
+ local sql_query = 'SELECT DISTINCT `b`.`id`, `b`.`name` \
+ FROM `group_permissions` `a` \
+ JOIN `groups` `b` ON `b`.`id` = `a`.`target_group_id` \
+ WHERE `a`.`permission` = ' .. self.database:escape(permission, '"') .. ' \
+ AND `a`.`group_id` IN (' .. table.concat(group_ids, ',') .. ') \
+ AND `b`.`active` IS TRUE \
+ GROUP BY `a`.`target_group_id` LIMIT ' .. MAX_GROUP_MEMBERSHIPS;
+
+ local group_names = {};
+ local group_ids = {};
+
+ self.database:query(sql_query, function(account_entry)
+ table.insert(group_names, account_entry.name);
+ table.insert(group_ids, tonumber(account_entry.id));
+ end);
+
+ return group_names, group_ids;
+end
+
+
+function Group.is_target(self, group_id, permission)
+ if not group_id or not permission then
+ return nil;
+ end
+
+ local sql_query = 'SELECT `b`.`name` \
+ FROM `group_permissions` `a` \
+ JOIN `groups` `b` ON `b`.`id` = `a`.`target_group_id` \
+ WHERE `a`.`permission` = ' .. self.database:escape(permission, '"') .. ' \
+ AND `a`.`group_id` = ' .. tonumber(group_id) .. ' \
+ AND `b`.`active` IS TRUE \
+ LIMIT 1';
+
+ return self.database:query_return_value(sql_query);
+end
+
+
+function Group.union(self, ...)
+ local groups = {};
+ local group_sets = {...};
+ for set_index=1, #group_sets do
+ if type(group_sets[set_index]) == 'table' then
+ local group_ids = group_sets[set_index];
+ for index=1, #group_ids do
+ groups[tonumber(group_ids[index])] = true;
+ end
+ end
+ end
+
+ local group_ids = {};
+ for group_id, status in pairs(groups) do
+ table.insert(group_ids, group_id);
+ end
+
+ return group_ids;
+end
+
+
+function Group.intersection(self, set_one, set_two)
+ if not set_one or not set_two then
+ return {};
+ end
+
+ local basic_set = {};
+ for index=1, #set_one do
+ basic_set[set_one[index]] = true;
+ end
+
+ local final_set = {};
+ for index=1, #set_two do
+ if basic_set[set_two[index]] then
+ table.insert(final_set, set_two[index]);
+ end
+ end
+
+ return final_set;
+end
diff --git a/misc/freeswitch/scripts/common/log.lua b/misc/freeswitch/scripts/common/log.lua
index 5aff2b8..b7c8d09 100644
--- a/misc/freeswitch/scripts/common/log.lua
+++ b/misc/freeswitch/scripts/common/log.lua
@@ -37,33 +37,33 @@ function Log.message(self, log_level, message_arguments )
end
function Log.console(self, ...)
- self:message(self.level_console, arg);
+ self:message(self.level_console, {...});
end
function Log.alert(self, ...)
- self:message(self.level_alert, arg);
+ self:message(self.level_alert, {...});
end
function Log.critical(self, ...)
- self:message(self.level_critical, arg);
+ self:message(self.level_critical, {...});
end
function Log.error(self, ...)
- self:message(self.level_error, arg);
+ self:message(self.level_error, {...});
end
function Log.warning(self, ...)
- self:message(self.level_warning, arg);
+ self:message(self.level_warning, {...});
end
function Log.notice(self, ...)
- self:message(self.level_notice, arg);
+ self:message(self.level_notice, {...});
end
function Log.info(self, ...)
- self:message(self.level_info, arg);
+ self:message(self.level_info, {...});
end
function Log.debug(self, ...)
- self:message(self.level_debug, arg);
+ self:message(self.level_debug, {...});
end
diff --git a/misc/freeswitch/scripts/common/object.lua b/misc/freeswitch/scripts/common/object.lua
new file mode 100644
index 0000000..5183b9f
--- /dev/null
+++ b/misc/freeswitch/scripts/common/object.lua
@@ -0,0 +1,106 @@
+-- Gemeinschaft 5 module: object class
+-- (c) AMOOMA GmbH 2013
+--
+
+module(...,package.seeall)
+
+Object = {}
+
+-- create object object ;)
+function Object.new(self, arg)
+ arg = arg or {}
+ object = arg.object or {}
+ setmetatable(object, self);
+ self.__index = self;
+ self.class = 'object';
+ self.log = arg.log;
+ self.database = arg.database;
+ return object;
+end
+
+-- find object
+function Object.find(self, attributes)
+ if not attributes.class then
+ return nil;
+ end
+
+ local object = nil;
+
+ require 'common.str';
+ local class = common.str.downcase(attributes.class);
+
+ if class == 'user' then
+ require 'dialplan.user';
+ if tonumber(attributes.id) then
+ object = dialplan.user.User:new{ log = self.log, database = self.database }:find_by_id(attributes.id);
+ elseif not common.str.blank(attributes.uuid) then
+ object = dialplan.user.User:new{ log = self.log, database = self.database }:find_by_uuid(attributes.uuid);
+ end
+
+ if object then
+ object.user_groups = object:list_groups();
+ end
+ elseif class == 'tenant' then
+ require 'dialplan.tenant';
+ if tonumber(attributes.id) then
+ object = dialplan.tenant.Tenant:new{ log = self.log, database = self.database }:find_by_id(attributes.id);
+ elseif not common.str.blank(attributes.uuid) then
+ object = dialplan.tenant.Tenant:new{ log = self.log, database = self.database }:find_by_uuid(attributes.uuid);
+ end
+ elseif class == 'sipaccount' then
+ require 'common.sip_account';
+ if not common.str.blank(attributes.auth_name) then
+ object = common.sip_account.SipAccount:new{ log = self.log, database = self.database }:find_by_auth_name(attributes.auth_name, attributes.domain);
+ elseif tonumber(attributes.id) then
+ object = common.sip_account.SipAccount:new{ log = self.log, database = self.database }:find_by_id(attributes.id);
+ elseif not common.str.blank(attributes.uuid) then
+ object = common.sip_account.SipAccount:new{ log = self.log, database = self.database }:find_by_uuid(attributes.uuid);
+ end
+
+ if object then
+ object.owner = self:find{class = object.record.sip_accountable_type, id = tonumber(object.record.sip_accountable_id)};
+ end
+ elseif class == 'huntgroup' then
+ require 'dialplan.hunt_group';
+
+ if tonumber(attributes.id) then
+ object = dialplan.hunt_group.HuntGroup:new{ log = self.log, database = self.database }:find_by_id(attributes.id);
+ elseif not common.str.blank(attributes.uuid) then
+ object = dialplan.hunt_group.HuntGroup:new{ log = self.log, database = self.database }:find_by_uuid(attributes.uuid);
+ end
+
+ if object then
+ object.owner = self:find{class = 'tenant', id = tonumber(object.record.tenant_id)};
+ end
+ elseif class == 'automaticcalldistributor' then
+ require 'dialplan.acd';
+
+ if tonumber(attributes.id) then
+ object = dialplan.acd.AutomaticCallDistributor:new{ log = self.log, database = self.database, domain = self.domain }:find_by_id(attributes.id);
+ elseif not common.str.blank(attributes.uuid) then
+ object = dialplan.acd.AutomaticCallDistributor:new{ log = self.log, database = self.database, domain = self.domain }:find_by_uuid(attributes.uuid);
+ end
+
+ if object then
+ object.owner = self:find{class = object.record.automatic_call_distributorable_type, id = tonumber(object.record.automatic_call_distributorable_id)};
+ end
+ elseif class == 'faxaccount' then
+ require 'dialplan.fax';
+ if tonumber(attributes.id) then
+ fax_account = dialplan.fax.Fax:new{ log = self.log, database = self.database }:find_by_id(attributes.id);
+ elseif not common.str.blank(attributes.uuid) then
+ fax_account = dialplan.fax.Fax:new{ log = self.log, database = self.database }:find_by_uuid(attributes.uuid);
+ end
+
+ if object then
+ object.owner = self:find{class = fax_account.record.fax_accountable_type, id = tonumber(fax_account.record.fax_accountable_id)};
+ end
+ end
+
+ if object then
+ require 'common.group';
+ object.groups, object.group_ids = common.group.Group:new{ log = self.log, database = self.database }:name_id_by_member(object.id, object.class);
+ end
+
+ return object;
+end
diff --git a/misc/freeswitch/scripts/common/sip_account.lua b/misc/freeswitch/scripts/common/sip_account.lua
index 5b1ea56..6cc7d25 100644
--- a/misc/freeswitch/scripts/common/sip_account.lua
+++ b/misc/freeswitch/scripts/common/sip_account.lua
@@ -16,6 +16,7 @@ function SipAccount.new(self, arg)
self.log = arg.log;
self.database = arg.database;
self.record = arg.record;
+ self.domain = arg.domain;
return object;
end
@@ -128,15 +129,32 @@ function SipAccount.send_text(self, text)
end
-function SipAccount.call_state(self)
- local state = nil
- local sql_query = "SELECT `callstate` FROM `channels` \
- WHERE `name` LIKE (\"\%" .. self.record.auth_name .. "@%\") \
- OR `name` LIKE (\"\%" .. self.record.auth_name .. "@%\") LIMIT 1";
+function SipAccount.call_state(self)
+ local sql_query = 'SELECT `callstate` FROM `detailed_calls` \
+ WHERE `presence_id` LIKE "' .. self.record.auth_name .. '@%" \
+ OR `b_presence_id` LIKE "' .. self.record.auth_name .. '@%" \
+ LIMIT 1';
- self.database:query(sql_query, function(channel_entry)
- state = channel_entry.callstate;
- end)
+ return self.database:query_return_value(sql_query);
+end
+
+
+function SipAccount.call_forwarding_on(self, service, destination, destination_type, timeout, source)
+
+ if not self.call_forwarding then
+ require 'common.call_forwarding';
+ self.call_forwarding = common.call_forwarding.CallForwarding:new{ log = self.log, database = self.database, parent = self, domain = self.domain };
+ end
+
+ return self.call_forwarding:call_forwarding_on(service, destination, destination_type, timeout, source)
+end
+
+
+function SipAccount.call_forwarding_off(self, service, source, delete)
+ if not self.call_forwarding then
+ require 'common.call_forwarding';
+ self.call_forwarding = common.call_forwarding.CallForwarding:new{ log = self.log, database = self.database, parent = self, domain = self.domain };
+ end
- return state;
+ return self.call_forwarding:call_forwarding_off(service, source, delete)
end
diff --git a/misc/freeswitch/scripts/dialplan/dialplan.lua b/misc/freeswitch/scripts/dialplan/dialplan.lua
index 4425f8b..ffad4da 100644
--- a/misc/freeswitch/scripts/dialplan/dialplan.lua
+++ b/misc/freeswitch/scripts/dialplan/dialplan.lua
@@ -144,119 +144,24 @@ function Dialplan.auth_gateway(self)
end
-function Dialplan.object_find(self, class, identifier, auth_name)
- require 'common.str'
- class = common.str.downcase(class);
-
- require 'common.group';
- local group_class = common.group.Group:new{ log = self.log, database = self.database };
-
- if class == 'user' then
- require 'dialplan.user'
- local user = nil;
- if type(identifier) == 'number' then
- user = dialplan.user.User:new{ log = self.log, database = self.database }:find_by_id(identifier);
- else
- user = dialplan.user.User:new{ log = self.log, database = self.database }:find_by_uuid(identifier);
- end
-
- if user then
- user.user_groups = user:list_groups();
- user.groups = group_class:name_id_by_member(user.id, user.class);
- end
-
- return user;
- elseif class == 'tenant' then
- require 'dialplan.tenant'
- local tenant = nil;
- if type(identifier) == 'number' then
- tenant = dialplan.tenant.Tenant:new{ log = self.log, database = self.database }:find_by_id(identifier);
- else
- tenant = dialplan.tenant.Tenant:new{ log = self.log, database = self.database }:find_by_uuid(identifier);
- end
-
- if tenant then
- tenant.groups = group_class:name_id_by_member(tenant.id, tenant.class);
- end
-
- return tenant;
- elseif class == 'sipaccount' then
- require 'common.sip_account'
- local sip_account = nil;
- if auth_name then
- sip_account = common.sip_account.SipAccount:new{ log = self.log, database = self.database }:find_by_auth_name(auth_name, identifier);
- elseif type(identifier) == 'number' then
- sip_account = common.sip_account.SipAccount:new{ log = self.log, database = self.database }:find_by_id(identifier);
- else
- sip_account = common.sip_account.SipAccount:new{ log = self.log, database = self.database }:find_by_uuid(identifier);
- end
- if sip_account then
- sip_account.owner = self:object_find(sip_account.record.sip_accountable_type, tonumber(sip_account.record.sip_accountable_id));
- sip_account.groups = group_class:name_id_by_member(sip_account.id, sip_account.class);
- end
- return sip_account;
- elseif class == 'huntgroup' then
- require 'dialplan.hunt_group'
-
- local hunt_group = nil;
- if type(identifier) == 'number' then
- hunt_group = dialplan.hunt_group.HuntGroup:new{ log = self.log, database = self.database }:find_by_id(identifier);
- else
- hunt_group = dialplan.hunt_group.HuntGroup:new{ log = self.log, database = self.database }:find_by_uuid(identifier);
- end
-
- if hunt_group then
- hunt_group.owner = self:object_find('tenant', tonumber(hunt_group.record.tenant_id));
- hunt_group.groups = group_class:name_id_by_member(hunt_group.id, hunt_group.class);
- end
-
- return hunt_group;
- elseif class == 'automaticcalldistributor' then
- require 'dialplan.acd'
-
- local acd = nil;
- if type(identifier) == 'number' then
- acd = dialplan.acd.AutomaticCallDistributor:new{ log = self.log, database = self.database, domain = self.domain }:find_by_id(identifier);
- else
- acd = dialplan.acd.AutomaticCallDistributor:new{ log = self.log, database = self.database, domain = self.domain }:find_by_uuid(identifier);
- end
-
- if acd then
- acd.owner = self:object_find(acd.record.automatic_call_distributorable_type, tonumber(acd.record.automatic_call_distributorable_id));
- acd.groups = group_class:name_id_by_member(acd.id, acd.class);
- end
-
- return acd;
- elseif class == 'faxaccount' then
- require 'dialplan.fax'
- local fax_account = nil;
- if type(identifier) == 'number' then
- fax_account = dialplan.fax.Fax:new{ log = self.log, database = self.database }:find_by_id(identifier);
- else
- fax_account = dialplan.fax.Fax:new{ log = self.log, database = self.database }:find_by_uuid(identifier);
- end
- if fax_account then
- fax_account.owner = self:object_find(fax_account.record.fax_accountable_type, tonumber(fax_account.record.fax_accountable_id));
- fax_account.groups = group_class:name_id_by_member(fax_account.id, fax_account.class);
- end
-
- return fax_account;
- end
+function Dialplan.object_find(self, arguments)
+ require 'common.object';
+ return common.object.Object:new{ log = self.log, database = self.database}:find(arguments);
end
function Dialplan.retrieve_caller_data(self)
require 'common.str'
- self.caller.caller_phone_numbers_hash = {}
+ self.caller.caller_phone_numbers_hash = {};
-- TODO: Set auth_account on transfer initiated by calling party
if not common.str.blank(self.caller.dialed_sip_user) then
- self.caller.auth_account = self:object_find('sipaccount', self.caller.dialed_domain, self.caller.dialed_sip_user);
+ self.caller.auth_account = self:object_find{class = 'sipaccount', domain = self.caller.dialed_domain, auth_account = self.caller.dialed_sip_user};
if self.caller.set_auth_account then
self.caller:set_auth_account(self.caller.auth_account);
end
elseif not common.str.blank(self.caller.auth_account_type) and not common.str.blank(self.caller.auth_account_uuid) then
- self.caller.auth_account = self:object_find(self.caller.auth_account_type, self.caller.auth_account_uuid);
+ self.caller.auth_account = self:object_find{class = self.caller.auth_account_type, uuid = self.caller.auth_account_uuid};
if self.caller.set_auth_account then
self.caller:set_auth_account(self.caller.auth_account);
end
@@ -274,7 +179,7 @@ function Dialplan.retrieve_caller_data(self)
end
if not common.str.blank(self.caller.account_type) and not common.str.blank(self.caller.account_uuid) then
- self.caller.account = self:object_find(self.caller.account_type, self.caller.account_uuid);
+ self.caller.account = self:object_find{class = self.caller.account_type, uuid = self.caller.account_uuid};
if self.caller.account then
require 'common.phone_number'
self.caller.caller_phone_numbers = common.phone_number.PhoneNumber:new{ log = self.log, database = self.database }:list_by_owner(self.caller.account.id, self.caller.account.class);
@@ -329,6 +234,7 @@ function Dialplan.destination_new(self, arg)
destination.id = common.str.to_i(destination.phone_number.record.phone_numberable_id);
destination.uuid = common.str.to_s(destination.phone_number.record.phone_numberable_uuid);
destination.node_id = common.str.to_i(destination.phone_number.record.gs_node_id);
+ destination.account = self:object_find{ class = destination.type, id = destination.id};
if self.caller then
require 'common.call_forwarding';
local call_forwarding_class = common.call_forwarding.CallForwarding:new{ log = self.log, database = self.database }
@@ -388,7 +294,7 @@ function Dialplan.dial(self, destination)
if destination.node_local and destination.type == 'sipaccount' then
destination.pickup_groups = {};
- destination.account = self:object_find(destination.type, destination.id);
+ destination.account = self:object_find{class = destination.type, id = destination.id};
if destination.account then
if destination.account.class == 'sipaccount' then
destination.callee_id_name = destination.account.record.caller_name;
@@ -407,7 +313,7 @@ function Dialplan.dial(self, destination)
if destination.account.owner.class == 'user' then
user_id = destination.account.owner.id;
tenant_id = tonumber(destination.account.owner.record.current_tenant_id);
- local user = self:object_find(destination.account.owner.class, tonumber(user_id));
+ local user = self:object_find{class = destination.account.owner.class, id = tonumber(user_id)};
elseif destination.account.owner.class == 'tenant' then
tenant_id = destination.account.owner.id;
end
@@ -417,22 +323,21 @@ function Dialplan.dial(self, destination)
if not self.caller.clir then
if user_id or tenant_id then
require 'common.str'
- local phone_book_entry = nil;
if self.phonebook_number_lookup then
require 'dialplan.phone_book'
- phone_book_entry = dialplan.phone_book.PhoneBook:new{ log = self.log, database = self.database }:find_entry_by_number_user_tenant(self.caller.caller_phone_numbers, user_id, tenant_id);
+ self.caller.phone_book_entry = dialplan.phone_book.PhoneBook:new{ log = self.log, database = self.database }:find_entry_by_number_user_tenant(self.caller.caller_phone_numbers, user_id, tenant_id);
end
- if phone_book_entry then
- self.log:info('PHONE_BOOK_ENTRY - phone_book=', phone_book_entry.phone_book_id, ' (', phone_book_entry.phone_book_name, '), caller_id_name: ', phone_book_entry.caller_id_name, ', ringtone: ', phone_book_entry.bellcore_id);
- destination.caller_id_name = common.str.to_ascii(phone_book_entry.caller_id_name);
- if tonumber(phone_book_entry.bellcore_id) then
- self.log:debug('RINGTONE - phonebookentry, index: ', phone_book_entry.bellcore_id);
- self.caller:export_variable('alert_info', 'http://amooma.de;info=Ringer' .. phone_book_entry.bellcore_id .. ';x-line-id=0');
+ if self.caller.phone_book_entry then
+ self.log:info('PHONE_BOOK_ENTRY - phone_book=', self.caller.phone_book_entry.phone_book_id, ' (', self.caller.phone_book_entry.phone_book_name, '), caller_id_name: ', self.caller.phone_book_entry.caller_id_name, ', ringtone: ', self.caller.phone_book_entry.bellcore_id);
+ destination.caller_id_name = common.str.to_ascii(self.caller.phone_book_entry.caller_id_name);
+ if tonumber(self.caller.phone_book_entry.bellcore_id) then
+ self.log:debug('RINGTONE - phonebookentry=', self.caller.phone_book_entry.id, ', ringtone: ', self.caller.phone_book_entry.bellcore_id);
+ self.caller:export_variable('alert_info', 'http://amooma.de;info=Ringer' .. self.caller.phone_book_entry.bellcore_id .. ';x-line-id=0');
end
- if phone_book_entry.image then
- self:set_caller_picture(phone_book_entry.id, 'phonebookentry', phone_book_entry.image);
+ if self.caller.phone_book_entry.image then
+ self:set_caller_picture(self.caller.phone_book_entry.id, 'phonebookentry', self.caller.phone_book_entry.image);
elseif self.caller.account and self.caller.account.owner then
self:set_caller_picture(self.caller.account.owner.id, self.caller.account.owner.class);
end
@@ -483,7 +388,7 @@ end
function Dialplan.huntgroup(self, destination)
- local hunt_group = self:object_find('huntgroup', tonumber(destination.id));
+ local hunt_group = self:object_find{class = 'huntgroup', id = tonumber(destination.id)};
if not hunt_group then
self.log:error('DIALPLAN_HUNTGROUP - huntgroup not found');
@@ -514,7 +419,7 @@ end
function Dialplan.acd(self, destination)
- local acd = self:object_find('automaticcalldistributor', tonumber(destination.id));
+ local acd = self:object_find{class = 'automaticcalldistributor', id = tonumber(destination.id)};
if not acd then
self.log:error('DIALPLAN_ACD - acd not found');
@@ -623,7 +528,7 @@ function Dialplan.callthrough(self, destination)
end
if type(authorization) == 'table' and tonumber(authorization.sip_account_id) and tonumber(authorization.sip_account_id) > 0 then
- local auth_account = self:object_find('sipaccount', tonumber(authorization.sip_account_id));
+ local auth_account = self:object_find{class = 'sipaccount', id = tonumber(authorization.sip_account_id)};
self.caller.forwarding_number = destination.number;
self.caller.forwarding_service = 'callthrough';
self.caller:set_variable('gs_forwarding_service', self.caller.forwarding_service);
@@ -699,7 +604,7 @@ end
function Dialplan.dialplanfunction(self, destination)
require 'dialplan.functions'
- return dialplan.functions.Functions:new{ log = self.log, database = self.database, domain = self.domain }:dialplan_function(self.caller, destination.number);
+ return dialplan.functions.Functions:new{ log = self.log, database = self.database, domain = self.domain, parent = self }:dialplan_function(self.caller, destination.number);
end
@@ -744,10 +649,17 @@ function Dialplan.switch(self, destination)
self.caller:export_variable('alert_info', self.default_ringtone);
if destination.phone_number then
- local ringtone = destination.phone_number:ringtone();
- if ringtone and ringtone.bellcore_id then
- self.log:debug('RINGTONE - ', ringtone.ringtoneable_type .. ', index: ' .. ringtone.bellcore_id);
- self.caller:export_variable('alert_info', 'http://amooma.de;info=Ringer' .. tonumber(ringtone.bellcore_id) .. ';x-line-id=0');
+ destination.ringtone = destination.phone_number:ringtone();
+ end
+
+ if not destination.ringtone and destination.account and destination.account.ringtone then
+ destination.ringtone = destination.account:ringtone();
+ end
+
+ if destination.ringtone then
+ if destination.ringtone.bellcore_id then
+ self.log:debug('DESTINATION_RINGTONE - ', destination.ringtone.ringtoneable_type .. '=', destination.ringtone.ringtoneable_id, ', ringtone: ' .. destination.ringtone.bellcore_id);
+ self.caller:export_variable('alert_info', 'http://amooma.de;info=Ringer' .. tonumber(destination.ringtone.bellcore_id) .. ';x-line-id=0');
end
end
@@ -821,10 +733,10 @@ function Dialplan.switch(self, destination)
if user_id or tenant_id then
require 'dialplan.phone_book'
- local phone_book_entry = dialplan.phone_book.PhoneBook:new{ log = self.log, database = self.database }:find_entry_by_number_user_tenant({ destination.number }, user_id, tenant_id);
- if phone_book_entry then
- self.log:info('PHONE_BOOK_ENTRY - phone_book=', phone_book_entry.phone_book_id, ' (', phone_book_entry.phone_book_name, '), callee_id_name: ', common.str.to_ascii(phone_book_entry.caller_id_name));
- destination.callee_id_name = common.str.to_ascii(phone_book_entry.caller_id_name);
+ self.caller.callee_phone_book_entry = dialplan.phone_book.PhoneBook:new{ log = self.log, database = self.database }:find_entry_by_number_user_tenant({ destination.number }, user_id, tenant_id);
+ if self.caller.callee_phone_book_entry then
+ self.log:info('PHONE_BOOK_ENTRY - phone_book=', self.caller.callee_phone_book_entry.phone_book_id, ' (', self.caller.callee_phone_book_entry.phone_book_name, '), callee_id_name: ', common.str.to_ascii(self.caller.callee_phone_book_entry.caller_id_name));
+ destination.callee_id_name = common.str.to_ascii(self.caller.callee_phone_book_entry.caller_id_name);
end
end
end
@@ -1005,7 +917,7 @@ function Dialplan.run(self, destination)
', destination: ', result.call_forwarding.type, '=', result.call_forwarding.id,
', number: ', result.call_forwarding.number);
- local auth_account = self:object_find(destination.type, destination.id);
+ local auth_account = self:object_find{class = destination.type, id = destination.id};
self.caller.forwarding_number = destination.number;
self.caller.forwarding_service = result.call_forwarding.service;
self.caller:set_variable('gs_forwarding_service', self.caller.forwarding_service);
diff --git a/misc/freeswitch/scripts/dialplan/functions.lua b/misc/freeswitch/scripts/dialplan/functions.lua
index 3706872..780e3be 100644
--- a/misc/freeswitch/scripts/dialplan/functions.lua
+++ b/misc/freeswitch/scripts/dialplan/functions.lua
@@ -37,6 +37,8 @@ function Functions.dialplan_function(self, caller, dialed_number)
result = self:transfer_all(caller, parameters[3]);
elseif fid == "ia" then
result = self:intercept_any_number(caller, parameters[3]);
+ elseif fid == "ig" then
+ result = self:group_pickup(caller, parameters[3]);
elseif fid == "anc" then
result = self:account_node_change(caller);
elseif fid == "li" then
@@ -159,12 +161,27 @@ function Functions.intercept_any_number(self, caller, destination_number)
return { continue = false, code = 404, phrase = 'Number not found', no_cdr = true };
end
- if not phone_number.record.phone_numberable_type:lower() == 'sipaccount' or not tonumber(phone_number.record.phone_numberable_id) then
- self.log:notice('FUNCTION_INTERCEPT_ANY_NUMBER - destination: ', phone_number.record.phone_numberable_type:lower(), '=', phone_number.record.phone_numberable_id, ', number: ', destination_number);
- return { continue = false, code = 505, phrase = 'Incompatible destination', no_cdr = true };
+ require 'common.object';
+ local phone_numberable = common.object.Object:new{ log = self.log, database = self.database}:find{class = phone_number.record.phone_numberable_type, id = phone_number.record.phone_numberable_id};
+
+ if not phone_numberable then
+ self.log:notice('FUNCTION_INTERCEPT_ANY_NUMBER - numberable not found: ', dphone_number.record.phone_numberable_type, '=', phone_number.record.phone_numberable_id);
+ return { continue = false, code = 404, phrase = 'Destination not found', no_cdr = true };
+ end
+
+ require 'common.str';
+ require 'common.group';
+ local group_class = common.group.Group:new{ log = self.log, database = self.database };
+ local group_ids = group_class:union(common.str.try(caller, 'auth_account.group_ids'), common.str.try(caller, 'auth_account.owner.group_ids'));
+ local target_groups, target_group_ids = group_class:permission_targets(group_ids, 'pickup');
+ local destination_group_ids = group_class:union(common.str.try(phone_numberable, 'group_ids'), common.str.try(phone_numberable, 'owner.group_ids'));
+
+ if #group_class:intersection(destination_group_ids, target_group_ids) == 0 then
+ self.log:notice('FUNCTION_INTERCEPT_ANY_NUMBER - Groups not found or insufficient permissions');
+ return { continue = false, code = 402, phrase = '"Insufficient permissions', no_cdr = true };
end
- self.log:info('FUNCTION_INTERCEPT_ANY_NUMBER intercepting call - to: ', phone_number.record.phone_numberable_type:lower(), '=', phone_number.record.phone_numberable_id, ', number: ', destination_number);
+ self.log:info('FUNCTION_INTERCEPT_ANY_NUMBER intercepting call - to: ', phone_numberable.class, '=',phone_numberable.id, '|', destination_number);
caller:set_variable('gs_pickup_group_pick', 's' .. phone_number.record.phone_numberable_id);
caller:execute('pickup', 's' .. phone_number.record.phone_numberable_id);
@@ -173,6 +190,31 @@ function Functions.intercept_any_number(self, caller, destination_number)
end
+function Functions.group_pickup(self, caller, group_id)
+ if not tonumber(group_id) then
+ return { continue = false, code = 505, phrase = 'Incompatible destination', no_cdr = true };
+ end
+
+ require 'common.str';
+ require 'common.group';
+ local group_class = common.group.Group:new{ log = self.log, database = self.database };
+ local group_ids = group_class:union(common.str.try(caller, 'auth_account.group_ids'), common.str.try(caller, 'auth_account.owner.group_ids'));
+ local target_group = group_class:is_target(group_id, 'pickup');
+
+ if not target_group then
+ self.log:notice('FUNCTION_GROUP_PICKUP - group=', group_id, ' not found or insufficient permissions');
+ return { continue = false, code = 402, phrase = '"Insufficient permissions', no_cdr = true };
+ end
+
+ self.log:notice('FUNCTION_GROUP_PICKUP - group=', group_id, '|', target_group);
+
+ caller:set_variable('gs_pickup_group_pick', 'g' .. group_id);
+ caller:execute('pickup', 'g' .. group_id);
+
+ return { continue = false, code = 200, phrase = 'OK', no_cdr = true }
+end
+
+
function Functions.account_node_change(self, caller)
self.log:info('NODE_CHANGE - caller: ', caller.account_type, '/', caller.account_uuid, ', caller_id: ', caller.caller_id_number);
@@ -618,32 +660,17 @@ function Functions.clip_off(self, caller)
end
function Functions.call_forwarding_off(self, caller, call_forwarding_service, delete)
- local defaults = {log = self.log, database = self.database, domain = caller.domain}
-
-- Find caller's SipAccount
local caller_sip_account = self:ensure_caller_sip_account(caller);
if not caller_sip_account then
return { continue = false, code = 403, phrase = 'Incompatible caller', no_cdr = true }
end
- require 'common.phone_number'
- local phone_number_class = common.phone_number.PhoneNumber:new{ log = self.log, database = self.database, domain = caller.domain };
- local phone_numbers = phone_number_class:list_by_owner(caller_sip_account.record.id, 'SipAccount');
+ caller_sip_account.domain = caller_sip_account.domain or caller.domain;
- local success = false;
- for index, phone_number in pairs(phone_numbers) do
- phone_number_object = phone_number_class:find_by_number(phone_number);
- if phone_number_object then
- if phone_number_object:call_forwarding_off(call_forwarding_service, nil, delete) then
- success = true;
- end
- end
- end
-
- if not success then
- self.log:notice("call forwarding could not be deactivated");
+ if not caller_sip_account:call_forwarding_off(call_forwarding_service, nil, delete) then
+ self.log:notice('FUNCTION_CALL_FORWARDING_OFF - call forwarding could not be deactivated');
return { continue = false, code = 500, phrase = 'Call Forwarding could not be deactivated', no_cdr = true }
-
end
caller:answer();
@@ -654,10 +681,8 @@ end
function Functions.call_forwarding_on(self, caller, call_forwarding_service, destination, destination_type, timeout)
- local defaults = {log = self.log, database = self.database, domain = caller.domain}
-
if not call_forwarding_service then
- self.log:notice('no call forwarding service specified');
+ self.log:notice('FUNCTION_CALL_FORWARDING_ON - no call forwarding service specified');
end
-- Find caller's SipAccount
@@ -666,24 +691,11 @@ function Functions.call_forwarding_on(self, caller, call_forwarding_service, des
return { continue = false, code = 403, phrase = 'Incompatible caller', no_cdr = true }
end
- require "common.phone_number"
- local phone_number_class = common.phone_number.PhoneNumber:new{ log = self.log, database = self.database, domain = caller.domain };
- local phone_numbers = phone_number_class:list_by_owner(caller_sip_account.record.id, 'SipAccount');
+ caller_sip_account.domain = caller_sip_account.domain or caller.domain;
- local success = false;
- for index, phone_number in pairs(phone_numbers) do
- phone_number_object = phone_number_class:find_by_number(phone_number);
- if phone_number_object then
- if phone_number_object:call_forwarding_on(call_forwarding_service, destination, timeout) then
- success = true;
- end
- end
- end
-
- if not success then
- self.log:notice("call forwarding could not be activated");
+ if not caller_sip_account:call_forwarding_on(call_forwarding_service, destination, destination_type, timeout) then
+ self.log:notice('FUNCTION_CALL_FORWARDING_ON - call forwarding could not be activated');
return { continue = false, code = 500, phrase = 'Call Forwarding could not be activated', no_cdr = true }
-
end
caller:answer();
diff --git a/misc/freeswitch/scripts/dialplan/router.lua b/misc/freeswitch/scripts/dialplan/router.lua
index bda80a7..8473c2b 100644
--- a/misc/freeswitch/scripts/dialplan/router.lua
+++ b/misc/freeswitch/scripts/dialplan/router.lua
@@ -8,6 +8,7 @@ Router = {}
-- create route object
function Router.new(self, arg)
+ require 'common.str';
arg = arg or {}
object = arg.object or {}
setmetatable(object, self);
diff --git a/misc/freeswitch/scripts/dialplan_default.lua b/misc/freeswitch/scripts/dialplan_default.lua
index 8fb9057..2b651c5 100644
--- a/misc/freeswitch/scripts/dialplan_default.lua
+++ b/misc/freeswitch/scripts/dialplan_default.lua
@@ -8,7 +8,7 @@ function hangup_hook_caller(s, status, arg)
if tostring(status) == 'transfer' then
if start_caller and start_caller.destination then
log:info('CALL_TRANSFERRED - destination was: ', start_caller.destination.type, '=', start_caller.destination.id,', number: ' .. tostring(start_caller.destination.number) .. ', to: ' .. start_caller:to_s('sip_refer_to'));
- start_caller.auth_account = start_caller.dialplan:object_find(start_caller.destination.type, start_caller.destination.id);
+ start_caller.auth_account = start_caller.dialplan:object_find{class = start_caller.destination.type, id = start_caller.destination.id};
start_caller.forwarding_number = start_caller.destination.number;
start_caller.forwarding_service = 'transfer';
end