Class: OSDN::CLI::Command::Relfile

Inherits:
FrsBase show all
Defined in:
lib/osdn/cli/command/relfile.rb

Instance Attribute Summary collapse

Attributes inherited from Base

#credential, #format, #logger

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from FrsBase

#run

Methods inherited from Base

#credential_path, #initialize, #load_credential, #load_variables, #set_client_token, #set_credential, #update_token, #update_variables, #write_credential, #write_variables

Constructor Details

This class inherits a constructor from OSDN::CLI::Command::Base

Instance Attribute Details

#force_digestObject

Returns the value of attribute force_digest.



6
7
8
# File 'lib/osdn/cli/command/relfile.rb', line 6

def force_digest
  @force_digest
end

#show_progressObject

Returns the value of attribute show_progress.



6
7
8
# File 'lib/osdn/cli/command/relfile.rb', line 6

def show_progress
  @show_progress
end

#target_packageObject

Returns the value of attribute target_package.



6
7
8
# File 'lib/osdn/cli/command/relfile.rb', line 6

def target_package
  @target_package
end

#target_projObject

Returns the value of attribute target_proj.



6
7
8
# File 'lib/osdn/cli/command/relfile.rb', line 6

def target_proj
  @target_proj
end

#target_releaseObject

Returns the value of attribute target_release.



6
7
8
# File 'lib/osdn/cli/command/relfile.rb', line 6

def target_release
  @target_release
end

#visibilityObject

Returns the value of attribute visibility.



6
7
8
# File 'lib/osdn/cli/command/relfile.rb', line 6

def visibility
  @visibility
end

Class Method Details

.descriptionObject



25
26
27
# File 'lib/osdn/cli/command/relfile.rb', line 25

def self.description
  "Manipulate frs files of project"
end

Instance Method Details

#calc_file_digest(filename) ⇒ Object



98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
# File 'lib/osdn/cli/command/relfile.rb', line 98

def calc_file_digest(filename)
  file = Pathname('.') + filename
  vars = load_variables(file.dirname)
  digests = nil
  if !@force_digest && vars.local_file_info &&
    vars.local_file_info[file.basename.to_s]
    finfo = vars.local_file_info[file.basename.to_s]
    if finfo.filesize == file.size && finfo.mtime == file.mtime
      digests = vars.local_file_info[file.basename.to_s].digests
    end
  end

  unless digests
    logger.info "Calculating digest for #{file}..."
    digests = {
      sha256: hexdigest(Digest::SHA256, file),
      sha1:   hexdigest(Digest::SHA1, file),
      md5:    hexdigest(Digest::MD5, file),
    }
    update_variables file.dirname, {local_file_info: {file.basename.to_s => {digests: digests, mtime: file.mtime, filesize: file.size}}}
  end
end

#createObject



86
87
88
89
90
91
92
93
94
95
96
# File 'lib/osdn/cli/command/relfile.rb', line 86

def create
  if ARGV.empty? || ARGV.first == ""
    logger.fatal "Target filename is missing."
    help
    return
  end

  ARGV.each do |f|
    create_one(f)
  end
end

#create_one(filename) ⇒ Object



121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
# File 'lib/osdn/cli/command/relfile.rb', line 121

def create_one(filename)
  file = Pathname('.') + filename
  calc_file_digest file
  vars = load_variables(file.dirname)
  fio = file.open
  logger.level <= Logger::INFO && @show_progress != false || @show_progress and
    OSDN::CLI._show_progress = true
  logger.info "Starting upload #{file} (#{file.size} bytes)..."
  max_upload_tries = 5
  upload_tries = 0
  remote_file = nil
  begin
    upload_tries += 1
    remote_file = api.create_release_file target_proj, target_package, target_release, fio, visibility: @visibility
  rescue OSDNClient::ApiError => e
    if max_upload_tries - upload_tries <= 0 
      logger.error "Max upload attempts (#{max_upload_tries}) has been exceeded, give up!"
      raise e
    elsif [0, 100, 502].member?(e.code.to_i)
      fio.rewind
      logger.error "Upload error (#{e.code} #{e.message}), retrying (#{upload_tries}/#{max_upload_tries})..."
      sleep 10
      retry
    else
      raise e
    end
  ensure
    fio.close
    OSDN::CLI._show_progress = false
  end
  
  if vars.local_file_info[file.basename.to_s].digests.find { |type, dig| rd = remote_file.send("digest_#{type}"); rd && rd != '' && rd != dig }
    logger.error "File digest mismatch! Uploaded file #{file} may be broken! Please check."
  elsif file.size != remote_file.size
    logger.error "File size mismatch! Uploaded file #{file} may be broken! Please check."
  else
    logger.info "Upload complete."
  end
  puts format_file(remote_file)
  remote_file
end

#deleteObject



179
180
181
182
183
184
185
186
187
188
# File 'lib/osdn/cli/command/relfile.rb', line 179

def delete
  target_id = ARGV.shift
  if !target_id
    logger.fatal "Target file ID is missing."
    help
    return
  end
  f = api.delete_release_file target_proj, target_package, target_release, target_id
  logger.info "file #{target_id} has been deleted."
end

#helpObject



8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# File 'lib/osdn/cli/command/relfile.rb', line 8

def help
  puts "#{$0} relfile [opts] [list]"
  puts "#{$0} relfile [opts] create <target-file> [target-files...]"
  puts "#{$0} relfile [opts] update <numeric-file-id>"
  puts "#{$0} relfile [opts] delete <numeric-file-id>"
  puts "Options:"
  puts "  -f --format=<pretty|json>  Set output format"
  puts "  -p --project=<project>     Target project (numeric id or name)"
  puts "     --package=<package-id>  Target package (numeric id)"
  puts "     --release=<release-id>  Target release (numeric id)"
  puts "  -v --visibility=<public|private|hidden>"
  puts "      --force-digest         Calc local file digest forcely"
  puts "      --progress             Force to show upload progress"
  puts "      --no-progress          Force to hide upload progress"
  puts "      --bwlimit=RATE         Limit bandwidth (in KB)"
end

#listObject



74
75
76
77
78
79
80
81
82
83
84
# File 'lib/osdn/cli/command/relfile.rb', line 74

def list
  release = api.get_release target_proj, target_package, target_release
  list = release.files
  if format == 'json'
    puts list.map{|i| i.to_hash}.to_json
  else
    list.each do |f|
      puts format_file(f)
    end
  end
end

#process_optionsObject



29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
# File 'lib/osdn/cli/command/relfile.rb', line 29

def process_options
  opts = GetoptLong.new(
    [ '--format', '-f', GetoptLong::REQUIRED_ARGUMENT ],
    [ '--project', '-p', GetoptLong::REQUIRED_ARGUMENT ],
    [ '--package', GetoptLong::REQUIRED_ARGUMENT ],
    [ '--release', GetoptLong::REQUIRED_ARGUMENT ],
    [ '--visibility', '-v', GetoptLong::REQUIRED_ARGUMENT ],
    [ '--force-digest', GetoptLong::NO_ARGUMENT],
    [ '--progress', GetoptLong::NO_ARGUMENT],
    [ '--no-progress', GetoptLong::NO_ARGUMENT],
    [ '--bwlimit', GetoptLong::REQUIRED_ARGUMENT ],
  )
  opts.each do |opt, arg|
    case opt
    when '--format'
      arg == 'json' and
        self.format = arg
    when '--project'
      arg.empty? or
        @target_proj = arg
    when '--package'
      arg.empty? or
        @target_package = arg
    when '--release'
      arg.empty? or
        @target_release = arg
    when '--force-digest'
      @force_digest = true
    when '--visibility'
      unless %w(public private hidden).member?(arg)
        logger.fatal "Invalid visibility status: #{arg}"
        exit
      end
      @visibility = arg
    when '--progress'
      @show_progress = true
    when '--no-progress'
      @show_progress = false
    when '--bwlimit'
      arg.to_i != 0 and
        OSDN::CLI._rate_limit = arg.to_i * 1024
    end
  end
end

#updateObject



163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
# File 'lib/osdn/cli/command/relfile.rb', line 163

def update
  target_id = ARGV.shift
  if !target_id
    logger.fatal "Target file ID is missing."
    help
    return
  end
  if @visibility.nil?
    logger.fatal "Visibility status is missing. Use '-v <public|private|hidden>'."
    return
  end
  f = api.update_release_file target_proj, target_package, target_release, target_id, visibility: @visibility
  logger.info "file #{target_id} has been updated."
  puts format_file(f)
end