repository_file.rb revision afd1d888784385307c9c0544597a513c2008d342
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomiclass RepositoryFile
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi class PathValidator < ActiveModel::Validator
f49f1c5fa6a9a55a194e5ada042df134907278f4Aki Tuomi def validate(record)
f49f1c5fa6a9a55a194e5ada042df134907278f4Aki Tuomi if record.repository.points_through_file?(record.target_path)
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi record.errors[:target_directory] = "Error! This path points to or through a file."
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi end
285bfe946c2d54928b272270dd5eef9041b24271Timo Sirainen end
b3a968f434cbb9e374ea3da0a7d493e20231a4aeAki Tuomi end
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi include ActiveModel::Conversion
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi include ActiveModel::Validations
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi extend ActiveModel::Naming
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi DEFAULT_BRANCH = 'master'
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi # basic repository file usage
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi attr_reader :repository, :file
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi attr_accessor :index
cd24dc2196f7480d4793ca5d5f9f8d70741bc103Aki Tuomi delegate :name, :path, :size, :mime_type, :mime_category,
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi :oid, :file?, :dir?, :type, to: :file
452d0005a47c6872590346f5ea8b247974689ac9Aki Tuomi
c6108c1bfa10d5fcd1def9c6a23ebcd5204d1775Timo Sirainen # only for new/edit
345f36ebc7dd445cfa3dbf157342d110cc74d7c7Aki Tuomi attr_reader :message, :temp_file, :target_directory, :target_filename
c6108c1bfa10d5fcd1def9c6a23ebcd5204d1775Timo Sirainen validates :message, :temp_file, presence: true
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi validates_with PathValidator, :if => :temp_file_exists?
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi def self.find_with_path(opts)
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi begin
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi new(opts)
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi rescue GitRepository::PathNotFoundError
17fbd200b78112bd0d89e89598aa01cea72a74e5Martti Rannanjärvi nil
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi end
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi end
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi def self.find_with_path!(opts)
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi self.find_with_path(opts) ||
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi raise(GitRepository::PathNotFoundError,
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi [opts[:repository_id], opts[:ref], opts[:path]].compact.join('/'))
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi end
de1c645a79d42c37dffb7f52e9c643b6251fdcd0Aki Tuomi
7c9a9ac8cd5652f0e12a24b07c8559a7be0f5554Timo Sirainen def self.find_with_basepath(opts)
de1c645a79d42c37dffb7f52e9c643b6251fdcd0Aki Tuomi repository = Repository.find_by_path(opts[:repository_id])
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi oid = compute_ref(repository, opts[:ref])[:oid]
7e1a69e513739a7c12e3c5ec53dff1eb01b90524Aki Tuomi
7e1a69e513739a7c12e3c5ec53dff1eb01b90524Aki Tuomi dir_path = opts[:path].split('/')[0..-2].join('/')
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi
149299c7d5136a8fb425ef3cf8953026a1358002Timo Sirainen entries = repository.git.folder_contents(oid, dir_path).select do |entry|
7e1a69e513739a7c12e3c5ec53dff1eb01b90524Aki Tuomi entry.path.start_with?(opts[:path]) && entry.file?
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi end.map do |entry|
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi new(repository_id: repository.to_param, path: entry.path)
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi end
ff95c6488eb3239654ed7fd51ed787a6b2c44506Timo Sirainen end
f089a10e4816e772992346c9837ec10db3894c65Timo Sirainen
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi def self.build(opts={})
ff95c6488eb3239654ed7fd51ed787a6b2c44506Timo Sirainen if opts[:content] # edit text of file
ff95c6488eb3239654ed7fd51ed787a6b2c44506Timo Sirainen tempfile = Tempfile.new('repository_tempfile')
ff95c6488eb3239654ed7fd51ed787a6b2c44506Timo Sirainen tempfile.write(opts[:content])
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi tempfile.close
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi opts.merge!({ temp_file: tempfile })
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi new(opts)
ff95c6488eb3239654ed7fd51ed787a6b2c44506Timo Sirainen elsif(opts[:repository_file]) # upload file
86ad487452c763152f3ff4dd4650512f3cecdc55Aki Tuomi new(opts[:repository_file].merge({repository_id: opts[:repository_id]}))
86ad487452c763152f3ff4dd4650512f3cecdc55Aki Tuomi else
86ad487452c763152f3ff4dd4650512f3cecdc55Aki Tuomi new(opts)
b3a968f434cbb9e374ea3da0a7d493e20231a4aeAki Tuomi end
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi end
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi def self.create(opts={})
ff95c6488eb3239654ed7fd51ed787a6b2c44506Timo Sirainen rf = build(opts)
86ad487452c763152f3ff4dd4650512f3cecdc55Aki Tuomi if rf.valid?
86ad487452c763152f3ff4dd4650512f3cecdc55Aki Tuomi rf.repository.save_file(rf.temp_file.path, rf.target_path, rf.message, opts[:user])
86ad487452c763152f3ff4dd4650512f3cecdc55Aki Tuomi end
b3a968f434cbb9e374ea3da0a7d493e20231a4aeAki Tuomi
316cbe323513a0f20d1cf519fe9405e231d633e2Aki Tuomi return rf
end
def initialize(opts)
opts = opts.symbolize_keys
if self.class.manipulating_file?(opts)
@repository = Repository.find_by_path(opts[:repository_id])
@message = opts[:message]
@temp_file = opts[:temp_file]
if opts[:path].present?
@target_directory = opts[:path].split('/')[0..-2].join('/')
@target_filename = opts[:path].split('/')[-1]
else
@target_directory = opts[:target_directory]
@target_filename = opts[:target_filename]
end
elsif opts[:git_file] && opts[:repository]
@repository = opts[:repository]
@file = opts[:git_file]
@commit_id = repository.commit_id(file.oid)
else
@repository = Repository.find_by_path(opts[:repository_id])
@commit_id = repository.commit_id(opts[:ref] || DEFAULT_BRANCH)
@file = repository.git.get_file!(opts[:path] || '/', commit_id[:oid])
end
end
def ontologies(child_name=nil)
if file?
@ontologies ||= begin
ontos = repository.ontologies.find_with_path(path).parents_first
if child_name
ontos.map!{ |o| o.children.where(name: child_name) }.flatten!
end
ontos
end
end
end
def content
@content ||= begin
cntnt = file.content
if dir?
cntnt.map! do |e|
self.class.new(repository: self.repository, git_file: e)
end
end
cntnt
end
end
def to_s
name
end
def to_param
path
end
# Needed for a Model
def persisted?
false
end
def grouped_entries
grouped ||= begin
content.each_with_index do |v,i|
v.index = i
end
Hash[content.group_by do | e |
{ type: e.type, name: basename(e.name) }
end.map do | k, v |
[k[:name], v]
end]
end
end
def basename(name)
name.split('.')[0..-2].join('.')
end
# only for new/edit
def target_path
@target_directory ||= ''
str = target_directory
str = str[1,-1] if target_directory.starts_with?("/")
str = str[0,-2] if target_directory.ends_with?("/")
str += "/" unless target_directory.empty?
str += target_filename.present? ? target_filename : temp_file.original_filename
end
def temp_file_exists?
temp_file.present?
end
protected
attr_reader :commit_id
def self.compute_ref(repository, ref)
repository.commit_id(ref || DEFAULT_BRANCH)
end
def self.manipulating_file?(opts)
opts[:temp_file].present?
end
end