def UpdateChannelStats(self): """Recompute num_members for a channel.""" channel = Channel.ChannelByName(self.request.get('channel'), create=False) if not channel: return # channel became empty? num_members = int(self.request.get('num_members', '0')) q = Person.all(keys_only=True).filter('channel =', channel).order('__key__') start_at = self.request.get('start_at') if start_at: q.filter('__key__ >', db.Key(start_at)) people = q.fetch(self._STATS_BATCH) if people: # More to go. num_members += len(people) params = { 'channel': channel.name, 'num_members': num_members, 'start_at': str(people[-1]), } taskqueue.Task(url='/task/update-channel-stats', params=params).add('stats') return # Finished channel.num_members = num_members channel.put() logging.debug('%s now has %d members.' % (channel, num_members))
def names_command(self, msg): """Handle /names commands.""" m = re.match(r'^(#(?P<channel>' + Channel.CHANNEL_NAME_REGEX + '))?$', msg.arg) if not m: msg.reply('* Bad /names syntax') return if m.group('channel'): channel = Channel.ChannelByName(m.group('channel'), create=False) if not channel: msg.reply('* No such channel: #%s' % m.group('channel')) return else: channel = self.person.channel if not channel: msg.reply( '* You either need to be in a channel, or specify one.') return q = Person.all().filter('channel =', channel) people = q.fetch(self._NAME_LIMIT + 1) if len(people) <= self._NAME_LIMIT: people = people[0:self._NAME_LIMIT] names = sorted([str(p) for p in people]) msg.reply('* Members of %s: %s' % (channel, ' '.join(names))) else: msg.reply('* More than %d people in %s' % (self._NAME_LIMIT, channel))
def join_command(self, msg): m = re.match(r'^#(?P<channel>' + Channel.CHANNEL_NAME_REGEX + ')$', msg.arg) if not m: msg.reply('* Bad /join syntax') return name = m.group('channel') if self.person.channel and (self.person.channel.name == name): msg.reply('* You\'re already in #%s!' % name) return # Leave the existing channel, and tell them about it. if self.person.channel: old = self.person.channel message = '%s has left %s' % (self.person, old) self.Broadcast(old, message, system=True) self.Log(old, message, system=True) self.person.channel = None taskqueue.Task(url='/task/update-channel-stats', params={'channel': old.name}).add('stats') channel = Channel.ChannelByName(name, create=True) if channel.num_members >= self._CHANNEL_SIZE_LIMIT: msg.reply('* Sorry, too many people (%d) already in %s' % (channel.num_members, channel)) return self.person.channel = channel self.person.put() msg.reply('* You have joined %s' % channel) message = '%s has joined %s' % (self.person, channel) self.Broadcast(channel, message, system=True) self.Log(channel, message, system=True) taskqueue.Task(url='/task/update-channel-stats', params={'channel': channel.name}).add('stats')
def Broadcast(self): channel = Channel.ChannelByName(self.request.get('channel'), create=False) if not channel: return # channel became empty? message = self.request.get('message') skip_person = self.request.get('skip') if skip_person: skip_person = Person.PersonByEmail(skip_person) q = Person.all().filter('channel =', channel).order('__key__') start_at = self.request.get('start_at') if start_at: q.filter('__key__ >', db.Key(start_at)) people = q.fetch(self._BROADCAST_BATCH) jids = [] for p in people: if skip_person == p: continue jids.append(p.jid()) if not jids: return try: xmpp.send_message(jids, message) except xmpp.InvalidJidError: logging.error('InvalidJidError caught. JIDs were [%s]', ', '.join(['"%s"' % x for x in jids])) raise # Add a task for the next batch. params = { 'channel': channel.name, 'message': message, 'start_at': str(people[-1].key()), } if skip_person: params['skip'] = skip_person.jid() taskqueue.Task(url='/task/broadcast', params=params).add('chats')