def create_zip_from_dir(self, dir_to_zip):
        """
        Adds all the files and subfolders from dir_to_zip into a Kolibri-compatible zip file.

        :param dir_to_zip: Directory containing files to zip.
        :return: Path to zip file. Note that this file is stored in the temp dir and will not persist across runs.
        """
        temp_zip = zip.create_predictable_zip(dir_to_zip)
        zip_hash = files.get_hash(temp_zip)
        zip_dir = os.path.join(self.cache_dir, 'zips')
        if not os.path.exists(zip_dir):
            os.makedirs(zip_dir)
        output_zip = os.path.join(zip_dir, '{}.zip'.format(zip_hash))
        os.rename(temp_zip, output_zip)
        return output_zip
    def get_scorm_topic_tree(self, parent, scorm_zip):
        license = licenses.SpecialPermissionsLicense(copyright_holder="ProFuturo", description="FIXME: Get license info")

        mod_zip_dir = os.path.join(self.DATA_DIR, 'modified_zips')
        zip_dir_name = os.path.splitext(os.path.basename(scorm_zip))[0]
        mod_zip_path = os.path.join(mod_zip_dir, '{}.zip'.format(zip_dir_name))
        # temporary workaround for a bug introduced when moving zips, this shouldn't be in the final version.
        if not os.path.exists(scorm_zip) and os.path.exists(mod_zip_path):
            shutil.move(mod_zip_path, scorm_zip)

        with tempfile.TemporaryDirectory() as extract_path:
            imscp_dict = extract_from_zip(
                    scorm_zip, license, extract_path)
            dep_zip_dir = os.path.join(self.DATA_DIR, 'dep_zips')
            os.makedirs(dep_zip_dir, exist_ok=True)
            os.makedirs(mod_zip_dir, exist_ok=True)
            if not os.path.exists(mod_zip_path):
                scorm_zip = self.modify_zip(scorm_zip)
                shutil.copy(scorm_zip, mod_zip_path)

            scorm_zip_hash = files.get_hash(mod_zip_path)
            scorm_zip_filename = '{}.zip'.format(scorm_zip_hash)
            scorm_zip_path = os.path.join(dep_zip_dir, scorm_zip_filename)
            # since we're hashing, if the file exists that means we already
            # copied it and it didn't change since the last run.
            if not os.path.exists(scorm_zip_path):
                shutil.copy(scorm_zip, scorm_zip_path)

            source_id = '{}-{}'.format(parent.source_id, os.path.splitext(os.path.basename(scorm_zip))[0])

            counter = 1
            for topic_dict in imscp_dict['organizations']:
                if not topic_dict['identifier']:
                    topic_dict['identifier'] = 'MANIFEST{}'.format(counter)
                    counter += 1

                node_options = {
                    'height': '580px',
                    'sandbox': 'allow-scripts allow-same-origin'
                }
                topic_tree = make_topic_tree_with_entrypoints(license, scorm_zip_path, topic_dict,
                        extract_path,
                        temp_dir=self.temp_dir, parent_id=source_id, node_options=node_options)
                parent.add_child(topic_tree)
Beispiel #3
0
def watermark_video(filename):
    # Check if we've processed this file before -- is it in the cache?
    key = files.generate_key("WATERMARKED",
                             filename,
                             settings=WATERMARK_SETTINGS)
    if not config.UPDATE and files.FILECACHE.get(key):
        return files.FILECACHE.get(key).decode('utf-8')

    # Create a temporary filename to write the watermarked video.
    tempf = tempfile.NamedTemporaryFile(suffix=".{}".format(file_formats.MP4),
                                        delete=False)
    tempf.close()
    tempfile_name = tempf.name

    # Now watermark it with the Touchable Earth logo!
    print("\t--- Watermarking ", filename)

    video_clip = mpe.VideoFileClip(config.get_storage_path(filename),
                                   audio=True)

    logo = (mpe.ImageClip(WATERMARK_SETTINGS["image"]).set_duration(
        video_clip.duration).resize(
            height=WATERMARK_SETTINGS["height"]).margin(
                right=WATERMARK_SETTINGS["right"],
                bottom=WATERMARK_SETTINGS["bottom"],
                opacity=0).set_pos(WATERMARK_SETTINGS["position"]))

    composite = mpe.CompositeVideoClip([video_clip, logo])
    composite.duration = video_clip.duration
    composite.write_videofile(tempfile_name, threads=4)

    # Now move the watermarked file to Ricecooker storage and hash its name
    # so it can be validated.
    watermarked_filename = "{}.{}".format(files.get_hash(tempfile_name),
                                          file_formats.MP4)
    files.copy_file_to_storage(watermarked_filename, tempfile_name)
    os.unlink(tempfile_name)

    files.FILECACHE.set(key, bytes(watermarked_filename, "utf-8"))
    return watermarked_filename
Beispiel #4
0
    def find_duplicates(self, filename_to_find):
        """
        Find all copies of the file that are identical in the content root.

        :return: A dictionary
        """

        matches = []
        for root, dirnames, filenames in os.walk(self.content_root):
            for filename in filenames:
                if filename.lower() == filename_to_find.lower():
                    matches.append(os.path.join(root, filename))

        print("len(matches) = {}".format(len(matches)))
        file_instances = {}
        for match in matches:
            hash = get_hash(match)
            if not hash in file_instances:
                file_instances[hash] = []
            file_instances[hash].append(match)

        return file_instances
def overlay_and_watermark_video(filename, youtube_id):
    # Check if we've processed this file before -- is it in the cache?
    key = files.generate_key("WATERMARKED",
                             filename,
                             settings=WATERMARK_SETTINGS)
    if not config.UPDATE and files.FILECACHE.get(key):
        return files.FILECACHE.get(key).decode('utf-8')

    # Create a temporary filename to write the watermarked video.
    tempf = tempfile.NamedTemporaryFile(suffix=".{}".format(file_formats.MP4),
                                        delete=False)
    tempf.close()
    tempfile_name = tempf.name

    # Now watermark it with the Touchable Earth logo!
    print("\t--- Watermarking and adding overlay ", filename)

    # First add the overlay image -- this is the image shown as the first frame
    # so that when the video hasn't been played yet, it will show this image
    # rather than a black screen (since Touchable Earth's videos start from
    # a blank black screen).

    # Download the overlay image based on the YouTube ID
    overlay_src = 'https://i.ytimg.com/vi_webp/%s/maxresdefault.webp' % youtube_id
    print("\t    ... grabbing overlay image from %s" % overlay_src)
    destination = tempfile.mkdtemp()
    overlay_filename = "overlay.webp"
    overlay_file = os.path.join(destination, overlay_filename)
    _, response = download_file(overlay_src,
                                destination,
                                request_fn=sess.get,
                                filename=overlay_filename)

    video_clip = mpe.VideoFileClip(config.get_storage_path(filename),
                                   audio=True)

    if response.status_code == 200:
        overlay_clip = mpe.ImageClip(overlay_file).set_duration(0.1)
        concat_clips = mpe.concatenate_videoclips([overlay_clip, video_clip])
    else:
        concat_clips = video_clip
        print("\t    WARNING: Could not download overlay image file from %s" %
              overlay_src)

    # Now create the watermark logo as a clip ...
    logo = (mpe.ImageClip(WATERMARK_SETTINGS["image"]).set_duration(
        concat_clips.duration).resize(
            height=WATERMARK_SETTINGS["height"]).margin(
                right=WATERMARK_SETTINGS["right"],
                bottom=WATERMARK_SETTINGS["bottom"],
                opacity=0).set_pos(WATERMARK_SETTINGS["position"]))

    # And then combine it with the video clip.
    composite = mpe.CompositeVideoClip([concat_clips, logo])
    composite.duration = concat_clips.duration
    composite.write_videofile(tempfile_name, threads=4)

    # Now move the watermarked file to Ricecooker storage and hash its name
    # so it can be validated.
    watermarked_filename = "{}.{}".format(files.get_hash(tempfile_name),
                                          file_formats.MP4)
    files.copy_file_to_storage(watermarked_filename, tempfile_name)
    os.unlink(tempfile_name)
    os.unlink(overlay_file)

    files.FILECACHE.set(key, bytes(watermarked_filename, "utf-8"))
    return watermarked_filename