(단말기) 창에 있는 저 BLÅHAJ는 얼마인가요?

IKEA’s toy BLÅHAJ shark은 지난 몇 년 동안 beloved Internet icon이 되었습니다. 정보를 얻기 위해 약간의 Perl을 작성하고 코드를 실행하는 터미널에서 바로 귀여운 그림을 표시하는 것이 귀엽다고 생각했습니다. 아마도 이것은 당신의 빠른 웹 클라이언트에 대한 몇 가지 아이디어를 줄 것입니다. 물론 curl , jq GNU coreutils base64 과 같은 개별 명령줄 유틸리티의 파이프라인을 사용하여 이러한 모든 작업을 수행할 수 있습니다. 그러나 이러한 예는 Perl as the glue 에 중점을 둡니다.

경고: dodgy API가 앞서 있습니다.



IKEA 제품 정보를 쿼리하기 위해 공개적으로 문서화되고 지원되는 공식 API를 찾지 못했지만 others have 회사의 웹 사이트AJAX 요청을 분해하여 대신 사용할 수 있습니다. 대안은 IKEA 웹 사이트를 직접 스크랩하는 것입니다. 가능하지만 디자인이 변경되면 더 지루하고 실패하기 쉽습니다. 비공식 API도 신뢰할 수 없지만 더 단순한 클라이언트 코드는 오류가 표면화될 경우 변경하기가 더 쉽습니다.

모졸리셔스에 들어가다



내 원래 목표는 single line issued to the perl command 에서 이 작업을 수행하는 것이었고 운 좋게도 Mojolicious framework’s ojo module 은 이러한 작업에 적합합니다. -Mojo 명령에 perl 스위치를 추가하면 빠른 웹 응용 프로그램을 시작하거나 많은 절차 없이 웹 요청을 만들고 해석하기 위한 12개 이상의 빠른 단일 문자 기능을 사용할 수 있습니다. 다음은 ojo’s g function을 사용하여 HTTP GET을 수행하고 응답 본문에서 터미널로 JSON을 표시하는 BLÅHAJ 제품 정보에 대한 IKEA API에 대한 한 줄 요청의 시작입니다.

perl -Mojo -E 'say g("https://sik.search.blue.cdtapps.com/us/en/search-result-page",
  form => {types => "PRODUCT", q => "BLÅHAJ"})->body'


이것은 현재 2,400줄 이상의 데이터를 반환하므로 이를 읽은 후 응답 본문 JSON을 Perl data structure으로 변환하고 ojo’s r function을 사용하여 주요 제품 정보만 덤프합니다.

perl -Mojo -E 'say r g("https://sik.search.blue.cdtapps.com/us/en/search-result-page",
  form => {types => "PRODUCT", q => "BLÅHAJ"})
  ->json->{searchResultPage}{products}{main}{items}[0]{product}'



{
  "availability" => [],
  "breathTaking" => bless( do{\(my $o = 0)}, 'JSON::PP::Boolean' ),
  "colors" => [
    {
      "hex" => "0058a3",
      "id" => 10007,
      "name" => "blue"
    },
    {
      "hex" => "ffffff",
      "id" => 10156,
      "name" => "white"
    }
  ],
  "contextualImageUrl" => "https://www.ikea.com/us/en/images/products/blahaj-soft-toy-shark__0877371_pe633608_s5.jpg",
  "currencyCode" => "USD",
  "discount" => "",
  "features" => [],
  "gprDescription" => {
    "numberOfVariants" => 0,
    "variants" => []
  },
  "id" => 90373590,
  "itemMeasureReferenceText" => "39 \x{bc} \"",
  "itemNo" => 90373590,
  "itemNoGlobal" => 30373588,
  "itemType" => "ART",
  "lastChance" => $VAR1->{"breathTaking"},
  "mainImageAlt" => "BL\x{c5}HAJ Soft toy, shark, 39 \x{bc} \"",
  "mainImageUrl" => "https://www.ikea.com/us/en/images/products/blahaj-soft-toy-shark__0710175_pe727378_s5.jpg",
  "name" => "BL\x{c5}HAJ",
  "onlineSellable" => bless( do{\(my $o = 1)}, 'JSON::PP::Boolean' ),
  "pipUrl" => "https://www.ikea.com/us/en/p/blahaj-soft-toy-shark-90373590/",
  "price" => {
    "decimals" => 99,
    "isRegularCurrency" => $VAR1->{"breathTaking"},
    "prefix" => "\$",
    "separator" => ".",
    "suffix" => "",
    "wholeNumber" => 19
  },
  "priceNumeral" => "19.99",
  "quickFacts" => [],
  "tag" => "NONE",
  "typeName" => "Soft toy"
}


가격만 원하면 다음을 수행할 수 있습니다.

$ perl -Mojo -E 'say g("https://sik.search.blue.cdtapps.com/us/en/search-result-page",
  form => {types => "PRODUCT", q => "BLÅHAJ"})->json
  ->{searchResultPage}{products}{main}{items}[0]{product}
  ->@{qw(currencyCode priceNumeral)}'
USD19.99


->@{qw(currencyCode priceNumeral)}는 끝으로 postfix reference slicing syntax을 도입하여 experimentally in Perl v5.20made official in v5.24을 사용한다. 이전 버전perl을 사용하는 경우 다음과 같이 말할 수 있습니다.

$ perl -Mojo -E 'say @{g("https://sik.search.blue.cdtapps.com/us/en/search-result-page",
  form => {types => "PRODUCT", q => "BLÅHAJ"})->json
  ->{searchResultPage}{products}{main}{items}[0]{product}}{qw(currencyCode priceNumeral)}'
USD19.99


하지만 저는 왼쪽에서 오른쪽으로 읽는 것이 더 쉽기 때문에 전자를 선호합니다.

하지만 난 미국에 있지 않아! 내 기본 통화는 어디에 있습니까?



위의 URL에서 ” us/en ”를 바꾸거나 다른 사용자의 로케일 간에 이식할 수 있다고 판단되면 Perl v5.8.5에 추가된 core I18N::LangTags::Detect module을 사용할 수 있습니다. 하지만 이것은 정말 스트레칭입니다the definition of ”one-liner,”.

$ LANG=de_DE.UTF-8 perl -Mojo -MI18N::LangTags::Detect \
  -E 'my @lang = (split /-/, I18N::LangTags::Detect::detect)[1,0];
  say g("https://sik.search.blue.cdtapps.com/"
  . join("/", @lang == 2 ? @lang : ("us", "en"))
  . "/search-result-page",
  form => {types => "PRODUCT", q => "BLÅHAJ"})->json
  ->{searchResultPage}{products}{main}{items}[0]{product}
  ->@{qw(currencyCode priceNumeral)}'
EUR27.99


윈도우 드레싱



숫자를 껴안는 것은 상상하기 어렵지만 다행스럽게도 위에서 반환된 제품 정보는 mainImageUrl 키의 JPEG 파일에 대한 링크입니다. 파일 또는 iTerm2 can display images inline 인코딩 데이터에서 내가 가장 좋아하는 터미널 앱Base64이므로 추가 HTTP 요청 및 encoding from the core MIME::Base64 module을 추가하면 다음이 생성됩니다.

perl -Mojo -MMIME::Base64 \
  -E 'say "\c[]1337;File=inline=1;width=100%:",
  encode_base64(g(g("https://sik.search.blue.cdtapps.com/us/en/search-result-page",
  form => {types => "PRODUCT", q => "BLÅHAJ"})->json
  ->{searchResultPage}{products}{main}{items}[0]{product}{mainImageUrl})->body),
  "\cG"'




(이미지 URL을 iTerm2’s bundled imgcat utility으로 보내면 되지만 그게 무슨 재미가 있겠습니까?)

imgcat --url `perl -Mojo \
  -E 'print g("https://sik.search.blue.cdtapps.com/us/en/search-result-page",
  form => {types => "PRODUCT", q => "BLÅHAJ"})->json
  ->{searchResultPage}{products}{main}{items}[0]{product}{mainImageUrl}'`


하지만 iTerm2나 Mac이 없습니다!



내가 잡았어. 256-color mode with ANSI codes을 사용하는 Image::Term256Color from CPANblock characters을 사용하는 유니코드 글꼴을 지원하는 모든 터미널에서 작동하는 버전이 있습니다. 또한 Term::ReadKey을 사용하여 창 너비에 맞게 이미지 크기를 조정합니다. (다시 말하지만 이것은 "한 줄짜리"의 정의를 확장합니다.)

perl -Mojo -MImage::Term256Color -MTerm::ReadKey \
  -E 'say for Image::Term256Color::convert(g(g("https://sik.search.blue.cdtapps.com/us/en/search-result-page",
  form => {types => "PRODUCT", q => "BLÅHAJ"})->json
  ->{searchResultPage}{products}{main}{items}[0]{product}{mainImageUrl})->body,
  {scale_x => (GetTerminalSize)[0], utf8 => 1})'




난 모졸리셔스가 싫어! 코어 모듈만 사용할 수는 없나요?



괜찮은. 다음은 HTTP::Tiny 및 순수 Perl JSON 구문 분석기JSON::PP를 사용하여 제품 가격을 검색하는 것입니다added to core in version 5.14.

$ perl -MHTTP::Tiny -MJSON::PP \
  -E 'say @{decode_json(HTTP::Tiny->new->get("https://sik.search.blue.cdtapps.com/us/en/search-result-page?types=PRODUCT&q=BLÅHAJ")
  ->{content})
  ->{searchResultPage}{products}{main}{items}[0]{product}}{qw(currencyCode priceNumeral)}'
USD19.99


위와 같이 MIME::Base64 또는 Image::Term256Color를 사용하여 껴안을 수 있는 상어의 사진을 가져오고 표시하는 것은 독자에게 연습 문제로 남겨둡니다.

좋은 웹페이지 즐겨찾기