Method: OpenC3::ActivityModel#create

Defined in:
lib/openc3/models/activity_model.rb

#create(overlap: true) ⇒ Object

Update the Redis hash at primary_key and set the score equal to the start Epoch time the member is set to the JSON generated via calling as_json



269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
# File 'lib/openc3/models/activity_model.rb', line 269

def create(overlap: true)
  if @recurring['end'] and @recurring['frequency'] and @recurring['span']
    # First validate the initial recurring activity ... all others are just offsets
    validate_input(start: @start, stop: @stop, kind: @kind, data: @data)

    # Create a uuid for deleting related recurring in the future
    @recurring['uuid'] = SecureRandom.uuid
    @recurring['start'] = @start
    duration = @stop - @start
    recurrence = 0
    case @recurring['span']
    when 'minutes'
      recurrence = @recurring['frequency'].to_i * 60
    when 'hours'
      recurrence = @recurring['frequency'].to_i * 3600
    when 'days'
      recurrence = @recurring['frequency'].to_i * 86400
    end

    unless overlap
      # Get all the existing events in the recurring time range as well as those before
      # the start of the recurring time range to ensure we don't start inside an existing event
      existing = Store.zrevrangebyscore(@primary_key, @recurring['end'] - 1, @recurring['start'] - MAX_DURATION)
      existing.map! {|value| JSON.parse(value, :allow_nan => true, :create_additions => true) }
    end
    last_stop = nil

    # Update @updated_at and add an event assuming it all completes ok
    @updated_at = Time.now.to_nsec_from_epoch
    add_event(status: 'created')

    Store.multi do |multi|
      (@start..@recurring['end']).step(recurrence).each do |start_time|
        @start = start_time
        @stop = start_time + duration

        if last_stop and @start < last_stop
          @events.pop # Remove previously created event
          raise ActivityOverlapError.new "Recurring activity overlap. Increase recurrence delta or decrease activity duration."
        end
        unless overlap
          existing.each do |value|
            if (@start >= value['start'] and @start < value['stop']) ||
              (@stop > value['start'] and @stop <= value['stop'])
              @events.pop # Remove previously created event
              raise ActivityOverlapError.new "activity overlaps existing at #{value['start']}"
            end
          end
        end
        multi.zadd(@primary_key, @start, JSON.generate(self.as_json(:allow_nan => true)))
        last_stop = @stop
      end
    end
    notify(kind: 'created')
  else
    validate_input(start: @start, stop: @stop, kind: @kind, data: @data)
    unless overlap
      # If we don't allow overlap we need to validate the time
      collision = validate_time(@start, @stop)
      unless collision.nil?
        raise ActivityOverlapError.new "activity overlaps existing at #{collision}"
      end
    end
    @updated_at = Time.now.to_nsec_from_epoch
    add_event(status: 'created')
    Store.zadd(@primary_key, @start, JSON.generate(self.as_json(:allow_nan => true)))
    notify(kind: 'created')
  end
end