Fetching an image from the .fuskin file via script?

User avatar
Midgardsormr
Fusionista
Posts: 799
Joined: Wed Nov 26, 2014 8:04 pm
Location: Los Angeles, CA, USA
Been thanked: 87 times
Contact:

Fetching an image from the .fuskin file via script?

#1

Post by Midgardsormr » Wed Dec 05, 2018 11:38 am

Does anyone know of a way to use Lua to fetch an image from a zip archive that doesn't have the .zip extension? I'd love to be able to grab Fusion's Cog icon directly from the .fuskin file instead of creating an unnecessary file dependency.

This works: Icon = ui:Icon{File = 'Fusion:'..[[Skins\Fusion.zip\Cog.png]]}, if I make a copy of the file with the .zip extension. This does not: Icon = ui:Icon{File = 'Fusion:'..[[Skins\Fusion.fuskin\Cog.png]]},.

Tags:

User avatar
theotheo
Fusionista
Posts: 257
Joined: Thu Aug 07, 2014 8:35 am
Been thanked: 53 times

Re: Fetching an image from the .fuskin file via script?

#2

Post by theotheo » Wed Dec 05, 2018 12:33 pm

Is it forbidden to trigger sys calls?

User avatar
Midgardsormr
Fusionista
Posts: 799
Joined: Wed Nov 26, 2014 8:04 pm
Location: Los Angeles, CA, USA
Been thanked: 87 times
Contact:

Re: Fetching an image from the .fuskin file via script?

#3

Post by Midgardsormr » Wed Dec 05, 2018 1:59 pm

It's not out of the question, but what did you have in mind?

User avatar
AndrewHazelden
Fusionator
Posts: 1042
Joined: Fri Apr 03, 2015 3:20 pm
Location: West Dover, Nova Scotia, Canada
Been thanked: 97 times
Contact:

Re: Fetching an image from the .fuskin file via script?

#4

Post by AndrewHazelden » Wed Dec 05, 2018 5:55 pm

Midgardsormr wrote:
Wed Dec 05, 2018 1:59 pm
It's not out of the question, but what did you have in mind?
Hi @Midgardsormr and @theotheo. It's been a while. :)

Here are some different ways for reading data from a .fuskin zipped file (or any zipped file) in Fusion via Lua scripts:

Option #1

You can use a vanilla cygwin for Windows install then extract the following zip libraries for Lua CLI based os.execute() or io.popen usage in your pipeline. That would let you do Lua/python/shell scripted Zipping/Unzipping.

Code: Select all

zip.exe
base64.exe
cygbz2-1.dll
cyggcc_s-seh-1.dll
cygiconv-2.dll
cygintl-8.dll
cygwin1.dll
gunzip
gzip.exe

Cygwin for Windows files like this:

cygwin-zip-tools.zip

Zipping files and folders using Lua scripts + os.execute()

I've used terminal based zip tools in Lua scripts for about two years now so have found them to be pretty reliable. Mac (/usr/bin/zip), Linux (/usr/bin/zip), and then Cygwin (C:\\cygwin64\\bin\\zip.exe).

Below is a zipping files/folder code chunk that came out of KartaVR's Send to AGI Photoscan tool in 2017. That code was then re-purposed to make a REZ packager compatible tool for Fusion. This script was created so Fusion could be used in VFX pipelines at large VFX companies that wanted a package based deployment of Fusion on the fly without needing root level access or a fixed install path.

The zip CLI based functions you might find useful to lift out of the following Lua script are:

Zip a Folder
Example: zipFolder('Temp:/archive.zip', 'Comp:/', false, true)

Zip a Single File
Example: zipFile('Temp:/archive.zip', 'Comp:/image.jpg', false)

The fact you can use Fusion PathMaps in the source and destination zip files path is kinda cool IMHO for a cross-platform CLI based zip wrapper script.

The "Fusion_Rez_Package_Creator.lua" file was a custom script made for a single VFX deployment needed at my own company's 704 core / 1830 GHz farm.

Footnote: I heard a vague rumour that having Rez support for FU and Resolve exist also might have helped get Fusion Studio adopted as an allowed tool *inside* the pipeline at a large VFX house, too. And a 700+ employee VFX house at that. That's something special in my books and quite a marvel. For me to know that having a small piece of Lua scripted technology exist that helped pull off a feat like that, simply makes me smile. @theotheo a good mutual friend, Mary-lou, would be so proud to know only a few months later that it was possible to use Fusion more on the big projects at companies with bold rebel's working in comp. :)

Code: [Select all] [Expand/Collapse] [Download] (Fusion_Rez_Package_Creator.lua)
  1. local _VERSION = 'v1.0 2018-10-02 12.11 PM'
  2. --[[
  3. Fusion Rez Package Creator
  4. By Andrew Hazelden <andrew@andrewhazelden.com>
  5.  
  6. ## Overview ##
  7.  
  8. This script converts a Linux installed version of Fusion Standalone + Fusion Render Node into a new Rez Package.
  9.  
  10. Rez is available from:
  11. https://github.com/nerdvegas/rez/
  12.  
  13.  
  14. ## Rez install ##
  15.  
  16. Step 1. Download the Rez package manager and unzip it.
  17.  
  18. Step 2. Change the working directory to the Rez folder you expanded and then run the Python based installer:
  19.  
  20. cd '$HOME/Downloads/rez-2.22.0/'
  21. sudo python ./install.py -v /opt/rez
  22.  
  23. Step 3. Edit the $HOME/.bash_profile to add the rez paths to the $PATH environment variable:
  24. # Rez path entry
  25. export PATH=$PATH:/opt/rez/bin/rez
  26.  
  27. Step 4. Source the .bash_profile to reload the $PATH env var:
  28. source /opt/rez/completion/complete.sh
  29.  
  30. Step 5. Make the local Rez packages folder:
  31. mkdir -p $HOME/packages/
  32.  
  33. Step 6. Add cmake to your system:
  34. sudo yum install cmake
  35.  
  36. Step 7. Create the default rez packages:
  37. rez-bind platform
  38. rez-bind arch
  39. rez-bind os
  40. rez-bind python
  41.  
  42. ## Generating your own Rez Fusion Package ##
  43.  
  44. Step 1. Install Fusion / Fusion Studio on your workstation using the regular GUI installer.
  45.  
  46. Step 2. Copy the "Fusion_Rez_Package_Creator.lua" script into the "Scripts:/Comp/" PathMap folder. Run this script using the Fusion "Scripts > Fusion_Rez_Package_Creator" menu item. Your new rez "fusion" package will be saved to your desktop folder.
  47.  
  48. Step 3. (Optional) By default the Reactor.fu file is downloaded from the Reactor GitLab repo and added to your new Rez Fusion package. You can disable this step by editing the "Fusion_Rez_Package_Creator.lua" script and setting the variable "reactorPackageSupport" to false.
  49.  
  50. # Installing the Rez Fusion Package
  51.  
  52. Step 1. Copy your "fusion" rez package to a fresh system that has rez installed on it.
  53.  
  54. Step 2. Install the "fusion" package in rez:
  55.  
  56. {
  57. cd $HOME/Desktop/fusion/
  58. rez-build --install
  59. rez-env fusion
  60. }
  61.  
  62. Step 3. Use Rez to launch Fusion Standalone:
  63.  
  64. # Launch Fusion
  65. rez-env fusion -- Fusion
  66.  
  67. # Launch the Fusion Render Node
  68. rez-env fusion -- FusionRenderNode /path/to/fusion.comp -render -start 1001 -end 1145 -step 1 -quit -quiet
  69.  
  70. ]]--
  71.  
  72. -- This script is designed just for Linux users
  73. local platform = 'Linux'
  74.  
  75. -- Should Reactor.fu be downloaded and added to the Rez fusion package? (true/false)
  76. local reactorPackageSupport = true
  77.  
  78. -- Should the Rez fusion package be zipped? (true/false)
  79. -- (This requires the zip terminal utility to be installed on the system)
  80. local rezPackageZipped = true
  81.  
  82. -- ---------------------------------------------------------------------------------------
  83. -- Main is where the magic happens
  84. -- ---------------------------------------------------------------------------------------
  85. function Main()
  86.     print('[Fusion Rez Package Creator] ' .. tostring(_VERSION))
  87.     print('[Created By] Andrew Hazelden andrew@andrewhazelden.com')
  88.     print('----------------------------------------------------------------------')
  89.     print('This script converts a Linux installed version of Fusion Standalone + Fusion Render Node into a new Rez Package.')
  90.     print('----------------------------------------------------------------------')
  91.    
  92.     -- pint the debug status info (true/false)
  93.     local printStatus = false
  94.    
  95.     -- ---------------------------------------------------------------------------------------
  96.     -- Fusion 9 Source filepaths
  97.     -- ---------------------------------------------------------------------------------------
  98.    
  99.     -- Fusion Standalone source folder
  100.     -- Example: /opt/BlackmagicDesign/Fusion9/
  101.     fusionFilepath = '/opt/BlackmagicDesign/Fusion9/'
  102.    
  103.     -- Fusion Render Node source folder
  104.     -- Example: /opt/BlackmagicDesign/FusionRenderNode9/
  105.     fusionRenderNodeFilepath = '/opt/BlackmagicDesign/FusionRenderNode9/'
  106.    
  107.     -- ---------------------------------------------------------------------------------------
  108.     -- Output Folders
  109.     -- ---------------------------------------------------------------------------------------
  110.    
  111.     -- Read the $HOME environment variable
  112.     -- Example: /home/vfx
  113.     local homeDirectory = os.getenv('HOME')
  114.    
  115.     -- Desktop folder
  116.     -- Example: /home/vfx/Desktop/
  117.     local desktopDirectory = homeDirectory .. '/Desktop/'
  118.     -- Create the Desktop folder (Fallback for foreign language OS)
  119.     os.execute('mkdir -p "' .. desktopDirectory .. '"')
  120.    
  121.     -- Rez fusion package output directory
  122.     -- Example: /home/vfx/Desktop/fusion
  123.     local outputDirectory = homeDirectory .. '/Desktop/fusion/'
  124.     print('\n[Creation Rez Folder] ' .. tostring(outputDirectory))
  125.     -- Create the Rez package output folder
  126.     os.execute('mkdir -p "' .. outputDirectory .. '"')
  127.    
  128.     -- Rez fusion opt directory
  129.     -- Example: /home/vfx/Desktop/fusion/opt/
  130.     local optDirectory = homeDirectory .. '/Desktop/fusion/opt/BlackmagicDesign/'
  131.     -- Create the Rez package opt folder
  132.     os.execute('mkdir -p "' .. optDirectory .. '"')
  133.    
  134.     -- Create the Rez package opt/Fusion9/ folder
  135.     local optFusionDirectory = optDirectory .. 'Fusion9/'
  136.     -- os.execute('mkdir -p "' .. optFusionDirectory .. "')
  137.     print('\n[Copying Fusion9] ' .. tostring(optFusionDirectory))
  138.     -- Copy the BMD Fusion 9 files to the Rez fusion package opt folder
  139.     os.execute('cp -R "' .. fusionFilepath .. '" "' .. optFusionDirectory .. '"')
  140.    
  141.     -- Create the Rez package opt/FusionRenderNode9/ folder
  142.     local optFusionRenderNodeDirectory = optDirectory .. 'FusionRenderNode9/'
  143.     print('\n[Copying FusionRenderNode9] ' .. tostring(optFusionRenderNodeDirectory))
  144.     -- os.execute('mkdir -p "' .. optFusionRenderNodeDirectory .. "')
  145.     -- Copy the BMD Fusion Render Node 9 files to the Rez fusion package opt folder
  146.     os.execute('cp -R "' .. fusionRenderNodeFilepath .. '" "' .. optFusionRenderNodeDirectory .. '"')
  147.    
  148.     -- Create the Rez package opt/Fusion9/Config folder
  149.     local optFusionConfigDirectory = optDirectory .. 'Fusion9/Config/'
  150.     os.execute('mkdir -p "' .. optFusionConfigDirectory .. '"')
  151.    
  152.     -- ---------------------------------------------------------------------------------------
  153.     -- Output Files
  154.     -- ---------------------------------------------------------------------------------------
  155.    
  156.     -- Rez fusion zipped project file
  157.     -- Example: /home/vfx/Desktop/fusion_rez.zip
  158.     zipFilepath = desktopDirectory .. 'fusion_rez.zip'
  159.    
  160.     -- Rez fusion CMakeLists.txt file
  161.     -- Example: /home/vfx/Desktop/fusion/CMakeLists.txt
  162.     cmakeFilepath = outputDirectory .. 'CMakeLists.txt'
  163.    
  164.     -- Rez fusion package.py file
  165.     -- Example: /home/vfx/Desktop/fusion/package.py
  166.     packageFilepath = outputDirectory .. 'package.py'
  167.    
  168.     -- Rez fusion README.txt file
  169.     -- Example: /home/vfx/Desktop/fusion/README.txt
  170.     readmeFilepath = outputDirectory .. 'README.txt'
  171.    
  172.     -- Rez fusion Reactor.fu file
  173.     -- Example: /home/vfx/Desktop/fusion/opt/BlackmagicFusion/Fusion9/Config/Reactor.fu
  174.     reactorFilepath = optFusionConfigDirectory .. 'Reactor.fu'
  175.    
  176.     -- ---------------------------------------------------------------------------------------
  177.     -- Create the CMakeLists.txt file
  178.     -- ---------------------------------------------------------------------------------------
  179.     print('\n[Saving CMakeLists.txt] ' .. tostring(cmakeFilepath))
  180.     local cmakeString = AddCmake()
  181.     writeTextFile(cmakeFilepath, cmakeString, printStatus)
  182.    
  183.     -- ---------------------------------------------------------------------------------------
  184.     -- Create the package.py file
  185.     -- ---------------------------------------------------------------------------------------
  186.     print('\n[Saving package.py] ' .. tostring(packageFilepath))
  187.     local packageString = AddPackage()
  188.     writeTextFile(packageFilepath, packageString, printStatus)
  189.    
  190.    
  191.     -- ---------------------------------------------------------------------------------------
  192.     -- Create the README.txt file
  193.     -- ---------------------------------------------------------------------------------------
  194.     print('\n[Saving README.txt] ' .. tostring(readmeFilepath))
  195.     local readmeString = AddReadme()
  196.     writeTextFile(readmeFilepath, readmeString, printStatus)
  197.    
  198.    
  199.     -- ---------------------------------------------------------------------------------------
  200.     -- Install the Reactor.fu file
  201.     -- ---------------------------------------------------------------------------------------
  202.     if reactorPackageSupport == true or reactorPackageSupport == 1 then
  203.         print('\n[Downloading Reactor.fu] ' .. tostring(reactorFilepath))
  204.         local reactorString = AddReactor()
  205.         writeTextFile(reactorFilepath, reactorString, printStatus)
  206.     else
  207.         print('\n[Skipping the Reactor.fu Stage]')
  208.     end
  209.    
  210.     -- ---------------------------------------------------------------------------------------
  211.     -- Zip the $Home/Desktop/fusion/ folder
  212.     -- ---------------------------------------------------------------------------------------
  213.     if rezPackageZipped == true or rezPackageZipped == 1 then
  214.         print('\n[Zipping Rez Files] ' .. tostring(zipFilepath))
  215.         zipFolder(zipFilepath, outputDirectory, false, false)
  216.     else
  217.         print('\n[Skipping the Zipping Stage]')
  218.     end
  219.    
  220.     print('\n')
  221.     print('----------------------------------------------------------------------')
  222.    
  223.     print('[Saving Rez Project] ' .. tostring(outputDirectory) .. '\n\n')
  224.     print('----------------------------------------------------------------------')
  225. end
  226.  
  227.  
  228. -- Add the CMakeLists.txt file
  229. -- Example: local cmakeString = AddCmake()
  230. function AddCmake()
  231.     local cmakeString = [[cmake_minimum_required(VERSION 2.8)
  232.  
  233. include(RezBuild)
  234.  
  235. file(GLOB_RECURSE opt_files "opt/*")
  236. rez_install_files(
  237.     ${opt_files}
  238.     DESTINATION .
  239.     EXECUTABLE
  240. )
  241.  
  242. file(GLOB_RECURSE txt_files "README.txt")
  243. rez_install_files(
  244.     ${txt_files}
  245.     DESTINATION .
  246.     EXECUTABLE
  247. )
  248.  
  249. ]]
  250.    
  251.     return cmakeString
  252. end
  253.  
  254.  
  255. -- Add the package.py file
  256. -- Example: local packageString = AddPackage()
  257. function AddPackage()
  258.     local packageString = [[# -*- coding: utf-8 -*-
  259. name = 'fusion'
  260. version = '9.0.2'
  261. description ='Fusion + Fusion Render Node package.'
  262. authors = [
  263.     'AndrewHazelden'
  264. ]
  265.  
  266. tools = [
  267.     'fuscript'
  268.     'Fusion'
  269.     'FusionServer'
  270.     'FusionRenderNode'
  271. ]
  272.  
  273. requires = [
  274.     'python-2.7'
  275. ]
  276.  
  277. def commands():
  278.     # Add the PATH values to the rez environment
  279.     env.PATH.append('{root}/opt/BlackmagicDesign/Fusion9')
  280.     env.PATH.append('{root}/opt/BlackmagicDesign/FusionRenderNode9')
  281.    
  282.     # Setup Reactor and define the "Reactor:" pathmap as "{root}/opt/Reactor"
  283.     env.REACTOR_INSTALL_PATHMAP.append('{root}/opt/')
  284.     env.REACTOR_DEBUG.append('true')
  285.     env.REACTOR_DEBUG_FILES.append('true')
  286.    
  287.     # Workaround a "libFusion.so" error by creating an alias so running the "Fusion" and "FusionRenderNode" program calls the absolute path version.
  288.     alias('Fusion', '{root}/opt/BlackmagicDesign/Fusion9/Fusion')
  289.     alias('FusionRenderNode', '{root}/opt/BlackmagicDesign/FusionRenderNode9/FusionRenderNode')
  290.  
  291. uuid = ']]  .. bmd.createuuid() .. [['
  292.  
  293. ]]
  294.    
  295.     return packageString
  296. end
  297.  
  298.  
  299. -- Add the README.txt file
  300. -- Example: local readmeString = AddReadme()
  301. function AddReadme()
  302.     local readmeString = [[# Fusion 9 Free Rez Package
  303. # by Andrew Hazelden <andrew@andrewhazelden.com>
  304. # ]] .. os.date('%Y-%m-%d %I:%M:%S %p') .. [[
  305.  
  306. # Unzip the "fusion_rez.zip" package on your desktop.
  307. mkdir -p $HOME/Desktop/fusion/
  308. cd $HOME/Desktop/fusion/
  309. unzip ../fusion_rez.zip
  310.  
  311. # Install the "fusion" package in rez:
  312. {
  313. cd $HOME/Desktop/fusion/
  314. rez-build --install
  315. rez-env fusion
  316. }
  317.  
  318. # By default Rez will install the "fusion" package at:
  319. # $HOME/packages/fusion/9.0.2/
  320.  
  321. # Check if the new "fusion" rez package was loadable in the rez environment and the "Fusion" program file can be located
  322. rez-env fusion -- which Fusion
  323.  
  324. # Example "which Fusion" output:
  325. # /home/vfx/packages/fusion/9.0.2/opt/BlackmagicDesign/Fusion9/Fusion
  326.  
  327. # Launch Fusion
  328. rez-env fusion -- Fusion
  329.  
  330. # Launch the Fusion Render Node
  331. rez-env fusion -- FusionRenderNode /path/to/fusion.comp -render -start 1001 -end 1145 -step 1 -quit -quiet
  332.  
  333. # ----------------------------------------------------------
  334.  
  335. # Fusion Startup Notes:
  336. # When Fusion and the FusionRenderNode executables are launched in the rez they have to be started by changing the working directory to the program's folder or by defining the absolute path. To make things easier the Rez "package.py" file has BASH aliases setup for "Fusion" and "FusionRenderNode" that will enter the absolute filepath when the program names are entered.
  337.  
  338. # Example Usage: Fusion
  339. # Example Usage: FusionRenderNode
  340.  
  341. # If the Rez "package.py" file didn't have an alias entry and you ran Fusion in the terminal merely by typing "Fusion", you would see an error in the Fusion GUI with the error message "[string "FFI Script"]:2095: libFusion.so: cannot open shared object file: No such file or directory". Click "OK" to continue.
  342.  
  343. # This "libFusion.so" error effects fuses from loading and macros from working. If you don't like the alias approach you could work around the problem by setting the working directory to the Fusion program folder then running "./Fusion".
  344.  
  345. # ----------------------------------------------------------
  346.  
  347. # Known Warnings When Starting Fusion from the Terminal:
  348.  
  349. # You will see a warning message in the terminal when Fusion starts up that says:
  350. # "ldconfig: command not found" which you can ignore for now and the Fusion GUI will load. Fusion uses ldconfig to find Python on the system but the warning message doesn't appear to effect the Rez package's usage of python 2.7 so it can likely be ignored.
  351.  
  352. # ----------------------------------------------------------
  353.  
  354. # Reactor for Fusion Notes:
  355.  
  356. # Reactor.fu can be found in the folder:
  357. # $HOME/packages/fusion/9.0.2/var/BlackmagicDesign/Fusion/Config/Reactor.fu
  358.  
  359. # The fusion rez "package.py" file sets up a "REACTOR_INSTALL_PATHMAP" evironment variable. This env var means the "Reactor:" PathMap files are downloaded and placed inside the "$HOME/packages/fusion/9.0.2/opt/Reactor/" folder.
  360.  
  361. # ----------------------------------------------------------
  362.  
  363. ]]
  364.    
  365.     return readmeString
  366. end
  367.  
  368.  
  369. -- Add the Reactor.fu file
  370. -- Example: local reactorString = AddReactor()
  371. function AddReactor()
  372.     -- Add the Reactor Public ProjectID to Reactor.cfg
  373.     local reactor_project_id = '5058837'
  374.    
  375.     -- Check the "REACTOR_BRANCH" environment variable to find out which GitLab branch should be used (master/dev/)
  376.     local branch = os.getenv('REACTOR_BRANCH')
  377.     if branch == nil then
  378.         branch = 'master'
  379.     end
  380.    
  381.     -- GitLab Public Access Token
  382.     local token = ''
  383.    
  384.     -- Download URL
  385.     local fuURL = 'https://gitlab.com/api/v4/projects/' .. reactor_project_id .. '/repository/files/Reactor%2Efu/raw?ref=' .. branch .. '&private_token=' .. token
  386.  
  387.     -- ---------------------------------------------------------------------------------------
  388.     -- Access the FFI and cURL Libraries
  389.     -- ---------------------------------------------------------------------------------------
  390.     ffi = require 'ffi'
  391.     curl = require 'lj2curl'
  392.     ezreq = require 'lj2curl.CRLEasyRequest'
  393.    
  394.     local req = ezreq(fuURL)
  395.     local body = {}
  396.     req:setOption(curl.CURLOPT_SSL_VERIFYPEER, 0)
  397.     req:setOption(curl.CURLOPT_WRITEFUNCTION, ffi.cast('curl_write_callback', function(buffer, size, nitems, userdata)
  398.         table.insert(body, ffi.string(buffer, size*nitems))
  399.         return nitems
  400.      end))
  401.      
  402.     ok, err = req:perform()
  403.     if ok then
  404.     -- Check if the file was downloaded correctly
  405.         if table.concat(body) == [[{"message":"401 Unauthorized"}]] then
  406.             print("[Error] The \"Token ID\" field is empty. Please enter a GitLab personal access token and then click the \"Install and Relaunch\" button again.\n")
  407.             return
  408.         elseif table.concat(body) == [[{"message":"404 Project Not Found"}]] then
  409.             print("[Error]\nThe \"Token ID\" field is empty. Please enter a GitLab personal access token and then click the \"Install and Relaunch\" button again.\n")
  410.             return
  411.         elseif table.concat(body) == [[{"message":"404 File Not Found"}]] then
  412.             print("[Error]\nThe main Reactor GitLab file has been renamed. Please download and install a new Reactor Bootstrap Installer script or you can try manually installing the latest Reactor.fu file.\n")
  413.             return
  414.         elseif table.concat(body) == [[{"error":"invalid_token","error_description":"Token was revoked. You have to re-authorize from the user."}]] then
  415.             print("[Error]\nYour GitLab TokenID has been revoked. Please enter a new TokenID value in your Reactor.cfg file, or switch to the Reactor Public repo and remove your existing Reactor.cfg file.\n")
  416.             return
  417.         elseif table.concat(body) == [[{"message":"404 Commit Not Found"}]] then
  418.             print("[Error]\nGitLab Previous CommitID Empty Error. Please remove your existing Reactor.cfg file and try again. Alternativly, you may have a REACTOR_BRANCH environment variable active and it is requesting a branch that does not exist.\n")
  419.             return
  420.         elseif table.concat(body) == [[{"error":"insufficient_scope","error_description":"The request requires higher privileges than provided by the access token.","scope":"api"}]] then
  421.             print("[Error]\nGitLab TokenID Permissions Scope Error. Your current GitLab TokenID privileges do not grant you access to this repository.\n")
  422.             return
  423.         end
  424.     end
  425.    
  426.     -- Return the downloaded Reactor.fu file
  427.     local reactorString = table.concat(body)
  428.     return reactorString
  429. end
  430.  
  431.  
  432. -- Write a string to a text file
  433. -- Example: writeTextFile('/Volumes/projects/untitled/file.txt', 'Hello World', true)
  434. function writeTextFile(filepath, text, status)
  435.     -- convert the pathmaps in the file path to an absolute path
  436.     -- absolutePath = comp:MapPath(filepath)
  437.     local absolutePath = filepath
  438.    
  439.     -- Create the output folder if required
  440.     if platform == 'Windows' then
  441.         os.execute('mkdir "' .. Dirname(absolutePath) .. '"')
  442.     else
  443.         -- Mac and Linux
  444.         os.execute('mkdir -p "' .. Dirname(absolutePath) .. '"')
  445.     end
  446.    
  447.     -- Open up the file pointer for the output textfile
  448.     local outFile, err = io.open(absolutePath, 'w')
  449.     if err then
  450.         print('[Error Opening File for Writing] ' .. absolutePath)
  451.         return
  452.     end
  453.    
  454.     if (string.len(text) >= 1) then
  455.         -- Print the file output details
  456.         if status == 1 or status == true then
  457.             print('[Saving File] ' .. absolutePath)
  458.             print(text)
  459.         end
  460.        
  461.         -- Write the text string to disk
  462.         outFile:write(text)
  463.     else
  464.         if status == 1 or status == true then
  465.             print('[No Text to Write]')
  466.         end
  467.     end
  468.    
  469.     -- Close the file pointer on the output textfile
  470.     outFile:close()
  471. end
  472.  
  473.  
  474. -- Get the parent directory for a file
  475. function Dirname(mediaDirName)
  476.     -- Get the current slash direction for the current OS platform
  477.     osSep = package.config:sub(1,1)
  478.    
  479.     return mediaDirName:match('(.*' .. osSep .. ')')
  480. end
  481.  
  482.  
  483. -- Check if a directory exists
  484. -- Example: DirectoryExists('/Volumes/projects/untitled/')
  485. function DirectoryExists(workingDir)
  486.     -- Fusion 9 based
  487.     return bmd.fileexists(workingDir)
  488.    
  489.     -- Todo: Use LuaJIT / luaFS native code to do this check
  490.     -- return true
  491. end
  492.  
  493.  
  494. -- Check if a file exists
  495. -- Example: FileExists('/Volumes/projects/untitled/file.txt')
  496. function FileExists(filename)
  497.     local filePtr = io.open(filename, "r")
  498.    
  499.     -- Check if a file pointer could be created for the specified document
  500.     if filePtr ~= nil then
  501.         io.close(filePtr)
  502.         return true
  503.     else
  504.         -- If a file pointer can't be made then the file doesn't exist or lacks read access
  505.         return false
  506.     end
  507. end
  508.  
  509.  
  510. -- Open a folder window up using your desktop file browser
  511. function OpenDirectory(mediaDirName)
  512.     local dir = Dirname(mediaDirName)
  513.    
  514.     -- Double check that the folder actually exists before trying to open it
  515.     if DirectoryExists(dir) == true then
  516.         local command = ''
  517.         if platform == 'Windows' then
  518.             -- Running on Windows
  519.             command = 'explorer "' .. dir .. '"'
  520.             print('[Launch Command] ', command)
  521.             os.execute(command)
  522.         elseif platform == 'Mac' then
  523.             -- Running on Mac
  524.             command = 'open "' .. dir .. '" &'
  525.             print('[Launch Command] ', command)
  526.             os.execute(command)
  527.         elseif platform == 'Linux' then
  528.             -- Running on Linux
  529.             command = 'nautilus "' .. dir .. '" &'
  530.             print('[Launch Command] ', command)
  531.             os.execute(command)
  532.         else
  533.             print('[Platform] ', platform)
  534.             print('There is an invalid platform defined in the local platform variable at the top of the code.')
  535.         end
  536.     end
  537. end
  538.  
  539.  
  540. -- Get the base filename from a filepath
  541. function GetFilename(mediaDirName)
  542.     local path, basename = string.match(mediaDirName, "^(.+[/\\])(.+)")
  543.    
  544.     return basename
  545. end
  546.  
  547.  
  548. -- Get the base filename without the file extension or frame number from a filepath
  549. function GetFilenameNoExt(mediaDirName)
  550.     local path, basename = string.match(mediaDirName, "^(.+[/\\])(.+)")
  551.     local name, extension = string.match(basename, "^(.+)(%..+)$")
  552.     local barename, sequence = string.match(name, "^(.-)(%d+)$")
  553.    
  554.     return barename
  555. end
  556.  
  557.  
  558. -- Get the file extension from a filepath
  559. function GetExt(mediaDirName)
  560.     local path, basename = string.match(mediaDirName, "^(.+[/\\])(.+)")
  561.     local name, extension = string.match(basename, "^(.+)(%..+)$")
  562.     local barename, sequence = string.match(name, "^(.-)(%d+)$")
  563.    
  564.     return extension
  565. end
  566.  
  567.  
  568. -- Read a binary file to calculate the filesize in bytes
  569. -- Example: size = GetFilesize('/image.png')
  570. function GetFilesize(filename)
  571.     fp, errMsg = io.open(filename, "rb")
  572.     if fp == nil then
  573.         print('[Filesize] Error reading the file: ' .. filename)
  574.         return 0
  575.     end
  576.    
  577.     local filesize = fp:seek('end')
  578.     fp:close()
  579.    
  580.     return filesize
  581. end
  582.  
  583.  
  584.  
  585. -- Zip a single file
  586. -- Example: zipFile('Temp:/archive.zip', 'Comp:/image.jpg', false)
  587. function zipFile(zipFilename, sourceFileName, moveFile)
  588.     -- Expand the pathmaps in the zip filename
  589.     -- pathMappedZipFilename = comp:MapPath(zipFilename)
  590.     pathMappedZipFilename = zipFilename
  591.    
  592.     -- Create the zip output folder if required
  593.     os.execute('mkdir "' .. Dirname(pathMappedZipFilename) .. '"')
  594.    
  595.     -- Expand the pathmaps in the filepath
  596.     -- pathMappedSourceFileName = comp:MapPath(sourceFileName)
  597.     pathMappedSourceFileName = sourceFileName
  598.    
  599.     -- The individual source file to be zipped with the absolute path removed
  600.     sourceFileNoPath = GetFilename(pathMappedSourceFileName)
  601.     workingFolder = Dirname(pathMappedSourceFileName)
  602.    
  603.     -- You can find custom zip flag options in the terminal using 'man zip'
  604.     zipOptions = ''
  605.    
  606.     if moveFile == true or moveFile == 1 then
  607.         -- The move option --move will remove the source files when the zip is created
  608.         zipOptions = zipOptions .. '--move' .. ' '
  609.     end
  610.    
  611.     -- Compression
  612.     zipOptions = zipOptions .. '--compression-method deflate' .. ' '
  613.     -- zipOptions = zipOptions .. '--compression-method store' .. ' '
  614.     -- zipOptions = zipOptions .. '--compression-method bzip2' .. ' '
  615.    
  616.     -- Compression Speed
  617.     -- -# range is -0 to -9 (where -0 = no compression just store the files and -9 = file savings)
  618.     -- zipOptions = zipOptions .. '-0' .. ' ' -- no compression just store the files
  619.     -- zipOptions = zipOptions .. '-6' .. ' ' -- Default compression level
  620.     -- zipOptions = zipOptions .. '-9' .. ' ' -- Slowest but maximum compression level
  621.    
  622.     -- Junk Paths
  623.     -- zipOptions = zipOptions .. '--junk-paths' .. ' ' -- remove the absolute folders from the output and store flat files in the zip with intermediate folders
  624.    
  625.     -- Viewer Variables
  626.     viewerProgram = nil
  627.     command = nil
  628.    
  629.     -- Command line zip program
  630.     if platform == 'Windows' then
  631.         -- Running on Windows
  632.         defaultProgram = "E:\\cygwin64\\bin\\zip.exe"
  633.         -- defaultProgram = 'zip.exe'
  634.         zipProgram = '"' .. defaultProgram .. '"'
  635.        
  636.         -- Add the cd command to change the working directory
  637.         -- command = 'cd "' .. workingFolder .. '" && ' .. 'start "" ' .. zipProgram .. ' ' .. zipOptions .. ' "' .. pathMappedZipFilename .. '" ' .. ' "' .. sourceFileNoPath .. '"'
  638.        
  639.         command = 'cd "' .. workingFolder .. '" && ' .. '' .. zipProgram .. ' ' .. zipOptions .. ' "' .. pathMappedZipFilename .. '" ' .. ' "' .. sourceFileNoPath .. '"'
  640.        
  641.         print('[Launch Command] ', command)
  642.         os.execute(command)
  643.     elseif platform == "Mac" then
  644.         -- Running on Mac
  645.         defaultProgram = '/usr/bin/zip'
  646.         zipProgram = '"' .. defaultProgram .. '"'
  647.         command = 'cd "' .. workingFolder .. '";' .. zipProgram .. ' ' .. zipOptions .. ' "' .. pathMappedZipFilename .. '" ' .. ' "' .. sourceFileNoPath .. '"'
  648.        
  649.         print('[Launch Command] ', command)
  650.         os.execute(command)
  651.     elseif platform == 'Linux' then
  652.         -- Running on Linux
  653.         defaultProgram = '/usr/bin/zip'
  654.         zipProgram = '"' .. defaultProgram .. '"'
  655.         command = 'cd "' .. workingFolder .. '";' .. zipProgram .. ' ' .. zipOptions .. ' "' .. pathMappedZipFilename .. '" ' .. ' "' .. sourceFileNoPath .. '"'
  656.        
  657.         print('[Launch Command] ', command)
  658.         os.execute(command)
  659.     else
  660.         print('[Platform] ', platform)
  661.         print('There is an invalid platform defined in the local platform variable at the top of the code.')
  662.     end
  663. end
  664.  
  665.  
  666. -- Zip a folder
  667. -- Example: zipFolder('Temp:/archive.zip', 'Comp:/', false, true)
  668. function zipFolder(zipFilename, sourceFolderName, moveFile, excludeZips)
  669.     -- Expand the pathmaps in the zip filename
  670.     -- pathMappedZipFilename = comp:MapPath(zipFilename)
  671.     pathMappedZipFilename = zipFilename
  672.    
  673.     -- Create the zip output folder if required
  674.     if platform == 'Windows' then
  675.         os.execute('mkdir "' .. Dirname(pathMappedZipFilename) .. '"')
  676.     else
  677.         os.execute('mkdir -p "' .. Dirname(pathMappedZipFilename) .. '"')
  678.     end
  679.     -- The individual source file to be zipped with the absolute path removed
  680.     -- workingFolder = comp:MapPath(sourceFolderName)
  681.     workingFolder = sourceFolderName
  682.    
  683.     -- You can find custom zip flag options in the terminal using 'man zip'
  684.     zipOptions = ''
  685.    
  686.     if moveFile == true or moveFile == 1 then
  687.         -- The move option --move will remove the source files when the zip is created
  688.         zipOptions = zipOptions .. '--move' .. ' '
  689.     end
  690.    
  691.     -- Recursively add sub-folders
  692.     zipOptions = zipOptions .. '-r' .. ' '
  693.    
  694.     -- Compression
  695.     zipOptions = zipOptions .. '--compression-method deflate' .. ' '
  696.     -- zipOptions = zipOptions .. '--compression-method store' .. ' '
  697.     -- zipOptions = zipOptions .. '--compression-method bzip2' .. ' '
  698.    
  699.     -- Compression Speed
  700.     -- -# range is -0 to -9 (where -0 = no compression just store the files and -9 = file savings)
  701.     -- zipOptions = zipOptions .. '-0' .. ' ' -- no compression just store the files
  702.     -- zipOptions = zipOptions .. '-6' .. ' ' -- Default compression level
  703.     -- zipOptions = zipOptions .. '-9' .. ' ' -- Slowest but maximum compression level
  704.    
  705.     -- Junk Paths
  706.     -- zipOptions = zipOptions .. '--junk-paths' .. ' ' -- remove the absolute folders from the output and store flat files in the zip with intermediate folders
  707.    
  708.     -- Exclude items from the zip
  709.     if excludeZips == true or excludeZips == 1 then
  710.         -- Exclude the .zip files and the OS generated thumbnails
  711.         zipExcludeList = '-x "*.DS_Store" "*Thumbs.db" "*.zip"' .. ' '
  712.     else
  713.         -- Exclude OS generated thumbnails and other files
  714.         zipExcludeList = '-x "*.DS_Store" "*Thumbs.db"' .. ' '
  715.     end
  716.    
  717.     -- Viewer Variables
  718.     viewerProgram = nil
  719.     command = nil
  720.    
  721.     -- Command line zip program
  722.     if platform == 'Windows' then
  723.         -- Running on Windows
  724.         defaultProgram = "C:\\cygwin64\\bin\\zip.exe"
  725.         -- defaultProgram = 'zip.exe'
  726.         zipProgram = '"' .. defaultProgram .. '"'
  727.        
  728.         -- Add the cd command to change the working directory
  729.         -- command = 'cd /D "' .. workingFolder .. '" && ' .. 'start "" ' .. zipProgram .. ' ' .. zipOptions .. ' "' .. pathMappedZipFilename .. '" ' .. ' . ' .. zipExcludeList
  730.        
  731.         -- Note: cd /D changes the drive letter and the directory
  732.         command = 'cd /D "' .. workingFolder .. '" && ' .. '' .. zipProgram .. ' ' .. zipOptions .. ' "' .. pathMappedZipFilename .. '" ' .. ' . ' .. zipExcludeList
  733.        
  734.         print('[Launch Command] ', command)
  735.         os.execute(command)
  736.     elseif platform == 'Mac' then
  737.         -- Running on Mac
  738.         defaultProgram = '/usr/bin/zip'
  739.         zipProgram = '"' .. defaultProgram .. '"'
  740.         command = 'cd "' .. workingFolder .. '";' .. zipProgram .. ' ' .. zipOptions .. ' "' .. pathMappedZipFilename .. '" ' .. ' . ' .. zipExcludeList
  741.    
  742.         print('[Launch Command] ', command)
  743.         os.execute(command)
  744.     elseif platform == 'Linux' then
  745.         -- Running on Linux
  746.         defaultProgram = '/usr/bin/zip'
  747.         zipProgram = '"' .. defaultProgram .. '"'
  748.         command = 'cd "' .. workingFolder .. '";' .. zipProgram .. ' ' .. zipOptions .. ' "' .. pathMappedZipFilename .. '" ' .. ' . ' .. zipExcludeList
  749.    
  750.         print('[Launch Command] ', command)
  751.         os.execute(command)
  752.     else
  753.         print('[Platform] ', platform)
  754.         print('There is an invalid platform defined in the local platform variable at the top of the code.')
  755.     end
  756. end
  757.  
  758. -- Main is where the magic happens
  759. Main()
  760. print('[Done]')
  761.  
  762.  


Added in 7 minutes 20 seconds:
Midgardsormr wrote:
Wed Dec 05, 2018 11:38 am
Does anyone know of a way to use Lua to fetch an image from a zip archive that doesn't have the .zip extension? I'd love to be able to grab Fusion's Cog icon directly from the .fuskin file instead of creating an unnecessary file dependency.

Option #2

You could use Fusion 9 + Lua + FFI + built-in Z-lib support in Fusion 9.02. and Resolve 15.2 (on Mac and Windows) . This won't help Midgardsormr if he is running this Lua script to unzip files in Fu 7. Nor will it help theotheo if you are trying to use that approach in Fusion 9 on Linux as their was a linking issue I think that was only fixed in Resolve 15.2-ish with z-lib + FFI in Lua. My memory is a bit hazy on that one. It was a while ago.

Here was a mini proof of concept Lua FFI Zip tools script I made back in March 16, 2018 for potential use with Reactor 1v/v2.

(Warning: It's unsupported and a rough WIP.)
Lua FFI Zip Tools.zip

Option #3

Install Resolve for Windows on one of your systems. Look in the Resolve Program Files folder. There is a ZIP expander exe in that folder that was an open source pre-compiled "pkzip" style extraction tool for Windows.You could use that directly in your pipeline Lua script at that filepath, or copy that item to a folder you manage then run it.

Option #4

Install Lua Rocks and then a z-lib style library for zip expansion. You could run using Lua FFI, or to run via the requires () stuff in Lua. I haven't done that with Lua Rocks on Windows but its worth can be done that way.

(FWIW I use macOS + Brew + Lua Rocks which is a breeze.)

Lots of choices for ZIP tools are possible to choose from here via Lua Rocks's search mode:
https://luarocks.org/search?q=zip

Option #5

Use the Lua 5.1 ~kinda compatible tool called LuaJIT and find a zip usable library via the LuaPower resource site. (These should be binary compatible with Fusion since Fusion uses a modified LuaJIT implementation internally for FuScript's JIT compiled Fuse and FFI support.)

https://luapower.com/minizip

Option #6

Use LuaJIT with your own FFI linked c-code compiled ZIP decoding library.

https://luajit.org/ext_ffi.html

Option #7

Use the Fusion capacity to call Python functions from inside a Lua script via a string of text that is run. Then use Python 2.x or 3.x and import and run the python zip module.

https://pymotw.com/2/zipfile/

https://docs.python.org/3/library/zipfile.html

Option 8

There are a few more ways like using Config:/ PathMap folder based .fu or .zfu entries / the Fusion Plugin compiled SDK to make new Fusion action entries to do unzippping. Then from Lua you could use Fusion:DoAction().

Option 9

There are a few more options you could also use like:

Reading the Zip .fuskin file data, and then base64 encoding those JPG/PNG image resources inline onto a HTML image sources element in your GUI using Cygwin + a bash script to extract/cache the images you need from the fuskin. Then back in your Lua script the base64 HTML rendering of a UI Manager GUI elements can be done. This whole base64 inline concept was first discovered by @Dunn on this 2017 era post here.

The usage of a base64 inline image can be seen in the Reactor installer Lua script's GUI's icon that can be seen in the source code in this section which is found at the bottom of the file on the line #909 in Reactor v2.0's Reactor-Installer.lua:

Code: Select all

-- Reactor logo encoded as Base64 content
-- Example: itm.Logo.HTML = ReactorLogo()
function ReactorLogo()
But really those earlier 1-8 options should be enough and be better at "Fetching an image from the .fuskin file via script". Option 9 is best for non clickable logos and thumbnails placed in a GUI simply as a visual flourish. :)
You do not have the required permissions to view the files attached to this post.

User avatar
Midgardsormr
Fusionista
Posts: 799
Joined: Wed Nov 26, 2014 8:04 pm
Location: Los Angeles, CA, USA
Been thanked: 87 times
Contact:

Re: Fetching an image from the .fuskin file via script?

#5

Post by Midgardsormr » Thu Dec 06, 2018 12:21 pm

Hi Andrew!

So the answer is probably "no" for the simple application I was looking for. I'd rather deal with a single small image dependency than require an entire Lua module or additional application just for a button icon. I can just see explaining to IT that I need Cygwin added to all of the workstation images just to make a pretty button!

Though I will look through the Z-Lib examples to see if that might do what I want. Thanks!

And for the internal pipeline, I just made a copy of the file and gave it the .zip extension. I'll have to do the same every time we update (assuming a new update ever arrives).

User avatar
SecondMan
Site Admin
Posts: 2806
Joined: Thu Jul 31, 2014 5:31 pm
Location: Vancouver, Canada
Been thanked: 114 times
Contact:

Re: Fetching an image from the .fuskin file via script?

#6

Post by SecondMan » Thu Dec 06, 2018 12:52 pm

Midgardsormr wrote:
Thu Dec 06, 2018 12:21 pm
And for the internal pipeline, I just made a copy of the file and gave it the .zip extension. I'll have to do the same every time we update (assuming a new update ever arrives).

Dumb question maybe but as a dirty workaround could that file not be created on the fly by the script?

If not .zip then copy .fuskin to .zip and go from there?

User avatar
AndrewHazelden
Fusionator
Posts: 1042
Joined: Fri Apr 03, 2015 3:20 pm
Location: West Dover, Nova Scotia, Canada
Been thanked: 97 times
Contact:

Re: Fetching an image from the .fuskin file via script?

#7

Post by AndrewHazelden » Thu Dec 06, 2018 12:56 pm

SecondMan wrote:
Thu Dec 06, 2018 12:52 pm
If not .zip then copy .fuskin to .zip and go from there
If this pipelining were being done on a macOS or Linux system I'd guess that a symlink could probably fulfill the filename .zip extension needs of a Fusion .fuskin without duplicating the file. :)

Added in 19 minutes 18 seconds:
Midgardsormr wrote:
Thu Dec 06, 2018 12:21 pm
So the answer is probably "no" for the simple application I was looking for.
Option #2 is built-in on Fusion 9.0.2. You just have to use the Zlib reading support, ;)

If you are an omniglot and can handle nested python + lua coding, then there is no reason why a simple !Py like this tip from "Fusion 8 Script Manual.pdf" page 20 couldn't be used to import and run the Py 2.x or 3.x zipfiles module via:

composition:Execute("!Py: ")
Midgardsormr wrote:
Thu Dec 06, 2018 12:21 pm
I can just see explaining to IT that I need Cygwin added to all of the workstation images just to make a pretty button!
You don't need all of Cygwin. Like 2MB worth of files. In a single folder you can place anywhere on a shared fileserve. TBH a pipeline that can't zip/unzip a file seems to be a bit lacking in my view of things. You can also use winzip or winrar via Lua os.execute too if you are so Windows centric nothing else would be allowed. :lol:

Eventually PIXAR USDZ or GLTF for models, or a Resolve .drp file, or some other other format that has a zippped wrapper will become relevant to you. Might as well discuss with IT that ZIP is a real file format. Soon enough .7z will be a reality for your pipeline too. :D

User avatar
SirEdric
Fusionator
Posts: 1222
Joined: Tue Aug 05, 2014 10:04 am
Been thanked: 108 times
Contact:

Re: Fetching an image from the .fuskin file via script?

#8

Post by SirEdric » Thu Dec 06, 2018 1:18 pm

AndrewHazelden wrote:
Thu Dec 06, 2018 1:15 pm
Eventually PIXAR USDZ or GLTF for models, or a Resolve .drp file, or some other other format that has a zippped wrapper will become relevant to you
Hell. They currently are. Both of them...:-)
(You should see my new default BlinnShader with Inputs for glTF Textures..:-))

User avatar
AndrewHazelden
Fusionator
Posts: 1042
Joined: Fri Apr 03, 2015 3:20 pm
Location: West Dover, Nova Scotia, Canada
Been thanked: 97 times
Contact:

Re: Fetching an image from the .fuskin file via script?

#9

Post by AndrewHazelden » Thu Dec 06, 2018 1:30 pm

SirEdric wrote:
Thu Dec 06, 2018 1:18 pm
Hell. They currently are. Both of them...:-)
Hi @SirEdric.

We need to be respectful. Germany and Nova Scotia do things differently pipeline wise then our LA counterparts might. We have less IT sitting between things like OBJ or MTL files and Lua parsers that re-write them on the fly. Not everyone is so lucky. ;)
SirEdric wrote:
Thu Dec 06, 2018 1:18 pm
(You should see my new default BlinnShader with Inputs for glTF Textures..:-))
You should see my SketchFab volumetric mesh sequence exporter some time. it does it all.
Including the MTL/OBJ sequence renaming and relinking, PNG to JPG sequence texture map convert, sketchfab.timeline creation, obj bounding box cropping, and 4x4 matrix transform, field-aligned grid mesh re-topo, and a CLI terminal zip too. #holograms #Lua

User avatar
SirEdric
Fusionator
Posts: 1222
Joined: Tue Aug 05, 2014 10:04 am
Been thanked: 108 times
Contact:

Re: Fetching an image from the .fuskin file via script?

#10

Post by SirEdric » Thu Dec 06, 2018 1:44 pm

AndrewHazelden wrote:
Thu Dec 06, 2018 1:30 pm
You should see my SketchFab volumetric mesh sequence exporter some time
When???
PM me for (paid) Details...:-)

User avatar
Midgardsormr
Fusionista
Posts: 799
Joined: Wed Nov 26, 2014 8:04 pm
Location: Los Angeles, CA, USA
Been thanked: 87 times
Contact:

Re: Fetching an image from the .fuskin file via script?

#11

Post by Midgardsormr » Thu Dec 06, 2018 2:55 pm

I think this thread is exemplifying the idiom "making a mountain from a mole hill." :D

I'm really not interested in expending this much effort for such a tiny "nice to have." If it ever comes to the point where I actually need to open an obfuscated zip archive, I may revisit it, but for the immediate future, I'll just distribute the danged png if and when I ever decide to share the script.

User avatar
AndrewHazelden
Fusionator
Posts: 1042
Joined: Fri Apr 03, 2015 3:20 pm
Location: West Dover, Nova Scotia, Canada
Been thanked: 97 times
Contact:

Re: Fetching an image from the .fuskin file via script?

#12

Post by AndrewHazelden » Thu Dec 06, 2018 3:13 pm

Midgardsormr wrote:
Thu Dec 06, 2018 2:55 pm
I think this thread is exemplifying the idiom "making a mount
You do hundreds of posts on the Fusion forums and WSL helping people all the time. How often can people try to help *you*?

Surely you can let SirEdric and Me do a bit of "Statler and Waldorf" from the Muppets like analysis for a very valid question. And have a chance to grok it fully for future Reactor atom's sake. :popcorn:

muppets - Statler and waldorf.jpg
Midgardsormr wrote:
Thu Dec 06, 2018 2:55 pm
If it ever comes to the point where I actually need to open an obfuscated zip archive, I may revisit it
Geez Midgardsormr.

That doesn't sound like a winning attitude if you want to be BMD "Vision" complaint and switch to the Resolve 15.2 Fusion page fully! You need to be willing to DRM lock your Fusion comp assets inside of a zipped binary .drp file. How do you expect to get BMD press release coverage in 2019 for Legion if you aren't willing to go for a bit of lock-in? :lol:
Midgardsormr wrote:
Thu Dec 06, 2018 2:55 pm
I may revisit it, but for the immediate future, I'll just distribute the danged png if and when I ever decide to share the script.
You would deny a spectator, a chance to try teaching a man how to fish? How will the man then feed his UI Manager based pipeline for a lifetime? <Lame analogy but I tried>

LOL. :D
You do not have the required permissions to view the files attached to this post.

User avatar
Midgardsormr
Fusionista
Posts: 799
Joined: Wed Nov 26, 2014 8:04 pm
Location: Los Angeles, CA, USA
Been thanked: 87 times
Contact:

Re: Fetching an image from the .fuskin file via script?

#13

Post by Midgardsormr » Thu Dec 06, 2018 4:04 pm

Ha! If it were a more pressing need, I'd be willing to hack at it for days, but considering I haven't yet written much of the code the button is supposed to execute, I don't think I should spend a whole lot of time on the completely nonconsequential. At least, not until I feel the need to procrastinate.

User avatar
AndrewHazelden
Fusionator
Posts: 1042
Joined: Fri Apr 03, 2015 3:20 pm
Location: West Dover, Nova Scotia, Canada
Been thanked: 97 times
Contact:

Re: Fetching an image from the .fuskin file via script?

#14

Post by AndrewHazelden » Thu Dec 06, 2018 4:13 pm

Okay. Can I suggest a potential alternative way to deliver you GUI based Lua scripts + image resources so they are nicely packed? Its a different way that would cut down on your install instructions and has a similar ergonomic factors of a single file install.

If you were trying to pull the Cog.png from FuSkin to keep things simple you could get some of that streamlined nature by:

Do a Config:/Cog.zfu which holds your Lua scripts + image resources + .fu menu system/hotkey. The .zfu file is essentially a zipped set of .lua + .fu + .png files. :)

User avatar
Midgardsormr
Fusionista
Posts: 799
Joined: Wed Nov 26, 2014 8:04 pm
Location: Los Angeles, CA, USA
Been thanked: 87 times
Contact:

Re: Fetching an image from the .fuskin file via script?

#15

Post by Midgardsormr » Thu Dec 06, 2018 4:51 pm

Ooh! That's nice!

The single-file install was part of what I was after. The other was the potential of an interface that would automatically update if the skin changed by pulling its assets from the skin file itself. That way, if BMD decided to alter the icons again, my GUI would adapt automatically. Assuming they didn't change file names, of course, which is a largeish assumption.

I did hack at the ZLib stuff a little this afternoon, but I didn't get far with it. Not surprising, since I just barely understand what some of it is doing.

Here's where I was after my most recent attempt:

Code: Select all

-- A snippet from my createWindow() function:
	-- Access the Fusion Skin file
	file = _fusion.CurrentComp:MapPath('Fusion:'..[[Skins\Fusion.fuskin]])
	ZipInit()
	local openZip = ZipOpen(file)
-- End of that snippet


-- From your sample code, modified to remove the Desktop: path map:

function ZipOpen(file)
	if file and bmd.fileexists(file) then
		print('[Opening Zip] File: ' .. file)
		return ffi.C.unzOpen64(file)
	else
		print('[Opening Zip] File Missing: ' .. file)
		return nil
	end
end

And my console output:

Code: Select all

[Adding FFI Zlib Support]
[Opening Zip] File: S:\net_exe\BlackMagic\fusion9\64bit\Fusion_Studio_9.02\Skins\Fusion.fuskin
...peline\wip\bray\Fusion MuseTools\Scripts\Comp\MT_dev.lua:682: cannot resolve symbol 'unzOpen64': The specified procedure could not be found.