tangled
alpha
login
or
join now
mackuba.eu
/
sdk.blue
6
fork
atom
A curated list of libraries & SDKs for the Bluesky API and AT Protocol
6
fork
atom
overview
issues
2
pulls
pipelines
starting to add Tangled repo support (wip)
mackuba.eu
6 months ago
78d84652
d7e5e24b
+116
-7
7 changed files
expand all
collapse all
unified
split
.gitignore
Gemfile
Gemfile.lock
_includes
project_card.html
lib
github_import.rb
metadata_import.rb
tangled_import.rb
+1
.gitignore
···
5
5
.jekyll-metadata
6
6
config/auth.yml
7
7
public
8
8
+
tmp
8
9
vendor
+3
Gemfile
···
2
2
3
3
gem "jekyll", "~> 4.3"
4
4
5
5
+
gem 'minisky', '~> 0.5'
6
6
+
gem 'didkit', '~> 0.2'
7
7
+
5
8
group :jekyll_plugins do
6
9
end
7
10
+5
Gemfile.lock
···
16
16
colorator (1.1.0)
17
17
concurrent-ruby (1.3.5)
18
18
csv (3.3.5)
19
19
+
didkit (0.2.3)
19
20
ed25519 (1.4.0)
20
21
em-websocket (0.5.3)
21
22
eventmachine (>= 0.12.9)
···
100
101
rb-inotify (~> 0.9, >= 0.9.10)
101
102
logger (1.7.0)
102
103
mercenary (0.4.0)
104
104
+
minisky (0.5.0)
105
105
+
base64 (~> 0.1)
103
106
net-scp (4.1.0)
104
107
net-ssh (>= 2.6.5, < 8.0.0)
105
108
net-sftp (4.0.0)
···
164
167
bcrypt_pbkdf (>= 1.0, < 2.0)
165
168
benchmark
166
169
capistrano (~> 2.0)
170
170
+
didkit (~> 0.2)
167
171
ed25519 (>= 1.2, < 2.0)
168
172
jekyll (~> 4.3)
169
173
logger
174
174
+
minisky (~> 0.5)
170
175
171
176
BUNDLED WITH
172
177
2.6.3
+1
-1
_includes/project_card.html
···
19
19
<p class="title">
20
20
<a class="project-name" href="{{ include.project.url }}" target="_blank">{{ info.name }}</a>
21
21
<span class="author"><span class="dot">•</span>
22
22
-
<a href="https://github.com/{{ info.user_login }}" target="_blank">{{ user }}</a></span>
22
22
+
<a href="{{ info.user_profile }}" target="_blank">{{ user }}</a></span>
23
23
{% if info.user_login == "bluesky-social" %}
24
24
<img class="butterfly" src="/assets/images/logo.png" width="16">
25
25
{% endif %}
+6
-5
lib/github_import.rb
···
59
59
60
60
def extract_repo_data(json)
61
61
data = {
62
62
-
'name' => json['name'],
63
63
-
'description' => json['description'],
64
64
-
'user_login' => json['owner']['login'],
65
65
-
'homepage' => json['homepage'],
66
66
-
'stars' => json['stargazers_count']
62
62
+
'name' => json['name'],
63
63
+
'description' => json['description'],
64
64
+
'user_login' => json['owner']['login'],
65
65
+
'user_profile' => "https://github.com/#{json['owner']['login']}",
66
66
+
'homepage' => json['homepage'],
67
67
+
'stars' => json['stargazers_count']
67
68
}
68
69
69
70
if json['license'] && json['license']['spdx_id'] != 'NOASSERTION'
+2
-1
lib/metadata_import.rb
···
1
1
require_relative 'github_import'
2
2
+
require_relative 'tangled_import'
2
3
3
4
class MetadataImport
4
5
OUTPUT_FILE = '_data/metadata.yml'
···
14
15
end
15
16
16
17
urls = get_repo_urls(language)
17
17
-
importers = [GithubImport.new]
18
18
+
importers = [GithubImport.new, TangledImport.new]
18
19
19
20
urls.each do |url|
20
21
if imp = importers.detect { |i| i.url_matches?(url) }
+98
lib/tangled_import.rb
···
1
1
+
require_relative 'npm_import'
2
2
+
require_relative 'requests'
3
3
+
4
4
+
require 'didkit'
5
5
+
require 'fileutils'
6
6
+
require 'minisky'
7
7
+
8
8
+
class TangledImport
9
9
+
include Requests
10
10
+
11
11
+
def initialize
12
12
+
@user_cache = {}
13
13
+
end
14
14
+
15
15
+
def url_matches?(url)
16
16
+
url =~ %r{^https://tangled\.sh/@[\w\-\.]+/[\w\-\.]+}
17
17
+
end
18
18
+
19
19
+
def import_url(url)
20
20
+
url =~ %r{^https://tangled\.sh/@([\w\-\.]+)/([\w\-\.]+)}
21
21
+
user, repo = $1, $2
22
22
+
23
23
+
did = DID.resolve_handle(user)
24
24
+
sky = Minisky.new(did.get_document.pds_endpoint, nil)
25
25
+
26
26
+
repos = sky.fetch_all('com.atproto.repo.listRecords',
27
27
+
{ repo: did, collection: 'sh.tangled.repo', limit: 100 },
28
28
+
field: 'records'
29
29
+
)
30
30
+
31
31
+
repo_record = repos.detect { |x| x['value']['name'] == repo }
32
32
+
33
33
+
repo_folder = clone_repo(user, repo)
34
34
+
35
35
+
data = repo_data_from_record(repo_record['value'])
36
36
+
data['user_login'] = user
37
37
+
data['user_profile'] = "https://tangled.sh/@#{user}"
38
38
+
39
39
+
if tag_info = get_latest_tag(repo_folder)
40
40
+
data['last_tag'] = tag_info
41
41
+
end
42
42
+
43
43
+
data['last_commit'] = get_latest_commit(repo_folder)
44
44
+
45
45
+
data
46
46
+
end
47
47
+
48
48
+
def clone_repo(user, repo)
49
49
+
repos_cache = File.expand_path(File.join(__dir__, '..', 'tmp', 'repos'))
50
50
+
FileUtils.mkdir_p(repos_cache)
51
51
+
52
52
+
dirname = "#{user}_#{repo}"
53
53
+
repo_folder = File.join(repos_cache, dirname)
54
54
+
55
55
+
if Dir.exist?(repo_folder)
56
56
+
Dir.chdir(repo_folder) do
57
57
+
system('git pull')
58
58
+
end
59
59
+
else
60
60
+
Dir.chdir(repos_cache) do
61
61
+
system("git clone https://tangled.sh/@#{user}/#{repo} #{dirname}")
62
62
+
end
63
63
+
end
64
64
+
65
65
+
repo_folder
66
66
+
end
67
67
+
68
68
+
def repo_data_from_record(record)
69
69
+
{
70
70
+
'name' => record['name'],
71
71
+
'description' => record['description'],
72
72
+
}
73
73
+
end
74
74
+
75
75
+
def get_latest_tag(repo_folder)
76
76
+
Dir.chdir(repo_folder) do
77
77
+
newest_tag_commit = %x(git rev-list --tags --max-count=1).strip
78
78
+
return nil if newest_tag_commit.empty?
79
79
+
80
80
+
newest_tag = %x(git tag --points-at "#{newest_tag_commit}" | head -1).strip
81
81
+
timestamp = %x(git show -s --format=%cI "#{newest_tag_commit}").strip
82
82
+
83
83
+
{
84
84
+
'name' => newest_tag,
85
85
+
'committer_date' => Time.parse(timestamp)
86
86
+
}
87
87
+
end
88
88
+
end
89
89
+
90
90
+
def get_latest_commit(repo_folder)
91
91
+
Dir.chdir(repo_folder) do
92
92
+
{
93
93
+
'committer_date' => %x(git show -s --format=%cI).strip.then { |x| Time.parse(x) },
94
94
+
'author_date' => %x(git show -s --format=%aI).strip.then { |x| Time.parse(x) }
95
95
+
}
96
96
+
end
97
97
+
end
98
98
+
end