+require 'digest'
+require 'ethon'
+
+module OSDN; module CLI; module Command
+ class FrsUpload < Base
+ @@_show_progress = false
+ def self._show_progress
+ @@_show_progress
+ end
+ def self._show_progress=(v)
+ need_reset = (!!@@_show_progress != !!v)
+ @@_show_progress = v
+ need_reset and _reset_all_typhoeus_pool
+ end
+
+ def self._reset_all_typhoeus_pool
+ first_easyid = nil
+ while true
+ e = Typhoeus::Pool.get
+ Typhoeus::Pool.release(e)
+ e.__id__ == first_easyid and break
+ first_easyid ||= e.__id__
+ end
+ end
+ end
+end; end; end
+
+module Ethon
+ class Easy
+ module Callbacks
+ alias_method :set_callbacks_orig, :set_callbacks
+ def set_callbacks
+ set_callbacks_orig
+ if OSDN::CLI::Command::FrsUpload._show_progress
+ Curl.set_option(:noprogress, false, handle)
+ else
+ Curl.set_option(:noprogress, true, handle)
+ end
+ end
+ end
+ end
+end
+
module OSDN; module CLI; module Command
class FrsUpload < Base
def help
Pathname.glob(@target_dir+'*').each do |pdir|
unless load_variables(pdir).package_id
logger.info "Createing new package '#{pdir.basename}'"
- pinfo = api.create_package target_proj, pdir.basename, visibility: @visibility
- update_variables pdir, package_id: pinfo.id
+ if @dry_run
+ pinfo = Hashie::Mash.new id: '(dry-run)', name: pdir.basename, url: '(dry-run)'
+ else
+ pinfo = api.create_package target_proj, pdir.basename, visibility: @visibility
+ update_variables pdir, package_id: pinfo.id
+ end
$stdout.puts "New package '#{pinfo.name}' has been created; #{pinfo.url}"
end
rinfo = api.get_release target_proj, target_package(rdir), target_release(rdir)
else vars.release_id
logger.info "Createing new release '#{rdir.basename}'"
- rinfo = nil
- if api.respond_to? :create_reelase # TODO: remove, just typo...
- rinfo = api.create_reelase target_proj, target_package(rdir), rdir.basename, visibility: @visibility
+ if @dry_run
+ rinfo = Hashie::Mash.new id: '(dry-run)', name: rdir.basename, url: '(dry-run)', files: []
else
rinfo = api.create_release target_proj, target_package(rdir), rdir.basename, visibility: @visibility
+ update_variables rdir, release_id: rinfo.id
end
- update_variables rdir, release_id: rinfo.id
$stdout.puts "New release '#{rinfo.name}' has been created; #{rinfo.url}"
end
next
end
- if rinfo.files.find { |f| f.name == file.basename.to_s }
+ logger.debug "Calculating digest for #{file}..."
+ digests = {
+ sha256: hexdigest(Digest::SHA256, file),
+ sha1: hexdigest(Digest::SHA1, file),
+ md5: hexdigest(Digest::MD5, file),
+ }
+ if remote_f = rinfo.files.find { |f| f.name == file.basename.to_s }
+ if digests.find { |type, dig| dig != remote_f.send("digest_#{type}") }
+ logger.error "#{file} was changed from remote file! Please delete remote file before uploading new one."
+ end
logger.warn "Skip already uploaded file '#{file}'"
else
logger.info "Uploading file #{file} (#{file.size} bytes)"
- # TODO: show progress bar!
- finfo = api.create_release_file target_proj, target_package(rdir), target_release(rdir), file.open, visibility: @visibility
- logger.info "Upload completed."
+ if @dry_run
+ finfo = Hashie::Mash.new id: '(dry-run)', url: '(dry-run)'
+ else
+ logger.level <= Logger::INFO and
+ self.class._show_progress = true
+ fio = file.open
+ logger.info "Starting upload #{file}..."
+ finfo = api.create_release_file target_proj, target_package(rdir), target_release(rdir), fio, visibility: @visibility
+ fio.close
+ self.class._show_progress = false
+ if digests.find { |type, dig| dig != finfo.send("digest_#{type}") }
+ logger.error "File digests are mismatch! Upload file #{file} may be broken! Please check."
+ else
+ logger.info "Upload completed."
+ end
+ end
$stdout.puts "New file '#{file}' has been uploaded; #{finfo.url}"
end
end
def api
OSDNClient::ProjectApi.new
end
+
+ def hexdigest(klass, file)
+ fio = file.open
+ dig = klass.new
+ while buf = fio.read(1024*1024) and buf.length > 0
+ dig << buf
+ end
+ fio.close
+ dig.hexdigest
+ end
+
end
end; end; end