Advertisement
Ham62

SubsonicCacheFix.bas

Dec 23rd, 2019
1,230
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. #include "crt.bi"
  2. #include "wshelper.bas"
  3. #include "inc\OpenSSL.bi"
  4. Declare Sub loadConfig()
  5. Declare function URLEncode(sStr as String) as String
  6. Declare Function getOldImageID(sBuff as String) as String
  7. const IDENTIFIER = "<lfm status=""ok""><artist><name>"
  8.  
  9. 'Image IDs are always 32 characters long
  10. dim shared as zString*33 szBadID = "2a96cbd8b46e442fc41c2b86b821562f"
  11.  
  12. dim as string sHost = "www.last.fm"
  13. dim as integer iPort = 443
  14.  
  15. loadConfig()
  16. dim as integer iIDLen = len(szBadID)
  17.  
  18. 'init wshelper
  19. hStart()
  20.  
  21. 'Init SSL
  22. SSL_load_error_strings()
  23. ERR_load_SSL_strings()
  24. OpenSSL_add_ssl_algorithms()
  25. var SSL_MethTLS = TLSv1_2_client_method()
  26. var SSL_Context = SSL_CTX_new(SSL_MethTLS)
  27.  
  28. ' Open connection to last.fm
  29. var hCliSock = hOpen()
  30. if hConnect(hCliSock, hResolve(sHost), iPort) = 0 then
  31.   printf(!"Failed to connect to %s:%i\n", sHost, iPort)
  32.   sleep:system
  33. end if
  34.  
  35. 'create a new SSL object and set the Socket / Name
  36. var pSSL = SSL_new(SSL_Context)
  37. SSL_set_fd( pSSL , hCliSock)
  38. SSL_set_tlsext_host_name( pSSL , strptr(sHost) )
  39. if SSL_connect( pSSL ) < 0 then
  40.   puts("Failed to secure connection")
  41.   sleep:system
  42. end if
  43.  
  44. dim as string sBuff ' For reading the file in
  45. dim as string sFile = dir("*.xml")
  46. while (sFile <> "")    
  47.     printf("Opening %s...", sFile)
  48.    
  49.     ' Open cache file
  50.     open sFile for input as #1
  51.     sBuff = space(lof(1))
  52.     get #1,, sBuff
  53.     close #1
  54.    
  55.     ' First verify this is the cache file for an artist bio
  56.     dim as integer iNameStart = instr(sBuff, IDENTIFIER)
  57.     if iNameStart > 0 then
  58.         ' only update cache if image ID is placeholder image
  59.         dim as string sOldImageID = getOldImageID(sBuff)
  60.         if sOldImageID <> szBadID then
  61.             print "Cache file already fixed"
  62.             sFile = dir()
  63.             continue while
  64.         end if
  65.        
  66.         ' Get the artist name so we can request the actual artwork
  67.         iNameStart += len(IDENTIFIER)
  68.         dim as integer iNameEnd = instr(iNameStart, sBuff, "<")
  69.         Dim as string sName = mid(sBuff, iNameStart, iNameEnd-iNameStart)
  70.        
  71.         ' Make HTTPS request
  72.         print URLEncode(sName)'sName
  73.         dim as string sURL = "/music/"+URLEncode(sName)
  74.         dim as zstring*4096 szBuffer
  75.         var iSz = sprintf( szBuffer, _
  76.             "GET %s HTTP/1.1" !"\r\n" _
  77.             "Host: %s:%i" !"\r\n" _
  78.             "Connection: close" !"\r\n\r\n", _
  79.             sUrl , sHost , iPort )
  80.            
  81.         if SSL_write(pSSL, strptr(szBuffer), iSz) <= 0 then
  82.             puts("failed to send request")
  83.         end if
  84.  
  85.         ' Download the HTML responce from the server
  86.         dim as string sResponce
  87.         do
  88.             var iLen = SSL_Read(pSSL, strptr(szBuffer), 4095)
  89.             if iLen <= 0 then exit do
  90.             szBuffer[iLen] = 0
  91.        
  92.             sResponce += szBuffer
  93.         loop
  94.         print sResponce
  95.         ' Locate image URL in the HTML document
  96.         const IMAGE_FOLDER = "+images/"
  97.         dim as integer iImgUrlIndex = instr(sResponce, IMAGE_FOLDER)
  98.         if iImgUrlIndex < 0 then
  99.             print "Failed to find image ID"
  100.             sleep: system
  101.         end if
  102.        
  103.         ' Extract the image ID from the HTML
  104.         dim as integer iStartTrim = iImgUrlIndex+len(IMAGE_FOLDER)
  105.         dim as integer iEndTrim = instr(iStartTrim, sResponce, """")
  106.         dim as string sID = mid(sResponce, iStartTrim, iEndTrim-iStartTrim)
  107.         print sID
  108.        
  109.         ' Replace all instances of placeholder artist image with new
  110.         dim as integer iPos = instr(1, sBuff, szBadID)
  111.         while iPos > 0
  112.             ' Copy new ID over the placeholder ID in the file buff
  113.             memcpy(@sBuff[iPos-1], strptr(sID), iIDLen)
  114.            
  115.             ' Find next instance of placeholder ID in file
  116.             iPos = instr(iPos, sBuff, szBadID)
  117.         wend
  118.        
  119.         ' Write updated cache file
  120.         open sFile for output as #1
  121.         put #1,, sBuff
  122.         close #1
  123.     else
  124.         print "Not an artist bio file"
  125.     end if
  126.    
  127.     sFile = dir()
  128. wend
  129.  
  130. ' Free the socket
  131. SSL_free( pSSL )
  132. hClose( hCliSock )
  133.  
  134. ' Free the SSL context
  135. SSL_CTX_free( SSL_Context )
  136. sleep
  137.  
  138. function getOldImageID(sBuff as String) as String
  139.     dim as integer iPos = instr(sBuff, ".png")
  140.     iPos -= 32
  141.     return mid(sBuff, iPos, 32)
  142. end function
  143.  
  144. ' Search backwards for image name starting at extension
  145. function getOldImageIDOld(sBuff as String) as String
  146.     dim as integer iEnd = instr(sBuff, ".png")
  147.     dim as integer iStart = iEnd
  148.     while sBuff[iStart-2] <> asc("/")
  149.         iStart -= 1
  150.     wend
  151.     return mid(sBuff, iStart, iEnd-iStart)
  152. end function
  153.  
  154. function URLEncode(sStr as String) as String
  155.     dim as string sOut
  156.     for i as integer = 0 to len(sStr)-1
  157.         ' Check if is an alphanumeric character
  158.         if (sStr[i] >= asc("0") AndAlso sStr[i] <= asc("9")) OrElse _
  159.            (sStr[i] >= asc("A") AndAlso sStr[i] <= asc("Z")) OrElse _
  160.            (sStr[i] >= asc("a") AndAlso sStr[i] <= asc("z")) then
  161.            sOut += chr(sStr[i])
  162.         else
  163.             sOut += "%"+hex(sStr[i], 2)
  164.         end if
  165.     next i
  166.     return sOut
  167. end function
  168.  
  169. sub loadConfig()
  170.     const PATH_CONST = "path="
  171.     const ID_CONST = "placeholderid="
  172.    
  173.     Dim as string sDir = "C:\subsonic\lastfmcache\"
  174.    
  175.    if open ("config.ini" for input as #1) then
  176.        print "Failed to load config file..."
  177.        printf(!"Defaulting to %s\r\n", sDir)
  178.    else
  179.        dim as string sLine
  180.        do
  181.            line input #1, sLine
  182.            if lcase(left(sLine, len(PATH_CONST))) = PATH_CONST then
  183.                sDir = mid(sLine, len(PATH_CONST)+1)
  184.            elseif lcase(left(sLine, len(ID_CONST))) = ID_CONST then
  185.                szBadID = mid(sLine, len(ID_CONST)+1)
  186.            end if
  187.        loop until eof(1)
  188.    end if
  189.    
  190.    if chdir(sDir) then
  191.        print "Failed to find local directory"
  192.        print sDir
  193.        sleep:system
  194.    end if
  195. end sub
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement