package com.ov3rk1ll.kinocast.utils; import android.content.Context; import com.ov3rk1ll.kinocast.api.Parser; import com.ov3rk1ll.kinocast.data.ViewModel; import org.json.JSONException; import org.json.JSONObject; import java.io.BufferedReader; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStreamReader; import java.lang.ref.SoftReference; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; public class TheMovieDb { public static final String IMAGE_BASE_PATH = "http://image.tmdb.org/t/p/"; private static final String DISK_CACHE_PATH = "/themoviedb_cache/"; private static final String API_KEY = "f9dc7e5d12b2640bf4ef1cf20835a1cc"; private ConcurrentHashMap<String, SoftReference<JSONObject>> memoryCache; private String diskCachePath; private boolean diskCacheEnabled = false; private ExecutorService writeThread; public TheMovieDb(Context context) { // Set up in-memory cache store memoryCache = new ConcurrentHashMap<>(); // Set up disk cache store Context appContext = context.getApplicationContext(); diskCachePath = appContext.getCacheDir().getAbsolutePath() + DISK_CACHE_PATH; File outFile = new File(diskCachePath); outFile.mkdirs(); diskCacheEnabled = outFile.exists(); // Set up threadpool for image fetching tasks writeThread = Executors.newSingleThreadExecutor(); } public JSONObject get(String url) { return get(url, true); } public JSONObject get(String url, boolean fetchIfNeeded) { JSONObject json; //String url = request.getUrl(); // Check for image in memory json = getFromMemory(url); // Check for image on disk cache if(json == null) { json = getFromDisk(url); // Write bitmap back into memory cache if(json != null) { cacheToMemory(url, json); } } if(json == null || fetchIfNeeded) { try { // Get IMDB-ID from page ViewModel item = Parser.getInstance().loadDetail(url); String param = url.substring(url.indexOf("#") + 1); // tt1646971?api_key=f9dc7e5d12b2640bf4ef1cf20835a1cc&language=de&external_source=imdb_id JSONObject data = Utils.readJson("http://api.themoviedb.org/3/find/" + item.getImdbId() + "?api_key=" + API_KEY + "&external_source=imdb_id&" + param); if(data == null) return null; if(data.getJSONArray("movie_results").length() > 0) { json = data.getJSONArray("movie_results").getJSONObject(0); }else if(data.getJSONArray("tv_results").length() > 0) { json = data.getJSONArray("tv_results").getJSONObject(0); } if(json != null) { put(url, json); } } catch (JSONException e) { e.printStackTrace(); } } return json; } private void put(String url, JSONObject json) { cacheToMemory(url, json); cacheToDisk(url, json); } private JSONObject getFromMemory(String url) { JSONObject json = null; SoftReference<JSONObject> softRef = memoryCache.get(getCacheKey(url)); if(softRef != null){ json = softRef.get(); } return json; } private JSONObject getFromDisk(String url) { JSONObject json = null; if(diskCacheEnabled){ String filePath = getFilePath(url); File file = new File(filePath); if(file.exists()) { try { BufferedReader input = new BufferedReader(new InputStreamReader(new FileInputStream(file))); StringBuilder content = new StringBuilder(); char[] buffer = new char[1024]; int num; while ((num = input.read(buffer)) > 0) { content.append(buffer, 0, num); } json = new JSONObject(content.toString()); } catch (JSONException | IOException e) { e.printStackTrace(); } } } return json; } private void cacheToMemory(final String url, final JSONObject json) { memoryCache.put(getCacheKey(url), new SoftReference<>(json)); } private void cacheToDisk(final String url, final JSONObject json) { writeThread.execute(new Runnable() { @Override public void run() { if(diskCacheEnabled) { FileOutputStream ostream = null; try { ostream = new FileOutputStream(new File(diskCachePath, getCacheKey(url))); ostream.write(json.toString().getBytes()); } catch (IOException e) { e.printStackTrace(); } finally { try { if(ostream != null) { ostream.flush(); ostream.close(); } } catch (IOException ignored) {} } } } }); } private String getFilePath(String url) { return diskCachePath + getCacheKey(url); } private String getCacheKey(String url) { if(url == null){ throw new RuntimeException("Null url passed in"); } else { if(url.contains("#")) url = url.substring(0, url.indexOf("#")); return url.replaceAll("[.:/,%?&=]", "+").replaceAll("[+]+", "+"); } } }