Apakah ada link ke GitHub untuk mendownload file di rilis terbaru repositori?

144

Menggunakan fitur Rilis GitHub , dimungkinkan untuk menyediakan tautan untuk mengunduh versi tertentu dari perangkat lunak yang diterbitkan. Namun, setiap kali rilis dibuat, gh-page juga perlu diperbarui.

Apakah ada cara untuk mendapatkan tautan ke file tertentu dari versi terbaru perangkat lunak apa pun?

misalnya, ini akan menjadi tautan statis:

https://github.com/USER/PROJECT/releases/download/v0.0.0/package.zip

Yang saya suka adalah seperti ini:

https://github.com/USER/PROJECT/releases/download/latest/package.zip

CATATAN: Perbedaan antara pertanyaan ini dan rilis terbaru GitHub adalah pertanyaan ini secara khusus meminta untuk mendapatkan akses ke file, bukan halaman rilis terbaru GitHub

Christian Rondeau
sumber
1
Ini didukung secara native oleh Github sekarang (dengan sedikit perbedaan dalam format URL). Lihat stackoverflow.com/questions/24987542/…
wisbucky

Jawaban:

48

Beberapa tahun terlambat, tetapi saya baru saja menerapkan pengalihan sederhana untuk mendukung https://github.com/USER/PROJECT/releases/latest/download/package.zip. Itu harus dialihkan ke package.zipaset rilis dengan tag terbaru . Semoga bermanfaat!

Joshua Peek
sumber
3
Didokumentasikan di help.github.com/en/articles/linking-to-releases : Jika Anda ingin menautkan langsung ke unduhan aset rilis terbaru Anda, Anda dapat menautkan ke / owner / name / release / latest / download / asset -name.zip
Liam
4
Akan sangat membantu jika fitur ini berfungsi dengan nama aset berversi.
Liam
3
Perhatikan bahwa perintah tersebut diaktifkan .../releases/latest/download/...vs .../releases/download/v0.0.0/.... Anda tidak bisa begitu saja mengganti v0.0.0dengan latestdi tempat.
wisbucky
2
@Joshua Peek Mungkin Anda bisa memperluas ini untuk memperluas "TERBARU" dalam nama aset menjadi string versi? Itu akan membuatnya berguna untuk aset dengan nomor versi di namanya.
jwatt
1
Bagaimana dengan mengunduh kode sumber terbaru? Apa nama aset dalam kasus itu?
skd
60

Solusi Linux untuk mendapatkan tautan unduhan aset rilis terbaru (hanya berfungsi jika rilis hanya memiliki satu aset)

curl -s https://api.github.com/repos/boxbilling/boxbilling/releases/latest | grep browser_download_url | cut -d '"' -f 4
Putna
sumber
7
Satu grep tambahan di pipeline akan menemukan file untuk distribusi dan arsitektur Anda. Untuk editor teks atom pada Ubuntu 64-bit:curl -s https://api.github.com/repos/atom/atom/releases | grep browser_download_url | grep '64[.]deb' | head -n 1 | cut -d '"' -f 4
kompor
3
Tidak ada lagi browser_download_url. Anda dapat menggunakan tarball_url sekarang. curl -s https://api.github.com/repos/git-ftp/git-ftp/releases | grep tarball_url | head -n 1 | cut -d '"' -f 4
maikel
4
@maikel grepping untuk browser_download_url masih berfungsi untuk saya.
Léo Lam
@ léo-lam Anda benar. Hanya jika Anda tidak memiliki aset, Anda dapat menggunakan tarball_url untuk mendapatkan kode sumbernya.
maikel
Anda hanya dapat memuat rilis terbaru untuk menghindari | head -n 1 api.github.com/repos/boxbilling/boxbilling/releases/latest
ya.teck
29

Anda dapat melakukan permintaan ajax untuk mendapatkan URL unduhan rilis terbaru menggunakan GitHub Releases API . Ini juga menunjukkan kapan dirilis dan jumlah unduhan:

function GetLatestReleaseInfo() {
  $.getJSON("https://api.github.com/repos/ShareX/ShareX/releases/latest").done(function(release) {
    var asset = release.assets[0];
    var downloadCount = 0;
    for (var i = 0; i < release.assets.length; i++) {
      downloadCount += release.assets[i].download_count;
    }
    var oneHour = 60 * 60 * 1000;
    var oneDay = 24 * oneHour;
    var dateDiff = new Date() - new Date(asset.updated_at);
    var timeAgo;
    if (dateDiff < oneDay) {
      timeAgo = (dateDiff / oneHour).toFixed(1) + " hours ago";
    } else {
      timeAgo = (dateDiff / oneDay).toFixed(1) + " days ago";
    }
    var releaseInfo = release.name + " was updated " + timeAgo + " and downloaded " + downloadCount.toLocaleString() + " times.";
    $(".download").attr("href", asset.browser_download_url);
    $(".release-info").text(releaseInfo);
    $(".release-info").fadeIn("slow");
  });
}

GetLatestReleaseInfo();
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<a class="download" href="https://github.com/ShareX/ShareX/releases/latest">Download</a>
<p class="release-info"></p>

Penting bagi Anda untuk mengatur URL tombol default ke halaman rilis (seperti https://github.com/ShareX/ShareX/releases/latest ) jadi jika browser tidak mendukung ajax (atau javascript) atau terlalu lambat untuk dapatkan URL-nya, tombol unduh akan tetap berfungsi.

Saat permintaan Ajax selesai, URL tombol ini akan berubah secara otomatis menjadi URL unduhan langsung.

Edit:

Saya juga membuat halaman unduhan yang menampilkan beberapa rilis yang dapat Anda temukan di sini: https://getsharex.com/downloads/

Kode sumbernya : https://github.com/ShareX/sharex.github.io/blob/master/js/downloads.js

Jaex
sumber
Keren. Tahukah Anda mengapa ini mungkin tidak berhasil? curl -s https://api.github.com/repos/DataTables/DataTables/releases/latest
Volte
Karena Anda tidak memiliki rilis apa pun. Periksa: api.github.com/repos/DataTables/DataTables/releases
Jaex
Funky ... github.com/DataTables/DataTables/releases menunjukkan banyak rilis. Pasti ada ambiguitas di sana.
Volte
Tidak, ini hanya tag. Tidak ada rilis.
MrD
2
github.com/jquery/jquery/releases mereka tidak memiliki rilis apa pun. Itu hanya tag versi.
Jaex
15

Dari baris perintah menggunakan curldan jq, ambil file pertama dari rilis terbaru :

curl -s https://api.github.com/repos/porjo/staticserve/releases/latest | \
  jq --raw-output '.assets[0] | .browser_download_url'
IanB
sumber
1
jq --raw-outputadalah cara yang lebih bersih untuk menghilangkan tanda kutip. Jika Anda hanya menginginkan yang terbaru, lebih murah untuk mengambil .../releases/latestdan melepaskan .[0] | . Tetapi mengambil semua rilis memungkinkan pertanyaan seperti jq '.[] | .assets[] | .browser_download_url | select(endswith(".deb"))'...
Beni Cherniavsky-Paskin
Terima kasih Beni, saya memperluas ini untuk mendapatkan docker-compose terbaru curl --silent "https://api.github.com/repos/docker/compose/releases/latest" | jq --arg PLATFORM_ARCH "$(echo `uname -s`-`uname -m`)" -r '.assets[] | select(.name | endswith($PLATFORM_ARCH)).browser_download_url' | xargs sudo curl -L -o /usr/local/bin/docker-compose --url ,. Akhirnya adalah keajaiban dan menggunakan lengkungan memungkinkan saya untuk mengabaikan file apa pun.sha256 yang biasanya ada tanpa melakukan |head -n 1.
dragon788
8

Solusi Linux lain menggunakan curl dan wget untuk mengunduh satu file biner dari halaman rilis terbaru

curl -s -L https://github.com/bosun-monitor/bosun/releases/latest | egrep -o '/bosun-monitor/bosun/releases/download/[0-9]*/scollector-linux-armv6' | wget --base=http://github.com/ -i - -O scollector

Penjelasan:

curl -s -L adalah mengunduh diam-diam HTML rilis terbaru (setelah mengikuti pengalihan)

egrep -o '...' menggunakan regex untuk menemukan file yang Anda inginkan

wget --base=http://github.com/ -i - mengonversi jalur relatif dari pipa ke URL absolut

dan -O scollectormengatur nama file yang diinginkan.

mungkin dapat menambahkan -Nke unduhan hanya jika file lebih baru tetapi S3 memberikan kesalahan 403 Terlarang.

Greg Bray
sumber
3
Tujuan saya adalah membuat link di situs web yang selalu mengarah ke versi terbaru. Perintah linux tidak akan mengizinkannya.
Christian Rondeau
1
Inilah yang saya cari tetapi Anda harus memastikan Anda memiliki karakter pelarian yang benar untuk wildcard dan titik saat menggunakan grep.
T. Thomas
@TdotThomas terima kasih, itulah petunjuk yang saya butuhkan untuk nomor rilis semver untuk keluar dari periode \.misalnya diperlukan 2.2.0/download/[0-9\.]*/
Jeff Puckett
Tidak, tidak. Tidak ada karakter melarikan diri. Tapi saya akan menganggap opsional vsebagai awalan, seperti tag v0.11.0. Cukup masukkan curl -s -L https://github.com/bosun-monitor/bosun/releases/latest | egrep -o '/bosun-monitor/bosun/releases/download/[v]?[0-9.]*/scollector-linux-armv6' | wget --base=http://github.com/ -i - -O scollectorCLI Anda dan itu bekerja dengan sempurna. Terima kasih, Greg !!
MS Berends
7

Seperti disebutkan sebelumnya, jq berguna untuk ini dan REST API lainnya .

tl; dr - detail selengkapnya di bawah

Dengan asumsi Anda menginginkan rilis macOS :

URL=$( curl -s "https://api.github.com/repos/atom/atom/releases/latest" \
   | jq -r '.assets[] | select(.name=="atom-mac.zip") | .browser_download_url' )
curl -LO "$URL"

Solusi untuk pelepasan atom

Perhatikan bahwa setiap repo dapat memiliki cara berbeda untuk menyediakan artefak yang diinginkan, jadi saya akan mendemonstrasikan untuk yang berperilaku baik seperti atom .

Dapatkan nama-nama aset yang diterbitkan

curl -s "https://api.github.com/repos/atom/atom/releases/latest" \
    | jq -r '.assets[] | .name'

atom-1.15.0-delta.nupkg
atom-1.15.0-full.nupkg
atom-amd64.deb
...

Dapatkan URL unduhan untuk aset yang diinginkan

Di bawah atom-mac adalah aset yang saya inginkan melalui jqselect(.name=="atom-mac.zip")

curl -s "https://api.github.com/repos/atom/atom/releases/latest" \
    | jq -r '.assets[] | select(.name=="atom-mac.zip") | .browser_download_url'

https://github.com/atom/atom/releases/download/v1.15.0/atom-mac.zip

Unduh artefak

curl -LO "https://github.com/atom/atom/releases/download/v1.15.0/atom-mac.zip"

jq Playground

sintaks jq bisa jadi sulit. Inilah tempat bermain untuk bereksperimen dengan hal jq- hal di atas: https://jqplay.org/s/h6_LfoEHLZ

Keamanan

Anda harus mengambil tindakan untuk memastikan validitas artefak yang diunduh melalui sha256sum dan gpg , jika memungkinkan.

Mike D
sumber
7

Solusi menggunakan (an inner) wget untuk mendapatkan konten HTML, filter untuk file zip (dengan egrep) dan kemudian unduh file zip (dengan wget luar).

wget https://github.com/$(wget https://github.com/<USER>/<PROJECT>/releases/latest -O - | egrep '/.*/.*/.*zip' -o)
Rolf
sumber
6

Cukup gunakan salah satu url di bawah untuk mengunduh rilis terbaru: (ambil url dari proyek boxbilling misalnya): https://api.github.com/repos/boxbilling/boxbilling/releases

Unduh rilis terbaru sebagai zip: https://api.github.com/repos/boxbilling/boxbilling/zipball

Unduh rilis terbaru sebagai tarball: https://api.github.com/repos/boxbilling/boxbilling/tarball

Klik salah satu url untuk mengunduh rilis terbaru secara instan. Saat saya menulis baris ini, sekarang: boxbilling-boxbilling-4.20-30-g452ad1c [.zip / .tar.gz]

PEMBARUAN: Menemukan url lain di file log saya (lihat contoh di atas) https://codeload.github.com/boxbilling/boxbilling/legacy.tar.gz/master

Lahmizzar
sumber
4
itu adalah repo bukan rilis
Wobbles
5

Tidak memungkinkan menurut dukungan GitHub pada 23-05-2018

Menghubungi [email protected] pada 2018-05-23 dengan pesan:

Bisakah Anda mengonfirmasi bahwa tidak ada cara selain mengotak-atik API saat ini?

dan mereka menjawab:

Terima kasih telah menghubungi. Kami merekomendasikan penggunaan API untuk mengambil rilis terbaru karena pendekatan tersebut stabil, didokumentasikan, dan tidak dapat berubah dalam waktu dekat:

https://developer.github.com/v3/repos/releases/#get-the-latest-release

Saya juga akan terus melacak ini di: https://github.com/isaacs/github/issues/658

Solusi Python tanpa ketergantungan apa pun

Kuat dan portabel:

#!/usr/bin/env python3

import json
import urllib.request

_json = json.loads(urllib.request.urlopen(urllib.request.Request(
    'https://api.github.com/repos/cirosantilli/linux-kernel-module-cheat/releases/latest',
     headers={'Accept': 'application/vnd.github.v3+json'},
)).read())
asset = _json['assets'][0]
urllib.request.urlretrieve(asset['browser_download_url'], asset['name'])

Lihat juga:

Pertimbangkan juga pra-rilis

/latesttidak melihat pra-rilis, tetapi itu mudah dilakukan karena /releasesmenampilkan yang terbaru terlebih dahulu:

#!/usr/bin/env python3

import json
import urllib.request

_json = json.loads(urllib.request.urlopen(urllib.request.Request(
    'https://api.github.com/repos/cirosantilli/linux-kernel-module-cheat/releases',
     headers={'Accept': 'application/vnd.github.v3+json'},
)).read())
asset = _json[0]['assets'][0]
urllib.request.urlretrieve(asset['browser_download_url'], asset['name'])
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功
sumber
4

The Menghubungkan ke rilis halaman bantuan tidak menyebutkan "Rilis terbaru" tombol, tapi itu tidak membuat Anda link download.

https://github.com/reactiveui/ReactiveUI/releases/latest

Untuk itu, Anda perlu mendapatkan tag terbaru terlebih dahulu (seperti yang disebutkan di " GitHub URL untuk rilis terbaru dari file unduhan ? "):

latestTag=$(git describe --tags `git rev-list --tags --max-count=1`)

curl -L https://github.com/reactiveui/ReactiveUI/releases/download/$latestTag/ReactiveUI-$latestTag.zip
VonC
sumber
2
Ini masih membutuhkan untuk mendorong versi baru dari gh-pagescabang setiap kali rilis baru dibuat; tujuannya adalah untuk memiliki tautan statis yang dapat saya gunakan untuk hanya "merujuk ke versi terbaru". Saat ini pilihan terbaik saya adalah hanya merujuk ke halaman rilis.
Christian Rondeau
@ChristianRondeau Saya setuju. Saya tidak melihat di mana pun di API cara untuk merujuk url lengkap arsip rilis "terbaru" secara langsung.
VonC
Namun, terima kasih atas tipnya; jika tidak ada jawaban yang lebih baik yang diberikan, saya mungkin akan membuat skrip untuk memperbarui halaman-gh menggunakan skrip Anda.
Christian Rondeau
3

Github sekarang mendukung tautan statis untuk mengunduh file individual dari rilis terbaru: https://help.github.com/en/articles/linking-to-releases

https://github.com/USER/PROJECT/releases/latest/download/package.zip
Kaloyan Raev
sumber
Jawaban yang sama telah diposting 6 bulan sebelumnya: stackoverflow.com/questions/24987542/…
wisbucky
Terima kasih telah menyampaikan hal ini kepada saya @wisbucky, saya menolaknya karena kedengarannya seperti implementasi khusus dari pengembang, bukan seseorang dari StackOverflow!
Christian Rondeau
2

dalam PHP - alihkan ke unduhan rilis terbaru. Cukup gunakan ruang web Anda

<?php

/**
 * Download latest release from github release articats
 * License: Public Domain
 */

define('REPO', 'imi-digital/iRobo');

$opts = [
    'http' => [
        'method' => 'GET',
        'header' => [
            'User-Agent: PHP'
        ]
    ]
];

$context = stream_context_create($opts);

$releases = file_get_contents('https://api.github.com/repos/' . REPO . '/releases', false, $context);
$releases = json_decode($releases);

$url = $releases[0]->assets[0]->browser_download_url;

header('Location: ' . $url);
Alex
sumber
2

Jika Anda ingin menggunakan, curlAnda dapat mencoba dengan -w '%{url_effective}'mencetak URL setelah rantai pengalihan (diikuti oleh curl jika Anda memanggilnya dengan -L). Jadi misalnya

curl -sLo /dev/null -w '%{url_effective}' https://github.com/github-tools/github/releases/latest

keluaran https://github.com/github-tools/github/releases/tag/v3.1.0.

Mapio
sumber
2

Seperti kebanyakan pengunjung pertanyaan ini, saya benar-benar frustrasi dengan menemukan cara untuk sepenuhnya mengunduh otomatis dari rilis versi TERBARU atau repo di Github. Manfaat dari solusi ini adalah Anda tidak perlu menentukan rilis atau nomor tag - ini hanya akan mengambil yang TERBARU .

Saya melakukan pengujian saya menggunakan pengguna & repo Github berikut:

" f1linux " = Pengguna Github
" pi-ap " = Repo

Nama direktori sembarang tempat penyimpanan repo diatur di:

--one-top-level="pi-ap"

LANGSUNG:

Menggunakan alat " Pengembang Web " Firefox (3 bilah di sudut kanan atas), di bagian " Jaringan " yang saya temukan https://api.github.comdialihkan ke https://codeload.github.com, jadi dengan menyalurkan curlke tarsaya dapat mengambil repo berversi terbaru dan menyimpannya ke nama yang dapat diprediksi sehingga itu bisa dioperasikan pada:

curl https://codeload.github.com/f1linux/pi-ap/legacy.tar.gz/master | tar xzvf - --one-top-level="pi-ap" --strip-components 1

TIDAK LANGSUNG:

Setelah saya mendapatkan unduhan otomatis sepenuhnya dari rilis versi terbaru menggunakan URL LANGSUNG , saya mengalihkan perhatian saya untuk mencapai hal yang sama dengan pengalihan Github:

curl -L https://api.github.com/repos/f1linux/pi-ap/tarball | tar xzvf - --one-top-level="pi-ap" --strip-components 1

Metode yang Disukai:

Namun, harap dicatat sesuai komentar Von di bawah ini bahwa TIDAK LANGSUNG adalah metode yang disukai

Validasi Lebih Lanjut:

Untuk memastikan hasil saya dapat direproduksi ke repo Github berversi lain, pengujian yang sama berhasil dijalankan untuk doctltoolkit api Digital Ocean (yang sebenarnya memulai seluruh latihan!):

Baik LANGSUNG dan TIDAK LANGSUNG bekerja menggunakan formulir yang sama seperti di atas, hanya mengubah nama pengguna & repo:

LANGSUNG:

curl https://codeload.github.com/digitalocean/doctl/legacy.tar.gz/master | tar xzvf - --one-top-level="doctl" --strip-components 1 

TIDAK LANGSUNG:

curl -L https://api.github.com/repos/digitalocean/doctl/tarball | tar xzvf - --one-top-level="doctl" --strip-components 1
F1Linux
sumber
Menarik. Suara positif. Saya tidak mengetahui tentang codeload, meskipun menggunakan API masih disarankan: stackoverflow.com/a/60198721/6309
VonC
Saya mengalami kesedihan dengan pengalihan pada awalnya dan seperti yang disebutkan dalam jawaban alat "Pengembang Web" Firefox membuat saya pergi ke jalur yang benar. Tidak bisa berhenti di situ, harus membuatnya bekerja dengan pengalihan. Terima kasih atas upvote- sangat berterima kasih!
F1Linux
1
@VonC Baru saja menambahkan tanggapan Anda ke jawabannya. Saya sama sekali tidak menyadarinya. Terima kasih telah menunjukkannya!
F1Linux
1

Saya ingin mengunduh rilis dari README.mdfile dalam deskripsi repositori. Di sana, saya tidak dapat menjalankan JavaScript.

Saya dapat menambahkan tautan seperti ini ke file README atau halaman github untuk semua repositori saya:

  • https://niccokunzmann.github.io/download_latest/<USER>/<REPOSITORY>/<FILE>
    Unduh file rilis terbaru dari repositori.
  • https://niccokunzmann.github.io/download_latest/<FILE>
    Ini berfungsi karena perujuk JavaScript ditetapkan dan repositori yang akan diunduh ditentukan document.referrer. Dengan demikian, tautan juga akan berfungsi untuk garpu.

Anda dapat menemukan kode sumbernya di sini , fork atau cukup gunakan repo saya.

Pengguna
sumber
1
Itu ide yang cukup pintar :) itu tidak akan berfungsi ketika berbagi tautan atau menggunakan curl atau sejenisnya, tetapi ide ini dapat dilakukan di halaman github proyek.
Christian Rondeau
1
Karena ini dimungkinkan sebagai situs web JavaScript, seseorang juga dapat menulis layanan yang melakukan pengalihan. download-service.com/organization/repository/artifact
Pengguna
1

Ini untuk Linux.

Saya melihat jawaban yang diterima di atas

A few years late, but I just implemented a simple redirect to support https://github.com/USER/PROJECT/releases/latest/download/package.zip. That should redirected to the latest tagged package.zip release asset. Hope it's handy!

oleh Joshua Peek tetapi sebuah komentar mencatat itu tidak mendukung nama file berversi.

Setelah mencari sedikit, saya membuat panggilan satu baris yang berfungsi untuk nama file berversi. Ini menggunakan curl untuk mendapatkan versi file terbaru dan kemudian menggunakan dukungan pengalihan yang ditambahkan untuk mengunduh file berversi terbaru.

wget $'https://github.com/<UMBRELLA PROJECT>/<REPO NAME>/releases/latest/download/<FILE NAME START>-'$(curl -s https://github.com/<UMBRELLA PROJECT>/<REPO NAME>/releases/latest | grep -o -P '(?<=releases/tag/).*(?=\">)')$'<FILE NAME END>'

Jadi itu menargetkan file yang dinamai seperti <REPO NAME>-linux64_arm-<VERSION NUMBER>.tar.gzitu di halaman web https://github.com/<UMBRELLA PROJECT>/<REPO NAME>/releases/latestsetelah itu dialihkan. Ini dilakukan dengan mencari <VERSION NUMBER>antara releases/tag/dan ">dalam teks yang dikembalikan dari panggilan curl. Jadi untuk menjadi sangat eksplisit, <FILE NAME START>adalah <REPO NAME>-linux64_arm-dan <FILE NAME END>adalah .tar.gzdalam contoh di atas. Dapatkan bit STARTdan ENDdengan melihat apa yang https://github.com/<UMBRELLA PROJECT>/<REPO NAME>/releases/latestdigunakan sebagai skema penamaan file.

Saya mengarang ini dengan meniru bagaimana grep dan curl digunakan oleh orang lain dan baru saja mempelajari semua ini sekarang, jadi beri tahu saya jika itu melakukan sesuatu yang benar-benar nakal yang bahkan tidak saya pahami! Juga saya katakan <UMBRELLA PROJECT>tetapi nama pengguna harus bisa pergi ke sana dengan baik juga. Teriak ke https://stackoverflow.com/a/13245961/2403531 untuk panggilan grep, https://unix.stackexchange.com/a/10264 untuk $ string $ concatenation.

pengguna2403531
sumber
1

Jika Anda ingin menggunakan di alpine , ikuti langkah-langkah berikut

 apk add curl ca-certificates wget

wget -q $(curl -s https://api.github.com/repos/<USER>/<REPOSITORY>/releases/latest | grep browser_download_url | grep "$ARCH" | cut -d '"' -f 4)

-q di wget adalah mode cukup, jika Anda ingin melihat output maka gunakan tanpa q

Hariharnath Paduchuru
sumber
0

Jika repo hanya menggunakan tag daripada rilis - cf. jQuery - solusi yang didasarkan pada satu URL tidak berfungsi.

Alih-alih, Anda harus menanyakan semua tag, mengurutkannya, dan menyusun URL unduhan. Saya menerapkan solusi seperti itu untuk bahasa Go dan repo jQuery: Tautkan ke Github .

Mungkin, ini membantu seseorang.

SommerEngineering
sumber