Skip to content

Commit d9b2ef7

Browse files
committed
Added biography api
1 parent 5a0a96e commit d9b2ef7

File tree

3 files changed

+463
-0
lines changed

3 files changed

+463
-0
lines changed
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
package com.mygcc.api;
2+
3+
import com.mygcc.datacollection.Biography;
4+
import com.mygcc.datacollection.ExpiredSessionException;
5+
import com.mygcc.datacollection.InvalidCredentialsException;
6+
import com.mygcc.datacollection.NetworkException;
7+
import com.mygcc.datacollection.Token;
8+
import com.mygcc.datacollection.UnexpectedResponseException;
9+
10+
import javax.ws.rs.GET;
11+
import javax.ws.rs.HeaderParam;
12+
import javax.ws.rs.Path;
13+
import javax.ws.rs.Produces;
14+
import javax.ws.rs.core.MediaType;
15+
import javax.ws.rs.core.Response;
16+
import java.util.Map;
17+
18+
/**
19+
* Get data about client.
20+
*/
21+
@Path("/1/user")
22+
public class BiographyResource extends MyGCCResource {
23+
/**
24+
* Get all data about client.
25+
* @param token Authorization token
26+
* @return Response to client
27+
*/
28+
@Path("/")
29+
@GET
30+
@Produces(MediaType.APPLICATION_JSON)
31+
public final Response getAllData(
32+
@HeaderParam("Authorization") final String token) {
33+
Token auth;
34+
35+
// Try to decrypt token sent by client
36+
try {
37+
auth = new Token(token);
38+
} catch (InvalidCredentialsException e) {
39+
return invalidCredentialsException();
40+
}
41+
42+
Biography bio = new Biography(auth);
43+
try {
44+
Map<String, String> data = bio.getData();
45+
return Response.status(Response.Status.OK)
46+
.entity(data)
47+
.type("application/json")
48+
.build();
49+
} catch (ExpiredSessionException e) {
50+
return sessionExpiredMessage();
51+
} catch (InvalidCredentialsException e) {
52+
return invalidCredentialsException();
53+
} catch (NetworkException e) {
54+
return networkException();
55+
} catch (UnexpectedResponseException e) {
56+
return unexpectedResponseException();
57+
}
58+
}
59+
}
Lines changed: 238 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,238 @@
1+
package com.mygcc.datacollection;
2+
3+
import org.jsoup.Jsoup;
4+
import org.jsoup.nodes.Document;
5+
import org.jsoup.select.Elements;
6+
7+
import java.io.IOException;
8+
import java.net.HttpURLConnection;
9+
import java.util.HashMap;
10+
import java.util.LinkedHashMap;
11+
import java.util.Map;
12+
13+
/**
14+
* Chapel class.
15+
*
16+
* The Chapel class is used to get Chapel data from myGCC.
17+
*/
18+
public class Biography extends MyGCCDataCollection {
19+
/**
20+
* myGCC chapel URL.
21+
*/
22+
private static final String URL = "https://my.gcc.edu/ICS/";
23+
24+
/**
25+
* Enumeration of Biography Info page HTML selectors for relevant data.
26+
*/
27+
private enum BiographyID {
28+
/**
29+
* Degree.
30+
*/
31+
DEGREE("#CP_V_rptEducation_ctl00_lblDegreeDesc"),
32+
33+
/**
34+
* Major.
35+
*/
36+
MAJOR("#CP_V_rptEducation_ctl00_lblMajorDesc"),
37+
38+
/**
39+
* Name.
40+
*/
41+
NAME("#CP_V_lblUserName"),
42+
43+
/**
44+
* Email.
45+
*/
46+
EMAIL("#CP_V_divOtherAddresses table tbody tr:eq(0) td:eq(1)"),
47+
48+
/**
49+
* Birth date.
50+
*/
51+
BIRTHDATE("#CP_V_txtBirthdate"),
52+
53+
/**
54+
* Marital status.
55+
*/
56+
MARITALSTAT("#CP_V_txtMaritalStatus"),
57+
58+
/**
59+
* Gender.
60+
*/
61+
GENDER("#CP_V_txtGender"),
62+
63+
/**
64+
* Ethnicity.
65+
*/
66+
ETHNICITY("#CP_V_txtEthnicity"),
67+
68+
/**
69+
* ID number.
70+
*/
71+
IDNUMBER("#CP_V_txtIDNumber");
72+
73+
/**
74+
* Identifier.
75+
*/
76+
private String id;
77+
78+
/**
79+
* Set identifier.
80+
* @param ident identifier
81+
*/
82+
BiographyID(final String ident) {
83+
this.id = ident;
84+
}
85+
86+
/**
87+
* Get identifier.
88+
* @return identifier
89+
*/
90+
public String id() {
91+
return id;
92+
}
93+
}
94+
95+
/**
96+
* myGCC credentials authorization object.
97+
*/
98+
private Session auth;
99+
100+
/**
101+
* Chapel constructor.
102+
* @param token myGCC login credentials
103+
*/
104+
public Biography(final Token token) {
105+
this.auth = new Session(token);
106+
}
107+
108+
/**
109+
* Get client personal information from myGCC.
110+
* @return Map with chapel data
111+
* @throws ExpiredSessionException myGCC session expired
112+
* @throws UnexpectedResponseException unexpected response from myGCC
113+
* @throws NetworkException bad connection to myGCC
114+
* @throws InvalidCredentialsException invalid myGCC credentials
115+
*/
116+
public final Map<String, String> getData() throws
117+
ExpiredSessionException, UnexpectedResponseException,
118+
NetworkException, InvalidCredentialsException {
119+
// Create session
120+
auth.createSession();
121+
122+
try {
123+
// Make first request to open the personal info site.
124+
LinkedHashMap<String, String> postValues = new
125+
LinkedHashMap<String, String>() { {
126+
put("_scriptManager_HiddenField", "");
127+
put("__EVENTTARGET", "welcomeBackBar");
128+
put("__EVENTARGUMENT", "accountInfo");
129+
put("__VIEWSTATE", auth.getViewstate());
130+
put("__VIEWSTATEGENERATOR", "38ABEAAB");
131+
put("___BrowserRefresh", auth.getBrowserRefresh());
132+
put("ctl04$tbSearch", "Search...");
133+
put("CP$V$PreferredName", "");
134+
put("CP$V$HideMiddleName", "on");
135+
put("CP$V$Prefix", "");
136+
put("CP$V$Suffix", "");
137+
} };
138+
139+
String postData = postData(postValues, auth.getBoundary());
140+
141+
HttpURLConnection http = createPOST(URL,
142+
new HashMap<String, String>() { {
143+
put("Content-Type",
144+
"multipart/form-data; boundary="
145+
+ auth.getBoundary());
146+
put("Cookie",
147+
"ASP.NET_SessionId=" + auth.getSessionID()
148+
+ "; .ASPXAUTH=" + auth.getASPXAuth());
149+
put("Accept", "text/html,application/xhtml+xml,"
150+
+ "application/xml;q=0.9,*/*;q=0.8");
151+
} }, postData);
152+
153+
String html = convertStreamToString(http.getInputStream());
154+
auth.setBrowserRefresh(parseBrowserRefresh(html));
155+
auth.setViewstate(parseViewState(html));
156+
157+
// Make second request to open the biography info tab.
158+
LinkedHashMap<String, String> postValues2 = new
159+
LinkedHashMap<String, String>() { {
160+
put("_scriptManager_HiddenField", "");
161+
put("__EVENTTARGET", "CP$t6");
162+
put("__EVENTARGUMENT", "Biography View");
163+
put("__VIEWSTATE", auth.getViewstate());
164+
put("__VIEWSTATEGENERATOR", "38ABEAAB");
165+
put("___BrowserRefresh", auth.getBrowserRefresh());
166+
put("ctl04$tbSearch", "Search...");
167+
put("CP$V$PreferredName", "");
168+
put("CP$V$HideMiddleName", "on");
169+
put("CP$V$Prefix", "");
170+
put("CP$V$Suffix", "");
171+
} };
172+
173+
String postData2 = postData(postValues2, auth.getBoundary());
174+
175+
HttpURLConnection http2 = createPOST(URL,
176+
new HashMap<String, String>() { {
177+
put("Content-Type",
178+
"multipart/form-data; boundary="
179+
+ auth.getBoundary());
180+
put("Cookie",
181+
"ASP.NET_SessionId=" + auth.getSessionID()
182+
+ "; .ASPXAUTH=" + auth.getASPXAuth());
183+
put("Accept", "text/html,application/xhtml+xml,"
184+
+ "application/xml;q=0.9,*/*;q=0.8");
185+
} }, postData2);
186+
187+
String bioHTML = convertStreamToString(http2.getInputStream());
188+
189+
return getUserDataFromHTML(bioHTML);
190+
} catch (IOException e) {
191+
e.printStackTrace();
192+
throw new UnexpectedResponseException("unknown IOException "
193+
+ "occurred");
194+
}
195+
}
196+
197+
/**
198+
* Parse HTML and get user data.
199+
* @param html data
200+
* @return Map of data
201+
* @throws UnexpectedResponseException unexpected response from myGCC
202+
*/
203+
private Map<String, String> getUserDataFromHTML(final String html) throws
204+
UnexpectedResponseException {
205+
Document doc = Jsoup.parse(html);
206+
return new HashMap<String, String>() { {
207+
put("name", getDataFromHTML(doc, BiographyID.NAME.id()));
208+
put("major", getDataFromHTML(doc, BiographyID.MAJOR.id()));
209+
put("degree", getDataFromHTML(doc, BiographyID.DEGREE.id()));
210+
put("email", getDataFromHTML(doc, BiographyID.EMAIL.id()));
211+
put("birth", getDataFromHTML(doc, BiographyID.BIRTHDATE.id()));
212+
put("marital", getDataFromHTML(doc, BiographyID.MARITALSTAT.id()));
213+
put("gender", getDataFromHTML(doc, BiographyID.GENDER.id()));
214+
put("ethnicity", getDataFromHTML(doc, BiographyID.ETHNICITY.id()));
215+
put("ID", getDataFromHTML(doc, BiographyID.IDNUMBER.id()));
216+
} };
217+
}
218+
219+
/**
220+
* Get selector value from HTML.
221+
* @param html document to parse
222+
* @param selector HTML selector
223+
* @return selected value
224+
*/
225+
private String getDataFromHTML(final Document html, final String selector) {
226+
Elements name = html.select(selector);
227+
return trim(name.text());
228+
}
229+
230+
/**
231+
* Trim space characters and non-breaking spaces.
232+
* @param value string to trim
233+
* @return trimmed string
234+
*/
235+
private String trim(final String value) {
236+
return value.trim().replaceAll("(^\\h*)|(\\h*$)", "");
237+
}
238+
}

0 commit comments

Comments
 (0)