I have the following snippet
class PresentationUpload {
def uploadForm(form:NodeSeq) : NodeSeq = {
var fileHolder: Box[FileParamHolder] = Empty
def handleFile() = {
fileHolder.map { holder =>
val filePath = "src/main/webapp/files"
val oFile = new File(filePath, holder.fileName)
val output = new FileOutputStream(oFile)
output.write(holder.file)
output.close()
} openOr {
// Do something
}
}
val bindForm = "type=file" #> fileUpload((fph) => fileHolder = Full(fph)) &
"type=submit" #> ajaxSubmit("Submit", handleFile _)
ajaxForm(bindForm(form))
}
}
The file uploads correctly but then reloads the application, is this the correct way to handle ajax uploads or is there another method I should be using?
Thanks for any help, much appreciated
I've configured the lift project (normally "project/build/LiftProject.scala") to not reload after changes to the files directory, problem solved :)
override def scanDirectories = (
temporaryWarPath / "WEB-INF" * ("classes" | "lib")
).get.toSeq
Related
I am trying to copy an image that is stored in my application folder to a predefined folder in my gallery.
I started from an image sharing code..
This is my code :
val extension = when (requireNotNull(pictureResult).format) {
PictureFormat.JPEG -> "jpg"
PictureFormat.DNG -> "dng"
else -> throw RuntimeException("Unknown format.")
}
val timestamp = System.currentTimeMillis()
val namePhoto = "picture_"+timestamp+"."+extension;
val destFile = File(filesDir, namePhoto)
val folder = "/CustomFolder"
CameraUtils.writeToFile(requireNotNull(pictureResult?.data), destFile) { file ->
if (file != null) {
// Code to share - it works
/*
val context = this#PicturePreviewActivity
val intent = Intent(Intent.ACTION_SEND)
intent.type = "image/*"
val uri = FileProvider.getUriForFile(context, context.packageName + ".provider", file)
intent.putExtra(Intent.EXTRA_STREAM, uri)
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
startActivity(intent)
*/
*/
// Code to save image to gallery - doesn't work :(
val photoDirectory = File(Environment.DIRECTORY_PICTURES+folder, namePhoto)
val sourcePath = Paths.get(file.toURI())
Log.i("LOG","sourcePath : "+sourcePath.toString()) // /data/user/0/com.app.demo/files/picture_1663772068143.jpg
val targetPath = Paths.get(photoDirectory.toURI())
Log.i("LOG","targetPath : "+targetPath.toString()) // /Pictures/CustomFolder/picture_1663772068143.jpg
Files.move(sourcePath, targetPath, StandardCopyOption.REPLACE_EXISTING)
// Error here but I don't know why
} else {
Toast.makeText(this#PicturePreviewActivity, "Error while writing file.", Toast.LENGTH_SHORT).show()
}
}
How do I copy the image to a predefined folder?
Ok, I did it !
Solution :
val folder = "/CustomFolder/" // name of your folder
val timestamp = System.currentTimeMillis()
val namePicture = "picture_"+timestamp+"."+extension;
try {
val path = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES+folder);
if (!path.exists()) {
path.mkdir();
}
val pathImage = File(path,namePicture)
val stream = FileOutputStream(pathImage)
stream.write(imageByteArray).run {
stream.flush()
stream.close()
}
} catch (e: FileNotFoundException) {
e.printStackTrace()
}
I have two action methods in my Controller class:
DetailsAll: to get some data and display in the view
SaveAsPDF: Called on windows.load of DetailsAll.cshtml which should save DetailsAll view as pdf
My issue is in SaveAsPDF Action method. Here I am trying to use Rotativa ActionAsPdf and subsequently BuildFile methods to generate and save the PDF. However, when executing the line "BuildFile", it is not hitting the breakpoint in my DetailsAll Action method, subsequently causing the PDF to be generated blank.
Could you please help where I am going wrong?
[HttpGet]
public ActionResult DetailsAll()
{
var selectionBuilder = builderFactory.GetGeocodeReportSelectionViewModelBuilder();
var companyList = selectionBuilder.Build();
List<GeocodeReportViewModel> viewModel = new List<GeocodeReportViewModel>();
foreach(SelectListItem record in companyList.Companies)
{
var builder = builderFactory.GetGeocodeReportViewModelBuilder(int.Parse(record.Value));
viewModel.Add(builder.Build());
}
var model = new AllGeocodeReportViewModel
{
GeocodeReports = viewModel
};
return View(model);
}
[HttpGet]
public string SaveAsPDF()
{
var report = new ActionAsPdf("DetailsAll")
{
FileName = "OEM_GeocodeReport_" + System.DateTime.Now.ToString("MMYY") + ".pdf",
PageSize = Size.A4,
PageOrientation = Orientation.Landscape,
PageMargins = { Left = 1, Right = 1 }
};
byte[] pdf = report.BuildFile(ControllerContext);
System.IO.File.WriteAllBytes("C:\\" + report.FileName, pdf);
return "true";
}
Finally found the issue after extensive search. I need to send Authentication cookies along with the BuildFile request for this to work. Added the below code and it generates PDF correctly now:
public void SaveAsPDF()
{
var cookies = Request.Cookies.AllKeys.ToDictionary(k => k, k => Request.Cookies[k].Value);
var report = new ActionAsPdf("DetailsAll")
{
FileName = "OEM_GeocodeReport_" + System.DateTime.Now.ToString("MMyy") + ".pdf",
PageSize = Size.A4,
PageOrientation = Orientation.Portrait,
PageMargins = { Left = 3, Right = 3 },
FormsAuthenticationCookieName = System.Web.Security.FormsAuthentication.FormsCookieName,
Cookies = cookies
};
byte[] pdf = report.BuildFile(ControllerContext);
System.IO.File.WriteAllBytes("C:\\" + report.FileName, pdf);
}
In general, I have created rest controller for both uploading and downloading a file from front end (React) to our file system. Uploading works great, as expected. However, downloading rest api not functioning properly. it downloads only 12kb or smth like that of the file. Is there anything [configs] that I am missing in my project or what? Please help! any comment or suggestion would be appreciated thanks in advance
#GetMapping("/get")
fun getFile(#Valid data: FileDeleteDTO): ResponseEntity<Resource>{
val header = HttpHeaders()
val fileGetFromDb = baseFileUploaderAttachmentService.getByUid(data.qquuid)
if (!fileGetFromDb.isPresent)
throw FileNotFoundException()
val pathFileName = fileGetFromDb.get().filename + '.' + fileGetFromDb.get().extension
val originalFileName = fileGetFromDb.get().originalName + '.' + fileGetFromDb.get().extension
// val filePath = UPLOAD_ROOT_FOLDER + fileGetFromDb.get().path + pathFileName
val filePath = UPLOAD_ROOT_FOLDER + fileGetFromDb.get().path
// val file = File(filePath)
header.contentType = (MediaType.valueOf(fileGetFromDb.get().mime_type!!))
header.contentLength = fileGetFromDb.get().size
header.set("Content-Disposition", "attachment; filename=$originalFileName")
return ResponseEntity.ok()
.headers(header)
.body(loadFileAsResource(pathFileName,Paths.get(filePath)))
}
fun loadFileAsResource(fileName: String, fileStorageLocation: Path): Resource {
try {
val filePath = fileStorageLocation.resolve(fileName).normalize()
val resource = UrlResource(filePath.toUri())
return if (resource.exists()) {
resource
} else {
throw FileNotFoundException("File not found $fileName")
}
} catch (ex: MalformedURLException) {
throw Exception("File not found $fileName", ex)
}
}
I have no idea what happened but i have solved above problem by adding some header elements like below:
#RequestMapping(value = ["/download"], method = [RequestMethod.GET])
#Throws(IOException::class)
fun downloadFile(#Valid data: FileDeleteDTO): ResponseEntity<Any> {
val fileGetFromDb = baseFileUploaderAttachmentService.getByUid(data.qquuid)
val pathFileName = fileGetFromDb.get().filename + '.' + fileGetFromDb.get().extension
val originalFileName = fileGetFromDb.get().originalName + '.' + fileGetFromDb.get().extension
val filePath = UPLOAD_ROOT_FOLDER + fileGetFromDb.get().path + pathFileName
val file = File(filePath)
val resource = InputStreamResource(FileInputStream(file))
val headers = HttpHeaders()
headers.add("Content-Disposition", String.format("attachment; filename=\"%s\"", originalFileName))
headers.add("Cache-Control", "no-cache, no-store, must-revalidate")
headers.add("Pragma", "no-cache")
headers.add("Expires", "0")
return ResponseEntity.ok().headers(headers).contentLength(
file.length()
).contentType((MediaType.valueOf(fileGetFromDb.get().mime_type!!))).body(resource)
}
Just wondering does Cache control has impact on this issue? Where can i learn about headers?
what's the best way to replace strings within the [] (including the brackets) with values from attributes?
{
"VoiceMessageTemplateEnglish" : "Hello, this is [LocationName] calling to confirm an appointment for [Name] on [AppointmentDate] at [AppointmentTime] with [Name]. Please press 1 To confirm, Press 2 To Cancel",
}
I tried using ExecuteScript processor with JS but did not have any luck.
Thanks!
processor ExecuteGroovyScript in nifi 1.5.0
def ff = session.get()
if(!ff)return
def attr = ff.getAttributes()
def text = ff.read().getText("UTF-8")
text = text.replaceAll( /\[(\w+)\]/ ) { attr[it[1]] ?: "noValue" }
ff.write("UTF-8", text)
REL_SUCCESS << ff
I ended up using JS to solve the problem:
thanks #daggett for pointing me in the right direction
var flowFile = session.get();
if (flowFile != null) {
var lclAppointmentDate = flowFile.getAttribute("AppointmentDate");
var lclAppointmentStartTime = flowFile.getAttribute("AppointmentStartTime");
var lclName = flowFile.getAttribute("Name");
var lclVoiceMailTemplate = flowFile.getAttribute("VoiceMailTemplate");
if (lclVoiceMailTemplate != null){
lclVoiceMailTemplate = lclVoiceMailTemplate
.replace('[Name]', lclName)
.replace('[AppointmentDate]', lclAppointmentDate)
.replace('[AppointmentTime]', lclAppointmentStartTime);
flowFile = session.putAttribute(flowFile, "FinalVoiceMailTemplate", lclVoiceMailTemplate);
}
session.transfer(flowFile, REL_SUCCESS);
session.commit();
}
I need to save image to a folder in my application. So far I have learned to save image into a database but I need to save it to a folder. How can I do this? Can anyone please help me on this please? here is my code below to save into database >>>
def upload={
def user = User.findById(1)
CommonsMultipartFile file = params.list("photo")?.getAt(0)
user.avatar = file?.bytes
user.save()
}
Find below for the step wise implementation, I have added a GSP page with the uploadForm(it will have multipart form submission by default), and then a controller function to handle file save request, and a service method to save file in a specified directory:
Step1: Create a form for file upload:
<g:uploadForm name="picUploadForm" class="well form-horizontal" controller="<your-controller-name>" action="savePicture">
Select Picture: <input type="file" name="productPic"/>
<button type="submit" class="btn btn-success"><g:message code="shopItem.btn.saveProductImage" default="Save Image" /></button>
</g:uploadForm>
Step2: Then in your controller's savePicture action:
String baseImageName = java.util.UUID.randomUUID().toString();
// Saving image in a folder assets/channelImage/, in the web-app, with the name: baseImageName
def downloadedFile = request.getFile( "product.baseImage" )
String fileUploaded = fileUploadService.uploadFile( downloadedFile, "${baseImageName}.jpg", "assets/channelImage/" )
if( fileUploaded ){
// DO further actions, for example make a db entry for the file name
}
Step3: and in the file uploader service(User defined service with the name FileUploadService in this case):
def String uploadFile( MultipartFile file, String name, String destinationDirectory ) {
def serveletContext = ServletContextHolder.servletContext
def storagePath = serveletContext.getRealPath( destinationDirectory )
def storagePathDirectory = new File( storagePath )
if( !storagePathDirectory.exists() ){
println("creating directory ${storagePath}")
if(storagePathDirectory.mkdirs()){
println "SUCCESS"
}else{
println "FAILED"
}
}
// Store file
if(!file.isEmpty()){
file.transferTo( new File("${storagePath}/${name}") )
println("Saved File: ${storagePath}/${name}")
return "${storagePath}/${name}"
}else{
println "File: ${file.inspect()} was empty"
return null
}
}
You have only to copy the MutipartFile into web-app folder. This is how :
MultipartHttpServletRequest mpr = (MultipartHttpServletRequest)request;
CommonsMultipartFile f = (CommonsMultipartFile) mpr.getFile("myfile");
String fileName = System.currentTimeMillis() + f.name
String destinationFileName = configService.getAbsoluteDocumentsPath() + fileName // We will put it on web-app/documents/xxxxx
f.renameTo(new File(destinationFileName))
//Save filename to database in
user.avatar = fileName
user.save()
And in configService I have that (used to calculate paths)
class ConfigService {
def grailsApplication
/**
* #return absolute path of documents
*/
def getAbsoluteDocumentsPath(){
def asolutePath = grailsApplication.mainContext.servletContext.getRealPath('documents')
return asolutePath.endsWith("/") ? asolutePath : asolutePath + "/"
}
}
EDIT
To make sure that your request is an instance of MutipartHttServletRequest Add the following test
if(request instanceof MultipartHttpServletRequest) {
//Do stuff here
}
Don't forget to check the the encoding of the form in which you put the file input.
I have solve this so easily as follows. You will have to import followings :
import org.apache.commons.io.FileUtils
import org.springframework.web.multipart.commons.CommonsMultipartFile
import org.springframework.web.multipart.*
Good luck who needs this >>>
def saveImageToFolder = {
String message = ""
MultipartHttpServletRequest mpr = (MultipartHttpServletRequest)request;
CommonsMultipartFile f = (CommonsMultipartFile) mpr.getFile("userPhoto")
if(!f.empty) {
def usr = User.findByUsername(1)
if(!usr){
User user = new User()
user.username = params.username
user.avatarType = f.getContentType()
if(user.save()){
def userId = user.id
String username = user.username
String fileName = username + "." + f.getContentType().substring(6) // here my file type is image/jpeg
byte[] userImage = f.getBytes()
FileUtils.writeByteArrayToFile(new File( grailsApplication.config.images.location.toString() + File.separatorChar + fileName ), userImage )
message = "User Created Successfully."
}else{
message = "Can not Create User !!!"
}
}else{
message = "Username already exists. Please try another one !!!"
}
}
else {
message = 'file cannot be empty'
}
render(view: 'addUser', model:[message: message])
}
and in your config file paste this >>>
images.location = "web-app/images/userImages/" // after web-app/folder name/folder name and go on if you want to add other folder