Advertisement
Guest User

Imgur AppleScript Library

a guest
Sep 12th, 2018
184
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. use framework "Foundation"
  2. use scripting additions
  3.  
  4. -- ref. https://apidocs.imgur.com
  5. property apiUrl : "https://api.imgur.com/3/image"
  6. property authHeadArg : {"-H", "Authorization: Client-ID cc2c5a0c5e345d1"}
  7. property authHead : " " & item 1 of authHeadArg & " '" & item 2 of authHeadArg & "'"
  8. property logFilePath : (POSIX path of (path to library folder from user domain)) & "/Logs/ImgurLib.log"
  9. property deliveryFilePath : (POSIX path of (path to temporary items folder from user domain)) & "ImgurLib.delivery"
  10.  
  11. (* >>>>>>>>
  12.     Upload image file to Imgur
  13. *)
  14. on upload for imageFilePath given completeTo:completeHandleObject : missing value
  15.     return uploadAsyncWithImageFile(imageFilePath, completeHandleObject)
  16. end upload
  17.  
  18. on delete of hash
  19.     deleteWithHash(hash)
  20. end delete
  21.  
  22. on lock by hash
  23.     lockWithHash(hash)
  24. end lock
  25.  
  26. on uploadWithImageFile(imageFilePath)
  27.     return uploadAsyncWithImageFile(imageFilePath, missing value)
  28. end uploadWithImageFile
  29.  
  30. on uploadAsyncWithImageFile(imageFilePath, completeHandleObject)
  31.     set uploadTaskInfo to uploadExecute(imageFilePath)
  32.     set theResult to uploadTaskInfo
  33.     if |error| of theResult is not missing value then return theResult
  34.    
  35.     if completeHandleObject is missing value then
  36.         (task of uploadTaskInfo)'s waitUntilExit()
  37.         return uploadResult(uploadTaskInfo)
  38.     end if
  39.    
  40.     set uploadTaskInfo to uploadTaskInfo & {completeHandleObject:completeHandleObject}
  41.     current application's NSTimer's scheduledTimerWithTimeInterval:0.1 target:me selector:"uploadAsyncPollingTimerFire:" userInfo:uploadTaskInfo repeats:true
  42.    
  43.     return {imageURL:"In progress...", hash:"In progress...", |error|:missing value, filePath:filePath of uploadTaskInfo, fileName:fileName of uploadTaskInfo}
  44. end uploadAsyncWithImageFile
  45.  
  46. -- Private's for upload image file
  47. on uploadAsyncPollingTimerFire:timer
  48.     set uploadTaskInfo to (timer's userInfo) as record
  49.     if (task of uploadTaskInfo)'s isRunning() then return
  50.     timer's invalidate()
  51.    
  52.     set theResult to uploadResult(uploadTaskInfo)
  53.     try
  54.         -- imgurUploadAsyncCompleted(theResult) of completeHandleObject of uploadTaskInfo
  55.         imgurUploadCompleted of (completeHandleObject of uploadTaskInfo) by theResult
  56.     on error message
  57.         displayCriticalError(message)
  58.     end try
  59. end uploadAsyncPollingTimerFire:
  60.  
  61. on uploadExecute(imageFilePath)
  62.     set imageFileName to ""
  63.     set task to missing value
  64.     try
  65.         if class of imageFilePath is in {alias, «class furl»} then set imageFilePath to POSIX path of imageFilePath
  66.         set imageFilePath to (current application's NSString's stringWithString:imageFilePath)'s stringByStandardizingPath()
  67.         set imageFileName to imageFilePath's lastPathComponent() as text
  68.         set imageFilePath to imageFilePath as text
  69.        
  70.         set workspace to current application's NSWorkspace's sharedWorkspace
  71.         set {fileTypeUTI, |error|} to workspace's typeOfFile:imageFilePath |error|:(reference)
  72.         if fileTypeUTI is missing value then error |error|'s localizedDescription
  73.         if not (workspace's type:fileTypeUTI conformsToType:"public.image") then error "Could not upload because that is not an image file."
  74.        
  75.         set task to current application's NSTask's alloc's init
  76.         set task's launchPath to "/usr/bin/curl"
  77.         (*
  78.         set task's arguments to {"--show-error", "--silent", apiUrl} & authHeadArg & {"-F", "image=@" & imageFilePath}
  79.         *)
  80.         set task's arguments to {"--show-error", "--silent", apiUrl} & authHeadArg & {"-F", "image=@-"}
  81.         set {fileHandle, |error|} to current application's NSFileHandle's fileHandleForReadingFromURL:(current application's NSURL's fileURLWithPath:imageFilePath isDirectory:false) |error|:(reference)
  82.         if fileHandle is missing value then error |error|'s localizedDescription
  83.         set task's standardInput to fileHandle
  84.         (*
  85.         set task's launchPath to "/bin/bash"
  86.         set task's arguments to {"-c", "cat " & quoted form of imageFilePath & " | curl --show-error --silent " & apiUrl & authHead & " -F image=@-"}
  87.         *)
  88.         set task's currentDirectoryPath to POSIX path of (path to temporary items)
  89.         set task's standardOutput to current application's NSPipe's pipe
  90.         set task's standardError to current application's NSPipe's pipe
  91.     on error |error|
  92.         return {imageURL:missing value, hash:missing value, |error|:(|error| as text), filePath:imageFilePath, fileName:imageFileName}
  93.     end try
  94.    
  95.     task's |launch|()
  96.     return {|error|:missing value, task:task, filePath:imageFilePath, fileName:imageFileName}
  97. end uploadExecute
  98.  
  99. on uploadResult(uploadTaskInfo)
  100.     set task to task of uploadTaskInfo
  101.     set filePath to filePath of uploadTaskInfo
  102.     set fileName to fileName of uploadTaskInfo
  103.     set respRec to {}
  104.     try
  105.         if task's terminationStatus as integer is not 0 then error current application's NSString's alloc()'s initWithData:(task's standardError's fileHandleForReading's readDataToEndOfFile()) encoding:(current application's NSUTF8StringEncoding)
  106.         set {respRec, |error|} to current application's NSJSONSerialization's JSONObjectWithData:(task's standardOutput's fileHandleForReading's readDataToEndOfFile()) options:0 |error|:(reference)
  107.         if respRec is missing value then |error|'s localizedDescription
  108.         set respRec to respRec as record
  109.        
  110.         if not (success of respRec) then error errorMessageInResponse(respRec)
  111.     on error |error|
  112.         return {imageURL:missing value, hash:missing value, |error|:(|error| as text), filePath:filePath, fileName:fileName}
  113.     end try
  114.    
  115.     set imgUrl to link of |data| of respRec
  116.     set deleteHash to deleteHash of |data| of respRec
  117.    
  118.     set AppleScript's text item delimiters to " "
  119.     do shell script "printf '[%s] uploaded " & deleteHash & "
  120.     %s
  121.     %s
  122.     %s
  123.     curl %s
  124. ' \"$(date)\" " & quoted form of fileName & " " & quoted form of filePath & " " & quoted form of imgUrl & " " & quoted form of curlArgsStringWithDeleteHash(deleteHash) & " >> " & quoted form of logFilePath
  125.    
  126.     return {imageURL:imgUrl, hash:deleteHash, |error|:missing value, filePath:filePath, fileName:fileName}
  127. end uploadResult
  128.  
  129. (* >>>>>>>>
  130.     Delete image file from Imgur
  131. *)
  132. on deleteWithHash(deleteHash)
  133.     set respRec to {}
  134.     try
  135.         set respJson to do shell script "curl --show-error --silent " & curlArgsStringWithDeleteHash(deleteHash)
  136.         set respRec to run script "JSON.parse(" & quoted form of respJson & ");" in "JavaScript"
  137.        
  138.         if not (success of respRec) then error errorMessageInResponse(respRec)
  139.     on error |error|
  140.         return {success:false, |error|:(|error| as text)}
  141.     end try
  142.    
  143.     do shell script "printf '[%s] deleted " & deleteHash & "
  144. ' \"$(date)\" >> " & quoted form of logFilePath
  145.    
  146.     return {success:true, |error|:missing value}
  147. end deleteWithHash
  148.  
  149. (* >>>>>>>>
  150.     Lock(except/hide for list) uploaded imfe file in logfile
  151. *)
  152. on lockWithHash(deleteHash)
  153.     do shell script "printf '[%s] locked " & deleteHash & "
  154. ' \"$(date)\" >> " & quoted form of logFilePath
  155. end lockWithHash
  156.  
  157. (* >>>>>>>>
  158.     List uploaded info from logfile
  159. *)
  160. on uploaded()
  161.     set uploads to current application's NSMutableArray's new()
  162.     set hashes to current application's NSMutableArray's new()
  163.     repeat with theLine in (every paragraph of (do shell script "tail -n 300 " & quoted form of logFilePath & " | awk '
  164. /^[^    ].*(deleted|locked)/{
  165.     printf \"-%s\\n\", $NF;
  166. }
  167. /^[^    ].*uploaded/{
  168.     hash=$NF; sub(\" uploaded.*$\", \"\"); date=$0; getline; sub(\"^    \", \"\");
  169.     printf \"+%s “%s”   - %s\\n\", date,  $0, hash;
  170. }'"))
  171.         set hash to last word of theLine
  172.         if first text of theLine is "+" then
  173.             (uploads's addObject:(text 2 thru -1 of theLine))
  174.             (hashes's addObject:hash)
  175.         else
  176.             set theIndex to (hashes's indexOfObject:hash)
  177.             if theIndex is not (current application's NSNotFound) then
  178.                 (uploads's removeObjectAtIndex:theIndex)
  179.                 (hashes's removeObjectAtIndex:theIndex)
  180.             end if
  181.         end if
  182.     end repeat
  183.    
  184.     return (uploads's reverseObjectEnumerator()'s allObjects()) as list
  185. end uploaded
  186.  
  187. (* >>>>>>>>
  188.     Post(save) file list into temporary file for delivery process to process
  189. *)
  190. on postDeliveryFiles(theFiles)
  191.     set posixFiles to ""
  192.     repeat with theFile in theFiles
  193.         set thePath to theFile
  194.         if class of thePath is in {alias, «class furl»} then set thePath to POSIX path of thePath
  195.         set posixFiles to posixFiles & thePath & (ASCII character 10)
  196.     end repeat
  197.     if length of posixFiles is 0 then return
  198.    
  199.     do shell script "cat >> " & quoted form of deliveryFilePath & " << IMGURLIB_DELIVERY_END
  200. " & posixFiles & "IMGURLIB_DELIVERY_END
  201. "
  202. end postDeliveryFiles
  203.  
  204. (* >>>>>>>>
  205.     Take(load) file list from temporary file for delivery process to process
  206. *)
  207. on takeDeliveryFilePaths()
  208.     return every paragraph of (do shell script "IMGURFILE=" & quoted form of deliveryFilePath & ";cat \"$IMGURFILE\" 2> /dev/null; rm -f \"$IMGURFILE\"; exit 0")
  209. end takeDeliveryFilePaths
  210.  
  211. -- Private's
  212. on curlArgsStringWithDeleteHash(deleteHash)
  213.     return "-X DELETE " & apiUrl & "/" & deleteHash & authHead
  214. end curlArgsStringWithDeleteHash
  215.  
  216. on errorMessageInResponse(response)
  217.     set message to |error| of |data| of response
  218.     if class of message is in {string, text} then return message
  219.     try
  220.         return message of message
  221.     end try
  222.     if class of message is list then
  223.         return (current application's NSArray's arrayWithArray:message)'s |description|()
  224.     else if class of message is record then
  225.         return (current application's NSDictionary's dictionaryWithDictionary:message)'s |description|()
  226.     end if
  227.     return "Error message unknown by ImgurLib"
  228. end errorMessageInResponse
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement