@Override public void onPageFinished(WebView view, String url) { super.onPageFinished(view, url); String authCookie = ""; String cookies; switch (service) { case 'p': if (url.contains("pna.utexas.edu")) { cookies = CookieManager.getInstance().getCookie("https://pna.utexas.edu"); if (cookies != null && cookies.contains("AUTHCOOKIE=")) { for (String s : cookies.split("; ")) { if (s.startsWith("AUTHCOOKIE=")) { authCookie = s.substring(11); break; } } } if (!authCookie.equals("")) { AuthCookie pnaAuthCookie = UTilitiesApplication.getInstance().getAuthCookie(PNA_AUTH_COOKIE_KEY); pnaAuthCookie.setAuthCookieVal(authCookie); continueToActivity("UT PNA"); return; } } break; case 'u': if (url.contains("utexas.edu")) { cookies = CookieManager.getInstance().getCookie("https://login.utexas.edu"); if (cookies != null) { for (String s : cookies.split("; ")) { if (s.startsWith("utlogin-prod=")) { authCookie = s.substring(13); break; } } } if (!authCookie.equals("") && url.equals("https://www.utexas.edu/")) { AuthCookie utdAuthCookie = UTilitiesApplication.getInstance().getAuthCookie(UTD_AUTH_COOKIE_KEY); utdAuthCookie.setAuthCookieVal(authCookie); continueToActivity("UTLogin"); return; } } break; } }
public void updateView(String restId, Boolean update) { this.restId = restId; if (!restId.equals("0") && (listOfLists.size() == 0 || update)) { if (mApp.getCachedTask(TASK_TAG) == null) { FetchMenuTask fetchMTask = new FetchMenuTask(TASK_TAG); prepareToLoad(); Utility.parallelExecute(fetchMTask, restId, title); } } }
public class MenuFragment extends Fragment implements AdapterView.OnItemClickListener { private List<MyPair<String, List<Food>>> listOfLists = new ArrayList<>(); private MenuAdapter menuAdapter; private AmazingListView foodListView; private LinearLayout progressLayout; private TextView errorTextView; private View errorLayout; private String restId; private String title; private String TASK_TAG; private final UTilitiesApplication mApp = UTilitiesApplication.getInstance(); public static MenuFragment newInstance(String title, String restId) { MenuFragment f = new MenuFragment(); Bundle args = new Bundle(); args.putString("title", title); args.putString("restId", restId); f.setArguments(args); return f; } @Override public View onCreateView( LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View vg = inflater.inflate(R.layout.menu_fragment_layout, container, false); progressLayout = (LinearLayout) vg.findViewById(R.id.menu_progressbar_ll); foodListView = (AmazingListView) vg.findViewById(R.id.menu_listview); errorTextView = (TextView) vg.findViewById(R.id.tv_failure); errorLayout = vg.findViewById(R.id.menu_error); foodListView.setPinnedHeaderView( getActivity() .getLayoutInflater() .inflate(R.layout.menu_header_item_view, foodListView, false)); foodListView.setOnItemClickListener(this); foodListView.setAdapter(menuAdapter); updateView(restId, false); return vg; } @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); if (savedInstanceState != null) { restId = savedInstanceState.getString("restid"); listOfLists = (ArrayList) savedInstanceState.getSerializable("listoflists"); } else { restId = getArguments().getString("restId"); } title = getArguments().getString("title"); TASK_TAG = getClass().getSimpleName() + title; menuAdapter = new MenuAdapter(getActivity(), listOfLists); } public void updateView(String restId, Boolean update) { this.restId = restId; if (!restId.equals("0") && (listOfLists.size() == 0 || update)) { if (mApp.getCachedTask(TASK_TAG) == null) { FetchMenuTask fetchMTask = new FetchMenuTask(TASK_TAG); prepareToLoad(); Utility.parallelExecute(fetchMTask, restId, title); } } } @Override public void onStart() { super.onStart(); MyBus.getInstance().register(this); } @Override public void onStop() { MyBus.getInstance().unregister(this); super.onStop(); } @Override public void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); outState.putSerializable("listoflists", (ArrayList) listOfLists); outState.putString("restid", restId); } @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { String url = "http://hf-food.austin.utexas.edu/foodpro/" + ((Food) (parent.getItemAtPosition(position))).nutritionLink; SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(getActivity()); if (sp.getBoolean("embedded_browser", true)) { Intent i = new Intent(getActivity(), NutritionInfoActivity.class); i.putExtra("url", url); i.putExtra("title", ((Food) parent.getItemAtPosition(position)).name); startActivity(i); } else { Intent i = new Intent(Intent.ACTION_VIEW); i.setData(Uri.parse(url)); startActivity(i); } } static class FetchMenuTask extends TaggedAsyncTask<String, Integer, List<MyPair<String, List<Food>>>> { private String errorMsg; private final String FETCH_URL = "http://hf-food.austin.utexas.edu/foodpro/pickMenu.asp?locationNum=%s&mealName=%s"; public FetchMenuTask(String tag) { super(tag); } @Override protected List<MyPair<String, List<Food>>> doInBackground(String... params) { List<Food> foodList; List<MyPair<String, List<Food>>> tempListOfLists = new ArrayList<>(); OkHttpClient client = UTilitiesApplication.getInstance().getHttpClient(); String restId = params[0]; String meal = params[1]; String location; // Special case for JCM, which combines Lunch and Dinner if (restId.equals("05") && (meal.equals("Lunch") || meal.equals("Dinner"))) { location = String.format(FETCH_URL, restId, "Lunch/Dinner"); } else { location = String.format(FETCH_URL, restId, meal); } Request request = new Request.Builder().url(location).build(); String pagedata; try { Response response = client.newCall(request).execute(); pagedata = response.body().string(); } catch (IOException e) { errorMsg = "UTilities could not fetch this menu"; e.printStackTrace(); cancel(true); return null; } if (pagedata.contains("No Data Available")) { errorMsg = "No food offered at this time"; cancel(true); return null; } else { // have to leave in the lookahead so the regex matches don't // overlap Pattern catPattern = Pattern.compile( "<div class=\'pickmenucolmenucat\'.*?(?=<div class='pickmenucolmenucat'|</html>)", Pattern.DOTALL); Matcher catMatcher = catPattern.matcher(pagedata); while (catMatcher.find()) { String categoryData = catMatcher.group(); String category; foodList = new ArrayList<>(); Pattern catNamePattern = Pattern.compile(">-- (.*?) --<"); Matcher catNameMatcher = catNamePattern.matcher(categoryData); if (catNameMatcher.find()) { category = catNameMatcher.group(1); } else { category = "Unknown Category"; } Pattern nutritionLinkPattern = Pattern.compile("a href=\'(.*?)\'"); Matcher nutritionLinkMatcher = nutritionLinkPattern.matcher(categoryData); // This pattern is glitchy on a Nexus S 4G running CM10.1 nightly // Seems to activate Pattern.DOTALL by default. Set flags to // 0 to try and mitigate? Pattern foodPattern = Pattern.compile("<a href=.*?\">(\\w.*?)</a>", 0); Matcher foodMatcher = foodPattern.matcher(categoryData); while (foodMatcher.find() && nutritionLinkMatcher.find()) { foodList.add(new Food(foodMatcher.group(1), nutritionLinkMatcher.group(1))); } tempListOfLists.add(new MyPair<>(category, foodList)); if (isCancelled()) { return null; } } } return tempListOfLists; } @Override protected void onPostExecute(List<MyPair<String, List<Food>>> listOfLists) { super.onPostExecute(listOfLists); MyBus.getInstance().post(new LoadSucceededEvent(getTag(), listOfLists)); } @Override protected void onCancelled() { super.onCancelled(); MyBus.getInstance().post(new LoadFailedEvent(getTag(), errorMsg)); } } @Subscribe public void loadFailed(LoadFailedEvent event) { if (TASK_TAG.equals(event.tag)) { errorTextView.setText(event.errorMessage); progressLayout.setVisibility(View.GONE); errorLayout.setVisibility(View.VISIBLE); foodListView.setVisibility(View.GONE); } } @Subscribe public void loadSucceeded(LoadSucceededEvent event) { if (TASK_TAG.equals(event.tag)) { listOfLists.clear(); listOfLists.addAll(event.listOfLists); menuAdapter.notifyDataSetChanged(); foodListView.setVisibility(View.VISIBLE); progressLayout.setVisibility(View.GONE); errorLayout.setVisibility(View.GONE); } } private void prepareToLoad() { progressLayout.setVisibility(View.VISIBLE); errorLayout.setVisibility(View.GONE); foodListView.setVisibility(View.GONE); } static class LoadSucceededEvent { public String tag; public List<MyPair<String, List<Food>>> listOfLists; public LoadSucceededEvent(String tag, List<MyPair<String, List<Food>>> listOfLists) { this.tag = tag; this.listOfLists = listOfLists; } } static class Food implements Serializable { String name; String nutritionLink; public Food(String name, String nutritionLink) { this.name = name; this.nutritionLink = nutritionLink; } public String getName() { return name; } public String getLink() { return nutritionLink; } } static class MenuAdapter extends StickyHeaderAdapter<Food> { public MenuAdapter(Context con, List<MyPair<String, List<Food>>> all) { super(con, all); } @Override public View getAmazingView(int position, View convertView, ViewGroup parent) { View res = convertView; if (res == null) { res = LayoutInflater.from(mContext).inflate(R.layout.menu_item_view, parent, false); } TextView lName = (TextView) res.findViewById(R.id.lName); Food f = getItem(position); lName.setText(f.name); return res; } @Override public void configurePinnedHeader(View header, int position, int alpha) { TextView lSectionHeader = (TextView) header; lSectionHeader.setText(getSections()[getSectionForPosition(position)]); } } }
@Override protected List<MyPair<String, List<Food>>> doInBackground(String... params) { List<Food> foodList; List<MyPair<String, List<Food>>> tempListOfLists = new ArrayList<>(); OkHttpClient client = UTilitiesApplication.getInstance().getHttpClient(); String restId = params[0]; String meal = params[1]; String location; // Special case for JCM, which combines Lunch and Dinner if (restId.equals("05") && (meal.equals("Lunch") || meal.equals("Dinner"))) { location = String.format(FETCH_URL, restId, "Lunch/Dinner"); } else { location = String.format(FETCH_URL, restId, meal); } Request request = new Request.Builder().url(location).build(); String pagedata; try { Response response = client.newCall(request).execute(); pagedata = response.body().string(); } catch (IOException e) { errorMsg = "UTilities could not fetch this menu"; e.printStackTrace(); cancel(true); return null; } if (pagedata.contains("No Data Available")) { errorMsg = "No food offered at this time"; cancel(true); return null; } else { // have to leave in the lookahead so the regex matches don't // overlap Pattern catPattern = Pattern.compile( "<div class=\'pickmenucolmenucat\'.*?(?=<div class='pickmenucolmenucat'|</html>)", Pattern.DOTALL); Matcher catMatcher = catPattern.matcher(pagedata); while (catMatcher.find()) { String categoryData = catMatcher.group(); String category; foodList = new ArrayList<>(); Pattern catNamePattern = Pattern.compile(">-- (.*?) --<"); Matcher catNameMatcher = catNamePattern.matcher(categoryData); if (catNameMatcher.find()) { category = catNameMatcher.group(1); } else { category = "Unknown Category"; } Pattern nutritionLinkPattern = Pattern.compile("a href=\'(.*?)\'"); Matcher nutritionLinkMatcher = nutritionLinkPattern.matcher(categoryData); // This pattern is glitchy on a Nexus S 4G running CM10.1 nightly // Seems to activate Pattern.DOTALL by default. Set flags to // 0 to try and mitigate? Pattern foodPattern = Pattern.compile("<a href=.*?\">(\\w.*?)</a>", 0); Matcher foodMatcher = foodPattern.matcher(categoryData); while (foodMatcher.find() && nutritionLinkMatcher.find()) { foodList.add(new Food(foodMatcher.group(1), nutritionLinkMatcher.group(1))); } tempListOfLists.add(new MyPair<>(category, foodList)); if (isCancelled()) { return null; } } } return tempListOfLists; }
@Override protected Integer doInBackground(Boolean... params) { Boolean recursing = params[0]; // "stateful" stuff, I'll get it figured out in the next release // if(classList == null) classList = new ArrayList<UTClass>(); // else // return classList.size(); String reqUrl = "https://utdirect.utexas.edu/registration/classlist.WBX?sem=" + semId; Request request = new Request.Builder().url(reqUrl).build(); String pagedata = ""; try { Response response = client.newCall(request).execute(); pagedata = response.body().string(); } catch (IOException e) { errorMsg = "UTilities could not fetch your class listing"; e.printStackTrace(); cancel(true); return -1; } // now parse the Class Listing data // did we hit the login screen? if (pagedata.contains("<title>UT EID Login</title>")) { errorMsg = "You've been logged out of UTDirect, back out and log in again."; if (parentAct != null) { UTilitiesApplication mApp = (UTilitiesApplication) parentAct.getApplication(); if (!recursing) { try { mApp.getAuthCookie(UTD_AUTH_COOKIE_KEY).logout(); mApp.getAuthCookie(UTD_AUTH_COOKIE_KEY).login(); } catch (IOException e) { errorMsg = "UTilities could not fetch your class listing"; cancel(true); e.printStackTrace(); return null; } catch (TempLoginException tle) { /* ooooh boy is this lazy. I'd rather not init SharedPreferences here to check if persistent login is on, so we'll just catch the exception */ Intent login = new Intent(parentAct, LoginActivity.class); login.putExtra("activity", parentAct.getIntent().getComponent().getClassName()); login.putExtra("service", 'u'); parentAct.startActivity(login); parentAct.finish(); errorMsg = "Session expired, please log in again"; cancel(true); return null; } return doInBackground(true); } else { mApp.logoutAll(); } } cancel(true); return null; } Pattern semSelectPattern = Pattern.compile("<select name=\"sem\">.*</select>", Pattern.DOTALL); Matcher semSelectMatcher = semSelectPattern.matcher(pagedata); if (semSelectMatcher.find() && initialFragment) { Pattern semesterPattern = Pattern.compile("<option.*?value=\"(\\d*)\"\\s*>([\\w\\s]*?)</option>", Pattern.DOTALL); Matcher semesterMatcher = semesterPattern.matcher(semSelectMatcher.group()); while (semesterMatcher.find()) { // the "current" semester that has been downloaded is the one with the // "selected" attribute, so we don't want to load it again if (!semesterMatcher.group(0).contains("selected=\"selected\"")) { publishProgress(semesterMatcher.group(2), semesterMatcher.group(1)); } } } Pattern scheduleTablePattern = Pattern.compile("<table.*</table>", Pattern.DOTALL); Matcher scheduletableMatcher = scheduleTablePattern.matcher(pagedata); if (scheduletableMatcher.find()) { pagedata = scheduletableMatcher.group(0); } else { // if no <table>, user probably isn't enrolled for semester return 0; } Pattern classPattern = Pattern.compile("<tr .*?</tr>", Pattern.DOTALL); Matcher classMatcher = classPattern.matcher(pagedata); int classCount = 0, colorCount = 0; while (classMatcher.find()) { String classContent = classMatcher.group(); String uniqueid = "", classid = "", classname = ""; String[] buildings, rooms, days, times; boolean dropped = false; Pattern classAttPattern = Pattern.compile("<td >(.*?)</td>", Pattern.DOTALL); Matcher classAttMatcher = classAttPattern.matcher(classContent); if (classAttMatcher.find()) { uniqueid = classAttMatcher.group(1); } else { classParseIssue = true; continue; } if (classAttMatcher.find()) { classid = classAttMatcher.group(1); } else { classParseIssue = true; continue; } if (classAttMatcher.find()) { classname = classAttMatcher.group(1); } else { classParseIssue = true; continue; } if (classAttMatcher.find()) { buildings = classAttMatcher.group(1).split("<br />"); for (int i = 0; i < buildings.length; i++) { buildings[i] = buildings[i].replaceAll("<.*?>", "").trim(); } } else { classParseIssue = true; continue; } if (classAttMatcher.find()) { rooms = classAttMatcher.group(1).split("<br />"); for (int i = 0; i < rooms.length; i++) { rooms[i] = rooms[i].trim(); } } else { classParseIssue = true; continue; } if (classAttMatcher.find()) { days = classAttMatcher.group(1).split("<br />"); // Thursday represented by H so I can treat all days as single characters for (int a = 0; a < days.length; a++) { days[a] = days[a].replaceAll("TH", "H").trim(); } } else { classParseIssue = true; continue; } if (classAttMatcher.find()) { times = classAttMatcher.group(1).replaceAll("- ", "-").split("<br />"); for (int i = 0; i < times.length; i++) { times[i] = times[i].trim(); } } else { classParseIssue = true; continue; } if (classAttMatcher.find()) { String remark = classAttMatcher.group(1); if (remark.contains("Dropped")) { dropped = true; } } else { classParseIssue = true; continue; } if (!dropped) { classList.add( new UTClass( uniqueid, classid, classname, buildings, rooms, days, times, semId, colors[colorCount])); colorCount = (colorCount == colors.length - 1) ? 0 : colorCount + 1; classCount++; } } return classCount; }