diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..94a25f7 --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/java/com/gabriel/projectmonster/DSync.java b/app/src/main/java/com/gabriel/projectmonster/DSync.java index e88e76d..36e20c9 100644 --- a/app/src/main/java/com/gabriel/projectmonster/DSync.java +++ b/app/src/main/java/com/gabriel/projectmonster/DSync.java @@ -8,13 +8,22 @@ import android.os.Binder; import android.os.IBinder; import android.support.annotation.Nullable; +import org.jsoup.Jsoup; +import org.jsoup.nodes.Document; + +import java.io.IOException; + public class DSync extends Service { + public int cacheTimeoutSeconds = 3600; + public static final String url = "www.luckyprison.com/"; public static final String store = "store.luckyprison.com"; public static final String[] pages = {"?page=%p", "forums/", "members/"}; //Simple reference to pages on site public static final String[] memberType = {"", "positive_ratings", "points", "staff"}; + public static final String CACHE_FRONT_PAGE_NOID = "front_page_"; + // Helpful lcasses class DBinder extends Binder { DSync getDataSyncService(){ return DSync.this; } } public class BootReceiver extends BroadcastReceiver{ @@ -45,7 +54,6 @@ public class DSync extends Service { } public static boolean isRunning(){ return running; } - public String loadFrontPage(){ - - } + //TODO: Not this + public String loadFrontPage() throws IOException { return null; } } diff --git a/libcacher/src/main/java/com/tofvesson/Cacher.java b/libcacher/src/main/java/com/tofvesson/Cacher.java index ab092b3..659b916 100644 --- a/libcacher/src/main/java/com/tofvesson/Cacher.java +++ b/libcacher/src/main/java/com/tofvesson/Cacher.java @@ -1,38 +1,200 @@ package com.tofvesson; +import com.sun.istack.internal.Nullable; + +import java.io.BufferedReader; +import java.io.Closeable; import java.io.File; +import java.io.FileInputStream; import java.io.FileNotFoundException; +import java.io.FileReader; +import java.io.IOException; +import java.io.OutputStream; import java.io.PrintStream; import java.io.UnsupportedEncodingException; +import java.util.ArrayList; +import java.util.Date; import java.util.HashMap; +import java.util.List; import java.util.Map; -public class Cacher { +@SuppressWarnings("ALL") +public class Cacher implements Closeable{ + + private class CacheDataHolder{ int unixTimeCached = 0; String data = ""; public CacheDataHolder(String s, int i){ unixTimeCached=i; data=s; } } private PrintStream cache; - Map cachedValues = new HashMap<>(); + private BufferedReader cacheIn; + private FileReader cacheFileReader; + private File cacheFile; + private Map cachedValues = new HashMap<>(); public Cacher(File file, String s) throws FileNotFoundException, UnsupportedEncodingException { + if(!(cacheFile = file).isFile()) try { file.createNewFile(); } catch (IOException e) { e.printStackTrace(); } cache = new PrintStream(file, s); + cacheIn = new BufferedReader(cacheFileReader = new FileReader(file)); + if(!verifyCacheIntegrity(false, System.out)){ + cache.close(); + try { cacheIn.close(); } catch (IOException e) { e.printStackTrace(); } + file.delete(); + try { file.createNewFile(); } catch (IOException e) { e.printStackTrace(); } + cache = new PrintStream(file, s); + cacheIn = new BufferedReader(cacheFileReader = new FileReader(file)); + } } public Cacher(File file) throws FileNotFoundException { + if(!(cacheFile = file).isFile()) try { file.createNewFile(); } catch (IOException e) { e.printStackTrace(); } cache = new PrintStream(file); + cacheIn = new BufferedReader(cacheFileReader = new FileReader(file)); + if(!verifyCacheIntegrity(false, System.out)){ + cache.close(); + try { cacheIn.close(); } catch (IOException e) { e.printStackTrace(); } + file.delete(); + try { file.createNewFile(); } catch (IOException e) { e.printStackTrace(); } + cache = new PrintStream(file); + cacheIn = new BufferedReader(cacheFileReader = new FileReader(file)); + } } public Cacher(String s, String s1) throws FileNotFoundException, UnsupportedEncodingException { + if(!(cacheFile = new File(s)).isFile()) try { new File(s).createNewFile(); } catch (IOException e) { e.printStackTrace(); } cache = new PrintStream(s, s1); + cacheIn = new BufferedReader(cacheFileReader = new FileReader(s)); + if(!verifyCacheIntegrity(false, System.out)){ + cache.close(); + try { cacheIn.close(); } catch (IOException e) { e.printStackTrace(); } + File f = new File(s); + f.delete(); + try { f.createNewFile(); } catch (IOException e) { e.printStackTrace(); } + cache = new PrintStream(s, s1); + cacheIn = new BufferedReader(cacheFileReader = new FileReader(f)); + } } public Cacher(String s) throws FileNotFoundException { + if(!(cacheFile = new File(s)).isFile()) try { new File(s).createNewFile(); } catch (IOException e) { e.printStackTrace(); } cache = new PrintStream(s); + cacheIn = new BufferedReader(cacheFileReader = new FileReader(s)); + if(!verifyCacheIntegrity(false, System.out)){ + cache.close(); + try { cacheIn.close(); } catch (IOException e) { e.printStackTrace(); } + File f = new File(s); + f.delete(); + try { f.createNewFile(); } catch (IOException e) { e.printStackTrace(); } + cache = new PrintStream(f); + cacheIn = new BufferedReader(cacheFileReader = new FileReader(f)); + } } - public void print(String k, String v){ - + private void resetReader(){ + try { + cacheFileReader.reset(); + cacheIn = new BufferedReader(cacheFileReader); + } catch (IOException e) { + e.printStackTrace(); + } } - public void println(String k, String v){ + public boolean cacheContainsKey(String k){ + String s = ""; + try { resetReader(); while((s = cacheIn.readLine())!=null) if(k.equals(s.substring(0, s.indexOf(" ")))) return true; } catch (IOException e) { return false; } + return false; + } + public void store(String k, String v, int cacheTime){ + if(cachedValues.containsKey(k = k.replace("[", "[lb").replace(" ", "[sp"))) cachedValues.replace(k, new CacheDataHolder(v.replace("[", "[lb").replace(" ", "[sp"), cacheTime)); + else cachedValues.put(k, new CacheDataHolder(v.replace("[", "[lb").replace(" ", "[sp"), cacheTime)); + } + + public void store(String k, String v){ store(k, v, (int) System.currentTimeMillis() / 1000); } + + @Nullable + public CacheDataHolder load(String k) { + k = k.replace("[", "[lb").replace(" ", "[sp"); + CacheDataHolder tmp; + if(cachedValues.containsKey(k)) return new CacheDataHolder((tmp=cachedValues.get(k)).data.replace(" ", "[sp").replace("[", "[lb"), tmp.unixTimeCached); + else if(cacheContainsKey(k)) return new CacheDataHolder((tmp=loadFromCache(k)).data.replace(" ", "[sp").replace("[", "[lb"), tmp.unixTimeCached); + return null; + } + + @Nullable + private CacheDataHolder loadFromCache(String k){ + k = k.replace("[", "[lb").replace(" ", "[sp"); + String s = ""; + try { + while((s = cacheIn.readLine())!=null) if(s.substring(0, s.indexOf(" ")).equals(k)) //value 123 + return new CacheDataHolder(s.substring(s.indexOf(" ")+1, s.substring(s.indexOf(" ")+1).indexOf(" ")+s.indexOf(" ")).replace(" ", "[sp").replace("[", "[lb"), + Integer.parseInt(s.substring(s.substring(s.indexOf(" ")+1).indexOf(" ")+1+s.indexOf(" ")))); + } catch (IOException e) { + e.printStackTrace(); + } + return null; + } + + public List loadKeysFromCache(){ + String s = ""; + List keys = new ArrayList<>(); + try { resetReader(); while((s = cacheIn.readLine())!=null) keys.add(s.substring(s.indexOf(" "))); } catch (IOException e) { e.printStackTrace(); } + + return keys; + } + + public void flush() throws IOException { + List fileKeys = loadKeysFromCache(); + for(String k : fileKeys) + if(cachedValues.containsKey(k)) cachedValues.replace(k, loadFromCache(k)); + else cachedValues.put(k, loadFromCache(k)); + cacheFile.delete(); + cacheFile.createNewFile(); + cache = new PrintStream(cacheFile); + cacheIn = new BufferedReader(cacheFileReader = new FileReader(cacheFile)); + for(String k : cachedValues.keySet()) + store(k, cachedValues.get(k).data, cachedValues.get(k).unixTimeCached); + } + + public boolean verifyCacheIntegrity(boolean debug, PrintStream debugOut){ + + String s = ""; + int count = 0; + if(debug) debugOut.println("Checking RAM cache integrity..."); + for(String j : cachedValues.keySet()) + if(j == null){ + if(debug) System.out.println("Found a null key at index "+count); + return false; + }else if(debug) ++count; + for(CacheDataHolder j : cachedValues.values()) + if(j == null || j.unixTimeCached<0 || j.data == null){ + if(debug) System.out.println("Found a null value at index "+count); + return false; + }else if(debug) ++count; + System.out.println("RAM cache integrity is sound. Verifying filesystem integrity..."); + try { + while((s = cacheIn.readLine())!=null){ + if(!s.contains(" ") || s.indexOf(" ")==0 || allOccurrencesOf(s, " ")!=2) return false; + s = s.substring(s.indexOf(" ")+1); + if(!s.contains(" ") || s.indexOf(" ")==0) return false; + //noinspection ResultOfMethodCallIgnored + Integer.parseInt(s.substring(s.indexOf(" ")+1)); + } + } catch (Exception e) { + if(debug) System.out.println("Encountered error when attempting to read cache file! Integrity is not sound!\n"+e.toString()); + return false; + } + return true; + } + + private int allOccurrencesOf(String s, String sequence){ + int i = 0; + //Assign string to the substring *after* first instance of sequence by incrementing counter, dividing counter variable by itself (i/i = 1) + //and multiplying by length of sequence to exclude it from new string + while(s.indexOf(sequence)!=0) s = s.substring(s.indexOf(sequence)+(((++i)/i)*sequence.length())); + return i; + } + + @Override + public void close() throws IOException { + cache.close(); + cacheIn.close(); } }