Вытащить все гисты из Github?

Есть ли вызов API или какие-либо скрипты, которые мне не удалось отменить, которые вытащили бы все мои Gists из Github во внешний репозиторий git или просто вернули бы мне список их имен? Я знаю, что каждый из них представляет собой отдельный репозиторий git, поэтому я предположил, что лучшее, что я могу сделать, это получить последний, а затем написать сценарий, чтобы получить их все в моем локальном ящике.

РЕДАКТИРОВАТЬ 1: я знаю, как вытягивать и передавать репозитории git из одного сервиса в другой, я специально ищу людей, у которых есть 411 для сбора авторитетного списка всех Gists, которые у меня есть, частных и public. Я также подумал, что это может быть полезно другим. Речь идет не столько о миграции, сколько о стратегии резервного копирования. . . видов.

EDIT 2: похоже, это невозможно. Очевидно, я недостаточно погуглил, чтобы выполнить поиск в обновленном Github/Gist API. Другие вызовы API работают с простыми командами curl, но не с API v1 для Gist. Тем не менее, API говорит, что TBD для всех частных и общедоступных Gists, так что я думаю, что это ставит в тупик все это, если только просвещенная душа не подключит отвар.

$ curl http://github.com/api/v2/json/repos/show/alharaka
{"repositories":[{"url":"https://github.com/alharaka/babushka","has_wiki":true,"homepage":"http:
... # tons of more output
echo $?
0
$ 

Этот не работает так жарко.

$ curl https://gist.github.com/api/v1/:format/gists/:alharaka
$ echo $?
0
$

EDIT 3: до того, как меня спросили, я заметил разницу в версиях API; не помог и этот "гениальный хак". Хотя все равно очень круто.

$ curl https://gist.github.com/api/v2/:format/gists/:alharaka # Notice v2 instead of v1
$ echo $?
0
$

person songei2f    schedule 10.07.2011    source источник
comment
Я думаю, что этот вопрос нуждается в более четком описании того, что вы пытаетесь сделать.   -  person Soren    schedule 10.07.2011
comment
Я это предвидел. См. выше. Если еще непонятно, не знаю, как еще пояснить: API позволяет мне использовать JSON, аутентифицированный или нет, для получения данных о репозиториях или записи в них. Довольно круто, должен сказать. Тем не менее, функционал еще не весь.   -  person songei2f    schedule 10.07.2011
comment
gist.github.com/1622504   -  person endolith    schedule 18.05.2012


Ответы (11)


Версия 3 GitHub API позволяет это сделать довольно просто:

https://api.github.com/users/koraktor/gists

дает вам список всех Gists пользователя, и этот список предлагает различное количество URL-адресов, включая URL-адреса API для отдельных Gists, таких как

https://api.github.com/gists/921286

См. документацию Gists API v3.

person Koraktor    schedule 17.07.2011
comment
Забыл прокомментировать некоторое время назад. Это выглядит многообещающе. Когда у меня будет система для работы с этим, я свяжусь с вами. Спасибо. - person songei2f; 04.08.2011
comment
Я проверил это, и он не отображает все сведения для пользователя. - person Brad; 01.07.2014
comment
Обратите внимание, что приведенная выше ссылка даст всю суть только на первой странице. Если вам нужно получить доступ ко всей своей сути, поместите ?page=‹number› в конце URL-адреса, по умолчанию он открывает первую 1 страницу. - person Mohd Shahril; 12.07.2017

Существует адаптация API v3 скрипт nicerobot, изначально написанный для API v1:

#!/usr/bin/env python
# Clone or update all a user's gists
# curl -ks https://raw.github.com/gist/5466075/gist-backup.py | USER=fedir python
# USER=fedir python gist-backup.py

import json
import urllib
from subprocess import call
from urllib import urlopen
import os
import math
USER = os.environ['USER']

perpage=30.0
userurl = urlopen('https://api.github.com/users/' + USER)
public_gists = json.load(userurl)
gistcount = public_gists['public_gists']
print "Found gists : " + str(gistcount)
pages = int(math.ceil(float(gistcount)/perpage))
print "Found pages : " + str(pages)

f=open('./contents.txt', 'w+')

for page in range(pages):
    pageNumber = str(page + 1)
    print "Processing page number " + pageNumber
    pageUrl = 'https://api.github.com/users/' + USER  + '/gists?page=' + pageNumber + '&per_page=' + str(int(perpage))
    u = urlopen (pageUrl)
    gists = json.load(u)
    startd = os.getcwd()
    for gist in gists:
        gistd = gist['id']
        gistUrl = 'git://gist.github.com/' + gistd + '.git' 
        if os.path.isdir(gistd):
            os.chdir(gistd)
            call(['git', 'pull', gistUrl])
            os.chdir(startd)
        else:
            call(['git', 'clone', gistUrl])
        if gist['description'] == None:
            description = ''
        else:
            description = gist['description'].encode('utf8').replace("\r",' ').replace("\n",' ')
        print >> f, gist['id'], gistUrl, description
person Fedir RYKHTIK    schedule 26.04.2013
comment
Оператор curl теперь выглядит следующим образом: curl -ks gist.githubusercontent.com/ fedir/5466075/raw/gist-backup.py | ПОЛЬЗОВАТЕЛЬ=федир питон - person philshem; 14.04.2014
comment
@philshem Спасибо, точно, github изменил URL-адрес, я обновил ответ. - person Fedir RYKHTIK; 14.04.2014

Версия скрипта @Fedir, который учитывает разбиение на страницы Github (если у вас есть несколько сотен списков):

#!/usr/bin/env python
# Clone or update all a user's gists
# curl -ks https://raw.github.com/gist/5466075/gist-backup.py | USER=fedir python
# USER=fedir python gist-backup.py

import json
import urllib
from subprocess import call
from urllib import urlopen
import os
import math
USER = os.environ['USER']

perpage=30.0
userurl = urlopen('https://api.github.com/users/' + USER)
public_gists = json.load(userurl)
gistcount = public_gists['public_gists']
print "Found gists : " + str(gistcount)
pages = int(math.ceil(float(gistcount)/perpage))
print "Found pages : " + str(pages)

f=open('./contents.txt', 'w+')

for page in range(pages):
    pageNumber = str(page + 1)
    print "Processing page number " + pageNumber
    pageUrl = 'https://api.github.com/users/' + USER  + '/gists?page=' + pageNumber + '&per_page=' + str(int(perpage))
    u = urlopen (pageUrl)
    gists = json.load(u)
    startd = os.getcwd()
    for gist in gists:
        gistd = gist['id']
        gistUrl = 'git://gist.github.com/' + gistd + '.git' 
        if os.path.isdir(gistd):
            os.chdir(gistd)
            call(['git', 'pull', gistUrl])
            os.chdir(startd)
        else:
            call(['git', 'clone', gistUrl])
person saranicole    schedule 10.07.2013
comment
Хорошее улучшение. Вроде бы, какая итерация страницы должна начинаться с 1, а не с 0, иначе Вы не получите последнюю страницу. - person Fedir RYKHTIK; 23.07.2014
comment
Хороший сценарий, легко адаптируемый, так что он также раскрывает частную суть. - person bryan_basho; 04.10.2014
comment
Как я могу использовать этот скрипт, чтобы вытащить мои секреты? - person yeedle; 04.08.2017
comment
@bryan_basho, как легко адаптировался?? - person brasofilo; 24.12.2018

Основываясь на подсказке в этом ответе, я написал этот простой скрипт Python, который помогает мне.

Это очень минимальный код, практически без проверки ошибок, и он клонирует все списки пользователя в текущий каталог.

#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""Clone all gists of GitHub username given on the command line."""

import subprocess
import sys
import requests

if len(sys.argv) > 1:
    gh_user = sys.argv[1]
else:
    print("Usage: clone-gists.py <GitHub username>")
    sys.exit(1)

req = requests.get('https://api.github.com/users/%s/gists' % gh_user)

for gist in req.json():
    ret = subprocess.call(['git', 'clone', gist['git_pull_url']])
    if ret != 0:
        print("ERROR cloning gist %s. Please check output." % gist['id'])

См. https://gist.github.com/SpotlightKid/042491a9a2987af04a5a для версии, которая обрабатывает обновления. также.

person Chris Arndt    schedule 02.12.2015

В дополнение к нескольким ответам Thomas Traum. Кажется, что пользовательский агент теперь обязателен: http://developer.github.com/v3/#user-agent-required.

Поэтому я сделал собственное упражнение по адресу: https://github.com/sanusart/gists-backup. Он также знает о подкачке, дублирующихся описаниях и отсутствующих описаниях.

person sanusart    schedule 13.03.2014
comment
Ага. Немного обновил. - person sanusart; 11.10.2014

Я написал быстрый скрипт node.js в качестве упражнения, загружает все списки и сохраняет их с тем же именем файла, что и исходная суть, в папке, которая соответствует имени «суть описания». https://gist.github.com/thomastraum/5227541

var request = require('request')
    , path = require('path')
    , fs = require('fs')
    , url = "https://api.github.com/users/thomastraum/gists"
    , savepath = './gists';

request(url, function (error, response, body) {

    if (!error && response.statusCode == 200) {

        gists = JSON.parse( body );
        gists.forEach( function(gist) {

            console.log( "description: ", gist.description );
            var dir = savepath + '/' + gist.description;

            fs.mkdir( dir, function(err){
                for(var file in gist.files){

                    var raw_url = gist.files[file].raw_url;
                    var filename = gist.files[file].filename;

                    console.log( "downloading... " + filename );
                    request(raw_url).pipe(fs.createWriteStream( dir + '/' + filename ));
                }
            });
        });

    }

});
person Thomas Traum    schedule 23.03.2013

Этот рубиновый драгоценный камень, кажется, помогает решить вашу проблему. Я еще не пробовал, но выглядит многообещающе.

Первый

gem install gisty

И нужно поставить

export GISTY_DIR="$HOME/dev/gists"

в вашем .bashrc или .zshrc. В этом каталоге сохраняются ваши файлы.

тебе следует

git config --global github.user your_id
git config --global github.token your_token

добавьте приведенную выше конфигурацию в свой .gitconfig

Использование

  • гистый пост файл1 файл2 ...

    отправляет файл1 и файл2 в суть

  • gisty private_post файл1 файл2 ...

    публикует файл1 и файл2 в частном порядке

  • прямая синхронизация

    Синхронизация со всеми вашими списками

  • gisty pull_all

    Вытащить в локальное репо

  • краткий список

    Список клонированных локальных репозиториев gist

person studiomohawk    schedule 16.08.2011
comment
Сейчас он использует OAuth. На момент написания этой статьи отлично работает с v3 Gist API! - person Mark Jaquith; 02.02.2013

Если все, что вам нужно сделать, это загрузить все списки от определенного пользователя, то этот простой скрипт на Python поможет.

Основная информация для конкретного пользователя предоставляется через API

"https://api.github.com/users/" + username + "/gists"

Вы можете просто просмотреть JSON, предоставляемый API, получить список сущностей, выполнить клонирование или просто загрузить сущности, используя указанный необработанный URL-адрес. Простой скрипт ниже перебирает JSON, извлекает имя файла и необработанный URL-адрес, загружает все списки и сохраняет их в локальной папке.

import requests

# Replace username with correct username
url = "https://api.github.com/users/" + username + "/gists"

resp = requests.get(url)
gists = resp.json()

for gist in gists:
    for file in gist["files"]:
        fname = gist["files"][file]["filename"]
        furl = gist["files"][file]["raw_url"]
        print("{}:{}".format(fname, furl)) # This lists out all gists

        Use this to download all gists
        pyresp = requests.get(furl)

        with open("../folder/" + fname, "wb") as pyfile:
            for chunk in pyresp.iter_content(chunk_size=1024):
                if chunk:
                    pyfile.write(chunk)
        print("{} downloaded successfully".format(fname))
person HVS    schedule 20.12.2015

Обновление за март 2021 г. (Python3)

Если у пользователя есть тонна списков с одним и тем же именем файла, это прекрасно работает.

import requests, json, time, uuid
headers = {"content-type" : "application/json"}
url =  'https://api.github.com/users/ChangeToYourTargetUser/gists?per_page=100&page='

for page in range(1,100):  #do pages start at 1 or 0?
    print('page: ' + str(page))
    r = requests.get(url+str(page), headers = headers)
    metadata_file = './data/my_gist_list.json'
    # Getting metadata
    prettyJson = json.dumps(r.json(), indent=4, sort_keys=True)
    f = open(metadata_file, 'w')
    f.write(prettyJson)

    print('Metadata obtained as {}'.format(metadata_file))

    # Downloading files
    data = r.json()
    counter = 0
    for i in data:
        time.sleep(1.1)
        files_node = i['files']
        file_name = [k for k in files_node][0]
        r = requests.get(files_node[file_name]['raw_url'])
        f = open('./data/{}'.format(str(uuid.uuid4())), 'w')
        f.write(r.text)
        f.close()
        print('Download' + str(i))
        counter += 1

    print('{} files successfully downloaded.'.format(counter))
person juanMSFT    schedule 08.03.2021
comment
это питон? - person Jens Baitinger; 08.03.2021
comment
да, питон версии 3. - person juanMSFT; 12.03.2021

Я использую это, и это работает как шарм!


# first: mkdir user && cd user && cp /path/to/get_gists.py .
# python3 get_gists.py user
import requests
import sys
from subprocess import call

user = sys.argv[1]

r = requests.get('https://api.github.com/users/{0}/gists'.format(user))

for i in r.json():
    call(['git', 'clone', i['git_pull_url']])

    description_file = './{0}/description.txt'.format(i['id'])
    with open(description_file, 'w') as f:
        f.write('{0}\n'.format(i['description']))


person Bryan C Guner    schedule 18.03.2021

А как насчет GitHub CLI?

brew install gh

gh auth login

gh gist list [flags]

  Options:

    -L, --limit int   Maximum number of gists to fetch (default 10)
    --public          Show only public gists
    --secret          Show only secret gists

gh gist clone <gist> [<directory>] [-- <gitflags>...]
person Rogério R. Alcântara    schedule 21.07.2021