Skip to content

Commit

Permalink
created captionsLanguage functions
Browse files Browse the repository at this point in the history
    squash 3de7cf1 added feature
  • Loading branch information
atarisafari committed Jul 17, 2019
1 parent cdfa365 commit bda94dc
Show file tree
Hide file tree
Showing 12 changed files with 183 additions and 3 deletions.
6 changes: 5 additions & 1 deletion app.json
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,11 @@
"ADMIN_PANEL_ENABLED": {
"description": "Enable the Admin Panel feature. False disables access and removes the block from the configuration XML.",
"value": "false"
}
},
"CANVAS_COURSE_LANGUAGE": {
"description": "The ISO 639-1 language code for the Canvas course. Defaults to English (en) if not set.",
"required": false
},
},
"addons": [
"heroku-postgresql:hobby-dev"
Expand Down
3 changes: 3 additions & 0 deletions config/herokuConfig.php
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,9 @@
/* Google Analytics Tracking Code */
define('GA_TRACKING_CODE', getenv('GA_TRACKING_CODE')?:'');

/* Course Language */
define('COURSE_LANGUAGE', getenv('CANVAS_COURSE_LANGUAGE')?:'');

// Fix some issues caused by the heroku load balancer
// The OAUTH signature verification doesn't know it's using https w/o this
if (!empty($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] == 'https') {
Expand Down
6 changes: 6 additions & 0 deletions config/localConfig.template.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@
/* Disable headings check character count */
$doc_length = '1500';

/* Default course language */
$default_locale = '';

/* Unscannable Suggestion */
$unscannable_suggestion = 'Consider converting these documents to Pages, since they are easier to update, easier to view on mobile devices, and generally more accessible.';
$unscannable_suggestion_on = true;
Expand All @@ -34,6 +37,9 @@
/* Google Analytics Tracking Code */
define('GA_TRACKING_CODE', '');

/* Course Language */
define('COURSE_LANGUAGE', '');

/* Database Config */
$db_type = 'mysql'; // 'mysql' or 'pgsql'
$db_host = ''; // localhost or some other domain/ip
Expand Down
3 changes: 3 additions & 0 deletions config/localConfig.test.php
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,9 @@
/* Vimeo API Key */
define('VIMEO_API_KEY', 'TEST_VIMEO_KEY');

/* Course Language */
define('COURSE_LANGUAGE', 'TEST_COURSE_LANGUAGE');

/* Database Config */
$db_type = 'test'; // 'mysql' or 'pgsql'
$db_host = ''; // localhost or ip
Expand Down
11 changes: 11 additions & 0 deletions config/tests.php
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,17 @@
],
'example' => '',
],
[
'name' => 'videoCaptionsAreCorrectLanguage',
'title' => 'No <a href="http://webaim.org/techniques/captions/">closed captions</a> found.',
'desc' => '<p>Closed captions that match the course language should be included in the video to provide dialogue to users who are hearing impaired. (Please note that videos that have been removed, deleted, or are Unlisted will also cause this error, and will need to be manually verified.)</p>',
'resources' => [
'<a href="https://support.google.com/youtube/answer/2734796?hl=en">Adding Captions to Youtube</a>',
'<a href="http://guides.instructure.com/m/4152/l/98632-how-do-i-create-captions-for-new-or-uploaded-videos-in-canvas">Creating Captions for Video Uploaded to Canvas</a>',
'WCAG Standard: <a href="http://www.w3.org/TR/WCAG20/#media-equiv-captions">1.2.2</a>',
],
'example' => '',
],
[
'name' => 'contentTooLong',
'title' => 'Content length should not exceed 3000 words.',
Expand Down
47 changes: 46 additions & 1 deletion lib/quail/quail/common/accessibility_tests.php
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@
* If 2 adjacent links have the same destination then this error will be generated.
*/


/**
* There are no adjacent text and image links having the same destination.
* This objective of this technique is to avoid unnecessary duplication that occurs when adjacent text and iconic versions of a link are contained in a document.
Expand Down Expand Up @@ -6457,6 +6456,52 @@ function check()
}
}
}
/**
* Videos with manual captions should have some that match the course language
*/
class videoCaptionsAreCorrectLanguage extends quailTest
{
/**
* @var int $default_severity The default severity code for this test.
*/
var $default_severity = QUAIL_TEST_SUGGESTION;

/**
* @var array $services The services that this test will need.
*/
var $services = [
'youtube' => 'media/youtube',
'vimeo' => 'media/vimeo'
];

/**
* The main check function. This is called by the parent class to actually check content
*/
function check()
{
$search_youtube = '/(youtube|youtu.be)/';
$search_vimeo = '/(vimeo)/';

foreach ($this->getAllElements(array('a', 'embed', 'iframe')) as $video) {
$attr = ($video->tagName == 'a') ? 'href' : 'src';
if ($video->hasAttribute($attr)) {
$attr_val = $video->getAttribute($attr);
if ( preg_match($search_youtube, $attr_val) ) {
$service = 'youtube';
}
elseif ( preg_match($search_vimeo, $attr_val) ) {
$service = 'vimeo';
}
if (isset($service)) {
$captionState = $this->services[$service]->captionsLanguage($attr_val);
if($captionState != 2) {
$this->addReport($video, null, null, $captionState, ($captionState == 1));
}
}
}
}
}
}

/**
* Checks that a document is written clearly to a minimum of a 60 on the
Expand Down
43 changes: 43 additions & 0 deletions lib/quail/quail/common/services/media/vimeo.php
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,49 @@ function captionsMissing($link_url)
return 2;
}

function captionsLanguage($link_url)
{
$url = $this->search_url;
$api_key = constant( 'VIMEO_API_KEY' );

if(!empty(constant( 'COURSE_LANGUAGE' ))) {
$courseLanguage = constant( 'COURSE_LANGUAGE' );
}

else {
$courseLanguage = 'LOL';
}

// If the API key is blank, flag the video for manual inspection
$key_trimmed = trim($api_key);
if( empty($key_trimmed) ){
return 1;
}

if( $vimeo_id = $this->isVimeoVideo($link_url) ) {
$url = $url.$vimeo_id.'/texttracks';
$response = Request::get($url)->addHeader('Authorization', "Bearer $api_key")->send();

// Response header code is used to determine if video exists, doesn't exist, or is unaccessible
// 400 means a video is private, 404 means a video doesn't exist, and 200 means the video exists
if($response->code === 400 || $response->code === 404) {
return 1;
} else if(($response->code === 200) && $response->body->total === 0) {
return 2;
}

foreach ( $response->body->data as $track) {
if( $track->language === $courseLanguage ) {
return 2;
}
}

return 0;
}

return 2;
}

/**
* Checks to see if the provided link URL is a Vimeo video. If so, it returns
* the video code, if not, it returns null.
Expand Down
56 changes: 55 additions & 1 deletion lib/quail/quail/common/services/media/youtube.php
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<?php
<?php session_start();

require_once('mediaService.php');
// require_once('../config/localConfig.php');
Expand Down Expand Up @@ -65,7 +65,61 @@ function captionsMissing($link_url)
}

return 2;
}

/**
* Checks to see if a video is missing caption information in YouTube
* @param string $link_url The URL to the video or video resource
* @return int 0 if captions are manual and wrong language, 1 if video is private, 2 if captions are auto-generated or manually generated and correct language
*/
function captionsLanguage($link_url)
{
$url = $this->search_url;
$api_key = constant( 'GOOGLE_API_KEY' );

if(!empty(constant( 'COURSE_LANGUAGE' ))) {
$courseLanguage = constant( 'COURSE_LANGUAGE' );
}

else {
$courseLanguage = 'LOL';
}

$foundManual = false;

// If the API key is blank, flag the video for manual inspection
$key_trimmed = trim($api_key);
if( empty($key_trimmed) ){
return 1;
}

if( $youtube_id = $this->isYouTubeVideo($link_url) ) {
$url = $url.$youtube_id.'&key='.$api_key;
$response = Request::get($url)->send();

// If the video was pulled due to copyright violations, is unlisted, or is unavailable, the response header will be 404
if( $response->code == 404) {
return 1;
}
// Looks through the captions and checks if they are of the correct language
foreach ( $response->body->items as $track) {
//If the track was manually generated, set the flag to true
if( $track->snippet->trackKind != 'ASR' ){
$foundManual = true;
}

if( $track->snippet->language == $courseLanguage && $track->snippet->trackKind != 'ASR' ) {
return 2;
}

}
//If we found any manual captions and have not returned, then none are the correct language
if( $foundManual === true ){
return 0;
}
}

return 2;
}

/**
Expand Down
1 change: 1 addition & 0 deletions lib/quail/quail/guidelines/translations/en.txt
Original file line number Diff line number Diff line change
Expand Up @@ -239,6 +239,7 @@
"cssTextStyleEmphasize","Avoid using color alone for emphasis","<p>When emphasizing text, you may use color with sufficient contrast as long as you also apply some other form of emphasis, such as bold or italics. This ensures that screen reader users are aware of the text's importance.</p>","1"
"videoProvidesCaptions","No closed captions found on media comment.","<p>Media comments are required to have closed captioning. Please follow the article <a target="_blank" href="https://community.canvaslms.com/docs/DOC-13043">How do I add captions to new or uploaded videos in Canvas as an instructor?</a> for information on how to fix this issue.","2"
"videosEmbeddedOrLinkedNeedCaptions","No closed captions found.","<p>Videos used on online courses are required to have closed captioning. Unfortunately, automatic captioning (such as on YouTube videos) is not accurate enough for educational use. You have three options:</p><ul><li>Contact the creator of the video and request captions be added.</li><li>Create captions yourself using a service like Amara (http://amara.org/).</li><li>Find a different video that has closed captioning.</li></ul>","1"
"videoCaptionsAreCorrectLanguage","Captions don't match course language","<p>While this video has captions, there are no captions available for your course language. While not imperative to fix, if you'd like to you have three options:</p><ul><li>Contact the creator of the video and request captions be added.</li><li>Create captions yourself using a service like Amara (http://amara.org/).</li><li>Find a different video that has closed captioning for your course language.</li></ul>","1"
"documentIsWrittenClearly","The document should be written to the target audience and read clearly","<p>If a document is beyond a 10th grade level, then a summary or other guide should also be provided to guide the user through the content.</p>","2"
"headersHaveText","Headings should contain text","<p>Sighted and <a href='http://en.wikipedia.org/wiki/Screen_reader'>screen reader</a> users depend on headings to organize the content on the page. Headings should not be empty and should represent an accurate outline of the content</p>","1"
"labelsAreAssignedToAnInput","All labels should be associated with an input","<p>All <code>label</code> elements should be assigned to an input item, and should have a <em>for</em> attribute which equals the <em>id</em> attribute of a form element.</p>","1"
Expand Down
1 change: 1 addition & 0 deletions lib/quail/quail/guidelines/wcag2aaa.php
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,7 @@ class Wcag2aaaGuideline extends quailGuideline
'videoEmbedChecked',
'videoProvidesCaptions',
'videosEmbeddedOrLinkedNeedCaptions',
'videoCaptionsAreCorrectLanguage',
];
}
/*@}*/
8 changes: 8 additions & 0 deletions lib/quail/quail/reporters/reporter.static.php
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,14 @@ function getReport()
$testResult['description'] = $description;
}
break;
case 'videoCaptionsAreCorrectLanguage':
if($problem->manual == true || $test_count > 0) {
if($problem->manual == true) $test_count++;
$testResult['description'] = $description."<p>⚠️ ".$test_count.' items require manual verification because UDOIT was unable to detect captions. This is most likely due to the video being unlisted, private, or deleted.</p>';
} else {
$testResult['description'] = $description;
}
break;

default:
$testResult['description'] = $description;
Expand Down
1 change: 1 addition & 0 deletions public/index.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
*/

require_once(__DIR__.'/../config/settings.php');

global $logger;

function isEmpty($teststr)
Expand Down

0 comments on commit bda94dc

Please sign in to comment.