SHARE
TWEET

SubsonicCacheFix.bas

Ham62 Dec 23rd, 2019 73 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
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
Top