about summary refs log tree commit diff
diff options
context:
space:
mode:
authorNgô Ngọc Đức Huy <huyngo@disroot.org>2021-06-13 11:24:07 +0700
committerNgô Ngọc Đức Huy <huyngo@disroot.org>2021-06-13 11:24:07 +0700
commitf5f00b800f4158aeef28f73407e2064b29113ac3 (patch)
tree20564ecedecad661aea3411548dccfce7cba9626
parent687e0787abcd9b019da285534764acdab5e262df (diff)
downloadblog-f5f00b800f4158aeef28f73407e2064b29113ac3.tar.gz
Update blog
-rw-r--r--content/posts/2021-06-13-jq.md204
1 files changed, 204 insertions, 0 deletions
diff --git a/content/posts/2021-06-13-jq.md b/content/posts/2021-06-13-jq.md
new file mode 100644
index 0000000..49d2148
--- /dev/null
+++ b/content/posts/2021-06-13-jq.md
@@ -0,0 +1,204 @@
+---
+title: "jq is a powerful JSON processor"
+date: 2021-06-13
+categories: [ blog ]
+tags: [unix, jq, json, cli, guide, tinker]
+---
+
+So lately I've been using `jq` quite a bit. It is a CLI JSON processor that
+makes your life easier if you have to deal with a lot of JSON.  Here I'm going
+to give two examples of how it's used.
+
+# Search response
+
+I've been dealing with JSON from Elasticsearch API[^0], but as they would not
+release their documents under a free license, I will take an example from
+OpenSearch instead[^1]:
+
+```json
+{
+  "took": 39,
+  "timed_out": false,
+  "_shards": {
+    "total": 68,
+    "successful": 68,
+    "skipped": 0,
+    "failed": 0
+  },
+  "hits": {
+    "total": {
+      "value": 5837,
+      "relation": "eq"
+    },
+    "max_score": 7.8623476,
+    "hits": [
+      {
+        "_index": "new_shakespeare",
+        "_type": "_doc",
+        "_id": "100763",
+        "_score": 7.8623476,
+        "_source": {
+          "type": "line",
+          "line_id": 100764,
+          "play_name": "Troilus and Cressida",
+          "speech_number": 43,
+          "line_number": "3.1.68",
+          "speaker": "PANDARUS",
+          "text_entry": "Sweet queen, sweet queen! thats a sweet queen, i faith."
+        }
+      },
+      {
+        "_index": "shakespeare",
+        "_type": "_doc",
+        "_id": "28559",
+        "_score": 5.8923807,
+        "_source": {
+          "type": "line",
+          "line_id": 28560,
+          "play_name": "Cymbeline",
+          "speech_number": 20,
+          "line_number": "1.1.81",
+          "speaker": "QUEEN",
+          "text_entry": "No, be assured you shall not find me, daughter,"
+        }
+      }
+    ]
+  }
+}
+```
+
+Woah that's long!
+
+How do you know how much time it took?  I want to measure the performance.
+
+```sh
+$ curl ... | jq '.took'
+39
+```
+
+Nice.  Not very helpful, though---I can easily see that at the top of the
+result.  I want to see which responses were returned.
+
+```sh
+$ curl ... | jq '.hits.hits'
+[
+  {
+    "_index": "new_shakespeare",
+    "_type": "_doc",
+    "_id": "100763",
+    "_score": 7.8623476,
+    "_source": {
+      "type": "line",
+      "line_id": 100764,
+      "play_name": "Troilus and Cressida",
+      "speech_number": 43,
+      "line_number": "3.1.68",
+      "speaker": "PANDARUS",
+      "text_entry": "Sweet queen, sweet queen! thats a sweet queen, i faith."
+    }
+  },
+  {
+    "_index": "shakespeare",
+    "_type": "_doc",
+    "_id": "28559",
+    "_score": 5.8923807,
+    "_source": {
+      "type": "line",
+      "line_id": 28560,
+      "play_name": "Cymbeline",
+      "speech_number": 20,
+      "line_number": "1.1.81",
+      "speaker": "QUEEN",
+      "text_entry": "No, be assured you shall not find me, daughter,"
+    }
+  }
+]
+```
+
+The response is the value of `hits` inside a `hits`, so the query is
+`.hits.hits`.  How intuitive!
+
+But this is hard to read. Let's just take the `play_name` of the result.
+
+```sh
+$ curl ... | jq .hits.hits[]._source.play_name
+"Troilus and Cressida"
+"Cymbeline"
+```
+
+Neat!  But how does it work?  The brackets `[]` signifies that we should take
+all the results, from each of which the value for `._source.play_name` is
+taken.
+
+There might be the option to write that in the search query DSL, which also
+reduces the data transferred, but I bet this is much easier to write.
+
+# Wallpaper
+
+I use `feh` for setting wallpaper, which can take an image from the internet.
+Previously, I used a static list that I collected myself, but I recently
+discovered a wallpaper API from [wallhaven](https://wallhaven.cc/help/api).
+
+Let's say, I want to get a space image as wallpaper, I would use this command:
+
+```sh
+curl -s 'https://wallhaven.cc/api/v1/search?q=space&ratios=16x9&sorting=toplist'
+```
+
+Where `q` is the query, `ratios` is the image ratio so that it fits the screen,
+and `sorting` is the way the results would be sorted before pagination.  The
+results is long, but it looks like this:
+
+```json
+{
+  "data": [
+      {
+      "id": "l3zmwy",
+      "url": "https://wallhaven.cc/w/l3zmwy",
+      "short_url": "https://whvn.cc/l3zmwy",
+      "views": 67050,
+      "favorites": 705,
+      "source": "https://www.artstation.com/artwork/YaQwgP",
+      "purity": "sfw",
+      "category": "general",
+      "dimension_x": 1920,
+      "dimension_y": 1080,
+      "resolution": "1920x1080",
+      "ratio": "1.78",
+      "file_size": 781731,
+      "file_type": "image/jpeg",
+      "created_at": "2021-05-18 19:26:23",
+      "colors": [
+        "#424153",
+        "#000000",
+        "#663300",
+        "#996633",
+        "#999999"
+      ],
+      "path": "https://w.wallhaven.cc/full/l3/wallhaven-l3zmwy.jpg",
+      "thumbs": {
+        "large": "https://th.wallhaven.cc/lg/l3/l3zmwy.jpg",
+        "original": "https://th.wallhaven.cc/orig/l3/l3zmwy.jpg",
+        "small": "https://th.wallhaven.cc/small/l3/l3zmwy.jpg"
+      }
+    },
+    ...
+  ]
+}
+```
+
+So, to get the image path from this, I run:
+
+```sh
+curl ... | jq -r .data[].path | shuf -n 1 | feh --bg-center
+```
+
+I use `shuf` because I'd like a new wallpaper every time I run this script.
+Put this as the startup script or add a cron job and you'll have a changing
+wallpaper.  Disclaimer: this script does not always work, because of `feh`.
+If you're using GNOME, for example, `feh` can't be used to set background.
+
+[^0]: Yes I know it's no longer free software (it still partially is I think).
+  I have no choice, and I would still be more at peace with a source available
+  software that is self-hostable.
+[^1]: Copyright 2021 OpenSearch contributors.  Released under Apache License.