def construct_channel(self, *args, **kwargs): channel = self.get_channel(**kwargs) videos_topic = TopicNode(source_id="/wiki/Category:Articles_containing_video_clips", title="Articles containing video clips") channel.add_child(videos_topic) thumbnail_url = 'https://upload.wikimedia.org/wikipedia/commons/thumb/e/ee/A_Is_for_Atom_1953.webm/220px--A_Is_for_Atom_1953.webm.jpg' page = download_wikipedia_page('/wiki/Category:Articles_containing_video_clips', thumbnail_url, 'A Is for Atom') videos_topic.add_child(page) video_url = 'https://upload.wikimedia.org/wikipedia/commons/e/ee/A_Is_for_Atom_1953.webm' video_file = VideoFile(path=video_url) video_node = VideoNode(title='A Is for Atom 1953', source_id='A_Is_for_Atom_1953.webm', files=[video_file], license=licenses.PublicDomainLicense()) subtitle_url = 'https://commons.wikimedia.org/w/api.php?action=timedtext&title=File%3AA_Is_for_Atom_1953.webm&lang={}&trackformat=srt' subtitle_languages = [ 'en', 'es', ] for lang in subtitle_languages: subtitle_file = SubtitleFile(path=subtitle_url.format(lang), language=lang, subtitlesformat='srt') video_node.add_file(subtitle_file) videos_topic.add_child(video_node) return channel
def construct_channel(self, **kwargs): channel = self.get_channel(**kwargs) old_title = None old_group = None i = 0 for metadata, zfilename, [title, group] in index.no_dl_index(): i = i + 1 if title != old_title: old_title = title title_node = TopicNode(source_id=title + str(i), title=replace(title)) channel.add_child(title_node) old_group = None if group != old_group: old_group = group group_node = TopicNode(source_id=title + group + str(i + 0.5), title=replace(group)) title_node.add_child(group_node) doc_node = HTML5AppNode( title=metadata.title, description=metadata.description, source_id=zfilename + str(i + 0.9), license=LICENCE, language='es', files=[HTMLZipFile(path=zfilename)], ) group_node.add_child(doc_node) return channel
def construct_channel(self, **kwargs): # create channel channel = self.get_channel(**kwargs) # create a topic "Ebooks" and add it to channel topic = TopicNode( source_id="ebooksfolder", title="Ebooks", language=languages.getlang('en').code, ) channel.add_child(topic) # Create an ePub file and add ePub file to a DocumentNode epub_file = EPubFile( path='samplefiles/documents/laozi_tao-te-ching.epub') doc_node = DocumentNode( source_id="<en_doc_id>", title='Tao Te Ching', author='Lao Zi', description='This is a sample epub document', license=licenses.PUBLIC_DOMAIN, language=languages.getlang('en').code, files=[epub_file], ) # Add document node to the topic topic.add_child(doc_node) return channel
def get_things(all_things, parent_node, new_node=True): for thing in all_things: _id = thing.url.strip('/').split('/')[-1] # TODO hash if new_node: this_node = TopicNode(source_id = thing.url, title=thing.title) else: this_node = parent_node content_node = make_youtube_video(thing.youtube, "Video: {}".format(thing.title), "video__{}".format(thing.url)) # TODO hash if content_node is not None: this_node.add_child(content_node) try: os.mkdir('html') except Exception: pass fn = "html/{}.zip".format(_id) with open(fn, "wb") as f: f.write(thing.app) app_zip = HTMLZipFile(fn) if thing.title[0] in "AEIOUaeiou": an = "an" else: an = "a" app_node = HTML5AppNode(source_id = "app_{}".format(thing.url), title = "Being {} {}".format(an, thing.title), license = LICENCE, files=[app_zip]) this_node.add_child(app_node) if new_node: parent_node.add_child(this_node)
def construct_channel(self, **kwargs): channel = self.get_channel(**kwargs) for name, _id in catnum.items(): cat_node = TopicNode(source_id=str(_id), title=name) channel.add_child(cat_node) links = crawl.get_all_links(_id) for link in list(links): zipfilename, title = localise.zip_from_url(link) appzip = HTMLZipFile(zipfilename) if os.path.exists(zipfilename + "_2.jpg"): thumb = ThumbnailFile(zipfilename + "_2.jpg") else: thumb = None zipnode = HTML5AppNode(source_id=link, title=title, license=licenses.CC_BY, copyright_holder=CHANNEL_NAME, files=[appzip], author=crawl.author_lookup[link], thumbnail=thumb) zipnode.validate() cat_node.add_child(zipnode) cat_node.validate() print("DONE") return channel
def get_files(topic_name, directory, files): topic = TopicNode(title=topic_name, source_id="{}_id".format(topic_name)) for filename in files: if filename.endswith("h5p"): title = None else: title = os.path.splitext(filename)[0] node = get_file(topic_name, directory, filename, title) if node: topic.add_child(node) return topic
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 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_course(course, base_path): topic = TopicNode(title=course, source_id="{}_id".format(course)) course_dir = os.path.join(base_path, course) course_contents = os.listdir(course_dir) course_contents.sort() for f in course_contents: content = os.path.join(course_dir, f) if os.path.isdir(content): total_files = os.listdir(content) if len(total_files) > 1: node = get_files(f, content, total_files) if node: topic.add_child(node) elif len(total_files) == 1: topic.add_child(get_file(f, content, total_files[0])) return topic
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 make_topic_for_settings(title, ffmpeg_settings): """ Assumes global VIDEO_URLS available. """ topic = TopicNode( source_id=title, title=title, description='', author=None, language=getlang('en').id, thumbnail=None, ) for counter, video_url in enumerate(VIDEO_URLS): vid_number = counter + 1 video_title = 'Video ' + str(vid_number) video_node = make_video_node(video_title, video_url, ffmpeg_settings=ffmpeg_settings) topic.add_child(video_node) return topic
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, **kwargs): if not download_pdfs(): print('==> Download of PDFS FAILED!') return False chapters_en = split_chapters(LANG_CODE_EN) if chapters_en is None: print('==> Split chapters for en PDFs FAILED!') return False chapters_my = split_chapters(LANG_CODE_MY) if chapters_en is None: print('==> Split chapters for my PDFs FAILED!') return False channel = self.get_channel(**kwargs) # English topics main_topic = TopicNode(title="English", source_id="pointb_en_main") topic_guide = TopicNode(title="21st Century Guide", source_id="pointb_en_topic") topic_videos_en = TopicNode(title="Videos", source_id="pointb_en_videos") main_topic.add_child(topic_guide) main_topic.add_child(topic_videos_en) # Burmese topics main_topic_my = TopicNode(title="Burmese", source_id="pointb_my_main") topic_guide_my = TopicNode(title="21st Century Guide", source_id="pointb_my_guide") topic_videos_my = TopicNode(title="Videos", source_id="pointb_my_videos") main_topic_my.add_child(topic_guide_my) main_topic_my.add_child(topic_videos_my) channel.add_child(main_topic) channel.add_child(main_topic_my) # English topics build_pdf_topics(topic_guide, chapters_en, lang_code=LANG_CODE_EN) # Burmese topics build_pdf_topics(topic_guide_my, chapters_my, lang_code=LANG_CODE_MY) # English videos topic = build_english_video_topics(topic_videos_en) # Burmese videos topic = build_burmese_video_topics(topic_videos_my) return channel
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 test_generate_tiled_thumbnail(self, document, html, video, audio): topic = TopicNode('test-topic', 'Topic') topic.add_child(document) topic.add_child(html) topic.add_child(video) topic.add_child(audio) config.THUMBNAILS = True for child in topic.children: # must process children before topic node child.process_files() filenames = topic.process_files() assert len(filenames) == 1, 'expected one filename' self.check_has_thumbnail(topic)
def construct_channel(self, **kwargs): channel = self.get_channel(**kwargs) for cat in index_root.get_children(): cat_node = TopicNode("__" + str(cat._id), cat.name) channel.add_child(cat_node) for subcat in cat.get_children(): subcat_node = TopicNode("__" + str(subcat._id), subcat.name) cat_node.add_child(subcat_node) for article in subcat.get_children(): print("article: ", article.name) article_node = TopicNode("__" + str(article._id), article.name) subcat_node.add_child(article_node) htmlnode, videonodes = detail.handle_lesson(article) article_node.add_child(htmlnode) for video in videonodes: article_node.add_child(video) return channel # outdent for real version
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 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(self, **kwargs): 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 get_things(all_things, parent_node, new_node=True): for thing in all_things: _id = thing.url.strip('/').split('/')[-1] # TODO hash if new_node: this_node = TopicNode(source_id = thing.url, title=thing.title) else: this_node = parent_node content_node = make_youtube_video(thing.youtube, "Video: {}".format(thing.title), "video__{}".format(thing.url)) # TODO hash if content_node is not None: this_node.add_child(content_node) try: os.mkdir('html') except Exception: pass fn = "html/{}.zip".format(_id) with open(fn, "wb") as f: f.write(thing.app) app_zip = HTMLZipFile(fn) if thing.title[0] in "AEIOUaeiou": an = "an" else: an = "a" app_node = HTML5AppNode(source_id = "app_{}".format(thing.url), title = "Being {} {}".format(an, thing.title), license = LICENCE, files=[app_zip]) this_node.add_child(app_node) if new_node: parent_node.add_child(this_node) video_list = [] video_set = set() channel = self.get_channel(**kwargs) role_node = TopicNode(source_id="roles", title="Career Clusters") life_skill_node = TopicNode(source_id="lifeskills", title="Life Skills") lessons_node = TopicNode(source_id = "lessons", title = "Career-Based Empowerment Lessons", description = "What is your passion? What are you good at? Whether you think you want to be a fashion designer, a filmmaker, an engineer, or something else, these are two questions you might ask yourself when you think about a career. Watch our role models to learn more.") resources_node = TopicNode(source_id="resources", title="Student Resources") skill_node = TopicNode(source_id="skill", title="Skill-Based Empowerment Lessons") major_node = TopicNode(source_id="major", title="College Majors and Requirements") advice_node = TopicNode(source_id="advice", title="College Advice") educators_node = TopicNode(source_id="edu", title="Educators, Parents and Mentors") channel.add_child(role_node) channel.add_child(lessons_node) channel.add_child(resources_node) channel.add_child(skill_node) channel.add_child(major_node) channel.add_child(advice_node) channel.add_child(educators_node) import majors for app in majors.apps: major_node.add_child(app) if DEBUG: return channel import educators for app in educators.apps: educators_node.add_child(app) for title, resources in educators.resources: node = TopicNode(source_id="edu"+title, title=title) educators_node.add_child(node) add_resources(resources, node, COACH) # college advice and lifeskills import advice for id_, title in advice.videos: advice_node.add_child(make_youtube_video(id_, title, id_)) add_resources(advice.resources, advice_node) import skills for id_, title in skills.videos: skill_node.add_child(make_youtube_video(id_, title, id_)) add_resources(skills.resources, skill_node) if DEBUG: return channel _lessons, resources = lessons.lesson_index() for lesson in _lessons: lesson_node = TopicNode(source_id=lesson.title, title=lesson.title, description=lesson.description) for video in lesson.video_ids: lesson_video = make_youtube_video(video, lesson.title, video) lesson_node.add_child(lesson_video) add_resources(lesson.resources, lesson_node) lessons_node.add_child(lesson_node) add_resources(lessons.student_resources(), resources_node) #return channel # TODO all_life_skills = list(cg_index.all_life_skills()) get_things(all_life_skills, life_skill_node) all_jobs = list(cg_index.all_jobs())# # each job has a job.title. # TODO WRONG get_things(all_jobs, job_node) -- reimplement # role models # setup top_lookup = {} second_lookup = {} for top in clusters.top: node = TopicNode(source_id = "role_top_"+top, title = top, description = clusters.cluster_meta[top]['desc'], thumbnail = ThumbnailFile(urljoin("https://careergirls.org/", clusters.cluster_meta[top]['img']))) top_lookup[top] = node role_node.add_child(node) for top, second in clusters.second: node = TopicNode(source_id = "role_top_"+top+"_"+second, title = second) second_lookup[tuple([top, second])] = node top_lookup[top].add_child(node) # add "Jobs" tree segment which is relevant relevant_jobs = [x for x in all_jobs if x.title == second] assert relevant_jobs, "No job for " + repr(second) get_things(relevant_jobs, node, new_node=False) # dragon ^^^ untested role_urls = set() # populate role_urls with list of all job titles for job in all_jobs: for role in job.roles: role_urls.add(role) for role_url in sorted(list(role_urls)): _id = role_url.strip('/').split('/')[-1] role = cg_index.index_role(role_url) role_found= False for cluster_role in clusters.role_data: if cluster_role[3] in role_url: ## this section was outside the loop before this_role = TopicNode(source_id = "role__{}_{}".format(_id, disambig()), title="{}, {}".format(role.title, role.name), description = role.bio) for v_id, v_name in zip(role.video_ids, role.video_names): if v_id is not None: video_node = make_youtube_video(v_id[0], v_name[0], v_id[0]) this_role.add_child(video_node) video_list.append(v_id[0]) video_set.add(v_id[0]) ## end section that was outside the loop before second_lookup[tuple(cluster_role[:2])].add_child(this_role) role_found = True assert role_found, role_url # role_node.add_child(this_role) print ("DONE") # todo? : role.skill_links, role.skill_names 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 (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)
def create_exercise_nodes(self, channel): """ This function adds a few exercise nodes to the channel content tree. TODO: handle exercises with embedded image links + base64 encoded data. """ # EXERCISES exercices_folder = TopicNode( source_id='uniqid011', title='Exercise Nodes', description='Put folder description here', author=None, language=getlang('en').id, thumbnail=None, ) channel.add_child(exercices_folder) exercise1 = ExerciseNode( source_id='uniqid012', title='Basic questions', author='LE content team', description= 'Showcase of the simple exercises supported by Ricecooker and Studio', language=getlang('en').id, license=get_license(licenses.CC_BY, copyright_holder='Copyright holder name'), thumbnail=None, exercise_data={ 'mastery_model': exercises.M_OF_N, # or exercises.DO_ALL 'randomize': True, 'm': 2, 'n': 3, }, questions=[ MultipleSelectQuestion( id='ex2aQ1', question= "Which numbers are even?\n\nTest local image include: ![](content/ricecooker-channel-files/html5_vuejs.jpg)", correct_answers=[ "2", "4", ], all_answers=["1", "2", "3", "4", "5"], hints=[ "There are two answers.", "Both answers are multiples of two." ]), SingleSelectQuestion( id='ex2aQ2', question="What is 2 times 3?", correct_answer="6", all_answers=["2", "3", "5", "6"], ), InputQuestion( id='ex2aQ3', question="Name a factor of 10.", answers=["1", "2", "5", "10"], ) ]) exercices_folder.add_child(exercise1) # LOAD JSON DATA (as string) FOR PERSEUS QUESTIONS SAMPLE_PERSEUS_4_JSON = open( './content/ricecooker-channel-files/perseus_graph_question.json', 'r').read() exercise2 = ExerciseNode( source_id='baszzzs1', title='Perseus questions', author='LE content team', description='An example exercise with Persus questions', language=getlang('en').id, license=get_license(licenses.CC_BY, copyright_holder='Copyright holder name'), thumbnail=None, exercise_data={ 'mastery_model': exercises.M_OF_N, # or exercises.DO_ALL 'randomize': True, 'm': 1, 'n': 1, }, questions=[ PerseusQuestion( id='ex2bQ4', raw_data=SAMPLE_PERSEUS_4_JSON, source_url= 'https://github.com/learningequality/sample-channels/blob/master/contentnodes/exercise/sample_perseus04.json' ), ]) exercices_folder.add_child(exercise2)
def construct_channel(self, **kwargs): def video_node(video, subtitle, data): if subtitle: files = [video, subtitle] else: files = [video] return VideoNode( source_id=data['link'], title=data['link'], license=licenses.CC_BY_NC_SA, copyright_holder="JFK Center for the Performing Arts", files=files, ) # create channel _id = 0 _subid = 0 channel = self.get_channel(**kwargs) # create a topic and add it to channel data = {} urls = set() for item in lessons: topic = TopicNode( "__" + item, item, "Resources for {} school students".format(item.lower())) channel.add_child(topic) for lesson in lessons[item]: print(lesson) if ':' in lesson.title: title = lesson.title.partition(":")[2] else: title = lesson.title lesson_node = TopicNode("__{}".format(_id), title, "") _id = _id + 1 topic.add_child(lesson_node) urls.add(lesson.link) sources = set() old_text = None subnode = None html_response = requests.get( urljoin("https://artsedge.kennedy-center.org/", lesson.link)) html_response.raise_for_status() soup = BeautifulSoup(html_response.content, "html5lib") zipfile_name = localise.make_local( soup, urljoin("https://artsedge.kennedy-center.org/", lesson.link)) print("HTML Filesize: ", os.path.getsize(zipfile_name), os.path.abspath(zipfile_name)) html_node = add_file.create_node(HTMLZipFile, filename=zipfile_name, title=title) lesson_node.add_child(html_node) for text, node in get_lesson( urljoin("https://artsedge.kennedy-center.org/", lesson.link)): print(repr(text), repr(old_text)) if not text: text = "Discussion" if text != old_text: subnode = TopicNode("__SUB_{}".format(_subid), text[0] + text[1:].lower(), "") _subid = _subid + 1 old_text = text lesson_node.add_child(subnode) if node.source_id in sources: # skip duplicates continue subnode.add_child(node) sources.add(node.source_id) return channel
def construct_channel(self, *args, **kwargs): """ Create ChannelNode and build topic tree. """ channel = self.get_channel( *args, **kwargs) # create ChannelNode from data in self.channel_info topic1 = TopicNode( source_id='121232ms', title='Content Nodes', description='Put folder description here', author=None, language=getlang('en').id, thumbnail=None, ) channel.add_child(topic1) # HTML5 APPS topic13 = TopicNode( source_id='asasa331', title='HTML5App Nodes', description='Put folder description here', author=None, language=getlang('en').id, thumbnail=None, ) topic1.add_child(topic13) content13a = HTML5AppNode( source_id='302723b4', title='Shared Zip File 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=None, files=[ HTMLZipFile(path='./content/zipfiles/shared.zip', language=getlang('en').id) ]) topic13.add_child(content13a) content13b = HTML5AppNode( source_id='302723b5', title='Thin app 1', 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=[ HTMLZipFile(path='./content/zipfiles/thinapp1.zip', language=getlang('en').id) ]) topic13.add_child(content13b) raise_for_invalid_channel(channel) return channel
def construct_channel(self, **kwargs): channel = self.get_channel(**kwargs) #Create each topic node for t_id, t_info in courseData['Topics'].items(): topic = TopicNode(title=t_info['name'], source_id=t_info['topicId'], derive_thumbnail=True, thumbnail=None) channel.add_child(topic) #iterate through assignments and add them if they match the assingnment topic for a_id, a_info in courseData['Assignments'].items(): if 'topicId' in a_info and a_info['topicId'] == t_info[ 'topicId']: assignment = addAssignment(a_info) topic.add_child(assignment) if "materials" in a_info: #iterate through materials in the current assignment and add them if they match the material type for spec_mat in a_info["materials"]: if "youtubeVideo" in spec_mat: assignment.add_child(videoAssignment(spec_mat)) elif "link" in spec_mat: assignment.add_child(linkAssignment(spec_mat)) #Add this case with web scraping elif "form" in spec_mat: assignment.add_child(formAssignment(spec_mat)) #Might not add this case elif "driveFile" in spec_mat: assignment.add_child( documentAssignment(spec_mat)) elif 'topicId' not in a_info and a_id in courseDataCopy[ "Assignments"]: assignment = addAssignment(a_info) channel.add_child(assignment) if "materials" in a_info: for spec_mat in a_info["materials"]: if "youtubeVideo" in spec_mat: assignment.add_child(videoAssignment(spec_mat)) elif "link" in spec_mat: assignment.add_child(linkAssignment(spec_mat)) #Add this case with web scraping elif "form" in spec_mat: assignment.add_child(formAssignment(spec_mat)) #Might not add this case elif "driveFile" in spec_mat: assignment.add_child( documentAssignment(spec_mat)) del courseDataCopy['Assignments'][a_id] 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 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 create_exercise_nodes(self, channel): """ This function adds a few exercise nodes to the channel content tree. TODO: handle exercises with embedded image links + base64 encoded data. """ # EXERCISES exercices_folder = TopicNode( source_id='mdmdmai3i13', title='Exercise Nodes', description='Put folder description here', author=None, language=getlang('en').id, thumbnail=None, ) channel.add_child(exercices_folder) exercise2a = ExerciseNode( source_id='asisis9', title='Basic questions', author='LE content team', description= 'Showcase of the simple exercises supported by Ricecooker and Studio', language=getlang('en').id, license=get_license(licenses.CC_BY, copyright_holder='Copyright holder name'), thumbnail=None, exercise_data={ 'mastery_model': exercises.M_OF_N, # or exercises.DO_ALL 'randomize': True, 'm': 2, 'n': 3, }, questions=[ MultipleSelectQuestion( id='ex2aQ1', question="Which numbers are even?", correct_answers=[ "2", "4", ], all_answers=["1", "2", "3", "4", "5"], # hints? ), SingleSelectQuestion( id='ex2aQ2', question="What is 2 times 3?", correct_answer="6", all_answers=["2", "3", "5", "6"], # hints? ), InputQuestion( id='ex2aQ3', question="Name a factor of 10.", answers=["1", "2", "5", "10"], # hints? ) ]) exercices_folder.add_child(exercise2a) # LOAD JSON DATA (as string) FOR PERSEUS QUESTIONS SAMPLE_PERSEUS_4_JSON = open( './content/ricecooker-channel-files/sample_perseus04.json', 'r').read() exercise2b = ExerciseNode( source_id='baszzzs1', title='Perseus questions', author='LE content team', description='An example exercise with Persus questions', language=getlang('en').id, license=get_license(licenses.CC_BY, copyright_holder='Copyright holder name'), thumbnail=None, exercise_data={ 'mastery_model': exercises.M_OF_N, # or exercises.DO_ALL 'randomize': True, 'm': 2, 'n': 3, }, questions=[ PerseusQuestion( id='ex2bQ4', raw_data=SAMPLE_PERSEUS_4_JSON, source_url= 'https://github.com/learningequality/sample-channels/blob/master/contentnodes/exercise/sample_perseus04.json' ), ]) exercices_folder.add_child(exercise2b) SAMPLE_PERSEUS_4_dhanam4_JSON = open( './content/ricecooker-channel-files/sample_perseus04dhanam4.json', 'r').read() exercise2b_dhanam4 = ExerciseNode( source_id='test_dhanam4', title='Perseus question by dhanam4', author='dhanam4', description='dhanam4\'s example exercise with Persus questions', language=getlang('en').id, license=get_license(licenses.CC_BY, copyright_holder='dhanam4'), thumbnail=None, exercise_data={ 'mastery_model': exercises.M_OF_N, # or exercises.DO_ALL 'randomize': True, 'm': 2, 'n': 3, }, questions=[ PerseusQuestion( id='test_ex2bQ4dhanam4', raw_data=SAMPLE_PERSEUS_4_dhanam4_JSON, source_url= 'doesnt matter what goes here.. used for information purposes only' ), ]) exercices_folder.add_child(exercise2b_dhanam4)