国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

chrome插件開發 - github倉庫star趨勢圖

chnmagnus / 2154人閱讀

摘要:于是,又接著搜索,發現了這個倉庫。在正式進入開發之前,我們再來體驗下的調用。再發幾次請求會發現,一直在持續減少。。。其中明確提到,它會根據來限制調用的頻次。對于未授權的訪問,一小時最多次而授權的訪問,一小時最多次。

1. 前言

這天,在逛github(就是劃水)的時候,突然想看看某個倉庫的star走勢,但是在star列表中翻了半天愣是沒找到相應的功能。于是乎,谷歌一搜,發現有個叫Star History的谷歌插件,然而竟然要收費。。。

于是,又接著搜索,發現了這個倉庫。好巧的是,這個倉庫就是那個插件的源碼。稍微瞅了下源碼,感覺我也能行?

由于之前就想學學怎么寫chrome插件,本著學習的態度和好奇心驅使(都是劃水,沒有什么不同),于是也做了一個可以查看倉庫Star趨勢的插件。效果如下:

2. 準備工作 2.1 chrome插件簡單入門

由于也是第一次寫Chrome插件,作為小白,就先搜搜大家都是怎么寫chrome插件的吧。果然,一搜一大堆。。。不過,最終還是選擇了官方文檔,畢竟是第一手資料,雖然是英文,但寫得還算通俗易懂,閱讀起來沒啥問題。

這里推薦看Getting Started,非常友好,一步步教你完成一個最簡單的修改網頁背景顏色的Chrome插件。跟著教程完成之后你就會發現,原來Chrome插件就像完成一個web項目一樣。

manifest.json是項目的配置文件(類似于package.json),插件所需要的一些能力(例如Storage)就在這個文件中聲明。剩下的工作,無非就是根據Chrome插件提供的API實現你想要的功能即可。

我們來看下要創建的項目目錄manifest.json配置文件:

├── README.md
├── dist
│?? └── bundle.js
├── images
│?? ├── trending128.png
│?? ├── trending16.png
│?? ├── trending32.png
│?? └── trending48.png
├── manifest.json
├── package.json
├── src
│?? └── injected.js
└── webpack.config.js
{
  "name": "Github-Star-Trend",
  "version": "1.0",
  "manifest_version": 2,
  "description": "Generates a star trend graph for a github repository",
  "icons": {
    "16": "images/trending16.png",
    "32": "images/trending32.png",
    "48": "images/trending48.png",
    "128": "images/trending128.png"
  },
  "content_scripts": [
    {
      "matches": ["https://github.com/*"],
      "js": ["dist/bundle.js"]
    }
  ]
}

這里需要解釋一點,根據最一開始我們看到的效果圖,可以發現我們正在瀏覽的頁面上多了一個Star Trend按鈕。所以我們要完成的插件需要能夠往頁面注入一個按鈕,而這正是通過manifest.json中的content_scripts字段實現的。它允許我們往matches字段匹配的網頁中注入js字段中的腳本文件。

因此,上面的配置意思很簡單,就是在匹配到url是https://github.com/* 的網頁時,注入我們dist目錄下的bundle.js文件。而bundle.js其實是我們為了在項目中用上ES6而采用webpack編譯得到的,源碼就是src/injected.js。接下來的工作就是在我們的src目錄下開發就行了(都是寫js,沒什么不同)。

2.2 Github API

在正式進入開發之前,我們再來體驗下Github的API調用。官方文檔在這兒,概覽看完之后,經過一番搜索,終于找到我們的主角Starring APi。

根據這個API,我們可以拿到某個倉庫的Star列表。仔細看文檔,能夠看到有這么一條:

You can also find out when stars were created by passing the following custom media type via the Accept header:
Accept: application/vnd.github.v3.star+json

太棒了,這不正是我們所需的star時間嗎?趕緊打開postman測試一把:

果然,我們順利拿到了star倉庫的時間。不過這里有一個問題,這個請求每次返回的個數只有30條,也就是說假如像react這樣十幾萬star的倉庫豈不是要請求3k+次。。。而且,還有另外一個重要的問題,那就是Github API對調用的頻率也有限制。。。

在上面的圖片中,Response Header中告訴我們limit是60次,remaning還有59次。再發幾次請求會發現,remaning一直在持續減少。。。在翻閱了一番文檔之后,我找到了這個。

For API requests using Basic Authentication or OAuth, you can make up to 5000 requests per hour. For unauthenticated requests, the rate limit allows for up to 60 requests per hour. Unauthenticated requests are associated with the originating IP address, and not the user making requests.

其中明確提到,它會根據ip來限制API調用的頻次。對于未授權的訪問,一小時最多60次;而授權的訪問,一小時最多5000次。所以,為了盡可能避免的訪問頻次帶來的問題,我們在請求中需要帶上access_token。有關access_token,你可以在這里申請。

3. 開工

經過前期的一番調研,事實證明想法確實可以實現。我們再來簡單理下思路:

根據頁面的dom結構,找到注入Star Trend按鈕的位置(injected.js)

給Star Trend按鈕綁定點擊事件,發起獲取Star時間的請求,收集數據(fetchHistoryData.js)

根據返回的數據,利用echart.js繪制趨勢圖(createChart.js)

3.1 injected.js

利用chrome的元素審查功能,我們可以很輕松地找到要注入按鈕的位置,并給它綁定上相應的點擊事件。

/**
 * star趨勢按鈕點擊事件
 */
function onClickStarTrend() {
  // todo: 發起請求
  console.log("u click star trend");
}

/**
 * 創建star趨勢按鈕
 */
const createStarTrendBtn = () => {
  const starTrendBtn = document.createElement("button");
  starTrendBtn.setAttribute("class", "btn btn-sm");
  starTrendBtn.innerHTML = `Star Trend`;
  starTrendBtn.addEventListener("click", onClickStarTrend);
  return starTrendBtn;
};

/**
 * 注入star趨勢按鈕
 */
const injectStarTrendBtn = () => {
  var newNode = document.createElement("li");
  newNode.appendChild(createStarTrendBtn());
  var firstBtn = document.querySelector(".pagehead-actions > li");
  if(firstBtn && firstBtn.parentNode) {
    firstBtn.parentNode.insertBefore(newNode, firstBtn);
  }
};

(function run() {
  injectStarTrendBtn();
}());

如果你已經安裝了本地的這個插件,這個時候刷新頁面你會發現多了一個Star Trend的按鈕,點擊的時候會在控制臺打印出u click star trend的字樣。

3.2 fetchHistoryData.js

獲取數據首先要解決的就是構造請求url,根據文檔所示,我們需要當前的倉庫信息。這個倒是簡單,直接上正則從當前的location.href中匹配出來即可:

const repoRegRet = location.href.match(/https?://github.com/([^/]+/[^/]+)/?.*/);

然后是請求參數:

const requestConfig = {headers: {Accept: "application/vnd.github.v3.star+json"}};

這樣,我們就可以用axios發起一次請求:

const url = `https://api.github.com/repos/${repoRegRet[1]}/stargazers`;
axios.get(url, requestConfig).then(firstResponse => console.log(firstResponse));

查看log,我們成功地獲取到了一個倉庫第一頁的star列表。不過,這里有幾個問題需要解決:

如何獲取第2頁,第3頁,第N頁的star列表?

如何知道一個倉庫有多少頁star(即N是多少)?

當一個倉庫的star數多到要發送幾百次,甚至上千次請求時,如何決策?

第一個問題很好解決,在上面的url后面,跟上?page=n就表示請求第n頁的star數據。

第二個問題有兩種解法。一種是知道該倉庫有多少star,然后除以30(一頁返回30條數據)就可以知道有多少頁了;還有一種方法其實API文檔已經告訴我們了,第一次請求返回的數據已經告訴我們有多少頁了,只不過這個數據被放在了response的headers中。其中有一個link字段:

; rel="next", ; rel="last"

以上就是link字段的一個例子,可以看到它包含了lastPage的url地址。因此,我們可以再次用正則提取出來:

let totalPage = 1;
const linkVal = firstResponse.headers.link;
if(linkVal) {
  const pageRegRet = linkVal.match(/next.*?page=(d+).*?last/);
  if(pageRegRet) {
    totalPage = Math.min(pageRegRet[1], 1333);
  }
}

這里有兩個坑,需要特別注意:

當star數只有1頁時,link字段是沒有的,所以這里需要判斷一下;

不知道什么原因,lastPage的值最大是1334(即使倉庫有十幾萬的star),且當page=1334發起請求時會失敗。因此,totalPage最大也只能是1333。

第三個問題其實并沒有完美的解決方法,通過第二個問題我們知道最多需要發1333次請求。姑且不論服務器是否對訪問頻次是否有限制,這么多的請求所需要的耗時其實也是不能接受的,那么怎么辦呢?對于一個趨勢圖,其實我們沒必要用成千上萬的點來繪制,也許我們只用10個點(可以做成配置)來繪制就夠了。因此,我們只要用均分的策略從[1, totalPage]中選取10個page就可以了??创a:

// 最多10個請求
const URL_NUM = 10;

// 構造待請求的urls
const urls = new Array(totalPage - 1).fill(1).slice(0, URL_NUM - 1).map((_, idx) => {
  let page = idx + 2;
  if(totalPage > URL_NUM) {
    page = Math.round(page / URL_NUM * totalPage);
  }
  return {page, url: `https://api.github.com/repos/${repoRegRet[1]}/stargazers?page=${page}`};
});

// 構造請求
const requests = [
  {page: 1, request: Promise.resolve(firstResponse)},
  ...urls.map(item => ({page: item.page, request: axios.get(item.url, requestConfig)}))
];

// 發起請求
Promise.all(requests.map(_ => _.request)).then(responses => console.log(responses));

到這兒,請求數據的問題基本都已經解決了。不過還有一個容易忽視的坑,那就是由于lastPage最大只能到1333,所以當倉庫的star數大于3990時,我們拿到的數據其實是少于該倉庫真實的star數。因此針對這種情況,我們還需要調用這個API接口拿到倉庫的基本信息,也就知道了這個倉庫的總star數。

至此,我們拿到了可以構造趨勢圖的數據(這里就不貼構造圖的數據的代碼,完整代碼可以點這里查看)。

3.3 createChart.js

首先,我們把injected.js中的onClickStarTrend這個坑先給填上:

let chart = createChart();
function onClickStarTrend() {
  chart.show();
  fetchHistoryData(location.href).then(data => {
    chart.ready(data);
  }).catch(err => {
    chart.fail(err);
  });
}

從上面的代碼中,我們可以看到chart需要暴露出3個方法:

show:展示loading狀態

ready:展示圖表

fail:展示錯誤信息

所以代碼框架可以搭成這樣:

class Chart {

  show() {
    this.node = document.createElement("div");
    this.node.style = "";                    // 添加合適的樣式
    this.loadingNode = document.createElement("div");
    this.loadingNode.innerHTML = "";        // 用一個svg動畫,增加趣味性
    this.node.appendChild(this.loadingNode);
    document.body.appendChild(this.node);
  }
  
  ready(data) {
    this.node.innerHTML = `
`; ECharts.init(document.getElementById("chart")).setOption({ color: "#40A9FF", title: {text: "STAR TREND"}, xAxis: { type: "time", boundaryGap: false, splitLine: {show: false} }, yAxis: {type: "value"}, tooltip: {trigger: "axis"}, series: [{ data, type: "line", smooth: true, symbol: "none", name: "star count" }] }); } fail(err) { this.node.innerHTML = ""; // 錯誤節點內容 } }

限于篇幅,這里就不貼詳細的dom節點代碼,完整版可以看這里。而對于echarts的配置和使用,也可以參考官網上的例子。

4. 完結

整個插件的制作過程,到這兒基本上就已經完了。其他的還有網絡請求異常(例如由于訪問頻次被限制)和設置AccessToken沒有詳細介紹,不過這些都是錯誤處理的步驟,大體上不影響插件的使用。如果想了解更多的,也可以直接看源碼。

回過頭再來看,這次劃水也算有所收獲,既體驗了一把chrome插件開發,也學到了Github API的調用。雖然用到的都只是一些冰山一角,不過也算是開了個頭,為以后的騷操作打下基礎。

5. 參考

chrome插件官方文檔

timqian/star-history

Github API rate limiting

Github API - starring

Github API - repos

本文所有代碼托管在這兒,喜歡的可以給個star。

文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。

轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/104765.html

相關文章

  • Chrome插件Github Travis Stat

    摘要:所以就萌發了做一個插件的想法,我期望這個插件可以做到以下幾件事情在上顯示開通服務的倉庫當前的狀態,不管是自己的還是別人的。在每個內顯示最近次的的狀態變化。 博客原文地址:http://yaowenjie.github.io/%E7%BC%96%E7%A8%8B%E7%9B%B8%E5%85%B3/travis-github-chrome-extension 太長不讀版 最近自己寫了一...

    TigerChain 評論0 收藏0
  • Crown -- 一款快速檢索并切換你的書簽與Tabs的chrome擴展

    摘要:在此期間我的文章會同步更新在以下地方歡迎大家在自己長逛的網站中關注或者我的來了解我的最新消息推薦大家收藏關注我的博客網站,因為我的最新更改與文章只會在這里更新,其他地方的文章可能會存在更新不及時或者忘記更新等問題。 之前一直在找一款現成的已經實現了如標題所說的chrome擴展, 但卻一直沒有找到, 于是最近花了私底下的一些空閑時間去按照自己所想要的功能去打造了這么一款chrome擴展,...

    SHERlocked93 評論0 收藏0
  • GitHub 值得收藏的前端項目[每月更新...]

    摘要:也是一款優秀的響應式框架站點所使用的一套框架為微信服務量身設計的一套框架一組很小的,響應式的組件,你可以在網頁的項目上到處使用一個可定制的文件,使瀏覽器呈現的所有元素,更一致和符合現代標準。 GitHub 值得收藏的前端項目 整理與收集的一些比較優秀github項目,方便自己閱讀,順便分享出來,大家一起學習,本篇文章會持續更新,版權歸原作者所有。歡迎github star與fork 預...

    maxmin 評論0 收藏0
  • 基于 Github API 的Chrome 插件開發全紀錄

    摘要:最近基于開發了一款圖床插件,現在已經開源并上架應用商店。通過方法把轉成,然后放在里測試一下看來效果是的,接下來就是對圖床插件進行開發的步驟了。至此,整個插件的開發發布流程就已經完成了。 showImg(https://user-images.githubusercontent.com/12172868/57382983-8f29b900-71e0-11e9-8fe9-c0f12fd54...

    DoINsiSt 評論0 收藏0

發表評論

0條評論

最新活動
閱讀需要支付1元查看
<