Advertisement
Ham62

subsonic?.java

Jul 4th, 2019
502
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 8.46 KB | None | 0 0
  1. import java.io.*;
  2. import java.nio.charset.StandardCharsets;
  3. import java.net.*;
  4. import java.security.MessageDigest;
  5. import javax.xml.bind.DatatypeConverter;
  6.  
  7. public class SubsonicConnectTest1 {
  8.  
  9.   static final String CLIENT_NAME = "Hamsonic Streaming App";
  10.   static String sServerURL = "http://localhost:4040/";
  11.   static String sDefaultParams;
  12.  
  13.   static String sUsername = "Ham62";
  14.   static String sPassword = "lolno";
  15.  
  16.   public static void main(String[] args) throws Exception{
  17.     sDefaultParams = "?f=json&v=1.13.0&c="+URLEncoder.encode(CLIENT_NAME, StandardCharsets.UTF_8.toString());
  18.            
  19.     System.out.println("Ping successful? "+pingServer());
  20.    
  21.     getSong("4659");
  22.     //System.out.println(sendRequest("getRandomSongs", "&size=2"));
  23.     //downloadSong("4659");
  24.   }
  25.  
  26.   static void downloadSong(String sID, SongInfo song) throws Exception {
  27.     InputStream stream = sendRequest("stream", sID);
  28.     if (stream == null) return;
  29.    
  30.     BufferedInputStream in = new BufferedInputStream(stream);
  31.     FileOutputStream outFile = new FileOutputStream("test.mp3");
  32.     byte dataBuffer[] = new byte[524288];
  33.     int bytesRead;
  34.     while ((bytesRead = in.read(dataBuffer, 0, dataBuffer.length)) != -1) {
  35.       outFile.write(dataBuffer, 0, bytesRead);
  36.     }
  37.     outFile.close();
  38.   }
  39.  
  40.   static SongInfo getSong(String sID) throws Exception {
  41.     InputStream stream = sendRequest("getSong", "&id="+sID);
  42.     if (stream == null) return null;
  43.  
  44.     BufferedReader in = new BufferedReader(new InputStreamReader(stream));
  45.         String readLine;
  46.     StringBuffer response = new StringBuffer();
  47.     while ((readLine = in.readLine()) != null)
  48.       response.append(readLine);
  49.     in.close();
  50.    
  51.     // Parse the JSON
  52.     int i = 0;
  53.     String[] input = response.toString().split("\"");
  54.     SongInfo songInfo = new SongInfo();
  55.     while (i < input.length) {
  56.       if (input[i].equals("status")) {
  57.         if (!input[i+2].equals("ok")) {
  58.           for (int e = i+3; e < input.length; e++) {
  59.             if (input[e].equals("message")) {
  60.               System.out.println("Error: "+input[e+2]);
  61.               return null;
  62.             }
  63.           }
  64.         }
  65.          
  66.       } else if (input[i].equals("id")) {
  67.         songInfo.id = input[i+2];
  68.         i += 3; continue;
  69.        
  70.       } else if (input[i].equals("parent")) {
  71.         songInfo.parent = input[i+2];
  72.         i += 3; continue;
  73.      
  74.       } else if (input[i].equals("title")) {
  75.         songInfo.title = input[i+2];
  76.         i += 3; continue;
  77.  
  78.       } else if (input[i].equals("album")) {
  79.         songInfo.album = input[i+2];
  80.         i += 3; continue;
  81.  
  82.       } else if (input[i].equals("artist")) {
  83.         songInfo.artist = input[i+2];
  84.         i += 3; continue;
  85.  
  86.       } else if (input[i].equals("track")) {
  87.         songInfo.track = extractInteger(input[i+1]);
  88.         i += 2; continue;
  89.  
  90.       } else if (input[i].equals("year")) {
  91.         songInfo.year = extractInteger(input[i+1]);
  92.         i += 2; continue;
  93.        
  94.       } else if (input[i].equals("genre")) {
  95.         songInfo.genre = input[i+2];
  96.         i += 3; continue;
  97.  
  98.       } else if (input[i].equals("coverArt")) {
  99.         songInfo.coverArt = input[i+2];
  100.         i += 3; continue;
  101.        
  102.       } else if (input[i].equals("transcodedSuffix")) {
  103.         songInfo.transcodedSuffix = input[i+2];
  104.         i += 3; continue;
  105.        
  106.       } else if (input[i].equals("duration")) {
  107.         songInfo.duration = extractInteger(input[i+1]);
  108.         i += 2; continue;
  109.        
  110.       } else if (input[i].equals("path")) {
  111.         songInfo.path = input[i+2];
  112.         i += 3; continue;
  113.  
  114.       } else if (input[i].equals("playCount")) {
  115.         songInfo.playCount = extractInteger(input[i+1]);
  116.         i += 2; continue;
  117.        
  118.       }
  119.       i++;
  120.     }
  121.  
  122.     return songInfo;
  123.   }
  124.  
  125.   // Attempt to ping the server and check if the login info is correct
  126.   static boolean pingServer() throws Exception {
  127.     InputStream stream = sendRequest("ping", "");
  128.     if (stream == null) return false;
  129.      
  130.     // Download the response from the server
  131.     BufferedReader in = new BufferedReader(new InputStreamReader(stream));
  132.     String readLine;
  133.     StringBuffer response = new StringBuffer();
  134.     while ((readLine = in.readLine()) != null)
  135.       response.append(readLine);
  136.     in.close();
  137.    
  138.     // Parse the JSON
  139.     int i = 0;
  140.     String[] input = response.toString().split("\"");
  141.     String sStatus = "", sVersion = "", sErrorMsg = "";
  142.     while (i < input.length) {
  143.       if (input[i].equals("status")) {
  144.         sStatus = input[i+2];
  145.         i += 3; continue;
  146.        
  147.       } else if (input[i].equals("version")) {
  148.         sVersion = input[i+2];
  149.         i += 3; continue;
  150.        
  151.       } else if (input[i].equals("message")) {
  152.         sErrorMsg = input[i+2];
  153.         i += 3; continue;
  154.       }
  155.      
  156.       i++;
  157.     }
  158.        
  159.     //System.out.println("Status: "+sStatus);
  160.     //System.out.println("Server protocol version: "+sVersion);
  161.    
  162.     if (sStatus.equals("ok")) return true;
  163.     System.out.println("Error: "+sErrorMsg);
  164.     return false;
  165.   }
  166.    
  167.   // Send a generic request to the server returning an input stream with the response
  168.   static InputStream sendRequest(String sMethod, String sExtraParams) throws Exception {
  169.     // Generate login info for request string
  170.     String sSalt = generateSalt(8);
  171.     String sToken = generateMD5Hash(sPassword+sSalt);
  172.     String sLoginInfo = String.format("&u=%s&t=%s&s=%s", sUsername, sToken, sSalt);
  173.  
  174.     // Generate the request URL for the server
  175.     String sRequest = sServerURL+"rest/"+sMethod+sDefaultParams+sLoginInfo+sExtraParams;
  176.    
  177.     HttpURLConnection connection;
  178.     int iResponse;
  179.    
  180.     // Attempt to resolve the URL address and connect to the server
  181.     try {
  182.       URL requestURL = new URL(sRequest);
  183.       connection = (HttpURLConnection)requestURL.openConnection();
  184.       connection.setRequestMethod("GET");
  185.       iResponse = connection.getResponseCode();
  186.     } catch (Exception e) {
  187.       if (e instanceof MalformedURLException) {
  188.         System.out.println(e.getMessage());
  189.       } else if (e instanceof UnknownHostException) {
  190.         System.out.println("Unknown host: "+e.getMessage());
  191.       } else if (e instanceof ConnectException) {
  192.         System.out.println(e.getMessage());
  193.       } else {
  194.         System.out.println(e);
  195.       }
  196.       return null;
  197.     }
  198.    
  199.     // Non-200 response means we did something wrong
  200.     if (iResponse != 200) {
  201.       System.out.println("Server returned error code: "+iResponse);
  202.       return null;
  203.     }
  204.    
  205.     // Return the stream from the server
  206.     return connection.getInputStream();
  207.   }
  208.  
  209.   // Generate an MD5 hash from a string
  210.   static String generateMD5Hash(String sPassword) throws Exception {
  211.     MessageDigest md = MessageDigest.getInstance("MD5");
  212.     md.update(sPassword.getBytes());
  213.     byte[] digest = md.digest();
  214.    
  215.     return DatatypeConverter.printHexBinary(digest).toLowerCase();
  216.   }
  217.  
  218.   // Generate a random salt of specified length
  219.   static String generateSalt(int iLength) {
  220.     byte[] salt = new byte[iLength];
  221.     for (int i = 0; i < salt.length; i++) {
  222.       // Random chance of number or upper/lowecase letter
  223.       switch (random(3)) {
  224.         case 0:
  225.           salt[i] = (byte)('0' + random(10));
  226.           break;
  227.         case 1:
  228.           salt[i] = (byte)('A' + random(26));
  229.           break;
  230.         case 2:
  231.           salt[i] = (byte)('a' + random(26));
  232.           break;
  233.       }
  234.     }  
  235.     return new String(salt);
  236.   }
  237.  
  238.   // Return a random number in range (0-max)
  239.   static int random(int max) {
  240.     return (int)(Math.random() * max);
  241.   }
  242.  
  243.   // Extract an integer from a token which is surrounded by space/non-numbers
  244.   static int extractInteger(String sToken) {
  245.     // Start at the end of the string and work backward
  246.     int iPos = sToken.length()-1;
  247.    
  248.     // Find end of integer
  249.     while (!charIsNumber(sToken.charAt(iPos--)));    
  250.     int iTopOffset = iPos+1;
  251.  
  252.     // Find start of integer
  253.     while (iPos > 1 && (charIsNumber(sToken.charAt(iPos--))));
  254.     int iBottomOffset = iPos-1;
  255.     if (iBottomOffset < 0) iBottomOffset = 0;
  256.    
  257.     System.out.println("");
  258.     System.out.println(sToken.substring(iBottomOffset, iTopOffset));
  259.    
  260.     // Return integer
  261.     return Integer.parseInt(sToken.substring(iBottomOffset, iTopOffset));
  262.   }
  263.  
  264.   static boolean charIsNumber(char c) {
  265.     return (c < '0' || c > '0');
  266.   }
  267. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement