用 GitHub Actions 記錄 API 資料的變化

Hacker News Daily 上看到的方式,Simon Willison 利用了 GitHub Actions 定時去抓資料更新 git repository:「Git scraping: track changes over time by scraping to a Git repository」。

文章裡面測試了 JSON 檔案的變化:

這個方式利用了 GitHub 自家的架構做完所有的事情,因為他的範例是拉加州政府的資料,感覺 g0v 裡應該有些專案也用這個方式搞,翻了一下 Telegram 上的記錄,果然翻到記錄了:「零營運費用開源開發」。

另外我猜用 free-for.dev 這邊的資源應該也有機會堆出類似的東西...

MySQL 的 TIME 範圍

這篇算是考古文,找出 MySQLTIME 資料型態奇怪範圍的由來:「TIME for a WTF MySQL moment」。

在官方的文件裡面可以看到 TIME 的範圍是個奇怪的數字,如果把各版本的文件都拉出來看,會發現都沒改過:「11.2.3 The TIME Type (8.0)」、「11.2.3 The TIME Type (5.7)」、「11.2.3 The TIME Type (5.6)」,「11.3.2 The TIME Type (5.5,靠 Internet Archive 的存檔頁面)」、「11.3.2 The TIME Type (5.1,靠 Internet Archive 的存檔頁面)」、「11.3.2 The TIME Type (5.0,靠 Internet Archive 的存檔頁面)」,裡面一直都是:

TIME values may range from '-838:59:59' to '838:59:59'.

這個數字看起來應該是某個限制,但作者粗粗算了幾種可能都不像,所以就一路考古,發現算是在 MySQL 3 年代因為某個特別公式留下來的遺毒,就一路用到現在了:

One of the bits was used for the sign as well, but the remaining 23 bits were an integer value produced like this: Hours × 10000 + Minutes × 100 + Seconds; in other words, the two least significant decimal digits of the number contained the seconds, the next two contained the minutes, and the remaining ones contained the hours. 223 is 83888608, i.e. 838:86:08, therefore, the maximum valid time in this format is 838:59:59.

話說回來,用 MySQL 的人還是很習慣用 INTBIGINT 來存時間,這樣可以自動遠離這些鳥問題,之前在「MySQL 裡儲存時間的方式...」與「Facebook 在 MySQL 裡存時間的型態」這邊都寫過...

不過最近用 PostgreSQL 比較多,可以比較「正常」的使用各種資料型態...

Splitgraph 把公開資料轉成 PostgreSQL 服務

看到「Port 5432 is open: introducing the Splitgraph Data Delivery Network」這個,Splitgraph 把 public dataset 轉成 PostgreSQL 服務:

We launch the Splitgraph Data Delivery Network: a single endpoint that lets any PostgreSQL application, client or BI tool to connect and query over 40,000 public datasets hosted or proxied by Splitgraph.

這樣看起來可以讓很多 BI 工具直接接進來用,如果再支援 ODBC 或是 JDBC 的話通用性就更好了,但目前沒看到定價策略 (感覺應該頗好賣的?),應該是還在開發階段?

丟給公司內 data team 看一下好了,如果資料的品質沒問題的話,感覺會是個好用的服務...

cURL 支援 Zstandard

在「curl 7.72.0 – more compression」這邊看到新版的 cURL 要支援 Zstandard 了,查了一下發現 Zstandard 有對應的 RFC,在 RFC 8478:「Zstandard Compression and the application/zstd Media Type」。

對應到 server 端的部份,看起來可以用 tokers/zstd-nginx-module 搭 (在 nginx 環境下),不然就是 application 端要自己壓縮了。

不過普及率比較高的演算法是 Google 主導的 Brotli,查了一下壓縮率大概在同一個等級。

Facebook 沒有自家瀏覽器,推這些東西比較辛苦一點,但這次 cURL 決定支援 Zstandard 算是一個開始,讓開發者多了一個選擇可以用...

EU-US Privacy Shield 被歐盟法院拒絕

在「EU rejects US data sharing agreement over privacy concerns」這邊看到的新聞,引用自「EU rejects US data sharing agreement over privacy concerns」這邊的新聞報導。

歐盟最高法院的新聞稿則是在「The Court of Justice invalidates Decision 2016/1250 on the adequacy of the protection provided by the EU-US Data Protection Shield」這邊可以看到,雖然 EU-US Privacy Shield 被推翻,但本來在 2010 年的框架仍然有效:

However, it considers that Commission Decision 2010/87 on standard contractual clauses for the transfer of personal data to processors established in third countries is valid.

維基百科上的條目寫的比較簡單,主要是協議裡美國的保護機制不到歐盟的標準:

A final CJEU decision was published on 16 July 2020. The EU-US Privacy Shield for data sharing was struck down by the European Court of Justice on the grounds it did not provide adequate protections to EU citizens on government snooping.

記得這個戰了好久,最後在最高法院定案了...

第四堂:「Data Wrangling」

有陣子沒寫了,來還個債...

這個系列是從『MIT 的「The Missing Semester of Your CS Education」』這邊延伸出來的,這邊講的是「Data Wrangling」這篇。

這篇是在講 pipe 的用法,在講這些工具之前,其實有個很重要的概念應該要說明 (但沒有在這篇文章裡被提到),也就是 Unix philosophy,這個哲學是指 unix 環境下的工具,都會設計成只做好一件事情。

而要怎麼把這些工具串起來,最常見的就是 pipe,你可以在文章裡看到 grepsedsort 這些工具的用法,以及怎麼用 pipe 串起來。

這邊剛好也可以提一下,利用 pipe 可以把不同功能打散到不同的 process 上,剛好也可以稍微利用到現在常見的多 CPU 的環境。

另外上面因為提到了 grep,文章內花了不少篇幅在講 Regular expression 這個在 CS 課程裡面也是重要的基礎。

會放這種篇幅長度,一方面是 Regular expression 的實用性很高,另外一方面,學術上與自動機理論中的 DFANFA 都有關,算是學習計算理論的起點:

然後後面就有提到 AWK 這個工具,這邊要注意的是,雖然可以用 Perl 之類的工具作到類似的事情 (而且更強大),但 AWK 有被放到 POSIX 標準裡,所以在各種作業系統內幾乎都一定會出現,加上語法算是簡單,學起來還是很有幫助...

然後再最後面的段落冒出一個 gnuplot 畫個圖,以及示範 xargs 這種神器要怎麼用 (這邊會更建議看一下 manpage,可以配合 find 之類的工具用,並且平行化同時處理)。

然後最後示範了 binary data 怎麼處理。

疾管署的 COVID-19 每日送檢數的 Open Data

記者會上有提到現在疾管署的網站上有公開每日送檢數的資料,花了些時間找,在「台灣COVID-19冠狀病毒檢測每日送驗數」這邊可以看到,網站提供的 preview 的界面沒辦法看到最新的資料,但下載後可以看到檔案格式是 UTF-8 的 CSV 檔,應該還算能處理...

找到這個資料花了一些功夫 (因為用 DuckDuckGoGoogle 都沒直接找到),後來是靠這樣的步驟找到的:

本來點選熱門資料那邊的「COVID-19台灣最新病例、檢驗統計」結果發現只有一筆資料,而且看起來最後更新時間是 2020/04/24,所以得往其他地方翻。

首先點了上面的「最新消息」發現是個系統公告區,不是我要的,接下來才又找到正確的路線...

這時候就會看到最前面提到的「台灣COVID-19冠狀病毒檢測每日送驗數」了。

然後 data.cdc.gov.tw 這個網站看起來是放在 Microsoft Azure 的日本區?

歐盟更新了對於 Cookie 同意方式的準則

TechCrunch 上面看到的,歐盟更新了對於 Cookie 同意方式的準則:「No cookie consent walls — and no, scrolling isn’t consent, says EU data protection body」,英文版的 PDF 文件可以在「Guidelines 05/2020 on consent under Regulation 2016/679」這邊看到。

這篇準則主要是在說明,什麼情境下取得的「同意」才是有效的。主要在在說明使用者與開發者權力不對等的情況下,GDPR 會擋下哪些對使用者不利的情況。

準則文件裡開頭的地方先解釋了什麼是 free/freely given,然後給了不少範例,另外翻例子的時候還看到在雇傭關係下因為員工有無法拒絕的壓力,這時候的同意也未必是有效的,藉以保護員工...

而 TechCrunch 的文章則是拉出了兩個目前在 internet 上很常用的情況來報導 (cookie wall 與 scrolling),解釋現在 internet 上面常用的這些方法在 GDPR 下並沒有取得授權。

這樣的話 Medium 的 login wall 應該也會踩到 (強迫你要註冊 Medium 才能看,這邊會需要同意 Medium 的使用條款),這次歐盟文件算是蠻清楚的,多幾次訴訟,再讓 GDPR 跑個幾年,應該有會有不同的方法了...

Brave 出手檢舉 Google 沒有遵守 GDPR

Brave (從 Chromium 分支出來的瀏覽器) 檢舉 Google 沒有遵守 GDPR 的規定:「Formal GDPR complaint against Google’s internal data free-for-all」。

主要是「purpose limitation」這個部份,出自「REGULATION (EU) 2016/679 OF THE EUROPEAN PARLIAMENT AND OF THE COUNCIL of 27 April 2016」:

1. Personal data shall be:

(b)

collected for specified, explicit and legitimate purposes and not further processed in a manner that is incompatible with those purposes; further processing for archiving purposes in the public interest, scientific or historical research purposes or statistical purposes shall, in accordance with Article 89(1), not be considered to be incompatible with the initial purposes (‘purpose limitation’);

比較重要的是 specified 與 explicit 這兩個詞,GDPR 規定必須明確指明用途,而可以從整理出來的文件「Inside the black box」裡的「Purported processing purpose」看到大量的極為廣泛的說明。

Google 應該會就這塊反擊認為這樣的描述就夠用,就看歐盟決定要怎麼做了...

Google 用 x-client-data 追蹤使用者的問題

前陣子 Chromium 團隊在研究要移除 User-Agent 字串的事情 (參考「User-Agent 的淘汰提案」),結果 kiwibrowser 就直接炸下去,Google 很久前就會針對自家網站送出 x-client-data 這個 HTTP header,裡面足以辨識使用者瀏覽器的單一性:「Partial freezing of the User-Agent string#467」。

Google 的白皮書裡面是說用在 server 的試驗:

We want to build features that users want, so a subset of users may get a sneak peek at new functionality being tested before it’s launched to the world at large. A list of field trials that are currently active on your installation of Chrome will be included in all requests sent to Google. This Chrome-Variations header (X-Client-Data) will not contain any personally identifiable information, and will only describe the state of the installation of Chrome itself, including active variations, as well as server-side experiments that may affect the installation.

The variations active for a given installation are determined by a seed number which is randomly selected on first run. If usage statistics and crash reports are disabled, this number is chosen between 0 and 7999 (13 bits of entropy). If you would like to reset your variations seed, run Chrome with the command line flag “--reset-variation-state”. Experiments may be further limited by country (determined by your IP address), operating system, Chrome version and other parameters.

但因為這個預設值開啟的關係,就算關掉後也足以把使用者再分類到另外一個區塊,仍然具有高度辨識性,不是你 Google 說無法辨識就算數。

另外如果看 source code 裡的說明:

    // Note the criteria for attaching client experiment headers:
    // 1. We only transmit to Google owned domains which can evaluate
    // experiments.
    //    1a. These include hosts which have a standard postfix such as:
    //         *.doubleclick.net or *.googlesyndication.com or
    //         exactly www.googleadservices.com or
    //         international TLD domains *.google. or *.youtube..
    // 2. Only transmit for non-Incognito profiles.
    // 3. For the X-Client-Data header, only include non-empty variation IDs.

可以看到 *.doubleclick.net*.googlesyndication.comwww.googleadservices.com 全部都是廣告相關,另外 Google 自家搜尋引擎是直接提供廣告 (不透過前面提到的網域),YouTube 也是一樣的情況,所以完全可以猜測 x-client-data 這個資料就是用在廣告相關的系統上。

The Register 在「Is Chrome really secretly stalking you across Google sites using per-install ID numbers? We reveal the truth」這邊用粗體的 Update 提到了 GDPR 的問題,不確定是不是開始有單位在調查了:

Updated Google is potentially facing a massive privacy and GDPR row over Chrome sending per-installation ID numbers to the mothership.

在這個問題沒修正之前,只能暫時用操作 HTTP header 的 extension 移掉這個欄位。