1
0
mirror of https://github.com/uetchy/namae.git synced 2025-03-17 04:30:31 +09:00

feat: add Google Play Store

This commit is contained in:
uetchy 2020-08-31 09:44:05 +09:00 committed by uetchy
parent f5f7b51fcb
commit 66ade01c4d
10 changed files with 303 additions and 211 deletions

View File

@ -0,0 +1,37 @@
import { send, sendError, fetch } from '../../../util/http';
import { NowRequest, NowResponse } from '@vercel/node';
export default async function handler(
req: NowRequest,
res: NowResponse
): Promise<void> {
const { query } = req.query;
if (!query || typeof query !== 'string') {
return sendError(res, new Error('No query given'));
}
try {
const responseText = await fetch(
`https://play.google.com/store/search?c=apps&q=${encodeURIComponent(
query
)}`,
'GET'
).then((res) => res.text());
const response = JSON.parse(
responseText.match(
/AF_initDataCallback.+?hash: '5'.+?data:([\w\W]+?), sideChannel/m
)[1]
);
const apps = response[0][1][0][0][0].map((entry) => ({
id: entry[12][0],
name: entry[2],
author: entry[4][0][0][0],
rating: entry[6][0][2][1][1],
url: 'https://play.google.com' + entry[9][4][2],
}));
send(res, { result: apps.slice(0, 10) });
} catch (err) {
sendError(res, err);
}
}

View File

@ -1,52 +1,52 @@
{ {
"title": "Schnapp dir einen guten Namen für deine neue App", "about": "Zusammenfassung",
"available": "Verfügbar",
"blog": "Blog-Artikel",
"community": "Gemeinschaft",
"contributors": "Mitwirkende",
"countryCode": "de",
"description": "Überprüfen Sie sofort die Verfügbarkeit Ihres neuen Anwendungsnamens in allen wichtigen Registern.", "description": "Überprüfen Sie sofort die Verfügbarkeit Ihres neuen Anwendungsnamens in allen wichtigen Registern.",
"gettingStarted": "Fertig werden",
"gettingStartedWithExample": "Untersuche namae",
"issues": "Issues",
"language": "Sprache",
"noResult": "Kein Ergebnis",
"placeholder": "suchen", "placeholder": "suchen",
"pressEnterToSearch": "Drücken Sie die Eingabetaste, um zu suchen",
"providers": { "providers": {
"appStore": "App Store",
"domains": "Domänen", "domains": "Domänen",
"firebase": "Firebase",
"github": "GitHub Organisation", "github": "GitHub Organisation",
"githubSearch": "GitHub Repository",
"gitlab": "GitLab", "gitlab": "GitLab",
"google": "Google-Suche",
"heroku": "Heroku",
"homebrew": "Homebrew",
"instagram": "Instagram",
"jsorg": "js.org",
"linux": "Linux",
"netlify": "Netlify",
"now": "Vercel",
"npm": "npm", "npm": "npm",
"nta": "Firma (JP)",
"ocaml": "OCaml",
"pypi": "PyPI", "pypi": "PyPI",
"rubygems": "RubyGems", "rubygems": "RubyGems",
"rust": "Rust", "rust": "Rust",
"homebrew": "Homebrew",
"linux": "Linux",
"instagram": "Instagram",
"twitter": "Twitter",
"slack": "Slack",
"s3": "AWS S3", "s3": "AWS S3",
"jsorg": "js.org", "slack": "Slack",
"githubSearch": "GitHub Repository",
"appStore": "App Store",
"google": "Google-Suche",
"spectrum": "Spectrum", "spectrum": "Spectrum",
"heroku": "Heroku", "twitter": "Twitter"
"now": "Vercel",
"netlify": "Netlify",
"nta": "Firma (JP)",
"ocaml": "OCaml",
"firebase": "Firebase"
}, },
"uniqueness": {
"high": "Ziemlich einzigartig",
"moderate": "Mäßig einzigartig",
"low": "Typisch",
"description": "UNIQ zeigt, wie eindeutig der Name ist (0 bis 100)"
},
"countryCode": "de",
"try": "Wie wäre es mit?",
"showMore": "Zeig mehr", "showMore": "Zeig mehr",
"noResult": "Kein Ergebnis", "title": "Schnapp dir einen guten Namen für deine neue App",
"gettingStarted": "Fertig werden", "try": "Wie wäre es mit?",
"gettingStartedWithExample": "Untersuche namae",
"pressEnterToSearch": "Drücken Sie die Eingabetaste, um zu suchen",
"available": "Verfügbar",
"unavailable": "Nicht verfügbar", "unavailable": "Nicht verfügbar",
"language": "Sprache", "uniqueness": {
"community": "Gemeinschaft", "description": "UNIQ zeigt, wie eindeutig der Name ist (0 bis 100)",
"about": "Zusammenfassung", "high": "Ziemlich einzigartig",
"contributors": "Mitwirkende", "low": "Typisch",
"issues": "Issues", "moderate": "Mäßig einzigartig"
"blog": "Blog-Artikel" }
} }

View File

@ -1,52 +1,53 @@
{ {
"title": "Grab a slick name for your new app", "about": "About",
"available": "Available",
"blog": "Blog Article",
"community": "Community",
"contributors": "Contributors",
"countryCode": "us",
"description": "Check availability for your new app name ideas across major registries at once.", "description": "Check availability for your new app name ideas across major registries at once.",
"gettingStarted": "Getting Started",
"gettingStartedWithExample": "Try with namae",
"issues": "Issues",
"language": "Language",
"noResult": "No Result",
"placeholder": "search", "placeholder": "search",
"pressEnterToSearch": "Press Enter to search",
"providers": { "providers": {
"appStore": "App Store",
"domains": "Domains", "domains": "Domains",
"firebase": "Firebase",
"github": "GitHub Organization", "github": "GitHub Organization",
"githubSearch": "GitHub Repository",
"gitlab": "GitLab", "gitlab": "GitLab",
"google": "Google Search",
"heroku": "Heroku",
"homebrew": "Homebrew",
"instagram": "Instagram",
"jsorg": "js.org",
"linux": "Linux",
"netlify": "Netlify",
"now": "Vercel",
"npm": "npm", "npm": "npm",
"nta": "Company (JP)",
"ocaml": "OCaml",
"playStore": "Google Play Store",
"pypi": "PyPI", "pypi": "PyPI",
"rubygems": "RubyGems", "rubygems": "RubyGems",
"rust": "Rust", "rust": "Rust",
"homebrew": "Homebrew",
"linux": "Linux",
"instagram": "Instagram",
"twitter": "Twitter",
"slack": "Slack",
"s3": "AWS S3", "s3": "AWS S3",
"jsorg": "js.org", "slack": "Slack",
"githubSearch": "GitHub Repository",
"appStore": "App Store",
"google": "Google Search",
"spectrum": "Spectrum", "spectrum": "Spectrum",
"heroku": "Heroku", "twitter": "Twitter"
"now": "Vercel",
"netlify": "Netlify",
"nta": "Company (JP)",
"ocaml": "OCaml",
"firebase": "Firebase"
}, },
"uniqueness": {
"high": "Pretty unique",
"moderate": "Moderately unique",
"low": "Typical",
"description": "UNIQ shows how unique the name is (0 to 100)"
},
"countryCode": "us",
"try": "How about this?",
"showMore": "show more", "showMore": "show more",
"noResult": "No Result", "title": "Grab a slick name for your new app",
"gettingStarted": "Getting Started", "try": "How about this?",
"gettingStartedWithExample": "Try with namae",
"pressEnterToSearch": "Press Enter to search",
"available": "Available",
"unavailable": "Unavailable", "unavailable": "Unavailable",
"language": "Language", "uniqueness": {
"community": "Community", "description": "UNIQ shows how unique the name is (0 to 100)",
"about": "About", "high": "Pretty unique",
"contributors": "Contributors", "low": "Typical",
"issues": "Issues", "moderate": "Moderately unique"
"blog": "Blog Article" }
} }

View File

@ -1,52 +1,52 @@
{ {
"title": "Trouvez un nom original pour votre nouvelle application", "about": "À propos",
"available": "Disponible",
"blog": "Article de Blog",
"community": "Communauté",
"contributors": "Contributeurs",
"countryCode": "fr",
"description": "Vérifiez immédiatement la disponibilité de vos nouvelles idées de noms d'applications dans les principaux registres.", "description": "Vérifiez immédiatement la disponibilité de vos nouvelles idées de noms d'applications dans les principaux registres.",
"gettingStarted": "Pour commencer",
"gettingStartedWithExample": "Essayez avec namae",
"issues": "Issues",
"language": "Langue",
"noResult": "Pas de résultat",
"placeholder": "rechercher", "placeholder": "rechercher",
"pressEnterToSearch": "Appuyez sur la touche Entrée pour effectuer une recherche",
"providers": { "providers": {
"appStore": "App Store",
"domains": "Domaines", "domains": "Domaines",
"firebase": "Firebase",
"github": "Organisation GitHub", "github": "Organisation GitHub",
"githubSearch": "Dépôt GitHub",
"gitlab": "GitLab", "gitlab": "GitLab",
"google": "Recherche Google",
"heroku": "Heroku",
"homebrew": "Homebrew",
"instagram": "Instagram",
"jsorg": "js.org",
"linux": "Linux",
"netlify": "Netlify",
"now": "Vercel",
"npm": "npm", "npm": "npm",
"nta": "Company (JP)",
"ocaml": "OCaml",
"pypi": "PyPI", "pypi": "PyPI",
"rubygems": "RubyGems", "rubygems": "RubyGems",
"rust": "Rust", "rust": "Rust",
"homebrew": "Homebrew",
"linux": "Linux",
"instagram": "Instagram",
"twitter": "Twitter",
"slack": "Slack",
"s3": "AWS S3", "s3": "AWS S3",
"jsorg": "js.org", "slack": "Slack",
"githubSearch": "Dépôt GitHub",
"appStore": "App Store",
"google": "Recherche Google",
"spectrum": "Spectrum", "spectrum": "Spectrum",
"heroku": "Heroku", "twitter": "Twitter"
"now": "Vercel",
"netlify": "Netlify",
"nta": "Company (JP)",
"ocaml": "OCaml",
"firebase": "Firebase"
}, },
"uniqueness": {
"high": "Plutôt unique",
"moderate": "Modérément unique",
"low": "Typique",
"description": "L'UNIQ indique à quel point le nom est unique (0 à 100)"
},
"countryCode": "fr",
"try": "Que pensez-vous de cela ?",
"showMore": "afficher plus", "showMore": "afficher plus",
"noResult": "Pas de résultat", "title": "Trouvez un nom original pour votre nouvelle application",
"gettingStarted": "Pour commencer", "try": "Que pensez-vous de cela ?",
"gettingStartedWithExample": "Essayez avec namae",
"pressEnterToSearch": "Appuyez sur la touche Entrée pour effectuer une recherche",
"available": "Disponible",
"unavailable": "Indisponible", "unavailable": "Indisponible",
"language": "Langue", "uniqueness": {
"community": "Communauté", "description": "L'UNIQ indique à quel point le nom est unique (0 à 100)",
"about": "À propos", "high": "Plutôt unique",
"contributors": "Contributeurs", "low": "Typique",
"issues": "Issues", "moderate": "Modérément unique"
"blog": "Article de Blog" }
} }

View File

@ -1,52 +1,52 @@
{ {
"title": "唯一無二の名前を見つける", "about": "概要",
"available": "取得できます",
"blog": "ブログ",
"community": "コミュニティ",
"contributors": "貢献者",
"countryCode": "jp",
"description": "namae はあなたのアプリ、ライブラリ、組織に素敵な名前をつけるお手伝いをします。", "description": "namae はあなたのアプリ、ライブラリ、組織に素敵な名前をつけるお手伝いをします。",
"gettingStarted": "はじめる",
"gettingStartedWithExample": "namae を調べる",
"issues": "Issues",
"language": "言語",
"noResult": "該当なし",
"placeholder": "調べる", "placeholder": "調べる",
"pressEnterToSearch": "エンターキーで検索",
"providers": { "providers": {
"appStore": "App Store",
"domains": "ドメイン", "domains": "ドメイン",
"firebase": "Firebase",
"github": "GitHub Organization", "github": "GitHub Organization",
"githubSearch": "GitHub リポジトリ",
"gitlab": "GitLab", "gitlab": "GitLab",
"google": "Google 検索",
"heroku": "Heroku",
"homebrew": "Homebrew",
"instagram": "Instagram",
"jsorg": "js.org",
"linux": "Linux",
"netlify": "Netlify",
"now": "Vercel",
"npm": "npm", "npm": "npm",
"nta": "法人",
"ocaml": "OCaml",
"pypi": "PyPI", "pypi": "PyPI",
"rubygems": "RubyGems", "rubygems": "RubyGems",
"rust": "Rust", "rust": "Rust",
"homebrew": "Homebrew",
"linux": "Linux",
"instagram": "Instagram",
"twitter": "Twitter",
"slack": "Slack",
"s3": "AWS S3", "s3": "AWS S3",
"jsorg": "js.org", "slack": "Slack",
"githubSearch": "GitHub リポジトリ",
"appStore": "App Store",
"google": "Google 検索",
"spectrum": "Spectrum", "spectrum": "Spectrum",
"heroku": "Heroku", "twitter": "Twitter"
"now": "Vercel",
"netlify": "Netlify",
"nta": "法人",
"ocaml": "OCaml",
"firebase": "Firebase"
}, },
"uniqueness": {
"high": "超ユニーク",
"moderate": "そこそこユニーク",
"low": "普通",
"description": "UNIQ は名前がどれくらいユニークかを示しています(0から100)"
},
"countryCode": "jp",
"try": "これはどう?",
"showMore": "さらに表示", "showMore": "さらに表示",
"noResult": "該当なし", "title": "唯一無二の名前を見つける",
"gettingStarted": "はじめる", "try": "これはどう?",
"gettingStartedWithExample": "namae を調べる",
"pressEnterToSearch": "エンターキーで検索",
"available": "取得できます",
"unavailable": "取得できません", "unavailable": "取得できません",
"language": "言語", "uniqueness": {
"community": "コミュニティ", "description": "UNIQ は名前がどれくらいユニークかを示しています(0から100)",
"about": "概要", "high": "超ユニーク",
"contributors": "貢献者", "low": "普通",
"issues": "Issues", "moderate": "そこそこユニーク"
"blog": "ブログ" }
} }

View File

@ -1,52 +1,52 @@
{ {
"title": "为您的新应用取个好听的名字", "about": "关于",
"available": "可获得",
"blog": "博客",
"community": "社区",
"contributors": "贡献者",
"countryCode": "jp",
"description": "namae可让您给您的应用程序、Web服务或组织起一个好名字。", "description": "namae可让您给您的应用程序、Web服务或组织起一个好名字。",
"gettingStarted": "起步",
"gettingStartedWithExample": "试试 namae",
"issues": "Issues",
"language": "语言",
"noResult": "无结果",
"placeholder": "检验", "placeholder": "检验",
"pressEnterToSearch": "按Enter键搜索",
"providers": { "providers": {
"appStore": "App Store",
"domains": "域名", "domains": "域名",
"firebase": "Firebase",
"github": "GitHub 组织", "github": "GitHub 组织",
"githubSearch": "GitHub 仓库",
"gitlab": "GitLab", "gitlab": "GitLab",
"google": "谷歌",
"heroku": "Heroku",
"homebrew": "Homebrew",
"instagram": "Instagram",
"jsorg": "js.org",
"linux": "Linux",
"netlify": "Netlify",
"now": "Vercel",
"npm": "npm", "npm": "npm",
"nta": "在日本的公司",
"ocaml": "OCaml",
"pypi": "PyPI", "pypi": "PyPI",
"rubygems": "RubyGems", "rubygems": "RubyGems",
"rust": "Rust", "rust": "Rust",
"homebrew": "Homebrew",
"linux": "Linux",
"instagram": "Instagram",
"twitter": "推特",
"slack": "Slack",
"s3": "AWS S3", "s3": "AWS S3",
"jsorg": "js.org", "slack": "Slack",
"githubSearch": "GitHub 仓库",
"appStore": "App Store",
"google": "谷歌",
"spectrum": "Spectrum", "spectrum": "Spectrum",
"heroku": "Heroku", "twitter": "推特"
"now": "Vercel",
"netlify": "Netlify",
"nta": "在日本的公司",
"ocaml": "OCaml",
"firebase": "Firebase"
}, },
"uniqueness": {
"high": "超级独特",
"moderate": "有点独特",
"low": "普通",
"description": "UNIQ表示名称的独特性(0-100)"
},
"countryCode": "jp",
"try": "这个呢?",
"showMore": "更多", "showMore": "更多",
"noResult": "无结果", "title": "为您的新应用取个好听的名字",
"gettingStarted": "起步", "try": "这个呢?",
"gettingStartedWithExample": "试试 namae",
"pressEnterToSearch": "按Enter键搜索",
"available": "可获得",
"unavailable": "不可获得", "unavailable": "不可获得",
"language": "语言", "uniqueness": {
"community": "社区", "description": "UNIQ表示名称的独特性(0-100)",
"about": "关于", "high": "超级独特",
"contributors": "贡献者", "low": "普通",
"issues": "Issues", "moderate": "有点独特"
"blog": "博客" }
} }

View File

@ -1,52 +1,52 @@
{ {
"title": "為您的新應用取個好聽的名字", "about": "關於",
"available": "可獲得",
"blog": "博客",
"community": "社區",
"contributors": "貢獻者",
"countryCode": "jp",
"description": "namae可讓您給您的應用程序、Web服務或組織起一個好名字。", "description": "namae可讓您給您的應用程序、Web服務或組織起一個好名字。",
"gettingStarted": "起步",
"gettingStartedWithExample": "試試 namae",
"issues": "Issues",
"language": "語言",
"noResult": "無結果",
"placeholder": "檢驗", "placeholder": "檢驗",
"pressEnterToSearch": "按Enter鍵搜索",
"providers": { "providers": {
"appStore": "App Store",
"domains": "域名", "domains": "域名",
"firebase": "Firebase",
"github": "GitHub 組織", "github": "GitHub 組織",
"githubSearch": "GitHub 倉庫",
"gitlab": "GitLab", "gitlab": "GitLab",
"google": "谷歌",
"heroku": "Heroku",
"homebrew": "Homebrew",
"instagram": "Instagram",
"jsorg": "js.org",
"linux": "Linux",
"netlify": "Netlify",
"now": "Vercel",
"npm": "npm", "npm": "npm",
"nta": "在日本的公司",
"ocaml": "OCaml",
"pypi": "PyPI", "pypi": "PyPI",
"rubygems": "RubyGems", "rubygems": "RubyGems",
"rust": "Rust", "rust": "Rust",
"homebrew": "Homebrew",
"linux": "Linux",
"instagram": "Instagram",
"twitter": "推特",
"slack": "Slack",
"s3": "AWS S3", "s3": "AWS S3",
"jsorg": "js.org", "slack": "Slack",
"githubSearch": "GitHub 倉庫",
"appStore": "App Store",
"google": "谷歌",
"spectrum": "Spectrum", "spectrum": "Spectrum",
"heroku": "Heroku", "twitter": "推特"
"now": "Vercel",
"netlify": "Netlify",
"nta": "在日本的公司",
"ocaml": "OCaml",
"firebase": "Firebase"
}, },
"uniqueness": {
"high": "超級獨特",
"moderate": "有點獨特",
"low": "普通",
"description": "UNIQ表示名稱的獨特性(0-100)"
},
"countryCode": "jp",
"try": "這個呢?",
"showMore": "更多", "showMore": "更多",
"noResult": "無結果", "title": "為您的新應用取個好聽的名字",
"gettingStarted": "起步", "try": "這個呢?",
"gettingStartedWithExample": "試試 namae",
"pressEnterToSearch": "按Enter鍵搜索",
"available": "可獲得",
"unavailable": "不可獲得", "unavailable": "不可獲得",
"language": "語言", "uniqueness": {
"community": "社區", "description": "UNIQ表示名稱的獨特性(0-100)",
"about": "關於", "high": "超級獨特",
"contributors": "貢獻者", "low": "普通",
"issues": "Issues", "moderate": "有點獨特"
"blog": "博客" }
} }

View File

@ -18,6 +18,7 @@ import NetlifyCard from './providers/Netlify';
import NpmCard from './providers/Npm'; import NpmCard from './providers/Npm';
import NtaCard from './providers/Nta'; import NtaCard from './providers/Nta';
import OcamlCard from './providers/Ocaml'; import OcamlCard from './providers/Ocaml';
import PlayStoreCard from './providers/PlayStore';
import PypiCard from './providers/PyPI'; import PypiCard from './providers/PyPI';
import RubyGemsCard from './providers/RubyGems'; import RubyGemsCard from './providers/RubyGems';
import S3Card from './providers/S3'; import S3Card from './providers/S3';
@ -58,6 +59,7 @@ const Index: React.FC<{ query: string }> = ({ query }) => {
<Cards> <Cards>
<GithubSearchCard query={query} /> <GithubSearchCard query={query} />
<AppStoreCard query={query} /> <AppStoreCard query={query} />
<PlayStoreCard query={query} />
{language === 'ja' ? <NtaCard query={query} /> : null} {language === 'ja' ? <NtaCard query={query} /> : null}
</Cards> </Cards>
</> </>

View File

@ -0,0 +1,52 @@
import useFetch from 'fetch-suspense';
import React from 'react';
import { useTranslation } from 'react-i18next';
import { FaInfoCircle } from 'react-icons/fa';
import { IoMdAppstore } from 'react-icons/io';
import { Card, Result } from '../core';
const Search: React.FC<{ query: string }> = ({ query }) => {
const { t } = useTranslation();
const response = useFetch(
`/api/services/playstore/${encodeURIComponent(query)}}`
) as {
result: Array<{
id: string;
name: string;
author: string;
rating: number;
url: string;
}>;
};
const apps = response.result;
return (
<>
{apps && apps.length > 0 ? (
apps.map((app) => (
<Result
title={app.name}
message={`Rating: ${app.rating}`}
link={app.url}
icon={<IoMdAppstore />}
key={app.id}
/>
))
) : (
<Result title={t('noResult')} icon={<FaInfoCircle />} />
)}
</>
);
};
const PlayStoreCard: React.FC<{ query: string }> = ({ query }) => {
const { t } = useTranslation();
return (
<Card title={t('providers.playStore')}>
<Search query={query} />
</Card>
);
};
export default PlayStoreCard;

View File

@ -5,7 +5,7 @@ import XHR from 'i18next-xhr-backend';
import LanguageDetector from 'i18next-browser-languagedetector'; import LanguageDetector from 'i18next-browser-languagedetector';
import { initReactI18next } from 'react-i18next'; import { initReactI18next } from 'react-i18next';
const TRANSLATION_VERSION = '3'; const TRANSLATION_VERSION = '4';
i18n i18n
.use(Backend) .use(Backend)