<commit_before>package com.mick88.dittimetable.timetable;

import java.io.FileInputStream;
import java.io.IOException;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;

import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;

import android.content.Context;
import android.os.AsyncTask;
import android.util.Log;

import com.flurry.android.FlurryAgent;
import com.mick88.dittimetable.AppSettings;
import com.mick88.dittimetable.timetable.Exceptions.ServerConnectionException;
import com.mick88.dittimetable.web.Connection;

public abstract class TimetableDownloader extends AsyncTask<Void, Integer, RuntimeException>
{
	private static final String logTag = "TimetableDownloader";
	final Connection connection;
	final AppSettings appSettings;
	final Timetable timetable;
	final Context context;
	
	public TimetableDownloader(Context context,	Timetable timetable)
	{
		this.appSettings = timetable.getSettings();
		this.connection = new Connection(appSettings);
		this.timetable = timetable;
		this.context = context;
	}
	
	public TimetableDownloader(Context context, AppSettings appSettings)
	{
		this.connection = new Connection(appSettings);
		this.appSettings = appSettings;
		this.timetable = new Timetable(appSettings);
		this.context = context;
	}
	
	/** 
	 * Gets the timetable url
	 * @return address to the web timetable
	 */
	public String getQueryAddress(Timetable timetable)
	{
		if (timetable.weekRange == -1) return String.format(Locale.ENGLISH, 
				"?reqtype=timetable&action=getgrid&sKey=%s%%7C%s&sTitle=Computing&sYear=%d&sEventType=&sModOccur=&sFromDate=&sToDate=&sWeeks=%s&sType=course&instCode=-2&instName=", 
				getDataset(), timetable.course, timetable.year, timetable.weeks);
		else return String.format(Locale.ENGLISH, 
				"?reqtype=timetable&action=getgrid&sKey=%s%%7C%s&sTitle=Computing&sYear=%d&sEventType=&sModOccur=&sFromDate=&sToDate=&weekRange=%d&sType=course&instCode=-2&instName=", 
				getDataset(), timetable.course, timetable.year, timetable.weekRange);
	}
	
	public static String getDataset()
	{
		Calendar c = Calendar.getInstance();
		int startYear=0;
		
		if (Timetable.getSemester() == 1)
			startYear = c.get(Calendar.YEAR);
		else
			startYear = c.get(Calendar.YEAR)-1;
		
		StringBuilder builder = new StringBuilder(6);
		builder.append(startYear);
		builder.append((startYear+1) % 100);
		return builder.toString();
	}
	
	/**
	 * Downloads timetable content from web timetables - graphic view
	 * @param context
	 * @return true if successful
	 */
	public void download()
	{
		if (connection.areCredentialsPresent() == false)
			throw new Exceptions.SettingsEmptyException();

		String query = getQueryAddress(timetable);
		
		String string;
		try
		{
			string = connection.getContent(query);
		} 
		catch (ServerConnectionException e)
		{
			throw new Exceptions.TimetableException(e.toString());
		}
		catch (IOException e)
		{
			e.printStackTrace();
			throw new Exceptions.ServerConnectionException();
		}
		
		if (string == null)
			throw new Exceptions.ServerConnectionException();
		
		if (string.contains("You must login again."))
			throw new Exceptions.SessionExpiredException();
		
		if (string.contains("There are no events to display."))
			throw new Exceptions.NoEventsException();
		
		if (string.contains("The system is loading commonly used data at the moment"))
			throw new Exceptions.ServerLoadingException();
		
		if (string.contains("Your login details are incorrect. Please attempt login again."))
			throw new Exceptions.IncorrectCredentialsException();
		
		if (string.contains("There are no events in the selected timetable."))
			throw new Exceptions.EmptyTimetableException();
		
		if (string.contains("There are no course records matching the criteria."))
			throw new Exceptions.WrongCourseException();
		
		boolean result = parseGrid(string);
		
		if (result == false) 
		{
			throw new Exceptions.InvalidDataException();
		}
		
		// finalize by saving to file and downloading detailde info
		if (result == true) 
		{
			for (TimetableDay day : timetable.days)
			{
				for (TimetableEvent event : day.events)
				{
					if (isCancelled()) break;
					try
					{
						downloadAdditionalInfo(event);
					} catch (IOException e)
					{
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
				}
			}
			
			timetable.exportTimetable(context);
			Log.i(logTag, "Timetable successfully downloaded");
			timetable.lastUpdated = new Date();
		}
	}
	
	
	/**
	 * Loads additional information about event from web timetables.<commit_msg>dont download event if already updated<commit_after>package com.mick88.dittimetable.timetable;

import java.io.FileInputStream;
import java.io.IOException;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;

import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;

import android.content.Context;
import android.os.AsyncTask;
import android.util.Log;

import com.flurry.android.FlurryAgent;
import com.mick88.dittimetable.AppSettings;
import com.mick88.dittimetable.timetable.Exceptions.ServerConnectionException;
import com.mick88.dittimetable.web.Connection;

public abstract class TimetableDownloader extends AsyncTask<Void, Integer, RuntimeException>
{
	private static final String logTag = "TimetableDownloader";
	final Connection connection;
	final AppSettings appSettings;
	final Timetable timetable;
	final Context context;
	
	public TimetableDownloader(Context context,	Timetable timetable)
	{
		this.appSettings = timetable.getSettings();
		this.connection = new Connection(appSettings);
		this.timetable = timetable;
		this.context = context;
	}
	
	public TimetableDownloader(Context context, AppSettings appSettings)
	{
		this.connection = new Connection(appSettings);
		this.appSettings = appSettings;
		this.timetable = new Timetable(appSettings);
		this.context = context;
	}
	
	/** 
	 * Gets the timetable url
	 * @return address to the web timetable
	 */
	public String getQueryAddress(Timetable timetable)
	{
		if (timetable.weekRange == -1) return String.format(Locale.ENGLISH, 
				"?reqtype=timetable&action=getgrid&sKey=%s%%7C%s&sTitle=Computing&sYear=%d&sEventType=&sModOccur=&sFromDate=&sToDate=&sWeeks=%s&sType=course&instCode=-2&instName=", 
				getDataset(), timetable.course, timetable.year, timetable.weeks);
		else return String.format(Locale.ENGLISH, 
				"?reqtype=timetable&action=getgrid&sKey=%s%%7C%s&sTitle=Computing&sYear=%d&sEventType=&sModOccur=&sFromDate=&sToDate=&weekRange=%d&sType=course&instCode=-2&instName=", 
				getDataset(), timetable.course, timetable.year, timetable.weekRange);
	}
	
	public static String getDataset()
	{
		Calendar c = Calendar.getInstance();
		int startYear=0;
		
		if (Timetable.getSemester() == 1)
			startYear = c.get(Calendar.YEAR);
		else
			startYear = c.get(Calendar.YEAR)-1;
		
		StringBuilder builder = new StringBuilder(6);
		builder.append(startYear);
		builder.append((startYear+1) % 100);
		return builder.toString();
	}
	
	/**
	 * Downloads timetable content from web timetables - graphic view
	 * @param context
	 * @return true if successful
	 */
	public void download()
	{
		if (connection.areCredentialsPresent() == false)
			throw new Exceptions.SettingsEmptyException();

		String query = getQueryAddress(timetable);
		
		String string;
		try
		{
			string = connection.getContent(query);
		} 
		catch (ServerConnectionException e)
		{
			throw new Exceptions.TimetableException(e.toString());
		}
		catch (IOException e)
		{
			e.printStackTrace();
			throw new Exceptions.ServerConnectionException();
		}
		
		if (string == null)
			throw new Exceptions.ServerConnectionException();
		
		if (string.contains("You must login again."))
			throw new Exceptions.SessionExpiredException();
		
		if (string.contains("There are no events to display."))
			throw new Exceptions.NoEventsException();
		
		if (string.contains("The system is loading commonly used data at the moment"))
			throw new Exceptions.ServerLoadingException();
		
		if (string.contains("Your login details are incorrect. Please attempt login again."))
			throw new Exceptions.IncorrectCredentialsException();
		
		if (string.contains("There are no events in the selected timetable."))
			throw new Exceptions.EmptyTimetableException();
		
		if (string.contains("There are no course records matching the criteria."))
			throw new Exceptions.WrongCourseException();
		
		boolean result = parseGrid(string);
		
		if (result == false) 
		{
			throw new Exceptions.InvalidDataException();
		}
		
		// finalize by saving to file and downloading detailde info
		if (result == true) 
		{
			for (TimetableDay day : timetable.days)
			{
				for (TimetableEvent event : day.events)
				{
					if (isCancelled()) break;
					if (event.isUpdated()) continue;
					try
					{
						downloadAdditionalInfo(event);
					} catch (IOException e)
					{
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
				}
			}
			
			timetable.exportTimetable(context);
			Log.i(logTag, "Timetable successfully downloaded");
			timetable.lastUpdated = new Date();
		}
	}
	
	
	/**
	 * Loads additional information about event from web timetables.
{'fraction_non_alphanumeric': 0.10970553842882959, 'fraction_numerical': 0.004464760284894228, 'mean_word_length': 4.410005750431282, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 19, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5106231', 'n_tokens_mistral': 3333, 'n_tokens_neox': 2782, 'n_words': 663}