成人无码视频,亚洲精品久久久久av无码,午夜精品久久久久久毛片,亚洲 中文字幕 日韩 无码

資訊專欄INFORMATION COLUMN

chrome插件開(kāi)發(fā) - github倉(cāng)庫(kù)star趨勢(shì)圖

chnmagnus / 2222人閱讀

摘要:于是,又接著搜索,發(fā)現(xiàn)了這個(gè)倉(cāng)庫(kù)。在正式進(jìn)入開(kāi)發(fā)之前,我們?cè)賮?lái)體驗(yàn)下的調(diào)用。再發(fā)幾次請(qǐng)求會(huì)發(fā)現(xiàn),一直在持續(xù)減少。。。其中明確提到,它會(huì)根據(jù)來(lái)限制調(diào)用的頻次。對(duì)于未授權(quán)的訪問(wèn),一小時(shí)最多次而授權(quán)的訪問(wèn),一小時(shí)最多次。

1. 前言

這天,在逛github(就是劃水)的時(shí)候,突然想看看某個(gè)倉(cāng)庫(kù)的star走勢(shì),但是在star列表中翻了半天愣是沒(méi)找到相應(yīng)的功能。于是乎,谷歌一搜,發(fā)現(xiàn)有個(gè)叫Star History的谷歌插件,然而竟然要收費(fèi)。。。

于是,又接著搜索,發(fā)現(xiàn)了這個(gè)倉(cāng)庫(kù)。好巧的是,這個(gè)倉(cāng)庫(kù)就是那個(gè)插件的源碼。稍微瞅了下源碼,感覺(jué)我也能行?

由于之前就想學(xué)學(xué)怎么寫(xiě)chrome插件,本著學(xué)習(xí)的態(tài)度和好奇心驅(qū)使(都是劃水,沒(méi)有什么不同),于是也做了一個(gè)可以查看倉(cāng)庫(kù)Star趨勢(shì)的插件。效果如下:

2. 準(zhǔn)備工作 2.1 chrome插件簡(jiǎn)單入門

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

這里推薦看Getting Started,非常友好,一步步教你完成一個(gè)最簡(jiǎn)單的修改網(wǎng)頁(yè)背景顏色的Chrome插件。跟著教程完成之后你就會(huì)發(fā)現(xiàn),原來(lái)Chrome插件就像完成一個(gè)web項(xiàng)目一樣。

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

我們來(lái)看下要?jiǎng)?chuàng)建的項(xiàng)目目錄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"]
    }
  ]
}

這里需要解釋一點(diǎn),根據(jù)最一開(kāi)始我們看到的效果圖,可以發(fā)現(xiàn)我們正在瀏覽的頁(yè)面上多了一個(gè)Star Trend按鈕。所以我們要完成的插件需要能夠往頁(yè)面注入一個(gè)按鈕,而這正是通過(guò)manifest.json中的content_scripts字段實(shí)現(xiàn)的。它允許我們往matches字段匹配的網(wǎng)頁(yè)中注入js字段中的腳本文件。

因此,上面的配置意思很簡(jiǎn)單,就是在匹配到url是https://github.com/* 的網(wǎng)頁(yè)時(shí),注入我們dist目錄下的bundle.js文件。而bundle.js其實(shí)是我們?yōu)榱嗽陧?xiàng)目中用上ES6而采用webpack編譯得到的,源碼就是src/injected.js。接下來(lái)的工作就是在我們的src目錄下開(kāi)發(fā)就行了(都是寫(xiě)js,沒(méi)什么不同)。

2.2 Github API

在正式進(jìn)入開(kāi)發(fā)之前,我們?cè)賮?lái)體驗(yàn)下Github的API調(diào)用。官方文檔在這兒,概覽看完之后,經(jīng)過(guò)一番搜索,終于找到我們的主角Starring APi。

根據(jù)這個(gè)API,我們可以拿到某個(gè)倉(cāng)庫(kù)的Star列表。仔細(xì)看文檔,能夠看到有這么一條:

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時(shí)間嗎?趕緊打開(kāi)postman測(cè)試一把:

果然,我們順利拿到了star倉(cāng)庫(kù)的時(shí)間。不過(guò)這里有一個(gè)問(wèn)題,這個(gè)請(qǐng)求每次返回的個(gè)數(shù)只有30條,也就是說(shuō)假如像react這樣十幾萬(wàn)star的倉(cāng)庫(kù)豈不是要請(qǐng)求3k+次。。。而且,還有另外一個(gè)重要的問(wèn)題,那就是Github API對(duì)調(diào)用的頻率也有限制。。。

在上面的圖片中,Response Header中告訴我們limit是60次,remaning還有59次。再發(fā)幾次請(qǐng)求會(huì)發(fā)現(xiàn),remaning一直在持續(xù)減少。。。在翻閱了一番文檔之后,我找到了這個(gè)。

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.

其中明確提到,它會(huì)根據(jù)ip來(lái)限制API調(diào)用的頻次。對(duì)于未授權(quán)的訪問(wèn),一小時(shí)最多60次;而授權(quán)的訪問(wèn),一小時(shí)最多5000次。所以,為了盡可能避免的訪問(wèn)頻次帶來(lái)的問(wèn)題,我們?cè)谡?qǐng)求中需要帶上access_token。有關(guān)access_token,你可以在這里申請(qǐng)。

3. 開(kāi)工

經(jīng)過(guò)前期的一番調(diào)研,事實(shí)證明想法確實(shí)可以實(shí)現(xiàn)。我們?cè)賮?lái)簡(jiǎn)單理下思路:

根據(jù)頁(yè)面的dom結(jié)構(gòu),找到注入Star Trend按鈕的位置(injected.js)

給Star Trend按鈕綁定點(diǎn)擊事件,發(fā)起獲取Star時(shí)間的請(qǐng)求,收集數(shù)據(jù)(fetchHistoryData.js)

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

3.1 injected.js

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

/**
 * star趨勢(shì)按鈕點(diǎn)擊事件
 */
function onClickStarTrend() {
  // todo: 發(fā)起請(qǐng)求
  console.log("u click star trend");
}

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

/**
 * 注入star趨勢(shì)按鈕
 */
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();
}());

如果你已經(jīng)安裝了本地的這個(gè)插件,這個(gè)時(shí)候刷新頁(yè)面你會(huì)發(fā)現(xiàn)多了一個(gè)Star Trend的按鈕,點(diǎn)擊的時(shí)候會(huì)在控制臺(tái)打印出u click star trend的字樣。

3.2 fetchHistoryData.js

獲取數(shù)據(jù)首先要解決的就是構(gòu)造請(qǐng)求url,根據(jù)文檔所示,我們需要當(dāng)前的倉(cāng)庫(kù)信息。這個(gè)倒是簡(jiǎn)單,直接上正則從當(dāng)前的location.href中匹配出來(lái)即可:

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

然后是請(qǐng)求參數(shù):

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

這樣,我們就可以用axios發(fā)起一次請(qǐng)求:

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

查看log,我們成功地獲取到了一個(gè)倉(cāng)庫(kù)第一頁(yè)的star列表。不過(guò),這里有幾個(gè)問(wèn)題需要解決:

如何獲取第2頁(yè),第3頁(yè),第N頁(yè)的star列表?

如何知道一個(gè)倉(cāng)庫(kù)有多少頁(yè)star(即N是多少)?

當(dāng)一個(gè)倉(cāng)庫(kù)的star數(shù)多到要發(fā)送幾百次,甚至上千次請(qǐng)求時(shí),如何決策?

第一個(gè)問(wèn)題很好解決,在上面的url后面,跟上?page=n就表示請(qǐng)求第n頁(yè)的star數(shù)據(jù)。

第二個(gè)問(wèn)題有兩種解法。一種是知道該倉(cāng)庫(kù)有多少star,然后除以30(一頁(yè)返回30條數(shù)據(jù))就可以知道有多少頁(yè)了;還有一種方法其實(shí)API文檔已經(jīng)告訴我們了,第一次請(qǐng)求返回的數(shù)據(jù)已經(jīng)告訴我們有多少頁(yè)了,只不過(guò)這個(gè)數(shù)據(jù)被放在了response的headers中。其中有一個(gè)link字段:

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

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

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);
  }
}

這里有兩個(gè)坑,需要特別注意:

當(dāng)star數(shù)只有1頁(yè)時(shí),link字段是沒(méi)有的,所以這里需要判斷一下;

不知道什么原因,lastPage的值最大是1334(即使倉(cāng)庫(kù)有十幾萬(wàn)的star),且當(dāng)page=1334發(fā)起請(qǐng)求時(shí)會(huì)失敗。因此,totalPage最大也只能是1333。

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

// 最多10個(gè)請(qǐng)求
const URL_NUM = 10;

// 構(gòu)造待請(qǐng)求的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}`};
});

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

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

到這兒,請(qǐng)求數(shù)據(jù)的問(wèn)題基本都已經(jīng)解決了。不過(guò)還有一個(gè)容易忽視的坑,那就是由于lastPage最大只能到1333,所以當(dāng)倉(cāng)庫(kù)的star數(shù)大于3990時(shí),我們拿到的數(shù)據(jù)其實(shí)是少于該倉(cāng)庫(kù)真實(shí)的star數(shù)。因此針對(duì)這種情況,我們還需要調(diào)用這個(gè)API接口拿到倉(cāng)庫(kù)的基本信息,也就知道了這個(gè)倉(cāng)庫(kù)的總star數(shù)。

至此,我們拿到了可以構(gòu)造趨勢(shì)圖的數(shù)據(jù)(這里就不貼構(gòu)造圖的數(shù)據(jù)的代碼,完整代碼可以點(diǎn)這里查看)。

3.3 createChart.js

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

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

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

show:展示loading狀態(tài)

ready:展示圖表

fail:展示錯(cuò)誤信息

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

class Chart {

  show() {
    this.node = document.createElement("div");
    this.node.style = "";                    // 添加合適的樣式
    this.loadingNode = document.createElement("div");
    this.loadingNode.innerHTML = "";        // 用一個(gè)svg動(dòng)畫(huà),增加趣味性
    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 = ""; // 錯(cuò)誤節(jié)點(diǎn)內(nèi)容 } }

限于篇幅,這里就不貼詳細(xì)的dom節(jié)點(diǎn)代碼,完整版可以看這里。而對(duì)于echarts的配置和使用,也可以參考官網(wǎng)上的例子。

4. 完結(jié)

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

回過(guò)頭再來(lái)看,這次劃水也算有所收獲,既體驗(yàn)了一把chrome插件開(kāi)發(fā),也學(xué)到了Github API的調(diào)用。雖然用到的都只是一些冰山一角,不過(guò)也算是開(kāi)了個(gè)頭,為以后的騷操作打下基礎(chǔ)。

5. 參考

chrome插件官方文檔

timqian/star-history

Github API rate limiting

Github API - starring

Github API - repos

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

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://m.hztianpu.com/yun/104765.html

相關(guān)文章

  • Chrome插件Github Travis Stat

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

    TigerChain 評(píng)論0 收藏0
  • Crown -- 一款快速檢索并切換你的書(shū)簽與Tabs的chrome擴(kuò)展

    摘要:在此期間我的文章會(huì)同步更新在以下地方歡迎大家在自己長(zhǎng)逛的網(wǎng)站中關(guān)注或者我的來(lái)了解我的最新消息推薦大家收藏關(guān)注我的博客網(wǎng)站,因?yàn)槲业淖钚赂呐c文章只會(huì)在這里更新,其他地方的文章可能會(huì)存在更新不及時(shí)或者忘記更新等問(wèn)題。 之前一直在找一款現(xiàn)成的已經(jīng)實(shí)現(xiàn)了如標(biāo)題所說(shuō)的chrome擴(kuò)展, 但卻一直沒(méi)有找到, 于是最近花了私底下的一些空閑時(shí)間去按照自己所想要的功能去打造了這么一款chrome擴(kuò)展,...

    SHERlocked93 評(píng)論0 收藏0
  • GitHub 值得收藏的前端項(xiàng)目[每月更新...]

    摘要:也是一款優(yōu)秀的響應(yīng)式框架站點(diǎn)所使用的一套框架為微信服務(wù)量身設(shè)計(jì)的一套框架一組很小的,響應(yīng)式的組件,你可以在網(wǎng)頁(yè)的項(xiàng)目上到處使用一個(gè)可定制的文件,使瀏覽器呈現(xiàn)的所有元素,更一致和符合現(xiàn)代標(biāo)準(zhǔn)。 GitHub 值得收藏的前端項(xiàng)目 整理與收集的一些比較優(yōu)秀github項(xiàng)目,方便自己閱讀,順便分享出來(lái),大家一起學(xué)習(xí),本篇文章會(huì)持續(xù)更新,版權(quán)歸原作者所有。歡迎github star與fork 預(yù)...

    maxmin 評(píng)論0 收藏0
  • 基于 Github API 的Chrome 插件開(kāi)發(fā)全紀(jì)錄

    摘要:最近基于開(kāi)發(fā)了一款圖床插件,現(xiàn)在已經(jīng)開(kāi)源并上架應(yīng)用商店。通過(guò)方法把轉(zhuǎn)成,然后放在里測(cè)試一下看來(lái)效果是的,接下來(lái)就是對(duì)圖床插件進(jìn)行開(kāi)發(fā)的步驟了。至此,整個(gè)插件的開(kāi)發(fā)發(fā)布流程就已經(jīng)完成了。 showImg(https://user-images.githubusercontent.com/12172868/57382983-8f29b900-71e0-11e9-8fe9-c0f12fd54...

    DoINsiSt 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

閱讀需要支付1元查看
<