Refactor IPFS archiving to support cidv1-base32

This commit is contained in:
Kyle Drake 2019-01-19 03:02:26 -08:00
parent 9b8d7747b8
commit 8b0d396565
8 changed files with 20 additions and 74 deletions

View file

@ -53,7 +53,7 @@ post '/settings/:username/profile' do
@site.update( @site.update(
profile_comments_enabled: params[:site][:profile_comments_enabled], profile_comments_enabled: params[:site][:profile_comments_enabled],
profile_enabled: params[:site][:profile_enabled], profile_enabled: params[:site][:profile_enabled],
archiving_disabled: params[:site][:archiving_disabled] ipfs_archiving_enabled: params[:site][:ipfs_archiving_enabled]
) )
flash[:success] = 'Profile settings changed.' flash[:success] = 'Profile settings changed.'
redirect "/settings/#{@site.username}#profile" redirect "/settings/#{@site.username}#profile"

View file

@ -39,7 +39,7 @@ end
get '/site/:username/archives' do get '/site/:username/archives' do
@site = Site[username: params[:username]] @site = Site[username: params[:username]]
not_found if @site.nil? || @site.archiving_disabled not_found if @site.nil? || !@site.ipfs_archiving_enabled
@title = "Site archives for #{@site.title}" @title = "Site archives for #{@site.title}"
@archives = @site.archives_dataset.limit(300).order(:updated_at.desc).all @archives = @site.archives_dataset.limit(300).order(:updated_at.desc).all
erb :'site/archives' erb :'site/archives'

View file

@ -1,41 +0,0 @@
module Base58
class << self
def int_to_base58(int_val, leading_zero_bytes=0)
alpha = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"
base58_val, base = '', alpha.size
while int_val > 0
int_val, remainder = int_val.divmod(base)
base58_val = alpha[remainder] + base58_val
end
base58_val
end
def base58_to_int(base58_val)
alpha = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"
int_val, base = 0, alpha.size
base58_val.reverse.each_char.with_index do |char,index|
raise ArgumentError, 'Value not a valid Base58 String.' unless char_index = alpha.index(char)
int_val += char_index*(base**index)
end
int_val
end
def base58_to_bytestring(base58_val)
[Base58.decode_base58(base58_val)].pack('H*')
end
def encode_base58(hex)
leading_zero_bytes = (hex.match(/^([0]+)/) ? $1 : '').size / 2
("1"*leading_zero_bytes) + int_to_base58( hex.to_i(16) )
end
def decode_base58(base58_val)
s = base58_to_int(base58_val).to_s(16); s = (s.bytesize.odd? ? '0'+s : s)
s = '' if s == '00'
leading_zero_bytes = (base58_val.match(/^([1]+)/) ? $1 : '').size
s = ("00"*leading_zero_bytes) + s if leading_zero_bytes > 0
s
end
alias_method :base58_to_hex, :decode_base58
end
end

View file

@ -5,21 +5,13 @@ class Archive < Sequel::Model
set_primary_key [:site_id, :ipfs_hash] set_primary_key [:site_id, :ipfs_hash]
unrestrict_primary_key unrestrict_primary_key
MAXIMUM_ARCHIVES_PER_SITE = 100 MAXIMUM_ARCHIVES_PER_SITE = 100
ARCHIVE_WAIT_TIME = 10.minutes ARCHIVE_WAIT_TIME = 1.minute
def before_destroy def before_destroy
unpin unpin
super super
end end
def self.base58_to_hshca(base58)
Base32.encode(Base58.base58_to_bytestring(base58)).gsub('=', '').downcase
end
def hshca_hash
self.class.base58_to_hshca ipfs_hash
end
def unpin def unpin
# Not ideal. An SoA version is in progress. # Not ideal. An SoA version is in progress.
if ENV['RACK_ENV'] == 'production' && $config['ipfs_ssh_host'] && $config['ipfs_ssh_user'] if ENV['RACK_ENV'] == 'production' && $config['ipfs_ssh_host'] && $config['ipfs_ssh_user']
@ -41,6 +33,6 @@ class Archive < Sequel::Model
end end
def url def url
"http://#{hshca_hash}.ipfs.neocitiesops.net" "https://#{ipfs_hash}.ipfs.neocitiesops.net"
end end
end end

View file

@ -707,7 +707,7 @@ class Site < Sequel::Model
purge_cache path purge_cache path
end end
Rye::Cmd.add_command :ipfs, nil, 'add', :r, :Q Rye::Cmd.add_command :ipfs
def add_to_ipfs def add_to_ipfs
# Not ideal. An SoA version is in progress. # Not ideal. An SoA version is in progress.
@ -717,18 +717,21 @@ class Site < Sequel::Model
end end
if $config['ipfs_ssh_host'] && $config['ipfs_ssh_user'] if $config['ipfs_ssh_host'] && $config['ipfs_ssh_user']
rbox = Rye::Box.new $config['ipfs_ssh_host'], :user => $config['ipfs_ssh_user'] rbox = Rye::Box.new $config['ipfs_ssh_host'], user: $config['ipfs_ssh_user']
begin begin
response = rbox.ipfs "sites/#{self.class.sharding_dir self.username}/#{self.username.gsub(/\/|\.\./, '')}" cidv0 = rbox.ipfs(:add, :r, :Q, "sites/#{self.class.sharding_dir self.username}/#{self.username.gsub(/\/|\.\./, '')}").first
cidv1b32 = rbox.ipfs(:cid, :base32, cidv0).first
ensure ensure
rbox.disconnect rbox.disconnect
end end
else else
line = Terrapin::CommandLine.new('ipfs', 'add -r -Q :path') line = Terrapin::CommandLine.new('ipfs', 'add -r -Q :path')
response = line.run path: files_path response = line.run(path: files_path).strip
line = Terrapin::CommandLine.new('ipfs', 'cid base32 :hash')
cidv1b32 = line.run(hash: response).strip
end end
response.strip cidv1b32
end end
def purge_old_archives def purge_old_archives
@ -738,11 +741,6 @@ class Site < Sequel::Model
end end
def archive! def archive!
#if ENV["RACK_ENV"] == 'test'
# ipfs_hash = "QmcKi2ae3uGb1kBg1yBpsuwoVqfmcByNdMiZ2pukxyLWD8"
#else
#end
ipfs_hash = add_to_ipfs ipfs_hash = add_to_ipfs
archive = archives_dataset.where(ipfs_hash: ipfs_hash).first archive = archives_dataset.where(ipfs_hash: ipfs_hash).first
@ -1597,7 +1595,7 @@ class Site < Sequel::Model
] ]
sql.first sql.first
unless archiving_disabled if ipfs_archiving_enabled
ArchiveWorker.perform_in Archive::ARCHIVE_WAIT_TIME, self.id ArchiveWorker.perform_in Archive::ARCHIVE_WAIT_TIME, self.id
end end
end end

View file

@ -17,7 +17,7 @@
</p> </p>
<p> <p>
IPFS archiving is now enabled on all sites. You'll see an IPFS hash link on the site profile, and an archive link that allows you to see past versions of your site (note: this is still a preview, so past site archives may still disappear, but we're working on making it better). IPFS archiving is now enabled on all sites. You'll see an IPFS CID link on the site profile, and an archive link that allows you to see past versions of your site (note: this is still a preview, so past site archives may still disappear, but we're working on making it better).
</p> </p>
<p> <p>
@ -25,7 +25,7 @@
</p> </p>
<p> <p>
<code>$ ipfs pin add -r THE_IPFS_HASH_FOR_YOUR_SITE</code> <code>$ ipfs pin add -r THE_IPFS_CID_FOR_YOUR_SITE</code>
</p> </p>
</article> </article>
</div> </div>

View file

@ -24,10 +24,10 @@
<h3>IPFS Archiving</h3> <h3>IPFS Archiving</h3>
<div style="display: inline-block; text-align: left; margin-bottom: 10px"> <div style="display: inline-block; text-align: left; margin-bottom: 10px">
<input name="site[archiving_disabled]" type="hidden" value="false"> <input name="site[ipfs_archiving_enabled]" type="hidden" value="false">
<input name="site[archiving_disabled]" type="checkbox" value="true" <input name="site[ipfs_archiving_enabled]" type="checkbox" value="true"
<% if @site.archiving_disabled == true %>checked<% end %> <% if @site.ipfs_archiving_enabled == true %>checked<% end %>
> Disable IPFS Archiving > Enable IPFS Archiving
</div> </div>
</div> </div>

View file

@ -11,7 +11,7 @@
<% else %> <% else %>
<table class="table"> <table class="table">
<tr> <tr>
<th>IPFS Hash <small style="display: inline"><a href="/permanent-web">(what is this?)</a></small></th> <th>IPFS CID <small style="display: inline"><a href="/permanent-web">(what is this?)</a></small></th>
<th>Archived Time</th> <th>Archived Time</th>
</tr> </tr>
<% @archives.each do |archive| %> <% @archives.each do |archive| %>
@ -28,9 +28,6 @@
<p> <p>
Archives are captured once every <%= Archive::ARCHIVE_WAIT_TIME / 60 %> minutes, so if you don't see your latest changes, check back later. Archives are captured once every <%= Archive::ARCHIVE_WAIT_TIME / 60 %> minutes, so if you don't see your latest changes, check back later.
</p> </p>
<p>
The URLs are using <a href="https://github.com/neocities/hshca">hshca</a>, a standard for using cryptographic hashes with subdomains.
</p>
<% end %> <% end %>
</article> </article>
</div> </div>