Beispiel #1
0
 def clear_programs(cls, cid=None, all=False):
   if cid:
     channel = Channel.get_by_key_name(cid)
     Programming.clear_channel(channel)
   elif all:
     Programming.clear()
   else:
     Programming.clear_channels()
Beispiel #2
0
  def remove_program(cls, channel_id, media):
    from model import Channel

    cached_programming = memcache.get('programming') or {}
    new_schedule = []
    sched = 0
    if cached_programming.get(channel_id):
      for program in cached_programming[channel_id]:
        time = iso8601.parse_date(program['time']).replace(tzinfo=None)
        if program['media']['id'] == media.id:
          sched += 1
          continue
        if sched:
          new_time = time - datetime.timedelta(seconds=(sched * media.duration))
          program['time'] = new_time.isoformat()
        new_schedule.append(program)
    channel = Channel.get_by_key_name(channel_id)
    channel.next_time = channel.next_time - datetime.timedelta(seconds=(sched * media.duration))
    channel.put()
    cached_programming[channel_id] = new_schedule
    memcache.set('programming', cached_programming)
    return new_schedule
Beispiel #3
0
  def set_programming(cls, channel_id, duration=3600, schedule_next=False, fetch_twitter=True,
                      queue='programming', target=None, kickoff=False):
    import broadcast
    import constants
    from model import Channel
    from model import Program

    # Stored programming
    programming = memcache.get('programming') or {}
    onlineUsers = memcache.get('web_channels') or {}

    logging.info('programming: ' + channel_id)

    next_programs = Programming.next_programs(programming.get(channel_id, []), duration, prelude=300)
    gap = Programming.gap(programming.get(channel_id, []), duration)

    logging.info('GAP: ' + str(gap))

    if programming.get(channel_id) and len(programming[channel_id]) and \
        programming[channel_id][0]['media'].get('live') == True:
      logging.info('live tweets')
      # Update tweets for live events
      media = Media.get_by_key_name(programming[channel_id][0]['media']['id'])
      deferred.defer(Programming.fetch_related_tweets, [],
                     _name='twitter-' + channel_id + '-' + str(uuid.uuid1()),
                     _queue='twitter')

    programs = []
    if not programming.get(channel_id) or gap > 60:
      logging.info('PROGRAOMMING')
      channel = Channel.get_by_key_name(channel_id)
      #channel.update_next_time()
      viewers = (memcache.get('channel_viewers') or {}).get(str(channel_id), [])
      cols = channel.get_collections()
      all_medias = []
      backup_medias = []
      limit = 100
      for col in cols:
        medias = []
        filtered_medias = []
        offset = 0
        while offset <= 400:
          medias = col.get_medias(limit=limit, offset=offset)
          logging.info('fetched medias: ' + str(len(medias)))
          if not len(medias):
            break
          backup_medias += medias

          # Dont reprogram anytihng already scheduled
          filtered_medias = Programming.no_reprogram(programming.get(channel_id, []), medias)

          # Don't repeat the same program within two hour
          cutoff = 7200 if col.lifespan else 43200
          filtered_medias = [c for c in filtered_medias if not c.last_programmed or
                   (datetime.datetime.now() - c.last_programmed).seconds > cutoff]

          # At most, 30% of the audience has already "witnessed" this program
          # filtered_medias = [m for m in filtered_medias if not len(viewers) or
          #           float(len(Programming.have_seen(m, viewers)))/len(viewers) < .3]

          all_medias += filtered_medias
          logging.info('all medias: ' + str(len(all_medias)))
          offset += limit

      all_medias = backup_medias if not len(all_medias) else all_medias

      # Don't repeat already programmed
#      all_medias = Programming.no_reprogram(next_programs, all_medias)

      # StorySort algorithm
      # all_medias = Programming.story_sort(all_medias)

      # Only one publisher per story
      all_medias = Programming.unique_publishers(all_medias)

      # Grab "duration" seconds of programming
      all_medias = Programming.timed_subset(all_medias, duration)

      if fetch_twitter:
        # Find related twitter posts
        deferred.defer(Programming.fetch_related_tweets, all_medias,
                       _name='twitter-' + channel.name.replace(' ', '') + '-' + str(uuid.uuid1()),
                       _queue='twitter',
                       _countdown=30)

      # Truncate old programs
      programming[channel_id] = Programming.cutoff_programs(programming.get(channel_id), 300)

      for media in all_medias:
        program = Program.add_program(channel, media, min_time=datetime.datetime.now(),
                                      max_time=(datetime.datetime.now() + datetime.timedelta(seconds=duration)))
        logging.info(program)
        if program:
          if not programming.get(channel_id, None):
            programming[channel_id] = []
          programming.get(channel_id).append(program.toJson(fetch_channel=False, fetch_media=True, media_desc=False, pub_desc=False))
          programs.append(program)
          logging.info('ADDING: ' + media.name + ' at: ' + program.time.isoformat())
          if len(pickle.dumps(programming)) > 1000000:
            # We can only fit 1mb into memcache
            break

      if len(programs):
        broadcast.broadcastNewPrograms(channel, programs)

      memcache.set('programming', programming)

      channels = memcache.get('channels') or []
      updated = False
      for i,c in enumerate(channels):
        if c['id'] == channel_id:
          channels[i] = channel.toJson(get_programming=False)
          updated = True
      if not updated:
        channels.append(channel.toJson(get_programming=False))

      memcache.set('channels', channels)

    # Schedule our next programming selection
    if schedule_next and (not constants.SLEEP_PROGRAMMING or
                          (constants.SLEEP_PROGRAMMING and (kickoff or len(onlineUsers.keys())))):
      logging.info('NUMBER OF PROGRAMS: ' + str(len(programs)))
      if len(programs) > 1:
        next_gen = (programs[-2].time - datetime.datetime.now()).seconds / 2
      elif len(programs) == 1:
        next_gen = programs[0].media.duration / 2
      else:
        next_gen = 60
      next_gen = min(next_gen,
                     reduce(lambda x, y: x + y, [p.media.duration for p in programs], 0) \
                     if len(programs) else 10)
      next_gen = min(next_gen, duration / 2)
      logging.info('COUNTDOWN FOR ' + channel_id + ': ' + str(next_gen))
      deferred.defer(Programming.set_programming, channel_id, fetch_twitter=fetch_twitter,
                     _name=channel_id + '-' + str(uuid.uuid1()),
                     _countdown=next_gen,
                     _queue=queue)
    return programs