soundcloud lolllllll
This commit is contained in:
		
							
								
								
									
										23
									
								
								.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										23
									
								
								.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,23 @@
 | 
				
			|||||||
 | 
					lib/test.html
 | 
				
			||||||
 | 
					lib/postdata.json
 | 
				
			||||||
 | 
					lib/nextpage.json
 | 
				
			||||||
 | 
					scraper/brave.html
 | 
				
			||||||
 | 
					scraper/yandex.json
 | 
				
			||||||
 | 
					scraper/marginalia.json
 | 
				
			||||||
 | 
					banner_og/
 | 
				
			||||||
 | 
					scraper/mojeek.html
 | 
				
			||||||
 | 
					scraper/google.html
 | 
				
			||||||
 | 
					scraper/google-img.html
 | 
				
			||||||
 | 
					scraper/google-video.html
 | 
				
			||||||
 | 
					scraper/google-news.html
 | 
				
			||||||
 | 
					scraper/google-img-nextpage.html
 | 
				
			||||||
 | 
					scraper/brave-image.html
 | 
				
			||||||
 | 
					scraper/brave-video.html
 | 
				
			||||||
 | 
					scraper/facebook.html
 | 
				
			||||||
 | 
					scraper/facebook-nextpage.json
 | 
				
			||||||
 | 
					scraper/yandex-video.json
 | 
				
			||||||
 | 
					scraper/yandex.html
 | 
				
			||||||
 | 
					scraper/soundcloud.json
 | 
				
			||||||
 | 
					scraper/mp3-pm.html
 | 
				
			||||||
 | 
					banner/*
 | 
				
			||||||
 | 
					!banner/*default*
 | 
				
			||||||
							
								
								
									
										29
									
								
								api.txt
									
									
									
									
									
								
							
							
						
						
									
										29
									
								
								api.txt
									
									
									
									
									
								
							@@ -242,6 +242,21 @@
 | 
				
			|||||||
    the endpoint above.
 | 
					    the endpoint above.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					+ /api/v1/music
 | 
				
			||||||
 | 
					    Each entry under "song" contains a array index called "stream" that
 | 
				
			||||||
 | 
					    looks like this ::
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					        endpoint: audio_sc
 | 
				
			||||||
 | 
					        url: https://api-v2.soundcloud <...>
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    When the endpoint is "audio_sc", you MUST use 4get's audio_sc
 | 
				
			||||||
 | 
					    endpoint, for example, if you want an audio stream back. Otherwise,
 | 
				
			||||||
 | 
					    you are free to handle the json+m3u8 crap yourself. If the endpoint
 | 
				
			||||||
 | 
					    is equal to "audio", that URL SHOULD return a valid HTTP audio
 | 
				
			||||||
 | 
					    stream, and using the "audio" endpoint becomes optional again.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
+ /favicon
 | 
					+ /favicon
 | 
				
			||||||
    Get the favicon for a website. The only parameter is "s", and must
 | 
					    Get the favicon for a website. The only parameter is "s", and must
 | 
				
			||||||
    include the protocol.
 | 
					    include the protocol.
 | 
				
			||||||
@@ -284,6 +299,20 @@
 | 
				
			|||||||
    The parameter is "s" for the audio link.
 | 
					    The parameter is "s" for the audio link.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					+ /audio_sc
 | 
				
			||||||
 | 
					    Get a proxied audio file for SoundCloud. Does not support downloads
 | 
				
			||||||
 | 
					    trough WGET or CURL, since it returns 30kb~160kb "206 Partial
 | 
				
			||||||
 | 
					    Content" parts, due to technical limitations that comes with
 | 
				
			||||||
 | 
					    converting m3u8 playlists to seekable audio files. If you use this
 | 
				
			||||||
 | 
					    endpoint, you must support these 206 codes and also handle the
 | 
				
			||||||
 | 
					    initial 302 HTTP redirect. I used this method as I didn't want to
 | 
				
			||||||
 | 
					    store information about your request needlessly. This method also
 | 
				
			||||||
 | 
					    allows noJS users to access the files.
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    The parameter is "s" for the SoundCloud JSON m3u8 abomination. It
 | 
				
			||||||
 | 
					    does not support "normal" SoundCloud URLs at this time.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
+ Appendix
 | 
					+ Appendix
 | 
				
			||||||
    If you have any questions or need clarifications, please send an
 | 
					    If you have any questions or need clarifications, please send an
 | 
				
			||||||
    email my way to will at lolcat.ca
 | 
					    email my way to will at lolcat.ca
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										26
									
								
								api/v1/music.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										26
									
								
								api/v1/music.php
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,26 @@
 | 
				
			|||||||
 | 
					<?php
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					header("Content-Type: application/json");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					chdir("../../");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					include "lib/frontend.php";
 | 
				
			||||||
 | 
					$frontend = new frontend();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[$scraper, $filters] = $frontend->getscraperfilters(
 | 
				
			||||||
 | 
						"music",
 | 
				
			||||||
 | 
						isset($_GET["scraper"]) ? $_GET["scraper"] : null
 | 
				
			||||||
 | 
					);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					$get = $frontend->parsegetfilters($_GET, $filters);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					try{
 | 
				
			||||||
 | 
						echo json_encode(
 | 
				
			||||||
 | 
							$scraper->music($get),
 | 
				
			||||||
 | 
							JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES
 | 
				
			||||||
 | 
						);
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
					}catch(Exception $e){
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
						echo json_encode(["status" => $e->getMessage()]);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										223
									
								
								audio_sc.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										223
									
								
								audio_sc.php
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,223 @@
 | 
				
			|||||||
 | 
					<?php
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					new sc_audio();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class sc_audio{
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
						public function __construct(){
 | 
				
			||||||
 | 
							
 | 
				
			||||||
 | 
							include "lib/curlproxy.php";
 | 
				
			||||||
 | 
							$this->proxy = new proxy();
 | 
				
			||||||
 | 
							
 | 
				
			||||||
 | 
							if(isset($_GET["u"])){
 | 
				
			||||||
 | 
								
 | 
				
			||||||
 | 
								/*
 | 
				
			||||||
 | 
									we're now proxying audio
 | 
				
			||||||
 | 
								*/
 | 
				
			||||||
 | 
								$viewkey = $_GET["u"];
 | 
				
			||||||
 | 
								
 | 
				
			||||||
 | 
								if(!isset($_GET["r"])){
 | 
				
			||||||
 | 
									
 | 
				
			||||||
 | 
									$this->do404("Ranges(r) are missing");
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								
 | 
				
			||||||
 | 
								$ranges = explode(",", $_GET["r"]);
 | 
				
			||||||
 | 
								
 | 
				
			||||||
 | 
								// sanitize ranges
 | 
				
			||||||
 | 
								foreach($ranges as &$range){
 | 
				
			||||||
 | 
									
 | 
				
			||||||
 | 
									if(!is_numeric($range)){
 | 
				
			||||||
 | 
										
 | 
				
			||||||
 | 
										$this->do404("Invalid range specified");
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
									
 | 
				
			||||||
 | 
									$range = (int)$range;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								
 | 
				
			||||||
 | 
								// sort ranges (just to make sure)
 | 
				
			||||||
 | 
								sort($ranges);
 | 
				
			||||||
 | 
								
 | 
				
			||||||
 | 
								// convert ranges to pairs
 | 
				
			||||||
 | 
								$last = -1;
 | 
				
			||||||
 | 
								foreach($ranges as &$r){
 | 
				
			||||||
 | 
									
 | 
				
			||||||
 | 
									$tmp = $r;
 | 
				
			||||||
 | 
									$r = [$last + 1, $r];
 | 
				
			||||||
 | 
									
 | 
				
			||||||
 | 
									$last = $tmp;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								
 | 
				
			||||||
 | 
								$browser_headers = getallheaders();
 | 
				
			||||||
 | 
								
 | 
				
			||||||
 | 
								// get the requested range from client
 | 
				
			||||||
 | 
								$client_range = 0;
 | 
				
			||||||
 | 
								foreach($browser_headers as $key => $value){
 | 
				
			||||||
 | 
									
 | 
				
			||||||
 | 
									if(strtolower($key) == "range"){
 | 
				
			||||||
 | 
										
 | 
				
			||||||
 | 
										preg_match(
 | 
				
			||||||
 | 
											'/bytes=([0-9]+)/',
 | 
				
			||||||
 | 
											$value,
 | 
				
			||||||
 | 
											$client_regex
 | 
				
			||||||
 | 
										);
 | 
				
			||||||
 | 
										
 | 
				
			||||||
 | 
										if(isset($client_regex[1])){
 | 
				
			||||||
 | 
											
 | 
				
			||||||
 | 
											$client_range = (int)$client_regex[1];
 | 
				
			||||||
 | 
										}else{
 | 
				
			||||||
 | 
											
 | 
				
			||||||
 | 
											$client_range = 0;
 | 
				
			||||||
 | 
										}
 | 
				
			||||||
 | 
										break;
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								
 | 
				
			||||||
 | 
								if(
 | 
				
			||||||
 | 
									$client_range < 0 ||
 | 
				
			||||||
 | 
									$client_range > $ranges[count($ranges) - 1][1]
 | 
				
			||||||
 | 
								){
 | 
				
			||||||
 | 
									
 | 
				
			||||||
 | 
									// range is not satisfiable
 | 
				
			||||||
 | 
									http_response_code(416);
 | 
				
			||||||
 | 
									header("Content-Type: text/plain");
 | 
				
			||||||
 | 
									die();
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								
 | 
				
			||||||
 | 
								$rng = null;
 | 
				
			||||||
 | 
								for($i=0; $i<count($ranges); $i++){
 | 
				
			||||||
 | 
									
 | 
				
			||||||
 | 
									if($ranges[$i][0] <= $client_range){
 | 
				
			||||||
 | 
										
 | 
				
			||||||
 | 
										$rng = $ranges[$i];
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								
 | 
				
			||||||
 | 
								// proxy data!
 | 
				
			||||||
 | 
								http_response_code(206); // partial content
 | 
				
			||||||
 | 
								header("Accept-Ranges: bytes");
 | 
				
			||||||
 | 
								header("Content-Range: bytes {$rng[0]}-{$rng[1]}/" . ($ranges[count($ranges) - 1][1] + 1));
 | 
				
			||||||
 | 
								
 | 
				
			||||||
 | 
								$viewkey =
 | 
				
			||||||
 | 
									preg_replace(
 | 
				
			||||||
 | 
										'/\/media\/([0-9]+)\/[0-9]+\/[0-9]+/',
 | 
				
			||||||
 | 
										'/media/$1/' . $rng[0] . '/' . $rng[1],
 | 
				
			||||||
 | 
										$viewkey
 | 
				
			||||||
 | 
									);
 | 
				
			||||||
 | 
								
 | 
				
			||||||
 | 
								try{
 | 
				
			||||||
 | 
									
 | 
				
			||||||
 | 
									$this->proxy->stream_linear_audio(
 | 
				
			||||||
 | 
										$viewkey
 | 
				
			||||||
 | 
									);
 | 
				
			||||||
 | 
								}catch(Exception $error){
 | 
				
			||||||
 | 
									
 | 
				
			||||||
 | 
									$this->do404("Could not read stream");
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								
 | 
				
			||||||
 | 
								die();
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							
 | 
				
			||||||
 | 
							/*
 | 
				
			||||||
 | 
								redirect user to correct resource
 | 
				
			||||||
 | 
								we need to scrape and store the byte positions in the result URL
 | 
				
			||||||
 | 
							*/
 | 
				
			||||||
 | 
							if(!isset($_GET["s"])){
 | 
				
			||||||
 | 
								
 | 
				
			||||||
 | 
								$this->do404("The URL(s) parameter is missing");
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							
 | 
				
			||||||
 | 
							$viewkey = $_GET["s"];
 | 
				
			||||||
 | 
							
 | 
				
			||||||
 | 
							if(
 | 
				
			||||||
 | 
								preg_match(
 | 
				
			||||||
 | 
									'/soundcloud\.com$/',
 | 
				
			||||||
 | 
									parse_url($viewkey, PHP_URL_HOST)
 | 
				
			||||||
 | 
								) === false
 | 
				
			||||||
 | 
							){
 | 
				
			||||||
 | 
								
 | 
				
			||||||
 | 
								$this->do404("This endpoint can only be used for soundcloud streams");
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							
 | 
				
			||||||
 | 
							try{
 | 
				
			||||||
 | 
								
 | 
				
			||||||
 | 
								$json = $this->proxy->get($viewkey)["body"];
 | 
				
			||||||
 | 
							}catch(Exception $error){
 | 
				
			||||||
 | 
								
 | 
				
			||||||
 | 
								$this->do404("Curl error: " . $error->getMessage());
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							
 | 
				
			||||||
 | 
							$json = json_decode($json, true);
 | 
				
			||||||
 | 
							
 | 
				
			||||||
 | 
							if(!isset($json["url"])){
 | 
				
			||||||
 | 
								
 | 
				
			||||||
 | 
								$this->do404("Could not get URL from JSON");
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							
 | 
				
			||||||
 | 
							$viewkey = $json["url"];
 | 
				
			||||||
 | 
							
 | 
				
			||||||
 | 
							$m3u8 = $this->proxy->get($viewkey)["body"];
 | 
				
			||||||
 | 
							
 | 
				
			||||||
 | 
							$m3u8 = explode("\n", $m3u8);
 | 
				
			||||||
 | 
							
 | 
				
			||||||
 | 
							$lineout = null;
 | 
				
			||||||
 | 
							$streampos_arr = [];
 | 
				
			||||||
 | 
							foreach($m3u8 as $line){
 | 
				
			||||||
 | 
								
 | 
				
			||||||
 | 
								$line = trim($line);
 | 
				
			||||||
 | 
								if($line[0] == "#"){
 | 
				
			||||||
 | 
									
 | 
				
			||||||
 | 
									continue;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								
 | 
				
			||||||
 | 
								if($lineout === null){
 | 
				
			||||||
 | 
									$lineout = $line;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								
 | 
				
			||||||
 | 
								preg_match(
 | 
				
			||||||
 | 
									'/\/media\/[0-9]+\/([0-9]+)\/([0-9]+)/',
 | 
				
			||||||
 | 
									$line,
 | 
				
			||||||
 | 
									$matches
 | 
				
			||||||
 | 
								);
 | 
				
			||||||
 | 
								
 | 
				
			||||||
 | 
								if(isset($matches[0])){
 | 
				
			||||||
 | 
									
 | 
				
			||||||
 | 
									$streampos_arr[] = [
 | 
				
			||||||
 | 
										(int)$matches[1],
 | 
				
			||||||
 | 
										(int)$matches[2]
 | 
				
			||||||
 | 
									];
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							
 | 
				
			||||||
 | 
							if($lineout === null){
 | 
				
			||||||
 | 
								
 | 
				
			||||||
 | 
								$this->do404("Could not get stream URL");
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							
 | 
				
			||||||
 | 
							$lineout =
 | 
				
			||||||
 | 
								preg_replace(
 | 
				
			||||||
 | 
									'/\/media\/([0-9]+)\/[0-9]+\/[0-9]+/',
 | 
				
			||||||
 | 
									'/media/$1/0/0',
 | 
				
			||||||
 | 
									$lineout
 | 
				
			||||||
 | 
								);
 | 
				
			||||||
 | 
							
 | 
				
			||||||
 | 
							$streampos = [];
 | 
				
			||||||
 | 
							
 | 
				
			||||||
 | 
							foreach($streampos_arr as $pos){
 | 
				
			||||||
 | 
								
 | 
				
			||||||
 | 
								$streampos[] = $pos[1];
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							
 | 
				
			||||||
 | 
							$streampos = implode(",", $streampos);
 | 
				
			||||||
 | 
							
 | 
				
			||||||
 | 
							header("Location: audio_sc?u=" . urlencode($lineout) . "&r=$streampos");
 | 
				
			||||||
 | 
							header("Accept-Ranges: bytes");
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
						private function do404($error){
 | 
				
			||||||
 | 
							
 | 
				
			||||||
 | 
							http_response_code(404);
 | 
				
			||||||
 | 
							header("Content-Type: text/plain");
 | 
				
			||||||
 | 
							header("X-Error: $error");
 | 
				
			||||||
 | 
							die();
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -150,7 +150,7 @@ class proxy{
 | 
				
			|||||||
					$curl,
 | 
										$curl,
 | 
				
			||||||
					CURLOPT_HTTPHEADER,
 | 
										CURLOPT_HTTPHEADER,
 | 
				
			||||||
					[
 | 
										[
 | 
				
			||||||
						"User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:107.0) Gecko/20100101 Firefox/110.0",
 | 
											"User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/116.0",
 | 
				
			||||||
						"Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8",
 | 
											"Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8",
 | 
				
			||||||
						"Accept-Language: en-US,en;q=0.5",
 | 
											"Accept-Language: en-US,en;q=0.5",
 | 
				
			||||||
						"Accept-Encoding: gzip, deflate",
 | 
											"Accept-Encoding: gzip, deflate",
 | 
				
			||||||
@@ -178,7 +178,7 @@ class proxy{
 | 
				
			|||||||
					$curl,
 | 
										$curl,
 | 
				
			||||||
					CURLOPT_HTTPHEADER,
 | 
										CURLOPT_HTTPHEADER,
 | 
				
			||||||
					[
 | 
										[
 | 
				
			||||||
						"User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:107.0) Gecko/20100101 Firefox/107.0",
 | 
											"User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/116.0",
 | 
				
			||||||
						"Accept: image/avif,image/webp,*/*",
 | 
											"Accept: image/avif,image/webp,*/*",
 | 
				
			||||||
						"Accept-Language: en-US,en;q=0.5",
 | 
											"Accept-Language: en-US,en;q=0.5",
 | 
				
			||||||
						"Accept-Encoding: gzip, deflate",
 | 
											"Accept-Encoding: gzip, deflate",
 | 
				
			||||||
@@ -380,7 +380,7 @@ class proxy{
 | 
				
			|||||||
					$curl,
 | 
										$curl,
 | 
				
			||||||
					CURLOPT_HTTPHEADER,
 | 
										CURLOPT_HTTPHEADER,
 | 
				
			||||||
					[
 | 
										[
 | 
				
			||||||
						"User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:107.0) Gecko/20100101 Firefox/110.0",
 | 
											"User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/116.0",
 | 
				
			||||||
						"Accept: image/avif,image/webp,*/*",
 | 
											"Accept: image/avif,image/webp,*/*",
 | 
				
			||||||
						"Accept-Language: en-US,en;q=0.5",
 | 
											"Accept-Language: en-US,en;q=0.5",
 | 
				
			||||||
						"Accept-Encoding: gzip, deflate, br",
 | 
											"Accept-Encoding: gzip, deflate, br",
 | 
				
			||||||
@@ -396,7 +396,7 @@ class proxy{
 | 
				
			|||||||
					$curl,
 | 
										$curl,
 | 
				
			||||||
					CURLOPT_HTTPHEADER,
 | 
										CURLOPT_HTTPHEADER,
 | 
				
			||||||
					[
 | 
										[
 | 
				
			||||||
						"User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:107.0) Gecko/20100101 Firefox/110.0",
 | 
											"User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/116.0",
 | 
				
			||||||
						"Accept: audio/webm,audio/ogg,audio/wav,audio/*;q=0.9,application/ogg;q=0.7,video/*;q=0.6,*/*;q=0.5",
 | 
											"Accept: audio/webm,audio/ogg,audio/wav,audio/*;q=0.9,application/ogg;q=0.7,video/*;q=0.6,*/*;q=0.5",
 | 
				
			||||||
						"Accept-Language: en-US,en;q=0.5",
 | 
											"Accept-Language: en-US,en;q=0.5",
 | 
				
			||||||
						"Accept-Encoding: gzip, deflate, br",
 | 
											"Accept-Encoding: gzip, deflate, br",
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -98,7 +98,7 @@ class frontend{
 | 
				
			|||||||
			]);
 | 
								]);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	
 | 
						
 | 
				
			||||||
	public function drawtextresult($site, $greentext = null, $duration = null, $keywords, $tabindex = true){
 | 
						public function drawtextresult($site, $greentext = null, $duration = null, $keywords, $tabindex = true, $customhtml = null){
 | 
				
			||||||
		
 | 
							
 | 
				
			||||||
		$payload =
 | 
							$payload =
 | 
				
			||||||
			'<div class="text-result">';
 | 
								'<div class="text-result">';
 | 
				
			||||||
@@ -188,6 +188,8 @@ class frontend{
 | 
				
			|||||||
				'</div>';
 | 
									'</div>';
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		
 | 
							
 | 
				
			||||||
 | 
							$payload .= $customhtml;
 | 
				
			||||||
 | 
							
 | 
				
			||||||
		$payload .= '</a>';
 | 
							$payload .= '</a>';
 | 
				
			||||||
		
 | 
							
 | 
				
			||||||
		/*
 | 
							/*
 | 
				
			||||||
@@ -764,6 +766,7 @@ class frontend{
 | 
				
			|||||||
				'<a href="https://webcache.googleusercontent.com/search?q=cache:' . $urlencode . '" class="list" target="_BLANK"><img src="/favicon?s=https://google.com" alt="go">Google cache</a>' .
 | 
									'<a href="https://webcache.googleusercontent.com/search?q=cache:' . $urlencode . '" class="list" target="_BLANK"><img src="/favicon?s=https://google.com" alt="go">Google cache</a>' .
 | 
				
			||||||
				'<a href="https://web.archive.org/web/' . $urlencode . '" class="list" target="_BLANK"><img src="/favicon?s=https://archive.org" alt="ar">Archive.org</a>' .
 | 
									'<a href="https://web.archive.org/web/' . $urlencode . '" class="list" target="_BLANK"><img src="/favicon?s=https://archive.org" alt="ar">Archive.org</a>' .
 | 
				
			||||||
				'<a href="https://archive.is/newest/' . htmlspecialchars($link) . '" class="list" target="_BLANK"><img src="/favicon?s=https://archive.is" alt="ar">Archive.is</a>' .
 | 
									'<a href="https://archive.is/newest/' . htmlspecialchars($link) . '" class="list" target="_BLANK"><img src="/favicon?s=https://archive.is" alt="ar">Archive.is</a>' .
 | 
				
			||||||
 | 
									'<a href="https://ghostarchive.org/search?term=' . $urlencode . '" class="list" target="_BLANK"><img src="/favicon?s=https://ghostarchive.org" alt="gh">Ghostarchive</a>' .
 | 
				
			||||||
				'<a href="https://www.bing.com/search?q=url%3A' . $urlencode . '" class="list" target="_BLANK"><img src="/favicon?s=https://bing.com" alt="bi">Bing cache</a>' .
 | 
									'<a href="https://www.bing.com/search?q=url%3A' . $urlencode . '" class="list" target="_BLANK"><img src="/favicon?s=https://bing.com" alt="bi">Bing cache</a>' .
 | 
				
			||||||
				'<a href="https://megalodon.jp/?url=' . $urlencode . '" class="list" target="_BLANK"><img src="/favicon?s=https://megalodon.jp" alt="me">Megalodon</a>' .
 | 
									'<a href="https://megalodon.jp/?url=' . $urlencode . '" class="list" target="_BLANK"><img src="/favicon?s=https://megalodon.jp" alt="me">Megalodon</a>' .
 | 
				
			||||||
			'</div>';
 | 
								'</div>';
 | 
				
			||||||
@@ -835,6 +838,10 @@ class frontend{
 | 
				
			|||||||
			case "news":
 | 
								case "news":
 | 
				
			||||||
				$get_scraper = isset($_COOKIE["scraper_news"]) ? $_COOKIE["scraper_news"] : null;
 | 
									$get_scraper = isset($_COOKIE["scraper_news"]) ? $_COOKIE["scraper_news"] : null;
 | 
				
			||||||
				break;
 | 
									break;
 | 
				
			||||||
 | 
								
 | 
				
			||||||
 | 
								case "music":
 | 
				
			||||||
 | 
									$get_scraper = isset($_COOKIE["scraper_news"]) ? $_COOKIE["scraper_news"] : null;
 | 
				
			||||||
 | 
									break;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		
 | 
							
 | 
				
			||||||
		if(
 | 
							if(
 | 
				
			||||||
@@ -923,6 +930,14 @@ class frontend{
 | 
				
			|||||||
						"mojeek" => "Mojeek"
 | 
											"mojeek" => "Mojeek"
 | 
				
			||||||
					]
 | 
										]
 | 
				
			||||||
				];
 | 
									];
 | 
				
			||||||
 | 
								
 | 
				
			||||||
 | 
								case "music":
 | 
				
			||||||
 | 
									$filters["scraper"] = [
 | 
				
			||||||
 | 
										"display" => "Scraper",
 | 
				
			||||||
 | 
										"option" => [
 | 
				
			||||||
 | 
											"sc" => "SoundCloud"
 | 
				
			||||||
 | 
										]
 | 
				
			||||||
 | 
									];
 | 
				
			||||||
				break;
 | 
									break;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		
 | 
							
 | 
				
			||||||
@@ -994,6 +1009,11 @@ class frontend{
 | 
				
			|||||||
				include "scraper/wiby.php";
 | 
									include "scraper/wiby.php";
 | 
				
			||||||
				$lib = new wiby();
 | 
									$lib = new wiby();
 | 
				
			||||||
				break;
 | 
									break;
 | 
				
			||||||
 | 
								
 | 
				
			||||||
 | 
								case "sc":
 | 
				
			||||||
 | 
									include "scraper/sc.php";
 | 
				
			||||||
 | 
									$lib = new sc();
 | 
				
			||||||
 | 
									break;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		
 | 
							
 | 
				
			||||||
		// set scraper on $_GET
 | 
							// set scraper on $_GET
 | 
				
			||||||
@@ -1169,7 +1189,7 @@ class frontend{
 | 
				
			|||||||
		
 | 
							
 | 
				
			||||||
		$html = null;
 | 
							$html = null;
 | 
				
			||||||
		
 | 
							
 | 
				
			||||||
		foreach(["web", "images", "videos", "news"] as $type){
 | 
							foreach(["web", "images", "videos", "news", "music"] as $type){
 | 
				
			||||||
			
 | 
								
 | 
				
			||||||
			$html .= '<a href="/' . $type . '?s=' . urlencode($query);
 | 
								$html .= '<a href="/' . $type . '?s=' . urlencode($query);
 | 
				
			||||||
			
 | 
								
 | 
				
			||||||
@@ -1303,7 +1323,7 @@ class frontend{
 | 
				
			|||||||
			return htmlspecialchars($image);
 | 
								return htmlspecialchars($image);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		
 | 
							
 | 
				
			||||||
		return "/proxy?i=" . urlencode($image) . "&s=" . $format;
 | 
							return "/proxy.php?i=" . urlencode($image) . "&s=" . $format;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	
 | 
						
 | 
				
			||||||
	public function htmlnextpage($gets, $npt, $page){
 | 
						public function htmlnextpage($gets, $npt, $page){
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										224
									
								
								music.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										224
									
								
								music.php
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,224 @@
 | 
				
			|||||||
 | 
					<?php
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
						Initialize random shit
 | 
				
			||||||
 | 
					*/
 | 
				
			||||||
 | 
					include "lib/frontend.php";
 | 
				
			||||||
 | 
					$frontend = new frontend();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[$scraper, $filters] = $frontend->getscraperfilters("music");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					$get = $frontend->parsegetfilters($_GET, $filters);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					$frontend->loadheader(
 | 
				
			||||||
 | 
						$get,
 | 
				
			||||||
 | 
						$filters,
 | 
				
			||||||
 | 
						"music"
 | 
				
			||||||
 | 
					);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					$payload = [
 | 
				
			||||||
 | 
						"class" => "",
 | 
				
			||||||
 | 
						"right-left" => "",
 | 
				
			||||||
 | 
						"right-right" => "",
 | 
				
			||||||
 | 
						"left" => ""
 | 
				
			||||||
 | 
					];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					try{
 | 
				
			||||||
 | 
						$results = $scraper->music($get);
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
					}catch(Exception $error){
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
						echo
 | 
				
			||||||
 | 
							$frontend->drawerror(
 | 
				
			||||||
 | 
								"Shit",
 | 
				
			||||||
 | 
								'This scraper returned an error:' .
 | 
				
			||||||
 | 
								'<div class="code">' . htmlspecialchars($error->getMessage()) . '</div>' .
 | 
				
			||||||
 | 
								'Things you can try:' .
 | 
				
			||||||
 | 
								'<ul>' . 
 | 
				
			||||||
 | 
									'<li>Use a different scraper</li>' .
 | 
				
			||||||
 | 
									'<li>Remove keywords that could cause errors</li>' .
 | 
				
			||||||
 | 
									'<li>Use another 4get instance</li>' .
 | 
				
			||||||
 | 
								'</ul><br>' .
 | 
				
			||||||
 | 
								'If the error persists, please <a href="/about">contact the administrator</a>.'
 | 
				
			||||||
 | 
							);
 | 
				
			||||||
 | 
						die();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					$categories = [
 | 
				
			||||||
 | 
						"song" => "",
 | 
				
			||||||
 | 
						"author" => "",
 | 
				
			||||||
 | 
						"playlist" => ""
 | 
				
			||||||
 | 
					];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
						Set the main container
 | 
				
			||||||
 | 
					*/
 | 
				
			||||||
 | 
					$main = null;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if(count($results["song"]) !== 0){
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
						$main = "song";
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
					}elseif(count($results["author"]) !== 0){
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
						$main = "author";
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
					}elseif(count($results["playlist"]) !== 0){
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
						$main = "playlist";
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
					}else{
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
						// No results found!
 | 
				
			||||||
 | 
						echo
 | 
				
			||||||
 | 
							$frontend->drawerror(
 | 
				
			||||||
 | 
								"Nobody here but us chickens!",
 | 
				
			||||||
 | 
								'Have you tried:' .
 | 
				
			||||||
 | 
									'<ul>' .
 | 
				
			||||||
 | 
										'<li>Using a different scraper</li>' .
 | 
				
			||||||
 | 
										'<li>Using fewer keywords</li>' .
 | 
				
			||||||
 | 
										'<li>Defining broader filters (Is NSFW turned off?)</li>' .
 | 
				
			||||||
 | 
									'</ul>' .
 | 
				
			||||||
 | 
								'</div>'
 | 
				
			||||||
 | 
							);
 | 
				
			||||||
 | 
						die();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
						Generate list of songs
 | 
				
			||||||
 | 
					*/
 | 
				
			||||||
 | 
					foreach($categories as $name => $data){
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
						foreach($results[$name] as $item){
 | 
				
			||||||
 | 
							
 | 
				
			||||||
 | 
							$greentext = [];
 | 
				
			||||||
 | 
							
 | 
				
			||||||
 | 
							if(
 | 
				
			||||||
 | 
								isset($item["date"]) &&
 | 
				
			||||||
 | 
								$item["date"] !== null
 | 
				
			||||||
 | 
							){
 | 
				
			||||||
 | 
								
 | 
				
			||||||
 | 
								$greentext[] = date("jS M y @ g:ia", $item["date"]);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							
 | 
				
			||||||
 | 
							if(
 | 
				
			||||||
 | 
								isset($item["views"]) &&
 | 
				
			||||||
 | 
								$item["views"] !== null
 | 
				
			||||||
 | 
							){
 | 
				
			||||||
 | 
								
 | 
				
			||||||
 | 
								$views = number_format($item["views"]) . " views";
 | 
				
			||||||
 | 
								$greentext[] = $views;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							
 | 
				
			||||||
 | 
							if(
 | 
				
			||||||
 | 
								isset($item["followers"]) &&
 | 
				
			||||||
 | 
								$item["followers"] !== null
 | 
				
			||||||
 | 
							){
 | 
				
			||||||
 | 
								
 | 
				
			||||||
 | 
								$greentext[] = number_format($item["followers"]) . " followers";
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							
 | 
				
			||||||
 | 
							if(
 | 
				
			||||||
 | 
								isset($item["author"]["name"]) &&
 | 
				
			||||||
 | 
								$item["author"]["name"] !== null
 | 
				
			||||||
 | 
							){
 | 
				
			||||||
 | 
								
 | 
				
			||||||
 | 
								$greentext[] = $item["author"]["name"];
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							
 | 
				
			||||||
 | 
							$greentext = implode(" • ", $greentext);
 | 
				
			||||||
 | 
							
 | 
				
			||||||
 | 
							if(
 | 
				
			||||||
 | 
								isset($item["duration"]) &&
 | 
				
			||||||
 | 
								$item["duration"] !== null
 | 
				
			||||||
 | 
							){
 | 
				
			||||||
 | 
								
 | 
				
			||||||
 | 
								$duration = $frontend->s_to_timestamp($item["duration"]);
 | 
				
			||||||
 | 
							}else{
 | 
				
			||||||
 | 
								
 | 
				
			||||||
 | 
								$duration = null;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							
 | 
				
			||||||
 | 
							$tabindex = $name == $main ? true : false;
 | 
				
			||||||
 | 
							
 | 
				
			||||||
 | 
							$customhtml = null;
 | 
				
			||||||
 | 
							
 | 
				
			||||||
 | 
							if(
 | 
				
			||||||
 | 
								$name == "song" &&
 | 
				
			||||||
 | 
								$item["stream"]["endpoint"] !== null
 | 
				
			||||||
 | 
							){
 | 
				
			||||||
 | 
								
 | 
				
			||||||
 | 
								$customhtml =
 | 
				
			||||||
 | 
									'<audio src="' . $item["stream"]["endpoint"] . '?s=' . urlencode($item["stream"]["url"]) . '" controls autostart="false" preload="none">';
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							
 | 
				
			||||||
 | 
							$categories[$name] .= $frontend->drawtextresult($item, $greentext, $duration, $get["s"], $tabindex, $customhtml);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					$payload["left"] = $categories[$main];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// dont re-draw the category
 | 
				
			||||||
 | 
					unset($categories[$main]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
						Populate right handside
 | 
				
			||||||
 | 
					*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					$i = 1;
 | 
				
			||||||
 | 
					foreach($categories as $name => $value){
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
						if($value == ""){
 | 
				
			||||||
 | 
							
 | 
				
			||||||
 | 
							continue;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
						if($i % 2 === 1){
 | 
				
			||||||
 | 
							
 | 
				
			||||||
 | 
							$write = "right-left";
 | 
				
			||||||
 | 
						}else{
 | 
				
			||||||
 | 
							
 | 
				
			||||||
 | 
							$write = "right-right";
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
						$payload[$write] .=
 | 
				
			||||||
 | 
							'<div class="answer-wrapper">' .
 | 
				
			||||||
 | 
							'<input id="answer' . $i . '" class="spoiler" type="checkbox">' .
 | 
				
			||||||
 | 
							'<div class="answer">' .
 | 
				
			||||||
 | 
								'<div class="answer-title">' .
 | 
				
			||||||
 | 
									'<a class="answer-title" href="?s=' . urlencode($get["s"]);
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
						switch($name){
 | 
				
			||||||
 | 
							
 | 
				
			||||||
 | 
							case "playlist":
 | 
				
			||||||
 | 
								$payload[$write] .=
 | 
				
			||||||
 | 
									'&type=playlist"><h2>Playlists</h2></a>';
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							
 | 
				
			||||||
 | 
							case "author":
 | 
				
			||||||
 | 
								$payload[$write] .=
 | 
				
			||||||
 | 
									'&type=people"><h2>Authors</h2></a>';
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
						$payload[$write] .=
 | 
				
			||||||
 | 
								'</div>' .
 | 
				
			||||||
 | 
								$categories[$name] .
 | 
				
			||||||
 | 
							'</div>' .
 | 
				
			||||||
 | 
							'<label class="spoiler-button" for="answer' . $i . '"></label></div>';
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
						$i++;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if($i !== 1){
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
						$payload["class"] = " has-answer";
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if($results["npt"] !== null){
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
						$payload["left"] .=
 | 
				
			||||||
 | 
							'<a href="' . $frontend->htmlnextpage($get, $results["npt"], "music") . '" class="nextpage">Next page ></a>';
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					echo $frontend->load("search.html", $payload);
 | 
				
			||||||
							
								
								
									
										397
									
								
								scraper/sc.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										397
									
								
								scraper/sc.php
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,397 @@
 | 
				
			|||||||
 | 
					<?php
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class sc{
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
						public function __construct(){
 | 
				
			||||||
 | 
							
 | 
				
			||||||
 | 
							include "lib/nextpage.php";
 | 
				
			||||||
 | 
							$this->nextpage = new nextpage("sc");
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
						public function getfilters($page){
 | 
				
			||||||
 | 
							
 | 
				
			||||||
 | 
							return [
 | 
				
			||||||
 | 
								"type" => [
 | 
				
			||||||
 | 
									"display" => "Type",
 | 
				
			||||||
 | 
									"option" => [
 | 
				
			||||||
 | 
										"any" => "Any type",
 | 
				
			||||||
 | 
										"track" => "Tracks",
 | 
				
			||||||
 | 
										"people" => "People",
 | 
				
			||||||
 | 
										"album" => "Albums",
 | 
				
			||||||
 | 
										"playlist" => "Playlists",
 | 
				
			||||||
 | 
										"goplus" => "Go+ Tracks"
 | 
				
			||||||
 | 
									]
 | 
				
			||||||
 | 
								]
 | 
				
			||||||
 | 
							];
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
						private function get($url, $get = []){
 | 
				
			||||||
 | 
							
 | 
				
			||||||
 | 
							$curlproc = curl_init();
 | 
				
			||||||
 | 
							
 | 
				
			||||||
 | 
							if($get !== []){
 | 
				
			||||||
 | 
								$get = http_build_query($get);
 | 
				
			||||||
 | 
								$url .= "?" . $get;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							
 | 
				
			||||||
 | 
							curl_setopt($curlproc, CURLOPT_URL, $url);
 | 
				
			||||||
 | 
							
 | 
				
			||||||
 | 
							curl_setopt($curlproc, CURLOPT_ENCODING, ""); // default encoding
 | 
				
			||||||
 | 
							curl_setopt($curlproc, CURLOPT_HTTPHEADER,
 | 
				
			||||||
 | 
								["User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/116.0",
 | 
				
			||||||
 | 
								"Accept: application/json, text/javascript, */*; q=0.01",
 | 
				
			||||||
 | 
								"Accept-Language: en-US,en;q=0.5",
 | 
				
			||||||
 | 
								"Accept-Encoding: gzip",
 | 
				
			||||||
 | 
								"Referer: https://soundcloud.com/",
 | 
				
			||||||
 | 
								"Origin: https://soundcloud.com",
 | 
				
			||||||
 | 
								"DNT: 1",
 | 
				
			||||||
 | 
								"Connection: keep-alive",
 | 
				
			||||||
 | 
								"Sec-Fetch-Dest: empty",
 | 
				
			||||||
 | 
								"Sec-Fetch-Mode: cors",
 | 
				
			||||||
 | 
								"Sec-Fetch-Site: same-site"]
 | 
				
			||||||
 | 
							);
 | 
				
			||||||
 | 
							
 | 
				
			||||||
 | 
							curl_setopt($curlproc, CURLOPT_RETURNTRANSFER, true);
 | 
				
			||||||
 | 
							curl_setopt($curlproc, CURLOPT_SSL_VERIFYHOST, 2);
 | 
				
			||||||
 | 
							curl_setopt($curlproc, CURLOPT_SSL_VERIFYPEER, true);
 | 
				
			||||||
 | 
							curl_setopt($curlproc, CURLOPT_CONNECTTIMEOUT, 30);
 | 
				
			||||||
 | 
							curl_setopt($curlproc, CURLOPT_TIMEOUT, 30);
 | 
				
			||||||
 | 
							
 | 
				
			||||||
 | 
							$data = curl_exec($curlproc);
 | 
				
			||||||
 | 
							
 | 
				
			||||||
 | 
							if(curl_errno($curlproc)){
 | 
				
			||||||
 | 
								
 | 
				
			||||||
 | 
								throw new Exception(curl_error($curlproc));
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							
 | 
				
			||||||
 | 
							curl_close($curlproc);
 | 
				
			||||||
 | 
							return $data;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
						public function music($get){
 | 
				
			||||||
 | 
							
 | 
				
			||||||
 | 
							if($get["npt"]){
 | 
				
			||||||
 | 
								
 | 
				
			||||||
 | 
								$params = $this->nextpage->get($get["npt"], "music");
 | 
				
			||||||
 | 
								$params = json_decode($params, true);
 | 
				
			||||||
 | 
								
 | 
				
			||||||
 | 
								$url = $params["url"];
 | 
				
			||||||
 | 
								unset($params["url"]);
 | 
				
			||||||
 | 
								
 | 
				
			||||||
 | 
							}else{
 | 
				
			||||||
 | 
								
 | 
				
			||||||
 | 
								// normal search:
 | 
				
			||||||
 | 
								// https://api-v2.soundcloud.com/search?q=freddie%20dredd&variant_ids=&facet=model&user_id=351062-302234-707916-795081&client_id=iMxZgT5mfGstBj8GWJbYMvpzelS8ne0E&limit=20&offset=0&linked_partitioning=1&app_version=1693487844&app_locale=en
 | 
				
			||||||
 | 
								
 | 
				
			||||||
 | 
								// soundcloud go+ search:
 | 
				
			||||||
 | 
								// https://api-v2.soundcloud.com/search/tracks?q=freddie%20dredd&variant_ids=&filter.content_tier=SUB_HIGH_TIER&facet=genre&user_id=630591-269800-703400-765403&client_id=iMxZgT5mfGstBj8GWJbYMvpzelS8ne0E&limit=20&offset=0&linked_partitioning=1&app_version=1693487844&app_locale=en
 | 
				
			||||||
 | 
								
 | 
				
			||||||
 | 
								// tracks search:
 | 
				
			||||||
 | 
								// https://api-v2.soundcloud.com/search/tracks?q=freddie%20dredd&variant_ids=&facet=genre&user_id=630591-269800-703400-765403&client_id=iMxZgT5mfGstBj8GWJbYMvpzelS8ne0E&limit=20&offset=0&linked_partitioning=1&app_version=1693487844&app_locale=en
 | 
				
			||||||
 | 
								
 | 
				
			||||||
 | 
								// users search:
 | 
				
			||||||
 | 
								// https://api-v2.soundcloud.com/search/users?q=freddie%20dredd&variant_ids=&facet=place&user_id=630591-269800-703400-765403&client_id=iMxZgT5mfGstBj8GWJbYMvpzelS8ne0E&limit=20&offset=0&linked_partitioning=1&app_version=1693487844&app_locale=en
 | 
				
			||||||
 | 
								
 | 
				
			||||||
 | 
								// albums search:
 | 
				
			||||||
 | 
								// https://api-v2.soundcloud.com/search/albums?q=freddie%20dredd&variant_ids=&facet=genre&user_id=630591-269800-703400-765403&client_id=iMxZgT5mfGstBj8GWJbYMvpzelS8ne0E&limit=20&offset=0&linked_partitioning=1&app_version=1693487844&app_locale=en
 | 
				
			||||||
 | 
								
 | 
				
			||||||
 | 
								// playlists search:
 | 
				
			||||||
 | 
								// https://api-v2.soundcloud.com/search/playlists_without_albums?q=freddie%20dredd&variant_ids=&facet=genre&user_id=630591-269800-703400-765403&client_id=iMxZgT5mfGstBj8GWJbYMvpzelS8ne0E&limit=20&offset=0&linked_partitioning=1&app_version=1693487844&app_locale=en
 | 
				
			||||||
 | 
								
 | 
				
			||||||
 | 
								$search = $get["s"];
 | 
				
			||||||
 | 
								$type = $get["type"];
 | 
				
			||||||
 | 
								
 | 
				
			||||||
 | 
								switch($type){
 | 
				
			||||||
 | 
									
 | 
				
			||||||
 | 
									case "any":
 | 
				
			||||||
 | 
										$url = "https://api-v2.soundcloud.com/search";
 | 
				
			||||||
 | 
										$params = [
 | 
				
			||||||
 | 
											"q" => $search,
 | 
				
			||||||
 | 
											"variant_ids" => "",
 | 
				
			||||||
 | 
											"facet" => "model",
 | 
				
			||||||
 | 
											"user_id" => "351062-302234-707916-795081",
 | 
				
			||||||
 | 
											"client_id" => "iMxZgT5mfGstBj8GWJbYMvpzelS8ne0E",
 | 
				
			||||||
 | 
											"limit" => 20,
 | 
				
			||||||
 | 
											"offset" => 0,
 | 
				
			||||||
 | 
											"linked_partitioning" => 1,
 | 
				
			||||||
 | 
											"app_version" => 1693487844,
 | 
				
			||||||
 | 
											"app_locale" => "en"
 | 
				
			||||||
 | 
										];
 | 
				
			||||||
 | 
										break;
 | 
				
			||||||
 | 
									
 | 
				
			||||||
 | 
									case "track":
 | 
				
			||||||
 | 
										$url = "https://api-v2.soundcloud.com/search/tracks";
 | 
				
			||||||
 | 
										$params = [
 | 
				
			||||||
 | 
											"q" => $search,
 | 
				
			||||||
 | 
											"variant_ids" => "",
 | 
				
			||||||
 | 
											"facet_genre" => "",
 | 
				
			||||||
 | 
											"user_id" => "351062-302234-707916-795081",
 | 
				
			||||||
 | 
											"client_id" => "iMxZgT5mfGstBj8GWJbYMvpzelS8ne0E",
 | 
				
			||||||
 | 
											"limit" => 20,
 | 
				
			||||||
 | 
											"offset" => 0,
 | 
				
			||||||
 | 
											"linked_partitioning" => 1,
 | 
				
			||||||
 | 
											"app_version" => 1693487844,
 | 
				
			||||||
 | 
											"app_locale" => "en"
 | 
				
			||||||
 | 
										];
 | 
				
			||||||
 | 
										break;
 | 
				
			||||||
 | 
									
 | 
				
			||||||
 | 
									case "people":
 | 
				
			||||||
 | 
										$url = "https://api-v2.soundcloud.com/search/users";
 | 
				
			||||||
 | 
										$params = [
 | 
				
			||||||
 | 
											"q" => $search,
 | 
				
			||||||
 | 
											"variant_ids" => "",
 | 
				
			||||||
 | 
											"facet" => "place",
 | 
				
			||||||
 | 
											"user_id" => "351062-302234-707916-795081",
 | 
				
			||||||
 | 
											"client_id" => "iMxZgT5mfGstBj8GWJbYMvpzelS8ne0E",
 | 
				
			||||||
 | 
											"limit" => 20,
 | 
				
			||||||
 | 
											"offset" => 0,
 | 
				
			||||||
 | 
											"linked_partitioning" => 1,
 | 
				
			||||||
 | 
											"app_version" => 1693487844,
 | 
				
			||||||
 | 
											"app_locale" => "en"
 | 
				
			||||||
 | 
										];
 | 
				
			||||||
 | 
										break;
 | 
				
			||||||
 | 
									
 | 
				
			||||||
 | 
									case "album":
 | 
				
			||||||
 | 
										$url = "https://api-v2.soundcloud.com/search/albums";
 | 
				
			||||||
 | 
										$params = [
 | 
				
			||||||
 | 
											"q" => $search,
 | 
				
			||||||
 | 
											"variant_ids" => "",
 | 
				
			||||||
 | 
											"facet" => "genre",
 | 
				
			||||||
 | 
											"user_id" => "351062-302234-707916-795081",
 | 
				
			||||||
 | 
											"client_id" => "iMxZgT5mfGstBj8GWJbYMvpzelS8ne0E",
 | 
				
			||||||
 | 
											"limit" => 20,
 | 
				
			||||||
 | 
											"offset" => 0,
 | 
				
			||||||
 | 
											"linked_partitioning" => 1,
 | 
				
			||||||
 | 
											"app_version" => 1693487844,
 | 
				
			||||||
 | 
											"app_locale" => "en"
 | 
				
			||||||
 | 
										];
 | 
				
			||||||
 | 
										break;
 | 
				
			||||||
 | 
									
 | 
				
			||||||
 | 
									case "playlist":
 | 
				
			||||||
 | 
										$url = "https://api-v2.soundcloud.com/search/playlists_without_albums";
 | 
				
			||||||
 | 
										$params = [
 | 
				
			||||||
 | 
											"q" => $search,
 | 
				
			||||||
 | 
											"variant_ids" => "",
 | 
				
			||||||
 | 
											"facet" => "genre",
 | 
				
			||||||
 | 
											"user_id" => "351062-302234-707916-795081",
 | 
				
			||||||
 | 
											"client_id" => "iMxZgT5mfGstBj8GWJbYMvpzelS8ne0E",
 | 
				
			||||||
 | 
											"limit" => 20,
 | 
				
			||||||
 | 
											"offset" => 0,
 | 
				
			||||||
 | 
											"linked_partitioning" => 1,
 | 
				
			||||||
 | 
											"app_version" => 1693487844,
 | 
				
			||||||
 | 
											"app_locale" => "en"
 | 
				
			||||||
 | 
										];
 | 
				
			||||||
 | 
										break;
 | 
				
			||||||
 | 
									
 | 
				
			||||||
 | 
									case "goplus":
 | 
				
			||||||
 | 
										$url = "https://api-v2.soundcloud.com/search/tracks";
 | 
				
			||||||
 | 
										$params = [
 | 
				
			||||||
 | 
											"q" => $search,
 | 
				
			||||||
 | 
											"variant_ids" => "",
 | 
				
			||||||
 | 
											"filter.content_tier" => "SUB_HIGH_TIER",
 | 
				
			||||||
 | 
											"facet" => "genre",
 | 
				
			||||||
 | 
											"user_id" => "351062-302234-707916-795081",
 | 
				
			||||||
 | 
											"client_id" => "iMxZgT5mfGstBj8GWJbYMvpzelS8ne0E",
 | 
				
			||||||
 | 
											"limit" => 20,
 | 
				
			||||||
 | 
											"offset" => 0,
 | 
				
			||||||
 | 
											"linked_partitioning" => 1,
 | 
				
			||||||
 | 
											"app_version" => 1693487844,
 | 
				
			||||||
 | 
											"app_locale" => "en"
 | 
				
			||||||
 | 
										];
 | 
				
			||||||
 | 
										break;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
								
 | 
				
			||||||
 | 
							try{
 | 
				
			||||||
 | 
								
 | 
				
			||||||
 | 
								$json = $this->get($url, $params);
 | 
				
			||||||
 | 
								
 | 
				
			||||||
 | 
							}catch(Exception $error){
 | 
				
			||||||
 | 
								
 | 
				
			||||||
 | 
								throw new Exception("Failed to fetch JSON");
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							
 | 
				
			||||||
 | 
							/*
 | 
				
			||||||
 | 
							$handle = fopen("scraper/soundcloud.json", "r");
 | 
				
			||||||
 | 
							$json = fread($handle, filesize("scraper/soundcloud.json"));
 | 
				
			||||||
 | 
							fclose($handle);
 | 
				
			||||||
 | 
							*/
 | 
				
			||||||
 | 
							
 | 
				
			||||||
 | 
							$json = json_decode($json, true);
 | 
				
			||||||
 | 
							
 | 
				
			||||||
 | 
							if($json === null){
 | 
				
			||||||
 | 
								
 | 
				
			||||||
 | 
								throw new Exception("Failed to decode JSON");
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							
 | 
				
			||||||
 | 
							$out = [
 | 
				
			||||||
 | 
								"status" => "ok",
 | 
				
			||||||
 | 
								"npt" => null,
 | 
				
			||||||
 | 
								"song" => [],
 | 
				
			||||||
 | 
								"playlist" => [],
 | 
				
			||||||
 | 
								"author" => []
 | 
				
			||||||
 | 
							];
 | 
				
			||||||
 | 
							
 | 
				
			||||||
 | 
							/*
 | 
				
			||||||
 | 
								Get next page
 | 
				
			||||||
 | 
							*/
 | 
				
			||||||
 | 
							if(isset($json["next_href"])){
 | 
				
			||||||
 | 
								
 | 
				
			||||||
 | 
								$params["query_urn"] = $json["query_urn"];
 | 
				
			||||||
 | 
								$params["offset"] = $params["offset"] + 20;
 | 
				
			||||||
 | 
								$params["url"] = $url; // we will remove this later
 | 
				
			||||||
 | 
								
 | 
				
			||||||
 | 
								$out["npt"] =
 | 
				
			||||||
 | 
									$this->nextpage->store(
 | 
				
			||||||
 | 
										json_encode($params),
 | 
				
			||||||
 | 
										"music"
 | 
				
			||||||
 | 
									);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							
 | 
				
			||||||
 | 
							/*
 | 
				
			||||||
 | 
								Scrape items
 | 
				
			||||||
 | 
							*/
 | 
				
			||||||
 | 
							foreach($json["collection"] as $item){
 | 
				
			||||||
 | 
								
 | 
				
			||||||
 | 
								switch($item["kind"]){
 | 
				
			||||||
 | 
									
 | 
				
			||||||
 | 
									case "user":
 | 
				
			||||||
 | 
										// parse author
 | 
				
			||||||
 | 
										$out["author"][] = [
 | 
				
			||||||
 | 
											"title" => $item["username"],
 | 
				
			||||||
 | 
											"followers" => $item["followers_count"],
 | 
				
			||||||
 | 
											"description" => $item["track_count"] . " songs. " . $this->limitstrlen($item["description"]),
 | 
				
			||||||
 | 
											"thumb" => [
 | 
				
			||||||
 | 
												"url" => $item["avatar_url"],
 | 
				
			||||||
 | 
												"ratio" => "1:1"
 | 
				
			||||||
 | 
											],
 | 
				
			||||||
 | 
											"url" => $item["permalink_url"]
 | 
				
			||||||
 | 
										];
 | 
				
			||||||
 | 
										break;
 | 
				
			||||||
 | 
									
 | 
				
			||||||
 | 
									case "playlist":
 | 
				
			||||||
 | 
										// parse playlist
 | 
				
			||||||
 | 
										$description = [];
 | 
				
			||||||
 | 
										$count = 0;
 | 
				
			||||||
 | 
										
 | 
				
			||||||
 | 
										foreach($item["tracks"] as $song){
 | 
				
			||||||
 | 
											
 | 
				
			||||||
 | 
											$count++;
 | 
				
			||||||
 | 
											
 | 
				
			||||||
 | 
											if(!isset($song["title"])){
 | 
				
			||||||
 | 
												
 | 
				
			||||||
 | 
												continue;
 | 
				
			||||||
 | 
											}
 | 
				
			||||||
 | 
											
 | 
				
			||||||
 | 
											$description[] = $song["title"];
 | 
				
			||||||
 | 
										}
 | 
				
			||||||
 | 
										
 | 
				
			||||||
 | 
										if(count($description) != 0){
 | 
				
			||||||
 | 
											
 | 
				
			||||||
 | 
											$description = $count . " songs. " . implode(", ", $description);
 | 
				
			||||||
 | 
										}
 | 
				
			||||||
 | 
										
 | 
				
			||||||
 | 
										if(
 | 
				
			||||||
 | 
											isset($item["artwork_url"]) &&
 | 
				
			||||||
 | 
											!empty($item["artwork_url"])
 | 
				
			||||||
 | 
										){
 | 
				
			||||||
 | 
											
 | 
				
			||||||
 | 
											$thumb = [
 | 
				
			||||||
 | 
												"ratio" => "1:1",
 | 
				
			||||||
 | 
												"url" => $item["artwork_url"]
 | 
				
			||||||
 | 
											];
 | 
				
			||||||
 | 
											
 | 
				
			||||||
 | 
										}elseif(
 | 
				
			||||||
 | 
											isset($item["tracks"][0]["artwork_url"]) &&
 | 
				
			||||||
 | 
											!empty($item["tracks"][0]["artwork_url"])
 | 
				
			||||||
 | 
										){
 | 
				
			||||||
 | 
											
 | 
				
			||||||
 | 
											$thumb = [
 | 
				
			||||||
 | 
												"ratio" => "1:1",
 | 
				
			||||||
 | 
												"url" => $item["tracks"][0]["artwork_url"]
 | 
				
			||||||
 | 
											];
 | 
				
			||||||
 | 
										}else{
 | 
				
			||||||
 | 
											
 | 
				
			||||||
 | 
											$thumb = [
 | 
				
			||||||
 | 
												"ratio" => null,
 | 
				
			||||||
 | 
												"url" => null
 | 
				
			||||||
 | 
											];
 | 
				
			||||||
 | 
										}
 | 
				
			||||||
 | 
										
 | 
				
			||||||
 | 
										$out["playlist"][] = [
 | 
				
			||||||
 | 
											"title" => $item["title"],
 | 
				
			||||||
 | 
											"description" => $description,
 | 
				
			||||||
 | 
											"author" => [
 | 
				
			||||||
 | 
												"name" => $item["user"]["username"],
 | 
				
			||||||
 | 
												"url" => $item["user"]["permalink_url"],
 | 
				
			||||||
 | 
												"avatar" => $item["user"]["avatar_url"]
 | 
				
			||||||
 | 
											],
 | 
				
			||||||
 | 
											"thumb" => $thumb,
 | 
				
			||||||
 | 
											"date" => strtotime($item["created_at"]),
 | 
				
			||||||
 | 
											"duration" => $item["duration"] / 1000,
 | 
				
			||||||
 | 
											"url" => $item["permalink_url"]
 | 
				
			||||||
 | 
										];
 | 
				
			||||||
 | 
										break;
 | 
				
			||||||
 | 
									
 | 
				
			||||||
 | 
									case "track":
 | 
				
			||||||
 | 
										if(stripos($item["monetization_model"], "TIER") === false){
 | 
				
			||||||
 | 
											
 | 
				
			||||||
 | 
											$stream = [
 | 
				
			||||||
 | 
												"endpoint" => "audio_sc",
 | 
				
			||||||
 | 
												"url" =>
 | 
				
			||||||
 | 
													$item["media"]["transcodings"][0]["url"] .
 | 
				
			||||||
 | 
													"?client_id=iMxZgT5mfGstBj8GWJbYMvpzelS8ne0E" .
 | 
				
			||||||
 | 
													"&track_authorization=" .
 | 
				
			||||||
 | 
													$item["track_authorization"]
 | 
				
			||||||
 | 
											];
 | 
				
			||||||
 | 
										}else{
 | 
				
			||||||
 | 
											
 | 
				
			||||||
 | 
											$stream = [
 | 
				
			||||||
 | 
												"endpoint" => null,
 | 
				
			||||||
 | 
												"url" => null
 | 
				
			||||||
 | 
											];
 | 
				
			||||||
 | 
										}
 | 
				
			||||||
 | 
										
 | 
				
			||||||
 | 
										// parse track
 | 
				
			||||||
 | 
										$out["song"][] = [
 | 
				
			||||||
 | 
											"title" => $item["title"],
 | 
				
			||||||
 | 
											"description" => $item["description"] == "" ? null : $this->limitstrlen($item["description"]),
 | 
				
			||||||
 | 
											"url" => $item["permalink_url"],
 | 
				
			||||||
 | 
											"views" => $item["playback_count"],
 | 
				
			||||||
 | 
											"author" => [
 | 
				
			||||||
 | 
												"name" => $item["user"]["username"],
 | 
				
			||||||
 | 
												"url" => $item["user"]["permalink_url"],
 | 
				
			||||||
 | 
												"avatar" => $item["user"]["avatar_url"]
 | 
				
			||||||
 | 
											],
 | 
				
			||||||
 | 
											"thumb" => [
 | 
				
			||||||
 | 
												"ratio" => "1:1",
 | 
				
			||||||
 | 
												"url" => $item["artwork_url"]
 | 
				
			||||||
 | 
											],
 | 
				
			||||||
 | 
											"date" => strtotime($item["created_at"]),
 | 
				
			||||||
 | 
											"duration" => (int)$item["full_duration"] / 1000,
 | 
				
			||||||
 | 
											"stream" => $stream
 | 
				
			||||||
 | 
										];
 | 
				
			||||||
 | 
										break;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							
 | 
				
			||||||
 | 
							return $out;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
						private function limitstrlen($text){
 | 
				
			||||||
 | 
							
 | 
				
			||||||
 | 
							return
 | 
				
			||||||
 | 
								explode(
 | 
				
			||||||
 | 
									"\n",
 | 
				
			||||||
 | 
									wordwrap(
 | 
				
			||||||
 | 
										str_replace(
 | 
				
			||||||
 | 
											"\n",
 | 
				
			||||||
 | 
											" ",
 | 
				
			||||||
 | 
											$text
 | 
				
			||||||
 | 
										),
 | 
				
			||||||
 | 
										300,
 | 
				
			||||||
 | 
										"\n"
 | 
				
			||||||
 | 
									)
 | 
				
			||||||
 | 
								)[0];
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -959,6 +959,7 @@ class yandex{
 | 
				
			|||||||
					"img"
 | 
										"img"
 | 
				
			||||||
				);
 | 
									);
 | 
				
			||||||
			
 | 
								
 | 
				
			||||||
 | 
								$c = 1;
 | 
				
			||||||
			if(count($thumb) === 0){
 | 
								if(count($thumb) === 0){
 | 
				
			||||||
				
 | 
									
 | 
				
			||||||
				$thumb = [
 | 
									$thumb = [
 | 
				
			||||||
@@ -967,7 +968,6 @@ class yandex{
 | 
				
			|||||||
				];
 | 
									];
 | 
				
			||||||
			}else{
 | 
								}else{
 | 
				
			||||||
				
 | 
									
 | 
				
			||||||
				$c = 1;
 | 
					 | 
				
			||||||
				$thumb = [
 | 
									$thumb = [
 | 
				
			||||||
					"url" =>
 | 
										"url" =>
 | 
				
			||||||
						str_replace(
 | 
											str_replace(
 | 
				
			||||||
@@ -1065,12 +1065,17 @@ class yandex{
 | 
				
			|||||||
				"views" => $views,
 | 
									"views" => $views,
 | 
				
			||||||
				"thumb" => $thumb,
 | 
									"thumb" => $thumb,
 | 
				
			||||||
				"url" =>
 | 
									"url" =>
 | 
				
			||||||
 | 
										str_replace(
 | 
				
			||||||
 | 
											"http://",
 | 
				
			||||||
 | 
											"https://",
 | 
				
			||||||
						$this->fuckhtml
 | 
											$this->fuckhtml
 | 
				
			||||||
						->getTextContent(
 | 
											->getTextContent(
 | 
				
			||||||
							$data["counters"]
 | 
												$data["counters"]
 | 
				
			||||||
							["toHostingLoaded"]
 | 
												["toHostingLoaded"]
 | 
				
			||||||
							["postfix"]
 | 
												["postfix"]
 | 
				
			||||||
							["href"]
 | 
												["href"]
 | 
				
			||||||
 | 
											),
 | 
				
			||||||
 | 
											$c
 | 
				
			||||||
					)
 | 
										)
 | 
				
			||||||
			];
 | 
								];
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										12
									
								
								settings.php
									
									
									
									
									
								
							
							
						
						
									
										12
									
								
								settings.php
									
									
									
									
									
								
							@@ -161,6 +161,16 @@ $settings = [
 | 
				
			|||||||
						"text" => "Mojeek"
 | 
											"text" => "Mojeek"
 | 
				
			||||||
					]
 | 
										]
 | 
				
			||||||
				]
 | 
									]
 | 
				
			||||||
 | 
								],
 | 
				
			||||||
 | 
								[
 | 
				
			||||||
 | 
									"description" => "Music",
 | 
				
			||||||
 | 
									"parameter" => "scraper_music",
 | 
				
			||||||
 | 
									"options" => [
 | 
				
			||||||
 | 
										[
 | 
				
			||||||
 | 
											"value" => "sc",
 | 
				
			||||||
 | 
											"text" => "SoundCloud"
 | 
				
			||||||
 | 
										]
 | 
				
			||||||
 | 
									]
 | 
				
			||||||
			]
 | 
								]
 | 
				
			||||||
		]
 | 
							]
 | 
				
			||||||
	]
 | 
						]
 | 
				
			||||||
@@ -235,7 +245,7 @@ echo
 | 
				
			|||||||
		'<head>' .
 | 
							'<head>' .
 | 
				
			||||||
			'<meta http-equiv="Content-Type" content="text/html;charset=utf-8">' .
 | 
								'<meta http-equiv="Content-Type" content="text/html;charset=utf-8">' .
 | 
				
			||||||
			'<title>Settings</title>' .
 | 
								'<title>Settings</title>' .
 | 
				
			||||||
			'<link rel="stylesheet" href="/static/style.css">' .
 | 
								'<link rel="stylesheet" href="/static/style.css?v3">' .
 | 
				
			||||||
			'<meta name="viewport" content="width=device-width,initial-scale=1">' .
 | 
								'<meta name="viewport" content="width=device-width,initial-scale=1">' .
 | 
				
			||||||
			'<meta name="robots" content="index,follow">' .
 | 
								'<meta name="robots" content="index,follow">' .
 | 
				
			||||||
			'<link rel="icon" type="image/x-icon" href="/favicon.ico">' .
 | 
								'<link rel="icon" type="image/x-icon" href="/favicon.ico">' .
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -51,6 +51,13 @@
 | 
				
			|||||||
audio{
 | 
					audio{
 | 
				
			||||||
	max-width:100%;
 | 
						max-width:100%;
 | 
				
			||||||
	display:block;
 | 
						display:block;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.left audio{
 | 
				
			||||||
 | 
						margin-top:7px;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.right-wrapper audio{
 | 
				
			||||||
	margin-bottom:17px;
 | 
						margin-bottom:17px;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -3,7 +3,7 @@
 | 
				
			|||||||
	<head>
 | 
						<head>
 | 
				
			||||||
		<meta http-equiv="Content-Type" content="text/html;charset=utf-8">
 | 
							<meta http-equiv="Content-Type" content="text/html;charset=utf-8">
 | 
				
			||||||
		<title>{%title%}</title>
 | 
							<title>{%title%}</title>
 | 
				
			||||||
		<link rel="stylesheet" href="/static/style.css?v2">
 | 
							<link rel="stylesheet" href="/static/style.css?v3">
 | 
				
			||||||
		<meta name="viewport" content="width=device-width,initial-scale=1">
 | 
							<meta name="viewport" content="width=device-width,initial-scale=1">
 | 
				
			||||||
		<meta name="robots" content="{%index%}index,{%index%}follow">
 | 
							<meta name="robots" content="{%index%}index,{%index%}follow">
 | 
				
			||||||
		<link rel="icon" type="image/x-icon" href="/favicon.ico">
 | 
							<link rel="icon" type="image/x-icon" href="/favicon.ico">
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -4,7 +4,7 @@
 | 
				
			|||||||
		<meta http-equiv="Content-Type" content="text/html;charset=utf-8">
 | 
							<meta http-equiv="Content-Type" content="text/html;charset=utf-8">
 | 
				
			||||||
		<title>4get</title>
 | 
							<title>4get</title>
 | 
				
			||||||
		<meta name="viewport" content="width=device-width,initial-scale=1">
 | 
							<meta name="viewport" content="width=device-width,initial-scale=1">
 | 
				
			||||||
		<link rel="stylesheet" href="/static/style.css?v2">
 | 
							<link rel="stylesheet" href="/static/style.css?v3">
 | 
				
			||||||
		<meta name="robots" content="index,follow">
 | 
							<meta name="robots" content="index,follow">
 | 
				
			||||||
		<link rel="icon" type="image/x-icon" href="/favicon.ico">
 | 
							<link rel="icon" type="image/x-icon" href="/favicon.ico">
 | 
				
			||||||
		<meta name="description" content="4get.ca: They live in our walls!">
 | 
							<meta name="description" content="4get.ca: They live in our walls!">
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user