Changeset 35243


Ignore:
Timestamp:
2021-08-03T17:23:54+12:00 (3 years ago)
Author:
davidb
Message:

Implement ability to fetch and display transcriptions individually, and to show failed transcriptions.

Location:
main/trunk/model-interfaces-dev/atea
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • main/trunk/model-interfaces-dev/atea/js/asr/TranscribeService.js

    r35238 r35243  
     1/**
     2 * The transcription object returned from our transcription endpoint.
     3 *
     4 * @typedef {Object} TranscriptionModel
     5 * @property {String} transcription The transcription.
     6 * @property {{char: String, start_time: Number}[]} metadata The character metadata.
     7 * @property {String} file_name The name of the file that was transcribed.
     8 */
     9
    110/**
    211 * A service that uploads audio files in a multipart request to the Korero Maori API Interface servlet, and interprets the result.
     
    1423     *
    1524     * @param {FileList} files The files to upload.
    16      * @returns {Promise<string>} A promise with an HTML response.
     25     * @returns {Promise<TranscriptionModel>} A promise for an object representation of the JSON response.
    1726     */
    1827    async doFetchUpload(files)
     
    4251
    4352        return response.json();
     53    }
     54
     55    /**
     56     * @callback TranscriptionPromiseCallback
     57     * @param {Promise<Response>} promise A fetch promise containing an HTTP response.
     58     * @param {String} filename The file that this transcription is for.
     59     * @returns {void}
     60     */
     61
     62    /**
     63     *
     64     * @param {FileList} files The files to upload
     65     * @param {TranscriptionPromiseCallback} callback A callback made with the fetch promise.
     66     */
     67    doIndividualFetchUpload(files, callback)
     68    {
     69        const that = this;
     70       
     71        for (let f of files)
     72        {
     73            const formData = new FormData();
     74            formData.append("audioFile", f, f.name);
     75            formData.append("audioFileKeys", "audioFile");
     76
     77            let promise = fetch
     78            (
     79                that.queryUrl,
     80                {
     81                    method: "POST",
     82                    body: formData
     83                }
     84            )
     85            callback(promise, f.name);
     86        }
    4487    }
    4588
  • main/trunk/model-interfaces-dev/atea/js/asr/asr-controller.js

    r35238 r35243  
    2020 * @param {Event} ev The event
    2121 * @returns {void}
    22  */
    23 
    24 /**
    25  * The transcription object returned from our transcription endpoint.
    26  *
    27  * @typedef {Object} TranscriptionModel
    28  * @property {String} transcription The transcription.
    29  * @property {{char: String, start_time: Number}[]} metadata The character metadata.
    30  * @property {String} file_name The name of the file that was transcribed.
    3122 */
    3223
     
    6354    $(FILE_UPLOAD_PROGRESS_CONTAINER_NAME).removeClass("asr-hidden");
    6455
    65     transcribeService.doFetchUpload(files)
     56    // Remove old transcriptions
     57    const parent = document.querySelector("#transcriptionsList");
     58    while (parent.lastChild) {
     59        parent.removeChild(parent.lastChild);
     60    }
     61
     62    transcribeService.doIndividualFetchUpload(files, (promise, fileName) => {
     63        promise
    6664        .then
    6765        (
    68             transcriptions => {
    69                 // Remove old transcriptions
    70                 const parent = document.querySelector("#transcriptionsList");
    71                 while (parent.lastChild) {
    72                     parent.removeChild(parent.lastChild);
    73                 }
     66            async response =>
     67            {
     68                /** @type {TranscriptionModel[]} */
     69                const transcription = await response.json();
    7470
    75                 // Insert each new transcription
    76                 for (let t of transcriptions) {
     71                // Note that there will only be one transcription here, however the proxy API always returns a list.
     72                for (let t of transcription) {
     73                    console.log("Inserting one transcription");
    7774                    insertTranscription(t);
    7875                }
    79             },
    80             reason => {
    81                 console.log(reason)
    8276            }
    8377        )
    84         .catch(error => console.log("Failed to upload audio files for transcription: " + error)) // TODO: display error to user
    85         .finally(() => $(FILE_UPLOAD_PROGRESS_CONTAINER_NAME).addClass("asr-hidden"));
     78        .catch
     79        (
     80            reason =>
     81            {
     82                insertError(fileName);
     83                console.log(`Transcription for file ${fileName} failed with reason ${reason}`);
     84            }
     85        );
     86    })
     87
     88    // transcribeService.doFetchUpload(files)
     89    //     .then
     90    //     (
     91    //         transcriptions => {
     92    //             // Insert each new transcription
     93    //             for (let t of transcriptions) {
     94    //                 insertTranscription(t);
     95    //             }
     96    //         },
     97    //         reason => {
     98    //             console.log(reason)
     99    //         }
     100    //     )
     101    //     .catch(error => console.log("Failed to upload audio files for transcription: " + error)) // TODO: display error to user
     102    //     .finally(() => $(FILE_UPLOAD_PROGRESS_CONTAINER_NAME).addClass("asr-hidden"));
    86103    return false;
    87104}
     
    90107const transcriptionTemplate = document.querySelector('#transcriptionTemplate');
    91108const metadataTemplate = document.querySelector("#metadataTemplate");
     109const errorTemplate = document.querySelector("#errorTemplate");
    92110
    93111/**
    94  * Inserts a transcription object into the DOM
     112 * Inserts a transcription object into the DOM.
    95113 *
    96114 * @param {TranscriptionModel} transcription The transcription to insert.
    97  * @returns {void} 
    98115 */
    99116function insertTranscription(transcription)
     
    135152}
    136153
     154/**
     155 * Inserts a transcription error into the DOM.
     156 *
     157 * @param {String} fileName
     158 */
     159function insertError(fileName)
     160{
     161    // Get the transcription list and template
     162    let list = document.querySelector("#transcriptionsList");
     163
     164    if (list == null || errorTemplate == null) {
     165        console.error("Could not find transcription list and/or error template");
     166        return;
     167    }
     168
     169    // Insert a new transcription row
     170    let clone = errorTemplate.content.firstElementChild.cloneNode(true);
     171    let spans = clone.querySelectorAll("span");
     172    spans[0].textContent = fileName;
     173
     174    list.appendChild(clone);
     175}
     176
    137177$(FILE_UPLOAD_INPUT_NAME).on("input", toggleUploadButtonState);
    138178
  • main/trunk/model-interfaces-dev/atea/style/asr.css

    r35238 r35243  
    2525.transcription-list-item .spaced-block:last-child {
    2626  margin-bottom: 0;
     27}
     28
     29.error-list-item {
     30  list-style-type: none;
     31  background-color: rgba(255, 0, 0, 0.329);
     32  border: 1px solid rgba(255, 0, 0, 0.651);
     33  border-radius: 5px;
     34  margin-bottom: 5px;
     35  padding: 1em;
    2736}
    2837
  • main/trunk/model-interfaces-dev/atea/transform/pages/asr.xsl

    r35238 r35243  
    3333    <!-- the page content -->
    3434    <xsl:template match="/page">
    35  
    36         <!-- <xsl:choose>
    37             <xsl:when test="$this-element/displayItemList/displayItem[@name='icon']">
    38               <img border="0">
    39                 <xsl:attribute name="src"><xsl:value-of select="$this-element/metadataList/metadata[@name='httpPath']"/>/images/<xsl:value-of select="$this-element/displayItemList/displayItem[@name='icon']"/></xsl:attribute>
    40                 <xsl:attribute name="alt">
    41                   <xsl:value-of select="$this-element/displayItemList/displayItem[@name='name']"/>
    42                 </xsl:attribute>
    43                 <xsl:attribute name="title">
    44                   <xsl:value-of select="util:getInterfaceText($interface_name, /page/@lang, 'aboutpage')"/>
    45                 </xsl:attribute>
    46               </img>       
    47             </xsl:when>     
    48         </xsl:choose> -->
    49        
    5035        <xsl:call-template name="audio-upload"/>
    5136    </xsl:template>
     
    5338    <!-- Template for processing audio file uploads -->
    5439    <xsl:template name="audio-upload">
    55         <link rel="stylesheet" href="interfaces/{$interface_name}/style/asr.css" type="text/css"/>
     40        <link rel="stylesheet" href="interfaces/{$interface_name}/style/asr.css" type="text/css" />
    5641       
    5742        <div>
     
    7055        <div id="transcriptionsDisplayContainer">
    7156            <ul id="transcriptionsList" class="transcription-list"></ul>
    72            
     57
    7358            <template id="transcriptionTemplate">
    7459                <li class="transcription-list-item">
     
    9681            </template>
    9782
     83            <template id="errorTemplate">
     84                <li class="error-list-item">
     85                    <div>
     86                        Transcription failed!<br />
     87                        <b>File: </b><span></span>
     88                    </div>
     89                </li>
     90            </template>
     91
    9892            <template id="metadataTemplate">
    9993                <tr>
Note: See TracChangeset for help on using the changeset viewer.