NextCloud addon

Is that your local site secrets? I’m not sure actually. I believe @Petr_Kalis fiddled around with that recently for some ayon-deadline development and @iLLiCiT commented here which may confirm that there is indeed no client-facing access to secrets.

What solutions there are to that - I’m not entirely sure. @iLLiCiT does mention they can ‘read them’.

Hmmmmmmmmmmmmmmmmmmmmm

so what you would recomend: expose non sercet knob in settings and use some service account in nextcloud (i believe this is insecure, but a lot easier)

or create tray to put in login credecials for each user? (creating nextcloud for each user and create extra one line for logging it (ayon, kitsu, nextcloud)

Maybe I’ll go with easy way, because anyway plugin settings is open only for admins

@BigRoy I believe tha last question how to make conversion from this to path on drive?

Weren’t you using the published_path or alike from the representations before? Why isn’t that a solution anymore?

Anyway, formatting a path like that you might want to use the Anatomy and StringTemplate.

There is some relevant bits in instance.data:

anatomy: Anatomy = instance.context.data["anatomy"]
anatomy_data: Dict[str, Any] = instance.data["anatomyData"]

You should be able to just use your own formatting string like that and do:

from ayon_core.lib import StringTemplate

template_str = "{root[work]}/{project[name]}/..."
template = StringTemplate(template_str)
anatomy_data = instance.data["anatomyData"]
path = template.format_strict(anatomy_data)

Some other potential references:

1 Like

It is! I wanted this for organization folder whitch i would like to share
because i want link to one folderfor all representations and some custization for those who want to use different folders and i believe that will help with order issue

sorry i dont get it where do i need to put this? i tried several places and have no sucsess

# -*- coding: utf-8 -*-
import os
import pyblish.api
from ayon_core.lib import StringTemplate, Anatomy 

import requests
from requests.auth import HTTPBasicAuth
import xml.etree.ElementTree as ET

from nextcloud.pipeline import NextCloudPublishContextPlugin




class IntegrateNextcloudShare(NextCloudPublishContextPlugin):
        order = pyblish.api.IntegratorOrder
        label = "NextCloud share"


        def process(self, instance):
            self.log.debug('im working from disk') #comment later

            nextcloudurl = os.environ["NEXTCLOUD_SERVER"]
            self.log.debug('nextcloudurl is '+ nextcloudurl) #comment later

            ocs_api_url = "/ocs/v2.php/apps/files_sharing/api/v1/shares"
            req_url = nextcloudurl + ocs_api_url
            self.log.debug('completed url '+ req_url) #comment later

            nextcloud_login = os.environ["NEXTCLOUD_LOGIN"]
            self.log.debug('login '+ nextcloud_login) #comment later

            nextcloud_password = os.environ["NEXTCLOUD_PASSWORD"]
            self.log.debug('password '+ nextcloud_password) #comment later

            nextcloud_mount = os.environ["NEXTCLOUD_MOUNT"]
            self.log.debug('nextcloud_mount '+ nextcloud_mount) #comment later

            ayon_mount= os.environ["AYON_MOUNT"]
            self.log.debug('ayon_mount '+ ayon_mount) #comment later

            
            anatomy: Anatomy = instance.context.data["anatomy"]
            anatomy_data: Dict[str, Any] = instance.data["anatomyData"]

            review_path = os.environ["PUBLISH_FOLDER"]

            template_str = "{root[work]}/{project[name]}/..."
            template = StringTemplate(template_str)
            anatomy_data = instance.data["anatomyData"]
            review_path = template.format_strict(anatomy_data)

            self.log.debug('path '+ review_path) #comment later

if i try like that

            review_path = os.environ["PUBLISH_FOLDER"]

            template_str = "{root[work]}/{project[name]}/..."
            template = StringTemplate(template_str)
            anatomy_data = instance.data["anatomyData"]
            review_path = template.format_strict(anatomy_data)

            self.log.debug('path '+ review_path) #comment later

i get this

    raise TemplateUnsolved(
ayon_core.lib.path_templates.TemplateUnsolved: Template "{root[work]}/{project[name]}/..." is unsolved. Missing keys: "root".

if like that

            review_path = os.environ["PUBLISH_FOLDER"]

            template_str = review_path
            template = StringTemplate(template_str)
            anatomy_data = instance.data["anatomyData"]
            review_path = template.format_strict(anatomy_data)

i get

ayon_core.lib.path_templates.TemplateUnsolved: Template "{root[work]}/{project[name]}/{hierarchy}/{folder[name]}/publish/{product[type]}/{product[name]}/{@version}" is unsolved. Missing keys: "@version, hierarchy, root, product, folder".

I’ve solved it!!

            review_path = os.environ["PUBLISH_FOLDER"]
            template_data = instance.data("anatomyData")
            anatomy = instance.context.data["anatomy"]
            template_data["root"] = anatomy.roots
            template_str = review_path
            template = StringTemplate(template_str)
            review_path = template.format_strict(template_data)

but i have another problem {@version} not working here

ayon_core.lib.path_templates.TemplateUnsolved: Template "{root[work]}/{project[name]}/{hierarchy}/{folder[name]}/publish/{product[type]}/{product[name]}/{@version}" is unsolved. Missing keys: "@version".

every other key works and gives me right path. Using just {version} is not suitablehere because it’ll give me version wo paddings

this was solved too using formatting

            version= template_data["version"]
            version_template = anatomy.templates["version"]        
            template_data["@version"] = version_template.format(version = version)

yep i run itto this but found some simple solution: I just create a folder whitch i want to share before inteagration so EVERYTHING WORKS NOW!!!

@BigRoy @mustafa_jafar HUUUUUUUGE THANKS FOR YOU HELP AND YOUR TIME

tommorow i’ll make some clenup of a code and post it!

And last: if i want this plugin to perform only if “review” enabled do i put like that?

families = ["review"]
1 Like

Yep, this how it’s done.

1 Like

So here it is)

I find some difficult spots that’s why i needed to use webdav api to nextcloud to create folders but now it works reliably

again thank you guys! @BigRoy @mustafa_jafar

now in kistu i see
image
and iside a link all organized as i wish!)

2 Likes

Oh man, that’s great!
I’m so happy for you :clap::clap:

1 Like

Just briefly went through conversation, sorry for not reading fully. Small question/note from the code. Where is env variable "PUBLISH_FOLDER" comming from? The way it’s used, it looks like it is filled with anatomy template (there is "@version", which is inner key used in anatomy templates)? Because you probably should not use "@version" in template, if it’s not comming from anatomy, and you should use Anatomy object if it is comming from anatomy. You can have multiple instances that are published to different directories during single publish and single env variable is not enough, also using Anatomy object will fill those inner keys for your.

Not sure what exactly nextcloud does. Does it upload/download files to cloud or it is just metadata based cloud? If it does upload them, then it might be better to add integration to site sync addon, which cares about sync of files on the background.

It’s not downloading or uploading anything it just

  1. creates folder (same folder whitch will be created in integration state, but i need to modify comment before kitsu, so i just create folder myself). Folder comes from settings of an addon (maybe implementing it from anatomy would be better but i’m not skilled enought so i aproach simpler way beacause anyway it need to be only publish but wo {representation} tocken). I import version formating from anatomy settings and just format {version} using tempate from anatomy to create @version myself

  2. it sends post request to nextcloud connected to the same shared drive to create share link to this created folder

  3. it adds the link to the comment

later integration process will collect all files inside already created folder and with sitesync i can confirm it works too

This addon is sooo simple and plays automatization role for produsers to have already created links from cloud that could be sended to the client (i know about delivery button but it not works for me, because of a client specific reasons: they just will not view files in kitsu or somewhere else they alway prefer to have some file to download and view localy)

about different folder publishing: i dont see a case when some representations of a work will be in different spots or using different templates, for me it always publish\product\version\ (and representations inside)

if i understand it right you maybe just doesn’t know what nextcloud is. So its just my own local based aka google cloud, its opensource and lets you mount your shared drive just inside it so artist can work using shared drive and admins can just create sharing links for clients to directly download or upload files.

but i need to modify comment before kitsu, so i just create folder mysel

I don’t understand this, I guess it’s based on some studio workflow?

Oh, that is very well possible, and used. You can have defined 1-n different publish templates for different cases, check ayon+settings://core/tools/publish/template_name_profiles settings and anatomy templates where is category publish where you can define multiple different templates. And also category hero which is used for hero version integration (using different template).

if i understand it right you maybe just doesn’t know what nextcloud is. So its just my own local based aka google cloud, its opensource and lets you mount your shared drive just inside it so artist can work using shared drive and admins can just create sharing links for clients to directly download or upload files.

It’s not downloading or uploading anything it just

Well, isn’t google cloud used to upload/download files? It just “behaves” as drive…

Anyway, the point is that we do handle gdrive sync using site sync addon. Not saying you have to do the same, just wanted to point to it as it handles it representation file based, instead of folder based. Also allows to combine different providers.

I wonder why you get @version
whenever I get any templates, I don’t get {@version} but rather {version:0>3}
for reference, I was testing using this resolve_paths_using_template_data.py

Here’s how it looks like on my side.

[
    {
        "frame": "{frame:0>4}",
        "version": "v{version:0>3}",
        "frame_padding": 4,
        "version_padding": 3,
        "file": "{project[code]}_{folder[name]}_{task[name]}_v{version:0>3}<_{comment}>.{ext}",
        "directory": "{root[work]}/{project[name]}/{hierarchy}/{folder[name]}/work/{task[name]}"
    },
    {
        "frame": "{frame:0>4}",
        "version": "v{version:0>3}",
        "frame_padding": 4,
        "version_padding": 3,
        "file": "{project[code]}_{folder[name]}_{product[name]}_v{version:0>3}<_{output}><.{frame:0>4}><_{udim}>.{ext}",
        "directory": "{root[work]}/{project[name]}/{hierarchy}/{folder[name]}/publish/{product[type]}/{product[name]}/v{version:0>3}"
    }
]

idk i just wanted to do it exactley like in anatomy and in anomy @version presist and its easy to convert to why not just use same tocken?)

i mean kitstu using comment in note and status integration stage and this stage is the first in a chain so to post comment with link i need to modify comment before kitsu so i do integration order - 0.01 and it means that my addon is doing its BEFORE integration so it cant create link to folder whitch is not exist yet so i just create nessesary folder myself using webdav nextcloud api

thats why i just create share links for a client simple task) i already have all my files synced beetwen ayon and nextcloud (same shared drive)