Guest User

Untitled

a guest
May 31st, 2021
1,173
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 8.27 KB | None | 0 0
  1. let spotifyCredentials
  2.  
  3. let widget = await createWidget()
  4. if (config.runsInApp) await widget.presentSmall()
  5. else if (config.runsInWidget) Script.setWidget(widget)
  6. Script.complete()
  7.  
  8. async function createWidget() {
  9. let fm = FileManager.iCloud()
  10. let dir = fm.documentsDirectory()
  11. let path = fm.joinPath(dir, "scriptable-corona.json")
  12. let imgPath = dir + '/bg.b63'
  13. var list = new ListWidget()
  14.  
  15. if (config.runsInWidget) {
  16. list.backgroundImage = await Image.fromFile(imgPath)
  17. } else if (config.runsInApp) {
  18. list.backgroundImage = await Photos.fromLibrary()
  19. await fm.writeImage(imgPath, list.backgroundImage)
  20. }
  21.  
  22. let widget = new ListWidget()
  23. let spotifyIcon = await getImage("spotify-icon.png")
  24.  
  25.  
  26.  
  27.  
  28. // load spotify credentials from iCloud Drive
  29. spotifyCredentials = await loadSpotifyCredentials()
  30. if(spotifyCredentials != null) {
  31. widget.url = "spotify://"
  32. let nowPlaying = await loadNowPlaying()
  33. if(nowPlaying != null) {
  34. widget.setPadding(20,12, 8, 8)
  35. let cleanTitle = nowPlaying.item.name.split(" (")[0]
  36. cleanTitle = cleanTitle.split(" - ")[0]
  37. const artist = nowPlaying.item.artists[0].name
  38. // console.log("Now Playing: " + cleanTitle + " - " + artist)
  39.  
  40.  
  41. // cover art
  42. const coverUrl = nowPlaying.item.album.images[0].url
  43. let coverImage = await loadImage(coverUrl)
  44.  
  45. let row = widget.addStack()
  46. let stack = row.addStack()
  47. stack.layoutHorizontally()
  48. stack.size = new Size(105,105)
  49.  
  50. let cover = stack.addImage(coverImage)
  51. cover.cornerRadius = 6
  52. cover.borderColor = new Color("#1DB954")
  53. cover.borderWidth = 3
  54. stack.addSpacer(10)
  55.  
  56. let stack2 = row.addStack()
  57. stack2.layoutVertically()
  58.  
  59. let spotifyIconImage = stack2.addImage(spotifyIcon)
  60. stack2.addSpacer(10)
  61.  
  62. let shuffleIcon = await getImage("shuffle-icon.png")
  63. let shuffleIconImage = stack2.addImage(shuffleIcon)
  64. if(nowPlaying.shuffle_state == true) {
  65. shuffleIconImage.imageOpacity = 1
  66. } else {
  67. shuffleIconImage.imageOpacity = 0.3
  68. }
  69.  
  70. let repeatIcon = await getImage("repeat-icon.png")
  71. stack2.addSpacer(10)
  72. let repeatIconImage = stack2.addImage(repeatIcon)
  73. if(nowPlaying.repeat_state === "off") {
  74. repeatIconImage.imageOpacity = 0.3
  75. } else {
  76. repeatIconImage.imageOpacity = 1.0
  77. }
  78.  
  79. // add title and artist
  80. let titleTxt = widget.addText(cleanTitle)
  81. titleTxt.font = Font.semiboldSystemFont(11)
  82. titleTxt.textColor = Color.white()
  83. titleTxt.lineLimit = 1
  84. widget.addSpacer(2)
  85.  
  86. let artistTxt = widget.addText(artist)
  87. artistTxt.font = Font.boldSystemFont(11)
  88. artistTxt.textColor = new Color("#1DB954")
  89. artistTxt.lineLimit = 1
  90.  
  91. widget.addSpacer()
  92.  
  93. } else {
  94. // Spotify playback stopped
  95. let spotifyImage = widget.addImage(spotifyIcon)
  96. spotifyImage.imageSize = new Size(25,25)
  97. spotifyImage.rightAlignImage()
  98. widget.addSpacer(10)
  99.  
  100. let offIcon = await getImage("offline-icon.png")
  101. let offImage = widget.addImage(offIcon)
  102. offImage.imageSize = new Size(25,25)
  103. offImage.centerAlignImage()
  104. widget.addSpacer(5)
  105.  
  106. let playbackText = widget.addText("Playback stopped")
  107. playbackText.font = Font.semiboldSystemFont(11)
  108. playbackText.textColor = Color.white()
  109. playbackText.centerAlignText()
  110. widget.addSpacer()
  111. }
  112. } else {
  113. // no credentials found
  114. let spotifyImage = widget.addImage(spotifyIcon)
  115. spotifyImage.imageSize = new Size(25,25)
  116. spotifyImage.rightAlignImage()
  117. widget.addSpacer(10)
  118. console.log("Could not find Spotify credentials!")
  119. let ts = widget.addText("Couldn't find your spotify credentials in iCloud Drive. \n\n Please tap me for setup instructions.")
  120. ts.textColor = Color.white()
  121. ts.font = Font.boldSystemFont(11)
  122. ts.leftAlignText()
  123. widget.url = "https://gist.github.com/marco79cgn/79a6a265d978dc22cc2a12058b24e02b#gistcomment-3469230"
  124. }
  125.  
  126. return widget
  127. }
  128.  
  129. // get nowPlaying via Spotify Web API
  130. async function loadNowPlaying() {
  131. const req = new Request("https://api.spotify.com/v1/me/player")
  132. req.headers = { "Authorization": "Bearer " + spotifyCredentials.accessToken, "Content-Type": "application/json" }
  133. let npResult = await req.load()
  134. if (req.response.statusCode == 401) {
  135. // access token expired, trying to refresh
  136. let success = await refreshSpotifyAccessToken()
  137. if(success) {
  138. return await loadNowPlaying()
  139. } else {
  140. return null
  141. }
  142. } else if (req.response.statusCode == 204) {
  143. // no playback
  144. return null
  145. } else if (req.response.statusCode == 200) {
  146. npResult = JSON.parse(npResult.toRawString())
  147. }
  148. return npResult
  149. }
  150.  
  151. // load and validate spotify credentials from iCloud Drive
  152. async function loadSpotifyCredentials() {
  153. let fm = FileManager.iCloud()
  154. let dir = fm.documentsDirectory()
  155. let path = fm.joinPath(dir, "spotify-credentials.json")
  156. let spotifyCredentials
  157. if(fm.fileExists(path)) {
  158. await fm.downloadFileFromiCloud(path)
  159. let spotifyCredentialsFile = Data.fromFile(path)
  160. spotifyCredentials = JSON.parse(spotifyCredentialsFile.toRawString())
  161. if (isNotEmpty(spotifyCredentials.clientId)
  162. && isNotEmpty(spotifyCredentials.clientSecret)
  163. && isNotEmpty(spotifyCredentials.accessToken)
  164. && isNotEmpty(spotifyCredentials.refreshToken)) {
  165. return spotifyCredentials
  166. }
  167. }
  168. return null
  169. }
  170.  
  171. // helper function to check not empty strings
  172. function isNotEmpty(stringToCheck) {
  173. if (stringToCheck != null && stringToCheck.length > 0) {
  174. return true
  175. } else {
  176. return false
  177. }
  178. }
  179.  
  180. // The Spotify access token expired so we get a new one by using the refresh token (Authorization Flow)
  181. async function refreshSpotifyAccessToken() {
  182. if(spotifyCredentials != null) {
  183. let req = new Request("https://accounts.spotify.com/api/token")
  184. req.method = "POST"
  185. req.headers = { "Content-Type": "application/x-www-form-urlencoded" }
  186. req.body = "grant_type=refresh_token&refresh_token=" + spotifyCredentials.refreshToken + "&client_id=" + spotifyCredentials.clientId + "&client_secret=" + spotifyCredentials.clientSecret
  187. let result = await req.loadJSON()
  188. spotifyCredentials.accessToken = result.access_token
  189. let fm = FileManager.iCloud()
  190. let dir = fm.documentsDirectory()
  191. let path = fm.joinPath(dir, "spotify-credentials.json")
  192. fm.write(path, Data.fromString(JSON.stringify(spotifyCredentials)))
  193. return true
  194. }
  195. return false
  196.  
  197. }
  198.  
  199. // get images from local filestore or download them once
  200. async function getImage(image) {
  201. let fm = FileManager.local()
  202. let dir = fm.documentsDirectory()
  203. let path = fm.joinPath(dir, image)
  204. if(fm.fileExists(path)) {
  205. return fm.readImage(path)
  206. } else {
  207. // download once
  208. let imageUrl
  209. switch (image) {
  210. case 'spotify-icon.png':
  211. imageUrl = "https://upload.wikimedia.org/wikipedia/commons/thumb/1/19/Spotify_logo_without_text.svg/240px-Spotify_logo_without_text.svg.png"
  212. break
  213. case 'shuffle-icon.png':
  214. imageUrl = "https://www.iconsdb.com/icons/download/white/shuffle-128.png"
  215. break
  216. case 'repeat-icon.png':
  217. imageUrl = "https://www.iconsdb.com/icons/download/white/repeat-128.png"
  218. break
  219. case 'offline-icon.png':
  220. imageUrl = "http://cdn.1001freedownloads.com/vector/thumb/98366/clarity-shutdown-icon.png"
  221. break
  222. default:
  223. console.log(`Sorry, couldn't find ${image}.`);
  224. }
  225. let iconImage = await loadImage(imageUrl)
  226. fm.writeImage(path, iconImage)
  227. return iconImage
  228. }
  229. }
  230.  
  231. // helper function to download an image from a given url
  232. async function loadImage(imgUrl) {
  233. const req = new Request(imgUrl)
  234. return await req.loadImage()
  235. }
Advertisement
Add Comment
Please, Sign In to add comment