class Mod < ActiveRecord::Base has_and_belongs_to_many :sixconfigs has_and_belongs_to_many :servers has_and_belongs_to_many :queryservers has_and_belongs_to_many :networks has_and_belongs_to_many :categories #has_many :dependentmods #has_many :depmods, :through => :dependentmods has_and_belongs_to_many :mods, :association_foreign_key => "depmod_id", :class_name => "Mod", :join_table => "dependentmods" has_and_belongs_to_many :depmods, :foreign_key => "depmod_id", :class_name => "Mod", :join_table => "dependentmods" six_guid OVERRIDE_MODEL = Mod # TODO # - fix dependencies attr_accessor :dependencies # Workaround for missing db fields attr_accessor :homepage, :changelog, :readme, :license, :license_url, :details, :repository_yml, :guid, :cpp_name, :full_name, :description, :author, :aliases, :mod_version, :size_wd, :maxbuild, :minbuild def all_dependentmods(mods = []) mods += [self] self.mods.each do |mod| next if mods.include?(mod) mods += mod.all_dependentmods(mods) mods << mod end mods -= [self] mods += [self] mods.uniq end def self.appset Kernel.const_get(self.short+"Appsetting") end def process(setting, reset, autoskip, force = false) self.update_version(setting) # TODO: this already runs in updater_yml, but there doesn't run if autoskip is disabled if reset && !autoskip self.skip = false else self.update_skip if autoskip end self.save unless self.new_record? unless force self.disabled = true if (!self.exists?(setting) || self.installed? || self.class.appset::SPECIFIC) && !self.version_match?(setting) end #self.skip = true if (self.exists?(setting) && !self.has_rsync?(setting)) end def uconfig_name self.real_name.sub(/^@/, "") end def userconfig(setting = Appsetting.new) # Packs everything that matches Find.find('tests') #File.open('test.tar', 'wb') { |tar| Archive::Tar::Minitar.pack('tests', tar) } # Unpacks 'test.tar' to 'x', creating 'x' if necessary. # Archive::Tar::Minitar.unpack('test.tar', 'x') rpath = self.real_path(setting) path = File.join(rpath, 'store', 'userconfig.tar') path = File.join(rpath, 'store', 'userconfig') unless File.exists?(path) path = File.join(rpath, 'userconfig') unless File.exists?(path) if File.exists?(path) #f = .clone #f.gsub!('@', '') #uconfig = File.join(setting.real_path, 'userconfig') #uconfigpath = File.join(uconfig, self.uconfig_name) if File.directory? path else #Archive::Tar::Minitar.unpack('test.tar', 'x') end end end def status(setting = Appsetting.new) return :special if self.special return :disabled if self.disabled if self.installed? || self.exists?(setting) self.skip ? :skip : :check else :install end end # arma2 mod: works for all subclasses # armaoa mod; works for arma2-oa-st, arma2-oa- def self.label self.appset.label end def self.short self.to_s.sub("Mod", "") end def self.types return [Arma2Mod] if self.class == Appsetting e = self types = [] unless e.nil? || [Mod, ActiveRecord::Base].include?(e) types << e e = e.class end types end def version_match?(setting) # setting.type == "ArmA2OaSt" (Arma2Oa, ArmA2) # self.type == "ArmA2" # setting.type == "ArmA2OaSt" (ArmA2Oa, ArmA2) # self.type == "ArmA2Oa" return nil if setting.nil? self.type.nil? ? true : setting.found_types.map{|e| e.short }.include?(self.class.short) end def real_name return unless self.name case RUBY_PLATFORM when /-mingw32$/, /-mswin32$/ self.name else self.name.downcase end end def installed? self.version_local && !self.version_local.empty? end def my_path(setting) return nil if setting.real_modpath.nil? || self.real_name.nil? File.join(self.real_path(setting), self.real_name).gsub("\\", "/") end def exists?(setting) path = self.my_path(setting) return false unless path File.exists?(path) end def has_rsync?(setting) path = self.my_path(setting) return false unless path File.exists?(File.join(path, ".rsync")) end def remote end def rema "mods/show" end def read_version(setting) path = self.my_path(setting) return unless path cfg = File.join(path, '.rsync', '.repository.yml') return nil unless File.exists?(cfg) conf = YAML::load_file(cfg) return nil unless conf begin; conf[:version]; rescue; nil; end end def update_version(setting) self.version_local = self.read_version(setting).to_s end def update_skip_by_version(setting) self.update_version(setting) self.update_skip end def real_path(setting) self.path.nil? || self.path.empty? ? setting.real_modpath : self.path end def all_repositories rep = if self.networks.empty? Repository.find(:all) else repos = [] self.networks.each { |net| repos += net.repositories unless net.disabled } repos end prio = nil rep.each {|e| unless e.priority.nil?; prio = true; break; end } prio ? rep.sort{|a, b| a.prio <=> b.prio} : rep.shuffle end def update_skip self.skip = if self.new_record?; true ; else; ((self.version == self.version_local) && !self.version.nil?); end end def special self.incl && !self.incl.empty? end def to_updater_yml return unless self.real_name hash = Hash.new hash[:folder] = self.real_name hash[:repository] = [] hash[:skip] = self.skip # TODO: Enable once proper processing is implemented #hash[:path] = self.path hash[:disabled] = self.disabled if self.incl hash[:include] = self.incl.split(";") hash[:force] = true unless hash[:include].empty? end if self.excl hash[:exclude] = self.excl.split(";") end hash[:priority] = self.priority name = self.real_name.clone name.gsub!("@", '') unless self.new_record? self.all_repositories.each do |rep| hash[:repository] << "#{rep.to_updater_yml}/rel/#{name.downcase}/." unless rep.disabled end end hash end def self.read_modfolders(setting) Dir.chdir setting.real_modpath.clone do Dir["@*"].each do |dir| next unless File.directory?(dir) m = Mod.find(:first, :conditions => ["name LIKE ?", dir]) unless m m = Mod.new :name => dir m.save end logger.debug "#{m.inspect}" end end end end