-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathbackground.js
More file actions
184 lines (155 loc) · 6.05 KB
/
background.js
File metadata and controls
184 lines (155 loc) · 6.05 KB
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
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
// Copyright (c) 2018
// @author Michael Weir
// Use of this source code is govered by the GPLv3 license that can be
// found in the LICENSE file
// This file contains the following background functionality
// - XMLHttpRequest Send Headers Callback
// * Listener that Intercepts request to api.j-novel.club/users. The
// extension intercepts these requests to learn both the user id
// and current session authentication ID. The extension uses this
// information to make its own authentication request for user
// information (aka what chapter they have read).
// - Alarm Callback
// * The alarm callback fires once a day. When fired the extension polls
// j-novel for both new chapter expired chapters. Saves the
// result locally for use by feed.js.
// - Page Action
// * Handles enabling the page action functionality (when
// the user is on j-novel.club).
//================== XMLHttpRequest Send Headers Callback =====================
var base_url = "https://api.j-novel.club/api/users/"
var filter = {urls: [base_url + "*"]};
// Function is notified any time a call is made to api.j-novel.club/api/users
// The function saves both the user id and the current authorization token
// from the request. This information is used by feed.js to query
// which chapters a user has already read
//
// @param req The HTTP request object
function send_headers_callback(req) {
if (req.method == "GET") {
var auth_obj = {};
auth_obj["user_id"] = req.url.match(base_url + "(.*)[\?/]")[1];
if (auth_obj["user_id"]) {
for (var i = 0; i < req.requestHeaders.length; ++i) {
var header = req.requestHeaders[i];
if (header.name.toLowerCase() == "authorization") {
auth_obj["auth_value"] = header.value;
break;
}
}
}
chrome.storage.local.set({"auth_obj": JSON.stringify(auth_obj)},
save_auth_callback);
}
}
// Empty function that is called after the auth object is saved
function save_auth_callback()
{
}
// Adds a listener for HTTP request to api.j-novel.club/api/users
chrome.webRequest.onSendHeaders.addListener(
send_headers_callback, filter, ["requestHeaders"]);
//================== Alarm Callback + Chapter Polling =========================
var seriesUrl = 'https://api.j-novel.club/api/series/findOne?filter={%22where%22:{%22titleslug%22:%22'
var seriesInclude = '%22},%22include%22:[%22parts%22]}'
var follow_series_list;
var follow_index;
var parts_hash_table;
var req;
// This function retrieves the list of novels the user is following. For each
// novel in the list, the poll function retrieves the chapter list and
// saves the updated list to be used by feed.js. This function is called either
// by the alarm callback (once a day) or when the user modifies the list
// of novels which they are following
function poll()
{
parts_hash_table = {};
chrome.storage.sync.get('follow_list', poll_callback);
}
// This function is the callback funciton that handle parsing the
// follow novel list. It parses the list and the kicks off the process
// of retrieving the chapter list for each of the novels the user is
// following
function poll_callback(items)
{
follow_index = 0;
if (items.hasOwnProperty('follow_list')) {
follow_series_list = JSON.parse(items.follow_list);
retrieve_series_parts();
}
}
// This function is a recursive function that is controlled by the
// global variable follow_index. Follow index is initialized by
// poll_callback to zero. It controls which novel chapter list the background
// script is updating. After upating a novel chapter list, the funciton
// increments the follow_index and calls itself to update the next novel
// chapter list. When the follow_index equals the last novel, the
// function returns
function retrieve_series_parts()
{
if (follow_series_list.length <= follow_index) {
chrome.storage.local.set({
"parts_hash_table": JSON.stringify(parts_hash_table)},
save_parts_callback);
return;
}
var titleslug = follow_series_list[follow_index].titleslug;
// Request to update the novel chapter list
req = new XMLHttpRequest();
req.onload = handleResponse;
req.onerror = handleError;
req.open('GET', seriesUrl + titleslug + seriesInclude, true);
req.send(null);
}
// Empty Callback Function
function save_parts_callback()
{
}
// Handles the update novel chapter list HTTP request response. The function
// parses the response and adds all the unexpired chapters to the chapter
// hash table.
function handleResponse()
{
var novel_obj = JSON.parse(req.response);
var novel_id = novel_obj.id;
console.log(novel_obj);
parts_hash_table[novel_id] = [];
for (var i = 0; i < novel_obj.parts.length; ++i) {
var temp = {};
if (novel_obj.parts[i].expired)
continue;
temp.title = novel_obj.parts[i].title;
temp.titleslug = novel_obj.parts[i].titleslug;
temp.id = novel_obj.parts[i].id;
parts_hash_table[novel_id].push(temp);
}
follow_index = follow_index + 1;
retrieve_series_parts();
}
// Handles an error when trying to update the novel chapter list
function handleError()
{
console.log(req);
}
// Alarm Callback. The alarm callback is called when the alarms fires. It
// initiates the update chapter list process.
function alarm_callback(alarm)
{
console.log("Got an alarm", alarm);
poll();
}
// Adds a listener for alarms
chrome.alarms.onAlarm.addListener(alarm_callback);
//============================ Page Action ====================================
// Callback function that checks if the user is visiting j-novel.club.
// If the users is visiting j-novel, the extension enables the page action.
function checkForValidUrl(tabId, changeInfo, tab)
{
if (tab && tab.url) {
if (tab.url.indexOf('j-novel.club') > -1) {
chrome.pageAction.show(tabId);
}
}
}
// Adds a listener for tab updates
chrome.tabs.onUpdated.addListener(checkForValidUrl);