Last active
March 1, 2023 13:40
-
-
Save Sillium/0ef7decee63fc57d52a564d9982c0525 to your computer and use it in GitHub Desktop.
Library to fetch data from Telekom API
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
console.log("Test"); | |
class TelekomDataService { | |
/*--- | |
/ STATIC PROPERTIES | |
/---*/ | |
static fileManager = FileManager.iCloud(); | |
static scriptDir = module.filename.replace(TelekomDataService.fileManager.fileName(module.filename, true), ''); | |
static cacheFile = TelekomDataService.fileManager.joinPath(TelekomDataService.scriptDir, "cache.json"); | |
static historyDir = TelekomDataService.fileManager.joinPath(TelekomDataService.scriptDir, "history"); | |
/*--- | |
/ STATIC METHODS | |
/---*/ | |
static #formatVolume(amount, language) { | |
var formatterGiga = new Intl.NumberFormat(language, { | |
style: 'decimal', | |
minimumFractionDigits: 0, | |
maximumFractionDigits: 2 | |
}); | |
let amount_str; | |
if (amount >= 100*1024*1024) { | |
amount_str = formatterGiga.format(amount / (1024*1024*1024)) + " GB"; | |
} else if (amount >= 100*1024) { | |
amount_str = formatterGiga.format(amount / (1024*1024)) + " MB"; | |
} else if (amount >= 100) { | |
amount_str = formatterGiga.format(amount / 1024) + " kB"; | |
} else { | |
amount_str = formatterGiga.format(amount) + " B"; | |
} | |
return amount_str; | |
} | |
/** | |
* Translates seconds into human readable format of seconds, minutes, hours, days, and years | |
* | |
* @param {number} seconds The number of seconds to be processed | |
* @return {string} The phrase describing the amount of time | |
*/ | |
static #forHumans(seconds) { | |
var levels = [ | |
[Math.floor(seconds / 31536000), 'years'], | |
[Math.floor((seconds % 31536000) / 86400), 'days'], | |
[Math.floor(((seconds % 31536000) % 86400) / 3600), 'hours'], | |
[Math.floor((((seconds % 31536000) % 86400) % 3600) / 60), 'minutes'], | |
[(((seconds % 31536000) % 86400) % 3600) % 60, 'seconds'], | |
]; | |
var returntext = ''; | |
for (var i = 0, max = levels.length; i < max; i++) { | |
if ( levels[i][0] === 0 ) continue; | |
returntext += ' ' + levels[i][0] + ' ' + (levels[i][0] === 1 ? levels[i][1].substr(0, levels[i][1].length-1): levels[i][1]); | |
}; | |
return returntext.trim(); | |
} | |
static #makeSureDirectoryExists(dir) { | |
if (TelekomDataService.fileManager.fileExists(dir) && !TelekomDataService.fileManager.isDirectory(dir)) { | |
TelekomDataService.fileManager.remove(dir); | |
} | |
if (!TelekomDataService.fileManager.fileExists(dir)) { | |
TelekomDataService.fileManager.createDirectory(dir, true); | |
} | |
} | |
static async #makeSureFileIsDownloadedFromiCloud(file) { | |
if (TelekomDataService.fileManager.fileExists(file)) { | |
await TelekomDataService.fileManager.downloadFileFromiCloud(file); | |
} | |
} | |
/*--- | |
/ PRIVATE PROPERTIES | |
/---*/ | |
#source = "UNINITIALIZED" | |
#rawData = { | |
additionalData: {} | |
}; | |
#fetchedAt = null; | |
#fetchedByDevice = null; | |
/*--- | |
/ PRIVATE METHODS | |
/---*/ | |
async #writeToCache() { | |
await TelekomDataService.#makeSureFileIsDownloadedFromiCloud(TelekomDataService.cacheFile); | |
TelekomDataService.fileManager.writeString(TelekomDataService.cacheFile, JSON.stringify(this.rawData, null, 2)); | |
} | |
async #writeToHistory() { | |
const dateFormatter = new DateFormatter(); | |
dateFormatter.dateFormat = 'yyyy/MM/dd'; | |
const dayDir = TelekomDataService.fileManager.joinPath(TelekomDataService.historyDir, dateFormatter.string(this.usedAtUTC)); | |
TelekomDataService.#makeSureDirectoryExists(dayDir); | |
dateFormatter.dateFormat = 'HH-mm-ss'; | |
const historyFile = TelekomDataService.fileManager.joinPath(dayDir, dateFormatter.string(this.usedAtUTC) + ".json"); | |
await TelekomDataService.#makeSureFileIsDownloadedFromiCloud(historyFile); | |
TelekomDataService.fileManager.writeString(historyFile, JSON.stringify(this.rawData, null, 2)); | |
const datestr = this.usedAtStr.split(" ")[0]; | |
const year = datestr.split("-")[0]; | |
const month = datestr.split("-")[1]; | |
const day = datestr.split("-")[2]; | |
const lastFileOfDay = TelekomDataService.fileManager.joinPath(TelekomDataService.historyDir, year + "-" + month + "-" + day + ".json"); | |
await TelekomDataService.#makeSureFileIsDownloadedFromiCloud(lastFileOfDay); | |
TelekomDataService.fileManager.writeString(lastFileOfDay, JSON.stringify(this.rawData, null, 2)); | |
const lastFileOfMonth = TelekomDataService.fileManager.joinPath(TelekomDataService.historyDir, year + "-" + month + ".json"); | |
await TelekomDataService.#makeSureFileIsDownloadedFromiCloud(lastFileOfMonth); | |
TelekomDataService.fileManager.writeString(lastFileOfMonth, JSON.stringify(this.rawData, null, 2)); | |
} | |
async #readCachedData() { | |
try { | |
const cacheData = JSON.parse(TelekomDataService.fileManager.readString(TelekomDataService.cacheFile), null); | |
//delete cacheData.additionalData; | |
console.log("Fetched cached data from cache file:\n" + JSON.stringify(cacheData, null, 2)); | |
this.#source = "CACHE"; | |
cacheData.additionalData.source = this.source; | |
this.#rawData = cacheData; | |
} catch(err) { | |
console.log("Error while reading cache file:\n" + err); | |
} | |
} | |
async #readProviderData() { | |
try { | |
const req = new Request("https://pass.telekom.de/api/service/generic/v1/status"); | |
req.headers = { | |
"User-Agent": "Mozilla/5.0 (iPhone; CPU iPhone OS 13_5_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.1.1 Mobile/15E148 Safari/604.1" | |
} | |
const providerData = await req.loadJSON(); | |
console.log("Request object:\n" + JSON.stringify(req, null, 2)); | |
if (isEmpty(providerData)) { | |
throw "Returned data is empty."; | |
} | |
if ('error' in providerData) { | |
throw "Returned data contains error message: " + providerData.error; | |
} | |
console.log("Fetched fresh data from Telekom API:\n" + JSON.stringify(providerData, null, 2)) | |
this.#source = "PROVIDER"; | |
this.#fetchedAt = Date.now(); | |
this.#fetchedByDevice = Device.name(); | |
let additionalData = { | |
//source: this.source, | |
fetchedByDevice: this.fetchedByDevice, | |
availableVolume: this.availableVolume, | |
availableVolumeForHumans: this.availableVolumeForHumans, | |
usedVolumeForHumans: this.usedVolumeForHumans, | |
initialVolumeForHumans: this.initialVolumeForHumans, | |
remainingDays: this.remainingDays, | |
remainingTimeForHumans: this.remainingTimeForHumans, | |
availablePercentage: this.availablePercentage, | |
fetchedAtUTC: this.fetchedAtUTC, | |
fetchedAtUTCMs: this.fetchedAtUTCMs, | |
fetchedAtStr: this.fetchedAtStr, | |
usedAtUTC: this.usedAtUTC, | |
usedAtUTCMs: this.usedAtUTCMs, | |
usedAtStr: this.usedAtStr | |
} | |
this.#rawData = { | |
...providerData, | |
additionalData | |
} | |
this.#writeToCache(); | |
// if (this.#enableWriteToHistory) { | |
this.#writeToHistory(); | |
// } | |
} catch(err) { | |
console.log("Error while accessing Telekom API:\n" + err); | |
} | |
} | |
/*--- | |
/ CONSTRUCTOR | |
/---*/ | |
/* | |
constructor(enableWriteToHistory = true) { | |
this.#enableWriteToHistory = enableWriteToHistory; | |
console.log("TelekomDataService (" + module.filename + ") object instantiated."); | |
} | |
*/ | |
constructor() { | |
console.log("TelekomDataService (" + module.filename + ") object instantiated."); | |
} | |
/*--- | |
/ PUBLIC METHODS | |
/---*/ | |
async update() { | |
await this.#readCachedData(); | |
await this.#readProviderData(); | |
} | |
get rawData() { | |
return this.#rawData; | |
} | |
get data() { | |
let data = { | |
...this.rawData | |
} | |
data.additionalData.source = this.source; | |
return data; | |
} | |
get source() { | |
return this.#source; | |
} | |
get usedAt() { | |
if (isEmpty(this.rawData)) { | |
return null; | |
} | |
return this.rawData.usedAt; | |
} | |
get initialVolume() { | |
if (isEmpty(this.rawData)) { | |
return null; | |
} | |
return this.rawData.initialVolume; | |
} | |
get initialVolumeStr() { | |
if (isEmpty(this.rawData)) { | |
return null; | |
} | |
return this.rawData.initialVolumeStr; | |
} | |
get usedVolume() { | |
if (isEmpty(this.rawData)) { | |
return null; | |
} | |
return this.rawData.usedVolume; | |
} | |
get usedVolumeStr() { | |
if (isEmpty(this.rawData)) { | |
return null; | |
} | |
return this.rawData.usedVolumeStr; | |
} | |
get usedPercentage() { | |
if (isEmpty(this.rawData)) { | |
return null; | |
} | |
return this.rawData.usedPercentage; | |
} | |
get remainingSeconds() { | |
if (isEmpty(this.rawData)) { | |
return null; | |
} | |
return this.rawData.remainingSeconds; | |
} | |
get remainingTimeStr() { | |
if (isEmpty(this.rawData)) { | |
return null; | |
} | |
return this.rawData.remainingTimeStr; | |
} | |
get availableVolume() { | |
if (isEmpty(this.rawData)) { | |
return null; | |
} | |
return this.initialVolume - this.usedVolume; | |
} | |
get availableVolumeForHumans() { | |
if (isEmpty(this.rawData)) { | |
return null; | |
} | |
return TelekomDataService.#formatVolume(this.availableVolume, 'en'); | |
} | |
get initialVolumeForHumans() { | |
if (isEmpty(this.rawData)) { | |
return null; | |
} | |
return TelekomDataService.#formatVolume(this.initialVolume, 'en'); | |
} | |
get usedVolumeForHumans() { | |
if (isEmpty(this.rawData)) { | |
return null; | |
} | |
return TelekomDataService.#formatVolume(this.usedVolume, 'en'); | |
} | |
get remainingDays() { | |
if (isEmpty(this.rawData)) { | |
return null; | |
} | |
return Math.floor(this.remainingSeconds / (24 * 60 * 60)); | |
} | |
get remainingTimeForHumans() { | |
if (isEmpty(this.rawData)) { | |
return null; | |
} | |
return TelekomDataService.#forHumans(this.remainingSeconds); | |
} | |
get availablePercentage() { | |
if (isEmpty(this.rawData)) { | |
return null; | |
} | |
return 100 - this.usedPercentage; | |
} | |
get fetchedByDevice() { | |
return this.#fetchedByDevice; | |
} | |
get fetchedAt() { | |
return this.#fetchedAt; | |
} | |
get fetchedAtUTC() { | |
if (!!this.fetchedAt) { | |
var fetchedAt = new Date(); | |
fetchedAt.setTime(this.fetchedAt); | |
return fetchedAt; | |
} | |
return null; | |
} | |
get fetchedAtUTCMs() { | |
if (!!this.fetchedAtUTC) { | |
return this.fetchedAtUTC.getTime(); | |
} | |
return null; | |
} | |
get fetchedAtStr() { | |
if (!!this.fetchedAtUTC) { | |
let dF = new DateFormatter(); | |
dF.dateFormat = 'yyyy-MM-dd HH-mm-ss'; | |
return dF.string(this.fetchedAtUTC); | |
} | |
return null; | |
} | |
get usedAtUTC() { | |
if (isEmpty(this.rawData)) { | |
return null; | |
} | |
var usedAt = new Date(); | |
usedAt.setTime(this.rawData.usedAt); | |
return usedAt; | |
} | |
get usedAtUTCMs() { | |
if (isEmpty(this.rawData)) { | |
return null; | |
} | |
return this.usedAtUTC.getTime(); | |
} | |
get usedAtStr() { | |
if (isEmpty(this.rawData)) { | |
return null; | |
} | |
let dF = new DateFormatter(); | |
dF.dateFormat = 'yyyy-MM-dd HH-mm-ss'; | |
return dF.string(this.usedAtUTC); | |
} | |
} | |
module.exports = TelekomDataService; | |
function isEmpty(obj) { | |
return Object.keys(obj).length === 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment