├── .gitignore ├── LICENSE ├── README.md ├── classes └── lookup.php ├── composer.json ├── composer.lock ├── favicon.ico ├── index.php ├── misc └── servers │ └── servers.json ├── screenshot.png ├── scripts ├── jquery.js ├── script.js └── table2csv.js ├── styles ├── simple-grid.css └── style.css └── vendor ├── autoload.php ├── bin ├── parse └── update-psl ├── composer ├── ClassLoader.php ├── LICENSE ├── autoload_classmap.php ├── autoload_files.php ├── autoload_namespaces.php ├── autoload_psr4.php ├── autoload_real.php ├── autoload_static.php └── installed.json ├── helgesverre └── domain-availability │ ├── .gitattributes │ ├── .gitignore │ ├── .travis.yml │ ├── LICENSE.md │ ├── README.md │ ├── composer.json │ ├── composer.lock │ ├── example.php │ ├── src │ ├── Client │ │ ├── SimpleWhoisClient.php │ │ └── WhoisClientInterface.php │ ├── Loader │ │ ├── JsonLoader.php │ │ └── LoaderInterface.php │ ├── Service │ │ └── DomainAvailability.php │ └── data │ │ └── servers.json │ └── tests │ ├── DomainAvailabilityTest.php │ ├── JsonLoaderTest.php │ └── SimpleWhoisClientTest.php └── jeremykendall └── php-domain-parser ├── .gitignore ├── .php_cs ├── .travis.yml ├── ASF-LICENSE-2.0 ├── CONTRIBUTING.md ├── LICENSE ├── README.md ├── bin ├── parse └── update-psl ├── build.properties ├── build.xml ├── composer.json ├── data └── public-suffix-list.php ├── example.php ├── phpunit.xml.dist ├── src ├── Pdp │ ├── HttpAdapter │ │ ├── CurlHttpAdapter.php │ │ └── HttpAdapterInterface.php │ ├── Parser.php │ ├── PublicSuffixList.php │ ├── PublicSuffixListManager.php │ └── Uri │ │ ├── Url.php │ │ └── Url │ │ └── Host.php └── pdp-parse-url.php └── tests ├── bootstrap.php └── src └── Pdp ├── CheckPublicSuffixTest.php ├── HttpAdapter └── CurlHttpAdapterTest.php ├── ParserTest.php ├── PublicSuffixListManagerTest.php └── Uri ├── Url └── HostTest.php └── UrlTest.php /.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/ignore-files/ for more about ignoring files. 2 | 3 | # misc 4 | .DS_Store 5 | .env.local 6 | .env.development.local 7 | .env.test.local 8 | .env.production.local 9 | # .env.example 10 | 11 | # generated by os 12 | .DS_Store 13 | .DS_Store? 14 | ._* 15 | .Spotlight-V100 16 | .Trashes 17 | ehthumbs.db 18 | Thumbs.db 19 | 20 | # intellij project files 21 | *.iml 22 | *.iws 23 | *.ipr 24 | .idea/ 25 | 26 | # eclipse project file 27 | .settings/ 28 | .classpath 29 | .project 30 | 31 | # netbeans specific 32 | nbproject/private/ 33 | build/ 34 | nbbuild/ 35 | dist/ 36 | nbdist/ 37 | nbactions.xml 38 | nb-configuration.xml 39 | 40 | # visual code 41 | .vscode/ 42 | 43 | # composer package 44 | # vendor 45 | 46 | 47 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 abaron 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Bulk Domain Availability 2 | Simple tools for create your own unlimited bulk domain checker 3 | 4 | ## Requirements 5 | | Require | Minimum Version | Recomended Version | 6 | | ------ | ------ | ------ | 7 | | PHP | v5.3 | v7.1 | 8 | | php-intl | - | - | 9 | | php-curl | - | - | 10 | 11 | Without composer, without database 12 | 13 | ## Project Installation 14 | - Clone the repository `$ git clone https://github.com/abaron/bulk-domain-availability.git` 15 | - RUN. Enjoy 16 | 17 | ## Feature 18 | - Bulk checker availability 19 | - Pause 20 | - Resume 21 | - Stop 22 | - Combine a word 23 | - Export to CSV 24 | - ??? 25 | 26 | ## Screenshot 27 | [![Abaron Bulk Domain Availability](https://github.com/abaron/bulk-domain-availability/raw/master/screenshot.png)](#) 28 | 29 | ## TODO 30 | - [x] Bulk checker 31 | - [x] Whois 32 | - [x] Combine 33 | - [x] Stop, Pause, Resume 34 | - [x] Retry 35 | - [x] Export 36 | - [ ] Send to email 37 | - [ ] Remaining time 38 | - [ ] Performance 39 | - [ ] Unit test 40 | - [ ] Architecture 41 | - [ ] Design pattern 42 | - [ ] Docs 43 | 44 | Thank you 45 | -------------------------------------------------------------------------------- /classes/lookup.php: -------------------------------------------------------------------------------- 1 | 6 | * @since Mar 30, 2019 7 | */ 8 | 9 | require_once(dirname(dirname(__FILE__)) . DIRECTORY_SEPARATOR . 'vendor' . DIRECTORY_SEPARATOR . 'autoload.php'); 10 | 11 | use Helge\Loader\JsonLoader; 12 | use Helge\Client\SimpleWhoisClient; 13 | use Helge\Service\DomainAvailability; 14 | 15 | class Lookup 16 | { 17 | public $domain; 18 | public $servers; 19 | public $whoisServer; 20 | public $executeTime = 0; 21 | public $response = [ 22 | "code" => 200, 23 | "status" => "OK", 24 | "message" => "", 25 | "data" => [] 26 | ]; 27 | 28 | public function __construct() 29 | { 30 | } 31 | 32 | public function setDomain($domain) 33 | { 34 | $this->domain = (string) $domain; 35 | } 36 | 37 | public function getDomain() 38 | { 39 | return $this->domain; 40 | } 41 | 42 | public function setservers($servers) 43 | { 44 | $this->servers = (string) $servers; 45 | } 46 | 47 | public function getservers() 48 | { 49 | return $this->server; 50 | } 51 | 52 | public function setWhoisServer($whoisServer) 53 | { 54 | $this->whoisServer = (string) $whoisServer; 55 | } 56 | 57 | public function getWhoisServer() 58 | { 59 | return $this->whoisServer; 60 | } 61 | 62 | /** 63 | * Availability checker 64 | * @param string $domain domain name with extension 65 | * @return boolean true if available 66 | */ 67 | public function isAvailable($domain) 68 | { 69 | $whoisClient = new SimpleWhoisClient(); 70 | $dataLoader = new JsonLoader($this->servers); 71 | 72 | try { 73 | $service = new DomainAvailability($whoisClient, $dataLoader); 74 | $start = microtime(true); 75 | $result = $service->isAvailable($domain); 76 | $this->executeTime = number_format(microtime(true) - $start, 2); 77 | 78 | return $result; 79 | } catch (Exception $e) { 80 | } 81 | 82 | return false; 83 | } 84 | 85 | /** 86 | * Get whois data 87 | * @param string $domain domain name with extension 88 | * @return string whois data 89 | */ 90 | public function getWhois($domain) 91 | { 92 | $whoisClient = new SimpleWhoisClient($this->whoisServer); 93 | $whoisClient->query($domain); 94 | 95 | return $whoisClient->getResponse(); 96 | } 97 | 98 | /** 99 | * Request handler in one method 100 | * @param array $post array of $_POST 101 | * @param string $servers path of servers.json 102 | * @return json json data result 103 | */ 104 | public function run($post, $servers = null) 105 | { 106 | if (!$this->isAjax()) return false; 107 | 108 | header('Content-type: application/json'); 109 | 110 | if ( 111 | empty($servers) || 112 | !file_exists($servers) || 113 | !self::isValidJson(file_get_contents($servers)) 114 | ) 115 | $this->servers = dirname(dirname(__FILE__)) . 116 | "/vendor/helgesverre/domain-availability/src/data/servers.json"; 117 | else 118 | $this->servers = $servers; 119 | 120 | $serverDecoded = json_decode(file_get_contents($this->servers), true); 121 | $domain = isset($post['domain']) ? trim($post['domain']) : null; 122 | 123 | if (!empty($post['whois'])) { 124 | if (!empty($domain) && is_string($domain)) { 125 | if (!self::isValidDomain(trim($domain))) { 126 | $this->response = [ 127 | "code" => 411, 128 | "status" => "Error", 129 | "message" => "Invalid domain name", 130 | "data" => [] 131 | ]; 132 | } else { 133 | $this->whoisServer = empty(self::getExtension($domain)) ? '-' : ( 134 | isset($serverDecoded[substr(self::getExtension($domain), 1)]['server']) ? $serverDecoded[substr(self::getExtension($domain), 1)]['server'] : '-' 135 | ); 136 | $this->response['data']['domain'] = strtolower($domain); 137 | $this->response['data']['whois_data'] = $this->getWhois($domain); 138 | $this->response['data']['execute_time'] = $this->executeTime; 139 | $this->response['data']['execute_time_unit'] = 's'; 140 | $this->response['data']['whois_server'] = empty(self::getExtension($domain)) ? '-' : ( 141 | isset($serverDecoded[substr(self::getExtension($domain), 1)]['server']) ? $serverDecoded[substr(self::getExtension($domain), 1)]['server'] : '-' 142 | ); 143 | } 144 | } 145 | } else if (!empty($domain) && is_string($domain)) { 146 | if (!self::isValidDomain(trim($domain))) { 147 | $this->response = [ 148 | "code" => 411, 149 | "status" => "Error", 150 | "message" => "Invalid domain name", 151 | "data" => [] 152 | ]; 153 | } else { 154 | $this->response['data']['domain'] = strtolower($domain); 155 | 156 | if ($this->isAvailable($domain)) { 157 | $this->response['data']['is_available'] = true; 158 | } else { 159 | $this->response['data']['is_available'] = false; 160 | } 161 | 162 | $this->response['data']['execute_time'] = $this->executeTime; 163 | $this->response['data']['execute_time_unit'] = 's'; 164 | $this->response['data']['whois_server'] = empty(self::getExtension($domain)) ? '-' : ( 165 | isset($serverDecoded[substr(self::getExtension($domain), 1)]['server']) ? $serverDecoded[substr(self::getExtension($domain), 1)]['server'] : '-' 166 | ); 167 | } 168 | } else { 169 | $this->response = [ 170 | "code" => 499, 171 | "status" => "Error", 172 | "message" => "Invalid param(s)", 173 | "data" => [] 174 | ]; 175 | } 176 | 177 | die(json_encode($this->response)); 178 | } 179 | 180 | /** 181 | * Generate html options of tld 182 | * @param string $servers path of servers.json 183 | * @return string options html 184 | */ 185 | public static function htmlOptions($servers = null) 186 | { 187 | if (empty($servers)) 188 | $servers = dirname(dirname(__FILE__)) . 189 | "/vendor/helgesverre/domain-availability/src/data/servers.json"; 190 | 191 | if (self::isValidJson($json = file_get_contents($servers))) { 192 | $html = ''; 193 | $option = ''; 194 | $serverDecoded = json_decode($json, true); 195 | ksort($serverDecoded); 196 | self::moveToTop($serverDecoded, 'com'); 197 | self::moveToTop($serverDecoded, 'net'); 198 | self::moveToTop($serverDecoded, 'org'); 199 | 200 | foreach ($serverDecoded as $k => $v) { 201 | if (in_array($k, ['com', 'net', 'org'])) 202 | $html = sprintf($option, $k, ' selected="selected"') . $html; 203 | else 204 | $html .= sprintf($option, $k, ''); 205 | } 206 | 207 | return sprintf($option, '-- Choose Extensions --', 'disabled="disabled"') . $html; 208 | } 209 | 210 | return ''; 211 | } 212 | 213 | /** 214 | * Parse domain to get extension 215 | * @param string $domain domain name with extension 216 | * @return string tld / extension of domain 217 | */ 218 | public static function getExtension($domain) 219 | { 220 | $host = parse_url('http://' . $domain); 221 | preg_match('/(.*?)((\.co)?.[a-z]{2,4})$/i', $host['host'], $m); 222 | 223 | return isset($m[2]) ? $m[2] : ''; 224 | } 225 | 226 | /** 227 | * Validate string json 228 | * @param string $data string json 229 | * @return boolean true if valid 230 | */ 231 | public static function isValidJson($data = null) 232 | { 233 | if (!empty($data)) { 234 | @json_decode($data); 235 | return (json_last_error() === JSON_ERROR_NONE); 236 | } 237 | 238 | return false; 239 | } 240 | 241 | /** 242 | * Domain name validator 243 | * @param string $domain domain name with extension 244 | * @return boolean true if valid 245 | */ 246 | public static function isValidDomain($domain) 247 | { 248 | $re = '/^(?!\-)(?:[a-zA-Z\d\-]{0,62}[a-zA-Z\d]\.){1,126}(?!\d+)[a-zA-Z\d]{2,63}$/m'; 249 | 250 | return preg_match($re, $domain); 251 | } 252 | 253 | /** 254 | * Move array element to top of array by key 255 | * @param array &$array array data 256 | * @param mixed $key string or integer key 257 | * @return pointer return $array 258 | */ 259 | public static function moveToTop(&$array, $key) { 260 | $temp = array($key => $array[$key]); 261 | unset($array[$key]); 262 | $array = $temp + $array; 263 | } 264 | 265 | /** 266 | * Ajax request validator 267 | * @return boolean true if ajax request 268 | */ 269 | public static function isAjax() 270 | { 271 | return !empty($_SERVER['HTTP_X_REQUESTED_WITH']) && 272 | strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest'; 273 | } 274 | } 275 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "require": { 3 | "helgesverre/domain-availability": "~0.2.3" 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /composer.lock: -------------------------------------------------------------------------------- 1 | { 2 | "_readme": [ 3 | "This file locks the dependencies of your project to a known state", 4 | "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", 5 | "This file is @generated automatically" 6 | ], 7 | "content-hash": "deb48e5ac1121a42069860f25730154e", 8 | "packages": [ 9 | { 10 | "name": "helgesverre/domain-availability", 11 | "version": "0.2.3", 12 | "source": { 13 | "type": "git", 14 | "url": "https://github.com/HelgeSverre/Domain-Availability.git", 15 | "reference": "f69f8dfc28959f744de371b626e5c6d7d316ef93" 16 | }, 17 | "dist": { 18 | "type": "zip", 19 | "url": "https://api.github.com/repos/HelgeSverre/Domain-Availability/zipball/f69f8dfc28959f744de371b626e5c6d7d316ef93", 20 | "reference": "f69f8dfc28959f744de371b626e5c6d7d316ef93", 21 | "shasum": "" 22 | }, 23 | "require": { 24 | "jeremykendall/php-domain-parser": "^3.0", 25 | "php": ">=5.3" 26 | }, 27 | "require-dev": { 28 | "phpunit/phpunit": "5.0.*" 29 | }, 30 | "type": "library", 31 | "autoload": { 32 | "psr-4": { 33 | "Helge\\Service\\": "src/Service", 34 | "Helge\\Loader\\": "src/Loader", 35 | "Helge\\Client\\": "src/Client" 36 | } 37 | }, 38 | "notification-url": "https://packagist.org/downloads/", 39 | "license": [ 40 | "MIT" 41 | ], 42 | "authors": [ 43 | { 44 | "name": "Helge Sverre", 45 | "email": "email@helgesverre.com", 46 | "homepage": "https://www.helgesverre.com", 47 | "role": "developer" 48 | } 49 | ], 50 | "description": "A PHP library for checking if a domain name is registered or not", 51 | "homepage": "https://helgesverre.com/products/domain-availability", 52 | "keywords": [ 53 | "domain" 54 | ], 55 | "time": "2015-10-23T00:00:00+00:00" 56 | }, 57 | { 58 | "name": "jeremykendall/php-domain-parser", 59 | "version": "3.0.0", 60 | "source": { 61 | "type": "git", 62 | "url": "https://github.com/jeremykendall/php-domain-parser.git", 63 | "reference": "896e7e70f02bd4fd77190052799bc61e4d779672" 64 | }, 65 | "dist": { 66 | "type": "zip", 67 | "url": "https://api.github.com/repos/jeremykendall/php-domain-parser/zipball/896e7e70f02bd4fd77190052799bc61e4d779672", 68 | "reference": "896e7e70f02bd4fd77190052799bc61e4d779672", 69 | "shasum": "" 70 | }, 71 | "require": { 72 | "ext-curl": "*", 73 | "ext-intl": "*", 74 | "ext-mbstring": "*", 75 | "php": ">=5.3.0" 76 | }, 77 | "require-dev": { 78 | "jeremykendall/debug-die": "0.0.1.*", 79 | "mikey179/vfsstream": "~1.4", 80 | "phpunit/phpunit": "~4.4" 81 | }, 82 | "bin": [ 83 | "bin/parse", 84 | "bin/update-psl" 85 | ], 86 | "type": "library", 87 | "autoload": { 88 | "psr-0": { 89 | "Pdp\\": "src/" 90 | }, 91 | "files": [ 92 | "src/pdp-parse-url.php" 93 | ] 94 | }, 95 | "notification-url": "https://packagist.org/downloads/", 96 | "license": [ 97 | "MIT" 98 | ], 99 | "authors": [ 100 | { 101 | "name": "Jeremy Kendall", 102 | "homepage": "http://about.me/jeremykendall", 103 | "role": "Developer" 104 | }, 105 | { 106 | "name": "Contributors", 107 | "homepage": "https://github.com/jeremykendall/php-domain-parser/graphs/contributors" 108 | } 109 | ], 110 | "description": "Public Suffix List based URL parsing implemented in PHP.", 111 | "homepage": "https://github.com/jeremykendall/php-domain-parser", 112 | "keywords": [ 113 | "Public Suffix List", 114 | "domain parsing", 115 | "url parsing" 116 | ], 117 | "time": "2015-03-30T12:49:45+00:00" 118 | } 119 | ], 120 | "packages-dev": [], 121 | "aliases": [], 122 | "minimum-stability": "stable", 123 | "stability-flags": [], 124 | "prefer-stable": false, 125 | "prefer-lowest": false, 126 | "platform": [], 127 | "platform-dev": [] 128 | } 129 | -------------------------------------------------------------------------------- /favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abaron/bulk-domain-availability/1d2a07d294a7cbc11ce084300d4dc0c1e0f539ac/favicon.ico -------------------------------------------------------------------------------- /index.php: -------------------------------------------------------------------------------- 1 | run($_POST, $serverList); 8 | 9 | ?> 10 | 11 | 12 | 13 | 14 | Bulk Domain Availability 15 | 16 | 17 | 18 | 23 | 28 | 33 | 34 | 35 |
36 | 37 | 40 | 41 | 42 |
43 |
44 |
45 | 46 |
47 |
48 | 51 |
52 |
53 |
54 |
55 | 56 |
57 |
58 | 59 |
60 |
61 | 62 |
63 |
64 |
65 |
66 | 67 | 68 |
69 |
70 | 71 | 72 |
73 |
74 | 75 | 76 |
77 |
78 |
79 | 80 |
81 |
82 | 83 |
84 |
85 | 86 | 87 | 88 | 89 |
90 |
91 |
92 |
93 | 94 | 157 | 158 | 159 |
160 |
161 |
162 | Copyright © abaron 163 |
164 |
165 |
166 | 167 |
168 | 169 | 170 | 171 | 172 | 173 | -------------------------------------------------------------------------------- /screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abaron/bulk-domain-availability/1d2a07d294a7cbc11ce084300d4dc0c1e0f539ac/screenshot.png -------------------------------------------------------------------------------- /scripts/script.js: -------------------------------------------------------------------------------- 1 | window.domains = []; 2 | window.domainsError = []; 3 | window.domainsLength = 0; 4 | window.isPaused = false; 5 | 6 | $('form#availability-form').submit(function(e) { 7 | e.preventDefault(); 8 | 9 | domains = []; 10 | domainsLength = 0; 11 | isPaused = false; 12 | $('#progress, #domains-checked').html(0); 13 | $('#available-counter span, #unavailable-counter span, #error-counter span').html(0); 14 | $('.retry-error').addClass('hidden'); 15 | 16 | var tmpDomains = $('textarea[name="domains"]').val().replace(/\n/g, " ").split(" "); 17 | var tlds = $('select[name="tlds"]').val(); 18 | 19 | // trim all values 20 | $.map(tmpDomains, $.trim); 21 | 22 | // remove empty values 23 | var tmpDomains = tmpDomains.filter(function (el) { 24 | return el != ''; 25 | }); 26 | 27 | // generate domains with tld 28 | $.each(tmpDomains, function(kdomain, domain) { 29 | 30 | $.each(tlds, function(ktld, tld) { 31 | if (isValidDomain(domain)) { 32 | window.domains.push(domain); 33 | 34 | return true; 35 | } 36 | 37 | domain = addPrefixSuffix(domain); 38 | 39 | if (isValidDomain(domain + '.' + tld) && isValidLength(domain)) { 40 | window.domains.push(domain + '.' + tld); 41 | } 42 | }); 43 | }); 44 | 45 | // combine without separator 46 | if ($('input[name=combine][value=1]:checked').length) { 47 | $.each(tmpDomains, function(kdomain, domain) { 48 | $.each(tmpDomains, function(kdomain2, domain2) { 49 | if (!isValidDomain(domain) && !isValidDomain(domain2)) { 50 | $.each(tlds, function(ktld, tld) { 51 | var domainCombined = addPrefixSuffix(domain + domain2); 52 | 53 | if (isValidDomain(domainCombined + '.' + tld) && isValidLength(domainCombined)) { 54 | window.domains.push(domainCombined + '.' + tld); 55 | } 56 | }); 57 | } 58 | }); 59 | }); 60 | } 61 | 62 | // combine with "-" as separator 63 | if ($('input[name=combine][value=2]:checked').length) { 64 | $.each(tmpDomains, function(kdomain, domain) { 65 | $.each(tmpDomains, function(kdomain2, domain2) { 66 | if (!isValidDomain(domain) && !isValidDomain(domain2)) { 67 | $.each(tlds, function(ktld, tld) { 68 | var domainCombined = addPrefixSuffix(domain + '-' + domain2); 69 | 70 | if (isValidDomain(domainCombined + '.' + tld) && isValidLength(domainCombined)) { 71 | window.domains.push(domainCombined + '.' + tld); 72 | } 73 | }); 74 | } 75 | }); 76 | }); 77 | } 78 | 79 | // to unique 80 | domains = Array.from(new Set(domains)); 81 | 82 | // remove empty value (reorder) 83 | domains.filter(n => n); 84 | 85 | domains.reverse(); 86 | 87 | domainsLength = domains.length; 88 | 89 | $('#domains-length').html(domainsLength); 90 | 91 | $('.result').removeClass('hidden'); 92 | 93 | if (domains.length) { 94 | $('#pause, #stop').removeClass('hidden'); 95 | $('#search, #resume').addClass('hidden'); 96 | 97 | requestAvailability(); 98 | } 99 | }); 100 | 101 | $(document).on('click', '.close-whois', function(e) { 102 | e.preventDefault(); 103 | $(this).closest('tr').remove(); 104 | }); 105 | 106 | $(document).on('click', '[data-whois]', function(e) { 107 | e.preventDefault(); 108 | var whoisElem = $(this); 109 | var close = 'Close
'; 110 | 111 | if (whoisElem.closest('tr').next().attr('class') == 'result-whois') { 112 | whoisElem.closest('tr').next().remove(); 113 | return true; 114 | } 115 | 116 | $.ajax({ 117 | url: "", 118 | type: "post", 119 | data: "domain=" + $(this).data('whois') + '&whois=1', 120 | success: function(res) { 121 | $('' + close + res.data.whois_data.replace(new RegExp('\r?\n','g'), '
') + '').insertAfter(whoisElem.closest('tr')); 122 | }, 123 | error: function(jqXHR, textStatus, errorThrown) { 124 | $('' + close + 'Failure get whois data').insertAfter(whoisElem.closest('tr')); 125 | } 126 | }); 127 | }); 128 | 129 | function requestAvailability() { 130 | if (!domains.length) { 131 | stop(); 132 | 133 | return true; 134 | } if (isPaused) { 135 | pause(); 136 | 137 | return true; 138 | } else if (typeof(Storage) !== "undefined" && localStorage.getItem(domains[domains.length-1])) { 139 | $('#checking span').html(domains[domains.length-1]); 140 | 141 | var start = new Date().getTime(); 142 | 143 | var response = JSON.parse(localStorage.getItem(domains[domains.length-1])); 144 | 145 | var end = new Date().getTime(); 146 | response.data.execute_time = end - start; 147 | response.data.execute_time_unit = 'ms'; 148 | 149 | writeTable(response, 'cache'); 150 | 151 | requestDone(); 152 | 153 | return true; 154 | } 155 | 156 | $('#checking span').html(domains[domains.length-1]); 157 | 158 | $.ajax({ 159 | url: "", 160 | type: "post", 161 | data: "domain=" + domains[domains.length-1], 162 | timeout: 7000, 163 | success: function(res) { 164 | writeTable(res, window.location.hostname); 165 | 166 | if ($('input[name=cache][value=1]:checked').length && typeof(Storage) !== "undefined") { 167 | delete res.data.execute_time; 168 | delete res.data.execute_time_unit; 169 | 170 | try { 171 | window.localStorage.setItem(res.data.domain, JSON.stringify(res)); 172 | } 173 | catch (e) { 174 | console.log("Local Storage is full"); 175 | } 176 | } 177 | }, 178 | error: function(jqXHR, textStatus, errorThrown) { 179 | // console.log(textStatus, errorThrown); 180 | 181 | var res = {}; 182 | res.data = {}; 183 | res.code = 500; 184 | res.status = 'Error'; 185 | res.message = 'Server time out'; 186 | res.data.is_available = false; 187 | res.data.domain = domains[domains.length-1]; 188 | res.data.whois_server = '-'; 189 | res.data.execute_time = '-'; 190 | res.data.execute_time_unit = ''; 191 | window.domainsError.push(domains[domains.length-1]); 192 | 193 | // add space for error flag 194 | writeTable(res, window.location.hostname + ' '); 195 | requestDone(); 196 | $('.retry-error').removeClass('hidden'); 197 | } 198 | }).done(function(data) { 199 | requestDone(); 200 | }); 201 | } 202 | 203 | function requestDone() { 204 | domains = domains.filter(function(value, index, arr){ 205 | return value != domains[domains.length-1]; 206 | }); 207 | 208 | $('#domains-checked').html(parseInt($('#domains-checked').html()) + 1); 209 | $('#progress').html(((parseInt($('#domains-checked').html())) * 100 / domainsLength).toFixed(2)); 210 | 211 | if (domains.length) { 212 | requestAvailability(); 213 | } else { 214 | stop(); 215 | } 216 | } 217 | 218 | function writeTable(res, resource) { 219 | if (res.data.is_available) { 220 | $('#available-counter span').html( 221 | (parseInt($('#available-counter span').html()) + 1) 222 | ); 223 | } else if (resource == window.location.hostname + ' ') { 224 | $('#error-counter span').html( 225 | (parseInt($('#error-counter span').html()) + 1) 226 | ); 227 | } else { 228 | $('#unavailable-counter span').html( 229 | (parseInt($('#unavailable-counter span').html()) + 1) 230 | ); 231 | } 232 | 233 | // fix numbering start from 1 if last tr is whois row 234 | if ($('#result-table tbody tr:last').attr('class') == 'result-whois') { 235 | $('#result-table tbody tr:last').remove(); 236 | } 237 | 238 | $('#result-table').append( 239 | '\ 240 | ' + ($('#result-table tbody tr:last:not(.result-whois) td:first').length ? (parseInt($('#result-table tbody tr:last td:first').html()) + 1) : '1') + '\ 241 | ' + res.data.domain + '\ 242 | ' + (res.data.is_available ? 'Available' : 'Unavailable') + '\ 243 | ' + (res.data.domain.match(/([^.]+)\.\w{2,12}(?:\.\w{2})?$/) || [[],[]])[1].length + '\ 244 | ' + (res.message == '' ? '-' : res.message) + '\ 245 | ' + (res.data.whois_server) + '\ 246 | ' + resource + '\ 247 | ' + res.data.execute_time + res.data.execute_time_unit + '\ 248 | ' + (res.data.is_available ? 'Buy Now' : 'www | whois') + '\ 249 | ' 250 | ); 251 | } 252 | 253 | $('#availability-form [type=reset]').click(function(e) { 254 | e.preventDefault(); 255 | 256 | var result = confirm("Are you sure to reset form and delete all result?"); 257 | if (result) { 258 | $('#result-table tbody').html(''); 259 | $(this).closest('form')[0].reset(); 260 | $('#available-counter span').html(0); 261 | $('#unavailable-counter span').html(0); 262 | $('#error-counter span').html(0); 263 | $('#error-counter label').addClass('hidden'); 264 | } 265 | }); 266 | 267 | $('#clear-cache').click(function(e) { 268 | e.preventDefault(); 269 | 270 | var result = confirm("Are you sure to clear all cache?"); 271 | if (result) { 272 | localStorage.clear(); 273 | } 274 | }); 275 | 276 | $("#hide-whois").click(function(e, parameters) { 277 | var nonUI = false; 278 | try { 279 | nonUI = parameters.nonUI; 280 | } catch (e) {} 281 | var checked = nonUI ? !this.checked : this.checked; 282 | 283 | if (checked) { 284 | $('head') 285 | .append(''); 286 | } else { 287 | $('#css-clm-whois').remove(); 288 | } 289 | }); 290 | 291 | $("#hide-exec-time").click(function(e, parameters) { 292 | var nonUI = false; 293 | try { 294 | nonUI = parameters.nonUI; 295 | } catch (e) {} 296 | var checked = nonUI ? !this.checked : this.checked; 297 | 298 | if (checked) { 299 | $('head') 300 | .append(''); 301 | } else { 302 | $('#css-clm-exec-time').remove(); 303 | } 304 | }); 305 | 306 | $("#hide-resource").click(function(e, parameters) { 307 | var nonUI = false; 308 | try { 309 | nonUI = parameters.nonUI; 310 | } catch (e) {} 311 | var checked = nonUI ? !this.checked : this.checked; 312 | 313 | if (checked) { 314 | $('head') 315 | .append(''); 316 | } else { 317 | $('#css-clm-resource').remove(); 318 | } 319 | }); 320 | 321 | $("#hide-unavailable").click(function(e, parameters) { 322 | var nonUI = false; 323 | try { 324 | nonUI = parameters.nonUI; 325 | } catch (e) {} 326 | var checked = nonUI ? !this.checked : this.checked; 327 | 328 | if (checked) { 329 | $('head') 330 | .append(''); 331 | } else { 332 | $('#css-row-unavailable').remove(); 333 | } 334 | }); 335 | 336 | $('#pause').click(function(e) { 337 | e.preventDefault(); 338 | pause(); 339 | }); 340 | 341 | $('#resume').click(function(e) { 342 | e.preventDefault(); 343 | resume(); 344 | }); 345 | 346 | $('#stop').click(function(e) { 347 | e.preventDefault(); 348 | 349 | var result = confirm("Are you sure to stop?"); 350 | if (result) { 351 | stop(); 352 | } 353 | }); 354 | 355 | $('#retry-error').click(function(e) { 356 | e.preventDefault(); 357 | 358 | $('#domains-checked').html(parseInt($('#domains-checked').html()) - domainsError.length); 359 | $('#progress').html(((parseInt($('#domains-checked').html())) * 100 / domainsLength).toFixed(2)); 360 | $('.retry-error').addClass('hidden'); 361 | $('#error-counter span').html(0); 362 | 363 | 364 | domains = [...domainsError, ...domains]; 365 | domainsError = []; 366 | 367 | // if finished or stopped 368 | if (parseInt($('#progress').html()) <= 0) { 369 | domainsLength = domains.length; 370 | 371 | $('#domains-checked').html(0); 372 | $('#domains-length').html(domains.length); 373 | 374 | $('#pause, #stop').removeClass('hidden'); 375 | $('#search, #resume').addClass('hidden'); 376 | 377 | requestAvailability(); 378 | } 379 | }); 380 | 381 | function pause() { 382 | isPaused = true; 383 | 384 | $('#pause').addClass('hidden'); 385 | $('#resume').removeClass('hidden'); 386 | 387 | $('#checking span').html('paused'); 388 | } 389 | 390 | function resume() { 391 | isPaused = false; 392 | 393 | $('#pause').removeClass('hidden'); 394 | $('#resume').addClass('hidden'); 395 | 396 | requestAvailability(); 397 | } 398 | 399 | function stop() { 400 | isPaused = false; 401 | domains = []; 402 | 403 | $('#pause, #resume, #stop').addClass('hidden'); 404 | $('#search').removeClass('hidden'); 405 | 406 | $('#domains-checked, #domains-length, #progress').html(0); 407 | 408 | $('#checking span').html('-'); 409 | } 410 | 411 | $('table').each(function () { 412 | var $table = $(this); 413 | 414 | var $button = $("