I am working in an application which uses facebook connect to fetch a user’s profile picture. But after the connection is made I still have to be able to crop and resize the “large” image. Therefor I want to download the profile picture from the facebook server to my own server.
As of now I am not able to download the picture to my server. Here is what I am doing:
The facebook profile picture get sync in our application from facebook with the following path http://graph.facebook.com/uid/picture?type=large
Now we need the image to be get saved locally from the URL mentioned above
Crop it and display it, but we are unable to save the image from the provided URL
Question
• So how we can save the facebook profile picture in our server using this path http://graph.facebook.com/uid/picture?type=large?
• Or what is the other solution to save facebook profile? Picture to be save in our server first before displaying it?
• How do we still keep it in sync with facebook if we use the saved picture?
Then I have another question:
How do you delete the cookies for a once established facebook connect connections if a user does not want to use facebook connect no more?
If have tried to do this with the following code but no results:
var api_key = "135xxxxxxxxxxx";
var channel_path = ""+2;
FB.init(api_key , cookie:false, channel_path, { "ifUserConnected": update_user_box });
Function update_user_box(){
Var fbId=FB.Connect.get_loggedInUser();
The code given above to delete the false cookie is not working. What do I have to do to resolve this issue?
Instead of saving all the profile photos you could display the photo in a div that is too small for the entire image. Basically let the html do the cropping.
<body>
<div style="background-image: url(http://scm-l3.technorati.com/11/01/14/25023/facebook-logo.jpg); width: 380px; height: 300px;">
</div>
</body>
OR, per my comments below, you could wrap an image and resize the div. Both options work. One avoids using a CSS url() which might not follow redirects in come rare cases.
<body>
<div style="width: 380px; height: 300px; overflow: hidden;">
<img src="http://scm-l3.technorati.com/11/01/14/25023/facebook-logo.jpg" alt="Facebook" />
</div>
</body>
Like OffBySome said above, the key is knowing that it will redirect you. So, we turn off following the redirect automatically and retrieve the actual URL of the picture from the header of the profile URL. Here's a snippet I've used to download the actual image file. Available as a gist here: https://gist.github.com/1092990
private static final String PROFILE_PICTURE_URL = "https://graph.facebook.com/%s/picture?type=large&access_token=%s";
private String downloadFacebookProfilePicture(String uid, String accessToken, String username) throws MalformedURLException, IOException {
//Get the picture url
HttpURLConnection.setFollowRedirects(false);
String profilePictureUrlString = new URL(String.format(PROFILE_PICTURE_URL, uid, accessToken)).openConnection().getHeaderField(
"location");
//Set up temp location for picture
String fileExtension = StringUtils.substring(profilePictureUrlString,
StringUtils.lastIndexOf(profilePictureUrlString, ".") + 1);
String tempFilePath = (new StringBuilder(String.valueOf(System
.getProperty("java.io.tmpdir"))))
.append(StringUtils.replace(username, ".", "_")).append(".")
.append(fileExtension).toString();
String exportUrl = profilePictureUrlString;
//Download file to temp location
downloadFile(exportUrl, tempFilePath);
return tempFilePath;
}
private void downloadFile(String exportUrl, String filepath)
throws IOException, MalformedURLException {
InputStream inStream = new URL(exportUrl).openStream();
FileOutputStream outStream = new FileOutputStream(filepath);
copyStreams(inStream, outStream);
}
private void copyStreams(InputStream inStream, OutputStream outStream)
throws IOException {
try {
int c;
while ((c = inStream.read()) != -1) {
outStream.write(c);
}
} finally {
if (inStream != null) {
inStream.close();
}
if (outStream != null) {
outStream.flush();
outStream.close();
}
}
}
You should probably split your questions into separate questions but as others have pointed out, https://graph.facebook.com/me/picture will return a 302 redirect to the image URL that you can save to your server so you'll need to make sure you're either following the redirect or reading the Location header (more on how to do that here) to get the URI of the actual image.
As for your question on how to make sure you are always using the most up to date picture, you should subscribe to the "/picture" connection of the "User" object using Real-time Updates and we will ping your callback whenever any user of your app updates their picture so you can go pull the latest one. This way you won't have to keep polling to see if the user has changed their picture.
If you're able to achieve what you're going for with just CSS (without caching the pic on your own server), check out squinlan's solution.
When you try to download the image, make sure whatever you are download the image with can follow 302 redirects because the graph Facebook link only returns a redirect to the image, not the actual image itself. But cropping the image with CSS would make a lot more sense.
Related
I'm developing some kind of android mail app and I get each mail attachments as an ArrayList of urls from a rest api and I want to use them in some kind of attachment section. I need to check the urls and pass image links to a preview adapter using glide api and show other urls (other file formats, like .pdf, .docx or ...) in another section as a download link.
Is there any way to know if the url is link to a image file or not before downloading it?
I know there are seemingly similar threads that are answered already but this is different in two ways.
First I want to to know if the url is link to image or not before downloading it.
Second I don't want to use static extension check. Because there are like tons of different extensions like .jpg, .png,... and they may change and I don't want to update my app with each change.
There is a way you can do it but I'm not sure its the best approach.
Code:
new Thread(new Runnable() { // if already doing the checking on network thread then no need to add this thread
#Override
public void run() {
try {
URLConnection connection = new URL("image url here").openConnection();
String contentType = connection.getHeaderField("Content-Type");
boolean image = contentType.startsWith("image/"); //true if image
Log.i("IS IMAGE", "" + image);
} catch (IOException e) {
e.printStackTrace();
}
}
}).start();
Hope this helps!
You can provide additional fields,which can help you identify file format, in your rest API.
You can checkout response content-type. Checkout this answer:
https://stackoverflow.com/a/5802223
If you have the URI you could:
use this for the full path
and substring after the last "."
I have been working on creating a series of buttons that uploads, downloads, and deletes files in Spring MVC, with JSP pages, and Java this past few days. I have the Upload and Delete working perfectly, and just got the download almost working. I stress almost because the download comes with a very odd condition.
If I upload say an exe or a jar file, and then go back and try and download it. A box will show up asking me if I want to open it or save it. If I want to do either it's not corrupted or anything, it's just fine.
If, however, the file is text based, as in a PDF, TXT, .doc, even XML, a browser tab will open, and it will show up in there.
So can anyone point me in the direction on how I might fix this?
The first block of code is my controller method, the second is the line in my jsp that triggers the button.
#RequestMapping("/FileDownload")
public ModelAndView FileDownload(
#RequestParam(value = "FileID", required = false) int fileID,
#RequestParam(value = "theFile", required = false) MultipartFile thefile,
#ModelAttribute("fileAttachment") #Valid fileAttachment, BindingResult result, HttpServletResponse response){
ModelAndView mav = new ModelAndView();
fileAttachment doc = attachmentService.getFileAttachment(fileID);
try {
response.setHeader("Content- Disposition", "inline;filename=\""
+ doc.getFileName() + "\"");
OutputStream out = response.getOutputStream();
response.setContentType(doc.getFileType());
FileCopyUtils.copy(doc.getFileContent(), response.getOutputStream());
out.flush();
out.close();
} catch (IOException e) {
e.printStackTrace();
Here is the line that configures the button in the jsp
<button name="FileDownloadd" type="button" value="Download" onClick="location.href=FileDownload.html?FileID=${fileattach.FileID}'">Download</button> </td>
Marc's comment above was the answer. Since it was a comment, and I want to close this. I will post it in quotes.
you're telling the browser to display it inline. That means if the browser >knows how to render the file's contents, it will. text/pdf/xml can be rendered >directly by a browser (or at least via a plugin). If you want to force a >download, then use attachment as your disposition, and/or force a mime-type >like application/octet-stream, which the browser WON'T try to render.
I am working with .pdf files that are available on my companies' website only. I am not aware of any way to download them and store in one folder.
The link that I click to get the .pdf file has the following source code:
<a href="javascript:propertiesView('documentName')">
As I click on the link, a .pdf file pops up in a new browser window with no url and no source code. I presume that there is no way to manipulate that .pdf directly, then how can I save it then in order to manipulate the .pdfs from a folder?
Thank You
You may have luck by simply telling your browser to always save PDF files to disk (credits to Dirk):
firefoxProfile.setPreference("browser.helperApps.neverAsk.saveToDisk", "application/pdf");
If that doesn't work, you are probably able to iterate through all open windows/tabs by using the switchTo() methods. Try something like this to get some insight about your opened windows (credits to Prashant Shukla):
public void getWindows() {
Set<String> windows = driver.getWindowHandles();
for (String window : windows) {
driver.switchTo().window(window);
System.out.println(driver.getTitle());
}
}
A non-selenium solution to download the file would be to use the apache-commons library (creadits to Shengyuan Lu):
org.apache.commons.io.FileUtils.copyURLToFile(URL, File)
But this would require that you know the URL of the window, which you probably are able to fetch with the second approach i mentioned (driver.switchTo()) and driver.getCurrentUrl().
I presume that there is no way to manipulate that .pdf directly
That's correct. With Selenium, you cannot.
how can I save it then in order to manipulate the .pdfs from a folder?
I've actually implemented this exact thing in our regression system where I work.
My first step, was to construct a Url based on what the propertiesView(). method did.
in your case, propertiesView() does some sort of window.open is my guess. So your goal is, to extract that Url that it opens, and use concatenation to construct the url.
Once you've found your Url, the rest is a cakewalk. Just download the url to a folder named /pdfs. See this question for how to do that.
It may even require calling that method to figure it out.. Due to my ignorance of your System Under Test, it's difficult for me to give you a code answer, unless you posted it.
A hint that i'll tell you, is if you are using Selenium 1, use
String url =selenium.getEval("var url = something; url;");
to fetch the url and get it into a java object.
(If using selenium 2, use the JavaScriptExecutor#executeScript)
If you want to save a PDF to your hard drive in IE with selenium, you need to use pywinauto with selenium. I just used this code for PDF files that open up in the browser.
//selenium imports
from pywinauto import application //pywinauto import
//write selenium code to open up pdf in the browser
driver = webdriver.Ie("IEDriverServer.exe", capabilities = caps)
//this could be a get or driver.execute_script() to click a link
driver.get("link to pdf")
//save pdf
app = application.Application()
//get the ie window by the title of the application (assuming only one window is open here)
ie = app.window_(title_re = ".*Internet Explorer.*")
//this line focuses on the pdf that is open in the browser
static = ie.Static
//focus on the pdf so we can access the internal controls
static.SetFocus()
//control + h shows the pdf bar, but you don't really need this step
//for it to work. i just used it as a debug
static.TypeKeys("^H")
//open save file dialog
static.TypeKeys("+^S")
//tricky here because the save file dialog opens up as another app instance
//which is how pywinauto sees it
app2 = application.Application()
//bind to the window by title - name of the dialog
save = app2.window_(title_re = ".*Save As.*")
//this is the name of the property where you type in the filename
//way to be undescriptive microsoft
file_name = save[u'FloatNotifySink']
//type in the file name
save.TypeKeys("hello")
//pause for a second - you don't have to do this
time.sleep(4)
//find and bind the save button
button = save[u'&SaveButton']
//click the save button
button.Click()
This question already has answers here:
How to save generated file temporarily in servlet based web application
(2 answers)
Simplest way to serve static data from outside the application server in a Java web application
(10 answers)
Closed 5 years ago.
I am using Eclipse dynamic web project with tomcat 7. I am extremely new at this and slowly working through tutorials.
I am trying to make a simple webapp where a user enters information which is used to generate a QR code. I can make the image and save it to the WebContent folder. I want to show this image to the user and store it. Eventually I will have an account for each user with their stored QR codes and other images. I have an index.html that takes the information through a form and passes it to a servlet that creates the image and saves it in my WebContent folder, then builds a simple HTML to show the image. However, the image is not shown unless I tell eclipse to refresh the project. My guess is that eclipse doesn't know about the new image file until it gets refreshed, and for some reason the HTML generated by the servlet isn't picking up on the image even though it's in the right place.
The answer here suggests storing the data outside the webapp folders and streaming it. This is something I am unfamiliar with. I have tried to store the image in an outside folder and refer to it using both absolute and relative paths from the WebContent folder to the image file, neither works. And the QR code I was able to show from inside the WebContent folder doesn't update when I give it different data to build the image from, I have to refresh the project in eclipse even though the file name and location is the same. When I use the file browser to open the image file it has the new data.
I am asking for very basic help, I'm not incompetent but I've never done internet programming before and this is a lot to learn. In general I need to know how to get and store data and generate new data and then call it back up dynamically to display to the user. Thank you.
Here is my doPost method for the servlet:
public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException{
username = request.getParameter("userName");
password = request.getParameter("password");
PrintWriter out = response.getWriter();
response.setContentType("text/html");
// check the input and create the html
checkFormData();
// Unless something goes very wrong, this string should be replaced.
String html = "<html><p>SOMETHING BROKE!</p></html>";
if(usernameOK && passwordOK){
html = buildHTMLForGoodInfo();
}else{
html = buildHTMLForBadInfo();
}
out.println(html);
}
And here is where I generate the QR code and create the HTML to display it:
private String buildHTMLForGoodInfo(){
QRGenerator qrg = new QRGenerator();
// This file goes into the webcontent folder
File filename1 = new File("/home/NAME/Workspace/MyWebApp/WebContent/qr1.png");
// This file goes outside the webcontent folder
File filename2 = new File("/home/NAME/Workspace/Data/qr2.png");
String result = "User Name = " + username + " Password = " + password +".";
qrg.makeQR(result, filename1);
qrg.makeQR(result, filename2);
String html = "<html><head><title>Results Page</title></head>\n" +
"<body><center>\n" +
"<p>Your user name is " + username + ".<p>\n" +
"<br/>\n" +
"<p>Your password is " + password + ".<p>\n" +
"<br/>\n" +
"<p> Have a QR Code</p>\n" +
"<br/>\n" +
// Show the image from inside the webcontent folder
"<img src=\"qr1.png\" alt=\"qr1.png\" border=\"1\">\n" +
// show the image from outside the webcontent folder
"<img src=\"/home/NAME/Workspace/Data/qr2.png\" alt=\"qr2.png\" border=\"1\">\n" +
"</center></body></html>";
return html;
}
NOTE: I have obfuscated my linux username to provide me with a tiny sense of false security.
Here is a screenshot of the output:
The QR code on the left decodes to old data, it should show the new data, username = UserName, password = Password. The image on the right does not appear. When I use the file manager to navigate to both file's locations on my computer, both files have QR codes with the correct data. I don't know where the old incorrect QR code is being stored, it doesn't show up in the file manager and I have checked for hidden files.
EDIT:
I have solved my issue by using an image servlet, unfortunately I can't find the stackoverflow page that led me in that path. I made a simple servlet with this doGet method:
#Override
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException{
// In the event of an error, make a red square.
int[] pixels = new int[128*128*3];
for(int i = 0; i < 128*128; i++){
pixels[i] = 200 << 16 | 0 << 8 | 0;
}
BufferedImage image = new BufferedImage(128,128,BufferedImage.TYPE_INT_RGB);
image.setRGB(0,0,128,128, pixels,0,128);
// get the file's address from the request
File imageID = new File(request.getParameter("imageID"));
// Try to read the file into the image, if you can't read it, print an error
try{
image = ImageIO.read(imageID);
}catch(Exception e){
System.out.println("IMAGE IO ERROR");
e.printStackTrace();
}
System.out.println(imageID.toString());
// get the response output stream and pass the image to it
ServletOutputStream out = response.getOutputStream();
ImageIO.write(image, "png", out);
}
Then when I want to display an image, I use this html:
img src=\"ImageServlet?imageID= PUT YOUR IMAGE ADDRESS HERE "
SUMMARY
I need to store both uploaded and server-generated images, with portable and
predictable paths so my server code is aware of where these images exist.
I need to generate URLs to these images that can be sent to the client. These URLs will be used in HTML image elements.
PROBLEM
My web application allows the user to upload an image, using gwtupload(Apache Commons). This image is stored on the server and a URL returned to the client so the image is shown. gwtupload provides a clientside method to get this URL for the uploaded image. This works in deployment; the following aspects do not:
In certain cases, the uploaded image must be cropped. This results in
a new image being generated by a servlet method. I want to store this
cropped image and return(to the client) an access URL.
Then, this image is used by another method to generate another
image. This method must know the location on the file system of
the previously uploaded(and/or cropped) image. A URL for the new
image must then be returned to client.
I have implementation working perfectly in GWT development mode. However, as I expected, after deployment to my own Tomcat server, the remote services fail due to my confusion regarding the file system. I do not know the correct way of storing these images in a predictable place on the server filesystem, nor do I know how to generate access URLs(for files residing outwith the WAR, as these images will.)
All these images are only needed for the current session, so the locations can be temporary directories. I have spent two days experimenting and trawling the web for a solution to no avail.
I will post abridged code below. This is my attempt to simply use the working directory and relative pathnames. Using the Eclipse debugger attached to my servlet container, I could see the results of String dataDir = context.getRealPath("foo") indicating a temp folder within the servlet: but when I navigated there using explorer, NONE of the files had been written to the disk. I am very confused.
public String[] generatePreview(String xml) {
PreviewManager manager = new PreviewManager();
String url;
try{
preview = manager.generatePreview(xml);
}
catch (Exception e){e.printStackTrace();}
//Create the preview directory
File folder = new File("previews");
if (!folder.exists()) folder.mkdir();
//The file to be written to
File output = new File(folder, "front.jpg");
ServletContext context = getServletContext();
String dataDir = context.getRealPath("previews");
try {
ImageIO.write(image, "jpg", output);
} catch (IOException e) {
e.printStackTrace();
}
url = "previews/" + output.getName();
return url;
}
#Override
public String cropBackground(int[] coord_pair, String relativePath) {
File backgroundsFolder = new File("backgrounds");
if (!backgroundsFolder.exists()) backgroundsFolder.mkdir();
ServletContext context = getServletContext();
String dataDir = context.getRealPath("backgrounds");
File current = new File(relativePath);
String croppedName = "cropped_" + relativePath.replace("./backgrounds/", "");
int x = coord_pair[0];
int y = coord_pair[1];
int width = coord_pair[2];
int height = coord_pair[3];
String croppedPath = null;
try {
croppedPath = imageCropper.createCroppedImage(current, "backgrounds", croppedName, x, y, width, height);
}
catch (IOException e){
e.printStackTrace();
}
current.delete();
return "backgrounds/" + croppedPath;
I am aware that my current 'return' statements would never work in deployment: I need to generate the URLs properly and return as strings. I'm sorry about the question length but I wanted to make my problem clear.
Choose a directory where your images will be stored, outside of Tomcat. Assign some unique ID to each uploaded or generated image, and store the images in this directory (with the ID as file name, for example).
Generate URLs to an image servlet that will read the image by ID in this directory, and send the bytes of the image to the output stream of the servlet response : image.action?id=theImageId.