private static void RelocateAsset(ref WebPebbleProjectAsset media, ModificationCode code, WebPebbleProject proj) { //Relocate string originalPath = media.GetAbsolutePath(proj.projectId); //Run modification code code(ref media); //Move string newPath = media.GetAbsolutePath(proj.projectId); if (originalPath != newPath) { File.Move(originalPath, newPath); } }
public static async Task OnMediaCreateRequest(Microsoft.AspNetCore.Http.HttpContext e, E_RPWS_User user, WebPebbleProject proj) { //Validate that the request method is indeed POST. RequestHttpMethod method = Program.FindRequestMethod(e); if (method != RequestHttpMethod.post) { await ThrowError(e, "Unknown method.", 2); return; } //Read the JSON data from the stream. MediaCreateRequestBody request = Program.GetPostBodyJson <MediaCreateRequestBody>(e); //Validate if (request.name == null || request.sub_type == null || request.type == null) { await ThrowError(e, "Missing one or more required values in the JSON payload.", 3); return; } //Generate a unique ID string id = LibRpws.LibRpwsCore.GenerateRandomString(16); if (proj.media == null) { proj.media = new Dictionary <string, WebPebbleProjectAsset>(); } while (proj.media.ContainsKey(id)) { id = LibRpws.LibRpwsCore.GenerateRandomString(16); } //Create the object to save to disk. var media = new WebPebbleProjectAsset(); //Find types from URL. media.type = request.type; media.innerType = request.sub_type; media.nickname = request.name; media.id = id; if (request.filename == null) { request.filename = media.id; } //Ensure directory is created. media.filename = ""; Directory.CreateDirectory(media.GetAbsolutePath(proj.projectId)); //Append filename media.filename = WebPebbleProject.CreateSafeFilename(request.filename); //If this was a template, load it. if (request.template != null) { //Try to find the template ID. if (templateMap.ContainsKey(request.template)) { //Write this template to the location. File.Copy(Program.config.media_dir + "Templates/" + templateMap[request.template], media.GetAbsolutePath(proj.projectId)); } else { //Invalid template! await ThrowError(e, "Invalid template name.", 6); return; } } //If this requested that we use appinfo.json, apply it. if (request.appInfoJson != null) { SaveOutsideAppinfoJsonOnAsset(media, request.appInfoJson, proj); } //Save proj.media.Add(id, media); proj.SaveProject(); //Write to user await Program.QuickWriteJsonToDoc(e, media); }
public static async Task OnMediaRequest(Microsoft.AspNetCore.Http.HttpContext e, E_RPWS_User user, WebPebbleProject proj) { //Get the request method RequestHttpMethod method = Program.FindRequestMethod(e); //Get the params string[] urlParams = Program.GetUrlPathRequestFromInsideProject(e); string id = urlParams[0]; //If the ID is create, pass this request to the creation. if (id == "create") { await OnMediaCreateRequest(e, user, proj); return; } //Try to find the asset. It's ok if it doesn't exist. WebPebbleProjectAsset media = null; if (proj.media.ContainsKey(id)) { media = proj.media[id]; } //Decide what to do. //If it doesn't exist. if (media == null) { //Requesting a non-existing asset. await ThrowError(e, "This asset ID does not exist.", 1); return; } //Handle object editing (POST). if (method == RequestHttpMethod.post) { //Get the payload. MediaRequestPostPayload payload = Program.GetPostBodyJson <MediaRequestPostPayload>(e); //If a value isn't null, apply it. if (payload.name != null) { media.nickname = payload.name; } if (payload.type != null) { //Relocate RelocateAsset(ref media, (ref WebPebbleProjectAsset m) => { m.type = (AssetType)payload.type; }, proj); } if (payload.sub_type != null) { //Relocate RelocateAsset(ref media, (ref WebPebbleProjectAsset m) => { m.innerType = (InnerAssetType)payload.sub_type; }, proj); } if (payload.filename != null) { //Relocate RelocateAsset(ref media, (ref WebPebbleProjectAsset m) => { m.filename = WebPebbleProject.CreateSafeFilename(payload.filename); }, proj); } if (payload.appinfoData != null) { //Modify the appinfo data and set it on the PebbleProject. SaveOutsideAppinfoJsonOnAsset(media, payload.appinfoData, proj); } //Save proj.media[id] = media; proj.SaveProject(); await Program.QuickWriteJsonToDoc(e, media); return; } //Handle object uploading. if (method == RequestHttpMethod.put) { //Check the upload type in the query. FileUploadType uploadType = Enum.Parse <FileUploadType>(e.Request.Query["upload_method"]); Stream source; int length; if (uploadType == FileUploadType.Binary) { //Read body directly length = (int)e.Request.ContentLength; source = e.Request.Body; } else { //This is sent from the uploader in the interface. //Get the file uploaded. var f = e.Request.Form.Files["data"]; //Check if the file is valid. if (f == null) { //No file uploaded. await Program.QuickWriteJsonToDoc(e, new PutRequestReply { ok = false, size = -1, uploader_error = $"No file was uploaded." }); return; } //Set source = f.OpenReadStream(); length = (int)f.Length; } //Check if a file is too large. if (length > MAXIMUM_UPLOADED_SIZE) { //Yup. Stop. source.Close(); await Program.QuickWriteJsonToDoc(e, new PutRequestReply { ok = false, size = length, uploader_error = $"Your file is too powerful! The maximum filesize is {MAXIMUM_UPLOADED_SIZE_NAME} ({MAXIMUM_UPLOADED_SIZE.ToString()} bytes)." }); } //Remove an existing file if it exists. if (File.Exists(media.GetAbsolutePath(proj.projectId))) { File.Delete(media.GetAbsolutePath(proj.projectId)); } //Save using (FileStream fs = new FileStream(media.GetAbsolutePath(proj.projectId), FileMode.CreateNew)) await source.CopyToAsync(fs); //Tell the user it is ok await Program.QuickWriteJsonToDoc(e, new PutRequestReply { ok = true, size = length, uploader_error = null }); return; } //Handle object downloading if (method == RequestHttpMethod.get) { //Check if the file has been created yet string path = media.GetAbsolutePath(proj.projectId); if (!File.Exists(path)) { await ThrowError(e, "This asset exists, but has not been uploaded yet.", 4); return; } //Get the MIME type from the query. if (!e.Request.Query.ContainsKey("mime")) { //Assume we are querying the information. await Program.QuickWriteJsonToDoc(e, media); return; } //Set content type. e.Response.ContentType = e.Request.Query["mime"]; //Set no-cache headers e.Response.Headers.Add("Cache-Control", "no-cache, no-store, must-revalidate"); //Just load the data and copy it to the output stream. using (FileStream fs = new FileStream(path, FileMode.Open)) { e.Response.ContentLength = fs.Length; e.Response.StatusCode = 200; await fs.CopyToAsync(e.Response.Body); } return; } //Handle object deleting if (method == RequestHttpMethod.delete) { //Delete the file if it exists. string path = media.GetAbsolutePath(proj.projectId); if (File.Exists(path)) { File.Delete(path); } //Delete in appinfo.json. DeleteOutsideAppinfoJsonOnAsset(media.id, proj); //Delete proj.media.Remove(media.id); proj.SaveProject(); //Tell the user it is ok await WriteOkReply(e); return; } //Unknown. await ThrowError(e, $"Invalid method for requesting media '{media.id}'.", 5); }