X-Git-Url: http://git.osdn.net/view?a=blobdiff_plain;f=app%2Fmodels%2Fpanel.rb;h=3bfcbf37eb2cda118b8c6a78138f716c66fe41d1;hb=f8eca380d74ad1e371fb2e5c4de62a493e9f84f7;hp=f60b8017ec68f3e4eaea79ab23dfb9f8edc11b5b;hpb=7594d60b8019ba8dde474df7ac8a74066d8e01c7;p=pettanr%2Fpettanr.git diff --git a/app/models/panel.rb b/app/models/panel.rb index f60b8017..3bfcbf37 100644 --- a/app/models/panel.rb +++ b/app/models/panel.rb @@ -1,54 +1,457 @@ +#コマ class Panel < ActiveRecord::Base - belongs_to :comic + belongs_to :author + belongs_to :resource_picture + has_many :stories has_many :panel_pictures, :dependent => :destroy - has_many :balloons, :dependent => :destroy + has_many :speech_balloons, :dependent => :destroy + has_many :ground_pictures, :dependent => :destroy + has_many :ground_colors, :dependent => :destroy accepts_nested_attributes_for :panel_pictures, :allow_destroy => true - accepts_nested_attributes_for :balloons, :allow_destroy => true + accepts_nested_attributes_for :speech_balloons, :allow_destroy => true + accepts_nested_attributes_for :ground_pictures, :allow_destroy => true + accepts_nested_attributes_for :ground_colors, :allow_destroy => true - def self.max_t comic_id - Panel.maximum(:t, :conditions => ['comic_id = ?', comic_id]).to_i + validates :width, :presence => true, :numericality => true, :natural_number => true + validates :height, :presence => true, :numericality => true, :natural_number => true + validates :border, :presence => true, :numericality => {:greater_than_or_equal_to => 0} + validates :author_id, :presence => true, :numericality => true, :existence => {:both => false} + validates :publish, :presence => true, :numericality => true + + before_validation :valid_encode + + def valid_encode + ['caption'].each do |a| + next if attributes[a] == nil + raise Pettanr::BadRequest unless attributes[a].valid_encoding? + end end - def self.find_t comic_id, t - Panel.find(:first, :conditions => ['comic_id = ? and t = ?', comic_id, t]) + def self.each_element_class_names + Pettanr::Application.elements.each do |k, n| + yield k + end end - - #更新する時にPanelIDをチェックしとかないと勝手に所属先を変えられるゾ!? - - def vdt_save - f = nil - max_t = Panel.max_t self.comic_id - f = Panel.find_t(self.comic_id, self.t) if self.t - if f - Panel.update_all('t = t + 1', ['comic_id = ? and t >= ?', self.comic_id, self.t]) - else - self.t = max_t + 1 + + def self.class_name_to_class k + Object.const_get k + end + + def self.each_element_classes + self.each_element_class_names do |k| + e = self.class_name_to_class k + yield e end - self.save end - def move_to new_t - return true if self.t == new_t - if self.t > new_t - Panel.update_all('t = t + 1', ['comic_id = ? and (t >= ? and t < ?)', self.comic_id, new_t, self.t]) + def elements_by_class_name class_name + self.__send__ class_name.tableize + end + + def supply_default + self.border = 2 + self.publish = 0 + end + + def overwrite au + self.author_id = au.id + end + + def own? roles + roles = [roles] unless roles.respond_to?(:each) + au = Panel.get_author_from_roles roles + return false unless au + self.author_id == au.id + end + + def visible? roles + if MagicNumber['run_mode'] == 0 + return false unless guest_role_check(roles) else - nf = Panel.find_t(self.comic_id, new_t) - max_t = Panel.max_t self.comic_id - new_t = max_t if new_t > max_t - Panel.update_all('t = t - 1', ['comic_id = ? and (t > ? and t <= ?)', self.comic_id, self.t, new_t]) + return false unless reader_role_check(roles) + end + return true if self.own?(roles) + self.publish? + end + + def usable? au + visible? au + end + + def publish? + self.publish > 0 + end + + def tag_id c = nil + 'panel' + self.tag_panel_id + c.to_s + end + + def tag_panel_id + self.new_record? ? '0' : self.id.to_s + end + + def field_tag_id f + self.tag_id + f.to_s + end + + def tag_attributes column = nil, opt = {} + { + :id => self.field_tag_id(column), :panel_id => self.tag_panel_id + }.merge(opt) + end + + def select_tag_attributes(selected, column, opt = {}) + [ + :last, :first, + {:html => {:selected => selected}}, + self.field_tag_attributes(column, opt) + ] + end + + def field_tag_attributes column, opt = {} + self.tag_attributes(column).merge( + {:column => column} + ).merge(opt) + end + + def tag_attr column = nil, opt = {} + self.tag_attributes(column, opt).to_attr + end + + def field_tag_attr column, no_attr, opt = {} + self.field_tag_attributes(column, no_attr, opt).to_attr + end + + def self.default_page_size + 25 + end + + def self.max_page_size + 100 + end + + def self.page prm = nil + page = prm.to_i + page = 1 if page < 1 + page + end + + def self.page_size prm = self.default_page_size + page_size = prm.to_i + page_size = self.max_page_size if page_size > self.max_page_size + page_size = self.default_page_size if page_size < 1 + page_size + end + + def self.list_where + 'panels.publish > 0' + end + + def self.mylist_where au + ['panels.author_id = ?', au.id] + end + + def self.himlist_where au + ['panels.author_id = ? and panels.publish > 0', au.id] + end + + def self.list page = 1, page_size = self.default_page_size + Panel.where(self.list_where()).includes(Panel.list_opt).order('panels.updated_at desc').offset((page -1) * page_size).limit(page_size) + end + + def self.mylist au, page = 1, page_size = Author.default_panel_page_size + Panel.where(self.mylist_where(au)).includes(Panel.list_opt).order('panels.updated_at desc').offset((page -1) * page_size).limit(page_size) + end + + def self.himlist au, page = 1, page_size = Author.default_panel_page_size + Panel.where(self.himlist_where(au)).includes(Panel.list_opt).order('panels.updated_at desc').offset((page -1) * page_size).limit(page_size) + end + + def self.list_paginate page = 1, page_size = self.default_page_size + Kaminari.paginate_array(Array.new(Panel.where(self.list_where()).count, nil)).page(page).per(page_size) + end + + def self.mylist_paginate au, page = 1, page_size = Author.default_panel_page_size + Kaminari.paginate_array(Array.new(Panel.where(self.mylist_where(au)).count, nil)).page(page).per(page_size) + end + + def self.himlist_paginate au, page = 1, page_size = Author.default_panel_page_size + Kaminari.paginate_array(Array.new(Panel.where(self.himlist_where(au)).count, nil)).page(page).per(page_size) + end + + def self.list_opt + r = { + :author => {} + } + self.each_element_classes do |e| + r.merge!(e.list_opt_for_panel) end - self.t = new_t - self.save + r + end + + def self.show rid, roles + opt = {} + opt.merge!(Panel.show_opt) + res = Panel.find(rid, opt) + raise ActiveRecord::Forbidden unless res.visible?(roles) + res + end + + def self.edit rid, au + opt = {} + opt.merge!(Panel.show_opt) + res = Panel.find(rid, opt) + raise ActiveRecord::Forbidden unless res.own?(au) + res + end + + def self.show_opt + r = { + :author => {} + } + self.each_element_classes do |e| + r.merge!(e.show_opt_for_panel) + end + {:include => r} + end + + def parts_element + r = [] + self.class.each_element_class_names do |k| + r += (self.elements_by_class_name(k) || []) + end + r + end + + def zorderd_elements + res = [] + self.parts_element.each do |e| + res[e.z-1] = e + end + res + end + + def panel_elements + res = [] + self.parts_element.each do |e| + res[e.t] = e + end + res + end + + def elements + self.panel_elements.map {|e| + #(-_-;)<... kore wa hidoi + JSON.parse e.to_json({:include => e.class.json_opt_for_panel}) + } + end + + def panel_elements_as_json + self.to_json({:include => {:author => {}}, :methods => :elements}) + end + + def self.list_as_json_text ary + '[' + ary.map {|i| i.panel_elements_as_json }.join(',') + ']' + end + + def new_t + self.panel_elements.size + end + + def new_z + self.panel_elements.size + 1 + end + + def scenario + panel_elements.map { |e| + e.scenario + }.join + end + + def plain_scenario + panel_elements.map { |e| + e.plain_scenario + }.join + end + + def licensed_pictures + r = {} + self.panel_elements.each do |elm| + next unless elm.class.has_picture? + r[elm.picture_id] = elm.picture unless r[elm.picture_id] + end + r + end + + def self.visible_count + Panel.count + end + + def self.collect_element_value elements, name + elements.map {|e| + e.map {|o| + if o['_destroy'] or o[:_destroy] + nil + else + o[name] + end + }.compact + }.flatten + end + + def self.validate_serial ary, offset = 0 + i = offset + ary.compact.sort.each do |n| + break false unless n == i + i += 1 + end + ary.compact.size == i - offset + end + + def self.validate_element_serial elements, name, offset = 0 + Panel.validate_serial(Panel.collect_element_value(elements, name), offset) + end + + def self.validate_elements_serial c + c.map {|conf| + Panel.validate_element_serial(conf[:elements], conf[:name], conf[:offset]) ? nil : false + }.compact.empty? + end + + def validate_serial_list + l = [] + self.class.each_element_class_names do |k| + l << self.elements_by_class_name(k) + end + [ + {:elements => l, :name => :t, :offset => 0}, + {:elements => l, :name => :z, :offset => 1} + ] + end + def validate_child +# r1 = Panel.validate_elements_id validate_id_list + Panel.validate_elements_serial validate_serial_list + end + + def boost + @new_element_index = 0 + self.panel_elements.each do |elm| + if elm.new_record? + elm.new_index = @new_element_index + @new_element_index += 1 + end + end + end + + def store attr, au + if attr == false + self.errors.add :base, I18n.t('errors.invalid_json') + return false + end + self.attributes = attr + self.overwrite au + res = false + Panel.transaction do + self.panel_elements.each do |elm| + elm.new_panel = self + elm.boost + end +#self.publish = nil + res = self.save + unless validate_child + res = false + self.errors.add :base, I18n.t('errors.invalid_t') + raise ActiveRecord::Rollback + end + end + res + end + + def remove_element target, au + ct = target.t + cz = target.z + panel_attributes = {} + self.panel_elements.each do |elm| + attr = elm.attributes + if elm == target + attr['_destroy'] = true + end + if elm.t > ct + attr['t'] -= 1 + end + if elm.z > cz + attr['z'] -= 1 + end + panel_attributes[elm.class.to_s.tableize + '_attributes'] ||= {} + panel_attributes[elm.class.to_s.tableize + '_attributes'][elm.id] = attr + end + self.store(panel_attributes, au) + end + + def destroy_with_elements + res = false + Panel.transaction do + self.parts_element.each do |element| + raise ActiveRecord::Rollback unless element.destroy + end + raise ActiveRecord::Rollback unless self.destroy + res = true + end + res + end + + def copy + attr = self.copy_attributes + Panel.each_element_class_names do |n| + attr.merge! Panel.class_name_to_class(n).panelize(self.elements_by_class_name(n).map {|elm| elm.copy_attributes}) + end + attr + end + + def copy_attributes + r = self.attributes + r.delete 'id' + r.delete 'author_id' + r.delete 'created_at' + r.delete 'updated_at' + r + end + + def self.panelize panel + attr = panel.attributes + attr.delete 'id' + attr + end + + +=begin + def self.validate_id ary, pid + ary.map {|v| + if pid + (v == pid or v == nil) ? nil : false + else + v ? false : nil + end + }.compact.empty? + end + + def self.validate_element_id elements, name, pid + Panel.validate_id(Panel.collect_element_value(elements, name), pid) end - def destroy_and_shorten - Panel.update_all('t = t - 1', ['comic_id = ? and (t > ?)', self.comic_id, self.t]) - self.destroy + def self.validate_elements_id c + c.map {|conf| + Panel.validate_element_id(conf[:elements], conf[:name], conf[:parent_id]) ? nil : false + }.compact.empty? end - def own? author - return false unless author - self.author_id == author.id + def validate_id_list + r = self.speech_balloons.map {|sb| + {:elements => [sb.speeches, sb.balloons], :name => :speech_balloon_id, :parent_id => sb.id} + } + r.unshift({:elements => [self.panel_pictures, self.speech_balloons], :name => :panel_id, :parent_id => self.id}) + r end +=end end