skala
Juan Carlos Raña 13 years ago
commit 8d965d673d
  1. BIN
      main/document/Wami.swf
  2. 14
      main/document/document.php
  3. 9
      main/document/record_audio.php
  4. 199
      main/document/record_audio_wami.php
  5. 72
      main/document/save_pixlr.php
  6. 33
      main/inc/lib/nanogong/receiver.php
  7. 2
      main/inc/lib/svg-edit/extensions/filesave.php
  8. BIN
      main/inc/lib/wami-recorder/Wami.swf
  9. BIN
      main/inc/lib/wami-recorder/buttons.png
  10. 349
      main/inc/lib/wami-recorder/gui.js
  11. 6
      main/inc/lib/wami-recorder/index.html
  12. 64
      main/inc/lib/wami-recorder/record_document.php
  13. 273
      main/inc/lib/wami-recorder/recorder.js
  14. 7
      main/install/db_main.sql
  15. 5
      main/install/migrate-db-1.8.8-1.9.0-pre.sql

Binary file not shown.

@ -505,7 +505,7 @@ foreach ($docs_and_folders as $file) {
//errorAlerts: true,
//warningAlerts: true,
swfPath: "'.$js_path.'jquery-jplayer",
//supplied: "m4a, oga, mp3, ogg, wav",
supplied: "m4a, oga, mp3, ogg, wav",
wmode: "window",
//solution: "flash, html", // Do not change this setting otherwise
cssSelectorAncestor: "#jp_container_'.$count.'",
@ -1073,7 +1073,7 @@ if ($is_allowed_to_edit || $group_member_with_upload_rights || is_my_shared_fold
<?php
}
// Record new audio
// Record new audio nanogong
if (api_get_setting('enable_nanogong') == 'true') {
?>
<a href="record_audio.php?<?php echo api_get_cidreq(); ?>&id=<?php echo $document_id.$req_gid; ?>">
@ -1081,7 +1081,15 @@ if ($is_allowed_to_edit || $group_member_with_upload_rights || is_my_shared_fold
<?php
}
// Create new audio
// Record new audio wami record
if (api_get_setting('enable_wami_record') == 'true') {
?>
<a href="record_audio_wami.php?<?php echo api_get_cidreq(); ?>&id=<?php echo $document_id.$req_gid; ?>">
<?php Display::display_icon('new_recording.png', get_lang('RecordMyVoice'),'',ICON_SIZE_MEDIUM); ?></a>
<?php
}
// Create new audio from text
if (api_get_setting('enabled_text2audio') == 'true'){
?>
<a href="create_audio.php?<?php echo api_get_cidreq(); ?>&id=<?php echo $document_id.$req_gid; ?>">

@ -135,15 +135,18 @@ function submitVoice() {
var lang_give_a_title="<?php echo get_lang('NanogongGiveTitle'); ?>";
var lang_failled_to_submit="<?php echo get_lang('NanogongFailledToSubmit'); ?>";
var lang_submitted="<?php echo get_lang('NanogongSubmitted'); ?>";
// user and group id
var nano_user_id="<?php echo api_get_user_id(); ?>";
var nano_group_id="<?php echo api_get_group_id(); ?>";
var nano_session_id="<?php echo api_get_session_id(); ?>";
//path, url and filename
var filename = document.getElementById("audio_title").value+".wav";
var filename = document.getElementById("audio_title").value+"_chnano_.wav";//adding name file, tag and extension
var filename = filename.replace(/\s/g, "_");//replace spaces by _
var filename = encodeURIComponent(filename);
var filepath="<?php echo urlencode($filepath); ?>";
var dir="<?php echo urlencode($dir); ?>";
var course_code="<?php echo urlencode($course_code); ?>";
var urlnanogong="../inc/lib/nanogong/receiver.php?filename="+filename+"&filepath="+filepath+"&dir="+dir+"&course_code="+course_code;
var urlnanogong="../inc/lib/nanogong/receiver.php?filename="+filename+"&filepath="+filepath+"&dir="+dir+"&course_code="+course_code+"&nano_group_id="+nano_group_id+"&nano_session_id="+nano_session_id+"&nano_user_id="+nano_user_id;
//check
var recorder

@ -0,0 +1,199 @@
<?php
/* For licensing terms, see /license.txt */
/**
* This file allows record wav files.
*
* @package chamilo.document
*
* @author Juan Carlos Raña Trabado herodoto@telefonica.net
* @since 5/april/2012
*/
/**
* Code
*/
/* INIT SECTION */
// Name of the language file that needs to be included
$language_file = array('document');
require_once '../inc/global.inc.php';
$_SESSION['whereami'] = 'document/voicerecord';
$this_section = SECTION_COURSES;
require_once api_get_path(SYS_CODE_PATH).'document/document.inc.php';
require_once api_get_path(LIBRARY_PATH).'groupmanager.lib.php';
$nameTools = get_lang('VoiceRecord');
api_protect_course_script();
api_block_anonymous_users();
$document_data = DocumentManager::get_document_data_by_id($_GET['id'], api_get_course_id(), true);
if (empty($document_data)) {
if (api_is_in_group()) {
$group_properties = GroupManager::get_group_properties(api_get_group_id());
$document_id = DocumentManager::get_document_id(api_get_course_info(), $group_properties['directory']);
$document_data = DocumentManager::get_document_data_by_id($document_id, api_get_course_id());
}
}
$document_id = $document_data['id'];
$dir = $document_data['path'];
//make some vars
$wamidir=$dir;
if($wamidir=="/"){
$wamidir="";
}
$wamiurlplay=api_get_path(WEB_COURSE_PATH).api_get_course_path().'/document'.$wamidir."/";
$is_allowed_to_edit = api_is_allowed_to_edit(null, true);
// Please, do not modify this dirname formatting
if (strstr($dir, '..')) {
$dir = '/';
}
if ($dir[0] == '.') {
$dir = substr($dir, 1);
}
if ($dir[0] != '/') {
$dir = '/'.$dir;
}
if ($dir[strlen($dir) - 1] != '/') {
$dir .= '/';
}
$filepath = api_get_path(SYS_COURSE_PATH).$_course['path'].'/document'.$dir;
if (!is_dir($filepath)) {
$filepath = api_get_path(SYS_COURSE_PATH).$_course['path'].'/document/';
$dir = '/';
}
//make some vars
//$waminame="audiorecord.wav";
$wamiuserid=api_get_user_id();
$userinfo=Database::get_user_info_from_id($wamiuserid);
$waminame = api_get_person_name($userinfo['firstname'], $userinfo['lastname']).'.wav';
$waminame = replace_dangerous_char($waminame, 'strict');
$waminame_noex=basename($waminame, ".wav");
$dirBaseDocuments = api_get_path(SYS_COURSE_PATH).$_course['path'].'/document';
$saveDir=$dirBaseDocuments.$wamidir;
if (file_exists($saveDir.'/'.$waminame)){
$i = 1;
while (file_exists($saveDir.'/'.$waminame_noex.'_'.$i.'.wav')) $i++;
$waminame = $waminame_noex . '_' . $i . '.wav';
}
//groups //TODO: clean
if (isset ($_SESSION['_gid']) && $_SESSION['_gid'] != 0) {
$req_gid = '&amp;gidReq='.$_SESSION['_gid'];
$interbreadcrumb[] = array ("url" => "../group/group_space.php?gidReq=".$_SESSION['_gid'], "name" => get_lang('GroupSpace'));
$noPHP_SELF = true;
$to_group_id = $_SESSION['_gid'];
$group = GroupManager :: get_group_properties($to_group_id);
$path = explode('/', $dir);
if ('/'.$path[1] != $group['directory']) {
api_not_allowed(true);
}
}
$interbreadcrumb[] = array ("url" => "./document.php?id=".$document_id.$req_gid, "name" => get_lang('Documents'));
if (!$is_allowed_in_course) {
api_not_allowed(true);
}
if (!($is_allowed_to_edit || $_SESSION['group_member_with_upload_rights'] || is_my_shared_folder(api_get_user_id(), Security::remove_XSS($dir),api_get_session_id()))) {
api_not_allowed(true);
}
/* Header */
event_access_tool(TOOL_DOCUMENT);
$display_dir = $dir;
if (isset ($group)) {
$display_dir = explode('/', $dir);
unset ($display_dir[0]);
unset ($display_dir[1]);
$display_dir = implode('/', $display_dir);
}
// Interbreadcrumb for the current directory root path
$counter = 0;
if (isset($document_data['parents'])) {
foreach($document_data['parents'] as $document_sub_data) {
//fixing double group folder in breadcrumb
if (api_get_group_id()) {
if ($counter == 0) {
$counter++;
continue;
}
}
$interbreadcrumb[] = array('url' => $document_sub_data['document_url'], 'name' => $document_sub_data['title']);
$counter++;
}
}
Display :: display_header($nameTools, 'Doc');
echo '<div class="actions">';
echo '<a href="document.php?id='.$document_id.'">'.Display::return_icon('back.png',get_lang('BackTo').' '.get_lang('DocumentsOverview'),'',ICON_SIZE_MEDIUM).'</a>';
echo '</div>';
?>
<!-- swfobject is a commonly used library to embed Flash content https://ajax.googleapis.com/ajax/libs/swfobject/2.2/ -->
<script type="text/javascript" src="<?php echo api_get_path(WEB_LIBRARY_PATH) ?>swfobject/swfobject.js"></script>
<!-- Setup the recorder interface -->
<script type="text/javascript" src="<?php echo api_get_path(WEB_LIBRARY_PATH) ?>wami-recorder/recorder.js"></script>
<!-- GUI code... take it or leave it -->
<script type="text/javascript" src="<?php echo api_get_path(WEB_LIBRARY_PATH) ?>wami-recorder/gui.js"></script>
<script>
function setupRecorder() {
Wami.setup({
id : "wami",
onReady : setupGUI
});
}
function setupGUI() {
var gui = new Wami.GUI({
id : "wami",
recordUrl : "<?php echo api_get_path(WEB_LIBRARY_PATH) ?>wami-recorder/record_document.php?waminame=<?php echo $waminame; ?>&wamidir=<?php echo $wamidir; ?>&wamiuserid=<?php echo $wamiuserid; ?>",
playUrl : "<?php echo $wamiurlplay.$waminame; ?>",
buttonUrl : "<?php echo api_get_path(WEB_LIBRARY_PATH) ?>wami-recorder/buttons.png",
swfUrl : "<?php echo api_get_path(WEB_LIBRARY_PATH) ?>wami-recorder/Wami.swf",
});
gui.setPlayEnabled(false);
}
</script>
<div id="wami" style="margin-left: 460px; margin-top:50px;"></div>
<div align="center" style="margin-top:200px;">
<?php
Display::display_normal_message(get_lang('VoiceRecord'), false);
?>
</div>
<body onLoad="setupRecorder()">
<?php
Display :: display_footer();

@ -15,20 +15,28 @@ require_once '../inc/global.inc.php';
require_once api_get_path(LIBRARY_PATH).'fileUpload.lib.php';
require_once api_get_path(LIBRARY_PATH).'document.lib.php';
api_protect_course_script();
api_block_anonymous_users();
if(!isset($_GET['title']) && !isset($_GET['type']) && !isset($_GET['image'])) {
if ($_user['user_id']!= api_get_user_id() || api_get_user_id()==0 || $_user['user_id']==0) {
api_not_allowed();
die();
}
if(!isset($_GET['title']) || !isset($_GET['type']) || !isset($_GET['image'])) {
api_not_allowed();
die();
}
if(!isset($_SESSION['paint_dir']) || !isset($_SESSION['whereami']) ){
api_not_allowed();//
api_not_allowed();
die();
}
//pixlr return
$filename=Security::remove_XSS($_GET['title']);//The user preferred file name of the image.
$extension=Security::remove_XSS($_GET['type']);//The image type, "pdx", "jpg", "bmp" or "png".
$urlcontents=Security::remove_XSS($_GET['image']);//A URL to the image on Pixlr.com server or the raw file post of the saved image.
@ -42,9 +50,18 @@ $relativeUrlPath=$_SESSION['paint_dir'];
$currentTool=$_SESSION['whereami'];
$dirBaseDocuments = api_get_path(SYS_COURSE_PATH).$_course['path'].'/document';
$saveDir=$dirBaseDocuments.$_SESSION['paint_dir'];
$contents = file_get_contents($urlcontents);
//Verify that the URL is pointing to a file @ pixlr.com domain or an ip @ pixlr.com
//Security. Verify that the URL is pointing to a file @ pixlr.com domain or an ip @ pixlr.com. Comment because sometimes return a ip number
/*
if (strpos($urlcontents, "pixlr.com") === 0){
echo "Invalid referrer";
exit;
}
*/
//Security. Allway get from pixlr.com. Comment because for now this does not run
/*
$urlcontents1='http://pixlr.com/';
$urlcontents2 = strstr($urlcontents, '_temp');
@ -52,26 +69,50 @@ $urlcontents_to_save=$urlcontents1.$urlcontents2;
$contents = file_get_contents($urlcontents_to_save);//replace line 45.
*/
//Verify that the file is an image
$headers = get_headers($urlcontents, 1);
$content_type = explode("/", $headers['Content-Type']);
if ($content_type[0] != "image"){
echo "Invalid file type";
exit;
}
//a bit title security
$filename = addslashes(trim($filename));
$filename = Security::remove_XSS($filename);
$filename = replace_dangerous_char($filename, 'strict');
$filename = disable_dangerous_file($filename);
// a bit extension security
if($extension!= 'jpg' && $extension!= 'png' && $extension!= 'bmp' && $extension!= 'pxd'){
if (strlen(trim($filename))==0) {
echo "The title is empty";//if title is empty, headers Content-Type = application/octet-stream, then not create a new title here please
exit;
}
//check file_get_contents
if ($contents === false) {
echo "I cannot read: ".$urlcontents;
exit;
}
// Extension security
if($extension!= 'jpg' && $extension!= 'png' && $extension!= 'pxd'){
die();
}
if($extension=='pxd') {
echo "pxd file type does not supported";// not secure because check security headers and finfo() return Content-Type = application/octet-stream
exit;
}
//TODO: a bit mime security
//Verify that the file is an image. Headers method
$headers = get_headers($urlcontents, 1);
$content_type = explode("/", $headers['Content-Type']);
if ($content_type[0] != "image") {
echo "Invalid file type";
exit;
}
//Verify that the file is an image. Fileinfo method
if (phpversion() >= '5.3' && extension_loaded('fileinfo')) {
$finfo = new finfo(FILEINFO_MIME);
$current_mime=$finfo->buffer($contents);
finfo_close($finfo);
if(strpos($current_mime, 'image')===false) {
echo "Invalid mime type file";
exit;
}
}
//path, file and title
$paintFileName = $filename.'.'.$extension;
@ -127,7 +168,8 @@ if($currentTool=='document/createpaint'){
//delete temporal file
unlink($_SESSION['temp_realpath_image']);
$temp_file_2delete=$_SESSION['temp_realpath_image'];
unlink($temp_file_2delete);
//Clean sessions and return to Chamilo file list
unset($_SESSION['paint_dir']);

@ -6,7 +6,7 @@
*
* @package chamilo.document
*
* @author Juan Carlos Ra<EFBFBD>a Trabado
* @author Juan Carlos Raña Trabado
* @since 5/mar/2011
*/
/**
@ -15,18 +15,23 @@
require_once '../../../inc/global.inc.php';
require_once api_get_path(LIBRARY_PATH).'fileUpload.lib.php';
//security. Nanogong need less security because under Firefox, Chrome..., not save user_id...
//security. Nanogong need less security because under Firefox, Chrome..., not stay SESSION
if (api_get_setting('enable_nanogong') == 'false'){
api_protect_course_script();
api_block_anonymous_users();
}
if (!isset($_GET['filename']) || !isset($_GET['filepath']) || !isset($_GET['dir']) || !isset($_GET['course_code'])){
api_not_allowed(true);
if (!isset($_GET['filename']) || !isset($_GET['filepath']) || !isset($_GET['dir']) || !isset($_GET['course_code'])|| !isset($_GET['nano_group_id']) || !isset($_GET['nano_session_id']) || !isset($_GET['nano_user_id'])){
echo 'Error. Not allowed';
exit;
}
if (!is_uploaded_file($_FILES['voicefile']['tmp_name'])) exit;
//clean
$nano_user_id=Security::remove_XSS($_GET['nano_user_id']);
$nano_group_id=Security::remove_XSS($_GET['nano_group_id']);
$nano_session_id=Security::remove_XSS($_GET['nano_session_id']);
$filename=Security::remove_XSS($_GET['filename']);
$filename=urldecode($filename);
$filepath=Security::remove_XSS(urldecode($_GET['filepath']));
@ -41,21 +46,33 @@ $filename = Database::escape_string($filename);
$filename = replace_dangerous_char($filename, $strict = 'loose');// or strict
$filename = disable_dangerous_file($filename);
$title= str_replace('_',' ',$filename);
$title= trim(str_replace('_chnano_.','.',$filename));//hide nanogong wav tag at title
$title= str_replace('_',' ',$title);
//
$documentPath = $filepath.$filename;
/*
//comment because here api_get_user_id() return alway 0
if ($nano_user_id!= api_get_user_id() || api_get_user_id()==0 || $nano_user_id==0) {
echo 'Not allowed';
exit;
}
*/
//Do not use here check Fileinfo method because return: text/plain
if (!file_exists($documentPath)){
//add document to disk
move_uploaded_file($_FILES['voicefile']['tmp_name'], $documentPath);
//add document to database
$current_session_id = api_get_session_id();
$groupId=$_SESSION['_gid'];
$current_session_id = $nano_session_id; // $nano_session_id instead api_get_session_id() because here $_SESSION is lost
$groupId=$nano_group_id; // $nano_group_id instead $_SESSION['_gid'], because here $_SESSION is lost.
$file_size = filesize($documentPath);
$relativeUrlPath=$dir;
$doc_id = add_document($_course, $relativeUrlPath.$filename, 'file', filesize($documentPath), $title);
api_item_property_update($_course, TOOL_DOCUMENT, $doc_id, 'DocumentAdded', $_user['user_id'], $groupId, null, null, null, $current_session_id);
api_item_property_update($_course, TOOL_DOCUMENT, $doc_id, 'DocumentAdded', $nano_user_id, $groupId, null, null, null, $current_session_id);// $nano_user_id instead $_user['user_id'], because here $_user['user_id'] is lost.
} else {
return get_lang('FileExistRename');
}

@ -83,7 +83,7 @@ if ($suffix!= 'svg' && $suffix!= 'png'){
//a bit mime security
//comment because finfo seems stopping the save process files in some php vers.
/*
if (phpversion() >= '5.3') {
if (phpversion() >= '5.3' && extension_loaded('fileinfo')) {
$finfo = new finfo(FILEINFO_MIME);
$current_mime=$finfo->buffer($contents);
finfo_close($finfo);

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

@ -0,0 +1,349 @@
var Wami = window.Wami || {};
// Upon a creation of a new Wami.GUI(options), we assume that a WAMI recorder
// has been initialized.
Wami.GUI = function(options) {
var RECORD_BUTTON = 1;
var PLAY_BUTTON = 2;
setOptions(options);
setupDOM();
var recordButton, playButton;
var recordInterval, playInterval;
function createDiv(id, style) {
var div = document.createElement("div");
if (id) {
div.setAttribute('id', id);
}
if (style) {
div.style.cssText = style;
}
return div;
}
function setOptions(options) {
if (!options.buttonUrl) {
options.buttonUrl = "buttons.png";
}
if (typeof options.listen == 'undefined' || options.listen) {
listen();
}
}
function setupDOM() {
var guidiv = createDiv(null,
"position: absolute; width: 214px; height: 137px;");
document.getElementById(options.id).appendChild(guidiv);
var rid = Wami.createID();
var recordDiv = createDiv(rid,
"position: absolute; left: 40px; top: 25px");
guidiv.appendChild(recordDiv);
recordButton = new Button(rid, RECORD_BUTTON, options.buttonUrl);
recordButton.onstart = startRecording;
recordButton.onstop = stopRecording;
recordButton.setEnabled(true);
if (!options.singleButton) {
var pid = Wami.createID();
var playDiv = createDiv(pid,
"position: absolute; right: 40px; top: 25px");
guidiv.appendChild(playDiv);
playButton = new Button(pid, PLAY_BUTTON, options.buttonUrl);
playButton.onstart = startPlaying;
playButton.onstop = stopPlaying;
}
}
/**
* These methods are called on clicks from the GUI.
*/
function startRecording() {
if (!options.recordUrl) {
alert("No record Url specified!");
}
recordButton.setActivity(0);
playButton.setEnabled(false);
Wami.startRecording(options.recordUrl,
Wami.nameCallback(onRecordStart), Wami
.nameCallback(onRecordFinish), Wami
.nameCallback(onError));
}
function stopRecording() {
Wami.stopRecording();
clearInterval(recordInterval);
recordButton.setEnabled(true);
}
function startPlaying() {
if (!options.playUrl) {
alert('No play URL specified!');
}
playButton.setActivity(0);
recordButton.setEnabled(false);
Wami.startPlaying(options.playUrl, Wami.nameCallback(onPlayStart), Wami
.nameCallback(onPlayFinish), Wami.nameCallback(onError));
}
function stopPlaying() {
Wami.stopPlaying();
}
this.setPlayUrl = function(url) {
options.playUrl = url;
}
this.setRecordUrl = function(url) {
options.recordUrl = url;
}
this.setPlayEnabled = function(val) {
playButton.setEnabled(val);
}
this.setRecordEnabled = function(val) {
recordButton.setEnabled(val);
}
/**
* Callbacks from the flash indicating certain events
*/
function onError(e) {
alert(e);
}
function onRecordStart() {
recordInterval = setInterval(function() {
if (recordButton.isActive()) {
var level = Wami.getRecordingLevel();
recordButton.setActivity(level);
}
}, 200);
if (options.onRecordStart) {
options.onRecordStart();
}
}
function onRecordFinish() {
playButton.setEnabled(true);
if (options.onRecordFinish) {
options.onRecordFinish();
}
}
function onPlayStart() {
playInterval = setInterval(function() {
if (playButton.isActive()) {
var level = Wami.getPlayingLevel();
playButton.setActivity(level);
}
}, 200);
if (options.onPlayStart) {
options.onPlayStart();
}
}
function onPlayFinish() {
clearInterval(playInterval);
recordButton.setEnabled(true);
playButton.setEnabled(true);
if (options.onPlayFinish) {
options.onPlayFinish();
}
}
function listen() {
Wami.startListening();
// Continually listening when the window is in focus allows us to
// buffer a little audio before the users clicks, since sometimes
// people talk too soon. Without "listening", the audio would record
// exactly when startRecording() is called.
window.onfocus = function() {
Wami.startListening();
};
// Note that the use of onfocus and onblur should probably be replaced
// with a more robust solution (e.g. jQuery's $(window).focus(...)
window.onblur = function() {
Wami.stopListening();
};
}
function Button(buttonid, type, url) {
var self = this;
self.active = false;
self.type = type;
init();
// Get the background button image position
// Index: 1) normal 2) pressed 3) mouse-over
function background(index) {
if (index == 1)
return "-56px 0px";
if (index == 2)
return "0px 0px";
if (index == 3)
return "-112px 0";
alert("Background not found: " + index);
}
// Get the type of meter and its state
// Index: 1) enabled 2) meter 3) disabled
function meter(index, offset) {
var top = 5;
if (offset)
top += offset;
if (self.type == RECORD_BUTTON) {
if (index == 1)
return "-169px " + top + "px";
if (index == 2)
return "-189px " + top + "px";
if (index == 3)
return "-249px " + top + "px";
} else {
if (index == 1)
return "-269px " + top + "px";
if (index == 2)
return "-298px " + top + "px";
if (index == 3)
return "-327px " + top + "px";
}
alert("Meter not found: " + self.type + " " + index);
}
function silhouetteWidth() {
if (self.type == RECORD_BUTTON) {
return "20px";
} else {
return "29px";
}
}
function mouseHandler(e) {
var rightclick;
if (!e)
var e = window.event;
if (e.which)
rightclick = (e.which == 3);
else if (e.button)
rightclick = (e.button == 2);
if (!rightclick) {
if (self.active && self.onstop) {
self.active = false;
self.onstop();
} else if (!self.active && self.onstart) {
self.active = true;
self.onstart();
}
}
}
function init() {
var div = document.createElement("div");
var elem = document.getElementById(buttonid);
if (elem) {
elem.appendChild(div);
} else {
alert('Could not find element on page named ' + buttonid);
}
self.guidiv = document.createElement("div");
self.guidiv.style.width = '56px';
self.guidiv.style.height = '63px';
self.guidiv.style.cursor = 'pointer';
self.guidiv.style.background = "url(" + url + ") no-repeat";
self.guidiv.style.backgroundPosition = background(1);
div.appendChild(self.guidiv);
// margin auto doesn't work in IE quirks mode
// http://stackoverflow.com/questions/816343/why-will-this-div-img-not-center-in-ie8
// text-align is a hack to force it to work even if you forget the
// doctype.
self.guidiv.style.textAlign = 'center';
self.meterDiv = document.createElement("div");
self.meterDiv.style.width = silhouetteWidth();
self.meterDiv.style.height = '63px';
self.meterDiv.style.margin = 'auto';
self.meterDiv.style.cursor = 'pointer';
self.meterDiv.style.position = 'relative';
self.meterDiv.style.background = "url(" + url + ") no-repeat";
self.meterDiv.style.backgroundPosition = meter(2);
self.guidiv.appendChild(self.meterDiv);
self.coverDiv = document.createElement("div");
self.coverDiv.style.width = silhouetteWidth();
self.coverDiv.style.height = '63px';
self.coverDiv.style.margin = 'auto';
self.coverDiv.style.cursor = 'pointer';
self.coverDiv.style.position = 'relative';
self.coverDiv.style.background = "url(" + url + ") no-repeat";
self.coverDiv.style.backgroundPosition = meter(1);
self.meterDiv.appendChild(self.coverDiv);
self.active = false;
self.guidiv.onmousedown = mouseHandler;
}
self.isActive = function() {
return self.active;
}
self.setActivity = function(level) {
self.guidiv.onmouseout = function() {
};
self.guidiv.onmouseover = function() {
};
self.guidiv.style.backgroundPosition = background(2);
self.coverDiv.style.backgroundPosition = meter(1, 5);
self.meterDiv.style.backgroundPosition = meter(2, 5);
var totalHeight = 31;
var maxHeight = 9;
// When volume goes up, the black image loses height,
// creating the perception of the colored one increasing.
var height = (maxHeight + totalHeight - Math.floor(level / 100
* totalHeight));
self.coverDiv.style.height = height + "px";
}
self.setEnabled = function(enable) {
var guidiv = self.guidiv;
self.active = false;
if (enable) {
self.coverDiv.style.backgroundPosition = meter(1);
self.meterDiv.style.backgroundPosition = meter(1);
guidiv.style.backgroundPosition = background(1);
guidiv.onmousedown = mouseHandler;
guidiv.onmouseover = function() {
guidiv.style.backgroundPosition = background(3);
};
guidiv.onmouseout = function() {
guidiv.style.backgroundPosition = background(1);
};
} else {
self.coverDiv.style.backgroundPosition = meter(3);
self.meterDiv.style.backgroundPosition = meter(3);
guidiv.style.backgroundPosition = background(1);
guidiv.onmousedown = null;
guidiv.onmouseout = function() {
};
guidiv.onmouseover = function() {
};
}
}
}
}

@ -0,0 +1,6 @@
<html>
<head>
</head>
<body>
</body>
</html>

@ -0,0 +1,64 @@
<?php
require_once '../../../inc/global.inc.php';
require_once api_get_path(LIBRARY_PATH).'fileUpload.lib.php';
require_once api_get_path(LIBRARY_PATH).'document.lib.php';
////Add security from Chamilo
api_protect_course_script();
api_block_anonymous_users();
//
# Save the audio to a URL-accessible directory for playback.
parse_str($_SERVER['QUERY_STRING'], $params);
if(isset($params['waminame']) && isset($params['wamidir']) && isset($params['wamiuserid'])) {
$waminame = $params['waminame'];
$wamidir = $params['wamidir'];
$wamiuserid = $params['wamiuserid'];
}
else {
api_not_allowed();
die();
}
if ($wamiuserid!= api_get_user_id() || api_get_user_id()==0 || $wamiuserid==0) {
api_not_allowed();
die();
}
//clean
$waminame = Security::remove_XSS($waminame);
$waminame = addslashes(trim($waminame));
$waminame = replace_dangerous_char($waminame, 'strict');
$waminame = disable_dangerous_file($waminame);
$wamidir = Security::remove_XSS($wamidir);
$content = file_get_contents('php://input');
//security extension
$ext = explode('.', $waminame);
$ext = strtolower($ext[sizeof($ext) - 1]);
if($ext!= 'wav'){
die();
}
//Do not use here check Fileinfo method because return: text/plain
$dirBaseDocuments = api_get_path(SYS_COURSE_PATH).$_course['path'].'/document';
$saveDir=$dirBaseDocuments.$wamidir;
$current_session_id = api_get_session_id();
$groupId=$_SESSION['_gid'];
$documentPath = $saveDir.'/'.$waminame;
$title=str_replace('_',' ',$waminame);
//$title=basename($waminame, ".wav");//save title whitout extension
//add to disk
$fh = fopen($documentPath, 'w') or die("can't open file");
fwrite($fh, $content);
fclose($fh);
//add document to database
$doc_id = add_document($_course, $wamidir.'/'.$waminame, 'file', filesize($documentPath), $title);
api_item_property_update($_course, TOOL_DOCUMENT, $doc_id, 'DocumentAdded', $_user['user_id'], $groupId, null, null, null, $current_session_id);
?>

@ -0,0 +1,273 @@
var Wami = window.Wami || {};
// Returns a (very likely) unique string with of random letters and numbers
Wami.createID = function() {
return "wid" + ("" + 1e10).replace(/[018]/g, function(a) {
return (a ^ Math.random() * 16 >> a / 4).toString(16)
});
}
// Creates a named callback in WAMI and returns the name as a string.
Wami.nameCallback = function(cb, cleanup) {
Wami._callbacks = Wami._callbacks || {};
var id = Wami.createID();
Wami._callbacks[id] = function() {
if (cleanup) {
Wami._callbacks[id] = null;
}
cb.apply(null, arguments);
};
var named = "Wami._callbacks['" + id + "']";
return named;
}
// This method ensures that a WAMI recorder is operational, and that
// the following API is available in the Wami namespace. All functions
// must be named (i.e. cannot be anonymous).
//
// Wami.startPlaying(url, startfn = null, finishedfn = null, failedfn = null);
// Wami.stopPlaying()
//
// Wami.startRecording(url, startfn = null, finishedfn = null, failedfn = null);
// Wami.stopRecording()
//
// Wami.getRecordingLevel() // Returns a number between 0 and 100
// Wami.getPlayingLevel() // Returns a number between 0 and 100
//
// Wami.hide()
// Wami.show()
//
// Manipulate the WAMI recorder's settings. In Flash
// we need to check if the microphone permission has been granted.
// We might also set/return sample rate here, etc.
//
// Wami.getSettings();
// Wami.setSettings(options);
//
// Optional way to set up browser so that it's constantly listening
// This is to prepend audio in case the user starts talking before
// they click-to-talk.
//
// Wami.startListening()
//
Wami.setup = function(options) {
if (Wami.startRecording) {
// Wami's already defined.
if (options.onReady) {
options.onReady();
}
return;
}
// Assumes that swfobject.js is included if Wami.swfobject isn't
// already defined.
Wami.swfobject = Wami.swfobject || swfobject;
if (!Wami.swfobject) {
alert("Unable to find swfobject to help embed the SWF.");
}
var _options;
setOptions(options);
embedWamiSWF(_options.id, Wami.nameCallback(delegateWamiAPI));
function supportsTransparency() {
// Detecting the OS is a big no-no in Javascript programming, but
// I can't think of a better way to know if wmode is supported or
// not... since NOT supporting it (like Flash on Ubuntu) is a bug.
return (navigator.platform.indexOf("Linux") == -1);
}
function setOptions(options) {
// Start with default options
_options = {
swfUrl : "Wami.swf",
onReady : function() {
Wami.hide();
},
onSecurity : checkSecurity,
onError : function(error) {
alert(error);
}
};
if (typeof options == 'undefined') {
alert('Need at least an element ID to place the Flash object.');
}
if (typeof options == 'string') {
_options.id = options;
} else {
_options.id = options.id;
}
if (options.swfUrl) {
_options.swfUrl = options.swfUrl;
}
if (options.onReady) {
_options.onReady = options.onReady;
}
if (options.onLoaded) {
_options.onLoaded = options.onLoaded;
}
if (options.onSecurity) {
_options.onSecurity = options.onSecurity;
}
if (options.onError) {
_options.onError = options.onError;
}
// Create a DIV for the SWF under _options.id
var container = document.createElement('div');
container.style.position = 'absolute';
_options.cid = Wami.createID();
container.setAttribute('id', _options.cid);
var swfdiv = document.createElement('div');
var id = Wami.createID();
swfdiv.setAttribute('id', id);
container.appendChild(swfdiv);
document.getElementById(_options.id).appendChild(container);
_options.id = id;
}
function checkSecurity() {
var settings = Wami.getSettings();
if (settings.microphone.granted) {
_options.onReady();
} else {
// Show any Flash settings panel you want:
// http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/system/SecurityPanel.html
Wami.showSecurity("privacy", "Wami.show", Wami
.nameCallback(_options.onSecurity), Wami
.nameCallback(_options.onError));
}
}
// Embed the WAMI SWF and call the named callback function when loaded.
function embedWamiSWF(id, initfn) {
var flashVars = {
visible : false,
loadedCallback : initfn
}
var params = {
allowScriptAccess : "always"
}
if (supportsTransparency()) {
params.wmode = "transparent";
}
if (typeof console !== 'undefined') {
flashVars.console = true;
}
var version = '10.0.0';
document.getElementById(id).innerHTML = "WAMI requires Flash "
+ version
+ " or greater<br />https://get.adobe.com/flashplayer/";
// This is the minimum size due to the microphone security panel
Wami.swfobject.embedSWF(_options.swfUrl, id, 214, 137, version, null,
flashVars, params);
// Without this line, Firefox has a dotted outline of the flash
Wami.swfobject.createCSS("#" + id, "outline:none");
}
// To check if the microphone settings were 'remembered', we
// must actually embed an entirely new Wami client and check
// whether its microphone is granted. If it is, it was remembered.
function checkRemembered(finishedfn) {
var id = Wami.createID();
var div = document.createElement('div');
div.style.top = '-999px';
div.style.left = '-999px';
div.setAttribute('id', id);
var body = document.getElementsByTagName('body').item(0);
body.appendChild(div);
var fn = Wami.nameCallback(function() {
var swf = document.getElementById(id);
Wami._remembered = swf.getSettings().microphone.granted;
Wami.swfobject.removeSWF(id);
eval(finishedfn + "()");
});
embedWamiSWF(id, fn);
}
// Attach all the audio methods to the Wami namespace in the callback.
function delegateWamiAPI() {
var recorder = document.getElementById(_options.id);
function delegate(name) {
Wami[name] = function() {
return recorder[name].apply(recorder, arguments);
}
}
delegate('startPlaying');
delegate('stopPlaying');
delegate('startRecording');
delegate('stopRecording');
delegate('startListening');
delegate('stopListening');
delegate('getRecordingLevel');
delegate('getPlayingLevel');
delegate('setSettings');
// Append extra information about whether mic settings are sticky
Wami.getSettings = function() {
var settings = recorder.getSettings();
settings.microphone.remembered = Wami._remembered;
return settings;
}
Wami.showSecurity = function(panel, startfn, finishedfn, failfn) {
// Flash must be on top for this.
var container = document.getElementById(_options.cid);
var augmentedfn = Wami.nameCallback(function() {
checkRemembered(finishedfn);
container.style.cssText = "position: absolute;";
});
container.style.cssText = "position: absolute; z-index: 99999";
recorder.showSecurity(panel, startfn, augmentedfn, failfn);
}
Wami.show = function() {
if (!supportsTransparency()) {
recorder.style.visibility = "visible";
}
}
Wami.hide = function() {
// Hiding flash in all the browsers is tricky. Please read:
// https://code.google.com/p/wami-recorder/wiki/HidingFlash
if (!supportsTransparency()) {
recorder.style.visibility = "hidden";
}
}
// If we already have permissions, they were previously 'remembered'
Wami._remembered = recorder.getSettings().microphone.granted;
if (_options.onLoaded) {
_options.onLoaded();
}
if (!_options.noSecurityCheck) {
checkSecurity();
}
}
}

@ -864,7 +864,8 @@ VALUES
('login_is_email', NULL, 'radio', 'Platform', 'false', 'LoginIsEmailTitle', 'LoginIsEmailComment', NULL, NULL, 0),
('courses_default_creation_visibility', NULL, 'radio', 'Course', '2', 'CoursesDefaultCreationVisibilityTitle', 'CoursesDefaultCreationVisibilityComment', NULL, NULL, 1),
('allow_browser_sniffer', NULL, 'radio', 'Tuning', 'false', 'AllowBrowserSnifferTitle', 'AllowBrowserSnifferComment', NULL, NULL, 0),
('chamilo_database_version',NULL,'textfield',NULL, '1.9.0.17053','DokeosDatabaseVersion','', NULL, NULL, 0);
('enable_wami_record',NULL,'radio','Tools','false','EnableWamiRecordTitle','EnableWamiRecordComment',NULL,NULL, 0),
('chamilo_database_version',NULL,'textfield',NULL, '1.9.0.17054','DokeosDatabaseVersion','', NULL, NULL, 0);
/*
('show_tabs', 'custom_tab_1', 'checkbox', 'Platform', 'true', 'ShowTabsTitle', 'ShowTabsComment', NULL, 'TabsCustom1', 1),
@ -1201,7 +1202,9 @@ VALUES
('courses_default_creation_visibility', '1', 'Private'),
('courses_default_creation_visibility', '0', 'CourseVisibilityClosed'),
('allow_browser_sniffer', 'true', 'Yes'),
('allow_browser_sniffer', 'false', 'No');
('allow_browser_sniffer', 'false', 'No'),
('enable_wami_record', 'true', 'Yes'),
('enable_wami_record', 'false', 'No');
UNLOCK TABLES;
/*

@ -148,6 +148,11 @@ INSERT INTO settings_current (variable, subkey, type, category, selected_value,
INSERT INTO settings_options (variable, value, display_text) VALUES ('allow_browser_sniffer', 'true', 'Yes');
INSERT INTO settings_options (variable, value, display_text) VALUES ('allow_browser_sniffer', 'false', 'No');
INSERT INTO settings_current (variable, subkey, type, category, selected_value, title, comment, scope, subkeytext, access_url_changeable) VALUES ('enable_wami_record', NULL, 'radio', 'Tools', 'false', 'EnableWamiRecordTitle', 'EnableWamiRecordComment', NULL, NULL, 0);
INSERT INTO settings_options (variable, value, display_text) VALUES ('enable_wami_record', 'true', 'Yes');
INSERT INTO settings_options (variable, value, display_text) VALUES ('enable_wami_record', 'false', 'No');
-- Course ranking
CREATE TABLE track_course_ranking (id int unsigned not null PRIMARY KEY AUTO_INCREMENT,c_id int unsigned not null, session_id int unsigned not null default 0, url_id int unsigned not null default 0, accesses int unsigned not null default 0, total_score int unsigned not null default 0, users int unsigned not null default 0, creation_date datetime not null);

Loading…
Cancel
Save