1 | import {cached, defineAssoc} from "./decorators.js";
|
2 | import {lib, Collection, RallyBase, sleep} from "./rally-tools.js";
|
3 | import File from "./file.js";
|
4 | import Provider from "./providers.js";
|
5 |
|
6 | class Asset extends RallyBase{
|
7 | constructor({data, remote, included, lite}){
|
8 | super();
|
9 | this.data = data;
|
10 | this.meta = {};
|
11 | this.remote = remote;
|
12 | if(included){
|
13 | this.meta.metadata = Asset.normalizeMetadata(included);
|
14 | }
|
15 | this.lite = !!lite;
|
16 | }
|
17 | static normalizeMetadata(payload){
|
18 | let newMetadata = {}
|
19 | for(let md of payload){
|
20 | if(md.type !== "metadata") continue;
|
21 | newMetadata[md.attributes.usage] = md.attributes.metadata;
|
22 | }
|
23 | return newMetadata;
|
24 | }
|
25 |
|
26 | async getMetadata(forceRefresh = false){
|
27 | if(this.meta.metadata && !forceRefresh) return this.meta.metadata;
|
28 | let req = await lib.makeAPIRequest({
|
29 | env: this.remote, path: `/movies/${this.id}/metadata`,
|
30 | });
|
31 |
|
32 | return this.meta.metadata = Asset.normalizeMetadata(req.data);
|
33 | }
|
34 |
|
35 | async patchMetadata(metadata){
|
36 | if(metadata.Workflow && false){
|
37 | let req = await lib.makeAPIRequest({
|
38 | env: this.remote, path: `/movies/${this.id}/metadata/Workflow`,
|
39 | method: "PATCH",
|
40 | payload: {
|
41 | "data": {
|
42 | "type": "metadata",
|
43 | "attributes": {
|
44 | "metadata": metadata.Workflow
|
45 | },
|
46 | }
|
47 | }
|
48 | });
|
49 | }
|
50 | if(metadata.Metadata){
|
51 | let req = await lib.makeAPIRequest({
|
52 | env: this.remote, path: `/movies/${this.id}/metadata/Metadata`,
|
53 | method: "PATCH",
|
54 | payload: {
|
55 | "data": {
|
56 | "type": "metadata",
|
57 | "attributes": {
|
58 | "metadata": metadata.Metadata
|
59 | },
|
60 | }
|
61 | }
|
62 | });
|
63 | }
|
64 | }
|
65 |
|
66 | static lite(id, remote){
|
67 | return new this({data: {id}, remote, lite: true})
|
68 | }
|
69 |
|
70 | chalkPrint(pad=false){
|
71 | let id = String("A-" + (this.remote && this.remote + "-" + this.id || "LOCAL"))
|
72 | if(pad) id = id.padStart(15);
|
73 | return chalk`{green ${id}}: {blue ${this.data.attributes ? this.name : "(lite asset)"}}`;
|
74 | }
|
75 |
|
76 | static async createNew(name, env){
|
77 | let req = await lib.makeAPIRequest({
|
78 | env, path: "/assets",
|
79 | method: "POST",
|
80 | payload: {
|
81 | data: {
|
82 | attributes: {name},
|
83 | type: "assets"
|
84 | }
|
85 | }
|
86 | });
|
87 | return new this({data: req.data, remote: env});
|
88 | }
|
89 |
|
90 | async delete(){
|
91 | let req = await lib.makeAPIRequest({
|
92 | env: this.remote, path: "/assets/" + this.id,
|
93 | method: "DELETE",
|
94 | });
|
95 | }
|
96 |
|
97 | async getFiles(){
|
98 | let req = await lib.indexPathFast({
|
99 | env: this.remote, path: `/assets/${this.id}/files`,
|
100 | method: "GET",
|
101 | });
|
102 |
|
103 |
|
104 | return new Collection(req.map(x => new File({data: x, remote: this.remote, parent: this})));
|
105 | }
|
106 |
|
107 | async addFile(label, fileuris){
|
108 | if(!Array.isArray(fileuris)) fileuris = [fileuris];
|
109 |
|
110 | let instances = {}
|
111 | for(let i = 0; i < fileuris.length; i++){
|
112 | instances[String(i + 1)] = {uri: fileuris[i]};
|
113 | }
|
114 |
|
115 | let req = await lib.makeAPIRequest({
|
116 | env: this.remote, path: "/files",
|
117 | method: "POST",
|
118 | payload: {
|
119 | "data": {
|
120 | "attributes": {
|
121 | label, instances,
|
122 | },
|
123 | "relationships": {
|
124 | "asset": {
|
125 | "data": {
|
126 | id: this.id,
|
127 | "type": "assets"
|
128 | }
|
129 | }
|
130 | },
|
131 | "type": "files"
|
132 | }
|
133 |
|
134 | }
|
135 | });
|
136 | return req;
|
137 | }
|
138 | async startWorkflow(jobName, {initData, priority} = {}){
|
139 | let attributes = {};
|
140 | if(initData){
|
141 |
|
142 | initData = typeof initData === "string" ? initData : JSON.stringify(initData);
|
143 | attributes.initData = initData;
|
144 | }
|
145 | if(priority){
|
146 | attributes.priority = priority
|
147 | }
|
148 |
|
149 | let req = await lib.makeAPIRequest({
|
150 | env: this.remote, path: "/workflows",
|
151 | method: "POST",
|
152 | payload: {
|
153 | "data": {
|
154 | "type": "workflows",
|
155 | attributes,
|
156 | "relationships": {
|
157 | "movie": {
|
158 | "data": {
|
159 | id: this.id,
|
160 | "type": "movies"
|
161 | }
|
162 | }, "rule": {
|
163 | "data": {
|
164 | "attributes": {
|
165 | "name": jobName,
|
166 | },
|
167 | "type": "rules"
|
168 | }
|
169 | }
|
170 | }
|
171 | }
|
172 | }
|
173 | });
|
174 | return req;
|
175 | }
|
176 | static async startAnonWorkflow(env, jobName, {initData, priority} = {}){
|
177 | let attributes = {};
|
178 | if(initData){
|
179 |
|
180 | initData = typeof initData === "string" ? initData : JSON.stringify(initData);
|
181 | attributes.initData = initData;
|
182 | }
|
183 | if(priority){
|
184 | attributes.priority = priority
|
185 | }
|
186 |
|
187 | let req = await lib.makeAPIRequest({
|
188 | env, path: "/workflows",
|
189 | method: "POST",
|
190 | payload: {
|
191 | "data": {
|
192 | "type": "workflows",
|
193 | attributes,
|
194 | "relationships": {
|
195 | "rule": {
|
196 | "data": {
|
197 | "attributes": {
|
198 | "name": jobName,
|
199 | },
|
200 | "type": "rules"
|
201 | }
|
202 | }
|
203 | }
|
204 | }
|
205 | }
|
206 | });
|
207 | return req;
|
208 |
|
209 | }
|
210 |
|
211 | async startEphemeralEvaluateIdeal(preset, dynamicPresetData){
|
212 | let res;
|
213 | const env = this.remote;
|
214 | let provider = await Provider.getByName(this.remote, "SdviEvaluate");
|
215 |
|
216 | write(chalk`Starting ephemeral evaluate on ${this.chalkPrint(false)}...`)
|
217 |
|
218 |
|
219 | let evalInfo = await lib.makeAPIRequest({
|
220 | env: this.remote, path: "/jobs", method: "POST",
|
221 | payload: {
|
222 | data: {
|
223 | attributes: {
|
224 | category: provider.category,
|
225 | providerTypeName: provider.name,
|
226 | rallyConfiguration: {},
|
227 | providerData: Buffer.from(preset.code, "binary").toString("base64"),
|
228 | dynamicPresetData,
|
229 | },
|
230 | type: "jobs",
|
231 | relationships: {
|
232 | movie: {
|
233 | data: {
|
234 | id: this.id,
|
235 | type: "movies",
|
236 | }
|
237 | }
|
238 | }
|
239 | }
|
240 | }
|
241 | });
|
242 |
|
243 | write(" Waiting for finish...");
|
244 | for(;;){
|
245 | res = await lib.makeAPIRequest({
|
246 | env, path_full: evalInfo.data.links.self
|
247 | });
|
248 | write(".");
|
249 | if(res.data.attributes.state == "Complete"){
|
250 | write(chalk`{green Done}...\n`);
|
251 | break;
|
252 | }
|
253 | await sleep(300);
|
254 | }
|
255 |
|
256 | return;
|
257 | }
|
258 |
|
259 | async startEvaluate(presetid, dynamicPresetData){
|
260 |
|
261 | let data = await lib.makeAPIRequest({
|
262 | env: this.remote, path: "/jobs", method: "POST",
|
263 | payload: {
|
264 | data: {
|
265 | type: "jobs",
|
266 | attributes: {
|
267 | dynamicPresetData,
|
268 | },
|
269 | relationships: {
|
270 | movie: {
|
271 | data: {
|
272 | id: this.id,
|
273 | type: "movies",
|
274 | }
|
275 | }, preset: {
|
276 | data: {
|
277 | id: presetid,
|
278 | type: "presets",
|
279 | }
|
280 | }
|
281 | }
|
282 | }
|
283 | }
|
284 | });
|
285 | return data;
|
286 | }
|
287 | async rename(newName){
|
288 | let req = await lib.makeAPIRequest({
|
289 | env: this.remote, path: `/assets/${this.id}`,
|
290 | method: "PATCH",
|
291 | payload: {
|
292 | data: {
|
293 | attributes: {
|
294 | name: newName,
|
295 | },
|
296 | type: "assets",
|
297 | }
|
298 | }
|
299 | });
|
300 |
|
301 | this.name = newName;
|
302 |
|
303 | return req;
|
304 | }
|
305 | }
|
306 |
|
307 | defineAssoc(Asset, "id", "data.id");
|
308 | defineAssoc(Asset, "name", "data.attributes.name");
|
309 | defineAssoc(Asset, "remote", "meta.remote");
|
310 | defineAssoc(Asset, "md", "meta.metadata");
|
311 | defineAssoc(Asset, "lite", "meta.lite");
|
312 | Asset.endpoint = "movies"
|
313 |
|
314 | export default Asset;
|