Guest User

Untitled

a guest
Nov 11th, 2020
92
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.45 KB | None | 0 0
  1. // Variables used by Scriptable.
  2. // These must be at the very top of the file. Do not edit.
  3. // icon-color: red; icon-glyph: calendar-alt;
  4.  
  5. // This widget was created by Max Zeryck @mzeryck
  6.  
  7. // Note: before using this script in a widget, change const TEST_MODE to true and run it in the Scriptable app.
  8. // The app will prompt you to give calendar access, and then show a preview of the widget.
  9. // Make sure to change it back to const TEST_MODE = false prior to adding it to a widget. Happy coding!
  10.  
  11. const IMAGE_SOURCE = "Unsplash"
  12. const TERMS = "nature,water"
  13.  
  14. const FORCE_IMAGE_UPDATE = false
  15. const TEST_MODE = false
  16.  
  17. // Store current datetime
  18. const date = new Date()
  19.  
  20. // If we're running the script normally, go to the Calendar.
  21. if (!config.runsInWidget && !TEST_MODE) {
  22. const appleDate = new Date('2001/01/01')
  23. const timestamp = (date.getTime() - appleDate.getTime()) / 1000
  24. const callback = new CallbackURL("calshow:"+timestamp)
  25. callback.open()
  26. Script.complete()
  27.  
  28. // Otherwise, create the widget.
  29. } else {
  30.  
  31. let widget = new ListWidget()
  32.  
  33. // Format the date info
  34. let df = new DateFormatter()
  35. df.dateFormat = "EEEE"
  36. let dayOfWeek = widget.addText(df.string(date).toUpperCase())
  37. let dateNumber = widget.addText(date.getDate().toString())
  38. dayOfWeek.font = Font.semiboldSystemFont(13)
  39. dateNumber.font = Font.lightSystemFont(34)
  40.  
  41. // Find future events that aren't all day and aren't canceled
  42. const events = await CalendarEvent.today([])
  43. let futureEvents = []
  44. for (const event of events) {
  45. if (event.startDate.getTime() > date.getTime() && !event.isAllDay && !event.title.startsWith("Canceled:")) {
  46. futureEvents.push(event)
  47. }
  48. }
  49.  
  50. // If there is at least one future event today
  51. if (futureEvents.length != 0) {
  52.  
  53. dayOfWeek.textColor = Color.red()
  54. widget.addSpacer()
  55.  
  56. let titleOne = widget.addText(futureEvents[0].title)
  57. titleOne.font = Font.mediumSystemFont(14)
  58.  
  59. widget.addSpacer(7)
  60.  
  61. let timeOne = widget.addText(formatTime(futureEvents[0].startDate))
  62. timeOne.font = Font.regularSystemFont(14)
  63. timeOne.textColor = Color.gray()
  64.  
  65. // If we have multiple future events, show the following one
  66. if (futureEvents.length > 1) {
  67.  
  68. // We only have room for single-line event names
  69. titleOne.lineLimit = 1
  70.  
  71. widget.addSpacer(12)
  72.  
  73. let titleTwo = widget.addText(futureEvents[1].title)
  74. titleTwo.font = Font.mediumSystemFont(14)
  75. titleTwo.lineLimit = 1
  76.  
  77. widget.addSpacer(7)
  78.  
  79. let timeTwo = widget.addText(formatTime(futureEvents[1].startDate))
  80. timeTwo.font = Font.regularSystemFont(14)
  81. timeTwo.textColor = Color.gray()
  82. }
  83.  
  84. // If there are no future events today
  85. } else {
  86. dayOfWeek.textColor = Color.white()
  87. dateNumber.textColor = Color.white()
  88.  
  89.  
  90. }
  91. let files = FileManager.local()
  92. const path = files.joinPath(files.documentsDirectory(), "mz_calendar_widget.jpg")
  93. const modificationDate = files.modificationDate(path)
  94.  
  95. // Download image if it doesn't exist, wasn't created today, or update is forced
  96. if (!modificationDate || !sameDay(modificationDate,date) || FORCE_IMAGE_UPDATE) {
  97. try {
  98. let img = await provideImage(IMAGE_SOURCE,TERMS)
  99. files.writeImage(path,img)
  100. widget.backgroundImage = img
  101. } catch {
  102. widget.backgroundImage = files.readImage(path)
  103. }
  104. } else {
  105. widget.backgroundImage = files.readImage(path)
  106. }
  107.  
  108. // Add overlay to image
  109. let gradient = new LinearGradient()
  110. gradient.colors = [new Color("#000000",0.5), new Color("#000000",0)]
  111. gradient.locations = [0, 0.5]
  112. widget.backgroundGradient = gradient
  113.  
  114. widget.addSpacer()
  115.  
  116. // Finalize widget settings
  117. widget.setPadding(16,16,16,0)
  118. widget.spacing = -3
  119.  
  120. Script.setWidget(widget)
  121. widget.presentSmall()
  122. Script.complete()
  123. }
  124.  
  125. // Helper function to interpret sources and terms
  126. async function provideImage(source,terms) {
  127.  
  128. if (source == "Bing") {
  129. const url = "http://www.bing.com/HPImageArchive.aspx?format=js&idx=0&n=1&mkt=en-US"
  130. const req = new Request(url)
  131. const json = await req.loadJSON()
  132. const imgURL = "http://bing.com" + json.images[0].url
  133. const img = await downloadImage(imgURL)
  134. const rect = new Rect(-78,0,356,200)
  135. return cropImage(img, rect)
  136.  
  137. } else if (source == "Unsplash") {
  138. const img = await downloadImage("https://source.unsplash.com/featured/500x500/?"+terms)
  139. return img
  140. }
  141.  
  142. }
  143.  
  144. // Helper function to download images
  145. async function downloadImage(url) {
  146. const req = new Request(url)
  147. return await req.loadImage()
  148. }
  149.  
  150. // Crop an image into a rect
  151. function cropImage(img,rect) {
  152.  
  153. let draw = new DrawContext()
  154. draw.respectScreenScale = true
  155.  
  156. draw.drawImageInRect(img,rect)
  157. return draw.getImage()
  158. }
  159.  
  160. // Formats the times under each event
  161. function formatTime(date) {
  162. let df = new DateFormatter()
  163. df.useNoDateStyle()
  164. df.useShortTimeStyle()
  165. return df.string(date)
  166. }
  167.  
  168. // Determines if two dates occur on the same day
  169. function sameDay(d1, d2) {
  170. return d1.getFullYear() === d2.getFullYear() &&
  171. d1.getMonth() === d2.getMonth() &&
  172. d1.getDate() === d2.getDate()
  173. }
Advertisement
Add Comment
Please, Sign In to add comment