forked from emilytsaimeow/Lab2-InterestingPicture
-
Notifications
You must be signed in to change notification settings - Fork 0
/
InterestingPictureModel.java
151 lines (137 loc) · 5.71 KB
/
InterestingPictureModel.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
package ds;
/*
* @author Joe Mertz
*
* This file is the Model component of the MVC, and it models the business
* logic for the web application. In this case, the business logic involves
* making a request to flickr.com and then screen scraping the HTML that is
* returned in order to fabricate an image URL.
*/
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.util.logging.Level;
import java.util.logging.Logger;
public class InterestingPictureModel {
/**
* Arguments.
*
* @param searchTag The tag of the photo to be searched for.
* @param picSize The string "mobile" or "desktop" indicating the size of
* photo requested.
*/
public String doFlickrSearch(String searchTag, String picSize)
throws UnsupportedEncodingException {
/*
* URL encode the searchTag, e.g. to encode spaces as %20
*
* There is no reason that UTF-8 would be unsupported. It is the
* standard encoding today. So if it is not supported, we have
* big problems, so don't catch the exception.
*/
searchTag = URLEncoder.encode(searchTag, "UTF-8");
String response = "";
// Create a URL for the page to be screen scraped
String flickrURL =
"https://www.flickr.com/search/?text="
+ searchTag
+"&license=2%2C3%2C4%2C5%2C6%2C9";
// Fetch the page
response = fetch(flickrURL);
//System.out.println(response);
/*
* Search the page to find the picture URL
*
* Screen scraping is an art that requires creatively looking at the
* HTML that is returned and figuring out how to cut out the data that
* is important to you.
*
* These particular searches were crafted by carefully looking at
* the HTML that Flickr returned, and finding (by experimentation) the
* generalizable steps that will reliably get a picture URL.
*
* First do a String search that gets me close to the picture URL target
*/
int cutLeft = response.indexOf("background-image: url(");
// If not found, then no such photo is available.
if (cutLeft == -1) {
System.out.println("pictureURL= null");
return (String) null;
}
// Skip past this string.
cutLeft += "background-image: url(".length();
// The next character would be the // which in a URL separates the
// protocol from the server (i.e. https://foo.com)
// Look for the close parenthesis
int cutRight = response.indexOf(")", cutLeft);
// Now snip out the part from positions cutLeft to cutRight
// and prepend the protocol (i.e. https).
String pictureURL = "https:"+response.substring(cutLeft, cutRight);
pictureURL = interestingPictureSize(pictureURL, picSize);
System.out.println("pictureURL= " + pictureURL);
return pictureURL;
}
/*
* Return a URL of an image of appropriate size
*
* Arguments
* @param picSize The string "mobile" or "desktop" indicating the size of
* photo requested.
* @return The URL an image of appropriate size.
*/
private String interestingPictureSize(String pictureURL, String picSize) {
int finalDot = pictureURL.lastIndexOf(".");
/*
* From the flickr online documentation, an underscore and a letter
* before the final "." and file extension is a size indicator.
* "_m" for small and "-z" for big.
*/
String sizeLetter = (picSize.equals("mobile")) ? "m" : "z";
if (pictureURL.indexOf("_", finalDot-2) == -1) {
// If the URL currently did not have a _? size indicator, add it.
return (pictureURL.substring(0, finalDot) + "_" + sizeLetter
+ pictureURL.substring(finalDot));
} else {
// Else just change it
return (pictureURL.substring(0, finalDot - 1) + sizeLetter
+ pictureURL.substring(finalDot));
}
}
/*
* Make an HTTP request to a given URL
*
* @param urlString The URL of the request
* @return A string of the response from the HTTP GET. This is identical
* to what would be returned from using curl on the command line.
*/
private String fetch(String urlString) {
String response = "";
try {
URL url = new URL(urlString);
/*
* Create an HttpURLConnection. This is useful for setting headers
* and for getting the path of the resource that is returned (which
* may be different than the URL above if redirected).
* HttpsURLConnection (with an "s") can be used if required by the site.
*/
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
// Read all the text returned by the server
BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream(), "UTF-8"));
String str;
// Read each line of "in" until done, adding each to "response"
while ((str = in.readLine()) != null) {
// str is one line of text readLine() strips newline characters
response += str;
}
in.close();
} catch (IOException e) {
System.out.println("Eeek, an exception");
// Do something reasonable. This is left for students to do.
}
return response;
}
}