From 3ba444ee09abceac73a0507130035a4bf099ffc4 Mon Sep 17 00:00:00 2001 From: Peter Kozak Date: Thu, 28 Feb 2013 03:13:31 -0500 Subject: update fax tiff file --- app/controllers/trigger_controller.rb | 1 - 1 file changed, 1 deletion(-) diff --git a/app/controllers/trigger_controller.rb b/app/controllers/trigger_controller.rb index 64a5f91..6cc9fa7 100644 --- a/app/controllers/trigger_controller.rb +++ b/app/controllers/trigger_controller.rb @@ -89,7 +89,6 @@ class TriggerController < ApplicationController 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 -- cgit v1.2.3 From 3a0f9f2736ec6a253e632b5671dfd669ffe99173 Mon Sep 17 00:00:00 2001 From: Peter Kozak Date: Thu, 28 Feb 2013 03:13:57 -0500 Subject: fax documents index view --- app/views/fax_documents/_index_core.html.haml | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) 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 ? '⇨' : '⇦'}".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 -- cgit v1.2.3 From 137e3a9bdff7954fc14a5abe866ab38cd08b04fb Mon Sep 17 00:00:00 2001 From: Peter Kozak Date: Thu, 28 Feb 2013 03:15:53 -0500 Subject: translations --- config/locales/navigation.en.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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' -- cgit v1.2.3 From 9511b56c4a06a17ac68b4fc053a6217e0273a132 Mon Sep 17 00:00:00 2001 From: Peter Kozak Date: Thu, 28 Feb 2013 04:39:53 -0500 Subject: preserve ringtones and phone_book_entries in dialplan --- misc/freeswitch/scripts/dialplan/dialplan.lua | 43 ++++++++++++++++----------- 1 file changed, 25 insertions(+), 18 deletions(-) diff --git a/misc/freeswitch/scripts/dialplan/dialplan.lua b/misc/freeswitch/scripts/dialplan/dialplan.lua index 4425f8b..99b551c 100644 --- a/misc/freeswitch/scripts/dialplan/dialplan.lua +++ b/misc/freeswitch/scripts/dialplan/dialplan.lua @@ -329,6 +329,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(destination.type, 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 } @@ -417,22 +418,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 @@ -744,10 +744,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 +828,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 -- cgit v1.2.3 From 1353b9c0563da02f1b17e54d802f28221cdce982 Mon Sep 17 00:00:00 2001 From: Peter Kozak Date: Thu, 28 Feb 2013 09:02:19 -0500 Subject: breadcrumbs --- app/controllers/calls_controller.rb | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) 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 -- cgit v1.2.3 From 6238abea422a1be14d5f3d8cbacd78f2e72fd466 Mon Sep 17 00:00:00 2001 From: Peter Kozak Date: Thu, 28 Feb 2013 09:09:10 -0500 Subject: group defaults --- app/controllers/groups_controller.rb | 2 +- app/models/group.rb | 3 +++ app/views/groups/_form_core.html.haml | 2 +- 3 files changed, 5 insertions(+), 2 deletions(-) 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/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/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') -- cgit v1.2.3 From e1c2ef6e5d2d48eab026f788d93e6c170d276194 Mon Sep 17 00:00:00 2001 From: Peter Kozak Date: Thu, 28 Feb 2013 09:38:07 -0500 Subject: phone book entry view --- app/views/phone_book_entries/show.html.haml | 27 +++++++++++++++++++------- config/locales/views/phone_book_entries/de.yml | 2 +- config/locales/views/phone_book_entries/en.yml | 2 +- 3 files changed, 22 insertions(+), 9 deletions(-) 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/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' -- cgit v1.2.3 From 24fbc181d0f767103b4062be4482af92feb5ffd5 Mon Sep 17 00:00:00 2001 From: spag Date: Thu, 28 Feb 2013 22:37:11 +0100 Subject: call forwarding entry scope extended --- app/models/call_forward.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 -- cgit v1.2.3 From 290befe401fb068b6a18d6d62b0184b6b5449bb5 Mon Sep 17 00:00:00 2001 From: spag Date: Fri, 1 Mar 2013 07:29:54 +0100 Subject: arg depreciated in lua 5.2 --- misc/freeswitch/scripts/common/log.lua | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) 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 -- cgit v1.2.3 From f9675ecb2a7415ecb8e1f5cc7abcc0dd75dac7f6 Mon Sep 17 00:00:00 2001 From: spag Date: Fri, 1 Mar 2013 07:31:05 +0100 Subject: ensure router loads common.str --- misc/freeswitch/scripts/dialplan/router.lua | 1 + 1 file changed, 1 insertion(+) 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); -- cgit v1.2.3 From 351fdd558c7a14b2a9fd7992ade8adebe71f4688 Mon Sep 17 00:00:00 2001 From: spag Date: Fri, 1 Mar 2013 07:38:50 +0100 Subject: f-ig dialplan function added --- misc/freeswitch/scripts/dialplan/functions.lua | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/misc/freeswitch/scripts/dialplan/functions.lua b/misc/freeswitch/scripts/dialplan/functions.lua index 3706872..e3a8675 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 @@ -173,6 +175,18 @@ 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 + + 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); -- cgit v1.2.3 From 0bb03f2159503613d21f09e5b7fc90fb1252828a Mon Sep 17 00:00:00 2001 From: Peter Kozak Date: Fri, 1 Mar 2013 04:04:37 -0500 Subject: ignore_on_update table fixed --- misc/freeswitch/scripts/common/database.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 = {}; -- cgit v1.2.3 From b8884e1b15ee25486ed33b7455e5a9a783b136f9 Mon Sep 17 00:00:00 2001 From: Peter Kozak Date: Fri, 1 Mar 2013 05:23:01 -0500 Subject: set call forwarding in call forwarding class --- misc/freeswitch/scripts/common/call_forwarding.lua | 185 ++++++++++++++++++++- 1 file changed, 183 insertions(+), 2 deletions(-) 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 -- cgit v1.2.3 From 6de79d3edf6dfc0212b417751151bd6c5ab35740 Mon Sep 17 00:00:00 2001 From: Peter Kozak Date: Fri, 1 Mar 2013 05:23:45 -0500 Subject: pass call forwarding to CallForwarding class --- misc/freeswitch/scripts/common/sip_account.lua | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/misc/freeswitch/scripts/common/sip_account.lua b/misc/freeswitch/scripts/common/sip_account.lua index 5b1ea56..90fa379 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 @@ -140,3 +141,24 @@ function SipAccount.call_state(self) return state; 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 self.call_forwarding:call_forwarding_off(service, source, delete) +end -- cgit v1.2.3 From ff57c349adcada4392386fc2820f7e0a0fc974aa Mon Sep 17 00:00:00 2001 From: Peter Kozak Date: Fri, 1 Mar 2013 05:24:40 -0500 Subject: set call forwarding for sip_account instead of phone_number --- misc/freeswitch/scripts/dialplan/functions.lua | 44 ++++---------------------- 1 file changed, 7 insertions(+), 37 deletions(-) diff --git a/misc/freeswitch/scripts/dialplan/functions.lua b/misc/freeswitch/scripts/dialplan/functions.lua index e3a8675..0d15b86 100644 --- a/misc/freeswitch/scripts/dialplan/functions.lua +++ b/misc/freeswitch/scripts/dialplan/functions.lua @@ -632,32 +632,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(); @@ -668,10 +653,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 @@ -680,24 +663,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(); -- cgit v1.2.3 From ecf2b91a0b0538b60fb708a237e10af77afe33dc Mon Sep 17 00:00:00 2001 From: Peter Kozak Date: Sat, 2 Mar 2013 02:44:34 -0500 Subject: call waiting fixed --- misc/freeswitch/scripts/common/sip_account.lua | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/misc/freeswitch/scripts/common/sip_account.lua b/misc/freeswitch/scripts/common/sip_account.lua index 90fa379..6cc7d25 100644 --- a/misc/freeswitch/scripts/common/sip_account.lua +++ b/misc/freeswitch/scripts/common/sip_account.lua @@ -129,17 +129,13 @@ 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"; - - self.database:query(sql_query, function(channel_entry) - state = channel_entry.callstate; - end) +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'; - return state; + return self.database:query_return_value(sql_query); end -- cgit v1.2.3 From 6ed538ee9385245a7bbac838dd5b796bba2ea0c6 Mon Sep 17 00:00:00 2001 From: Peter Kozak Date: Sat, 2 Mar 2013 03:38:16 -0500 Subject: use imagemagick when ghostscript fails --- app/models/fax_document.rb | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) 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,8 +96,17 @@ 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 -- cgit v1.2.3 From b8425f5453eab4a0fe475952af89d55ace45878e Mon Sep 17 00:00:00 2001 From: Peter Kozak Date: Sun, 3 Mar 2013 04:03:24 -0500 Subject: firewall restart after intruder changes --- app/controllers/intruders_controller.rb | 3 +- app/models/intruder.rb | 86 ++++++++++++++++++++++++------- app/views/intruders/_form_core.html.haml | 4 +- app/views/intruders/_index_core.html.haml | 12 +---- app/views/intruders/index.html.haml | 9 ++-- 5 files changed, 79 insertions(+), 35 deletions(-) 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/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/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..b9c5a76 100644 --- a/app/views/intruders/_index_core.html.haml +++ b/app/views/intruders/_index_core.html.haml @@ -2,11 +2,8 @@ %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') @@ -19,21 +16,16 @@ %td - if intruder.list_type == 'whitelist' %i.icon-ok - - elsif intruder.bans > 0 + - elsif intruder.bans.to_i > 0 %i.icon-fire - - elsif intruder.points > 0 + - elsif intruder.points.to_i > 0 %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} -- cgit v1.2.3 From 7ec2f96979317912b464b801731c5d10be538e6d Mon Sep 17 00:00:00 2001 From: Peter Kozak Date: Mon, 4 Mar 2013 02:25:17 -0500 Subject: missing url fixed --- app/controllers/conference_invitees_controller.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 -- cgit v1.2.3 From 295ca363ad12150b7a029075e915574afd61c82e Mon Sep 17 00:00:00 2001 From: Peter Kozak Date: Mon, 4 Mar 2013 02:39:21 -0500 Subject: call_forwards controler fixed --- app/controllers/call_forwards_controller.rb | 48 ++++++++++++++++------------- 1 file changed, 27 insertions(+), 21 deletions(-) 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? -- cgit v1.2.3 From d15047f9965803ba021eba226241c43d133930cb Mon Sep 17 00:00:00 2001 From: Peter Kozak Date: Mon, 4 Mar 2013 03:31:46 -0500 Subject: permission_targets method added --- misc/freeswitch/scripts/common/group.lua | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/misc/freeswitch/scripts/common/group.lua b/misc/freeswitch/scripts/common/group.lua index c4125bc..5bd866e 100644 --- a/misc/freeswitch/scripts/common/group.lua +++ b/misc/freeswitch/scripts/common/group.lua @@ -86,3 +86,26 @@ 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 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 groups = {}; + + self.database:query(sql_query, function(account_entry) + groups[account_entry.id] = account_entry.name; + end); + + return groups; +end -- cgit v1.2.3 From f19afefdda27a9661702d872c56b5d862e50452d Mon Sep 17 00:00:00 2001 From: Peter Kozak Date: Mon, 4 Mar 2013 03:32:03 -0500 Subject: combine method added --- misc/freeswitch/scripts/common/group.lua | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/misc/freeswitch/scripts/common/group.lua b/misc/freeswitch/scripts/common/group.lua index 5bd866e..ac2f542 100644 --- a/misc/freeswitch/scripts/common/group.lua +++ b/misc/freeswitch/scripts/common/group.lua @@ -109,3 +109,24 @@ function Group.permission_targets(self, group_ids, permission) return groups; end + + +function Group.combine(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 -- cgit v1.2.3 From 017198093547d5ff67a6ebfbb745b8fd09992c87 Mon Sep 17 00:00:00 2001 From: Peter Kozak Date: Mon, 4 Mar 2013 03:32:37 -0500 Subject: save group ids --- misc/freeswitch/scripts/dialplan/dialplan.lua | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/misc/freeswitch/scripts/dialplan/dialplan.lua b/misc/freeswitch/scripts/dialplan/dialplan.lua index 99b551c..2e15124 100644 --- a/misc/freeswitch/scripts/dialplan/dialplan.lua +++ b/misc/freeswitch/scripts/dialplan/dialplan.lua @@ -162,7 +162,7 @@ function Dialplan.object_find(self, class, identifier, auth_name) if user then user.user_groups = user:list_groups(); - user.groups = group_class:name_id_by_member(user.id, user.class); + user.groups, user.group_ids = group_class:name_id_by_member(user.id, user.class); end return user; @@ -176,7 +176,7 @@ function Dialplan.object_find(self, class, identifier, auth_name) end if tenant then - tenant.groups = group_class:name_id_by_member(tenant.id, tenant.class); + tenant.groups, tenant.group_ids = group_class:name_id_by_member(tenant.id, tenant.class); end return tenant; @@ -192,7 +192,7 @@ function Dialplan.object_find(self, class, identifier, auth_name) 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); + sip_account.groups, sip_account.group_ids = group_class:name_id_by_member(sip_account.id, sip_account.class); end return sip_account; elseif class == 'huntgroup' then @@ -207,7 +207,7 @@ function Dialplan.object_find(self, class, identifier, auth_name) 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); + hunt_group.groups, hunt_group.group_ids = group_class:name_id_by_member(hunt_group.id, hunt_group.class); end return hunt_group; @@ -223,7 +223,7 @@ function Dialplan.object_find(self, class, identifier, auth_name) 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); + acd.groups, acd.group_ids = group_class:name_id_by_member(acd.id, acd.class); end return acd; @@ -237,7 +237,7 @@ function Dialplan.object_find(self, class, identifier, auth_name) 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); + fax_account.groups, fax_account.group_ids = group_class:name_id_by_member(fax_account.id, fax_account.class); end return fax_account; -- cgit v1.2.3 From 79797464f29913b18a6591cfbc2cac5b86b30777 Mon Sep 17 00:00:00 2001 From: Peter Kozak Date: Mon, 4 Mar 2013 03:33:25 -0500 Subject: pickup group dialplan function honors permissions --- misc/freeswitch/scripts/dialplan/functions.lua | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/misc/freeswitch/scripts/dialplan/functions.lua b/misc/freeswitch/scripts/dialplan/functions.lua index 0d15b86..e9f9962 100644 --- a/misc/freeswitch/scripts/dialplan/functions.lua +++ b/misc/freeswitch/scripts/dialplan/functions.lua @@ -179,7 +179,20 @@ 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:combine(common.str.try(caller, 'auth_account.group_ids'), common.str.try(caller, 'auth_account.owner.group_ids')); + local target_groups = group_class:permission_targets(group_ids, 'pickup'); + + if not target_groups[group_id] then + self.log:notice('FUNCTION_GROUP_PICKUP - group=', group_id, ' not found or insufficient permissions'); + return { continue = false, code = 401, phrase = '"Insufficient permissions', no_cdr = true }; + end + + self.log:notice('FUNCTION_GROUP_PICKUP - group=', group_id, '|', target_groups[group_id]); + caller:set_variable('gs_pickup_group_pick', 'g' .. group_id); caller:execute('pickup', 'g' .. group_id); -- cgit v1.2.3 From 92b79f7f1f43a9c95fdbb9df2a85b08eefb6c8d8 Mon Sep 17 00:00:00 2001 From: Peter Kozak Date: Mon, 4 Mar 2013 05:27:18 -0500 Subject: presence permission type added --- app/models/group_permission.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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" -- cgit v1.2.3 From 86e4f6f2241fee9597d7c1a7de1ff585634da4c5 Mon Sep 17 00:00:00 2001 From: Peter Kozak Date: Mon, 4 Mar 2013 05:28:26 -0500 Subject: display group item --- app/views/group_memberships/_index_core.html.haml | 3 ++- app/views/group_memberships/show.html.haml | 4 ++++ 2 files changed, 6 insertions(+), 1 deletion(-) 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 } -- cgit v1.2.3 From 716a7dc8e7838fe397b6d9ca2a52f6d8b2ff52a9 Mon Sep 17 00:00:00 2001 From: Peter Kozak Date: Mon, 4 Mar 2013 05:29:45 -0500 Subject: list permissions and memberships in group index --- app/views/groups/_index_core.html.haml | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) 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} -- cgit v1.2.3 From 8042e6c314737feab61209e0b8b26ddba5c7e763 Mon Sep 17 00:00:00 2001 From: Peter Kozak Date: Mon, 4 Mar 2013 05:34:43 -0500 Subject: display provisioning key activity flag --- app/views/phones/_form_core.html.haml | 2 +- app/views/phones/show.html.haml | 11 +++++------ 2 files changed, 6 insertions(+), 7 deletions(-) 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 -- cgit v1.2.3 From aaffa89ef9aef6ac30e3304d735a8c58f4bdaaef Mon Sep 17 00:00:00 2001 From: Stefan Wintermeyer Date: Mon, 4 Mar 2013 11:54:19 +0100 Subject: rake backup:now starts a new backup. --- lib/tasks/backup.rake | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/lib/tasks/backup.rake b/lib/tasks/backup.rake index 55369b6..8f56015 100644 --- a/lib/tasks/backup.rake +++ b/lib/tasks/backup.rake @@ -4,6 +4,12 @@ namespace :backup do # This would be the daily backup. end + desc "Do a backup. Now!" + task :now => :environment do + backup_job = BackupJob.create + 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. -- cgit v1.2.3 From 46e3a768b175a80ae54e6b97b8cf6c4146718134 Mon Sep 17 00:00:00 2001 From: Stefan Wintermeyer Date: Mon, 4 Mar 2013 11:56:03 +0100 Subject: rake db:queue_a_new_backup (better name) --- lib/tasks/backup.rake | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/tasks/backup.rake b/lib/tasks/backup.rake index 8f56015..f08bb39 100644 --- a/lib/tasks/backup.rake +++ b/lib/tasks/backup.rake @@ -4,8 +4,8 @@ namespace :backup do # This would be the daily backup. end - desc "Do a backup. Now!" - task :now => :environment do + desc "Do a backup." + task :queue_a_new_backup => :environment do backup_job = BackupJob.create echo "BackupJob ID: #{backup_job.id}" end -- cgit v1.2.3 From 5b0c099cebaad0465380458d09aeeec904ae6691 Mon Sep 17 00:00:00 2001 From: Stefan Wintermeyer Date: Mon, 4 Mar 2013 12:04:00 +0100 Subject: rake db:force_now (does a backup without queuing). --- app/models/backup_job.rb | 9 +++++++-- lib/tasks/backup.rake | 6 ++++++ 2 files changed, 13 insertions(+), 2 deletions(-) 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/lib/tasks/backup.rake b/lib/tasks/backup.rake index f08bb39..51fd2f2 100644 --- a/lib/tasks/backup.rake +++ b/lib/tasks/backup.rake @@ -10,6 +10,12 @@ namespace :backup do 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. -- cgit v1.2.3 From 27a7c93ba8b96e4d2422296dce6922d4ae6bb3de Mon Sep 17 00:00:00 2001 From: Stefan Wintermeyer Date: Mon, 4 Mar 2013 12:43:52 +0100 Subject: Added db/schema.rb --- .gitignore | 2 ++ 1 file changed, 2 insertions(+) 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 -- cgit v1.2.3 From fd030bcb2824d93108867f13ac3f4dcb4a63e204 Mon Sep 17 00:00:00 2001 From: Stefan Wintermeyer Date: Mon, 4 Mar 2013 12:44:02 +0100 Subject: ... --- db/schema.rb | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/db/schema.rb b/db/schema.rb index 60bc7f5..1895257 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -150,16 +150,15 @@ ActiveRecord::Schema.define(:version => 20130225160423) do 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" + t.string "destinationable_type" + t.integer "destinationable_id" 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" -- cgit v1.2.3 From 6e388bedb33a07373675625a90a859bc8cf2c688 Mon Sep 17 00:00:00 2001 From: Stefan Wintermeyer Date: Mon, 4 Mar 2013 12:44:30 +0100 Subject: delete --- db/schema.rb | 1175 ---------------------------------------------------------- 1 file changed, 1175 deletions(-) delete mode 100644 db/schema.rb diff --git a/db/schema.rb b/db/schema.rb deleted file mode 100644 index 1895257..0000000 --- a/db/schema.rb +++ /dev/null @@ -1,1175 +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 "depth" - t.string "call_forwardable_type" - t.integer "call_forwardable_id" - t.integer "position" - t.string "uuid" - t.string "destinationable_type" - t.integer "destinationable_id" - end - - 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 -- cgit v1.2.3 From 78a0ef0fce768c3743d66d5856c95c0595aadfaf Mon Sep 17 00:00:00 2001 From: Peter Kozak Date: Mon, 4 Mar 2013 07:45:04 -0500 Subject: object loader class added --- misc/freeswitch/scripts/common/object.lua | 106 ++++++++++++++++++++++++++++++ 1 file changed, 106 insertions(+) create mode 100644 misc/freeswitch/scripts/common/object.lua 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 -- cgit v1.2.3 From b0118a229516766c22ee8268c182c91c3c15b1cd Mon Sep 17 00:00:00 2001 From: Peter Kozak Date: Mon, 4 Mar 2013 07:46:03 -0500 Subject: object loader class vs. dialplan method --- misc/freeswitch/scripts/dialplan/dialplan.lua | 125 ++++---------------------- misc/freeswitch/scripts/dialplan_default.lua | 2 +- 2 files changed, 16 insertions(+), 111 deletions(-) diff --git a/misc/freeswitch/scripts/dialplan/dialplan.lua b/misc/freeswitch/scripts/dialplan/dialplan.lua index 2e15124..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, user.group_ids = 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, tenant.group_ids = 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, sip_account.group_ids = 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, hunt_group.group_ids = 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, acd.group_ids = 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, fax_account.group_ids = 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,7 +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(destination.type, destination.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 } @@ -389,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; @@ -408,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 @@ -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 @@ -1012,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_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 -- cgit v1.2.3 From edb0e6cae9d39610739da9bf9c428468d9a53617 Mon Sep 17 00:00:00 2001 From: Peter Kozak Date: Mon, 4 Mar 2013 07:46:45 -0500 Subject: set theory --- misc/freeswitch/scripts/common/group.lua | 46 ++++++++++++++++++++++++++++---- 1 file changed, 41 insertions(+), 5 deletions(-) diff --git a/misc/freeswitch/scripts/common/group.lua b/misc/freeswitch/scripts/common/group.lua index ac2f542..db56129 100644 --- a/misc/freeswitch/scripts/common/group.lua +++ b/misc/freeswitch/scripts/common/group.lua @@ -87,6 +87,7 @@ 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 not permission then return {}; @@ -100,18 +101,36 @@ function Group.permission_targets(self, group_ids, permission) AND `b`.`active` IS TRUE \ GROUP BY `a`.`target_group_id` LIMIT ' .. MAX_GROUP_MEMBERSHIPS; - - local groups = {}; + local group_names = {}; + local group_ids = {}; self.database:query(sql_query, function(account_entry) - groups[account_entry.id] = account_entry.name; + table.insert(group_names, account_entry.name); + table.insert(group_ids, tonumber(account_entry.id)); end); - return groups; + 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.combine(self, ...) +function Group.union(self, ...) local groups = {}; local group_sets = {...}; for set_index=1, #group_sets do @@ -130,3 +149,20 @@ function Group.combine(self, ...) return group_ids; end + + +function Group.intersection(self, set_one, set_two) + 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 -- cgit v1.2.3 From 14facb5c1f50ae9edd0ac842001ab8e7afa52b21 Mon Sep 17 00:00:00 2001 From: Peter Kozak Date: Mon, 4 Mar 2013 07:47:32 -0500 Subject: call pickup authorization added --- misc/freeswitch/scripts/dialplan/functions.lua | 33 +++++++++++++++++++------- 1 file changed, 24 insertions(+), 9 deletions(-) diff --git a/misc/freeswitch/scripts/dialplan/functions.lua b/misc/freeswitch/scripts/dialplan/functions.lua index e9f9962..780e3be 100644 --- a/misc/freeswitch/scripts/dialplan/functions.lua +++ b/misc/freeswitch/scripts/dialplan/functions.lua @@ -161,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); @@ -183,15 +198,15 @@ function Functions.group_pickup(self, caller, group_id) require 'common.str'; require 'common.group'; local group_class = common.group.Group:new{ log = self.log, database = self.database }; - local group_ids = group_class:combine(common.str.try(caller, 'auth_account.group_ids'), common.str.try(caller, 'auth_account.owner.group_ids')); - local target_groups = group_class:permission_targets(group_ids, 'pickup'); + 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_groups[group_id] then + if not target_group then self.log:notice('FUNCTION_GROUP_PICKUP - group=', group_id, ' not found or insufficient permissions'); - return { continue = false, code = 401, phrase = '"Insufficient permissions', no_cdr = true }; + return { continue = false, code = 402, phrase = '"Insufficient permissions', no_cdr = true }; end - self.log:notice('FUNCTION_GROUP_PICKUP - group=', group_id, '|', target_groups[group_id]); + 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); -- cgit v1.2.3 From 39cfd26ddb2ac6b27932f82a486f04130bc3a646 Mon Sep 17 00:00:00 2001 From: Peter Kozak Date: Mon, 4 Mar 2013 08:00:40 -0500 Subject: group_ids can be empty --- misc/freeswitch/scripts/common/group.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/misc/freeswitch/scripts/common/group.lua b/misc/freeswitch/scripts/common/group.lua index db56129..1763e69 100644 --- a/misc/freeswitch/scripts/common/group.lua +++ b/misc/freeswitch/scripts/common/group.lua @@ -89,7 +89,7 @@ end function Group.permission_targets(self, group_ids, permission) - if not group_ids or not permission then + if not group_ids or #group_ids == 0 or not permission then return {}; end -- cgit v1.2.3 From c5ab74f9adb52228ef6583353b89d855f0dc4a3a Mon Sep 17 00:00:00 2001 From: Peter Kozak Date: Mon, 4 Mar 2013 08:02:50 -0500 Subject: sets can be nil --- misc/freeswitch/scripts/common/group.lua | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/misc/freeswitch/scripts/common/group.lua b/misc/freeswitch/scripts/common/group.lua index 1763e69..b9cae61 100644 --- a/misc/freeswitch/scripts/common/group.lua +++ b/misc/freeswitch/scripts/common/group.lua @@ -152,6 +152,10 @@ 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; -- cgit v1.2.3 From 45fe4f5022f7181aa5d6e66f03ba3c8cf281879a Mon Sep 17 00:00:00 2001 From: Peter Kozak Date: Mon, 4 Mar 2013 10:41:59 -0500 Subject: sort gs_parameters by entity+section --- app/controllers/gs_parameters_controller.rb | 12 ++++++-- app/views/gs_parameters/index.html.haml | 48 +++++++++++++++++++++++------ app/views/gs_parameters/show.html.haml | 10 ++++-- 3 files changed, 56 insertions(+), 14 deletions(-) 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/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 @@ -3,16 +3,22 @@ - cache(@gs_parameter) do %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') + ":" %td = @gs_parameter.section + %tr + %td + %strong= t('gs_parameters.show.name') + ":" + %td + = @gs_parameter.name %tr %td %strong= t('gs_parameters.show.value') + ":" -- cgit v1.2.3 From ef4bb3de4a23e0a4068c46caf05e2150e9922b71 Mon Sep 17 00:00:00 2001 From: Peter Kozak Date: Tue, 5 Mar 2013 01:44:21 -0500 Subject: display last missed call on idle screen --- app/views/config_polycom/idle_screen.xml.haml | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) 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}" -- cgit v1.2.3 From 2f2276dc424196ace5d1859dfa3d3999926effce Mon Sep 17 00:00:00 2001 From: Peter Kozak Date: Tue, 5 Mar 2013 01:45:31 -0500 Subject: bypassing softkeys controller --- app/controllers/softkeys_controller.rb | 8 ++----- app/models/softkey.rb | 37 ++++++++++++++------------------- app/views/softkeys/_form_core.html.haml | 4 ++-- 3 files changed, 20 insertions(+), 29 deletions(-) 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/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/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') -- cgit v1.2.3 From fbbbb9dfe10ad8b25d075e00f4a149086b7c27a5 Mon Sep 17 00:00:00 2001 From: spag Date: Tue, 5 Mar 2013 08:30:52 +0100 Subject: send fax notification --- app/controllers/trigger_controller.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/app/controllers/trigger_controller.rb b/app/controllers/trigger_controller.rb index 6cc9fa7..8e70ef2 100644 --- a/app/controllers/trigger_controller.rb +++ b/app/controllers/trigger_controller.rb @@ -84,6 +84,7 @@ class TriggerController < ApplicationController fax_document.state = 'successful' if fax_document.save + Notifications.new_fax(fax_document).deliver begin File.delete(pdf_file) rescue => e -- cgit v1.2.3 From 75362f4b48f02fc28ac45762bfb6b28a06d38b72 Mon Sep 17 00:00:00 2001 From: Stefan Wintermeyer Date: Tue, 5 Mar 2013 09:42:12 +0100 Subject: Fixed the backup. --- config/backup.rb | 20 ++------------------ 1 file changed, 2 insertions(+), 18 deletions(-) diff --git a/config/backup.rb b/config/backup.rb index 88edd94..0cb6a32 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 @@ -81,4 +65,4 @@ Backup::Model.new(:GS5, 'GS5 backup') do # Gzip [Compressor] # compress_with Gzip -end \ No newline at end of file +end -- cgit v1.2.3 From 260264886fd136b388ad4adaaa93e264d7da87ba Mon Sep 17 00:00:00 2001 From: Stefan Wintermeyer Date: Tue, 5 Mar 2013 09:53:59 +0100 Subject: Fixed a caching issue. #221 --- app/views/tenants/_table_of_automatic_call_distributors.html.haml | 2 +- app/views/tenants/_table_of_hunt_groups.html.haml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) 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 ) -- cgit v1.2.3 From 00db10565a2b1906728087eeb95542214720fb23 Mon Sep 17 00:00:00 2001 From: spag Date: Tue, 5 Mar 2013 10:01:27 +0100 Subject: colors added --- app/views/intruders/_index_core.html.haml | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/app/views/intruders/_index_core.html.haml b/app/views/intruders/_index_core.html.haml index b9c5a76..1fca601 100644 --- a/app/views/intruders/_index_core.html.haml +++ b/app/views/intruders/_index_core.html.haml @@ -9,16 +9,25 @@ %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.to_i > 0 + - elsif entry_class == 'error' %i.icon-fire - - elsif intruder.points.to_i > 0 + - elsif entry_class == 'warn' %i.icon-warning-sign %td= intruder.contact_ip -- cgit v1.2.3 From a865b1f9506b900ed8643c01d94c86268e907720 Mon Sep 17 00:00:00 2001 From: Stefan Wintermeyer Date: Tue, 5 Mar 2013 17:30:45 +0100 Subject: Added voicemails and recordings to the backup/restore. #195 --- config/backup.rb | 9 +++++++++ lib/tasks/backup.rake | 6 ++++++ 2 files changed, 15 insertions(+) diff --git a/config/backup.rb b/config/backup.rb index 0cb6a32..2c2984b 100644 --- a/config/backup.rb +++ b/config/backup.rb @@ -45,6 +45,15 @@ Backup::Model.new(:GS5, 'GS5 backup') do end end + ## + # Voicemails + # + if File.exists?('/var/opt/gemeinschaft/freeswitch/recordings') + archive :recordings do |archive| + archive.add '/var/opt/gemeinschaft/freeswitch/recordings' + end + end + ## # Avatars # diff --git a/lib/tasks/backup.rake b/lib/tasks/backup.rake index 51fd2f2..ad4d41d 100644 --- a/lib/tasks/backup.rake +++ b/lib/tasks/backup.rake @@ -41,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") -- cgit v1.2.3 From ee959b78ebfdd5cce50f2e2935e62ebba96ae3c4 Mon Sep 17 00:00:00 2001 From: "Mario \"Kuroir\" Ricalde" Date: Tue, 5 Mar 2013 11:23:06 -0600 Subject: Fixes #191 --- app/assets/stylesheets/gemeinschaft-generic.css.scss | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/app/assets/stylesheets/gemeinschaft-generic.css.scss b/app/assets/stylesheets/gemeinschaft-generic.css.scss index 9448b84..515a5fe 100644 --- a/app/assets/stylesheets/gemeinschaft-generic.css.scss +++ b/app/assets/stylesheets/gemeinschaft-generic.css.scss @@ -32,6 +32,7 @@ input, textarea, .uneditable-input { width: 96%; } } + input, textarea { &.invalid { box-shadow: inset -9px 0px 0px rgb(255, 219, 219), inset -14px 0px 0px rgb(255, 245, 245) !important; @@ -46,7 +47,13 @@ select { @media (max-width: 480px) { width: 99.5%; } +} +.form-horizontal { + input + .help-block, select + .help-block, textarea + .help-block { + font-size: 11px; + margin-top: 1px; + } } @media (max-width: 979px) { -- cgit v1.2.3 From 134150c4f6b1f0a50c837e00a3c2bbe186dfb14e Mon Sep 17 00:00:00 2001 From: Peter Kozak Date: Wed, 6 Mar 2013 03:01:28 -0500 Subject: show sim_cards in user view depending on existence and ability --- app/views/users/show.html.haml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/app/views/users/show.html.haml b/app/views/users/show.html.haml index 8148005..ea90ab4 100644 --- a/app/views/users/show.html.haml +++ b/app/views/users/show.html.haml @@ -75,10 +75,11 @@ - cache(['user_show_phones_overview', I18n.locale, @user, @user.phones]) do = render :partial => 'phones', :locals => {:user => @user} - - if GsParameter.get('SIM_CARDS') == true + - if GsParameter.get('SIM_CARDS') == true && (@user.sim_cards.count > 0 || can?( :create, SimCard )) - cache(['user_show_sim_cards_overview', I18n.locale, @user, @user.sim_cards]) do %h2=t('sim_cards.index.page_title') - = render :partial => 'sim_cards/index_core', :locals => {:parent => SimCardProvider.first, :sim_cards => @user.sim_cards} + - if @user.sim_cards.count > 0 + = render :partial => 'sim_cards/index_core', :locals => {:parent => SimCardProvider.first, :sim_cards => @user.sim_cards} = render :partial => 'shared/create_link', :locals => {:parent => SimCardProvider.first, :child_class => SimCard} - cache(['user_show_fax_accounts_overview', I18n.locale, @user, @user.fax_accounts]) do -- cgit v1.2.3 From 860b346781a5c7508ad0158d26f34454be810860 Mon Sep 17 00:00:00 2001 From: Peter Kozak Date: Wed, 6 Mar 2013 03:44:43 -0500 Subject: ringtone and call_forward abilities fixed --- app/models/ability.rb | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/app/models/ability.rb b/app/models/ability.rb index 48cce84..3cd1d4d 100644 --- a/app/models/ability.rb +++ b/app/models/ability.rb @@ -134,9 +134,6 @@ class Ability can :read, SipAccount, :sip_accountable_type => 'User', :sip_accountable_id => user.id user.sip_accounts.each do |sip_account| can :read, PhoneNumber, :id => sip_account.phone_number_ids - can :manage, CallForward, :call_forwardable_id => sip_account.phone_number_ids - can :manage, Ringtone, :ringtoneable_type => 'PhoneNumber', :ringtoneable_id => sip_account.phone_number_ids - can :manage, Ringtone, :ringtoneable_type => 'SipAccount', :ringtoneable_id => sip_account.id can [:read, :destroy, :call] , CallHistory, :id => sip_account.call_history_ids end can :read, Phone, :phoneable_type => 'User', :phoneable_id => user.id @@ -161,10 +158,17 @@ class Ability can :manage, ConferenceInvitee, :conference_id => conference.id end - # User can manage CallForwards of the PhoneNumbers of his - # own SipAccounts: + # User can manage CallForwards of its SipAccount and PhoneNumbers # - can :manage, CallForward, :call_forwardable_id => user.phone_number_ids + can :manage, CallForward, :call_forwardable_type => 'PhoneNumber', :call_forwardable_id => user.phone_number_ids + can :manage, CallForward, :call_forwardable_type => 'SipAccount', :call_forwardable_id => user.sip_account_ids + can :create, CallForward + + # User can manage Ringtones of its SipAccount and PhoneNumbers + # + can :manage, Ringtone, :ringtoneable_type => 'PhoneNumber', :ringtoneable_id => user.phone_number_ids + can :manage, Ringtone, :ringtoneable_type => 'SipAccount', :ringtoneable_id => user.sip_account_ids + can :create, Ringtone # SoftkeyFunctions # -- cgit v1.2.3 From 8c11f5ae917a0f81b4bcf604c76b3967430ba111 Mon Sep 17 00:00:00 2001 From: Peter Kozak Date: Wed, 6 Mar 2013 06:37:44 -0500 Subject: retrieving fax objects fixed --- misc/freeswitch/scripts/common/object.lua | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/misc/freeswitch/scripts/common/object.lua b/misc/freeswitch/scripts/common/object.lua index 5183b9f..8c195e5 100644 --- a/misc/freeswitch/scripts/common/object.lua +++ b/misc/freeswitch/scripts/common/object.lua @@ -87,13 +87,13 @@ function Object.find(self, attributes) 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); + object = 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); + object = 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)}; + object.owner = self:find{class = object.record.fax_accountable_type, id = tonumber(object.record.fax_accountable_id)}; end end -- cgit v1.2.3 From a710d0d8033c84b72e1a6395adfbd6beebf80730 Mon Sep 17 00:00:00 2001 From: Peter Kozak Date: Wed, 6 Mar 2013 06:38:08 -0500 Subject: collect errors --- app/controllers/trigger_controller.rb | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/app/controllers/trigger_controller.rb b/app/controllers/trigger_controller.rb index 8e70ef2..5e836c4 100644 --- a/app/controllers/trigger_controller.rb +++ b/app/controllers/trigger_controller.rb @@ -62,12 +62,14 @@ class TriggerController < ApplicationController def fax if !params[:fax_account_id].blank? fax_account = FaxAccount.where(:id => params[:fax_account_id].to_i).first + errors = Array.new() if fax_account fax_account.fax_documents.where(:state => 'received').each do |fax_document| pdf_file = fax_document.tiff_to_pdf if !pdf_file + errors << "#{fax_document.tiff} cound not be converted" fax_document.state = 'unsuccessful' fax_document.save next @@ -89,15 +91,21 @@ class TriggerController < ApplicationController File.delete(pdf_file) rescue => e logger.error "PDF fax file could not be deleted: #{pdf_file} => #{e.inspect}" + errors << "#{pdf_file} cound not be deleted" end fax_document.save fax_document.render_thumbnails else + errors << "#{fax_document.id} cound not be saved" fax_document.state = 'unsuccessful' fax_document.save end end - + else + errors << "fax_account=#{params[:fax_account_id]} not found" + end + + if errors.count == 0 render( :status => 200, :layout => false, @@ -105,11 +113,11 @@ class TriggerController < ApplicationController :text => "", ) else - render( - :status => 404, + render( + :status => 501, :layout => false, :content_type => 'text/plain', - :text => "", + :text => "", ) end end -- cgit v1.2.3 From 287e9d8fe964b0b0449732597f1f5ef5057cf4b3 Mon Sep 17 00:00:00 2001 From: Peter Kozak Date: Wed, 6 Mar 2013 06:39:15 -0500 Subject: Abort on conversion errors --- app/controllers/fax_documents_controller.rb | 10 ++++++++-- config/locales/views/fax_documents/de.yml | 1 + config/locales/views/fax_documents/en.yml | 1 + 3 files changed, 10 insertions(+), 2 deletions(-) diff --git a/app/controllers/fax_documents_controller.rb b/app/controllers/fax_documents_controller.rb index c2b3083..43852c6 100644 --- a/app/controllers/fax_documents_controller.rb +++ b/app/controllers/fax_documents_controller.rb @@ -61,8 +61,14 @@ class FaxDocumentsController < ApplicationController @fax_document = @fax_account.fax_documents.build(params[:fax_document]) @fax_document.retry_counter = @fax_account.retries if @fax_document.save - @fax_document.queue_for_sending! - redirect_to fax_account_fax_document_path(@fax_document.fax_account, @fax_document), :notice => t('fax_documents.controller.successfuly_created') + if @fax_document.tiff.blank? + @fax_document.destroy + @fax_document.errors.add(:document, t('fax_documents.controller.tiff_not_created')) + render :new + else + @fax_document.queue_for_sending! + redirect_to fax_account_fax_document_path(@fax_document.fax_account, @fax_document), :notice => t('fax_documents.controller.successfuly_created') + end else render :new end diff --git a/config/locales/views/fax_documents/de.yml b/config/locales/views/fax_documents/de.yml index da59833..236c031 100644 --- a/config/locales/views/fax_documents/de.yml +++ b/config/locales/views/fax_documents/de.yml @@ -5,6 +5,7 @@ de: successfuly_created: 'Eine neues Fax-Dokument wurde erstellt.' successfuly_updated: 'Das Fax-Dokument wurde aktualisiert.' successfuly_destroyed: 'Das Fax-Dokument wurde gelöscht.' + tiff_not_created: 'Konnte nicht konvertiert werden.' states: queued_for_sending: 'In der Warteschleife zum Versand' sending: 'Wird aktuell versendet' diff --git a/config/locales/views/fax_documents/en.yml b/config/locales/views/fax_documents/en.yml index ff5f8f8..0606e81 100644 --- a/config/locales/views/fax_documents/en.yml +++ b/config/locales/views/fax_documents/en.yml @@ -5,6 +5,7 @@ en: successfuly_created: 'Successfully created fax.' successfuly_updated: 'Successfully updated fax.' successfuly_destroyed: 'Successfully destroyed fax.' + tiff_not_created: 'Could not be converted.' states: queued_for_sending: 'Queued for sending' sending: 'Currently sending' -- cgit v1.2.3 From 3c3f90f4b43a41187dd65af3fe08e0409b30b68a Mon Sep 17 00:00:00 2001 From: Peter Kozak Date: Wed, 6 Mar 2013 09:12:05 -0500 Subject: tenant can have groups --- app/models/tenant.rb | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/app/models/tenant.rb b/app/models/tenant.rb index 0622f52..ffa68a7 100644 --- a/app/models/tenant.rb +++ b/app/models/tenant.rb @@ -59,6 +59,10 @@ class Tenant < ActiveRecord::Base has_many :users_fax_accounts, :through => :users, :source => :fax_accounts, :readonly => true has_many :users_fax_accounts_phone_numbers, :through => :users_fax_accounts, :source => :phone_numbers, :readonly => true + # Groups + has_many :group_memberships, :as => :item, :dependent => :destroy, :uniq => true + has_many :groups, :through => :group_memberships + # Validations: # validates_presence_of :name, :state, :country, :language -- cgit v1.2.3 From 5ebafb77ecbfdb2cb22a6d3acdd4a9b56dca8ad0 Mon Sep 17 00:00:00 2001 From: Peter Kozak Date: Wed, 6 Mar 2013 09:12:51 -0500 Subject: group methods added --- app/models/group.rb | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/app/models/group.rb b/app/models/group.rb index c459530..993d274 100644 --- a/app/models/group.rb +++ b/app/models/group.rb @@ -11,4 +11,17 @@ class Group < ActiveRecord::Base def to_s self.name end + + def permission_targets(permission) + group_permissions.where(:permission => permission).pluck(:target_group_id) + end + + def self.union(sets=[]) + group_ids = [] + sets.each do |set| + group_ids = group_ids + set + end + + return group_ids.uniq + end end -- cgit v1.2.3 From bc3f8ae65689046f2b41123c7b392c4718d48dfd Mon Sep 17 00:00:00 2001 From: Peter Kozak Date: Wed, 6 Mar 2013 09:13:17 -0500 Subject: target_sip_accounts_by_permission method added --- app/models/sip_account.rb | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/app/models/sip_account.rb b/app/models/sip_account.rb index 5660e37..1499d62 100644 --- a/app/models/sip_account.rb +++ b/app/models/sip_account.rb @@ -156,6 +156,24 @@ class SipAccount < ActiveRecord::Base end + def target_sip_accounts_by_permission(permission) + target_groups = Group.union(self.groups.collect{|g| g.permission_targets(permission)}) + target_groups = target_groups + Group.union(self.sip_accountable.groups.collect{|g| g.permission_targets(permission)}) + sip_accounts = [] + GroupMembership.where(:group_id => target_groups).each do |group_membership| + if group_membership.item.class == User || group_membership.item.class == Tenant + sip_accounts = sip_accounts + group_membership.item.sip_accounts + elsif group_membership.item.class == SipAccount + sip_accounts << group_membership.item + end + + sip_accounts = sip_accounts.uniq + end + + return sip_accounts + end + + private def save_value_of_to_s -- cgit v1.2.3 From c98072557273ff4383013f73621061ece34fc6d2 Mon Sep 17 00:00:00 2001 From: Peter Kozak Date: Thu, 7 Mar 2013 02:36:38 -0500 Subject: call model table changed --- app/models/call.rb | 2 +- app/models/sip_account.rb | 2 +- app/views/calls/_form_core.html.haml | 2 +- app/views/calls/_index_core.html.haml | 10 +++---- db/migrate/20130307065200_create_calls_active.rb | 38 ++++++++++++++++++++++++ 5 files changed, 46 insertions(+), 8 deletions(-) create mode 100644 db/migrate/20130307065200_create_calls_active.rb diff --git a/app/models/call.rb b/app/models/call.rb index db6d9d6..b0cd9b2 100644 --- a/app/models/call.rb +++ b/app/models/call.rb @@ -1,5 +1,5 @@ class Call < ActiveRecord::Base - self.table_name = 'detailed_calls' + self.table_name = 'calls_active' self.primary_key = 'uuid' attr_writer :sip_account_id diff --git a/app/models/sip_account.rb b/app/models/sip_account.rb index 1499d62..81b9c1c 100644 --- a/app/models/sip_account.rb +++ b/app/models/sip_account.rb @@ -38,7 +38,7 @@ class SipAccount < ActiveRecord::Base has_many :ringtones, :as => :ringtoneable, :dependent => :destroy - has_many :calls, :finder_sql => lambda { |s| "SELECT DISTINCT detailed_calls.* FROM detailed_calls WHERE presence_id LIKE '#{self.auth_name}@%' OR b_presence_id LIKE '#{self.auth_name}@%'" } + has_many :calls, :finder_sql => lambda { |s| "SELECT DISTINCT calls_active.* FROM calls_active WHERE sip_account_id = #{self.id} OR b_sip_account_id = #{self.id}" } # Delegations: # diff --git a/app/views/calls/_form_core.html.haml b/app/views/calls/_form_core.html.haml index 4cdd55e..ec795f2 100644 --- a/app/views/calls/_form_core.html.haml +++ b/app/views/calls/_form_core.html.haml @@ -1,2 +1,2 @@ .inputs - = f.input :dest, :as => :string, :label => t('calls.form.destination.label'), :hint => conditional_hint('calls.form.destination.hint'), :autofocus => true + = f.input :destination, :as => :string, :label => t('calls.form.destination.label'), :hint => conditional_hint('calls.form.destination.hint'), :autofocus => true diff --git a/app/views/calls/_index_core.html.haml b/app/views/calls/_index_core.html.haml index e5b769e..5ed5538 100644 --- a/app/views/calls/_index_core.html.haml +++ b/app/views/calls/_index_core.html.haml @@ -19,17 +19,17 @@ - else %i.icon-arrow-right %td - = call.created + = l Time.at(call.start_stamp), :format => :short %td - = call.dest + = call.destination %td - = "#{call.cid_name} #{call.cid_num}" + = "#{call.caller_id_name} #{call.caller_id_number}" %td - = "#{call.callee_name} #{call.callee_num}" + = "#{call.callee_name} #{call.callee_number}" %td = call.callstate %td - = "#{call.read_codec}/#{call.write_codec}" + = "#{call.read_codec}/#{call.read_rate}:#{call.write_codec}/#{call.write_rate}" %td %p diff --git a/db/migrate/20130307065200_create_calls_active.rb b/db/migrate/20130307065200_create_calls_active.rb new file mode 100644 index 0000000..930bbc7 --- /dev/null +++ b/db/migrate/20130307065200_create_calls_active.rb @@ -0,0 +1,38 @@ +class CreateCallsActive < ActiveRecord::Migration + def self.up + execute %q{CREATE VIEW calls_active AS SELECT + a.uuid AS uuid, + a.direction AS direction, + a.created_epoch AS start_stamp, + a.cid_name AS caller_id_name, + a.cid_num AS caller_id_number, + a.dest AS destination, + d.id AS sip_account_id, + d.caller_name AS sip_caller_name, + a.callee_name as callee_name, + a.callee_num as callee_number, + a.callstate AS callstate, + a.read_codec AS read_codec, + a.read_rate AS read_rate, + a.read_bit_rate AS read_bit_rate, + a.write_codec AS write_codec, + a.write_rate AS write_rate, + a.write_bit_rate AS write_bit_rate, + a.secure AS secure, + b.uuid AS b_uuid, + b.cid_name AS b_caller_id_name, + b.cid_num AS b_caller_id_number, + e.id AS b_sip_account_id, + e.caller_name AS b_sip_caller_name + FROM channels a + LEFT JOIN calls c ON a.uuid = c.caller_uuid AND a.hostname = c.hostname + LEFT JOIN channels b ON b.uuid = c.callee_uuid AND b.hostname = c.hostname + LEFT JOIN sip_accounts d ON a.presence_id LIKE CONCAT(d.auth_name, "@%") + LEFT JOIN sip_accounts e ON b.presence_id LIKE CONCAT(e.auth_name, "@%") + WHERE a.uuid = c.caller_uuid OR a.uuid NOT IN (select callee_uuid from calls)} + end + + def self.down + execute "DROP VIEW calls_active" + end +end -- cgit v1.2.3 From 2964ebf277568536ac215f3a651e1841a73d68f8 Mon Sep 17 00:00:00 2001 From: Peter Kozak Date: Thu, 7 Mar 2013 03:11:28 -0500 Subject: call origination fixed --- app/controllers/calls_controller.rb | 7 ++-- app/models/call.rb | 76 +++++++++---------------------------- 2 files changed, 21 insertions(+), 62 deletions(-) diff --git a/app/controllers/calls_controller.rb b/app/controllers/calls_controller.rb index 22ff92d..9d85a10 100644 --- a/app/controllers/calls_controller.rb +++ b/app/controllers/calls_controller.rb @@ -18,11 +18,11 @@ class CallsController < ApplicationController protocol, separator, phone_number = params[:url].partition(':') if ! phone_number.blank? @call = @parent.calls.new() - @call.dest = phone_number + @call.destination = phone_number end elsif !params[:number].blank? @call = @parent.calls.new() - @call.dest = params[:number] + @call.destination = params[:number] end end @@ -31,8 +31,7 @@ class CallsController < ApplicationController end def create - params[:call][:sip_account] = @sip_account - @call = Call.create(params[:call]) + @call = @sip_account.calls.create(params[:call]) if @call && @call.call m = method( :"#{@parent.class.name.underscore}_calls_url" ) diff --git a/app/models/call.rb b/app/models/call.rb index b0cd9b2..8f657fa 100644 --- a/app/models/call.rb +++ b/app/models/call.rb @@ -2,29 +2,31 @@ class Call < ActiveRecord::Base self.table_name = 'calls_active' self.primary_key = 'uuid' - attr_writer :sip_account_id + belongs_to :sip_account + belongs_to :b_sip_account, :class_name => SipAccount - validates :dest, + validates :sip_account_id, :presence => true - - def create(attributes=nil) - if ! attributes - return - end - self.sip_account = SipAccount.where(:id => attributes[:sip_account_id]).first - self.dest = attributes[:dest] - return self + validates :destination, + :presence => true + + def save(attributes=nil) end - def save(attributes=nil) - - end + def call + if self.sip_account && self.destination + return self.sip_account.call(self.destination) + end - def call(number=nil) - if @sip_account && self.dest - return @sip_account.call(self.dest) + if !self.sip_account + errors.add(:sip_account_id, 'no sip_account') end + + if self.destination.blank? + errors.add(:destination, 'no destination') + end + return false end @@ -37,38 +39,6 @@ class Call < ActiveRecord::Base return FreeswitchAPI.execute('uuid_kill', self.uuid, true); end - def sip_account=(sip_a) - @sip_account = sip_a - end - - def sip_account - if @sip_account - return @sip_account - end - - result = self.presence_id.match('^(.+)@(.+)$') - - if result && ! result[1].blank? and ! result[2].blank? - domain = SipDomain.where(:host => result[2]).first - if domain - @sip_account = SipAccount.where(:auth_name => result[1], :sip_domain_id => domain.id).first - end - end - - return @sip_account - end - - def sip_account_bleg - result = self.b_presence_id.match('^(.+)@(.+)$') - - if result && ! result[1].blank? and ! result[2].blank? - domain = SipDomain.where(:host => result[2]).first - if domain - return SipAccount.where(:auth_name => result[1], :sip_domain_id => domain.id).first - end - end - end - def get_variable_from_uuid(channel_uuid, variable_name) if channel_uuid.blank? return nil @@ -92,14 +62,4 @@ class Call < ActiveRecord::Base return get_variable_from_uuid(self.b_uuid, variable_name); end - def is_sip - return self.name.match('^sofia') != nil - end - - def is_caller - if (self.uuid == self.call_uuid) || self.call_uuid.blank? - true - end - end - end -- cgit v1.2.3 From 1bcb85853b282606f28f1c9cd7f4e13d494a7290 Mon Sep 17 00:00:00 2001 From: Peter Kozak Date: Thu, 7 Mar 2013 03:44:36 -0500 Subject: presence permissions for softkeys added --- app/models/softkey.rb | 26 ++++++++++++++++++++++++++ app/views/softkeys/_form_core.html.haml | 5 +++-- 2 files changed, 29 insertions(+), 2 deletions(-) diff --git a/app/models/softkey.rb b/app/models/softkey.rb index 470605c..6063017 100644 --- a/app/models/softkey.rb +++ b/app/models/softkey.rb @@ -42,6 +42,10 @@ class Softkey < ActiveRecord::Base return call_forwards end + def possible_blf_sip_accounts + self.sip_account.target_sip_accounts_by_permission('presence') + end + def to_s if self.softkeyable.blank? if ['log_out', 'log_in'].include?(self.softkey_function.name) @@ -77,7 +81,29 @@ class Softkey < ActiveRecord::Base if self.softkey_function_id != nil case self.softkey_function.name when 'blf' + has_permission = false self.softkeyable = PhoneNumber.where(:number => self.number, :phone_numberable_type => 'SipAccount').first.try(:phone_numberable) + if self.softkeyable + self.sip_account.groups.each do |group| + if group.has_permission(self.softkeyable.class.name, self.softkeyable.id, :presence) + has_permission = true + break + end + end + if !has_permission && self.sip_account.sip_accountable + self.sip_account.sip_accountable.groups.each do |group| + if group.has_permission(self.softkeyable.class.name, self.softkeyable.id, :presence) + has_permission = true + break + end + end + end + end + + if !has_permission + self.softkeyable = nil + self.number = nil + end when 'conference' self.softkeyable = PhoneNumber.where(:number => self.number, :phone_numberable_type => 'Conference').first.try(:phone_numberable) when 'call_forwarding' diff --git a/app/views/softkeys/_form_core.html.haml b/app/views/softkeys/_form_core.html.haml index 7c1dd4a..f447aa6 100644 --- a/app/views/softkeys/_form_core.html.haml +++ b/app/views/softkeys/_form_core.html.haml @@ -6,7 +6,8 @@ .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 @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 + - call_forwards = @softkey.possible_call_forwards + - if call_forwards && call_forwards.count > 0 + = f.association :softkeyable, :collection => 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') -- cgit v1.2.3 From 88785c0ca2189c47b0a994473ef73a542ed36688 Mon Sep 17 00:00:00 2001 From: Peter Kozak Date: Thu, 7 Mar 2013 03:45:05 -0500 Subject: has_permission method added --- app/models/group.rb | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/app/models/group.rb b/app/models/group.rb index 993d274..6c65f70 100644 --- a/app/models/group.rb +++ b/app/models/group.rb @@ -16,6 +16,11 @@ class Group < ActiveRecord::Base group_permissions.where(:permission => permission).pluck(:target_group_id) end + def has_permission(target_type, target_id, permission) + target_group_ids = GroupMembership.where(:item_id => target_id, :item_type => target_type).pluck(:group_id) + return group_permissions.where(:permission => permission, :target_group_id => target_group_ids).first != nil + end + def self.union(sets=[]) group_ids = [] sets.each do |set| -- cgit v1.2.3 From 846c6ca704e587621eab0c373693c4f52e4c8433 Mon Sep 17 00:00:00 2001 From: Stefan Wintermeyer Date: Thu, 7 Mar 2013 11:25:33 +0100 Subject: Added a different VIEW definition for sqlite3 and refactored some has_many code for the sip_account. --- app/models/sip_account.rb | 7 +- db/migrate/20130307065200_create_calls_active.rb | 99 ++++++++++++++++-------- 2 files changed, 74 insertions(+), 32 deletions(-) diff --git a/app/models/sip_account.rb b/app/models/sip_account.rb index 81b9c1c..cdb609d 100644 --- a/app/models/sip_account.rb +++ b/app/models/sip_account.rb @@ -38,7 +38,8 @@ class SipAccount < ActiveRecord::Base has_many :ringtones, :as => :ringtoneable, :dependent => :destroy - has_many :calls, :finder_sql => lambda { |s| "SELECT DISTINCT calls_active.* FROM calls_active WHERE sip_account_id = #{self.id} OR b_sip_account_id = #{self.id}" } + has_many :call_legs, :class_name => 'Call' + has_many :b_call_legs, :class_name => 'Call', :foreign_key => 'b_sip_account_id' # Delegations: # @@ -83,6 +84,10 @@ class SipAccount < ActiveRecord::Base def to_s truncate((self.caller_name || "SipAccount ID #{self.id}"), :length => GsParameter.get('TO_S_MAX_CALLER_NAME_LENGTH')) + " (#{truncate(self.auth_name, :length => GsParameter.get('TO_S_MAX_LENGTH_OF_AUTH_NAME'))}@...#{self.host.split(/\./)[2,3].to_a.join('.') if self.host })" end + + def calls + self.call_legs + self.b_call_legs + end def call_forwarding_toggle( call_forwarding_service, to_voicemail = nil ) if ! self.phone_numbers.first diff --git a/db/migrate/20130307065200_create_calls_active.rb b/db/migrate/20130307065200_create_calls_active.rb index 930bbc7..0ea877d 100644 --- a/db/migrate/20130307065200_create_calls_active.rb +++ b/db/migrate/20130307065200_create_calls_active.rb @@ -1,38 +1,75 @@ class CreateCallsActive < ActiveRecord::Migration def self.up - execute %q{CREATE VIEW calls_active AS SELECT - a.uuid AS uuid, - a.direction AS direction, - a.created_epoch AS start_stamp, - a.cid_name AS caller_id_name, - a.cid_num AS caller_id_number, - a.dest AS destination, - d.id AS sip_account_id, - d.caller_name AS sip_caller_name, - a.callee_name as callee_name, - a.callee_num as callee_number, - a.callstate AS callstate, - a.read_codec AS read_codec, - a.read_rate AS read_rate, - a.read_bit_rate AS read_bit_rate, - a.write_codec AS write_codec, - a.write_rate AS write_rate, - a.write_bit_rate AS write_bit_rate, - a.secure AS secure, - b.uuid AS b_uuid, - b.cid_name AS b_caller_id_name, - b.cid_num AS b_caller_id_number, - e.id AS b_sip_account_id, - e.caller_name AS b_sip_caller_name - FROM channels a - LEFT JOIN calls c ON a.uuid = c.caller_uuid AND a.hostname = c.hostname - LEFT JOIN channels b ON b.uuid = c.callee_uuid AND b.hostname = c.hostname - LEFT JOIN sip_accounts d ON a.presence_id LIKE CONCAT(d.auth_name, "@%") - LEFT JOIN sip_accounts e ON b.presence_id LIKE CONCAT(e.auth_name, "@%") - WHERE a.uuid = c.caller_uuid OR a.uuid NOT IN (select callee_uuid from calls)} + if ActiveRecord::Base.connection_config[:adapter] != 'sqlite3' + execute <<-SQL + CREATE VIEW calls_active AS SELECT + a.uuid AS uuid, + a.direction AS direction, + a.created_epoch AS start_stamp, + a.cid_name AS caller_id_name, + a.cid_num AS caller_id_number, + a.dest AS destination, + d.id AS sip_account_id, + d.caller_name AS sip_caller_name, + a.callee_name as callee_name, + a.callee_num as callee_number, + a.callstate AS callstate, + a.read_codec AS read_codec, + a.read_rate AS read_rate, + a.read_bit_rate AS read_bit_rate, + a.write_codec AS write_codec, + a.write_rate AS write_rate, + a.write_bit_rate AS write_bit_rate, + a.secure AS secure, + b.uuid AS b_uuid, + b.cid_name AS b_caller_id_name, + b.cid_num AS b_caller_id_number, + e.id AS b_sip_account_id, + e.caller_name AS b_sip_caller_name + FROM channels a + LEFT JOIN calls c ON a.uuid = c.caller_uuid AND a.hostname = c.hostname + LEFT JOIN channels b ON b.uuid = c.callee_uuid AND b.hostname = c.hostname + LEFT JOIN sip_accounts d ON a.presence_id LIKE CONCAT(d.auth_name, "@%") + LEFT JOIN sip_accounts e ON b.presence_id LIKE CONCAT(e.auth_name, "@%") + WHERE a.uuid = c.caller_uuid OR a.uuid NOT IN (select callee_uuid from calls) + SQL + else + execute <<-SQL + CREATE VIEW calls_active AS SELECT + a.uuid AS uuid, + a.direction AS direction, + a.created_epoch AS start_stamp, + a.cid_name AS caller_id_name, + a.cid_num AS caller_id_number, + a.dest AS destination, + d.id AS sip_account_id, + d.caller_name AS sip_caller_name, + a.callee_name as callee_name, + a.callee_num as callee_number, + a.callstate AS callstate, + a.read_codec AS read_codec, + a.read_rate AS read_rate, + a.read_bit_rate AS read_bit_rate, + a.write_codec AS write_codec, + a.write_rate AS write_rate, + a.write_bit_rate AS write_bit_rate, + a.secure AS secure, + b.uuid AS b_uuid, + b.cid_name AS b_caller_id_name, + b.cid_num AS b_caller_id_number, + e.id AS b_sip_account_id, + e.caller_name AS b_sip_caller_name + FROM channels a + LEFT JOIN calls c ON a.uuid = c.caller_uuid AND a.hostname = c.hostname + LEFT JOIN channels b ON b.uuid = c.callee_uuid AND b.hostname = c.hostname + LEFT JOIN sip_accounts d ON a.presence_id LIKE (d.auth_name || "@%") + LEFT JOIN sip_accounts e ON b.presence_id LIKE (e.auth_name || "@%") + WHERE a.uuid = c.caller_uuid OR a.uuid NOT IN (select callee_uuid from calls) + SQL + end end def self.down execute "DROP VIEW calls_active" end -end +end \ No newline at end of file -- cgit v1.2.3 From 3e19646f46c772e10ed3d7a45e8c974ab23f625b Mon Sep 17 00:00:00 2001 From: Stefan Wintermeyer Date: Thu, 7 Mar 2013 11:34:22 +0100 Subject: Added belongs_to :call_route, :touch => true #223 --- app/models/route_element.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/models/route_element.rb b/app/models/route_element.rb index 94f0f84..7d37db0 100644 --- a/app/models/route_element.rb +++ b/app/models/route_element.rb @@ -3,7 +3,7 @@ class RouteElement < ActiveRecord::Base attr_accessible :call_route_id, :var_in, :var_out, :pattern, :replacement, :action, :mandatory, :position - belongs_to :call_route + belongs_to :call_route, :touch => true acts_as_list :scope => :call_route -- cgit v1.2.3