Module: Card::Machine

Included in:
Set::Right::Script, Set::Right::Style, Set::Type::CoffeeScript, Set::Type::Css, Set::Type::JavaScript, Set::Type::Skin
Defined in:
mod/03_machines/lib/card/machine.rb

Defined Under Namespace

Modules: ClassMethods

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.define_machine_events(host_class) ⇒ Object



73
74
75
76
77
78
79
# File 'mod/03_machines/lib/card/machine.rb', line 73

def self.define_machine_events host_class
  event_suffix = host_class.name.tr ':', '_'
  event_name = "reset_machine_output_#{event_suffix}".to_sym
  host_class.event event_name, after: :expire_related, on: :save do
    reset_machine_output!
  end
end

.define_machine_views(host_class) ⇒ Object



81
82
83
84
85
86
87
# File 'mod/03_machines/lib/card/machine.rb', line 81

def self.define_machine_views host_class
  host_class.format do
    view :machine_output_url do |_args|
      machine_output_url
    end
  end
end

.included(host_class) ⇒ Object



58
59
60
61
62
63
64
65
66
67
68
69
70
71
# File 'mod/03_machines/lib/card/machine.rb', line 58

def self.included host_class
  host_class.extend(ClassMethods)
  host_class.output_config = { filetype: 'txt' }

  # for compatibility with old migrations
  return unless  Codename[:machine_output]

  host_class.card_accessor :machine_output, type: :file
  host_class.card_accessor :machine_input, type: :pointer

  set_default_machine_behaviour host_class
  define_machine_views host_class
  define_machine_events host_class
end

.set_default_input_collection_method(host_class) ⇒ Object



116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
# File 'mod/03_machines/lib/card/machine.rb', line 116

def self.set_default_input_collection_method host_class
  host_class.collect_input_cards do
    # traverse through all levels of pointers and
    # collect all item cards as input
    items = [self]
    new_input = []
    already_extended = {} # avoid loops
    loop_limit = 5
    while items.size > 0
      item = items.shift
      next if item.trash || already_extended[item.id].to_i > loop_limit
      if item.item_cards == [item] # no pointer card
        new_input << item
      else
        # item_cards instantiates non-existing cards
        # we don't want those
        items.insert(0, item.item_cards.reject(&:unknown?))
        items.flatten!

        new_input << item if item != self && item.known?
        already_extended[item] = already_extended[item].to_i + 1
      end
    end
    new_input
  end
end

.set_default_input_preparation_method(host_class) ⇒ Object



96
97
98
# File 'mod/03_machines/lib/card/machine.rb', line 96

def self.set_default_input_preparation_method host_class
  host_class.prepare_machine_input {}
end

.set_default_machine_behaviour(host_class) ⇒ Object



89
90
91
92
93
94
# File 'mod/03_machines/lib/card/machine.rb', line 89

def self.set_default_machine_behaviour host_class
  set_default_input_collection_method host_class
  set_default_input_preparation_method host_class
  set_default_output_storage_method host_class
  host_class.machine_engine { |input| input }
end

.set_default_output_storage_method(host_class) ⇒ Object



100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
# File 'mod/03_machines/lib/card/machine.rb', line 100

def self.set_default_output_storage_method host_class
  host_class.store_machine_output do |output|
    filetype = host_class.output_config[:filetype]
    file = Tempfile.new [id.to_s, ".#{filetype}"]
    file.write output
    file.rewind
    Card::Auth.as_bot do
      p = machine_output_card
      p.file = file
      p.save!
    end
    file.close
    file.unlink
  end
end

Instance Method Details

#ensure_machine_outputObject



212
213
214
215
216
# File 'mod/03_machines/lib/card/machine.rb', line 212

def ensure_machine_output
  output = fetch trait: :machine_output
  return if output && output.selected_content_action_id
  update_machine_output
end

#input_item_cardsObject



197
198
199
# File 'mod/03_machines/lib/card/machine.rb', line 197

def input_item_cards
  machine_input_card.item_cards
end

#lock!Object



185
186
187
# File 'mod/03_machines/lib/card/machine.rb', line 185

def lock!
  Card.cache.write lock_cache_key, true
end

#lock_cache_keyObject



177
178
179
# File 'mod/03_machines/lib/card/machine.rb', line 177

def lock_cache_key
  "UPDATE-LOCK:#{key}"
end

#locked?Boolean

Returns:

  • (Boolean)


181
182
183
# File 'mod/03_machines/lib/card/machine.rb', line 181

def locked?
  Card.cache.read lock_cache_key
end

#machine_output_pathObject



207
208
209
210
# File 'mod/03_machines/lib/card/machine.rb', line 207

def machine_output_path
  ensure_machine_output
  machine_output_card.file.path
end

#machine_output_urlObject



201
202
203
204
205
# File 'mod/03_machines/lib/card/machine.rb', line 201

def machine_output_url
  ensure_machine_output
  machine_output_card.file.url # (:default, timestamp: false)
  # to get rid of additional number in url
end

#reset_machine_output!Object



157
158
159
160
161
162
163
# File 'mod/03_machines/lib/card/machine.rb', line 157

def reset_machine_output!
  Auth.as_bot do
    (moc = machine_output_card) && moc.real? && moc.delete!
    # mic = machine_input_card  and mic.real? and mic.delete!
    update_input_card
  end
end

#run_machine(joint = "\n") ⇒ Object



143
144
145
146
147
148
149
150
151
152
153
154
155
# File 'mod/03_machines/lib/card/machine.rb', line 143

def run_machine joint="\n"
  before_engine
  output =
    input_item_cards.map do |input|
      next if input.is_a? Card::Set::Type::Pointer
      if input.respond_to? :machine_input
        engine(input.machine_input)
      else
        engine(input.format._render_raw)
      end
    end.select(&:present?).join(joint)
  after_engine output
end

#unlock!Object



189
190
191
# File 'mod/03_machines/lib/card/machine.rb', line 189

def unlock!
  Card.cache.write lock_cache_key, false
end

#update_input_cardObject



193
194
195
# File 'mod/03_machines/lib/card/machine.rb', line 193

def update_input_card
  machine_input_card.items = engine_input
end

#update_machine_outputObject



165
166
167
168
169
170
171
172
173
174
175
# File 'mod/03_machines/lib/card/machine.rb', line 165

def update_machine_output
  if ok?(:read) && !(was_already_locked = locked?)
    Auth.as_bot do
      lock!
      update_input_card
      run_machine
    end
  end
ensure
  unlock! unless was_already_locked
end