How to mkdirs on gwt when fileupload on client - gwt

i mode development in eclipse. the fileupload works just fine. but i will make directory to /var/wms/year/month/file.jpg on linux. this my source code from client:
add component to form
fileUpload = new SingleUploader(FileInputType.LABEL);
fileUpload.setFileInputPrefix("PJ");
fileUpload.addOnFinishUploadHandler(onFinishUploaderHandler);
layoutContainerItemRight.add(fileUpload, formData);
method is addOnFinishUploadHandler
private IUploader.OnFinishUploaderHandler onFinishUploaderHandler = new IUploader.OnFinishUploaderHandler() {
public void onFinish(IUploader uploader) {
if (uploader.getStatus() == gwtupload.client.IUploadStatus.Status.SUBMITING) {
String month = VisionProperties.getBulan();
String year = DateTimeFormat.getFormat( "d-M-yyyy" ).format( new Date() ).split( "-")[2];
String strDirectoy = "/var/wms/" + year + "/" + month + "/";
File file = new File(strDirectoy);
if (!file.exists()) {
file.mkdirs();
}
}
if (uploader.getStatus() == gwtupload.client.IUploadStatus.Status.SUCCESS) {
String msg = uploader.getServerInfo().message;
fileName = msg.toString();
if(selectWindow != 2){
img.setUrl("servlet.gupld?show=&fieldname=" + fileName);
itemPanel.render(img.getElement());
}else{
tb.setVisible(true);
tb.setText("Download File "+uploader.getFileName());
}
}
}
};
how to make directory file when upload file process?

You are trying to use to use java.io.File in the client side which is not supported by the set of packages in the GWT jre emulation.
If you want to do this in client side you have to use the javascript File Api which is not supported by old browsers, and is not implemented in gwt-core. Using elemental you could use the Api only with Chrome, but I'm not positive. So it is better to wrap it via jsni, it is planned in gwtupload, but there is no a timeframe yet. Be aware that using js File Api, you dont have access to your real filesystem, but a virtual one inside your browser. To save created files in the local filesystem you have to download it using and iframe so as it asks the user where to save it.
Otherwise, If you wanted to do this work at server side, do it overriding the executeAction in your servlet if you are extending UploadAction.

You cannot do this on client side. You can perform this on server side in the following ways
before you upload the files to server by another rpc/http call.
after you upload the files to server when the file upload servlet is being executed on the srever side.
HTML5 FILE API are restricted to readonly behavior in even modern browser.
Reference -
1. Basic File upload in GWT
2. How to retrieve file from GWT FileUpload component?

Related

How to Return File from SvelteKit Endpoint

I am trying to serve a PDF file that my SvelteKit app generates and allow a user to download it from an endpoint.
My project structure looks like this:
---------------------
/src/routes/downloads
---------------------
[file].ts
ABC.pdf
XYZ.pdf
My [file].ts endpoint looks like this:
import fs from 'fs'
// ----- GET -----
export async function get({ params }){
//console.log(params.file) -> ABC
var pdf = fs.readFileSync('./src/routes/downloads/'+params.file+'.pdf')
return{
status:200,
headers: {
"Content-type" : "application/pdf",
"Content-Disposition": "attachment; filename="+params.file+".pdf"
},
body: pdf
}
}
So then when I hit http://localhost:3000/downloads/ABC, the PDF file named ABC.pdf downloads.
But my readFileSync path isn't something that's going to work on production. As far as I know, there is no /src/routes folder.
How do I serve my file from a http://localhost:3000 url? Everything I've tried yields a 404 and it can't find the file. I'm also open to a different way of handling this scenario. This is just my best guess of how to do this in SvelteKit.
The recommended way to do this, for adapter-node, is to place your application data in a new folder under your project's root directory (ie. alongside /src and /static). You can then read files with a relative path: fs.readFile('./my-app-data/foo.txt').
For deployment, you just have to make sure to execute node build from the project root, as this guarantees that you have the same working directory during both development and production.
The static folder works, but it is not meant to carry application data—files in this folder represent new routes that are served directly to users, so this is not desirable if your generated files must be protected in any way. Even if they're meant to be public files, it still blurs what is supposed to be production and source data: should a new deploy overwrite all the files in static? If you're not careful, a naming clash could mean overwriting production data.
You can use import.meta.glob for this.
export async function get({ params }){
const file = `./${params.file}.pdf`;
const pdfs = import.meta.glob(('./*.pdf', { as: 'raw' });
const pdf = pdfs[file];
return {
status:200,
headers: {
"Content-type" : "application/pdf",
"Content-Disposition": "attachment; filename="+params.file+".pdf"
},
body: pdf
}
}
The import.meta.glob in combination with the as: 'raw' option will effectively embed the contents of each file in your resulting code. (this is purely server side so no worries about shipping to much to the client)
Note that this of course means that only files present during build can be served this way.
As #Stephane suggest, put your files under statics folder. This way you can serve directly through a reverse proxy, like Nginx

Eclipse Plugin Open a PDF file from inside a plugin package

I am trying to open a PDF file that represents the documentation of my plugin from inside a package, since I have opened a properties file the same way using getClass().getResource(URI).
I am trying the same with the PDF file, and I'm trying to get the URL of the file, then passing it to Desktop.browse() converted to URI, but it gives me a Malformed URI exception. Is there a way to do this easier and also to work?
This is my code so far:
try{
URL url = new URL(getClass().getResource("Documentation.pdf"), null);
Desktop.getDesktop().browse(url.toURI());
}catch(Exception exception){
Status status = new Status(IStatus.ERROR, Activator.PLUGIN_ID, exception.getLocalizedMessage(), exception);
ErrorDialog.openError(null, "Error", "Error occured!", status);
}
The URL/URI you get back from getResource uses the bundleresource scheme which is not understood by many things.
For an Eclipse plugin you should use the FileLocator class.
Bundle bundle = FrameworkUtil.getBundle(getClass());
IPath path = new Path("path relative to root of the plugin");
URL url = FileLocator.find(bundle, path, null);
URL fileURL = FileLocator.toFileURL(url);
Desktop.getDesktop().browse(fileURL.toURI());
Again the URL returned by FileLocator.find uses a special scheme and is not understood by many things. FileLocator.toFileURL converts this URL to a normal file scheme - to do this it may be necessary to unpack the file from the plugin jar to a temporary location.
Note: Path is org.eclipse.core.runtime.Path

Multiple s3 buckets in Filepicker.io

I need to upload to multiple s3 buckets with filepicker.io. I found a tweet that indicated that there was a hacky, but possible, way to do this. Support hasn't gotten back to me yet, so I'm hoping that someone here already knows the answer!
Have you tried generating a second application/API key? It looks like they lock your S3/AWS credentials to an application/API key rather than directly to the account.
Support just got back to me. There's no way to do this besides creating multiple applications, which is okay if you are just switching between prod/staging/dev, but not a good solution if you have to upload to arbitrary buckets.
My solution is to execute a PUT request with the x-amz-copy-source header after the file has been uploaded, which copies it to the correct bucket.
This is pretty hacky as it request two extra requests per file -- one filepicker.stat and one more call to s3 (or your server).
#Ben
I am developing code with same issue of files needing to go into many buckets. I'm working in ASP.net.
What I have done is have one Filepicker 'application' with it's own S3 bucket.
I already had a callback to the server in the javascript onSuccess() function (which is passed as a parameter to filepicker.store()). This callback needed to be there to do some book-keeping anyway.
So I have just added in an extra bit to the server-side callback code which uses the AWS SDK to copy the object from the bucket filepicker uploades it to, to it's final destination bucket.
This is my C# code for moving, or rather copying, an object between buckets:
public bool MoveObject(string bucket1, string key1, string bucket2, string key2 = null)
{
bool success = false;
if (key2 == null) key2 = key1;
Logger logger = new Logger(); // my logging system
try
{
RegionEndpoint region = RegionEndpoint.EUWest1; // use your region here
using (AmazonS3Client s3Client = new AmazonS3Client(region))
{
// TODO: CheckForBucketFunction
CopyObjectRequest request = new CopyObjectRequest();
request.SourceBucket = bucket1;
request.SourceKey = key1;
request.DestinationBucket = bucket2;
request.DestinationKey = key2;
S3Response response = s3Client.CopyObject(request);
logger.Info2Log("response xml = \n{0}\n", response.ResponseXml);
response.Dispose();
success = true;
}
}
catch (AmazonS3Exception ex)
{
logger.Info2Log("Error copying file between buckets: {0} - {1}",
ex.ErrorCode, ex.Message);
success = false;
}
return success;
}
There are AWS SDKs for other server languages and the good news is Amazon doesn't charge for copying objects between buckets in the same region.
Now I just have to decide how to delete the object from the filepicker application bucket. I could do it on the server using more AWS SDK code but that will be messy as it leaves links to the object in the filepicker console. Or I could do it from the browser using filepicker code.

Help with a Windows Service/Scheduled Task that must use a web browser and file dialogs

What I'm Trying To Do
I'm trying to create a solution of any kind that will run nightly on a Windows server, authenticate to a website, check a web page on the site for new links indicating a new version of a zip file, use new links (if present) to download a zip file, unzip the downloaded file to an existing folder on the server, use the unzipped contents (sql scripts, etc.) to build an instance of a database, and log everything that happens to a text file.
Forms App: The Part That Sorta Works
I created a Windows Forms app that uses a couple of WebBrowser controls, a couple of threads, and a few timers to do all that except the running nightly. It works great as a Form when I'm logged in and run it, but I need to get it (or something like it) to run on it's own like a Service or scheduled task.
My Service Attempt
So, I created a Windows Service that ticks every hour and, if the System.DateTime.Now.Hour >= 22, attempts to launch the Windows Forms app to do it's thing. When the Service attempts to launch the Form, this error occurs:
ActiveX control '8856f961-340a-11d0-a96b-00c04fd705a2' cannot be instantiated because the current thread is not in a single-threaded apartment.
which I researched and tried to resolve by either placing the [STAThread] attribute on the Main method of the Service's Program class or using some code like this in a few places including the Form constructor:
webBrowseThread = new Thread(new ThreadStart(InitializeComponent));
webBrowseThread.SetApartmentState(ApartmentState.STA);
webBrowseThread.Start();
I couldn't get either approach to work. In the latter approach, the controls on the Form (which would get initialized inside IntializeComponent) don't get initialized and I get null reference exceptions.
My Scheduled Task Attempt
So, I tried creating a nightly scheduled task using my own credentials to run the Form locally on my dev machine (just testing). It gets farther than the Service did, but gets hung up at the File Download Dialog.
Related Note: To send the key sequences to get through the File Download and File Save As dialogs, my Form actually runs a couple of vbscript files that use WScript.Shell.SendKeys. Ok, that's embarassing to admit, but I tried a few different things including SendMessage in Win32 API and referencing IWshRuntimeLibrary to use SendKeys inside my C# code. When I was researching how to get through the dialogs, the Win32 API seemed to be the recommended way to go, but I couldn't figure it out. The vbscript files was the only thing I could get to work, but I'm worried now that this may be the reason why a scheduled task won't work.
Regarding My Choice of WebBrowser Control
I have read about the System.WebClient class as an alternative to the WebBrowser control, but at a glance, it doesn't look like it has what I need to get this done. For example, I needed (or I think I needed) the WebBrowser's DocumentCompleted and FileDownload events to handle the delays in pages loading, files downloading, etc. Is there more to WebClient that I'm not seeing? Is there another class besides WebBrowser that is more Service-friendly and would do the trick?
In Summary
Geez, this is long. Sorry! It would help to even have a high level recommendation for a better way to do what I'm trying to do, because nothing I've tried has worked.
Update 10/22/09
Well, I think I'm closer, but I'm stuck again. I should end up with a decent-sized zip file with several files in it, but the zip file resulting from my code is empty. Here's my code:
// build post request
string targetHref = "http://wwwcf.nlm.nih.gov/umlslicense/kss/login.cfm";
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(targetHref);
request.Method = "POST";
request.ContentType = "application/x-www-form-urlencoded";
// encoding to use
Encoding enc = Encoding.GetEncoding(1252);
// build post string containing authentication information and add to post request
string poststring = "returnUrl=" + fixCharacters(targetDownloadFileUrl);
poststring += getUsernameAndPasswordString();
poststring += "&login2.x=0&login2.y=0";
// convert to required byte array
byte[] postBytes = enc.GetBytes(poststring);
request.ContentLength = postBytes.Length;
// write post to request
Stream postStream = request.GetRequestStream();
postStream.Write(postBytes, 0, postBytes.Length);
postStream.Close();
// get response as stream
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
Stream responseStream = response.GetResponseStream();
// writes stream to zip file
FileStream writeStream = new FileStream(fullZipFileName, FileMode.Create, FileAccess.Write);
ReadWriteStream(responseStream, writeStream);
response.Close();
responseStream.Close();
The code for ReadWriteStream looks like this.
private void ReadWriteStream(Stream readStream, Stream writeStream)
{
// taken verbatum from http://www.developerfusion.com/code/4669/save-a-stream-to-a-file/
int Length = 256;
Byte[] buffer = new Byte[Length];
int bytesRead = readStream.Read(buffer, 0, Length);
// write the required bytes
while (bytesRead > 0)
{
writeStream.Write(buffer, 0, bytesRead);
bytesRead = readStream.Read(buffer, 0, Length);
}
readStream.Close();
writeStream.Close();
}
The building of the post string is taken from my previous forms app that works. I compared the resulting values in poststring for both sets of code (my working forms app and this one) and they're identical.
I'm not even sure how to troubleshoot this further. Anyone see anything obvious as to why this isn't working?
Conclusion 10/23/09
I finally have this working. A couple of important hurdles I had to get over. I had some problems with the ReadWriteStream method code that I got online. I don't know why, but it wasn't working for me. A guy named JB in Claudio Lassala's Virtual Brown Bag meeting helped me to come up with this code which worked much better for my purposes:
private void WriteResponseStreamToFile(Stream responseStreamToRead, string zipFileFullName)
{
// responseStreamToRead will contain a zip file, write it to a file in
// the target location at zipFileFullName
FileStream fileStreamToWrite = new FileStream(zipFileFullName, FileMode.Create);
int readByte = responseStreamToRead.ReadByte();
while (readByte != -1)
{
fileStreamToWrite.WriteByte((byte)readByte);
readByte = responseStreamToRead.ReadByte();
}
fileStreamToWrite.Flush();
fileStreamToWrite.Close();
}
As Will suggested below, I did have trouble with the authentication. The following code is what worked to get around that issue. A few comments inserted addressing key issues I ran into.
string targetHref = "http://wwwcf.nlm.nih.gov/umlslicense/kss/login.cfm";
HttpWebRequest firstRequest = (HttpWebRequest)WebRequest.Create(targetHref);
firstRequest.AllowAutoRedirect = false; // this is critical, without this, NLM redirects and the whole thing breaks
// firstRequest.Proxy = new WebProxy("127.0.0.1", 8888); // not needed for production, but this helped in order to debug the http traffic using Fiddler
firstRequest.Method = "POST";
firstRequest.ContentType = "application/x-www-form-urlencoded";
// build post string containing authentication information and add to post request
StringBuilder poststring = new StringBuilder("returnUrl=" + fixCharacters(targetDownloadFileUrl));
poststring.Append(getUsernameAndPasswordString());
poststring.Append("&login2.x=0&login2.y=0");
// convert to required byte array
byte[] postBytes = Encoding.UTF8.GetBytes(poststring.ToString());
firstRequest.ContentLength = postBytes.Length;
// write post to request
Stream postStream = firstRequest.GetRequestStream();
postStream.Write(postBytes, 0, postBytes.Length); // Fiddler shows that post and response happen on this line
postStream.Close();
// get response as stream
HttpWebResponse firstResponse = (HttpWebResponse)firstRequest.GetResponse();
// create new request for new location and cookies
HttpWebRequest secondRequest = (HttpWebRequest)WebRequest.Create(firstResponse.GetResponseHeader("location"));
secondRequest.AllowAutoRedirect = false;
secondRequest.Headers.Add(HttpRequestHeader.Cookie, firstResponse.GetResponseHeader("Set-Cookie"));
// get response to second request
HttpWebResponse secondResponse = (HttpWebResponse)secondRequest.GetResponse();
// write stream to zip file
Stream responseStreamToRead = secondResponse.GetResponseStream();
WriteResponseStreamToFile(responseStreamToRead, fullZipFileName);
responseStreamToRead.Close();
sl.logScriptActivity("Downloading update.");
firstResponse.Close();
I want to underscore that setting AllowAutoRedirect to false on the first HttpWebRequest instance was critical to the whole thing working. Fiddler showed two additional requests that occurred when this was not set, and it broke the rest of the script.
You're trying to use UI controls to do something in a windows service. This will never work.
What you need to do is just use the WebRequest and WebResponse classes to download the contents of the webpage.
var request = WebRequest.Create("http://www.google.com");
var response = request.GetResponse();
var stream = response.GetResponseStream();
You can dump the contents of the stream, parse the text looking for updates, and then construct a new request for the URL of the file you want to download. That response stream will then have the file, which you can dump on the filesystem and etc etc.
Before you wonder, GetResponse will block until the response returns, and the stream will block as data is being received, so you don't need to worry about events firing when everything has been downloaded.
You definitely need to re-think your approach (as you've already begun to do) to eliminate the Forms-based application approach. The service you're describing needs to operate with no UI at all.
I'm not familiar with the details of System.WebClient, but since it
provides common methods for sending
data to and receiving data from a
resource identified by a URI,
it will probably be your answer.
At first glance, WebClient.DownloadFile(...) or WebClient.DownloadFileAsync(...) will do what you need.
The only thing I can add is that once you have scraped your screen and have the fully qualified name of the file you want to download, you could pass it along to the Windows/DOS command 'get' which will fetch files via HTTP. You can also script a command-line FTP client if desired. It's been a long time since I tried something like this in Windows, but I think you're almost there. Once you have fetched the correct file, building a batch file to do everything else should be pretty easy. If you are more comfortable with Unix, google "unix services for windows" just keep an eye on the services they start running (DHCP, etc). There are some nice utilities which will let your treat dos as a unix-like shell (ls -l, grep, etc) Finally, you could try another language like Perl or Python but I don't think that's the kind of advice you were looking for. :)

how can I check for an existing web folder

I work as software tester entry level and I was given a task to save my log files to the specific folder on my company website and this website only can be accessed internally by the company employees. So far I know how to save file onto the site, but how would I check which specific folder is already there before I save the file to it?
private void SaveLogsTogWeb(string file)
{
try
{
//create WebClient object
WebClient client = new WebClient();
client.Credentials = CredentialCache.DefaultCredentials;
client.UploadFile(#"http://myCompnay/MyProjects/TestLogs/" + file, "PUT", file);
client.Dispose();
}
catch (Exception err)
{
MessageBox.Show(err.Message);
}
}
Thanks in advance for the helps
Use this code:
if(!Directory.Exists({path}))
{
//create the directory
}
It checks to see if the directory doesn't exist. And if it doesn't then you can create it!
One way would be to put a dummy file in that folder (dummy.txt) and do an HTTP GET of the file. If you can successfully do that, you can then assume the folder exists (barring any virtual folders, etc.)