cleanup root of repository

This commit is contained in:
Jakub Trllo 2024-02-05 14:17:58 +01:00
parent 56bfe209f6
commit 22260b3e6d
775 changed files with 5 additions and 61446 deletions

View file

@ -33,117 +33,18 @@ body:
id: _version
attributes:
label: Version
description: What version are you running? Look to OpenPype Tray
description: What version are you running? Look to AYON Tray
options:
- 3.18.7-nightly.1
- 3.18.6
- 3.18.6-nightly.2
- 3.18.6-nightly.1
- 3.18.5
- 3.18.5-nightly.3
- 3.18.5-nightly.2
- 3.18.5-nightly.1
- 3.18.4
- 3.18.4-nightly.1
- 3.18.3
- 3.18.3-nightly.2
- 3.18.3-nightly.1
- 3.18.2
- 3.18.2-nightly.6
- 3.18.2-nightly.5
- 3.18.2-nightly.4
- 3.18.2-nightly.3
- 3.18.2-nightly.2
- 3.18.2-nightly.1
- 3.18.1
- 3.18.1-nightly.1
- 3.18.0
- 3.17.7
- 3.17.7-nightly.7
- 3.17.7-nightly.6
- 3.17.7-nightly.5
- 3.17.7-nightly.4
- 3.17.7-nightly.3
- 3.17.7-nightly.2
- 3.17.7-nightly.1
- 3.17.6
- 3.17.6-nightly.3
- 3.17.6-nightly.2
- 3.17.6-nightly.1
- 3.17.5
- 3.17.5-nightly.3
- 3.17.5-nightly.2
- 3.17.5-nightly.1
- 3.17.4
- 3.17.4-nightly.2
- 3.17.4-nightly.1
- 3.17.3
- 3.17.3-nightly.2
- 3.17.3-nightly.1
- 3.17.2
- 3.17.2-nightly.4
- 3.17.2-nightly.3
- 3.17.2-nightly.2
- 3.17.2-nightly.1
- 3.17.1
- 3.17.1-nightly.3
- 3.17.1-nightly.2
- 3.17.1-nightly.1
- 3.17.0
- 3.16.7
- 3.16.7-nightly.2
- 3.16.7-nightly.1
- 3.16.6
- 3.16.6-nightly.1
- 3.16.5
- 3.16.5-nightly.5
- 3.16.5-nightly.4
- 3.16.5-nightly.3
- 3.16.5-nightly.2
- 3.16.5-nightly.1
- 3.16.4
- 3.16.4-nightly.3
- 3.16.4-nightly.2
- 3.16.4-nightly.1
- 3.16.3
- 3.16.3-nightly.5
- 3.16.3-nightly.4
- 3.16.3-nightly.3
- 3.16.3-nightly.2
- 3.16.3-nightly.1
- 3.16.2
- 3.16.2-nightly.2
- 3.16.2-nightly.1
- 3.16.1
- 3.16.0
- 3.16.0-nightly.2
- 3.16.0-nightly.1
- 3.15.12
- 3.15.12-nightly.4
- 3.15.12-nightly.3
- 3.15.12-nightly.2
- 3.15.12-nightly.1
- 3.15.11
- 3.15.11-nightly.5
- 3.15.11-nightly.4
- 3.15.11-nightly.3
- 3.15.11-nightly.2
- 3.15.11-nightly.1
- 3.15.10
- 3.15.10-nightly.2
- 3.15.10-nightly.1
- 3.15.9
- 3.15.9-nightly.2
- 3.15.9-nightly.1
- 1.0.0
validations:
required: true
- type: dropdown
validations:
required: true
attributes:
label: What platform you are running OpenPype on?
label: What platform you are running on?
description: |
Please specify the operating systems you are running OpenPype with.
Please specify the operating systems you are using.
multiple: true
options:
- Windows

View file

@ -1,102 +0,0 @@
# Add type: unittest label if any changes in tests folders
'type: unittest':
- '*/*tests*/**/*'
# any changes in documentation structure
'type: documentation':
- '*/**/*website*/**/*'
- '*/**/*docs*/**/*'
# hosts triage
'host: Nuke':
- '*/**/*nuke*'
- '*/**/*nuke*/**/*'
'host: Photoshop':
- '*/**/*photoshop*'
- '*/**/*photoshop*/**/*'
'host: Harmony':
- '*/**/*harmony*'
- '*/**/*harmony*/**/*'
'host: UE':
- '*/**/*unreal*'
- '*/**/*unreal*/**/*'
'host: Houdini':
- '*/**/*houdini*'
- '*/**/*houdini*/**/*'
'host: Maya':
- '*/**/*maya*'
- '*/**/*maya*/**/*'
'host: Resolve':
- '*/**/*resolve*'
- '*/**/*resolve*/**/*'
'host: Blender':
- '*/**/*blender*'
- '*/**/*blender*/**/*'
'host: Hiero':
- '*/**/*hiero*'
- '*/**/*hiero*/**/*'
'host: Fusion':
- '*/**/*fusion*'
- '*/**/*fusion*/**/*'
'host: Flame':
- '*/**/*flame*'
- '*/**/*flame*/**/*'
'host: TrayPublisher':
- '*/**/*traypublisher*'
- '*/**/*traypublisher*/**/*'
'host: 3dsmax':
- '*/**/*max*'
- '*/**/*max*/**/*'
'host: TV Paint':
- '*/**/*tvpaint*'
- '*/**/*tvpaint*/**/*'
'host: CelAction':
- '*/**/*celaction*'
- '*/**/*celaction*/**/*'
'host: After Effects':
- '*/**/*aftereffects*'
- '*/**/*aftereffects*/**/*'
'host: Substance Painter':
- '*/**/*substancepainter*'
- '*/**/*substancepainter*/**/*'
# modules triage
'module: Deadline':
- '*/**/*deadline*'
- '*/**/*deadline*/**/*'
'module: RoyalRender':
- '*/**/*royalrender*'
- '*/**/*royalrender*/**/*'
'module: Sitesync':
- '*/**/*sync_server*'
- '*/**/*sync_server*/**/*'
'module: Ftrack':
- '*/**/*ftrack*'
- '*/**/*ftrack*/**/*'
'module: Shotgrid':
- '*/**/*shotgrid*'
- '*/**/*shotgrid*/**/*'
'module: Kitsu':
- '*/**/*kitsu*'
- '*/**/*kitsu*/**/*'

View file

@ -1,65 +0,0 @@
name: 📜 Documentation
on:
pull_request:
branches: [develop]
types: [review_requested, ready_for_review]
paths:
- 'website/**'
push:
branches: [main]
paths:
- 'website/**'
workflow_dispatch:
jobs:
check-build:
if: github.event_name != 'push'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1
- uses: actions/setup-node@v1
with:
node-version: 14.x
cache: yarn
- name: Test Build
run: |
cd website
if [ -e yarn.lock ]; then
yarn install --frozen-lockfile
elif [ -e package-lock.json ]; then
npm ci
else
npm i
fi
npm run build
deploy-website:
if: github.event_name != 'pull_request'
runs-on: ubuntu-latest
steps:
- name: 🚚 Get latest code
uses: actions/checkout@v2
- uses: actions/setup-node@v1
with:
node-version: 14.x
cache: yarn
- name: 🔨 Build
run: |
cd website
if [ -e yarn.lock ]; then
yarn install --frozen-lockfile
elif [ -e package-lock.json ]; then
npm ci
else
npm i
fi
npm run build
- name: 📂 Sync files
uses: SamKirkland/FTP-Deploy-Action@4.0.0
with:
server: ftp.openpype.io
username: ${{ secrets.ftp_user }}
password: ${{ secrets.ftp_password }}
local-dir: ./website/build/

View file

@ -1,28 +0,0 @@
name: 👉🏻 Milestone - assign to PRs
on:
pull_request_target:
types: [closed]
jobs:
run_if_release:
if: startsWith(github.base_ref, 'release/')
runs-on: ubuntu-latest
steps:
- name: 'Assign Milestone [next-minor]'
if: github.event.pull_request.milestone == null
uses: zoispag/action-assign-milestone@v1
with:
repo-token: "${{ secrets.YNPUT_BOT_TOKEN }}"
milestone: 'next-minor'
run_if_develop:
if: ${{ github.base_ref == 'develop' }}
runs-on: ubuntu-latest
steps:
- name: 'Assign Milestone [next-patch]'
if: github.event.pull_request.milestone == null
uses: zoispag/action-assign-milestone@v1
with:
repo-token: "${{ secrets.YNPUT_BOT_TOKEN }}"
milestone: 'next-patch'

View file

@ -1,62 +0,0 @@
name: Milestone - create default
on:
milestone:
types: [closed, edited]
jobs:
generate-next-patch:
runs-on: ubuntu-latest
steps:
- name: 'Get Milestones'
uses: "WyriHaximus/github-action-get-milestones@master"
id: milestones
env:
GITHUB_TOKEN: "${{ secrets.YNPUT_BOT_TOKEN }}"
- run: printf "name=number::%s" $(printenv MILESTONES | jq --arg MILESTONE $(printenv MILESTONE) '.[] | select(.title == $MILESTONE) | .number')
id: querymilestone
env:
MILESTONES: ${{ steps.milestones.outputs.milestones }}
MILESTONE: "next-patch"
- name: Read output
run: |
echo "${{ steps.querymilestone.outputs.number }}"
- name: 'Create `next-patch` milestone'
if: steps.querymilestone.outputs.number == ''
id: createmilestone
uses: "WyriHaximus/github-action-create-milestone@v1"
with:
title: 'next-patch'
env:
GITHUB_TOKEN: "${{ secrets.YNPUT_BOT_TOKEN }}"
generate-next-minor:
runs-on: ubuntu-latest
steps:
- name: 'Get Milestones'
uses: "WyriHaximus/github-action-get-milestones@master"
id: milestones
env:
GITHUB_TOKEN: "${{ secrets.YNPUT_BOT_TOKEN }}"
- run: printf "name=number::%s" $(printenv MILESTONES | jq --arg MILESTONE $(printenv MILESTONE) '.[] | select(.title == $MILESTONE) | .number')
id: querymilestone
env:
MILESTONES: ${{ steps.milestones.outputs.milestones }}
MILESTONE: "next-minor"
- name: Read output
run: |
echo "${{ steps.querymilestone.outputs.number }}"
- name: 'Create `next-minor` milestone'
if: steps.querymilestone.outputs.number == ''
id: createmilestone
uses: "WyriHaximus/github-action-create-milestone@v1"
with:
title: 'next-minor'
env:
GITHUB_TOKEN: "${{ secrets.YNPUT_BOT_TOKEN }}"

View file

@ -1,44 +0,0 @@
name: 🚩 Milestone Release [trigger]
on:
workflow_dispatch:
inputs:
milestone:
required: true
milestone:
types: closed
jobs:
milestone-title:
runs-on: ubuntu-latest
outputs:
milestone: ${{ steps.milestoneTitle.outputs.value }}
steps:
- name: Switch input milestone
uses: haya14busa/action-cond@v1
id: milestoneTitle
with:
cond: ${{ inputs.milestone == '' }}
if_true: ${{ github.event.milestone.title }}
if_false: ${{ inputs.milestone }}
- name: Print resulted milestone
run: |
echo "${{ steps.milestoneTitle.outputs.value }}"
call-ci-tools-milestone-release:
needs: milestone-title
uses: ynput/ci-tools/.github/workflows/milestone_release_ref.yml@main
with:
milestone: ${{ needs.milestone-title.outputs.milestone }}
repo-owner: ${{ github.event.repository.owner.login }}
repo-name: ${{ github.event.repository.name }}
version-py-path: "./openpype/version.py"
pyproject-path: "./pyproject.toml"
secrets:
token: ${{ secrets.YNPUT_BOT_TOKEN }}
user_email: ${{ secrets.CI_EMAIL }}
user_name: ${{ secrets.CI_USER }}
cu_api_key: ${{ secrets.CLICKUP_API_KEY }}
cu_team_id: ${{ secrets.CLICKUP_TEAM_ID }}
cu_field_id: ${{ secrets.CLICKUP_RELEASE_FIELD_ID }}

View file

@ -1,29 +0,0 @@
name: 🔀 Dev -> Main
on:
schedule:
- cron: '21 3 * * 3,6'
workflow_dispatch:
jobs:
develop-to-main:
runs-on: ubuntu-latest
steps:
- name: 🚛 Checkout Code
uses: actions/checkout@v2
- name: 🔨 Merge develop to main
uses: everlytic/branch-merge@1.1.0
with:
github_token: ${{ secrets.YNPUT_BOT_TOKEN }}
source_ref: 'develop'
target_branch: 'main'
commit_message_template: '[Automated] Merged {source_ref} into {target_branch}'
- name: Invoke pre-release workflow
uses: benc-uk/workflow-dispatch@v1
with:
workflow: prerelease.yml
token: ${{ secrets.YNPUT_BOT_TOKEN }}

View file

@ -1,73 +0,0 @@
name: ⏳ Nightly Prerelease
on:
workflow_dispatch:
jobs:
create_nightly:
runs-on: ubuntu-latest
steps:
- name: 🚛 Checkout Code
uses: actions/checkout@v2
with:
fetch-depth: 0
- name: Set up Python
uses: actions/setup-python@v2
with:
python-version: 3.9
- name: Install Python requirements
run: pip install gitpython semver PyGithub
- name: 🔎 Determine next version type
id: version_type
run: |
TYPE=$(python ./tools/ci_tools.py --bump --github_token ${{ secrets.YNPUT_BOT_TOKEN }})
echo "type=${TYPE}" >> $GITHUB_OUTPUT
- name: 💉 Inject new version into files
id: version
if: steps.version_type.outputs.type != 'skip'
run: |
NEW_VERSION_TAG=$(python ./tools/ci_tools.py --nightly --github_token ${{ secrets.YNPUT_BOT_TOKEN }})
echo "next_tag=${NEW_VERSION_TAG}" >> $GITHUB_OUTPUT
- name: 💾 Commit and Tag
id: git_commit
if: steps.version_type.outputs.type != 'skip'
run: |
git config user.email ${{ secrets.CI_EMAIL }}
git config user.name ${{ secrets.CI_USER }}
git checkout main
git pull
git add .
git commit -m "[Automated] Bump version"
tag_name="CI/${{ steps.version.outputs.next_tag }}"
echo $tag_name
git tag -a $tag_name -m "nightly build"
- name: Push to protected main branch
uses: CasperWA/push-protected@v2.10.0
with:
token: ${{ secrets.YNPUT_BOT_TOKEN }}
branch: main
tags: true
unprotect_reviews: true
- name: 🔨 Merge main back to develop
uses: everlytic/branch-merge@1.1.0
if: steps.version_type.outputs.type != 'skip'
with:
github_token: ${{ secrets.YNPUT_BOT_TOKEN }}
source_ref: 'main'
target_branch: 'develop'
commit_message_template: '[Automated] Merged {source_ref} into {target_branch}'
- name: Invoke Update bug report workflow
uses: benc-uk/workflow-dispatch@v1
with:
workflow: update_bug_report.yml
token: ${{ secrets.YNPUT_BOT_TOKEN }}

View file

@ -1,66 +0,0 @@
# This workflow will upload a Python Package using Twine when a release is created
# For more information see: https://help.github.com/en/actions/language-and-framework-guides/using-python-with-github-actions#publishing-to-package-registries
name: 🏗️ Test Build
on:
pull_request:
branches: [develop]
types: [review_requested, ready_for_review]
paths-ignore:
- 'docs/**'
- 'website/**'
- 'vendor/**'
jobs:
Windows-latest:
runs-on: windows-latest
strategy:
matrix:
python-version: [3.9]
steps:
- name: 🚛 Checkout Code
uses: actions/checkout@v2
- name: Set up Python
uses: actions/setup-python@v2
with:
python-version: ${{ matrix.python-version }}
- name: 🧵 Install Requirements
shell: pwsh
run: |
./tools/create_env.ps1
- name: 🔨 Build
shell: pwsh
run: |
$env:SKIP_THIRD_PARTY_VALIDATION="1"
./tools/build.ps1
Ubuntu-latest:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: [3.9]
steps:
- name: 🚛 Checkout Code
uses: actions/checkout@v2
- name: Set up Python
uses: actions/setup-python@v2
with:
python-version: ${{ matrix.python-version }}
- name: 🧵 Install Requirements
run: |
./tools/create_env.sh
- name: 🔨 Build
run: |
export SKIP_THIRD_PARTY_VALIDATION="1"
./tools/build.sh

7
.gitmodules vendored
View file

@ -1,10 +1,3 @@
[submodule "tools/modules/powershell/BurntToast"]
path = tools/modules/powershell/BurntToast
url = https://github.com/Windos/BurntToast.git
[submodule "tools/modules/powershell/PSWriteColor"]
path = tools/modules/powershell/PSWriteColor
url = https://github.com/EvotecIT/PSWriteColor.git
[submodule "openpype/hosts/unreal/integration"]
path = openpype/hosts/unreal/integration
url = https://github.com/ynput/ayon-unreal-plugin.git

View file

@ -1,77 +0,0 @@
# Architecture
OpenPype is a monolithic Python project that bundles several parts, this document will try to give a birds eye overview of the project and, to a certain degree, each of the sub-projects.
The current file structure looks like this:
```
.
├── common - Code in this folder is backend portion of Addon distribution logic for v4 server.
├── docs - Documentation of the source code.
├── igniter - The OpenPype bootstrapper, deals with running version resolution and setting up the connection to the mongodb.
├── openpype - The actual OpenPype core package.
├── schema - Collection of JSON files describing schematics of objects. This follows Avalon's convention.
├── tests - Integration and unit tests.
├── tools - Conveninece scripts to perform common actions (in both bash and ps1).
├── vendor - When using the igniter, it deploys third party tools in here, such as ffmpeg.
└── website - Source files for https://openpype.io/ which is Docusaursus (https://docusaurus.io/).
```
The core functionality of the pipeline can be found in `igniter` and `openpype`, which in turn rely on the `schema` files, whenever you build (or download a pre-built) version of OpenPype, these two are bundled in there, and `Igniter` is the entry point.
## Igniter
It's the setup and update tool for OpenPype, unless you want to package `openpype` separately and deal with all the config manually, this will most likely be your entry point.
```
igniter/
├── bootstrap_repos.py - Module that will find or install OpenPype versions in the system.
├── __init__.py - Igniter entry point.
├── install_dialog.py- Show dialog for choosing central pype repository.
├── install_thread.py - Threading helpers for the install process.
├── __main__.py - Like `__init__.py` ?
├── message_dialog.py - Qt Dialog with a message and "Ok" button.
├── nice_progress_bar.py - Fancy Qt progress bar.
├── splash.txt - ASCII art for the terminal installer.
├── stylesheet.css - Installer Qt styles.
├── terminal_splash.py - Terminal installer animation, relies in `splash.txt`.
├── tools.py - Collection of methods that don't fit in other modules.
├── update_thread.py - Threading helper to update existing OpenPype installs.
├── update_window.py - Qt UI to update OpenPype installs.
├── user_settings.py - Interface for the OpenPype user settings.
└── version.py - Igniter's version number.
```
## OpenPype
This is the main package of the OpenPype logic, it could be loosely described as a combination of [Avalon](https://getavalon.github.io), [Pyblish](https://pyblish.com/) and glue around those with custom OpenPype only elements, things are in progress of being moved around to better prepare for V4, which will be released under a new name AYON.
```
openpype/
├── client - Interface for the MongoDB.
├── hooks - Hooks to be executed on certain OpenPype Applications defined in `openpype.lib.applications`.
├── host - Base class for the different hosts.
├── hosts - Integration with the different DCCs (hosts) using the `host` base class.
├── lib - Libraries that stitch together the package, some have been moved into other parts.
├── modules - OpenPype modules should contain separated logic of specific kind of implementation, such as Ftrack connection and its python API.
├── pipeline - Core of the OpenPype pipeline, handles creation of data, publishing, etc.
├── plugins - Global/core plugins for loader and publisher tool.
├── resources - Icons, fonts, etc.
├── scripts - Loose scipts that get run by tools/publishers.
├── settings - OpenPype settings interface.
├── style - Qt styling.
├── tests - Unit tests.
├── tools - Core tools, check out https://openpype.io/docs/artist_tools.
├── vendor - Vendoring of needed required Python packes.
├── widgets - Common re-usable Qt Widgets.
├── action.py - LEGACY: Lives now in `openpype.pipeline.publish.action` Pyblish actions.
├── cli.py - Command line interface, leverages `click`.
├── __init__.py - Sets two constants.
├── __main__.py - Entry point, calls the `cli.py`
├── plugin.py - Pyblish plugins.
├── pype_commands.py - Implementation of OpenPype commands.
└── version.py - Current version number.
```

18614
CHANGELOG.md

File diff suppressed because it is too large Load diff

View file

@ -1,82 +0,0 @@
# Build Pype docker image
FROM ubuntu:focal AS builder
ARG OPENPYPE_PYTHON_VERSION=3.9.12
ARG BUILD_DATE
ARG VERSION
LABEL maintainer="info@openpype.io"
LABEL description="Docker Image to build and run OpenPype under Ubuntu 20.04"
LABEL org.opencontainers.image.name="pypeclub/openpype"
LABEL org.opencontainers.image.title="OpenPype Docker Image"
LABEL org.opencontainers.image.url="https://openpype.io/"
LABEL org.opencontainers.image.source="https://github.com/pypeclub/OpenPype"
LABEL org.opencontainers.image.documentation="https://openpype.io/docs/system_introduction"
LABEL org.opencontainers.image.created=$BUILD_DATE
LABEL org.opencontainers.image.version=$VERSION
USER root
ARG DEBIAN_FRONTEND=noninteractive
# update base
RUN apt-get update \
&& apt-get install -y --no-install-recommends \
ca-certificates \
bash \
git \
cmake \
make \
curl \
wget \
build-essential \
checkinstall \
libssl-dev \
zlib1g-dev \
libbz2-dev \
libreadline-dev \
libsqlite3-dev \
llvm \
libncursesw5-dev \
xz-utils \
tk-dev \
libxml2-dev \
libxmlsec1-dev \
libffi-dev \
liblzma-dev \
patchelf
SHELL ["/bin/bash", "-c"]
RUN mkdir /opt/openpype
# download and install pyenv
RUN curl https://pyenv.run | bash \
&& echo 'export PATH="$HOME/.pyenv/bin:$PATH"'>> $HOME/init_pyenv.sh \
&& echo 'eval "$(pyenv init -)"' >> $HOME/init_pyenv.sh \
&& echo 'eval "$(pyenv virtualenv-init -)"' >> $HOME/init_pyenv.sh \
&& echo 'eval "$(pyenv init --path)"' >> $HOME/init_pyenv.sh
# install python with pyenv
RUN source $HOME/init_pyenv.sh \
&& pyenv install ${OPENPYPE_PYTHON_VERSION}
COPY . /opt/openpype/
RUN chmod +x /opt/openpype/tools/create_env.sh && chmod +x /opt/openpype/tools/build.sh
WORKDIR /opt/openpype
# set local python version
RUN cd /opt/openpype \
&& source $HOME/init_pyenv.sh \
&& pyenv local ${OPENPYPE_PYTHON_VERSION}
# fetch third party tools/libraries
RUN source $HOME/init_pyenv.sh \
&& ./tools/create_env.sh \
&& ./tools/fetch_thirdparty_libs.sh
# build openpype
RUN source $HOME/init_pyenv.sh \
&& bash ./tools/build.sh

View file

@ -1,118 +0,0 @@
# Build Pype docker image
FROM centos:7 AS builder
ARG OPENPYPE_PYTHON_VERSION=3.9.12
LABEL org.opencontainers.image.name="pypeclub/openpype"
LABEL org.opencontainers.image.title="OpenPype Docker Image"
LABEL org.opencontainers.image.url="https://openpype.io/"
LABEL org.opencontainers.image.source="https://github.com/pypeclub/pype"
LABEL org.opencontainers.image.documentation="https://openpype.io/docs/system_introduction"
LABEL org.opencontainers.image.created=$BUILD_DATE
LABEL org.opencontainers.image.version=$VERSION
USER root
# update base
RUN yum -y install deltarpm \
&& yum -y update \
&& yum clean all
# add tools we need
RUN yum -y install https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm \
&& yum -y install centos-release-scl \
&& yum -y install \
bash \
which \
git \
make \
devtoolset-7 \
cmake \
curl \
wget \
gcc \
zlib-devel \
pcre-devel \
perl-core \
bzip2 \
bzip2-devel \
readline-devel \
sqlite sqlite-devel \
openssl-devel \
openssl-libs \
openssl11-devel \
openssl11-libs \
tk-devel libffi-devel \
patchelf \
automake \
autoconf \
patch \
ncurses \
ncurses-devel \
qt5-qtbase-devel \
xcb-util-wm \
xcb-util-renderutil \
&& yum clean all
# we need to build our own patchelf
WORKDIR /temp-patchelf
RUN git clone -b 0.17.0 --single-branch https://github.com/NixOS/patchelf.git . \
&& source scl_source enable devtoolset-7 \
&& ./bootstrap.sh \
&& ./configure \
&& make \
&& make install
RUN mkdir /opt/openpype
# RUN useradd -m pype
# RUN chown pype /opt/openpype
# USER pype
RUN curl https://pyenv.run | bash
# ENV PYTHON_CONFIGURE_OPTS --enable-shared
RUN echo 'export PATH="$HOME/.pyenv/bin:$PATH"'>> $HOME/.bashrc \
&& echo 'eval "$(pyenv init -)"' >> $HOME/.bashrc \
&& echo 'eval "$(pyenv virtualenv-init -)"' >> $HOME/.bashrc \
&& echo 'eval "$(pyenv init --path)"' >> $HOME/.bashrc
RUN source $HOME/.bashrc \
&& export CPPFLAGS="-I/usr/include/openssl11" \
&& export LDFLAGS="-L/usr/lib64/openssl11 -lssl -lcrypto" \
&& export PATH=/usr/local/openssl/bin:$PATH \
&& export LD_LIBRARY_PATH=/usr/local/openssl/lib:$LD_LIBRARY_PATH \
&& pyenv install ${OPENPYPE_PYTHON_VERSION}
COPY . /opt/openpype/
RUN rm -rf /openpype/.poetry || echo "No Poetry installed yet."
# USER root
# RUN chown -R pype /opt/openpype
RUN chmod +x /opt/openpype/tools/create_env.sh && chmod +x /opt/openpype/tools/build.sh
# USER pype
WORKDIR /opt/openpype
RUN cd /opt/openpype \
&& source $HOME/.bashrc \
&& pyenv local ${OPENPYPE_PYTHON_VERSION}
RUN source $HOME/.bashrc \
&& ./tools/create_env.sh
RUN source $HOME/.bashrc \
&& ./tools/fetch_thirdparty_libs.sh
RUN echo 'export PYTHONPATH="/opt/openpype/vendor/python:$PYTHONPATH"'>> $HOME/.bashrc
RUN source $HOME/.bashrc \
&& bash ./tools/build.sh
RUN cp /usr/lib64/libffi* ./build/exe.linux-x86_64-3.9/lib \
&& cp /usr/lib64/openssl11/libssl* ./build/exe.linux-x86_64-3.9/lib \
&& cp /usr/lib64/openssl11/libcrypto* ./build/exe.linux-x86_64-3.9/lib \
&& ln -sr ./build/exe.linux-x86_64-3.9/lib/libssl.so ./build/exe.linux-x86_64-3.9/lib/libssl.1.1.so \
&& ln -sr ./build/exe.linux-x86_64-3.9/lib/libcrypto.so ./build/exe.linux-x86_64-3.9/lib/libcrypto.1.1.so \
&& cp /root/.pyenv/versions/${OPENPYPE_PYTHON_VERSION}/lib/libpython* ./build/exe.linux-x86_64-3.9/lib \
&& cp /usr/lib64/libxcb* ./build/exe.linux-x86_64-3.9/vendor/python/PySide2/Qt/lib
RUN cd /opt/openpype \
rm -rf ./vendor/bin

View file

@ -1,81 +0,0 @@
# Build Pype docker image
FROM debian:bullseye AS builder
ARG OPENPYPE_PYTHON_VERSION=3.9.12
ARG BUILD_DATE
ARG VERSION
LABEL maintainer="info@openpype.io"
LABEL description="Docker Image to build and run OpenPype under Ubuntu 20.04"
LABEL org.opencontainers.image.name="pypeclub/openpype"
LABEL org.opencontainers.image.title="OpenPype Docker Image"
LABEL org.opencontainers.image.url="https://openpype.io/"
LABEL org.opencontainers.image.source="https://github.com/pypeclub/OpenPype"
LABEL org.opencontainers.image.documentation="https://openpype.io/docs/system_introduction"
LABEL org.opencontainers.image.created=$BUILD_DATE
LABEL org.opencontainers.image.version=$VERSION
USER root
ARG DEBIAN_FRONTEND=noninteractive
# update base
RUN apt-get update \
&& apt-get install -y --no-install-recommends \
ca-certificates \
bash \
git \
cmake \
make \
curl \
wget \
build-essential \
libssl-dev \
zlib1g-dev \
libbz2-dev \
libreadline-dev \
libsqlite3-dev \
llvm \
libncursesw5-dev \
xz-utils \
tk-dev \
libxml2-dev \
libxmlsec1-dev \
libffi-dev \
liblzma-dev \
patchelf
SHELL ["/bin/bash", "-c"]
RUN mkdir /opt/openpype
# download and install pyenv
RUN curl https://pyenv.run | bash \
&& echo 'export PATH="$HOME/.pyenv/bin:$PATH"'>> $HOME/init_pyenv.sh \
&& echo 'eval "$(pyenv init -)"' >> $HOME/init_pyenv.sh \
&& echo 'eval "$(pyenv virtualenv-init -)"' >> $HOME/init_pyenv.sh \
&& echo 'eval "$(pyenv init --path)"' >> $HOME/init_pyenv.sh
# install python with pyenv
RUN source $HOME/init_pyenv.sh \
&& pyenv install ${OPENPYPE_PYTHON_VERSION}
COPY . /opt/openpype/
RUN chmod +x /opt/openpype/tools/create_env.sh && chmod +x /opt/openpype/tools/build.sh
WORKDIR /opt/openpype
# set local python version
RUN cd /opt/openpype \
&& source $HOME/init_pyenv.sh \
&& pyenv local ${OPENPYPE_PYTHON_VERSION}
# fetch third party tools/libraries
RUN source $HOME/init_pyenv.sh \
&& ./tools/create_env.sh \
&& ./tools/fetch_thirdparty_libs.sh
# build openpype
RUN source $HOME/init_pyenv.sh \
&& bash ./tools/build.sh

3808
HISTORY.md

File diff suppressed because it is too large Load diff

355
README.md
View file

@ -2,358 +2,5 @@
<!-- ALL-CONTRIBUTORS-BADGE:START - Do not remove or modify this section -->
[![All Contributors](https://img.shields.io/badge/all_contributors-28-orange.svg?style=flat-square)](#contributors-)
<!-- ALL-CONTRIBUTORS-BADGE:END -->
OpenPype
AYON-core
========
[![documentation](https://github.com/pypeclub/pype/actions/workflows/documentation.yml/badge.svg)](https://github.com/pypeclub/pype/actions/workflows/documentation.yml) ![GitHub VFX Platform](https://img.shields.io/badge/vfx%20platform-2022-lightgrey?labelColor=303846)
## Important Notice!
OpenPype as a standalone product has reach end of it's life and this repository is now used as a pipeline core code for [AYON](https://ynput.io/ayon/). You can read more details about the end of life process here https://community.ynput.io/t/openpype-end-of-life-timeline/877
Introduction
------------
Open-source pipeline for visual effects and animation built on top of the [Avalon](https://getavalon.github.io/) framework, expanding it with extra features and integrations. OpenPype connects your DCCs, asset database, project management and time tracking into a single system. It has a tight integration with [ftrack](https://www.ftrack.com/en/), but can also run independently or be integrated into a different project management solution.
OpenPype provides a robust platform for your studio, without the worry of a vendor lock. You will always have full access to the source-code and your project database will run locally or in the cloud of your choice.
To get all the information about the project, go to [OpenPype.io](http://openpype.io)
Requirements
------------
We aim to closely follow [**VFX Reference Platform**](https://vfxplatform.com/)
OpenPype is written in Python 3 with specific elements still running in Python2 until all DCCs are fully updated. To see the list of those, that are not quite there yet, go to [VFX Python3 tracker](https://vfxpy.com/)
The main things you will need to run and build OpenPype are:
- **Terminal** in your OS
- PowerShell 5.0+ (Windows)
- Bash (Linux)
- [**Python 3.9.6**](#python) or higher
- [**MongoDB**](#database) (needed only for local development)
It can be built and ran on all common platforms. We develop and test on the following:
- **Windows** 10
- **Linux**
- **Ubuntu** 20.04 LTS
- **Centos** 7
- **Mac OSX**
- **10.15** Catalina
- **11.1** Big Sur (using Rosetta2)
For more details on requirements visit [requirements documentation](https://openpype.io/docs/dev_requirements)
Building OpenPype
-----------------
To build OpenPype you currently need [Python 3.9](https://www.python.org/downloads/) as we are following
[vfx platform](https://vfxplatform.com). Because of some Linux distros comes with newer Python version
already, you need to install **3.9** version and make use of it. You can use perhaps [pyenv](https://github.com/pyenv/pyenv) for this on Linux.
**Note**: We do not support 3.9.0 because of [this bug](https://github.com/python/cpython/pull/22670). Please, use higher versions of 3.9.x.
### Windows
You will need [Python >= 3.9.1](https://www.python.org/downloads/) and [git](https://git-scm.com/downloads).
More tools might be needed for installing dependencies (for example for **OpenTimelineIO**) - mostly
development tools like [CMake](https://cmake.org/) and [Visual Studio](https://visualstudio.microsoft.com/cs/downloads/)
#### Clone repository:
```sh
git clone --recurse-submodules git@github.com:ynput/OpenPype.git
```
#### To build OpenPype:
1) Run `.\tools\create_env.ps1` to create virtual environment in `.\venv`.
2) Run `.\tools\fetch_thirdparty_libs.ps1` to download third-party dependencies like ffmpeg and oiio. Those will be included in build.
3) Run `.\tools\build.ps1` to build OpenPype executables in `.\build\`.
To create distributable OpenPype versions, run `./tools/create_zip.ps1` - that will
create zip file with name `openpype-vx.x.x.zip` parsed from current OpenPype repository and
copy it to user data dir, or you can specify `--path /path/to/zip` to force it there.
You can then point **Igniter** - OpenPype setup tool - to directory containing this zip and
it will install it on current computer.
OpenPype is build using [CX_Freeze](https://cx-freeze.readthedocs.io/en/latest) to freeze itself and all dependencies.
### macOS
You will need [Python >= 3.9](https://www.python.org/downloads/) and [git](https://git-scm.com/downloads). You'll need also other tools to build
some OpenPype dependencies like [CMake](https://cmake.org/) and **XCode Command Line Tools** (or some other build system).
Easy way of installing everything necessary is to use [Homebrew](https://brew.sh):
1) Install **Homebrew**:
```sh
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
```
2) Install **cmake**:
```sh
brew install cmake
```
3) Install [pyenv](https://github.com/pyenv/pyenv):
```sh
brew install pyenv
echo 'eval "$(pyenv init -)"' >> ~/.zshrc
pyenv init
exec "$SHELL"
PATH=$(pyenv root)/shims:$PATH
```
4) Pull in required Python version 3.9.x:
```sh
# install Python build dependences
brew install openssl readline sqlite3 xz zlib
# replace with up-to-date 3.9.x version
pyenv install 3.9.6
```
5) Set local Python version:
```sh
# switch to OpenPype source directory
pyenv local 3.9.6
```
#### To build OpenPype:
1) Run `.\tools\create_env.sh` to create virtual environment in `.\venv`
2) Run `.\tools\fetch_thirdparty_libs.sh` to download third-party dependencies like ffmpeg and oiio. Those will be included in build.
3) Run `.\tools\build.sh` to build OpenPype executables in `.\build\`
### Linux
#### Docker
Easiest way to build OpenPype on Linux is using [Docker](https://www.docker.com/). Just run:
```sh
sudo ./tools/docker_build.sh
```
This will by default use Debian as base image. If you need to make Centos 7 compatible build, please run:
```sh
sudo ./tools/docker_build.sh centos7
```
If all is successful, you'll find built OpenPype in `./build/` folder.
Docker build can be also started from Windows machine, just use `./tools/docker_build.ps1` instead of shell script.
This could be used even for building linux build (with argument `centos7` or `debian`)
#### Manual build
You will need [Python >= 3.9](https://www.python.org/downloads/) and [git](https://git-scm.com/downloads). You'll also need [curl](https://curl.se) on systems that doesn't have one preinstalled.
To build Python related stuff, you need Python header files installed (`python3-dev` on Ubuntu for example).
You'll need also other tools to build
some OpenPype dependencies like [CMake](https://cmake.org/). Python 3 should be part of all modern distributions. You can use your package manager to install **git** and **cmake**.
<details>
<summary>Details for Ubuntu</summary>
Install git, cmake and curl
```sh
sudo apt install build-essential checkinstall
sudo apt install git cmake curl
```
#### Note:
In case you run in error about `xcb` when running OpenPype,
you'll need also additional libraries for Qt5:
```sh
sudo apt install qt5-default
```
or if you are on Ubuntu > 20.04, there is no `qt5-default` packages so you need to install its content individually:
```sh
sudo apt-get install qtbase5-dev qtchooser qt5-qmake qtbase5-dev-tools
```
</details>
<details>
<summary>Details for Centos</summary>
Install git, cmake and curl
```sh
sudo yum install qit cmake
```
#### Note:
In case you run in error about `xcb` when running OpenPype,
you'll need also additional libraries for Qt5:
```sh
sudo yum install qt5-qtbase-devel
```
</details>
<details>
<summary>Use pyenv to install Python version for OpenPype build</summary>
You will need **bzip2**, **readline**, **sqlite3** and other libraries.
For more details about Python build environments see:
https://github.com/pyenv/pyenv/wiki#suggested-build-environment
**For Ubuntu:**
```sh
sudo apt-get update; sudo apt-get install --no-install-recommends make build-essential libssl-dev zlib1g-dev libbz2-dev libreadline-dev libsqlite3-dev wget curl llvm libncurses5-dev xz-utils tk-dev libxml2-dev libxmlsec1-dev libffi-dev liblzma-dev
```
**For Centos:**
```sh
yum install gcc zlib-devel bzip2 bzip2-devel readline-devel sqlite sqlite-devel openssl-devel tk-devel libffi-devel
```
**install pyenv**
```sh
curl https://pyenv.run | bash
# you can add those to ~/.bashrc
export PATH="$HOME/.pyenv/bin:$PATH"
eval "$(pyenv init -)"
eval "$(pyenv virtualenv-init -)"
# reload shell
exec $SHELL
# install Python 3.9.x
pyenv install -v 3.9.6
# change path to OpenPype 3
cd /path/to/openpype-3
# set local python version
pyenv local 3.9.6
```
</details>
#### To build OpenPype:
1) Run `.\tools\create_env.sh` to create virtual environment in `.\venv`
2) Run `.\tools\build.sh` to build OpenPype executables in `.\build\`
Running OpenPype
----------------
OpenPype can by executed either from live sources (this repository) or from
*"frozen code"* - executables that can be build using steps described above.
If OpenPype is executed from live sources, it will use OpenPype version included in them. If
it is executed from frozen code it will try to find latest OpenPype version installed locally
on current computer and if it is not found, it will ask for its location. On that location
OpenPype can be either in directories or zip files. OpenPype will try to find latest version and
install it to user data directory (on Windows to `%LOCALAPPDATA%\pypeclub\openpype`, on Linux
`~/.local/share/openpype` and on macOS in `~/Library/Application Support/openpype`).
### From sources
OpenPype can be run directly from sources by activating virtual environment:
```sh
poetry run python start.py tray
```
This will use current OpenPype version with sources. You can override this with `--use-version=x.x.x` and
then OpenPype will try to find locally installed specified version (present in user data directory).
### From frozen code
You need to build OpenPype first. This will produce two executables - `openpype_gui(.exe)` and `openpype_console(.exe)`.
First one will act as GUI application and will not create console (useful in production environments).
The second one will create console and will write output there - useful for headless application and
debugging purposes. If you need OpenPype version installed, just run `./tools/create_zip(.ps1|.sh)` without
arguments and it will create zip file that OpenPype can use.
Building documentation
----------------------
To build API documentation, run `.\tools\make_docs(.ps1|.sh)`. It will create html documentation
from current sources in `.\docs\build`.
**Note that it needs existing virtual environment.**
Running tests
-------------
To run tests, execute `.\tools\run_tests(.ps1|.sh)`.
**Note that it needs existing virtual environment.**
Developer tools
---------------
In case you wish to add your own tools to `.\tools` folder without git tracking, it is possible by adding it with `dev_*` suffix (example: `dev_clear_pyc(.ps1|.sh)`).
## Contributors ✨
Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/docs/en/emoji-key)):
<!-- ALL-CONTRIBUTORS-LIST:START - Do not remove or modify this section -->
<!-- prettier-ignore-start -->
<!-- markdownlint-disable -->
<table>
<tbody>
<tr>
<td align="center" valign="top" width="14.28%"><a href="http://pype.club/"><img src="https://avatars.githubusercontent.com/u/3333008?v=4?s=100" width="100px;" alt="Milan Kolar"/><br /><sub><b>Milan Kolar</b></sub></a><br /><a href="https://github.com/ynput/OpenPype/commits?author=mkolar" title="Code">💻</a> <a href="https://github.com/ynput/OpenPype/commits?author=mkolar" title="Documentation">📖</a> <a href="#infra-mkolar" title="Infrastructure (Hosting, Build-Tools, etc)">🚇</a> <a href="#business-mkolar" title="Business development">💼</a> <a href="#content-mkolar" title="Content">🖋</a> <a href="#fundingFinding-mkolar" title="Funding Finding">🔍</a> <a href="#maintenance-mkolar" title="Maintenance">🚧</a> <a href="#projectManagement-mkolar" title="Project Management">📆</a> <a href="https://github.com/ynput/OpenPype/pulls?q=is%3Apr+reviewed-by%3Amkolar" title="Reviewed Pull Requests">👀</a> <a href="#mentoring-mkolar" title="Mentoring">🧑‍🏫</a> <a href="#question-mkolar" title="Answering Questions">💬</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://www.linkedin.com/in/jakubjezek79"><img src="https://avatars.githubusercontent.com/u/40640033?v=4?s=100" width="100px;" alt="Jakub Ježek"/><br /><sub><b>Jakub Ježek</b></sub></a><br /><a href="https://github.com/ynput/OpenPype/commits?author=jakubjezek001" title="Code">💻</a> <a href="https://github.com/ynput/OpenPype/commits?author=jakubjezek001" title="Documentation">📖</a> <a href="#infra-jakubjezek001" title="Infrastructure (Hosting, Build-Tools, etc)">🚇</a> <a href="#content-jakubjezek001" title="Content">🖋</a> <a href="https://github.com/ynput/OpenPype/pulls?q=is%3Apr+reviewed-by%3Ajakubjezek001" title="Reviewed Pull Requests">👀</a> <a href="#maintenance-jakubjezek001" title="Maintenance">🚧</a> <a href="#mentoring-jakubjezek001" title="Mentoring">🧑‍🏫</a> <a href="#projectManagement-jakubjezek001" title="Project Management">📆</a> <a href="#question-jakubjezek001" title="Answering Questions">💬</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/antirotor"><img src="https://avatars.githubusercontent.com/u/33513211?v=4?s=100" width="100px;" alt="Ondřej Samohel"/><br /><sub><b>Ondřej Samohel</b></sub></a><br /><a href="https://github.com/ynput/OpenPype/commits?author=antirotor" title="Code">💻</a> <a href="https://github.com/ynput/OpenPype/commits?author=antirotor" title="Documentation">📖</a> <a href="#infra-antirotor" title="Infrastructure (Hosting, Build-Tools, etc)">🚇</a> <a href="#content-antirotor" title="Content">🖋</a> <a href="https://github.com/ynput/OpenPype/pulls?q=is%3Apr+reviewed-by%3Aantirotor" title="Reviewed Pull Requests">👀</a> <a href="#maintenance-antirotor" title="Maintenance">🚧</a> <a href="#mentoring-antirotor" title="Mentoring">🧑‍🏫</a> <a href="#projectManagement-antirotor" title="Project Management">📆</a> <a href="#question-antirotor" title="Answering Questions">💬</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/iLLiCiTiT"><img src="https://avatars.githubusercontent.com/u/43494761?v=4?s=100" width="100px;" alt="Jakub Trllo"/><br /><sub><b>Jakub Trllo</b></sub></a><br /><a href="https://github.com/ynput/OpenPype/commits?author=iLLiCiTiT" title="Code">💻</a> <a href="https://github.com/ynput/OpenPype/commits?author=iLLiCiTiT" title="Documentation">📖</a> <a href="#infra-iLLiCiTiT" title="Infrastructure (Hosting, Build-Tools, etc)">🚇</a> <a href="https://github.com/ynput/OpenPype/pulls?q=is%3Apr+reviewed-by%3AiLLiCiTiT" title="Reviewed Pull Requests">👀</a> <a href="#maintenance-iLLiCiTiT" title="Maintenance">🚧</a> <a href="#question-iLLiCiTiT" title="Answering Questions">💬</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/kalisp"><img src="https://avatars.githubusercontent.com/u/4457962?v=4?s=100" width="100px;" alt="Petr Kalis"/><br /><sub><b>Petr Kalis</b></sub></a><br /><a href="https://github.com/ynput/OpenPype/commits?author=kalisp" title="Code">💻</a> <a href="https://github.com/ynput/OpenPype/commits?author=kalisp" title="Documentation">📖</a> <a href="#infra-kalisp" title="Infrastructure (Hosting, Build-Tools, etc)">🚇</a> <a href="https://github.com/ynput/OpenPype/pulls?q=is%3Apr+reviewed-by%3Akalisp" title="Reviewed Pull Requests">👀</a> <a href="#maintenance-kalisp" title="Maintenance">🚧</a> <a href="#question-kalisp" title="Answering Questions">💬</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/64qam"><img src="https://avatars.githubusercontent.com/u/26925793?v=4?s=100" width="100px;" alt="64qam"/><br /><sub><b>64qam</b></sub></a><br /><a href="https://github.com/ynput/OpenPype/commits?author=64qam" title="Code">💻</a> <a href="https://github.com/ynput/OpenPype/pulls?q=is%3Apr+reviewed-by%3A64qam" title="Reviewed Pull Requests">👀</a> <a href="https://github.com/ynput/OpenPype/commits?author=64qam" title="Documentation">📖</a> <a href="#infra-64qam" title="Infrastructure (Hosting, Build-Tools, etc)">🚇</a> <a href="#projectManagement-64qam" title="Project Management">📆</a> <a href="#maintenance-64qam" title="Maintenance">🚧</a> <a href="#content-64qam" title="Content">🖋</a> <a href="#userTesting-64qam" title="User Testing">📓</a></td>
<td align="center" valign="top" width="14.28%"><a href="http://www.colorbleed.nl/"><img src="https://avatars.githubusercontent.com/u/2439881?v=4?s=100" width="100px;" alt="Roy Nieterau"/><br /><sub><b>Roy Nieterau</b></sub></a><br /><a href="https://github.com/ynput/OpenPype/commits?author=BigRoy" title="Code">💻</a> <a href="https://github.com/ynput/OpenPype/commits?author=BigRoy" title="Documentation">📖</a> <a href="https://github.com/ynput/OpenPype/pulls?q=is%3Apr+reviewed-by%3ABigRoy" title="Reviewed Pull Requests">👀</a> <a href="#mentoring-BigRoy" title="Mentoring">🧑‍🏫</a> <a href="#question-BigRoy" title="Answering Questions">💬</a></td>
</tr>
<tr>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/tokejepsen"><img src="https://avatars.githubusercontent.com/u/1860085?v=4?s=100" width="100px;" alt="Toke Jepsen"/><br /><sub><b>Toke Jepsen</b></sub></a><br /><a href="https://github.com/ynput/OpenPype/commits?author=tokejepsen" title="Code">💻</a> <a href="https://github.com/ynput/OpenPype/commits?author=tokejepsen" title="Documentation">📖</a> <a href="https://github.com/ynput/OpenPype/pulls?q=is%3Apr+reviewed-by%3Atokejepsen" title="Reviewed Pull Requests">👀</a> <a href="#mentoring-tokejepsen" title="Mentoring">🧑‍🏫</a> <a href="#question-tokejepsen" title="Answering Questions">💬</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/jrsndl"><img src="https://avatars.githubusercontent.com/u/45896205?v=4?s=100" width="100px;" alt="Jiri Sindelar"/><br /><sub><b>Jiri Sindelar</b></sub></a><br /><a href="https://github.com/ynput/OpenPype/commits?author=jrsndl" title="Code">💻</a> <a href="https://github.com/ynput/OpenPype/pulls?q=is%3Apr+reviewed-by%3Ajrsndl" title="Reviewed Pull Requests">👀</a> <a href="https://github.com/ynput/OpenPype/commits?author=jrsndl" title="Documentation">📖</a> <a href="#content-jrsndl" title="Content">🖋</a> <a href="#tutorial-jrsndl" title="Tutorials"></a> <a href="#userTesting-jrsndl" title="User Testing">📓</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://barbierisimone.com/"><img src="https://avatars.githubusercontent.com/u/1087869?v=4?s=100" width="100px;" alt="Simone Barbieri"/><br /><sub><b>Simone Barbieri</b></sub></a><br /><a href="https://github.com/ynput/OpenPype/commits?author=simonebarbieri" title="Code">💻</a> <a href="https://github.com/ynput/OpenPype/commits?author=simonebarbieri" title="Documentation">📖</a></td>
<td align="center" valign="top" width="14.28%"><a href="http://karimmozilla.xyz/"><img src="https://avatars.githubusercontent.com/u/82811760?v=4?s=100" width="100px;" alt="karimmozilla"/><br /><sub><b>karimmozilla</b></sub></a><br /><a href="https://github.com/ynput/OpenPype/commits?author=karimmozilla" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Allan-I"><img src="https://avatars.githubusercontent.com/u/76656700?v=4?s=100" width="100px;" alt="Allan I. A."/><br /><sub><b>Allan I. A.</b></sub></a><br /><a href="https://github.com/ynput/OpenPype/commits?author=Allan-I" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://www.linkedin.com/in/mmuurrpphhyy/"><img src="https://avatars.githubusercontent.com/u/352795?v=4?s=100" width="100px;" alt="murphy"/><br /><sub><b>murphy</b></sub></a><br /><a href="https://github.com/ynput/OpenPype/commits?author=m-u-r-p-h-y" title="Code">💻</a> <a href="https://github.com/ynput/OpenPype/pulls?q=is%3Apr+reviewed-by%3Am-u-r-p-h-y" title="Reviewed Pull Requests">👀</a> <a href="#userTesting-m-u-r-p-h-y" title="User Testing">📓</a> <a href="https://github.com/ynput/OpenPype/commits?author=m-u-r-p-h-y" title="Documentation">📖</a> <a href="#projectManagement-m-u-r-p-h-y" title="Project Management">📆</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/aardschok"><img src="https://avatars.githubusercontent.com/u/26920875?v=4?s=100" width="100px;" alt="Wijnand Koreman"/><br /><sub><b>Wijnand Koreman</b></sub></a><br /><a href="https://github.com/ynput/OpenPype/commits?author=aardschok" title="Code">💻</a></td>
</tr>
<tr>
<td align="center" valign="top" width="14.28%"><a href="http://jedimaster.cnblogs.com/"><img src="https://avatars.githubusercontent.com/u/1798206?v=4?s=100" width="100px;" alt="Bo Zhou"/><br /><sub><b>Bo Zhou</b></sub></a><br /><a href="https://github.com/ynput/OpenPype/commits?author=zhoub" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://www.linkedin.com/in/clementhector/"><img src="https://avatars.githubusercontent.com/u/7068597?v=4?s=100" width="100px;" alt="Clément Hector"/><br /><sub><b>Clément Hector</b></sub></a><br /><a href="https://github.com/ynput/OpenPype/commits?author=ClementHector" title="Code">💻</a> <a href="https://github.com/ynput/OpenPype/pulls?q=is%3Apr+reviewed-by%3AClementHector" title="Reviewed Pull Requests">👀</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://twitter.com/davidlatwe"><img src="https://avatars.githubusercontent.com/u/3357009?v=4?s=100" width="100px;" alt="David Lai"/><br /><sub><b>David Lai</b></sub></a><br /><a href="https://github.com/ynput/OpenPype/commits?author=davidlatwe" title="Code">💻</a> <a href="https://github.com/ynput/OpenPype/pulls?q=is%3Apr+reviewed-by%3Adavidlatwe" title="Reviewed Pull Requests">👀</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/2-REC"><img src="https://avatars.githubusercontent.com/u/42170307?v=4?s=100" width="100px;" alt="Derek "/><br /><sub><b>Derek </b></sub></a><br /><a href="https://github.com/ynput/OpenPype/commits?author=2-REC" title="Code">💻</a> <a href="https://github.com/ynput/OpenPype/commits?author=2-REC" title="Documentation">📖</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/gabormarinov"><img src="https://avatars.githubusercontent.com/u/8620515?v=4?s=100" width="100px;" alt="Gábor Marinov"/><br /><sub><b>Gábor Marinov</b></sub></a><br /><a href="https://github.com/ynput/OpenPype/commits?author=gabormarinov" title="Code">💻</a> <a href="https://github.com/ynput/OpenPype/commits?author=gabormarinov" title="Documentation">📖</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/icyvapor"><img src="https://avatars.githubusercontent.com/u/1195278?v=4?s=100" width="100px;" alt="icyvapor"/><br /><sub><b>icyvapor</b></sub></a><br /><a href="https://github.com/ynput/OpenPype/commits?author=icyvapor" title="Code">💻</a> <a href="https://github.com/ynput/OpenPype/commits?author=icyvapor" title="Documentation">📖</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/jlorrain"><img src="https://avatars.githubusercontent.com/u/7955673?v=4?s=100" width="100px;" alt="Jérôme LORRAIN"/><br /><sub><b>Jérôme LORRAIN</b></sub></a><br /><a href="https://github.com/ynput/OpenPype/commits?author=jlorrain" title="Code">💻</a></td>
</tr>
<tr>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/dmo-j-cube"><img src="https://avatars.githubusercontent.com/u/89823400?v=4?s=100" width="100px;" alt="David Morris-Oliveros"/><br /><sub><b>David Morris-Oliveros</b></sub></a><br /><a href="https://github.com/ynput/OpenPype/commits?author=dmo-j-cube" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/BenoitConnan"><img src="https://avatars.githubusercontent.com/u/82808268?v=4?s=100" width="100px;" alt="BenoitConnan"/><br /><sub><b>BenoitConnan</b></sub></a><br /><a href="https://github.com/ynput/OpenPype/commits?author=BenoitConnan" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Malthaldar"><img src="https://avatars.githubusercontent.com/u/33671694?v=4?s=100" width="100px;" alt="Malthaldar"/><br /><sub><b>Malthaldar</b></sub></a><br /><a href="https://github.com/ynput/OpenPype/commits?author=Malthaldar" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="http://www.svenneve.com/"><img src="https://avatars.githubusercontent.com/u/2472863?v=4?s=100" width="100px;" alt="Sven Neve"/><br /><sub><b>Sven Neve</b></sub></a><br /><a href="https://github.com/ynput/OpenPype/commits?author=svenneve" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/zafrs"><img src="https://avatars.githubusercontent.com/u/26890002?v=4?s=100" width="100px;" alt="zafrs"/><br /><sub><b>zafrs</b></sub></a><br /><a href="https://github.com/ynput/OpenPype/commits?author=zafrs" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="http://felixdavid.com/"><img src="https://avatars.githubusercontent.com/u/22875539?v=4?s=100" width="100px;" alt="Félix David"/><br /><sub><b>Félix David</b></sub></a><br /><a href="https://github.com/ynput/OpenPype/commits?author=Tilix4" title="Code">💻</a> <a href="https://github.com/ynput/OpenPype/commits?author=Tilix4" title="Documentation">📖</a></td>
<td align="center" valign="top" width="14.28%"><a href="http://abogomolov.com"><img src="https://avatars.githubusercontent.com/u/11698866?v=4?s=100" width="100px;" alt="Alexey Bogomolov"/><br /><sub><b>Alexey Bogomolov</b></sub></a><br /><a href="https://github.com/ynput/OpenPype/commits?author=movalex" title="Code">💻</a></td>
</tr>
</tbody>
</table>
<!-- markdownlint-restore -->
<!-- prettier-ignore-end -->
<!-- ALL-CONTRIBUTORS-LIST:END -->
This project follows the [all-contributors](https://github.com/all-contributors/all-contributors) specification. Contributions of any kind welcome!

View file

@ -1,49 +0,0 @@
"""Launch process that is not child process of python or OpenPype.
This is written for linux distributions where process tree may affect what
is when closed or blocked to be closed.
"""
import os
import sys
import subprocess
import json
def main(input_json_path):
"""Read launch arguments from json file and launch the process.
Expected that json contains "args" key with string or list of strings.
Arguments are converted to string using `list2cmdline`. At the end is added
`&` which will cause that launched process is detached and running as
"background" process.
## Notes
@iLLiCiT: This should be possible to do with 'disown' or double forking but
I didn't find a way how to do it properly. Disown didn't work as
expected for me and double forking killed parent process which is
unexpected too.
"""
with open(input_json_path, "r") as stream:
data = json.load(stream)
# Change environment variables
env = data.get("env") or {}
for key, value in env.items():
os.environ[key] = value
# Prepare launch arguments
args = data["args"]
if isinstance(args, list):
args = subprocess.list2cmdline(args)
# Run the command as background process
shell_cmd = args + " &"
os.system(shell_cmd)
sys.exit(0)
if __name__ == "__main__":
# Expect that last argument is path to a json with launch args information
main(sys.argv[-1])

View file

@ -1,3 +0,0 @@
# -*- coding: utf-8 -*-
"""Conftest."""
...

View file

@ -1,19 +0,0 @@
# Minimal makefile for Sphinx documentation
#
# You can set these variables from the command line.
SPHINXOPTS =
SPHINXBUILD = sphinx-build
SOURCEDIR = source
BUILDDIR = build
# Put it first so that "make" without argument is like "make help".
help:
@$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
.PHONY: help Makefile
# Catch-all target: route all unknown targets to Sphinx using the new
# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS).
%: Makefile
@$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)

View file

@ -1,74 +0,0 @@
API Documentation
=================
This documents the way how to build and modify API documentation using Sphinx and AutoAPI. Ground for documentation
should be directly in sources - in docstrings and markdowns. Sphinx and AutoAPI will crawl over them and generate
RST files that are in turn used to generate HTML documentation. For docstrings we prefer "Napoleon" or "Google" style
docstrings, but RST is also acceptable mainly in cases where you need to use Sphinx directives.
Using only docstrings is not really viable as some documentation should be done on higher level - like overview of
some modules/functionality and so on. This should be done directly in RST files and committed to repository.
Configuration
-------------
Configuration is done in `/docs/source/conf.py`. The most important settings are:
- `autodoc_mock_imports`: add modules that can't be actually imported by Sphinx in running environment, like `nuke`, `maya`, etc.
- `autoapi_ignore`: add directories that shouldn't be processed by **AutoAPI**, like vendor dirs, etc.
- `html_theme_options`: you can use these options to influence how the html theme of the generated files will look.
- `myst_gfm_only`: are Myst parser option for Markdown setting what flavour of Markdown should be used.
How to build it
---------------
You can run:
```sh
cd .\docs
make.bat html
```
on linux/macOS:
```sh
cd ./docs
make html
```
This will go over our code and generate **.rst** files in `/docs/source/autoapi` and from those it will generate
full html documentation in `/docs/build/html`.
During the build you may see tons of red errors that are pointing to our issues:
1) **Wrong imports** -
Invalid import are usually wrong relative imports (too deep) or circular imports.
2) **Invalid docstrings** -
Docstrings to be processed into documentation needs to follow some syntax - this can be checked by running
`pydocstyle` that is already included with OpenPype
3) **Invalid markdown/rst files** -
Markdown/RST files can be included inside RST files using `.. include::` directive. But they have to be properly
formatted.
Editing RST templates
---------------------
Everything starts with `/docs/source/index.rst` - this file should be properly edited, Right now it just
includes `readme.rst` that in turn include and parse main `README.md`. This is entrypoint to API documentation.
All templates generated by AutoAPI are in `/docs/source/autoapi`. They should be eventually committed to repository
and edited too.
Steps for enhancing API documentation
-------------------------------------
1) Run `/docs/make.bat html`
2) Read the red errors/warnings - fix it in the code
3) Run `/docs/make.bat html` - again until there are no red lines
4) Edit RST files and add some meaningful content there
Resources
=========
- [ReStructuredText on Wikipedia](https://en.wikipedia.org/wiki/ReStructuredText)
- [RST Quick Reference](https://docutils.sourceforge.io/docs/user/rst/quickref.html)
- [Sphinx AutoAPI Documentation](https://sphinx-autoapi.readthedocs.io/en/latest/)
- [Example of Google Style Python Docstrings](https://sphinxcontrib-napoleon.readthedocs.io/en/latest/example_google.html)
- [Sphinx Directives](https://www.sphinx-doc.org/en/master/usage/restructuredtext/directives.html)

View file

@ -1,35 +0,0 @@
@ECHO OFF
pushd %~dp0
REM Command file for Sphinx documentation
if "%SPHINXBUILD%" == "" (
set SPHINXBUILD=..\.poetry\bin\poetry run sphinx-build
)
set SOURCEDIR=source
set BUILDDIR=build
if "%1" == "" goto help
%SPHINXBUILD% >NUL 2>NUL
if errorlevel 9009 (
echo.
echo.The 'sphinx-build' command was not found. Make sure you have Sphinx
echo.installed, then set the SPHINXBUILD environment variable to point
echo.to the full path of the 'sphinx-build' executable. Alternatively you
echo.may add the Sphinx directory to PATH.
echo.
echo.If you don't have Sphinx installed, grab it from
echo.http://sphinx-doc.org/
exit /b 1
)
%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS%
goto end
:help
%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS%
:end
popd

View file

@ -1,38 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg width="100%" height="100%" viewBox="0 0 1801 501" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:2;">
<g transform="matrix(1,0,0,1,-13243,-17814)">
<g id="AYON_tight_G" transform="matrix(0.736439,0,0,0.560717,-6190.22,8134.09)">
<rect x="26388.3" y="17264.3" width="2444.2" height="891.715" style="fill:none;"/>
<g id="AYON_logo" transform="matrix(5.32251,0,0,6.99052,25370,15936.6)">
<g transform="matrix(1,0,0,1,471.969,279.213)">
<path d="M0,-34.016C9.378,-34.016 17.008,-26.386 17.008,-17.008C17.008,-7.63 9.378,0 0,0C-9.378,0 -17.008,-7.63 -17.008,-17.008C-17.008,-26.386 -9.378,-34.016 0,-34.016M0,-68.032C-28.18,-68.032 -51.024,-45.188 -51.024,-17.008C-51.024,11.172 -28.18,34.016 0,34.016C28.18,34.016 51.024,11.172 51.024,-17.008C51.024,-45.188 28.18,-68.032 0,-68.032" style="fill:rgb(0,214,161);fill-rule:nonzero;"/>
</g>
<g transform="matrix(1,0,0,1,293.386,211.343)">
<path d="M0,101.886C-4.696,101.886 -8.504,98.078 -8.504,93.382L-8.504,28.874L-79.027,99.395C-82.349,102.716 -87.73,102.716 -91.052,99.395C-94.374,96.075 -94.374,90.689 -91.052,87.369L-6.012,2.33C-3.583,-0.103 0.071,-0.83 3.255,0.487C6.432,1.803 8.504,4.902 8.504,8.343L8.504,93.382C8.504,98.078 4.696,101.886 0,101.886" style="fill:rgb(0,214,161);fill-rule:nonzero;"/>
</g>
<g transform="matrix(1,0,0,1,548.504,211.343)">
<path d="M0,101.886C-4.696,101.886 -8.504,98.078 -8.504,93.382L-8.504,8.343C-8.504,4.902 -6.432,1.803 -3.255,0.487C-0.075,-0.83 3.579,-0.103 6.013,2.33L91.052,87.369C94.374,90.689 94.374,96.075 91.052,99.395C87.73,102.716 82.349,102.716 79.027,99.395L8.504,28.874L8.504,93.382C8.504,98.078 4.696,101.886 0,101.886" style="fill:rgb(0,214,161);fill-rule:nonzero;"/>
</g>
<g transform="matrix(1,0,0,1,633.543,211.181)">
<path d="M0,68.032C-4.696,68.032 -8.504,64.224 -8.504,59.528L-8.504,8.504C-8.504,3.808 -4.696,0 0,0C4.696,0 8.504,3.808 8.504,8.504L8.504,59.528C8.504,64.224 4.696,68.032 0,68.032" style="fill:rgb(0,214,161);fill-rule:nonzero;"/>
</g>
<g transform="matrix(-1,0,0,1,654.804,-155.906)">
<rect x="318.898" y="367.087" width="17.008" height="17.008" style="fill:rgb(0,214,161);"/>
</g>
<g transform="matrix(-1,0,0,1,688.82,-121.89)">
<rect x="335.906" y="350.079" width="17.008" height="17.008" style="fill:rgb(0,214,161);"/>
</g>
<g transform="matrix(0,-1,-1,0,361.417,270.709)">
<path d="M-8.504,-8.504C-13.2,-8.504 -17.008,-4.697 -17.008,0C-17.008,4.697 -13.2,8.504 -8.504,8.504C-3.807,8.504 0,4.697 0,0C0,-4.697 -3.807,-8.504 -8.504,-8.504" style="fill:rgb(0,214,161);fill-rule:nonzero;"/>
</g>
<g transform="matrix(0,-1,-1,0,361.417,296.221)">
<path d="M-8.504,-8.504C-13.201,-8.504 -17.008,-4.697 -17.008,0C-17.008,4.697 -13.201,8.504 -8.504,8.504C-3.807,8.504 0,4.697 0,0C0,-4.697 -3.807,-8.504 -8.504,-8.504" style="fill:rgb(0,214,161);fill-rule:nonzero;"/>
</g>
<g transform="matrix(1,0,0,1,403.937,262.205)">
<path d="M0,-68.031L-51.023,-17.008L-51.023,0L-34.016,0L17.008,-51.023L17.008,-68.031L0,-68.031Z" style="fill:rgb(0,214,161);fill-rule:nonzero;"/>
</g>
</g>
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 3.8 KiB

View file

@ -1,15 +0,0 @@
API Reference
=============
This page contains auto-generated API reference documentation [#f1]_.
.. toctree::
:titlesonly:
{% for page in pages %}
{% if page.top_level_object and page.display %}
{{ page.include_path }}
{% endif %}
{% endfor %}
.. [#f1] Created with `sphinx-autoapi <https://github.com/readthedocs/sphinx-autoapi>`_

View file

@ -1 +0,0 @@
{% extends "python/data.rst" %}

View file

@ -1,58 +0,0 @@
{% if obj.display %}
.. py:{{ obj.type }}:: {{ obj.short_name }}{% if obj.args %}({{ obj.args }}){% endif %}
{% for (args, return_annotation) in obj.overloads %}
{{ " " * (obj.type | length) }} {{ obj.short_name }}{% if args %}({{ args }}){% endif %}
{% endfor %}
{% if obj.bases %}
{% if "show-inheritance" in autoapi_options %}
Bases: {% for base in obj.bases %}{{ base|link_objs }}{% if not loop.last %}, {% endif %}{% endfor %}
{% endif %}
{% if "show-inheritance-diagram" in autoapi_options and obj.bases != ["object"] %}
.. autoapi-inheritance-diagram:: {{ obj.obj["full_name"] }}
:parts: 1
{% if "private-members" in autoapi_options %}
:private-bases:
{% endif %}
{% endif %}
{% endif %}
{% if obj.docstring %}
{{ obj.docstring|indent(3) }}
{% endif %}
{% if "inherited-members" in autoapi_options %}
{% set visible_classes = obj.classes|selectattr("display")|list %}
{% else %}
{% set visible_classes = obj.classes|rejectattr("inherited")|selectattr("display")|list %}
{% endif %}
{% for klass in visible_classes %}
{{ klass.render()|indent(3) }}
{% endfor %}
{% if "inherited-members" in autoapi_options %}
{% set visible_properties = obj.properties|selectattr("display")|list %}
{% else %}
{% set visible_properties = obj.properties|rejectattr("inherited")|selectattr("display")|list %}
{% endif %}
{% for property in visible_properties %}
{{ property.render()|indent(3) }}
{% endfor %}
{% if "inherited-members" in autoapi_options %}
{% set visible_attributes = obj.attributes|selectattr("display")|list %}
{% else %}
{% set visible_attributes = obj.attributes|rejectattr("inherited")|selectattr("display")|list %}
{% endif %}
{% for attribute in visible_attributes %}
{{ attribute.render()|indent(3) }}
{% endfor %}
{% if "inherited-members" in autoapi_options %}
{% set visible_methods = obj.methods|selectattr("display")|list %}
{% else %}
{% set visible_methods = obj.methods|rejectattr("inherited")|selectattr("display")|list %}
{% endif %}
{% for method in visible_methods %}
{{ method.render()|indent(3) }}
{% endfor %}
{% endif %}

View file

@ -1,37 +0,0 @@
{% if obj.display %}
.. py:{{ obj.type }}:: {{ obj.name }}
{%- if obj.annotation is not none %}
:type: {%- if obj.annotation %} {{ obj.annotation }}{%- endif %}
{%- endif %}
{%- if obj.value is not none %}
:value: {% if obj.value is string and obj.value.splitlines()|count > 1 -%}
Multiline-String
.. raw:: html
<details><summary>Show Value</summary>
.. code-block:: python
"""{{ obj.value|indent(width=8,blank=true) }}"""
.. raw:: html
</details>
{%- else -%}
{%- if obj.value is string -%}
{{ "%r" % obj.value|string|truncate(100) }}
{%- else -%}
{{ obj.value|string|truncate(100) }}
{%- endif -%}
{%- endif %}
{%- endif %}
{{ obj.docstring|indent(3) }}
{% endif %}

View file

@ -1 +0,0 @@
{% extends "python/class.rst" %}

View file

@ -1,15 +0,0 @@
{% if obj.display %}
.. py:function:: {{ obj.short_name }}({{ obj.args }}){% if obj.return_annotation is not none %} -> {{ obj.return_annotation }}{% endif %}
{% for (args, return_annotation) in obj.overloads %}
{{ obj.short_name }}({{ args }}){% if return_annotation is not none %} -> {{ return_annotation }}{% endif %}
{% endfor %}
{% for property in obj.properties %}
:{{ property }}:
{% endfor %}
{% if obj.docstring %}
{{ obj.docstring|indent(3) }}
{% endif %}
{% endif %}

View file

@ -1,19 +0,0 @@
{%- if obj.display %}
.. py:method:: {{ obj.short_name }}({{ obj.args }}){% if obj.return_annotation is not none %} -> {{ obj.return_annotation }}{% endif %}
{% for (args, return_annotation) in obj.overloads %}
{{ obj.short_name }}({{ args }}){% if return_annotation is not none %} -> {{ return_annotation }}{% endif %}
{% endfor %}
{% if obj.properties %}
{% for property in obj.properties %}
:{{ property }}:
{% endfor %}
{% else %}
{% endif %}
{% if obj.docstring %}
{{ obj.docstring|indent(3) }}
{% endif %}
{% endif %}

View file

@ -1,114 +0,0 @@
{% if not obj.display %}
:orphan:
{% endif %}
:py:mod:`{{ obj.name }}`
=========={{ "=" * obj.name|length }}
.. py:module:: {{ obj.name }}
{% if obj.docstring %}
.. autoapi-nested-parse::
{{ obj.docstring|indent(3) }}
{% endif %}
{% block subpackages %}
{% set visible_subpackages = obj.subpackages|selectattr("display")|list %}
{% if visible_subpackages %}
Subpackages
-----------
.. toctree::
:titlesonly:
:maxdepth: 3
{% for subpackage in visible_subpackages %}
{{ subpackage.short_name }}/index.rst
{% endfor %}
{% endif %}
{% endblock %}
{% block submodules %}
{% set visible_submodules = obj.submodules|selectattr("display")|list %}
{% if visible_submodules %}
Submodules
----------
.. toctree::
:titlesonly:
:maxdepth: 1
{% for submodule in visible_submodules %}
{{ submodule.short_name }}/index.rst
{% endfor %}
{% endif %}
{% endblock %}
{% block content %}
{% if obj.all is not none %}
{% set visible_children = obj.children|selectattr("short_name", "in", obj.all)|list %}
{% elif obj.type is equalto("package") %}
{% set visible_children = obj.children|selectattr("display")|list %}
{% else %}
{% set visible_children = obj.children|selectattr("display")|rejectattr("imported")|list %}
{% endif %}
{% if visible_children %}
{{ obj.type|title }} Contents
{{ "-" * obj.type|length }}---------
{% set visible_classes = visible_children|selectattr("type", "equalto", "class")|list %}
{% set visible_functions = visible_children|selectattr("type", "equalto", "function")|list %}
{% set visible_attributes = visible_children|selectattr("type", "equalto", "data")|list %}
{% if "show-module-summary" in autoapi_options and (visible_classes or visible_functions) %}
{% block classes scoped %}
{% if visible_classes %}
Classes
~~~~~~~
.. autoapisummary::
{% for klass in visible_classes %}
{{ klass.id }}
{% endfor %}
{% endif %}
{% endblock %}
{% block functions scoped %}
{% if visible_functions %}
Functions
~~~~~~~~~
.. autoapisummary::
{% for function in visible_functions %}
{{ function.id }}
{% endfor %}
{% endif %}
{% endblock %}
{% block attributes scoped %}
{% if visible_attributes %}
Attributes
~~~~~~~~~~
.. autoapisummary::
{% for attribute in visible_attributes %}
{{ attribute.id }}
{% endfor %}
{% endif %}
{% endblock %}
{% endif %}
{% for obj_item in visible_children %}
{{ obj_item.render()|indent(0) }}
{% endfor %}
{% endif %}
{% endblock %}

View file

@ -1 +0,0 @@
{% extends "python/module.rst" %}

View file

@ -1,15 +0,0 @@
{%- if obj.display %}
.. py:property:: {{ obj.short_name }}
{% if obj.annotation %}
:type: {{ obj.annotation }}
{% endif %}
{% if obj.properties %}
{% for property in obj.properties %}
:{{ property }}:
{% endfor %}
{% endif %}
{% if obj.docstring %}
{{ obj.docstring|indent(3) }}
{% endif %}
{% endif %}

View file

@ -1,261 +0,0 @@
# -*- coding: utf-8 -*-
#
# Configuration file for the Sphinx documentation builder.
#
# This file does only contain a selection of the most common options. For a
# full list see the documentation:
# http://www.sphinx-doc.org/en/master/config
# -- Path setup --------------------------------------------------------------
# If extensions (or modules to document with autodoc) are in another directory,
# add these directories to sys.path here. If the directory is relative to the
# documentation root, use os.path.abspath to make it absolute, like shown here.
#
# import os
# import sys
import os
import sys
import revitron_sphinx_theme
openpype_root = os.path.abspath('../..')
sys.path.insert(0, openpype_root)
# app = QApplication([])
"""
repos = os.listdir(os.path.abspath("../../repos"))
repos = [os.path.join(openpype_root, "repos", repo) for repo in repos]
for repo in repos:
sys.path.append(repo)
"""
todo_include_todos = True
autodoc_mock_imports = ["maya", "pymel", "nuke", "nukestudio", "nukescripts",
"hiero", "bpy", "fusion", "houdini", "hou", "unreal",
"__builtin__", "resolve", "pysync", "DaVinciResolveScript"]
# -- Project information -----------------------------------------------------
project = 'OpenPype'
copyright = '2023 Ynput'
author = 'Ynput'
# The short X.Y version
version = ''
# The full version, including alpha/beta/rc tags
release = ''
# -- General configuration ---------------------------------------------------
# If your documentation needs a minimal Sphinx version, state it here.
#
# needs_sphinx = '1.0'
# Add any Sphinx extension module names here, as strings. They can be
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
# ones.
extensions = [
'sphinx.ext.autodoc',
'sphinx.ext.napoleon',
'sphinx.ext.intersphinx',
'sphinx.ext.todo',
'sphinx.ext.coverage',
'sphinx.ext.mathjax',
'sphinx.ext.autosummary',
'revitron_sphinx_theme',
'autoapi.extension',
'myst_parser'
]
##############################
# Autoapi settings
##############################
autoapi_dirs = ['../../openpype', '../../igniter']
# bypass modules with a lot of python2 content for now
autoapi_ignore = [
"*vendor*",
"*schemas*",
"*startup/*",
"*/website*",
"*openpype/hooks*",
"*openpype/style*",
"openpype/tests*",
# to many levels of relative import:
"*/modules/sync_server/*"
]
autoapi_keep_files = True
autoapi_options = [
'members',
'undoc-members',
'show-inheritance',
'show-module-summary'
]
autoapi_add_toctree_entry = True
autoapi_template_dir = '_templates/autoapi'
# Add any paths that contain templates here, relative to this directory.
templates_path = ['_templates']
# The suffix(es) of source filenames.
# You can specify multiple suffix as a list of string:
#
# source_suffix = ['.rst', '.md']
source_suffix = ['.rst', '.md']
# The master toctree document.
master_doc = 'index'
# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
#
# This is also used if you do content translation via gettext catalogs.
# Usually you set "language" from the command line for these cases.
language = "English"
# List of patterns, relative to source directory, that match files and
# directories to ignore when looking for source files.
# This pattern also affects html_static_path and html_extra_path.
exclude_patterns = [
"openpype.hosts.resolve.*",
"openpype.tools.*"
]
# The name of the Pygments (syntax highlighting) style to use.
pygments_style = 'friendly'
# -- Options for autodoc -----------------------------------------------------
autodoc_default_flags = ['members']
autosummary_generate = True
# -- Options for HTML output -------------------------------------------------
# -- Options for HTML output -------------------------------------------------
# The theme to use for HTML and HTML Help pages. See the documentation for
# a list of builtin themes.
#
html_theme = 'revitron_sphinx_theme'
# Theme options are theme-specific and customize the look and feel of a theme
# further. For a list of options available for each theme, see the
# documentation.
#
html_theme_options = {
'collapse_navigation': True,
'sticky_navigation': True,
'navigation_depth': 4,
'includehidden': True,
'titles_only': False,
'github_url': '',
}
html_logo = '_static/AYON_tight_G.svg'
# Add any paths that contain custom static files (such as style sheets) here,
# relative to this directory. They are copied after the builtin static files,
# so a file named "default.css" will overwrite the builtin "default.css".
html_static_path = ['_static']
# Custom sidebar templates, must be a dictionary that maps document names
# to template names.
#
# The default sidebars (for documents that don't match any pattern) are
# defined by theme itself. Builtin themes are using these templates by
# default: ``['localtoc.html', 'relations.html', 'sourcelink.html',
# 'searchbox.html']``.
#
# html_sidebars = {}
# -- Options for HTMLHelp output ---------------------------------------------
# Output file base name for HTML help builder.
htmlhelp_basename = 'pypedoc'
# -- Options for LaTeX output ------------------------------------------------
latex_elements = {
# The paper size ('letterpaper' or 'a4paper').
#
# 'papersize': 'letterpaper',
# The font size ('10pt', '11pt' or '12pt').
#
# 'pointsize': '10pt',
# Additional stuff for the LaTeX preamble.
#
# 'preamble': '',
# Latex figure (float) alignment
#
# 'figure_align': 'htbp',
}
# Grouping the document tree into LaTeX files. List of tuples
# (source start file, target name, title,
# author, documentclass [howto, manual, or own class]).
latex_documents = [
(master_doc, 'openpype.tex', 'OpenPype Documentation',
'Ynput', 'manual'),
]
# -- Options for manual page output ------------------------------------------
# One entry per manual page. List of tuples
# (source start file, name, description, authors, manual section).
man_pages = [
(master_doc, 'openpype', 'OpenPype Documentation',
[author], 1)
]
# -- Options for Texinfo output ----------------------------------------------
# Grouping the document tree into Texinfo files. List of tuples
# (source start file, target name, title, author,
# dir menu entry, description, category)
texinfo_documents = [
(master_doc, 'OpenPype', 'OpenPype Documentation',
author, 'OpenPype', 'Pipeline for studios',
'Miscellaneous'),
]
# -- Options for Epub output -------------------------------------------------
# Bibliographic Dublin Core info.
epub_title = project
# The unique identifier of the text. This can be a ISBN number
# or the project homepage.
#
# epub_identifier = ''
# A unique identification for the text.
#
# epub_uid = ''
# A list of files that should not be packed into the epub file.
epub_exclude_files = ['search.html']
# -- Extension configuration -------------------------------------------------
# -- Options for intersphinx extension ---------------------------------------
# Example configuration for intersphinx: refer to the Python standard library.
intersphinx_mapping = {
'https://docs.python.org/3/': None
}
myst_gfm_only = True

View file

@ -1,19 +0,0 @@
.. openpype documentation master file, created by
sphinx-quickstart on Mon May 13 17:18:23 2019.
You can adapt this file completely to your liking, but it should at least
contain the root `toctree` directive.
Welcome to OpenPype's API documentation!
========================================
.. toctree::
Readme <readme.rst>
Indices and tables
==================
* :ref:`genindex`
* :ref:`modindex`
* :ref:`search`

View file

@ -1,6 +0,0 @@
===============
OpenPype Readme
===============
.. include:: ../../README.md
:parser: myst_parser.sphinx_

View file

@ -1,93 +0,0 @@
Copyright 2020 The Poppins Project Authors (https://github.com/itfoundry/Poppins)
This Font Software is licensed under the SIL Open Font License, Version 1.1.
This license is copied below, and is also available with a FAQ at:
http://scripts.sil.org/OFL
-----------------------------------------------------------
SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
-----------------------------------------------------------
PREAMBLE
The goals of the Open Font License (OFL) are to stimulate worldwide
development of collaborative font projects, to support the font creation
efforts of academic and linguistic communities, and to provide a free and
open framework in which fonts may be shared and improved in partnership
with others.
The OFL allows the licensed fonts to be used, studied, modified and
redistributed freely as long as they are not sold by themselves. The
fonts, including any derivative works, can be bundled, embedded,
redistributed and/or sold with any software provided that any reserved
names are not used by derivative works. The fonts and derivatives,
however, cannot be released under any other type of license. The
requirement for fonts to remain under this license does not apply
to any document created using the fonts or their derivatives.
DEFINITIONS
"Font Software" refers to the set of files released by the Copyright
Holder(s) under this license and clearly marked as such. This may
include source files, build scripts and documentation.
"Reserved Font Name" refers to any names specified as such after the
copyright statement(s).
"Original Version" refers to the collection of Font Software components as
distributed by the Copyright Holder(s).
"Modified Version" refers to any derivative made by adding to, deleting,
or substituting -- in part or in whole -- any of the components of the
Original Version, by changing formats or by porting the Font Software to a
new environment.
"Author" refers to any designer, engineer, programmer, technical
writer or other person who contributed to the Font Software.
PERMISSION & CONDITIONS
Permission is hereby granted, free of charge, to any person obtaining
a copy of the Font Software, to use, study, copy, merge, embed, modify,
redistribute, and sell modified and unmodified copies of the Font
Software, subject to the following conditions:
1) Neither the Font Software nor any of its individual components,
in Original or Modified Versions, may be sold by itself.
2) Original or Modified Versions of the Font Software may be bundled,
redistributed and/or sold with any software, provided that each copy
contains the above copyright notice and this license. These can be
included either as stand-alone text files, human-readable headers or
in the appropriate machine-readable metadata fields within text or
binary files as long as those fields can be easily viewed by the user.
3) No Modified Version of the Font Software may use the Reserved Font
Name(s) unless explicit written permission is granted by the corresponding
Copyright Holder. This restriction only applies to the primary font name as
presented to the users.
4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
Software shall not be used to promote, endorse or advertise any
Modified Version, except to acknowledge the contribution(s) of the
Copyright Holder(s) and the Author(s) or with their explicit written
permission.
5) The Font Software, modified or unmodified, in part or in whole,
must be distributed entirely under this license, and must not be
distributed under any other license. The requirement for fonts to
remain under this license does not apply to any document created
using the Font Software.
TERMINATION
This license becomes null and void if any of the above conditions are
not met.
DISCLAIMER
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
OTHER DEALINGS IN THE FONT SOFTWARE.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View file

@ -1,105 +0,0 @@
# -*- coding: utf-8 -*-
"""Open install dialog."""
import os
import sys
os.chdir(os.path.dirname(__file__)) # for override sys.path in Deadline
from .bootstrap_repos import (
BootstrapRepos,
OpenPypeVersion
)
from .version import __version__ as version
# Store OpenPypeVersion to 'sys.modules'
# - this makes it available in OpenPype processes without modifying
# 'sys.path' or 'PYTHONPATH'
if "OpenPypeVersion" not in sys.modules:
sys.modules["OpenPypeVersion"] = OpenPypeVersion
def _get_qt_app():
from qtpy import QtWidgets, QtCore
app = QtWidgets.QApplication.instance()
if app is not None:
return app
for attr_name in (
"AA_EnableHighDpiScaling",
"AA_UseHighDpiPixmaps",
):
attr = getattr(QtCore.Qt, attr_name, None)
if attr is not None:
QtWidgets.QApplication.setAttribute(attr)
policy = os.getenv("QT_SCALE_FACTOR_ROUNDING_POLICY")
if (
hasattr(QtWidgets.QApplication, "setHighDpiScaleFactorRoundingPolicy")
and not policy
):
QtWidgets.QApplication.setHighDpiScaleFactorRoundingPolicy(
QtCore.Qt.HighDpiScaleFactorRoundingPolicy.PassThrough
)
return QtWidgets.QApplication(sys.argv)
def open_dialog():
"""Show Igniter dialog."""
if os.getenv("OPENPYPE_HEADLESS_MODE"):
print("!!! Can't open dialog in headless mode. Exiting.")
sys.exit(1)
from .install_dialog import InstallDialog
app = _get_qt_app()
d = InstallDialog()
d.open()
app.exec_()
return d.result()
def open_update_window(openpype_version):
"""Open update window."""
if os.getenv("OPENPYPE_HEADLESS_MODE"):
print("!!! Can't open dialog in headless mode. Exiting.")
sys.exit(1)
from .update_window import UpdateWindow
app = _get_qt_app()
d = UpdateWindow(version=openpype_version)
d.open()
app.exec_()
version_path = d.get_version_path()
return version_path
def show_message_dialog(title, message):
"""Show dialog with a message and title to user."""
if os.getenv("OPENPYPE_HEADLESS_MODE"):
print("!!! Can't open dialog in headless mode. Exiting.")
sys.exit(1)
from .message_dialog import MessageDialog
app = _get_qt_app()
dialog = MessageDialog(title, message)
dialog.open()
app.exec_()
__all__ = [
"BootstrapRepos",
"open_dialog",
"open_update_window",
"show_message_dialog",
"version"
]

View file

@ -1,25 +0,0 @@
# -*- coding: utf-8 -*-
"""Open install dialog."""
import sys
from qtpy import QtWidgets
from .install_dialog import InstallDialog
RESULT = 0
def get_result(res: int):
"""Sets result returned from dialog."""
global RESULT
RESULT = res
app = QtWidgets.QApplication(sys.argv)
d = InstallDialog()
d.finished.connect(get_result)
d.open()
app.exec()
sys.exit(RESULT)

File diff suppressed because it is too large Load diff

View file

@ -1,509 +0,0 @@
# -*- coding: utf-8 -*-
"""Show dialog for choosing central pype repository."""
import os
import sys
import re
import collections
from qtpy import QtCore, QtGui, QtWidgets
from .install_thread import InstallThread
from .tools import (
validate_mongo_connection,
get_openpype_icon_path
)
from .nice_progress_bar import NiceProgressBar
from .user_settings import OpenPypeSecureRegistry
from .tools import load_stylesheet
from .version import __version__
class ButtonWithOptions(QtWidgets.QFrame):
option_clicked = QtCore.Signal(str)
def __init__(self, commands, parent=None):
super(ButtonWithOptions, self).__init__(parent)
self.setObjectName("ButtonWithOptions")
options_btn = QtWidgets.QToolButton(self)
options_btn.setArrowType(QtCore.Qt.DownArrow)
options_btn.setIconSize(QtCore.QSize(12, 12))
default = None
default_label = None
options_menu = QtWidgets.QMenu(self)
for option, option_label in commands.items():
if default is None:
default = option
default_label = option_label
continue
action = QtWidgets.QAction(option_label, options_menu)
action.setData(option)
options_menu.addAction(action)
main_btn = QtWidgets.QPushButton(default_label, self)
main_btn.setFlat(True)
main_layout = QtWidgets.QHBoxLayout(self)
main_layout.setContentsMargins(0, 0, 0, 0)
main_layout.setSpacing(1)
main_layout.addWidget(main_btn, 1, QtCore.Qt.AlignVCenter)
main_layout.addWidget(options_btn, 0, QtCore.Qt.AlignVCenter)
main_btn.clicked.connect(self._on_main_button)
options_btn.clicked.connect(self._on_options_click)
options_menu.triggered.connect(self._on_trigger)
self.main_btn = main_btn
self.options_btn = options_btn
self.options_menu = options_menu
options_btn.setEnabled(not options_menu.isEmpty())
self._default_value = default
def resizeEvent(self, event):
super(ButtonWithOptions, self).resizeEvent(event)
self.options_btn.setFixedHeight(self.main_btn.height())
def _on_options_click(self):
pos = self.main_btn.rect().bottomLeft()
point = self.main_btn.mapToGlobal(pos)
self.options_menu.popup(point)
def _on_trigger(self, action):
self.option_clicked.emit(action.data())
def _on_main_button(self):
self.option_clicked.emit(self._default_value)
class ConsoleWidget(QtWidgets.QWidget):
def __init__(self, parent=None):
super(ConsoleWidget, self).__init__(parent)
# style for normal and error console text
default_console_style = QtGui.QTextCharFormat()
error_console_style = QtGui.QTextCharFormat()
default_console_style.setForeground(
QtGui.QColor.fromRgb(72, 200, 150)
)
error_console_style.setForeground(
QtGui.QColor.fromRgb(184, 54, 19)
)
label = QtWidgets.QLabel("Console:", self)
console_output = QtWidgets.QPlainTextEdit(self)
console_output.setMinimumSize(QtCore.QSize(300, 200))
console_output.setReadOnly(True)
console_output.setCurrentCharFormat(default_console_style)
console_output.setObjectName("Console")
main_layout = QtWidgets.QVBoxLayout(self)
main_layout.setContentsMargins(0, 0, 0, 0)
main_layout.addWidget(label, 0)
main_layout.addWidget(console_output, 1)
self.default_console_style = default_console_style
self.error_console_style = error_console_style
self.label = label
self.console_output = console_output
self.hide_console()
def hide_console(self):
self.label.setVisible(False)
self.console_output.setVisible(False)
self.updateGeometry()
def show_console(self):
self.label.setVisible(True)
self.console_output.setVisible(True)
self.updateGeometry()
def update_console(self, msg: str, error: bool = False) -> None:
if not error:
self.console_output.setCurrentCharFormat(
self.default_console_style
)
else:
self.console_output.setCurrentCharFormat(
self.error_console_style
)
self.console_output.appendPlainText(msg)
class MongoUrlInput(QtWidgets.QLineEdit):
"""Widget to input mongodb URL."""
def set_valid(self):
"""Set valid state on mongo url input."""
self.setProperty("state", "valid")
self.style().polish(self)
def remove_state(self):
"""Set invalid state on mongo url input."""
self.setProperty("state", "")
self.style().polish(self)
def set_invalid(self):
"""Set invalid state on mongo url input."""
self.setProperty("state", "invalid")
self.style().polish(self)
class InstallDialog(QtWidgets.QDialog):
"""Main Igniter dialog window."""
mongo_url_regex = re.compile(r"^(mongodb|mongodb\+srv)://.*?")
_width = 500
_height = 200
commands = collections.OrderedDict([
("run", "Start"),
("run_from_code", "Run from code")
])
def __init__(self, parent=None):
super(InstallDialog, self).__init__(parent)
self.setWindowTitle(
f"OpenPype Igniter {__version__}"
)
self.setWindowFlags(
QtCore.Qt.WindowCloseButtonHint
| QtCore.Qt.WindowMinimizeButtonHint
)
current_dir = os.path.dirname(os.path.abspath(__file__))
roboto_font_path = os.path.join(current_dir, "RobotoMono-Regular.ttf")
poppins_font_path = os.path.join(current_dir, "Poppins")
# Install roboto font
QtGui.QFontDatabase.addApplicationFont(roboto_font_path)
for filename in os.listdir(poppins_font_path):
if os.path.splitext(filename)[1] == ".ttf":
QtGui.QFontDatabase.addApplicationFont(filename)
# Load logo
icon_path = get_openpype_icon_path()
pixmap_openpype_logo = QtGui.QPixmap(icon_path)
# Set logo as icon of window
self.setWindowIcon(QtGui.QIcon(pixmap_openpype_logo))
secure_registry = OpenPypeSecureRegistry("mongodb")
mongo_url = ""
try:
mongo_url = (
os.getenv("OPENPYPE_MONGO", "")
or secure_registry.get_item("openPypeMongo")
)
except ValueError:
pass
self.mongo_url = mongo_url
self._pixmap_openpype_logo = pixmap_openpype_logo
self._secure_registry = secure_registry
self._controls_disabled = False
self._install_thread = None
self.resize(QtCore.QSize(self._width, self._height))
self._init_ui()
# Set stylesheet
self.setStyleSheet(load_stylesheet())
# Trigger Mongo URL validation
self._mongo_input.setText(self.mongo_url)
def _init_ui(self):
# basic visual style - dark background, light text
# Main info
# --------------------------------------------------------------------
main_label = QtWidgets.QLabel("Welcome to <b>OpenPype</b>", self)
main_label.setWordWrap(True)
main_label.setObjectName("MainLabel")
# Mongo box | OK button
# --------------------------------------------------------------------
mongo_input = MongoUrlInput(self)
mongo_input.setPlaceholderText(
"Enter your database Address. Example: mongodb://192.168.1.10:2707"
)
mongo_messages_widget = QtWidgets.QWidget(self)
mongo_connection_msg = QtWidgets.QLabel(mongo_messages_widget)
mongo_connection_msg.setVisible(True)
mongo_connection_msg.setTextInteractionFlags(
QtCore.Qt.TextSelectableByMouse
)
mongo_messages_layout = QtWidgets.QVBoxLayout(mongo_messages_widget)
mongo_messages_layout.setContentsMargins(0, 0, 0, 0)
mongo_messages_layout.addWidget(mongo_connection_msg)
# Progress bar
# --------------------------------------------------------------------
progress_bar = NiceProgressBar(self)
progress_bar.setAlignment(QtCore.Qt.AlignCenter)
progress_bar.setTextVisible(False)
# Console
# --------------------------------------------------------------------
console_widget = ConsoleWidget(self)
# Bottom button bar
# --------------------------------------------------------------------
bottom_widget = QtWidgets.QWidget(self)
btns_widget = QtWidgets.QWidget(bottom_widget)
openpype_logo_label = QtWidgets.QLabel("openpype logo", bottom_widget)
openpype_logo_label.setPixmap(self._pixmap_openpype_logo)
run_button = ButtonWithOptions(
self.commands,
btns_widget
)
run_button.setMinimumSize(64, 24)
run_button.setToolTip("Run OpenPype")
# install button - - - - - - - - - - - - - - - - - - - - - - - - - - -
exit_button = QtWidgets.QPushButton("Exit", btns_widget)
exit_button.setObjectName("ExitBtn")
exit_button.setFlat(True)
exit_button.setMinimumSize(64, 24)
exit_button.setToolTip("Exit")
btns_layout = QtWidgets.QHBoxLayout(btns_widget)
btns_layout.setContentsMargins(0, 0, 0, 0)
btns_layout.addWidget(run_button, 0)
btns_layout.addWidget(exit_button, 0)
bottom_layout = QtWidgets.QHBoxLayout(bottom_widget)
bottom_layout.setContentsMargins(0, 0, 0, 0)
bottom_layout.setAlignment(QtCore.Qt.AlignHCenter)
bottom_layout.addWidget(openpype_logo_label, 0)
bottom_layout.addStretch(1)
bottom_layout.addWidget(btns_widget, 0)
# add all to main
main = QtWidgets.QVBoxLayout(self)
main.addSpacing(15)
main.addWidget(main_label, 0)
main.addSpacing(15)
main.addWidget(mongo_input, 0)
main.addWidget(mongo_messages_widget, 0)
main.addWidget(progress_bar, 0)
main.addSpacing(15)
main.addWidget(console_widget, 1)
main.addWidget(bottom_widget, 0)
run_button.option_clicked.connect(self._on_run_btn_click)
exit_button.clicked.connect(self._on_exit_clicked)
mongo_input.textChanged.connect(self._on_mongo_url_change)
self._console_widget = console_widget
self.main_label = main_label
self._mongo_input = mongo_input
self._mongo_connection_msg = mongo_connection_msg
self._run_button = run_button
self._exit_button = exit_button
self._progress_bar = progress_bar
def _on_run_btn_click(self, option):
# Disable buttons
self._disable_buttons()
# Set progress to any value
self._update_progress(1)
self._progress_bar.repaint()
# Add label to show that is connecting to mongo
self.set_invalid_mongo_connection(self.mongo_url, True)
# Process events to repaint changes
QtWidgets.QApplication.processEvents()
if not self.validate_url():
self._enable_buttons()
self._update_progress(0)
# Update any messages
self._mongo_input.setText(self.mongo_url)
return
if option == "run":
self._run_openpype()
elif option == "run_from_code":
self._run_openpype_from_code()
else:
raise AssertionError("BUG: Unknown variant \"{}\"".format(option))
def _run_openpype_from_code(self):
os.environ["OPENPYPE_MONGO"] = self.mongo_url
try:
self._secure_registry.set_item("openPypeMongo", self.mongo_url)
except ValueError:
print("Couldn't save Mongo URL to keyring")
self.done(2)
def _run_openpype(self):
"""Start install process.
This will once again validate entered path and mongo if ok, start
working thread that will do actual job.
"""
# Check if install thread is not already running
if self._install_thread and self._install_thread.isRunning():
return
self._mongo_input.set_valid()
install_thread = InstallThread(self)
install_thread.message.connect(self.update_console)
install_thread.progress.connect(self._update_progress)
install_thread.finished.connect(self._installation_finished)
install_thread.set_mongo(self.mongo_url)
self._install_thread = install_thread
install_thread.start()
def _installation_finished(self):
# TODO we should find out why status can be set to 'None'?
# - 'InstallThread.run' should handle all cases so not sure where
# that come from
status = self._install_thread.result()
if status is not None and status >= 0:
self._update_progress(100)
QtWidgets.QApplication.processEvents()
self.done(3)
else:
self._enable_buttons()
self._show_console()
def _update_progress(self, progress: int):
self._progress_bar.setValue(progress)
text_visible = self._progress_bar.isTextVisible()
if progress == 0:
if text_visible:
self._progress_bar.setTextVisible(False)
elif not text_visible:
self._progress_bar.setTextVisible(True)
def _on_exit_clicked(self):
self.reject()
def _on_mongo_url_change(self, new_value):
# Strip the value
new_value = new_value.strip()
# Store new mongo url to variable
self.mongo_url = new_value
msg = None
# Change style of input
if not new_value:
self._mongo_input.remove_state()
elif not self.mongo_url_regex.match(new_value):
self._mongo_input.set_invalid()
msg = (
"Mongo URL should start with"
" <b>\"mongodb://\"</b> or <b>\"mongodb+srv://\"</b>"
)
else:
self._mongo_input.set_valid()
self.set_invalid_mongo_url(msg)
def validate_url(self):
"""Validate if entered url is ok.
Returns:
True if url is valid monogo string.
"""
if self.mongo_url == "":
return False
is_valid, reason_str = validate_mongo_connection(self.mongo_url)
if not is_valid:
self.set_invalid_mongo_connection(self.mongo_url)
self._mongo_input.set_invalid()
self.update_console(f"!!! {reason_str}", True)
return False
self.set_invalid_mongo_connection(None)
self._mongo_input.set_valid()
return True
def set_invalid_mongo_url(self, reason):
if reason is None:
self._mongo_connection_msg.setText("")
else:
self._mongo_connection_msg.setText("- {}".format(reason))
def set_invalid_mongo_connection(self, mongo_url, connecting=False):
if mongo_url is None:
self.set_invalid_mongo_url(mongo_url)
return
if connecting:
msg = "Connecting to: <b>{}</b>".format(mongo_url)
else:
msg = "Can't connect to: <b>{}</b>".format(mongo_url)
self.set_invalid_mongo_url(msg)
def update_console(self, msg: str, error: bool = False) -> None:
"""Display message in console.
Args:
msg (str): message.
error (bool): if True, print it red.
"""
self._console_widget.update_console(msg, error)
def _show_console(self):
self._console_widget.show_console()
self.updateGeometry()
def _disable_buttons(self):
"""Disable buttons so user interaction doesn't interfere."""
self._exit_button.setEnabled(False)
self._run_button.setEnabled(False)
self._controls_disabled = True
def _enable_buttons(self):
"""Enable buttons after operation is complete."""
self._exit_button.setEnabled(True)
self._run_button.setEnabled(True)
self._controls_disabled = False
def closeEvent(self, event): # noqa
"""Prevent closing if window when controls are disabled."""
if self._controls_disabled:
return event.ignore()
return super(InstallDialog, self).closeEvent(event)
if __name__ == "__main__":
app = QtWidgets.QApplication(sys.argv)
d = InstallDialog()
d.show()
sys.exit(app.exec_())

View file

@ -1,217 +0,0 @@
# -*- coding: utf-8 -*-
"""Working thread for installer."""
import os
import sys
from pathlib import Path
from qtpy import QtCore
from .bootstrap_repos import (
BootstrapRepos,
OpenPypeVersionInvalid,
OpenPypeVersionIOError,
OpenPypeVersionExists,
OpenPypeVersion
)
from .tools import (
get_openpype_global_settings,
get_local_openpype_path_from_settings,
validate_mongo_connection
)
class InstallThread(QtCore.QThread):
"""Install Worker thread.
This class takes care of finding OpenPype version on user entered path
(or loading this path from database). If nothing is entered by user,
OpenPype will create its zip files from repositories that comes with it.
If path contains plain repositories, they are zipped and installed to
user data dir.
"""
progress = QtCore.Signal(int)
message = QtCore.Signal((str, bool))
def __init__(self, parent=None,):
self._mongo = None
self._result = None
super().__init__(parent)
def result(self):
"""Result of finished installation."""
return self._result
def _set_result(self, value):
if self._result is not None:
raise AssertionError("BUG: Result was set more than once!")
self._result = value
def run(self):
"""Thread entry point.
Using :class:`BootstrapRepos` to either install OpenPype as zip files
or copy them from location specified by user or retrieved from
database.
"""
self.message.emit("Installing OpenPype ...", False)
# find local version of OpenPype
bs = BootstrapRepos(
progress_callback=self.set_progress, message=self.message)
local_version = OpenPypeVersion.get_installed_version_str()
# user did not entered url
if self._mongo:
self.message.emit("Saving mongo connection string ...", False)
bs.secure_registry.set_item("openPypeMongo", self._mongo)
elif os.getenv("OPENPYPE_MONGO"):
self._mongo = os.getenv("OPENPYPE_MONGO")
else:
# try to get it from settings registry
try:
self._mongo = bs.secure_registry.get_item(
"openPypeMongo")
except ValueError:
self.message.emit(
"!!! We need MongoDB URL to proceed.", True)
self._set_result(-1)
return
os.environ["OPENPYPE_MONGO"] = self._mongo
if not validate_mongo_connection(self._mongo):
self.message.emit(f"Cannot connect to {self._mongo}", True)
self._set_result(-1)
return
global_settings = get_openpype_global_settings(self._mongo)
data_dir = get_local_openpype_path_from_settings(global_settings)
bs.set_data_dir(data_dir)
self.message.emit(
f"Detecting installed OpenPype versions in {bs.data_dir}",
False)
detected = bs.find_openpype(include_zips=True)
if not detected and getattr(sys, 'frozen', False):
self.message.emit("None detected.", True)
self.message.emit(("We will use OpenPype coming with "
"installer."), False)
openpype_version = bs.create_version_from_frozen_code()
if not openpype_version:
self.message.emit(
f"!!! Install failed - {openpype_version}", True)
self._set_result(-1)
return
self.message.emit(f"Using: {openpype_version}", False)
bs.install_version(openpype_version)
self.message.emit(f"Installed as {openpype_version}", False)
self.progress.emit(100)
self._set_result(1)
return
if detected and not OpenPypeVersion.get_installed_version().is_compatible(detected[-1]): # noqa: E501
self.message.emit((
f"Latest detected version {detected[-1]} "
"is not compatible with the currently running "
f"{local_version}"
), True)
self.message.emit((
"Filtering detected versions to compatible ones..."
), False)
# filter results to get only compatible versions
detected = [
version for version in detected
if version.is_compatible(
OpenPypeVersion.get_installed_version())
]
if detected:
if OpenPypeVersion(
version=local_version, path=Path()) < detected[-1]:
self.message.emit((
f"Latest installed version {detected[-1]} is newer "
f"then currently running {local_version}"
), False)
self.message.emit("Skipping OpenPype install ...", False)
if detected[-1].path.suffix.lower() == ".zip":
bs.extract_openpype(detected[-1])
self._set_result(0)
return
if OpenPypeVersion(version=local_version).get_main_version() == detected[-1].get_main_version(): # noqa: E501
self.message.emit((
f"Latest installed version is the same as "
f"currently running {local_version}"
), False)
self.message.emit("Skipping OpenPype install ...", False)
self._set_result(0)
return
self.message.emit((
"All installed versions are older then "
f"currently running one {local_version}"
), False)
self.message.emit("None detected.", False)
self.message.emit(
f"We will use local OpenPype version {local_version}", False)
local_openpype = bs.create_version_from_live_code()
if not local_openpype:
self.message.emit(
f"!!! Install failed - {local_openpype}", True)
self._set_result(-1)
return
try:
bs.install_version(local_openpype)
except (OpenPypeVersionExists,
OpenPypeVersionInvalid,
OpenPypeVersionIOError) as e:
self.message.emit(f"Installed failed: ", True)
self.message.emit(str(e), True)
self._set_result(-1)
return
self.message.emit(f"Installed as {local_openpype}", False)
self.progress.emit(100)
self._set_result(1)
return
self.progress.emit(100)
self._set_result(1)
return
def set_path(self, path: str) -> None:
"""Helper to set path.
Args:
path (str): Path to set.
"""
self._path = path
def set_mongo(self, mongo: str) -> None:
"""Helper to set mongo url.
Args:
mongo (str): Mongodb url.
"""
self._mongo = mongo
def set_progress(self, progress: int) -> None:
"""Helper to set progress bar.
Args:
progress (int): Progress in percents.
"""
self.progress.emit(progress)

View file

@ -1,44 +0,0 @@
from qtpy import QtWidgets, QtGui
from .tools import (
load_stylesheet,
get_openpype_icon_path
)
class MessageDialog(QtWidgets.QDialog):
"""Simple message dialog with title, message and OK button."""
def __init__(self, title, message):
super(MessageDialog, self).__init__()
# Set logo as icon of window
icon_path = get_openpype_icon_path()
pixmap_openpype_logo = QtGui.QPixmap(icon_path)
self.setWindowIcon(QtGui.QIcon(pixmap_openpype_logo))
# Set title
self.setWindowTitle(title)
# Set message
label_widget = QtWidgets.QLabel(message, self)
ok_btn = QtWidgets.QPushButton("OK", self)
btns_layout = QtWidgets.QHBoxLayout()
btns_layout.addStretch(1)
btns_layout.addWidget(ok_btn, 0)
layout = QtWidgets.QVBoxLayout(self)
layout.addWidget(label_widget, 1)
layout.addLayout(btns_layout, 0)
ok_btn.clicked.connect(self._on_ok_clicked)
self._label_widget = label_widget
self._ok_btn = ok_btn
def _on_ok_clicked(self):
self.close()
def showEvent(self, event):
super(MessageDialog, self).showEvent(event)
self.setStyleSheet(load_stylesheet())

View file

@ -1,20 +0,0 @@
from qtpy import QtWidgets
class NiceProgressBar(QtWidgets.QProgressBar):
def __init__(self, parent=None):
super(NiceProgressBar, self).__init__(parent)
self._real_value = 0
def setValue(self, value):
self._real_value = value
if value != 0 and value < 11:
value = 11
super(NiceProgressBar, self).setValue(value)
def value(self):
return self._real_value
def text(self):
return "{} %".format(self._real_value)

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 124 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.9 KiB

View file

@ -1,413 +0,0 @@
*
.*
*
.*
*
.
*
.*
*
.
.
*
.*
.*
.*
*
.
.
*
.*
.*
.*
*
.
_.
/**
\ *
\*
*
*
.
__.
---*
\ \*
\ *
\*
*
.
\___.
/* *
\ \ *
\ \*
\ *
\*
.
|____.
/* *
\|\ *
\ \ *
\ \ *
\ \*
\/.
_/_____.
/* *
/ \ *
\ \ *
\ \ *
\ \__*
\/__.
__________.
--*-- ___*
\ \ \/_*
\ \ __*
\ \ \_*
\ \____\*
\/____/.
\____________ .
/* ___ \*
\ \ \/_\ *
\ \ _____*
\ \ \___/*
\ \____\ *
\/____/ .
|___________ .
/* ___ \ *
\|\ \/_\ \ *
\ \ _____/ *
\ \ \___/ *
\ \____\ / *
\/____/ \.
_/__________ .
/* ___ \ *
/ \ \/_\ \ *
\ \ _____/ *
\ \ \___/ ---*
\ \____\ / \__*
\/____/ \/__.
____________ .
--*-- ___ \ *
\ \ \/_\ \ *
\ \ _____/ *
\ \ \___/ ---- *
\ \____\ / \____\*
\/____/ \/____/.
____________
/\ ___ \ .
\ \ \/_\ \ *
\ \ _____/ *
\ \ \___/ ---- *
\ \____\ / \____\ .
\/____/ \/____/
____________
/\ ___ \
\ \ \/_\ \ .
\ \ _____/ *
\ \ \___/ ---- *
\ \____\ / \____\ .
\/____/ \/____/
____________
/\ ___ \
\ \ \/_\ \
\ \ _____/ .
\ \ \___/ ---- *
\ \____\ / \____\ .
\/____/ \/____/
____________
/\ ___ \
\ \ \/_\ \
\ \ _____/
\ \ \___/ ---- *
\ \____\ / \____\
\/____/ \/____/
____________
/\ ___ \
\ \ \/_\ \
\ \ _____/
\ \ \___/ ---- .
\ \____\ / \____\
\/____/ \/____/
____________
/\ ___ \
\ \ \/_\ \
\ \ _____/ _
\ \ \___/ ----
\ \____\ / \____\
\/____/ \/____/
____________
/\ ___ \
\ \ \/_\ \
\ \ _____/ ___
\ \ \___/ ----
\ \____\ / \____\
\/____/ \/____/
____________
/\ ___ \
\ \ \/_\ \
\ \ _____/ ___
\ \ \___/ ---- \
\ \____\ / \____\
\/____/ \/____/
____________
/\ ___ \
\ \ \/_\ \
\ \ _____/ ___
\ \ \___/ ---- \
\ \____\ / \____\ \
\/____/ \/____/
____________
/\ ___ \
\ \ \/_\ \
\ \ _____/ ___
\ \ \___/ ---- \
\ \____\ / \____\ __\
\/____/ \/____/
____________
/\ ___ \
\ \ \/_\ \
\ \ _____/ ___
\ \ \___/ ---- \
\ \____\ / \____\ \__\
\/____/ \/____/
____________
/\ ___ \
\ \ \/_\ \
\ \ _____/ ___
\ \ \___/ ---- \ \
\ \____\ / \____\ \__\
\/____/ \/____/
____________
/\ ___ \
\ \ \/_\ \
\ \ _____/ ___
\ \ \___/ ---- \ \
\ \____\ / \____\ \__\
\/____/ \/____/
____________
/\ ___ \
\ \ \/_\ \
\ \ _____/ ___.
\ \ \___/ ---- \ \\
\ \____\ / \____\ \__\,
\/____/ \/____/
____________
/\ ___ \
\ \ \/_\ \
\ \ _____/ ___ .
\ \ \___/ ---- \ \\
\ \____\ / \____\ \__\\,
\/____/ \/____/
____________
/\ ___ \
\ \ \/_\ \
\ \ _____/ ___ _.
\ \ \___/ ---- \ \\\
\ \____\ / \____\ \__\\\
\/____/ \/____/
____________
/\ ___ \
\ \ \/_\ \
\ \ _____/ ___ __.
\ \ \___/ ---- \ \\ \
\ \____\ / \____\ \__\\_/.
\/____/ \/____/
____________
/\ ___ \
\ \ \/_\ \
\ \ _____/ ___ ___.
\ \ \___/ ---- \ \\ \\
\ \____\ / \____\ \__\\__\.
\/____/ \/____/
____________
/\ ___ \
\ \ \/_\ \
\ \ _____/ ___ ___ .
\ \ \___/ ---- \ \\ \\
\ \____\ / \____\ \__\\__\\.
\/____/ \/____/
____________
/\ ___ \
\ \ \/_\ \
\ \ _____/ ___ ___ _.
\ \ \___/ ---- \ \\ \\\
\ \____\ / \____\ \__\\__\\.
\/____/ \/____/
____________
/\ ___ \
\ \ \/_\ \
\ \ _____/ ___ ___ __.
\ \ \___/ ---- \ \\ \\ \
\ \____\ / \____\ \__\\__\\_.
\/____/ \/____/
____________
/\ ___ \
\ \ \/_\ \
\ \ _____/ ___ ___ __.
\ \ \___/ ---- \ \\ \\ \
\ \____\ / \____\ \__\\__\\__.
\/____/ \/____/
____________
/\ ___ \
\ \ \/_\ \
\ \ _____/ ___ ___ ___
\ \ \___/ ---- \ \\ \\ \
\ \____\ / \____\ \__\\__\\__\
\/____/ \/____/ .
____________
/\ ___ \
\ \ \/_\ \
\ \ _____/ ___ ___ ___
\ \ \___/ ---- \ \\ \\ \
\ \____\ / \____\ \__\\__\\__\
\/____/ \/____/ *
____________
/\ ___ \
\ \ \/_\ \
\ \ _____/ ___ ___ ___
\ \ \___/ ---- \ \\ \\ \
\ \____\ / \____\ \__\\__\\__\
\/____/ \/____/ O*
____________
/\ ___ \
\ \ \/_\ \
\ \ _____/ ___ ___ ___
\ \ \___/ ---- \ \\ \\ \
\ \____\ / \____\ \__\\__\\__\
\/____/ \/____/ oO*
____________
/\ ___ \
\ \ \/_\ \
\ \ _____/ ___ ___ ___
\ \ \___/ ---- \ \\ \\ \
\ \____\ / \____\ \__\\__\\__\
\/____/ \/____/ .oO*
____________
/\ ___ \
\ \ \/_\ \
\ \ _____/ ___ ___ ___
\ \ \___/ ---- \ \\ \\ \
\ \____\ / \____\ \__\\__\\__\
\/____/ \/____/ ..oO*
____________
/\ ___ \
\ \ \/_\ \
\ \ _____/ ___ ___ ___
\ \ \___/ ---- \ \\ \\ \
\ \____\ / \____\ \__\\__\\__\
\/____/ \/____/ . .oO*
____________
/\ ___ \
\ \ \/_\ \
\ \ _____/ ___ ___ ___
\ \ \___/ ---- \ \\ \\ \
\ \____\ / \____\ \__\\__\\__\
\/____/ \/____/ . p.oO*
____________
/\ ___ \
\ \ \/_\ \
\ \ _____/ ___ ___ ___
\ \ \___/ ---- \ \\ \\ \
\ \____\ / \____\ \__\\__\\__\
\/____/ \/____/ . Py.oO*
____________
/\ ___ \
\ \ \/_\ \
\ \ _____/ ___ ___ ___
\ \ \___/ ---- \ \\ \\ \
\ \____\ / \____\ \__\\__\\__\
\/____/ \/____/ . PYp.oO*
____________
/\ ___ \
\ \ \/_\ \
\ \ _____/ ___ ___ ___
\ \ \___/ ---- \ \\ \\ \
\ \____\ / \____\ \__\\__\\__\
\/____/ \/____/ . PYPe.oO*
____________
/\ ___ \
\ \ \/_\ \
\ \ _____/ ___ ___ ___
\ \ \___/ ---- \ \\ \\ \
\ \____\ / \____\ \__\\__\\__\
\/____/ \/____/ . PYPE .oO*
____________
/\ ___ \
\ \ \/_\ \
\ \ _____/ ___ ___ ___
\ \ \___/ ---- \ \\ \\ \
\ \____\ / \____\ \__\\__\\__\
\/____/ \/____/ . PYPE c.oO*
____________
/\ ___ \
\ \ \/_\ \
\ \ _____/ ___ ___ ___
\ \ \___/ ---- \ \\ \\ \
\ \____\ / \____\ \__\\__\\__\
\/____/ \/____/ . PYPE C1.oO*
____________
/\ ___ \
\ \ \/_\ \
\ \ _____/ ___ ___ ___
\ \ \___/ ---- \ \\ \\ \
\ \____\ / \____\ \__\\__\\__\
\/____/ \/____/ . PYPE ClU.oO*
____________
/\ ___ \
\ \ \/_\ \
\ \ _____/ ___ ___ ___
\ \ \___/ ---- \ \\ \\ \
\ \____\ / \____\ \__\\__\\__\
\/____/ \/____/ . PYPE CluB.oO*
____________
/\ ___ \
\ \ \/_\ \
\ \ _____/ ___ ___ ___
\ \ \___/ ---- \ \\ \\ \
\ \____\ / \____\ \__\\__\\__\
\/____/ \/____/ . PYPE Club .oO*
____________
/\ ___ \
\ \ \/_\ \
\ \ _____/ ___ ___ ___
\ \ \___/ ---- \ \\ \\ \
\ \____\ / \____\ \__\\__\\__\
\/____/ \/____/ . PYPE Club . ..
____________
/\ ___ \
\ \ \/_\ \
\ \ _____/ ___ ___ ___
\ \ \___/ ---- \ \\ \\ \
\ \____\ / \____\ \__\\__\\__\
\/____/ \/____/ . PYPE Club . ..
____________
/\ ___ \
\ \ \/_\ \
\ \ _____/ ___ ___ ___
\ \ \___/ ---- \ \\ \\ \
\ \____\ / \____\ \__\\__\\__\
\/____/ \/____/ . PYPE Club . .
____________
/\ ___ \
\ \ \/_\ \
\ \ _____/ ___ ___ ___
\ \ \___/ ---- \ \\ \\ \
\ \____\ / \____\ \__\\__\\__\
\/____/ \/____/ . PYPE Club .

View file

@ -1,280 +0,0 @@
*{
font-size: 10pt;
font-family: "Poppins";
}
QWidget {
color: #bfccd6;
background-color: #282C34;
border-radius: 0px;
}
QMenu {
border: 1px solid #555555;
background-color: #21252B;
}
QMenu::item {
padding: 5px 10px 5px 10px;
border-left: 5px solid #313741;;
}
QMenu::item:selected {
border-left-color: rgb(84, 209, 178);
background-color: #222d37;
}
QLineEdit, QPlainTextEdit {
border: 1px solid #464b54;
border-radius: 3px;
background-color: #21252B;
padding: 0.5em;
}
QLineEdit[state="valid"] {
background-color: rgb(19, 19, 19);
color: rgb(64, 230, 132);
border-color: rgb(32, 64, 32);
}
QLineEdit[state="invalid"] {
background-color: rgb(32, 19, 19);
color: rgb(255, 69, 0);
border-color: rgb(64, 32, 32);
}
QLabel {
background: transparent;
color: #969b9e;
}
QLabel:hover {color: #b8c1c5;}
QPushButton {
border: 1px solid #aaaaaa;
border-radius: 3px;
padding: 5px;
}
QPushButton:hover {
background-color: #333840;
border: 1px solid #fff;
color: #fff;
}
QTableView {
border: 1px solid #444;
gridline-color: #6c6c6c;
background-color: #201F1F;
alternate-background-color:#21252B;
}
QTableView::item:pressed, QListView::item:pressed, QTreeView::item:pressed {
background: #78879b;
color: #FFFFFF;
}
QTableView::item:selected:active, QTreeView::item:selected:active, QListView::item:selected:active {
background: #3d8ec9;
}
QProgressBar {
border: 1px solid grey;
border-radius: 10px;
color: #222222;
font-weight: bold;
}
QProgressBar:horizontal {
height: 20px;
}
QProgressBar::chunk {
border-radius: 10px;
background-color: qlineargradient(
x1: 0,
y1: 0.5,
x2: 1,
y2: 0.5,
stop: 0 rgb(72, 200, 150),
stop: 1 rgb(82, 172, 215)
);
}
QScrollBar:horizontal {
height: 15px;
margin: 3px 15px 3px 15px;
border: 1px transparent #21252B;
border-radius: 4px;
background-color: #21252B;
}
QScrollBar::handle:horizontal {
background-color: #4B5362;
min-width: 5px;
border-radius: 4px;
}
QScrollBar::add-line:horizontal {
margin: 0px 3px 0px 3px;
border-image: url(:/qss_icons/rc/right_arrow_disabled.png);
width: 10px;
height: 10px;
subcontrol-position: right;
subcontrol-origin: margin;
}
QScrollBar::sub-line:horizontal {
margin: 0px 3px 0px 3px;
border-image: url(:/qss_icons/rc/left_arrow_disabled.png);
height: 10px;
width: 10px;
subcontrol-position: left;
subcontrol-origin: margin;
}
QScrollBar::add-line:horizontal:hover,QScrollBar::add-line:horizontal:on {
border-image: url(:/qss_icons/rc/right_arrow.png);
height: 10px;
width: 10px;
subcontrol-position: right;
subcontrol-origin: margin;
}
QScrollBar::sub-line:horizontal:hover, QScrollBar::sub-line:horizontal:on {
border-image: url(:/qss_icons/rc/left_arrow.png);
height: 10px;
width: 10px;
subcontrol-position: left;
subcontrol-origin: margin;
}
QScrollBar::up-arrow:horizontal, QScrollBar::down-arrow:horizontal {
background: none;
}
QScrollBar::add-page:horizontal, QScrollBar::sub-page:horizontal {
background: none;
}
QScrollBar:vertical {
background-color: #21252B;
width: 15px;
margin: 15px 3px 15px 3px;
border: 1px transparent #21252B;
border-radius: 4px;
}
QScrollBar::handle:vertical {
background-color: #4B5362;
min-height: 5px;
border-radius: 4px;
}
QScrollBar::sub-line:vertical {
margin: 3px 0px 3px 0px;
border-image: url(:/qss_icons/rc/up_arrow_disabled.png);
height: 10px;
width: 10px;
subcontrol-position: top;
subcontrol-origin: margin;
}
QScrollBar::add-line:vertical {
margin: 3px 0px 3px 0px;
border-image: url(:/qss_icons/rc/down_arrow_disabled.png);
height: 10px;
width: 10px;
subcontrol-position: bottom;
subcontrol-origin: margin;
}
QScrollBar::sub-line:vertical:hover,QScrollBar::sub-line:vertical:on {
border-image: url(:/qss_icons/rc/up_arrow.png);
height: 10px;
width: 10px;
subcontrol-position: top;
subcontrol-origin: margin;
}
QScrollBar::add-line:vertical:hover, QScrollBar::add-line:vertical:on {
border-image: url(:/qss_icons/rc/down_arrow.png);
height: 10px;
width: 10px;
subcontrol-position: bottom;
subcontrol-origin: margin;
}
QScrollBar::up-arrow:vertical, QScrollBar::down-arrow:vertical {
background: none;
}
QScrollBar::add-page:vertical, QScrollBar::sub-page:vertical {
background: none;
}
#MainLabel {
color: rgb(200, 200, 200);
font-size: 12pt;
}
#Console {
background-color: #21252B;
color: rgb(72, 200, 150);
font-family: "Roboto Mono";
font-size: 8pt;
}
#ExitBtn {
/* `border` must be set to background of flat button is painted .*/
border: none;
color: rgb(39, 39, 39);
background-color: #828a97;
padding: 0.5em;
font-weight: 400;
}
#ExitBtn:hover{
background-color: #b2bece
}
#ExitBtn:disabled {
background-color: rgba(185, 185, 185, 31);
color: rgba(64, 64, 64, 63);
}
#ButtonWithOptions QPushButton{
border-top-right-radius: 0px;
border-bottom-right-radius: 0px;
border: none;
background-color: rgb(84, 209, 178);
color: rgb(39, 39, 39);
font-weight: 400;
padding: 0.5em;
}
#ButtonWithOptions QPushButton:hover{
background-color: rgb(85, 224, 189)
}
#ButtonWithOptions QPushButton:disabled {
background-color: rgba(72, 200, 150, 31);
color: rgba(64, 64, 64, 63);
}
#ButtonWithOptions QToolButton{
border: none;
border-top-left-radius: 0px;
border-bottom-left-radius: 0px;
border-top-right-radius: 3px;
border-bottom-right-radius: 3px;
background-color: rgb(84, 209, 178);
color: rgb(39, 39, 39);
}
#ButtonWithOptions QToolButton:hover{
background-color: rgb(85, 224, 189)
}
#ButtonWithOptions QToolButton:disabled {
background-color: rgba(72, 200, 150, 31);
color: rgba(64, 64, 64, 63);
}

View file

@ -1,43 +0,0 @@
# -*- coding: utf-8 -*-
"""OpenPype terminal animation."""
import blessed
from pathlib import Path
from time import sleep
NO_TERMINAL = False
try:
term = blessed.Terminal()
except AttributeError:
# this happens when blessed cannot find proper terminal.
# If so, skip printing ascii art animation.
NO_TERMINAL = True
def play_animation():
"""Play ASCII art OpenPype animation."""
if NO_TERMINAL:
return
print(term.home + term.clear)
frame_size = 7
splash_file = Path(__file__).parent / "splash.txt"
with splash_file.open("r") as sf:
animation = sf.readlines()
animation_length = int(len(animation) / frame_size)
current_frame = 0
for _ in range(animation_length):
frame = "".join(
scanline
for y, scanline in enumerate(
animation[current_frame : current_frame + frame_size]
)
)
with term.location(0, 0):
# term.aquamarine3_bold(frame)
print(f"{term.bold}{term.aquamarine3}{frame}{term.normal}")
sleep(0.02)
current_frame += frame_size
print(term.move_y(7))

View file

@ -1,247 +0,0 @@
# -*- coding: utf-8 -*-
"""Tools used in **Igniter** GUI."""
import os
from typing import Union
from urllib.parse import urlparse, parse_qs
from pathlib import Path
import platform
import certifi
from pymongo import MongoClient
from pymongo.errors import (
ServerSelectionTimeoutError,
InvalidURI,
ConfigurationError,
OperationFailure
)
class OpenPypeVersionNotFound(Exception):
"""OpenPype version was not found in remote and local repository."""
pass
class OpenPypeVersionIncompatible(Exception):
"""OpenPype version is not compatible with the installed one (build)."""
pass
def should_add_certificate_path_to_mongo_url(mongo_url):
"""Check if should add ca certificate to mongo url.
Since 30.9.2021 cloud mongo requires newer certificates that are not
available on most of workstation. This adds path to certifi certificate
which is valid for it. To add the certificate path url must have scheme
'mongodb+srv' or has 'ssl=true' or 'tls=true' in url query.
"""
parsed = urlparse(mongo_url)
query = parse_qs(parsed.query)
lowered_query_keys = set(key.lower() for key in query.keys())
add_certificate = False
# Check if url 'ssl' or 'tls' are set to 'true'
for key in ("ssl", "tls"):
if key in query and "true" in query[key]:
add_certificate = True
break
# Check if url contains 'mongodb+srv'
if not add_certificate and parsed.scheme == "mongodb+srv":
add_certificate = True
# Check if url does already contain certificate path
if add_certificate and "tlscafile" in lowered_query_keys:
add_certificate = False
return add_certificate
def validate_mongo_connection(cnx: str) -> (bool, str):
"""Check if provided mongodb URL is valid.
Args:
cnx (str): URL to validate.
Returns:
(bool, str): True if ok, False if not and reason in str.
"""
parsed = urlparse(cnx)
if parsed.scheme not in ["mongodb", "mongodb+srv"]:
return False, "Not mongodb schema"
kwargs = {
"serverSelectionTimeoutMS": os.environ.get("AVALON_TIMEOUT", 2000)
}
# Add certificate path if should be required
if should_add_certificate_path_to_mongo_url(cnx):
kwargs["tlsCAFile"] = certifi.where()
try:
client = MongoClient(cnx, **kwargs)
client.server_info()
with client.start_session():
pass
client.close()
except ServerSelectionTimeoutError as e:
return False, f"Cannot connect to server {cnx} - {e}"
except ValueError:
return False, f"Invalid port specified {parsed.port}"
except (ConfigurationError, OperationFailure, InvalidURI) as exc:
return False, str(exc)
else:
return True, "Connection is successful"
def validate_mongo_string(mongo: str) -> (bool, str):
"""Validate string if it is mongo url acceptable by **Igniter**..
Args:
mongo (str): String to validate.
Returns:
(bool, str):
True if valid, False if not and in second part of tuple
the reason why it failed.
"""
if not mongo:
return True, "empty string"
return validate_mongo_connection(mongo)
def validate_path_string(path: str) -> (bool, str):
"""Validate string if it is path to OpenPype repository.
Args:
path (str): Path to validate.
Returns:
(bool, str):
True if valid, False if not and in second part of tuple
the reason why it failed.
"""
if not path:
return False, "empty string"
if not Path(path).exists():
return False, "path doesn't exists"
if not Path(path).is_dir():
return False, "path is not directory"
return True, "valid path"
def get_openpype_global_settings(url: str) -> dict:
"""Load global settings from Mongo database.
We are loading data from database `openpype` and collection `settings`.
There we expect document type `global_settings`.
Args:
url (str): MongoDB url.
Returns:
dict: With settings data. Empty dictionary is returned if not found.
"""
kwargs = {}
if should_add_certificate_path_to_mongo_url(url):
kwargs["tlsCAFile"] = certifi.where()
try:
# Create mongo connection
client = MongoClient(url, **kwargs)
# Access settings collection
openpype_db = os.environ.get("OPENPYPE_DATABASE_NAME") or "openpype"
col = client[openpype_db]["settings"]
# Query global settings
global_settings = col.find_one({"type": "global_settings"}) or {}
# Close Mongo connection
client.close()
except Exception:
# TODO log traceback or message
return {}
return global_settings.get("data") or {}
def get_openpype_path_from_settings(settings: dict) -> Union[str, None]:
"""Get OpenPype path from global settings.
Args:
settings (dict): mongodb url.
Returns:
path to OpenPype or None if not found
"""
paths = (
settings
.get("openpype_path", {})
.get(platform.system().lower())
) or []
# For cases when `openpype_path` is a single path
if paths and isinstance(paths, str):
paths = [paths]
return next((path for path in paths if os.path.exists(path)), None)
def get_local_openpype_path_from_settings(settings: dict) -> Union[str, None]:
"""Get OpenPype local path from global settings.
Used to download and unzip OP versions.
Args:
settings (dict): settings from DB.
Returns:
path to OpenPype or None if not found
"""
path = (
settings
.get("local_openpype_path", {})
.get(platform.system().lower())
)
if path:
return Path(path)
return None
def get_expected_studio_version_str(
staging=False, global_settings=None
) -> str:
"""Version that should be currently used in studio.
Args:
staging (bool): Get current version for staging.
global_settings (dict): Optional precached global settings.
Returns:
str: OpenPype version which should be used. Empty string means latest.
"""
mongo_url = os.environ.get("OPENPYPE_MONGO")
if global_settings is None:
global_settings = get_openpype_global_settings(mongo_url)
key = "staging_version" if staging else "production_version"
return global_settings.get(key) or ""
def load_stylesheet() -> str:
"""Load css style sheet.
Returns:
str: content of the stylesheet
"""
stylesheet_path = Path(__file__).parent.resolve() / "stylesheet.css"
return stylesheet_path.read_text()
def get_openpype_icon_path() -> str:
"""Path to OpenPype icon png file."""
return os.path.join(
os.path.dirname(os.path.abspath(__file__)),
"openpype_icon.png"
)

View file

@ -1,63 +0,0 @@
# -*- coding: utf-8 -*-
"""Working thread for update."""
from qtpy import QtCore
from .bootstrap_repos import (
BootstrapRepos,
OpenPypeVersion
)
class UpdateThread(QtCore.QThread):
"""Install Worker thread.
This class takes care of finding OpenPype version on user entered path
(or loading this path from database). If nothing is entered by user,
OpenPype will create its zip files from repositories that comes with it.
If path contains plain repositories, they are zipped and installed to
user data dir.
"""
progress = QtCore.Signal(int)
message = QtCore.Signal((str, bool))
def __init__(self, parent=None):
self._result = None
self._openpype_version = None
super().__init__(parent)
def set_version(self, openpype_version: OpenPypeVersion):
self._openpype_version = openpype_version
def result(self):
"""Result of finished installation."""
return self._result
def _set_result(self, value):
if self._result is not None:
raise AssertionError("BUG: Result was set more than once!")
self._result = value
def run(self):
"""Thread entry point.
Using :class:`BootstrapRepos` to either install OpenPype as zip files
or copy them from location specified by user or retrieved from
database.
"""
bs = BootstrapRepos(
progress_callback=self.set_progress, message=self.message)
bs.set_data_dir(OpenPypeVersion.get_local_openpype_path())
version_path = bs.install_version(self._openpype_version)
self._set_result(version_path)
def set_progress(self, progress: int) -> None:
"""Helper to set progress bar.
Args:
progress (int): Progress in percents.
"""
self.progress.emit(progress)

View file

@ -1,147 +0,0 @@
# -*- coding: utf-8 -*-
"""Progress window to show when OpenPype is updating/installing locally."""
import os
from qtpy import QtCore, QtGui, QtWidgets
from .update_thread import UpdateThread
from .bootstrap_repos import OpenPypeVersion
from .nice_progress_bar import NiceProgressBar
from .tools import load_stylesheet
class UpdateWindow(QtWidgets.QDialog):
"""OpenPype update window."""
_width = 500
_height = 100
def __init__(self, version: OpenPypeVersion, parent=None):
super(UpdateWindow, self).__init__(parent)
self._openpype_version = version
self._result_version_path = None
self.setWindowTitle(
f"OpenPype is updating ..."
)
self.setModal(True)
self.setWindowFlags(
QtCore.Qt.WindowMinimizeButtonHint
)
current_dir = os.path.dirname(os.path.abspath(__file__))
roboto_font_path = os.path.join(current_dir, "RobotoMono-Regular.ttf")
poppins_font_path = os.path.join(current_dir, "Poppins")
icon_path = os.path.join(current_dir, "openpype_icon.png")
# Install roboto font
QtGui.QFontDatabase.addApplicationFont(roboto_font_path)
for filename in os.listdir(poppins_font_path):
if os.path.splitext(filename)[1] == ".ttf":
QtGui.QFontDatabase.addApplicationFont(filename)
# Load logo
pixmap_openpype_logo = QtGui.QPixmap(icon_path)
# Set logo as icon of window
self.setWindowIcon(QtGui.QIcon(pixmap_openpype_logo))
self._pixmap_openpype_logo = pixmap_openpype_logo
self._update_thread = None
self._init_ui()
# Set stylesheet
self.setStyleSheet(load_stylesheet())
self._run_update()
def _init_ui(self):
# Main info
# --------------------------------------------------------------------
main_label = QtWidgets.QLabel(
f"<b>OpenPype</b> is updating to {self._openpype_version}", self)
main_label.setWordWrap(True)
main_label.setObjectName("MainLabel")
# Progress bar
# --------------------------------------------------------------------
progress_bar = NiceProgressBar(self)
progress_bar.setAlignment(QtCore.Qt.AlignCenter)
progress_bar.setTextVisible(False)
# add all to main
main = QtWidgets.QVBoxLayout(self)
main.addSpacing(15)
main.addWidget(main_label, 0)
main.addSpacing(15)
main.addWidget(progress_bar, 0)
main.addSpacing(15)
self._progress_bar = progress_bar
def showEvent(self, event):
super().showEvent(event)
current_size = self.size()
new_size = QtCore.QSize(
max(current_size.width(), self._width),
max(current_size.height(), self._height)
)
if current_size != new_size:
self.resize(new_size)
def _run_update(self):
"""Start install process.
This will once again validate entered path and mongo if ok, start
working thread that will do actual job.
"""
# Check if install thread is not already running
if self._update_thread and self._update_thread.isRunning():
return
self._progress_bar.setRange(0, 0)
update_thread = UpdateThread(self)
update_thread.set_version(self._openpype_version)
update_thread.message.connect(self.update_console)
update_thread.progress.connect(self._update_progress)
update_thread.finished.connect(self._installation_finished)
self._update_thread = update_thread
update_thread.start()
def get_version_path(self):
return self._result_version_path
def _installation_finished(self):
status = self._update_thread.result()
self._result_version_path = status
self._progress_bar.setRange(0, 1)
self._update_progress(100)
QtWidgets.QApplication.processEvents()
self.done(0)
def _update_progress(self, progress: int):
# not updating progress as we are not able to determine it
# correctly now. Progress bar is set to un-deterministic mode
# until we are able to get progress in better way.
"""
self._progress_bar.setRange(0, 0)
self._progress_bar.setValue(progress)
text_visible = self._progress_bar.isTextVisible()
if progress == 0:
if text_visible:
self._progress_bar.setTextVisible(False)
elif not text_visible:
self._progress_bar.setTextVisible(True)
"""
return
def update_console(self, msg: str, error: bool = False) -> None:
"""Display message in console.
Args:
msg (str): message.
error (bool): if True, print it red.
"""
print(msg)

View file

@ -1,493 +0,0 @@
# -*- coding: utf-8 -*-
"""Package to deal with saving and retrieving user specific settings."""
import os
from datetime import datetime
from abc import ABCMeta, abstractmethod
import json
# disable lru cache in Python 2
try:
from functools import lru_cache
except ImportError:
def lru_cache(maxsize):
def max_size(func):
def wrapper(*args, **kwargs):
value = func(*args, **kwargs)
return value
return wrapper
return max_size
# ConfigParser was renamed in python3 to configparser
try:
import configparser
except ImportError:
import ConfigParser as configparser
import platform
import six
import appdirs
_PLACEHOLDER = object()
class OpenPypeSecureRegistry:
"""Store information using keyring.
Registry should be used for private data that should be available only for
user.
All passed registry names will have added prefix `OpenPype/` to easier
identify which data were created by OpenPype.
Args:
name(str): Name of registry used as identifier for data.
"""
def __init__(self, name):
try:
import keyring
except Exception:
raise NotImplementedError(
"Python module `keyring` is not available."
)
# hack for cx_freeze and Windows keyring backend
if platform.system().lower() == "windows":
from keyring.backends import Windows
keyring.set_keyring(Windows.WinVaultKeyring())
# Force "OpenPype" prefix
self._name = "/".join(("OpenPype", name))
def set_item(self, name, value):
# type: (str, str) -> None
"""Set sensitive item into system's keyring.
This uses `Keyring module`_ to save sensitive stuff into system's
keyring.
Args:
name (str): Name of the item.
value (str): Value of the item.
.. _Keyring module:
https://github.com/jaraco/keyring
"""
import keyring
keyring.set_password(self._name, name, value)
@lru_cache(maxsize=32)
def get_item(self, name, default=_PLACEHOLDER):
"""Get value of sensitive item from system's keyring.
See also `Keyring module`_
Args:
name (str): Name of the item.
default (Any): Default value if item is not available.
Returns:
value (str): Value of the item.
Raises:
ValueError: If item doesn't exist and default is not defined.
.. _Keyring module:
https://github.com/jaraco/keyring
"""
import keyring
value = keyring.get_password(self._name, name)
if value:
return value
if default is not _PLACEHOLDER:
return default
# NOTE Should raise `KeyError`
raise ValueError(
"Item {}:{} does not exist in keyring.".format(self._name, name)
)
def delete_item(self, name):
# type: (str) -> None
"""Delete value stored in system's keyring.
See also `Keyring module`_
Args:
name (str): Name of the item to be deleted.
.. _Keyring module:
https://github.com/jaraco/keyring
"""
import keyring
self.get_item.cache_clear()
keyring.delete_password(self._name, name)
@six.add_metaclass(ABCMeta)
class ASettingRegistry():
"""Abstract class defining structure of **SettingRegistry** class.
It is implementing methods to store secure items into keyring, otherwise
mechanism for storing common items must be implemented in abstract
methods.
Attributes:
_name (str): Registry names.
"""
def __init__(self, name):
# type: (str) -> ASettingRegistry
super(ASettingRegistry, self).__init__()
self._name = name
self._items = {}
def set_item(self, name, value):
# type: (str, str) -> None
"""Set item to settings registry.
Args:
name (str): Name of the item.
value (str): Value of the item.
"""
self._set_item(name, value)
@abstractmethod
def _set_item(self, name, value):
# type: (str, str) -> None
# Implement it
pass
def __setitem__(self, name, value):
self._items[name] = value
self._set_item(name, value)
def get_item(self, name):
# type: (str) -> str
"""Get item from settings registry.
Args:
name (str): Name of the item.
Returns:
value (str): Value of the item.
Raises:
ValueError: If item doesn't exist.
"""
return self._get_item(name)
@abstractmethod
def _get_item(self, name):
# type: (str) -> str
# Implement it
pass
def __getitem__(self, name):
return self._get_item(name)
def delete_item(self, name):
# type: (str) -> None
"""Delete item from settings registry.
Args:
name (str): Name of the item.
"""
self._delete_item(name)
@abstractmethod
def _delete_item(self, name):
# type: (str) -> None
"""Delete item from settings.
Note:
see :meth:`openpype.lib.user_settings.ARegistrySettings.delete_item`
"""
pass
def __delitem__(self, name):
del self._items[name]
self._delete_item(name)
class IniSettingRegistry(ASettingRegistry):
"""Class using :mod:`configparser`.
This class is using :mod:`configparser` (ini) files to store items.
"""
def __init__(self, name, path):
# type: (str, str) -> IniSettingRegistry
super(IniSettingRegistry, self).__init__(name)
# get registry file
version = os.getenv("OPENPYPE_VERSION", "N/A")
self._registry_file = os.path.join(path, "{}.ini".format(name))
if not os.path.exists(self._registry_file):
with open(self._registry_file, mode="w") as cfg:
print("# Settings registry", cfg)
print("# Generated by OpenPype {}".format(version), cfg)
now = datetime.now().strftime("%d/%m/%Y %H:%M:%S")
print("# {}".format(now), cfg)
def set_item_section(
self, section, name, value):
# type: (str, str, str) -> None
"""Set item to specific section of ini registry.
If section doesn't exists, it is created.
Args:
section (str): Name of section.
name (str): Name of the item.
value (str): Value of the item.
"""
value = str(value)
config = configparser.ConfigParser()
config.read(self._registry_file)
if not config.has_section(section):
config.add_section(section)
current = config[section]
current[name] = value
with open(self._registry_file, mode="w") as cfg:
config.write(cfg)
def _set_item(self, name, value):
# type: (str, str) -> None
self.set_item_section("MAIN", name, value)
def set_item(self, name, value):
# type: (str, str) -> None
"""Set item to settings ini file.
This saves item to ``DEFAULT`` section of ini as each item there
must reside in some section.
Args:
name (str): Name of the item.
value (str): Value of the item.
"""
# this does the some, overridden just for different docstring.
# we cast value to str as ini options values must be strings.
super(IniSettingRegistry, self).set_item(name, str(value))
def get_item(self, name):
# type: (str) -> str
"""Gets item from settings ini file.
This gets settings from ``DEFAULT`` section of ini file as each item
there must reside in some section.
Args:
name (str): Name of the item.
Returns:
str: Value of item.
Raises:
ValueError: If value doesn't exist.
"""
return super(IniSettingRegistry, self).get_item(name)
@lru_cache(maxsize=32)
def get_item_from_section(self, section, name):
# type: (str, str) -> str
"""Get item from section of ini file.
This will read ini file and try to get item value from specified
section. If that section or item doesn't exist, :exc:`ValueError`
is risen.
Args:
section (str): Name of ini section.
name (str): Name of the item.
Returns:
str: Item value.
Raises:
ValueError: If value doesn't exist.
"""
config = configparser.ConfigParser()
config.read(self._registry_file)
try:
value = config[section][name]
except KeyError:
raise ValueError(
"Registry doesn't contain value {}:{}".format(section, name))
return value
def _get_item(self, name):
# type: (str) -> str
return self.get_item_from_section("MAIN", name)
def delete_item_from_section(self, section, name):
# type: (str, str) -> None
"""Delete item from section in ini file.
Args:
section (str): Section name.
name (str): Name of the item.
Raises:
ValueError: If item doesn't exist.
"""
self.get_item_from_section.cache_clear()
config = configparser.ConfigParser()
config.read(self._registry_file)
try:
_ = config[section][name]
except KeyError:
raise ValueError(
"Registry doesn't contain value {}:{}".format(section, name))
config.remove_option(section, name)
# if section is empty, delete it
if len(config[section].keys()) == 0:
config.remove_section(section)
with open(self._registry_file, mode="w") as cfg:
config.write(cfg)
def _delete_item(self, name):
"""Delete item from default section.
Note:
See :meth:`~openpype.lib.IniSettingsRegistry.delete_item_from_section`
"""
self.delete_item_from_section("MAIN", name)
class JSONSettingRegistry(ASettingRegistry):
"""Class using json file as storage."""
def __init__(self, name, path):
# type: (str, str) -> JSONSettingRegistry
super(JSONSettingRegistry, self).__init__(name)
#: str: name of registry file
self._registry_file = os.path.join(path, "{}.json".format(name))
now = datetime.now().strftime("%d/%m/%Y %H:%M:%S")
header = {
"__metadata__": {
"openpype-version": os.getenv("OPENPYPE_VERSION", "N/A"),
"generated": now
},
"registry": {}
}
if not os.path.exists(os.path.dirname(self._registry_file)):
os.makedirs(os.path.dirname(self._registry_file), exist_ok=True)
if not os.path.exists(self._registry_file):
with open(self._registry_file, mode="w") as cfg:
json.dump(header, cfg, indent=4)
@lru_cache(maxsize=32)
def _get_item(self, name):
# type: (str) -> object
"""Get item value from registry json.
Note:
See :meth:`openpype.lib.JSONSettingRegistry.get_item`
"""
with open(self._registry_file, mode="r") as cfg:
data = json.load(cfg)
try:
value = data["registry"][name]
except KeyError:
raise ValueError(
"Registry doesn't contain value {}".format(name))
return value
def get_item(self, name):
# type: (str) -> object
"""Get item value from registry json.
Args:
name (str): Name of the item.
Returns:
value of the item
Raises:
ValueError: If item is not found in registry file.
"""
return self._get_item(name)
def _set_item(self, name, value):
# type: (str, object) -> None
"""Set item value to registry json.
Note:
See :meth:`openpype.lib.JSONSettingRegistry.set_item`
"""
with open(self._registry_file, "r+") as cfg:
data = json.load(cfg)
data["registry"][name] = value
cfg.truncate(0)
cfg.seek(0)
json.dump(data, cfg, indent=4)
def set_item(self, name, value):
# type: (str, object) -> None
"""Set item and its value into json registry file.
Args:
name (str): name of the item.
value (Any): value of the item.
"""
self._set_item(name, value)
def _delete_item(self, name):
# type: (str) -> None
self._get_item.cache_clear()
with open(self._registry_file, "r+") as cfg:
data = json.load(cfg)
del data["registry"][name]
cfg.truncate(0)
cfg.seek(0)
json.dump(data, cfg, indent=4)
class OpenPypeSettingsRegistry(JSONSettingRegistry):
"""Class handling OpenPype general settings registry.
Attributes:
vendor (str): Name used for path construction.
product (str): Additional name used for path construction.
"""
def __init__(self, name=None):
self.vendor = "pypeclub"
self.product = "openpype"
if not name:
name = "openpype_settings"
path = appdirs.user_data_dir(self.product, self.vendor)
super(OpenPypeSettingsRegistry, self).__init__(name, path)

View file

@ -1,4 +0,0 @@
# -*- coding: utf-8 -*-
"""Definition of Igniter version."""
__version__ = "1.0.2"

View file

@ -1,55 +0,0 @@
; Script generated by the Inno Setup Script Wizard.
; SEE THE DOCUMENTATION FOR DETAILS ON CREATING INNO SETUP SCRIPT FILES!
#define MyAppName "OpenPype"
#define Build GetEnv("BUILD_DIR")
#define AppVer GetEnv("BUILD_VERSION")
[Setup]
; NOTE: The value of AppId uniquely identifies this application. Do not use the same AppId value in installers for other applications.
; (To generate a new GUID, click Tools | Generate GUID inside the IDE.)
AppId={{B9E9DF6A-5BDA-42DD-9F35-C09D564C4D93}
AppName={#MyAppName}
AppVersion={#AppVer}
AppVerName={#MyAppName} version {#AppVer}
AppPublisher=Ynput s.r.o
AppPublisherURL=https://ynput.io
AppSupportURL=https://ynput.io
AppUpdatesURL=https://ynput.io
DefaultDirName={autopf}\{#MyAppName}\{#AppVer}
UsePreviousAppDir=no
DisableProgramGroupPage=yes
OutputBaseFilename={#MyAppName}-{#AppVer}-install
AllowCancelDuringInstall=yes
; Uncomment the following line to run in non administrative install mode (install for current user only.)
;PrivilegesRequired=lowest
PrivilegesRequiredOverridesAllowed=dialog
SetupIconFile=igniter\openpype.ico
OutputDir=build\
Compression=lzma2
SolidCompression=yes
WizardStyle=modern
[Languages]
Name: "english"; MessagesFile: "compiler:Default.isl"
[Tasks]
Name: "desktopicon"; Description: "{cm:CreateDesktopIcon}"; GroupDescription: "{cm:AdditionalIcons}"
[InstallDelete]
; clean everything in previous installation folder
Type: filesandordirs; Name: "{app}\*"
[Files]
Source: "build\{#build}\*"; DestDir: "{app}"; Flags: ignoreversion recursesubdirs createallsubdirs
; NOTE: Don't use "Flags: ignoreversion" on any shared system files
[Icons]
Name: "{autoprograms}\{#MyAppName} {#AppVer}"; Filename: "{app}\openpype_gui.exe"
Name: "{autodesktop}\{#MyAppName} {#AppVer}"; Filename: "{app}\openpype_gui.exe"; Tasks: desktopicon
[Run]
Filename: "{app}\openpype_gui.exe"; Description: "{cm:LaunchProgram,OpenPype}"; Flags: nowait postinstall skipifsilent

3500
poetry.lock generated

File diff suppressed because it is too large Load diff

View file

@ -1,5 +0,0 @@
[virtualenvs]
in-project = true
[repositories.pype]
url = "https://distribute.openpype.io/wheels/"

View file

@ -1,188 +0,0 @@
[tool.poetry]
name = "OpenPype"
version = "3.18.6" # OpenPype
description = "Open VFX and Animation pipeline with support."
authors = ["OpenPype Team <info@openpype.io>"]
license = "MIT License"
homepage = "https://openpype.io"
documentation = "https://openpype.io/docs/artist_getting_started"
repository = "https://github.com/pypeclub/openpype"
readme = "README.md"
keywords = ["Pipeline", "Avalon", "VFX", "animation", "automation", "tracking", "asset management"]
packages = [
{include = "igniter"},
{include = "repos"},
{include = "tools"},
{include = "tests"},
{include = "docs"},
{include = "openpype"},
{include = "start.py"},
{include = "LICENSE"},
{include = "README.md"},
{include = "setup.py"},
{include = "pyproject.toml"},
{include = "poetry.lock"}
]
[tool.poetry.scripts]
openpype = 'start:boot'
[tool.poetry.dependencies]
python = ">=3.9.1,<3.10"
aiohttp = "^3.7"
aiohttp_json_rpc = "*" # TVPaint server
acre = { git = "https://github.com/pypeclub/acre.git" }
appdirs = { git = "https://github.com/ActiveState/appdirs.git", branch = "master" }
blessed = "^1.17" # openpype terminal formatting
coolname = "*"
clique = "1.6.*"
Click = "7.1.2"
dnspython = "^2.1.0"
ftrack-python-api = "^2.3.3"
arrow = "^0.17"
shotgun_api3 = {git = "https://github.com/shotgunsoftware/python-api.git", rev = "v3.3.3"}
gazu = "^0.9.3"
google-api-python-client = "^1.12.8" # sync server google support (should be separate?)
jsonschema = "^2.6.0"
keyring = "^22.0.1"
log4mongo = "^1.7"
pathlib2= "^2.3.5" # deadline submit publish job only (single place, maybe not needed?)
Pillow = "^9.0" # used in TVPaint and for slates
pyblish-base = "^1.8.11"
pynput = "^1.7.2" # idle manager in tray
pymongo = "^3.11.2"
"Qt.py" = "^1.3.3"
QtPy = "^2.3.0"
qtawesome = "0.7.3"
speedcopy = "^2.1"
six = "^1.15"
urllib3 = "1.26.16"
semver = "^2.13.0" # for version resolution
wsrpc_aiohttp = "^3.1.1" # websocket server
pywin32 = { version = "301", markers = "sys_platform == 'win32'" }
jinxed = [
{ version = "^1.0.1", markers = "sys_platform == 'darwin'" },
{ version = "^1.0.1", markers = "sys_platform == 'linux'" }
]
python3-xlib = { version="*", markers = "sys_platform == 'linux'"}
enlighten = "^1.9.0"
slack-sdk = "^3.6.0"
requests = "^2.25.1"
pysftp = "^0.2.9"
dropbox = "^11.20.0"
aiohttp-middlewares = "^2.0.0"
Unidecode = "1.2.0"
cryptography = "39.0.0"
[tool.poetry.dev-dependencies]
flake8 = "^6.0"
autopep8 = "^2.0"
coverage = "*"
cx_freeze = "6.12.0"
GitPython = "^3.1.17"
jedi = "^0.13"
Jinja2 = "^3"
markupsafe = "2.0.1"
pycodestyle = "*"
pydocstyle = "*"
linkify-it-py = "^2.0.0"
myst-parser = "^0.18.1"
pylint = "^2.4.4"
pytest = "^6.1"
pytest-cov = "*"
pytest-print = "*"
Sphinx = "^5.3"
m2r2 = "^0.3.3.post2"
sphinx-autoapi = "^2.0.1"
sphinxcontrib-napoleon = "^0.7"
revitron-sphinx-theme = { git = "https://github.com/revitron/revitron-sphinx-theme.git", branch = "master" }
recommonmark = "*"
wheel = "*"
enlighten = "*" # cool terminal progress bars
toml = "^0.10.2" # for parsing pyproject.toml
pre-commit = "*"
[tool.poetry.urls]
"Bug Tracker" = "https://github.com/pypeclub/openpype/issues"
"Discussions" = "https://github.com/pypeclub/openpype/discussions"
[[tool.poetry.source]]
name = "openpype"
url = "https://distribute.openpype.io/wheels/"
secondary = true
[build-system]
requires = ["poetry-core>=1.0.0"]
build-backend = "poetry.core.masonry.api"
[openpype]
# note: in here we can use pip version specifiers as this is installed with pip until
# Poetry will support custom location (-t flag for pip)
# https://pip.pypa.io/en/stable/cli/pip_install/#requirement-specifiers
[openpype.qtbinding.windows]
package = "PySide2"
version = "5.15.2"
[openpype.qtbinding.darwin]
package = "PySide6"
version = "6.4.3"
[openpype.qtbinding.linux]
package = "PySide2"
version = "5.15.2"
# Python dependencies that will be available only in runtime of
# OpenPype process - do not interfere with DCCs dependencies
[openpype.runtime-deps]
opencolorio = "2.2.1"
opentimelineio = "0.14.1"
# TODO: we will need to handle different linux flavours here and
# also different macos versions too.
[openpype.thirdparty.ffmpeg.windows]
url = "https://distribute.openpype.io/thirdparty/ffmpeg-4.4-windows.zip"
hash = "dd51ba29d64ee238e7c4c3c7301b19754c3f0ee2e2a729c20a0e2789e72db925"
[openpype.thirdparty.ffmpeg.linux]
url = "https://distribute.openpype.io/thirdparty/ffmpeg-4.4-linux.tgz"
hash = "10b9beda57cfbb69b9ed0ce896c0c8d99227b26ca8b9f611040c4752e365cbe9"
[openpype.thirdparty.ffmpeg.darwin]
url = "https://distribute.openpype.io/thirdparty/ffmpeg-4.4-macos.tgz"
hash = "95f43568338c275f80dc0cab1e1836a2e2270f856f0e7b204440d881dd74fbdb"
[openpype.thirdparty.oiio.windows]
url = "https://distribute.openpype.io/thirdparty/oiio_tools-2.3.10-windows.zip"
hash = "b9950f5d2fa3720b52b8be55bacf5f56d33f9e029d38ee86534995f3d8d253d2"
[openpype.thirdparty.oiio.linux]
url = "https://distribute.openpype.io/thirdparty/oiio_tools-2.2.20-linux-centos7.tgz"
hash = "3894dec7e4e521463891a869586850e8605f5fd604858b674c87323bf33e273d"
[openpype.thirdparty.ocioconfig]
url = "https://distribute.openpype.io/thirdparty/OpenColorIO-Configs-1.0.2.zip"
hash = "4ac17c1f7de83465e6f51dd352d7117e07e765b66d00443257916c828e35b6ce"
[tool.pyright]
include = [
"igniter",
"openpype",
"repos",
"vendor"
]
exclude = [
"**/node_modules",
"**/__pycache__"
]
ignore = ["website", "docs", ".git"]
reportMissingImports = true
reportMissingTypeStubs = false
[tool.poetry.extras]
docs = ["Sphinx", "furo", "sphinxcontrib-napoleon"]
[tool.pydocstyle]
inherit = false
convetion = "google"
match = "(?!test_).*\\.py"

View file

@ -5,10 +5,6 @@ max-line-length = 79
exclude =
.git,
__pycache__,
docs,
*/vendor,
website,
openpype/vendor,
*deadline/repository/custom/plugins
max-complexity = 30
@ -23,9 +19,6 @@ omit = /tests
[coverage:html]
directory = ./coverage
[tool:pytest]
norecursedirs = openpype/modules/ftrack/*
[isort]
line_length = 79
multi_line_output = 3

200
setup.py
View file

@ -1,200 +0,0 @@
# -*- coding: utf-8 -*-
"""Setup info for building OpenPype 3.0."""
import os
import re
import platform
import distutils.spawn
from pathlib import Path
from cx_Freeze import setup, Executable
from sphinx.setup_command import BuildDoc
openpype_root = Path(os.path.dirname(__file__))
def validate_thirdparty_binaries():
"""Check existence of thirdpart executables."""
low_platform = platform.system().lower()
binary_vendors_dir = os.path.join(
openpype_root,
"vendor",
"bin"
)
error_msg = (
"Missing binary dependency {}. Please fetch thirdparty dependencies."
)
# Validate existence of FFmpeg
ffmpeg_dir = os.path.join(binary_vendors_dir, "ffmpeg", low_platform)
if low_platform == "windows":
ffmpeg_dir = os.path.join(ffmpeg_dir, "bin")
ffmpeg_executable = os.path.join(ffmpeg_dir, "ffmpeg")
ffmpeg_result = distutils.spawn.find_executable(ffmpeg_executable)
if ffmpeg_result is None:
raise RuntimeError(error_msg.format("FFmpeg"))
# Validate existence of OpenImageIO (not on MacOs)
oiio_tool_path = None
if low_platform == "linux":
oiio_tool_path = os.path.join(
binary_vendors_dir,
"oiio",
low_platform,
"bin",
"oiiotool"
)
elif low_platform == "windows":
oiio_tool_path = os.path.join(
binary_vendors_dir,
"oiio",
low_platform,
"oiiotool"
)
oiio_result = None
if oiio_tool_path is not None:
oiio_result = distutils.spawn.find_executable(oiio_tool_path)
if oiio_result is None:
raise RuntimeError(error_msg.format("OpenImageIO"))
# Give ability to skip vaidation
if not os.getenv("SKIP_THIRD_PARTY_VALIDATION"):
validate_thirdparty_binaries()
version = {}
with open(openpype_root / "openpype" / "version.py") as fp:
exec(fp.read(), version)
version_match = re.search(r"(\d+\.\d+.\d+).*", version["__version__"])
__version__ = version_match.group(1)
low_platform_name = platform.system().lower()
IS_WINDOWS = low_platform_name == "windows"
IS_LINUX = low_platform_name == "linux"
IS_MACOS = low_platform_name == "darwin"
base = None
if IS_WINDOWS:
base = "Win32GUI"
# -----------------------------------------------------------------------
# build_exe
# Build options for cx_Freeze. Manually add/exclude packages and binaries
install_requires = [
"appdirs",
"cx_Freeze",
"keyring",
"clique",
"jsonschema",
"pathlib2",
"pkg_resources",
"PIL",
"pymongo",
"pynput",
"jinxed",
"blessed",
"Qt",
"qtpy",
"speedcopy",
"googleapiclient",
"httplib2",
# Harmony implementation
"filecmp",
"dns",
# Python defaults (cx_Freeze skip them by default)
"dbm",
"sqlite3",
"dataclasses",
"timeit"
]
includes = []
# WARNING: As of cx_freeze there is a bug?
# when this is empty, its hooks will not kick in
# and won't clean platform irrelevant modules
# like dbm mentioned above.
excludes = [
"openpype"
]
bin_includes = [
"vendor"
]
include_files = [
"igniter",
"openpype",
"LICENSE",
"README.md"
]
if IS_WINDOWS:
install_requires.extend([
# `pywin32` packages
"win32ctypes",
"win32comext",
"pythoncom"
])
icon_path = openpype_root / "igniter" / "openpype.ico"
mac_icon_path = openpype_root / "igniter" / "openpype.icns"
build_exe_options = dict(
packages=install_requires,
includes=includes,
excludes=excludes,
bin_includes=bin_includes,
include_files=include_files,
optimize=0
)
bdist_mac_options = dict(
bundle_name=f"OpenPype {__version__}",
iconfile=mac_icon_path
)
executables = [
Executable(
"start.py",
base=base,
target_name="openpype_gui",
icon=icon_path.as_posix()
),
Executable(
"start.py",
base=None,
target_name="openpype_console",
icon=icon_path.as_posix()
),
]
if IS_LINUX:
executables.append(
Executable(
"app_launcher.py",
base=None,
target_name="app_launcher",
icon=icon_path.as_posix()
)
)
setup(
name="OpenPype",
version=__version__,
description="OpenPype",
cmdclass={"build_sphinx": BuildDoc},
options={
"build_exe": build_exe_options,
"bdist_mac": bdist_mac_options,
"build_sphinx": {
"project": "OpenPype",
"version": __version__,
"release": __version__,
"source_dir": (openpype_root / "docs" / "source").as_posix(),
"build_dir": (openpype_root / "docs" / "build").as_posix()
}
},
executables=executables,
packages=[]
)

1213
start.py

File diff suppressed because it is too large Load diff

View file

@ -1 +0,0 @@
I have run

View file

@ -1,196 +0,0 @@
<#
.SYNOPSIS
Helper script to build OpenPype.
.DESCRIPTION
This script will detect Python installation, and build OpenPype to `build`
directory using existing virtual environment created by Poetry (or
by running `/tools/create_venv.ps1`). It will then shuffle dependencies in
build folder to optimize for different Python versions (2/3) in Python host.
.EXAMPLE
PS> .\build.ps1
.EXAMPLE
To build without automatical submodule update:
PS> .\build.ps1 --no-submodule-update
.LINK
https://openpype.io/docs
#>
$arguments=$ARGS
$disable_submodule_update=""
if($arguments -eq "--no-submodule-update") {
$disable_submodule_update=$true
}
$current_dir = Get-Location
$script_dir = Split-Path -Path $MyInvocation.MyCommand.Definition -Parent
$openpype_root = (Get-Item $script_dir).parent.FullName
# Install PSWriteColor to support colorized output to terminal
$env:PSModulePath = $env:PSModulePath + ";$($openpype_root)\tools\modules\powershell"
function Start-Progress {
param([ScriptBlock]$code)
$scroll = "/-\|/-\|"
$idx = 0
$job = Invoke-Command -ComputerName $env:ComputerName -ScriptBlock { $code } -AsJob
$origpos = $host.UI.RawUI.CursorPosition
# $origpos.Y -= 1
while (($job.State -eq "Running") -and ($job.State -ne "NotStarted"))
{
$host.UI.RawUI.CursorPosition = $origpos
Write-Host $scroll[$idx] -NoNewline
$idx++
if ($idx -ge $scroll.Length)
{
$idx = 0
}
Start-Sleep -Milliseconds 100
}
# It's over - clear the activity indicator.
$host.UI.RawUI.CursorPosition = $origpos
Write-Host ' '
<#
.SYNOPSIS
Display spinner for running job
.PARAMETER code
Job to display spinner for
#>
}
function Exit-WithCode($exitcode) {
# Only exit this host process if it's a child of another PowerShell parent process...
$parentPID = (Get-CimInstance -ClassName Win32_Process -Filter "ProcessId=$PID" | Select-Object -Property ParentProcessId).ParentProcessId
$parentProcName = (Get-CimInstance -ClassName Win32_Process -Filter "ProcessId=$parentPID" | Select-Object -Property Name).Name
if ('powershell.exe' -eq $parentProcName) { $host.SetShouldExit($exitcode) }
exit $exitcode
}
function Show-PSWarning() {
if ($PSVersionTable.PSVersion.Major -lt 7) {
Write-Color -Text "!!! ", "You are using old version of PowerShell - ", "$($PSVersionTable.PSVersion.Major).$($PSVersionTable.PSVersion.Minor)" -Color Red, Yellow, White
Write-Color -Text " Please update to at least 7.0 - ", "https://github.com/PowerShell/PowerShell/releases" -Color Yellow, White
Exit-WithCode 1
}
}
function Install-Poetry() {
Write-Color -Text ">>> ", "Installing Poetry ... " -Color Green, Gray
$env:POETRY_HOME="$openpype_root\.poetry"
(Invoke-WebRequest -Uri https://raw.githubusercontent.com/python-poetry/poetry/master/install-poetry.py -UseBasicParsing).Content | python -
}
$art = @"
. . .. . ..
_oOOP3OPP3Op_. .
.PPpo~. .. ~2p. .. .... . .
.Ppo . .pPO3Op.. . O:. . . .
.3Pp . oP3'. 'P33. . 4 .. . . . .. . . .
.~OP 3PO. .Op3 : . .. _____ _____ _____
.P3O . oP3oP3O3P' . . . . / /./ /./ /
O3:. O3p~ . .:. . ./____/./____/ /____/
'P . 3p3. oP3~. ..P:. . . .. . . .. . . .
. ': . Po' .Opo'. .3O. . o[ by Pype Club ]]]==- - - . .
. '_ .. . . _OP3.. . .https://openpype.io.. .
~P3.OPPPO3OP~ . .. .
. ' '. . .. . . . .. .
"@
Write-Host $art -ForegroundColor DarkGreen
# Enable if PS 7.x is needed.
# Show-PSWarning
$env:_INSIDE_OPENPYPE_TOOL = "1"
if (-not (Test-Path 'env:POETRY_HOME')) {
$env:POETRY_HOME = "$openpype_root\.poetry"
}
Set-Location -Path $openpype_root
$version_file = Get-Content -Path "$($openpype_root)\openpype\version.py"
$result = [regex]::Matches($version_file, '__version__ = "(?<version>\d+\.\d+.\d+.*)"')
$openpype_version = $result[0].Groups['version'].Value
if (-not $openpype_version) {
Write-Color -Text "!!! ", "Cannot determine OpenPype version." -Color Yellow, Gray
Exit-WithCode 1
}
# Create build directory if not exist
if (-not (Test-Path -PathType Container -Path "$($openpype_root)\build")) {
New-Item -ItemType Directory -Force -Path "$($openpype_root)\build"
}
Write-Color -Text "--- ", "Cleaning build directory ..." -Color Yellow, Gray
try {
Remove-Item -Recurse -Force "$($openpype_root)\build\*"
}
catch {
Write-Color -Text "!!! ", "Cannot clean build directory, possibly because process is using it." -Color Red, Gray
Write-Color -Text $_.Exception.Message -Color Red
Exit-WithCode 1
}
if (-not $disable_submodule_update) {
Write-Color -Text ">>> ", "Making sure submodules are up-to-date ..." -Color Green, Gray
& git submodule update --init --recursive
} else {
Write-Color -Text "*** ", "Not updating submodules ..." -Color Green, Gray
}
Write-Color -Text ">>> ", "OpenPype [ ", $openpype_version, " ]" -Color Green, White, Cyan, White
Write-Color -Text ">>> ", "Reading Poetry ... " -Color Green, Gray -NoNewline
if (-not (Test-Path -PathType Container -Path "$($env:POETRY_HOME)\bin")) {
Write-Color -Text "NOT FOUND" -Color Yellow
Write-Color -Text "*** ", "We need to install Poetry create virtual env first ..." -Color Yellow, Gray
& "$openpype_root\tools\create_env.ps1"
} else {
Write-Color -Text "OK" -Color Green
}
Write-Color -Text ">>> ", "Cleaning cache files ... " -Color Green, Gray -NoNewline
Get-ChildItem $openpype_root -Filter "*.pyc" -Force -Recurse | Where-Object { $_.FullName -inotmatch 'build' } | Remove-Item -Force
Get-ChildItem $openpype_root -Filter "*.pyo" -Force -Recurse | Where-Object { $_.FullName -inotmatch 'build' } | Remove-Item -Force
Get-ChildItem $openpype_root -Filter "__pycache__" -Force -Recurse | Where-Object { $_.FullName -inotmatch 'build' } | Remove-Item -Force -Recurse
Write-Color -Text "OK" -Color green
Write-Color -Text ">>> ", "Building OpenPype ..." -Color Green, White
$startTime = [int][double]::Parse((Get-Date -UFormat %s))
$out = & "$($env:POETRY_HOME)\bin\poetry" run python setup.py build 2>&1
Set-Content -Path "$($openpype_root)\build\build.log" -Value $out
if ($LASTEXITCODE -ne 0)
{
Write-Color -Text "------------------------------------------" -Color Red
Get-Content "$($openpype_root)\build\build.log"
Write-Color -Text "------------------------------------------" -Color Yellow
Write-Color -Text "!!! ", "Build failed. Check the log: ", ".\build\build.log" -Color Red, Yellow, White
Exit-WithCode $LASTEXITCODE
}
Set-Content -Path "$($openpype_root)\build\build.log" -Value $out
& "$($env:POETRY_HOME)\bin\poetry" run python "$($openpype_root)\tools\build_dependencies.py"
Write-Color -Text ">>> ", "Restoring current directory" -Color Green, Gray
Set-Location -Path $current_dir
$endTime = [int][double]::Parse((Get-Date -UFormat %s))
try
{
New-BurntToastNotification -AppLogo "$openpype_root/openpype/resources/icons/openpype_icon.png" -Text "OpenPype build complete!", "All done in $( $endTime - $startTime ) secs. You will find OpenPype and build log in build directory."
} catch {}
Write-Color -Text "*** ", "All done in ", $($endTime - $startTime), " secs. You will find OpenPype and build log in ", "'.\build'", " directory." -Color Green, Gray, White, Gray, White, Gray

View file

@ -1,230 +0,0 @@
#!/usr/bin/env bash
# Build Pype using existing virtual environment.
art () {
cat <<-EOF
. . .. . ..
_oOOP3OPP3Op_. .
.PPpo~· ·· ~2p. ·· ···· · ·
·Ppo · .pPO3Op.· · O:· · · ·
.3Pp · oP3'· 'P33· · 4 ·· · · · ·· · · ·
·~OP 3PO· .Op3 : · ·· _____ _____ _____
·P3O · oP3oP3O3P' · · · · / /·/ /·/ /
O3:· O3p~ · ·:· · ·/____/·/____/ /____/
'P · 3p3· oP3~· ·.P:· · · ·· · · ·· · · ·
· ': · Po' ·Opo'· .3O· . o[ by Pype Club ]]]==- - - · ·
· '_ .. · . _OP3·· · ·https://openpype.io·· ·
~P3·OPPPO3OP~ · ·· ·
· ' '· · ·· · · · ·· ·
EOF
}
# Colors for terminal
RST='\033[0m' # Text Reset
# Regular Colors
Black='\033[0;30m' # Black
Red='\033[0;31m' # Red
Green='\033[0;32m' # Green
Yellow='\033[0;33m' # Yellow
Blue='\033[0;34m' # Blue
Purple='\033[0;35m' # Purple
Cyan='\033[0;36m' # Cyan
White='\033[0;37m' # White
# Bold
BBlack='\033[1;30m' # Black
BRed='\033[1;31m' # Red
BGreen='\033[1;32m' # Green
BYellow='\033[1;33m' # Yellow
BBlue='\033[1;34m' # Blue
BPurple='\033[1;35m' # Purple
BCyan='\033[1;36m' # Cyan
BWhite='\033[1;37m' # White
# Bold High Intensity
BIBlack='\033[1;90m' # Black
BIRed='\033[1;91m' # Red
BIGreen='\033[1;92m' # Green
BIYellow='\033[1;93m' # Yellow
BIBlue='\033[1;94m' # Blue
BIPurple='\033[1;95m' # Purple
BICyan='\033[1;96m' # Cyan
BIWhite='\033[1;97m' # White
args=$@
disable_submodule_update=0
while :; do
case $1 in
--no-submodule-update)
disable_submodule_update=1
;;
--)
shift
break
;;
*)
break
esac
shift
done
##############################################################################
# Detect required version of python
# Globals:
# colors
# PYTHON
# Arguments:
# None
# Returns:
# None
###############################################################################
detect_python () {
echo -e "${BIGreen}>>>${RST} Using python \c"
command -v python >/dev/null 2>&1 || { echo -e "${BIRed}- NOT FOUND${RST} ${BIYellow}You need Python 3.9 installed to continue.${RST}"; return 1; }
local version_command
version_command="import sys;print('{0}.{1}'.format(sys.version_info[0], sys.version_info[1]))"
local python_version
python_version="$(python <<< ${version_command})"
oIFS="$IFS"
IFS=.
set -- $python_version
IFS="$oIFS"
if [ "$1" -ge "3" ] && [ "$2" -ge "9" ] ; then
if [ "$2" -gt "9" ] ; then
echo -e "${BIWhite}[${RST} ${BIRed}$1.$2 ${BIWhite}]${RST} - ${BIRed}FAILED${RST} ${BIYellow}Version is new and unsupported, use${RST} ${BIPurple}3.9.x${RST}"; return 1;
else
echo -e "${BIWhite}[${RST} ${BIGreen}$1.$2${RST} ${BIWhite}]${RST}"
fi
else
command -v python >/dev/null 2>&1 || { echo -e "${BIRed}$1.$2$ - ${BIRed}FAILED${RST} ${BIYellow}Version is old and unsupported${RST}"; return 1; }
fi
}
##############################################################################
# Clean pyc files in specified directory
# Globals:
# None
# Arguments:
# Optional path to clean
# Returns:
# None
###############################################################################
clean_pyc () {
local path
path=$openpype_root
echo -e "${BIGreen}>>>${RST} Cleaning pyc at [ ${BIWhite}$path${RST} ] ... \c"
find "$path" -path ./build -o -regex '^.*\(__pycache__\|\.py[co]\)$' -delete
echo -e "${BIGreen}DONE${RST}"
}
##############################################################################
# Return absolute path
# Globals:
# None
# Arguments:
# Path to resolve
# Returns:
# None
###############################################################################
realpath () {
echo $(cd $(dirname "$1") || return; pwd)/$(basename "$1")
}
# Main
main () {
echo -e "${BGreen}"
art
echo -e "${RST}"
detect_python || return 1
# Directories
openpype_root=$(dirname $(dirname "$(realpath ${BASH_SOURCE[0]})"))
pushd "$openpype_root" > /dev/null || return > /dev/null
version_command="import os;import re;version={};exec(open(os.path.join('$openpype_root', 'openpype', 'version.py')).read(), version);print(re.search(r'(\d+\.\d+.\d+).*', version['__version__'])[1]);"
openpype_version="$(python <<< ${version_command})"
_inside_openpype_tool="1"
if [[ -z $POETRY_HOME ]]; then
export POETRY_HOME="$openpype_root/.poetry"
fi
echo -e "${BIYellow}---${RST} Cleaning build directory ..."
rm -rf "$openpype_root/build" && mkdir "$openpype_root/build" > /dev/null
echo -e "${BIGreen}>>>${RST} Building OpenPype ${BIWhite}[${RST} ${BIGreen}$openpype_version${RST} ${BIWhite}]${RST}"
echo -e "${BIGreen}>>>${RST} Cleaning cache files ..."
clean_pyc
echo -e "${BIGreen}>>>${RST} Reading Poetry ... \c"
if [ -f "$POETRY_HOME/bin/poetry" ]; then
echo -e "${BIGreen}OK${RST}"
else
echo -e "${BIYellow}NOT FOUND${RST}"
echo -e "${BIYellow}***${RST} We need to install Poetry and virtual env ..."
. "$openpype_root/tools/create_env.sh" || { echo -e "${BIRed}!!!${RST} Poetry installation failed"; return 1; }
fi
if [ "$disable_submodule_update" == 1 ]; then
echo -e "${BIYellow}***${RST} Not updating submodules ..."
else
echo -e "${BIGreen}>>>${RST} Making sure submodules are up-to-date ..."
git submodule update --init --recursive || { echo -e "${BIRed}!!!${RST} Poetry installation failed"; return 1; }
fi
echo -e "${BIGreen}>>>${RST} Building ..."
if [[ "$OSTYPE" == "linux-gnu"* ]]; then
"$POETRY_HOME/bin/poetry" run python "$openpype_root/setup.py" build &> "$openpype_root/build/build.log" || { echo -e "${BIRed}------------------------------------------${RST}"; cat "$openpype_root/build/build.log"; echo -e "${BIRed}------------------------------------------${RST}"; echo -e "${BIRed}!!!${RST} Build failed, see the build log."; return 1; }
elif [[ "$OSTYPE" == "darwin"* ]]; then
"$POETRY_HOME/bin/poetry" run python "$openpype_root/setup.py" bdist_mac &> "$openpype_root/build/build.log" || { echo -e "${BIRed}------------------------------------------${RST}"; cat "$openpype_root/build/build.log"; echo -e "${BIRed}------------------------------------------${RST}"; echo -e "${BIRed}!!!${RST} Build failed, see the build log."; return 1; }
fi
"$POETRY_HOME/bin/poetry" run python "$openpype_root/tools/build_dependencies.py" || { echo -e "${BIRed}!!!>${RST} ${BIYellow}Failed to process dependencies${RST}"; return 1; }
if [[ "$OSTYPE" == "darwin"* ]]; then
# fix cx_Freeze libs issue
echo -e "${BIGreen}>>>${RST} Fixing libs ..."
mv "$openpype_root/build/OpenPype $openpype_version.app/Contents/MacOS/dependencies/cx_Freeze" "$openpype_root/build/OpenPype $openpype_version.app/Contents/MacOS/lib/" || { echo -e "${BIRed}!!!>${RST} ${BIYellow}Can't move cx_Freeze libs${RST}"; return 1; }
# force hide icon from Dock
defaults write "$openpype_root/build/OpenPype $openpype_version.app/Contents/Info" LSUIElement 1
# fix code signing issue
echo -e "${BIGreen}>>>${RST} Fixing code signatures ...\c"
codesign --remove-signature "$openpype_root/build/OpenPype $openpype_version.app/Contents/MacOS/openpype_console" || { echo -e "${BIRed}FAILED${RST}"; return 1; }
codesign --remove-signature "$openpype_root/build/OpenPype $openpype_version.app/Contents/MacOS/openpype_gui" || { echo -e "${BIRed}FAILED${RST}"; return 1; }
echo -e "${BIGreen}DONE${RST}"
if command -v create-dmg > /dev/null 2>&1; then
echo -e "${BIGreen}>>>${RST} Creating dmg image ...\c"
create-dmg \
--volname "OpenPype $openpype_version Installer" \
--window-pos 200 120 \
--window-size 600 300 \
--app-drop-link 100 50 \
"$openpype_root/build/OpenPype-Installer-$openpype_version.dmg" \
"$openpype_root/build/OpenPype $openpype_version.app"
test $? -eq 0 || { echo -e "${BIRed}FAILED${RST}"; return 1; }
echo -e "${BIGreen}DONE${RST}"
else
echo -e "${BIYellow}!!!${RST} ${BIWhite}create-dmg${RST} command is not available."
fi
fi
echo -e "${BICyan}>>>${RST} All done. You will find OpenPype and build log in \c"
echo -e "${BIWhite}$openpype_root/build${RST} directory."
}
return_code=0
main || return_code=$?
exit $return_code

View file

@ -1,226 +0,0 @@
# -*- coding: utf-8 -*-
"""Script to fix frozen dependencies.
Because Pype code needs to run under different versions of Python interpreter
(yes, even Python 2) we need to include all dependencies as source code
without Python's system stuff. Cx-freeze puts everything into lib and compile
it as .pyc/.pyo files and that doesn't work for hosts like Maya 2020 with
their own Python interpreter and libraries.
This script will take ``site-packages`` and copy them to built Pype under
``dependencies`` directory. It will then compare stuff inside with ``lib``
folder in frozen Pype, removing duplicities from there.
This must be executed after build finished and it is done by build PowerShell
script.
Note: Speedcopy can be used for copying if server-side copy is important for
speed.
"""
import os
import sys
import site
from sysconfig import get_platform
import platform
import subprocess
from pathlib import Path
import shutil
import blessed
import enlighten
import time
import re
term = blessed.Terminal()
manager = enlighten.get_manager()
def _print(msg: str, type: int = 0) -> None:
"""Print message to console.
Args:
msg (str): message to print
type (int): type of message (0 info, 1 error, 2 note)
"""
if type == 0:
header = term.aquamarine3(">>> ")
elif type == 1:
header = term.orangered2("!!! ")
elif type == 2:
header = term.tan1("... ")
else:
header = term.darkolivegreen3("--- ")
print(f"{header}{msg}")
def count_folders(path: Path) -> int:
"""Recursively count items inside given Path.
Args:
path (Path): Path to count.
Returns:
int: number of items.
"""
cnt = 0
for child in path.iterdir():
if child.is_dir():
cnt += 1
cnt += count_folders(child)
return cnt
_print("Starting dependency cleanup ...")
start_time = time.time_ns()
# path to venv site packages
sites = site.getsitepackages()
# WARNING: this assumes that all we've got is path to venv itself and
# another path ending with 'site-packages' as is default. But because
# this must run under different platform, we cannot easily check if this path
# is the one, because under Linux and macOS site-packages are in different
# location.
site_pkg = None
for s in sites:
site_pkg = Path(s)
if site_pkg.name == "site-packages":
break
_print("Getting venv site-packages ...")
assert site_pkg, "No venv site-packages are found."
_print(f"Working with: {site_pkg}", 2)
openpype_root = Path(os.path.dirname(__file__)).parent
version = {}
with open(openpype_root / "openpype" / "version.py") as fp:
exec(fp.read(), version)
version_match = re.search(r"(\d+\.\d+.\d+).*", version["__version__"])
openpype_version = version_match[1]
# create full path
if platform.system().lower() == "darwin":
build_dir = openpype_root.joinpath(
"build",
f"OpenPype {openpype_version}.app",
"Contents",
"MacOS")
else:
build_subdir = f"exe.{get_platform()}-{sys.version[:3]}"
build_dir = openpype_root / "build" / build_subdir
_print(f"Using build at {build_dir}", 2)
if not build_dir.exists():
_print("Build directory doesn't exist", 1)
_print("Probably freezing of code failed. Check ./build/build.log", 3)
sys.exit(1)
def _progress(_base, _names):
progress_bar.update()
return []
deps_dir = build_dir / "dependencies"
vendor_dir = build_dir / "vendor"
vendor_src = openpype_root / "vendor"
# copy vendor files
_print("Copying vendor files ...")
total_files = count_folders(vendor_src)
progress_bar = enlighten.Counter(
total=total_files, desc="Copying vendor files ...",
units="%", color=(64, 128, 222))
shutil.copytree(vendor_src.as_posix(),
vendor_dir.as_posix(),
ignore=_progress)
progress_bar.close()
# copy all files
_print("Copying dependencies ...")
total_files = count_folders(site_pkg)
progress_bar = enlighten.Counter(
total=total_files, desc="Processing Dependencies",
units="%", color=(53, 178, 202))
shutil.copytree(site_pkg.as_posix(),
deps_dir.as_posix(),
ignore=_progress)
progress_bar.close()
# iterate over frozen libs and create list to delete
libs_dir = build_dir / "lib"
# On Linux use rpath from source libraries in destination libraries
if platform.system().lower() == "linux":
src_pyside_dir = openpype_root / "vendor" / "python" / "PySide2"
dst_pyside_dir = build_dir / "vendor" / "python" / "PySide2"
src_rpath_per_so_file = {}
for filepath in src_pyside_dir.glob("*.so"):
filename = filepath.name
rpath = (
subprocess.check_output(["patchelf", "--print-rpath", filepath])
.decode("utf-8")
.strip()
)
src_rpath_per_so_file[filename] = rpath
for filepath in dst_pyside_dir.glob("*.so"):
filename = filepath.name
if filename not in src_rpath_per_so_file:
continue
src_rpath = src_rpath_per_so_file[filename]
subprocess.check_call(
["patchelf", "--set-rpath", src_rpath, filepath]
)
to_delete = []
# _print("Finding duplicates ...")
deps_items = list(deps_dir.iterdir())
item_count = len(list(libs_dir.iterdir()))
find_progress_bar = enlighten.Counter(
total=item_count, desc="Finding duplicates", units="%",
color=(56, 211, 159))
for d in libs_dir.iterdir():
if (deps_dir / d.name) in deps_items:
to_delete.append(d)
# _print(f"found {d}", 3)
find_progress_bar.update()
find_progress_bar.close()
# add openpype and igniter in libs too
to_delete.append(libs_dir / "openpype")
to_delete.append(libs_dir / "igniter")
to_delete.append(libs_dir / "openpype.pth")
to_delete.append(deps_dir / "openpype.pth")
# delete duplicates
# _print(f"Deleting {len(to_delete)} duplicates ...")
delete_progress_bar = enlighten.Counter(
total=len(to_delete), desc="Deleting duplicates", units="%",
color=(251, 192, 32))
for d in to_delete:
if d.is_dir():
shutil.rmtree(d)
else:
try:
d.unlink()
except FileNotFoundError:
# skip non-existent silently
pass
delete_progress_bar.update()
delete_progress_bar.close()
end_time = time.time_ns()
total_time = (end_time - start_time) / 1000000000
_print(f"Dependency cleanup done in {total_time} secs.")

View file

@ -1,177 +0,0 @@
<#
.SYNOPSIS
Helper script to build OpenPype Installer.
.DESCRIPTION
This script will use already built OpenPype (in `build` directory) and
create Windows installer from it using Inno Setup (https://jrsoftware.org/)
.EXAMPLE
PS> .\build_win_installer.ps1
#>
$current_dir = Get-Location
$script_dir = Split-Path -Path $MyInvocation.MyCommand.Definition -Parent
$openpype_root = (Get-Item $script_dir).parent.FullName
# Install PSWriteColor to support colorized output to terminal
$env:PSModulePath = $env:PSModulePath + ";$($openpype_root)\tools\modules\powershell"
function Start-Progress {
param([ScriptBlock]$code)
$scroll = "/-\|/-\|"
$idx = 0
$job = Invoke-Command -ComputerName $env:ComputerName -ScriptBlock { $code } -AsJob
$origpos = $host.UI.RawUI.CursorPosition
# $origpos.Y -= 1
while (($job.State -eq "Running") -and ($job.State -ne "NotStarted"))
{
$host.UI.RawUI.CursorPosition = $origpos
Write-Host $scroll[$idx] -NoNewline
$idx++
if ($idx -ge $scroll.Length)
{
$idx = 0
}
Start-Sleep -Milliseconds 100
}
# It's over - clear the activity indicator.
$host.UI.RawUI.CursorPosition = $origpos
Write-Host ' '
<#
.SYNOPSIS
Display spinner for running job
.PARAMETER code
Job to display spinner for
#>
}
function Exit-WithCode($exitcode) {
# Only exit this host process if it's a child of another PowerShell parent process...
$parentPID = (Get-CimInstance -ClassName Win32_Process -Filter "ProcessId=$PID" | Select-Object -Property ParentProcessId).ParentProcessId
$parentProcName = (Get-CimInstance -ClassName Win32_Process -Filter "ProcessId=$parentPID" | Select-Object -Property Name).Name
if ('powershell.exe' -eq $parentProcName) { $host.SetShouldExit($exitcode) }
exit $exitcode
}
function Show-PSWarning() {
if ($PSVersionTable.PSVersion.Major -lt 7) {
Write-Color -Text "!!! ", "You are using old version of PowerShell - ", "$($PSVersionTable.PSVersion.Major).$($PSVersionTable.PSVersion.Minor)" -Color Red, Yellow, White
Write-Color -Text " Please update to at least 7.0 - ", "https://github.com/PowerShell/PowerShell/releases" -Color Yellow, White
Exit-WithCode 1
}
}
$art = @"
. . .. . ..
_oOOP3OPP3Op_. .
.PPpo~. .. ~2p. .. .... . .
.Ppo . .pPO3Op.. . O:. . . .
.3Pp . oP3'. 'P33. . 4 .. . . . .. . . .
.~OP 3PO. .Op3 : . .. _____ _____ _____
.P3O . oP3oP3O3P' . . . . / /./ /./ /
O3:. O3p~ . .:. . ./____/./____/ /____/
'P . 3p3. oP3~. ..P:. . . .. . . .. . . .
. ': . Po' .Opo'. .3O. . o[ by Pype Club ]]]==- - - . .
. '_ .. . . _OP3.. . .https://openpype.io.. .
~P3.OPPPO3OP~ . .. .
. ' '. . .. . . . .. .
"@
Write-Host $art -ForegroundColor DarkGreen
# Enable if PS 7.x is needed.
# Show-PSWarning
Set-Location -Path $openpype_root
$version_file = Get-Content -Path "$($openpype_root)\openpype\version.py"
$result = [regex]::Matches($version_file, '__version__ = "(?<version>\d+\.\d+.\d+.*)"')
$openpype_version = $result[0].Groups['version'].Value
if (-not $openpype_version) {
Write-Color -Text "!!! ", "Cannot determine OpenPype version." -Color Yellow, Gray
Exit-WithCode 1
}
$env:BUILD_VERSION = $openpype_version
iscc
Write-Color ">>> ", "Detecting host Python ... " -Color Green, White -NoNewline
$python = "python"
if (Get-Command "pyenv" -ErrorAction SilentlyContinue) {
$pyenv_python = & pyenv which python
if (Test-Path -PathType Leaf -Path "$($pyenv_python)") {
$python = $pyenv_python
}
}
if (-not (Get-Command $python -ErrorAction SilentlyContinue)) {
Write-Color "!!! ", "Python not detected" -Color Red, Yellow
Set-Location -Path $current_dir
Exit-WithCode 1
}
$version_command = @'
import sys
print('{0}.{1}'.format(sys.version_info[0], sys.version_info[1]))
'@
$p = & $python -c $version_command
$env:PYTHON_VERSION = $p
$m = $p -match '(\d+)\.(\d+)'
if(-not $m) {
Write-Color "!!! ", "Cannot determine version" -Color Red, Yellow
Set-Location -Path $current_dir
Exit-WithCode 1
}
# We are supporting python 3.9
if (($matches[1] -lt 3) -or ($matches[2] -lt 9)) {
Write-Host "FAILED Version [ $p ] is old and unsupported" -ForegroundColor red
Set-Location -Path $current_dir
Exit-WithCode 1
} elseif (($matches[1] -eq 3) -and ($matches[2] -gt 9)) {
Write-Host "WARNING Version [ $p ] is unsupported, use at your own risk." -ForegroundColor yellow
Write-Host "*** " -NoNewline -ForegroundColor yellow
Write-Host "OpenPype supports only Python 3.9" -ForegroundColor white
} else {
Write-Host "OK [ $p ]" -ForegroundColor green
}
Write-Color -Text ">>> ", "Creating OpenPype installer ... " -Color Green, White
$build_dir_command = @"
import sys
from distutils.util import get_platform
print('exe.{}-{}'.format(get_platform(), sys.version[0:3]))
"@
$build_dir = & $python -c $build_dir_command
Write-Color -Text "--- ", "Build directory ", "${build_dir}" -Color Green, Gray, White
$env:BUILD_DIR = $build_dir
if (-not (Get-Command iscc -errorAction SilentlyContinue -ErrorVariable ProcessError)) {
Write-Color -Text "!!! ", "Cannot find Inno Setup command" -Color Red, Yellow
Write-Color "!!! You can download it at https://jrsoftware.org/" -ForegroundColor red
Exit-WithCode 1
}
& iscc "$openpype_root\inno_setup.iss"
if ($LASTEXITCODE -ne 0) {
Write-Color -Text "!!! ", "Creating installer failed." -Color Red, Yellow
Exit-WithCode 1
}
Write-Color -Text ">>> ", "Restoring current directory" -Color Green, Gray
Set-Location -Path $current_dir
try {
New-BurntToastNotification -AppLogo "$openpype_root/openpype/resources/icons/openpype_icon.png" -Text "OpenPype build complete!", "All done. You will find You will find OpenPype installer in '.\build' directory."
} catch {}
Write-Color -Text "*** ", "All done. You will find OpenPype installer in ", "'.\build'", " directory." -Color Green, Gray, White, Gray

View file

@ -1,231 +0,0 @@
import re
import sys
from semver import VersionInfo
from git import Repo
from optparse import OptionParser
from github import Github
import os
def get_release_type_github(Log, github_token):
minor_labels = ["Bump Minor"]
g = Github(github_token)
repo = g.get_repo("ynput/OpenPype")
labels = set()
for line in Log.splitlines():
match = re.search("pull request #(\d+)", line)
if match:
pr_number = match.group(1)
try:
pr = repo.get_pull(int(pr_number))
except:
continue
for label in pr.labels:
labels.add(label.name)
if any(label in labels for label in minor_labels):
return "minor"
else:
return "patch"
# TODO: if all is working fine, this part can be cleaned up eventually
# if any(label in labels for label in patch_labels):
# return "patch"
return None
def remove_prefix(text, prefix):
return text[text.startswith(prefix) and len(prefix):]
def get_last_version(match):
repo = Repo()
assert not repo.bare
version_types = {
"CI": "CI/[0-9]*",
"release": "[0-9]*"
}
tag = repo.git.describe(
'--tags',
f'--match={version_types[match]}',
'--abbrev=0'
)
if match == "CI":
return remove_prefix(tag, "CI/"), tag
else:
return tag, tag
def get_log_since_tag(version):
repo = Repo()
assert not repo.bare
return repo.git.log(f'{version}..HEAD', '--merges', '--oneline')
def release_type(log):
regex_minor = ["feature/", "(feat)"]
regex_patch = ["bugfix/", "fix/", "(fix)", "enhancement/", "update"]
for reg in regex_minor:
if re.search(reg, log):
return "minor"
for reg in regex_patch:
if re.search(reg, log):
return "patch"
return None
def file_regex_replace(filename, regex, version):
with open(filename, 'r+') as f:
text = f.read()
text = re.sub(regex, version, text)
# pp.pprint(f"NEW VERSION {version} INSERTED into {filename}")
f.seek(0)
f.write(text)
f.truncate()
def bump_file_versions(version, nightly=False):
filename = "./openpype/version.py"
regex = "(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(-((0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(\.(0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(\+([0-9a-zA-Z-]+(\.[0-9a-zA-Z-]+)*))?"
file_regex_replace(filename, regex, version)
if nightly:
# skip nightly reversion in pyproject.toml
return
# bump pyproject.toml
filename = "pyproject.toml"
regex = "version = \"(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(\+((0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(\.(0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(\+([0-9a-zA-Z-]+(\.[0-9a-zA-Z-]+)*))?\" # OpenPype"
pyproject_version = f"version = \"{version}\" # OpenPype"
file_regex_replace(filename, regex, pyproject_version)
def calculate_next_nightly(type="nightly", github_token=None):
last_prerelease, last_pre_tag = get_last_version("CI")
last_pre_v = VersionInfo.parse(last_prerelease)
last_pre_v_finalized = last_pre_v.finalize_version()
# print(last_pre_v_finalized)
last_release, last_release_tag = get_last_version("release")
last_release_v = VersionInfo.parse(last_release)
bump_type = get_release_type_github(
get_log_since_tag(last_release_tag),
github_token
)
if not bump_type:
return None
next_release_v = last_release_v.next_version(part=bump_type)
# print(next_release_v)
if next_release_v > last_pre_v_finalized:
next_tag = next_release_v.bump_prerelease(token=type).__str__()
return next_tag
elif next_release_v == last_pre_v_finalized:
next_tag = last_pre_v.bump_prerelease(token=type).__str__()
return next_tag
def finalize_latest_nightly():
last_prerelease, last_pre_tag = get_last_version("CI")
last_pre_v = VersionInfo.parse(last_prerelease)
last_pre_v_finalized = last_pre_v.finalize_version()
# print(last_pre_v_finalized)
return last_pre_v_finalized.__str__()
def finalize_prerelease(prerelease):
if "/" in prerelease:
prerelease = prerelease.split("/")[-1]
prerelease_v = VersionInfo.parse(prerelease)
prerelease_v_finalized = prerelease_v.finalize_version()
return prerelease_v_finalized.__str__()
def main():
usage = "usage: %prog [options] arg"
parser = OptionParser(usage)
parser.add_option("-n", "--nightly",
dest="nightly", action="store_true",
help="Bump nightly version and return it")
parser.add_option("-b", "--bump",
dest="bump", action="store_true",
help="Return if there is something to bump")
parser.add_option("-r", "--release-latest",
dest="releaselatest", action="store_true",
help="finalize latest prerelease to a release")
parser.add_option("-p", "--prerelease",
dest="prerelease", action="store",
help="define prerelease type")
parser.add_option("-f", "--finalize",
dest="finalize", action="store",
help="define prerelease type")
parser.add_option("-v", "--version",
dest="version", action="store",
help="work with explicit version")
parser.add_option("-l", "--lastversion",
dest="lastversion", action="store",
help="work with explicit version")
parser.add_option("-g", "--github_token",
dest="github_token", action="store",
help="github token")
(options, args) = parser.parse_args()
if options.bump:
last_release, last_release_tag = get_last_version("release")
bump_type_release = get_release_type_github(
get_log_since_tag(last_release_tag),
options.github_token
)
if bump_type_release is None:
print("skip")
else:
print(bump_type_release)
if options.nightly:
next_tag_v = calculate_next_nightly(github_token=options.github_token)
print(next_tag_v)
bump_file_versions(next_tag_v, True)
if options.finalize:
new_release = finalize_prerelease(options.finalize)
print(new_release)
bump_file_versions(new_release)
if options.lastversion:
last_release, last_release_tag = get_last_version(options.lastversion)
print(last_release_tag)
if options.releaselatest:
new_release = finalize_latest_nightly()
last_release, last_release_tag = get_last_version("release")
if VersionInfo.parse(new_release) > VersionInfo.parse(last_release):
print(new_release)
bump_file_versions(new_release)
else:
print("skip")
if options.prerelease:
current_prerelease = VersionInfo.parse(options.prerelease)
new_prerelease = current_prerelease.bump_prerelease().__str__()
print(new_prerelease)
bump_file_versions(new_prerelease)
if options.version:
bump_file_versions(options.version)
print(f"Injected version {options.version} into the release")
if __name__ == "__main__":
main()

View file

@ -1,196 +0,0 @@
<#
.SYNOPSIS
Helper script create virtual environment using Poetry.
.DESCRIPTION
This script will detect Python installation, create venv with Poetry
and install all necessary packages from `poetry.lock` or `pyproject.toml`
needed by OpenPype to be included during application freeze on Windows.
.EXAMPLE
PS> .\create_env.ps1
.EXAMPLE
Print verbose information from Poetry:
PS> .\create_env.ps1 --verbose
#>
$arguments=$ARGS
$poetry_verbosity=$null
if($arguments -eq "--verbose") {
$poetry_verbosity="-vvv"
}
$current_dir = Get-Location
$script_dir = Split-Path -Path $MyInvocation.MyCommand.Definition -Parent
$openpype_root = (Get-Item $script_dir).parent.FullName
& git submodule update --init --recursive
# Install PSWriteColor to support colorized output to terminal
$env:PSModulePath = $env:PSModulePath + ";$($openpype_root)\tools\modules\powershell"
function Exit-WithCode($exitcode) {
# Only exit this host process if it's a child of another PowerShell parent process...
$parentPID = (Get-CimInstance -ClassName Win32_Process -Filter "ProcessId=$PID" | Select-Object -Property ParentProcessId).ParentProcessId
$parentProcName = (Get-CimInstance -ClassName Win32_Process -Filter "ProcessId=$parentPID" | Select-Object -Property Name).Name
if ('powershell.exe' -eq $parentProcName) { $host.SetShouldExit($exitcode) }
exit $exitcode
}
function Show-PSWarning() {
if ($PSVersionTable.PSVersion.Major -lt 7) {
Write-Color -Text "!!! ", "You are using old version of PowerShell - ", "$($PSVersionTable.PSVersion.Major).$($PSVersionTable.PSVersion.Minor)" -Color Red, Yellow, White
Write-Color -Text " Please update to at least 7.0 - ", "https://github.com/PowerShell/PowerShell/releases" -Color Yellow, White
Exit-WithCode 1
}
}
function Install-Poetry() {
Write-Color -Text ">>> ", "Installing Poetry ... " -Color Green, Gray
$python = "python"
if (Get-Command "pyenv" -ErrorAction SilentlyContinue) {
if (-not (Test-Path -PathType Leaf -Path "$($openpype_root)\.python-version")) {
$result = & pyenv global
if ($result -eq "no global version configured") {
Write-Color -Text "!!! ", "Using pyenv but having no local or global version of Python set." -Color Red, Yellow
Exit-WithCode 1
}
}
$python = & pyenv which python
}
$env:POETRY_HOME="$openpype_root\.poetry"
$env:POETRY_VERSION="1.3.2"
(Invoke-WebRequest -Uri https://install.python-poetry.org/ -UseBasicParsing).Content | & $($python) -
}
function Test-Python() {
Write-Color -Text ">>> ", "Detecting host Python ... " -Color Green, Gray -NoNewline
$python = "python"
if (Get-Command "pyenv" -ErrorAction SilentlyContinue) {
$pyenv_python = & pyenv which python
if (Test-Path -PathType Leaf -Path "$($pyenv_python)") {
$python = $pyenv_python
}
}
if (-not (Get-Command $python -ErrorAction SilentlyContinue)) {
Write-Host "!!! Python not detected" -ForegroundColor red
Set-Location -Path $current_dir
Exit-WithCode 1
}
$version_command = @'
import sys
print('{0}.{1}'.format(sys.version_info[0], sys.version_info[1]))
'@
$p = & $python -c $version_command
$env:PYTHON_VERSION = $p
$m = $p -match '(\d+)\.(\d+)'
if(-not $m) {
Write-Host "!!! Cannot determine version" -ForegroundColor red
Set-Location -Path $current_dir
Exit-WithCode 1
}
# We are supporting python 3.9 only
if (([int]$matches[1] -lt 3) -or ([int]$matches[2] -lt 9)) {
Write-Color -Text "FAILED ", "Version ", "[", $p ,"]", "is old and unsupported" -Color Red, Yellow, Cyan, White, Cyan, Yellow
Set-Location -Path $current_dir
Exit-WithCode 1
} elseif (([int]$matches[1] -eq 3) -and ([int]$matches[2] -gt 9)) {
Write-Color -Text "WARNING Version ", "[", $p, "]", " is unsupported, use at your own risk." -Color Yellow, Cyan, White, Cyan, Yellow
Write-Color -Text "*** ", "OpenPype supports only Python 3.9" -Color Yellow, White
} else {
Write-Color "OK ", "[", $p, "]" -Color Green, Cyan, White, Cyan
}
}
if (-not (Test-Path 'env:POETRY_HOME')) {
$env:POETRY_HOME = "$openpype_root\.poetry"
}
Set-Location -Path $openpype_root
$art = @"
. . .. . ..
_oOOP3OPP3Op_. .
.PPpo~. .. ~2p. .. .... . .
.Ppo . .pPO3Op.. . O:. . . .
.3Pp . oP3'. 'P33. . 4 .. . . . .. . . .
.~OP 3PO. .Op3 : . .. _____ _____ _____
.P3O . oP3oP3O3P' . . . . / /./ /./ /
O3:. O3p~ . .:. . ./____/./____/ /____/
'P . 3p3. oP3~. ..P:. . . .. . . .. . . .
. ': . Po' .Opo'. .3O. . o[ by Pype Club ]]]==- - - . .
. '_ .. . . _OP3.. . .https://openpype.io.. .
~P3.OPPPO3OP~ . .. .
. ' '. . .. . . . .. .
"@
if (-not (Test-Path 'env:_INSIDE_OPENPYPE_TOOL')) {
Write-Host $art -ForegroundColor DarkGreen
}
# Enable if PS 7.x is needed.
# Show-PSWarning
$version_file = Get-Content -Path "$($openpype_root)\openpype\version.py"
$result = [regex]::Matches($version_file, '__version__ = "(?<version>\d+\.\d+.\d+.*)"')
$openpype_version = $result[0].Groups['version'].Value
if (-not $openpype_version) {
Write-Color -Text "!!! ", "Cannot determine OpenPype version." -Color Red, Yellow
Set-Location -Path $current_dir
Exit-WithCode 1
}
Write-Color -Text ">>> ", "Found OpenPype version ", "[ ", $($openpype_version), " ]" -Color Green, Gray, Cyan, White, Cyan
Test-Python
Write-Color -Text ">>> ", "Reading Poetry ... " -Color Green, Gray -NoNewline
if (-not (Test-Path -PathType Container -Path "$($env:POETRY_HOME)\bin")) {
Write-Color -Text "NOT FOUND" -Color Yellow
Install-Poetry
Write-Color -Text "INSTALLED" -Color Cyan
} else {
Write-Color -Text "OK" -Color Green
}
if (-not (Test-Path -PathType Leaf -Path "$($openpype_root)\poetry.lock")) {
Write-Color -Text ">>> ", "Installing virtual environment and creating lock." -Color Green, Gray
} else {
Write-Color -Text ">>> ", "Installing virtual environment from lock." -Color Green, Gray
}
$startTime = [int][double]::Parse((Get-Date -UFormat %s))
& "$env:POETRY_HOME\bin\poetry" install --no-root $poetry_verbosity --ansi
if ($LASTEXITCODE -ne 0) {
Write-Color -Text "!!! ", "Poetry command failed." -Color Red, Yellow
Set-Location -Path $current_dir
Exit-WithCode 1
}
Write-Color -Text ">>> ", "Installing pre-commit hooks ..." -Color Green, White
& "$env:POETRY_HOME\bin\poetry" run pre-commit install
if ($LASTEXITCODE -ne 0) {
Write-Color -Text "!!! ", "Installation of pre-commit hooks failed." -Color Red, Yellow
Set-Location -Path $current_dir
Exit-WithCode 1
}
$endTime = [int][double]::Parse((Get-Date -UFormat %s))
Set-Location -Path $current_dir
try
{
New-BurntToastNotification -AppLogo "$openpype_root/openpype/resources/icons/openpype_icon.png" -Text "OpenPype", "Virtual environment created.", "All done in $( $endTime - $startTime ) secs."
} catch {}
Write-Color -Text ">>> ", "Virtual environment created." -Color Green, White

View file

@ -1,202 +0,0 @@
#!/usr/bin/env bash
# This script will detect Python installation, create venv with Poetry
# and install all necessary packages from `poetry.lock` or `pyproject.toml`
# needed by OpenPype to be included during application freeze on unix.
art () {
cat <<-EOF
. . .. . ..
_oOOP3OPP3Op_. .
.PPpo~· ·· ~2p. ·· ···· · ·
·Ppo · .pPO3Op.· · O:· · · ·
.3Pp · oP3'· 'P33· · 4 ·· · · · ·· · · ·
·~OP 3PO· .Op3 : · ·· _____ _____ _____
·P3O · oP3oP3O3P' · · · · / /·/ /·/ /
O3:· O3p~ · ·:· · ·/____/·/____/ /____/
'P · 3p3· oP3~· ·.P:· · · ·· · · ·· · · ·
· ': · Po' ·Opo'· .3O· . o[ by Pype Club ]]]==- - - · ·
· '_ .. · . _OP3·· · ·https://openpype.io·· ·
~P3·OPPPO3OP~ · ·· ·
· ' '· · ·· · · · ·· ·
EOF
}
# Colors for terminal
RST='\033[0m' # Text Reset
# Regular Colors
Black='\033[0;30m' # Black
Red='\033[0;31m' # Red
Green='\033[0;32m' # Green
Yellow='\033[0;33m' # Yellow
Blue='\033[0;34m' # Blue
Purple='\033[0;35m' # Purple
Cyan='\033[0;36m' # Cyan
White='\033[0;37m' # White
# Bold
BBlack='\033[1;30m' # Black
BRed='\033[1;31m' # Red
BGreen='\033[1;32m' # Green
BYellow='\033[1;33m' # Yellow
BBlue='\033[1;34m' # Blue
BPurple='\033[1;35m' # Purple
BCyan='\033[1;36m' # Cyan
BWhite='\033[1;37m' # White
# Bold High Intensity
BIBlack='\033[1;90m' # Black
BIRed='\033[1;91m' # Red
BIGreen='\033[1;92m' # Green
BIYellow='\033[1;93m' # Yellow
BIBlue='\033[1;94m' # Blue
BIPurple='\033[1;95m' # Purple
BICyan='\033[1;96m' # Cyan
BIWhite='\033[1;97m' # White
poetry_verbosity=""
while :; do
case $1 in
--verbose)
poetry_verbosity="-vvv"
;;
--)
shift
break
;;
*)
break
esac
shift
done
##############################################################################
# Detect required version of python
# Globals:
# colors
# PYTHON
# Arguments:
# None
# Returns:
# None
###############################################################################
detect_python () {
echo -e "${BIGreen}>>>${RST} Using python \c"
command -v python >/dev/null 2>&1 || { echo -e "${BIRed}- NOT FOUND${RST} ${BIYellow}You need Python 3.9 installed to continue.${RST}"; return 1; }
local version_command="import sys;print('{0}.{1}'.format(sys.version_info[0], sys.version_info[1]))"
local python_version="$(python <<< ${version_command})"
oIFS="$IFS"
IFS=.
set -- $python_version
IFS="$oIFS"
if [ "$1" -ge "3" ] && [ "$2" -ge "9" ] ; then
if [ "$2" -gt "9" ] ; then
echo -e "${BIWhite}[${RST} ${BIRed}$1.$2 ${BIWhite}]${RST} - ${BIRed}FAILED${RST} ${BIYellow}Version is new and unsupported, use${RST} ${BIPurple}3.9.x${RST}"; return 1;
else
echo -e "${BIWhite}[${RST} ${BIGreen}$1.$2${RST} ${BIWhite}]${RST}"
fi
else
command -v python >/dev/null 2>&1 || { echo -e "${BIRed}$1.$2$ - ${BIRed}FAILED${RST} ${BIYellow}Version is old and unsupported${RST}"; return 1; }
fi
}
install_poetry () {
echo -e "${BIGreen}>>>${RST} Installing Poetry ..."
export POETRY_HOME="$openpype_root/.poetry"
export POETRY_VERSION="1.3.2"
command -v curl >/dev/null 2>&1 || { echo -e "${BIRed}!!!${RST}${BIYellow} Missing ${RST}${BIBlue}curl${BIYellow} command.${RST}"; return 1; }
curl -sSL https://install.python-poetry.org/ | python -
}
##############################################################################
# Clean pyc files in specified directory
# Globals:
# None
# Arguments:
# Optional path to clean
# Returns:
# None
###############################################################################
clean_pyc () {
local path
path=$openpype_root
echo -e "${BIGreen}>>>${RST} Cleaning pyc at [ ${BIWhite}$path${RST} ] ... \c"
find "$path" -path ./build -o -regex '^.*\(__pycache__\|\.py[co]\)$' -delete
echo -e "${BIGreen}DONE${RST}"
}
##############################################################################
# Return absolute path
# Globals:
# None
# Arguments:
# Path to resolve
# Returns:
# None
###############################################################################
realpath () {
echo $(cd $(dirname "$1"); pwd)/$(basename "$1")
}
main () {
# Main
if [[ -z $_inside_openpype_tool ]]; then
echo -e "${BGreen}"
art
echo -e "${RST}"
fi
detect_python || return 1
# Directories
openpype_root=$(realpath $(dirname $(dirname "${BASH_SOURCE[0]}")))
if [[ -z $POETRY_HOME ]]; then
export POETRY_HOME="$openpype_root/.poetry"
fi
pushd "$openpype_root" > /dev/null || return > /dev/null
echo -e "${BIGreen}>>>${RST} Reading Poetry ... \c"
if [ -f "$POETRY_HOME/bin/poetry" ]; then
echo -e "${BIGreen}OK${RST}"
else
echo -e "${BIYellow}NOT FOUND${RST}"
install_poetry || { echo -e "${BIRed}!!!${RST} Poetry installation failed"; return 1; }
fi
if [ -f "$openpype_root/poetry.lock" ]; then
echo -e "${BIGreen}>>>${RST} Updating dependencies ..."
else
echo -e "${BIGreen}>>>${RST} Installing dependencies ..."
fi
"$POETRY_HOME/bin/poetry" install --no-root $poetry_verbosity || { echo -e "${BIRed}!!!${RST} Poetry environment installation failed"; return 1; }
if [ $? -ne 0 ] ; then
echo -e "${BIRed}!!!${RST} Virtual environment creation failed."
return 1
fi
echo -e "${BIGreen}>>>${RST} Cleaning cache files ..."
clean_pyc
# reinstall these because of bug in poetry? or cx_freeze?
# cx_freeze will crash on missing __pychache__ on these but
# reinstalling them solves the problem.
echo -e "${BIGreen}>>>${RST} Post-venv creation fixes ..."
local openpype_index=$("$POETRY_HOME/bin/poetry" run python "$openpype_root/tools/parse_pyproject.py" tool.poetry.source.0.url)
echo -e "${BIGreen}- ${RST} Using index: ${BIWhite}$openpype_index${RST}"
"$POETRY_HOME/bin/poetry" run python -m pip install --disable-pip-version-check --force-reinstall pip
echo -e "${BIGreen}>>>${RST} Installing pre-commit hooks ..."
"$POETRY_HOME/bin/poetry" run pre-commit install
}
return_code=0
main || return_code=$?
exit $return_code

View file

@ -1,105 +0,0 @@
<#
.SYNOPSIS
Helper script create distributable OpenPype zip.
.DESCRIPTION
This script will detect Python installation and run OpenPype to create
zip. It will create zip from current source code
version and copy it top `%LOCALAPPDATA%/pypeclub/openpype` if `--path` or `-p`
argument is not used.
.EXAMPLE
PS> .\create_zip.ps1
.EXAMPLE
To put generated zip to C:\OpenPype directory:
PS> .\create_zip.ps1 --path C:\OpenPype
#>
$current_dir = Get-Location
$script_dir = Split-Path -Path $MyInvocation.MyCommand.Definition -Parent
$openpype_root = (Get-Item $script_dir).parent.FullName
# Install PSWriteColor to support colorized output to terminal
$env:PSModulePath = $env:PSModulePath + ";$($openpype_root)\tools\modules\powershell"
function Exit-WithCode($exitcode) {
# Only exit this host process if it's a child of another PowerShell parent process...
$parentPID = (Get-CimInstance -ClassName Win32_Process -Filter "ProcessId=$PID" | Select-Object -Property ParentProcessId).ParentProcessId
$parentProcName = (Get-CimInstance -ClassName Win32_Process -Filter "ProcessId=$parentPID" | Select-Object -Property Name).Name
if ('powershell.exe' -eq $parentProcName) { $host.SetShouldExit($exitcode) }
exit $exitcode
}
function Show-PSWarning() {
if ($PSVersionTable.PSVersion.Major -lt 7) {
Write-Color -Text "!!! ", "You are using old version of PowerShell - ", "$($PSVersionTable.PSVersion.Major).$($PSVersionTable.PSVersion.Minor)" -Color Red, Yellow, White
Write-Color -Text " Please update to at least 7.0 - ", "https://github.com/PowerShell/PowerShell/releases" -Color Yellow, White
Exit-WithCode 1
}
}
$env:_INSIDE_OPENPYPE_TOOL = "1"
if (-not (Test-Path 'env:POETRY_HOME')) {
$env:POETRY_HOME = "$openpype_root\.poetry"
}
Set-Location -Path $openpype_root
$art = @"
. . .. . ..
_oOOP3OPP3Op_. .
.PPpo~. .. ~2p. .. .... . .
.Ppo . .pPO3Op.. . O:. . . .
.3Pp . oP3'. 'P33. . 4 .. . . . .. . . .
.~OP 3PO. .Op3 : . .. _____ _____ _____
.P3O . oP3oP3O3P' . . . . / /./ /./ /
O3:. O3p~ . .:. . ./____/./____/ /____/
'P . 3p3. oP3~. ..P:. . . .. . . .. . . .
. ': . Po' .Opo'. .3O. . o[ by Pype Club ]]]==- - - . .
. '_ .. . . _OP3.. . .https://openpype.io.. .
~P3.OPPPO3OP~ . .. .
. ' '. . .. . . . .. .
"@
Write-Host $art -ForegroundColor DarkGreen
# Enable if PS 7.x is needed.
# Show-PSWarning
$version_file = Get-Content -Path "$($openpype_root)\openpype\version.py"
$result = [regex]::Matches($version_file, '__version__ = "(?<version>\d+\.\d+.\d+.*)"')
$openpype_version = $result[0].Groups['version'].Value
if (-not $openpype_version) {
Write-Color -Text "!!! ", "Cannot determine OpenPype version." -Color Yellow, Gray
Exit-WithCode 1
}
Write-Color -Text ">>> ", "Reading Poetry ... " -Color Green, Gray -NoNewline
if (-not (Test-Path -PathType Container -Path "$($env:POETRY_HOME)\bin")) {
Write-Color -Text "NOT FOUND" -Color Yellow
Write-Color -Text "*** ", "We need to install Poetry create virtual env first ..." -Color Yellow, Gray
& "$openpype_root\tools\create_env.ps1"
} else {
Write-Color -Text "OK" -Color Green
}
Write-Color -Text ">>> ", "Cleaning cache files ... " -Color Green, Gray -NoNewline
Get-ChildItem $openpype_root -Filter "__pycache__" -Force -Recurse| Where-Object {( $_.FullName -inotmatch '\\build\\' ) -and ( $_.FullName -inotmatch '\\.venv' )} | Remove-Item -Force -Recurse
Get-ChildItem $openpype_root -Filter "*.pyc" -Force -Recurse | Where-Object {( $_.FullName -inotmatch '\\build\\' ) -and ( $_.FullName -inotmatch '\\.venv' )} | Remove-Item -Force
Get-ChildItem $openpype_root -Filter "*.pyo" -Force -Recurse | Where-Object {( $_.FullName -inotmatch '\\build\\' ) -and ( $_.FullName -inotmatch '\\.venv' )} | Remove-Item -Force
Write-Color -Text "OK" -Color Green
Write-Color -Text ">>> ", "Generating zip from current sources ..." -Color Green, Gray
$env:PYTHONPATH="$($openpype_root);$($env:PYTHONPATH)"
$env:OPENPYPE_ROOT="$($openpype_root)"
& "$($env:POETRY_HOME)\bin\poetry" run python "$($openpype_root)\tools\create_zip.py" $ARGS
Set-Location -Path $current_dir

View file

@ -1,68 +0,0 @@
# -*- coding: utf-8 -*-
"""Create OpenPype version from live sources."""
from igniter import bootstrap_repos
import click
import enlighten
import blessed
from pathlib2 import Path
term = blessed.Terminal()
manager = enlighten.get_manager()
last_increment = 0
@click.group(invoke_without_command=True)
@click.option("--path", required=False,
help="path where to put version",
type=click.Path(exists=True))
def main(path):
# create zip file
progress_bar = enlighten.Counter(
total=100, desc="OpenPype ZIP", units="%", color="green")
def progress(inc: int):
"""Progress handler."""
global last_increment
progress_bar.update(incr=inc - last_increment)
last_increment = inc
bs = bootstrap_repos.BootstrapRepos(progress_callback=progress)
if path:
out_path = Path(path)
bs.data_dir = out_path
if out_path.is_file():
bs.data_dir = out_path.parent
_print(f"Creating zip in {bs.data_dir} ...")
repo_file = bs.create_version_from_live_code()
if not repo_file:
_print("Error while creating zip file.", 1)
exit(1)
_print(f"Created {repo_file}")
def _print(msg: str, message_type: int = 0) -> None:
"""Print message to console.
Args:
msg (str): message to print
message_type (int): type of message (0 info, 1 error, 2 note)
"""
if message_type == 0:
header = term.aquamarine3(">>> ")
elif message_type == 1:
header = term.orangered2("!!! ")
elif message_type == 2:
header = term.tan1("... ")
else:
header = term.darkolivegreen3("--- ")
print(f"{header}{msg}")
if __name__ == "__main__":
main()

View file

@ -1,138 +0,0 @@
#!/usr/bin/env bash
# This script will detect Python installation and run OpenPype to create
# zip. It needs mongodb running. I will create zip from current source code
# version and copy it top `~/.local/share/pype` if `--path` or `-p`
# argument is not used.
art () {
cat <<-EOF
. . .. . ..
_oOOP3OPP3Op_. .
.PPpo~· ·· ~2p. ·· ···· · ·
·Ppo · .pPO3Op.· · O:· · · ·
.3Pp · oP3'· 'P33· · 4 ·· · · · ·· · · ·
·~OP 3PO· .Op3 : · ·· _____ _____ _____
·P3O · oP3oP3O3P' · · · · / /·/ /·/ /
O3:· O3p~ · ·:· · ·/____/·/____/ /____/
'P · 3p3· oP3~· ·.P:· · · ·· · · ·· · · ·
· ': · Po' ·Opo'· .3O· . o[ by Pype Club ]]]==- - - · ·
· '_ .. · . _OP3·· · ·https://openpype.io·· ·
~P3·OPPPO3OP~ · ·· ·
· ' '· · ·· · · · ·· ·
EOF
}
# Colors for terminal
RST='\033[0m' # Text Reset
# Regular Colors
Black='\033[0;30m' # Black
Red='\033[0;31m' # Red
Green='\033[0;32m' # Green
Yellow='\033[0;33m' # Yellow
Blue='\033[0;34m' # Blue
Purple='\033[0;35m' # Purple
Cyan='\033[0;36m' # Cyan
White='\033[0;37m' # White
# Bold
BBlack='\033[1;30m' # Black
BRed='\033[1;31m' # Red
BGreen='\033[1;32m' # Green
BYellow='\033[1;33m' # Yellow
BBlue='\033[1;34m' # Blue
BPurple='\033[1;35m' # Purple
BCyan='\033[1;36m' # Cyan
BWhite='\033[1;37m' # White
# Bold High Intensity
BIBlack='\033[1;90m' # Black
BIRed='\033[1;91m' # Red
BIGreen='\033[1;92m' # Green
BIYellow='\033[1;93m' # Yellow
BIBlue='\033[1;94m' # Blue
BIPurple='\033[1;95m' # Purple
BICyan='\033[1;96m' # Cyan
BIWhite='\033[1;97m' # White
##############################################################################
# Detect required version of python
# Globals:
# colors
# PYTHON
# Arguments:
# None
# Returns:
# None
###############################################################################
detect_python () {
echo -e "${BIGreen}>>>${RST} Using python \c"
local version_command="import sys;print('{0}.{1}'.format(sys.version_info[0], sys.version_info[1]))"
local python_version="$(python3 <<< ${version_command})"
oIFS="$IFS"
IFS=.
set -- $python_version
IFS="$oIFS"
if [ "$1" -ge "3" ] && [ "$2" -ge "9" ] ; then
if [ "$2" -gt "9" ] ; then
echo -e "${BIWhite}[${RST} ${BIRed}$1.$2 ${BIWhite}]${RST} - ${BIRed}FAILED${RST} ${BIYellow}Version is new and unsupported, use${RST} ${BIPurple}3.9.x${RST}"; return 1;
else
echo -e "${BIWhite}[${RST} ${BIGreen}$1.$2${RST} ${BIWhite}]${RST}"
fi
else
command -v python3 >/dev/null 2>&1 || { echo -e "${BIRed}$1.$2$ - ${BIRed}FAILED${RST} ${BIYellow}Version is old and unsupported${RST}"; return 1; }
fi
}
##############################################################################
# Return absolute path
# Globals:
# None
# Arguments:
# Path to resolve
# Returns:
# None
###############################################################################
realpath () {
echo $(cd $(dirname "$1"); pwd)/$(basename "$1")
}
# Main
main () {
echo -e "${BGreen}"
art
echo -e "${RST}"
detect_python || return 1
# Directories
openpype_root=$(realpath $(dirname $(dirname "${BASH_SOURCE[0]}")))
_inside_openpype_tool="1"
if [[ -z $POETRY_HOME ]]; then
export POETRY_HOME="$openpype_root/.poetry"
fi
pushd "$openpype_root" > /dev/null || return > /dev/null
echo -e "${BIGreen}>>>${RST} Reading Poetry ... \c"
if [ -f "$POETRY_HOME/bin/poetry" ]; then
echo -e "${BIGreen}OK${RST}"
else
echo -e "${BIYellow}NOT FOUND${RST}"
echo -e "${BIYellow}***${RST} We need to install Poetry and virtual env ..."
. "$openpype_root/tools/create_env.sh" || { echo -e "${BIRed}!!!${RST} Poetry installation failed"; return; }
fi
echo -e "${BIGreen}>>>${RST} Generating zip from current sources ..."
export PYTHONPATH="$openpype_root:$PYTHONPATH"
export OPENPYPE_ROOT="$openpype_root"
"$POETRY_HOME/bin/poetry" run python3 "$openpype_root/tools/create_zip.py" "$@"
}
main "$@"

View file

@ -1,98 +0,0 @@
$current_dir = Get-Location
$script_dir = Split-Path -Path $MyInvocation.MyCommand.Definition -Parent
$repo_root = (Get-Item $script_dir).parent.FullName
$env:PSModulePath = $env:PSModulePath + ";$($repo_root)\tools\modules\powershell"
function Exit-WithCode($exitcode) {
# Only exit this host process if it's a child of another PowerShell parent process...
$parentPID = (Get-CimInstance -ClassName Win32_Process -Filter "ProcessId=$PID" | Select-Object -Property ParentProcessId).ParentProcessId
$parentProcName = (Get-CimInstance -ClassName Win32_Process -Filter "ProcessId=$parentPID" | Select-Object -Property Name).Name
if ('powershell.exe' -eq $parentProcName) { $host.SetShouldExit($exitcode) }
exit $exitcode
}
function Restore-Cwd() {
$tmp_current_dir = Get-Location
if ("$tmp_current_dir" -ne "$current_dir") {
Write-Color -Text ">>> ", "Restoring current directory" -Color Green, Gray
Set-Location -Path $current_dir
}
}
function Get-Container {
if (-not (Test-Path -PathType Leaf -Path "$($repo_root)\build\docker-image.id")) {
Write-Color -Text "!!! ", "Docker command failed, cannot find image id." -Color Red, Yellow
Restore-Cwd
Exit-WithCode 1
}
$id = Get-Content "$($repo_root)\build\docker-image.id"
Write-Color -Text ">>> ", "Creating container from image id ", "[", $id, "]" -Color Green, Gray, White, Cyan, White
$cid = docker create $id bash
if ($LASTEXITCODE -ne 0) {
Write-Color -Text "!!! ", "Cannot create container." -Color Red, Yellow
Restore-Cwd
Exit-WithCode 1
}
return $cid
}
function Change-Cwd() {
Set-Location -Path $repo_root
}
function New-DockerBuild {
$version_file = Get-Content -Path "$($repo_root)\openpype\version.py"
$result = [regex]::Matches($version_file, '__version__ = "(?<version>\d+\.\d+.\d+.*)"')
$openpype_version = $result[0].Groups['version'].Value
$startTime = [int][double]::Parse((Get-Date -UFormat %s))
Write-Color -Text ">>> ", "Building OpenPype using Docker ..." -Color Green, Gray, White
$variant = $args[0]
if ($variant.Length -eq 0) {
$dockerfile = "$($repo_root)\Dockerfile"
} else {
$dockerfile = "$( $repo_root )\Dockerfile.$variant"
}
if (-not (Test-Path -PathType Leaf -Path $dockerfile)) {
Write-Color -Text "!!! ", "Dockerfile for specifed platform ", "[", $variant, "]", "doesn't exist." -Color Red, Yellow, Cyan, White, Cyan, Yellow
Restore-Cwd
Exit-WithCode 1
}
Write-Color -Text ">>> ", "Using Dockerfile for ", "[ ", $variant, " ]" -Color Green, Gray, White, Cyan, White
$build_dir = "$($repo_root)\build"
if (-not(Test-Path $build_dir)) {
New-Item -ItemType Directory -Path $build_dir
}
Write-Color -Text "--- ", "Cleaning build directory ..." -Color Yellow, Gray
try {
Remove-Item -Recurse -Force "$($build_dir)\*"
} catch {
Write-Color -Text "!!! ", "Cannot clean build directory, possibly because process is using it." -Color Red, Gray
Write-Color -Text $_.Exception.Message -Color Red
Exit-WithCode 1
}
Write-Color -Text ">>> ", "Running Docker build ..." -Color Green, Gray, White
docker build --pull --iidfile $repo_root/build/docker-image.id --build-arg BUILD_DATE=$(Get-Date -UFormat %Y-%m-%dT%H:%M:%SZ) --build-arg VERSION=$openpype_version -t pypeclub/openpype:$openpype_version -f $dockerfile .
if ($LASTEXITCODE -ne 0) {
Write-Color -Text "!!! ", "Docker command failed.", $LASTEXITCODE -Color Red, Yellow, Red
Restore-Cwd
Exit-WithCode 1
}
Write-Color -Text ">>> ", "Copying build from container ..." -Color Green, Gray, White
$cid = Get-Container
docker cp "$($cid):/opt/openpype/build/exe.linux-x86_64-3.9" "$($repo_root)/build"
docker cp "$($cid):/opt/openpype/build/build.log" "$($repo_root)/build"
$endTime = [int][double]::Parse((Get-Date -UFormat %s))
try {
New-BurntToastNotification -AppLogo "$openpype_root/openpype/resources/icons/openpype_icon.png" -Text "OpenPype build complete!", "All done in $( $endTime - $startTime ) secs. You will find OpenPype and build log in build directory."
} catch {}
Write-Color -Text "*** ", "All done in ", $($endTime - $startTime), " secs. You will find OpenPype and build log in ", "'.\build'", " directory." -Color Green, Gray, White, Gray, White, Gray
}
Change-Cwd
New-DockerBuild $ARGS

View file

@ -1,99 +0,0 @@
#!/usr/bin/env bash
# Colors for terminal
RST='\033[0m' # Text Reset
BIGreen='\033[1;92m' # Green
BIYellow='\033[1;93m' # Yellow
BIRed='\033[1;91m' # Red
##############################################################################
# Return absolute path
# Globals:
# None
# Arguments:
# Path to resolve
# Returns:
# None
###############################################################################
realpath () {
echo $(cd $(dirname "$1"); pwd)/$(basename "$1")
}
create_container () {
if [ ! -f "$openpype_root/build/docker-image.id" ]; then
echo -e "${BIRed}!!!${RST} Docker command failed, cannot find image id."
exit 1
fi
local id=$(<"$openpype_root/build/docker-image.id")
echo -e "${BIYellow}---${RST} Creating container from $id ..."
cid="$(docker create $id bash)"
if [ $? -ne 0 ] ; then
echo -e "${BIRed}!!!${RST} Cannot create container."
exit 1
fi
}
retrieve_build_log () {
create_container
echo -e "${BIYellow}***${RST} Copying build log to ${BIWhite}$openpype_root/build/build.log${RST}"
docker cp "$cid:/opt/openpype/build/build.log" "$openpype_root/build"
}
openpype_root=$(realpath $(dirname $(dirname "${BASH_SOURCE[0]}")))
if [ -z $1 ]; then
dockerfile="Dockerfile"
else
dockerfile="Dockerfile.$1"
if [ ! -f "$openpype_root/$dockerfile" ]; then
echo -e "${BIRed}!!!${RST} Dockerfile for specifed platform ${BIWhite}$1${RST} doesn't exist."
exit 1
else
echo -e "${BIGreen}>>>${RST} Using Dockerfile for ${BIWhite}$1${RST} ..."
fi
fi
# Main
main () {
openpype_root=$(realpath $(dirname $(dirname "${BASH_SOURCE[0]}")))
pushd "$openpype_root" > /dev/null || return > /dev/null
echo -e "${BIYellow}---${RST} Cleaning build directory ..."
rm -rf "$openpype_root/build" && mkdir "$openpype_root/build" > /dev/null
local version_command="import os;exec(open(os.path.join('$openpype_root', 'openpype', 'version.py')).read());print(__version__);"
local openpype_version="$(python3 <<< ${version_command})"
echo -e "${BIGreen}>>>${RST} Running docker build ..."
# docker build --pull --no-cache -t pypeclub/openpype:$openpype_version .
docker build --pull --iidfile $openpype_root/build/docker-image.id --build-arg BUILD_DATE=$(date -u +'%Y-%m-%dT%H:%M:%SZ') --build-arg VERSION=$openpype_version -t pypeclub/openpype:$openpype_version -f $dockerfile .
if [ $? -ne 0 ] ; then
echo $?
echo -e "${BIRed}!!!${RST} Docker build failed."
retrieve_build_log
return 1
fi
echo -e "${BIGreen}>>>${RST} Copying build from container ..."
create_container
echo -e "${BIYellow}---${RST} Copying ..."
docker cp "$cid:/opt/openpype/build/exe.linux-x86_64-3.9" "$openpype_root/build"
docker cp "$cid:/opt/openpype/build/build.log" "$openpype_root/build"
if [ $? -ne 0 ] ; then
echo -e "${BIRed}!!!${RST} Copying failed."
return 1
fi
echo -e "${BIGreen}>>>${RST} Fixing user ownership ..."
local username="$(logname)"
chown -R $username ./build
echo -e "${BIGreen}>>>${RST} All done, you can delete container:"
echo -e "${BIYellow}$cid${RST}"
}
return_code=0
main || return_code=$?
exit $return_code

View file

@ -1,44 +0,0 @@
<#
.SYNOPSIS
Download and extract third-party dependencies for OpenPype.
.DESCRIPTION
This will download third-party dependencies specified in pyproject.toml
and extract them to vendor/bin folder.
.EXAMPLE
PS> .\fetch_thirdparty_libs.ps1
#>
$current_dir = Get-Location
$script_dir = Split-Path -Path $MyInvocation.MyCommand.Definition -Parent
$openpype_root = (Get-Item $script_dir).parent.FullName
# Install PSWriteColor to support colorized output to terminal
$env:PSModulePath = $env:PSModulePath + ";$($openpype_root)\tools\modules\powershell"
$env:_INSIDE_OPENPYPE_TOOL = "1"
if (-not (Test-Path 'env:POETRY_HOME')) {
$env:POETRY_HOME = "$openpype_root\.poetry"
}
Set-Location -Path $openpype_root
Write-Color -Text ">>> ", "Reading Poetry ... " -Color Green, Gray -NoNewline
if (-not (Test-Path -PathType Container -Path "$($env:POETRY_HOME)\bin")) {
Write-Color -Text "NOT FOUND" -Color Yellow
Write-Color -Text "*** ", "We need to install Poetry create virtual env first ..." -Color Yellow, Gray
& "$openpype_root\tools\create_env.ps1"
} else {
Write-Color -Text "OK" -Color Green
}
$startTime = [int][double]::Parse((Get-Date -UFormat %s))
& "$($env:POETRY_HOME)\bin\poetry" run python "$($openpype_root)\tools\fetch_thirdparty_libs.py"
$endTime = [int][double]::Parse((Get-Date -UFormat %s))
Set-Location -Path $current_dir
try
{
New-BurntToastNotification -AppLogo "$openpype_root/openpype/resources/icons/openpype_icon.png" -Text "OpenPype", "Dependencies downloaded", "All done in $( $endTime - $startTime ) secs."
} catch {}

View file

@ -1,244 +0,0 @@
# -*- coding: utf-8 -*-
"""Fetch, verify and process third-party dependencies of OpenPype.
Those should be defined in `pyproject.toml` in OpenPype sources root.
"""
import os
import sys
import toml
import shutil
from pathlib import Path
from urllib.parse import urlparse
import requests
import enlighten
import platform
import blessed
import tempfile
import math
import hashlib
import tarfile
import zipfile
import time
import subprocess
term = blessed.Terminal()
manager = enlighten.get_manager()
hash_buffer_size = 65536
def sha256_sum(filename: Path):
"""Calculate sha256 hash for given file.
Args:
filename (Path): path to file.
Returns:
str: hex hash.
"""
_hash = hashlib.sha256()
with open(filename, 'rb', buffering=0) as f:
buffer = bytearray(128 * 1024)
mv = memoryview(buffer)
for n in iter(lambda: f.readinto(mv), 0):
_hash.update(mv[:n])
return _hash.hexdigest()
def _print(msg: str, message_type: int = 0) -> None:
"""Print message to console.
Args:
msg (str): message to print
message_type (int): type of message (0 info, 1 error, 2 note)
"""
if message_type == 0:
header = term.aquamarine3(">>> ")
elif message_type == 1:
header = term.orangered2("!!! ")
elif message_type == 2:
header = term.tan1("... ")
else:
header = term.darkolivegreen3("--- ")
print(f"{header}{msg}")
def _pip_install(openpype_root, package, version=None):
arg = None
if package and version:
arg = f"{package}=={version}"
elif package:
arg = package
if not arg:
_print("Couldn't find package to install")
sys.exit(1)
_print(f"We'll install {arg}")
python_vendor_dir = openpype_root / "vendor" / "python"
try:
subprocess.run(
[
sys.executable,
"-m", "pip", "install", "--upgrade", arg,
"-t", str(python_vendor_dir)
],
check=True,
stdout=subprocess.DEVNULL
)
except subprocess.CalledProcessError as e:
_print(f"Error during {package} installation.", 1)
_print(str(e), 1)
sys.exit(1)
def install_qtbinding(pyproject, openpype_root, platform_name):
_print("Handling Qt binding framework ...")
qtbinding_def = pyproject["openpype"]["qtbinding"][platform_name]
package = qtbinding_def["package"]
version = qtbinding_def.get("version")
_pip_install(openpype_root, package, version)
python_vendor_dir = openpype_root / "vendor" / "python"
# Remove libraries for QtSql which don't have available libraries
# by default and Postgre library would require to modify rpath of
# dependency
if platform_name == "darwin":
sqldrivers_dir = (
python_vendor_dir / package / "Qt" / "plugins" / "sqldrivers"
)
for filepath in sqldrivers_dir.iterdir():
os.remove(str(filepath))
def install_runtime_dependencies(pyproject, openpype_root):
_print("Installing Runtime Dependencies ...")
runtime_deps = pyproject["openpype"]["runtime-deps"]
for package, version in runtime_deps.items():
_pip_install(openpype_root, package, version)
def install_thirdparty(pyproject, openpype_root, platform_name):
_print("Processing third-party dependencies ...")
try:
thirdparty = pyproject["openpype"]["thirdparty"]
except AttributeError:
_print("No third-party libraries specified in pyproject.toml", 1)
sys.exit(1)
for k, v in thirdparty.items():
_print(f"processing {k}")
destination_path = openpype_root / "vendor" / "bin" / k
if not v.get(platform_name):
_print(("missing definition for current "
f"platform [ {platform_name} ]"), 2)
_print("trying to get universal url for all platforms")
url = v.get("url")
if not url:
_print("cannot get url for all platforms", 1)
_print((f"Warning: {k} is not installed for current platform "
"and it might be missing in the build"), 1)
continue
else:
url = v.get(platform_name).get("url")
destination_path = destination_path / platform_name
parsed_url = urlparse(url)
# check if file is already extracted in /vendor/bin
if destination_path.exists():
_print("destination path already exists, deleting ...", 2)
if destination_path.is_dir():
try:
shutil.rmtree(destination_path)
except OSError as e:
_print("cannot delete folder.", 1)
raise SystemExit(e)
# download file
_print(f"Downloading {url} ...")
with tempfile.TemporaryDirectory() as temp_dir:
temp_file = Path(temp_dir) / Path(parsed_url.path).name
r = requests.get(url, stream=True)
content_len = int(r.headers.get('Content-Length', '0')) or None
with manager.counter(
color='green',
total=content_len and math.ceil(content_len / 2 ** 20),
unit='MiB',
leave=False
) as counter:
with open(temp_file, 'wb', buffering=2 ** 24) as file_handle:
for chunk in r.iter_content(chunk_size=2 ** 20):
file_handle.write(chunk)
counter.update()
# get file with checksum
_print("Calculating sha256 ...", 2)
calc_checksum = sha256_sum(temp_file)
if v.get(platform_name):
item_hash = v.get(platform_name).get("hash")
else:
item_hash = v.get("hash")
if item_hash != calc_checksum:
_print("Downloaded files checksum invalid.")
sys.exit(1)
_print("File OK", 3)
if not destination_path.exists():
destination_path.mkdir(parents=True)
# extract to destination
archive_type = temp_file.suffix.lstrip(".")
_print(f"Extracting {archive_type} file to {destination_path}")
if archive_type in ['zip']:
zip_file = zipfile.ZipFile(temp_file)
zip_file.extractall(destination_path)
zip_file.close()
elif archive_type in [
'tar', 'tgz', 'tar.gz', 'tar.xz', 'tar.bz2'
]:
if archive_type == 'tar':
tar_type = 'r:'
elif archive_type.endswith('xz'):
tar_type = 'r:xz'
elif archive_type.endswith('gz'):
tar_type = 'r:gz'
elif archive_type.endswith('bz2'):
tar_type = 'r:bz2'
else:
tar_type = 'r:*'
try:
tar_file = tarfile.open(temp_file, tar_type)
except tarfile.ReadError:
raise SystemExit("corrupted archive")
tar_file.extractall(destination_path)
tar_file.close()
_print("Extraction OK", 3)
def main():
start_time = time.time_ns()
openpype_root = Path(os.path.dirname(__file__)).parent
pyproject = toml.load(openpype_root / "pyproject.toml")
platform_name = platform.system().lower()
install_qtbinding(pyproject, openpype_root, platform_name)
install_runtime_dependencies(pyproject, openpype_root)
install_thirdparty(pyproject, openpype_root, platform_name)
end_time = time.time_ns()
total_time = (end_time - start_time) / 1000000000
_print(f"Downloading and extracting took {total_time} secs.")
if __name__ == "__main__":
main()

View file

@ -1,101 +0,0 @@
#!/usr/bin/env bash
art () {
cat <<-EOF
. . .. . ..
_oOOP3OPP3Op_. .
.PPpo~· ·· ~2p. ·· ···· · ·
·Ppo · .pPO3Op.· · O:· · · ·
.3Pp · oP3'· 'P33· · 4 ·· · · · ·· · · ·
·~OP 3PO· .Op3 : · ·· _____ _____ _____
·P3O · oP3oP3O3P' · · · · / /·/ /·/ /
O3:· O3p~ · ·:· · ·/____/·/____/ /____/
'P · 3p3· oP3~· ·.P:· · · ·· · · ·· · · ·
· ': · Po' ·Opo'· .3O· . o[ by Pype Club ]]]==- - - · ·
· '_ .. · . _OP3·· · ·https://openpype.io·· ·
~P3·OPPPO3OP~ · ·· ·
· ' '· · ·· · · · ·· ·
EOF
}
# Colors for terminal
RST='\033[0m' # Text Reset
# Regular Colors
Black='\033[0;30m' # Black
Red='\033[0;31m' # Red
Green='\033[0;32m' # Green
Yellow='\033[0;33m' # Yellow
Blue='\033[0;34m' # Blue
Purple='\033[0;35m' # Purple
Cyan='\033[0;36m' # Cyan
White='\033[0;37m' # White
# Bold
BBlack='\033[1;30m' # Black
BRed='\033[1;31m' # Red
BGreen='\033[1;32m' # Green
BYellow='\033[1;33m' # Yellow
BBlue='\033[1;34m' # Blue
BPurple='\033[1;35m' # Purple
BCyan='\033[1;36m' # Cyan
BWhite='\033[1;37m' # White
# Bold High Intensity
BIBlack='\033[1;90m' # Black
BIRed='\033[1;91m' # Red
BIGreen='\033[1;92m' # Green
BIYellow='\033[1;93m' # Yellow
BIBlue='\033[1;94m' # Blue
BIPurple='\033[1;95m' # Purple
BICyan='\033[1;96m' # Cyan
BIWhite='\033[1;97m' # White
##############################################################################
# Return absolute path
# Globals:
# None
# Arguments:
# Path to resolve
# Returns:
# None
###############################################################################
realpath () {
echo $(cd $(dirname "$1"); pwd)/$(basename "$1")
}
# Main
main () {
echo -e "${BGreen}"
art
echo -e "${RST}"
# Directories
openpype_root=$(realpath $(dirname $(dirname "${BASH_SOURCE[0]}")))
_inside_openpype_tool="1"
if [[ -z $POETRY_HOME ]]; then
export POETRY_HOME="$openpype_root/.poetry"
fi
echo -e "${BIGreen}>>>${RST} Reading Poetry ... \c"
if [ -f "$POETRY_HOME/bin/poetry" ]; then
echo -e "${BIGreen}OK${RST}"
else
echo -e "${BIYellow}NOT FOUND${RST}"
echo -e "${BIYellow}***${RST} We need to install Poetry and virtual env ..."
. "$openpype_root/tools/create_env.sh" || { echo -e "${BIRed}!!!${RST} Poetry installation failed"; return; }
fi
pushd "$openpype_root" > /dev/null || return > /dev/null
echo -e "${BIGreen}>>>${RST} Running Pype tool ..."
"$POETRY_HOME/bin/poetry" run python "$openpype_root/tools/fetch_thirdparty_libs.py"
}
main

View file

@ -1,83 +0,0 @@
# -*- coding: utf-8 -*-
"""Get version and license information on used Python packages.
This is getting over all packages installed with Poetry and printing out
their name, version and available license information from PyPi in Markdown
table format.
Usage:
./.poetry/bin/poetry run python ./tools/get_python_packages_info.py
"""
import toml
import requests
packages = []
# define column headers
package_header = "Package"
version_header = "Version"
license_header = "License"
name_col_width = len(package_header)
version_col_width = len(version_header)
license_col_width = len(license_header)
# read lock file to get packages
with open("poetry.lock", "r") as fb:
lock_content = toml.load(fb)
for package in lock_content["package"]:
# query pypi for license information
url = f"https://pypi.org/pypi/{package['name']}/json"
response = requests.get(
f"https://pypi.org/pypi/{package['name']}/json")
package_data = response.json()
version = package.get("version") or "N/A"
try:
package_license = package_data["info"].get("license") or "N/A"
except KeyError:
package_license = "N/A"
if len(package_license) > 64:
package_license = f"{package_license[:32]}..."
packages.append(
(
package["name"],
version,
package_license
)
)
# update column width based on max string length
if len(package["name"]) > name_col_width:
name_col_width = len(package["name"])
if len(version) > version_col_width:
version_col_width = len(version)
if len(package_license) > license_col_width:
license_col_width = len(package_license)
# pad columns
name_col_width += 2
version_col_width += 2
license_col_width += 2
# print table header
print((f"|{package_header.center(name_col_width)}"
f"|{version_header.center(version_col_width)}"
f"|{license_header.center(license_col_width)}|"))
print(
"|" + ("-" * len(package_header.center(name_col_width))) +
"|" + ("-" * len(version_header.center(version_col_width))) +
"|" + ("-" * len(license_header.center(license_col_width))) + "|")
# print rest of the table
for package in packages:
print((
f"|{package[0].center(name_col_width)}"
f"|{package[1].center(version_col_width)}"
f"|{package[2].center(license_col_width)}|"
))

View file

@ -1,73 +0,0 @@
<#
.SYNOPSIS
Helper script to update OpenPype Sphinx sources.
.DESCRIPTION
This script will run apidoc over OpenPype sources and generate new source rst
files for documentation. Then it will run build_sphinx to create test html
documentation build.
.EXAMPLE
PS> .\make_docs.ps1
#>
$current_dir = Get-Location
$script_dir = Split-Path -Path $MyInvocation.MyCommand.Definition -Parent
$openpype_root = (Get-Item $script_dir).parent.FullName
$env:_INSIDE_OPENPYPE_TOOL = "1"
if (-not (Test-Path 'env:POETRY_HOME')) {
$env:POETRY_HOME = "$openpype_root\.poetry"
}
Set-Location -Path $openpype_root
$art = @"
. . .. . ..
_oOOP3OPP3Op_. .
.PPpo~. .. ~2p. .. .... . .
.Ppo . .pPO3Op.. . O:. . . .
.3Pp . oP3'. 'P33. . 4 .. . . . .. . . .
.~OP 3PO. .Op3 : . .. _____ _____ _____
.P3O . oP3oP3O3P' . . . . / /./ /./ /
O3:. O3p~ . .:. . ./____/./____/ /____/
'P . 3p3. oP3~. ..P:. . . .. . . .. . . .
. ': . Po' .Opo'. .3O. . o[ by Pype Club ]]]==- - - . .
. '_ .. . . _OP3.. . .https://openpype.io.. .
~P3.OPPPO3OP~ . .. .
. ' '. . .. . . . .. .
"@
$current_dir = Get-Location
$script_dir = Split-Path -Path $MyInvocation.MyCommand.Definition -Parent
$openpype_root = (Get-Item $script_dir).parent.FullName
# Install PSWriteColor to support colorized output to terminal
$env:PSModulePath = $env:PSModulePath + ";$($openpype_root)\tools\modules\powershell"
Write-Host $art -ForegroundColor DarkGreen
Write-Color -Text ">>> ", "Reading Poetry ... " -Color Green, Gray -NoNewline
if (-not (Test-Path -PathType Container -Path "$($env:POETRY_HOME)\bin")) {
Write-Color -Text "NOT FOUND" -Color Yellow
Install-Poetry
Write-Color -Text "INSTALLED" -Color Cyan
} else {
Write-Color -Text "OK" -Color Green
}
Write-Color -Text "... ", "This will not overwrite existing source rst files, only scan and add new." -Color Yellow, Gray
Set-Location -Path $openpype_root
Write-Color -Text ">>> ", "Running apidoc ..." -Color Green, Gray
& "$env:POETRY_HOME\bin\poetry" run sphinx-apidoc -M -e -d 10 --ext-intersphinx --ext-todo --ext-coverage --ext-viewcode -o "$($openpype_root)\docs\source" igniter
& "$env:POETRY_HOME\bin\poetry" run sphinx-apidoc.exe -M -e -d 10 --ext-intersphinx --ext-todo --ext-coverage --ext-viewcode -o "$($openpype_root)\docs\source" openpype vendor, openpype\vendor
Write-Color -Text ">>> ", "Building html ..." -Color Green, Gray
& "$env:POETRY_HOME\bin\poetry" run python "$($openpype_root)\setup.py" build_sphinx
Set-Location -Path $current_dir

Some files were not shown because too many files have changed in this diff Show more