Beispiel #1
0
def build_playlist_job(playlist, email):
    """
    Build playlist file (concatenate all mnovie previews). This function is
    aimed at being runned as a job in a job queue.
    """
    from zou.app import app, mail

    with app.app_context():
        job = None
        try:
            job = build_playlist_movie_file(playlist)
        except:
            if job is not None:
                end_build_job(playlist, job)
            raise

        message_text = """
Your playlist %s is available at:
https://%s/api/data/playlists/%s/jobs/%s/build/mp4
""" % (
            playlist["name"],
            config.DOMAIN_NAME,
            playlist["id"],
            job["id"],
        )
        message = Message(
            body=message_text,
            subject="CGWire playlist download",
            recipients=[email],
        )
        mail.send(message)
Beispiel #2
0
def build_playlist_job(playlist, shots, params, email, full, remote):
    """
    Build playlist file (concatenate all movie previews). This function is
    aimed at being runned as a job in a job queue.
    """
    from zou.app import app, mail

    with app.app_context():
        job = build_playlist_movie_file(playlist, shots, params, full, remote)

        # Just in case, since rq jobs which encounter an error raise an
        # exception in order to be flagged as failed.
        if job["status"] == "succeeded":
            message_text = """
Your playlist %s is available at:
https://%s/api/data/playlists/%s/jobs/%s/build/mp4
""" % (
                playlist["name"],
                config.DOMAIN_NAME,
                playlist["id"],
                job["id"],
            )
            message = Message(
                body=message_text,
                subject="CGWire playlist download",
                recipients=[email],
            )
            mail.send(message)
 def test_get_month_time_spents(self):
     with app.app_context():
         tasks = time_spents_service.get_month_time_spents(
             self.person_id, "2018", "5")
         self.assertEqual(len(tasks), 1)
         self.assertEqual(tasks[0]["entity_name"], "Tree")
         self.assertEqual(tasks[0]["duration"], 600)
 def test_get_day_table(self):
     with app.app_context():
         day_table = time_spents_service.get_day_table("2018", "06")
         self.assertEqual(day_table["3"][self.person_id], 600)
         self.assertEqual(day_table["4"][self.person_id], 800)
         self.assertEqual(day_table["3"][self.user_id], 600)
         self.assertTrue("1" not in day_table)
Beispiel #5
0
def download_preview_from_another_instance(preview_file):
    """
    Download all files link to preview file entry: orginal file and variants.
    """

    from zou.app import app
    print("download preview %s (%s)" %
          (preview_file.id, preview_file.extension))
    is_movie = preview_file.extension == "mp4"
    is_picture = preview_file.extension == "png"
    is_file = not is_movie and not is_picture

    preview_file_id = str(preview_file.id)
    save_func = file_store.add_file
    with app.app_context():
        if is_file:
            save_func = file_store.add_file
            exists_func = file_store.exists_file
        elif is_movie:
            save_func = file_store.add_movie
            exists_func = file_store.exists_movie
        else:
            save_func = file_store.add_picture
            exists_func = file_store.exists_picture

        if is_movie or is_picture:
            for prefix in ["thumbnails", "thumbnails-square", "original"]:
                if not exists_func(prefix, preview_file_id):
                    download_file_from_another_instance(
                        file_store.add_picture, prefix, preview_file_id,
                        preview_file.extension)
        if not exists_func("previews", preview_file_id):
            download_file_from_another_instance(save_func, "previews",
                                                preview_file_id,
                                                preview_file.extension)
Beispiel #6
0
def prepare_and_store_movie(preview_file_id, uploaded_movie_path):
    """
    Prepare movie preview, normalize the movie as a .mp4, build the thumbnails
    and store the files.
    """
    from zou.app import app as current_app
    with current_app.app_context():
        project = get_project_from_preview_file(preview_file_id)
        fps = get_preview_file_fps(project)
        (width, height) = get_preview_file_dimensions(project)

        # Build movie
        current_app.logger.info("start normalization")
        try:
            (normalized_movie_path, normalized_movie_low_path,
             err) = movie.normalize_movie(uploaded_movie_path,
                                          fps=fps,
                                          width=width,
                                          height=height)

            if err:
                current_app.logger.error(
                    "Fail to add silent audiotrack to: %s" %
                    uploaded_movie_path)
                current_app.logger.error(err)

            current_app.logger.info("file normalized %s" %
                                    normalized_movie_path)
            file_store.add_movie("previews", preview_file_id,
                                 normalized_movie_path)
            file_store.add_movie("lowdef", preview_file_id,
                                 normalized_movie_low_path)
            current_app.logger.info("file stored")
        except Exception as exc:
            if isinstance(exc, ffmpeg.Error):
                current_app.logger.error(exc.stderr)
            current_app.logger.error("failed", exc_info=1)
            preview_file = set_preview_file_as_broken(preview_file_id)
            return preview_file

        # Build thumbnails
        size = movie.get_movie_size(normalized_movie_path)
        original_picture_path = \
            movie.generate_thumbnail(normalized_movie_path)
        tile_picture_path = \
            movie.generate_tile(normalized_movie_path)
        thumbnail_utils.resize(original_picture_path, size)
        save_variants(preview_file_id, original_picture_path)
        file_size = os.path.getsize(normalized_movie_path)
        current_app.logger.info("thumbnail created %s" % original_picture_path)

        # Remove files and update status
        os.remove(uploaded_movie_path)
        os.remove(normalized_movie_path)
        preview_file = update_preview_file(preview_file_id, {
            "status": "ready",
            "file_size": file_size
        })
        return preview_file
 def test_get_week_table(self):
     with app.app_context():
         week_table = time_spents_service.get_week_table("2018")
         self.assertEqual(week_table["18"][self.person_id], 600)
         self.assertEqual(week_table["22"][self.person_id], 600)
         self.assertEqual(week_table["22"][self.user_id], 600)
         self.assertEqual(week_table["23"][self.person_id], 800)
         self.assertTrue("1" not in week_table)
Beispiel #8
0
def stamp_db():
    "Upgrade database schema."

    from zou.app import app
    with app.app_context():
        import zou
        directory = os.path.join(os.path.dirname(zou.__file__), "migrations")
        flask_migrate.stamp(directory=directory)
 def test_get_time_spents(self):
     with app.app_context():
         time_spents = time_spents_service.get_time_spents(
             self.person_id, "2018-06-04")
         duration = 0
         for time_spent in time_spents:
             duration += time_spent["duration"]
         self.assertEqual(len(time_spents), 2)
         self.assertEqual(duration, 800)
Beispiel #10
0
def store_db_backup(filename):
    """
    Store given file located in the same directory, inside the files bucket
    using the `dbbackup` prefix.
    """
    from zou.app import app

    with app.app_context():
        file_store.add_file("dbbackup", filename, filename)
Beispiel #11
0
def init_db():
    "Creates datababase table (database must be created through PG client)."

    print("Creating database and tables...")
    from zou.app import app
    with app.app_context():
        import zou
        directory = os.path.join(os.path.dirname(zou.__file__), "migrations")
        flask_migrate.upgrade(directory=directory)
    print("Database and tables created.")
Beispiel #12
0
def reset_migrations():
    "Set the database schema revision to first one."

    from zou.app import app

    with app.app_context():
        import zou

        directory = os.path.join(os.path.dirname(zou.__file__), "migrations")
        flask_migrate.stamp(directory=directory, revision="base")
Beispiel #13
0
def build_playlist_movie_file(playlist, shots, params, full, remote):
    """
    Build a movie for all files for a given playlist into the temporary folder.
    """
    job = start_build_job(playlist)
    success = False
    try:
        previews = playlist_previews(shots, only_movies=True)
        movie_file_path = get_playlist_movie_file_path(job)
        tmp_file_paths = retrieve_playlist_tmp_files(previews)

        if not remote:
            success = False
            if not full:
                success = _run_concatenation(
                    playlist,
                    job,
                    tmp_file_paths,
                    movie_file_path,
                    params,
                    movie.concat_demuxer,
                )

            # Try again using concat filter
            if not success:
                success = _run_concatenation(
                    playlist,
                    job,
                    tmp_file_paths,
                    movie_file_path,
                    params,
                    movie.concat_filter,
                )
        else:
            from zou.app import app

            with app.app_context():
                try:
                    _run_remote_job_build_playlist(
                        app, job, previews, params, movie_file_path, full
                    )
                    success = True
                except Exception as exc:
                    current_app.logger.error(exc)
                    success = False

    # exception will be logged by rq
    finally:
        job = end_build_job(playlist, job, success)

    if not success:
        raise Exception("Failure while building playlist %r" % playlist["id"])

    return job
Beispiel #14
0
 def test_get_month_table_with_different_projects(self):
     with app.app_context():
         self.generate_fixture_project_standard()
         self.generate_fixture_asset_standard()
         self.generate_fixture_task_standard()
         tasks_service.create_or_update_time_spent(self.task_standard.id,
                                                   self.person_id,
                                                   "2018-05-03", 600)
         month_table = time_spents_service.get_month_table(
             "2018", project_id=self.project_standard.id)
         self.assertEqual(month_table["5"][self.person_id], 600)
Beispiel #15
0
    def test_check_project_access(self):
        from zou.app import app
        with app.app_context():
            self.generate_fixture_user_cg_artist()
            self.log_in_cg_artist()
            with self.assertRaises(permissions.PermissionDenied):
                user_service.check_project_access(self.project_id)

            self.project.team.append(self.user)
            self.project.save()
            self.assertTrue(user_service.check_project_access(self.project_id))
Beispiel #16
0
Datei: cli.py Projekt: cgwire/zou
def downgrade_db(revision):
    """
    Downgrade db to previous revision of the database schema
    (for development only). For revision you can use an hash or a relative migration identifier.
    """

    from zou.app import app

    with app.app_context():
        import zou

        directory = os.path.join(os.path.dirname(zou.__file__), "migrations")
        flask_migrate.downgrade(directory=directory, revision=revision)
Beispiel #17
0
Datei: cli.py Projekt: cgwire/zou
def stamp_db(revision):
    "Set the database schema revision to current one."

    from zou.app import app

    with app.app_context():
        import zou

        directory = os.path.join(os.path.dirname(zou.__file__), "migrations")
        if revision is None:
            flask_migrate.stamp(directory=directory)
        else:
            flask_migrate.stamp(directory=directory, revision=revision)
Beispiel #18
0
def migrate_db():
    """
    Generate migration files to describe a new revision of the database schema
    (for development only).
    """

    from zou.app import app

    with app.app_context():
        import zou

        directory = os.path.join(os.path.dirname(zou.__file__), "migrations")
        flask_migrate.migrate(directory=directory)
Beispiel #19
0
    def test_check_entity_access(self):
        from zou.app import app

        self.asset_id = str(self.asset.id)
        with app.app_context():
            self.generate_fixture_user_vendor()
            self.log_in_vendor()
            person_id = str(self.get_current_user_raw().id)
            projects_service.add_team_member(self.project_id, person_id)
            with self.assertRaises(permissions.PermissionDenied):
                user_service.check_entity_access(str(self.asset_id))
            tasks_service.assign_task(self.task_id, person_id)
            self.assertTrue(
                user_service.check_entity_access(str(self.asset_id)))
Beispiel #20
0
Datei: cli.py Projekt: cgwire/zou
def clear_db():
    "Drop all tables from database"

    from zou.app import app

    with app.app_context():
        import zou

        print("Deleting database and tables...")
        dbhelpers.drop_all()
        print("Database and tables deleted.")

        directory = os.path.join(os.path.dirname(zou.__file__), "migrations")
        flask_migrate.stamp(directory=directory, revision="base")
Beispiel #21
0
 def save_thumbnail(person, thumbnail):
     from zou.app import app
     with app.app_context():
         thumbnail_path = "/tmp/ldap_th.jpg"
         with open(thumbnail_path, "wb") as th_file:
             th_file.write(thumbnail)
         thumbnail_png_path = thumbnail_utils.convert_jpg_to_png(
             thumbnail_path)
         thumbnail_utils.turn_into_thumbnail(
             thumbnail_png_path, size=thumbnail_utils.BIG_SQUARE_SIZE)
         file_store.add_picture("thumbnails", person["id"],
                                thumbnail_png_path)
         os.remove(thumbnail_png_path)
         persons_service.update_person(person["id"], {"has_avatar": True})
Beispiel #22
0
def download_attachment_files_from_another_instance(project=None):
    from zou.app import app

    if project:
        project_dict = gazu.project.get_project_by_name(project)
        attachment_files = (AttachmentFile.query.join(Comment).join(
            Task, Comment.object_id == Task.id).filter(
                Task.project_id == project_dict["id"]).all())
    else:
        attachment_files = AttachmentFile.query.all()
    for attachment_file in attachment_files:
        with app.app_context():
            download_attachment_file_from_another_instance(
                attachment_file.present())
Beispiel #23
0
def send_email(subject, body, recipient_email, html=None):
    """
    Send an email with given subject and body to given recipient.
    """
    if html is None:
        html = body
    with app.app_context():
        mail_default_sender = app.config["MAIL_DEFAULT_SENDER"]
        message = Message(sender="Kitsu Bot <%s>" % mail_default_sender,
                          body=body,
                          html=html,
                          subject=subject,
                          recipients=[recipient_email])
        mail.send(message)
Beispiel #24
0
    def test_check_project_access(self):
        from zou.app import app
        with app.app_context():
            self.generate_fixture_user_cg_artist()
            self.log_in_cg_artist()
            with self.assertRaises(permissions.PermissionDenied):
                user_service.check_project_access(str(self.project_id))

            projects_service.add_team_member(
                str(self.project.id), str(self.get_current_user_raw().id))
            project = projects_service.get_project_with_relations(
                self.project_id)
            self.assertTrue(
                user_service.check_project_access(str(self.project_id)))
Beispiel #25
0
def send_email(subject, body, recipient_email, html=None):
    """
    Send an email with given subject and body to given recipient.
    """
    if html is None:
        html = body
    with app.app_context():
        message = Message(
            sender="Kitsu Bot <*****@*****.**>",
            body=body,
            html=html,
            subject=subject,
            recipients=[recipient_email]
        )
        mail.send(message)
Beispiel #26
0
 def test_get_month_time_spents_with_different_projects(self):
     with app.app_context():
         self.generate_fixture_project_standard()
         self.generate_fixture_asset_standard()
         self.generate_fixture_task_standard()
         tasks_service.create_or_update_time_spent(self.task_standard.id,
                                                   self.person_id,
                                                   "2018-05-03", 400)
         tasks = time_spents_service.get_month_time_spents(
             self.person_id,
             "2018",
             "5",
             project_id=self.project_standard.id)
         self.assertEqual(len(tasks), 1)
         self.assertEqual(tasks[0]["entity_name"], "Car")
         self.assertEqual(tasks[0]["duration"], 400)
Beispiel #27
0
def download_thumbnail_from_another_instance(model_name, model_id):
    """
    Download into the local storage the thumbnail for a given model instance.
    """
    from zou.app import app
    with app.app_context():
        file_path = "/tmp/thumbnails-%s.png" % str(model_id)
        path = "/pictures/thumbnails/%ss/%s.png" % (model_name, model_id)
        try:
            gazu.client.download(path, file_path)
            file_store.add_picture("thumbnails", model_id, file_path)
            os.remove(file_path)
            print("%s downloaded" % file_path)
        except Exception as e:
            print(e)
            print("%s download failed" % file_path)
        return path
Beispiel #28
0
    def test_get_last_notifications(self):
        from zou.app import app

        with app.app_context():
            persons_service.get_current_user = self.get_current_user_artist
            self.generate_fixture_user_cg_artist()
            self.log_in_cg_artist()
            person_id = self.user_cg_artist["id"]
            projects_service.add_team_member(self.project_id, person_id)
            tasks_service.assign_task(self.task_id, person_id)
            notifications = user_service.get_last_notifications()
            self.assertEqual(len(notifications), 0)
            comments_service.create_comment(
                self.user["id"],
                self.task_id,
                self.to_review_status_id,
                "Lets go",
                [],
                {},
                None,
            )
            notifications = user_service.get_last_notifications()
            self.assertEqual(len(notifications), 1)

            comments_service.create_comment(
                self.user_client["id"],
                self.task_id,
                self.to_review_status_id,
                "Wrong picture",
                [],
                {},
                None,
            )
            notifications = user_service.get_last_notifications()
            self.assertEqual(len(notifications), 2)
            self.assertEqual(len(notifications[0]["comment_text"]), 0)
            self.assertGreater(len(notifications[1]["comment_text"]), 0)
Beispiel #29
0
def build_playlist_movie_file(playlist, shots, params, remote):
    """
    Build a movie for all files for a given playlist into the temporary folder.
    """
    job = start_build_job(playlist)
    success = False
    try:
        previews = playlist_previews(shots, only_movies=True)
        movie_file_path = get_playlist_movie_file_path(job)
        tmp_file_paths = retrieve_playlist_tmp_files(previews)

        # First, try using concat demuxer
        success = _run_concatenation(playlist, job, tmp_file_paths,
                                     movie_file_path, params,
                                     movie.concat_demuxer)

        # Try again using concat filter
        if not success:
            if not remote:
                success = _run_concatenation(playlist, job, tmp_file_paths,
                                             movie_file_path, params,
                                             movie.concat_filter)
            else:
                from zou.app import app
                with app.app_context():
                    _execute_nomad_job(job, previews, params, movie_file_path)
                    success = True

    # exception will by logged by rq
    finally:
        job = end_build_job(playlist, job, success)

    if not success:
        raise Exception("Failure while building playlist %r" % playlist["id"])

    return job
Beispiel #30
0
 def setUp(self):
     super(FileStoreTestCase, self).setUp()
     with app.app_context():
         self.preview_path = app.config["PREVIEW_FOLDER"]
         self.store = file_store
         self.store.clear()