summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Kozak <spag@golwen.net>2013-01-16 08:33:45 -0500
committerPeter Kozak <spag@golwen.net>2013-01-16 08:33:45 -0500
commit113e3c6c6117fbeca7b9bf1f0e6dc26b0db9c407 (patch)
treeaca6e293b1e9ce855bef23954dd59ab4e3c5b32c
parent076a5fa7b4b6d16281eb7d510ff8e7e21154caf9 (diff)
call_routes added
-rw-r--r--app/controllers/call_routes_controller.rb41
-rw-r--r--app/helpers/call_routes_helper.rb2
-rw-r--r--app/models/call_route.rb3
-rw-r--r--app/views/call_routes/_form.html.haml7
-rw-r--r--app/views/call_routes/_form_core.html.haml6
-rw-r--r--app/views/call_routes/_index_core.html.haml17
-rw-r--r--app/views/call_routes/edit.html.haml3
-rw-r--r--app/views/call_routes/index.html.haml6
-rw-r--r--app/views/call_routes/new.html.haml3
-rw-r--r--app/views/call_routes/show.html.haml19
-rw-r--r--config/locales/views/call_routes/de.yml60
-rw-r--r--config/locales/views/call_routes/en.yml60
-rw-r--r--config/routes.rb2
-rw-r--r--db/migrate/20130116133243_create_call_routes.rb16
-rw-r--r--misc/freeswitch/scripts/dialplan/router.lua203
-rw-r--r--test/functional/call_routes_controller_test.rb49
-rw-r--r--test/unit/call_route_test.rb7
17 files changed, 504 insertions, 0 deletions
diff --git a/app/controllers/call_routes_controller.rb b/app/controllers/call_routes_controller.rb
new file mode 100644
index 0000000..631339b
--- /dev/null
+++ b/app/controllers/call_routes_controller.rb
@@ -0,0 +1,41 @@
+class CallRoutesController < ApplicationController
+ def index
+ @call_routes = CallRoute.all
+ end
+
+ def show
+ @call_route = CallRoute.find(params[:id])
+ end
+
+ def new
+ @call_route = CallRoute.new
+ end
+
+ def create
+ @call_route = CallRoute.new(params[:call_route])
+ if @call_route.save
+ redirect_to @call_route, :notice => t('call_routes.controller.successfuly_created')
+ else
+ render :new
+ end
+ end
+
+ def edit
+ @call_route = CallRoute.find(params[:id])
+ end
+
+ def update
+ @call_route = CallRoute.find(params[:id])
+ if @call_route.update_attributes(params[:call_route])
+ redirect_to @call_route, :notice => t('call_routes.controller.successfuly_updated')
+ else
+ render :edit
+ end
+ end
+
+ def destroy
+ @call_route = CallRoute.find(params[:id])
+ @call_route.destroy
+ redirect_to call_routes_url, :notice => t('call_routes.controller.successfuly_destroyed')
+ end
+end
diff --git a/app/helpers/call_routes_helper.rb b/app/helpers/call_routes_helper.rb
new file mode 100644
index 0000000..dfe87dd
--- /dev/null
+++ b/app/helpers/call_routes_helper.rb
@@ -0,0 +1,2 @@
+module CallRoutesHelper
+end
diff --git a/app/models/call_route.rb b/app/models/call_route.rb
new file mode 100644
index 0000000..4cf2445
--- /dev/null
+++ b/app/models/call_route.rb
@@ -0,0 +1,3 @@
+class CallRoute < ActiveRecord::Base
+ attr_accessible :table, :name, :endpoint_type, :endpoint_id, :position
+end
diff --git a/app/views/call_routes/_form.html.haml b/app/views/call_routes/_form.html.haml
new file mode 100644
index 0000000..1415852
--- /dev/null
+++ b/app/views/call_routes/_form.html.haml
@@ -0,0 +1,7 @@
+= simple_form_for(@call_route) do |f|
+ = f.error_notification
+
+ = render "form_core", :f => f
+
+ .actions
+ = f.button :submit, conditional_t('call_routes.form.submit') \ No newline at end of file
diff --git a/app/views/call_routes/_form_core.html.haml b/app/views/call_routes/_form_core.html.haml
new file mode 100644
index 0000000..4b97434
--- /dev/null
+++ b/app/views/call_routes/_form_core.html.haml
@@ -0,0 +1,6 @@
+.inputs
+ = f.input :table, :label => t('call_routes.form.table.label'), :hint => conditional_hint('call_routes.form.table.hint')
+ = f.input :name, :label => t('call_routes.form.name.label'), :hint => conditional_hint('call_routes.form.name.hint')
+ = f.input :endpoint_type, :label => t('call_routes.form.endpoint_type.label'), :hint => conditional_hint('call_routes.form.endpoint_type.hint')
+ = f.input :endpoint_id, :label => t('call_routes.form.endpoint_id.label'), :hint => conditional_hint('call_routes.form.endpoint_id.hint')
+ = f.input :position, :label => t('call_routes.form.position.label'), :hint => conditional_hint('call_routes.form.position.hint')
diff --git a/app/views/call_routes/_index_core.html.haml b/app/views/call_routes/_index_core.html.haml
new file mode 100644
index 0000000..6ea3af7
--- /dev/null
+++ b/app/views/call_routes/_index_core.html.haml
@@ -0,0 +1,17 @@
+%table
+ %tr
+ %th= t('call_routes.index.table')
+ %th= t('call_routes.index.name')
+ %th= t('call_routes.index.endpoint_type')
+ %th= t('call_routes.index.endpoint_id')
+ %th= t('call_routes.index.position')
+
+ - reset_cycle
+ - for call_route in call_routes
+ %tr{:class => cycle('odd', 'even')}
+ %td= call_route.table
+ %td= call_route.name
+ %td= call_route.endpoint_type
+ %td= call_route.endpoint_id
+ %td= call_route.position
+ =render :partial => 'shared/index_view_edit_destroy_part', :locals => {:child => call_route} \ No newline at end of file
diff --git a/app/views/call_routes/edit.html.haml b/app/views/call_routes/edit.html.haml
new file mode 100644
index 0000000..0ad46c5
--- /dev/null
+++ b/app/views/call_routes/edit.html.haml
@@ -0,0 +1,3 @@
+- title t("call_routes.edit.page_title")
+
+= render "form" \ No newline at end of file
diff --git a/app/views/call_routes/index.html.haml b/app/views/call_routes/index.html.haml
new file mode 100644
index 0000000..687a9dc
--- /dev/null
+++ b/app/views/call_routes/index.html.haml
@@ -0,0 +1,6 @@
+- title t("call_routes.index.page_title")
+
+- if @call_routes && @call_routes.count > 0
+ = render "index_core", :call_routes => @call_routes
+
+= render :partial => 'shared/create_link', :locals => {:child_class => CallRoute} \ No newline at end of file
diff --git a/app/views/call_routes/new.html.haml b/app/views/call_routes/new.html.haml
new file mode 100644
index 0000000..0796d7f
--- /dev/null
+++ b/app/views/call_routes/new.html.haml
@@ -0,0 +1,3 @@
+- title t("call_routes.new.page_title")
+
+= render "form" \ No newline at end of file
diff --git a/app/views/call_routes/show.html.haml b/app/views/call_routes/show.html.haml
new file mode 100644
index 0000000..31c3cb0
--- /dev/null
+++ b/app/views/call_routes/show.html.haml
@@ -0,0 +1,19 @@
+- title t("call_routes.show.page_title")
+
+%p
+ %strong= t('call_routes.show.table') + ":"
+ = @call_route.table
+%p
+ %strong= t('call_routes.show.name') + ":"
+ = @call_route.name
+%p
+ %strong= t('call_routes.show.endpoint_type') + ":"
+ = @call_route.endpoint_type
+%p
+ %strong= t('call_routes.show.endpoint_id') + ":"
+ = @call_route.endpoint_id
+%p
+ %strong= t('call_routes.show.position') + ":"
+ = @call_route.position
+
+= render :partial => 'shared/show_edit_destroy_part', :locals => { :child => @call_route } \ No newline at end of file
diff --git a/config/locales/views/call_routes/de.yml b/config/locales/views/call_routes/de.yml
new file mode 100644
index 0000000..34af575
--- /dev/null
+++ b/config/locales/views/call_routes/de.yml
@@ -0,0 +1,60 @@
+de:
+ call_routes:
+ name: 'Call route'
+ controller:
+ successfuly_created: 'Call route wurde angelegt.'
+ successfuly_updated: 'Call route wurde aktualisiert.'
+ successfuly_destroyed: 'Call route wurde gelöscht.'
+ index:
+ page_title: 'Übersicht von Call route'
+ table: 'Table'
+ name: 'Name'
+ endpoint_type: 'Endpoint type'
+ endpoint_id: 'Endpoint'
+ position: 'Position'
+ actions:
+ confirm: 'Sind Sie sicher, dass Sie folgendes löschen möchten: Call route'
+ destroy: 'Löschen'
+ edit: 'Bearbeiten'
+ show: 'Anzeigen'
+ create: 'Neu anlegen'
+ create_for: 'Call route neu anlegen für %{resource}'
+ show:
+ page_title: 'Call route bearbeiten'
+ table: 'Table'
+ name: 'Name'
+ endpoint_type: 'Endpoint type'
+ endpoint_id: 'Endpoint'
+ position: 'Position'
+ actions:
+ confirm: 'Sind Sie sicher, dass die dieses Element löschen möchten?'
+ destroy: 'Löschen'
+ edit: 'Bearbeiten'
+ view_all: 'Alle anzeigen'
+ new:
+ page_title: 'Call route neu anlegen'
+ actions:
+ back_to_list: 'Zurück zur Übersicht'
+ edit:
+ page_title: 'Call route bearbeiten'
+ actions:
+ back_to_list: 'Zurück zur Übersicht'
+ edit: 'Bearbeiten'
+ view_all: 'Alle anzeigen'
+ form:
+ table:
+ label: 'Table'
+ hint: ''
+ name:
+ label: 'Name'
+ hint: ''
+ endpoint_type:
+ label: 'Endpoint type'
+ hint: ''
+ endpoint_id:
+ label: 'Endpoint'
+ hint: ''
+ position:
+ label: 'Position'
+ hint: ''
+ button: 'Absenden' \ No newline at end of file
diff --git a/config/locales/views/call_routes/en.yml b/config/locales/views/call_routes/en.yml
new file mode 100644
index 0000000..251f76e
--- /dev/null
+++ b/config/locales/views/call_routes/en.yml
@@ -0,0 +1,60 @@
+en:
+ call_routes:
+ name: 'Call route'
+ controller:
+ successfuly_created: 'Successfully created Call route.'
+ successfuly_updated: 'Successfully updated Call route.'
+ successfuly_destroyed: 'Successfully destroyed Call route.'
+ index:
+ page_title: 'Listing Call route'
+ table: 'Table'
+ name: 'Name'
+ endpoint_type: 'Endpoint type'
+ endpoint_id: 'Endpoint'
+ position: 'Position'
+ actions:
+ confirm: 'Are you sure you want to delete this Call route?'
+ destroy: 'Delete'
+ edit: 'Edit'
+ show: 'View'
+ create: 'New'
+ create_for: 'New Call route for %{resource}'
+ show:
+ page_title: 'Show Call route'
+ table: 'Table'
+ name: 'Name'
+ endpoint_type: 'Endpoint type'
+ endpoint_id: 'Endpoint'
+ position: 'Position'
+ actions:
+ confirm: 'Are you sure you want to delete this element?'
+ destroy: 'Delete'
+ edit: 'Edit'
+ view_all: 'View All'
+ new:
+ page_title: 'New Call route'
+ actions:
+ back_to_list: 'Back to Index'
+ edit:
+ page_title: 'Editing Call route'
+ actions:
+ back_to_list: 'Back to Index'
+ edit: 'Edit'
+ view_all: 'View All'
+ form:
+ table:
+ label: 'Table'
+ hint: ''
+ name:
+ label: 'Name'
+ hint: ''
+ endpoint_type:
+ label: 'Endpoint type'
+ hint: ''
+ endpoint_id:
+ label: 'Endpoint'
+ hint: ''
+ position:
+ label: 'Position'
+ hint: ''
+ button: 'Submit' \ No newline at end of file
diff --git a/config/routes.rb b/config/routes.rb
index 4e812c0..2834d69 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -1,5 +1,7 @@
Gemeinschaft42c::Application.routes.draw do
+ resources :call_routes
+
resources :gateways do
resources :gateway_settings
resources :gateway_parameters
diff --git a/db/migrate/20130116133243_create_call_routes.rb b/db/migrate/20130116133243_create_call_routes.rb
new file mode 100644
index 0000000..c2d3f45
--- /dev/null
+++ b/db/migrate/20130116133243_create_call_routes.rb
@@ -0,0 +1,16 @@
+class CreateCallRoutes < ActiveRecord::Migration
+ def self.up
+ create_table :call_routes do |t|
+ t.string :table
+ t.string :name
+ t.string :endpoint_type
+ t.integer :endpoint_id
+ t.integer :position
+ t.timestamps
+ end
+ end
+
+ def self.down
+ drop_table :call_routes
+ end
+end
diff --git a/misc/freeswitch/scripts/dialplan/router.lua b/misc/freeswitch/scripts/dialplan/router.lua
new file mode 100644
index 0000000..76d7ada
--- /dev/null
+++ b/misc/freeswitch/scripts/dialplan/router.lua
@@ -0,0 +1,203 @@
+-- Gemeinschaft 5 module: call router class
+-- (c) AMOOMA GmbH 2013
+--
+
+module(...,package.seeall)
+
+Router = {}
+
+-- create route object
+function Router.new(self, arg)
+ arg = arg or {}
+ object = arg.object or {}
+ setmetatable(object, self);
+ self.__index = self;
+ self.class = 'router';
+ self.log = arg.log;
+ self.database = arg.database;
+ self.routes = arg.routes or {};
+ self.caller = arg.caller;
+ self.variables = arg.variables or {};
+ return object;
+end
+
+function Router.build_tables(self)
+ local elements = {
+ { var_in = 'group', var_out = '', pattern = '^users$', replacement = '', action = 'not_match', mandatory = true },
+ { var_in = 'destination_number', var_out = 'destination_number', pattern = '^1$', replacement = '+123456', action = 'not_match', mandatory = true },
+ { var_in = 'caller_id_number', var_out = 'caller_id_number', pattern = '^100$', replacement = '+4930100', action = 'set_route_var', mandatory = false },
+ }
+
+ local elements2 = {
+ { var_in = 'group', var_out = '', pattern = '^users$', replacement = '', action = 'match', mandatory = true },
+ { var_in = 'destination_number', var_out = 'destination_number', pattern = '^1$', replacement = '+123456', action = 'not_match', mandatory = true },
+ { var_in = 'caller_id_number', var_out = 'caller_id_number', pattern = '^100$', replacement = '+4930100', action = 'set_route_var', mandatory = false },
+ }
+
+ local elements3 = {
+ { var_in = 'destination_number', var_out = 'destination_number', pattern = '^#31#(%d+)$', replacement = 'f-dcliron-%1', action = 'set_route_var', mandatory = false },
+ }
+
+ local elements4 = {
+ { var_in = 'destination_number', var_out = 'destination_number', pattern = '^(%d+)$', replacement = '%1', action = 'set_route_var', mandatory = true },
+ { var_in = 'caller_id_number', var_out = 'caller_id_number', pattern = '^(.+)$', replacement = '+49%1', action = 'set_route_var', mandatory = false },
+ }
+
+ local routes = {
+ prerouting = {
+ { id = 10, name = 'feature codes', elements = elements3, endpoint_type = 'dialplanfunction', endpoint_id = 0 },
+ },
+ outbound = {
+ { id = 1, name = 'no users', elements = elements, endpoint_type = 'gateway', endpoint_id = 1, },
+ { id = 2, name = 'all users', elements = elements2, endpoint_type = 'gateway', endpoint_id = 1, },
+ { id = 3, name = 'all users', elements = elements2, endpoint_type = 'gateway', endpoint_id = 1, },
+ },
+ inbound = {
+ { id = 20, name = 'haeron', elements = elements4, endpoint_type = 'phonenumber', endpoint_id = 1, },
+ },
+
+ };
+
+ return routes;
+end
+
+
+function Router.failover_table(self)
+ return {
+ ['603'] = true,
+ ['480'] = true,
+ UNALLOCATED_NUMBER = true,
+ NORMAL_TEMPORARY_FAILURE = true,
+ }
+end
+
+
+function Router.expand_variables(self, line)
+ return (line:gsub('{([%a%d_]+)}', function(captured)
+ return variables[captured] or '';
+ end))
+end
+
+
+function Router.set_parameter(self, action, name, value)
+ if action == 'set_session_var' then
+ self.log:debug('ROUTER_SET_SESSION_VARIABLE - ', name, ' = ', value);
+ self.caller[name] = value;
+ elseif action == 'set_channel_var' then
+ self.log:debug('ROUTER_SET_VARIABLE - ', name, ' = ', value);
+ self.caller:set_variable(name, value);
+ elseif action == 'export_channel_var' then
+ self.log:debug('ROUTER_EXPORT_VARIABLE - ', name, ' = ', value);
+ self.caller:export_variable(name, value);
+ elseif action == 'set_header' then
+ self.log:debug('ROUTER_SIP_HEADER - ', name, ': ', value);
+ self.caller:export_variable('sip_h_' .. name, value);
+ else
+ self.log:error('ROUTER_SET_PARAMERER - unknown action: ', action, ', ', name, ' = ', value);
+ end
+end
+
+
+function Router.element_match(self, pattern, search_string, replacement)
+ local variables_list = {};
+ local success, result = pcall(string.find, search_string, pattern);
+
+ if not success then
+ self.log:error('ELEMENT_MATCH - table error - pattern: ', pattern, ', search_string: ', search_string);
+ elseif result then
+ return true, search_string:gsub(pattern, self:expand_variables(replacement, variables_list));
+ end
+
+ return false;
+end
+
+
+function Router.route_match(self, route)
+ local destination = {
+ gateway = 'gateway' .. route.endpoint_id,
+ ['type'] = route.endpoint_type,
+ id = route.endpoint_id,
+ actions = {}
+ };
+
+ local route_matches = false;
+
+ for index=1, #route.elements do
+ local result = false;
+ local replacement = nil;
+
+ local element = route.elements[index];
+ if element.var_in == 'group' then
+ local groups = common.str.try(self.caller, 'auth_account.owner.groups');
+ if not groups or type(groups) ~= 'table' then
+ if element.mandatory then
+ return false;
+ end
+ end
+
+ for group_name, value in pairs(groups) do
+ result, replacement = self:element_match(tostring(element.pattern), tostring(group_name), tostring(element.replacement));
+ if result then
+ break;
+ end
+ end
+
+ else
+ local search_string = tostring(common.str.try(self.caller, element.var_in))
+ result, replacement = self:element_match(tostring(element.pattern), tostring(search_string), tostring(element.replacement));
+ end
+
+ if element.action == 'not_match' then
+ result = not result;
+ end
+
+ if not result then
+ if element.mandatory then
+ return false;
+ end
+ elseif element.action ~= 'match' and element.action ~= 'not_match' then
+ if element.action == 'set_route_var' then
+ destination[element.var_out] = replacement;
+ else
+ table.insert(destination.actions, {action = element.action, name = element.var_out, value = replacement});
+ end
+ end
+
+ if result then
+ route_matches = true;
+ end
+ end
+
+ if route_matches then
+ return destination;
+ end;
+
+ return nil;
+end
+
+
+function Router.route_run(self, table_name, phone_number, find_first)
+ local routing_tables = self:build_tables();
+ local routing_table = routing_tables[table_name];
+
+ local routes = {};
+
+ if type(routing_table) == 'table' then
+ for index=1, #routing_table do
+ local route = self:route_match(routing_table[index], phone_number);
+ if route then
+ table.insert(routes, route);
+ self.log:info('ROUTE ', #routes,' - ', table_name,'=', routing_table[index].id, '/', routing_table[index].name, ', destination: ', route.type, '=', route.id);
+ if find_first then
+ return route;
+ end
+ else
+ self.log:debug('ROUTE_NO_MATCH - ', table_name, '=', routing_table[index].id, '/', routing_table[index].name);
+ end
+ end
+ end
+
+ if not find_first then
+ return routes;
+ end
+end
diff --git a/test/functional/call_routes_controller_test.rb b/test/functional/call_routes_controller_test.rb
new file mode 100644
index 0000000..77c0b2a
--- /dev/null
+++ b/test/functional/call_routes_controller_test.rb
@@ -0,0 +1,49 @@
+require 'test_helper'
+
+class CallRoutesControllerTest < ActionController::TestCase
+ setup do
+ @call_route = call_routes(:one)
+ end
+
+ test "should get index" do
+ get :index
+ assert_response :success
+ assert_not_nil assigns(:call_routes)
+ end
+
+ test "should get new" do
+ get :new
+ assert_response :success
+ end
+
+ test "should create call_route" do
+ assert_difference('CallRoute.count') do
+ post :create, call_route: @call_route.attributes
+ end
+
+ assert_redirected_to call_route_path(assigns(:call_route))
+ end
+
+ test "should show call_route" do
+ get :show, id: @call_route.to_param
+ assert_response :success
+ end
+
+ test "should get edit" do
+ get :edit, id: @call_route.to_param
+ assert_response :success
+ end
+
+ test "should update call_route" do
+ put :update, id: @call_route.to_param, call_route: @call_route.attributes
+ assert_redirected_to call_route_path(assigns(:call_route))
+ end
+
+ test "should destroy call_route" do
+ assert_difference('CallRoute.count', -1) do
+ delete :destroy, id: @call_route.to_param
+ end
+
+ assert_redirected_to call_routes_path
+ end
+end
diff --git a/test/unit/call_route_test.rb b/test/unit/call_route_test.rb
new file mode 100644
index 0000000..5eb2e50
--- /dev/null
+++ b/test/unit/call_route_test.rb
@@ -0,0 +1,7 @@
+require 'test_helper'
+
+class CallRouteTest < ActiveSupport::TestCase
+ def test_should_be_valid
+ assert CallRoute.new.valid?
+ end
+end