Revision 332
- Date:
- 2013/05/03 13:35:48
- Files:
-
- /utf8/plugins/tokbox/comps
- /utf8/plugins/tokbox/comps/contenido
- /utf8/plugins/tokbox/comps/contenido/tokbox
- /utf8/plugins/tokbox/comps/contenido/tokbox/autohandler (Diff) (Checkout)
- /utf8/plugins/tokbox/comps/contenido/tokbox/dhandler (Diff) (Checkout)
- /utf8/plugins/tokbox/comps/contenido/tokbox/index.html (Diff) (Checkout)
- /utf8/plugins/tokbox/config.proto (Diff) (Checkout)
- /utf8/plugins/tokbox/lib
- /utf8/plugins/tokbox/lib/tokbox
- /utf8/plugins/tokbox/lib/tokbox/Apache.pm (Diff) (Checkout)
- /utf8/plugins/tokbox/lib/tokbox/Init.pm (Diff) (Checkout)
- /utf8/plugins/tokbox/lib/tokbox/Keeper.pm (Diff) (Checkout)
- /utf8/plugins/tokbox/lib/tokbox/Session.pm (Diff) (Checkout)
- /utf8/plugins/tokbox/lib/tokbox/State.pm.proto (Diff) (Checkout)
Legend:
- Added
- Removed
- Modified
-
utf8/plugins/tokbox/comps/contenido/tokbox/autohandler
1 <%init> 2 3 $r->content_type('text/html'); 4 $m->call_next(); 5 6 </%init> -
utf8/plugins/tokbox/comps/contenido/tokbox/dhandler
1 <& $call, %ARGS &> 2 <%init> 3 4 my $call; 5 if ( $r->uri eq '/contenido/tokbox/' ) { 6 $call = 'index.html'; 7 } else { 8 &abort404; 9 } 10 11 </%init> -
utf8/plugins/tokbox/comps/contenido/tokbox/index.html
1 <& "/contenido/components/header.msn" &> 2 <& "/contenido/components/naviline.msn" &> 3 4 <p>PLugin [tokbox]</p> 5 6 </body> 7 </html> -
utf8/plugins/tokbox/config.proto
1 ############################################################################# 2 # 3 # Параметры данного шаблона необходимо ВРУЧНУЮ добавить в config.mk проекта 4 # и привести в соответствие с требованиями проекта 5 # 6 ############################################################################# 7 PLUGINS += tokbox 8 9 TOKBOX_API_KEY = 10 TOKBOX_SECRET = 11 12 REWRITE += TOKBOX_API_KEY TOKBOX_SECRET -
utf8/plugins/tokbox/lib/tokbox/Apache.pm
1 package tokbox::Apache; 2 3 use strict; 4 use warnings 'all'; 5 6 use tokbox::State; 7 use Contenido::Globals; 8 9 10 sub child_init { 11 # встраиваем keeper плагина в keeper проекта 12 $keeper->{tokbox} = tokbox::Keeper->new($state->tokbox); 13 } 14 15 sub request_init { 16 } 17 18 sub child_exit { 19 } 20 21 1; -
utf8/plugins/tokbox/lib/tokbox/Init.pm
1 package tokbox::Init; 2 3 use strict; 4 use warnings 'all'; 5 6 use Contenido::Globals; 7 use tokbox::Apache; 8 use tokbox::Keeper; 9 use tokbox::Session; 10 11 12 # загрузка всех необходимых плагину классов 13 # tokbox::SQL::SomeTable 14 # tokbox::SomeClass 15 Contenido::Init::load_classes(qw( 16 )); 17 18 sub init { 19 0; 20 } 21 22 1; -
utf8/plugins/tokbox/lib/tokbox/Keeper.pm
1 package tokbox::Keeper; 2 3 use strict; 4 use warnings 'all'; 5 use Time::HiRes; 6 use MIME::Base64; 7 use Digest::SHA1 qw(sha1 sha1_hex); 8 use LWP::UserAgent; 9 use URI; 10 use Data::Dumper; 11 use XML::Fast; 12 13 use base qw(Contenido::Keeper); 14 15 use Contenido::Globals; 16 17 our $SUBSCRIBER = "subscriber"; 18 our $PUBLISHER = "publisher"; 19 our $MODERATOR = "moderator"; 20 21 sub OpenTokSession { 22 my ($self, $sessionId, $properties) = @_; 23 return tokbox::Session->new( sessionId => $sessionId, properties => $properties ); 24 } 25 26 27 ### - Generate a token 28 # 29 # session_id - If session_id is not blank, this token can only join the call with the specified session_id. 30 # role - One of the constants defined in RoleConstants. Default is publisher, look in the documentation to learn more about roles. 31 # expire_time - Optional timestamp to change when the token expires. See documentation on token for details. 32 # connection_data - Optional string data to pass into the stream. See documentation on token for details. 33 # 34 ########################################################################################################## 35 sub generateToken { 36 my ($self, %opts) = @_; 37 38 my $session_id = delete $opts{session_id} || ''; 39 my $role = delete $opts{role} || ''; 40 my $expire_time = delete $opts{expire_time}; 41 my $connection_data = delete $opts{connection_data} || ''; 42 43 my $create_time = time; 44 my $nonce = gettimeofday() . rand(); 45 46 if ( !$role ) { 47 $role = $PUBLISHER; 48 } elsif ( $role ne $SUBSCRIBER && $role ne $PUBLISHER && $role ne $MODERATOR ) { 49 warn "unknown role $role\n"; 50 return; 51 } 52 my $data_string = "session_id=$session_id&create_time=$create_time&role=$role&nonce=$nonce"; 53 if ( defined $expire_time ) { 54 if ( $expire_time =~ /\D/ ) { 55 warn "Expire time must be a number\n"; 56 return; 57 } elsif ( $expire_time < $create_time ) { 58 warn "Expire time must be in the future\n"; 59 return; 60 } elsif ( $expire_time > $create_time + 2592000 ) { 61 warn "Expire time must be in the next 30 days\n"; 62 return; 63 } 64 $data_string .= "&expire_time=$expire_time"; 65 } 66 if ( $connection_data ) { 67 if ( length $connection_data > 1000 ) { 68 warn "Connection data must be less than 1000 characters\n"; 69 return; 70 } 71 $data_string .= "&connection_data=" . Utils::HTML::url_escape($connection_data); 72 } 73 my $sig = $self->_sign_string($data_string, $self->state->{tokbox_secret}); 74 my $api_key = $self->state->{tokbox_api_key}; 75 76 return "T1==" . encode_base64("partner_id=$api_key&sig=$sig:$data_string"); 77 } 78 79 80 ### 81 # 82 # Creates a new session. 83 # location - IP address to geolocate the call around. 84 # properties - Optional array, keys are defined in SessionPropertyConstants 85 # 86 ################################################################################### 87 sub createSession { 88 my ($self, %opts) = @_; 89 90 my $location = delete $opts{location} || ''; 91 my $properties = delete $opts{properties} || {}; 92 $properties->{"location"} = $location; 93 $properties->{"api_key"} = $self->state->{tokbox_api_key}; 94 95 my $createSessionResult = $self->_do_request("/session/create", $properties); 96 return unless $createSessionResult; 97 my $createSessionXML = xml2hash ($createSessionResult); 98 unless ( ref $createSessionXML ) { 99 warn "Failed to create session: Invalid response from server\n"; 100 return; 101 } 102 103 unless( exists $createSessionXML->{sessions}{Session}{session_id} ) { 104 warn "Failed to create session.\n"; 105 warn Dumper $createSessionXML; 106 return; 107 } 108 my $sessionId = $createSessionXML->{sessions}{Session}{session_id}; 109 110 return $self->OpenTokSession( $sessionId ); 111 } 112 113 114 115 ######################################################## 116 # Inner functions 117 ######################################################## 118 sub _sign_string { 119 my ($self, $string, $secret) = @_; 120 return sha1_hex($string, $secret); 121 } 122 123 sub _do_request { 124 my ($self, $url, $data, $auth) = @_; 125 126 $auth = {} unless ref $auth; 127 $auth->{'type'} = 'partner' unless exists $auth->{type}; 128 129 $url = $self->state->{tokbox_server} . $url; 130 131 my %authHeader; 132 if ( $auth->{type} eq 'token' ) { 133 $authHeader{"X-TB-TOKEN-AUTH"} = $auth->{'token'}; 134 } else { 135 $authHeader{"X-TB-PARTNER-AUTH"} = $self->state->{tokbox_api_key}.":".$self->state->{tokbox_secret}; 136 } 137 138 my $req = URI->new( $url ); 139 my $ua = LWP::UserAgent->new; 140 $ua->timeout(3); 141 $ua->default_header( 'Content-type' => 'application/x-www-form-urlencoded' ); 142 $ua->default_header( %authHeader ); 143 warn "Post: [$url] params:".Dumper($data) if $DEBUG; 144 my $res = $ua->post( $req, $data ); 145 unless ($res->code == 200) { 146 warn "Request failed: ".$res->status_line; 147 return undef; 148 } else { 149 warn "Responce: ".Dumper($res) if $DEBUG; 150 } 151 return $res->content; 152 } 153 154 155 1; -
utf8/plugins/tokbox/lib/tokbox/Session.pm
1 package tokbox::Session; 2 3 use strict; 4 use warnings 'all'; 5 use Contenido::Globals; 6 use tokbox::Keeper; 7 8 our $P2P_PREFERENCE = 'p2p.preference'; 9 10 sub new { 11 my ($proto, %params) = @_; 12 my $class = ref($proto) || $proto; 13 my $self = {}; 14 bless $self, $class; 15 16 $self->{sessionId} = $params{sessionId} || ''; 17 $self->{sessionProperties} = $params{properties}; 18 19 return $self; 20 } 21 22 23 sub sessionId { 24 my $self = shift; 25 return exists $self->{sessionId} && $self->{sessionId} ? $self->{sessionId} : undef; 26 } 27 28 sub sessionProperties { 29 my $self = shift; 30 return exists $self->{sessionProperties} && $self->{sessionProperties} ? $self->{sessionProperties} : undef; 31 } 32 33 sub getSessionId { 34 my $self = shift; 35 return $self->sessionId; 36 } 37 38 sub id { 39 my $self = shift; 40 return $self->sessionId; 41 } 42 43 1; -
utf8/plugins/tokbox/lib/tokbox/State.pm.proto
1 package tokbox::State; 2 3 use strict; 4 use warnings 'all'; 5 use vars qw($AUTOLOAD); 6 7 8 sub new { 9 my ($proto) = @_; 10 my $class = ref($proto) || $proto; 11 my $self = {}; 12 bless $self, $class; 13 14 # configured 15 $self->{debug} = (lc('') eq 'yes'); 16 $self->{project} = ''; 17 18 # зашитая конфигурация плагина 19 $self->{db_type} = 'none'; ### For REAL database use 'remote' 20 $self->{db_keepalive} = 0; 21 $self->{db_host} = ''; 22 $self->{db_name} = ''; 23 $self->{db_user} = ''; 24 $self->{db_password} = ''; 25 $self->{db_port} = ''; 26 $self->{store_method} = 'toast'; 27 $self->{cascade} = 1; 28 $self->{db_prepare} = 0; 29 30 $self->{memcached_enable} = lc( '' ) eq 'yes' ? 1 : 0; 31 $self->{memcached_enable_compress} = 1; 32 $self->{memcached_backend} = ''; 33 $self->{memcached_servers} = [qw()]; 34 $self->{memcached_busy_lock} = 60; 35 $self->{memcached_delayed} = lc('') eq 'yes' ? 1 : 0; 36 37 $self->{serialize_with} = 'json'; ### or 'dumper' 38 39 # not implemented really (core compatibility) 40 $self->{binary_directory} = '/nonexistent'; 41 $self->{data_directory} = '/nonexistent'; 42 $self->{images_directory} = '/nonexistent'; 43 $self->{preview} = '0'; 44 45 $self->{tokbox_api_key} = '@TOKBOX_API_KEY@'; 46 $self->{tokbox_secret} = '@TOKBOX_SECRET@'; 47 $self->{tokbox_server} = 'http://api.opentok.com/hl'; 48 49 $self->_init_(); 50 $self; 51 } 52 53 sub info { 54 my $self = shift; 55 return unless ref $self; 56 57 for (sort keys %{$self->{attributes}}) { 58 my $la = length $_; 59 warn "\t$_".("\t" x (2-int($la/8))).": $self->{$_}\n"; 60 } 61 } 62 63 sub _init_ { 64 my $self = shift; 65 66 # зашитая конфигурация плагина 67 $self->{attributes}->{$_} = 'SCALAR' for qw( 68 debug 69 project 70 71 db_type 72 db_keepalive 73 db_host 74 db_port 75 db_name 76 db_user 77 db_password 78 store_method 79 cascade 80 db_prepare 81 db_client_encoding 82 83 memcached_enable 84 memcached_enable_compress 85 memcached_backend 86 memcached_servers 87 memcached_busy_lock 88 memcached_delayed 89 90 binary_directory 91 data_directory 92 images_directory 93 preview 94 ); 95 } 96 97 sub AUTOLOAD { 98 my $self = shift; 99 my $attribute = $AUTOLOAD; 100 101 $attribute =~ s/.*:://; 102 return unless $attribute =~ /[^A-Z]/; # Отключаем методы типа DESTROY 103 104 if (!exists $self->{attributes}->{$attribute}) { 105 warn "Contenido Error (tokbox::State): Вызов метода, для которого не существует обрабатываемого свойства: ->$attribute()\n"; 106 return; 107 } 108 109 $self->{$attribute} = shift @_ if $#_>=0; 110 $self->{$attribute}; 111 } 112 113 1;