I have a table which stores attachments uploaded by the users. The attachments can be of type text/doc/jpg etc. Also there would be multiple users uploading files. So there are chances that the file name may be same is some cases. So when this happen the file which is first in the DB table gets downloaded. So along with the file name can one more parameter be added to ensure that correct file is getting downloaded. That other parameter could be the attachment_id which is unique in each case.
This is the action method used to download file on basis of its name
public String downloadAttachFile() throws FileNotFoundException {
attachFileName = ServletActionContext.getRequest().getParameter("myFileFileName");
fileInputStream = new FileInputStream(new File(AttachFileName));
return SUCCESS;
}
Thanks In advance.
Not sure where your files are (file system ?) and how can they be stored with the same name (different folders ?), nor when / how you download multiple files at a time, but you just need to replicate the OS mechanism to rename multiple files with the same name with (n) at the end, like foo.txt and foo(1).txt.
Feel free to adapt the function I've written in the answer to my own ZIP question:
// Set-up a list of filenames to prevent duplicate entries
HashSet<String> entries = new HashSet<String>();
/* ====== ====== ====== ====== ====== ====== ====== ====== ====== ====== ======
then call getUniqueFileName() for each file passing "entries" as parameter
to get an unique file name.
====== ====== ====== ====== ====== ====== ====== ====== ====== ====== ====== */
private String getUniqueFileName(HashSet<String> entries, String completeFileName){
if (entries.contains(completeFileName)){
int extPos = completeFileName.lastIndexOf('.');
String extension = extPos>0 ? completeFileName.substring(extPos) : "";
String partialFileName = extension.length()==0 ? completeFileName : completeFileName.substring(0,extPos);
int x=1;
while (entries.contains(completeFileName = partialFileName + "(" + x + ")" + extension))
x++;
}
entries.add(completeFileName);
return completeFileName;
}
Related
I am trying to attach a text file to a data row in my custom object. I must be missing something. I have the pointer to the current record (asn) and the Byte array (retLabels.Labels) but I can't figure out what the third parameter should be. Also, do I need to execute an update and save after attaching the file?
if (retLabels.Code == "OK" || ediDemo)
{
asnGraph.ASN.Current = asn;
PXNoteAttribute.AttachFile(asn, retLabels.Labels, ???? PX.SM.FileInfo );
}
Create the file in memory:
PX.SM.FileInfo file = new PX.SM.FileInfo("textfile.txt",
null,
Encoding.UTF8.GetBytes("Text file content."));
Upload the file in Acumatica:
UploadFileMaintenance upload = PXGraph.CreateInstance<UploadFileMaintenance>();
upload.SaveFile(file,
FileExistsAction.CreateVersion);
Attach the file to any DAC records by linking file UID (unique ID) to DAC NoteID field:
PXNoteAttribute.SetFileNotes(Base.Caches[typeof(DAC)], dacRecord, file.UID.Value);
I have realize that the SaveImage() command uses the last the last type of format that has been selected during normal DM operation. I assume that this option is selected somewhere in the GobalInfo tags. Please, could someone tell me which tag I have to modify to select dm4 format when I use SaveImage()?
'SaveImage()' is just a convenience wrapper. It is generally not the
Image which is saved to file, but an ImageDocument which can contain one ore more images. The latest DigitalMicograph help
documentation is more detailed about loading/saving than previous
ones, so I'm just copy-pasting the according passages below:
For example to store the front-most displayed image(document) as DM images, you may use:
string name = "C:\\TempImg"
string handler = "Gatan 3 Format"
ImageDocument doc = GetFrontImageDocument()
doc.ImageDocumentSaveToFile( handler, name )
And you can always get the ImageDocument from any image, using:
string handler = "Gatan 3 Format"
image img := RealImage("Test - not yet shown", 4, 100, 100 )
string name = "C:\\" + img.GetName()
ImageDocument doc = img.ImageGetOrCreateImageDocument()
doc.ImageDocumentSaveToFile( handler, name )
I want to delete a pdf file form my database as well as my public/uploads folder. It is deleting from the database but not from my public folder.
This is my controller:
public function deleteArticle($id) {
$article = Article::findOrFail($id);
File::delete($article->document);
$article->delete();
return redirect()->back();
}
/*This handles the posting of the file into the folder and storing of the url into the datab
$file = Input::file('document');
$file->move('uploads', $file->getClientOriginalName());
$document = asset('uploads/'.$file->getClientOriginalName());
$newArticle->document = $document;
As you are currently saving a url to the database ( by using the asset() function ) you can't delete the file by using that information.
It is usually enough to save just the document name in the database.
$document = $file->getClientOriginalName();
$newArticle->document = $document;
To delete the file you can then call:
File::delete(public_path('uploads/'.$article->document);
To Link to your file you can use the asset() method
asset('uploads/'.$article->document);
Storing the full URL in database is a bad idea. It will very hard to maintain files later. The best way is store only the filename with extension.
If you only have the filename in database, you can delete the file in this way:
$article = Article:findOrFail($id);
$document = $article->document; // take the image name from database
File::delete('uploads/'.$document); // delete the file
$article->delete() // delete the record from database
Edit
If you still want to use URL in database you can get the image name by using substr() and strpos() function. Example:
$image = substr($article->document,0,strpos("uploads/"));
You can get only the document name from URL and use it to delete the file.
To store only the filename follow this:
$document = $request->file('document')->getClientOriginalName();
I have path Manipulation problem. The following code is placed in Page_load method of ASPx page.
String rName = Request.QueryString["reportName"];
string path = "C:\\hari" + rName;
if (File.Exists(path))
{
File.Delete(path);
}
But Fortify scan report for the above sample code shows ‘Path Manipulation’ issue as high
Need help to modify above code so that it can pass fortify scan
Jackson is right, this is a direct File Path Manipulation vulnerability that can be fixed through indirect selection.
From your known directory, list all the files. Use the value coming from your own directory list, not the user-supplied value.
String rName = Request.QueryString["reportName"];
String knownPath = "C:\\hari";
DirectoryInfo di = new DirectoryInfo(knownPath);
FileInfo[] files = di.GetFiles(rName);
if (files.length > 0)
{
files[0].Delete();
}
I think the problem is that someone could spoof a request with reportName = "..\\Windows\\Something important" which is clearly a security flaw. You need to change your code so that it doesn't read a partial filename from the request query string.
References:
http://www.grails.org/plugin/amazon-s3
http://svn.codehaus.org/grails-plugins/grails-amazon-s3/trunk/grails-app/services/org/grails/s3/S3AssetService.groovy
http://svn.codehaus.org/grails-plugins/grails-amazon-s3/trunk/grails-app/domain/org/grails/s3/S3Asset.groovy
By "happy" names, I mean the real name of the file I'm uploading... for instance, if I'm putting a file called "foo.png" I'd expect the url to the file to be /foo.png. Currently, I'm just getting what appears to be a GUID (with no file extension) for the file name.
Any ideas?
You can set the key field on the S3Asset object to achieve what you need.
I'll update the doco page with more information on this.
With length, inputstream and fileName given from the uploaded file, you should achieve what you want with the following code :
S3Service s3Service = new RestS3Service(new AWSCredentials(accessKey, secretKey))
S3Object up = new S3Object(s3Service.getBucket("myBucketName"), fileName)
up.setAcl AccessControlList.REST_CANNED_PUBLIC_READ
up.setContentLength length
up.setContentType "image/jpeg"
up.setDataInputStream inputstream
up = s3Service.putObject(bucket, up)
I hope it helps.
Actual solution (as provided by #leebutts):
import java.io.*;
import org.grails.s3.*;
def s3AssetService;
def file = new File("foo.png"); //assuming this file exists
def asset = new S3Asset(file);
asset.mimeType = extension;
asset.key = "foo.png"
s3AssetService.put(asset);