Compare commits
7 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 776b0afdab | |||
| c428e4ab11 | |||
| d19b9ced8f | |||
| 4a506de6fe | |||
| 2070cdb30a | |||
| fcb9f9dbf3 | |||
| 094e2d2b81 |
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"manifest_version": 3,
|
"manifest_version": 3,
|
||||||
"name": "not-a-rescheduler",
|
"name": "not-a-rescheduler",
|
||||||
"version": "0.0.1",
|
"version": "0.0.3",
|
||||||
"permissions": [ "storage", "tabs", "activeTab", "notifications", "declarativeContent" ],
|
"permissions": [ "storage", "tabs", "activeTab", "notifications", "declarativeContent" ],
|
||||||
"content_scripts": [
|
"content_scripts": [
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -55,7 +55,7 @@
|
|||||||
<label for="frequency">Check frequency<br>(every <span id="frequency_info">N</span> minutes)</label>
|
<label for="frequency">Check frequency<br>(every <span id="frequency_info">N</span> minutes)</label>
|
||||||
</div>
|
</div>
|
||||||
<div class="col">
|
<div class="col">
|
||||||
<input type="range" id="frequency" name="frequency" min="1" max="15" step="1">
|
<input type="range" id="frequency" name="frequency" min="0.5" max="10" step="0.5">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
@@ -75,12 +75,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- consulates -->
|
<!-- current appointment -->
|
||||||
<div class="row">
|
|
||||||
<div class="col">Consulates:</div>
|
|
||||||
</div>
|
|
||||||
<div id="consulatesConfig">
|
|
||||||
</div>
|
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col">
|
<div class="col">
|
||||||
Current appointment: <span id="currApptConsulate">somewhere</span>, <span id="currApptDate">some time</span>
|
Current appointment: <span id="currApptConsulate">somewhere</span>, <span id="currApptDate">some time</span>
|
||||||
@@ -91,6 +86,12 @@
|
|||||||
Status: <span class="smooth-text" id="status">Inactive</span>
|
Status: <span class="smooth-text" id="status">Inactive</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!-- consulates -->
|
||||||
|
<div id="consulatesConfig">
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- buttons -->
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col">
|
<div class="col">
|
||||||
<button type="button" class="btn btn-info btn-sm" id="showConfigButton">Config</button>
|
<button type="button" class="btn btn-info btn-sm" id="showConfigButton">Config</button>
|
||||||
|
|||||||
@@ -107,7 +107,7 @@ function smoothTextChange(element, newText) {
|
|||||||
<th scope="col">City</th>
|
<th scope="col">City</th>
|
||||||
<th scope="col" style="white-space: nowrap;">Current Date</th>
|
<th scope="col" style="white-space: nowrap;">Current Date</th>
|
||||||
<th scope="col" style="white-space: nowrap;">Best Date</th>
|
<th scope="col" style="white-space: nowrap;">Best Date</th>
|
||||||
<th scope="col">Autobook</th>
|
<th scope="col">Book</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ const pathnameRegex = /^\/\w{2}-\w{2}\/n?iv/;
|
|||||||
const MAX_SIGNIN_ATTEMPTS = 1;
|
const MAX_SIGNIN_ATTEMPTS = 1;
|
||||||
const PAGE_WAIT_TIME = 3792;
|
const PAGE_WAIT_TIME = 3792;
|
||||||
const MINUTE = 60;
|
const MINUTE = 60;
|
||||||
|
const RANDOM_JITTER = 0.1;
|
||||||
const SOFT_BAN_TIMEOUT = 27;
|
const SOFT_BAN_TIMEOUT = 27;
|
||||||
const NOTIF_CHANNEL = "snegov_test"
|
const NOTIF_CHANNEL = "snegov_test"
|
||||||
|
|
||||||
@@ -44,11 +45,15 @@ function getRandomInt(max) {
|
|||||||
return Math.floor(Math.random() * Math.floor(max));
|
return Math.floor(Math.random() * Math.floor(max));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function getJitter(frequency) {
|
||||||
|
return frequency * MINUTE * RANDOM_JITTER;
|
||||||
|
}
|
||||||
|
|
||||||
function getFutureDate(minutes, maxRandomSeconds = 0) {
|
function getFutureDate(minutes, maxRandomSeconds = 0) {
|
||||||
// return date some amount of minutes in future plus random amount of seconds
|
// return date some amount of minutes in future plus random amount of seconds
|
||||||
let futureDate = new Date();
|
let futureDate = new Date();
|
||||||
futureDate.setMinutes(futureDate.getMinutes() + minutes);
|
futureDate.setSeconds(futureDate.getSeconds() + minutes * MINUTE + getRandomInt(maxRandomSeconds));
|
||||||
futureDate.setSeconds(futureDate.getSeconds() + getRandomInt(maxRandomSeconds));
|
|
||||||
return futureDate.toISOString();
|
return futureDate.toISOString();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -86,7 +91,7 @@ function getPathnameParts(pathname) {
|
|||||||
let pathParts = pathname.split('/');
|
let pathParts = pathname.split('/');
|
||||||
let locale = pathParts[1] || 'en-us';
|
let locale = pathParts[1] || 'en-us';
|
||||||
let visaType = pathParts[2] || 'niv';
|
let visaType = pathParts[2] || 'niv';
|
||||||
return { locale, visaType };
|
return [ locale, visaType ];
|
||||||
}
|
}
|
||||||
|
|
||||||
function isSignInPage() {
|
function isSignInPage() {
|
||||||
@@ -124,10 +129,8 @@ async function handleHttpError(e) {
|
|||||||
console.log(msg);
|
console.log(msg);
|
||||||
await sendNotification(msg);
|
await sendNotification(msg);
|
||||||
await logOut();
|
await logOut();
|
||||||
return null;
|
|
||||||
} else {
|
} else {
|
||||||
console.error(e);
|
console.error(e);
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -195,7 +198,7 @@ async function getConsulates() {
|
|||||||
"isSelected": option.selected,
|
"isSelected": option.selected,
|
||||||
"bestDate": null,
|
"bestDate": null,
|
||||||
"currentDate": null,
|
"currentDate": null,
|
||||||
"nextCheckAt": getFutureDate(0, config.frequency * MINUTE),
|
"nextCheckAt": getFutureDate(0, getJitter(config.frequency)),
|
||||||
"autobook": false,
|
"autobook": false,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -206,12 +209,16 @@ async function getAvailableDates(consulateId) {
|
|||||||
let uri = window.location.pathname + `/days/${consulateId}.json?appointments[expedite]=false`
|
let uri = window.location.pathname + `/days/${consulateId}.json?appointments[expedite]=false`
|
||||||
let dates = fetch(uri, { headers: { "x-requested-with": "XMLHttpRequest" }})
|
let dates = fetch(uri, { headers: { "x-requested-with": "XMLHttpRequest" }})
|
||||||
.then(d => d.json())
|
.then(d => d.json())
|
||||||
|
.catch(async e => {
|
||||||
|
await handleHttpError(e);
|
||||||
|
throw e;
|
||||||
|
})
|
||||||
.then(data => {
|
.then(data => {
|
||||||
let dateList = data.map(item => item.date);
|
let dateList = data.map(item => item.date);
|
||||||
dateList.sort();
|
dateList.sort();
|
||||||
return dateList;
|
return dateList;
|
||||||
})
|
})
|
||||||
.catch(async e => handleHttpError(e));
|
.catch(e => null);
|
||||||
return dates;
|
return dates;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -229,8 +236,12 @@ async function getAvailableTimes(consulateId, date) {
|
|||||||
let uri = window.location.pathname + `/times/${consulateId}.json?date=${date}&appointments[expedite]=false`
|
let uri = window.location.pathname + `/times/${consulateId}.json?date=${date}&appointments[expedite]=false`
|
||||||
let times = await fetch(uri, { headers: { "x-requested-with": "XMLHttpRequest" } })
|
let times = await fetch(uri, { headers: { "x-requested-with": "XMLHttpRequest" } })
|
||||||
.then(d => d.json())
|
.then(d => d.json())
|
||||||
|
.catch(async e => {
|
||||||
|
await handleHttpError(e);
|
||||||
|
throw e;
|
||||||
|
})
|
||||||
.then(data => data.available_times)
|
.then(data => data.available_times)
|
||||||
.catch(e => handleHttpError(e));
|
.catch(e => null);
|
||||||
return times;
|
return times;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -247,7 +258,7 @@ async function runner() {
|
|||||||
config.activate = result['__activate'] || false;
|
config.activate = result['__activate'] || false;
|
||||||
config.username = result['__username'] || "";
|
config.username = result['__username'] || "";
|
||||||
config.password = result['__password'] || "";
|
config.password = result['__password'] || "";
|
||||||
config.frequency = parseInt(result['__frequency'] || 1);
|
config.frequency = parseFloat(result['__frequency'] || 1);
|
||||||
config.signinAttempts = result['__signinAttempts'] || 0;
|
config.signinAttempts = result['__signinAttempts'] || 0;
|
||||||
config.apptId = result['__apptId'] || null;
|
config.apptId = result['__apptId'] || null;
|
||||||
config.currentAppt = result['__currentAppt'] || { consulate: null, date: null };
|
config.currentAppt = result['__currentAppt'] || { consulate: null, date: null };
|
||||||
@@ -278,7 +289,7 @@ async function runner() {
|
|||||||
if (key === 'frequency') {
|
if (key === 'frequency') {
|
||||||
let wasChanged = false;
|
let wasChanged = false;
|
||||||
for (let consulate in config.consulates) {
|
for (let consulate in config.consulates) {
|
||||||
let newNextCheckAt = getFutureDate(config.frequency, 10);
|
let newNextCheckAt = getFutureDate(config.frequency, getJitter(config.frequency));
|
||||||
if (config.consulates[consulate].nextCheckAt > newNextCheckAt) {
|
if (config.consulates[consulate].nextCheckAt > newNextCheckAt) {
|
||||||
config.consulates[consulate].nextCheckAt = newNextCheckAt;
|
config.consulates[consulate].nextCheckAt = newNextCheckAt;
|
||||||
wasChanged = true;
|
wasChanged = true;
|
||||||
@@ -334,6 +345,7 @@ async function runner() {
|
|||||||
if (currentHourUTC >= 23 || currentHourUTC < 9) {
|
if (currentHourUTC >= 23 || currentHourUTC < 9) {
|
||||||
// Continue running the code
|
// Continue running the code
|
||||||
} else {
|
} else {
|
||||||
|
await chrome.storage.local.set({ "__status": "not operational hours" });
|
||||||
isRunning = false;
|
isRunning = false;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -507,7 +519,7 @@ async function runner() {
|
|||||||
console.log(msg);
|
console.log(msg);
|
||||||
await chrome.storage.local.set({ "__status": msg });
|
await chrome.storage.local.set({ "__status": msg });
|
||||||
let availDates = await getAvailableDates(config.consulates[consulate].id);
|
let availDates = await getAvailableDates(config.consulates[consulate].id);
|
||||||
config.consulates[consulate].nextCheckAt = getFutureDate(config.frequency, 10);
|
config.consulates[consulate].nextCheckAt = getFutureDate(config.frequency, getJitter(config.frequency));
|
||||||
|
|
||||||
if (!availDates) {
|
if (!availDates) {
|
||||||
msg = `Failed to fetch available dates in ${consulate}`;
|
msg = `Failed to fetch available dates in ${consulate}`;
|
||||||
@@ -529,7 +541,7 @@ async function runner() {
|
|||||||
|
|
||||||
// Only set SOFT_BAN_TIMEOUT if it's not the first 5 minutes of 23pm UTC
|
// Only set SOFT_BAN_TIMEOUT if it's not the first 5 minutes of 23pm UTC
|
||||||
if (!(currentHourUTC === 23 && currentMinuteUTC < 5)) {
|
if (!(currentHourUTC === 23 && currentMinuteUTC < 5)) {
|
||||||
config.consulates[consulate].nextCheckAt = getFutureDate(SOFT_BAN_TIMEOUT, 10);
|
config.consulates[consulate].nextCheckAt = getFutureDate(SOFT_BAN_TIMEOUT, getJitter(config.frequency));
|
||||||
}
|
}
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
|
|||||||
Reference in New Issue
Block a user