<commit_before># Rice Cooker

A framework for creating channels on [Kolibri Studio](https://contentworkshop.learningequality.org/).


## Installation

* [Install pip](https://pypi.python.org/pypi/pip) if you don't have it already.

* Run `pip install ricecooker`

* You can now reference ricecooker using `import ricecooker` in your .py files


## Using the Rice Cooker

A sample program has been created [here](https://github.com/learningequality/ricecooker/blob/master/ricecooker/sample_program.py)

* **Initializing the Channel**

	In order for the rice cooker to run properly, you must include a `create_channel` method in your target py file
	that returns a ChannelNode model. This function will be responsible for building a tree based on `ricecooker.classes`.

	Start by importing `ChannelNode` from `ricecooker.classes.nodes` and create a ChannelNode model. The ChannelNode model has
	the following fields:

    - source_id (str): channel's unique id
    - source_domain (str): who is providing the content (e.g. learningequality.org)
    - title (str): name of channel
    - description (str): description of the channel (optional)
    - thumbnail (str): local path or url to image file (optional)

	For example:
	```
	from ricecooker.classes.nodes import ChannelNode

	def construct_channel(args):

	    channel = ChannelNode(
	        source_domain="learningequality.org",
	        source_id="rice-channel",
	        title="Rice Channel",
	        thumbnail="http://path/to/some/image.png"
	    )
	    _build_tree(channel, <source tree>) 	# see sample_program.py for example build_tree function

	    return channel
    ```


* **Building the Tree**

	Once your channel is created, you can start adding content. To do this, you will need to convert your data to
	the rice cooker's models. Here are the model types that are available to you:

	- TopicNode: folders to add hierarchy to the channel's content
    - VideoNode: mp4
    - AudioNode: mp3 or wav
    - DocumentNode: pdf
    - ExerciseNode: assessment-based content with questions
    - HTML5AppNode: zip containing html content (must have `index.html` file at topmost level)

    The `ricecooker.classes.nodes` module has the function `guess_content_kind`, which takes in a file path (this
    should be the primary file for the node), web video data (e.g. a YouTube link), or a list of questions and determines what model best suits the given data (if no match could be found, an `UnknownContentKindError`
    will be raised). For example:
    ```
    	>> guess_content_kind()
    	'topic'
    	>> guess_content_kind(path="http://path/to/some/file.mp4")
    	'video'
    	>> guess_content_kind(web_video_data="<youtube_id>")
    	'video'
    	>> guess_content_kind(questions=["Question?"])
    	'exercise'
    ```

    Once you have created the model, add it to a parent node with `<parent-node>.add_child(<child-node>)`


* **Adding Files**

	For example:
	```
	node = Exercise(
		exercise_data={'mastery_model': exercises.M_OF_N, 'randomize': True, 'm': 3, 'n': 5},
		...
	)
	```

	To add a question to your exercise, you must first create a question model from `ricecooker.classes.questions`.
	Your program is responsible for determining which question type to create. Here are the available question types:

	AUDIO_FILE = 0
    THUMBNAIL = 1
    DOCUMENT_FILE = 2
    VIDEO_FILE = 3
    YOUTUBE_VIDEO_FILE = 4
    WEB_VIDEO_FILE = 5
    VECTORIZED_VIDEO_FILE = 6
    VIDEO_THUMBNAIL = 7
    YOUTUBE_VIDEO_THUMBNAIL_FILE = 8
    HTML_ZIP_FILE = 9
    SUBTITLE_FILE = 10
    TILED_THUMBNAIL_FILE = 11
    UNIVERSAL_SUBS_SUBTITLE_FILE = 12
    BASE64_FILE = 13

	To set the correct answer(s) for input questions, you must provide an array of all of the accepted answers (`answers [str]`).
	For multiple selection questions, you must provide a list of all of the possible choices as well as an array of the correct
	answers (`all_answers [str]`) and `correct_answers [str]` respectively). For single selection questions, you must provide
	a list of all possible choices as well as the correct answer (`all_answers [str]` and `correct_answer str` respectively).

	To add images to a question's question, answers, or hints, format the image path with `'![](<path/to/some/file.png>)'`

	Once you have created the appropriate question model, add it to an exercise model with `<exercise-node>.add_question(<question>)`


* **Adding Exercises**

	Exercises are special model kinds that have questions used for assessment. In order to set the criteria
	for completing exercises, you must set `exercise_data` to equal a dict containing a mastery_model field
	based on the mastery models provided under `le_utils.constants.exercises`. If no data is provided,
	the rice cooker will default to mastery at 3 of 5 correct. For example:
	```
	node = ExerciseNode(
		exercise_data={'mastery_model': exercises.M_OF_N, 'randomize': True, 'm': 3, 'n': 5},<commit_msg>more readme documentation<commit_after># Rice Cooker

A framework for creating channels on [Kolibri Studio](https://contentworkshop.learningequality.org/).


## Installation

* [Install pip](https://pypi.python.org/pypi/pip) if you don't have it already.

* Run `pip install ricecooker`

* You can now reference ricecooker using `import ricecooker` in your .py files


## Using the Rice Cooker

A sample program has been created [here](https://github.com/learningequality/ricecooker/blob/master/ricecooker/sample_program.py)

* **Initializing the Channel**

	In order for the rice cooker to run properly, you must include a `create_channel` method in your target py file
	that returns a ChannelNode model. This function will be responsible for building a tree based on `ricecooker.classes`.

	Start by importing `ChannelNode` from `ricecooker.classes.nodes` and create a ChannelNode model. The ChannelNode model has
	the following fields:

    - source_id (str): channel's unique id
    - source_domain (str): who is providing the content (e.g. learningequality.org)
    - title (str): name of channel
    - description (str): description of the channel (optional)
    - thumbnail (str): local path or url to image file (optional)

	For example:
	```
	from ricecooker.classes.nodes import ChannelNode

	def construct_channel(args):

	    channel = ChannelNode(
	        source_domain="learningequality.org",
	        source_id="rice-channel",
	        title="Rice Channel",
	        thumbnail="http://path/to/some/image.png"
	    )
	    _build_tree(channel, <source tree>) 	# see sample_program.py for example build_tree function

	    return channel
    ```


* **Building the Tree**

	Once your channel is created, you can start adding content. To do this, you will need to convert your data to
	the rice cooker's models. Here are the model types that are available to you:

	- TopicNode: folders to add hierarchy to the channel's content
    - VideoNode: mp4
    - AudioNode: mp3 or wav
    - DocumentNode: pdf
    - ExerciseNode: assessment-based content with questions
    - HTML5AppNode: zip containing html content (must have `index.html` file at topmost level)

    The `ricecooker.classes.nodes` module has the function `guess_content_kind`, which takes in a file path (this
    should be the primary file for the node), web video data (e.g. a YouTube link), or a list of questions and determines what model best suits the given data (if no match could be found, an `UnknownContentKindError`
    will be raised). For example:
    ```
    	>> guess_content_kind()
    	'topic'
    	>> guess_content_kind(path="http://path/to/some/file.mp4")
    	'video'
    	>> guess_content_kind(web_video_data="<youtube_id>")
    	'video'
    	>> guess_content_kind(questions=["Question?"])
    	'exercise'
    ```

    Once you have created the model, add it to a parent node with `<parent-node>.add_child(<child-node>)`


* **Adding Files**

	To add a file to your node, you must start by creating a file model from `ricecooker.classes.files`.
	If you don't know which file model to use, you can use the function `guess_file_type` from
	`ricecooker.classes.files`, which accepts a kind and a path, web video url, youtube id, or encoding
	and returns the appropriate file type. For example:

	```
    	>> guess_file_type(filepath="http://path/to/some/file.mp4")
    	'video'
    	>> guess_file_type(web_url="<youtube_id>")
    	'video'
    	>> guess_file_type(youtube_id=["Question?"])
    	'exercise'
    	>> guess_file_type(encoding=["Question?"])
    	'exercise'
    	>> guess_file_type()
    	'AssertionError: Cannot guess file type: must include a filepath, web_url, youtube_id, or encoding'
    ```

   	Here are the available file models:

	To add a question to your exercise, you must first create a question model from `ricecooker.classes.questions`.
	Your program is responsible for determining which question type to create. Here are the available question types:



class File(object):
    def __init__(self, preset=None, language=None):

class DownloadFile(File):
    def __init__(self, path, **kwargs):
        self.path = path
        super(DownloadFile, self).__init__(**kwargs)

class ThumbnailFile(DownloadFile):

class AudioFile(DownloadFile):

class DocumentFile(DownloadFile):

class HTMLZipFile(DownloadFile):

class ExtractedVideoThumbnailFile(DownloadFile):

class VideoFile(DownloadFile):
    def __init__(self, path, ffmpeg_settings=None, **kwargs):
        self.ffmpeg_settings = ffmpeg_settings
    def process_file(self):
            if self.filename and (self.ffmpeg_settings or config.COMPRESS):
                self.filename = compress(self.filename, self.ffmpeg_settings)

class SubtitleFile(DownloadFile):
    def __init__(self, path, language, **kwargs):

class WebVideoFile(File):
    def __init__(self, web_url, download_settings=None, high_resolution=True, **kwargs):

class YouTubeVideoFile(WebVideoFile):
    def __init__(self, youtube_id, **kwargs):



















* **Adding Exercises**

	Exercises are special model kinds that have questions used for assessment. In order to set the criteria
	for completing exercises, you must set `exercise_data` to equal a dict containing a mastery_model field
	based on the mastery models provided under `le_utils.constants.exercises`. If no data is provided,
	the rice cooker will default to mastery at 3 of 5 correct. For example:
	```
	node = ExerciseNode(
		exercise_data={'mastery_model': exercises.M_OF_N, 'randomize': True, 'm': 3, 'n': 5},
{'fraction_non_alphanumeric': 0.09123109324143212, 'fraction_numerical': 0.003733486502010339, 'mean_word_length': 3.9278301886792453, 'pattern_counts': {'":': 0, '<': 15, '<?xml version=': 0, '>': 41, 'https://': 6, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 12, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6022788', 'n_tokens_mistral': 3184, 'n_tokens_neox': 3005, 'n_words': 1147}