7 Commits

Author SHA1 Message Date
776b0afdab Bump version 2024-04-26 23:46:14 -07:00
c428e4ab11 Probably fix HTTP 401 2024-04-26 23:45:56 -07:00
d19b9ced8f Update frequency config
- Set values from 0.5 to 10 with 0.5 step
- Add random increment equal to 10% of frequency parameter
2024-04-26 23:16:59 -07:00
4a506de6fe Fix error in getPathnameParts() 2024-04-26 22:35:51 -07:00
2070cdb30a Add status for non operational hours 2024-04-26 02:53:55 -07:00
fcb9f9dbf3 Bump version 2024-04-26 02:36:22 -07:00
094e2d2b81 UI rearrangement 2024-04-26 02:36:05 -07:00
4 changed files with 34 additions and 21 deletions

View File

@@ -1,7 +1,7 @@
{
"manifest_version": 3,
"name": "not-a-rescheduler",
"version": "0.0.1",
"version": "0.0.3",
"permissions": [ "storage", "tabs", "activeTab", "notifications", "declarativeContent" ],
"content_scripts": [
{

View File

@@ -55,7 +55,7 @@
<label for="frequency">Check frequency<br>(every <span id="frequency_info">N</span> minutes)</label>
</div>
<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 class="row">
@@ -75,12 +75,7 @@
</div>
</div>
<!-- consulates -->
<div class="row">
<div class="col">Consulates:</div>
</div>
<div id="consulatesConfig">
</div>
<!-- current appointment -->
<div class="row">
<div class="col">
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>
</div>
</div>
<!-- consulates -->
<div id="consulatesConfig">
</div>
<!-- buttons -->
<div class="row">
<div class="col">
<button type="button" class="btn btn-info btn-sm" id="showConfigButton">Config</button>

View File

@@ -107,7 +107,7 @@ function smoothTextChange(element, newText) {
<th scope="col">City</th>
<th scope="col" style="white-space: nowrap;">Current Date</th>
<th scope="col" style="white-space: nowrap;">Best Date</th>
<th scope="col">Autobook</th>
<th scope="col">Book</th>
</tr>
</thead>
<tbody>

View File

@@ -5,6 +5,7 @@ const pathnameRegex = /^\/\w{2}-\w{2}\/n?iv/;
const MAX_SIGNIN_ATTEMPTS = 1;
const PAGE_WAIT_TIME = 3792;
const MINUTE = 60;
const RANDOM_JITTER = 0.1;
const SOFT_BAN_TIMEOUT = 27;
const NOTIF_CHANNEL = "snegov_test"
@@ -44,11 +45,15 @@ function getRandomInt(max) {
return Math.floor(Math.random() * Math.floor(max));
}
function getJitter(frequency) {
return frequency * MINUTE * RANDOM_JITTER;
}
function getFutureDate(minutes, maxRandomSeconds = 0) {
// return date some amount of minutes in future plus random amount of seconds
let futureDate = new Date();
futureDate.setMinutes(futureDate.getMinutes() + minutes);
futureDate.setSeconds(futureDate.getSeconds() + getRandomInt(maxRandomSeconds));
futureDate.setSeconds(futureDate.getSeconds() + minutes * MINUTE + getRandomInt(maxRandomSeconds));
return futureDate.toISOString();
}
@@ -86,7 +91,7 @@ function getPathnameParts(pathname) {
let pathParts = pathname.split('/');
let locale = pathParts[1] || 'en-us';
let visaType = pathParts[2] || 'niv';
return { locale, visaType };
return [ locale, visaType ];
}
function isSignInPage() {
@@ -124,10 +129,8 @@ async function handleHttpError(e) {
console.log(msg);
await sendNotification(msg);
await logOut();
return null;
} else {
console.error(e);
return null;
}
}
@@ -195,7 +198,7 @@ async function getConsulates() {
"isSelected": option.selected,
"bestDate": null,
"currentDate": null,
"nextCheckAt": getFutureDate(0, config.frequency * MINUTE),
"nextCheckAt": getFutureDate(0, getJitter(config.frequency)),
"autobook": false,
};
}
@@ -206,12 +209,16 @@ async function getAvailableDates(consulateId) {
let uri = window.location.pathname + `/days/${consulateId}.json?appointments[expedite]=false`
let dates = fetch(uri, { headers: { "x-requested-with": "XMLHttpRequest" }})
.then(d => d.json())
.catch(async e => {
await handleHttpError(e);
throw e;
})
.then(data => {
let dateList = data.map(item => item.date);
dateList.sort();
return dateList;
})
.catch(async e => handleHttpError(e));
.catch(e => null);
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 times = await fetch(uri, { headers: { "x-requested-with": "XMLHttpRequest" } })
.then(d => d.json())
.catch(async e => {
await handleHttpError(e);
throw e;
})
.then(data => data.available_times)
.catch(e => handleHttpError(e));
.catch(e => null);
return times;
}
@@ -247,7 +258,7 @@ async function runner() {
config.activate = result['__activate'] || false;
config.username = result['__username'] || "";
config.password = result['__password'] || "";
config.frequency = parseInt(result['__frequency'] || 1);
config.frequency = parseFloat(result['__frequency'] || 1);
config.signinAttempts = result['__signinAttempts'] || 0;
config.apptId = result['__apptId'] || null;
config.currentAppt = result['__currentAppt'] || { consulate: null, date: null };
@@ -278,7 +289,7 @@ async function runner() {
if (key === 'frequency') {
let wasChanged = false;
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) {
config.consulates[consulate].nextCheckAt = newNextCheckAt;
wasChanged = true;
@@ -334,6 +345,7 @@ async function runner() {
if (currentHourUTC >= 23 || currentHourUTC < 9) {
// Continue running the code
} else {
await chrome.storage.local.set({ "__status": "not operational hours" });
isRunning = false;
return;
}
@@ -507,7 +519,7 @@ async function runner() {
console.log(msg);
await chrome.storage.local.set({ "__status": msg });
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) {
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
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;