Ejemplo n.º 1
0
  def get(self):
    online_users = models.OnlineUser.all(keys_only = True).fetch(1000)
    users_status = memcache.get_multi([config.MEMCACHE_LAST_BEEN_ONLINE(u.id_or_name()) for u in online_users]).keys()

    todel = []
    for u in online_users:
      if config.MEMCACHE_LAST_BEEN_ONLINE(u.id_or_name()) not in users_status:
        todel.append(u)

    db.delete(todel)
Ejemplo n.º 2
0
  def get(self, userchat_name):
    userchat_name = unquote_plus(userchat_name)
    userchat = db.Query(models.UserChat).ancestor(self.get_current_user_key()).filter('name =', userchat_name).get()

    if not userchat:
      self.response.set_status(404)
      return

    self.login(chat_id = userchat.key().id_or_name())

    chat_key = db.Key.from_path('Chat', userchat.key().id_or_name())
    messages_query = db.Query(models.Message).ancestor(chat_key).order('-date_time')
    messages = messages_query.fetch(config.CHAT_HISTORY_MESSAGE_COUNT)

    try:
      chat_timestamp = messages[0].date_time
    except IndexError:
      chat_timestamp = self.now

    messages.reverse()

    peer_key = common.get_ref_key(userchat, 'peer_userchat').parent()
    peer_status = self.memcache_fetcher.get(config.MEMCACHE_LAST_BEEN_ONLINE(peer_key.id_or_name()))

    self.template_values["peer_username"] = models.User.get_username(peer_key)
    self.template_values["peer_status_class"] = "offline" if peer_status.get_result() is None else "online"
    self.template_values["title"] = userchat.title
    self.template_values["userchat_key"] = userchat.key()
    self.template_values["messages"] = [{'message_string': msg.message_string, 'username': models.User.get_username(common.get_ref_key(msg, 'sender').parent())} for msg in messages]
    if len(messages) >= config.CHAT_HISTORY_MESSAGE_COUNT:
      self.template_values['more_cursor'] = messages_query.cursor()

    self.client_update['chat_timestamp'] = str(chat_timestamp)

    self.render_page('ChatPage.html')
Ejemplo n.º 3
0
    def get(self):
        self.login()

        conversations = [
            self.datastore_fetcher.get(
                db.Key.from_path('User', self.user_key.id_or_name(),
                                 'UserChat', c.id_or_name()))
            for c in db.Query(models.UnreadChat, keys_only=True).ancestor(
                self.user_key).fetch(5)
        ]

        peer_keys = [
            common.get_ref_key(c.get_result(), 'peer_userchat').parent()
            for c in conversations
        ]
        peers_status = [
            self.memcache_fetcher.get(
                config.MEMCACHE_LAST_BEEN_ONLINE(pk.id_or_name()))
            for pk in peer_keys
        ]

        conversations_value = []
        for i in range(len(conversations)):
            conv = conversations[i].get_result()
            status_class = "online" if peers_status[i].get_result(
            ) is not None else "offline"
            username = models.User.get_username(peer_keys[i])
            c = {
                'username': username,
                'title': conv.title,
                'name': conv.name,
                'status_class': status_class
            }
            conversations_value.append(c)

        context = get_user_context(self.user_key)
        if context:
            self.template_values['context'] = context

        self.template_values['top_searches'] = get_top_searches()
        self.template_values['conversations'] = conversations_value
        self.template_values['num_online_users'] = get_num_online_users()

        self.render_page('HomePage.html')
Ejemplo n.º 4
0
  def get(self):
    self.login()
    convs_query = db.Query(models.UserChat).ancestor(self.user_key).order('-last_updated')
    cur = self.request.get('cursor')
    if cur:
      convs_query.with_cursor(start_cursor = cur)
      with_cursor = True
    else:
      with_cursor = False
    
    conversations = []
    users_status = []
    unread_chats = []
    counter = 0
    cursor = None
    for conv in convs_query:
      if not conv.last_updated:
        continue
      counter += 1
      c = {'title' : conv.title, 'name' : conv.name}
      peer_key = common.get_ref_key(conv, 'peer_userchat').parent()
      c['username'] = models.User.get_username(peer_key)

      conversations.append(c)
      unread_chats.append(self.datastore_fetcher.get(db.Key.from_path('User', self.user_key.id_or_name(), 'UnreadChat', conv.key().id_or_name())))
      users_status.append(self.memcache_fetcher.get(config.MEMCACHE_LAST_BEEN_ONLINE(peer_key.id_or_name())))

      if counter >= config.ITEMS_PER_PAGE:
        cursor = convs_query.cursor()
        break

    for i in range(len(conversations)):
      conv = conversations[i]
      status_class = "online" if users_status[i].get_result() is not None else "offline"
      conv['status_class'] = status_class
      conv['unread'] = False if unread_chats[i].get_result() is None else True

    self.template_values["conversations"] = conversations
    self.template_values["cursor"] = cursor
    self.template_values["with_cursor"] = with_cursor

    self.render_page('InboxPage.html')
Ejemplo n.º 5
0
    def login(self,
              prev_update_id=None,
              chat_id=None,
              prev_chat_update_id=None):
        batch_status_update = {}

        if self.session.has_key("user"):
            try:
                if self.request.cookies['login_hash'] == self.session[
                        'login_hash']:
                    self.user_key = self.session["user"]
                else:
                    raise ValueError()
            except (KeyError, ValueError):
                self.session.pop('user')
                self.session.pop('login_hash')

        if self.user_key is None and self.session.has_key("anon_user"):
            self.user_key = self.session["anon_user"]

        if self.user_key is None:
            user = models.User()
            user.put()
            self.session["anon_user"] = self.user_key = user.key()
            self.session.pop("user")

        refresh_unread_count = False

        last_been_online = self.memcache_fetcher.get(
            config.MEMCACHE_LAST_BEEN_ONLINE(self.user_key.id_or_name()))
        update_id = self.memcache_fetcher.get(
            config.MEMCACHE_USER_UPDATE_ID(self.user_key.id_or_name()))
        unread_count = self.memcache_fetcher.get(
            config.MEMCACHE_USER_UNREAD_COUNT(self.user_key.id_or_name()))

        if chat_id is not None:
            chat_update_id = self.memcache_fetcher.get(
                config.MEMCACHE_CHAT_UPDATE_ID(chat_id))
            open_chat = self.memcache_fetcher.get(
                config.MEMCACHE_USER_OPEN_CHAT(self.user_key.id_or_name(),
                                               chat_id))

        if last_been_online.get_result() is None:
            # make sure the user exists in datastore
            user = self.datastore_fetcher.get(self.user_key).get_result()
            if user is None:
                self.user_key = None
                self.session.terminate()
                self.redirect('/')
                return
            user.last_activity = self.now
            db.put(user)

        if last_been_online.get_result() is None or (
                self.now - last_been_online.get_result()
        ).seconds > config.STATUS_UPDATE_THRESHOLD:
            batch_status_update[last_been_online.get_key()] = self.now

        if last_been_online.get_result() is None:
            online_user_key = db.Key.from_path('OnlineUser',
                                               self.user_key.id_or_name())
            online_user = models.OnlineUser(key=online_user_key)
            online_user.put()

        if chat_id is not None:
            if open_chat.get_result() is None or (
                    self.now - open_chat.get_result()
            ).seconds > config.STATUS_UPDATE_THRESHOLD:
                batch_status_update[open_chat.get_key()] = self.now
            if open_chat.get_result() is None:
                db.delete(
                    db.Key.from_path('User', self.user_key.id_or_name(),
                                     'UnreadChat', chat_id))
                refresh_unread_count = True

        if update_id.get_result() is None and prev_update_id != 0:
            self.update_id = 0

        if update_id.get_result(
        ) is not None and update_id.get_result() != prev_update_id:
            if prev_update_id is None or update_id.get_result() < update_id:
                start_notification_id = 1
            else:
                start_notification_id = prev_update_id + 1
            end_notification_id = int(update_id.get_result())

            notifications = [
                (i,
                 self.memcache_fetcher.get(
                     config.MEMCACHE_USER_NOTIFICATION(
                         self.user_key.id_or_name(), i)))
                for i in range(start_notification_id, end_notification_id + 1)
            ]

            for i, n in notifications:
                self.update_id = i
                if n.get_result() is not None:
                    self.notifications.append(n.get_result())

        if unread_count.get_result() is None or len(
                self.notifications) or refresh_unread_count:
            self._refresh_unread_count()
        else:
            self.unread_count = unread_count.get_result()

        if chat_id is not None:
            if chat_update_id.get_result() is None:
                self.chat_update_id = 0
            elif int(chat_update_id.get_result()) != prev_chat_update_id:
                self.chat_update_id = int(chat_update_id.get_result())

        if batch_status_update:
            memcache.set_multi(batch_status_update,
                               time=config.OFFLINE_THRESHOLD)
Ejemplo n.º 6
0
    def get_update(self):
        update_id = self.request.get('update_id', None)
        if update_id is not None:
            update_id = int(update_id)

        chat_update_id = self.request.get('chat_update_id', None)
        if chat_update_id is not None:
            chat_update_id = int(chat_update_id)

        userchat_key = db.Key(self.request.get("userchat_key", None))

        chat_id = userchat_key.id_or_name()
        if chat_id:
            peer_id_holder = self.memcache_fetcher.get(
                config.MEMCACHE_PEER_ID(userchat_key.parent().id_or_name(),
                                        chat_id))
        self.login(prev_update_id=update_id,
                   chat_id=chat_id,
                   prev_chat_update_id=chat_update_id)

        message = None
        if chat_id:
            if userchat_key.parent() != self.user_key:
                self.response.set_status(404)
                return
            chat_key = db.Key.from_path('Chat', chat_id)
            chat_timestamp = common.str2datetime(
                self.request.get('chat_timestamp'))

            message = self.request.get("message", None)

            peer_id = peer_id_holder.get_result()
            if peer_id is None:
                userchat = self.datastore_fetcher.get(userchat_key)
                peer_userchat_key = common.get_ref_key(userchat.get_result(),
                                                       'peer_userchat')
                peer_id = peer_userchat_key.parent().id_or_name()
                memcache.set(peer_id_holder.get_key(), peer_id, time=600)

            peer_status = self.memcache_fetcher.get(
                config.MEMCACHE_LAST_BEEN_ONLINE(peer_id))
            message_entity = None
            if message:
                message = common.htmlize_string(
                    common.sanitize_string(message))
                message_entity = models.Message(parent=chat_key,
                                                message_string=message,
                                                sender=userchat_key)

                peer_chat_open = self.memcache_fetcher.get(
                    config.MEMCACHE_USER_OPEN_CHAT(peer_id, chat_id))
                if peer_chat_open.get_result() is None:
                    peer_unreadchat_key = db.Key.from_path(
                        'User', peer_id, 'UnreadChat', chat_id)
                    peer_unreadchat = models.UnreadChat(
                        key=peer_unreadchat_key)

                    userchat_holder = self.datastore_fetcher.get(userchat_key)
                    peer_userchat_holder = self.datastore_fetcher.get(
                        db.Key.from_path('User', peer_id, 'UserChat', chat_id))
                    userchat = userchat_holder.get_result()
                    peer_userchat = peer_userchat_holder.get_result()
                    userchat.last_updated = self.now
                    peer_userchat.last_updated = self.now
                    db.put([
                        message_entity, peer_unreadchat, peer_userchat,
                        userchat
                    ])

                    peer_update_id = memcache.incr(
                        config.MEMCACHE_USER_UPDATE_ID(peer_id),
                        initial_value=0)
                    memcache.set(
                        config.MEMCACHE_USER_NOTIFICATION(
                            peer_id, peer_update_id),
                        {
                            'username':
                            models.User.get_username(self.user_key),
                            'chat_id':
                            chat_id,
                            'message':
                            message,
                            'link':
                            '/chat/%s' %
                            models.User.get_username(self.user_key),
                            'timestamp':
                            message_entity.date_time,
                        },
                        time=config.NOTIFICATION_DURATION,
                    )
                else:
                    db.put(message_entity)

            if self.chat_update_id:
                new_messages = db.Query(
                    models.Message).ancestor(chat_key).filter(
                        'date_time >',
                        chat_timestamp).order('-date_time').fetch(10)
                try:
                    self.client_update['chat_timestamp'] = str(
                        new_messages[0].date_time)
                except:
                    pass
                new_messages.reverse()

                template_values = {
                    "username":
                    models.User.get_username(self.user_key),
                    "messages": [{
                        'message_string':
                        msg.message_string,
                        'username':
                        models.User.get_username(
                            common.get_ref_key(msg, 'sender').parent())
                    } for msg in new_messages],
                }
                path = os.path.join(os.path.dirname(__file__),
                                    '_messages.html')
                self.client_update['messages_html'] = template.render(
                    path, template_values).decode('utf-8')
            elif message_entity is not None:
                self.client_update['chat_timestamp'] = str(
                    message_entity.date_time)
                template_values = {
                    "username":
                    models.User.get_username(self.user_key),
                    "messages": [{
                        'message_string':
                        message_entity.message_string,
                        'username':
                        models.User.get_username(
                            common.get_ref_key(message_entity,
                                               'sender').parent())
                    }],
                }
                path = os.path.join(os.path.dirname(__file__),
                                    '_messages.html')
                self.client_update['messages_html'] = template.render(
                    path, template_values).decode('utf-8')

            if chat_id and message_entity:
                self.chat_update_id = memcache.incr(
                    config.MEMCACHE_CHAT_UPDATE_ID(chat_id),
                    delta=1,
                    initial_value=0)

            self.client_update[
                'status_class'] = "offline" if peer_status.get_result(
                ) is None else "online"

        self._get_client_update()
        return self.client_update
Ejemplo n.º 7
0
    def get(self):
        q = self.request.get('q').strip()

        if not q:
            self.redirect("/")
            return

        self.login()

        clean_string = search.clean_query_string(q)
        query_hash = common.get_query_hash(clean_string)

        query_key = db.Key.from_path('Query', query_hash, parent=self.user_key)
        existing_query = self.datastore_fetcher.get(query_key)

        keyword_hashes = search.get_keyword_hashes(clean_string)
        search_hashes = keyword_hashes[:config.MAX_SEARCH_KEYWORDS]

        context = self.datastore_fetcher.get(
            db.Key.from_path('UserContext', self.user_key.id_or_name()))

        search_query = search.get_search_query(search_hashes)
        cur = self.request.get('cursor')
        if cur is not None:
            search_query.with_cursor(cur)

        result_keys = []
        existing_chats = {}
        users_status = {}
        unread_chats = {}
        cursor = None

        res_keys = search_query.fetch(config.ITEMS_PER_PAGE)
        if len(res_keys) >= config.ITEMS_PER_PAGE:
            cursor = search_query.cursor()

        for k in res_keys:
            q_key = search.decode_query_index_key_name(k.name())
            user_key = q_key.parent()
            if user_key != self.user_key:
                result_keys.append(q_key)
                chat_id = common.get_chat_key_name(self.user_key, user_key)
                existing_chats[user_key] = self.datastore_fetcher.get(
                    db.Key.from_path('User', self.user_key.id_or_name(),
                                     'UserChat', chat_id))
                users_status[user_key] = self.memcache_fetcher.get(
                    config.MEMCACHE_LAST_BEEN_ONLINE(user_key.id_or_name()))
                unread_chats[user_key] = self.datastore_fetcher.get(
                    db.Key.from_path('User', self.user_key.id_or_name(),
                                     'UnreadChat', chat_id))

        results = self.datastore_fetcher.get(result_keys)

        result_values = []
        online_count = 1
        for r in results:
            user_key = r.parent_key()
            status_class = "online" if users_status[user_key].get_result(
            ) is not None else "offline"
            if status_class == 'online':
                online_count += 1

            v = {
                'query': r.query_string,
                'key': r.key(),
                'username': models.User.get_username(user_key),
                'status_class': status_class,
                'context': common.htmlize_string(r.context),
            }

            if existing_chats[user_key].get_result() is not None:
                v['existing_chat'] = existing_chats[user_key].name
                if unread_chats[user_key].get_result() is not None:
                    v['existing_chat_unread'] = True

            result_values.append(v)

        if not result_values:
            self.template_values['top_searches'] = get_top_searches()

        if not cursor:
            context_text = ""
            if context:
                context_text = context.context
                keyword_hashes = list(
                    keyword_hashes + search.get_keyword_hashes(
                        search.clean_query_string(context_text)))[:config.
                                                                  MAX_KEYWORDS]
            query = existing_query.get_result()
            if query is not None:
                existing_index = db.Query(models.QueryIndex,
                                          keys_only=True).filter(
                                              'query =', query).get()
                if existing_index is not None:
                    db.delete(existing_index)
                query.query_string = q
                query.context = context_text
                query.date_time = self.now
            else:
                query = models.Query(key=query_key,
                                     query_string=q,
                                     context=context_text,
                                     date_time=self.now)

            index = models.QueryIndex(
                key_name=search.encode_query_index_key_name(query_key),
                query=query_key,
                user=self.user_key,
                keyword_hashes=keyword_hashes)

            top_search = models.TopSearch(
                key_name=query_key.name(),
                query_string=q,
                rating=float(len(search_hashes) * online_count))
            db.put([query, index, top_search])

        self.template_values["results"] = result_values
        self.template_values["key"] = query.key()
        self.template_values["query"] = q
        self.template_values["cursor"] = cursor

        self.render_page('SearchPage.html')