Class | Event
In: | app/models/event.rb
Parent: | Document

Clase para los eventos. Es subclase de Document, por lo que su tabla es `documents`

### Methods

check_user_can_create_this_type_of_event confirmed confirmed= confirmed? copy_from description_for_ics disable_unnecessary_fields ends_later_than_it_starts fill_lat_lng_data irekia_tag irekia_tags is_destroyable? is_private= is_private? is_public? microformat_body pretty_dates pretty_hours pretty_place private_event private_event= published? published_in_agencia? schedule_alerts schedule_id schedule_id= schedule_name schedule_name schedule_tweets set_draft_value set_l_attends set_publication_date set_to_draft_if_deleted show_in show_in= show_in_opts starts_at_in_agencia_for_ferret streaming_room sync_streaming_and_room to_ics translated_to? visibility_can_change? visible_in

### Included Modules

Geokit::Geocoders Tools::Calendar::InstanceMethods

### Attributes

schedule_id | [RW] |

### Public Class methods

irekia_tags()

Dependiendo de la sección donde se muestra un evento en Irekia, al evento le corresponde un `Tag` u otro. Esta función devuelve la lista con los tags que corresponden al evento.

[Source]

         # File app/models/event.rb, line 429
    429:   def self.irekia_tags
    430:     self.show_in_opts.map {|opt| Tag.find_by_name_es("Irekia::#{opt.capitalize}")}.compact
    431:   end

schedule_name()

El nombre de la agenda para los eventos compartidos es "Agenda compartida".

[Source]

         # File app/models/event.rb, line 522
    522:   def self.schedule_name
    523:     I18n.translate('sadmin.events.agenda_compartida')
    524:   end

show_in_opts()

Los eventos que se muestran en Irekia corresponden a una de las tres secciones: actos, acciones y eventos. Esta función devuelve la lista con los nombres de estas secciones.

[Source]

         # File app/models/event.rb, line 423
    423:   def self.show_in_opts
    424:     ["actos", "acciones", "eventos"]
    425:   end

### Public Instance methods

check_user_can_create_this_type_of_event()

Los miembros de departamento tienen restrigido el lugar donde pueden publicar eventos (privados, irekia o agencia). Aunque el formulario sólo les muestra las opciones que les corresponden, nos aseguramos que no añaden eventos donde no pueden.

[Source]

         # File app/models/event.rb, line 200
    200:   def check_user_can_create_this_type_of_event
    201:     yes_he_can = false
    202:     current_user = User.find(UserActionObserver.current_user)
    203:     if (self.is_private? && current_user.can?("create_private", "events")) || \
    204:       (self.show_in_irekia? && current_user.can?("create_irekia", "events")) || \
    205:       (self.show_in_agencia? && current_user.can?("create_agencia", "events"))
    206:         yes_he_can = true
    207:     end
    208:     if yes_he_can
    209:       return true
    210:     else
    211:       errors.add_to_base "No puedes crear eventos de este tipo"
    212:       return false
    213:     end
    214:   end

confirmed()

Indica si el estado del evento es ‘confirmado’.

[Source]

         # File app/models/event.rb, line 390
    390:   def confirmed
    391:     self.state.eql?('confirmado')
    392:   end

confirmed=(val)

Asigna el valor del campo `state`. Si `val = true` el evento es confirmado. y el valor del campo `state` es `confirmado`. En el caso contrario, el valor del campo `state` es `previsto`.

Este método se llama cuando se reciben los datos de un formulario. En el formulario se usa un check_box para indicar si el evento es confirmado o no y por lo tanto el valor del `val` es 0 o 1.

[Source]

         # File app/models/event.rb, line 400
    400:   def confirmed=(val)
    401:     case val
    402:       when true
    403:         self.state = 'confirmado'
    404:       when false
    405:         self.state = 'previsto'
    406:     else
    407:       self.state = val.to_i.eql?(1) ? 'confirmado' : 'previsto'
    408:     end
    409:   end

confirmed?()

Indica si el evento está confirmado o no.

[Source]

         # File app/models/event.rb, line 385
    385:   def confirmed?
    386:     self.confirmed
    387:   end

copy_from(evt)

Copia los datos del `evt` a `self`.

[Source]

         # File app/models/event.rb, line 550
    550:   def copy_from(evt)
    551:     evt_attr = evt.attributes
    552:     evt_attr.delete('id')
    553:     evt_attr.each do |at, value|
    554:       if self.respond_to?("#{at}=")
    555:         self.send("#{at}=", value)
    556:       end
    557:     end
    558:
    559:     if evt.is_a?(ScheduleEvent)
    560:       # self.is_private = true
    561:
    562:       # By default the event goes to schedule department if present or to Lehendakaritza.
    563:       self.organization_id = evt.organization_id || Organization.find_by_internal_id(1).id
    564:     end
    565:
    566:     self
    567:   end

description_for_ics()

Descripción formateada para ical

[Source]

         # File app/models/event.rb, line 491
    491:   def description_for_ics
    492:     description = "#{self.organization.name}.\n"
    493:     description << "#{self.speaker}.\n" if self.speaker.present?
    494:     description << self.body.strip_html
    495:     return description
    496:   end

disable_unnecessary_fields()

No todas las columnas de la tabla documents se utilizan en los eventos, por lo que nos aseguramos de que están vacías. Se llama desde before_save

[Source]

         # File app/models/event.rb, line 111
    111:   def disable_unnecessary_fields
    112:     self.has_comments = false
    113:     self.comments_closed = true
    114:     self.has_comments_with_photos = false
    115:     self.has_ratings = false
    116:     self.comments_count = 0
    117:     self.cover_photo_file_name = nil
    118:     self.cover_photo_content_type = nil
    119:     self.cover_photo_file_size = nil
    120:     self.cover_photo_updated_at = nil
    121:   end

ends_later_than_it_starts()

Comprueba que la fecha de finalización es posterior a la de inicio. Se llama en validate

[Source]

        # File app/models/event.rb, line 60
    60:   def ends_later_than_it_starts
    61:     errors.add_to_base "La fecha de fin debe ser posterior a la de inicio" if self.ends_at < self.starts_at
    62:   end

fill_lat_lng_data()

Averigua las coordenadas geográficas donde ocurrirá el evento para poder mostrarlo en el mapa. Se llama desde `before_save`

[Source]

         # File app/models/event.rb, line 125
    125:   def fill_lat_lng_data
    126:     if location_for_gmaps_changed?
    127:       if "#{location_for_gmaps} #{city}".blank?
    128:         self.lat = self.lng = nil
    129:       else
    130:         full_location = "#{location_for_gmaps}, #{city}, Spain"
    131:         loc = MultiGeocoder.geocode("#{full_location}")
    132:         unless loc.success
    133:           loc = MultiGeocoder.geocode(location_for_gmaps)
    134:         end
    135:
    136:         if loc.success
    137:           self.lat, self.lng = loc.lat, loc.lng
    138:         end
    139:       end
    140:     end
    141:   end

irekia_tag()

Devuelve el `Tag` relacionado con la sección de Irekia donde sale en evento.

[Source]

         # File app/models/event.rb, line 444
    444:   def irekia_tag
    445:     for i in Event.show_in_opts
    446:       res = self.tags.detect {|t| t.name_es.eql?("Irekia::#{i.capitalize}") }
    447:       return res unless res.nil?
    448:     end
    449:     nil
    450:   end

is_destroyable?()

El evento puede eliminarse por completo si no hay que notificar sobre su eliminación

[Source]

         # File app/models/event.rb, line 499
    499:   def is_destroyable?
    500:     if (!self.deleted? && self.alerts.sent.count > 0) || (self.deleted? && self.alerts.unsent.count > 0)
    501:       false
    502:     else
    503:       true
    504:     end
    505:   end

is_private=(val)

Si el valor de `val` es `false` el evento es privado y por lo tanto se asigna `false` como valor de los campos `show_in_irekia` y `show_in_agencia`.

[Source]

        # File app/models/event.rb, line 88
    88:   def is_private=(val)
    89:     if val
    90:       self.show_in_irekia = false
    91:       self.show_in_agencia = false
    92:     end
    93:   end

is_private?()

Devuelve `true` si el evento es privado y `false` si no lo es.

[Source]

        # File app/models/event.rb, line 82
    82:   def is_private?
    83:     !show_in_irekia? && !show_in_agencia?
    84:   end

is_public?()

Método auxiliar. Un evento es púbico si no es privado.

[Source]

         # File app/models/event.rb, line 313
    313:   def is_public?
    314:     !self.is_private?
    315:   end

microformat_body()

Devuelve el cuerpo del evento en microformato

[Source]

         # File app/models/event.rb, line 357
    357:   def microformat_body
    358:     m = body.to_s.match(/(.+)<p.*>###<\/p>(.+)/m)
    359:     # m = body.match(/((.+?)<\/p>)/m)
    360:     if m
    361:       b = "<div class='description'>#{m[1]}</div>
    362:         #{m[2]}"
    363:     else
    364:       b = body
    365:     end
    366:     return b
    367:   end

pretty_dates(locale=I18n.locale)

Formatea las fechas para mostrar al público

[Source]

         # File app/models/event.rb, line 318
    318:   def pretty_dates(locale=I18n.locale)
    319:     if starts_at.eql?(ends_at)
    320:       if starts_at.strftime('%H%M') == "0000"
    321:         # Remove hour if it is scheduled for midnight
    322:         I18n.localize(starts_at.to_date, :format => :long, :locale => locale)
    323:       else
    324:         I18n.localize(starts_at, :format => :long, :locale => locale)
    325:       end
    326:     elsif starts_at.to_date.eql?(ends_at.to_date)
    327:       # Same day, different hours
    328:       "#{I18n.localize(starts_at.to_date, :format => :long, :locale => locale)}, #{starts_at.strftime('%H:%M')} - #{ends_at.strftime('%H:%M')}"
    329:     else
    330:       # Different dates
    331:       start_date = starts_at.strftime('%H%M') == "0000" ? I18n.localize(starts_at.to_date, :format => :long, :locale => locale) : I18n.localize(starts_at, :format => :long, :locale => locale)
    332:       end_date = ends_at.strftime('%H%M') == "0000" ? I18n.localize(ends_at.to_date, :format => :long, :locale => locale) : I18n.localize(ends_at, :format => :long, :locale => locale)
    333:       "#{start_date} - #{end_date}"
    334:     end
    335:   end

pretty_hours(locale=I18n.locale)

Formatea las horas para mostrar en la vista semanal de la administración de la agenda

[Source]

         # File app/models/event.rb, line 338
    338:   def pretty_hours(locale=I18n.locale)
    339:     if starts_at.to_date.eql?(ends_at.to_date)
    340:       # Same day, different hours
    341:       "#{starts_at.strftime('%H:%M')} - #{ends_at.strftime('%H:%M')}"
    342:     else
    343:       # Different dates
    344:       start_date = starts_at.strftime('%H%M') == "0000" ? I18n.localize(starts_at.to_date, :format => :long, :locale => locale) : I18n.localize(starts_at, :format => :long, :locale => locale)
    345:       end_date = ends_at.strftime('%H%M') == "0000" ? I18n.localize(ends_at.to_date, :format => :long, :locale => locale) : I18n.localize(ends_at, :format => :long, :locale => locale)
    346:       "#{start_date} - #{end_date}"
    347:     end
    348:   end

pretty_place()

Formatea el lugar donde ocurre el evento

[Source]

         # File app/models/event.rb, line 351
    351:   def pretty_place
    352:     full_info = [self.place, self.city].map {|e| e.blank? ? nil : e }.compact
    353:     full_info.empty? ? "" : full_info.join(", ")
    354:   end

private_event()

Devuelve 1 si el evento es privado y 0 en el caso contrario.

[Source]

         # File app/models/event.rb, line 412
    412:   def private_event
    413:     self.is_private? ? 1 : 0
    414:   end

private_event=(val)

Llama el método `is_private` con argumento `val`.

[Source]

         # File app/models/event.rb, line 417
    417:   def private_event=(val)
    418:     self.is_private = val.to_i.eql?(1)
    419:   end

published?()

Indica si el evento está publicado en Irekia

[Source]

         # File app/models/event.rb, line 370
    370:   def published?
    371:     (!self.draft?) && (self.show_in_irekia || self.show_in_agencia) && self.confirmed? && (published_at <= Time.zone.now)
    372:   end

published_in_agencia?()

Indica si el evento está publicado en Irekia

[Source]

         # File app/models/event.rb, line 375
    375:   def published_in_agencia?
    376:      self.published? && self.show_in_agencia && (self.starts_at <= (Time.zone.now + 3.days))
    377:   end

schedule_alerts()

Programa las alertas que se deberán enviar relativas a este evento. Hay dos tipos de alertas

- Alertas para periodistas: Cada vez que un campo relevante del evento de la agencia cambia (fecha, lugar, visibilidad…), se envía un email notificándolo. Se envían 3 días antes de su comienzo
- Alertas para operadores de streaming y responsables de salas: Cuando se confirma el streaming para un evento, se envían alertas a los operadores de streaming, responsables de sala, y creador del evento para que preparen lo necesario para el streaming. Se envian 1 día antes de que comiencen

[Source]

         # File app/models/event.rb, line 224
    224:   def schedule_alerts
    225:     if self.starts_at_changed? || self.ends_at_changed? || self.place_changed? || self.state_changed?  || self.show_in_agencia_changed? || deleted_changed?
    226:       self.journalist_alert_version += 1
    227:
    228:       EventAlert.delete_all(["spammable_type = ? AND event_id= ? AND sent_at IS NULL", 'Journalist', self.id])
    229:       event_department_id = self.organization.is_a?(Department) ? self.organization_id : self.organization.department.id
    230:       Subscription.active.with_alerts.find(:all, :conditions => "subscriptions.department_id = #{event_department_id}").each do |subscription|
    231:         create_alert = false
    232:         last_sent_alert = EventAlert.find(:first,
    233:           :conditions => ["event_id = ? AND spammable_id = ? AND spammable_type = ?", self.id, subscription.user_id, "Journalist"],
    234:           :order => "sent_at DESC")
    235:         if !last_sent_alert
    236:           if self.confirmed? && self.published_in_agencia?
    237:             create_alert = true
    238:             alert_send_at = self.starts_at - 3.days
    239:           end
    240:         else
    241:           create_alert = true
    242:           if self.draft?
    243:             alert_send_at = self.starts_at - 3.days
    244:           else
    245:             alert_send_at = Time.zone.now
    246:           end
    247:         end
    248:         if create_alert
    249:           # logger.info "Creando alerta para periodista"
    250:           self.alerts.build(:spammable_id => subscription.user_id, :spammable_type => "Journalist", :version => self.journalist_alert_version, :send_at => alert_send_at)
    251:         end
    252:       end
    253:     end
    254:
    255:     if self.starts_at_changed? || self.ends_at_changed? || self.place_changed? || self.state_changed? || streaming_live_changed? || deleted_changed?
    256:       self.staff_alert_version += 1
    257:
    258:       EventAlert.delete_all(["spammable_type <> ? AND event_id= ? AND sent_at IS NULL", 'Journalist', self.id])
    259:       this_event_alert_recipients = StreamingOperator.find(:all)
    260:       this_event_alert_recipients << User.find(self.created_by) if self.created_by
    261:       if self.stream_flow
    262:         this_event_alert_recipients = this_event_alert_recipients + self.stream_flow.room_managers
    263:       end
    264:       this_event_alert_recipients.each do |recipient|
    265:         create_alert = false
    266:         last_sent_alert = EventAlert.find(:first, :conditions => ["event_id = ? AND spammable_id = ? AND spammable_type = ?", self.id, recipient.id, recipient.class.to_s], :order => "sent_at DESC")
    267:         if !last_sent_alert
    268:           if self.confirmed? && self.published_in_agencia? && self.streaming_live?
    269:             create_alert = true
    270:             alert_send_at = self.starts_at - 1.day
    271:           end
    272:         else
    273:           create_alert = true
    274:           if self.draft?
    275:             alert_send_at = self.starts_at - 1.days
    276:           else
    277:             alert_send_at = Time.zone.now
    278:           end
    279:         end
    280:         if create_alert
    281:           # logger.info "Creando alerta para #{recipient.class.to_s}"
    282:           self.alerts.build(:spammable_id => recipient.id, :spammable_type => recipient.class.to_s, :version => self.staff_alert_version, :send_at => alert_send_at)
    283:         end
    284:       end
    285:     end
    286:   end

schedule_id()

El `schedule_id` es `nil` para los evento compartidos.

[Source]

         # File app/models/event.rb, line 531
    531:   def schedule_id
    532:     nil
    533:   end

schedule_id=(val)

Aunque se le asigne un valor desde el formulario, un evento comprtido siempre tiene `schedule_id = nil`

[Source]

         # File app/models/event.rb, line 536
    536:   def schedule_id=(val)
    537:     @schedule_id = nil
    538:     true
    539:   end

schedule_name()

[Source]

         # File app/models/event.rb, line 526
    526:   def schedule_name
    527:     Event.schedule_name
    528:   end

schedule_tweets()

Programa el tweet referente a este evento, si está publicado y se muestra en Irekia. Se tweetea 3 días antes de su comienzo.

[Source]

         # File app/models/event.rb, line 291
    291:   def schedule_tweets
    292:     # Primero borramos los tweets pendientes de este evento, por si ha cambiado la fecha
    293:     DocumentTweet.delete_all(["document_id= ? AND tweeted_at IS NULL", self.id])
    294:
    295:     Event::LANGUAGES.each do |l|
    296:       if self.published? && self.show_in_irekia? && self.translated_to?(l) && !DocumentTweet.exists?(:document_id => self.id, :tweet_locale => l)
    297:         self.tweets.build(:tweet_account => "irekia_agenda", :tweet_at => self.starts_at - 3.days, :tweet_locale => l)
    298:       end
    299:     end
    300:   end

set_draft_value()

Asigna el valor del campo `draft`. Si el evento es privado, `draft = true`. Si el evento es público, el valor de `draft` es `true` si el evento no está confirmado y `false` si el evento está confirmado.

[Source]

         # File app/models/event.rb, line 176
    176:   def set_draft_value
    177:     if self.is_private?
    178:       self.draft = true
    179:     else
    180:       self.draft = !self.state.eql?("confirmado")
    181:     end
    182:     return true
    183:   end

set_l_attends()

Asigna el valor por defecto del campo `l_attends` si este no tiene ningún valor asignado.

[Source]

         # File app/models/event.rb, line 167
    167:   def set_l_attends
    168:     self.l_attends ||= false
    169:     true
    170:   end

set_publication_date()

Pone el valor correcto para `publication_date` a partir del valor de otros atributos. Se llama desde `before_save`

[Source]

         # File app/models/event.rb, line 148
    148:   def set_publication_date
    149:     if self.is_private?
    150:       self.published_at = nil
    151:     else
    152:       if self.show_in_agencia? && !self.show_in_irekia?
    153:         self.published_at = self.starts_at - 3.days
    154:       else
    155:         if self.show_in_irekia? && self.confirmed?
    156:           self.published_at = Time.zone.now
    157:         else
    158:           self.published_at = nil
    159:         end
    160:       end
    161:     end
    162:     return true
    163:   end

set_to_draft_if_deleted()

Los eventos no se pueden eliminar completamente si se han enviado alertas sobre su presencia, hasta que no se envia otra alerta sobre su eliminación. Cuando se marca como eliminado, se pasa a borrador para que deje de aparecer en la parte pública. Se llama desde before_save

[Source]

         # File app/models/event.rb, line 190
    190:   def set_to_draft_if_deleted
    191:     # asi nos aseguramos de que no aparecera en la parte publica
    192:     self.draft = true if self.deleted?
    193:     return true
    194:   end

show_in()

Devuelve el nombre de la sección donde sale el evento en Irekia.

[Source]

         # File app/models/event.rb, line 434
    434:   def show_in
    435:     res = ""
    436:     for i in Event.show_in_opts
    437:       res = i if self.tag_list.include?("Irekia::#{i.capitalize}")
    438:     end
    439:     res
    440:   end

show_in=(val)

Asigna el `Tag` correspondiente a la sección de Irekia donde sale el evento. El valor que se pasa tiene que ser alguna de las opciones que devuelve el método `show_in_opts`.

[Source]

         # File app/models/event.rb, line 454
    454:   def show_in=(val)
    455:     if Event.show_in_opts.include?(val)
    456:       self.tag_list = self.tag_list - Event.show_in_opts.map {|opt| "Irekia::#{opt.capitalize}"}
    457:       self.tag_list << "Irekia::#{val.capitalize}"
    458:     end
    459:   end

starts_at_in_agencia_for_ferret()

Fecha de inicio del evento para Ferret. Los eventos en la agencia se pueden ver 3 dias antes de que empiecen, por eso ponemos como fecha de inicio, 3 días antes.

[Source]

         # File app/models/event.rb, line 509
    509:   def starts_at_in_agencia_for_ferret
    510:     (self.starts_at - 3.days).to_s(:number)
    511:   end

streaming_room()

Comprueba que se que especifica la sala de streaming, en caso de que vaya a haberlo

[Source]

        # File app/models/event.rb, line 66
    66:   def streaming_room
    67:     if self.streaming_live && !self.stream_flow_id
    68:       errors.add :streaming_live, "Debes elegir la sala"
    69:     end
    70:   end

sync_streaming_and_room()

Asegura que no tiene sala de streaming si no hay streaming

[Source]

         # File app/models/event.rb, line 304
    304:   def sync_streaming_and_room
    305:     if !self.streaming_live
    306:       self.stream_flow_id = nil
    307:     else
    308:       return true
    309:     end
    310:   end

to_ics(cal) {|[:url] if block.present?| ...}

Devuelve el evento en formato ical

[Source]

         # File app/models/event.rb, line 462
    462:   def to_ics(cal, &block)
    463:     if self.deleted?
    464:       cal.add_x_property('METHOD', 'CANCEL')
    465:     else
    466:       cal.add_x_property('METHOD', 'REQUEST')
    467:     end
    468:     cal.event do |event|
    469:       event.uid = "uid_" + self.id.to_s + "irekia_euskadi_net"
    470:       event.sequence = self.staff_alert_version
    471:       event.summary = self.title
    472:       event.description = self.description_for_ics
    473:       event.dtstart =  self.starts_at.getutc.strftime("%Y%m%dT%H%M%SZ")
    474:       event.dtend = self.ends_at.getutc.strftime("%Y%m%dT%H%M%SZ")
    475:       event.location = self.pretty_place
    476:       event.url = yield[:url] if block.present?
    477:       event.created = self.created_at.getutc.strftime("%Y%m%dT%H%M%SZ")
    478:       event.last_modified = self.updated_at.getutc.strftime("%Y%m%dT%H%M%SZ")
    479:       event.dtstamp = Time.now.getutc.strftime("%Y%m%dT%H%M%SZ")
    480:       if self.deleted?
    481:         event.status = "CANCELLED"
    482:       elsif self.confirmed?
    483:         event.status = "TENTATIVE"
    484:       else
    485:         event.status = "CONFIRMED"
    486:       end
    487:     end
    488:   end

translated_to?(lang_code)

Indica si el evento está traducido a `lang_code` Los idiomas disponibles son `Document::LANGUAGES`

[Source]

         # File app/models/event.rb, line 97
     97:   def translated_to?(lang_code)
     98:     translated = self.send("title_#{lang_code}").present?
     99:     unless self.send("body_#{I18n.default_locale}").blank?
    100:       # Los eventos pueden no tener body en ningun idioma
    101:       translated = translated && self.send("body_#{lang_code}").present?
    102:     end
    103:     return translated
    104:   end

visibility_can_change?()

Indica si el evento se puede cambiar de privado a público y vice versa.

[Source]

         # File app/models/event.rb, line 544
    544:   def visibility_can_change?
    545:     true
    546:   end

visible_in()

Crea una lista con los sitios donde este evento es visible.

[Source]

        # File app/models/event.rb, line 73
    73:   def visible_in
    74:     show_in = []
    75:     show_in << "private" if self.is_private?
    76:     show_in << "irekia" if self.show_in_irekia?
    77:     show_in << "agencia" if self.show_in_agencia?
    78:     return show_in
    79:   end

[Validate]