hyerob

pastebin_api.ahk

Apr 3rd, 2019
1,423
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. ;README (INSTRUCTIONS START ON LINE 44; CODE STARTS ON LINE 169)
  2. ;
  3. ;Pastebin API Hotkeys (MS Windows only)
  4. ;AutoHotkey V2 32-Bit program (Compatible with 64-bit MS Windows)
  5. ;
  6. ;FEATURES:
  7. ;
  8. ;0. Correctly handles UTF-8 http request responses from pastebin.com
  9. ;1. Create a new paste from highlighted text (confirms overwrite if an existing
  10. ;filename is specified and creates timestamped backup copy locally)
  11. ;2. Create new pastes from highlighted files and/or folders (confirms overwrite
  12. ;for existing files and creates timestamped backup copies locally)(currenty
  13. ;supports files that match extensions .txt, .md, .ahk, .xml, .py, .pl, .php,
  14. ;.ps1, .js, .csv, and .tsv -- More extensions can be added by simply
  15. ;adjusting the regular expression on lines 760 and 773)
  16. ;3. Download the content of an existing paste
  17. ;4. Append to an existing paste (creates timestamped backup copy of original
  18. ;locally)(Adds a Windows new line character `r`n to separate original content and
  19. ;appended content)
  20. ;5. Backup pastes based on regular expression (creates time_stamped local folder
  21. ;of downloaded pastes)
  22. ;6. Delete pastes based on regular expression (creates timestamped backup copies
  23. ;stored locally)
  24. ;7. List all pastes
  25. ;8. List pastes based on regular expression
  26. ;9. Get a paste link for an existing paste name
  27. ;10. Log into Pastebin.com (automates your browser through programmatic key
  28. ;strokes) (currently works when Opera is default browser)
  29. ;
  30. ;HOTKEYS (numbers correspond to the above 1 through 10):
  31. ;
  32. ;1. Create new paste = ^!1 (Ctrl+Alt+1)
  33. ;2. Create new paste from files/folders = ^!2 (Ctrl+Alt+2)
  34. ;3. Download existing paste = ^!3 (Ctrl+Alt+3)
  35. ;4. Append to existing paste = ^!4 (Ctrl+Alt+4)
  36. ;5. Backup pastes = ^!5 (Ctrl+Alt+5)
  37. ;6. Delete pastes = ^!6 (Ctrl+Alt+6)
  38. ;7. List all pastes = ^!7 (Ctrl+Alt+7)
  39. ;8. List pastes = ^!8 (Ctrl+Alt+8)
  40. ;9. Get paste link = ^!9 (Ctrl+Alt+9)
  41. ;10. Log into pastebin = ^!0 (Ctrl+Alt+0)
  42. ;11. Help message = ^!h (Ctrl+Alt+h)
  43. ;
  44. ;HOW TO USE:
  45. ;
  46. ;1. Download the latest version of AutoHotkey Version 2 (as of 2019-1-23)
  47. ;https://www.autohotkey.com/download/2.0/AutoHotkey_2.0-a100-52515e2.zip
  48. ;
  49. ;2. Unzip the file "AutoHotkey_2.0-a100-52515e2.zip"
  50. ;
  51. ;3. Double click the folder "AutoHotkey_2.0-a100-52515e2"
  52. ;
  53. ;4. Copy the executable "AutoHotkeyU32.exe" and place it a separate folder.
  54. ;
  55. ;5. Put this file "pastebin_api.ahk" in the same folder as the
  56. ;"AutoHotkeyU32.exe" executable.
  57. ;
  58. ;6. Create a folder called "configuration"
  59. ;
  60. ;7. In the "configuration" folder, create the "pastebin.txt" configuration file
  61. ;(see lines 72-121 for more information on this step.
  62. ;
  63. ;8. In the folder containing the "AutoHotkeyU32.exe" executable, open Windows
  64. ;Powershell by clicking File -> Open Windows Powershell from Windows Explorer.
  65. ;
  66. ;9. Type ".\AutoHotkeyU32.exe pastebin_api.ahk"
  67. ;
  68. ;10. Use the Hotkeys in lines 32-42 to interact with the Pastebin.com API
  69. ;
  70. ;CONFIGURATION & EXTRA INFORMATION:
  71. ;
  72. ;1. Configuration information is stored in local file:
  73. ;configuration/pastebin.txt
  74. ;
  75. ;Please create the folder "configuration" in the same folder as the script, and
  76. ;then create the "pastebin.txt" configuration file in the "configuration" folder
  77. ;you just created.
  78. ;
  79. ;###Sample configuration configuration/pastebin.txt file (lines 81-87). Please
  80. ;create a similar one###
  81. ;api_dev_key=APIKEY
  82. ;api_user_name=USERNAME
  83. ;api_user_password=PASSWORD
  84. ;api_user_key=
  85. ;api_paste_format=text
  86. ;api_paste_private=2
  87. ;api_paste_expire_date=N
  88. ;#########################################################################
  89. ;
  90. ;Get your api_dev_key by logging into Pastebin.com and going to
  91. ;https://pastebin.com/api
  92. ;
  93. ;api_user_name is your Pastebin.com login username.
  94. ;
  95. ;api_user_password is your Pastebin.com login password.
  96. ;
  97. ;If the api_user_key is blank, the program will automatically generate it and
  98. ;store it after starting the program. If you already have an api_user_key, enter
  99. ;it after the "=" sign. No whitespace allowed.
  100. ;
  101. ;Valid api_paste_format values are available at https://pastebin.com/api
  102. ;An api_paste_format of "text" means "no syntax highlighting"
  103. ;
  104. ;Valid api_paste_private values are 0, 1, 2, which mean public, unlisted, and
  105. ;private, respectively.
  106. ;
  107. ;Value api_paste_expire_date values are the following:
  108. ;N = Never
  109. ;10M = 10 Minutes
  110. ;1H = 1 Hour
  111. ;1D = 1 Day
  112. ;1W = 1 Week
  113. ;2W = 2 Weeks
  114. ;1M = 1 Month
  115. ;6M = 6 Months
  116. ;1Y = 1 Year
  117. ;
  118. ;2. The program will not make any changes to existing Pastebin.com pastes
  119. ;without first backing up the existing file locally. If the backup fails, the
  120. ;thread will exit and nothing will be changed to the paste at Pastebin.com. This
  121. ;is important when overwriting, appending to, and deleting pastes.
  122. ;
  123. ;CURRENTLY KNOWN LIMITATIONS:
  124. ;
  125. ;1. When files are overwritten for paste or append, the original Pastebin.com
  126. ;link is deleted and a new link is generated and saved to the clipboard.
  127. ;2. Since the pastebin.com API does not support folders, please ensure that
  128. ;there are no files with duplicated names when using the file/folder paste hotkey
  129. ;(Ctrl+Alt+2). In the event that there are duplicated names and something gets
  130. ;deleted from pastebin.com, please check your local pastebin_backup folder for
  131. ;timestamped backups.
  132. ;3. This program only supports up to 1,000 files since this is the limitation
  133. ;imposed by the pastebin.com API when retrieving a list of pastes.
  134. ;4. This program works with UTF-8 encoded files. If your files use another
  135. ;encoding, strange things may happen.
  136. ;5. Due to the nature of the pastebin.com service, original file permissions and
  137. ;attributes such as modification date are not reflected in files downloaded or
  138. ;backed up from pastebin.com
  139. ;6. The pastebin.com API seems to remove trailing carriage returns and newlines
  140. ;from pastes, so if your paste require that these carriage returns and newlines
  141. ;be maintained (for example, C language files), then please be forewarned about
  142. ;this.
  143. ;
  144. ;SUPPORT
  145. ;No support is provided.
  146. ;
  147. ;LICENSE
  148. ;
  149. ;This software is completely free. You can do whatever you want with it.
  150. ;
  151. ;LEGAL DISCLAIMER
  152. ;
  153. ;Short Version
  154. ;USE AT YOUR OWN RISK.
  155. ;
  156. ;Long Version
  157. ;THIS SOFTWARE IS PROVIDED FOR THE PURPOSE OF ILLUSTRATION ONLY AND IS NOT
  158. ;INTENDED TO BE USED IN A PRODUCTION ENVIRONMENT.
  159. ;
  160. ;THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  161. ;IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  162. ;FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  163. ;AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  164. ;LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  165. ;FROM, OUT OF OR IN CONNECTION WITH THIS SOFTWARE OR THE USE OR OTHER DEALINGS
  166. ;IN THIS SOFTWARE.
  167.  
  168.  
  169. ;###########CODE STARTS HERE####################
  170.  
  171. ;#Warn  ; Enable warnings to assist with detecting common errors.
  172. SendMode("Input")  ; Recommended for new scripts due to its superior speed and reliability.
  173. SetWorkingDir(A_ScriptDir)  ; Ensures a consistent starting directory.
  174.  
  175. ;AUTOHOTKEY V2 32-BIT SCRIPT
  176.  
  177. ;##########Default settings#####################
  178. pastebin_backup_dir := A_WorkingDir . '\pastebin_backup\'
  179. If !DirExist(pastebin_backup_dir)
  180. {
  181.     DirCreate(pastebin_backup_dir)
  182. }
  183. ;##########Get Pastebin.com credentials#####################
  184. credentials_file := A_WorkingDir . '\configuration\pastebin.txt'
  185. If !FileExist(credentials_file)
  186. {
  187.     MsgBox("You need to create your credentials file at:`n`n" . credentials_file . "`n`nCheck the help information provided at the top of the script for instructions on creating this file.")
  188.     ExitApp()
  189. }
  190. api_dev_key := ''
  191. api_user_name := ''
  192. api_user_password := ''
  193. api_user_key := ''
  194. api_paste_format := ''
  195. api_paste_private := ''
  196. api_paste_expire_date := ''
  197. Loop Read, credentials_file
  198. {
  199.     line := StrSplit(A_LoopReadLine, "=")
  200.     If line[1] = 'api_dev_key'
  201.     {
  202.         api_dev_key := line[2]
  203.     }
  204.     Else If line[1] = 'api_user_name'
  205.     {
  206.         api_user_name := line[2]
  207.     }
  208.     Else If line[1] = 'api_user_password'
  209.     {
  210.         api_user_password := line[2]
  211.     }
  212.     Else If line[1] = 'api_user_key'
  213.     {
  214.         api_user_key := line[2]
  215.     }
  216.     Else If line[1] = 'api_paste_format'
  217.     {
  218.         api_paste_format := line[2]
  219.     }
  220.     Else If line[1] = 'api_paste_private'
  221.     {
  222.         api_paste_private := line[2]
  223.     }
  224.     Else If line[1] = 'api_paste_expire_date'
  225.     {
  226.         api_paste_expire_date := line[2]
  227.     }
  228. }
  229.  
  230. If !api_user_key
  231. {
  232.     result := MsgBox("No api_user_key! Would you like to generate one? (Press Yes or No)",, "YesNo")
  233.     If result = "Yes"
  234.     {
  235.         api_user_name := UriEncode(api_user_name)
  236.         api_user_password := UriEncode(api_user_password)      
  237.         post_fields := 'api_dev_key=' . api_dev_key . '&api_user_name=' . api_user_name . '&api_user_password=' . api_user_password
  238.         url := "https://pastebin.com/api/api_login.php"
  239.         HttpObj := ComObjCreate("WinHttp.WinHttpRequest.5.1")
  240.         HttpObj.Open("POST", url)
  241.         HttpObj.SetRequestHeader("Content-Type","application/x-www-form-urlencoded")
  242.         HttpObj.Send(post_fields)
  243.        
  244.         ; Check response
  245.        
  246.         backup_file := pastebin_backup_dir . "pastebin.txt"
  247.         response := HttpObj.ResponseText
  248.         status := HttpObj.Status
  249.         If status = '200'
  250.         {
  251.             api_user_key := response
  252.             FileCopy(credentials_file, backup_file, '1')
  253.             If !(FileExist(backup_file) And FileGetSize(backup_file) And CheckAgeConfig(credentials_file, backup_file))
  254.             {
  255.                 MsgBox("Local backup of " . credentials_file . " failed! Aborting overwrite...")
  256.                 CheckKeyState()
  257.                 Exit()
  258.             }
  259.             FileDelete(credentials_file)
  260.             content := "api_dev_key=" . api_dev_key . "`napi_user_name=" . api_user_name . "`napi_user_password=" . api_user_password . "`napi_user_key=" . api_user_key . "`napi_paste_format=" . api_paste_format . "`napi_paste_private=" . api_paste_private . "`napi_paste_expire_date=" . api_paste_expire_date
  261.             FileAppend(content, credentials_file)
  262.             MsgBox('api_user_key ' . api_user_key . ' appended to `n' . credentials_file)
  263.         }
  264.         Else
  265.         {
  266.             MsgBox("There was a problem generating the api_user_key. Make sure your credentials file is correct or try again a little later.")
  267.             CheckKeyState()
  268.             Exit()
  269.         }
  270.     }
  271.     Else
  272.     {
  273.         CheckKeyState()
  274.         Exit()
  275.     }
  276.  
  277. }
  278.  
  279. ;##########Utility functions#####################
  280.  
  281. OpenWindowPastebin(win_title, tab_title, run_command, username, password)
  282. {
  283.     If WinExist(win_title)
  284.     {
  285.         WinActivate(win_title)
  286.         Sleep(150)
  287.         If WinActive(tab_title)
  288.         {
  289.             Loop 23
  290.             {
  291.                 SendInput("{Tab}")
  292.                 Sleep(150)
  293.             }
  294.             SendInput(username)
  295.             Sleep(500)
  296.             SendInput("{Tab}")
  297.             Sleep(250)
  298.             SendInput(password)
  299.             Sleep(500)
  300.             SendInput("{Enter}")
  301.             Sleep(250)
  302.             Return
  303.         }
  304.         Loop 9
  305.         {
  306.             SendInput("{Ctrl down}{" . A_Index . "}")
  307.             Sleep(200)
  308.             SendInput("{Ctrl up}")
  309.             Sleep(200)
  310.             If WinActive(tab_title)
  311.             {
  312.                 Loop 23
  313.                 {
  314.                     SendInput("{Tab}")
  315.                     Sleep(150)
  316.                 }
  317.                 SendInput(username)
  318.                 Sleep(500)
  319.                 SendInput("{Tab}")
  320.                 Sleep(250)
  321.                 SendInput(password)
  322.                 Sleep(500)
  323.                 SendInput("{Enter}")
  324.                 Sleep(250)
  325.                 Return
  326.             }
  327.         }
  328.         Run(run_command)
  329.         While !WinActive(tab_title)
  330.         {
  331.             Sleep(100)
  332.         }
  333.         Sleep(7000)
  334.         Loop 23
  335.         {
  336.             SendInput("{Tab}")
  337.             Sleep(150)
  338.         }
  339.         SendInput(username)
  340.         Sleep(500)
  341.         SendInput("{Tab}")
  342.         Sleep(250)
  343.         SendInput(password)
  344.         Sleep(500)
  345.         SendInput("{Enter}")
  346.         Sleep(250)
  347.         Return
  348.     }
  349.     Else
  350.     {
  351.         Run(run_command)
  352.         While !WinActive(tab_title)
  353.         {
  354.             Sleep(100)
  355.         }
  356.         Sleep(7000)
  357.         Loop 23
  358.         {
  359.             SendInput("{Tab}")
  360.             Sleep(150)
  361.         }
  362.         SendInput(username)
  363.         Sleep(500)
  364.         SendInput("{Tab}")
  365.         Sleep(250)
  366.         SendInput(password)
  367.         Sleep(500)
  368.         SendInput("{Enter}")
  369.         Sleep(250)
  370.         Return
  371.     }
  372. }
  373.  
  374. CheckAge(file)
  375. {
  376.     ; check that file modification date is < 10 seconds old
  377.    
  378.     time_now := A_Now
  379.     file_mod_time := FileGetTime(file, "M")
  380.     age := DateDiff(time_now, file_mod_time, "seconds")
  381.     If age < 10
  382.     {
  383.         Return(True)
  384.     }
  385.     Else
  386.     {
  387.         Return(False)
  388.     }
  389. }
  390.  
  391. CheckAgeConfig(orig, copy)
  392. {
  393.     ; check that file modification date is the same
  394.    
  395.     orig_mod_time := FileGetTime(orig, "M")
  396.     copy_mod_time := FileGetTime(copy, "M")
  397.     age := DateDiff(orig_mod_time, copy_mod_time, "seconds")
  398.     If age = 0
  399.     {
  400.         Return(True)
  401.     }
  402.     Else
  403.     {
  404.         Return(False)
  405.     }
  406. }
  407.  
  408. CheckKeyState()
  409. {
  410.     Sleep(1000)
  411.     While 1
  412.     {
  413.         If GetKeyState("Control")
  414.         {
  415.             MsgBox("Control key is down")
  416.             Continue
  417.         }
  418.         If GetKeyState("Alt")
  419.         {
  420.             MsgBox("Alt key is down")
  421.             Continue
  422.         }
  423.         Break
  424.     }
  425. }
  426.  
  427. UriEncode(string)
  428. {
  429.     string := RegExReplace(string, "%([025789ACD]{2})", "%25$1")
  430.     string := RegExReplace(string, "'", "%27")
  431.     string := RegExReplace(string, '"', "%22")
  432.    string := RegExReplace(string, "\\", "%5C")
  433.    string := RegExReplace(string, "\n", "%0A")
  434.    string := RegExReplace(string, "\r", "%0D")
  435.    string := RegExReplace(string, "\(", "%28")
  436.    string := RegExReplace(string, "\)", "%29")
  437.    oSC := ComObjCreate("ScriptControl")
  438.    oSC.Language := "JScript"
  439.     Script := 'var Encoded = encodeURIComponent(' . '"' . string . '")'
  440.     oSC.ExecuteStatement(Script)
  441.     string := oSC.Eval("Encoded")
  442.     string := RegExReplace(string, "%2527", "%27")
  443.    string := RegExReplace(string, "%2522", "%22")
  444.    string := RegExReplace(string, "%255C", "%5C")
  445.    string := RegExReplace(string, "%250A", "%0A")
  446.    string := RegExReplace(string, "%250D", "%0D")
  447.    string := RegExReplace(string, "%2528", "%28")
  448.    string := RegExReplace(string, "%2529", "%29")
  449.    string := RegExReplace(string, "%2525([025789ACD]{2})", "%25$1")
  450.     Return(string)
  451. }
  452.  
  453. BcryptMd5(string)
  454. {
  455.    Static BCRYPT_MD5_ALGORITHM := "MD5"
  456.    Static BCRYPT_HASH_LENGTH   := "HashDigestLength"
  457.  
  458.    If !(hBCRYPT := DllCall("LoadLibrary", "str", "bcrypt.dll", "ptr"))
  459.        throw Exception("Failed to load bcrypt.dll", -1)
  460.  
  461.    If (NT_STATUS := DllCall("bcrypt\BCryptOpenAlgorithmProvider", "ptr*", hAlgo, "ptr", &BCRYPT_MD5_ALGORITHM, "ptr", 0, "uint", 0) != 0)
  462.        throw Exception("BCryptOpenAlgorithmProvider: " NT_STATUS, -1)
  463.  
  464.    If (NT_STATUS := DllCall("bcrypt\BCryptGetProperty", "ptr", hAlgo, "ptr", &BCRYPT_HASH_LENGTH, "uint*", cbHash, "uint", 4, "uint*", cbResult, "uint", 0) != 0)
  465.        throw Exception("BCryptGetProperty: " NT_STATUS, -1)
  466.  
  467.    VarSetCapacity(pbInput, StrPut(string, "UTF-8"), 0) && cbInput := StrPut(string, &pbInput, "UTF-8") - 1, VarSetCapacity(pbHash, cbHash, 0)
  468.    If (NT_STATUS := DllCall("bcrypt\BCryptHash", "ptr", hAlgo, "ptr", 0, "uint", 0, "ptr", &pbInput, "uint", cbInput, "ptr", &pbHash, "uint", cbHash) != 0)
  469.        throw Exception("BCryptHash: " NT_STATUS, -1)
  470.  
  471.    Loop cbHash
  472.        hash .= Format("{:02x}", NumGet(pbHash, A_Index - 1, "uchar"))
  473.  
  474.    DllCall("bcrypt\BCryptCloseAlgorithmProvider", "ptr", hAlgo, "uint", 0)
  475.    DllCall("FreeLibrary", "ptr", hBCRYPT)
  476.  
  477.    Return(hash)
  478. }
  479.  
  480. ;#########Pastebin hotkeys###################
  481.  
  482. ; Pastebin API paste
  483. ^!1::
  484.     global api_dev_key
  485.     global api_user_key
  486.     global api_paste_format
  487.     global api_paste_private
  488.     global api_paste_expire_date
  489.     global pastebin_backup_dir
  490.    
  491.     old_clipboard := ClipboardAll
  492.     Clipboard := ""
  493.     SendInput("^c")
  494.     Clipwait(1.0)
  495.     If ErrorLevel
  496.     {
  497.         MsgBox("Clipboard operation failed!")
  498.         Clipboard := old_clipboard
  499.         CheckKeyState()
  500.         Exit()
  501.     }
  502.    
  503.     api_paste_code := Clipboard ; content of the paste
  504.    
  505.     ; Get api_paste_name
  506.    
  507.     Gui := GuiCreate(, "Create filename for Pastebin paste")
  508.     Gui.Add("Text",, "Please name the file:")
  509.     Gui.Add("Edit", "w400 vsearch")
  510.     Gui.Add("Button", "default", "OK").OnEvent("Click", () => ProcessUserInputPaste(Gui))
  511.     Gui.Add("Button", "x+5", "Cancel").OnEvent("Click", () => CancelUserInputPaste(Gui))
  512.     Gui.OnEvent("Close", "ProcessUserInputPaste")
  513.     Gui.OnEvent("Close", "CancelUserInputPaste")
  514.     Gui.Show()
  515.     Sleep(300)
  516.     ProcessUserInputPaste(this)
  517.     {
  518.         global api_paste_code ; required global
  519.         saved := this.Submit()  ; Save the contents of named controls into an object.
  520.         api_paste_name := saved.search
  521.        
  522.         ; Check to see if the file already exists by calling API for existing pastes
  523.        
  524.         api_results_limit := '1000'
  525.         api_option := 'list'
  526.         post_fields := 'api_option=' . api_option . '&api_user_key=' . api_user_key . '&api_dev_key=' . api_dev_key . '&api_results_limit=' . api_results_limit
  527.         url := "https://pastebin.com/api/api_post.php"
  528.         HttpObj := ComObjCreate("WinHttp.WinHttpRequest.5.1")
  529.         HttpObj.Open("POST", url)
  530.         HttpObj.SetRequestHeader("Content-Type","application/x-www-form-urlencoded")
  531.         HttpObj.Send(post_fields)
  532.        
  533.         ; Check response
  534.        
  535.         stream := ComObjCreate("adodb.stream")
  536.         stream.Type := 1
  537.         stream.Mode := 3
  538.         stream.Open()
  539.         stream.Write(HttpObj.ResponseBody) ; get bytes from ResponseBody
  540.         stream.Position := 0
  541.         stream.Type := 2
  542.         stream.Charset := 'UTF-8'
  543.         response := stream.ReadText()
  544.         stream.Close()
  545.         status := HttpObj.Status
  546.        
  547.         If !status = '200'
  548.         {
  549.             MsgBox("Http request failure in file listing! Error code: " . status)
  550.             Clipboard := old_clipboard
  551.             CheckKeyState()
  552.             Exit()
  553.         }
  554.         If !(InStr(response,"paste"))
  555.         {
  556.             MsgBox("Could not get list of pastes to compare file names.`nStatus = " . status . "`nPlease make sure your configuration file is correct.`n" . response)
  557.             Clipboard := old_clipboard
  558.             CheckKeyState()
  559.             Exit()
  560.         }
  561.        
  562.         ; Check to see if the file name already exists
  563.        
  564.         api_paste_key := '' ; We will extract this in order to use it when backing up and overwriting files
  565.         start_pos := 1
  566.         find_pos := ''
  567.         matches := []
  568.         regexp := 's)<paste_key>.*?</paste_title>'
  569.         Loop
  570.         {
  571.             find_pos := RegExMatch(response, regexp, match, start_pos)
  572.             If find_pos
  573.             {
  574.                 matches.Push(match[0])
  575.                 start_pos := match.Pos(0) + match.Len(0)
  576.             }
  577.         } Until find_pos = 0
  578.         exists := 0
  579.         Loop matches.Length()
  580.         {
  581.             string := matches[A_Index]
  582.             api_paste_name_regex := RegExReplace(api_paste_name, "([\.\^\$\*\+\?\(\)\[\{\\\|])", '\$1')
  583.             If RegExMatch(string, '<paste_title>' . api_paste_name_regex . '</paste_title>')
  584.             {
  585.                 match_pos := RegExMatch(string, '<paste_key>(.*?)</paste_key>', match)
  586.                 api_paste_key := match[1]
  587.                 exists := 1
  588.                 Break
  589.             }
  590.         }
  591.         If exists
  592.         {
  593.             result := MsgBox("The file already exists! Would you like to overwrite it? (Press Yes or No)",, "YesNo")
  594.             If result = "Yes"
  595.             {
  596.                 ; Create local backup
  597.                
  598.                 api_option := 'show_paste'
  599.                 post_fields := 'api_option=' . api_option . '&api_user_key=' . api_user_key . '&api_dev_key=' . api_dev_key . '&api_paste_key=' . api_paste_key
  600.                 url := "https://pastebin.com/api/api_raw.php"
  601.                 HttpObj := ComObjCreate("WinHttp.WinHttpRequest.5.1")
  602.                 HttpObj.Open("POST", url)
  603.                 HttpObj.SetRequestHeader("Content-Type","application/x-www-form-urlencoded")
  604.                 HttpObj.Send(post_fields)
  605.                
  606.                 ; Check response
  607.                
  608.                 status := HttpObj.Status
  609.                 If !status = '200'
  610.                 {
  611.                     MsgBox("Http request failure in file backup! Error code: " . status . "`nOriginal file not overwritten.")
  612.                     Clipboard := old_clipboard
  613.                     CheckKeyState()
  614.                     Exit()
  615.                 }
  616.                
  617.                 ; Decode bytes (WinHttp.WinHttpRequest.5.1 ResponseText wrongly decodes encoding)
  618.                
  619.                 stream := ComObjCreate("adodb.stream")
  620.                 stream.Type := 1
  621.                 stream.Mode := 3
  622.                 stream.Open()
  623.                 stream.Write(HttpObj.ResponseBody) ; get bytes from ResponseBody
  624.                 stream.Position := 0
  625.                 stream.Type := 2
  626.                 stream.Charset := 'UTF-8'
  627.                 response := stream.ReadText()
  628.                 stream.Close()
  629.                
  630.                 ; Write paste to local backup directory
  631.                
  632.                 backup_file := pastebin_backup_dir . api_paste_name
  633.                 t := A_NOW
  634.                 ts := FormatTime(t, "_yyyyMMdd-HHmmss")
  635.                 backup_file := RegExReplace(backup_file, '(.*?)(\.[^.]*$)', '$1' . ts . '$2')
  636.                 FileDelete(backup_file)
  637.                 FileAppend(response, backup_file, "UTF-8")
  638.                
  639.                 If !(FileExist(backup_file) And CheckAge(backup_file))
  640.                 {
  641.                     MsgBox("Local backup of " . api_paste_name . "failed! Aborting overwrite...")
  642.                     Clipboard := old_clipboard
  643.                     CheckKeyState()
  644.                     Exit()
  645.                 }
  646.                
  647.                 ; Delete paste (Irreversible in event of interruption between delete and paste!)
  648.                
  649.                 api_option := 'delete'
  650.                 post_fields := 'api_option=' . api_option . '&api_user_key=' . api_user_key . '&api_dev_key=' . api_dev_key . '&api_paste_key=' . api_paste_key
  651.                 url := "https://pastebin.com/api/api_post.php"
  652.                 HttpObj := ComObjCreate("WinHttp.WinHttpRequest.5.1")
  653.                 HttpObj.Open("POST", url)
  654.                 HttpObj.SetRequestHeader("Content-Type","application/x-www-form-urlencoded")
  655.                 HttpObj.Send(post_fields)
  656.                
  657.                 ; Check response
  658.                
  659.                 response := HttpObj.ResponseText
  660.                 status := HttpObj.Status
  661.                 If !status = '200'
  662.                 {
  663.                     MsgBox("Http request failure deleting file for overwrite! Error code: " . status . "`nOriginal file not overwritten.")
  664.                     Clipboard := old_clipboard
  665.                     CheckKeyState()
  666.                     Exit()
  667.                 }
  668.                 If !(InStr(response,"removed"))
  669.                 {
  670.                     MsgBox("Overwrite failure occurred! File not overwritten.`n" . response)
  671.                     Clipboard := old_clipboard
  672.                     CheckKeyState()
  673.                     Exit()
  674.                 }
  675.                
  676.             }
  677.             Else
  678.             {
  679.                 Clipboard := old_clipboard
  680.                 CheckKeyState()
  681.                 Exit()
  682.             }
  683.         }
  684.        
  685.         ; Create paste
  686.        
  687.         api_option := 'paste'
  688.         api_paste_name := UriEncode(api_paste_name)
  689.         api_paste_code := UriEncode(api_paste_code)
  690.         post_fields := 'api_option=' . api_option . '&api_user_key=' . api_user_key . '&api_paste_private=' . api_paste_private . '&api_paste_name=' . api_paste_name . '&api_paste_expire_date=' . api_paste_expire_date . '&api_paste_format=' . api_paste_format . '&api_dev_key=' . api_dev_key . '&api_paste_code=' . api_paste_code
  691.         ;MsgBox(post_fields)
  692.         ;Exit()
  693.         url := "https://pastebin.com/api/api_post.php"
  694.         HttpObj := ComObjCreate("WinHttp.WinHttpRequest.5.1")
  695.         HttpObj.Open("POST", url)
  696.         HttpObj.SetRequestHeader("Content-Type","application/x-www-form-urlencoded")
  697.         HttpObj.Send(post_fields)
  698.        
  699.         ; Check response
  700.        
  701.         response := HttpObj.ResponseText
  702.         status := HttpObj.Status
  703.         If !status = '200'
  704.         {
  705.             MsgBox("Http request failure in paste! Error code: " . status . "`nPlease check your backup folder if the previous version of the file was deleted from pastebin.com")
  706.             Clipboard := old_clipboard
  707.             CheckKeyState()
  708.             Exit()
  709.         }
  710.         If !(InStr(response,"pastebin"))
  711.         {
  712.             MsgBox("Paste failure occurred! File not pasted to Pastebin.com.`nPlease make sure your configuration file is correct.`n" . response . "`nPlease check your backup folder if the previous version of the file was deleted from pastebin.com")
  713.             Clipboard := old_clipboard
  714.             CheckKeyState()
  715.             Exit()
  716.         }
  717.         Else
  718.         {
  719.             Clipboard := response ; send paste link to the clipboard
  720.             MsgBox("Sucessfully pasted!" . response . "`nPaste link copied to clipboard")
  721.             CheckKeyState()
  722.             Exit()
  723.         }
  724.     }
  725.     CancelUserInputPaste(this)
  726.     {
  727.         saved := this.Submit()  ; Save the contents of named controls into an object.
  728.         Clipboard := old_clipboard
  729.         CheckKeyState()
  730.         Exit()
  731.     }
  732. Return
  733.  
  734. ; Folder and file paste
  735. ^!2::
  736.     global api_dev_key
  737.     global api_user_key
  738.     global api_paste_format
  739.     global api_paste_private
  740.     global api_paste_expire_date
  741.     global pastebin_backup_dir
  742.    
  743.     old_clipboard := ClipboardAll
  744.     Clipboard := ""
  745.     SendInput("^c")
  746.     Clipwait(1.0)
  747.     If ErrorLevel
  748.     {
  749.         MsgBox("Clipboard operation failed!")
  750.         Clipboard := old_clipboard
  751.         CheckKeyState()
  752.         Exit()
  753.     }
  754.     files := []
  755.     files_unique := {}
  756.     Loop Parse, Clipboard, "`n", "`r"
  757.     {
  758.         If !InStr(FileGetAttrib(A_LoopField), "D")
  759.         {
  760.              If RegExMatch(A_LoopField, "\.txt$|\.md$|\.ahk$|\.p[ylhs][p1]?$|\.html?$|\.js$|\.[ct]sv$")
  761.             {
  762.                 files.Push(A_LoopField)
  763.                 RegExMatch(A_LoopField, "[^\\]*$", match) ; get file name only (no path)
  764.                 files_unique[match[0]] := 1
  765.             }
  766.         }
  767.         Else
  768.         {
  769.             Loop Files, A_LoopField . "\*.*", "FDR"
  770.             {
  771.                 If !InStr(FileGetAttrib(A_LoopFileFullPath), "D")
  772.                 {
  773.                      If RegExMatch(A_LoopFileFullPath, "\.txt$|\.md$|\.ahk$|\.p[ylhs][p1]?$|\.html?$|\.js$|\.[ct]sv$")
  774.                     {
  775.                         files.Push(A_LoopFileFullPath)
  776.                         RegExMatch(A_LoopFileFullPath, "[^\\]*$", match) ; get file name only
  777.                         files_unique[match[0]] := 1
  778.                     }
  779.                 }
  780.             }
  781.         }
  782.     }
  783.    
  784.     ; If there are no files with duplicate names, we can grab the list only once
  785.     ; So we need to create a flag
  786.    
  787.     list_flag := 0
  788.     list_loop := 1
  789.    
  790.     If files.Length() = files_unique.Length()
  791.     {
  792.         ; No duplicate names
  793.         list_flag := 1
  794.     }
  795.    
  796.     paste_results := '' ; summary of files pasted
  797.     paste_count := 0
  798.     paste_errors := 0
  799.     duplicate_results := '' ; summary of files with duplicate content (not overwritten or re-pasted)
  800.     duplicate_count := 0
  801.     list_matches := []
  802.    
  803.     Loop files.Length()
  804.     {
  805.         match_pos := RegExMatch(files[A_Index], "[^\\]*$", match) ; get file name only (no path)
  806.        
  807.         api_paste_name := match[0]
  808.         api_paste_code := FileRead(files[A_Index], "UTF-8")
  809.         ; NEED TO STRIP OFF NEWLINES BECAUSE PASTEBIN.COM STRIPS OFF ALL TRAILING NEWLINES FROM API-BASED PASTES
  810.         api_paste_code_stripped := RegExReplace(api_paste_code, '(?:\r?\n)*$', '')
  811.         api_paste_code_md5 := BcryptMd5(api_paste_code_stripped) ; for checking file content
  812.        
  813.         ; Check to see if the file already exists by calling API for existing pastes
  814.        
  815.         If list_loop
  816.         {
  817.             api_results_limit := '1000'
  818.             api_option := 'list'
  819.             post_fields := 'api_option=' . api_option . '&api_user_key=' . api_user_key . '&api_dev_key=' . api_dev_key . '&api_results_limit=' . api_results_limit
  820.             url := "https://pastebin.com/api/api_post.php"
  821.             HttpObj := ComObjCreate("WinHttp.WinHttpRequest.5.1")
  822.             HttpObj.Open("POST", url)
  823.             HttpObj.SetRequestHeader("Content-Type","application/x-www-form-urlencoded")
  824.             HttpObj.Send(post_fields)
  825.  
  826.             ; Check response
  827.            
  828.             stream := ComObjCreate("adodb.stream")
  829.             stream.Type := 1
  830.             stream.Mode := 3
  831.             stream.Open()
  832.             stream.Write(HttpObj.ResponseBody) ; get bytes from ResponseBody
  833.             stream.Position := 0
  834.             stream.Type := 2
  835.             stream.Charset := 'UTF-8'
  836.             response := stream.ReadText()
  837.             stream.Close()
  838.             status := HttpObj.Status
  839.            
  840.             If !status = '200'
  841.             {
  842.                 result := MsgBox("Http request failure in file listing for " . api_paste_name . "! Error code: " . status . "`nPlease make sure your configuration file is correct.`nDo you want to try to continue pasting the rest of the files? This error may occur repeatedly.",, "YesNo")
  843.                 If result = "Yes"
  844.                 {
  845.                     paste_errors++
  846.                     Continue
  847.                 }
  848.                 Else
  849.                 {
  850.                     Clipboard := old_clipboard
  851.                     paste_results := paste_count . " file(s) were pasted to pastebin.com with " . ++paste_errors . " error(s)!`n" . paste_results . "`n" . duplicate_count . " duplicate(s)`n" . duplicate_results
  852.                     MsgBox(paste_results)
  853.                     CheckKeyState()
  854.                     Exit()
  855.                 }
  856.             }
  857.             If !(InStr(response,"paste"))
  858.             {
  859.                 result := MsgBox("Could not get list of pastes to compare file names for " . api_paste_name . "! Error code: " . status . "`nPlease make sure your configuration file is correct.`nResponse: " . response . "`nDo you want to try to continue pasting the rest of the files? This error may occur repeatedly.",, "YesNo")
  860.                 If result = "Yes"
  861.                 {
  862.                     paste_errors++
  863.                     Continue
  864.                 }
  865.                 Else
  866.                 {
  867.                     Clipboard := old_clipboard
  868.                     paste_results := paste_count . " file(s) were pasted to pastebin.com with " . ++paste_errors . " error(s)!`n" . paste_results . "`n" . duplicate_count . " duplicate(s)`n" . duplicate_results
  869.                     MsgBox(paste_results)
  870.                     CheckKeyState()
  871.                     Exit()
  872.                 }
  873.             }
  874.            
  875.             ; Check to see if the file name already exists
  876.            
  877.             api_paste_key := '' ; We will extract this in order to use it when backing up and overwriting files
  878.             start_pos := 1
  879.             find_pos := ''
  880.             list_matches := []
  881.             regexp := 's)<paste_key>.*?</paste_title>'
  882.             Loop
  883.             {
  884.                 find_pos := RegExMatch(response, regexp, match, start_pos)
  885.                 If find_pos
  886.                 {
  887.                     list_matches.Push(match[0])
  888.                     start_pos := match.Pos(0) + match.Len(0)
  889.                 }
  890.             } Until find_pos = 0
  891.             If list_flag
  892.             {
  893.                 list_loop := 0
  894.             }
  895.         }
  896.         exists := 0
  897.         Loop list_matches.Length()
  898.         {
  899.             string := list_matches[A_Index]
  900.             api_paste_name_regex := RegExReplace(api_paste_name, "([\.\^\$\*\+\?\(\)\[\{\\\|])", '\$1')
  901.             If RegExMatch(string, '<paste_title>' . api_paste_name_regex . '</paste_title>')
  902.             {
  903.                 match_pos := RegExMatch(string, '<paste_key>(.*?)</paste_key>', match)
  904.                 api_paste_key := match[1]
  905.                 exists := 1
  906.                 Break
  907.             }
  908.         }
  909.         If exists = 1
  910.         {
  911.             ; Get paste content from pastebin.com to check md5 and possibly backup and overwrite
  912.            
  913.             api_option := 'show_paste'
  914.             post_fields := 'api_option=' . api_option . '&api_user_key=' . api_user_key . '&api_dev_key=' . api_dev_key . '&api_paste_key=' . api_paste_key
  915.             url := "https://pastebin.com/api/api_raw.php"
  916.             HttpObj := ComObjCreate("WinHttp.WinHttpRequest.5.1")
  917.             HttpObj.Open("POST", url)
  918.             HttpObj.SetRequestHeader("Content-Type","application/x-www-form-urlencoded")
  919.             HttpObj.Send(post_fields)
  920.            
  921.             ; Check response
  922.            
  923.             status := HttpObj.Status
  924.             If !status = '200'
  925.             {
  926.                 result := MsgBox("Http request failure while checking for duplicate files for " . api_paste_name . "! Error code: " . status "`nOriginal file not overwritten.`nDo you want to try to continue pasting the rest of the files? This error may occur repeatedly.",, "YesNo")
  927.                 If result = "Yes"
  928.                 {
  929.                     paste_errors++
  930.                     Continue
  931.                 }
  932.                 Else
  933.                 {
  934.                     Clipboard := old_clipboard
  935.                     paste_results := paste_count . " file(s) were pasted to pastebin.com with " . ++paste_errors . " error(s)!`n" . paste_results . "`n" . duplicate_count . " duplicate(s)`n" . duplicate_results
  936.                     MsgBox(paste_results)
  937.                     CheckKeyState()
  938.                     Exit()
  939.                 }
  940.             }
  941.            
  942.             ; Decode bytes (WinHttp.WinHttpRequest.5.1 ResponseText wrongly decodes encoding)
  943.            
  944.             stream := ComObjCreate("adodb.stream")
  945.             stream.Type := 1
  946.             stream.Mode := 3
  947.             stream.Open()
  948.             stream.Write(HttpObj.ResponseBody) ; get bytes from ResponseBody
  949.             stream.Position := 0
  950.             stream.Type := 2
  951.             stream.Charset := 'UTF-8'
  952.             response := stream.ReadText()
  953.             stream.Close()
  954.            
  955.             ; Get and check md5
  956.            
  957.             response_md5 := BcryptMd5(response)
  958.             If response_md5 = api_paste_code_md5
  959.             {
  960.                 ; Paste content is the same. Don't backup or re-paste
  961.                 duplicate_count++
  962.                 duplicate_results .= A_Tab . api_paste_name . "`n"
  963.                 Continue
  964.             }
  965.                            
  966.             result := MsgBox(api_paste_name . " already exists! Would you like to overwrite it? (Press Yes or No)",, "YesNo")
  967.             If result = "Yes"
  968.             {
  969.                 ; Write paste to local backup directory
  970.                
  971.                 backup_file := pastebin_backup_dir . api_paste_name
  972.                 t := A_NOW
  973.                 ts := FormatTime(t, "_yyyyMMdd-HHmmss")
  974.                 backup_file := RegExReplace(backup_file, '(.*?)(\.[^.]*$)', '$1' . ts . '$2')
  975.                 FileDelete(backup_file)
  976.                 FileAppend(response, backup_file, "UTF-8")
  977.                
  978.                 If !(FileExist(backup_file) And CheckAge(backup_file))
  979.                 {
  980.                     result := MsgBox("Local backup of " . api_paste_name . "failed! Aborting overwrite. Do you want to try to continue pasting the rest of the files? This error may occur repeatedly.",, "YesNo")
  981.                     If result = "Yes"
  982.                     {
  983.                         paste_errors++
  984.                         Continue
  985.                     }
  986.                     Else
  987.                     {
  988.                         Clipboard := old_clipboard
  989.                         paste_results := paste_count . " file(s) were pasted to pastebin.com with " . ++paste_errors . " error(s)!`n" . paste_results . "`n" . duplicate_count . " duplicate(s)`n" . duplicate_results
  990.                         MsgBox(paste_results)
  991.                         CheckKeyState()
  992.                         Exit()
  993.                     }
  994.                 }
  995.                
  996.                 ; Delete paste (Irreversible in event of interruption between delete and paste!)
  997.                
  998.                 api_option := 'delete'
  999.                 post_fields := 'api_option=' . api_option . '&api_user_key=' . api_user_key . '&api_dev_key=' . api_dev_key . '&api_paste_key=' . api_paste_key
  1000.                 url := "https://pastebin.com/api/api_post.php"
  1001.                 HttpObj := ComObjCreate("WinHttp.WinHttpRequest.5.1")
  1002.                 HttpObj.Open("POST", url)
  1003.                 HttpObj.SetRequestHeader("Content-Type","application/x-www-form-urlencoded")
  1004.                 HttpObj.Send(post_fields)
  1005.                
  1006.                 ; Check response
  1007.                
  1008.                 response := HttpObj.ResponseText
  1009.                 status := HttpObj.Status
  1010.                 If !status = '200'
  1011.                 {
  1012.                     result := MsgBox("Http request failure deleting " . api_paste_name . " for overwrite! Error code: " . status . "`nDo you want to try to continue pasting the rest of the files? This error may occur repeatedly.",, "YesNo")
  1013.                     If result = "Yes"
  1014.                     {
  1015.                         paste_errors++
  1016.                         Continue
  1017.                     }
  1018.                     Else
  1019.                     {
  1020.                         Clipboard := old_clipboard
  1021.                         paste_results := paste_count . " file(s) were pasted to pastebin.com with " . ++paste_errors . " error(s)!`n" . paste_results . "`n" . duplicate_count . " duplicate(s)`n" . duplicate_results
  1022.                         MsgBox(paste_results)
  1023.                         CheckKeyState()
  1024.                         Exit()
  1025.                     }
  1026.                 }
  1027.                 If !(InStr(response,"removed"))
  1028.                 {
  1029.                     result := MsgBox("Overwrite failure occurred for " . api_paste_name . " ! File not overwritten.`nResponse: " . response . "`nDo you want to try to continue pasting the rest of the files? This error may occur repeatedly.",, "YesNo")
  1030.                     If result = "Yes"
  1031.                     {
  1032.                         paste_errors++
  1033.                         Continue
  1034.                     }
  1035.                     Else
  1036.                     {
  1037.                         Clipboard := old_clipboard
  1038.                         paste_results := paste_count . " file(s) were pasted to pastebin.com with " . ++paste_errors . " error(s)!`n" . paste_results . "`n" . duplicate_count . " duplicate(s)`n" . duplicate_results
  1039.                         MsgBox(paste_results)
  1040.                         CheckKeyState()
  1041.                         Exit()
  1042.                     }
  1043.                 }
  1044.                
  1045.             }
  1046.             Else
  1047.             {
  1048.                 Continue ; keep processing the rest of the files
  1049.             }
  1050.         }
  1051.        
  1052.         ; Create paste
  1053.        
  1054.         api_option := 'paste'
  1055.         paste_name := api_paste_name
  1056.         api_paste_name := UriEncode(api_paste_name)
  1057.         api_paste_code := UriEncode(api_paste_code)
  1058.         post_fields := 'api_option=' . api_option . '&api_user_key=' . api_user_key . '&api_paste_private=' . api_paste_private . '&api_paste_name=' . api_paste_name . '&api_paste_expire_date=' . api_paste_expire_date . '&api_paste_format=' . api_paste_format . '&api_dev_key=' . api_dev_key . '&api_paste_code=' . api_paste_code
  1059.         ;MsgBox(post_fields)
  1060.         ;Exit()
  1061.         url := "https://pastebin.com/api/api_post.php"
  1062.         HttpObj := ComObjCreate("WinHttp.WinHttpRequest.5.1")
  1063.         HttpObj.Open("POST", url)
  1064.         HttpObj.SetRequestHeader("Content-Type","application/x-www-form-urlencoded")
  1065.         HttpObj.Send(post_fields)
  1066.        
  1067.         ; Check response
  1068.        
  1069.         response := HttpObj.ResponseText
  1070.         status := HttpObj.Status
  1071.         If !status = '200'
  1072.         {
  1073.             result := MsgBox("Http request failure in paste for " . paste_name . " ! Error code: " . status . "`nDo you want to try to continue pasting the rest of the files? This error may occur repeatedly.",, "YesNo")
  1074.             If result = "Yes"
  1075.             {
  1076.                 paste_errors++
  1077.                 Continue
  1078.             }
  1079.             Else
  1080.             {
  1081.                 Clipboard := old_clipboard
  1082.                 paste_results := paste_count . " file(s) were pasted to pastebin.com with " . ++paste_errors . " error(s)!`n" . paste_results . "`n" . duplicate_count . " duplicate(s)`n" . duplicate_results
  1083.                 MsgBox(paste_results)
  1084.                 CheckKeyState()
  1085.                 Exit()
  1086.             }
  1087.         }
  1088.         If !(InStr(response,"pastebin"))
  1089.         {
  1090.             result := MsgBox("Paste failure occurred for " . paste_name . " ! Error code: " . status . "`nResponse: " . response . "`nDo you want to try to continue pasting the rest of the files? This error may occur repeatedly.",, "YesNo")
  1091.             If result = "Yes"
  1092.             {
  1093.                 paste_errors++
  1094.                 Continue
  1095.             }
  1096.             Else
  1097.             {
  1098.                 Clipboard := old_clipboard
  1099.                 paste_results := paste_count . " file(s) were pasted to pastebin.com with " . ++paste_errors . " error(s)!`n" . paste_results . "`n" . duplicate_count . " duplicate(s)`n" . duplicate_results
  1100.                 MsgBox(paste_results)
  1101.                 CheckKeyState()
  1102.                 Exit()
  1103.             }
  1104.         }
  1105.         Else
  1106.         {
  1107.             paste_results .= A_Tab . paste_name . ":" . A_Tab . response . "`n"
  1108.             paste_count++
  1109.         }
  1110.     }
  1111.     paste_results := "Results summary (also copied to your computer's clipboard):`n`n" . paste_count . " file(s) were pasted to pastebin.com with " . paste_errors . " error(s)!`n" . paste_results . "`n" . duplicate_count . " duplicate(s)`n" . duplicate_results
  1112.     Clipboard := paste_results
  1113.     MsgBox(paste_results)
  1114.     CheckKeyState()
  1115. Return
  1116.  
  1117. ; Pastebin API grab content to clipboard
  1118. ^!3::
  1119.     global api_dev_key
  1120.     global api_user_key
  1121.    
  1122.     ; Get api_paste_name
  1123.    
  1124.     Gui := GuiCreate(, "Enter filename for Pastebin download")
  1125.     Gui.Add("Text",, "Please enter the filename:")
  1126.     Gui.Add("Edit", "w400 vsearch")
  1127.     Gui.Add("Button", "default", "OK").OnEvent("Click", () => ProcessUserInputDownload(Gui))
  1128.     Gui.Add("Button", "x+5", "Cancel").OnEvent("Click", () => CancelUserInputDownload(Gui))
  1129.     Gui.OnEvent("Close", "ProcessUserInputDownload")
  1130.     Gui.OnEvent("Close", "CancelUserInputDownload")
  1131.     Gui.Show()
  1132.     Sleep(300)
  1133.     ProcessUserInputDownload(this)
  1134.     {
  1135.         saved := this.Submit()  ; Save the contents of named controls into an object.
  1136.         api_paste_name := saved.search
  1137.        
  1138.         ; Check to see if the file exists by calling API for existing pastes
  1139.        
  1140.         api_results_limit := '1000'
  1141.         api_option := 'list'
  1142.         post_fields := 'api_option=' . api_option . '&api_user_key=' . api_user_key . '&api_dev_key=' . api_dev_key . '&api_results_limit=' . api_results_limit
  1143.         url := "https://pastebin.com/api/api_post.php"
  1144.         HttpObj := ComObjCreate("WinHttp.WinHttpRequest.5.1")
  1145.         HttpObj.Open("POST", url)
  1146.         HttpObj.SetRequestHeader("Content-Type","application/x-www-form-urlencoded")
  1147.         HttpObj.Send(post_fields)
  1148.        
  1149.         ; Check response
  1150.        
  1151.         stream := ComObjCreate("adodb.stream")
  1152.         stream.Type := 1
  1153.         stream.Mode := 3
  1154.         stream.Open()
  1155.         stream.Write(HttpObj.ResponseBody) ; get bytes from ResponseBody
  1156.         stream.Position := 0
  1157.         stream.Type := 2
  1158.         stream.Charset := 'UTF-8'
  1159.         response := stream.ReadText()
  1160.         stream.Close()
  1161.         status := HttpObj.Status
  1162.        
  1163.         If !status = '200'
  1164.         {
  1165.             MsgBox("Http request failure in file listing! Error code: " . status . "`nPlease make sure your configuration file is correct.")
  1166.             CheckKeyState()
  1167.             Exit()
  1168.         }
  1169.         If !(InStr(response,"paste"))
  1170.         {
  1171.             MsgBox("Could not get list of pastes to compare file names.`nPlease make sure your configuration file is correct.`n" . response)
  1172.             CheckKeyState()
  1173.             Exit()
  1174.         }
  1175.        
  1176.         ; Check to see if the file name already exists
  1177.        
  1178.         api_paste_key := '' ; We will extract this in order to use it when backing up and overwriting files
  1179.         start_pos := 1
  1180.         find_pos := ''
  1181.         matches := []
  1182.         regexp := 's)<paste_key>.*?</paste_title>'
  1183.         Loop
  1184.         {
  1185.             find_pos := RegExMatch(response, regexp, match, start_pos)
  1186.             If find_pos
  1187.             {
  1188.                 matches.Push(match[0])
  1189.                 start_pos := match.Pos(0) + match.Len(0)
  1190.             }
  1191.         } Until find_pos = 0
  1192.         exists := 0
  1193.         Loop matches.Length()
  1194.         {
  1195.             string := matches[A_Index]
  1196.             api_paste_name_regex := RegExReplace(api_paste_name, "([\.\^\$\*\+\?\(\)\[\{\\\|])", '\$1')
  1197.             If RegExMatch(string, '<paste_title>' . api_paste_name_regex . '</paste_title>')
  1198.             {
  1199.                 match_pos := RegExMatch(string, '<paste_key>(.*?)</paste_key>', match)
  1200.                 api_paste_key := match[1]
  1201.                 exists := 1
  1202.                 Break
  1203.             }
  1204.         }
  1205.         If exists
  1206.         {
  1207.             ; Download the paste to the clipboard
  1208.            
  1209.             api_option := 'show_paste'
  1210.             post_fields := 'api_option=' . api_option . '&api_user_key=' . api_user_key . '&api_dev_key=' . api_dev_key . '&api_paste_key=' . api_paste_key
  1211.             url := "https://pastebin.com/api/api_raw.php"
  1212.             HttpObj := ComObjCreate("WinHttp.WinHttpRequest.5.1")
  1213.             HttpObj.Open("POST", url)
  1214.             HttpObj.SetRequestHeader("Content-Type","application/x-www-form-urlencoded")
  1215.             HttpObj.Send(post_fields)
  1216.            
  1217.             ; Check response
  1218.            
  1219.             status := HttpObj.Status
  1220.             If !status = '200'
  1221.             {
  1222.                 MsgBox("Http request failure in paste download! Error code: " . status)
  1223.                 Clipboard := old_clipboard
  1224.                 CheckKeyState()
  1225.                 Exit()
  1226.             }
  1227.            
  1228.             ; Decode bytes (WinHttp.WinHttpRequest.5.1 ResponseText wrongly decodes encoding)
  1229.            
  1230.             stream := ComObjCreate("adodb.stream")
  1231.             stream.Type := 1
  1232.             stream.Mode := 3
  1233.             stream.Open()
  1234.             stream.Write(HttpObj.ResponseBody) ; get bytes from ResponseBody
  1235.             stream.Position := 0
  1236.             stream.Type := 2
  1237.             stream.Charset := 'utf-8'
  1238.             response := stream.ReadText()
  1239.             stream.Close()
  1240.            
  1241.             ; Paste to clipboard
  1242.            
  1243.             Clipboard := response
  1244.             MsgBox(api_paste_name . " copied to clipboard.")
  1245.             CheckKeyState()
  1246.             Exit()
  1247.         }
  1248.         Else
  1249.         {
  1250.             MsgBox(api_paste_name . " does not exist!")
  1251.             CheckKeyState()
  1252.             Exit()
  1253.         }
  1254.     }
  1255.     CancelUserInputDownload(this)
  1256.     {
  1257.         saved := this.Submit()  ; Save the contents of named controls into an object.
  1258.         Clipboard := old_clipboard
  1259.         CheckKeyState()
  1260.         Exit()
  1261.     }
  1262. Return
  1263.  
  1264. ; Pastebin API paste append
  1265. ^!4::
  1266.     global api_dev_key
  1267.     global api_user_key
  1268.     global api_paste_format
  1269.     global api_paste_private
  1270.     global api_paste_expire_date
  1271.     global pastebin_backup_dir
  1272.    
  1273.     api_paste_name := ''
  1274.     old_clipboard := ClipboardAll
  1275.     Clipboard := ""
  1276.     SendInput("^c")
  1277.     Clipwait(1.0)
  1278.     If ErrorLevel
  1279.     {
  1280.         MsgBox("Clipboard operation failed!")
  1281.         Clipboard := old_clipboard
  1282.         CheckKeyState()
  1283.         Exit()
  1284.     }
  1285.     api_paste_code := Clipboard ; content to append
  1286.    
  1287.     ; Get api_paste_name
  1288.    
  1289.     Gui := GuiCreate(, "Enter the filename for appending")
  1290.     Gui.Add("Text",, "Please enter the filename:")
  1291.     Gui.Add("Edit", "w400 vsearch")
  1292.     Gui.Add("Button", "default", "OK").OnEvent("Click", () => ProcessUserInputAppend(Gui))
  1293.     Gui.Add("Button", "x+5", "Cancel").OnEvent("Click", () => CancelUserInputAppend(Gui))
  1294.     Gui.OnEvent("Close", "ProcessUserInputAppend")
  1295.     Gui.OnEvent("Close", "CancelUserInputAppend")
  1296.     Gui.Show()
  1297.     Sleep(300)
  1298.     ProcessUserInputAppend(this)
  1299.     {
  1300.         global api_paste_code ; required global
  1301.         saved := this.Submit()  ; Save the contents of named controls into an object.
  1302.         api_paste_name := saved.search
  1303.        
  1304.         ; Check to see if the file already exists by calling API for existing pastes
  1305.        
  1306.         api_results_limit := '1000'
  1307.         api_option := 'list'
  1308.         post_fields := 'api_option=' . api_option . '&api_user_key=' . api_user_key . '&api_dev_key=' . api_dev_key . '&api_results_limit=' . api_results_limit
  1309.         url := "https://pastebin.com/api/api_post.php"
  1310.         HttpObj := ComObjCreate("WinHttp.WinHttpRequest.5.1")
  1311.         HttpObj.Open("POST", url)
  1312.         HttpObj.SetRequestHeader("Content-Type","application/x-www-form-urlencoded")
  1313.         HttpObj.Send(post_fields)
  1314.        
  1315.         ; Check response
  1316.        
  1317.         stream := ComObjCreate("adodb.stream")
  1318.         stream.Type := 1
  1319.         stream.Mode := 3
  1320.         stream.Open()
  1321.         stream.Write(HttpObj.ResponseBody) ; get bytes from ResponseBody
  1322.         stream.Position := 0
  1323.         stream.Type := 2
  1324.         stream.Charset := 'UTF-8'
  1325.         response := stream.ReadText()
  1326.         stream.Close()
  1327.         status := HttpObj.Status
  1328.        
  1329.         If !status = '200'
  1330.         {
  1331.             MsgBox("Http request failure in file listing! Error code: " . status . "`nPlease make sure your configuration file is correct.")
  1332.             Clipboard := old_clipboard
  1333.             CheckKeyState()
  1334.             Exit()
  1335.         }
  1336.         If !(InStr(response,"paste"))
  1337.         {
  1338.             MsgBox("Could not get list of pastes to compare file names.`nPlease make sure your configuration file is correct.`n" . response)
  1339.             Clipboard := old_clipboard
  1340.             CheckKeyState()
  1341.             Exit()
  1342.         }
  1343.        
  1344.         ; Check to see if the filename already exists
  1345.        
  1346.         api_paste_key := '' ; We will extract this in order to use it when backing up and overwriting files
  1347.         start_pos := 1
  1348.         find_pos := ''
  1349.         matches := []
  1350.         regexp := 's)<paste_key>.*?</paste_title>'
  1351.         Loop
  1352.         {
  1353.             find_pos := RegExMatch(response, regexp, match, start_pos)
  1354.             If find_pos
  1355.             {
  1356.                 matches.Push(match[0])
  1357.                 start_pos := match.Pos(0) + match.Len(0)
  1358.             }
  1359.         } Until find_pos = 0
  1360.         exists := 0
  1361.         Loop matches.Length()
  1362.         {
  1363.             string := matches[A_Index]
  1364.             api_paste_name_regex := RegExReplace(api_paste_name, "([\.\^\$\*\+\?\(\)\[\{\\\|])", '\$1')
  1365.             If RegExMatch(string, '<paste_title>' . api_paste_name_regex . '</paste_title>')
  1366.             {
  1367.                 match_pos := RegExMatch(string, '<paste_key>(.*?)</paste_key>', match)
  1368.                 api_paste_key := match[1]
  1369.                 exists := 1
  1370.                 Break
  1371.             }
  1372.         }
  1373.         If exists
  1374.         {
  1375.             ; Create local backup
  1376.            
  1377.             api_option := 'show_paste'
  1378.             post_fields := 'api_option=' . api_option . '&api_user_key=' . api_user_key . '&api_dev_key=' . api_dev_key . '&api_paste_key=' . api_paste_key
  1379.             url := "https://pastebin.com/api/api_raw.php"
  1380.             HttpObj := ComObjCreate("WinHttp.WinHttpRequest.5.1")
  1381.             HttpObj.Open("POST", url)
  1382.             HttpObj.SetRequestHeader("Content-Type","application/x-www-form-urlencoded")
  1383.             HttpObj.Send(post_fields)
  1384.            
  1385.             ; Check response
  1386.            
  1387.             status := HttpObj.Status
  1388.             If !status = '200'
  1389.             {
  1390.                 MsgBox("Http request failure in file backup! Error code: " . status)
  1391.                 Clipboard := old_clipboard
  1392.                 CheckKeyState()
  1393.                 Exit()
  1394.             }
  1395.            
  1396.             ; Decode bytes (WinHttp.WinHttpRequest.5.1 ResponseText wrongly decodes encoding)
  1397.            
  1398.             stream := ComObjCreate("adodb.stream")
  1399.             stream.Type := 1
  1400.             stream.Mode := 3
  1401.             stream.Open()
  1402.             stream.Write(HttpObj.ResponseBody) ; get bytes from ResponseBody
  1403.             stream.Position := 0
  1404.             stream.Type := 2
  1405.             stream.Charset := 'UTF-8'
  1406.             response := stream.ReadText()
  1407.             stream.Close()
  1408.            
  1409.             ; Write paste to local backup directory
  1410.            
  1411.             backup_file := pastebin_backup_dir . api_paste_name
  1412.             t := A_NOW
  1413.             ts := FormatTime(t, "_yyyyMMdd-HHmmss")
  1414.             backup_file := RegExReplace(backup_file, '(.*?)(\.[^.]*$)', '$1' . ts . '$2')
  1415.             FileDelete(backup_file)
  1416.             FileAppend(response, backup_file, "UTF-8")
  1417.            
  1418.             If !(FileExist(backup_file) And CheckAge(backup_file))
  1419.             {
  1420.                 MsgBox("Local backup of " . api_paste_name . "failed! File not updated. Aborting append...")
  1421.                 Exit()
  1422.             }
  1423.            
  1424.             ; Update api_paste_code
  1425.            
  1426.             api_paste_code := response . "`r`n" . api_paste_code ; Windows new line
  1427.            
  1428.             ; Delete paste (Irreversible in event of interruption between delete and paste!)
  1429.            
  1430.             api_option := 'delete'
  1431.             post_fields := 'api_option=' . api_option . '&api_user_key=' . api_user_key . '&api_dev_key=' . api_dev_key . '&api_paste_key=' . api_paste_key
  1432.             url := "https://pastebin.com/api/api_post.php"
  1433.             HttpObj := ComObjCreate("WinHttp.WinHttpRequest.5.1")
  1434.             HttpObj.Open("POST", url)
  1435.             HttpObj.SetRequestHeader("Content-Type","application/x-www-form-urlencoded")
  1436.             HttpObj.Send(post_fields)
  1437.            
  1438.             ; Check response
  1439.            
  1440.             response := HttpObj.ResponseText
  1441.             status := HttpObj.Status
  1442.             If !status = '200'
  1443.             {
  1444.                 MsgBox("Http request failure during append! Original file not changed. Error code: " . status)
  1445.                 Clipboard := old_clipboard
  1446.                 CheckKeyState()
  1447.                 Exit()
  1448.             }
  1449.             If !(InStr(response,"removed"))
  1450.             {
  1451.                 MsgBox("Append failure occurred! File not appended to.`n" . response)
  1452.                 Clipboard := old_clipboard
  1453.                 CheckKeyState()
  1454.                 Exit()
  1455.             }
  1456.            
  1457.             ; Create appended paste
  1458.            
  1459.             api_option := 'paste'
  1460.             api_paste_name := UriEncode(api_paste_name)
  1461.             api_paste_code := UriEncode(api_paste_code)
  1462.             post_fields := 'api_option=' . api_option . '&api_user_key=' . api_user_key . '&api_paste_private=' . api_paste_private . '&api_paste_name=' . api_paste_name . '&api_paste_expire_date=' . api_paste_expire_date . '&api_paste_format=' . api_paste_format . '&api_dev_key=' . api_dev_key . '&api_paste_code=' . api_paste_code
  1463.             ;MsgBox(post_fields)
  1464.             url := "https://pastebin.com/api/api_post.php"
  1465.             HttpObj := ComObjCreate("WinHttp.WinHttpRequest.5.1")
  1466.             HttpObj.Open("POST", url)
  1467.             HttpObj.SetRequestHeader("Content-Type","application/x-www-form-urlencoded")
  1468.             HttpObj.Send(post_fields)
  1469.            
  1470.             ; Check response
  1471.                    
  1472.             response := HttpObj.ResponseText
  1473.             status := HttpObj.Status
  1474.             If !status = '200'
  1475.             {
  1476.                 MsgBox("Http request failure! File not appended to and original file deleted! Please check local backup.`nError code: " . status)
  1477.                 Clipboard := old_clipboard
  1478.                 CheckKeyState()
  1479.                 Exit()
  1480.             }
  1481.             If !(InStr(response,"pastebin"))
  1482.             {
  1483.                 MsgBox("Paste append failed! File not appended to and original file deleted! Please check local backup.`n" . response)
  1484.                 Clipboard := old_clipboard
  1485.                 CheckKeyState()
  1486.                 Exit()
  1487.             }
  1488.             Else
  1489.             {
  1490.                 Clipboard := response ; copy paste link to clipboard
  1491.                 MsgBox("Sucessfully appended paste!" . response . "`nPaste link copied to clipboard")
  1492.                 CheckKeyState()
  1493.                 Exit()
  1494.             }
  1495.         }
  1496.         Else
  1497.         {
  1498.             result := MsgBox(api_paste_name . " does not exist! Do you want to create it? (Press Yes or No)",, "YesNo")
  1499.             If result = "Yes"
  1500.             {
  1501.                 ; Create paste
  1502.        
  1503.                 api_option := 'paste'
  1504.                 api_paste_name := UriEncode(api_paste_name)
  1505.                 api_paste_code := UriEncode(api_paste_code)
  1506.                 post_fields := 'api_option=' . api_option . '&api_user_key=' . api_user_key . '&api_paste_private=' . api_paste_private . '&api_paste_name=' . api_paste_name . '&api_paste_expire_date=' . api_paste_expire_date . '&api_paste_format=' . api_paste_format . '&api_dev_key=' . api_dev_key . '&api_paste_code=' . api_paste_code
  1507.                 ;MsgBox(post_fields)
  1508.                 url := "https://pastebin.com/api/api_post.php"
  1509.                 HttpObj := ComObjCreate("WinHttp.WinHttpRequest.5.1")
  1510.                 HttpObj.Open("POST", url)
  1511.                 HttpObj.SetRequestHeader("Content-Type","application/x-www-form-urlencoded")
  1512.                 HttpObj.Send(post_fields)
  1513.                
  1514.                 ; Check response
  1515.                        
  1516.                 response := HttpObj.ResponseText
  1517.                 status := HttpObj.Status
  1518.                 If !status = '200'
  1519.                 {
  1520.                     MsgBox("Http request failure in paste! Error code: " . status)
  1521.                     Clipboard := old_clipboard
  1522.                     CheckKeyState()
  1523.                     Exit()
  1524.                 }
  1525.                 If !(InStr(response,"pastebin"))
  1526.                 {
  1527.                     MsgBox("Paste failure occurred! File not pasted to Pastebin.com`n" . response)
  1528.                     Clipboard := old_clipboard
  1529.                     CheckKeyState()
  1530.                     Exit()
  1531.                 }
  1532.                 Else
  1533.                 {
  1534.                     Clipboard := response ; paste copied to clipboard
  1535.                     MsgBox("Sucessfully pasted!" . response . "`nPaste link copied to clipboard")
  1536.                     CheckKeyState()
  1537.                     Exit()
  1538.                 }
  1539.             }
  1540.             Else
  1541.             {
  1542.                 Clipboard := old_clipboard
  1543.                 CheckKeyState()
  1544.                 Exit()
  1545.             }
  1546.         }
  1547.     }
  1548.     CancelUserInputAppend(this)
  1549.     {
  1550.         saved := this.Submit()  ; Save the contents of named controls into an object.
  1551.         Clipboard := old_clipboard
  1552.         CheckKeyState()
  1553.         Exit()
  1554.     }
  1555. Return
  1556.  
  1557. ; Backup pastes based on regular expression
  1558. ^!5::
  1559.     global api_dev_key
  1560.     global api_user_key
  1561.    
  1562.     ; Create backup folder
  1563.     time_stamp := A_Now
  1564.     paste_backup_dir := A_WorkingDir . '\paste_backup_' . time_stamp . '\'
  1565.     If !DirExist(paste_backup_dir)
  1566.     {
  1567.         DirCreate(paste_backup_dir)
  1568.     }
  1569.    
  1570.     ; Get regexp
  1571.    
  1572.     Gui := GuiCreate(, "Enter a search query (e.g., regex) for files to backup")
  1573.     Gui.Add("Text",, "Search query:")
  1574.     Gui.Add("Edit", "w400 vsearch")
  1575.     Gui.Add("Button", "default", "OK").OnEvent("Click", () => ProcessUserInputBackup(Gui))
  1576.     Gui.Add("Button", "x+5", "Cancel").OnEvent("Click", () => CancelUserInputBackup(Gui))
  1577.     Gui.OnEvent("Close", "ProcessUserInputBackup")
  1578.     Gui.OnEvent("Close", "CancelUserInputBackup")
  1579.     Gui.Show()
  1580.     Sleep(300)
  1581.     ProcessUserInputBackup(this)
  1582.     {
  1583.         global paste_backup_dir
  1584.         saved := this.Submit()  ; Save the contents of named controls into an object.
  1585.         regexp := saved.search
  1586.        
  1587.         ; Get list of all pastes
  1588.        
  1589.         api_results_limit := '1000'
  1590.         api_option := 'list'
  1591.         post_fields := 'api_option=' . api_option . '&api_user_key=' . api_user_key . '&api_dev_key=' . api_dev_key . '&api_results_limit=' . api_results_limit
  1592.         url := "https://pastebin.com/api/api_post.php"
  1593.         HttpObj := ComObjCreate("WinHttp.WinHttpRequest.5.1")
  1594.         HttpObj.Open("POST", url)
  1595.         HttpObj.SetRequestHeader("Content-Type","application/x-www-form-urlencoded")
  1596.         HttpObj.Send(post_fields)
  1597.        
  1598.         ; Check response
  1599.        
  1600.         stream := ComObjCreate("adodb.stream")
  1601.         stream.Type := 1
  1602.         stream.Mode := 3
  1603.         stream.Open()
  1604.         stream.Write(HttpObj.ResponseBody) ; get bytes from ResponseBody
  1605.         stream.Position := 0
  1606.         stream.Type := 2
  1607.         stream.Charset := 'UTF-8'
  1608.         response := stream.ReadText()
  1609.         stream.Close()
  1610.         status := HttpObj.Status
  1611.        
  1612.         If !status = '200'
  1613.         {
  1614.             MsgBox("Http request failure in file listing! Error code: " . status . "`nPlease make sure your configuration file is correct.")
  1615.             CheckKeyState()
  1616.             Exit()
  1617.         }
  1618.         If !(InStr(response,"paste"))
  1619.         {
  1620.             MsgBox("Could not get list of pastes to compare file names.`nPlease make sure your configuration file is correct.`n" . response)
  1621.             CheckKeyState()
  1622.             Exit()
  1623.         }
  1624.        
  1625.         ; Check to see if regexp matches any paste titles
  1626.        
  1627.         ; First grab titles and keys
  1628.        
  1629.         api_paste_key := '' ; We will extract this in order to use it when backing up
  1630.         start_pos := 1
  1631.         find_pos := ''
  1632.         matches := []
  1633.         response_regexp := 's)<paste_key>.*?</paste_title>'
  1634.         Loop
  1635.         {
  1636.             find_pos := RegExMatch(response, response_regexp, match, start_pos)
  1637.             If find_pos
  1638.             {
  1639.                 matches.Push(match[0])
  1640.                 start_pos := match.Pos(0) + match.Len(0)
  1641.             }
  1642.         } Until find_pos = 0
  1643.         exists := 0
  1644.         titles := []
  1645.         keys := []
  1646.         Loop matches.Length()
  1647.         {
  1648.             string := matches[A_Index]
  1649.             match_pos := RegExMatch(string, '<paste_title>(.*?)</paste_title>', title_match)
  1650.             title_match := title_match[1]
  1651.             If RegExMatch(title_match, regexp)
  1652.             {
  1653.                 match_pos := RegExMatch(string, '<paste_key>(.*?)</paste_key>', match)
  1654.                 keys.Push(match[1])
  1655.                 ;match_pos := RegExMatch(string, '<paste_title>(.*?)</paste_title>', match)
  1656.                 ;titles.Push(match[1])
  1657.                 titles.Push(title_match)
  1658.                 exists := 1
  1659.             }
  1660.         }
  1661.         If exists
  1662.         {
  1663.             ; Print out files that match and confirm backup
  1664.             message := "Do you want to backup all of these files?`nList of files also copied to your computer's clipboard.`n"
  1665.             Loop titles.Length()
  1666.             {
  1667.                 message .= titles[A_Index] . '`n'
  1668.             }
  1669.             Clipboard := message
  1670.             result := MsgBox(message,, "YesNo")
  1671.             If result = "Yes"
  1672.             {
  1673.                 ; Create local backups
  1674.                
  1675.                 backup_count := 0
  1676.                 backup_names := ""
  1677.                 errors := 0
  1678.                 Loop keys.Length()
  1679.                 {
  1680.                     api_option := 'show_paste'
  1681.                     post_fields := 'api_option=' . api_option . '&api_user_key=' . api_user_key . '&api_dev_key=' . api_dev_key . '&api_paste_key=' . keys[A_Index]
  1682.                     url := "https://pastebin.com/api/api_raw.php"
  1683.                     HttpObj := ComObjCreate("WinHttp.WinHttpRequest.5.1")
  1684.                     HttpObj.Open("POST", url)
  1685.                     HttpObj.SetRequestHeader("Content-Type","application/x-www-form-urlencoded")
  1686.                     HttpObj.Send(post_fields)
  1687.                    
  1688.                     ; Check response
  1689.                    
  1690.                     status := HttpObj.Status
  1691.                     If !status = '200'
  1692.                     {
  1693.                         result := MsgBox("Http request failure in " . titles[A_Index] . " backup! Error code: " . status . "`nDo you want to continue with the rest of the backups?",, "YesNo")
  1694.                         If result = "Yes"
  1695.                         {
  1696.                             errors++
  1697.                             Continue
  1698.                         }
  1699.                         Else
  1700.                         {
  1701.                             MsgBox(backup_count . " pastes backed up from Pastebin.com.`n" . ++errors . "occurred.`nBackups stored in local timestamped backups folder:`n" . backup_names)
  1702.                             CheckKeyState()
  1703.                             Exit()
  1704.                         }
  1705.                     }
  1706.                    
  1707.                     ; Decode bytes (WinHttp.WinHttpRequest.5.1 ResponseText wrongly decodes encoding)
  1708.                    
  1709.                     stream := ComObjCreate("adodb.stream")
  1710.                     stream.Type := 1
  1711.                     stream.Mode := 3
  1712.                     stream.Open()
  1713.                     stream.Write(HttpObj.ResponseBody) ; get bytes from ResponseBody
  1714.                     stream.Position := 0
  1715.                     stream.Type := 2
  1716.                     stream.Charset := 'UTF-8'
  1717.                     response := stream.ReadText()
  1718.                     stream.Close()
  1719.                    
  1720.                     ; Write paste to local backup directory
  1721.                    
  1722.                     backup_file := paste_backup_dir . titles[A_Index]
  1723.                     FileDelete(backup_file)
  1724.                     FileAppend(response, backup_file, "UTF-8")
  1725.                    
  1726.                     If !(FileExist(backup_file) And CheckAge(backup_file))
  1727.                     {
  1728.                         result := MsgBox("Local backup of " . titles[A_Index] . "failed! File not backed up from Pastebin.com.`nDo you want to continue with the rest of the backups?",, "YesNo")
  1729.                         If result = "Yes"
  1730.                         {
  1731.                             errors++
  1732.                             Continue
  1733.                         }
  1734.                         Else
  1735.                         {
  1736.                             MsgBox(backup_count . " pastes backed up from Pastebin.com.`n" . ++errors . "occurred.`nBackups stored in local timestamped backups folder:`n" . backup_names)
  1737.                             CheckKeyState()
  1738.                             Exit()
  1739.                         }
  1740.                     }
  1741.                     backup_count++
  1742.                     backup_names .= '`t' . titles[A_Index] . '`n'
  1743.                 }
  1744.                 If backup_count = keys.Length()
  1745.                 {
  1746.                     MsgBox(backup_count . " pastes backed up from Pastebin.com.`nBackups stored in local timestamped backups folder:`n" . backup_names)
  1747.                 }
  1748.                 Else
  1749.                 {
  1750.                     MsgBox(backup_count . " pastes backed up from Pastebin.com.`n" . errors . "occurred.`nBackups stored in local timestamped backups folder:`n" . backup_names)
  1751.                 }
  1752.             }
  1753.             Else
  1754.             {
  1755.                 DirDelete(paste_backup_dir)
  1756.                 MsgBox("Backup aborted by user. No pastes backed up.")
  1757.                 CheckKeyState()
  1758.                 Exit()
  1759.             }
  1760.         }
  1761.         Else
  1762.         {
  1763.             MsgBox("No pastes match that search query! Nothing backed up!")
  1764.             CheckKeyState()
  1765.             Exit()
  1766.         }
  1767.     }
  1768.     CancelUserInputBackup(this)
  1769.     {
  1770.         saved := this.Submit()  ; Save the contents of named controls into an object.
  1771.         CheckKeyState()
  1772.         Exit()
  1773.     }
  1774. Return
  1775.  
  1776. ; Delete pastes based on regular expression
  1777. ^!6::
  1778.     global api_dev_key
  1779.     global api_user_key
  1780.     global pastebin_backup_dir
  1781.    
  1782.     ; Get regexp
  1783.    
  1784.     Gui := GuiCreate(, "Enter a search query (e.g., regex) for files to delete")
  1785.     Gui.Add("Text",, "Search query:")
  1786.     Gui.Add("Edit", "w400 vsearch")
  1787.     Gui.Add("Button", "default", "OK").OnEvent("Click", () => ProcessUserInputDelete(Gui))
  1788.     Gui.Add("Button", "x+5", "Cancel").OnEvent("Click", () => CancelUserInputDelete(Gui))
  1789.     Gui.OnEvent("Close", "ProcessUserInputDelete")
  1790.     Gui.OnEvent("Close", "CancelUserInputDelete")
  1791.     Gui.Show()
  1792.     Sleep(300)
  1793.     ProcessUserInputDelete(this)
  1794.     {
  1795.         saved := this.Submit()  ; Save the contents of named controls into an object.
  1796.         regexp := saved.search
  1797.        
  1798.         ; Get list of all pastes
  1799.        
  1800.         api_results_limit := '1000'
  1801.         api_option := 'list'
  1802.         post_fields := 'api_option=' . api_option . '&api_user_key=' . api_user_key . '&api_dev_key=' . api_dev_key . '&api_results_limit=' . api_results_limit
  1803.         url := "https://pastebin.com/api/api_post.php"
  1804.         HttpObj := ComObjCreate("WinHttp.WinHttpRequest.5.1")
  1805.         HttpObj.Open("POST", url)
  1806.         HttpObj.SetRequestHeader("Content-Type","application/x-www-form-urlencoded")
  1807.         HttpObj.Send(post_fields)
  1808.        
  1809.         ; Check response
  1810.        
  1811.         stream := ComObjCreate("adodb.stream")
  1812.         stream.Type := 1
  1813.         stream.Mode := 3
  1814.         stream.Open()
  1815.         stream.Write(HttpObj.ResponseBody) ; get bytes from ResponseBody
  1816.         stream.Position := 0
  1817.         stream.Type := 2
  1818.         stream.Charset := 'UTF-8'
  1819.         response := stream.ReadText()
  1820.         stream.Close()
  1821.    
  1822.         status := HttpObj.Status
  1823.         If !status = '200'
  1824.         {
  1825.             MsgBox("Http request failure in file listing! Error code: " . status . "`nPlease make sure your configuration file is correct.")
  1826.             CheckKeyState()
  1827.             Exit()
  1828.         }
  1829.         If !(InStr(response,"paste"))
  1830.         {
  1831.             MsgBox("Could not get list of pastes to compare file names.`nPlease make sure your configuration file is correct.`n" . response)
  1832.             CheckKeyState()
  1833.             Exit()
  1834.         }
  1835.        
  1836.         ; Check to see if regexp matches any paste titles
  1837.        
  1838.         ; First grab titles and keys
  1839.        
  1840.         api_paste_key := '' ; We will extract this in order to use it when backing up and overwriting files
  1841.         start_pos := 1
  1842.         find_pos := ''
  1843.         matches := []
  1844.         response_regexp := 's)<paste_key>.*?</paste_title>'
  1845.         Loop
  1846.         {
  1847.             find_pos := RegExMatch(response, response_regexp, match, start_pos)
  1848.             If find_pos
  1849.             {
  1850.                 matches.Push(match[0])
  1851.                 start_pos := match.Pos(0) + match.Len(0)
  1852.             }
  1853.         } Until find_pos = 0
  1854.         exists := 0
  1855.         titles := []
  1856.         keys := []
  1857.         Loop matches.Length()
  1858.         {
  1859.             string := matches[A_Index]
  1860.             match_pos := RegExMatch(string, '<paste_title>(.*?)</paste_title>', title_match)
  1861.             title_match := title_match[1]
  1862.             If RegExMatch(title_match, regexp)
  1863.             {
  1864.                 match_pos := RegExMatch(string, '<paste_key>(.*?)</paste_key>', match)
  1865.                 keys.Push(match[1])
  1866.                 ;match_pos := RegExMatch(string, '<paste_title>(.*?)</paste_title>', match)
  1867.                 ;titles.Push(match[1])
  1868.                 titles.Push(title_match)
  1869.                 exists := 1
  1870.             }
  1871.         }
  1872.         If exists
  1873.         {
  1874.             ; Print out files that match and confirm delete
  1875.             message := "Do you want to delete all of these files? (Backups are still made locally.)`nList of files also copied to your computer's clipboard.`n"
  1876.             Loop titles.Length()
  1877.             {
  1878.                 message .= titles[A_Index] . '`n'
  1879.             }
  1880.             Clipboard := message
  1881.             result := MsgBox(message,, "YesNo")
  1882.             If result = "Yes"
  1883.             {
  1884.                 ; Create local backups
  1885.                 delete_count := 0
  1886.                 delete_errors := 0
  1887.                 delete_names := ''
  1888.                 Loop keys.Length()
  1889.                 {
  1890.                     api_option := 'show_paste'
  1891.                     post_fields := 'api_option=' . api_option . '&api_user_key=' . api_user_key . '&api_dev_key=' . api_dev_key . '&api_paste_key=' . keys[A_Index]
  1892.                     url := "https://pastebin.com/api/api_raw.php"
  1893.                     HttpObj := ComObjCreate("WinHttp.WinHttpRequest.5.1")
  1894.                     HttpObj.Open("POST", url)
  1895.                     HttpObj.SetRequestHeader("Content-Type","application/x-www-form-urlencoded")
  1896.                     HttpObj.Send(post_fields)
  1897.                    
  1898.                     ; Check response
  1899.                    
  1900.                     status := HttpObj.Status
  1901.                     If !status = '200'
  1902.                     {
  1903.                         result := MsgBox("Http request failure in " . titles[A_Index] . " backup before delete! Error code: " . status . "`nDo you want to continue deleting the rest of the files?",, "YesNo")
  1904.                         If result = "Yes"
  1905.                         {
  1906.                             delete_errors++
  1907.                             Continue
  1908.                         }
  1909.                         Else
  1910.                         {
  1911.                             MsgBox(delete_count . " pastes deleted from Pastebin.com.`n" . ++delete_errors . "occurred.`nThe following files were deleted:`n" . delete_names)
  1912.                             CheckKeyState()
  1913.                             Exit()
  1914.                         }
  1915.                     }
  1916.                    
  1917.                     ; Decode bytes (WinHttp.WinHttpRequest.5.1 ResponseText wrongly decodes encoding)
  1918.                    
  1919.                     stream := ComObjCreate("adodb.stream")
  1920.                     stream.Type := 1
  1921.                     stream.Mode := 3
  1922.                     stream.Open()
  1923.                     stream.Write(HttpObj.ResponseBody) ; get bytes from ResponseBody
  1924.                     stream.Position := 0
  1925.                     stream.Type := 2
  1926.                     stream.Charset := 'UTF-8'
  1927.                     response := stream.ReadText()
  1928.                     stream.Close()
  1929.                    
  1930.                     ; Write paste to local backup directory
  1931.                    
  1932.                     backup_file := pastebin_backup_dir . titles[A_Index]
  1933.                     t := A_NOW
  1934.                     ts := FormatTime(t, "_yyyyMMdd-HHmmss")
  1935.                     backup_file := RegExReplace(backup_file, '(.*?)(\.[^.]*$)', '$1' . ts . '$2')
  1936.                     FileDelete(backup_file)
  1937.                     FileAppend(response, backup_file, "UTF-8")
  1938.                    
  1939.                     If !(FileExist(backup_file) And CheckAge(backup_file))
  1940.                     {
  1941.                         result := MsgBox("Local backup of " . titles[A_Index] . "failed! File not deleted from Pastebin.com.`nDo you want to continue deleting the rest of the files?",, "YesNo")
  1942.                         If result = "Yes"
  1943.                         {
  1944.                             delete_errors++
  1945.                             Continue
  1946.                         }
  1947.                         Else
  1948.                         {
  1949.                             MsgBox(delete_count . " pastes deleted from Pastebin.com.`n" . ++delete_errors . "occurred.`nThe following files were deleted:`n" . delete_names)
  1950.                             CheckKeyState()
  1951.                             Exit()
  1952.                         }
  1953.                     }
  1954.                 }
  1955.                
  1956.                 ; Delete pastes from Pastebin.com
  1957.                
  1958.                 Loop keys.Length()
  1959.                 {
  1960.                     api_option := 'delete'
  1961.                     post_fields := 'api_option=' . api_option . '&api_user_key=' . api_user_key . '&api_dev_key=' . api_dev_key . '&api_paste_key=' . keys[A_Index]
  1962.                     url := "https://pastebin.com/api/api_post.php"
  1963.                     HttpObj := ComObjCreate("WinHttp.WinHttpRequest.5.1")
  1964.                     HttpObj.Open("POST", url)
  1965.                     HttpObj.SetRequestHeader("Content-Type","application/x-www-form-urlencoded")
  1966.                     HttpObj.Send(post_fields)
  1967.                    
  1968.                     ; Check response
  1969.                    
  1970.                     response := HttpObj.ResponseText
  1971.                     status := HttpObj.Status
  1972.                     If !status = '200'
  1973.                     {
  1974.                         result := MsgBox("Http request failure during delete! " . titles[A_Index] . " not deleted. Error code: " . status . "`nDo you want to continue deleting the rest of the files?", "YesNo")
  1975.                         If result = "Yes"
  1976.                         {
  1977.                             delete_errors++
  1978.                             Continue
  1979.                         }
  1980.                         Else
  1981.                         {
  1982.                             MsgBox(delete_count . " pastes deleted from Pastebin.com.`n" . ++delete_errors . "occurred.`nThe following files were deleted:`n" . delete_names)
  1983.                             CheckKeyState()
  1984.                             Exit()
  1985.                         }
  1986.                     }
  1987.                     If !(InStr(response,"removed"))
  1988.                     {
  1989.                         result := MsgBox("Delete failure occurred! " . titles[A_Index] . " not deleted.`nResponse: " . response . "`nDo you want to continue deleting the rest of the files?", "YesNo")
  1990.                         If result = "Yes"
  1991.                         {
  1992.                             delete_errors++
  1993.                             Continue
  1994.                         }
  1995.                         Else
  1996.                         {
  1997.                             MsgBox(delete_count . " pastes deleted from Pastebin.com.`n" . ++delete_errors . "occurred.`nThe following files were deleted:`n" . delete_names)
  1998.                             CheckKeyState()
  1999.                             Exit()
  2000.                         }
  2001.                     }
  2002.                     delete_count++
  2003.                     delete_names .= '`t' . titles[A_Index] . '`n'
  2004.                 }
  2005.                 If delete_count = keys.Length()
  2006.                 {
  2007.                     MsgBox(delete_count . " pastes deleted from Pastebin.com.:`n" . delete_names)
  2008.                 }
  2009.                 Else
  2010.                 {
  2011.                     MsgBox(delete_count . " pastes deleted from Pastebin.com.`n" . errors . "occurred.`nThe following files were deleted:`n" . delete_names)
  2012.                 }
  2013.             }
  2014.             Else
  2015.             {
  2016.                 DirDelete(paste_backup_dir)
  2017.                 MsgBox("Delete aborted by user. No pastes deleted.")
  2018.                 CheckKeyState()
  2019.                 Exit()
  2020.             }
  2021.         }
  2022.         Else
  2023.         {
  2024.             MsgBox("No pastes match that search query! Nothing deleted!")
  2025.             CheckKeyState()
  2026.             Exit()
  2027.         }
  2028.     }
  2029.     CancelUserInputDelete(this)
  2030.     {
  2031.         saved := this.Submit()  ; Save the contents of named controls into an object.
  2032.         CheckKeyState()
  2033.         Exit()
  2034.     }
  2035. Return
  2036.  
  2037. ; Show all pastes
  2038. ^!7::
  2039.     global api_dev_key
  2040.     global api_user_key
  2041.    
  2042.     ; Get list of all pastes
  2043.        
  2044.     api_results_limit := '1000'
  2045.     api_option := 'list'
  2046.     post_fields := 'api_option=' . api_option . '&api_user_key=' . api_user_key . '&api_dev_key=' . api_dev_key . '&api_results_limit=' . api_results_limit
  2047.     url := "https://pastebin.com/api/api_post.php"
  2048.     HttpObj := ComObjCreate("WinHttp.WinHttpRequest.5.1")
  2049.     HttpObj.Open("POST", url)
  2050.     HttpObj.SetRequestHeader("Content-Type","application/x-www-form-urlencoded")
  2051.     HttpObj.Send(post_fields)
  2052.    
  2053.     ; Check response
  2054.    
  2055.     stream := ComObjCreate("adodb.stream")
  2056.     stream.Type := 1
  2057.     stream.Mode := 3
  2058.     stream.Open()
  2059.     stream.Write(HttpObj.ResponseBody) ; get bytes from ResponseBody
  2060.     stream.Position := 0
  2061.     stream.Type := 2
  2062.     stream.Charset := 'UTF-8'
  2063.     response := stream.ReadText()
  2064.     stream.Close()
  2065.  
  2066.     status := HttpObj.Status
  2067.     If !status = '200'
  2068.     {
  2069.         MsgBox("Http request failure in file listing! Error code: " . status . "`nPlease make sure your configuration file is correct.")
  2070.         CheckKeyState()
  2071.         Exit()
  2072.     }
  2073.     If !(InStr(response,"paste"))
  2074.     {
  2075.         MsgBox("Could not get list of pastes to compare file names.`nPlease make sure your configuration file is correct.`n" . response)
  2076.         CheckKeyState()
  2077.         Exit()
  2078.    }
  2079.    
  2080.    ; Grab titles
  2081.    
  2082.     start_pos := 1
  2083.     find_pos := ''
  2084.     matches := []
  2085.     response_regexp := 's)<paste_key>.*?</paste_title>'
  2086.     Loop
  2087.     {
  2088.         find_pos := RegExMatch(response, response_regexp, match, start_pos)
  2089.         If find_pos
  2090.         {
  2091.             matches.Push(match[0])
  2092.             start_pos := match.Pos(0) + match.Len(0)
  2093.         }
  2094.     } Until find_pos = 0
  2095.     file_count := matches.Length()
  2096.     file_list := 'You have ' . matches.Length() . ' pastes.`n`n'
  2097.     Loop matches.Length()
  2098.     {
  2099.         string := matches[A_Index]
  2100.         match_pos := RegExMatch(string, '<paste_title>(.*?)</paste_title>', title_match)
  2101.         title_match := title_match[1]
  2102.         match_pos := RegExMatch(string, '<paste_key>(.*?)</paste_key>', key_match)
  2103.         key_match := "https://pastebin.com/" . key_match[1]
  2104.         file_list .= title_match . '`n' . key_match . '`n`n'
  2105.     }
  2106.     Clipboard := file_list
  2107.     MsgBox("You have " . file_count . " pastes.`nA list of your pastes has been copied to your clipboard.")
  2108. Return
  2109.  
  2110. ; List pastes based on regular expression
  2111. ^!8::
  2112.     global api_dev_key
  2113.     global api_user_key
  2114.    
  2115.     ; Get regex for listing pastes
  2116.    
  2117.     Gui := GuiCreate(, "Enter search query for listing pastes")
  2118.     Gui.Add("Text",, "Please enter search query (regular expression):")
  2119.     Gui.Add("Edit", "w400 vsearch")
  2120.     Gui.Add("Button", "default", "OK").OnEvent("Click", () => ProcessUserInputList(Gui))
  2121.     Gui.Add("Button", "x+5", "Cancel").OnEvent("Click", () => CancelUserInputList(Gui))
  2122.     Gui.OnEvent("Close", "ProcessUserInputList")
  2123.     Gui.OnEvent("Close", "CancelUserInputList")
  2124.     Gui.Show()
  2125.     Sleep(300)
  2126.     ProcessUserInputList(this)
  2127.     {
  2128.         saved := this.Submit()  ; Save the contents of named controls into an object.
  2129.         regexp_search := saved.search
  2130.        
  2131.         ; Check to see if the file exists by calling API for existing pastes
  2132.        
  2133.         api_results_limit := '1000'
  2134.         api_option := 'list'
  2135.         post_fields := 'api_option=' . api_option . '&api_user_key=' . api_user_key . '&api_dev_key=' . api_dev_key . '&api_results_limit=' . api_results_limit
  2136.         url := "https://pastebin.com/api/api_post.php"
  2137.         HttpObj := ComObjCreate("WinHttp.WinHttpRequest.5.1")
  2138.         HttpObj.Open("POST", url)
  2139.         HttpObj.SetRequestHeader("Content-Type","application/x-www-form-urlencoded")
  2140.         HttpObj.Send(post_fields)
  2141.        
  2142.         ; Check response
  2143.        
  2144.         stream := ComObjCreate("adodb.stream")
  2145.         stream.Type := 1
  2146.         stream.Mode := 3
  2147.         stream.Open()
  2148.         stream.Write(HttpObj.ResponseBody) ; get bytes from ResponseBody
  2149.         stream.Position := 0
  2150.         stream.Type := 2
  2151.         stream.Charset := 'UTF-8'
  2152.         response := stream.ReadText()
  2153.         stream.Close()
  2154.         status := HttpObj.Status
  2155.        
  2156.         If !status = '200'
  2157.         {
  2158.             MsgBox("Http request failure in file listing! Error code: " . status . "`nPlease make sure your configuration file is correct.")
  2159.             CheckKeyState()
  2160.             Exit()
  2161.         }
  2162.         If !(InStr(response,"paste"))
  2163.         {
  2164.             MsgBox("Could not get list of pastes to compare file names.`nPlease make sure your configuration file is correct.`n" . response)
  2165.             CheckKeyState()
  2166.             Exit()
  2167.         }
  2168.        
  2169.         ; Check to see if any filenames match the regular expression
  2170.        
  2171.         start_pos := 1
  2172.         find_pos := ''
  2173.         matches := []
  2174.         response_regexp := 's)<paste_key>.*?</paste_title>'
  2175.         Loop
  2176.         {
  2177.             find_pos := RegExMatch(response, response_regexp, match, start_pos)
  2178.             If find_pos
  2179.             {
  2180.                 matches.Push(match[0])
  2181.                 start_pos := match.Pos(0) + match.Len(0)
  2182.             }
  2183.         } Until find_pos = 0
  2184.         list_results := ''
  2185.         result_count := 0
  2186.         Loop matches.Length()
  2187.         {
  2188.             string := matches[A_Index]
  2189.             match_pos := RegExMatch(string, '<paste_title>(.*?)</paste_title>', title_match)
  2190.             title_match := title_match[1]
  2191.             If RegExMatch(title_match, regexp_search)
  2192.             {
  2193.                 match_pos := RegExMatch(string, '<paste_key>(.*?)</paste_key>', key_match)
  2194.                 key_match := "https://pastebin.com/" . key_match[1]
  2195.                 list_results .= title_match . '`n' . key_match . '`n`n'
  2196.                 result_count++
  2197.             }
  2198.         }
  2199.         list_results := 'You have ' . result_count . ' pastes.`n`n' . list_results
  2200.         If list_results
  2201.         {
  2202.             Clipboard := list_results
  2203.             MsgBox(result_count . ' search results copied to clipboard.')
  2204.             CheckKeyState()
  2205.             Exit()
  2206.         }
  2207.         Else
  2208.         {
  2209.             MsgBox('0 search results.')
  2210.             CheckKeyState()
  2211.             Exit()
  2212.         }
  2213.     }
  2214.     CancelUserInputList(this)
  2215.     {
  2216.         saved := this.Submit()  ; Save the contents of named controls into an object.
  2217.         CheckKeyState()
  2218.         Exit()
  2219.     }
  2220. Return
  2221.  
  2222. ; Get paste link
  2223. ^!9::
  2224.     global api_dev_key
  2225.     global api_user_key
  2226.    
  2227.     ; Get api_paste_name
  2228.    
  2229.     Gui := GuiCreate(, "Get link for Pastebin paste")
  2230.     Gui.Add("Text",, "Please enter the file name:")
  2231.     Gui.Add("Edit", "w400 vsearch")
  2232.     Gui.Add("Button", "default", "OK").OnEvent("Click", () => ProcessUserInputLink(Gui))
  2233.     Gui.Add("Button", "x+5", "Cancel").OnEvent("Click", () => CancelUserInputLink(Gui))
  2234.     Gui.OnEvent("Close", "ProcessUserInputLink")
  2235.     Gui.OnEvent("Close", "CancelUserInputLink")
  2236.     Gui.Show()
  2237.     Sleep(300)
  2238.     ProcessUserInputLink(this)
  2239.     {
  2240.         saved := this.Submit()  ; Save the contents of named controls into an object.
  2241.         api_paste_name := saved.search
  2242.        
  2243.         ; Check to see if the file already exists by calling API for existing pastes
  2244.        
  2245.         api_results_limit := '1000'
  2246.         api_option := 'list'
  2247.         post_fields := 'api_option=' . api_option . '&api_user_key=' . api_user_key . '&api_dev_key=' . api_dev_key . '&api_results_limit=' . api_results_limit
  2248.         url := "https://pastebin.com/api/api_post.php"
  2249.         HttpObj := ComObjCreate("WinHttp.WinHttpRequest.5.1")
  2250.         HttpObj.Open("POST", url)
  2251.         HttpObj.SetRequestHeader("Content-Type","application/x-www-form-urlencoded")
  2252.         HttpObj.Send(post_fields)
  2253.        
  2254.         ; Check response
  2255.        
  2256.         stream := ComObjCreate("adodb.stream")
  2257.         stream.Type := 1
  2258.         stream.Mode := 3
  2259.         stream.Open()
  2260.         stream.Write(HttpObj.ResponseBody) ; get bytes from ResponseBody
  2261.         stream.Position := 0
  2262.         stream.Type := 2
  2263.         stream.Charset := 'UTF-8'
  2264.         response := stream.ReadText()
  2265.         stream.Close()
  2266.         status := HttpObj.Status
  2267.        
  2268.         If !status = '200'
  2269.         {
  2270.             MsgBox("Http request failure in file listing! Error code: " . status . "`nPlease make sure your configuration file is correct.")
  2271.             Clipboard := old_clipboard
  2272.             CheckKeyState()
  2273.             Exit()
  2274.         }
  2275.         If !(InStr(response,"paste"))
  2276.         {
  2277.             MsgBox("Could not get list of pastes to compare file names.`nPlease make sure your configuration file is correct.`n" . response)
  2278.             Clipboard := old_clipboard
  2279.             CheckKeyState()
  2280.             Exit()
  2281.         }
  2282.        
  2283.         ; Check to see if the file name already exists
  2284.        
  2285.         api_paste_key := '' ; We will extract this in order to use it when backing up and overwriting files
  2286.         start_pos := 1
  2287.         find_pos := ''
  2288.         matches := []
  2289.         regexp := 's)<paste_key>.*?</paste_title>'
  2290.         Loop
  2291.         {
  2292.             find_pos := RegExMatch(response, regexp, match, start_pos)
  2293.             If find_pos
  2294.             {
  2295.                 matches.Push(match[0])
  2296.                 start_pos := match.Pos(0) + match.Len(0)
  2297.             }
  2298.         } Until find_pos = 0
  2299.         exists := 0
  2300.         Loop matches.Length()
  2301.         {
  2302.             string := matches[A_Index]
  2303.             api_paste_name_regex := RegExReplace(api_paste_name, "([\.\^\$\*\+\?\(\)\[\{\\\|])", '\$1')
  2304.             If RegExMatch(string, '<paste_title>' . api_paste_name_regex . '</paste_title>')
  2305.             {
  2306.                 match_pos := RegExMatch(string, '<paste_key>(.*?)</paste_key>', match)
  2307.                 api_paste_key := match[1]
  2308.                 exists++
  2309.             }
  2310.         }
  2311.         If exists = 1
  2312.         {
  2313.             Clipboard := "https://pastebin.com/" . api_paste_key
  2314.             MsgBox("The link has been copied to the clipboard.`n" . Clipboard)
  2315.             CheckKeyState()
  2316.             Exit()
  2317.         }
  2318.         Else If exists > 1
  2319.         {
  2320.             MsgBox("More than 1 file with the same name exists. Please check your Pastebin.com pastes.")
  2321.             CheckKeyState()
  2322.             Exit()
  2323.         }
  2324.         Else
  2325.         {
  2326.             MsgBox("That file does not exist")
  2327.             CheckKeyState()
  2328.             Exit()
  2329.         }
  2330.    }
  2331.     CancelUserInputLink(this)
  2332.     {
  2333.         saved := this.Submit()  ; Save the contents of named controls into an object.
  2334.         CheckKeyState()
  2335.         Exit()
  2336.     }
  2337. Return
  2338.  
  2339. ; Login to Pastebin.com (Default browser is Opera)
  2340. ^!0::
  2341.     global api_user_name
  2342.     global api_user_password
  2343.     win_title := "ahk_class Chrome_WidgetWin_1" ; Opera (found with Window Spy)
  2344.     tab_title := "Pastebin.com - Login Page"
  2345.     run_command := "https://pastebin.com/login"
  2346.     OpenWindowPastebin(win_title, tab_title, run_command, api_user_name, api_user_password)
  2347.     CheckKeyState()
  2348. Return
  2349.  
  2350. ; Help message
  2351. ^!h::
  2352.     help_message := "1. Create new paste = ^!1 (Ctrl+Alt+1)`n2. Create new paste from files/folders = ^!2 (Ctrl+Alt+2)`n3. Download existing paste = ^!3 (Ctrl+Alt+3)`n4. Append to existing paste = ^!4 (Ctrl+Alt+4)`n5. Backup pastes = ^!5 (Ctrl+Alt+5)`n6. Delete pastes = ^!6 (Ctrl+Alt+6)`n7. List all pastes = ^!7 (Ctrl+Alt+7)`n8. List pastes = ^!8 (Ctrl+Alt+8)`n9. Get paste link = ^!9 (Ctrl+Alt+9)`n10. Log into pastebin = ^!0 (Ctrl+Alt+0)`n11. Help message = ^!h (Ctrl+Alt+h)"
  2353.     MsgBox(help_message)
  2354.     CheckKeyState()
  2355. Return
Add Comment
Please, Sign In to add comment