Something went wrong. Try again.
A curated list of libraries & SDKs for the Bluesky API and AT Protocol forked from mackuba.eu/sdk.blue
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260require_relative 'cargo_import'require_relative 'import_helpers'require_relative 'npm_import'require_relative 'requests'require_relative 'ruby_gems_import'
require 'base64'require 'json'require 'time'
class GithubImport include ImportHelpers include Requests
def initialize @user_cache = {} end
def request_headers { 'Authorization' => "Bearer " + auth_config['github_token'] } end
def url_matches?(url) url =~ %r{^https://github\.com/[\w\-\.]+/[\w\-\.]+} end
def import_url(url, project) url =~ %r{^https://github\.com/([\w\-\.]+)/([\w\-\.]+)} user, repo = $1, $2
repo_info = get_repo_info(user, repo) data = extract_repo_data(repo_info)
if release = get_latest_release(user, repo) data['last_release'] = release end
if tag_info = get_latest_tag(user, repo) data['last_tag'] = tag_info end
if project.language == :ruby gems = get_rubygems_releases(user, repo, project) last_update = gems.map { |gem| gem.last_release_time }.sort.last
if last_update && (release.nil? || last_update > release['published_at']) data['last_release'] = { 'published_at' => last_update } end elsif project.language == :js npm = get_npm_releases(user, repo, project) last_update = npm.map { |n| n.last_release_time }.sort.last
if last_update && (release.nil? || last_update > release['published_at']) data['last_release'] = { 'published_at' => last_update } end elsif project.language == :rust crates = get_cargo_releases(user, repo, project) last_update = crates.map { |c| c.last_release_time }.sort.last
if last_update && (release.nil? || last_update > release['published_at']) data['last_release'] = { 'published_at' => last_update } end end
data['last_commit'] = get_latest_commit(user, repo)
if user_info = get_user_info(user) data['user_name'] = user_info['name'] end
data end
def get_repo_info(user, repo) response = get_response("https://api.github.com/repos/#{user}/#{repo}") raise FetchError.new(response) unless response.code.to_i == 200
JSON.parse(response.body) end
def extract_repo_data(json) data = { 'name' => json['name'], 'description' => json['description'], 'user_login' => json['owner']['login'], 'user_profile' => "https://github.com/#{json['owner']['login']}", 'homepage' => json['homepage'], 'stars' => json['stargazers_count'] }
if json['license'] && json['license']['spdx_id'] != 'NOASSERTION' data['license'] = json['license']['spdx_id'] end
data end
def get_latest_release(user, repo) response = get_response("https://api.github.com/repos/#{user}/#{repo}/releases/latest")
if response.code.to_i == 200 json = JSON.parse(response.body)
{ 'tag_name' => json['tag_name'], 'name' => json['name'], 'draft' => json['draft'], 'prerelease' => json['prerelease'], 'created_at' => Time.parse(json['created_at']), 'published_at' => Time.parse(json['published_at']) } elsif response.code.to_i == 404 nil else raise FetchError.new(response) end end
def get_latest_tag(user, repo) response = get_response("https://api.github.com/repos/#{user}/#{repo}/tags") raise FetchError.new(response) unless response.code.to_i == 200
json = JSON.parse(response.body)
if tag = json.first tag_name = tag['name'] response = get_response(tag['commit']['url']) raise FetchError.new(response) unless response.code.to_i == 200
json = JSON.parse(response.body) { 'name' => tag_name, 'author_date' => Time.parse(json['commit']['author']['date']), 'committer_date' => Time.parse(json['commit']['committer']['date']) } else nil end end
def get_latest_commit(user, repo) response = get_response("https://api.github.com/repos/#{user}/#{repo}/commits") raise FetchError.new(response) unless response.code.to_i == 200
json = JSON.parse(response.body)
if commit = json.first { 'author_date' => Time.parse(commit['commit']['author']['date']), 'committer_date' => Time.parse(commit['commit']['committer']['date']) } else raise FetchError.new(response) end end
def get_user_info(user) @user_cache[user] ||= begin response = get_response("https://api.github.com/users/#{user}") raise FetchError.new(response) unless response.code.to_i == 200
JSON.parse(response.body) end end
def get_npm_releases(user, repo, project) sleep 5
search_url = URI("https://api.github.com/search/code") search_url.query = URI.encode_www_form(q: "repo:#{user}/#{repo} filename:package.json", per_page: 100) response = get_response(search_url, retries: 5) raise FetchError.new(response) unless response.code.to_i == 200
json = JSON.parse(response.body) releases = []
json['items'].each do |file| response = get_response(file['url'], retries: 5) raise FetchError.new(response) unless response.code.to_i == 200
details = JSON.parse(response.body) contents = Base64.decode64(details['content']) package = NPMImport::PackageJSON.new(contents)
next if package.version.nil? || package.private?
if npm = NPMImport.new.get_package_info(package.name) package_repo_url = normalize_repo_url(npm.repository_url) package_homepage = normalize_repo_url(npm.homepage_url)
if project.urls.map { |u| normalize_repo_url(u) }.any? { |u| u == package_repo_url || u == package_homepage } releases << npm end end end
releases end
def get_cargo_releases(user, repo, project) sleep 5
search_url = URI("https://api.github.com/search/code") search_url.query = URI.encode_www_form(q: "repo:#{user}/#{repo} filename:Cargo.toml", per_page: 100) response = get_response(search_url) raise FetchError.new(response) unless response.code.to_i == 200
json = JSON.parse(response.body) releases = []
json['items'].each do |file| response = get_response(file['url']) raise FetchError.new(response) unless response.code.to_i == 200
details = JSON.parse(response.body) contents = Base64.decode64(details['content']) package = CargoImport::CargoToml.new(contents)
next if package.name.nil?
if crate = CargoImport.new.get_crate_info(package.name) crate_repo_url = normalize_repo_url(crate.repository_url) crate_homepage = normalize_repo_url(crate.homepage_url)
if project.urls.map { |u| normalize_repo_url(u) }.any? { |u| u == crate_repo_url || u == crate_homepage } releases << crate end end end
releases end
def get_rubygems_releases(user, repo, project) response = get_response("https://api.github.com/repos/#{user}/#{repo}/contents") raise FetchError.new(response) unless response.code.to_i == 200
gemspec_files = JSON.parse(response.body) .select { |file| file['type'] == 'file' && file['name'].end_with?('.gemspec') } .sort_by { |file| file['name'] }
releases = []
gemspec_files.each do |gemspec_file| response = get_response(gemspec_file['url']) raise FetchError.new(response) unless response.code.to_i == 200
details = JSON.parse(response.body) gemspec = RubyGemsImport::Gemspec.new(Base64.decode64(details['content'])) next unless gemspec.name
if gem = RubyGemsImport.new.get_gem_info(gemspec.name) releases << gem end end
releases endend