# @name Instagram # @desc Follower count of an Instagram profile # @author Blueforcer # @version 2.0 # @config user text "Profile name" default="blueforcer" maxlen=32 class Instagram var url, user, period var count, label, full, err var ticks, busy var opts, px, ramp def init() self.user = store.get("user") self.url = "https://www.instagram.com/api/v1/users/web_profile_info/?username=" + self.user self.period = 3600 # once an hour # Last known value, but only if it belongs to the profile now configured. self.count = store.get("who") == self.user ? store.get("n") : nil self.label = self.count == nil ? nil : self.human(self.count) self.full = self.count == nil ? nil : str(self.count) self.err = false self.ticks = 9 self.busy = false self.opts = {'headers': {'X-IG-App-ID': '936619743392459', 'User-Agent': 'Mozilla/5.0'}, 'find': "edge_followed_by\":{\"count\":", 'keep': 48} self.px = [0x605D5B5B, 0x64666462, 0x7F7F7F60, 0x667F7F7F, 0x62607F63, 0x6B7F7F64, 0x7F6A7F6A, 0x707F707F, 0x7F707F70, 0x737F737F, 0x090D7F77, 0x777F0305, 0x7F7F7F0C, 0x037F7F7F, 0x0D111415, 0x76010509] self.ramp = [0x833AB4, 0xFCAF45] end def human(n) if n < 1000 return str(n) end var d = 1000 var suf = "K" if n >= 1000000000 d = 1000000000 suf = "B" elif n >= 1000000 d = 1000000 suf = "M" end var v = n / (d + 0.0) if v >= 10 return str(round(v)) + suf end var t = round(v * 10) return str(int(t / 10)) + "." + str(t % 10) + suf end def on_body(body, status) self.busy = false shared.set("f", 0) if status != 200 || body == nil self.err = true return end var m = re.search("(\\d+)", body) if m == nil self.err = true return end var n = num(m[1]) if n == nil return end self.err = false if n == self.count return end self.count = n self.full = str(n) self.label = self.human(n) store.set("n", n) store.set("who", self.user) end def tls_busy() for k : shared.keys() if size(k) > 2 && k[size(k) - 2 .. size(k) - 1] == ".f" && shared.get(k) == 1 var a = shared.age(k) if a != nil && a < 20000 return true end end end return false end def loop() if self.ticks <= 0 if !self.busy && !self.tls_busy() self.ticks = self.period self.busy = true shared.set("f", 1) http.get(self.url, / b, st -> self.on_body(b, st), self.opts) end end self.ticks -= 1 end def draw() clear() for y : 0 .. 7 for x : 0 .. 7 var i = y * 8 + x var v = (self.px[i / 4] >> ((i % 4) * 8)) & 255 pixel(x, y, v == 127 ? 0xFFFFFF : hsv(v * 3, 100, 100)) end end if self.label != nil var avail = width() - 9 var s = self.full var w = text_ink_width(s) if w > avail s = self.label w = text_ink_width(s) end ramp_text(9 + (avail - w) / 2, 6, s, self.ramp) return end var s = self.err ? "?" : "..." var w = text_ink_width(s) text(9 + (width() - 9 - w) / 2, 6, s, self.err ? 0xCC7722 : 0x555555) end end return Instagram()