Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

pre launch hook for installing AYON extension #6

Merged
merged 33 commits into from
Jan 22, 2025

Conversation

Sponge96
Copy link
Contributor

@Sponge96 Sponge96 commented Jan 7, 2025

Changelog Description

A simple prelaunch hook that automates the install of the AYON Premiere extension.

Additional review information

Right now for both Premiere and AfterEffect the users are expected to install the AYON extension via ExManCmd or Anastasiy's Extension Manager (see: https://github.com/ynput/ayon-aftereffects/blob/05dee927235bcdb654ce27fbed3d4f07fbd8f1dc/client/ayon_aftereffects/api/README.md). In my opinion it's better for AYON to handle this process instead of the user, it's a bit too technical for most users.

I'm creating this PR as a starting point on the discussion of how better to integrate the Adobe products into AYON as this method (or something similar) could easily be reused in AfterEffects.

Edit: The initial implementation attempted to use the ExManCMD cli tool to automate but we quickly hit permissions error due to the extraction of the .zxp being to a system path. The new approach simply creates a folder in the users appdata and unzip's the contents of the .zxp directly to that folder.

IMPORTANT: If you have already installed the AYON Premiere extension to users you will need to remove this via the tool you used (either ExManCmd or Anastasiy's Extension Manager) since they are located in system paths we are unable to remove these due to permissions. You will not experience any error by having the extension in both paths BUT its a gamble on which one it's actually loading.

Testing notes:

1. Upload new Premiere addon to server
2. Configure bundle to include new addon version.
3. Enable the new hook via settings
4. Install ExManCmd
5. Populate "Path to ExManCmd executable"
6. Launch Premiere
7. Check that the extension has installed (Window->Extensions->AYON)

  1. Upload New Premiere addon to server
  2. Configure bundle to include new addon.
  3. Enable the new hook via settings.
  4. Launch Premiere
  5. Validate that the extension has installed (window->extensions->AYON)

@Sponge96
Copy link
Contributor Author

Sponge96 commented Jan 7, 2025

Hit permissions error due to Extensions being installed to system path, seems that ExManCmd may also be replaced, will look into alternative shortly.

@Sponge96 Sponge96 marked this pull request as ready for review January 8, 2025 11:59
@BigRoy BigRoy requested a review from kalisp January 8, 2025 12:09
@BigRoy BigRoy added the enhancement New feature or request label Jan 8, 2025
@Sponge96 Sponge96 changed the title pre launch hook for installing AYON addon (using ExManCmd) pre launch hook for installing AYON extension Jan 8, 2025
@kalisp kalisp requested a review from 64qam January 21, 2025 11:51
@64qam 64qam requested a review from MilaKudr January 21, 2025 12:05
@kalisp
Copy link
Member

kalisp commented Jan 21, 2025

I added check for extension version, if different found, deployed extension folder gets purged and redeployed.

If you could @Sponge96 give it a go, please.

@Sponge96
Copy link
Contributor Author

I added check for extension version, if different found, deployed extension folder gets purged and redeployed.

haha I was literally working on this and about to push as well, will see if my version does anything different

@Sponge96
Copy link
Contributor Author

        # Extension already installed, compare the versions to see if we need to replace
        if os.path.exists(target_path):
            self.log.info(
                f"The extension already exists at: {target_path}. Comparing versions.."
            )
            if not self._compare_extension_versions(target_path, extension_path):
                return

  def _compare_extension_versions(self, target_path, extension_path):
       try:
           import xml.etree.ElementTree as ET
           from shutil import rmtree

           # opens the existing extension manifest to get the Version attribute.
           with open(f"{target_path}/CSXS/manifest.xml", "rb") as xml_file:
               installed_version = (
                   ET.parse(xml_file).find("*/Extension").attrib.get("Version")
               )
           self.log.debug(f"Current extension version found: {installed_version}")

           if not installed_version:
               self.log.warning(
                   "Unable to resolve the currently installed extension version. Cancelling.."
               )
               return False

           # opens the .zxp manifest to get the Version attribute.
           with ZipFile(extension_path, "r") as archive:
               xml_file = archive.open("CSXS/manifest.xml")
               new_version = (
                   ET.parse(xml_file).find("*/Extension").attrib.get("Version")
               )
               if not new_version:
                   self.log.warning(
                       "Unable to resolve the new extension version. Cancelling.."
                   )
               self.log.debug(f"New extension version found: {new_version}")

               # compare the two versions, a simple == is enough since the we don't care if the
               # version increments or decrements, if they match nothing happens.
               if installed_version == new_version:
                   self.log.info("Versions matched. Cancelling..")
                   return False

               # remove the existing addon to prevent any side effects when unzipping later.
               self.log.info("Version mismatch found. Removing old extensions..")
               rmtree(target_path)
               return True

       except PermissionError as error:
           self.log.warning(
               f"Permissions error has occured while comparing versions: {error}"
           )
           return False

       except OSError as error:
           self.log.warning(f"OS error has occured while comparing versions: {error}")
           return False

       except Exception as error:
           self.log.warning(
               f"An unexpected error occured when comparing version: {error}"
           )
           return False

@kalisp ours are very similar, mine branches off at the check on if the folder exist and uses the xml parser, I've thrown the code here and I guess we can see if you want to pinch anything or if we keep with your impl @BigRoy tagging for opinion as well

Copy link

@MilaKudr MilaKudr left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tested with admin and standard user accounts, works in both cases.

@kalisp kalisp merged commit bae8ed6 into ynput:develop Jan 22, 2025
1 check passed
@kalisp
Copy link
Member

kalisp commented Jan 22, 2025

Merged, thanks for contribution @Sponge96 :).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants