def build_pdf_topics(main_topic, sections, lang_code): """ Adds the documents from the sections tree to the `main_topic`. - CASE A = no children => add as DocumentNode - CASE B = has children => add as TopicNode and add all children as DocumentNode """ LICENSE = get_license("CC BY-NC-SA", copyright_holder=POINTB) for i, section in enumerate(sections): # CASE A: All sections except Section 2 if 'children' not in section: title = section['title'] abspath = section['path'] filename = os.path.basename(abspath) doc_node = DocumentNode( title=title, description= 'Chapter from A GUIDE TO BECOMING A 21ST CENTURY TEACHER', source_id='%s-%s' % (filename, lang_code), license=LICENSE, aggregator=LE, language=lang_code, role=roles.COACH, files=[DocumentFile(path=abspath, language=lang_code)]) main_topic.add_child(doc_node) # CASE B: Section 2 else: section_topic = TopicNode(title=section['title'], source_id="pointb_section_" + str(i)) main_topic.add_child(section_topic) for subsection in section['children']: title = subsection['title'] abspath = subsection['path'] filename = os.path.basename(abspath) subsection_doc_node = DocumentNode( title=title, description='', source_id='%s-%s' % (filename, lang_code), license=LICENSE, aggregator=LE, language=lang_code, role=roles.COACH, files=[DocumentFile(path=abspath, language=lang_code)]) section_topic.add_child(subsection_doc_node) return main_topic
def googleNode(url): #Get doc id id = getIdFromUrl(url) #Call proper google download function if (url.find('document') != -1): print("Found Document") #Uses download function to get pdf of document, returns filename fileName = downloadDocument(id) elif (url.find('presentation') != -1): print("Found Presentation") #Uses download function to get pdf of powerpoint, returns filename fileName = downloadPowerpoint(id) elif (url.find('spreadsheets') != -1): print("Found Spreadsheet") fileName = downloadSpreadsheet(id) #Use download and filename to create node googleNode = DocumentNode( source_id=id, title=fileName, language="en", description="", license=get_license(licenses.CC_BY, copyright_holder='Copyright holder name'), files=[DocumentFile( path=fileName, language="en", )], ) return googleNode
def invalid_video_file(): local_path = os.path.join("tests", "testcontent", "generated", "invalid_video.mp4") if not os.path.exists(local_path): with open(local_path, 'wb') as f: f.write(b'this is an invalid video file') return DocumentFile(local_path)
def invalid_audio_file(): local_path = os.path.join("tests", "testcontent", "generated", "invalid_audio.mp3") if not os.path.exists(local_path): with open(local_path, 'wb') as f: f.write(b'invalid MP3') return DocumentFile(local_path)
def document_file(): source_url = "https://ia802506.us.archive.org/8/items/generalmanual_000075878/generalmanual_000075878.pdf" local_path = os.path.join("tests", "testcontent", "downloaded", "testdocument.pdf") download_fixture_file(source_url, local_path) assert os.path.exists(local_path) return DocumentFile(local_path)
def pdfNode(infoDict): #Get response from converted-to-pdf path response = requests.get(infoDict['pdfPath'], auth=auth) global pdfCopy if os.path.exists(infoDict['pdfTitle']): infoDict['pdfTitle'] = infoDict['pdfTitle'].replace( ".pdf", str(pdfCopy) + ".pdf") pdfCopy += 1 #Write pdf to local file with open(infoDict['pdfTitle'], 'wb') as f: f.write(response.content) filesCreated.append(infoDict['pdfTitle']) #Create Document Node pdfNode = DocumentNode( source_id=str(infoDict['id']), title=infoDict['pdfTitle'], language="en", description="", license=get_license(licenses.CC_BY, copyright_holder='Copyright holder name'), files=[DocumentFile( path=infoDict['pdfTitle'], language="en", )], ) return pdfNode
def invalid_document_file(): local_path = os.path.join("tests", "testcontent", "generated", "invalid_document.pdf") if not os.path.exists(local_path): with open(local_path, 'wb') as f: f.write(b'invalid PDF') return DocumentFile(local_path)
def get_file(name, directory, filename, title=None): filepath = os.path.join(directory, filename) if title is None: title = name source_id = "{}/{}".format(name, filename) node = None if filename.endswith(".pdf"): node = DocumentNode( title=title, description="Documentación de {}".format(name), source_id=source_id, license=AIEP_License, language="es", files=[DocumentFile( path=filepath, language="es", )], ) elif filename.endswith("h5p"): mp4_file = get_video_from_h5p(filepath) if mp4_file is None: classNode = H5PAppNode classFile = H5PFile else: classNode = VideoNode classFile = VideoFile filepath = mp4_file node = classNode( title=get_title_from_video(title, filename), description="Vídeo explicativo de la {}".format(name), source_id=source_id, license=AIEP_License, language="es", files=[classFile( path=filepath, language="es", )], ) elif filename.endswith("xls"): node = ExerciseNode( source_id=source_id, title="Ejercicios de {}".format(name), author="Equipo de AIEP", description="Preguntas de la unidad 1", language="es", license=AIEP_License, thumbnail=None, exercise_data={ "mastery_model": exercises.M_OF_N, # \ "m": 2, # learners must get 2/3 questions correct to complete "n": 3, # / "randomize": True, # show questions in random order }, questions=leer_preguntas(filepath), ) return node
def add_resources(resources, node, role=LEARNER): for title, url in resources: pdf_node = DocumentNode(source_id = "pdf_"+url, title = title, license = LICENCE, files = [DocumentFile(path=url)], role = role ) node.add_child(pdf_node)
def test_non_existent_epub_fails(self): node = DocumentNode('doc-src-id', "Document", licenses.PUBLIC_DOMAIN, thumbnail=None) non_existent_path = 'does/not/exist.epub' document_file = DocumentFile(non_existent_path, language='en') node.add_file(document_file) config.THUMBNAILS = True filenames = node.process_files() assert filenames == [None], 'expected one None (the non existent epub)' assert len(config.FAILED_FILES) == 1, 'expected one failed file'
def construct_channel(self, *args, **kwargs): """ This method is reponsible for creating a `ChannelNode` object and populating it with `TopicNode` and `ContentNode` children. """ # Create channel ######################################################################## channel = self.get_channel(*args, **kwargs) # uses self.channel_info # Create topics to add to your channel ######################################################################## teen_topic = TopicNode(source_id="topic-teen", title="K-12 Resources") adult_topic = TopicNode(source_id="topic-adult", title="Adult Continue Education Resources") channel.add_child(teen_topic) channel.add_child(adult_topic) level_map = {} for index, teen_level in enumerate(teen_levels): level_map[teen_level] = TopicNode(source_id="topic-teen-" + teen_level, title=teen_level) for index, adult_level in enumerate(adult_levels): level_map[adult_level] = TopicNode(source_id="topic-adult-" + adult_level, title=adult_level) for level, subtopics in parse_website().items(): for subtopic, resources in subtopics.items(): subtopic_node = TopicNode(source_id=subtopic, title=subtopic) for resource in resources: resource_file = DocumentFile(path=resource['link']) resource_pdf = DocumentNode(title=resource['title'], source_id=resource['title'], files=[resource_file], license=get_license( licenses.PUBLIC_DOMAIN)) subtopic_node.add_child(resource_pdf) level_map[level].add_child(subtopic_node) for key, value in level_map.items(): if key in teen_levels: teen_topic.add_child(value) elif key in adult_levels: adult_topic.add_child(value) # the `construct_channel` method returns a ChannelNode that will be # processed by the ricecooker framework return channel
def doc_node(doc, title): if type(doc) == bytes: doc = doc.decode('utf-8') files = [DocumentFile(doc)] if str(doc) in done_nodes: return None done_nodes.append(str(doc)) return DocumentNode( source_id="doc " + str(doc), title=title, license=LICENCE, copyright_holder="nashmi.net", files=files, )
def add_documents(topic, chapters, language): for idx, chapter in enumerate(chapters): # if chapter has 'children' if 'children' in chapter.keys(): doc_title = chapter['title'] child_topic_node = TopicNode(title=doc_title, source_id=language + doc_title, thumbnail=DOWNLOADS_FOLDER + '/thumbnail.png') for child in chapter['children']: child_doc_title = child['title'] doc_node = DocumentNode( title=child_doc_title, description=f'Chapter {idx} from {doc_title}', source_id=language + child_doc_title, license=get_license('CC BY', copyright_holder='NC-SA 4.0'), language=language, thumbnail=DOWNLOADS_FOLDER + '/thumbnail.png', files=[ DocumentFile(path=child['path'], language=language) ], ) child_topic_node.add_child(doc_node) topic.add_child(child_topic_node) else: doc_title = chapter['title'] doc_node = DocumentNode( title=doc_title, description=f'Chapter {idx} from 21ST CENTURY GUIDE', source_id=language + doc_title, license=get_license('CC BY', copyright_holder='NC-SA 4.0'), language=language, thumbnail=DOWNLOADS_FOLDER + '/thumbnail.png', files=[DocumentFile(path=chapter['path'], language=language)], ) topic.add_child(doc_node)
def documentAssignment(material): docPath = "documents/" + slugify( material["driveFile"]["driveFile"]["title"]) + ".pdf" document_node = DocumentNode( source_id=material["driveFile"]["driveFile"]["id"], title=material["driveFile"]["driveFile"]["title"], language=getlang('en').id, license=get_license(licenses.CC_BY, copyright_holder='Copyright holder name'), derive_thumbnail=True, thumbnail=None, files=[DocumentFile(path=str(docPath), language=getlang('en').id)]) print(courseDataCopy["Assignments"]) return document_node
def construct_channel(self, **kwargs): channel = self.get_channel(**kwargs) potato_topic = TopicNode(title="Potatoes!", source_id="<potatos_id>") channel.add_child(potato_topic) doc_node = DocumentNode( title='Growing potatoes', description='An article about growing potatoes on your rooftop.', source_id='pubs/mafri-potatoe', license=get_license('CC BY', copyright_holder='University of Alberta'), language='en', files=[DocumentFile(path='https://www.gov.mb.ca/inr/pdf/pubs/mafri-potatoe.pdf', language='en')], ) potato_topic.add_child(doc_node) return channel
def get_contents(parent, path): doc = get_page(path) try: menu_row = doc.find('div', {'id': 'row-exu'}) except Exception as e: LOGGER.error('get_contents: %s : %s' % (e, doc)) return for content in menu_row.find_all('div', {'class': 'col-md-3'}): try: title = content.find('div', {'class': 'txtline'}).get_text() thumbnail = content.find('a').find('img')['src'] thumbnail = get_absolute_path(thumbnail) main_file, master_file, source_id = get_content_link(content) LOGGER.info(' content: %s: %s' % (source_id, title)) if main_file.endswith('mp4'): video = VideoNode(title=title, source_id=source_id, license=licenses.PUBLIC_DOMAIN, thumbnail=thumbnail, files=[VideoFile(main_file)]) parent.add_child(video) elif main_file.endswith('pdf'): pdf = DocumentNode(title=title, source_id=source_id, license=licenses.PUBLIC_DOMAIN, thumbnail=thumbnail, files=[DocumentFile(main_file)]) parent.add_child(pdf) elif main_file.endswith('html') and master_file.endswith('zip'): zippath = get_zip_file(master_file, main_file) if zippath: html5app = HTML5AppNode( title=title, source_id=source_id, license=licenses.PUBLIC_DOMAIN, thumbnail=thumbnail, files=[HTMLZipFile(zippath)], ) parent.add_child(html5app) else: LOGGER.error('Content not supported: %s, %s' % (main_file, master_file)) except Exception as e: LOGGER.error('get_contents: %s : %s' % (e, content))
def construct_channel(self, **kwargs): channel = self.get_channel(**kwargs) potato_topic = TopicNode(title="Potatoes!", source_id="<potatoes_id>") channel.add_child(potato_topic) document_node = DocumentNode( title="Growing potatoes", description="An article about growing potatoes on your rooftop.", source_id="pubs/mafri-potatoe", license=get_license("CC BY", copyright_holder="University of Alberta"), language="en", files=[ DocumentFile( path="https://www.gov.mb.ca/inr/pdf/pubs/mafri-potatoe.pdf", language="en", ) ], ) potato_topic.add_child(document_node) return channel
def construct_channel(self, **kwargs): channel = self.get_channel(**kwargs) # Soupify goalkicker main page gk_url = 'https://' + self.channel_info['CHANNEL_SOURCE_DOMAIN'] + '/' gk_soup = get_soup(gk_url) # Get urls for each goalkicker book els_with_page_urls = gk_soup.find_all(class_='bookContainer') page_urls = [ gk_url + el.find('a')['href'] for el in els_with_page_urls ] for page_url in page_urls: # Soupify book page page_soup = get_soup(page_url) # Extract and construct book info book_info = parse_book_info(page_soup) book_info['absolute_url'] = page_url + book_info['relative_url'] # Add book to channel tree topic_node_source_id = 'topic/' + book_info['subject'] page_topic_node = TopicNode(title=book_info['subject'], source_id=topic_node_source_id) channel.add_child(page_topic_node) doc_node = DocumentNode( title=book_info['title'], description=book_info['description'], source_id=book_info['source_id'], license=get_license('CC BY-SA', copyright_holder='Creative Commons'), language='en', files=[ DocumentFile(path=book_info['absolute_url'], language='en') ], ) page_topic_node.add_child(doc_node) return channel
def construct_channel(self, *args, **kwargs): """ This method is reponsible for creating a `ChannelNode` object and populating it with `TopicNode` and `ContentNode` children. """ # Create channel ######################################################################## channel = self.get_channel(*args, **kwargs) # uses self.channel_info # Create topics to add to your channel ######################################################################## # Here we are creating a topic named 'Example Topic' exampletopic = TopicNode(source_id="topic-1", title="Example Topic") # TODO: Create your topic here # Now we are adding 'Example Topic' to our channel channel.add_child(exampletopic) # TODO: Add your topic to channel here # You can also add subtopics to topics # Here we are creating a subtopic named 'Example Subtopic' examplesubtopic = TopicNode(source_id="topic-1a", title="Example Subtopic") # TODO: Create your subtopic here # Now we are adding 'Example Subtopic' to our 'Example Topic' exampletopic.add_child(examplesubtopic) # TODO: Add your subtopic to your topic here # Content # You can add documents (pdfs and ePubs), videos, audios, and other content ######################################################################## # let's create a document file called 'Example PDF' document_file = DocumentFile( path="http://www.pdf995.com/samples/pdf.pdf") examplepdf = DocumentNode(title="Example PDF", source_id="example-pdf", files=[document_file], license=get_license(licenses.PUBLIC_DOMAIN)) # TODO: Create your pdf file here (use any url to a .pdf file) # We are also going to add a video file called 'Example Video' video_file = VideoFile( path= "https://ia600209.us.archive.org/27/items/RiceChef/Rice Chef.mp4") fancy_license = get_license( licenses.SPECIAL_PERMISSIONS, description='Special license for ricecooker fans only.', copyright_holder='The chef video makers') examplevideo = VideoNode(title="Example Video", source_id="example-video", files=[video_file], license=fancy_license) # TODO: Create your video file here (use any url to a .mp4 file) # Finally, we are creating an audio file called 'Example Audio' audio_file = AudioFile( path= "https://ia802508.us.archive.org/5/items/testmp3testfile/mpthreetest.mp3" ) exampleaudio = AudioNode(title="Example Audio", source_id="example-audio", files=[audio_file], license=get_license(licenses.PUBLIC_DOMAIN)) # TODO: Create your audio file here (use any url to a .mp3 file) # Now that we have our files, let's add them to our channel channel.add_child(examplepdf) # Adding 'Example PDF' to your channel exampletopic.add_child( examplevideo) # Adding 'Example Video' to 'Example Topic' examplesubtopic.add_child( exampleaudio) # Adding 'Example Audio' to 'Example Subtopic' # TODO: Add your pdf file to your channel # TODO: Add your video file to your topic # TODO: Add your audio file to your subtopic # the `construct_channel` method returns a ChannelNode that will be # processed by the ricecooker framework return channel
def make_random_subtree(parent, depth): for i in range(45): istr = str(i) title = ''.join( random.choice(string.ascii_uppercase + string.digits) for _ in range(10)) description = ''.join( random.choice(string.ascii_uppercase + string.digits) for _ in range(100)) typ = random.choice("tttttttvadh") if typ == 't': topic = TopicNode( source_id=title + istr, title=title, description=description, author=None, language=getlang('en').id, thumbnail=None, ) parent.add_child(topic) if depth > 0: make_random_subtree(topic, depth - 1) elif typ == 'a': content11a = AudioNode( source_id='940ac8ff' + istr, title='Whale sounds', author='First Last (author\'s name)', description='Put file description here', language=getlang('en').id, license=get_license(licenses.CC_BY, copyright_holder='Copyright holder name'), thumbnail=None, files=[], ) parent.add_child(content11a) audio_file = AudioFile( path='./content/ricecooker-channel-files/Whale_sounds.mp3', language=getlang('en').id) content11a.add_file(audio_file) elif typ == 'd': content12a = DocumentNode( source_id='80b7136f' + istr, title= 'The Supreme Court\u2019s Ruling in Brown vs. Board of Education', author='First Last (author\'s name)', description='Put file description here', language=getlang('en').id, license=get_license(licenses.CC_BY, copyright_holder='Copyright holder name'), thumbnail=None, files=[ DocumentFile( path= './content/ricecooker-channel-files/commonlit_the-supreme-court-s-ruling-in-brown-vs-board-of-education_student.pdf', language=getlang('en').id) ]) parent.add_child(content12a) elif typ == 'h': content13a = HTML5AppNode( source_id='302723b4' + istr, title='Sample React app', author='First Last (author\'s name)', description='Put file description here', language=getlang('en').id, license=get_license(licenses.CC_BY, copyright_holder='Copyright holder name'), thumbnail='./content/ricecooker-channel-files/html5_react.jpg', files=[ HTMLZipFile( path= './content/ricecooker-channel-files/html5_react.zip', language=getlang('en').id) ]) parent.add_child(content13a) elif type == 'v': content14a = VideoNode( source_id='9e355995', title='Wave particle duality explained in 2 mins', author='First Last (author\'s name)', description='Put file description here', language=getlang('en').id, license=get_license(licenses.CC_BY, copyright_holder='Copyright holder name'), derive_thumbnail=True, # video-specicig flag thumbnail=None, files=[ VideoFile( path= './content/ricecooker-channel-files/Wave_particle_duality.mp4', language=getlang('en').id) ]) parent.add_child(content14a)
def construct_channel(self, **kwargs): channel = self.get_channel(**kwargs) # Soupify goalkicker main page gk_url = 'https://' + self.channel_info['CHANNEL_SOURCE_DOMAIN'] + '/' gk_soup = get_soup(gk_url) # Get urls for each goalkicker book els_with_page_urls = gk_soup.find_all(class_='bookContainer') page_urls = [ gk_url + el.find('a')['href'] for el in els_with_page_urls ] for book_counter, page_url in enumerate(page_urls): # Soupify book page page_soup = get_soup(page_url) # Extract and construct book info book_info = parse_book_info(page_soup) book_info['absolute_url'] = page_url + book_info['relative_url'] # Add book to channel tree book_node_source_id = 'topic/' + book_info['subject'] book_node = TopicNode(title=book_info['subject'], source_id=book_node_source_id) channel.add_child(book_node) # Use separate download directory for each book's pdf chunks. Avoids name conflicts between books download_dir = 'downloads/book_' + str(book_counter).rjust( 2, '0') + '--' + book_info['subject'] # Get chapters info pdf_path = book_info['absolute_url'] with PDFParser(pdf_path, directory=download_dir) as pdfparser: chapters = pdfparser.split_chapters() # Add chapter nodes for i, chapter in enumerate(chapters): chapter_node_source_id = book_info[ 'source_id'] + '/' + chapter['title'] if chapter['title'].startswith('Chapter'): chapter_num = re.search('Chapter (\d+)', chapter['title']).group(1) chapter_description = 'Chapter ' + chapter_num + ' of the Goalkicker book on ' + book_info[ 'subject'] else: chapter_description = '"' + chapter[ 'title'] + '" section of the Goalkicker book on ' + book_info[ 'subject'] chapter_node = DocumentNode( title=chapter['title'], description=chapter_description, source_id=chapter_node_source_id, license=get_license('CC BY-SA', copyright_holder='Stack Overflow'), language='en', files=[DocumentFile(path=chapter['path'], language='en')], ) book_node.add_child(chapter_node) return channel
def construct_channel(*args, **kwargs): """ Start by creating your channel """ # Let's start by creating your own channel (replace <placeholders> with your own values) channel = ChannelNode( source_domain="vuzy.com", # (e.g. "jamiealexandre.com") source_id="apprentice", # (e.g. "my-sushi-chef") title="My First Try", # (e.g. "My Sushi Chef Channel") ) """ Create topics to add to your channel """ # Here we are creating a topic named 'Example Topic' exampletopic = TopicNode(source_id="topic-1", title="Example Topic") # TODO: Create your topic here # Now we are adding 'Example Topic' to our channel channel.add_child(exampletopic) # TODO: Add your topic to channel here """ You can also add subtopics to topics """ # Here we are creating a subtopic named 'Example Subtopic' examplesubtopic = TopicNode(source_id="topic-1a", title="Example Subtopic") # TODO: Create your subtopic here # Now we are adding 'Example Subtopic' to our 'Example Topic' exampletopic.add_child(examplesubtopic) # TODO: Add your subtopic to your topic here """ You can also add pdfs, videos, and audio files to your channel """ # Next, let's create a document file called 'Example PDF' examplepdf = DocumentNode( title="Example PDF", source_id="example-pdf", files=[DocumentFile(path="http://www.pdf995.com/samples/pdf.pdf")], license=licenses.CC_BY_SA) # TODO: Create your pdf file here (use any url to a .pdf file) # We are also going to add a video file called 'Example Video' examplevideo = VideoNode( title="Example Video", source_id="example-video", files=[ VideoFile( path= "https://ia600209.us.archive.org/27/items/RiceChef/Rice Chef.mp4" ) ], license=licenses.CC_BY_SA) # TODO: Create your video file here (use any url to a .mp4 file) # Finally, we are creating an audio file called 'Example Audio' exampleaudio = AudioNode( title="Example Audio", source_id="example-audio", files=[ AudioFile( path= "https://ia802508.us.archive.org/5/items/testmp3testfile/mpthreetest.mp3" ) ], license=licenses.CC_BY_SA) # TODO: Create your audio file here (use any url to a .mp3 file) # Now that we have our files, let's add them to our channel channel.add_child(examplepdf) # Adding 'Example PDF' to your channel exampletopic.add_child( examplevideo) # Adding 'Example Video' to 'Example Topic' examplesubtopic.add_child( exampleaudio) # Adding 'Example Audio' to 'Example Subtopic' # TODO: Add your pdf file to your channel # TODO: Add your video file to your topic # TODO: Add your audio file to your subtopic return channel
def create_content_nodes(self, channel): """ This function uses the methods `add_child` and `add_file` to build the hierarchy of topic nodes and content nodes. Every content node is associated with the underlying file node. """ content_nodes_folder = TopicNode( source_id='121232ms', title='Content Nodes', description='Put folder description here', author=None, language=getlang('en').id, thumbnail=None, ) channel.add_child(content_nodes_folder) # AUDIO audio_nodes_folder = TopicNode( source_id='138iuh23iu', title='Audio Files', description='Put folder description here', author=None, language=getlang('en').id, thumbnail=None, ) content_nodes_folder.add_child(audio_nodes_folder) audio_node = AudioNode( source_id='940ac8ff', title='Whale sounds', author='First Last (author\'s name)', description='Put file description here', language=getlang('en').id, license=get_license(licenses.CC_BY, copyright_holder='Copyright holder name'), thumbnail=None, files=[], ) audio_nodes_folder.add_child(audio_node) audio_file = AudioFile( path='./content/ricecooker-channel-files/Whale_sounds.mp3', language=getlang('en').id) audio_node.add_file(audio_file) # DOCUMENTS documents_folder = TopicNode( source_id='asanlksnaklsn', title='Document Nodes', description='Put folder description here', author=None, language=getlang('en').id, thumbnail=None, ) content_nodes_folder.add_child(documents_folder) document_node = DocumentNode( source_id='80b7136f', title= 'The Supreme Court\u2019s Ruling in Brown vs. Board of Education', author='First Last (author\'s name)', description='Put file description here', language=getlang('en').id, license=get_license(licenses.CC_BY, copyright_holder='Copyright holder name'), thumbnail=None, files=[ DocumentFile( path= './content/ricecooker-channel-files/commonlit_the-supreme-court-s-ruling-in-brown-vs-board-of-education_student.pdf', language=getlang('en').id) ]) documents_folder.add_child(document_node) # HTML5 APPS html5apps_folder = TopicNode( source_id='asasa331', title='HTML5App Nodes', description='Put folder description here', author=None, language=getlang('en').id, thumbnail=None, ) content_nodes_folder.add_child(html5apps_folder) html5_node_a = HTML5AppNode( source_id='302723b4', title='Sample React app', author='First Last (author\'s name)', description='Put file description here', language=getlang('en').id, license=get_license(licenses.CC_BY, copyright_holder='Copyright holder name'), thumbnail='./content/ricecooker-channel-files/html5_react.jpg', files=[ HTMLZipFile( path='./content/ricecooker-channel-files/html5_react.zip', language=getlang('en').id) ]) html5apps_folder.add_child(html5_node_a) html5_node_b = HTML5AppNode( source_id='3f91184e', title='Sample Vue.js app', author='First Last (author\'s name)', description='Put file description here', language=getlang('en').id, license=get_license(licenses.CC_BY, copyright_holder='Copyright holder name'), thumbnail='./content/ricecooker-channel-files/html5_vuejs.jpg', files=[ HTMLZipFile( path='./content/ricecooker-channel-files/html5_vuejs.zip', language=getlang('en').id) ]) html5apps_folder.add_child(html5_node_b) html5_node_c = HTML5AppNode( source_id='0aec4296', title='Sample wget-scraped web content', author='First Last (author\'s name)', description='Put file description here', language=getlang('en').id, license=get_license(licenses.CC_BY, copyright_holder='Copyright holder name'), thumbnail= './content/ricecooker-channel-files/html5_wget_scraped.jpg', files=[ HTMLZipFile( path= './content/ricecooker-channel-files/html5_wget_scraped.zip', language=getlang('en').id) ]) html5apps_folder.add_child(html5_node_c) # VIDEOS videos_folder = TopicNode( source_id='121213m3m3', title='Video Nodes', description='Put folder description here', author=None, language=getlang('en').id, thumbnail=None, ) content_nodes_folder.add_child(videos_folder) video_node = VideoNode( source_id='9e355995', title='Wave particle duality explained in 2 mins', author='First Last (author\'s name)', description='Put file description here', language=getlang('en').id, license=get_license(licenses.CC_BY, copyright_holder='Copyright holder name'), derive_thumbnail=True, # video-specicig flag thumbnail=None, files=[ VideoFile( path= './content/ricecooker-channel-files/Wave_particle_duality.mp4', language=getlang('en').id) ]) videos_folder.add_child(video_node)
def add_node_document(booklist, level_topic, as_booklist): """ Add books as DocumentNode under a specific level of reading. Parameters: * booklist - The list of books to be added as DocumentNodes * level_topic - The TopicNode regarding current level that the DocumentNodes will be attached to * as_booklist - The list of books from African Storybooks """ for item in booklist: # Initialize the source domain and content_id domain = uuid.uuid5(uuid.NAMESPACE_DNS, "storyweaver.org.in") book_id = str(item["source_id"]) # If the publisher is AS and the book is found, # then change the source_domain and content_id if item["publisher"] == "African Storybook Initiative": check = check_if_story_in_AS(as_booklist, item["title"]) if check[0]: domain = uuid.uuid5(uuid.NAMESPACE_DNS, "www.africanstorybook.org") book_id = check[1] # Given that StoryWeaver provides the link to a zip file, # we will download the zip file and extract the pdf file from it with tempfile.NamedTemporaryFile(suffix=".zip") as tempf: try: resp = downloader.make_request(item["link"], clear_cookies=False) resp.raise_for_status() tempf.write(resp.content) except Exception as e: # Do not create the node if download fails LOGGER.info("Error: {} when downloading {}".format( e, item["link"])) continue filename = "" with zipfile.ZipFile(tempf.name, "r") as f: for zipped_file in f.namelist(): if os.path.splitext(zipped_file)[1][1:] == "pdf": tempdir = os.path.dirname(tempf.name) f.extract(zipped_file, path=tempdir) filename = os.path.join(tempdir, zipped_file) break # If no pdf file has been found in the zip, do not create the node if not filename: continue # Create the document node with given information document_file = DocumentFile(path=filename) language_obj = getlang_by_name(item["language"]) book = DocumentNode( title=item["title"], source_id=book_id, author=item["author"], provider=item["publisher"], files=[document_file], license=get_license(licenses.CC_BY, copyright_holder="StoryWeaver"), thumbnail=item.get("thumbnail"), description=item["description"], domain_ns=domain, language=language_obj, ) level_topic.add_child(book)
def document_file(base_file_path): return DocumentFile(base_file_path)
def create_content_nodes(self, channel): """ This function uses the methods `add_child` and `add_file` to build the hierarchy of topic nodes (nested folder structure) and content nodes. Every content node is associated with one or more files. """ content_nodes_folder = TopicNode( source_id='uniqid001', title='Content Nodes', description='Put folder description here', author=None, language=getlang('en').id, thumbnail=None, ) channel.add_child(content_nodes_folder) # AUDIO audio_nodes_folder = TopicNode( source_id='uniqid002', title='Audio Files Folder', description='Put folder description here', author=None, language=getlang('en').id, thumbnail=None, ) content_nodes_folder.add_child(audio_nodes_folder) audio_node = AudioNode( source_id='uniqid003', title='Whale sounds', author='First Last (author\'s name)', description='Put file description here', language=getlang('en').id, license=get_license(licenses.CC_BY, copyright_holder='Copyright holder name'), thumbnail=None, files=[], ) audio_nodes_folder.add_child(audio_node) audio_file = AudioFile( path= './content/ricecooker-channel-files/Whale_sounds.mp3', # note path can also be a URL language=getlang('en').id) audio_node.add_file(audio_file) # DOCUMENTS documents_folder = TopicNode( source_id='uniqid004', title='Document Nodes', description='Put folder description here', author=None, language=getlang('en').id, thumbnail=None, ) content_nodes_folder.add_child(documents_folder) document_node = DocumentNode( source_id='uniqid005', title= 'The Supreme Court\u2019s Ruling in Brown vs. Board of Education', author='First Last (author\'s name)', description='Put file description here', language=getlang('en').id, license=get_license(licenses.CC_BY, copyright_holder='Copyright holder name'), thumbnail=None, files=[ DocumentFile( path= './content/ricecooker-channel-files/brown-vs-board-of-education.pdf', language=getlang('en').id) ]) documents_folder.add_child(document_node) # HTML5 APPS html5apps_folder = TopicNode( source_id='uniqid006', title='HTML5App Nodes', description='Put folder description here', author=None, language=getlang('en').id, thumbnail=None, ) content_nodes_folder.add_child(html5apps_folder) html5_node = HTML5AppNode( source_id='uniqid007', title='HTMLWeb capabilities test', author='First Last (author\'s name)', description= 'Tests different HTML/JS capabilities. What capabilities are allowed and disallowed by the sandboxed iframe used to render HTML5App nodes on Kolibri.', language=getlang('en').id, license=get_license(licenses.CC_BY, copyright_holder='Copyright holder name'), thumbnail='./content/ricecooker-channel-files/html5_tests.jpg', files=[ HTMLZipFile( path='./content/ricecooker-channel-files/html5_tests.zip', language=getlang('en').id) ]) html5apps_folder.add_child(html5_node) html5_node2 = HTML5AppNode( source_id='uniqid008', title='Sample Vue.js app', author='First Last (author\'s name)', description='Put file description here', language=getlang('en').id, license=get_license(licenses.CC_BY, copyright_holder='Copyright holder name'), thumbnail='./content/ricecooker-channel-files/html5_vuejs.jpg', files=[ HTMLZipFile( path='./content/ricecooker-channel-files/html5_vuejs.zip', language=getlang('en').id) ]) html5apps_folder.add_child(html5_node2) # VIDEOS videos_folder = TopicNode( source_id='uniqid009', title='Video Nodes', description='Put folder description here', author=None, language=getlang('en').id, thumbnail=None, ) content_nodes_folder.add_child(videos_folder) video_node = VideoNode( source_id='uniqid010', title='Wave particle duality explained in 2 mins', author='First Last (author\'s name)', description='Put file description here', language=getlang('en').id, license=get_license(licenses.CC_BY, copyright_holder='Copyright holder name'), derive_thumbnail=True, # video-specicig flag thumbnail=None, files=[ VideoFile( path= './content/ricecooker-channel-files/Wave_particle_duality.mp4', language=getlang('en').id) ]) videos_folder.add_child(video_node) youtube_id = 'VJyk81HmcZQ' video_node2 = VideoNode( source_id=youtube_id, # usually set source_id to youtube_id title='Estimating division that results in non whole numbers', author='Sal Khan', description='Video description would go here', language=getlang('en').id, license=get_license(licenses.CC_BY, copyright_holder='Khan Academy'), derive_thumbnail=True, # video-specicig flag thumbnail=None, files=[ YouTubeVideoFile(youtube_id=youtube_id, high_resolution=False, language='en'), YouTubeSubtitleFile(youtube_id=youtube_id, language='ko') ]) videos_folder.add_child(video_node2)