Socket
Socket
Sign inDemoInstall

google-that

Package Overview
Dependencies
47
Maintainers
1
Versions
4
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

Comparing version 0.0.1 to 0.0.2

439

dist/index.js

@@ -7,5 +7,5 @@ #!/usr/bin/env node

import enquirer from "enquirer";
import { ResultTypes } from "google-sr";
import { ResultTypes as ResultTypes2 } from "google-sr";
import prettyMilliseconds from "pretty-ms";
import boxen from "boxen";
import boxen2 from "boxen";
import fsPromises from "fs/promises";

@@ -15,4 +15,7 @@ import path from "path";

import slugify from "slugify";
import { stripIndents } from "common-tags";
import { stripIndents as stripIndents2 } from "common-tags";
// src/constants.ts
var estimateOffset = 1e3;
// src/query.ts

@@ -24,6 +27,26 @@ import cliProgress from "cli-progress";

var log = {
info: (...args) => console.log(`${c.blue.bold("[INFO]")} @ ${(/* @__PURE__ */ new Date()).toLocaleTimeString()} ${c.yellow(">")}`, ...args.map((s) => c.blueBright(s))),
success: (...args) => console.log(`${c.green.bold("[SUCCESS]")} @ ${(/* @__PURE__ */ new Date()).toLocaleTimeString()} ${c.yellow(">")}`, ...args.map((s) => c.greenBright(s))),
warn: (...args) => console.log(`${c.yellowBright.bold("[WARN]")} @ ${(/* @__PURE__ */ new Date()).toLocaleTimeString()} ${c.yellow(">")}`, ...args.map((s) => c.yellowBright(s))),
error: (...args) => console.log(`${c.red.bold("[ERROR]")} @ ${(/* @__PURE__ */ new Date()).toLocaleTimeString()} ${c.yellow(">")}`, ...args.map((s) => c.redBright(s)))
info: (...args) => console.log(
`${c.blue.bold("[INFO]")} @ ${(/* @__PURE__ */ new Date()).toLocaleTimeString()} ${c.yellow(
">"
)}`,
...args.map((s) => c.blueBright(s))
),
success: (...args) => console.log(
`${c.green.bold(
"[SUCCESS]"
)} @ ${(/* @__PURE__ */ new Date()).toLocaleTimeString()} ${c.yellow(">")}`,
...args.map((s) => c.greenBright(s))
),
warn: (...args) => console.log(
`${c.yellowBright.bold(
"[WARN]"
)} @ ${(/* @__PURE__ */ new Date()).toLocaleTimeString()} ${c.yellow(">")}`,
...args.map((s) => c.yellowBright(s))
),
error: (...args) => console.log(
`${c.red.bold("[ERROR]")} @ ${(/* @__PURE__ */ new Date()).toLocaleTimeString()} ${c.yellow(
">"
)}`,
...args.map((s) => c.redBright(s))
)
};

@@ -67,8 +90,271 @@ var getTimePerEachPage = /* @__PURE__ */ __name((noOfPages) => noOfPages > 10 ? 5e3 : 2e3, "getTimePerEachPage");

doSearch(page) {
return search({ query: this.query, page: pageToGoogleQueryPage(page) });
return search({ query: this.query, page: pageToGoogleQueryPage(page), filterResults: this.inputOptions.searchType });
}
};
// src/formatters.ts
import boxen from "boxen";
import { html, stripIndents, stripIndent } from "common-tags";
import { ResultTypes } from "google-sr";
function getJSONFormat(results) {
return JSON.stringify(results, null, 4);
}
__name(getJSONFormat, "getJSONFormat");
function getTXTFormat(results) {
let startTxt = stripIndents(html)`
${results.map(
(page, i) => html`
==============${i + 1}/${results.length}==================
${page.map((data) => {
switch (data.type) {
case ResultTypes.SearchResult:
return boxen(
stripIndents`
๐Ÿ” ${data.title}
๐Ÿ”— ${data.link}
๐Ÿ“ ${data.description}
`,
{ padding: 1 }
);
case ResultTypes.TranslateResult:
return boxen(
stripIndents`
๐ŸŒ ${data.source.language} => ๐ŸŒ ${data.translation.language}
๐Ÿ“œ ${data.source.text} => โœจ ${data.translation.text} ${data.translation.pronunciation ? `(\u{1F50A} ${data.translation.pronunciation})` : ""}
`,
{ padding: 1 }
);
case ResultTypes.DictionaryResult:
return boxen(
stripIndents(html)`
๐Ÿ“š ${data.word}
๐Ÿ”‰ ${data.phonetic}
${data.audio ? `\u{1F50A} ${data.audio}` : ""}
${data.definitions.map(
(definition) => stripIndent`
๐Ÿ“– ${definition[0]}
โ†ณ ${definition[1]}
`
)}
`,
{ padding: 1 }
);
case ResultTypes.TimeResult:
return boxen(
stripIndents(html)`
๐Ÿ“ ${data.location}
โฐ ${data.time}
๐Ÿ—ฃ๏ธ ${data.timeInWords}
`,
{ padding: 1 }
);
case ResultTypes.CurrencyResult:
return boxen(
stripIndents(html)`
๐Ÿ’ฐ ${data.from} => ๐Ÿ’ธ ${data.to}
`,
{ padding: 1 }
);
default:
return `Unsupported`;
}
})}
`
)}
`;
return startTxt;
}
__name(getTXTFormat, "getTXTFormat");
function getHTMLFormat(results, query, total) {
const pages = new Array(results.length).fill(null).map((_m, i) => i + 1);
return html`
<html>
<head>
<!-- Autogenerated by google-that (npm) on ${(/* @__PURE__ */ new Date()).toDateString()} -->
<title>Autogenerated query | ${query}</title>
<style>
body {
height: 100vh;
margin: 3;
background-color: #f0f0f0;
font-family: Arial, sans-serif;
}
input {
width: 100%;
padding: 10px;
border: 1px solid #ccc;
border-radius: 5px;
font-size: 16px;
margin-bottom: 20px;
box-sizing: border-box;
}
li a {
text-decoration: none;
color: #333;
}
.searchResult {
border: 1px solid #ccc;
padding: 10px;
margin: 10px 0;
border-radius: 10px;
background-color: rgb(216, 245, 245);
display: flex;
flex-direction: column;
gap: 2px;
}
.translateResult {
align-items: center;
background-color: rgb(243, 255, 174);
}
.dictionaryResult {
background-color: rgb(189, 174, 255);
}
.currencyResult {
background-color: rgb(241, 174, 255);
}
.timeResult {
background-color: rgb(186, 202, 255);
}
.ulReset {
list-style: none;
padding: 0;
margin: 0;
}
.hero {
display: flex;
gap: 3px;
align-items: center;
justify-content: center;
flex-direction: column;
}
.pagination {
display: flex;
gap: 3px;
align-items: center;
justify-content: center;
font-size: large;
}
</style>
</head>
<body>
<div class="hero">
<input value="${query}" name="query" readonly />
<h5>Generated on ${(/* @__PURE__ */ new Date()).toDateString()}</h5>
<h4>${total} results across ${results.length} pages</h4>
<div class="pagination">
<span><</span>
${pages.map((pageNo) => `<a href="#page${pageNo}">${pageNo}</a>`)}
<span>></span>
</div>
</div>
<hr />
${results.map(
(page, i) => html(stripIndents)`
<ul id="page-${i + 1}" class="ulReset">
<h3 id="page${i + 1}">Page ${i + 1} ${results.length > 1 ? `of ${results.length} pages` : ""} | ${page.length} entries for this page</h3>
${page.map((result) => {
switch (result.type) {
case ResultTypes.SearchResult:
return html`
<li class="searchResult">
<h1>${result.title}</h1>
<a href="${result.link}">${result.link}</a>
<p>${result.description}</p>
</li>
`;
case ResultTypes.TranslateResult:
return html`
<li class="searchResult translateResult">
<h3>
${result.source.text}
</h3>
โฌ‡๏ธ
<div>
<h3>
${result.translation.text}
</h3>
${result.translation.pronunciation ? `<h5>\u{1F4E2} ${result.translation.pronunciation}</h5>` : ""}
</div>
</li>
`;
case ResultTypes.DictionaryResult:
return html`
<li class="searchResult dictionaryResult">
<h1>${result.word}</h1>
<p>${result.phonetic}</p>
<audio controls>
<source src="${result.audio}" type="audio/mp3">
</audio>
<ul>
${result.definitions.map((definition) => `
<li>
<h5>${definition[0]}</h5>
<p>${definition[1]}</p>
</li>
`)}
</ul>
</li>
`;
case ResultTypes.CurrencyResult:
return html`
<li class="searchResult currencyResult">
<h3>${result.formula}</h3>
</li>
`;
case ResultTypes.TimeResult:
return html`
<li class="searchResult timeResult">
<h3>${result.location}</h3>
<p>${result.time}</p>
<p>${result.timeInWords}</p>
</li>
`;
default:
return "Unsupported";
}
})}
</ul>
`
)}
<hr />
<div class="pagination">
<span><</span>
${pages.map((pageNo) => `<a href="#page${pageNo}">${pageNo}</a>`)}
<span>></span>
</div>
</body>
</html>
`;
}
__name(getHTMLFormat, "getHTMLFormat");
// src/index.ts
async function main() {
console.clear();
console.log(
boxen2(
c2.yellow(stripIndents2`
๐ŸŽจ This CLI tool may sprinkle emojis for a touch of flair.
If your terminal doesn't support emojis, they might appear as question marks.
No worries though! The functionality of the CLI tool remains intact.
If you spot this rocket emoji, you're all set for takeoff! ๐Ÿš€
`),
{ padding: 1 }
)
);
const queryInput = await enquirer.prompt([

@@ -99,9 +385,9 @@ {

message: "Organic search",
name: ResultTypes.SearchResult,
name: ResultTypes2.SearchResult,
enabled: true
},
{ message: "Translate Result", name: ResultTypes.TranslateResult },
{ message: "Dictionary Result", name: ResultTypes.DictionaryResult },
{ message: "Current time search", name: ResultTypes.TimeResult },
{ message: "Currency conversions", name: ResultTypes.CurrencyResult }
{ message: "Translate Result", name: ResultTypes2.TranslateResult },
{ message: "Dictionary Result", name: ResultTypes2.DictionaryResult },
{ message: "Current time search", name: ResultTypes2.TimeResult },
{ message: "Currency conversions", name: ResultTypes2.CurrencyResult }
],

@@ -136,20 +422,30 @@ required: true,

if (!queries.length)
return log.error(`Query/Queries option is required`);
return log.error(`Query option is required`);
if (pages <= 0)
return log.error(`Pages must be greater than 0`);
return log.error(`Amount of pages must be greater than 0`);
if (/[\\/:*?"<>|]/.test(savePath) || savePath.includes(" "))
return log.error(
`Invalid file name. File names cannot contain spaces or the following characters: \\ / : * ? " < > |`
);
if (pages > 10)
log.warn(
`Fetching more than 10 pages per query, will fetch in delayed chunks to prevent rate limit`
`Fetching more than 10 pages per query. To prevent rate limits, the fetching will be done in delayed chunks.`
);
const perPage = getTimePerEachPage(pages);
const totalTime = perPage * pages * queries.length;
log.info(
`It will take ${prettyMilliseconds(totalTime)} with ${prettyMilliseconds(
perPage
)} for ${pages} pages with ${queries.length} queries / query`
const perQuery = perPage * pages;
const estimatedTime = perQuery * queries.length + estimateOffset;
console.log(
boxen2(
stripIndents2`
โฐ ETA: ${c2.green(prettyMilliseconds(estimatedTime))}
๐Ÿ“ƒ Per page: ${c2.green(prettyMilliseconds(perPage))}
๐Ÿ“– Pages: ${pages} pages
โ“ ${c2.yellow(String(queries.length))} ${queries.length > 2 ? "queries" : "query"}
๐Ÿ’ญ ${c2.italic.yellowBright(queries.join(","))}
`,
{ padding: 2, margin: 1 }
)
);
log.info(
`Searching for ${queries.length > 1 ? `multiple queries (${queries.length}) [${queries}]` : `query on "${queries[0]}"`}`
);
const downloads = [];
const start = Date.now();
for (const query of queries) {

@@ -160,31 +456,94 @@ log.info(

const searchQuery = new SearchQuery(query, queryInput, perPage);
const searchStart = Date.now();
try {
const results = await searchQuery.search();
log.success(`Retrieved ${results.length} result(s)`);
const saveAt = savePath.replace("%query%", slugify(query, { lower: false })).replace("%format%", resultType.toLowerCase());
const pathName = path.join(process.cwd(), saveAt);
log.info(`Saving results for query "${query}" to ${pathName}`);
if (!results.length) {
log.warn(`Query "${query}" did not return any results (likely error logs are above), skipping`);
continue;
}
let saveData;
const totalResults = results.reduce((a, b) => a.concat(b)).length;
switch (resultType) {
case "JSON":
await fsPromises.writeFile(pathName, JSON.stringify(results, null, 4));
saveData = getJSONFormat(results);
break;
case "TXT":
saveData = getTXTFormat(results);
break;
case "HTML":
saveData = getHTMLFormat(results, query, totalResults);
break;
default:
saveData = "Unsupported TYPE";
}
const totalResults = results.reduce((a, b) => a.concat(b)).length;
await fsPromises.writeFile(pathName, saveData);
const searchEnd = Date.now() - searchStart;
log.info(
`Saved results for query "${query}" to ${pathName} took ${prettyMilliseconds(searchEnd)}`
);
downloads.push({ query, pathName, total: totalResults });
} catch {
log.error(`Failed to search query`);
log.error(`Failed to search query "${query}"`);
}
}
await delay(2e3);
const end = Date.now() - start;
console.clear();
console.log(boxen(stripIndents`
โœ… google-that download finished.
โญ Star us here: ${c2.blue("https://github.com/typicalninja/google-sr")}
๐Ÿ“ฆ Github here: ${c2.blue("https://github.com/typicalninja/google-sr/tree/master/packages/cli")}
${c2.bgCyanBright.underline("Downloads")}
โ†งโ†งโ†งโ†ง
${downloads.map((download) => `\u2192 ${c2.bold.magenta(path.basename(download.pathName))} ("${c2.italic.yellow(download.query)}" [${download.total} results])`).join("\n")}
`));
if (!downloads.length) {
return console.log(
boxen2(
stripIndents2`
โŒ ${c2.red("google-that process finished. [FAILED]")}
๐Ÿ•ฐ๏ธ Finished in ${c2.blue(
prettyMilliseconds(end)
)} with a deviation of ${c2.yellow(
prettyMilliseconds(end - estimatedTime)
)} from estimated time (${prettyMilliseconds(estimatedTime)})
โญ Star us here: ${c2.blue("https://github.com/typicalninja/google-sr")}
๐Ÿ“ฆ Github here: ${c2.blue(
"https://github.com/typicalninja/google-sr/tree/master/packages/cli"
)}
๐Ÿ“š Documentation: ${c2.blue("https://typicalninja.github.io/google-sr/")}
${c2.cyanBright.underline("Downloads")}
โ†งโ†งโ†งโ†ง
${c2.red("Failed")}
`,
{ padding: 1, margin: 1 }
)
);
} else {
console.log(
boxen2(
stripIndents2`
โœ… ${c2.green("google-that process finished. [SUCCESS]")}
๐Ÿ•ฐ๏ธ Finished in ${c2.blue(
prettyMilliseconds(end)
)} with a deviation of ${c2.yellow(
prettyMilliseconds(end - estimatedTime)
)} from estimated time (${prettyMilliseconds(estimatedTime)})
โญ Star us here: ${c2.blue("https://github.com/typicalninja/google-sr")}
๐Ÿ“ฆ Github here: ${c2.blue(
"https://github.com/typicalninja/google-sr/tree/master/packages/cli"
)}
๐Ÿ“š Documentation: ${c2.blue("https://typicalninja.github.io/google-sr/")}
${c2.cyanBright.underline("Downloads")}
โ†งโ†งโ†งโ†ง
${downloads.map(
(download) => `\u2192 ${c2.bold.grey(
path.basename(download.pathName)
)} ("${c2.italic.yellow(download.query)}" [${c2.green(
String(download.total)
)} results across ${pages} page${pages > 1 ? "s" : ""}])`
).join("\n")}
`,
{ padding: 1, margin: 1 }
)
);
}
}

@@ -191,0 +550,0 @@ __name(main, "main");

6

package.json
{
"name": "google-that",
"version": "0.0.1",
"description": "CLI tool to scrape google search results without a api key [HOLDING]",
"version": "0.0.2",
"description": "CLI tool to scrape google search results without a api key",
"repository": "typicalninja/google-sr",
"homepage": "https://typicalninja.github.io/google-sr/",
"exports": "./dist/index.js",

@@ -6,0 +8,0 @@ "bin": "./dist/index.js",

# google-that
CLI tool to scrape google search results without a api key ๐Ÿš€.
CLI tool to scrape google search results without an api key ๐Ÿš€.
# Holding package
## Install ๐Ÿ“ฆ
Until the api is finalized this published package for npm is a name holding package
To get started, you can install **google-that** using your preferred package manager:
> We suggest you install the package as a global module
```bash
# npm
npm install -g google-sr
# pnpm
pnpm add -g google-sr
# yarn
yarn add -g google-sr
```
# Usage
If installation succeeded you can proceed to this step, run the following command in a **NEW** terminal window without any arguments
```bash
google-that
```
this should come up with bunch of question answer these to use the tool.
# Related projects
* [google-sr](https://github.com/typicalninja/google-sr) - **google-that** project is a wrapper around google-sr
* [google-sr](https://github.com/typicalninja/google-sr) - This project is a wrapper around google-sr

@@ -14,0 +44,0 @@ # Disclaimer

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with โšก๏ธ by Socket Inc