diff --git a/src/lib/cache.js b/src/lib/cache.js index 59ff25a..8cdb10c 100644 --- a/src/lib/cache.js +++ b/src/lib/cache.js @@ -55,7 +55,7 @@ class TtlCache { */ getTtl(key, factor = 1) { if (this.has(key)) { - return Math.max((Math.floor(Date.now() - this.cache.get(key).time) / factor), 0) + return Math.max(Math.ceil((this.cache.get(key).time + this.ttl - Date.now()) / factor), 0) } else { return null } diff --git a/src/lib/collectors.js b/src/lib/collectors.js index 3d73443..05d36e7 100644 --- a/src/lib/collectors.js +++ b/src/lib/collectors.js @@ -11,7 +11,8 @@ const timelineEntryCache = new TtlCache(constants.caching.resource_cache_time) function fetchUser(username) { return requestCache.getOrFetch("user/"+username, () => { return request(`https://www.instagram.com/${username}/`).then(res => { - if (res.status === 404) throw constants.symbols.NOT_FOUND + if (res.status === 302) throw constants.symbols.INSTAGRAM_DEMANDS_LOGIN + else if (res.status === 404) throw constants.symbols.NOT_FOUND else return res.text().then(text => { // require down here or have to deal with require loop. require cache will take care of it anyway. // User -> Timeline -> TimelineImage -> collectors -/> User diff --git a/src/lib/constants.js b/src/lib/constants.js index 2b0b5a7..b525a8a 100644 --- a/src/lib/constants.js +++ b/src/lib/constants.js @@ -37,7 +37,8 @@ let constants = { TYPE_GALLERY_IMAGE: Symbol("TYPE_GALLERY_IMAGE"), TYPE_GALLERY_VIDEO: Symbol("TYPE_GALLERY_VIDEO"), NOT_FOUND: Symbol("NOT_FOUND"), - NO_SHARED_DATA: Symbol("NO_SHARED_DATA") + NO_SHARED_DATA: Symbol("NO_SHARED_DATA"), + INSTAGRAM_DEMANDS_LOGIN: Symbol("INSTAGRAM_DEMANDS_LOGIN") } } diff --git a/src/lib/utils/request.js b/src/lib/utils/request.js index e7ce324..fac3bb4 100644 --- a/src/lib/utils/request.js +++ b/src/lib/utils/request.js @@ -5,7 +5,8 @@ function request(url) { return fetch(url, { headers: { "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.169 Safari/537.36" - } + }, + redirect: "manual" }) } diff --git a/src/site/api/routes.js b/src/site/api/routes.js index f756786..2e11267 100644 --- a/src/site/api/routes.js +++ b/src/site/api/routes.js @@ -1,6 +1,7 @@ const constants = require("../../lib/constants") -const {fetchUser, getOrFetchShortcode} = require("../../lib/collectors") +const {fetchUser, getOrFetchShortcode, requestCache} = require("../../lib/collectors") const {render, redirect} = require("pinski/plugins") +const {pugCache} = require("../passthrough") module.exports = [ { @@ -37,6 +38,17 @@ module.exports = [ title: "Not found", message: "This user doesn't exist." }) + } else if (error === constants.symbols.INSTAGRAM_DEMANDS_LOGIN) { + return { + statusCode: 503, + contentType: "text/html", + headers: { + "Retry-After": requestCache.getTtl("user/"+fill[0], 1000) + }, + content: pugCache.get("pug/blocked.pug").web({ + expiresMinutes: requestCache.getTtl("user/"+fill[0], 1000*60) + }) + } } else { throw error } diff --git a/src/site/pug/blocked.pug b/src/site/pug/blocked.pug new file mode 100644 index 0000000..4f0183d --- /dev/null +++ b/src/site/pug/blocked.pug @@ -0,0 +1,19 @@ +//- Needs expiresMinutes, instancesURL + +include includes/error.pug + +- const numberFormat = new Intl.NumberFormat().format + +doctype html +html + head + meta(charset="utf-8") + meta(name="viewport" content="width=device-width, initial-scale=1") + title= `Blocked | Bibliogram` + link(rel="stylesheet" type="text/css" href="/static/css/main.css") + body.error-page + +error(503, "Blocked by Instagram") + | Instagram is refusing to provide data to this server. Try again later to see if the block has been lifted. + | This error has been cached. The internal cache will expire in #{expiresMinutes} minutes. + | + a(href="https://github.com/cloudrac3r/bibliogram/wiki/Instances") You could try browsing Bibliogram on another instance. diff --git a/src/site/pug/friendlyerror.pug b/src/site/pug/friendlyerror.pug index 58ff684..3fc241e 100644 --- a/src/site/pug/friendlyerror.pug +++ b/src/site/pug/friendlyerror.pug @@ -1,7 +1,6 @@ -//- Needs title, message, statusCode +//- Needs title, message, statusCode ?explanation -include includes/timeline_page.pug -include includes/next_page_button.pug +include includes/error.pug - const numberFormat = new Intl.NumberFormat().format @@ -13,8 +12,6 @@ html title= `${title} | Bibliogram` link(rel="stylesheet" type="text/css" href="/static/css/main.css") body.error-page - h1.code= statusCode - p.message= message - if explanation - p.explanation= explanation - a(href="javascript:history.back()").back ← Go back? + +error(statusCode, message) + if explanation + =explanation diff --git a/src/site/pug/includes/error.pug b/src/site/pug/includes/error.pug new file mode 100644 index 0000000..b30aef7 --- /dev/null +++ b/src/site/pug/includes/error.pug @@ -0,0 +1,7 @@ +mixin error(statusCode, message) + h1.code= statusCode + p.message= message + if block + p.explanation + block + a(href="javascript:history.back()").back ← Go back? diff --git a/src/site/sass/main.sass b/src/site/sass/main.sass index be26e19..7b16e45 100644 --- a/src/site/sass/main.sass +++ b/src/site/sass/main.sass @@ -295,6 +295,9 @@ body justify-content: center align-items: center + a, a:visited + color: #4a93d2 + .code, .message, .explanation, .back-link line-height: 1.2 margin: 0px @@ -309,13 +312,14 @@ body color: #ccc .explanation + line-height: 1.3 margin-top: 10px font-size: 20px color: #bbb + white-space: pre-line .back margin-top: 15vh - color: #4a93d2 font-size: 25px .homepage