Advertisement
Guest User

Test

a guest
Feb 17th, 2021
137
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. const DEBUG = false
  2.  
  3. const lerp = (x, y, a) => x * (1 - a) + y * a;
  4. const clamp = (a, min = 0, max = 1) => Math.min(max, Math.max(min, a));
  5. const invlerp = (x, y, a) => clamp((a - x) / (y - x));
  6. const range = (x1, y1, x2, y2, a) => lerp(x2, y2, invlerp(x1, y1, a));
  7.  
  8. function formatText(text, font) {
  9.     text.textColor = new Color('#ffffff')
  10.     text.centerAlignText()
  11.     text.font = font
  12. }
  13.  
  14. async function showAlert(title, message, options) {
  15.     let alert = new Alert()
  16.     alert.title = title
  17.     alert.message = message
  18.     options.forEach(option => {
  19.         alert.addAction(option)
  20.     })
  21.     return await alert.presentAlert()
  22. }
  23.  
  24. const igWidget = {
  25.    
  26.     initialize(iCloudInUse = true) {
  27.         this.username = args.widgetParameter || 'unsplash'
  28.         this.fm = iCloudInUse ? FileManager.iCloud() : FileManager.local()
  29.         this.root = this.fm.documentsDirectory() + '/IGWidget'
  30.         this.cachePath = this.root + '/cache.json'
  31.         this.profileCachePath = this.root + `/Profiles/${this.username}.cache`
  32.         this.logPath = this.root + `/Logs/${this.username}.log`
  33.         this.user = {}
  34.         this.sessionid = ''
  35.     },
  36.  
  37.     async authorize() {
  38.         let url = 'https://instagram.com/'
  39.         let req = new Request(url)
  40.         await req.load()
  41.         let result = {}
  42.         req.response.cookies.forEach(cookie => {
  43.             if (cookie.name == 'sessionid') {result.sessionid = cookie.value; result.expiresDate = cookie.expiresDate}
  44.         })
  45.         if (! result.sessionid) {
  46.             if (config.runsInWidget) {throw 'You have to run this script inside the app first'}
  47.             await showAlert('Instagram login', 'You will have to login to instagram', ['Continue'])
  48.             let webview = new WebView()
  49.             await webview.loadURL(url)
  50.             await webview.present(false)
  51.             return await this.authorize()
  52.         } else {
  53.             await this.writeJSONTo(result, this.cachePath)
  54.             this.sessionid = result.sessionid
  55.             return result
  56.         }
  57.     },
  58.  
  59.     async logout() {
  60.         let req = new Request('https://www.instagram.com/accounts/logout')
  61.         await req.load()
  62.         if (this.fm.fileExists(this.cachePath)) {await this.fm.remove(this.cachePath)}
  63.     },
  64.  
  65.     async fetchData() {
  66.         const url = `https://www.instagram.com/${this.username}/?__a=1`
  67.         let req = new Request(url)
  68.         req.headers = {
  69.             'Cookie': `sessionid=${this.sessionid}`
  70.         }
  71.         try {
  72.             var response = await req.loadJSON()
  73.         } catch (Error) {
  74.             throw "Something went wrong. Try deleting the cache."
  75.         }
  76.         response.graphql.user.last_updated = Date.now()
  77.         this.user = response.graphql.user
  78.         await this.writeJSONTo(this.user, this.profileCachePath)
  79.         await this.logData()
  80.         return this.user
  81.     },
  82.  
  83.     getProfileInfo() {
  84.         let result = {
  85.             fbid: this.user.fbid,
  86.             id: this.user.id,
  87.             name: this.user.full_name,
  88.             username: this.user.username,
  89.             media_count: this.user.edge_owner_to_timeline_media.count,
  90.             followers: this.user.edge_followed_by.count,
  91.             following: this.user.edge_follow.count,
  92.             profile_pic_url: this.user.profile_pic_url_hd || this.user.profile_pic_url
  93.         }
  94.         return result
  95.     },
  96.  
  97.     getMediaData() {
  98.         let result = {
  99.             imageData: this.user.edge_owner_to_timeline_media.edges
  100.         }
  101.         return result
  102.     },
  103.  
  104.     async getJSONFrom(path) {
  105.         if (this.fm.fileExists(path)) {
  106.             if (! this.fm.isFileDownloaded(path)) {await this.fm.downloadFileFromiCloud(path)}
  107.             let result = await this.fm.read(path)
  108.             if (! result || ! result.toRawString()) return undefined
  109.             else return JSON.parse(result.toRawString())
  110.         }
  111.         return undefined
  112.     },
  113.  
  114.     async writeJSONTo(json, path) {
  115.         let filename = this.fm.fileName(path, true)
  116.         let s = path.split('/')
  117.         s.pop()
  118.         let dir = s.join('/')
  119.         if (! this.fm.isDirectory(dir)) {
  120.             this.fm.createDirectory(dir, true)
  121.         }
  122.         await this.fm.writeString(path, JSON.stringify(json))
  123.     },
  124.  
  125.     async logData() {
  126.         let data = this.getProfileInfo()
  127.         let logTime = String(Date.now())
  128.         let log = await this.getJSONFrom(this.logPath)
  129.         log = (log == undefined) ? {} : log
  130.         log[logTime] = {
  131.             followers: data.followers,
  132.             following: data.following,
  133.             media_count: data.media_count
  134.         }
  135.         let s = this.logPath.split('/')
  136.         s.pop()
  137.         let dir = s.join('/')
  138.         if (!this.fm.isDirectory(dir)) {await this.fm.createDirectory(dir, true)}
  139.         await this.fm.writeString(this.logPath, JSON.stringify(log))
  140.     },
  141.  
  142.     async showJSON() {
  143.         let table = new UITable()
  144.         for (let key in this.user) {
  145.             //console.log(`${key}: ${this.user[key]}`)
  146.             let row = new UITableRow()
  147.             let valueText = row.addText(String(this.user[key]), String(key))
  148.             table.addRow(row)
  149.         }
  150.         table.showSeparators = true
  151.         await table.present(false)
  152.     },
  153.  
  154.     async createDebugWidget() {
  155.         let user = this.getProfileInfo()
  156.         let widget = new ListWidget()
  157.         var stack = widget.addStack()
  158.         var text = widget.addText(JSON.stringify(user))
  159.         text.font = Font.regularRoundedSystemFont(5)
  160.         return widget
  161.     },
  162.  
  163.     async createSmallWidget() {
  164.         let user = this.getProfileInfo()
  165.         let widget = new ListWidget()
  166.         widget.setPadding(13, 0, 13, 0) // top, leading, bottom, trailing
  167.         var widgetRows = widget.addStack()
  168.         widgetRows.layoutVertically()
  169.         widgetRows.url = `https://www.instagram.com/${this.username}`
  170.        
  171.         // gackground gradient
  172.         var gradient = new LinearGradient()
  173.         gradient.colors = [new Color('#8134AF'), new Color('#DD2A7B'), new Color('#FEDA77')]
  174.         gradient.locations = [0.0,0.5,1.0]
  175.         gradient.startPoint = new Point(1,0)
  176.         gradient.endPoint
  177.         widget.backgroundGradient = gradient
  178.        
  179.         // username
  180.         var usernameRow = widgetRows.addStack()
  181.         usernameRow.url = `https://www.instagram.com/${this.username}`
  182.         usernameRow.layoutHorizontally()
  183.         usernameRow.addSpacer()
  184.         if (user.profile_pic_url) {
  185.             var req = new Request(user.profile_pic_url)
  186.             var img = await req.loadImage()
  187.             var image = usernameRow.addImage(img)
  188.             image.imageSize = new Size(24, 24)
  189.             image.cornerRadius = 12
  190.             usernameRow.addSpacer(3)
  191.         }
  192.         var usernameText = usernameRow.addText(`${this.username}`)
  193.         formatText(usernameText, Font.semiboldRoundedSystemFont(12))
  194.         usernameRow.addSpacer()
  195.         usernameRow.setPadding(0, 0, 15, 0)
  196.         usernameRow.centerAlignContent()
  197.        
  198.         // followers
  199.         var followerCountRow = widgetRows.addStack()
  200.         followerCountRow.layoutHorizontally()
  201.         followerCountRow.addSpacer()
  202.         var followerCount = followerCountRow.addText(`${user.followers}`)
  203.         formatText(followerCount, Font.heavyRoundedSystemFont(20))
  204.         followerCountRow.addSpacer()
  205.         followerCountRow.setPadding(0, 0, -3, 0)
  206.         var followerTextRow = widgetRows.addStack()
  207.         followerTextRow.layoutHorizontally()
  208.         followerTextRow.addSpacer()
  209.         var followerText = followerTextRow.addText('Followers')
  210.         formatText(followerText, Font.regularRoundedSystemFont(8))
  211.         followerTextRow.addSpacer()
  212.         followerTextRow.setPadding(0, 0, 15, 0)
  213.        
  214.         // media count
  215.         var mediaCountRow = widgetRows.addStack()
  216.         mediaCountRow.layoutHorizontally()
  217.         mediaCountRow.addSpacer()
  218.         var mediaCount = mediaCountRow.addText(`${user.media_count}`)
  219.         formatText(mediaCount, Font.heavyRoundedSystemFont(20))
  220.         mediaCountRow.addSpacer()
  221.         mediaCountRow.setPadding(0, 0, -3, 0)
  222.         var mediaTextRow = widgetRows.addStack()
  223.         mediaTextRow.layoutHorizontally()
  224.         mediaTextRow.addSpacer()
  225.         var mediaText = mediaTextRow.addText('Pictures')
  226.         formatText(mediaText, Font.regularRoundedSystemFont(8))
  227.         mediaTextRow.addSpacer()
  228.        
  229.         widget.addSpacer() // push everything up
  230.         return widget
  231.     },
  232.  
  233.     async createMediumWidget() {
  234.         let widget = new ListWidget()
  235.         var data = this.getMediaData()
  236.         var imageCount = data.imageData.length
  237.         //console.log(imageCount)
  238.         var randomImages = []
  239.         var usedIndices = []
  240.         for (i=0; i < 3; i++) {
  241.             do {
  242.                 var randomIndex = Math.floor(Math.random() * data.imageData.length)
  243.             } while (usedIndices.includes(randomIndex) && imageCount > 0)
  244.             var datum = data.imageData[randomIndex].node
  245.             var url = (datum.__typename == "GraphVideo") ? datum.thumbnail_src : datum.display_url
  246.             //console.log(url)
  247.             var req = new Request(url)
  248.             req.headers = {
  249.                 'Cookie': `sessionid=${this.session}`
  250.             }
  251.             var image = await req.loadImage()
  252.             imageCount--
  253.             usedIndices.push(randomIndex)
  254.             randomImages.push(image)
  255.         }
  256.        
  257.         widget.addSpacer()
  258.         var imagesRow = widget.addStack()
  259.         imagesRow.layoutHorizontally()
  260.         imagesRow.addSpacer()
  261.         let square = (Device.screenSize().height < Device.screenSize().width) ? Device.screenSize().height : Device.screenSize().width
  262.         square = square/4
  263.         for (i=0; i < randomImages.length; i++) {
  264.             var rect = imagesRow.addStack()
  265.             rect.size = new Size (square,square)
  266.             var wImage = rect.addImage(randomImages[i])
  267.             wImage.applyFillingContentMode()
  268.             if (i != randomImages.length - 1) {imagesRow.addSpacer()}
  269.             //wImage.imageSize = new Size(100,100)
  270.         }
  271.         imagesRow.addSpacer()
  272.         widget.addSpacer()
  273.         return widget
  274.     },
  275.  
  276.     async createLargeWidget() {
  277.         let user = this.getProfileInfo()
  278.         var widget = new ListWidget()
  279.         widget.setPadding(13, 0, 13, 0) // top, leading, bottom, trailing
  280.         var widgetRows = widget.addStack()
  281.         widgetRows.layoutVertically()
  282.        
  283.         // username
  284.         var usernameRow = widgetRows.addStack()
  285.         usernameRow.layoutHorizontally()
  286.         usernameRow.addSpacer()
  287.         if (user.profile_pic_url) {
  288.             var req = new Request(user.profile_pic_url)
  289.             var img = await req.loadImage()
  290.             var image = usernameRow.addImage(img)
  291.             image.imageSize = new Size(24, 24)
  292.             image.cornerRadius = 12
  293.             usernameRow.addSpacer(3)
  294.         }
  295.         var usernameText = usernameRow.addText(`${user.username}`)
  296.         usernameText.font = Font.boldRoundedSystemFont(12)
  297.         usernameRow.addSpacer()
  298.         usernameRow.setPadding(0, 0, 15, 0)
  299.         usernameRow.centerAlignContent()
  300.        
  301.         var log = await this.getJSONFrom(this.logPath)
  302.         var xs = []
  303.         var ys = []
  304.         for (let entry in log) {
  305.             if (entry >= Date.now() - 24*60*60*1000) {
  306.                 xs.push(parseInt(entry))
  307.                 ys.push(log[entry].followers)
  308.             }
  309.         }
  310.         var maxX = Math.max(...xs)
  311.         var minX = Math.min(...xs)
  312.         var maxY = Math.max(...ys)
  313.         var minY = Math.min(...ys)
  314.        
  315.         for (i=0; i < xs.length; i++) { // xs & ys are same length
  316.             xs[i] = range(minX, maxX, 1, 199, xs[i])
  317.             ys[i] = (minY == maxY) ? 100 : range(minY, maxY, 199, 1, ys[i])
  318.         }
  319.         var points = []
  320.         for (i=0; i < xs.length ; i++) { // xs & ys still same length
  321.             let p = new Point(xs[i],ys[i])
  322.             points.push(p)
  323.         }
  324.        
  325.         var graphRow = widget.addStack()
  326.         graphRow.layoutHorizontally()
  327.         graphRow.addSpacer()
  328.         var drawing = new DrawContext()
  329.         drawing.opaque = false
  330.         drawing.respectScreenScale = true
  331.         var graph = new Path()
  332.         graph.addLines(points)
  333.         drawing.addPath(graph)
  334.         drawing.setStrokeColor(new Color('#0000ff'))
  335.         drawing.setLineWidth(0.5)
  336.         drawing.strokePath()
  337.         var path = new Path()
  338.         path.addLines([new Point(0,0), new Point(0,200), new Point(200,200)])
  339.         drawing.addPath(path)
  340.         var blackWhite = Color.dynamic(new Color('#000000'), new Color('#ffffff'))
  341.         drawing.setLineWidth(1)
  342.         drawing.setStrokeColor(blackWhite)
  343.         drawing.strokePath()
  344.         var img = drawing.getImage()
  345.         var graph = graphRow.addImage(img)
  346.         graphRow.addSpacer()
  347.            
  348.         widget.addSpacer()
  349.        
  350.         return widget
  351.     }
  352. }
  353.  
  354. igWidget.initialize(true)
  355.  
  356. var sessionCache = await igWidget.getJSONFrom(igWidget.cachePath)
  357. if (! sessionCache || new Date() >= new Date(sessionCache.expiresDate)) { console.log('Refreshing session cache'); sessionCache = await igWidget.authorize() }
  358. igWidget.sessionid = sessionCache.sessionid
  359.  
  360. var userCache = await igWidget.getJSONFrom(igWidget.profileCachePath)
  361. if (!userCache || new Date() >= new Date(userCache.last_updated + 60*60*1000)) { console.log('Refreshing user cache'); userCache = await igWidget.fetchData() }
  362. igWidget.user = userCache
  363.  
  364. if (config.runsInApp) {
  365.     var w = await igWidget.createMediumWidget()
  366.     await w.presentMedium()
  367. } else if (config.runsInWidget) {
  368.     switch (config.widgetFamily) {
  369.         case 'small':
  370.             var w = await igWidget.createSmallWidget()
  371.             break
  372.         case 'medium':
  373.             var w = await igWidget.createMediumWidget()
  374.             break
  375.         case 'large':
  376.             var w = await igWidget.createLargeWidget()
  377.             break
  378.     }
  379.     Script.setWidget(w)
  380. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement