Advertisement
Guest User

Untitled

a guest
Sep 14th, 2017
129
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. SuperStrict
  2.  
  3. Framework BaH.libcurl
  4. Import BaH.RegEx
  5. Import BRL.StandardIO
  6. Import BRL.FileSystem
  7. Import BRL.Map
  8.  
  9. Import "TFile.bmx"
  10. Import "md5.c"
  11.  
  12. Extern
  13.     Function MD5_Init(State:Byte Ptr) = "md5_init"
  14.     Function MD5_Append(State:Byte Ptr, Buffer:Byte Ptr, Size:Int) = "md5_append"
  15.     Function MD5_Finish(State:Byte Ptr, Digest:Byte Ptr) = "md5_finish"
  16. EndExtern
  17.  
  18. If Not FileType("Images") Then CreateDir("Images")
  19.  
  20. InitializeImageEntries("Images")
  21. DownloadThreadList("oat", "Images")
  22.  
  23. Function InitializeImageEntries(Folder:String)
  24.     Local Dir:TFile = TFile.Open(Folder)
  25.     Dir.StripParent()
  26.     Dir.Filter(FILETYPE_FILE)
  27.    
  28.     For Local File:TFile = EachIn Dir
  29.         TImageEntry.Create(File.Path())
  30.     Next
  31. End Function
  32.  
  33. Function DownloadThreadList(Board:String, TargetPath:String)
  34.     Local Request:TCurlEasy = TCurlEasy.Create()
  35.    
  36.     Request.SetOptInt     (CURLOPT_FOLLOWLOCATION, 1)
  37.     Request.SetOptString  (CURLOPT_URL, "ponychan.net/chan/" + Board + "/catalog.html")
  38.     Request.SetWriteString()
  39.    
  40.     Local Result:Int = Request.Perform()
  41.     If Result Then Print "LibCurl error: " + CurlError(Result); Return
  42.    
  43.     Local Regex:TRegEx = TRegEx.Create("\/chan\/" + Board + "\/res\/([0-9]+)\.html")
  44.    
  45.     Local Match:TRegExMatch = Regex.Find(Request.ToString())
  46.     While Match
  47.         Print "Downloading thread with id " + Match.SubExp(1)
  48.        
  49.         DownloadThread("ponychan.net" + Match.SubExp(0), Board, TargetPath)
  50.        
  51.         Match = Regex.Find()
  52.     Wend
  53. End Function
  54.  
  55. Function DownloadThread(URL:String, Board:String, TargetPath:String)
  56.     TargetPath = StripSlash(TargetPath) + "\"
  57.    
  58.     Local Request:TCurlEasy = TCurlEasy.Create()
  59.    
  60.     Request.SetOptInt     (CURLOPT_FOLLOWLOCATION, 1)
  61.     Request.SetOptString  (CURLOPT_URL, URL)
  62.     Request.SetWriteString()
  63.    
  64.     Local Result:Int = Request.Perform()
  65.     If Result Then Print "LibCurl error: " + CurlError(Result); Return
  66.    
  67.     Local Regex:TRegEx = TRegEx.Create("expandimg\(\'[0-9]+\'\, \'http\:\/\/www\.(ponychan\.net\/chan\/" + Board + "\/src\/([0-9]+\.(jpg|png|gif)))") 'I AM THE REGEX GOD
  68.    
  69.     Local Match:TRegExMatch = Regex.Find(Request.ToString())
  70.     While Match
  71.         Print "Downloading " + Match.SubExp(1)
  72.        
  73.         Local Path:String = TargetPath + Match.SubExp(2)
  74.        
  75.         If Not FileType(Path) Then
  76.             Local Stream:TStream = WriteFile(Path)
  77.            
  78.             Request.SetOptString(CURLOPT_URL, Match.SubExp(1))
  79.             Request.SetWriteCallback(CustomWrite, Stream)
  80.            
  81.             Request.Perform()
  82.             Stream.Close()
  83.            
  84.             TImageEntry.Create(Path)
  85.         EndIf
  86.        
  87.         Match = Regex.Find()
  88.     Wend
  89.    
  90.     Request.Cleanup()
  91. End Function
  92.  
  93. Function CustomWrite:Int(Buffer:Byte Ptr, Size:Int, Data:Object)
  94.     Local FileStream:TStream = TStream(Data)
  95.    
  96.     Return FileStream.WriteBytes(Buffer, Size)
  97. End Function
  98.  
  99. Type TImageEntry
  100.     Global HashMap:TMap = New TMap
  101.     Global SizeMap:TMap = New TMap
  102.    
  103.     Global HashBuffer:Byte[10*1024]
  104.     Global HashStateBuffer:Byte[88]
  105.    
  106.     Field Path:String
  107.    
  108.     Field Size:Int
  109.    
  110.     Field HasHash:Int
  111.     Field MD5Hash:Int[4]
  112.    
  113.     Function Create:TImageEntry(Path:String)
  114.         If Not FileType(Path) Then Return Null
  115.        
  116.         Local Entry:TImageEntry = New TImageEntry
  117.         Entry.Path = Path
  118.         Entry.Size = FileSize(Path)
  119.        
  120.         If Entry.IsDuplicate() Then
  121.             Print "Duplicate detected at " + Path + ". Deleting..."
  122.            
  123.             DeleteFile(Path)
  124.            
  125.             Return Null
  126.         EndIf
  127.        
  128.         SizeMap.Insert(TBoxedInteger.Create(Entry.Size), Entry)
  129.        
  130.         Return Entry
  131.     End Function
  132.    
  133.     Method IsDuplicate:Int()
  134.         Local Entry:TImageEntry = TImageEntry(SizeMap.ValueForKey(TBoxedInteger.Create(Size)))
  135.        
  136.         If Entry Then
  137.             If Not Entry.HasHash Then Entry.GenerateHashAndInsert()
  138.             If Not       HasHash Then       GenerateHash()
  139.            
  140.             If HashMap.ValueForKey(Self) Then Return True
  141.            
  142.             HashMap.Insert(Self, Self)
  143.         EndIf
  144.        
  145.         Return False
  146.     End Method
  147.    
  148.     Method GenerateHashAndInsert()
  149.         GenerateHash()
  150.        
  151.         If HashMap.ValueForKey(Self) Then RuntimeError("TImageEntry::GenerateHashAndInsert: This should never happen")
  152.        
  153.         HashMap.Insert(Self, Self)
  154.     End Method
  155.    
  156.     Method GenerateHash()
  157.         Local TempSize:Int   = Size
  158.         Local Stream:TStream = ReadFile(Path)
  159.        
  160.         MD5_Init(Varptr HashStateBuffer[0])
  161.         While TempSize > 0
  162.             Stream.ReadBytes(Varptr HashBuffer[0], Min(HashBuffer.Length, TempSize))
  163.            
  164.             MD5_Append(Varptr HashStateBuffer[0], Varptr HashBuffer[0], Min(HashBuffer.Length, TempSize))
  165.            
  166.             TempSize :- HashBuffer.Length
  167.         Wend
  168.         MD5_Finish(Varptr HashStateBuffer[0], Varptr MD5Hash[0])
  169.        
  170.         HasHash = True
  171.     End Method
  172.    
  173.     Method Compare:Int(B:Object)
  174.         Local Other:TImageEntry = TImageEntry(B)
  175.        
  176.         If MD5Hash[0] - Other.MD5Hash[0] Then Return MD5Hash[0] - Other.MD5Hash[0]
  177.         If MD5Hash[1] - Other.MD5Hash[1] Then Return MD5Hash[1] - Other.MD5Hash[1]
  178.         If MD5Hash[2] - Other.MD5Hash[2] Then Return MD5Hash[2] - Other.MD5Hash[2]
  179.         If MD5Hash[3] - Other.MD5Hash[3] Then Return MD5Hash[3] - Other.MD5Hash[3]
  180.        
  181.         Return 0
  182.     End Method
  183. End Type
  184.  
  185. Type TBoxedInteger
  186.     Field Value:Int
  187.    
  188.     Method Compare:Int(B:Object)
  189.         Return Value - TBoxedInteger(B).Value
  190.     End Method
  191.    
  192.     Function Create:TBoxedInteger(Value:Int)
  193.         Local Integer:TBoxedInteger = New TBoxedInteger
  194.        
  195.         Integer.Value = Value
  196.        
  197.         Return Integer
  198.     End Function
  199. End Type
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement