Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 6 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
AudioXBlock
===========

This is a simple XBlock which will play audio files as an HTML5 audio
element. If unavailable, it will fall back to an embed element.
element and render the transcript as plain text. If unavailable, it will fall back to an embed element.

Usage:

<audio src="http://server.tld/static/song.mp3" />
<audio src="http://server.tld/static/song.mp3" transcript_src="http://transcripts.com/sample.srt"/>

open-edx:

key : "audio"
67 changes: 53 additions & 14 deletions audio/audio.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,17 @@
from xblock.fields import Scope, Integer, String
from xblock.fragment import Fragment

import re
import requests

regex = re.compile(
r'^(?:http|ftp)s?://' # http:// or https://
r'(?:(?:[A-Z0-9](?:[A-Z0-9-]{0,61}[A-Z0-9])?\.)+(?:[A-Z]{2,6}\.?|[A-Z0-9-]{2,}\.?)|' #domain...
r'localhost|' #localhost...
r'\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})' # ...or ip
r'(?::\d+)?' # optional port
r'(?:/?|[/?]\S+)$', re.IGNORECASE)


class AudioXBlock(XBlock):
"""
Expand All @@ -14,34 +25,58 @@ class AudioXBlock(XBlock):

# Fields are defined on the class. You can access them in your code as
# self.<fieldname>.
src = String(
scope = Scope.settings,
help = "URL for MP3 file to play"
)

# this variable holds the source of main media file
src = String(scope=Scope.settings, help="URL for .ogg file to play", default="")
# reference for script file
transcript_src = String(scope=Scope.settings, help="plain text", default="")
# holds the downloadable link of media file
downloadable_src = String(scope=Scope.settings, help="URL for .mp3 file to download", default="")
is_transcript_url_valid = String(scope=Scope.settings, help="transcript url validation flag", default="True")


def resource_string(self, path):
"""Handy helper for getting resources from our kit."""
data = pkg_resources.resource_string(__name__, path)
return data.decode("utf8")

# TO-DO: change this view to display your data your own way.
def student_view(self, context=None):
"""
The primary view of the AudioXBlock, shown to students
when viewing courses.
"""
html = self.resource_string("static/html/audio.html")
frag = Fragment(html.format(src = self.src))
frag.add_css(self.resource_string("static/css/audio.css"))

# Validate transcript link.
if self.transcript_src:
if not regex.match(self.transcript_src):
self.transcript_src = ''
self.is_transcript_url_valid = "False"
else:
r = requests.get(self.transcript_src)
content_type = r.headers['content-type']
if "text/plain" != content_type:
self.transcript_src = ''
self.is_transcript_url_valid = "False"

frag = Fragment(html.format(src=self.src,
transcript_src=self.transcript_src,
downloadable_src=self.downloadable_src,
is_transcript_url_valid=self.is_transcript_url_valid))

frag.add_css(self.resource_string("static/css/audio.scss"))
js = self.resource_string("static/js/src/audio.js")
frag.add_javascript(js)
frag.initialize_js('AudioXBlock')
return frag

def studio_view(self, context):
"""
The view for editing the AudioXBlock parameters inside Studio.
"""
html = self.resource_string("static/html/audio_edit.html")
frag = Fragment(html.format(src=self.src))

frag = Fragment(html.format(src=self.src, transcript_src=self.transcript_src, downloadable_src=self.downloadable_src))
frag.add_css(self.resource_string("static/css/audio_edit.scss"))
js = self.resource_string("static/js/src/audio_edit.js")
frag.add_javascript(js)
frag.initialize_js('AudioEditBlock')
Expand All @@ -54,20 +89,24 @@ def studio_submit(self, data, suffix=''):
Called when submitting the form in Studio.
"""
self.src = data.get('src')
self.transcript_src = data.get('transcript_src')
self.downloadable_src = data.get('downloadable_src')

return {'result': 'success'}

# TO-DO: change this to create the scenarios you'd like to see in the
# workbench while developing your XBlock.
@staticmethod
def workbench_scenarios():
"""A canned scenario for display in the workbench."""
return [
("AudioXBlock",
"""<vertical_demo>
<audio src="http://localhost/Ikea.mp3"> </audio>
<audio src="http://localhost/skull.mp3"> </audio>
<audio src="http://localhost/monkey.mp3"> </audio>
</vertical_demo>
<audio src="https://upload.wikimedia.org/wikipedia/en/4/45/ACDC_-_Back_In_Black-sample.ogg"
transcript_src="http://humanstxt.org/humans.txt"
downloadable_src="sdfsdf.mp3"> </audio>
<audio src=""
transcript_src="sdrfserf.txt"
downloadable_src="fasdf.mp3"> </audio>
</vertical_demo>
"""),
]
9 changes: 0 additions & 9 deletions audio/static/css/audio.css

This file was deleted.

Loading