aboutsummaryrefslogtreecommitdiff
path: root/src/main/java/uk/co/notori/gol/Util.java
blob: 6d57e619bfaae4f3ffa8da94d94c35e459cc5e2d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
package uk.co.notori.gol;

import com.amazon.kindle.booklet.AbstractBooklet;
import com.amazon.kindle.booklet.BookletContext;
import com.amazon.kindle.restricted.content.catalog.ContentCatalog;
import com.amazon.kindle.restricted.runtime.Framework;
import org.json.simple.JSONArray;
import org.json.simple.JSONObject;

import java.awt.*;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Date;

public class Util {
    private static boolean kindle;
    
    public static boolean isKindle() {
        return kindle;
    }
    
	public static void setKindle(boolean kindleValue) {
        kindle = kindleValue;
    }
    
	
    public static BookletContext getBookletContext(AbstractBooklet booklet) {
        BookletContext bc = null;
        Method[] methods = AbstractBooklet.class.getDeclaredMethods();
        for (int i = 0; i < methods.length; i++) {
            if (methods[i].getReturnType() == BookletContext.class) {
                // Double check that it takes no arguments, too...
                Class<?>[] params = methods[i].getParameterTypes();
                if (params.length == 0) {
                    try {
                        bc = (BookletContext) methods[i].invoke(booklet, (Object[]) null);
                    } catch (IllegalAccessException e) {
                        e.printStackTrace();
                    } catch (IllegalArgumentException e) {
                        e.printStackTrace();
                    } catch (InvocationTargetException e) {
                        e.printStackTrace();
                    }
                    break;
                }
            }
        }
        return bc;
    }
    
    public static Container getUIContainer(AbstractBooklet booklet) throws InvocationTargetException, IllegalAccessException {
        Method getUIContainer = null;
        
        // Should be the only method returning a Container in BookletContext...
        Method[] methods = BookletContext.class.getDeclaredMethods();
        for (int i = 0; i < methods.length; i++) {
            Method method = methods[i];
            if (method.getReturnType() == Container.class) {
                // Double check that it takes no arguments, too...
                Class<?>[] params = method.getParameterTypes();
                if (params.length == 0) {
                    getUIContainer = method;
                    break;
                }
            }
        }
        
        if (getUIContainer != null) {
            BookletContext bc = Util.getBookletContext(booklet);
            Container rootContainer = (Container) getUIContainer.invoke(bc, (Object[]) null);
            return rootContainer;
        } else {
            return null;
        }
    }

	// And this was always obfuscated...
	// NOTE: Pilfered from KPVBooklet (https://github.com/koreader/kpvbooklet/blob/master/src/com/github/chrox/kpvbooklet/ccadapter/CCAdapter.java)
	/**
	 * Perform CC request of type "query" and "change"
	 * @param req_type request type of "query" or "change"
	 * @param req_json request json string
	 * @return return json object
	 */
    private static JSONObject ccPerform(String req_type, String req_json) {
        ContentCatalog CC = Framework.getService(ContentCatalog.class);
        try {
            Method perform = null;
            
            // Enumeration approach
            Class<?>[] signature = {String.class, String.class, int.class, int.class};
            Method[] methods = ContentCatalog.class.getDeclaredMethods();
            for (int i = 0; i < methods.length; i++) {
                Method method = methods[i];
                Class<?>[] params = method.getParameterTypes();
                if (params.length == signature.length) {
                    int j = 0;
                    while (j < signature.length && params[j].isAssignableFrom(signature[j])) {
                        j++;
                    }
                    if (j == signature.length) {
                        perform = method;
                        break;
                    }
                }
            }
            
            if (perform != null) {
                return (JSONObject) perform.invoke(CC, new Object[]{req_type, req_json, Integer.valueOf(200), Integer.valueOf(5)});
            } else {
                System.err.println("Failed to find perform method!");
                return new JSONObject();
            }
        } catch (Throwable t) {
            throw new RuntimeException(t.toString());
        }
    }
    
    public static void updateCCDB(String tag, String path) {
        long lastAccess = System.currentTimeMillis() / 1000L;
        String escapedPath = JSONObject.escape(path);
        
        // Query for the file
        String json_query = "{\"filter\":{\"Equals\":{\"value\":\"" + escapedPath + "\",\"path\":\"location\"}},\"type\":\"QueryRequest\",\"maxResults\":1,\"sortOrder\":[{\"order\":\"descending\",\"path\":\"lastAccess\"},{\"order\":\"ascending\",\"path\":\"titles[0].collation\"}],\"startIndex\":0,\"id\":1,\"resultType\":\"fast\"}";
        JSONObject json = Util.ccPerform("query", json_query);
        JSONArray values = (JSONArray) json.get("values");
        JSONObject value = (JSONObject) values.get(0);
        String uuid = (String) value.get("uuid");
        
        // Update the file metadata
        String json_change = "{\"commands\":[{\"update\":{\"uuid\":\"" + uuid + "\",\"lastAccess\":" + lastAccess + ",\"displayTags\":[\"" + tag + "\"]" + "}}],\"type\":\"ChangeRequest\",\"id\":1}";
        Util.ccPerform("change", json_change);
    }
}