diff --git a/src/forge-delete.ts b/src/forge-delete.ts new file mode 100644 index 0000000..e7b7c66 --- /dev/null +++ b/src/forge-delete.ts @@ -0,0 +1,86 @@ +import * as ForgeSDK from "forge-apis"; +import * as axios from "axios"; + +const jsonVersion: ForgeSDK.JsonApiVersionJsonapi = {version: "1.0"} +const versionsAPI = new ForgeSDK.VersionsApi(); + +/** + * Kevin Pan | pan261@purdue.edu | Last Modified: 2/7/2021 + * + * Deletes a file using the versions API + * @param {string} projectID + * @param {string} itemID + * @param {ForgeSDK.AuthClient} credentials + */ + +exports.delete = (projectID: string, itemID: string, fileName: string, credentials: ForgeSDK.AuthToken) => { + const data:ForgeSDK.CreateVersionData = { + type: "versions", + attributes: { + name: fileName, + extension: { + type: "versions:autodesk.core:Deleted", + version: "1.0", + schema: { + href: "" + } + } + }, + relationships: { + item: { + data: { + type: "items", + id: itemID + } + } + } + } + + const body: ForgeSDK.CreateVersion = { + jsonapi: jsonVersion, + data: data + } + + axios.default({ + method: 'POST', + url: `https://developer.api.autodesk.com/data/v1/projects/${projectID}/versions`, + headers: { + "Content-Type": "application/vnd.api+json", + Authorization: `Bearer ${credentials.access_token}`, + }, + data: { + jsonapi: { + version: "1.0" + }, + data: { + type: "versions", + attributes: { + extension: { + type: "versions:autodesk.core:Deleted", + version: "1.0", + } + }, + relationships: { + item: { + data: { + type: "items", + id: itemID + } + } + } + } + } + }).then(res => { + console.log("Successfully deleted item with id: " + itemID); + }).catch(err => { + console.log("Error deleting item with id: " + itemID); + }); + + // versionsAPI.postVersion(projectID, body, config.authClient, credentials) + // .then((res: ForgeSDK.ApiResponse) => { + // console.log("Successfully deleted item with " + itemID); + // }).catch((err: ForgeSDK.ApiError) => { + // console.log("Error deleting file: " + itemID + ", Error code: " + err.statusCode); + // console.log(JSON.stringify(err)); + // }); +} \ No newline at end of file diff --git a/src/downloader.ts b/src/forge-download.ts similarity index 87% rename from src/downloader.ts rename to src/forge-download.ts index 586a1f7..204a55a 100644 --- a/src/downloader.ts +++ b/src/forge-download.ts @@ -1,32 +1,31 @@ -import * as axios from "axios"; import * as ForgeSDK from "forge-apis"; const fs = require("fs").promises; -// const axios = require('axios'); import * as config from "./config"; const ObjectsApi = new ForgeSDK.ObjectsApi(); const ItemsApi = new ForgeSDK.ItemsApi(); /** - * Kevin Pan | pan261@purdue.edu | Last Modified: 12/2/2021 + * Kevin Pan | pan261@purdue.edu | Last Modified: 2/7/2021 * * Downloads a file by using the Forge SDK to make a GET request * on the storageLocation and then saves the file as `filename` under the `destination` directory * @param {string} storageLocation * @param {string} fileName * @param {string} destination - * @param {Object} credentials + * @param {ForgeSDK.AuthClient} credentials */ exports.download = async (projectID: string, itemID: string, fileName: string, destination: string, credentials: ForgeSDK.AuthToken) => { const storageLocation = await getStorageLocation(projectID, itemID, credentials); console.log("Downloading file " + fileName); - ObjectsApi.getObject("wip.dm.prod", storageLocation, {}, config.authClient, credentials) + return ObjectsApi.getObject("wip.dm.prod", storageLocation, {}, config.authClient, credentials) .then((res: ForgeSDK.ApiResponse) => { console.log("Downloaded file " + fileName + " to " + destination); fs.writeFile(`${destination}/${fileName}`, res.body); + return itemID; }) .catch((err: ForgeSDK.ApiError) => { console.log("error while processing " + storageLocation); diff --git a/src/uploadfile.ts b/src/forge-upload.ts similarity index 94% rename from src/uploadfile.ts rename to src/forge-upload.ts index 24940af..77f9771 100644 --- a/src/uploadfile.ts +++ b/src/forge-upload.ts @@ -17,7 +17,7 @@ function getCreateStorageDataObject(fileName: string, folderID: string): ForgeSD relationships: { target: { data: { - type: "folders", + type: "folders", id: folderID } } @@ -69,7 +69,7 @@ function getCreateItemIncludedObject(fileName: string, objectID: string): ForgeS href: "" } } - }, + }, relationships: { storage: { data: { @@ -116,7 +116,7 @@ function getCreateVersionData(fileName: string, itemID: string):ForgeSDK.CreateV * @param folderID Fusion ID of folder * @param objectID fusion ID of uploaded bucket object * @param credentials Forge Authtoken - * Calls: + * Calls: * @function getCreateItemDataObject * @function getCreateItemIncludedObject */ @@ -136,7 +136,7 @@ function createItem(fileName: string, folderID: string, objectID: string, creden } return true; - }, + }, (err: ForgeSDK.ApiError) => { console.log("API ERROR CODE: ", err.statusCode, "\nMESSAGE: ", err.statusMessage, "\nBODY: ", err.statusBody); return false; @@ -164,12 +164,12 @@ function uploadFileObject(fileName: string, folderName: string, objectID: string const objectName:string = objIDTokens[1].trim(); objectsAPI.uploadObject( - bucketKey, + bucketKey, objectName, - fileBuffer.byteLength, - fileBuffer, - {contentDisposition: fileName}, - config.authClient, + fileBuffer.byteLength, + fileBuffer, + {contentDisposition: fileName}, + config.authClient, credentials).then( (resp: ForgeSDK.ApiResponse) => { if (resp.statusCode != 200) { @@ -188,7 +188,7 @@ function uploadFileObject(fileName: string, folderName: string, objectID: string /** * Wrapper for: @function ProjectsApi.postStorage() - * Extracts necessary information from arguments. + * Extracts necessary information from arguments. * Requests bucket storage for file name in specified project and folder. * On success: Uploads file object to bucket * On fail: Returns @@ -209,7 +209,7 @@ export function uploadFile(fileName: string, folderName: string, credentials: Fo jsonapi: jsonVersion, data: getCreateStorageDataObject(fileName, folderID) } - + projectsAPI.postStorage(config.projectID, body, config.authClient, credentials).then( (resp: ForgeSDK.ApiResponse) => { if (resp.statusCode != 201) { @@ -236,12 +236,12 @@ export function uploadFile(fileName: string, folderName: string, credentials: Fo export function newVersion(fileName: string, folderName: string, credentials: ForgeSDK.AuthToken) { - const folderID: string = config.folderMap[folderName].fusionID; const body: ForgeSDK.CreateVersion = { jsonapi: jsonVersion, data: getCreateVersionData(fileName, "") } - versionsAPI.postVersion(folderID, body, config.authClient, credentials).then( + + versionsAPI.postVersion(config.projectID, body, config.authClient, credentials).then( (resp: ForgeSDK.ApiResponse) => { if (resp.statusCode != 201) { console.log("Allocate Storage Error: ", resp.statusCode); diff --git a/src/webhooks.ts b/src/forge-webhooks.ts similarity index 98% rename from src/webhooks.ts rename to src/forge-webhooks.ts index 1e7fd85..545d3ea 100644 --- a/src/webhooks.ts +++ b/src/forge-webhooks.ts @@ -3,7 +3,7 @@ import * as ForgeSDK from "forge-apis"; import * as config from "./config"; /** - * Kevin Pan | pan261@purdue.edu | Last Modified: 1/24/2022 + * Kevin Pan | pan261@purdue.edu | Last Modified: 2/7/2022 * * Functions to manage hook lifecycle * setup() checks if hooks are valid and active, if not it will reactivated @@ -12,7 +12,7 @@ import * as config from "./config"; * * - 'dm.version.added' (file added) * - 'dm.version.modified' (file modified) - * - dm.version.deleted (file deleted) + * - 'dm.version.deleted' (file deleted) * */ @@ -131,6 +131,7 @@ const deleteHook = (event: string, hookID: string, credentials: ForgeSDK.AuthTok exports.setupToken = (credentials: ForgeSDK.AuthToken) => { console.log("Checking webhook token"); + axios.default({ method: "POST", url: "https://developer.api.autodesk.com/webhooks/v1/tokens", diff --git a/src/localhook.ts b/src/localhook.ts index d18bce7..e9b7855 100644 --- a/src/localhook.ts +++ b/src/localhook.ts @@ -1,6 +1,6 @@ import * as chokidar from 'chokidar'; import { AuthToken } from 'forge-apis'; -import * as uploader from './uploadfile'; +import * as uploader from './forge-upload'; const polltime: number = 100; diff --git a/src/server.ts b/src/server.ts index 709cdeb..b3a244c 100644 --- a/src/server.ts +++ b/src/server.ts @@ -7,8 +7,9 @@ import * as db from "./db"; import * as ForgeSDK from "forge-apis"; import { Request, Response, ErrorRequestHandler } from "express"; -const webhooks = require("./webhooks"); -const downloader = require("./downloader"); +const webhooks = require("./forge-webhooks"); +const downloader = require("./forge-download"); +const deleter = require("./forge-delete"); const localhook = require("./localhook"); /** @@ -145,7 +146,7 @@ const createServer = () => { } }); - app.post("/hook", function (req: any, res: Response) { + app.post("/hook", async function (req: any, res: Response) { if (!req.signature_match) { console.log("Request received from outside webhooks service"); return res.status(403).send("Not called from webhooks service"); @@ -159,18 +160,9 @@ const createServer = () => { const itemID = body.payload.lineageUrn; //TODO: check if extension is in the name const fileName = body.payload.name; - const destination = - __dirname + - "/file_share" + - config.folderIDtoLocal[body.payload.parentFolderUrn]; - - downloader.download( - config.projectID, - itemID, - fileName, - destination, - credentials - ); + const destination = __dirname + "/file_share" + config.folderIDtoLocal[body.payload.parentFolderUrn]; + await downloader.download(config.projectID, itemID, fileName, destination, credentials); + await deleter.delete(config.projectID, itemID, fileName, credentials); } });