Spis treści

Deno wyszukuje emoji

💻 👩‍💻 🦕 🔎 😀

Jak znaleźć emoji z terminala

Postanowiłam napisać małe narządko do wyszukiwania emoji z wiersza poleceń. Czasem potrzebuję odpowiedniego obrazka podczas pisania testu na bloga albo chcę sprawdzić, czy istnieje emoji na jakąś okazję. Nie chcę w tym celu odpalać przeglądarki. Pomyślałam więc sobie, że zrobię to używając Deno.

Wyszukiwarka emoji

W moim podejściu - jak zwykle i z konieczności “na szybko” - parsuję stronę html zwróconą przez zapytanie HTTP na https://emojipedia.org. Okazuje się, że wyszukiwarka emoji akceptuje zwykłe zapytanie GET z parametrem q: aby więc zapytać o emoji związane z domem, wystarczy wysłać https://emojipedia.org/search/?q=house.

Parsowanie

Obejrzałam źródło strony zwróconej przez wyszukiwarkę. Sprawdziłam, że wystarczy znaleźć element listy <ol class="search-results"> i przeszukać jej elementy, zawierające ikonę w elemencie <span class="emoji"> oraz opis w elemencie <p>:

/emojipedia-search.png

Moduł deno_dom

Do parsowania używam modułu https://deno.land/x/deno_dom/deno-dom-wasm.ts (strona deno_dom na deno.land):

1
2
3
4
5
6
import {
  DOMParser,
  Element,
  HTMLDocument,
  HTMLCollection }
from "https://deno.land/x/deno_dom/deno-dom-wasm.ts";

Do parsowania źródła strony użyję interfejsu DOMParser, który jest częścią WebAPI.

Żądana fraza w argumentach programu

Wyobrażam sobie, że mój program wczyta szukaną frazę jako argument(y) wywołania, więc na przykład mogę wywołać go tak:

1
deno run --allow-net main.ts house

bądź tak:

1
deno run --allow-net main.ts woman tech

W programie odczytam argumenty wywołania ze zmiennej Deno.args i skonstruuję na tej podstawie URL:

1
2
const BASE_URL = "https://emojipedia.org/search/?q="
const url = BASE_URL + Deno.args.join("+")

Pobranie źródła strony

Najpierw muszę mieć jednak źródło strony.

Użyję API fetch, w funkcji fetchFile, która zwróci Promise<string>:

1
2
3
4
5
6
7
const fetchFile = async (url:string): Promise<string> => {
const fresp = await fetch(url)
  if (fresp.ok) {
    return fresp.text()
  } else
    throw new Error("Something wrong")
}

Zdefiniowanie typu Emo

Chcę wydłubać ikonę oraz jej opis, definiuję więc prosty “typ” Emo:

1
2
3
4
5
type Emo = {
e: string,
desc: string,
}

Parsowanie treści strony - lista Emo

Piszę funkcję getEmos, która zawiera logikę parsowania treści strony (zwróconej przez fetchFile) - ta funkcja zwróci (być może pustą) listę Emo:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
const mkDOM = (s: string): HTMLDocument|null => {
return new DOMParser().parseFromString(s, 'text/html')
}

function getEmos(content: string): Emo[] {
const d = mkDOM(content)
const getOl = (d: HTMLDocument) =>
d.getElementsByClassName('search-results')[0]
const itemToEmo = (li: Element) =>
({e: emostr(li), desc: emodesc(li)})
const emostr = (el: Element) =>
el.getElementsByClassName('emoji')[0].textContent
const emodesc = (el: Element) =>
el.getElementsByTagName('p')[0].textContent

return d ?
new Array(...getOl(d).children).map(itemToEmo) :
[]
}

  • mkDOM: krok pierwszy to uzyskanie modelu obiektowego strony (DOM) - tutaj właśnie, w funkcji mkDOM, używam interfejsu DOMParser
  • getOl: teraz wyszukuję elementu ol z klasą search-results (z jej “dzieci”, elementów li, tworzę listę, której elementy mapuję na obiekty Emo
  • emostr: wewnątrz li szukam tekstowej zawartości elementu span z klasą ‘emoji’ - to właśnie emoji, którego szukam
  • emodesc: wewnątrz li szukam elementu p - to opis emoji
  • itemToEmo: funkcja mapująca li na Emo, tworzy prosty obiekt Emo wywołując emostr i emmodesc

Pewnie da się to zrobić jakoś bardziej inteligentnie, ale rozbiłam to na małe kroczki, żeby kod był czytelny.

Program główny

Główny program zajmuje teraz dwa wiersze kodu:

1
2
3
4
5
6
7
8
9
const emoPrinter = (emo: Emo) => {
  console.log(`${emo.e} - ${emo.desc}`)
}

if (import.meta.main) {
  const url = BASE_URL + Deno.args.join("+")
  getEmos(await fetchFile(url)).map(emoPrinter)
}

Rezultat:

Oto rezultat działania programu po wywołaniu:

1
deno run --allow-net  main.ts woman

/emojipedia-result.png

Tutaj wyjście programu na konsolę:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
[karma@tpd|~/d/j/emo]  (main) λ deno run --allow-net  main.ts woman
👩 - Emoji Meaning A woman of adult age. Differentiated from the girl emoji by the lack of pig-tails in her hair. …
👵 - Emoji Meaning An elderly woman with gray (grey) hair, and visible wrinkles. Wears glasses on some platforms. …
🤰 - Emoji Meaning A pregnant woman, intended to complete the family emoji set. Sometimes used in jest to represent feeling full after…
👡 - Emoji Meaning A sandal worn by a woman in summer, spring, or other weather that suits open-toed footwear. Has a heel at the back…
👚 - Emoji Meaning A blouse worn by women in a neat-casual setting. Shown in pink on Apple devices, yellow on Android, and purple on…
🙅‍♀️ - Emoji Meaning A woman with arms crossed forming an ‘X’ to indicate ‘no’ or ‘no good’. This motion is used on the TV game show Deal or No…
👩‍🚀 - Emoji Meaning A female astronaut or cosmonaut shown wearing a space suit and helmet. The Woman Astronaut emoji is a ZWJ…
👩‍💻 - Emoji Meaning A woman behind a computer screen, working in the field of technology. See also: 👨‍💻 Male Technologist The…
🚶‍♀️ - Emoji Meaning The female version of the 🚶 Pedestrian emoji. The Woman Walking emoji is a ZWJ sequence combining 🚶 Person…
🤦‍♀️ - Emoji Meaning The Woman Facepalming emoji is a ZWJ sequence combining 🤦 Person Facepalming, ‍ Zero Width Joiner and ♀️…
🤷‍♀️ - Emoji Meaning The Woman Shrugging emoji is a ZWJ sequence combining 🤷 Person Shrugging, ‍ Zero Width Joiner and ♀️ Female…
🤸‍♀️ - Emoji Meaning The Woman Cartwheeling emoji is a ZWJ sequence combining 🤸 Person Cartwheeling, ‍ Zero Width Joiner and ♀️…
🧏‍♀️ - Emoji Meaning The Deaf Woman emoji is a ZWJ sequence combining 🧏 Deaf Person, ‍ Zero Width Joiner and ♀️ Female Sign. …
🦹‍♀️ - Emoji Meaning The Woman Supervillain emoji is a ZWJ sequence combining 🦹 Supervillain, ‍ Zero Width Joiner and ♀️ Female…
👩‍🌾 - Emoji Meaning The Woman Farmer emoji is a ZWJ sequence combining 👩 Woman, ‍ Zero Width Joiner and 🌾 Sheaf of Rice. …
👩‍🚒 - Emoji Meaning The Woman Firefighter emoji is a ZWJ sequence combining 👩 Woman, ‍ Zero Width Joiner and 🚒 Fire Engine. …
🏃‍♀️ - Emoji Meaning The female version of the 🏃 Runner emoji. The Woman Running emoji is a ZWJ sequence combining 🏃 Person…
🏄‍♀️ - Emoji Meaning The female version of the 🏄 Surfer emoji. The Woman Surfing emoji is a ZWJ sequence combining 🏄 Person…
🚴‍♀️ - Emoji Meaning The female version of the 🚴 Bicyclist emoji. The Woman Biking emoji is a ZWJ sequence combining 🚴 Person…
🧎‍♀️ - Emoji Meaning The Woman Kneeling emoji is a ZWJ sequence combining 🧎 Person Kneeling, ‍ Zero Width Joiner and ♀️ Female…

Github

Wrzucone na githuba ku pamięci: deno emoji termial search

Może Cię zainteresować