C# Download an image from URL - c#

I use a website to get stats on wifi usage. The website creates an image of a graph representation of the data. The way it does this is by the user, setting a date. So for example, lets say it was last months statistics. The website generates a URL which is then sent to the server and the server returns an image. an examples of the link is like this:
https://www.example.com/graph/daily_usage?time_from=2015-06-01+00%3A00%3A00+%2B0100&time_to=2015-06-30+23%3A59%3A59+%2B0100&tsp=1436519988
The problem is, I am making a third party program that will download this image to be used in my program. However, I cannot use the file. It is as if the file is corrupt or something. I have tried a few methods but maybe someone can suggest a different approach. Basically, how do I download an image that is generated by a server from a URL link?
P.S.
Just noticed that if I download the file by right clicking through a browser and save, the image downloads with a size of 17.something kilobytes. But if I use the WebClient method to download the image, it only downloads 1.5kb. Why would that be? Seems like the WebClient method does not download completely.
Currently my code
if (hrefAtt == "Usage Graph")
{
string url = element.getAttribute("src");
WebClient client = new WebClient();
client.DownloadFile(url, tempFolderPath + "\\" + currentAcc + "_UsageSummary.png");
wd.AddImagesToDoc(tempFolderPath + "\\" + currentAcc + "_UsageSummary.png");
wd.SaveDocument();
}
TempFolderPath is my desktop\TempFolder\
UPDATE
Out of random, I decided to see the raw data of the file with notepad and interestingly, the image data was actually a copy of the websites homepage html code, not the raw data of the image :S how does that make sense?

This will download the Google logo:
var img = Bitmap.FromStream(new MemoryStream(new WebClient().DownloadData("https://www.google.co.uk/images/srpr/logo11w.png")));

First of all, you have to understand link texture. If all links are same or close to each other, you have to use substring/remove/datetime etc. methods to make your new request link. For example;
string today = DateTime.Now.ToShortDateString();
string generatedLink = #"http://www.yoururl.com/image + " + today + ".jpg";
string generatedFileName = #"C:\Usage\usage + " + today + ".jpg";
WebClient wClient = new WebClient();
wClient.DownloadFile(generatedLink, generatedFileName);

Related

C# - Checking several IP adresses with several download methods

I am new to this site so I apologise in advance if I made any formatting errors. Let me know if further clarification is needed.
I am currently working on a program in C# which aims at downloading files from several http or ftp sources.
I want it to go through several IP addresses and then check if several methods could download a known file successful. If one of these methods could download the file successfully it should go to the next IP and do the same thing again.
So far I am using a foreach loop that runs through an array containing the IP and creating a folder named "IPxx" and a FTP and HTTP URI because I do not know in advance which IP needs a FTP or HTTP address:
string[] ipArray = new string[4];
ipArray[0]= "xxx.xxx.xxx.xx";
ipArray[1]= "xxx.xxx.xxx.xx";
ipArray[2]= "xxx.xxx.xxx.xx";
ipArray[3]= "xxx.xxx.xxx.xx";
foreach(string ip in ipArray )
{
string ipXx = "IP" + ip.Substring(ip.Length-2);
string ipOrdner = folder + #"\" + ipXx;
Directory.CreateDirectory(ipOrdner);
string ftpAddr= "ftp://" + ip;
string httpAddr= "http://"+ip;
//DownloadTestMethod(httpAddr, ipFolder);
//DownloadTestMethod2(ftpAddr, ipFolder);
//DownloadTestMethod3(htppAddr, ipFolder);
}
So far so good, everything up to this level is working as expected.
However I struggle as soon as I need to go through several Download Methods and check if I can download the file successfully and if not it should go to the next DownloadMethod and try the same.
I came up with following DownloadTestMethod:
public static void DownloadTestMethod(string httpAddr, string ipFolder)
{
string fileName = "test_10k.bin";
string downloadpath = httpAddr + "/" + fileName;
// I want it to check if the http site is online/working
WebRequest request = WebRequest.Create(downloadpath);
request.Proxy.Credentials = CredentialCache.DefaultCredentials;
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
if (response != null)
{
WebClient webClient = new WebClient();
webClient.Proxy.Credentials=CredentialCache.DefaultCredentials;
webClient.DownloadFile(downloadpath, ipFolder + #"\" + fileName);
}
}
It is working for a successfully downloaded file, however I seem to get "stuck" in this method if the method cannot downloaded the requested file.
In this case I want it to jump to the next DownloadMethod and check again until all methods are checked.
Furthermore, if the program went through every IP and it could not download anytrhing, I want it to send an automated email. I know how to implement the EmailMethod but once again I struggle with flow control.
I am an absolute beginner and have no idea how to go from here to get my desired flow.
You might want to look at Task Parallel Library and in particular, its WhenAll() method.
Under it, you might want to look at error handling for the case that any of your methods return error / raise exception.
https://msdn.microsoft.com/en-us/library/dd270695(v=vs.110).aspx

How to download On demand Confluence page content image to local machine?

I am new user for on demand confluence, i am able to read the page content using REST API
https://{companyName}.atlassian.net/wiki/rest/prototype/1/content/524312?expand=attachments
I am find the image source link in this content like below
https://{companyName}.atlassian.net/wiki/download/attachments/524312/worddave1f7873c424d7824e580764369e7ee68.png
I am trying to download the images in the page content to local directory using the below c# coding
image=https://{companyName}.atlassian.net/wiki/download/attachments/524312/worddave1f7873c424d7824e580764369e7ee68.png;
imageLocation =#"C:\Images";
string[] FileName = image.Split(new char[] { '/' }, StringSplitOptions.RemoveEmptyEntries);
WebClient client = new WebClient();
client.Credentials = new NetworkCredential("xxx", "yyy");
client.DownloadFile(new Uri(image), imageLocation + "\\" + FileName[FileName.Count() - 1]);
I am not able to download the any images from on demand confluence page.
I also tried the below things
1. I have manually export the particular page by "Export to HTML" from page operations in on demand confluence
2. I have checked that export HTML zip file, an attachment directory have the images in the particular page
I need to achieve my goal like above, please share your knowledge
I have changed my code like below, than i have downloaded the on demand confluence page content images to my local machine
image=https://{companyName}.atlassian.net/wiki/download/attachments/524312/worddave1f7873c424d7824e580764369e7ee68.png;
imageLocation =#"C:\Images";
string[] FileName = image.Split(new char[] { '/' }, StringSplitOptions.RemoveEmptyEntries);
WebClient client = new WebClient();
client.DownloadFile(new Uri(image+"?&os_username=xxx&os_password=yyy"), imageLocation + "\\" + FileName[FileName.Count() - 1]);

C# Downloading a range of files

I know a few similar questions have been asked on how to download files using WebClient. I can download individual files perfectly fine, but I want to download a range of files. Anywhere from 1-6000 files. I can download them just fine into my current directory, but I am stumped on how to download them to a different directory based upon where they're being downloaded from. Do I need to temporarily change the current working directory just before downloading them?
And slightly on the same topic, I'm stuck on how to verify the files exist before downloading them. I don't want to waste bandwidth or diskspace with empty files.. Here's what I have so far:
for (int x = 1; x <= 6000; x++)
{
pbsscount = x.ToString();
// Used for downloading file
string directoryName = textBox1.Text.ToString().Replace(":", "_");
if (!Directory.Exists(textBox1.Text))
Directory.CreateDirectory(directoryName.Substring(7));
string wholePBSSurl = textBox1.Text + "/" + "pb" + pbsscount.PadLeft(6, '0') + ".png";
// Used for saving file, file name in directory
string partPBSSurl = "pb" + pbsscount.PadLeft(6, '0') + ".png";
Uri uri2 = new Uri(wholePBSSurl);
//if (fileExists(wholePBSSurl))
//{
// Initialize downloading info, grab progressbar info
WebClient webClient = new WebClient();
webClient.DownloadFileCompleted += new AsyncCompletedEventHandler(Completed);
webClient.DownloadProgressChanged += new DownloadProgressChangedEventHandler(ProgressChanged);
// Save file to folder
//webClient.DownloadFileAsync(uri2, textBox1.Text + "/" + partPBSSurl);
webClient.DownloadFileAsync(uri2, partPBSSurl);
//}
}
Do I need to temporarily change the current working directory just before downloading them?
The second parameter can be a full path #"C:\folder\file.png". If you're fine with relative path to your current directory, just change the code to webClient.DownloadFileAsync(uri2, directoryName + partPBSSurl); or even better use System.Path.Combine(directoryName, partPBSSurl)
Sure you can know the size before If sever supports that. See: How to get the file size from http headers
I don't want to waste bandwidth or diskspace with empty files.
I wouldn't worry about that. The performance slow down is negligible.
There is no need to change the current directory. You are already using an overload of DownloadFileAsync that accepts a file path as the second parameter.
Just ensure that partPBSSurl contains a full path to the destination file, including both the directory and filename.
With regard to your second question of avoiding wasted time if the file does not exist, it so happens that I asked the same question recently:
Fail Fast with WebClient
Finally, I recently extended WebClient to provide simpler progress change events and allow for the timeout to be changed. I posed that code here:
https://stackoverflow.com/a/9763976/141172

Trouble saving a downloaded file to the desktop in WPF C#

When I use:
WebClient web = new WebClient();
web.DownloadProgressChanged += new DownloadProgressChangedEventHandler(ProgressChangedWeb);
web.DownloadFileAsync(new Uri("http://www.website.com/Webs.exe"),
Environment.SpecialFolder.Desktop + #"\Webs.exe");
...Nothing downloads.
But if i change it to"
WebClient web = new WebClient();
web.DownloadProgressChanged += new DownloadProgressChangedEventHandler(ProgressChangedWeb);
web.DownloadFileAsync(new Uri("http://www.website.com/Webs.exe"),
Environment.SpecialFolder.Desktop + "Webs.exe");
Then It downloads, but I get a file named "desktopWebs.exe". So How can I save a file to the desktop?
Thanks
What you want is this...
Environment.GetFolderPath(Environment.SpecialFolder.Desktop) + #"\Webs.exe";
Otherwise you are just tacking on the word desktop instead of the actual path.
You can use Path.Combine
web.DownloadFileAsync(new Uri("http://www.website.com/Webs.exe"),
Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory), "Webs.exe"));
This function will automatically insert (or remove) slashes as well as adapt to any file system being used
You should also consider using Environment.SpecialFolder.DesktopDirectory, this points to the actual physical location of the desktop folder on the disk.

Saving images on the server

I'm getting the "generic error occurred on GDI++ wen trying to save images.
What I am missing here?
string appdatapath = AppDomain.CurrentDomain.GetData("DataDirectory").ToString();
if (!Directory.Exists(appdatapath + "/Images")
Directory.CreateDirectory(appdatapath + "/Images", Directory.GetAccessControl(appdatapath));
if (!Directory.Exists(appdatapath + "/Images/XBLContent/"))
Directory.CreateDirectory(appdatapath + "/Images/XBLContent/", Directory.GetAccessControl(appdatapath));
string imagesdir = Path.Combine(appdatapath, "/Images/XBLContent/");
Image image = FeedUtils.RequestImage(String.Format({0}/{1}/image.jpg", url, c.GUID));
image.Save(imagesdir + c.GUID + "sm.jpg");
Check whether your IIS worker process has write permissions to the local file system, and in particular the folder whether you are saving the image.
Also, use Server.MapPath() to get the physical location.
See this blog for a solution.

Categories