From 18bbff40bd26d9f09d05c73f8f7c51937137398b Mon Sep 17 00:00:00 2001 From: BrandonPacewic Date: Tue, 30 Jul 2024 17:36:40 -0700 Subject: [PATCH 01/24] Initial setup of exporter MacOS installer Co-authored-by: PepperLola --- .gitignore | 1 + installer/Linux/.gitignore | 6 - installer/Linux/README.md | 58 --- installer/Linux/Synthesis.AppDir/.DirIcon | 1 - installer/Linux/Synthesis.AppDir/AppRun | 89 ----- .../Linux/Synthesis.AppDir/synthesis.desktop | 6 - .../Linux/Synthesis.AppDir/synthesis.png | Bin 42175 -> 0 bytes installer/Linux/package.sh | 96 ----- installer/OSX-DMG/.gitignore | 9 - installer/OSX-DMG/README.md | 25 -- .../SynthesisMacInstallerBackground.png | Bin 5014 -> 0 bytes .../OSX-DMG/exporter-install-instructions.md | 12 - installer/OSX-DMG/license.txt | 188 ---------- installer/OSX-DMG/make-installer.sh | 22 -- installer/OSX/.gitignore | 12 - installer/OSX/App/payload/Contents/Info.plist | 39 -- installer/OSX/App/payload/Contents/README.md | 1 - installer/OSX/App/scripts/postinstall | 7 - installer/OSX/App/scripts/preinstall | 2 - .../OSX/Assets/payload/Contents/Info.plist | 39 -- .../payload/Contents/Synthesis/README.md | 1 - installer/OSX/Assets/scripts/postinstall | 5 - installer/OSX/Assets/scripts/preinstall | 2 - .../OSX/Exporter/payload/Contents/Info.plist | 39 -- .../SynthesisInventorGltfExporter/README.md | 1 - installer/OSX/Exporter/scripts/postinstall | 4 - installer/OSX/Exporter/scripts/preinstall | 3 - installer/OSX/Installer/Distribution.xml | 28 -- .../OSX/Installer/Resources/conclusion.html | 27 -- .../OSX/Installer/Resources/license.html | 206 ----------- .../OSX/Installer/Resources/welcome.html | 12 - installer/OSX/README.md | 36 -- installer/OSX/Resources/LICENSE.txt | 1 + installer/OSX/build.sh | 8 + installer/OSX/distribution.xml | 15 + installer/OSX/pkginstall | 12 - installer/Windows/.gitignore | 11 - installer/Windows/.gitkeep | 0 installer/Windows/MainInstaller.nsi | 332 ------------------ installer/Windows/README.md | 23 -- installer/Windows/W21_SYN_sidebar.bmp | Bin 152310 -> 0 bytes installer/Windows/orange-install-nsis.ico | Bin 25214 -> 0 bytes installer/Windows/orange-r.bmp | Bin 9744 -> 0 bytes installer/Windows/synthesis-logo-64x64.ico | Bin 184765 -> 0 bytes installer/exporter/.gitignore | 2 - installer/exporter/README.md | 14 - installer/exporter/create.sh | 11 - installer/exporter/install.bat | 10 - installer/exporter/install.sh | 10 - installer/exporter/setup.bat | 9 - 50 files changed, 25 insertions(+), 1410 deletions(-) delete mode 100644 installer/Linux/.gitignore delete mode 100644 installer/Linux/README.md delete mode 120000 installer/Linux/Synthesis.AppDir/.DirIcon delete mode 100755 installer/Linux/Synthesis.AppDir/AppRun delete mode 100755 installer/Linux/Synthesis.AppDir/synthesis.desktop delete mode 100644 installer/Linux/Synthesis.AppDir/synthesis.png delete mode 100755 installer/Linux/package.sh delete mode 100644 installer/OSX-DMG/.gitignore delete mode 100644 installer/OSX-DMG/README.md delete mode 100644 installer/OSX-DMG/SynthesisMacInstallerBackground.png delete mode 100644 installer/OSX-DMG/exporter-install-instructions.md delete mode 100755 installer/OSX-DMG/license.txt delete mode 100755 installer/OSX-DMG/make-installer.sh delete mode 100644 installer/OSX/.gitignore delete mode 100755 installer/OSX/App/payload/Contents/Info.plist delete mode 100644 installer/OSX/App/payload/Contents/README.md delete mode 100755 installer/OSX/App/scripts/postinstall delete mode 100755 installer/OSX/App/scripts/preinstall delete mode 100755 installer/OSX/Assets/payload/Contents/Info.plist delete mode 100644 installer/OSX/Assets/payload/Contents/Synthesis/README.md delete mode 100755 installer/OSX/Assets/scripts/postinstall delete mode 100755 installer/OSX/Assets/scripts/preinstall delete mode 100755 installer/OSX/Exporter/payload/Contents/Info.plist delete mode 100644 installer/OSX/Exporter/payload/Contents/SynthesisInventorGltfExporter/README.md delete mode 100755 installer/OSX/Exporter/scripts/postinstall delete mode 100755 installer/OSX/Exporter/scripts/preinstall delete mode 100755 installer/OSX/Installer/Distribution.xml delete mode 100755 installer/OSX/Installer/Resources/conclusion.html delete mode 100755 installer/OSX/Installer/Resources/license.html delete mode 100755 installer/OSX/Installer/Resources/welcome.html delete mode 100644 installer/OSX/README.md create mode 100644 installer/OSX/Resources/LICENSE.txt create mode 100755 installer/OSX/build.sh create mode 100644 installer/OSX/distribution.xml delete mode 100644 installer/OSX/pkginstall delete mode 100644 installer/Windows/.gitignore create mode 100644 installer/Windows/.gitkeep delete mode 100644 installer/Windows/MainInstaller.nsi delete mode 100644 installer/Windows/README.md delete mode 100644 installer/Windows/W21_SYN_sidebar.bmp delete mode 100644 installer/Windows/orange-install-nsis.ico delete mode 100644 installer/Windows/orange-r.bmp delete mode 100644 installer/Windows/synthesis-logo-64x64.ico delete mode 100644 installer/exporter/.gitignore delete mode 100644 installer/exporter/README.md delete mode 100755 installer/exporter/create.sh delete mode 100644 installer/exporter/install.bat delete mode 100755 installer/exporter/install.sh delete mode 100644 installer/exporter/setup.bat diff --git a/.gitignore b/.gitignore index a7ea447430..5057e53d24 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,4 @@ /build/ *.log .DS_Store +*.pkg diff --git a/installer/Linux/.gitignore b/installer/Linux/.gitignore deleted file mode 100644 index 2bdd6e8d6c..0000000000 --- a/installer/Linux/.gitignore +++ /dev/null @@ -1,6 +0,0 @@ -Synthesis.AppDir/usr/bin/* -Synthesis.AppDir/fields/* -Synthesis.AppDir/robots/* - -*.md5 -*.AppImage diff --git a/installer/Linux/README.md b/installer/Linux/README.md deleted file mode 100644 index 46e539d52a..0000000000 --- a/installer/Linux/README.md +++ /dev/null @@ -1,58 +0,0 @@ -# `>_` Synthesis App Image - -For running Synthesis we have decided to package our application as an AppImage. It allows Synthesis to be packaged as a single .AppImage file. This also allows for users to run Synthesis without needing a specific distribution. - -### Initial Setup ### -It is recommended that you update the packages on your system. For arch users, run `pacman -Syu` as root. Debian users can run `apt update && apt upgrade` as root. - -### Dependencies ### -Certain dependencies are necessary in order to package Synthesis as an AppImage. - -##### FUSE ##### -For Arch, you may need to run: `pacman -S fuse` as root. For Debian, run: `apt install fuse` as root. -If you are still encountering issues, refer to this page: https://docs.appimage.org/user-guide/troubleshooting/fuse.html#ref-install-fuse - -##### appimagetool ##### -You will also end up needing appimagetool to actually create the AppImage file. However the `package.sh` script will prompt you and install it automatically. If you wish to install in manually, download the latest release from here: https://github.com/AppImage/AppImageKit/releases and make it executable. It should be called appimagetool-$ARCH.AppImage ($ARCH = whatever architecture you are using to package synthesis; most likely x86_64). - -### Initial Setup ### -In order to acheive the proper package structure for proper extraction, you must first compile a Unity build as: `Synthesis.x86_64` and store it along with all other files and directories that came with it somewhere on your machine. - -Note: It is important that you do not modify or remove any of the files and folders that come built with the `Synthesis.x86_64` file. - -It is also strongly recommended that you have some fields and robots exported in the Mirabuf format. - -### Packaging ### -The recommended way of creating the AppImage is by using the `package.sh` script. You may also opt to package Synthesis manually. There is some documentation for that process but it is recommended that you have a good understanding of what you are doing if you choose this option. - -To run the script, you will likely need to make it executable by running: `chmod +x package.sh` in your preferred terminal. You may also right click on `package.sh` in a file browser and select the option to make it executable. - -Now run the script and specify input directories for the version of synthesis you compiled as well as fields and robots: `./init.sh -f /path/to/fields/ -r /path/to/robots/ -b /path/to/synthesis/` - -Note: While it is not strictly necessary to include fields and robots, it is strongly recommended to include at least one of each - -If it is not already installed, the script will ask to install appimagetool. We recommended answering yes as it will install appimagetool.AppImage to the `~/Applications/` directory and is necessary for creating AppImage files. - -### Installing appimagetool ### -appimagetool is the name of the program that is used to create AppImages. You can download and install appimagetool through the official website https://appimage.github.io/appimagetool/ or get it through your distribution's package manager. - -Note: appimagetool is usually packaged under AppImageKit rather than as a standalone application. - -### Manual Packaging ### - -##### File locations ##### -Certain files must be moved to the correct locations. First you should move any robot files to `Synthesis.AppDir/robots` (create it if it doesn't exist). Do the same for field files but put them in `Synthesis.AppDir/fields` (create it if it doesn't exist). Finally, move all files and directories in your Synthesis build directory into `Synthesis.AppDir/usr/bin/` (once again, create it if it doesn't exist). - -##### Creating The AppImage ##### -Finally you can create your AppImage! Make sure you have all dependencies installed and run: `ARCH=x86_64 appimagetool Synthesis.AppDir` which will create the Synthesis AppImage. - -Note: Run this instead if you installed appimagetool locally: `ARCH=x86_64 /path/to/appimagetool Synthesis.AppDir` - -### Final Note ### -When the end user is downloading the AppImage file, it is strongly recommended to have them put it in the `~/Applications/` directory. This allows it to be found by appimaged as well as itself when running uninstall. It is also recommended to allow them to download the checksum.md5 file so that the file integrity can be verified using `md5sum -c checksum.md5` in the same directory as the AppImage and md5 files. - -### Troubleshooting ### -Refer to the AppImage troubleshooting page first if you are having issues: https://docs.appimage.org/user-guide/troubleshooting/index.html -The general documentation may be of use as well: https://docs.appimage.org/index.html -If the issues persist, open a github issue with details about the problem. - diff --git a/installer/Linux/Synthesis.AppDir/.DirIcon b/installer/Linux/Synthesis.AppDir/.DirIcon deleted file mode 120000 index 8c7bb9a13f..0000000000 --- a/installer/Linux/Synthesis.AppDir/.DirIcon +++ /dev/null @@ -1 +0,0 @@ -synthesis.png \ No newline at end of file diff --git a/installer/Linux/Synthesis.AppDir/AppRun b/installer/Linux/Synthesis.AppDir/AppRun deleted file mode 100755 index da2da947f5..0000000000 --- a/installer/Linux/Synthesis.AppDir/AppRun +++ /dev/null @@ -1,89 +0,0 @@ -#!/bin/sh - -show_help() { - echo "-h display help message" - echo "-u run uninstall script" -} - -install_appimaged() { - mkdir -p ~/Applications - wget -c https://github.com/$(wget -q https://github.com/probonopd/go-appimage/releases -O - | grep "appimaged-.*-x86_64.AppImage" | head -n 1 | cut -d '"' -f 2) -P ~/Applications/ - chmod +x ~/Applications/appimaged-*.AppImage - - # Launch - ~/Applications/appimaged-*.AppImage & -} - -uninstall_synthesis() { - rm -R ~/.config/Autodesk/Synthesis/ - if [ -e ~/Applications/Synthesis*.AppImage ] - then - rm ~/Applications/Synthesis*.AppImage - fi - if [ -e ~/Applications/appimaged-*.AppImage ] - then - while true; do - read -p "Do You wish to try and uninstall appimaged? (recommended) (y/n): " yn - case $yn in - [Yy]* ) - rm ~/Applications/appimaged-*.AppImage - break - ;; - [Nn]* ) - break - ;; - * ) - echo "Please answer yes or no." - ;; - esac - done - fi -} - -run_synthesis() { - mkdir -p ~/.config/Autodesk/Synthesis/Mira/Fields - cp "$HERE/fields/"*.mira ~/.config/Autodesk/Synthesis/Mira/Fields - cp "$HERE/robots/"*.mira ~/.config/Autodesk/Synthesis/Mira/ - - if [ ! -e ~/Applications/appimaged-*.AppImage ] - then - while true; do - read -p "Do You wish to install and start appimaged? (recommended) (y/n): " yn - case $yn in - [Yy]* ) - install_appimaged; - break - ;; - [Nn]* ) - break - ;; - * ) - echo "Please answer yes or no." - ;; - esac - done - fi - - exec "$EXEC" -} - -HERE="$(dirname "$(readlink -f "${0}")")" -EXEC="$HERE/usr/bin/Synthesis.x86_64" - -OPTIND=1 -while getopts ":hu" opt; do - case "$opt" in - h|\?) - show_help - exit 0 - ;; - u) - uninstall_synthesis - exit 0 - ;; - esac -done - -shift $((OPTIND-1)) - -run_synthesis diff --git a/installer/Linux/Synthesis.AppDir/synthesis.desktop b/installer/Linux/Synthesis.AppDir/synthesis.desktop deleted file mode 100755 index 424ddebffb..0000000000 --- a/installer/Linux/Synthesis.AppDir/synthesis.desktop +++ /dev/null @@ -1,6 +0,0 @@ -[Desktop Entry] -Name=Synthesis -Exec=Synthesis.x86_64 -Icon=synthesis -Type=Application -Categories=Game diff --git a/installer/Linux/Synthesis.AppDir/synthesis.png b/installer/Linux/Synthesis.AppDir/synthesis.png deleted file mode 100644 index 35f6df073646ad75f8fa7dbe386068e65eaddbab..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 42175 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 ipQP(Ag4dq|DF1&1p4FHJdVSdd0000 $INIT_DIR/checksum.md5 - md5sum -c $INIT_DIR/checksum.md5 -} - -OPTIND=1 - -ARCH="x86_64" -APP_NAME="Synthesis" -INIT_DIR="$(dirname "$(readlink -f "${0}")")" -APP_DIR="$INIT_DIR/$APP_NAME.AppDir" - -mkdir -p "$APP_DIR/usr/bin/" -mkdir -p "$APP_DIR/fields" -mkdir -p "$APP_DIR/robots" - -while getopts "h?f:r:b:" opt; do - case "$opt" in - h|\?) - show_help - exit 0 - ;; - f) - fields="$OPTARG" - ;; - r) - robots="$OPTARG" - ;; - b) - build="$OPTARG" - ;; - esac -done - -shift $((OPTIND-1)) - -if [ ! -n "$build" ] ; then - echo "Specify synthesis build directory using \"-b\"" - exit 1 -fi - -if [ -n "$fields" ] ; then - cp "$fields/"*.mira "$APP_DIR/fields/" -fi - -if [ -n "$robots" ] ; then - cp "$robots/"*.mira "$APP_DIR/robots/" -fi - -cp -R "$build/"* "$APP_DIR/usr/bin" -chmod +x "$APP_DIR/AppRun" -chmod +x "$APP_DIR/synthesis.desktop" -chmod +x "$APP_DIR/usr/bin/Synthesis.x86_64" - -if [ ! -e ~/Applications/appimagetool-*.AppImage ] ; then - while true; do - read -p "Do you wish to install appimagetool (Needed for creating the AppImage file) (y/n): " yn - case $yn in - [Yy]* ) - install_appimagetool - break - ;; - [Nn]* ) - break - ;; - * ) - echo "Please answer yes or no." - ;; - esac - done -fi - -if [ -e ~/Applications/appimagetool-x86_64.AppImage ] ; then - create_appimage -else - echo "Install appimagetool before creating AppImage" -fi diff --git a/installer/OSX-DMG/.gitignore b/installer/OSX-DMG/.gitignore deleted file mode 100644 index 5ddb15821b..0000000000 --- a/installer/OSX-DMG/.gitignore +++ /dev/null @@ -1,9 +0,0 @@ -source_folder/Synthesis.app/ -exporter_source_folder/ -Synthesis-Installer.dmg -create-dmg/ -addins-folder-link - -exporter-install-instructions.pdf - -*.dmg diff --git a/installer/OSX-DMG/README.md b/installer/OSX-DMG/README.md deleted file mode 100644 index 18cd11dd1c..0000000000 --- a/installer/OSX-DMG/README.md +++ /dev/null @@ -1,25 +0,0 @@ -# Synthesis OSX Installer (DMG Version) - -## Setup -1. Install `create-dmg`: -``` -$ git clone git@github.com:create-dmg/create-dmg.git -``` - -2. Copy the signed Synthesis app into source_folder: -``` -$ cp -r [Location of app] ./source_folder/Synthesis.app -``` - -2. Compile the `exporter-install-instructions.md` into a PDF. I recommend using the Yzane extension in VSCode. - -## Create Disk Image -Run the `make-installer.sh` shell script: -``` -$ ./make-installer.sh -``` - -Disk Image will be created at `/installer/OSX-DMG/Synthesis-Installer.dmg` - -## Notes -Update `source_folder/license.html` as needed as well as settings for the `create-dmg` command inside of `make-installer.sh`. See [create-dmg repository](https://github.com/create-dmg/create-dmg) for configuration information. \ No newline at end of file diff --git a/installer/OSX-DMG/SynthesisMacInstallerBackground.png b/installer/OSX-DMG/SynthesisMacInstallerBackground.png deleted file mode 100644 index 0d4d27e9a140ec497ca72b0a09c210c7b4f5f5a4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5014 zcmeI0SyYqP7RTeoN>#ucL1suRMJQtdnTKcrBSi>^3Npo#LMT(1gG{kn1sReS5ra%Z zDuO@|nL;20#UvIGM39+Kh%!oIn8)OvJl~i5c3;d|-^yBNefwMIoc;gr{X6Hbn=3;4 zi1HB#1S0Kp-r*tya$pTSe|&uijCj@Ou)yEp$n#fYAP|{O@pFKUt@s5DD#bc_#d=_a zVsSr52SRW-oWZXVp)u&6BLfYv(U=0BjWPrxtKsBu_EJLO@+3C+{zp-Vfav4nqN5=y z-2d}evt9eZQN@9bKcQ=q%*1z(f*swUa+eN5e|&rErR3Rujayw;-b!4}y5@a+X6Djg zK_}f0TK3#6Cj>Uddb3iGwJW}^t$#DIwzaT+Qv$siM_C#pn{TG@Vz6DWU%x&Nfy^~z z)YA_@{#iS01^MoqdB`6(9!Z?}*G(D7;jh08{GawCk~7MIL@vsx+b9~+*DfY+PU6Uf z0uzjD+ulmIyS5ywaJ3IE%6j_r>D{rJzbulsB9qtOd%9n~d?Hi9&|r7}W&U^bk%y$E zq#RHv)ZW?vQj5OvX;fB1Lc++#MiqPwRqfrVqob?q+`IbW9+D*qOa6gkDk&*RZf$M- zAmFlz?ETFtn4h1Y_?z`XZ!*Tl#wu!SiRIlb3A=6RKV~b(r*CqoEQ(LF0gtvs z$zl8W_@Gy3-*6vRwX|5a3wM@s*l^(%m%7VqWt$FzmsP~`aE}Ut*Nijp_|vAQOg=-D z`i_t3EmUF#7*X0*x=d&=ZG@eD+Q2hRU-3vw%p8f^6h3aoBOzXq9^{lH@meY<6!nMZ)y-gq?*a+{R&l-EEFgC?uI<{rA>~QJU;a zmoB}kzFJ>KCTm=w_$qmnUr>sJ-@0|HE@_iT-I~dCCgdBTSru$#0!STteer!Aj?dWw zq0WS=>gufa_I46T_}@mlo|G&FRI<_2sw%W#hS@(fBp)6g-aj^`tl%5@f|Rta<%vp( z+xy&kOq1AG0*7ZXXQ;drH>wY+opaZd=N92OcY#)H;y;bJNBcTDI;vX5Y8$kDewl+F zs=g{)b)_Z)YzoO5$8)M>u~;O_m{}!8?mm*BW-Tu%qnci1jXMWK^l79{V`pb)=JlT% zg4Y_vSGJoI9xHTvd;6$`#}9iI8D)jrKU6zcGen9)(V+708zxTPT@v>lE&k?_xN zk^%cW>!NKE!r_vqCp!(6s+cLSpRwAjvhRF)DtXl<8Dxx1P*PVXP$-nBT1FI?6^zA} zyzS#p`%X(0iLx{hgjaW@Rc7uX?e3PAmL_bBVz_ryBD5`2`5by(=|b;1Cl{-U0`>f1xUaYTUSRXV0U9V zYPoSZuaFBoMkEjj9{#&8Bw<;-y}d?!`x_Sy77gy~?xMw(8W@mOF^|Zao}Ok9PaL^D z&*#I|BLpvAyclWt)kAEA6P~_Nrj*Cr!3XzOm+^Lx&0jA5?m5rzU@2 z+qUu(5Xw>61`Ta&u^d7Nq+6^zxM**cgofewqKpjDRi3qW%a&KFy`Te6kVLk6QrN%Z z4}Nrc>-2G#&oES4?dt0CY6y1M^P`>4)Ax}d_KkU?#8Km#8XFrg4lKI{7HbtJoGf=K zkY8S2mVIWTjWTGt*Y){xq%UqVu77w~0V+y5GNy)`fI2@g$hPLUnFRHaqVjOB6V^61 zSUH-`r^4Dn8QhvD6VIg-8Wb)aEQ%GEOC|TP-028N%4BV)E|oR z!fon&S>~y*RBZ)bv}9M;QY}Nh&t|oU%91~FyP~Qp^Uj?+;(`o3$-qYd`_O1KZMh@& z+R)m^Zp!2q6&DxJfBKXKQm=pH_DiQa3J4jk#~{MPmn%eGlETn~YLMfR9;#nj{uko; zFW~FAj!BZ}sI*S_e64NmowHyPH#S{g9K2T$oV9B3fP={1iRkL_JUJjcGgR5^&;qkF?apG_GJT%n}2@NH;x7&eERaRN~ zy#e415*(lE8$TNOWX~L#+ZZ~04uL=bI5LDnjj)`yc^;4O)lvDvM%%NN`JmJoM>m-t z5PfybcFnDAlas_%ZjG3vQI{yKKdEEG!?WKMm=i-Ov$L~XJ4?0B>Y^p9suM1q7hAhQ>z6(9lpoA77z) zA4_~w*53;{kHK?o?C`=pZTUD*Afg_*~ zeKesJkR`dfc{7({apu%b8O^ZqCVg*j?{l_QcA&?98^1heN;wm_!G_@-fWp`HM8B(G z+l)X5zffcqHyA~<+X-%4AM)XPt@SrHSmWXv>u`82G_fCO9Ub2g+T< zMga7|%pZyNMiAA-9%75332b22#>R$Md-8S#|LU`AXOqQ(4xv9OPSgSPk&R#Xw@^52 zweX2Ux8{KTm|s}93+D7d)jY5(S5Z+hGS9Ev_2aJKF~E9V!ONqD7v2&cwOzlcS}7$h zE!N%M-fAD3kg_LWGuyIi{OLOlbAag`FO=BXswaJ_J3Io-H9xC$ADj`|f9cWH)kXK0 zIo8E4yz^=by9(&T6qA6<8U|`^YjY_P5%jt+%jP zC@U+Mfr7lav?LO?0Q)R1E|$4zUsxfO+I(&077v)RtiIj^fM+wH5-lbTgaq{!t2H(@ yl7(osty*X- - - - - CFBundleDevelopmentRegion - English - CFBundleExecutable - Synthesis - CFBundleGetInfoString - Unity Player version 2019.4.0f1 (0af376155913). (c) 2020 Unity Technologies ApS. All rights reserved. - CFBundleIconFile - PlayerIcon.icns - CFBundleIdentifier - com.Autodesk.Synthesis - CFBundleInfoDictionaryVersion - 6.0 - CFBundleName - Synthesis - CFBundlePackageType - APPL - CFBundleShortVersionString - 0.1 - CFBundleSupportedPlatforms - - MacOSX - - CFBundleVersion - 0 - LSApplicationCategoryType - public.app-category.games - LSMinimumSystemVersion - 10.9.0 - NSAppTransportSecurity - - NSAllowsArbitraryLoads - - - - diff --git a/installer/OSX/App/payload/Contents/README.md b/installer/OSX/App/payload/Contents/README.md deleted file mode 100644 index 3b82ea5db1..0000000000 --- a/installer/OSX/App/payload/Contents/README.md +++ /dev/null @@ -1 +0,0 @@ -## Synthesis.zip diff --git a/installer/OSX/App/scripts/postinstall b/installer/OSX/App/scripts/postinstall deleted file mode 100755 index 2c990d0d53..0000000000 --- a/installer/OSX/App/scripts/postinstall +++ /dev/null @@ -1,7 +0,0 @@ -#!/bin/bash -mv $2/Contents/Synthesis.zip /Applications/ -rm -rf $2 -cd /Applications/ -unzip /Applications/Synthesis.zip -rm -rf Synthesis.zip -exit 0 diff --git a/installer/OSX/App/scripts/preinstall b/installer/OSX/App/scripts/preinstall deleted file mode 100755 index 06bd986563..0000000000 --- a/installer/OSX/App/scripts/preinstall +++ /dev/null @@ -1,2 +0,0 @@ -#!/bin/bash -exit 0 diff --git a/installer/OSX/Assets/payload/Contents/Info.plist b/installer/OSX/Assets/payload/Contents/Info.plist deleted file mode 100755 index 734c2b7a8a..0000000000 --- a/installer/OSX/Assets/payload/Contents/Info.plist +++ /dev/null @@ -1,39 +0,0 @@ - - - - - CFBundleDevelopmentRegion - English - CFBundleExecutable - Synthesis - CFBundleGetInfoString - Unity Player version 2019.4.0f1 (0af376155913). (c) 2020 Unity Technologies ApS. All rights reserved. - CFBundleIconFile - PlayerIcon.icns - CFBundleIdentifier - com.Autodesk.Synthesis - CFBundleInfoDictionaryVersion - 6.0 - CFBundleName - Synthesis - CFBundlePackageType - APPL - CFBundleShortVersionString - 0.1 - CFBundleSupportedPlatforms - - MacOSX - - CFBundleVersion - 0 - LSApplicationCategoryType - public.app-category.games - LSMinimumSystemVersion - 10.9.0 - NSAppTransportSecurity - - NSAllowsArbitraryLoads - - - - diff --git a/installer/OSX/Assets/payload/Contents/Synthesis/README.md b/installer/OSX/Assets/payload/Contents/Synthesis/README.md deleted file mode 100644 index 970708317f..0000000000 --- a/installer/OSX/Assets/payload/Contents/Synthesis/README.md +++ /dev/null @@ -1 +0,0 @@ -## Asset/Data Files diff --git a/installer/OSX/Assets/scripts/postinstall b/installer/OSX/Assets/scripts/postinstall deleted file mode 100755 index 421ba3de1c..0000000000 --- a/installer/OSX/Assets/scripts/postinstall +++ /dev/null @@ -1,5 +0,0 @@ -#!/bin/bash -rm -rf ~/.config/Autodesk/Synthesis -mv $2/Contents/Synthesis ~/.config/Autodesk/ -rm -rf $2 -exit 0 diff --git a/installer/OSX/Assets/scripts/preinstall b/installer/OSX/Assets/scripts/preinstall deleted file mode 100755 index 06bd986563..0000000000 --- a/installer/OSX/Assets/scripts/preinstall +++ /dev/null @@ -1,2 +0,0 @@ -#!/bin/bash -exit 0 diff --git a/installer/OSX/Exporter/payload/Contents/Info.plist b/installer/OSX/Exporter/payload/Contents/Info.plist deleted file mode 100755 index 734c2b7a8a..0000000000 --- a/installer/OSX/Exporter/payload/Contents/Info.plist +++ /dev/null @@ -1,39 +0,0 @@ - - - - - CFBundleDevelopmentRegion - English - CFBundleExecutable - Synthesis - CFBundleGetInfoString - Unity Player version 2019.4.0f1 (0af376155913). (c) 2020 Unity Technologies ApS. All rights reserved. - CFBundleIconFile - PlayerIcon.icns - CFBundleIdentifier - com.Autodesk.Synthesis - CFBundleInfoDictionaryVersion - 6.0 - CFBundleName - Synthesis - CFBundlePackageType - APPL - CFBundleShortVersionString - 0.1 - CFBundleSupportedPlatforms - - MacOSX - - CFBundleVersion - 0 - LSApplicationCategoryType - public.app-category.games - LSMinimumSystemVersion - 10.9.0 - NSAppTransportSecurity - - NSAllowsArbitraryLoads - - - - diff --git a/installer/OSX/Exporter/payload/Contents/SynthesisInventorGltfExporter/README.md b/installer/OSX/Exporter/payload/Contents/SynthesisInventorGltfExporter/README.md deleted file mode 100644 index 0ec8650013..0000000000 --- a/installer/OSX/Exporter/payload/Contents/SynthesisInventorGltfExporter/README.md +++ /dev/null @@ -1 +0,0 @@ -## Exporter Files diff --git a/installer/OSX/Exporter/scripts/postinstall b/installer/OSX/Exporter/scripts/postinstall deleted file mode 100755 index 4000f1e866..0000000000 --- a/installer/OSX/Exporter/scripts/postinstall +++ /dev/null @@ -1,4 +0,0 @@ -#!/bin/bash -mv $2/Contents/SynthesisFusionAddin ~/Library/Application\ Support/Autodesk/Autodesk\ Fusion\ 360/API/AddIns/ -rm -rf $2 -exit 0 diff --git a/installer/OSX/Exporter/scripts/preinstall b/installer/OSX/Exporter/scripts/preinstall deleted file mode 100755 index 495e3edbba..0000000000 --- a/installer/OSX/Exporter/scripts/preinstall +++ /dev/null @@ -1,3 +0,0 @@ -#!/bin/bash -mkdir -p ~/Library/Application Support/Autodesk/Autodesk Fusion 360/API/AddIns/ -exit 0 diff --git a/installer/OSX/Installer/Distribution.xml b/installer/OSX/Installer/Distribution.xml deleted file mode 100755 index 4d54db2521..0000000000 --- a/installer/OSX/Installer/Distribution.xml +++ /dev/null @@ -1,28 +0,0 @@ - - - - - - - - - - - - - - - - - - - App.pkg - - - - Assets.pkg - - - - Exporter.pkg - diff --git a/installer/OSX/Installer/Resources/conclusion.html b/installer/OSX/Installer/Resources/conclusion.html deleted file mode 100755 index 9151c5f509..0000000000 --- a/installer/OSX/Installer/Resources/conclusion.html +++ /dev/null @@ -1,27 +0,0 @@ - - - - - - - -
-

Synthesis: An Autodesk Technology | 5.0.0.0 ALPHA

-

Thank you for installing Synthesis: An Autodesk Technology

-
-
-

In order to improve this product and understand how it is used, we collect non-personal product usage information. This usage information may consist of custom events like Replay Mode, Driver Practice Mode, Tutorial Link Clicked, etc. This information is not used to identify or contact you. You can turn data collection off from the Control Panel within the simulator. By installing, you agree that you have read the terms of service agreement and data collection statement above.

-
-
-

Resources

-

Go through the following link for additional information.

- -
-
-
-

Copyright © 2021 Autodesk inc.

-
- - diff --git a/installer/OSX/Installer/Resources/license.html b/installer/OSX/Installer/Resources/license.html deleted file mode 100755 index 6be72e4428..0000000000 --- a/installer/OSX/Installer/Resources/license.html +++ /dev/null @@ -1,206 +0,0 @@ - - - - - - -
-

- Apache License
- Version 2.0, January 2004
- http://www.apache.org/licenses/

- -TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION

- -1. Definitions.

- -"License" shall mean the terms and conditions for use, reproduction, -and distribution as defined by Sections 1 through 9 of this document. -


-"Licensor" shall mean the copyright owner or entity authorized by -the copyright owner that is granting the License. -


-"Legal Entity" shall mean the union of the acting entity and all -other entities that control, are controlled by, or are under common -control with that entity. For the purposes of this definition, -"control" means (i) the power, direct or indirect, to cause the -direction or management of such entity, whether by contract or -otherwise, or (ii) ownership of fifty percent (50%) or more of the -outstanding shares, or (iii) beneficial ownership of such entity. -


-"You" (or "Your") shall mean an individual or Legal Entity -exercising permissions granted by this License. -


-"Source" form shall mean the preferred form for making modifications, -including but not limited to software source code, documentation -source, and configuration files. -


-"Object" form shall mean any form resulting from mechanical -transformation or translation of a Source form, including but -not limited to compiled object code, generated documentation, -and conversions to other media types. -


-"Work" shall mean the work of authorship, whether in Source or -Object form, made available under the License, as indicated by a -copyright notice that is included in or attached to the work -(an example is provided in the Appendix below). -


-"Derivative Works" shall mean any work, whether in Source or Object -form, that is based on (or derived from) the Work and for which the -editorial revisions, annotations, elaborations, or other modifications -represent, as a whole, an original work of authorship. For the purposes -of this License, Derivative Works shall not include works that remain -separable from, or merely link (or bind by name) to the interfaces of, -the Work and Derivative Works thereof. -


-"Contribution" shall mean any work of authorship, including -the original version of the Work and any modifications or additions -to that Work or Derivative Works thereof, that is intentionally -submitted to Licensor for inclusion in the Work by the copyright owner -or by an individual or Legal Entity authorized to submit on behalf of -the copyright owner. For the purposes of this definition, "submitted" -means any form of electronic, verbal, or written communication sent -to the Licensor or its representatives, including but not limited to -communication on electronic mailing lists, source code control systems, -and issue tracking systems that are managed by, or on behalf of, the -Licensor for the purpose of discussing and improving the Work, but -excluding communication that is conspicuously marked or otherwise -designated in writing by the copyright owner as "Not a Contribution." -


-"Contributor" shall mean Licensor and any individual or Legal Entity -on behalf of whom a Contribution has been received by Licensor and -subsequently incorporated within the Work. -


-2. Grant of Copyright License. Subject to the terms and conditions of -this License, each Contributor hereby grants to You a perpetual, -worldwide, non-exclusive, no-charge, royalty-free, irrevocable -copyright license to reproduce, prepare Derivative Works of, -publicly display, publicly perform, sublicense, and distribute the -Work and such Derivative Works in Source or Object form. -


-3. Grant of Patent License. Subject to the terms and conditions of -this License, each Contributor hereby grants to You a perpetual, -worldwide, non-exclusive, no-charge, royalty-free, irrevocable -(except as stated in this section) patent license to make, have made, -use, offer to sell, sell, import, and otherwise transfer the Work, -where such license applies only to those patent claims licensable -by such Contributor that are necessarily infringed by their -Contribution(s) alone or by combination of their Contribution(s) -with the Work to which such Contribution(s) was submitted. If You -institute patent litigation against any entity (including a -cross-claim or counterclaim in a lawsuit) alleging that the Work -or a Contribution incorporated within the Work constitutes direct -or contributory patent infringement, then any patent licenses -granted to You under this License for that Work shall terminate -as of the date such litigation is filed. -


-4. Redistribution. You may reproduce and distribute copies of the -Work or Derivative Works thereof in any medium, with or without -modifications, and in Source or Object form, provided that You -meet the following conditions: -


-(a) You must give any other recipients of the Work or -Derivative Works a copy of this License; and -


-(b) You must cause any modified files to carry prominent notices -stating that You changed the files; and -


-(c) You must retain, in the Source form of any Derivative Works -that You distribute, all copyright, patent, trademark, and -attribution notices from the Source form of the Work, -excluding those notices that do not pertain to any part of -the Derivative Works; and -


-(d) If the Work includes a "NOTICE" text file as part of its -distribution, then any Derivative Works that You distribute must -include a readable copy of the attribution notices contained -within such NOTICE file, excluding those notices that do not -pertain to any part of the Derivative Works, in at least one -of the following places: within a NOTICE text file distributed -as part of the Derivative Works; within the Source form or -documentation, if provided along with the Derivative Works; or, -within a display generated by the Derivative Works, if and -wherever such third-party notices normally appear. The contents -of the NOTICE file are for informational purposes only and -do not modify the License. You may add Your own attribution -notices within Derivative Works that You distribute, alongside -or as an addendum to the NOTICE text from the Work, provided -that such additional attribution notices cannot be construed -as modifying the License. -


-You may add Your own copyright statement to Your modifications and -may provide additional or different license terms and conditions -for use, reproduction, or distribution of Your modifications, or -for any such Derivative Works as a whole, provided Your use, -reproduction, and distribution of the Work otherwise complies with -the conditions stated in this License. -


-5. Submission of Contributions. Unless You explicitly state otherwise, -any Contribution intentionally submitted for inclusion in the Work -by You to the Licensor shall be under the terms and conditions of -this License, without any additional terms or conditions. -Notwithstanding the above, nothing herein shall supersede or modify -the terms of any separate license agreement you may have executed -with Licensor regarding such Contributions. -


-6. Trademarks. This License does not grant permission to use the trade -names, trademarks, service marks, or product names of the Licensor, -except as required for reasonable and customary use in describing the -origin of the Work and reproducing the content of the NOTICE file. -


-7. Disclaimer of Warranty. Unless required by applicable law or -agreed to in writing, Licensor provides the Work (and each -Contributor provides its Contributions) on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or -implied, including, without limitation, any warranties or conditions -of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A -PARTICULAR PURPOSE. You are solely responsible for determining the -appropriateness of using or redistributing the Work and assume any -risks associated with Your exercise of permissions under this License. -


-8. Limitation of Liability. In no event and under no legal theory, -whether in tort (including negligence), contract, or otherwise, -unless required by applicable law (such as deliberate and grossly -negligent acts) or agreed to in writing, shall any Contributor be -liable to You for damages, including any direct, indirect, special, -incidental, or consequential damages of any character arising as a -result of this License or out of the use or inability to use the -Work (including but not limited to damages for loss of goodwill, -work stoppage, computer failure or malfunction, or any and all -other commercial damages or losses), even if such Contributor -has been advised of the possibility of such damages. -


-9. Accepting Warranty or Additional Liability. While redistributing -the Work or Derivative Works thereof, You may choose to offer, -and charge a fee for, acceptance of support, warranty, indemnity, -or other liability obligations and/or rights consistent with this -License. However, in accepting such obligations, You may act only -on Your own behalf and on Your sole responsibility, not on behalf -of any other Contributor, and only if You agree to indemnify, -defend, and hold each Contributor harmless for any liability -incurred by, or claims asserted against, such Contributor by reason -of your accepting any such warranty or additional liability. -


-END OF TERMS AND CONDITIONS -


-APPENDIX: How to apply the Apache License to your work. -


-Copyright 2021 Autodesk inc. -


-Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at -


-http://www.apache.org/licenses/LICENSE-2.0 -


-Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -


-

-

Click “Continue" to continue the setup

-
- - diff --git a/installer/OSX/Installer/Resources/welcome.html b/installer/OSX/Installer/Resources/welcome.html deleted file mode 100755 index dcea4723b3..0000000000 --- a/installer/OSX/Installer/Resources/welcome.html +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - -
-

This will install Synthesis: An Autodesk Application 5.0.0.0 ALPHA on your computer. You will be guided through the steps necessary to install this software.

-

Click “Continue" to continue the setup

-
- - diff --git a/installer/OSX/README.md b/installer/OSX/README.md deleted file mode 100644 index 846f17c8b2..0000000000 --- a/installer/OSX/README.md +++ /dev/null @@ -1,36 +0,0 @@ -# OSX packager - -## Build Steps : - -1. Get signed Synthesis.app - -2. Zip Synthesis.app - -3. Copy Synthesis.zip to file system ` cp [Synthesis.zip] [synthesis/installer/OSX/App/payload/Contents] ` - - - Remove the Synthesis.zip placeholder ` rm [synthesis/installer/OSX/App/payload/Contents/README.md] ` - -3. Add data files to ` synthesis/installer/OSX/Assets/payload/Contents/Synthesis ` - - - Remove the data file placeholder ` rm [synthesis/installer/OSX/Assets/payload/Contents/Synthesis/README.md] ` - -4. Add unzipped exporter files to ` synthesis/installer/OSX/Exporter/payload/Contents/SynthesisFusionGltfExporter ` - - - Remove the exporter file placeholder ` rm [synthesis/installer/OSX/Exporter/payload/Contents/SynthesisFusionGltfExporter/README.md] ` - -5. Change directories to the OSX installer directory ` cd [synthesis/installer/OSX] ` - -6. Run the pkginstall script ` ./pkginstall ` - -### Optional Build Steps - -Update the license, welcome and conclusion installer menus located in ` [synthesis/installer/OSX/Installer/Resources] ` - -## Package - -Publish the newly created Synthesis.pkg - -## Important Note - -**Do not** rename or move files - diff --git a/installer/OSX/Resources/LICENSE.txt b/installer/OSX/Resources/LICENSE.txt new file mode 100644 index 0000000000..b10760de2f --- /dev/null +++ b/installer/OSX/Resources/LICENSE.txt @@ -0,0 +1 @@ +../../../LICENSE.txt diff --git a/installer/OSX/build.sh b/installer/OSX/build.sh new file mode 100755 index 0000000000..c6a2095a77 --- /dev/null +++ b/installer/OSX/build.sh @@ -0,0 +1,8 @@ +#!/bin/bash + +FUSION_ADDIN_LOCATION="Support/Autodesk/Autodesk\ Fusion\ 360/API/AddIns/" +EXPORTER_SOURCE_DIR=../../exporter/ +FUSION_ADDIN_LOCATION=~/Documents/ + +pkgbuild --root $EXPORTER_SOURCE_DIR --identifier com.Autodesk.Synthesis --version 1.0 --scripts Scripts --install-location $FUSION_ADDIN_LOCATION MyApp.pkg +productbuild --distribution distribution.xml --package-path . MyAppInstaller.pkg diff --git a/installer/OSX/distribution.xml b/installer/OSX/distribution.xml new file mode 100644 index 0000000000..534c1465b1 --- /dev/null +++ b/installer/OSX/distribution.xml @@ -0,0 +1,15 @@ + + + Synthesis Exporter Installer + + + + + + + + + + + #MyApp.pkg + diff --git a/installer/OSX/pkginstall b/installer/OSX/pkginstall deleted file mode 100644 index 359e862088..0000000000 --- a/installer/OSX/pkginstall +++ /dev/null @@ -1,12 +0,0 @@ -#!/bin/bash -#Priviledges -chmod -R 777 ./Assets/payload/Contents/Synthesis -#Build app -pkgbuild --install-location ~/.config/Autodesk/SynthesisAppInstall --root ./App/payload/ --scripts ./App/scripts/ --identifier org.autodesk.synthesis.app ./Installer/App.pkg -#Build data files -pkgbuild --install-location ~/.config/Autodesk/SynthesisAssetsInstall --root ./Assets/payload/ --scripts ./Assets/scripts/ --identifier org.autodesk.synthesis.assets ./Installer/Assets.pkg -#Build exporter -pkgbuild --install-location ~/.config/Autodesk/SynthesisExporterInstall --root ./Exporter/payload/ --scripts ./Exporter/scripts/ --identifier org.autodesk.synthesis.exporter ./Installer/Exporter.pkg -#Build installer -cd Installer -productbuild --distribution Distribution.xml --resources Resources/ ../Synthesis.pkg diff --git a/installer/Windows/.gitignore b/installer/Windows/.gitignore deleted file mode 100644 index 65fac130c8..0000000000 --- a/installer/Windows/.gitignore +++ /dev/null @@ -1,11 +0,0 @@ -Robots/ -Fields/ -Exporter/ -Themes/ -MixAndMatch/ -Synthesis/ - -Robots.zip -Fields.zip -Themes.zip -MixAndMatch.zip diff --git a/installer/Windows/.gitkeep b/installer/Windows/.gitkeep new file mode 100644 index 0000000000..e69de29bb2 diff --git a/installer/Windows/MainInstaller.nsi b/installer/Windows/MainInstaller.nsi deleted file mode 100644 index 7cf07b658e..0000000000 --- a/installer/Windows/MainInstaller.nsi +++ /dev/null @@ -1,332 +0,0 @@ -!include MUI2.nsh -!include x64.nsh -!define PRODUCT_VERSION "6.0.0" - -Name "Synthesis" - -;Icon "W16_SYN_launch.ico" -Icon "synthesis-logo-64x64.ico" - -Caption "Synthesis ${PRODUCT_VERSION} Setup" - -OutFile "SynthesisWin${PRODUCT_VERSION}.exe" - -InstallDir $PROGRAMFILES64\Autodesk\Synthesis - -InstallDirRegKey HKLM "Software\Synthesis" "Install_Dir" - -RequestExecutionLevel admin - - Section - ${If} ${RunningX64} - goto install_stuff - ${Else} - MessageBox MB_OK "ERROR: This install requires a 64 bit system." - Quit - ${EndIf} - install_stuff: - SectionEnd - -;-------------------------------- - -;Interface Settings - !define MUI_WELCOMEFINISHPAGE_BITMAP "W21_SYN_sidebar.bmp" - !define MUI_UNWELCOMEFINISHPAGE_BITMAP "W21_SYN_sidebar.bmp" - !define MUI_ICON "synthesis-logo-64x64.ico" - !define MUI_UNICON "synthesis-logo-64x64.ico" - !define MUI_HEADERIMAGE - !define MUI_HEADERIMAGE_BITMAP "orange-r.bmp" - !define MUI_HEADERIMAGE_RIGHT - !define MUI_ABORTWARNING - !define MUI_FINISHPAGE_TEXT 'Synthesis has been successfully installed on your system. $\r$\n $\r$\nIn order to improve this product and understand how it is used, we collect non-personal product usage information. This usage information may consist of custom events like Replay Mode, Driver Practice Mode, etc. $\r$\nThis information is not used to identify or contact you. $\r$\nYou can turn data collection off from the Control Panel within the simulator. $\r$\n $\r$\nBy clicking Finish, you agree that you have read the terms of service agreement and data collection statement above.' - !define MUI_FINISHPAGE_LINK "Synthesis Discord" - !define MUI_FINISHPAGE_LINK_LOCATION "https://www.discord.gg/hHcF9AVgZA" - -;-------------------------------- - - ; Installer GUI Pages - !insertmacro MUI_PAGE_WELCOME - !insertmacro MUI_PAGE_LICENSE "..\..\LICENSE.txt" - !insertmacro MUI_PAGE_COMPONENTS - !insertmacro MUI_PAGE_INSTFILES - !insertmacro MUI_PAGE_FINISH - - ; Uninstaller GUI Pages - !insertmacro MUI_UNPAGE_WELCOME - !insertmacro MUI_UNPAGE_CONFIRM - !insertmacro MUI_UNPAGE_INSTFILES - !insertmacro MUI_UNPAGE_FINISH - -;-------------------------------- - - ; Default Language - !insertmacro MUI_LANGUAGE "English" - -Section - -IfFileExists "$APPDATA\Autodesk\Synthesis" +1 +28 - MessageBox MB_YESNO "You appear to have Synthesis installed; would you like to reinstall it?" IDYES true IDNO false - true: - DeleteRegKey HKLM SOFTWARE\Synthesis - - ; Remove fusion plugins - RMDir /r "$APPDATA\Autodesk\Autodesk Fusion 360\API\AddIns\FusionRobotExporter" - RMDir /r "$APPDATA\Autodesk\Autodesk Fusion 360\API\AddIns\Synthesis" - RMDir /r "$APPDATA\Autodesk\Autodesk Fusion 360\API\AddIns\FusionExporter" - RMDir /r "$APPDATA\Autodesk\ApplicationPlugins\FusionRobotExporter.bundle" - RMDir /r "$APPDATA\Autodesk\ApplicationPlugins\FusionSynth.bundle" - - ; Remove inventor plugins - Delete "$APPDATA\Autodesk\Inventor 2021\Addins\Autodesk.InventorRobotExporter.Inventor.addin" - Delete "$APPDATA\Autodesk\Inventor 2020\Addins\Autodesk.InventorRobotExporter.Inventor.addin" - Delete "$APPDATA\Autodesk\Inventor 2019\Addins\Autodesk.InventorRobotExporter.Inventor.addin" - Delete "$APPDATA\Autodesk\Inventor 2018\Addins\Autodesk.InventorRobotExporter.Inventor.addin" - Delete "$APPDATA\Autodesk\Inventor 2017\Addins\Autodesk.InventorRobotExporter.Inventor.addin" - Delete "$APPDATA\Autodesk\ApplicationPlugins\Autodesk.InventorRobotExporter.Inventor.addin" - RMDir /r "$APPDATA\Autodesk\ApplicationPlugins\InventorRobotExporter" - - ; Remove deprecated bxd inventor plugins - Delete "$APPDATA\Autodesk\Inventor 2020\Addins\autodesk.BxDRobotExporter.inventor.addin" - Delete "$APPDATA\Autodesk\Inventor 2019\Addins\autodesk.BxDRobotExporter.inventor.addin" - Delete "$APPDATA\Autodesk\Inventor 2019\Addins\autodesk.BxDFieldExporter.inventor.addin" - Delete "$APPDATA\Autodesk\Inventor 2018\Addins\autodesk.BxDRobotExporter.inventor.addin" - Delete "$APPDATA\Autodesk\Inventor 2018\Addins\autodesk.BxDFieldExporter.inventor.addin" - Delete "$APPDATA\Autodesk\Inventor 2017\Addins\autodesk.BxDRobotExporter.inventor.addin" - Delete "$APPDATA\Autodesk\Inventor 2017\Addins\autodesk.BxDFieldExporter.inventor.addin" - Delete "$APPDATA\Autodesk\ApplicationPlugins\Autodesk.BxDRobotExporter.Inventor.addin" - RMDir /r "$APPDATA\Autodesk\ApplicationPlugins\BxDRobotExporter" - RMDIR /r $APPDATA\RobotViewer - - ; Remove excess shortcuts - Delete "$SMPROGRAMS\Synthesis.lnk" - Delete "$DESKTOP\Synthesis.lnk" - Delete "$SMPROGRAMS\BXD Synthesis.lnk" - Delete "$DESKTOP\BXD Synthesis.lnk" - Delete "$SMPROGRAMS\Autodesk Synthesis.lnk" - Delete "$DESKTOP\Autodesk Synthesis.lnk" - Delete "$DESKTOP\FieldExporter.lnk" - - ; Remove obsolete directories - RMDir /r $INSTDIR - RMDir /r $APPDATA\Synthesis - RMDir /r $APPDATA\BXD_Aardvark - RMDir /r $PROGRAMFILES\Autodesk\Synthesis - - DeleteRegKey HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Autodesk Synthesis" - DeleteRegKey HKCU "SOFTWARE\Autodesk\Synthesis" - ;DeleteRegKey HKCU "SOFTWARE\Autodesk\BXD Synthesis" - - Goto next - - false: - Quit - - next: - -# default section end -SectionEnd - -Section "Synthesis (required)" Synthesis - - SectionIn RO - - ; Set output path to the installation directory. - SetOutPath $INSTDIR - - File /r "Synthesis\*" - - CreateShortCut "$SMPROGRAMS\Synthesis.lnk" "$INSTDIR\Synthesis.exe" - CreateShortCut "$DESKTOP\Synthesis.lnk" "$INSTDIR\Synthesis.exe" - - WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Autodesk Synthesis" \ - "DisplayName" "Autodesk Synthesis" - - WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Autodesk Synthesis" \ - "DisplayIcon" "$INSTDIR\uninstall.exe" - - WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Autodesk Synthesis" \ - "Publisher" "Autodesk" - - WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Autodesk Synthesis" \ - "URLInfoAbout" "synthesis.autodesk.com/tutorials" - - WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Autodesk Synthesis" \ - "DisplayVersion" "${PRODUCT_VERSION}" - - WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Autodesk Synthesis" \ - "UninstallString" "$\"$INSTDIR\uninstall.exe$\"" - - - WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Synthesis" "NoModify" 1 - WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Synthesis" "NoRepair" 1 - WriteUninstaller "uninstall.exe" - -SectionEnd - -/* -Section "Inventor Exporter Plugin" iExporter - - ; Set extraction path to Inventor plugin directory - SetOutPath $INSTDIR\Exporter - File /r "InventorExporter\*" - - SetOutPath $APPDATA\Autodesk\ApplicationPlugins - File /r "InventorExporter\Autodesk.InventorRobotExporter.Inventor.addin" - -SectionEnd -*/ - -Section "Fusion Exporter Plugin" fExporter - - ; Set extraction path to Fusion plugin directories - SetOutPath "$APPDATA\Autodesk\Autodesk Fusion 360\API\AddIns\Synthesis" - File /r "Exporter\*" - ; File /r "..\..\exporter\SynthesisFusionAddin\*" - - ; SetOutPath "$APPDATA\Autodesk\ApplicationPlugins\FusionRobotExporter.bundle\Contents\" - ; File /r "FusionExporter\FusionRobotExporter.dll" - -SectionEnd - -Section "Robots and Fields" RobotFiles - - ; Set extraction path for preloaded robot files - SetOutPath $APPDATA\Autodesk\Synthesis\Mira - File /r "Robots\*" - - SetOutPath $APPDATA\Autodesk\Synthesis\Mira\Fields - File /r "Fields\*" - -SectionEnd - -Section "PartBuilder Samples" PartBuilder - - ; Set extraction path for preloaded robot files - SetOutPath $APPDATA\Autodesk\Synthesis\MixAndMatch - File /r "MixAndMatch\*" - -SectionEnd - -Section "Themes" Themes - - ; Set extraction path for preloaded robot files - SetOutPath $APPDATA\Autodesk\Synthesis\Themes - File /r "Themes\*" - -SectionEnd - -/* -Section "Code Emulator" Emulator - - ; INetC.dll must be installed to proper NSIS Plugins x86 directories - inetc::get "https://qemu.weilnetz.de/w64/2019/qemu-w64-setup-20190724.exe" "$PLUGINSDIR\qemu-w64-setup-20190724.exe" - Pop $R0 ;Get the return value - - ${If} $R0 == "OK" ;Return value should be "OK" - SetOutPath $APPDATA\Autodesk\Synthesis\Emulator - File /r "Emulator\*" - HideWindow - ExecWait '"$PLUGINSDIR\qemu-w64-setup-20190724.exe" /SILENT' - ShowWindow hwnd show_state - ${Else} - MessageBox MB_ICONSTOP "Error: $R0" ;Show cancel/error message - ${EndIf} - -SectionEnd -*/ - -;-------------------------------- -;Component Descriptions - - LangString DESC_Synthesis ${LANG_ENGLISH} "The Simulator Engine is the real-time physics environment which simulates the robots and fields." - ; LangString DESC_iExporter ${LANG_ENGLISH} "The Inventor Exporter Plugin is an Inventor addin used to export Autodesk Inventor Assemblies directly into the simulator" - LangString DESC_fExporter ${LANG_ENGLISH} "The Fusion360 Exporter Plugin is a Fusion addin used to export Autodesk Fusion Assemblies directly into the simulator" - LangString DESC_RobotFiles ${LANG_ENGLISH} "A library of sample robots and fields pre-loaded into the simulator" - LangString DESC_PartBuilder ${LANG_ENGLISH} "A library of sample parts to use in Robot Builder" - LangString DESC_Themes ${LANG_ENGLISH} "Preinstalled themes" - ; LangString DESC_Emulator ${LANG_ENGLISH} "The Robot Code Emulator allows you to emulate your C++ & JAVA robot code in the simulator" - - !insertmacro MUI_FUNCTION_DESCRIPTION_BEGIN - !insertmacro MUI_DESCRIPTION_TEXT ${Synthesis} $(DESC_Synthesis) - ; !insertmacro MUI_DESCRIPTION_TEXT ${iExporter} $(DESC_iExporter) - !insertmacro MUI_DESCRIPTION_TEXT ${fExporter} $(DESC_fExporter) - !insertmacro MUI_DESCRIPTION_TEXT ${RobotFiles} $(DESC_RobotFiles) - !insertmacro MUI_DESCRIPTION_TEXT ${PartBuilder} $(DESC_PartBuilder) - !insertmacro MUI_DESCRIPTION_TEXT ${Themes} $(DESC_Themes) - ; !insertmacro MUI_DESCRIPTION_TEXT ${Emulator} $(DESC_Emulator) - !insertmacro MUI_FUNCTION_DESCRIPTION_END - -;-------------------------------- - -Section "Uninstall" - - MessageBox MB_YESNO "Would you like to remove your robot files?" IDNO NawFam - RMDir /r /REBOOTOK $APPDATA\Synthesis - RMDir /r /REBOOTOK $APPDATA\Autodesk\Synthesis - - NawFam: - ; Remove registry keys - DeleteRegKey HKLM SOFTWARE\Synthesis - DeleteRegKey HKCU SOFTWARE\Autodesk\Synthesis - DeleteRegKey HKCU "SOFTWARE\Autodesk\BXD Synthesis" - DeleteRegKey HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Autodesk Synthesis" - - ; Remove installation directories - RMDir /r /REBOOTOK $INSTDIR - RMDir /r /REBOOTOK $PROGRAMFILES\Autodesk\Synthesis - RMDir /r /REBOOTOK $APPDATA\BXD_Aardvark - RMDir /r /REBOOTOK $APPDATA\SynthesisTEMP - - ; Remove fusion plugins - RMDir /r "$APPDATA\Autodesk\Autodesk Fusion 360\API\AddIns\FusionRobotExporter" - RMDir /r "$APPDATA\Autodesk\Autodesk Fusion 360\API\AddIns\Synthesis" - RMDir /r "$APPDATA\Autodesk\Autodesk Fusion 360\API\AddIns\FusionExporter" - RMDir /r "$APPDATA\Autodesk\ApplicationPlugins\FusionRobotExporter.bundle" - RMDir /r "$APPDATA\Autodesk\ApplicationPlugins\FusionSynth.bundle" - - ; Remove inventor plugins - Delete /REBOOTOK "$APPDATA\Autodesk\Inventor 2022\Addins\Autodesk.InventorRobotExporter.Inventor.addin" - Delete /REBOOTOK "$APPDATA\Autodesk\Inventor 2021\Addins\Autodesk.InventorRobotExporter.Inventor.addin" - Delete /REBOOTOK "$APPDATA\Autodesk\Inventor 2020\Addins\Autodesk.InventorRobotExporter.Inventor.addin" - Delete /REBOOTOK "$APPDATA\Autodesk\Inventor 2019\Addins\Autodesk.InventorRobotExporter.Inventor.addin" - Delete /REBOOTOK "$APPDATA\Autodesk\Inventor 2018\Addins\Autodesk.InventorRobotExporter.Inventor.addin" - Delete /REBOOTOK "$APPDATA\Autodesk\Inventor 2017\Addins\Autodesk.InventorRobotExporter.Inventor.addin" - Delete /REBOOTOK "$APPDATA\Autodesk\ApplicationPlugins\Autodesk.InventorRobotExporter.Inventor.addin" - - ; Remove deprecated bxd inventor plugins - Delete /REBOOTOK "$APPDATA\Autodesk\Inventor 2020\Addins\autodesk.BxDRobotExporter.inventor.addin" - Delete /REBOOTOK "$APPDATA\Autodesk\Inventor 2019\Addins\autodesk.BxDRobotExporter.inventor.addin" - Delete /REBOOTOK "$APPDATA\Autodesk\Inventor 2019\Addins\autodesk.BxDFieldExporter.inventor.addin" - Delete /REBOOTOK "$APPDATA\Autodesk\Inventor 2018\Addins\autodesk.BxDRobotExporter.inventor.addin" - Delete /REBOOTOK "$APPDATA\Autodesk\Inventor 2018\Addins\autodesk.BxDFieldExporter.inventor.addin" - Delete /REBOOTOK "$APPDATA\Autodesk\Inventor 2017\Addins\autodesk.BxDRobotExporter.inventor.addin" - Delete /REBOOTOK "$APPDATA\Autodesk\Inventor 2017\Addins\autodesk.BxDFieldExporter.inventor.addin" - Delete /REBOOTOK "$APPDATA\Autodesk\ApplicationPlugins\Autodesk.BxDRobotExporter.Inventor.addin" - RMDir /REBOOTOK "$APPDATA\Autodesk\ApplicationPlugins\BxDRobotExporter" - - ; Remove excess shortcuts - Delete "$SMPROGRAMS\Synthesis.lnk" - Delete "$DESKTOP\Synthesis.lnk" - Delete "$SMPROGRAMS\BXD Synthesis.lnk" - Delete "$DESKTOP\BXD Synthesis.lnk" - Delete "$SMPROGRAMS\Autodesk Synthesis.lnk" - Delete "$DESKTOP\Autodesk Synthesis.lnk" - Delete "$DESKTOP\FieldExporter.lnk" - - /* - ; Execute QEMU uninstaller - IfFileExists "$PROGRAMFILES64\qemu" file_found uninstall_complete - - file_found: - MessageBox MB_YESNO "Would you like to uninstall QEMU as well?" IDNO uninstall_complete - Exec '"$PROGRAMFILES64\qemu\qemu-uninstall.exe"' - Quit - - uninstall_complete: - */ - -SectionEnd - -Function .OnInstSuccess - Exec "$INSTDIR\Synthesis.exe" -FunctionEnd diff --git a/installer/Windows/README.md b/installer/Windows/README.md deleted file mode 100644 index 21ea8340c9..0000000000 --- a/installer/Windows/README.md +++ /dev/null @@ -1,23 +0,0 @@ -# logoNullsoft Scriptable Install System - -For installation on Windows Operating Systems, we use our own custom written NSIS installer in order to extract all the necessary files to their proper locations on the system. - -- [MainInstaller(x64)](https://github.com/Autodesk/synthesis/blob/prod/installer/Windows/MainInstaller.nsi) - (Used for the full installation of Synthesis, only compatible on 64 bit operating systems.) -- [EngInstaller(x86)](https://github.com/Autodesk/synthesis/blob/prod/installer/Windows/EngInstaller(x86).nsi) - (Used only for installation on 32 bit operating systems and extracts just the Unity Engine.) - -### Compiling NSIS: -In order to compile the NSIS configuration properly, you must compile all of the individual components of Synthesis pertaining to the particular script you are trying to compile. Then the compiled components must be stored in the same directory as the NSIS script, in order for them to be packaged during NSIS compilation. For details on this process, feel free to contact matthew.moradi@autodesk.com - -### NSIS FAQ: - -Q: Will I need admin privileges to run the installer? - -A: Yup. - -Q: If I download an updated Synthesis installer, will running it replace all of my custom robot export files? - -A: No, _reinstalling_ Synthesis will only replace all of the application components, but your custom robots will be saved. - -Q: Is it possible to accidently install multiple versions of Synthesis? - -A: It shouldn't be. The installer will always replace any existing Synthesis installations on your system. diff --git a/installer/Windows/W21_SYN_sidebar.bmp b/installer/Windows/W21_SYN_sidebar.bmp deleted file mode 100644 index 60c007ab76e40e022f2eb73aa36a4fdd86a7bbbd..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 152310 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 diff --git a/installer/Windows/orange-install-nsis.ico b/installer/Windows/orange-install-nsis.ico deleted file mode 100644 index ef3975f56c9bd8c1a06cef83c67c535010a65ee8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 25214 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 KKeFO?tN#O)lB@v$ diff --git a/installer/Windows/orange-r.bmp b/installer/Windows/orange-r.bmp deleted file mode 100644 index c74fbdd511d240983ed66bb3e37aec500df99f84..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 9744 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 j4Y6aeH~t00000NkvXXu0mjfPEVab diff --git a/installer/exporter/.gitignore b/installer/exporter/.gitignore deleted file mode 100644 index 290dfd77ff..0000000000 --- a/installer/exporter/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -/Synthesis -/*.zip diff --git a/installer/exporter/README.md b/installer/exporter/README.md deleted file mode 100644 index 631eb3527b..0000000000 --- a/installer/exporter/README.md +++ /dev/null @@ -1,14 +0,0 @@ -# Synthesis Exporter Installer - -## Creating the installer -### Windows -1. Run `setup.bat`. This will copy the Synthesis exporter into the current directory. -2. Zip together the `install.bat` script and the `Synthesis` directory. - -### MacOS -1. Run `create.sh`. This will copy the Synthesis exporter into the current directory and create a zip file with the necessary files. - -## Using the installer -1. Download the zip file. -2. Unzip it anywhere (likely your Downloads folder). -3. Run the `install.bat` (`install.sh` for MacOS) script. diff --git a/installer/exporter/create.sh b/installer/exporter/create.sh deleted file mode 100755 index 22efb4ac4b..0000000000 --- a/installer/exporter/create.sh +++ /dev/null @@ -1,11 +0,0 @@ -#!/bin/bash - -if test -d ./Synthesis; then - rm -rf ./Synthesis -fi - -cp -r ../../exporter/SynthesisFusionAddin/ ./Synthesis -echo "Copied over Synthesis exporter!" - -zip -r SynthesisExporter Synthesis/ install.sh -echo "Created zip installer!" diff --git a/installer/exporter/install.bat b/installer/exporter/install.bat deleted file mode 100644 index 293bac431a..0000000000 --- a/installer/exporter/install.bat +++ /dev/null @@ -1,10 +0,0 @@ -@echo off - -if exist "%AppData%\Autodesk\Autodesk Fusion 360\API\AddIns\Synthesis\" ( - echo "Removing existing Synthesis exporter..." - rmdir "%AppData%\Autodesk\Autodesk Fusion 360\API\AddIns\Synthesis\" /Q/S -) - -echo "Copying to %AppData%\Autodesk\Autodesk Fusion 360\API\AddIns\Synthesis..." -xcopy Synthesis "%AppData%\Autodesk\Autodesk Fusion 360\API\AddIns\Synthesis\" /E -echo "Synthesis Exporter Successfully Installed!" diff --git a/installer/exporter/install.sh b/installer/exporter/install.sh deleted file mode 100755 index 4ab0801918..0000000000 --- a/installer/exporter/install.sh +++ /dev/null @@ -1,10 +0,0 @@ -#!/bin/bash - -if test -d ~/Library/Application\ Support/Autodesk/Autodesk\ Fusion\ 360/API/AddIns/SynthesisFusionAddin; then - echo "Removing existing Synthesis exporter..." - rm -rf ~/Library/Application\ Support/Autodesk/Autodesk\ Fusion\ 360/API/AddIns/SynthesisFusionAddin -fi - -cp -r Synthesis/ ~/Library/Application\ Support/Autodesk/Autodesk\ Fusion\ 360/API/AddIns/SynthesisFusionAddin - -echo "Synthesis successfully copied!" diff --git a/installer/exporter/setup.bat b/installer/exporter/setup.bat deleted file mode 100644 index a6ec90bb68..0000000000 --- a/installer/exporter/setup.bat +++ /dev/null @@ -1,9 +0,0 @@ -@echo off - -if exist Synthesis\ ( - rmdir Synthesis /Q/S - echo Removed .\Synthesis -) - -xcopy ..\..\exporter\SynthesisFusionAddin Synthesis\ /E -echo Copied exporter into .\Synthesis From dce50890903aafb1194093315918c995f9680cad Mon Sep 17 00:00:00 2001 From: BrandonPacewic Date: Wed, 31 Jul 2024 09:29:38 -0700 Subject: [PATCH 02/24] Basic installer done --- installer/OSX/build.sh | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/installer/OSX/build.sh b/installer/OSX/build.sh index c6a2095a77..383b1519ae 100755 --- a/installer/OSX/build.sh +++ b/installer/OSX/build.sh @@ -1,8 +1,12 @@ #!/bin/bash -FUSION_ADDIN_LOCATION="Support/Autodesk/Autodesk\ Fusion\ 360/API/AddIns/" -EXPORTER_SOURCE_DIR=../../exporter/ -FUSION_ADDIN_LOCATION=~/Documents/ +FUSION_ADDIN_LOCATION=~/Library/Application\ Support/Autodesk/Autodesk\ Fusion\ 360/API/AddIns/ +EXPORTER_SOURCE_DIR=../../exporter/SynthesisFusionAddin/ -pkgbuild --root $EXPORTER_SOURCE_DIR --identifier com.Autodesk.Synthesis --version 1.0 --scripts Scripts --install-location $FUSION_ADDIN_LOCATION MyApp.pkg +mkdir -p tmp/ +cp -r "$EXPORTER_SOURCE_DIR"/* tmp/ + +pkgbuild --root tmp/ --identifier com.Autodesk.Synthesis --version 1.0 --install-location "$FUSION_ADDIN_LOCATION" MyApp.pkg productbuild --distribution distribution.xml --package-path . MyAppInstaller.pkg + +rm -r tmp/ From 0d51cf7294c6501833234a43be9fe1769a97e47e Mon Sep 17 00:00:00 2001 From: BrandonPacewic Date: Wed, 31 Jul 2024 10:41:55 -0700 Subject: [PATCH 03/24] Bump exporter version --- exporter/SynthesisFusionAddin/Synthesis.manifest | 2 +- installer/OSX/build.sh | 5 +++-- installer/OSX/distribution.xml | 3 +-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/exporter/SynthesisFusionAddin/Synthesis.manifest b/exporter/SynthesisFusionAddin/Synthesis.manifest index f8e96ae366..47434ab6a2 100644 --- a/exporter/SynthesisFusionAddin/Synthesis.manifest +++ b/exporter/SynthesisFusionAddin/Synthesis.manifest @@ -6,7 +6,7 @@ "description": { "": "Synthesis Exporter" }, - "version": "1.0.0", + "version": "2.0.0", "runOnStartup": true, "supportedOS": "windows|mac", "editEnabled": true diff --git a/installer/OSX/build.sh b/installer/OSX/build.sh index 383b1519ae..673c7c80a7 100755 --- a/installer/OSX/build.sh +++ b/installer/OSX/build.sh @@ -6,7 +6,8 @@ EXPORTER_SOURCE_DIR=../../exporter/SynthesisFusionAddin/ mkdir -p tmp/ cp -r "$EXPORTER_SOURCE_DIR"/* tmp/ -pkgbuild --root tmp/ --identifier com.Autodesk.Synthesis --version 1.0 --install-location "$FUSION_ADDIN_LOCATION" MyApp.pkg -productbuild --distribution distribution.xml --package-path . MyAppInstaller.pkg +pkgbuild --root tmp/ --identifier com.Autodesk.Synthesis --version 2.0.0 --install-location "$FUSION_ADDIN_LOCATION" SynthesisExporter.pkg +productbuild --distribution distribution.xml --package-path . SynthesisExporterInstaller.pkg +rm SynthesisExporter.pkg rm -r tmp/ diff --git a/installer/OSX/distribution.xml b/installer/OSX/distribution.xml index 534c1465b1..e46f643e6f 100644 --- a/installer/OSX/distribution.xml +++ b/installer/OSX/distribution.xml @@ -10,6 +10,5 @@ - - #MyApp.pkg + #SynthesisExporter.pkg From 304f0136b35563f943fbdef78b62f59cc60254a0 Mon Sep 17 00:00:00 2001 From: BrandonPacewic Date: Thu, 1 Aug 2024 14:12:13 -0700 Subject: [PATCH 04/24] Working windows python data installer --- installer/Windows/.gitkeep | 0 installer/Windows/build.bat | 31 ++++++++++++++++++ installer/Windows/installer.py | 57 ++++++++++++++++++++++++++++++++++ 3 files changed, 88 insertions(+) delete mode 100644 installer/Windows/.gitkeep create mode 100644 installer/Windows/build.bat create mode 100644 installer/Windows/installer.py diff --git a/installer/Windows/.gitkeep b/installer/Windows/.gitkeep deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/installer/Windows/build.bat b/installer/Windows/build.bat new file mode 100644 index 0000000000..f3cff018da --- /dev/null +++ b/installer/Windows/build.bat @@ -0,0 +1,31 @@ +@echo off +setlocal enabledelayedexpansion +setlocal + +set "FUSION_ADDIN_LOCATION=%USERPROFILE%\AppData\Local\Autodesk\Autodesk Fusion 360\API\AddIns\" +set "EXPORTER_SOURCE_DIR=..\..\exporter\SynthesisFusionAddin\" + +mkdir tmp\ +xcopy /e /i "%EXPORTER_SOURCE_DIR%" tmp\ +@REM pushd tmp\ +tar -a -c -f resources.zip tmp\* +@REM popd + +for /f "delims=" %%i in ('pip show pyinstaller') do ( + echo %%i | findstr /b /c:"Location:" >nul + if not errorlevel 1 ( + set "location_line=%%i" + ) +) + +set "executable=!location_line:Location: =!" +for %%a in ("%executable%") do set "executable=%%~dpa" +set "executable=%executable%Scripts\pyinstaller.exe " +set executable=%executable:~0,-1% + +%executable% --onefile --add-data "resources.zip;." installer.py + +rmdir /s /q tmp +del resources.zip + +endlocal diff --git a/installer/Windows/installer.py b/installer/Windows/installer.py new file mode 100644 index 0000000000..cf4c5194d8 --- /dev/null +++ b/installer/Windows/installer.py @@ -0,0 +1,57 @@ +import os +import shutil +import sys +import zipfile +import tempfile + +def resource_path(relative_path): + try: + base_path = sys._MEIPASS + except Exception: + base_path = os.path.dirname(__file__) + return os.path.join(base_path, relative_path) + +def extract_file(resource_name, dest_folder): + resource_full_path = resource_path(resource_name) + if not os.path.exists(resource_full_path): + raise FileNotFoundError(f"Resource '{resource_name}' not found.") + + shutil.copy(resource_full_path, os.path.join(dest_folder, resource_name)) + +def move_folder(src_folder, dest_folder): + if not os.path.exists(src_folder): + print(f"Source folder '{src_folder}' does not exist.") + return + + if not os.path.exists(dest_folder): + print(f"Destination folder '{dest_folder}' does not exist. Creating it.") + os.makedirs(dest_folder) + + try: + shutil.move(src_folder, dest_folder) + print(f"Successfully moved '{src_folder}' to '{dest_folder}'.") + except Exception as e: + print(f"Error: {e}") + +def main(): + if len(sys.argv) != 2: + print("Usage: installer.exe ") + sys.exit(1) + + destination_folder = sys.argv[1] + + with tempfile.TemporaryDirectory() as temp_dir: + try: + extract_file('resources.zip', temp_dir) + + with zipfile.ZipFile(os.path.join(temp_dir, 'resources.zip'), 'r') as zip_ref: + zip_ref.extractall(temp_dir) + + src_folder = os.path.join(temp_dir, 'tmp') + move_folder(src_folder, destination_folder) + + except Exception as e: + print(f"Error: {e}") + +if __name__ == "__main__": + main() From b7795a84fb6e4fc164e41555eebeabbbba3c9c05 Mon Sep 17 00:00:00 2001 From: BrandonPacewic Date: Thu, 1 Aug 2024 14:28:56 -0700 Subject: [PATCH 05/24] Formatting and dest updates for the windows installer --- .gitignore | 4 ++- installer/Windows/build.bat | 10 +++---- installer/Windows/installer.py | 48 +++++++++++++++------------------- 3 files changed, 29 insertions(+), 33 deletions(-) diff --git a/.gitignore b/.gitignore index 5057e53d24..a57a98b5ac 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,8 @@ .vs/ .vscode/ -/build/ +build/ +dist/ *.log .DS_Store *.pkg +*.exe diff --git a/installer/Windows/build.bat b/installer/Windows/build.bat index f3cff018da..c09485cf51 100644 --- a/installer/Windows/build.bat +++ b/installer/Windows/build.bat @@ -7,10 +7,10 @@ set "EXPORTER_SOURCE_DIR=..\..\exporter\SynthesisFusionAddin\" mkdir tmp\ xcopy /e /i "%EXPORTER_SOURCE_DIR%" tmp\ -@REM pushd tmp\ -tar -a -c -f resources.zip tmp\* -@REM popd +tar -a -c -f SynthesisExporter.zip tmp\* +@REM Find and run pyinstaller, this is a workaround that allows you to call pip packages as scripts without +@REM them being added to the system PATH. for /f "delims=" %%i in ('pip show pyinstaller') do ( echo %%i | findstr /b /c:"Location:" >nul if not errorlevel 1 ( @@ -23,9 +23,9 @@ for %%a in ("%executable%") do set "executable=%%~dpa" set "executable=%executable%Scripts\pyinstaller.exe " set executable=%executable:~0,-1% -%executable% --onefile --add-data "resources.zip;." installer.py +%executable% --onefile --add-data "SynthesisExporter.zip;." installer.py rmdir /s /q tmp -del resources.zip +del SynthesisExporter.zip endlocal diff --git a/installer/Windows/installer.py b/installer/Windows/installer.py index cf4c5194d8..cce42320c0 100644 --- a/installer/Windows/installer.py +++ b/installer/Windows/installer.py @@ -1,57 +1,51 @@ import os import shutil import sys -import zipfile import tempfile +import zipfile + def resource_path(relative_path): - try: + if getattr(sys, "frozen", False) and hasattr(sys, "_MEIPASS"): base_path = sys._MEIPASS - except Exception: + else: base_path = os.path.dirname(__file__) + return os.path.join(base_path, relative_path) + def extract_file(resource_name, dest_folder): resource_full_path = resource_path(resource_name) if not os.path.exists(resource_full_path): raise FileNotFoundError(f"Resource '{resource_name}' not found.") - + shutil.copy(resource_full_path, os.path.join(dest_folder, resource_name)) + def move_folder(src_folder, dest_folder): if not os.path.exists(src_folder): print(f"Source folder '{src_folder}' does not exist.") return - + if not os.path.exists(dest_folder): print(f"Destination folder '{dest_folder}' does not exist. Creating it.") os.makedirs(dest_folder) - - try: - shutil.move(src_folder, dest_folder) - print(f"Successfully moved '{src_folder}' to '{dest_folder}'.") - except Exception as e: - print(f"Error: {e}") + + shutil.move(src_folder, dest_folder) + print(f"Successfully moved '{src_folder}' to '{dest_folder}'.") + def main(): - if len(sys.argv) != 2: - print("Usage: installer.exe ") - sys.exit(1) - - destination_folder = sys.argv[1] + destination_folder = r"%appdata%\Autodesk\Autodesk Fusion\API\AddIns" with tempfile.TemporaryDirectory() as temp_dir: - try: - extract_file('resources.zip', temp_dir) - - with zipfile.ZipFile(os.path.join(temp_dir, 'resources.zip'), 'r') as zip_ref: - zip_ref.extractall(temp_dir) - - src_folder = os.path.join(temp_dir, 'tmp') - move_folder(src_folder, destination_folder) - - except Exception as e: - print(f"Error: {e}") + extract_file("resources.zip", temp_dir) + with zipfile.ZipFile(os.path.join(temp_dir, "resources.zip"), "r") as zip_ref: + zip_ref.extractall(temp_dir) + + src_folder = os.path.join(temp_dir, "tmp") + move_folder(src_folder, destination_folder) + if __name__ == "__main__": main() From f5f0d92beb9ea6d9d4b3c3bee5bcf6f24778b8e2 Mon Sep 17 00:00:00 2001 From: BrandonPacewic <92102436+BrandonPacewic@users.noreply.github.com> Date: Thu, 15 Aug 2024 10:23:39 -0700 Subject: [PATCH 06/24] Moved Mac install location into `ApplicationPlugins` --- exporter/SynthesisFusionAddin/Synthesis.py | 4 ++ exporter/SynthesisFusionAddin/src/Logging.py | 25 ++++++---- .../src/Parser/SynthesisParser/Components.py | 2 +- .../Parser/SynthesisParser/JointHierarchy.py | 2 +- .../src/Parser/SynthesisParser/Joints.py | 2 +- .../src/Parser/SynthesisParser/Materials.py | 2 +- .../src/Parser/SynthesisParser/Parser.py | 2 +- .../SynthesisParser/PhysicalProperties.py | 2 +- .../src/Parser/SynthesisParser/RigidGroup.py | 2 +- exporter/SynthesisFusionAddin/src/Types.py | 4 +- .../SynthesisFusionAddin/src/UI/Camera.py | 9 ++-- .../src/UI/ConfigCommand.py | 10 ++-- .../src/UI/Configuration/SerialCommand.py | 7 ++- exporter/SynthesisFusionAddin/src/Util.py | 7 +++ exporter/SynthesisFusionAddin/src/__init__.py | 24 +++++++++- installer/OSX/Resources/LICENSE.txt | 1 - installer/OSX/build.sh | 5 +- .../OSX/synthesis.bundle/Contents/Info.plist | 46 +++++++++++++++++++ .../OSX/synthesis.bundle/PackageContents.xml | 24 ++++++++++ 19 files changed, 151 insertions(+), 29 deletions(-) create mode 100644 exporter/SynthesisFusionAddin/src/Util.py delete mode 100644 installer/OSX/Resources/LICENSE.txt create mode 100644 installer/OSX/synthesis.bundle/Contents/Info.plist create mode 100644 installer/OSX/synthesis.bundle/PackageContents.xml diff --git a/exporter/SynthesisFusionAddin/Synthesis.py b/exporter/SynthesisFusionAddin/Synthesis.py index deba3c9551..80e43b4e3e 100644 --- a/exporter/SynthesisFusionAddin/Synthesis.py +++ b/exporter/SynthesisFusionAddin/Synthesis.py @@ -15,6 +15,7 @@ try: # Attempt to import required pip dependencies to verify their installation. import requests + from proto.proto_out import ( assembly_pb2, joint_pb2, @@ -69,6 +70,9 @@ def stop(_): Arguments: **context** *context* -- Fusion Data. """ + sys.path.remove(os.path.dirname(os.path.abspath(__file__))) + sys.path.remove(os.path.abspath(os.path.join(os.path.dirname(__file__), "proto", "proto_out"))) + unregister_all() app = adsk.core.Application.get() diff --git a/exporter/SynthesisFusionAddin/src/Logging.py b/exporter/SynthesisFusionAddin/src/Logging.py index e5f352f480..c2fbad7b9d 100644 --- a/exporter/SynthesisFusionAddin/src/Logging.py +++ b/exporter/SynthesisFusionAddin/src/Logging.py @@ -11,8 +11,9 @@ import adsk.core -from src import INTERNAL_ID +from src import INTERNAL_ID, IS_RELEASE, SUPPORT_PATH from src.UI.OsHelper import getOSPath +from src.Util import makeDirectories MAX_LOG_FILES_TO_KEEP = 10 TIMING_LEVEL = 25 @@ -30,14 +31,19 @@ def cleanupHandlers(self) -> None: def setupLogger() -> SynthesisLogger: now = datetime.now().strftime("%H-%M-%S") today = date.today() - logFileFolder = getOSPath(f"{pathlib.Path(__file__).parent.parent}", "logs") - logFiles = [os.path.join(logFileFolder, file) for file in os.listdir(logFileFolder) if file.endswith(".log")] - logFiles.sort() - if len(logFiles) >= MAX_LOG_FILES_TO_KEEP: - for file in logFiles[: len(logFiles) - MAX_LOG_FILES_TO_KEEP]: - os.remove(file) - - logFileName = f"{logFileFolder}{getOSPath(f'{INTERNAL_ID}-{today}-{now}.log')}" + if not IS_RELEASE: + logFileFolder = makeDirectories(getOSPath(f"{pathlib.Path(__file__).parent.parent}", "logs")) + else: + logFileFolder = makeDirectories(f"{SUPPORT_PATH}/Logs/") + + if not IS_RELEASE: # TODO: Decide if this is what I want to do or not + logFiles = [os.path.join(logFileFolder, file) for file in os.listdir(logFileFolder) if file.endswith(".log")] + logFiles.sort() + if len(logFiles) >= MAX_LOG_FILES_TO_KEEP: + for file in logFiles[: len(logFiles) - MAX_LOG_FILES_TO_KEEP]: + os.remove(file) + + logFileName = f"{logFileFolder}{getOSPath(f'{today}-{now}.log')}" logHandler = logging.handlers.WatchedFileHandler(logFileName, mode="w") logHandler.setFormatter(logging.Formatter("%(name)s - %(levelname)s - %(message)s")) @@ -46,6 +52,7 @@ def setupLogger() -> SynthesisLogger: logger = getLogger(INTERNAL_ID) logger.setLevel(10) # Debug logger.addHandler(logHandler) + return cast(SynthesisLogger, logger) diff --git a/exporter/SynthesisFusionAddin/src/Parser/SynthesisParser/Components.py b/exporter/SynthesisFusionAddin/src/Parser/SynthesisParser/Components.py index aea709f04a..fbdba1d891 100644 --- a/exporter/SynthesisFusionAddin/src/Parser/SynthesisParser/Components.py +++ b/exporter/SynthesisFusionAddin/src/Parser/SynthesisParser/Components.py @@ -1,8 +1,8 @@ # Contains all of the logic for mapping the Components / Occurrences import adsk.core import adsk.fusion -from proto.proto_out import assembly_pb2, joint_pb2, material_pb2, types_pb2 +from proto.proto_out import assembly_pb2, joint_pb2, material_pb2, types_pb2 from src.Logging import logFailure from src.Parser.ExporterOptions import ExporterOptions from src.Parser.SynthesisParser import PhysicalProperties diff --git a/exporter/SynthesisFusionAddin/src/Parser/SynthesisParser/JointHierarchy.py b/exporter/SynthesisFusionAddin/src/Parser/SynthesisParser/JointHierarchy.py index cf8c5e04b0..2bd563b489 100644 --- a/exporter/SynthesisFusionAddin/src/Parser/SynthesisParser/JointHierarchy.py +++ b/exporter/SynthesisFusionAddin/src/Parser/SynthesisParser/JointHierarchy.py @@ -3,8 +3,8 @@ import adsk.core import adsk.fusion -from proto.proto_out import joint_pb2, types_pb2 +from proto.proto_out import joint_pb2, types_pb2 from src import gm from src.Logging import getLogger, logFailure from src.Parser.ExporterOptions import ExporterOptions diff --git a/exporter/SynthesisFusionAddin/src/Parser/SynthesisParser/Joints.py b/exporter/SynthesisFusionAddin/src/Parser/SynthesisParser/Joints.py index 6b1650b3f9..0d0cdea910 100644 --- a/exporter/SynthesisFusionAddin/src/Parser/SynthesisParser/Joints.py +++ b/exporter/SynthesisFusionAddin/src/Parser/SynthesisParser/Joints.py @@ -28,8 +28,8 @@ import adsk.core import adsk.fusion -from proto.proto_out import assembly_pb2, joint_pb2, signal_pb2, types_pb2 +from proto.proto_out import assembly_pb2, joint_pb2, signal_pb2, types_pb2 from src.Logging import getLogger from src.Parser.ExporterOptions import ExporterOptions from src.Parser.SynthesisParser.PDMessage import PDMessage diff --git a/exporter/SynthesisFusionAddin/src/Parser/SynthesisParser/Materials.py b/exporter/SynthesisFusionAddin/src/Parser/SynthesisParser/Materials.py index a077c764b7..d8538b5d9b 100644 --- a/exporter/SynthesisFusionAddin/src/Parser/SynthesisParser/Materials.py +++ b/exporter/SynthesisFusionAddin/src/Parser/SynthesisParser/Materials.py @@ -1,6 +1,6 @@ import adsk -from proto.proto_out import material_pb2 +from proto.proto_out import material_pb2 from src.Logging import logFailure from src.Parser.ExporterOptions import ExporterOptions from src.Parser.SynthesisParser.PDMessage import PDMessage diff --git a/exporter/SynthesisFusionAddin/src/Parser/SynthesisParser/Parser.py b/exporter/SynthesisFusionAddin/src/Parser/SynthesisParser/Parser.py index 338f5a300a..37148fb622 100644 --- a/exporter/SynthesisFusionAddin/src/Parser/SynthesisParser/Parser.py +++ b/exporter/SynthesisFusionAddin/src/Parser/SynthesisParser/Parser.py @@ -4,8 +4,8 @@ import adsk.core import adsk.fusion from google.protobuf.json_format import MessageToJson -from proto.proto_out import assembly_pb2, types_pb2 +from proto.proto_out import assembly_pb2, types_pb2 from src import gm from src.APS.APS import getAuth, upload_mirabuf from src.Logging import getLogger, logFailure, timed diff --git a/exporter/SynthesisFusionAddin/src/Parser/SynthesisParser/PhysicalProperties.py b/exporter/SynthesisFusionAddin/src/Parser/SynthesisParser/PhysicalProperties.py index b178bcb3bb..15e025f4c7 100644 --- a/exporter/SynthesisFusionAddin/src/Parser/SynthesisParser/PhysicalProperties.py +++ b/exporter/SynthesisFusionAddin/src/Parser/SynthesisParser/PhysicalProperties.py @@ -19,8 +19,8 @@ from typing import Union import adsk -from proto.proto_out import types_pb2 +from proto.proto_out import types_pb2 from src.Logging import logFailure diff --git a/exporter/SynthesisFusionAddin/src/Parser/SynthesisParser/RigidGroup.py b/exporter/SynthesisFusionAddin/src/Parser/SynthesisParser/RigidGroup.py index 8516cefae6..b90a2167fe 100644 --- a/exporter/SynthesisFusionAddin/src/Parser/SynthesisParser/RigidGroup.py +++ b/exporter/SynthesisFusionAddin/src/Parser/SynthesisParser/RigidGroup.py @@ -16,8 +16,8 @@ import adsk.core import adsk.fusion -from proto.proto_out import assembly_pb2 +from proto.proto_out import assembly_pb2 from src.Logging import logFailure diff --git a/exporter/SynthesisFusionAddin/src/Types.py b/exporter/SynthesisFusionAddin/src/Types.py index 1aca3a5162..d8215d33b2 100644 --- a/exporter/SynthesisFusionAddin/src/Types.py +++ b/exporter/SynthesisFusionAddin/src/Types.py @@ -3,7 +3,9 @@ import platform from dataclasses import dataclass, field, fields, is_dataclass from enum import Enum, EnumType -from typing import Union, get_origin +from typing import Literal, TypeAlias, Union, get_origin + +OperatingSystemString: TypeAlias = Literal["Windows", "Darwin", "Linux"] # Not 100% sure what this is for - Brandon JointParentType = Enum("JointParentType", ["ROOT", "END"]) diff --git a/exporter/SynthesisFusionAddin/src/UI/Camera.py b/exporter/SynthesisFusionAddin/src/UI/Camera.py index 02de04083a..d59b1c6e28 100644 --- a/exporter/SynthesisFusionAddin/src/UI/Camera.py +++ b/exporter/SynthesisFusionAddin/src/UI/Camera.py @@ -2,8 +2,10 @@ import adsk.core +from src import SUPPORT_PATH from src.Logging import logFailure from src.Types import OString +from src.Util import makeDirectories @logFailure @@ -21,9 +23,10 @@ def captureThumbnail(size=250): ) # remove whitespace from just the filename ) - path = OString.ThumbnailPath(name) + path = makeDirectories(f"{SUPPORT_PATH}/Resources/Icons/") + path += name - saveOptions = adsk.core.SaveImageFileOptions.create(str(path.getPath())) + saveOptions = adsk.core.SaveImageFileOptions.create(path) saveOptions.height = size saveOptions.width = size saveOptions.isAntiAliased = True @@ -36,7 +39,7 @@ def captureThumbnail(size=250): app.activeViewport.saveAsImageFileWithOptions(saveOptions) app.activeViewport.camera = originalCamera - return str(path.getPath()) + return path def clearIconCache() -> None: diff --git a/exporter/SynthesisFusionAddin/src/UI/ConfigCommand.py b/exporter/SynthesisFusionAddin/src/UI/ConfigCommand.py index c50c7feed2..8cd9d31bad 100644 --- a/exporter/SynthesisFusionAddin/src/UI/ConfigCommand.py +++ b/exporter/SynthesisFusionAddin/src/UI/ConfigCommand.py @@ -305,9 +305,13 @@ def notify(self, args): # save was canceled return - updatedPath = pathlib.Path(savepath).parent - if updatedPath != self.current.filePath: - self.current.filePath = str(updatedPath) + # Transition: AARD-1742 + # With the addition of a 'release' build the fusion exporter will not have permissions within the sourced + # folder. Because of this we cannot use this kind of tmp path anymore. This code was already unused and + # should be removed. + # updatedPath = pathlib.Path(savepath).parent + # if updatedPath != self.current.filePath: + # self.current.filePath = str(updatedPath) else: savepath = processedFileName diff --git a/exporter/SynthesisFusionAddin/src/UI/Configuration/SerialCommand.py b/exporter/SynthesisFusionAddin/src/UI/Configuration/SerialCommand.py index 663afe9337..3163dc03b2 100644 --- a/exporter/SynthesisFusionAddin/src/UI/Configuration/SerialCommand.py +++ b/exporter/SynthesisFusionAddin/src/UI/Configuration/SerialCommand.py @@ -36,7 +36,12 @@ class SerialCommand: def __init__(self): self.general = General() self.advanced = Advanced() - self.filePath = generateFilePath() + + # Transition: AARD-1742 + # With the addition of a 'release' build the fusion exporter will not have permissions within the sourced + # folder. Because of this we cannot use this kind of tmp path anymore. This code was already unused and + # should be removed. + # self.filePath = generateFilePath() def toJSON(self) -> str: """Converts this class into a json object that can be written to the object data diff --git a/exporter/SynthesisFusionAddin/src/Util.py b/exporter/SynthesisFusionAddin/src/Util.py new file mode 100644 index 0000000000..3980e85975 --- /dev/null +++ b/exporter/SynthesisFusionAddin/src/Util.py @@ -0,0 +1,7 @@ +import os + + +def makeDirectories(directory: str | os.PathLike[str]) -> str | os.PathLike[str]: + """Ensures than an input directory exists and attempts to create it if it doesn't.""" + os.makedirs(directory, exist_ok=True) + return directory diff --git a/exporter/SynthesisFusionAddin/src/__init__.py b/exporter/SynthesisFusionAddin/src/__init__.py index 1e426279bb..ecfe620c72 100644 --- a/exporter/SynthesisFusionAddin/src/__init__.py +++ b/exporter/SynthesisFusionAddin/src/__init__.py @@ -1,17 +1,37 @@ import os import platform +from pathlib import Path from src.GlobalManager import GlobalManager +from src.Types import OperatingSystemString +from src.Util import makeDirectories APP_NAME = "Synthesis" APP_TITLE = "Synthesis Robot Exporter" DESCRIPTION = "Exports files from Fusion into the Synthesis Format" INTERNAL_ID = "Synthesis" ADDIN_PATH = os.path.dirname(os.path.realpath(__file__)) +IS_RELEASE = str(Path(os.path.abspath(__file__)).parent.parent.parent.parent).split("/")[-1] == "ApplicationPlugins" -SYSTEM = platform.system() +SYSTEM: OperatingSystemString = platform.system() assert SYSTEM != "Linux" +if SYSTEM == "Windows": + SUPPORT_PATH = makeDirectories(f"{os.getenv('APPDATA')}\\Autodesk\\Synthesis\\") +else: + assert SYSTEM == "Darwin" + SUPPORT_PATH = makeDirectories(f"{os.path.expanduser('~')}/.config/Autodesk/Synthesis/") + gm = GlobalManager() -__all__ = ["APP_NAME", "APP_TITLE", "DESCRIPTION", "INTERNAL_ID", "ADDIN_PATH", "SYSTEM", "gm"] +__all__ = [ + "APP_NAME", + "APP_TITLE", + "DESCRIPTION", + "INTERNAL_ID", + "ADDIN_PATH", + "IS_RELEASE", + "SYSTEM", + "SUPPORT_PATH", + "gm", +] diff --git a/installer/OSX/Resources/LICENSE.txt b/installer/OSX/Resources/LICENSE.txt deleted file mode 100644 index b10760de2f..0000000000 --- a/installer/OSX/Resources/LICENSE.txt +++ /dev/null @@ -1 +0,0 @@ -../../../LICENSE.txt diff --git a/installer/OSX/build.sh b/installer/OSX/build.sh index 673c7c80a7..3be9807fa7 100755 --- a/installer/OSX/build.sh +++ b/installer/OSX/build.sh @@ -1,10 +1,11 @@ #!/bin/bash -FUSION_ADDIN_LOCATION=~/Library/Application\ Support/Autodesk/Autodesk\ Fusion\ 360/API/AddIns/ +FUSION_ADDIN_LOCATION=~/Library/Application\ Support/Autodesk/ApplicationPlugins/ EXPORTER_SOURCE_DIR=../../exporter/SynthesisFusionAddin/ mkdir -p tmp/ -cp -r "$EXPORTER_SOURCE_DIR"/* tmp/ +cp -r synthesis.bundle tmp/ +cp -r "$EXPORTER_SOURCE_DIR"/* tmp/synthesis.bundle/Contents/ pkgbuild --root tmp/ --identifier com.Autodesk.Synthesis --version 2.0.0 --install-location "$FUSION_ADDIN_LOCATION" SynthesisExporter.pkg productbuild --distribution distribution.xml --package-path . SynthesisExporterInstaller.pkg diff --git a/installer/OSX/synthesis.bundle/Contents/Info.plist b/installer/OSX/synthesis.bundle/Contents/Info.plist new file mode 100644 index 0000000000..5c6c161002 --- /dev/null +++ b/installer/OSX/synthesis.bundle/Contents/Info.plist @@ -0,0 +1,46 @@ + + + + + CFBundleDevelopmentRegion + English + CFBundleGetInfoString + Synthesis addin for Fusion. + CFBundleIdentifier + Synthesis Exporter for Autodesk Fusion 360 + CFBundleShortVersionString + 2.0.0 + IFMajorVersion + 1 + IFMinorVersion + 0 + IFPkgFlagAllowBackRev + + IFPkgFlagAuthorizationAction + AdminAuthorization + IFPkgFlagBackgroundAlignment + topleft + IFPkgFlagBackgroundScaling + none + IFPkgFlagDefaultLocation + / + IFPkgFlagFollowLinks + + IFPkgFlagInstallFat + + IFPkgFlagIsRequired + + IFPkgFlagOverwritePermissions + + IFPkgFlagRelocatable + + IFPkgFlagRestartAction + NoRestart + IFPkgFlagRootVolumeOnly + + IFPkgFlagUpdateInstalledLanguages + + IFPkgFormatVersion + 0.1000000014901161 + + diff --git a/installer/OSX/synthesis.bundle/PackageContents.xml b/installer/OSX/synthesis.bundle/PackageContents.xml new file mode 100644 index 0000000000..7e3ffb9484 --- /dev/null +++ b/installer/OSX/synthesis.bundle/PackageContents.xml @@ -0,0 +1,24 @@ + + + + + + + + + + From b801c9b7eb9d33038838231a7419946fb0b6e65c Mon Sep 17 00:00:00 2001 From: BrandonPacewic <92102436+BrandonPacewic@users.noreply.github.com> Date: Thu, 15 Aug 2024 10:28:29 -0700 Subject: [PATCH 07/24] Resolve merge conflicts --- .../src/Parser/SynthesisParser/Components.py | 1 - .../src/Parser/SynthesisParser/JointHierarchy.py | 1 - .../SynthesisFusionAddin/src/Parser/SynthesisParser/Joints.py | 1 - .../SynthesisFusionAddin/src/Parser/SynthesisParser/Materials.py | 1 - .../SynthesisFusionAddin/src/Parser/SynthesisParser/Parser.py | 1 - .../src/Parser/SynthesisParser/PhysicalProperties.py | 1 - .../src/Parser/SynthesisParser/RigidGroup.py | 1 - 7 files changed, 7 deletions(-) diff --git a/exporter/SynthesisFusionAddin/src/Parser/SynthesisParser/Components.py b/exporter/SynthesisFusionAddin/src/Parser/SynthesisParser/Components.py index ba1212ca48..6190d55a99 100644 --- a/exporter/SynthesisFusionAddin/src/Parser/SynthesisParser/Components.py +++ b/exporter/SynthesisFusionAddin/src/Parser/SynthesisParser/Components.py @@ -2,7 +2,6 @@ import adsk.core import adsk.fusion -from proto.proto_out import assembly_pb2, joint_pb2, material_pb2, types_pb2 from src.Logging import logFailure from src.Parser.ExporterOptions import ExporterOptions from src.Parser.SynthesisParser import PhysicalProperties diff --git a/exporter/SynthesisFusionAddin/src/Parser/SynthesisParser/JointHierarchy.py b/exporter/SynthesisFusionAddin/src/Parser/SynthesisParser/JointHierarchy.py index 61e2bf3a5e..26dae4f2a4 100644 --- a/exporter/SynthesisFusionAddin/src/Parser/SynthesisParser/JointHierarchy.py +++ b/exporter/SynthesisFusionAddin/src/Parser/SynthesisParser/JointHierarchy.py @@ -4,7 +4,6 @@ import adsk.core import adsk.fusion -from proto.proto_out import joint_pb2, types_pb2 from src import gm from src.Logging import getLogger, logFailure from src.Parser.ExporterOptions import ExporterOptions diff --git a/exporter/SynthesisFusionAddin/src/Parser/SynthesisParser/Joints.py b/exporter/SynthesisFusionAddin/src/Parser/SynthesisParser/Joints.py index b10e23b2a0..7a3e0da3b9 100644 --- a/exporter/SynthesisFusionAddin/src/Parser/SynthesisParser/Joints.py +++ b/exporter/SynthesisFusionAddin/src/Parser/SynthesisParser/Joints.py @@ -29,7 +29,6 @@ import adsk.core import adsk.fusion -from proto.proto_out import assembly_pb2, joint_pb2, signal_pb2, types_pb2 from src.Logging import getLogger from src.Parser.ExporterOptions import ExporterOptions from src.Parser.SynthesisParser.PDMessage import PDMessage diff --git a/exporter/SynthesisFusionAddin/src/Parser/SynthesisParser/Materials.py b/exporter/SynthesisFusionAddin/src/Parser/SynthesisParser/Materials.py index c3ce4d5229..22b42180a2 100644 --- a/exporter/SynthesisFusionAddin/src/Parser/SynthesisParser/Materials.py +++ b/exporter/SynthesisFusionAddin/src/Parser/SynthesisParser/Materials.py @@ -1,6 +1,5 @@ import adsk -from proto.proto_out import material_pb2 from src.Logging import logFailure from src.Parser.ExporterOptions import ExporterOptions from src.Parser.SynthesisParser.PDMessage import PDMessage diff --git a/exporter/SynthesisFusionAddin/src/Parser/SynthesisParser/Parser.py b/exporter/SynthesisFusionAddin/src/Parser/SynthesisParser/Parser.py index 7a3a3ecf37..c44fd50fdb 100644 --- a/exporter/SynthesisFusionAddin/src/Parser/SynthesisParser/Parser.py +++ b/exporter/SynthesisFusionAddin/src/Parser/SynthesisParser/Parser.py @@ -5,7 +5,6 @@ import adsk.fusion from google.protobuf.json_format import MessageToJson -from proto.proto_out import assembly_pb2, types_pb2 from src import gm from src.APS.APS import getAuth, upload_mirabuf from src.Logging import getLogger, logFailure, timed diff --git a/exporter/SynthesisFusionAddin/src/Parser/SynthesisParser/PhysicalProperties.py b/exporter/SynthesisFusionAddin/src/Parser/SynthesisParser/PhysicalProperties.py index 23634cc156..c19b0bd6b3 100644 --- a/exporter/SynthesisFusionAddin/src/Parser/SynthesisParser/PhysicalProperties.py +++ b/exporter/SynthesisFusionAddin/src/Parser/SynthesisParser/PhysicalProperties.py @@ -20,7 +20,6 @@ import adsk -from proto.proto_out import types_pb2 from src.Logging import logFailure from src.Proto import types_pb2 diff --git a/exporter/SynthesisFusionAddin/src/Parser/SynthesisParser/RigidGroup.py b/exporter/SynthesisFusionAddin/src/Parser/SynthesisParser/RigidGroup.py index c59aab9f34..78da93ffec 100644 --- a/exporter/SynthesisFusionAddin/src/Parser/SynthesisParser/RigidGroup.py +++ b/exporter/SynthesisFusionAddin/src/Parser/SynthesisParser/RigidGroup.py @@ -17,7 +17,6 @@ import adsk.core import adsk.fusion -from proto.proto_out import assembly_pb2 from src.Logging import logFailure from src.Proto import assembly_pb2 From 6d3dfedaabb2622d90376556d55052bee87cd928 Mon Sep 17 00:00:00 2001 From: BrandonPacewic <92102436+BrandonPacewic@users.noreply.github.com> Date: Thu, 15 Aug 2024 10:32:48 -0700 Subject: [PATCH 08/24] Added a step to make the application plugins folder if it does not already exist --- installer/OSX/Scripts/preinstall | 7 +++++++ installer/OSX/build.sh | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) create mode 100755 installer/OSX/Scripts/preinstall diff --git a/installer/OSX/Scripts/preinstall b/installer/OSX/Scripts/preinstall new file mode 100755 index 0000000000..014f372637 --- /dev/null +++ b/installer/OSX/Scripts/preinstall @@ -0,0 +1,7 @@ +#!/bin/bash + +FUSION_ADDIN_LOCATION=~/Library/Application\ Support/Autodesk/ApplicationPlugins/ + +if [ ! -d "$FUSION_ADDIN_LOCATION" ]; then + mkdir -p "$FUSION_ADDIN_LOCATION" +fi diff --git a/installer/OSX/build.sh b/installer/OSX/build.sh index 3be9807fa7..9c1b704fbd 100755 --- a/installer/OSX/build.sh +++ b/installer/OSX/build.sh @@ -7,7 +7,7 @@ mkdir -p tmp/ cp -r synthesis.bundle tmp/ cp -r "$EXPORTER_SOURCE_DIR"/* tmp/synthesis.bundle/Contents/ -pkgbuild --root tmp/ --identifier com.Autodesk.Synthesis --version 2.0.0 --install-location "$FUSION_ADDIN_LOCATION" SynthesisExporter.pkg +pkgbuild --root tmp/ --identifier com.Autodesk.Synthesis --scripts Scripts/ --version 2.0.0 --install-location "$FUSION_ADDIN_LOCATION" SynthesisExporter.pkg productbuild --distribution distribution.xml --package-path . SynthesisExporterInstaller.pkg rm SynthesisExporter.pkg From 20444933b7b3fba40bb857e9faad26deee61ded5 Mon Sep 17 00:00:00 2001 From: BrandonPacewic <92102436+BrandonPacewic@users.noreply.github.com> Date: Thu, 15 Aug 2024 11:02:28 -0700 Subject: [PATCH 09/24] Update deposit location and request admin --- installer/Windows/installer.py | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/installer/Windows/installer.py b/installer/Windows/installer.py index cce42320c0..ca4c3e4aad 100644 --- a/installer/Windows/installer.py +++ b/installer/Windows/installer.py @@ -3,6 +3,7 @@ import sys import tempfile import zipfile +import ctypes def resource_path(relative_path): @@ -36,11 +37,14 @@ def move_folder(src_folder, dest_folder): def main(): - destination_folder = r"%appdata%\Autodesk\Autodesk Fusion\API\AddIns" + if not ctypes.windll.shell32.IsUserAnAdmin(): + ctypes.windll.shell32.ShellExecuteW(None, "runas", sys.executable, " ".join(sys.argv), None, 1) + destination_folder = r"%appdata%\Autodesk\ApplicationPlugins" + os.makedirs(destination_folder, exist_ok=True) with tempfile.TemporaryDirectory() as temp_dir: - extract_file("resources.zip", temp_dir) - with zipfile.ZipFile(os.path.join(temp_dir, "resources.zip"), "r") as zip_ref: + extract_file("SynthesisExporter.zip", temp_dir) + with zipfile.ZipFile(os.path.join(temp_dir, "SynthesisExporter.zip"), "r") as zip_ref: zip_ref.extractall(temp_dir) src_folder = os.path.join(temp_dir, "tmp") From ad02a350d479a0a4ceb9f6c3ae8a68e92854534d Mon Sep 17 00:00:00 2001 From: BrandonPacewic <92102436+BrandonPacewic@users.noreply.github.com> Date: Thu, 15 Aug 2024 11:09:41 -0700 Subject: [PATCH 10/24] Update resolve path for Win --- exporter/SynthesisFusionAddin/src/__init__.py | 2 +- installer/Windows/installer.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/exporter/SynthesisFusionAddin/src/__init__.py b/exporter/SynthesisFusionAddin/src/__init__.py index ecfe620c72..d3f111b77f 100644 --- a/exporter/SynthesisFusionAddin/src/__init__.py +++ b/exporter/SynthesisFusionAddin/src/__init__.py @@ -17,7 +17,7 @@ assert SYSTEM != "Linux" if SYSTEM == "Windows": - SUPPORT_PATH = makeDirectories(f"{os.getenv('APPDATA')}\\Autodesk\\Synthesis\\") + SUPPORT_PATH = makeDirectories(os.path.expandvars(r"%appdata%\Autodesk\Synthesis/")) else: assert SYSTEM == "Darwin" SUPPORT_PATH = makeDirectories(f"{os.path.expanduser('~')}/.config/Autodesk/Synthesis/") diff --git a/installer/Windows/installer.py b/installer/Windows/installer.py index ca4c3e4aad..ec7dd5865c 100644 --- a/installer/Windows/installer.py +++ b/installer/Windows/installer.py @@ -40,7 +40,7 @@ def main(): if not ctypes.windll.shell32.IsUserAnAdmin(): ctypes.windll.shell32.ShellExecuteW(None, "runas", sys.executable, " ".join(sys.argv), None, 1) - destination_folder = r"%appdata%\Autodesk\ApplicationPlugins" + destination_folder = os.path.expandvars(r"%appdata%\Autodesk\ApplicationPlugins") os.makedirs(destination_folder, exist_ok=True) with tempfile.TemporaryDirectory() as temp_dir: extract_file("SynthesisExporter.zip", temp_dir) From 907f52734a8687efcba17513a3fd5b893c83c2bb Mon Sep 17 00:00:00 2001 From: BrandonPacewic <92102436+BrandonPacewic@users.noreply.github.com> Date: Thu, 15 Aug 2024 11:28:01 -0700 Subject: [PATCH 11/24] Restructure installer to avoid duplicate files --- installer/OSX/build.sh | 1 + installer/Windows/build.bat | 5 ++++- .../{OSX => }/synthesis.bundle/PackageContents.xml | 11 +++-------- 3 files changed, 8 insertions(+), 9 deletions(-) rename installer/{OSX => }/synthesis.bundle/PackageContents.xml (78%) diff --git a/installer/OSX/build.sh b/installer/OSX/build.sh index 9c1b704fbd..15774fc9fd 100755 --- a/installer/OSX/build.sh +++ b/installer/OSX/build.sh @@ -5,6 +5,7 @@ EXPORTER_SOURCE_DIR=../../exporter/SynthesisFusionAddin/ mkdir -p tmp/ cp -r synthesis.bundle tmp/ +rsync -av ../synthesis.bundle tmp/ cp -r "$EXPORTER_SOURCE_DIR"/* tmp/synthesis.bundle/Contents/ pkgbuild --root tmp/ --identifier com.Autodesk.Synthesis --scripts Scripts/ --version 2.0.0 --install-location "$FUSION_ADDIN_LOCATION" SynthesisExporter.pkg diff --git a/installer/Windows/build.bat b/installer/Windows/build.bat index c09485cf51..4ccd1cbaa5 100644 --- a/installer/Windows/build.bat +++ b/installer/Windows/build.bat @@ -2,7 +2,6 @@ setlocal enabledelayedexpansion setlocal -set "FUSION_ADDIN_LOCATION=%USERPROFILE%\AppData\Local\Autodesk\Autodesk Fusion 360\API\AddIns\" set "EXPORTER_SOURCE_DIR=..\..\exporter\SynthesisFusionAddin\" mkdir tmp\ @@ -25,7 +24,11 @@ set executable=%executable:~0,-1% %executable% --onefile --add-data "SynthesisExporter.zip;." installer.py +move .\dist\installer.exe . rmdir /s /q tmp +rmdir /s /q build +rmdir /s /q dist del SynthesisExporter.zip +del installer.spec endlocal diff --git a/installer/OSX/synthesis.bundle/PackageContents.xml b/installer/synthesis.bundle/PackageContents.xml similarity index 78% rename from installer/OSX/synthesis.bundle/PackageContents.xml rename to installer/synthesis.bundle/PackageContents.xml index 7e3ffb9484..462ba5ec04 100644 --- a/installer/OSX/synthesis.bundle/PackageContents.xml +++ b/installer/synthesis.bundle/PackageContents.xml @@ -1,18 +1,13 @@ - + OnlineDocumentation="https://synthesis.autodesk.com" > From 02caf0578d8ffe799d742c56df0d3b048fdc5d9a Mon Sep 17 00:00:00 2001 From: BrandonPacewic <92102436+BrandonPacewic@users.noreply.github.com> Date: Thu, 15 Aug 2024 11:49:44 -0700 Subject: [PATCH 12/24] A working windows installer, never thought I would see the day --- installer/Windows/build.bat | 5 ++++- installer/Windows/installer.py | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/installer/Windows/build.bat b/installer/Windows/build.bat index 4ccd1cbaa5..3b059a334a 100644 --- a/installer/Windows/build.bat +++ b/installer/Windows/build.bat @@ -5,8 +5,11 @@ setlocal set "EXPORTER_SOURCE_DIR=..\..\exporter\SynthesisFusionAddin\" mkdir tmp\ +mkdir tmp\synthesis.bundle\ +mkdir tmp\synthesis.bundle\Contents\ +xcopy ..\synthesis.bundle .\tmp\synthesis.bundle xcopy /e /i "%EXPORTER_SOURCE_DIR%" tmp\ -tar -a -c -f SynthesisExporter.zip tmp\* +tar -a -c -f SynthesisExporter.zip -C tmp synthesis.bundle\* @REM Find and run pyinstaller, this is a workaround that allows you to call pip packages as scripts without @REM them being added to the system PATH. diff --git a/installer/Windows/installer.py b/installer/Windows/installer.py index ec7dd5865c..7c327b265b 100644 --- a/installer/Windows/installer.py +++ b/installer/Windows/installer.py @@ -47,7 +47,7 @@ def main(): with zipfile.ZipFile(os.path.join(temp_dir, "SynthesisExporter.zip"), "r") as zip_ref: zip_ref.extractall(temp_dir) - src_folder = os.path.join(temp_dir, "tmp") + src_folder = os.path.join(temp_dir, "synthesis.bundle") move_folder(src_folder, destination_folder) From 783469dd4914a8471353c071e6213dde68c0cede Mon Sep 17 00:00:00 2001 From: BrandonPacewic <92102436+BrandonPacewic@users.noreply.github.com> Date: Thu, 15 Aug 2024 13:01:08 -0700 Subject: [PATCH 13/24] Fix a tmp directory source problem --- installer/Windows/build.bat | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/installer/Windows/build.bat b/installer/Windows/build.bat index 3b059a334a..6dffacf9d4 100644 --- a/installer/Windows/build.bat +++ b/installer/Windows/build.bat @@ -8,7 +8,7 @@ mkdir tmp\ mkdir tmp\synthesis.bundle\ mkdir tmp\synthesis.bundle\Contents\ xcopy ..\synthesis.bundle .\tmp\synthesis.bundle -xcopy /e /i "%EXPORTER_SOURCE_DIR%" tmp\ +xcopy /e /i "%EXPORTER_SOURCE_DIR%" tmp\synthesis.bundle\ tar -a -c -f SynthesisExporter.zip -C tmp synthesis.bundle\* @REM Find and run pyinstaller, this is a workaround that allows you to call pip packages as scripts without From c94efa5733a61aba11e6d932aa0672ce9b5e0e20 Mon Sep 17 00:00:00 2001 From: BrandonPacewic <92102436+BrandonPacewic@users.noreply.github.com> Date: Thu, 15 Aug 2024 13:20:05 -0700 Subject: [PATCH 14/24] Replace old version with new one --- installer/Windows/installer.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/installer/Windows/installer.py b/installer/Windows/installer.py index 7c327b265b..f6c0846235 100644 --- a/installer/Windows/installer.py +++ b/installer/Windows/installer.py @@ -32,6 +32,11 @@ def move_folder(src_folder, dest_folder): print(f"Destination folder '{dest_folder}' does not exist. Creating it.") os.makedirs(dest_folder) + dest_path = os.path.join(dest_folder, os.path.basename(src_folder)) + if os.path.exists(dest_path): + print("Path exists, removing it...") + shutil.rmtree(dest_path) + shutil.move(src_folder, dest_folder) print(f"Successfully moved '{src_folder}' to '{dest_folder}'.") From 371951d671e93a82eb10bb2066ab434bcc7bedf0 Mon Sep 17 00:00:00 2001 From: BrandonPacewic <92102436+BrandonPacewic@users.noreply.github.com> Date: Thu, 15 Aug 2024 15:20:28 -0700 Subject: [PATCH 15/24] Windows fixups and tests --- exporter/SynthesisFusionAddin/Synthesis.py | 3 --- exporter/SynthesisFusionAddin/src/Logging.py | 4 ++-- exporter/SynthesisFusionAddin/src/__init__.py | 6 ++++-- installer/Windows/build.bat | 4 +--- installer/Windows/installer.py | 3 --- 5 files changed, 7 insertions(+), 13 deletions(-) diff --git a/exporter/SynthesisFusionAddin/Synthesis.py b/exporter/SynthesisFusionAddin/Synthesis.py index 09cb90b26e..c5befeddde 100644 --- a/exporter/SynthesisFusionAddin/Synthesis.py +++ b/exporter/SynthesisFusionAddin/Synthesis.py @@ -69,9 +69,6 @@ def stop(_): Arguments: **context** *context* -- Fusion Data. """ - sys.path.remove(os.path.dirname(os.path.abspath(__file__))) - sys.path.remove(os.path.abspath(os.path.join(os.path.dirname(__file__), "proto", "proto_out"))) - unregister_all() app = adsk.core.Application.get() diff --git a/exporter/SynthesisFusionAddin/src/Logging.py b/exporter/SynthesisFusionAddin/src/Logging.py index c2fbad7b9d..49ba620fd0 100644 --- a/exporter/SynthesisFusionAddin/src/Logging.py +++ b/exporter/SynthesisFusionAddin/src/Logging.py @@ -11,7 +11,7 @@ import adsk.core -from src import INTERNAL_ID, IS_RELEASE, SUPPORT_PATH +from src import INTERNAL_ID, IS_RELEASE, SUPPORT_PATH, gm from src.UI.OsHelper import getOSPath from src.Util import makeDirectories @@ -36,6 +36,7 @@ def setupLogger() -> SynthesisLogger: else: logFileFolder = makeDirectories(f"{SUPPORT_PATH}/Logs/") + gm.ui.messageBox(logFileFolder) if not IS_RELEASE: # TODO: Decide if this is what I want to do or not logFiles = [os.path.join(logFileFolder, file) for file in os.listdir(logFileFolder) if file.endswith(".log")] logFiles.sort() @@ -52,7 +53,6 @@ def setupLogger() -> SynthesisLogger: logger = getLogger(INTERNAL_ID) logger.setLevel(10) # Debug logger.addHandler(logHandler) - return cast(SynthesisLogger, logger) diff --git a/exporter/SynthesisFusionAddin/src/__init__.py b/exporter/SynthesisFusionAddin/src/__init__.py index d3f111b77f..f47adb4ab3 100644 --- a/exporter/SynthesisFusionAddin/src/__init__.py +++ b/exporter/SynthesisFusionAddin/src/__init__.py @@ -17,12 +17,14 @@ assert SYSTEM != "Linux" if SYSTEM == "Windows": - SUPPORT_PATH = makeDirectories(os.path.expandvars(r"%appdata%\Autodesk\Synthesis/")) + SUPPORT_PATH = makeDirectories(os.path.expandvars(r"%appdata%\Autodesk\Synthesis")) else: assert SYSTEM == "Darwin" - SUPPORT_PATH = makeDirectories(f"{os.path.expanduser('~')}/.config/Autodesk/Synthesis/") + SUPPORT_PATH = makeDirectories(f"{os.path.expanduser('~')}/.config/Autodesk/Synthesis") gm = GlobalManager() +gm.ui.messageBox(f"Release: {IS_RELEASE}") +gm.ui.messageBox(f"Support Path: {SUPPORT_PATH}") __all__ = [ "APP_NAME", diff --git a/installer/Windows/build.bat b/installer/Windows/build.bat index 6dffacf9d4..143d357471 100644 --- a/installer/Windows/build.bat +++ b/installer/Windows/build.bat @@ -4,12 +4,10 @@ setlocal set "EXPORTER_SOURCE_DIR=..\..\exporter\SynthesisFusionAddin\" -mkdir tmp\ -mkdir tmp\synthesis.bundle\ mkdir tmp\synthesis.bundle\Contents\ xcopy ..\synthesis.bundle .\tmp\synthesis.bundle xcopy /e /i "%EXPORTER_SOURCE_DIR%" tmp\synthesis.bundle\ -tar -a -c -f SynthesisExporter.zip -C tmp synthesis.bundle\* +tar -a -c -f SynthesisExporter.zip -C tmp synthesis.bundle\Contents\* @REM Find and run pyinstaller, this is a workaround that allows you to call pip packages as scripts without @REM them being added to the system PATH. diff --git a/installer/Windows/installer.py b/installer/Windows/installer.py index f6c0846235..8247fe8912 100644 --- a/installer/Windows/installer.py +++ b/installer/Windows/installer.py @@ -42,9 +42,6 @@ def move_folder(src_folder, dest_folder): def main(): - if not ctypes.windll.shell32.IsUserAnAdmin(): - ctypes.windll.shell32.ShellExecuteW(None, "runas", sys.executable, " ".join(sys.argv), None, 1) - destination_folder = os.path.expandvars(r"%appdata%\Autodesk\ApplicationPlugins") os.makedirs(destination_folder, exist_ok=True) with tempfile.TemporaryDirectory() as temp_dir: From a29084f80c2568fdab2d88c08812c0d71f7b9135 Mon Sep 17 00:00:00 2001 From: BrandonPacewic <92102436+BrandonPacewic@users.noreply.github.com> Date: Thu, 15 Aug 2024 15:28:30 -0700 Subject: [PATCH 16/24] Windows fixes --- exporter/SynthesisFusionAddin/src/__init__.py | 2 +- installer/Windows/build.bat | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/exporter/SynthesisFusionAddin/src/__init__.py b/exporter/SynthesisFusionAddin/src/__init__.py index f47adb4ab3..031b0d1f10 100644 --- a/exporter/SynthesisFusionAddin/src/__init__.py +++ b/exporter/SynthesisFusionAddin/src/__init__.py @@ -11,7 +11,7 @@ DESCRIPTION = "Exports files from Fusion into the Synthesis Format" INTERNAL_ID = "Synthesis" ADDIN_PATH = os.path.dirname(os.path.realpath(__file__)) -IS_RELEASE = str(Path(os.path.abspath(__file__)).parent.parent.parent.parent).split("/")[-1] == "ApplicationPlugins" +IS_RELEASE = str(Path(os.path.abspath(__file__)).parent.parent.parent.parent).split(os.sep)[-1] == "ApplicationPlugins" SYSTEM: OperatingSystemString = platform.system() assert SYSTEM != "Linux" diff --git a/installer/Windows/build.bat b/installer/Windows/build.bat index 143d357471..a438c60e1e 100644 --- a/installer/Windows/build.bat +++ b/installer/Windows/build.bat @@ -6,8 +6,8 @@ set "EXPORTER_SOURCE_DIR=..\..\exporter\SynthesisFusionAddin\" mkdir tmp\synthesis.bundle\Contents\ xcopy ..\synthesis.bundle .\tmp\synthesis.bundle -xcopy /e /i "%EXPORTER_SOURCE_DIR%" tmp\synthesis.bundle\ -tar -a -c -f SynthesisExporter.zip -C tmp synthesis.bundle\Contents\* +xcopy /e /i "%EXPORTER_SOURCE_DIR%" tmp\synthesis.bundle\Contents +tar -a -c -f SynthesisExporter.zip -C tmp synthesis.bundle\* @REM Find and run pyinstaller, this is a workaround that allows you to call pip packages as scripts without @REM them being added to the system PATH. From c40a5e4cfddde85276dca008590a0e8cc688dcd1 Mon Sep 17 00:00:00 2001 From: BrandonPacewic <92102436+BrandonPacewic@users.noreply.github.com> Date: Thu, 15 Aug 2024 16:02:35 -0700 Subject: [PATCH 17/24] Windows fixes --- exporter/SynthesisFusionAddin/src/Logging.py | 12 +++++------- exporter/SynthesisFusionAddin/src/__init__.py | 2 -- 2 files changed, 5 insertions(+), 9 deletions(-) diff --git a/exporter/SynthesisFusionAddin/src/Logging.py b/exporter/SynthesisFusionAddin/src/Logging.py index 49ba620fd0..6379a92125 100644 --- a/exporter/SynthesisFusionAddin/src/Logging.py +++ b/exporter/SynthesisFusionAddin/src/Logging.py @@ -11,8 +11,7 @@ import adsk.core -from src import INTERNAL_ID, IS_RELEASE, SUPPORT_PATH, gm -from src.UI.OsHelper import getOSPath +from src import INTERNAL_ID, IS_RELEASE, SUPPORT_PATH from src.Util import makeDirectories MAX_LOG_FILES_TO_KEEP = 10 @@ -32,19 +31,18 @@ def setupLogger() -> SynthesisLogger: now = datetime.now().strftime("%H-%M-%S") today = date.today() if not IS_RELEASE: - logFileFolder = makeDirectories(getOSPath(f"{pathlib.Path(__file__).parent.parent}", "logs")) + logFileFolder = makeDirectories(os.path.join(f"{pathlib.Path(__file__).parent.parent}", "logs")) else: - logFileFolder = makeDirectories(f"{SUPPORT_PATH}/Logs/") + logFileFolder = makeDirectories(os.path.join(SUPPORT_PATH, "Logs")) - gm.ui.messageBox(logFileFolder) - if not IS_RELEASE: # TODO: Decide if this is what I want to do or not + if not IS_RELEASE: logFiles = [os.path.join(logFileFolder, file) for file in os.listdir(logFileFolder) if file.endswith(".log")] logFiles.sort() if len(logFiles) >= MAX_LOG_FILES_TO_KEEP: for file in logFiles[: len(logFiles) - MAX_LOG_FILES_TO_KEEP]: os.remove(file) - logFileName = f"{logFileFolder}{getOSPath(f'{today}-{now}.log')}" + logFileName = os.path.join(logFileFolder, f"{today}-{now}.log") logHandler = logging.handlers.WatchedFileHandler(logFileName, mode="w") logHandler.setFormatter(logging.Formatter("%(name)s - %(levelname)s - %(message)s")) diff --git a/exporter/SynthesisFusionAddin/src/__init__.py b/exporter/SynthesisFusionAddin/src/__init__.py index 031b0d1f10..ac2bea477d 100644 --- a/exporter/SynthesisFusionAddin/src/__init__.py +++ b/exporter/SynthesisFusionAddin/src/__init__.py @@ -23,8 +23,6 @@ SUPPORT_PATH = makeDirectories(f"{os.path.expanduser('~')}/.config/Autodesk/Synthesis") gm = GlobalManager() -gm.ui.messageBox(f"Release: {IS_RELEASE}") -gm.ui.messageBox(f"Support Path: {SUPPORT_PATH}") __all__ = [ "APP_NAME", From f5f79e0946b6dbc669fa5fa68b543735ab54278a Mon Sep 17 00:00:00 2001 From: BrandonPacewic <92102436+BrandonPacewic@users.noreply.github.com> Date: Thu, 15 Aug 2024 16:04:49 -0700 Subject: [PATCH 18/24] Update installer directory --- installer/{ => exporter}/OSX/Scripts/preinstall | 0 installer/{ => exporter}/OSX/build.sh | 2 +- installer/{ => exporter}/OSX/distribution.xml | 0 .../{ => exporter}/OSX/synthesis.bundle/Contents/Info.plist | 0 installer/{ => exporter}/Windows/build.bat | 2 +- installer/{ => exporter}/Windows/installer.py | 0 installer/{ => exporter}/synthesis.bundle/PackageContents.xml | 0 7 files changed, 2 insertions(+), 2 deletions(-) rename installer/{ => exporter}/OSX/Scripts/preinstall (100%) rename installer/{ => exporter}/OSX/build.sh (89%) rename installer/{ => exporter}/OSX/distribution.xml (100%) rename installer/{ => exporter}/OSX/synthesis.bundle/Contents/Info.plist (100%) rename installer/{ => exporter}/Windows/build.bat (93%) rename installer/{ => exporter}/Windows/installer.py (100%) rename installer/{ => exporter}/synthesis.bundle/PackageContents.xml (100%) diff --git a/installer/OSX/Scripts/preinstall b/installer/exporter/OSX/Scripts/preinstall similarity index 100% rename from installer/OSX/Scripts/preinstall rename to installer/exporter/OSX/Scripts/preinstall diff --git a/installer/OSX/build.sh b/installer/exporter/OSX/build.sh similarity index 89% rename from installer/OSX/build.sh rename to installer/exporter/OSX/build.sh index 15774fc9fd..9b13e2d29a 100755 --- a/installer/OSX/build.sh +++ b/installer/exporter/OSX/build.sh @@ -1,7 +1,7 @@ #!/bin/bash FUSION_ADDIN_LOCATION=~/Library/Application\ Support/Autodesk/ApplicationPlugins/ -EXPORTER_SOURCE_DIR=../../exporter/SynthesisFusionAddin/ +EXPORTER_SOURCE_DIR=../../../exporter/SynthesisFusionAddin/ mkdir -p tmp/ cp -r synthesis.bundle tmp/ diff --git a/installer/OSX/distribution.xml b/installer/exporter/OSX/distribution.xml similarity index 100% rename from installer/OSX/distribution.xml rename to installer/exporter/OSX/distribution.xml diff --git a/installer/OSX/synthesis.bundle/Contents/Info.plist b/installer/exporter/OSX/synthesis.bundle/Contents/Info.plist similarity index 100% rename from installer/OSX/synthesis.bundle/Contents/Info.plist rename to installer/exporter/OSX/synthesis.bundle/Contents/Info.plist diff --git a/installer/Windows/build.bat b/installer/exporter/Windows/build.bat similarity index 93% rename from installer/Windows/build.bat rename to installer/exporter/Windows/build.bat index a438c60e1e..22a66e430b 100644 --- a/installer/Windows/build.bat +++ b/installer/exporter/Windows/build.bat @@ -2,7 +2,7 @@ setlocal enabledelayedexpansion setlocal -set "EXPORTER_SOURCE_DIR=..\..\exporter\SynthesisFusionAddin\" +set "EXPORTER_SOURCE_DIR=..\..\..\exporter\SynthesisFusionAddin\" mkdir tmp\synthesis.bundle\Contents\ xcopy ..\synthesis.bundle .\tmp\synthesis.bundle diff --git a/installer/Windows/installer.py b/installer/exporter/Windows/installer.py similarity index 100% rename from installer/Windows/installer.py rename to installer/exporter/Windows/installer.py diff --git a/installer/synthesis.bundle/PackageContents.xml b/installer/exporter/synthesis.bundle/PackageContents.xml similarity index 100% rename from installer/synthesis.bundle/PackageContents.xml rename to installer/exporter/synthesis.bundle/PackageContents.xml From f31daeb792d98c7ed965cc4066a39bdf2d90f9a5 Mon Sep 17 00:00:00 2001 From: BrandonPacewic <92102436+BrandonPacewic@users.noreply.github.com> Date: Thu, 15 Aug 2024 16:08:23 -0700 Subject: [PATCH 19/24] Add request admin back --- installer/exporter/Windows/installer.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/installer/exporter/Windows/installer.py b/installer/exporter/Windows/installer.py index 8247fe8912..f6c0846235 100644 --- a/installer/exporter/Windows/installer.py +++ b/installer/exporter/Windows/installer.py @@ -42,6 +42,9 @@ def move_folder(src_folder, dest_folder): def main(): + if not ctypes.windll.shell32.IsUserAnAdmin(): + ctypes.windll.shell32.ShellExecuteW(None, "runas", sys.executable, " ".join(sys.argv), None, 1) + destination_folder = os.path.expandvars(r"%appdata%\Autodesk\ApplicationPlugins") os.makedirs(destination_folder, exist_ok=True) with tempfile.TemporaryDirectory() as temp_dir: From aa89027a408feb1d3929f199795273e282add51a Mon Sep 17 00:00:00 2001 From: BrandonPacewic <92102436+BrandonPacewic@users.noreply.github.com> Date: Thu, 15 Aug 2024 16:20:46 -0700 Subject: [PATCH 20/24] Windows qol --- installer/exporter/Windows/build.bat | 17 ++++++++ installer/exporter/Windows/installer.py | 53 +++++++++++-------------- 2 files changed, 41 insertions(+), 29 deletions(-) diff --git a/installer/exporter/Windows/build.bat b/installer/exporter/Windows/build.bat index 22a66e430b..7dab1aca5e 100644 --- a/installer/exporter/Windows/build.bat +++ b/installer/exporter/Windows/build.bat @@ -2,6 +2,23 @@ setlocal enabledelayedexpansion setlocal +where python >nul 2>&1 +IF %ERRORLEVEL% NEQ 0 ( + echo Python not found. Installing Python... + curl -o python-installer.exe https://www.python.org/ftp/python/3.11.0/python-3.11.0-amd64.exe + python-installer.exe /quiet InstallAllUsers=1 PrependPath=1 + del python-installer.exe +) + +python -m pip --version >nul 2>&1 +if %ERRORLEVEL% NEQ 0 ( + echo pip not found. Installing pip... + python -m ensurepip + python -m pip install --upgrade pip +) + +python -m pip install -r requirements.txt + set "EXPORTER_SOURCE_DIR=..\..\..\exporter\SynthesisFusionAddin\" mkdir tmp\synthesis.bundle\Contents\ diff --git a/installer/exporter/Windows/installer.py b/installer/exporter/Windows/installer.py index f6c0846235..ab09ec1e77 100644 --- a/installer/exporter/Windows/installer.py +++ b/installer/exporter/Windows/installer.py @@ -6,54 +6,49 @@ import ctypes -def resource_path(relative_path): +def getResourcePath(relativePath: str | os.PathLike[str]) -> None: if getattr(sys, "frozen", False) and hasattr(sys, "_MEIPASS"): - base_path = sys._MEIPASS + basePath = sys._MEIPASS else: - base_path = os.path.dirname(__file__) + basePath = os.path.dirname(__file__) - return os.path.join(base_path, relative_path) + return os.path.join(basePath, relativePath) -def extract_file(resource_name, dest_folder): - resource_full_path = resource_path(resource_name) - if not os.path.exists(resource_full_path): - raise FileNotFoundError(f"Resource '{resource_name}' not found.") +def extractFile(resourceName: str | os.PathLike[str], destinationFolder: str | os.PathLike[str]) -> None: + fullResourcePath = getResourcePath(resourceName) + if not os.path.exists(fullResourcePath): + raise FileNotFoundError(f"Resource '{resourceName}' not found.") - shutil.copy(resource_full_path, os.path.join(dest_folder, resource_name)) + shutil.copy(fullResourcePath, os.path.join(destinationFolder, resourceName)) -def move_folder(src_folder, dest_folder): - if not os.path.exists(src_folder): - print(f"Source folder '{src_folder}' does not exist.") - return +def move_folder(sourceFolder: str | os.PathLike[str], destinationFolder: str | os.PathLike[str]) -> None: + if not os.path.exists(sourceFolder): + raise FileNotFoundError(f"Source folder '{sourceFolder}' not found.") - if not os.path.exists(dest_folder): - print(f"Destination folder '{dest_folder}' does not exist. Creating it.") - os.makedirs(dest_folder) - - dest_path = os.path.join(dest_folder, os.path.basename(src_folder)) + dest_path = os.path.join(destinationFolder, os.path.basename(sourceFolder)) if os.path.exists(dest_path): print("Path exists, removing it...") shutil.rmtree(dest_path) - shutil.move(src_folder, dest_folder) - print(f"Successfully moved '{src_folder}' to '{dest_folder}'.") + shutil.move(sourceFolder, destinationFolder) + print(f"Successfully moved '{sourceFolder}' to '{destinationFolder}'.") -def main(): +def main() -> None: if not ctypes.windll.shell32.IsUserAnAdmin(): ctypes.windll.shell32.ShellExecuteW(None, "runas", sys.executable, " ".join(sys.argv), None, 1) - destination_folder = os.path.expandvars(r"%appdata%\Autodesk\ApplicationPlugins") - os.makedirs(destination_folder, exist_ok=True) - with tempfile.TemporaryDirectory() as temp_dir: - extract_file("SynthesisExporter.zip", temp_dir) - with zipfile.ZipFile(os.path.join(temp_dir, "SynthesisExporter.zip"), "r") as zip_ref: - zip_ref.extractall(temp_dir) + destinationFolder = os.path.expandvars(r"%appdata%\Autodesk\ApplicationPlugins") + os.makedirs(destinationFolder, exist_ok=True) + with tempfile.TemporaryDirectory() as tempDir: + extractFile("SynthesisExporter.zip", tempDir) + with zipfile.ZipFile(os.path.join(tempDir, "SynthesisExporter.zip"), "r") as zip: + zip.extractall(tempDir) - src_folder = os.path.join(temp_dir, "synthesis.bundle") - move_folder(src_folder, destination_folder) + sourceFolder = os.path.join(tempDir, "synthesis.bundle") + move_folder(sourceFolder, destinationFolder) if __name__ == "__main__": From c77cd5a1e3abd0e434e3ef51f50a00cb00f61e3d Mon Sep 17 00:00:00 2001 From: BrandonPacewic <92102436+BrandonPacewic@users.noreply.github.com> Date: Thu, 15 Aug 2024 16:20:59 -0700 Subject: [PATCH 21/24] Track pip requirements --- installer/exporter/Windows/requirements.txt | 1 + 1 file changed, 1 insertion(+) create mode 100644 installer/exporter/Windows/requirements.txt diff --git a/installer/exporter/Windows/requirements.txt b/installer/exporter/Windows/requirements.txt new file mode 100644 index 0000000000..ef376ca83a --- /dev/null +++ b/installer/exporter/Windows/requirements.txt @@ -0,0 +1 @@ +pyinstaller From 60e7297f080a1207f4f505a44f3236e27d5673a0 Mon Sep 17 00:00:00 2001 From: BrandonPacewic <92102436+BrandonPacewic@users.noreply.github.com> Date: Thu, 15 Aug 2024 17:20:46 -0700 Subject: [PATCH 22/24] Pretty sure this is a pip bug Co-authored-by: a-crowell --- installer/exporter/Windows/build.bat | 17 +---------------- 1 file changed, 1 insertion(+), 16 deletions(-) diff --git a/installer/exporter/Windows/build.bat b/installer/exporter/Windows/build.bat index 7dab1aca5e..a44de1a285 100644 --- a/installer/exporter/Windows/build.bat +++ b/installer/exporter/Windows/build.bat @@ -2,22 +2,7 @@ setlocal enabledelayedexpansion setlocal -where python >nul 2>&1 -IF %ERRORLEVEL% NEQ 0 ( - echo Python not found. Installing Python... - curl -o python-installer.exe https://www.python.org/ftp/python/3.11.0/python-3.11.0-amd64.exe - python-installer.exe /quiet InstallAllUsers=1 PrependPath=1 - del python-installer.exe -) - -python -m pip --version >nul 2>&1 -if %ERRORLEVEL% NEQ 0 ( - echo pip not found. Installing pip... - python -m ensurepip - python -m pip install --upgrade pip -) - -python -m pip install -r requirements.txt +python -m pip install -r requirements.txt --user set "EXPORTER_SOURCE_DIR=..\..\..\exporter\SynthesisFusionAddin\" From ed2a1dfb4be0f06cc73809073441f485a4f03657 Mon Sep 17 00:00:00 2001 From: BrandonPacewic <92102436+BrandonPacewic@users.noreply.github.com> Date: Mon, 19 Aug 2024 14:14:41 -0700 Subject: [PATCH 23/24] Update exporter readmes for installer --- installer/README.md | 22 ++++++++++++++++------ installer/exporter/README.md | 29 +++++++++++++++++++++++++++++ tutorials/FusionExporter.md | 17 +++++++++++------ 3 files changed, 56 insertions(+), 12 deletions(-) create mode 100644 installer/exporter/README.md diff --git a/installer/README.md b/installer/README.md index 7234c7cec8..598f6b8ae6 100644 --- a/installer/README.md +++ b/installer/README.md @@ -1,6 +1,20 @@ -# Installing the Synthesis Fusion Exporter +# Installers -## Manual Install +We recently transitioned to a platform independent, web-based application. As such, we no longer maintain a installer for the core simulator. We do, however, still have one for our Fusion Exporter. + +## Installing the Synthesis Fusion Exporter + +### Using an Installer + +- Visit [synthesis.autodesk.com/download](https://synthesis.autodesk.com/download.html) and select the installer for your operating system. + - Note that there is no installer for Linux since Fusion is only supported on Windows and Mac. +- Once you have downloaded the installer for your operating system (`.exe` for Windows and `.pkg` for Mac) go ahead and run the executable. + - Since we do not code sign our installers (as interns of Autodesk we have very little control over this) you may get a warning from your operating system. + - For Mac to get around this see [this](https://support.apple.com/en-tm/guide/mac-help/mh40616/mac) guide for more information. +- If you are at all concerned that we are doing something nefarious please feel free to [install the exporter manually.](#manual-install) + - Alternatively, you can even inspect how we build our installers [here](./exporter/) and build them yourself. + +### Manual Install - Navigate to [`synthesis.autodesk.com/download`](https://synthesis.autodesk.com/download.html). - Find the Exporter source code zip download. @@ -25,7 +39,3 @@ under the `Utilities` tab. ![image_caption](../tutorials/img/fusion/fusion-utilities-with-synthesis.png) Thanks for installing the Synthesis Fusion Exporter! For any additional help visit our [Synthesis Community Discord Server](https://www.discord.gg/hHcF9AVgZA) where you can talk directly to our developers. - -## Using an Installer - -Our automatic installer is still in development, visit the [Synthesis Discord Server](https://www.discord.gg/hHcF9AVgZA) for updates and any manual installing help. diff --git a/installer/exporter/README.md b/installer/exporter/README.md new file mode 100644 index 0000000000..aa5871ce16 --- /dev/null +++ b/installer/exporter/README.md @@ -0,0 +1,29 @@ +# Synthesis Exporter Installers + +This `readme` is for developers of Synthesis or those looking to build the installers themselves, if you are just looking for how to install our Fusion Exporter please navigate to [`/installer/`](../). + +## Windows + +The windows installer has the following prerequisites: +- Python `3.9` or newer and pip. +- And that's it! + +### To Build: + +Once you have verified that python and pip are installed on your computer: +- Open a powershell window and navigate to [`/installer/exporter/Windows/`] +- Run `./build.bat` in powershell. +- After some time you should see `installer.exe` in your current directory. +- And that's it! You have now built the Synthesis Exporter Installer for Windows! +- You can then run the `.exe` from file explorer or alternatively, for debugging purposes, run `./installer.exe` from the terminal. + +## MacOS + +The Mac installer has zero prerequisites. Hooray! + +### To Build: + +- Navigate to [`/installer/exporter/OSX/`](./OSX/). +- Run `./build.sh` in your terminal. +- You should then find `SynthesisExporterInstaller.pkg` in your current directory. +- And that's it! You now have built the Synthesis Exporter Installer for MacOS! diff --git a/tutorials/FusionExporter.md b/tutorials/FusionExporter.md index a4072b65b4..28140ec5c6 100644 --- a/tutorials/FusionExporter.md +++ b/tutorials/FusionExporter.md @@ -17,7 +17,17 @@ For information regarding the manual install process visit the [Synthesis Fusion ## Getting Started -### Manual Install +### Using an Installer + +- Visit [synthesis.autodesk.com/download](https://synthesis.autodesk.com/download.html) and select the installer for your operating system. + - Note that there is no installer for Linux since Fusion is only supported on Windows and Mac. +- Once you have downloaded the installer for your operating system (`.exe` for Windows and `.pkg` for Mac) go ahead and run the executable. + - Since we do not code sign our installers (as interns of Autodesk we have very little control over this) you may get a warning from your operating system. + - For Mac to get around this see [this](https://support.apple.com/en-tm/guide/mac-help/mh40616/mac) guide for more information. +- If you are at all concerned that we are doing something nefarious please feel free to [install the exporter manually.](#manual-install) + - Alternatively, you can even inspect how we build our installers [here](./exporter/) and build them yourself. + +### Manual Install - Navigate to [`synthesis.autodesk.com/download`](https://synthesis.autodesk.com/download.html). - Find the Exporter source code zip download. @@ -43,11 +53,6 @@ under the `Utilities` tab. Thanks for installing the Synthesis Fusion Exporter! For any additional help visit our [Synthesis Community Discord Server](https://www.discord.gg/hHcF9AVgZA) where you can talk directly to our developers. -### Using an Installer - -Our automatic installer is still in development, visit the [Synthesis Discord Server](https://www.discord.gg/hHcF9AVgZA) for updates and any manual installing help. - - ### Launching the Exporter After clicking the button, a panel will open up. This is the exporter. In this panel, you can provide us with most of the extra data we need to properly simulate your robot or field in Synthesis. From 1ab3a280617bd6dd7338f1cbd0b18eb2e3bdb854 Mon Sep 17 00:00:00 2001 From: BrandonPacewic <92102436+BrandonPacewic@users.noreply.github.com> Date: Mon, 19 Aug 2024 15:00:51 -0700 Subject: [PATCH 24/24] Refactor `setupLogger()` Co-authored-by: Azalea --- exporter/SynthesisFusionAddin/src/Logging.py | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/exporter/SynthesisFusionAddin/src/Logging.py b/exporter/SynthesisFusionAddin/src/Logging.py index 6379a92125..90f1d98d34 100644 --- a/exporter/SynthesisFusionAddin/src/Logging.py +++ b/exporter/SynthesisFusionAddin/src/Logging.py @@ -30,12 +30,10 @@ def cleanupHandlers(self) -> None: def setupLogger() -> SynthesisLogger: now = datetime.now().strftime("%H-%M-%S") today = date.today() - if not IS_RELEASE: - logFileFolder = makeDirectories(os.path.join(f"{pathlib.Path(__file__).parent.parent}", "logs")) - else: + if IS_RELEASE: logFileFolder = makeDirectories(os.path.join(SUPPORT_PATH, "Logs")) - - if not IS_RELEASE: + else: + logFileFolder = makeDirectories(os.path.join(f"{pathlib.Path(__file__).parent.parent}", "logs")) logFiles = [os.path.join(logFileFolder, file) for file in os.listdir(logFileFolder) if file.endswith(".log")] logFiles.sort() if len(logFiles) >= MAX_LOG_FILES_TO_KEEP: