mirror of
https://github.com/ynput/ayon-core.git
synced 2025-12-24 04:44:41 +01:00
cleanup root of repository
This commit is contained in:
parent
56bfe209f6
commit
22260b3e6d
775 changed files with 5 additions and 61446 deletions
107
.github/ISSUE_TEMPLATE/bug_report.yml
vendored
107
.github/ISSUE_TEMPLATE/bug_report.yml
vendored
|
|
@ -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
|
||||
|
|
|
|||
102
.github/pr-glob-labeler.yml
vendored
102
.github/pr-glob-labeler.yml
vendored
|
|
@ -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*/**/*'
|
||||
65
.github/workflows/documentation.yml
vendored
65
.github/workflows/documentation.yml
vendored
|
|
@ -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/
|
||||
28
.github/workflows/milestone_assign.yml
vendored
28
.github/workflows/milestone_assign.yml
vendored
|
|
@ -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'
|
||||
62
.github/workflows/milestone_create.yml
vendored
62
.github/workflows/milestone_create.yml
vendored
|
|
@ -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 }}"
|
||||
44
.github/workflows/miletone_release_trigger.yml
vendored
44
.github/workflows/miletone_release_trigger.yml
vendored
|
|
@ -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 }}
|
||||
29
.github/workflows/nightly_merge.yml
vendored
29
.github/workflows/nightly_merge.yml
vendored
|
|
@ -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 }}
|
||||
73
.github/workflows/prerelease.yml
vendored
73
.github/workflows/prerelease.yml
vendored
|
|
@ -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 }}
|
||||
66
.github/workflows/test_build.yml
vendored
66
.github/workflows/test_build.yml
vendored
|
|
@ -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
7
.gitmodules
vendored
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
18614
CHANGELOG.md
File diff suppressed because it is too large
Load diff
82
Dockerfile
82
Dockerfile
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
3808
HISTORY.md
File diff suppressed because it is too large
Load diff
355
README.md
355
README.md
|
|
@ -2,358 +2,5 @@
|
|||
<!-- ALL-CONTRIBUTORS-BADGE:START - Do not remove or modify this section -->
|
||||
[](#contributors-)
|
||||
<!-- ALL-CONTRIBUTORS-BADGE:END -->
|
||||
OpenPype
|
||||
AYON-core
|
||||
========
|
||||
|
||||
[](https://github.com/pypeclub/pype/actions/workflows/documentation.yml) 
|
||||
|
||||
## 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!
|
||||
|
|
|
|||
|
|
@ -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])
|
||||
|
|
@ -1,3 +0,0 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
"""Conftest."""
|
||||
...
|
||||
|
|
@ -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)
|
||||
|
|
@ -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)
|
||||
|
|
@ -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
|
||||
|
|
@ -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 |
|
|
@ -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>`_
|
||||
|
|
@ -1 +0,0 @@
|
|||
{% extends "python/data.rst" %}
|
||||
|
|
@ -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 %}
|
||||
|
|
@ -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 %}
|
||||
|
|
@ -1 +0,0 @@
|
|||
{% extends "python/class.rst" %}
|
||||
|
|
@ -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 %}
|
||||
|
|
@ -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 %}
|
||||
|
|
@ -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 %}
|
||||
|
|
@ -1 +0,0 @@
|
|||
{% extends "python/module.rst" %}
|
||||
|
|
@ -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 %}
|
||||
|
|
@ -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
|
||||
|
|
@ -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`
|
||||
|
|
@ -1,6 +0,0 @@
|
|||
===============
|
||||
OpenPype Readme
|
||||
===============
|
||||
|
||||
.. include:: ../../README.md
|
||||
:parser: myst_parser.sphinx_
|
||||
|
|
@ -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.
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.
Binary file not shown.
|
|
@ -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"
|
||||
]
|
||||
|
|
@ -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
|
|
@ -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_())
|
||||
|
|
@ -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)
|
||||
|
|
@ -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())
|
||||
|
|
@ -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 |
|
|
@ -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 .
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
|
@ -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))
|
||||
247
igniter/tools.py
247
igniter/tools.py
|
|
@ -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"
|
||||
)
|
||||
|
|
@ -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)
|
||||
|
|
@ -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)
|
||||
|
|
@ -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)
|
||||
|
|
@ -1,4 +0,0 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
"""Definition of Igniter version."""
|
||||
|
||||
__version__ = "1.0.2"
|
||||
|
|
@ -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
3500
poetry.lock
generated
File diff suppressed because it is too large
Load diff
|
|
@ -1,5 +0,0 @@
|
|||
[virtualenvs]
|
||||
in-project = true
|
||||
|
||||
[repositories.pype]
|
||||
url = "https://distribute.openpype.io/wheels/"
|
||||
188
pyproject.toml
188
pyproject.toml
|
|
@ -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"
|
||||
|
|
@ -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
200
setup.py
|
|
@ -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=[]
|
||||
)
|
||||
|
|
@ -1 +0,0 @@
|
|||
I have run
|
||||
196
tools/build.ps1
196
tools/build.ps1
|
|
@ -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
|
||||
230
tools/build.sh
230
tools/build.sh
|
|
@ -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
|
||||
|
|
@ -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.")
|
||||
|
|
@ -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
|
||||
|
|
@ -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()
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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()
|
||||
|
|
@ -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 "$@"
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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 {}
|
||||
|
|
@ -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()
|
||||
|
|
@ -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
|
||||
|
|
@ -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)}|"
|
||||
))
|
||||
|
|
@ -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
Loading…
Add table
Add a link
Reference in a new issue