WIP: 103268-job-task-progress #104185
@ -4,7 +4,7 @@ This file contains the history of changes to Flamenco. Only changes that might
|
|||||||
be interesting for users are listed here, such as new features and fixes for
|
be interesting for users are listed here, such as new features and fixes for
|
||||||
bugs in actually-released versions.
|
bugs in actually-released versions.
|
||||||
|
|
||||||
## 3.2 - in development
|
## 3.2 - released 2023-02-21
|
||||||
|
|
||||||
- When rendering EXR files, use Blender's preview JPEG files to generate the preview video ([43bc22f10fae](https://developer.blender.org/rF43bc22f10fae0fcaed6a4a3b3ace1be617193e21)).
|
- When rendering EXR files, use Blender's preview JPEG files to generate the preview video ([43bc22f10fae](https://developer.blender.org/rF43bc22f10fae0fcaed6a4a3b3ace1be617193e21)).
|
||||||
- Fix issue where workers would switch immediately on a state change request, even if it was of the "after task is finished" kind.
|
- Fix issue where workers would switch immediately on a state change request, even if it was of the "after task is finished" kind.
|
||||||
@ -16,7 +16,10 @@ bugs in actually-released versions.
|
|||||||
- Increase preview image file size from 10 MB to 25 MB. Even though the Worker can down-scale render output before sending to the Manager as preview, they could still be larger than the limit of 10 MB.
|
- Increase preview image file size from 10 MB to 25 MB. Even though the Worker can down-scale render output before sending to the Manager as preview, they could still be larger than the limit of 10 MB.
|
||||||
- Fix a crash of the Manager when using an invalid frame range (`1 10` for example, instead of `1-10` or `1,10`)
|
- Fix a crash of the Manager when using an invalid frame range (`1 10` for example, instead of `1-10` or `1,10`)
|
||||||
- Make it possible to delete jobs. The job and its tasks are removed from Flamenco, including last-rendered images and logs. The input files (i.e. the to-be-rendered blend files and their dependencies) will only be removed if [the Shaman system](https://flamenco.blender.org/usage/shared-storage/shaman/) was used AND if the job was submitted with Flamenco 3.2 or newer.
|
- Make it possible to delete jobs. The job and its tasks are removed from Flamenco, including last-rendered images and logs. The input files (i.e. the to-be-rendered blend files and their dependencies) will only be removed if [the Shaman system](https://flamenco.blender.org/usage/shared-storage/shaman/) was used AND if the job was submitted with Flamenco 3.2 or newer.
|
||||||
|
- Security updates of some dependencies:
|
||||||
|
- https://pkg.go.dev/vuln/GO-2022-1031
|
||||||
|
- https://pkg.go.dev/vuln/GO-2023-1571
|
||||||
|
- https://pkg.go.dev/vuln/GO-2023-1572
|
||||||
|
|
||||||
|
|
||||||
## 3.1 - released 2022-10-18
|
## 3.1 - released 2022-10-18
|
||||||
|
4
Makefile
@ -2,8 +2,8 @@ PKG := git.blender.org/flamenco
|
|||||||
|
|
||||||
# To update the version number in all the relevant places, update the VERSION
|
# To update the version number in all the relevant places, update the VERSION
|
||||||
# variable below and run `make update-version`.
|
# variable below and run `make update-version`.
|
||||||
VERSION := 3.2-beta
|
VERSION := 3.2
|
||||||
RELEASE_CYCLE := beta
|
RELEASE_CYCLE := release
|
||||||
|
|
||||||
# _GIT_DESCRIPTION_OR_TAG is either something like '16-123abc' (when we're 16
|
# _GIT_DESCRIPTION_OR_TAG is either something like '16-123abc' (when we're 16
|
||||||
# commits since the last tag) or it's something like `v3.0-beta2` (when exactly
|
# commits since the last tag) or it's something like `v3.0-beta2` (when exactly
|
||||||
|
@ -12,7 +12,7 @@ bl_info = {
|
|||||||
"doc_url": "https://flamenco.blender.org/",
|
"doc_url": "https://flamenco.blender.org/",
|
||||||
"category": "System",
|
"category": "System",
|
||||||
"support": "COMMUNITY",
|
"support": "COMMUNITY",
|
||||||
"warning": "This is version 3.2-beta of the add-on, which is not a stable release",
|
"warning": "",
|
||||||
}
|
}
|
||||||
|
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
2
addon/flamenco/manager/__init__.py
generated
@ -10,7 +10,7 @@
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
__version__ = "3.2-beta"
|
__version__ = "3.2"
|
||||||
|
|
||||||
# import ApiClient
|
# import ApiClient
|
||||||
from flamenco.manager.api_client import ApiClient
|
from flamenco.manager.api_client import ApiClient
|
||||||
|
2
addon/flamenco/manager/api_client.py
generated
@ -76,7 +76,7 @@ class ApiClient(object):
|
|||||||
self.default_headers[header_name] = header_value
|
self.default_headers[header_name] = header_value
|
||||||
self.cookie = cookie
|
self.cookie = cookie
|
||||||
# Set default User-Agent.
|
# Set default User-Agent.
|
||||||
self.user_agent = 'Flamenco/3.2-beta (Blender add-on)'
|
self.user_agent = 'Flamenco/3.2 (Blender add-on)'
|
||||||
|
|
||||||
def __enter__(self):
|
def __enter__(self):
|
||||||
return self
|
return self
|
||||||
|
2
addon/flamenco/manager/configuration.py
generated
@ -404,7 +404,7 @@ conf = flamenco.manager.Configuration(
|
|||||||
"OS: {env}\n"\
|
"OS: {env}\n"\
|
||||||
"Python Version: {pyversion}\n"\
|
"Python Version: {pyversion}\n"\
|
||||||
"Version of the API: 1.0.0\n"\
|
"Version of the API: 1.0.0\n"\
|
||||||
"SDK Package Version: 3.2-beta".\
|
"SDK Package Version: 3.2".\
|
||||||
format(env=sys.platform, pyversion=sys.version)
|
format(env=sys.platform, pyversion=sys.version)
|
||||||
|
|
||||||
def get_host_settings(self):
|
def get_host_settings(self):
|
||||||
|
2
addon/flamenco/manager_README.md
generated
@ -4,7 +4,7 @@ Render Farm manager API
|
|||||||
The `flamenco.manager` package is automatically generated by the [OpenAPI Generator](https://openapi-generator.tech) project:
|
The `flamenco.manager` package is automatically generated by the [OpenAPI Generator](https://openapi-generator.tech) project:
|
||||||
|
|
||||||
- API version: 1.0.0
|
- API version: 1.0.0
|
||||||
- Package version: 3.2-beta
|
- Package version: 3.2
|
||||||
- Build package: org.openapitools.codegen.languages.PythonClientCodegen
|
- Build package: org.openapitools.codegen.languages.PythonClientCodegen
|
||||||
For more information, please visit [https://flamenco.io/](https://flamenco.io/)
|
For more information, please visit [https://flamenco.io/](https://flamenco.io/)
|
||||||
|
|
||||||
|
8
go.mod
@ -25,8 +25,8 @@ require (
|
|||||||
github.com/stretchr/testify v1.7.0
|
github.com/stretchr/testify v1.7.0
|
||||||
github.com/ziflex/lecho/v3 v3.1.0
|
github.com/ziflex/lecho/v3 v3.1.0
|
||||||
golang.org/x/crypto v0.0.0-20211215165025-cf75a172585e
|
golang.org/x/crypto v0.0.0-20211215165025-cf75a172585e
|
||||||
golang.org/x/image v0.0.0-20191009234506-e7c1f5e7dbb8
|
golang.org/x/image v0.5.0
|
||||||
golang.org/x/net v0.5.0
|
golang.org/x/net v0.7.0
|
||||||
gopkg.in/yaml.v2 v2.4.0
|
gopkg.in/yaml.v2 v2.4.0
|
||||||
gorm.io/gorm v1.23.8
|
gorm.io/gorm v1.23.8
|
||||||
modernc.org/sqlite v1.17.3
|
modernc.org/sqlite v1.17.3
|
||||||
@ -52,8 +52,8 @@ require (
|
|||||||
github.com/valyala/bytebufferpool v1.0.0 // indirect
|
github.com/valyala/bytebufferpool v1.0.0 // indirect
|
||||||
github.com/valyala/fasttemplate v1.2.1 // indirect
|
github.com/valyala/fasttemplate v1.2.1 // indirect
|
||||||
golang.org/x/mod v0.7.0 // indirect
|
golang.org/x/mod v0.7.0 // indirect
|
||||||
golang.org/x/sys v0.4.0 // indirect
|
golang.org/x/sys v0.5.0 // indirect
|
||||||
golang.org/x/text v0.6.0 // indirect
|
golang.org/x/text v0.7.0 // indirect
|
||||||
golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba // indirect
|
golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba // indirect
|
||||||
golang.org/x/tools v0.5.1-0.20230117180257-8aba49bb5ea2 // indirect
|
golang.org/x/tools v0.5.1-0.20230117180257-8aba49bb5ea2 // indirect
|
||||||
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect
|
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect
|
||||||
|
23
go.sum
@ -163,6 +163,7 @@ github.com/valyala/fasttemplate v1.2.1/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+
|
|||||||
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||||
github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
|
github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
|
||||||
github.com/yuin/goldmark v1.4.0/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
|
github.com/yuin/goldmark v1.4.0/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
|
||||||
|
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
|
||||||
github.com/ziflex/lecho/v3 v3.1.0 h1:65bSzSc0yw7EEhi44lMnkOI877ZzbE7tGDWfYCQXZwI=
|
github.com/ziflex/lecho/v3 v3.1.0 h1:65bSzSc0yw7EEhi44lMnkOI877ZzbE7tGDWfYCQXZwI=
|
||||||
github.com/ziflex/lecho/v3 v3.1.0/go.mod h1:dwQ6xCAKmSBHhwZ6XmiAiDptD7iklVkW7xQYGUncX0Q=
|
github.com/ziflex/lecho/v3 v3.1.0/go.mod h1:dwQ6xCAKmSBHhwZ6XmiAiDptD7iklVkW7xQYGUncX0Q=
|
||||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||||
@ -175,11 +176,13 @@ golang.org/x/crypto v0.0.0-20210817164053-32db794688a5/go.mod h1:GvvjBRRGRdwPK5y
|
|||||||
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||||
golang.org/x/crypto v0.0.0-20211215165025-cf75a172585e h1:1SzTfNOXwIS2oWiMF+6qu0OUDKb0dauo6MoDUQyu+yU=
|
golang.org/x/crypto v0.0.0-20211215165025-cf75a172585e h1:1SzTfNOXwIS2oWiMF+6qu0OUDKb0dauo6MoDUQyu+yU=
|
||||||
golang.org/x/crypto v0.0.0-20211215165025-cf75a172585e/go.mod h1:P+XmwS30IXTQdn5tA2iutPOUgjI07+tq3H3K9MVA1s8=
|
golang.org/x/crypto v0.0.0-20211215165025-cf75a172585e/go.mod h1:P+XmwS30IXTQdn5tA2iutPOUgjI07+tq3H3K9MVA1s8=
|
||||||
golang.org/x/image v0.0.0-20191009234506-e7c1f5e7dbb8 h1:hVwzHzIUGRjiF7EcUjqNxk3NCfkPxbDKRdnNE1Rpg0U=
|
|
||||||
golang.org/x/image v0.0.0-20191009234506-e7c1f5e7dbb8/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
|
golang.org/x/image v0.0.0-20191009234506-e7c1f5e7dbb8/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
|
||||||
|
golang.org/x/image v0.5.0 h1:5JMiNunQeQw++mMOz48/ISeNu3Iweh/JaZU8ZLqHRrI=
|
||||||
|
golang.org/x/image v0.5.0/go.mod h1:FVC7BI/5Ym8R25iw5OLsgshdUBbT1h5jZTpA+mvAdZ4=
|
||||||
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||||
golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||||
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||||
|
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
|
||||||
golang.org/x/mod v0.7.0 h1:LapD9S96VoQRhi/GrNTqeBJFrUjs5UHCAtTlgwA5oZA=
|
golang.org/x/mod v0.7.0 h1:LapD9S96VoQRhi/GrNTqeBJFrUjs5UHCAtTlgwA5oZA=
|
||||||
golang.org/x/mod v0.7.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
golang.org/x/mod v0.7.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
||||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||||
@ -190,12 +193,14 @@ golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v
|
|||||||
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
|
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
|
||||||
golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||||
golang.org/x/net v0.0.0-20210913180222-943fd674d43e/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
golang.org/x/net v0.0.0-20210913180222-943fd674d43e/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||||
golang.org/x/net v0.5.0 h1:GyT4nK/YDHSqa1c4753ouYCDajOYKTja9Xb/OHtgvSw=
|
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
||||||
golang.org/x/net v0.5.0/go.mod h1:DivGGAXEgPSlEBzxGzZI+ZLohi+xUj054jfeKui00ws=
|
golang.org/x/net v0.7.0 h1:rJrUqqhjsgNp7KqAIc25s9pZnjU7TUcSY7HcVZjdn1g=
|
||||||
|
golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
|
||||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
|
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
@ -222,17 +227,20 @@ golang.org/x/sys v0.0.0-20211025201205-69cdffdb9359/go.mod h1:oPkhp1MJrh7nUepCBc
|
|||||||
golang.org/x/sys v0.0.0-20211031064116-611d5d643895/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20211031064116-611d5d643895/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.0.0-20211103235746-7861aae1554b/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20211103235746-7861aae1554b/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.0.0-20220405052023-b1e9470b6e64/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20220405052023-b1e9470b6e64/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.4.0 h1:Zr2JFtRQNX3BCZ8YtxRE9hNJYC8J6I1MVbMg6owUp18=
|
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.4.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
|
golang.org/x/sys v0.5.0 h1:MUK/U/4lj1t1oPg0HfuXDN/Z1wv31ZJ/YcPiGccS4DU=
|
||||||
|
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
|
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
|
||||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||||
|
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
||||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||||
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||||
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
||||||
golang.org/x/text v0.6.0 h1:3XmdazWV+ubf7QgHSTWeykHOci5oeekaGJBLkrkaw4k=
|
golang.org/x/text v0.7.0 h1:4BRB4x83lYWy72KwLD/qYDuTu7q9PjSagHvijDw7cLo=
|
||||||
golang.org/x/text v0.6.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
||||||
golang.org/x/time v0.0.0-20201208040808-7e3f01d25324/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
golang.org/x/time v0.0.0-20201208040808-7e3f01d25324/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||||
golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba h1:O8mE0/t419eoIwhTFpKVkHiTs/Igowgfkj25AcZrtiE=
|
golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba h1:O8mE0/t419eoIwhTFpKVkHiTs/Igowgfkj25AcZrtiE=
|
||||||
golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||||
@ -243,6 +251,7 @@ golang.org/x/tools v0.0.0-20201124115921-2c860bdd6e78/go.mod h1:emZCQorbCU4vsT4f
|
|||||||
golang.org/x/tools v0.0.0-20210114065538-d78b04bdf963/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
golang.org/x/tools v0.0.0-20210114065538-d78b04bdf963/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||||
golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
|
golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
|
||||||
golang.org/x/tools v0.1.7/go.mod h1:LGqMHiF4EqQNHR1JncWGqT5BVaXmza+X+BDGol+dOxo=
|
golang.org/x/tools v0.1.7/go.mod h1:LGqMHiF4EqQNHR1JncWGqT5BVaXmza+X+BDGol+dOxo=
|
||||||
|
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
|
||||||
golang.org/x/tools v0.5.1-0.20230117180257-8aba49bb5ea2 h1:v0FhRDmSCNH/0EurAT6T8KRY4aNuUhz6/WwBMxG+gvQ=
|
golang.org/x/tools v0.5.1-0.20230117180257-8aba49bb5ea2 h1:v0FhRDmSCNH/0EurAT6T8KRY4aNuUhz6/WwBMxG+gvQ=
|
||||||
golang.org/x/tools v0.5.1-0.20230117180257-8aba49bb5ea2/go.mod h1:N+Kgy78s5I24c24dU8OfWNEotWjutIs8SnJvn5IDq+k=
|
golang.org/x/tools v0.5.1-0.20230117180257-8aba49bb5ea2/go.mod h1:N+Kgy78s5I24c24dU8OfWNEotWjutIs8SnJvn5IDq+k=
|
||||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
|
@ -24,6 +24,7 @@ var ApplicationGitHash = "set-during-build"
|
|||||||
// that only supports strings.
|
// that only supports strings.
|
||||||
var ReleaseCycle string = "set-during-build"
|
var ReleaseCycle string = "set-during-build"
|
||||||
|
|
||||||
|
const releaseCycleReleaseCandidate = "rc"
|
||||||
const releaseCycleRelease = "release"
|
const releaseCycleRelease = "release"
|
||||||
|
|
||||||
// FormattedApplicationInfo returns the application name & version as single string.
|
// FormattedApplicationInfo returns the application name & version as single string.
|
||||||
@ -39,9 +40,10 @@ func UserAgent() string {
|
|||||||
// ExtendedVersion returns the application version, and includes the Git hash if
|
// ExtendedVersion returns the application version, and includes the Git hash if
|
||||||
// this is not a release version. See `IsReleaseVersion`.
|
// this is not a release version. See `IsReleaseVersion`.
|
||||||
func ExtendedVersion() string {
|
func ExtendedVersion() string {
|
||||||
if ReleaseCycle == releaseCycleRelease {
|
switch ReleaseCycle {
|
||||||
|
case releaseCycleRelease, releaseCycleReleaseCandidate:
|
||||||
return ApplicationVersion
|
return ApplicationVersion
|
||||||
|
default:
|
||||||
|
return fmt.Sprintf("%s-%s", ApplicationVersion, ApplicationGitHash)
|
||||||
}
|
}
|
||||||
|
|
||||||
return fmt.Sprintf("%s-%s", ApplicationVersion, ApplicationGitHash)
|
|
||||||
}
|
}
|
||||||
|
Before Width: | Height: | Size: 9.3 KiB After Width: | Height: | Size: 9.3 KiB |
Before Width: | Height: | Size: 34 KiB After Width: | Height: | Size: 34 KiB |
Before Width: | Height: | Size: 9.4 KiB After Width: | Height: | Size: 9.4 KiB |
Before Width: | Height: | Size: 513 B After Width: | Height: | Size: 513 B |
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.1 KiB |
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 12 KiB |
Before Width: | Height: | Size: 34 KiB After Width: | Height: | Size: 34 KiB |
8
web/app/public/mkico.sh
Executable file
@ -0,0 +1,8 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
convert flamenco.png -bordercolor '#00000000' -border 0 \
|
||||||
|
\( -clone 0 -resize 16x16 \) \
|
||||||
|
\( -clone 0 -resize 32x32 \) \
|
||||||
|
\( -clone 0 -resize 48x48 \) \
|
||||||
|
\( -clone 0 -resize 64x64 \) \
|
||||||
|
-delete 0 -colors 256 favicon.ico
|
@ -26,7 +26,7 @@
|
|||||||
|
|
||||||
<script>
|
<script>
|
||||||
import * as API from '@/manager-api';
|
import * as API from '@/manager-api';
|
||||||
import { apiClient } from '@/stores/api-query-count';
|
import { getAPIClient } from "@/api-client";
|
||||||
import { backendURL } from '@/urls';
|
import { backendURL } from '@/urls';
|
||||||
|
|
||||||
import ApiSpinner from '@/components/ApiSpinner.vue'
|
import ApiSpinner from '@/components/ApiSpinner.vue'
|
||||||
@ -51,7 +51,7 @@ export default {
|
|||||||
methods: {
|
methods: {
|
||||||
// TODO: also call this when SocketIO reconnects.
|
// TODO: also call this when SocketIO reconnects.
|
||||||
fetchManagerInfo() {
|
fetchManagerInfo() {
|
||||||
const metaAPI = new API.MetaApi(apiClient);
|
const metaAPI = new API.MetaApi(getAPIClient());
|
||||||
metaAPI.getVersion().then((version) => {
|
metaAPI.getVersion().then((version) => {
|
||||||
this.flamencoName = version.name;
|
this.flamencoName = version.name;
|
||||||
this.flamencoVersion = version.version;
|
this.flamencoVersion = version.version;
|
||||||
|
@ -17,7 +17,7 @@ const DEFAULT_FLAMENCO_NAME = "Flamenco";
|
|||||||
const DEFAULT_FLAMENCO_VERSION = "unknown";
|
const DEFAULT_FLAMENCO_VERSION = "unknown";
|
||||||
import ApiSpinner from '@/components/ApiSpinner.vue'
|
import ApiSpinner from '@/components/ApiSpinner.vue'
|
||||||
import { MetaApi } from "@/manager-api";
|
import { MetaApi } from "@/manager-api";
|
||||||
import { apiClient } from '@/stores/api-query-count';
|
import { getAPIClient } from "@/api-client";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'SetupAssistant',
|
name: 'SetupAssistant',
|
||||||
@ -35,7 +35,7 @@ export default {
|
|||||||
methods: {
|
methods: {
|
||||||
// TODO: also call this when SocketIO reconnects.
|
// TODO: also call this when SocketIO reconnects.
|
||||||
fetchManagerInfo() {
|
fetchManagerInfo() {
|
||||||
const metaAPI = new MetaApi(apiClient);
|
const metaAPI = new MetaApi(getAPIClient());
|
||||||
metaAPI.getVersion().then((version) => {
|
metaAPI.getVersion().then((version) => {
|
||||||
this.flamencoName = version.name;
|
this.flamencoName = version.name;
|
||||||
this.flamencoVersion = version.version;
|
this.flamencoVersion = version.version;
|
||||||
|
39
web/app/src/api-client.js
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
import { ApiClient } from "@/manager-api";
|
||||||
|
import { CountingApiClient } from "@/stores/api-query-count";
|
||||||
|
import { api as apiURL } from '@/urls'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Scrub the custom User-Agent header from the API client, for those webbrowsers
|
||||||
|
* who do not want to have it set.
|
||||||
|
*
|
||||||
|
* It's actually scrubbed for all webbrowsers, as those privacy-first
|
||||||
|
* webbrowsers also make it hard to fingerprint which browser you're using (for
|
||||||
|
* good reason).
|
||||||
|
*
|
||||||
|
* @param {ApiClient} apiClient
|
||||||
|
*/
|
||||||
|
export function scrubAPIClient(apiClient) {
|
||||||
|
delete apiClient.defaultHeaders['User-Agent'];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @returns {ApiClient} Bare API client that is not connected to the UI in any way.
|
||||||
|
*/
|
||||||
|
export function newBareAPIClient() {
|
||||||
|
const apiClient = new ApiClient(apiURL());
|
||||||
|
scrubAPIClient(apiClient);
|
||||||
|
return apiClient;
|
||||||
|
}
|
||||||
|
|
||||||
|
let apiClient = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @returns {ApiClient} API client that updates the UI to show long-running queries.
|
||||||
|
*/
|
||||||
|
export function getAPIClient() {
|
||||||
|
if (apiClient == null) {
|
||||||
|
apiClient = new CountingApiClient(apiURL());
|
||||||
|
scrubAPIClient(apiClient);
|
||||||
|
}
|
||||||
|
return apiClient;
|
||||||
|
}
|
@ -26,7 +26,7 @@
|
|||||||
import { ref } from 'vue';
|
import { ref } from 'vue';
|
||||||
|
|
||||||
import { useNotifs } from '@/stores/notifications';
|
import { useNotifs } from '@/stores/notifications';
|
||||||
import { apiClient } from '@/stores/api-query-count';
|
import { getAPIClient } from "@/api-client";
|
||||||
import { JobsApi, JobPriorityChange } from '@/manager-api';
|
import { JobsApi, JobPriorityChange } from '@/manager-api';
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
@ -45,7 +45,7 @@ const errorMessage = ref('');
|
|||||||
// Methods
|
// Methods
|
||||||
function updateJobPriority() {
|
function updateJobPriority() {
|
||||||
const jobPriorityChange = new JobPriorityChange(priorityState.value);
|
const jobPriorityChange = new JobPriorityChange(priorityState.value);
|
||||||
const jobsAPI = new JobsApi(apiClient);
|
const jobsAPI = new JobsApi(getAPIClient());
|
||||||
return jobsAPI.setJobPriority(props.jobId, jobPriorityChange)
|
return jobsAPI.setJobPriority(props.jobId, jobPriorityChange)
|
||||||
.then(() => {
|
.then(() => {
|
||||||
notifs.add(`Updated job priority to ${priorityState.value}`)
|
notifs.add(`Updated job priority to ${priorityState.value}`)
|
||||||
|
@ -3,7 +3,7 @@ import { onMounted, onUnmounted } from 'vue'
|
|||||||
import { TabulatorFull as Tabulator } from 'tabulator-tables';
|
import { TabulatorFull as Tabulator } from 'tabulator-tables';
|
||||||
import { useTaskLog } from '@/stores/tasklog'
|
import { useTaskLog } from '@/stores/tasklog'
|
||||||
import { useTasks } from '@/stores/tasks'
|
import { useTasks } from '@/stores/tasks'
|
||||||
import { apiClient } from '@/stores/api-query-count';
|
import { getAPIClient } from "@/api-client";
|
||||||
import { JobsApi } from '@/manager-api';
|
import { JobsApi } from '@/manager-api';
|
||||||
|
|
||||||
const taskLog = useTaskLog();
|
const taskLog = useTaskLog();
|
||||||
@ -59,7 +59,7 @@ function _fetchLogTail(taskID) {
|
|||||||
|
|
||||||
if (!taskID) return;
|
if (!taskID) return;
|
||||||
|
|
||||||
const jobsAPI = new JobsApi(apiClient);
|
const jobsAPI = new JobsApi(getAPIClient());
|
||||||
return jobsAPI.fetchTaskLogTail(taskID)
|
return jobsAPI.fetchTaskLogTail(taskID)
|
||||||
.then((logTail) => {
|
.then((logTail) => {
|
||||||
taskLog.addChunk(logTail);
|
taskLog.addChunk(logTail);
|
||||||
|
@ -26,7 +26,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { apiClient } from '@/stores/api-query-count';
|
import { getAPIClient } from "@/api-client";
|
||||||
import { JobsApi } from '@/manager-api';
|
import { JobsApi } from '@/manager-api';
|
||||||
import LinkWorker from '@/components/LinkWorker.vue';
|
import LinkWorker from '@/components/LinkWorker.vue';
|
||||||
import { watch, onMounted, inject, ref, nextTick } from 'vue'
|
import { watch, onMounted, inject, ref, nextTick } from 'vue'
|
||||||
@ -35,7 +35,7 @@ import { watch, onMounted, inject, ref, nextTick } from 'vue'
|
|||||||
const props = defineProps(['jobID']);
|
const props = defineProps(['jobID']);
|
||||||
const emit = defineEmits(['reshuffled'])
|
const emit = defineEmits(['reshuffled'])
|
||||||
|
|
||||||
const jobsApi = new JobsApi(apiClient);
|
const jobsApi = new JobsApi(getAPIClient());
|
||||||
const isVisible = inject("isVisible");
|
const isVisible = inject("isVisible");
|
||||||
const isFetching = ref(false);
|
const isFetching = ref(false);
|
||||||
const errorMsg = ref("");
|
const errorMsg = ref("");
|
||||||
|
@ -18,7 +18,7 @@
|
|||||||
<script>
|
<script>
|
||||||
import { useJobs } from '@/stores/jobs';
|
import { useJobs } from '@/stores/jobs';
|
||||||
import { useNotifs } from '@/stores/notifications';
|
import { useNotifs } from '@/stores/notifications';
|
||||||
import { apiClient } from '@/stores/api-query-count';
|
import { getAPIClient } from "@/api-client";
|
||||||
import { JobsApi } from '@/manager-api';
|
import { JobsApi } from '@/manager-api';
|
||||||
import { JobDeletionInfo } from '@/manager-api';
|
import { JobDeletionInfo } from '@/manager-api';
|
||||||
|
|
||||||
@ -31,7 +31,7 @@ export default {
|
|||||||
data: () => ({
|
data: () => ({
|
||||||
jobs: useJobs(),
|
jobs: useJobs(),
|
||||||
notifs: useNotifs(),
|
notifs: useNotifs(),
|
||||||
jobsAPI: new JobsApi(apiClient),
|
jobsAPI: new JobsApi(getAPIClient()),
|
||||||
|
|
||||||
deleteInfo: null,
|
deleteInfo: null,
|
||||||
}),
|
}),
|
||||||
@ -98,7 +98,6 @@ export default {
|
|||||||
* @param { JobDeletionInfo } deleteInfo
|
* @param { JobDeletionInfo } deleteInfo
|
||||||
*/
|
*/
|
||||||
_showDeleteJobPopup(deleteInfo) {
|
_showDeleteJobPopup(deleteInfo) {
|
||||||
console.log("deleteInfo", deleteInfo);
|
|
||||||
this.deleteInfo = deleteInfo;
|
this.deleteInfo = deleteInfo;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -39,7 +39,7 @@
|
|||||||
<dd class="field-status-label" :class="'status-' + jobData.status">{{ jobData.status }}</dd>
|
<dd class="field-status-label" :class="'status-' + jobData.status">{{ jobData.status }}</dd>
|
||||||
|
|
||||||
<dt class="field-type" title="Type">Type</dt>
|
<dt class="field-type" title="Type">Type</dt>
|
||||||
<dd>{{ jobType? jobType.label : jobData.type }}</dd>
|
<dd>{{ jobType ? jobType.label : jobData.type }}</dd>
|
||||||
|
|
||||||
<dt class="field-priority" title="Priority">Priority</dt>
|
<dt class="field-priority" title="Priority">Priority</dt>
|
||||||
<dd>
|
<dd>
|
||||||
@ -76,7 +76,7 @@
|
|||||||
<script>
|
<script>
|
||||||
import * as datetime from "@/datetime";
|
import * as datetime from "@/datetime";
|
||||||
import * as API from '@/manager-api';
|
import * as API from '@/manager-api';
|
||||||
import { apiClient } from '@/stores/api-query-count';
|
import { getAPIClient } from "@/api-client";
|
||||||
import LastRenderedImage from '@/components/jobs/LastRenderedImage.vue'
|
import LastRenderedImage from '@/components/jobs/LastRenderedImage.vue'
|
||||||
import Blocklist from './Blocklist.vue'
|
import Blocklist from './Blocklist.vue'
|
||||||
import TabItem from '@/components/TabItem.vue'
|
import TabItem from '@/components/TabItem.vue'
|
||||||
@ -103,7 +103,7 @@ export default {
|
|||||||
datetime: datetime, // So that the template can access it.
|
datetime: datetime, // So that the template can access it.
|
||||||
copyElementText: copyElementText,
|
copyElementText: copyElementText,
|
||||||
simpleSettings: null, // Object with filtered job settings, or null if there is no job.
|
simpleSettings: null, // Object with filtered job settings, or null if there is no job.
|
||||||
jobsApi: new API.JobsApi(apiClient),
|
jobsApi: new API.JobsApi(getAPIClient()),
|
||||||
jobType: null, // API.AvailableJobType object for the current job type.
|
jobType: null, // API.AvailableJobType object for the current job type.
|
||||||
jobTypeSettings: null, // Mapping from setting key to its definition in the job type.
|
jobTypeSettings: null, // Mapping from setting key to its definition in the job type.
|
||||||
showAllSettings: false,
|
showAllSettings: false,
|
||||||
|
@ -17,7 +17,7 @@ import { TabulatorFull as Tabulator } from 'tabulator-tables';
|
|||||||
import * as datetime from "@/datetime";
|
import * as datetime from "@/datetime";
|
||||||
import * as API from '@/manager-api'
|
import * as API from '@/manager-api'
|
||||||
import { indicator } from '@/statusindicator';
|
import { indicator } from '@/statusindicator';
|
||||||
import { apiClient } from '@/stores/api-query-count';
|
import { getAPIClient } from "@/api-client";
|
||||||
import { useJobs } from '@/stores/jobs';
|
import { useJobs } from '@/stores/jobs';
|
||||||
|
|
||||||
import JobActionsBar from '@/components/jobs/JobActionsBar.vue'
|
import JobActionsBar from '@/components/jobs/JobActionsBar.vue'
|
||||||
@ -130,7 +130,7 @@ export default {
|
|||||||
this.fetchAllJobs();
|
this.fetchAllJobs();
|
||||||
},
|
},
|
||||||
fetchAllJobs() {
|
fetchAllJobs() {
|
||||||
const jobsApi = new API.JobsApi(apiClient);
|
const jobsApi = new API.JobsApi(getAPIClient());
|
||||||
const jobsQuery = {};
|
const jobsQuery = {};
|
||||||
this.jobs.isJobless = false;
|
this.jobs.isJobless = false;
|
||||||
jobsApi.queryJobs(jobsQuery).then(this.onJobsFetched, function (error) {
|
jobsApi.queryJobs(jobsQuery).then(this.onJobsFetched, function (error) {
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
import { reactive, ref, watch } from 'vue'
|
import { reactive, ref, watch } from 'vue'
|
||||||
import { api } from '@/urls';
|
import { api } from '@/urls';
|
||||||
import { JobsApi, JobLastRenderedImageInfo, SocketIOLastRenderedUpdate } from '@/manager-api';
|
import { JobsApi, JobLastRenderedImageInfo, SocketIOLastRenderedUpdate } from '@/manager-api';
|
||||||
import { apiClient } from '@/stores/api-query-count';
|
import { getAPIClient } from "@/api-client";
|
||||||
|
|
||||||
const props = defineProps([
|
const props = defineProps([
|
||||||
/* The job UUID to show renders for, or some false-y value if renders from all
|
/* The job UUID to show renders for, or some false-y value if renders from all
|
||||||
@ -27,7 +27,7 @@ const cssClasses = reactive({
|
|||||||
'nothing-rendered-yet': true,
|
'nothing-rendered-yet': true,
|
||||||
})
|
})
|
||||||
|
|
||||||
const jobsApi = new JobsApi(apiClient);
|
const jobsApi = new JobsApi(getAPIClient());
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Fetches the last-rendered info for the given job, then updates the <img> tag for it.
|
* Fetches the last-rendered info for the given job, then updates the <img> tag for it.
|
||||||
|
@ -73,7 +73,7 @@
|
|||||||
import * as datetime from "@/datetime";
|
import * as datetime from "@/datetime";
|
||||||
import { JobsApi } from '@/manager-api';
|
import { JobsApi } from '@/manager-api';
|
||||||
import { backendURL } from '@/urls';
|
import { backendURL } from '@/urls';
|
||||||
import { apiClient } from '@/stores/api-query-count';
|
import { getAPIClient } from "@/api-client";
|
||||||
import { useNotifs } from "@/stores/notifications";
|
import { useNotifs } from "@/stores/notifications";
|
||||||
import LinkWorker from '@/components/LinkWorker.vue';
|
import LinkWorker from '@/components/LinkWorker.vue';
|
||||||
import { copyElementText } from '@/clipboard';
|
import { copyElementText } from '@/clipboard';
|
||||||
@ -90,7 +90,7 @@ export default {
|
|||||||
return {
|
return {
|
||||||
datetime: datetime, // So that the template can access it.
|
datetime: datetime, // So that the template can access it.
|
||||||
copyElementText: copyElementText,
|
copyElementText: copyElementText,
|
||||||
jobsApi: new JobsApi(apiClient),
|
jobsApi: new JobsApi(getAPIClient()),
|
||||||
notifs: useNotifs(),
|
notifs: useNotifs(),
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
@ -17,7 +17,7 @@ import { TabulatorFull as Tabulator } from 'tabulator-tables';
|
|||||||
import * as datetime from "@/datetime";
|
import * as datetime from "@/datetime";
|
||||||
import * as API from '@/manager-api'
|
import * as API from '@/manager-api'
|
||||||
import { indicator } from '@/statusindicator';
|
import { indicator } from '@/statusindicator';
|
||||||
import { apiClient } from '@/stores/api-query-count';
|
import { getAPIClient } from "@/api-client";
|
||||||
import { useTasks } from '@/stores/tasks';
|
import { useTasks } from '@/stores/tasks';
|
||||||
|
|
||||||
import TaskActionsBar from '@/components/jobs/TaskActionsBar.vue'
|
import TaskActionsBar from '@/components/jobs/TaskActionsBar.vue'
|
||||||
@ -132,7 +132,7 @@ export default {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const jobsApi = new API.JobsApi(apiClient);
|
const jobsApi = new API.JobsApi(getAPIClient());
|
||||||
jobsApi.fetchJobTasks(this.jobID)
|
jobsApi.fetchJobTasks(this.jobID)
|
||||||
.then(this.onTasksFetched, function (error) {
|
.then(this.onTasksFetched, function (error) {
|
||||||
// TODO: error handling.
|
// TODO: error handling.
|
||||||
|
@ -6,11 +6,7 @@
|
|||||||
</option>
|
</option>
|
||||||
<option v-for="(action, key) in WORKER_ACTIONS" :value="key">{{ action.label }}</option>
|
<option v-for="(action, key) in WORKER_ACTIONS" :value="key">{{ action.label }}</option>
|
||||||
</select>
|
</select>
|
||||||
<button
|
<button :disabled="!canPerformAction" class="btn" @click.prevent="performWorkerAction">Apply</button>
|
||||||
:disabled="!canPerformAction"
|
|
||||||
class="btn"
|
|
||||||
@click.prevent="performWorkerAction"
|
|
||||||
>Apply</button>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
@ -18,46 +14,46 @@ import { computed, ref } from 'vue'
|
|||||||
import { useWorkers } from '@/stores/workers';
|
import { useWorkers } from '@/stores/workers';
|
||||||
import { useNotifs } from '@/stores/notifications';
|
import { useNotifs } from '@/stores/notifications';
|
||||||
import { WorkerMgtApi, WorkerStatusChangeRequest } from '@/manager-api';
|
import { WorkerMgtApi, WorkerStatusChangeRequest } from '@/manager-api';
|
||||||
import { apiClient } from '@/stores/api-query-count';
|
import { getAPIClient } from "@/api-client";
|
||||||
|
|
||||||
/* Freeze to prevent Vue.js from creating getters & setters all over this object.
|
/* Freeze to prevent Vue.js from creating getters & setters all over this object.
|
||||||
* We don't need it to be tracked, as it won't be changed anyway. */
|
* We don't need it to be tracked, as it won't be changed anyway. */
|
||||||
const WORKER_ACTIONS = Object.freeze({
|
const WORKER_ACTIONS = Object.freeze({
|
||||||
offline_lazy: {
|
offline_lazy: {
|
||||||
label: 'Shut Down (after task is finished)',
|
label: 'Shut Down (after task is finished)',
|
||||||
icon: '✝',
|
icon: '✝',
|
||||||
title: 'Shut down the worker after the current task finishes. The worker may automatically restart.',
|
title: 'Shut down the worker after the current task finishes. The worker may automatically restart.',
|
||||||
target_status: 'offline',
|
target_status: 'offline',
|
||||||
lazy: true,
|
lazy: true,
|
||||||
},
|
},
|
||||||
offline_immediate: {
|
offline_immediate: {
|
||||||
label: 'Shut Down (immediately)',
|
label: 'Shut Down (immediately)',
|
||||||
icon: '✝!',
|
icon: '✝!',
|
||||||
title: 'Immediately shut down the worker. It may automatically restart.',
|
title: 'Immediately shut down the worker. It may automatically restart.',
|
||||||
target_status: 'offline',
|
target_status: 'offline',
|
||||||
lazy: false,
|
lazy: false,
|
||||||
},
|
},
|
||||||
asleep_lazy: {
|
asleep_lazy: {
|
||||||
label: 'Send to Sleep (after task is finished)',
|
label: 'Send to Sleep (after task is finished)',
|
||||||
icon: '😴',
|
icon: '😴',
|
||||||
title: 'Let the worker sleep after finishing this task.',
|
title: 'Let the worker sleep after finishing this task.',
|
||||||
target_status: 'asleep',
|
target_status: 'asleep',
|
||||||
lazy: true,
|
lazy: true,
|
||||||
},
|
},
|
||||||
asleep_immediate: {
|
asleep_immediate: {
|
||||||
label: 'Send to Sleep (immediately)',
|
label: 'Send to Sleep (immediately)',
|
||||||
icon: '😴!',
|
icon: '😴!',
|
||||||
title: 'Let the worker sleep immediately.',
|
title: 'Let the worker sleep immediately.',
|
||||||
target_status: 'asleep',
|
target_status: 'asleep',
|
||||||
lazy: false,
|
lazy: false,
|
||||||
},
|
},
|
||||||
wakeup: {
|
wakeup: {
|
||||||
label: 'Wake Up',
|
label: 'Wake Up',
|
||||||
icon: '😃',
|
icon: '😃',
|
||||||
title: 'Wake the worker up. A sleeping worker can take a minute to respond.',
|
title: 'Wake the worker up. A sleeping worker can take a minute to respond.',
|
||||||
target_status: 'awake',
|
target_status: 'awake',
|
||||||
lazy: false,
|
lazy: false,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
const selectedAction = ref('');
|
const selectedAction = ref('');
|
||||||
@ -73,7 +69,7 @@ function performWorkerAction() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const api = new WorkerMgtApi(apiClient);
|
const api = new WorkerMgtApi(getAPIClient());
|
||||||
const action = WORKER_ACTIONS[selectedAction.value];
|
const action = WORKER_ACTIONS[selectedAction.value];
|
||||||
const statuschange = new WorkerStatusChangeRequest(action.target_status, action.lazy);
|
const statuschange = new WorkerStatusChangeRequest(action.target_status, action.lazy);
|
||||||
console.log("Requesting worker status change", statuschange);
|
console.log("Requesting worker status change", statuschange);
|
||||||
|
@ -123,7 +123,7 @@ import { useNotifs } from '@/stores/notifications'
|
|||||||
|
|
||||||
import * as datetime from "@/datetime";
|
import * as datetime from "@/datetime";
|
||||||
import { WorkerMgtApi, WorkerSleepSchedule } from '@/manager-api';
|
import { WorkerMgtApi, WorkerSleepSchedule } from '@/manager-api';
|
||||||
import { apiClient } from '@/stores/api-query-count';
|
import { getAPIClient } from "@/api-client";
|
||||||
import { workerStatus } from "../../statusindicator";
|
import { workerStatus } from "../../statusindicator";
|
||||||
import LinkWorkerTask from '@/components/LinkWorkerTask.vue';
|
import LinkWorkerTask from '@/components/LinkWorkerTask.vue';
|
||||||
import SwitchCheckbox from '@/components/SwitchCheckbox.vue';
|
import SwitchCheckbox from '@/components/SwitchCheckbox.vue';
|
||||||
@ -140,7 +140,7 @@ export default {
|
|||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
datetime: datetime, // So that the template can access it.
|
datetime: datetime, // So that the template can access it.
|
||||||
api: new WorkerMgtApi(apiClient),
|
api: new WorkerMgtApi(getAPIClient()),
|
||||||
workerStatusHTML: "",
|
workerStatusHTML: "",
|
||||||
workerSleepSchedule: this.defaultWorkerSleepSchedule(),
|
workerSleepSchedule: this.defaultWorkerSleepSchedule(),
|
||||||
isScheduleEditing: false,
|
isScheduleEditing: false,
|
||||||
|
@ -19,7 +19,7 @@
|
|||||||
import { TabulatorFull as Tabulator } from 'tabulator-tables';
|
import { TabulatorFull as Tabulator } from 'tabulator-tables';
|
||||||
import { WorkerMgtApi } from '@/manager-api'
|
import { WorkerMgtApi } from '@/manager-api'
|
||||||
import { indicator, workerStatus } from '@/statusindicator';
|
import { indicator, workerStatus } from '@/statusindicator';
|
||||||
import { apiClient } from '@/stores/api-query-count';
|
import { getAPIClient } from "@/api-client";
|
||||||
import { useWorkers } from '@/stores/workers';
|
import { useWorkers } from '@/stores/workers';
|
||||||
|
|
||||||
import StatusFilterBar from '@/components/StatusFilterBar.vue'
|
import StatusFilterBar from '@/components/StatusFilterBar.vue'
|
||||||
@ -117,7 +117,7 @@ export default {
|
|||||||
this.fetchAllWorkers();
|
this.fetchAllWorkers();
|
||||||
},
|
},
|
||||||
fetchAllWorkers() {
|
fetchAllWorkers() {
|
||||||
const api = new WorkerMgtApi(apiClient);
|
const api = new WorkerMgtApi(getAPIClient());
|
||||||
api.fetchWorkers().then(this.onWorkersFetched, function (error) {
|
api.fetchWorkers().then(this.onWorkersFetched, function (error) {
|
||||||
// TODO: error handling.
|
// TODO: error handling.
|
||||||
console.error(error);
|
console.error(error);
|
||||||
|
@ -7,7 +7,8 @@ import SetupAssistant from '@/SetupAssistant.vue'
|
|||||||
import autoreload from '@/autoreloader'
|
import autoreload from '@/autoreloader'
|
||||||
import router from '@/router/index'
|
import router from '@/router/index'
|
||||||
import setupAssistantRouter from '@/router/setup-assistant'
|
import setupAssistantRouter from '@/router/setup-assistant'
|
||||||
import { ApiClient, MetaApi } from "@/manager-api";
|
import { MetaApi } from "@/manager-api";
|
||||||
|
import { newBareAPIClient } from "@/api-client";
|
||||||
import * as urls from '@/urls'
|
import * as urls from '@/urls'
|
||||||
|
|
||||||
// Ensure Tabulator can find `luxon`, which it needs for sorting by
|
// Ensure Tabulator can find `luxon`, which it needs for sorting by
|
||||||
@ -24,7 +25,6 @@ autoreload();
|
|||||||
const pinia = createPinia()
|
const pinia = createPinia()
|
||||||
|
|
||||||
function normalMode() {
|
function normalMode() {
|
||||||
console.log("Flamenco is starting in normal operation mode");
|
|
||||||
const app = createApp(App)
|
const app = createApp(App)
|
||||||
app.use(pinia)
|
app.use(pinia)
|
||||||
app.use(router)
|
app.use(router)
|
||||||
@ -42,7 +42,7 @@ function setupAssistantMode() {
|
|||||||
/* This cannot use the client from '@/stores/api-query-count', as that would
|
/* This cannot use the client from '@/stores/api-query-count', as that would
|
||||||
* require Pinia, which is unavailable until the app is actually started. And to
|
* require Pinia, which is unavailable until the app is actually started. And to
|
||||||
* know which app to start, this API call needs to return data. */
|
* know which app to start, this API call needs to return data. */
|
||||||
const apiClient = new ApiClient(urls.api());;
|
const apiClient = newBareAPIClient();
|
||||||
const metaAPI = new MetaApi(apiClient);
|
const metaAPI = new MetaApi(apiClient);
|
||||||
metaAPI.getConfiguration()
|
metaAPI.getConfiguration()
|
||||||
.then((config) => {
|
.then((config) => {
|
||||||
|
2
web/app/src/manager-api/ApiClient.js
generated
@ -55,7 +55,7 @@ class ApiClient {
|
|||||||
* @default {}
|
* @default {}
|
||||||
*/
|
*/
|
||||||
this.defaultHeaders = {
|
this.defaultHeaders = {
|
||||||
'User-Agent': 'Flamenco/3.2-beta / webbrowser'
|
'User-Agent': 'Flamenco/3.2 / webbrowser'
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
import { defineStore } from "pinia";
|
import { defineStore } from "pinia";
|
||||||
import { ApiClient } from "@/manager-api";
|
import { ApiClient } from "@/manager-api";
|
||||||
import * as urls from '@/urls'
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Keep track of running API queries.
|
* Keep track of running API queries.
|
||||||
@ -42,5 +41,3 @@ export class CountingApiClient extends ApiClient {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export const apiClient = new CountingApiClient(urls.api());;
|
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
import { defineStore } from 'pinia'
|
import { defineStore } from 'pinia'
|
||||||
|
|
||||||
import * as API from '@/manager-api';
|
import * as API from '@/manager-api';
|
||||||
import { apiClient } from '@/stores/api-query-count';
|
import { getAPIClient } from "@/api-client";
|
||||||
|
|
||||||
|
|
||||||
const jobsAPI = new API.JobsApi(apiClient);
|
const jobsAPI = new API.JobsApi(getAPIClient());
|
||||||
|
|
||||||
// 'use' prefix is idiomatic for Pinia stores.
|
// 'use' prefix is idiomatic for Pinia stores.
|
||||||
// See https://pinia.vuejs.org/core-concepts/
|
// See https://pinia.vuejs.org/core-concepts/
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
import { defineStore } from 'pinia'
|
import { defineStore } from 'pinia'
|
||||||
|
|
||||||
import * as API from '@/manager-api';
|
import * as API from '@/manager-api';
|
||||||
import { apiClient } from '@/stores/api-query-count';
|
import { getAPIClient } from "@/api-client";
|
||||||
|
|
||||||
|
|
||||||
const jobsAPI = new API.JobsApi(apiClient);
|
const jobsAPI = new API.JobsApi(getAPIClient());
|
||||||
|
|
||||||
// 'use' prefix is idiomatic for Pinia stores.
|
// 'use' prefix is idiomatic for Pinia stores.
|
||||||
// See https://pinia.vuejs.org/core-concepts/
|
// See https://pinia.vuejs.org/core-concepts/
|
||||||
|
@ -39,7 +39,7 @@ import { useJobs } from '@/stores/jobs';
|
|||||||
import { useTasks } from '@/stores/tasks';
|
import { useTasks } from '@/stores/tasks';
|
||||||
import { useNotifs } from '@/stores/notifications'
|
import { useNotifs } from '@/stores/notifications'
|
||||||
import { useTaskLog } from '@/stores/tasklog'
|
import { useTaskLog } from '@/stores/tasklog'
|
||||||
import { apiClient } from '@/stores/api-query-count';
|
import { getAPIClient } from "@/api-client";
|
||||||
|
|
||||||
import FooterPopup from '@/components/footer/FooterPopup.vue'
|
import FooterPopup from '@/components/footer/FooterPopup.vue'
|
||||||
import GetTheAddon from '@/components/GetTheAddon.vue'
|
import GetTheAddon from '@/components/GetTheAddon.vue'
|
||||||
@ -127,7 +127,7 @@ export default {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const jobsAPI = new API.JobsApi(apiClient);
|
const jobsAPI = new API.JobsApi(getAPIClient());
|
||||||
jobsAPI.fetchTask(taskSummary.id)
|
jobsAPI.fetchTask(taskSummary.id)
|
||||||
.then((task) => {
|
.then((task) => {
|
||||||
this.tasks.setActiveTask(task);
|
this.tasks.setActiveTask(task);
|
||||||
@ -225,7 +225,7 @@ export default {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const jobsAPI = new API.JobsApi(apiClient);
|
const jobsAPI = new API.JobsApi(getAPIClient());
|
||||||
return jobsAPI.fetchJob(jobID)
|
return jobsAPI.fetchJob(jobID)
|
||||||
.then((job) => {
|
.then((job) => {
|
||||||
this.jobs.setActiveJob(job);
|
this.jobs.setActiveJob(job);
|
||||||
@ -254,7 +254,7 @@ export default {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const jobsAPI = new API.JobsApi(apiClient);
|
const jobsAPI = new API.JobsApi(getAPIClient());
|
||||||
return jobsAPI.fetchTask(taskID)
|
return jobsAPI.fetchTask(taskID)
|
||||||
.then((task) => {
|
.then((task) => {
|
||||||
this.tasks.setActiveTask(task);
|
this.tasks.setActiveTask(task);
|
||||||
|
@ -2,38 +2,28 @@
|
|||||||
<div class="setup-container">
|
<div class="setup-container">
|
||||||
<h1>Flamenco Setup Assistant</h1>
|
<h1>Flamenco Setup Assistant</h1>
|
||||||
<ul class="progress">
|
<ul class="progress">
|
||||||
<li
|
<li v-for="step in totalSetupSteps" :key="step" @click="jumpToStep(step)" :class="{
|
||||||
v-for="step in totalSetupSteps" :key="step"
|
current: step == currentSetupStep,
|
||||||
@click="jumpToStep(step)"
|
done: step < overallSetupStep,
|
||||||
:class="{
|
done_previously: (step < overallSetupStep && currentSetupStep > step),
|
||||||
current: step == currentSetupStep,
|
done_and_current: step == currentSetupStep && (step < overallSetupStep || step == 1),
|
||||||
done: step < overallSetupStep,
|
disabled: step > overallSetupStep,
|
||||||
done_previously: (step < overallSetupStep && currentSetupStep > step),
|
}">
|
||||||
done_and_current: step == currentSetupStep && (step < overallSetupStep || step == 1),
|
|
||||||
disabled: step > overallSetupStep,
|
|
||||||
}"
|
|
||||||
>
|
|
||||||
<span></span>
|
<span></span>
|
||||||
</li>
|
</li>
|
||||||
<div class="progress-bar"></div>
|
<div class="progress-bar"></div>
|
||||||
</ul>
|
</ul>
|
||||||
<div class="setup-step step-welcome">
|
<div class="setup-step step-welcome">
|
||||||
|
|
||||||
<step-item
|
<step-item v-show="currentSetupStep == 1" @next-clicked="nextStep" :is-next-clickable="true"
|
||||||
v-show="currentSetupStep == 1"
|
:is-back-visible="false" title="Welcome!" next-label="Let's go">
|
||||||
@next-clicked="nextStep"
|
|
||||||
:is-next-clickable="true"
|
|
||||||
:is-back-visible="false"
|
|
||||||
title="Welcome!"
|
|
||||||
next-label="Let's go"
|
|
||||||
>
|
|
||||||
<p>
|
<p>
|
||||||
This setup assistant will guide you through the initial configuration of Flamenco. You will be up
|
This setup assistant will guide you through the initial configuration of Flamenco. You will be up
|
||||||
and running in a few minutes!
|
and running in a few minutes!
|
||||||
</p>
|
</p>
|
||||||
<p>Before we start, here is a quick overview of the Flamenco architecture.</p>
|
<p>Before we start, here is a quick overview of the Flamenco architecture.</p>
|
||||||
|
|
||||||
<img src="@/assets/architecture.png" alt="Flamenco architecture"/>
|
<img src="@/assets/architecture.png" alt="Flamenco architecture" />
|
||||||
|
|
||||||
<p>The illustration shows the key components and how they interact together:</p>
|
<p>The illustration shows the key components and how they interact together:</p>
|
||||||
<ul>
|
<ul>
|
||||||
@ -41,26 +31,24 @@
|
|||||||
<strong>Manager</strong>: This application. It coordinates all the activity.
|
<strong>Manager</strong>: This application. It coordinates all the activity.
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<strong>Worker</strong>: A workstation or dedicated rendering machine. It executes the tasks assigned by the Manager.
|
<strong>Worker</strong>: A workstation or dedicated rendering machine. It executes the tasks assigned by the
|
||||||
|
Manager.
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<strong>Shared Storage</strong>: A location accessible by the Manager and the Workers, where the files to be rendered should be saved.
|
<strong>Shared Storage</strong>: A location accessible by the Manager and the Workers, where the files to be
|
||||||
|
rendered should be saved.
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<strong>Blender Add-on</strong>: This is needed to connect to the Manager and submit a job from Blender.
|
<strong>Blender Add-on</strong>: This is needed to connect to the Manager and submit a job from Blender.
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
<p>More information is available on the online documentation at
|
<p>More information is available on the online documentation at
|
||||||
<a href="https://flamenco.blender.org">flamenco.blender.org</a>.</p>
|
<a href="https://flamenco.blender.org">flamenco.blender.org</a>.
|
||||||
|
</p>
|
||||||
</step-item>
|
</step-item>
|
||||||
|
|
||||||
<step-item
|
<step-item v-show="currentSetupStep == 2" @next-clicked="nextStepAfterCheckSharedStoragePath"
|
||||||
v-show="currentSetupStep == 2"
|
@back-clicked="prevStep" :is-next-clickable="sharedStoragePath.length > 0" title="Shared Storage">
|
||||||
@next-clicked="nextStepAfterCheckSharedStoragePath"
|
|
||||||
@back-clicked="prevStep"
|
|
||||||
:is-next-clickable="sharedStoragePath.length > 0"
|
|
||||||
title="Shared Storage"
|
|
||||||
>
|
|
||||||
<p>Specify a path (or drive) where you want to store your Flamenco data.</p>
|
<p>Specify a path (or drive) where you want to store your Flamenco data.</p>
|
||||||
<p>
|
<p>
|
||||||
The location of the shared storage should be accessible by Flamenco Manager and by the Workers.
|
The location of the shared storage should be accessible by Flamenco Manager and by the Workers.
|
||||||
@ -79,37 +67,26 @@
|
|||||||
<a href="https://flamenco.blender.org/usage/shared-storage/">Learn more</a>.
|
<a href="https://flamenco.blender.org/usage/shared-storage/">Learn more</a>.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<input
|
<input v-model="sharedStoragePath" @keyup.enter="nextStepAfterCheckSharedStoragePath" type="text"
|
||||||
v-model="sharedStoragePath"
|
placeholder="Path to shared storage" :class="{
|
||||||
@keyup.enter="nextStepAfterCheckSharedStoragePath"
|
|
||||||
type="text"
|
|
||||||
placeholder="Path to shared storage"
|
|
||||||
:class="{
|
|
||||||
'is-invalid': (sharedStorageCheckResult != null) && !sharedStorageCheckResult.is_usable
|
'is-invalid': (sharedStorageCheckResult != null) && !sharedStorageCheckResult.is_usable
|
||||||
}"
|
|
||||||
>
|
|
||||||
<p v-if="sharedStorageCheckResult != null"
|
|
||||||
:class="{
|
|
||||||
'check-ok': sharedStorageCheckResult.is_usable,
|
|
||||||
'check-failed': !sharedStorageCheckResult.is_usable
|
|
||||||
}">
|
}">
|
||||||
|
<p v-if="sharedStorageCheckResult != null" :class="{
|
||||||
|
'check-ok': sharedStorageCheckResult.is_usable,
|
||||||
|
'check-failed': !sharedStorageCheckResult.is_usable
|
||||||
|
}">
|
||||||
{{ sharedStorageCheckResult.cause }}
|
{{ sharedStorageCheckResult.cause }}
|
||||||
</p>
|
</p>
|
||||||
</step-item>
|
</step-item>
|
||||||
|
|
||||||
<step-item
|
<step-item v-show="currentSetupStep == 3" @next-clicked="nextStepAfterCheckBlenderExePath" @back-clicked="prevStep"
|
||||||
v-show="currentSetupStep == 3"
|
:is-next-clickable="selectedBlender != null || customBlenderExe != (null || '')" title="Blender">
|
||||||
@next-clicked="nextStepAfterCheckBlenderExePath"
|
|
||||||
@back-clicked="prevStep"
|
|
||||||
:is-next-clickable="selectedBlender != null || customBlenderExe != (null || '')"
|
|
||||||
title="Blender"
|
|
||||||
>
|
|
||||||
|
|
||||||
<div v-if="isBlenderExeFinding" class="is-in-progress">Looking for Blender installs...</div>
|
<div v-if="isBlenderExeFinding" class="is-in-progress">Looking for Blender installs...</div>
|
||||||
|
|
||||||
<p v-if="autoFoundBlenders.length === 0">
|
<p v-if="autoFoundBlenders.length === 0">
|
||||||
Provide a path to a Blender executable accessible by all Workers.
|
Provide a path to a Blender executable accessible by all Workers.
|
||||||
<br/><br/>
|
<br /><br />
|
||||||
If your rendering setup features operating systems different from the one you are currently using,
|
If your rendering setup features operating systems different from the one you are currently using,
|
||||||
you can manually set up the other paths later.
|
you can manually set up the other paths later.
|
||||||
</p>
|
</p>
|
||||||
@ -119,23 +96,16 @@
|
|||||||
<fieldset v-if="autoFoundBlenders.length >= 1">
|
<fieldset v-if="autoFoundBlenders.length >= 1">
|
||||||
<label v-if="autoFoundBlenderPathEnvvar" for="blender-path_envvar">
|
<label v-if="autoFoundBlenderPathEnvvar" for="blender-path_envvar">
|
||||||
<div>
|
<div>
|
||||||
<input
|
<input v-model="selectedBlender" :value="autoFoundBlenderPathEnvvar" id="blender-path_envvar" name="blender"
|
||||||
v-model="selectedBlender"
|
|
||||||
:value="autoFoundBlenderPathEnvvar"
|
|
||||||
id="blender-path_envvar"
|
|
||||||
name="blender"
|
|
||||||
type="radio">
|
type="radio">
|
||||||
{{ sourceLabels[autoFoundBlenderPathEnvvar.source] }}
|
{{ sourceLabels[autoFoundBlenderPathEnvvar.source] }}
|
||||||
</div>
|
</div>
|
||||||
<div class="setup-path-command">
|
<div class="setup-path-command">
|
||||||
<span class="path">
|
<span class="path">
|
||||||
{{autoFoundBlenderPathEnvvar.path}}
|
{{ autoFoundBlenderPathEnvvar.path }}
|
||||||
</span>
|
</span>
|
||||||
<span
|
<span aria-label="Console output when running with --version" class="command-preview"
|
||||||
aria-label="Console output when running with --version"
|
data-microtip-position="top" role="tooltip">
|
||||||
class="command-preview"
|
|
||||||
data-microtip-position="top"
|
|
||||||
role="tooltip">
|
|
||||||
{{ autoFoundBlenderPathEnvvar.cause }}
|
{{ autoFoundBlenderPathEnvvar.cause }}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
@ -143,23 +113,16 @@
|
|||||||
|
|
||||||
<label v-if="autoFoundBlenderFileAssociation" for="blender-file_association">
|
<label v-if="autoFoundBlenderFileAssociation" for="blender-file_association">
|
||||||
<div>
|
<div>
|
||||||
<input
|
<input v-model="selectedBlender" :value="autoFoundBlenderFileAssociation" id="blender-file_association"
|
||||||
v-model="selectedBlender"
|
name="blender" type="radio">
|
||||||
:value="autoFoundBlenderFileAssociation"
|
{{ sourceLabels[autoFoundBlenderFileAssociation.source] }}
|
||||||
id="blender-file_association"
|
|
||||||
name="blender"
|
|
||||||
type="radio">
|
|
||||||
{{ sourceLabels[autoFoundBlenderFileAssociation.source] }}
|
|
||||||
</div>
|
</div>
|
||||||
<div class="setup-path-command">
|
<div class="setup-path-command">
|
||||||
<span class="path">
|
<span class="path">
|
||||||
{{autoFoundBlenderFileAssociation.path}}
|
{{ autoFoundBlenderFileAssociation.path }}
|
||||||
</span>
|
</span>
|
||||||
<span
|
<span aria-label="Console output when running with --version" class="command-preview"
|
||||||
aria-label="Console output when running with --version"
|
data-microtip-position="top" role="tooltip">
|
||||||
class="command-preview"
|
|
||||||
data-microtip-position="top"
|
|
||||||
role="tooltip">
|
|
||||||
{{ autoFoundBlenderFileAssociation.cause }}
|
{{ autoFoundBlenderFileAssociation.cause }}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
@ -167,24 +130,15 @@
|
|||||||
|
|
||||||
<label for="blender-input_path">
|
<label for="blender-input_path">
|
||||||
<div>
|
<div>
|
||||||
<input
|
<input type="radio" v-model="selectedBlender" name="blender" :value="blenderFromInputPath"
|
||||||
type="radio"
|
id="blender-input_path">
|
||||||
v-model="selectedBlender"
|
|
||||||
name="blender"
|
|
||||||
:value="blenderFromInputPath"
|
|
||||||
id="blender-input_path"
|
|
||||||
>
|
|
||||||
{{ sourceLabels['input_path'] }}
|
{{ sourceLabels['input_path'] }}
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<input
|
<input v-model="customBlenderExe" @keyup.enter="nextStepAfterCheckBlenderExePath"
|
||||||
v-model="customBlenderExe"
|
|
||||||
@keyup.enter="nextStepAfterCheckBlenderExePath"
|
|
||||||
@focus="selectedBlender = null"
|
@focus="selectedBlender = null"
|
||||||
:class="{'is-invalid': blenderExeCheckResult != null && !blenderExeCheckResult.is_usable}"
|
:class="{ 'is-invalid': blenderExeCheckResult != null && !blenderExeCheckResult.is_usable }" type="text"
|
||||||
type="text"
|
placeholder="Path to Blender">
|
||||||
placeholder="Path to Blender"
|
|
||||||
>
|
|
||||||
<p v-if="isBlenderExeChecking" class="is-in-progress">Checking...</p>
|
<p v-if="isBlenderExeChecking" class="is-in-progress">Checking...</p>
|
||||||
<p v-if="blenderExeCheckResult != null && !blenderExeCheckResult.is_usable" class="check-failed">
|
<p v-if="blenderExeCheckResult != null && !blenderExeCheckResult.is_usable" class="check-failed">
|
||||||
{{ blenderExeCheckResult.cause }}</p>
|
{{ blenderExeCheckResult.cause }}</p>
|
||||||
@ -193,13 +147,9 @@
|
|||||||
</fieldset>
|
</fieldset>
|
||||||
|
|
||||||
<div v-if="autoFoundBlenders.length === 0">
|
<div v-if="autoFoundBlenders.length === 0">
|
||||||
<input
|
<input v-model="customBlenderExe" @keyup.enter="nextStepAfterCheckBlenderExePath"
|
||||||
v-model="customBlenderExe"
|
:class="{ 'is-invalid': blenderExeCheckResult != null && !blenderExeCheckResult.is_usable }" type="text"
|
||||||
@keyup.enter="nextStepAfterCheckBlenderExePath"
|
placeholder="Path to Blender executable">
|
||||||
:class="{'is-invalid': blenderExeCheckResult != null && !blenderExeCheckResult.is_usable}"
|
|
||||||
type="text"
|
|
||||||
placeholder="Path to Blender executable"
|
|
||||||
>
|
|
||||||
|
|
||||||
<p v-if="isBlenderExeChecking" class="is-in-progress">Checking...</p>
|
<p v-if="isBlenderExeChecking" class="is-in-progress">Checking...</p>
|
||||||
<p v-if="blenderExeCheckResult != null && !blenderExeCheckResult.is_usable" class="check-failed">
|
<p v-if="blenderExeCheckResult != null && !blenderExeCheckResult.is_usable" class="check-failed">
|
||||||
@ -207,14 +157,8 @@
|
|||||||
</div>
|
</div>
|
||||||
</step-item>
|
</step-item>
|
||||||
|
|
||||||
<step-item
|
<step-item v-show="currentSetupStep == 4" @next-clicked="confirmSetupAssistant" @back-clicked="prevStep"
|
||||||
v-show="currentSetupStep == 4"
|
next-label="Confirm" title="Review" :is-next-clickable="setupConfirmIsClickable">
|
||||||
@next-clicked="confirmSetupAssistant"
|
|
||||||
@back-clicked="prevStep"
|
|
||||||
next-label="Confirm"
|
|
||||||
title="Review"
|
|
||||||
:is-next-clickable="setupConfirmIsClickable"
|
|
||||||
>
|
|
||||||
<div v-if="isConfigComplete">
|
<div v-if="isConfigComplete">
|
||||||
<p>This is the configuration that will be used by Flamenco:</p>
|
<p>This is the configuration that will be used by Flamenco:</p>
|
||||||
<dl>
|
<dl>
|
||||||
@ -253,7 +197,7 @@ import NotificationBar from '@/components/footer/NotificationBar.vue'
|
|||||||
import UpdateListener from '@/components/UpdateListener.vue'
|
import UpdateListener from '@/components/UpdateListener.vue'
|
||||||
import StepItem from '@/components/steps/StepItem.vue';
|
import StepItem from '@/components/steps/StepItem.vue';
|
||||||
import { MetaApi, PathCheckInput, SetupAssistantConfig } from "@/manager-api";
|
import { MetaApi, PathCheckInput, SetupAssistantConfig } from "@/manager-api";
|
||||||
import { apiClient } from '@/stores/api-query-count';
|
import { getAPIClient } from "@/api-client";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'SetupAssistantView',
|
name: 'SetupAssistantView',
|
||||||
@ -265,7 +209,7 @@ export default {
|
|||||||
data: () => ({
|
data: () => ({
|
||||||
sharedStoragePath: "",
|
sharedStoragePath: "",
|
||||||
sharedStorageCheckResult: null, // api.PathCheckResult
|
sharedStorageCheckResult: null, // api.PathCheckResult
|
||||||
metaAPI: new MetaApi(apiClient),
|
metaAPI: new MetaApi(getAPIClient()),
|
||||||
|
|
||||||
allBlenders: [], // combination of autoFoundBlenders and blenderExeCheckResult.
|
allBlenders: [], // combination of autoFoundBlenders and blenderExeCheckResult.
|
||||||
|
|
||||||
@ -458,7 +402,6 @@ export default {
|
|||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
<style>
|
<style>
|
||||||
|
|
||||||
.step-welcome ul {
|
.step-welcome ul {
|
||||||
padding-left: var(--spacer-xl);
|
padding-left: var(--spacer-xl);
|
||||||
margin-bottom: var(--spacer-xl);
|
margin-bottom: var(--spacer-xl);
|
||||||
@ -517,7 +460,8 @@ export default {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.progress-bar {
|
.progress-bar {
|
||||||
--width-each-segment: calc(100% / calc(v-bind('totalSetupSteps') - 1)); /* Substract 1 because the first step has no progress. */
|
--width-each-segment: calc(100% / calc(v-bind('totalSetupSteps') - 1));
|
||||||
|
/* Substract 1 because the first step has no progress. */
|
||||||
--progress-bar-width-at-current-step: calc(var(--width-each-segment) * calc(v-bind('currentSetupStep') - 1));
|
--progress-bar-width-at-current-step: calc(var(--width-each-segment) * calc(v-bind('currentSetupStep') - 1));
|
||||||
|
|
||||||
position: absolute;
|
position: absolute;
|
||||||
|
@ -7,8 +7,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<footer class="app-footer">
|
<footer class="app-footer">
|
||||||
<notification-bar />
|
<notification-bar />
|
||||||
<update-listener ref="updateListener" mainSubscription="allWorkers"
|
<update-listener ref="updateListener" mainSubscription="allWorkers" @workerUpdate="onSIOWorkerUpdate"
|
||||||
@workerUpdate="onSIOWorkerUpdate"
|
|
||||||
@sioReconnected="onSIOReconnected" @sioDisconnected="onSIODisconnected" />
|
@sioReconnected="onSIOReconnected" @sioDisconnected="onSIODisconnected" />
|
||||||
</footer>
|
</footer>
|
||||||
</template>
|
</template>
|
||||||
@ -17,6 +16,7 @@
|
|||||||
.col-workers-list {
|
.col-workers-list {
|
||||||
grid-area: col-1;
|
grid-area: col-1;
|
||||||
}
|
}
|
||||||
|
|
||||||
.col-workers-2 {
|
.col-workers-2 {
|
||||||
grid-area: col-2;
|
grid-area: col-2;
|
||||||
}
|
}
|
||||||
@ -26,7 +26,7 @@
|
|||||||
import { WorkerMgtApi } from '@/manager-api';
|
import { WorkerMgtApi } from '@/manager-api';
|
||||||
import { useNotifs } from '@/stores/notifications'
|
import { useNotifs } from '@/stores/notifications'
|
||||||
import { useWorkers } from '@/stores/workers';
|
import { useWorkers } from '@/stores/workers';
|
||||||
import { apiClient } from '@/stores/api-query-count';
|
import { getAPIClient } from "@/api-client";
|
||||||
|
|
||||||
import NotificationBar from '@/components/footer/NotificationBar.vue'
|
import NotificationBar from '@/components/footer/NotificationBar.vue'
|
||||||
import UpdateListener from '@/components/UpdateListener.vue'
|
import UpdateListener from '@/components/UpdateListener.vue'
|
||||||
@ -45,7 +45,7 @@ export default {
|
|||||||
data: () => ({
|
data: () => ({
|
||||||
workers: useWorkers(),
|
workers: useWorkers(),
|
||||||
notifs: useNotifs(),
|
notifs: useNotifs(),
|
||||||
api: new WorkerMgtApi(apiClient),
|
api: new WorkerMgtApi(getAPIClient()),
|
||||||
}),
|
}),
|
||||||
mounted() {
|
mounted() {
|
||||||
window.workersView = this;
|
window.workersView = this;
|
||||||
|
@ -10,11 +10,16 @@ people.
|
|||||||
|
|
||||||
## Steps to release a new version of Flamenco
|
## Steps to release a new version of Flamenco
|
||||||
|
|
||||||
|
Replace `${VERSION}` with the actual version number.
|
||||||
|
|
||||||
1. Update `CHANGELOG.md` and mark the to-be-released version as released today.
|
1. Update `CHANGELOG.md` and mark the to-be-released version as released today.
|
||||||
2. Update `Makefile` and change the `VERSION` and `RELEASE_CYCLE` variables.
|
2. Update `web/project-website/data/flamenco.yaml` for the new version.
|
||||||
3. Run `make update-version`
|
3. Update `Makefile` and change the `VERSION` and `RELEASE_CYCLE` variables.
|
||||||
4. Commit & tag with the commands shown in the 2nd step.
|
4. `make update-version`
|
||||||
5. Run `make release-package`
|
5. `git commit -m "Bump version to ${VERSION}"`
|
||||||
6. Check that the files in `dist/` are there and have a non-zero size.
|
6. `git tag v${VERSION}`
|
||||||
7. Run `make publish-release-packages` to upload the packages to the website.
|
7. `make release-package`
|
||||||
8. Run `make project-website` to generate and publish the new website.
|
8. Check that the files in `dist/` are there and have a non-zero size.
|
||||||
|
9. `make publish-release-packages` to upload the packages to the website.
|
||||||
|
10. `make project-website` to generate and publish the new website.
|
||||||
|
11. `git push && git push --tags`
|
||||||
|
@ -1 +1 @@
|
|||||||
latestVersion: "3.1"
|
latestVersion: "3.2"
|
||||||
|