예제 #1
0
  def get(self):
    vote_for = int(self.request.get('which_photo'))
    fb_uid = str(self.request.get('fb_uid'))
    user = CacheController.get_user_by_fb_id(fb_uid)

    if not user:
      self.write_error("Can't add vote: User with fb_uid %s is not logged in." % fb_uid)
      return

    # Since the post is taken from the cache, it might not be the most updated version
    # but that's ok, as it is only used as 'parent'
    choosie_post = CacheController.get_model(self.request.get('post_key'))

    vote = Vote(parent=choosie_post,
                user_fb_id=fb_uid,
                vote_for=int(vote_for))

    prev_vote = vote.prev_vote_for_user_for_post()
    #if the user voted to the same post but for different item, updating the vote
    if (prev_vote is not None and prev_vote.vote_for != vote_for):
      prev_vote.vote_for = vote_for
      prev_vote.put()
      choosie_post.add_vote_to_post(vote, False)
      self.response.write('Vote changed to photo number %d.' % vote_for)
    #if voted to same pic - error
    elif(prev_vote != None):
       self.write_error("already voted!")
    else:
      vote.put()
      ChoosiePost.add_vote_to_post(choosie_post, vote, True)
      # Make sure the ChoosiePost is invalidated in cache, so that next time it is asked
      # for, the updated one is retreived.
      Vote.invalidate_votes(self.request.get('post_key'))
      self.response.write('A new vote issued for photo number %d.' % vote_for)
 def post(self):
   fb_uid = str(self.request.get('fb_uid'))
   device_id = str(self.request.get('device_id'))
   user = CacheController.get_user_by_fb_id(fb_uid)
   if user is not None:
     logging.info("device id was set to " + device_id)
     user.device_id = device_id
     user.put()
     CacheController.invalidate_user_fb_id(fb_uid)
     logging.info("Device was registered successfully for user " + user.first_name + " " + user.last_name)
   else:
     logging.error("No user was found with user_id %s. Failed to register device." % fb_uid)
 def post(self, fb_uid):
     user = CacheController.get_user_by_fb_id(fb_uid)
     nick = self.request.get("nick")
     info = self.request.get("info")
     if nick == "":
         user.nick = None
     else:
         user.nick = nick
     user.info = info
     user.put()
     CacheController.invalidate_user_fb_id(fb_uid)
     self.response.out.write(json.dumps({"success": "true"}))
예제 #4
0
 def post(self, fb_uid):
    user = CacheController.get_user_by_fb_id(fb_uid)
    nick = self.request.get("nick")
    info = self.request.get("info")
    if nick == "":
      user.nick = None
    else:
      user.nick = nick
    user.info = info
    user.put()
    CacheController.invalidate_user_fb_id(fb_uid)
    self.response.out.write(json.dumps({"success" : "true"}))
  def add_scraped_comments_to_post_transaction(choosie_post_key, comments, votes):
    updated_post = db.get(choosie_post_key)
    comments_as_strings = [str(comment) for comment in comments]

    for comment_str in comments_as_strings:
      # Add only new comments to updated_post.comments
      if comment_str not in updated_post.comments:
        updated_post.comments.append(comment_str)

    for vote in votes:
      updated_post.add_vote_to_post_internal(vote)
    updated_post.put()
    CacheController.set_model(updated_post)
    def add_scraped_comments_to_post_transaction(choosie_post_key, comments,
                                                 votes):
        updated_post = db.get(choosie_post_key)
        comments_as_strings = [str(comment) for comment in comments]

        for comment_str in comments_as_strings:
            # Add only new comments to updated_post.comments
            if comment_str not in updated_post.comments:
                updated_post.comments.append(comment_str)

        for vote in votes:
            updated_post.add_vote_to_post_internal(vote)
        updated_post.put()
        CacheController.set_model(updated_post)
 def post(self):
     fb_uid = str(self.request.get('fb_uid'))
     device_id = str(self.request.get('device_id'))
     user = CacheController.get_user_by_fb_id(fb_uid)
     if user is not None:
         logging.info("device id was set to " + device_id)
         user.device_id = device_id
         user.put()
         CacheController.invalidate_user_fb_id(fb_uid)
         logging.info("Device was registered successfully for user " +
                      user.first_name + " " + user.last_name)
     else:
         logging.error(
             "No user was found with user_id %s. Failed to register device."
             % fb_uid)
  def notify_friends_async(self, choosie_post_key):
    try:
      choosie_post = CacheController.get_model(str(choosie_post_key))

      logging.info("choosie post key = %s", str(choosie_post.key()))
      for user in User.all():
        logging.info("%s: device %s, uid: %s", user.name(), user.device_id, user.fb_uid)

      users = User.all()
      top_list = self.top_users()
      recipients = [u for u in User.all()
                   if ((ChoosieConfiguration.get_send_to_rest_setting() == False) and (u.fb_uid in top_list) or (ChoosieConfiguration.get_send_to_rest_setting() == True))]

      logging.info("First selection: %s", ", ".join([user.name() for user in recipients]))

      recipients = [u for u in recipients
                    if u.device_id is not None and user.fb_uid != choosie_post.user_fb_id]

      result = NotifyHandler.send_notifiction(NotifyHandler.notify_type["new_post"],
                                              self.get_user().display_name(), 
                                              str(choosie_post_key),
                                              recipients)

      ChoosieConfiguration.set_sent_to_rest_setting(not ChoosieConfiguration.get_send_to_rest_setting())

      logging.info("result of notifying friends= " + result)
    except Exception, e:
      logging.error("Faled to notify friends on new post: %s" % e)
예제 #9
0
    def get(self, fb_uid):
        # This post is got from the cache. That's ok, because all of the actual
        # dynamic data (votes, comments) is retrieved from the datastore during
        # choosie_post.to_json().
        user = CacheController.get_user_by_fb_id(fb_uid)

        self.response.out.write(json.dumps(self.profile_details_json(user)))
예제 #10
0
  def get(self, fb_uid):
    # This post is got from the cache. That's ok, because all of the actual
    # dynamic data (votes, comments) is retrieved from the datastore during
    # choosie_post.to_json().
    user = CacheController.get_user_by_fb_id(fb_uid)

    self.response.out.write(json.dumps(self.profile_details_json(user)))
예제 #11
0
 def get(self, key):
   logging.info(key)
   # This post is got from the cache. That's ok, because all of the actual
   # dynamic data (votes, comments) is retrieved from the datastore during
   # choosie_post.to_json().
   choosie_post = CacheController.get_model(key)
   self.response.out.write(json.dumps(choosie_post.to_json()))
  def add_vote_to_post(self, vote, is_new):
    db.run_in_transaction(ChoosiePost.add_vote_to_post_transaction, self.key(), vote)
    logging.info("user_id" + self.user_fb_id)
    logging.info("vote_id " + vote.user_fb_id)

    if is_new:
      user = CacheController.get_user_by_fb_id(self.user_fb_id)
      if user.num_votes:
        user.num_votes += 1
      else:
        user.num_votes = 1
      user.put()
      CacheController.invalidate_user_fb_id(user.fb_uid)

    if self.user_fb_id != vote.user_fb_id and self.created_at > datetime.datetime.now() - datetime.timedelta(0.1): # if i didnt vote on my self and the post was uploaded less then 2.5 hours ago
      vote_from = vote.get_user().display_name()
      deferred.defer(self.notify_vote_async, self.key(), self.user_fb_id, vote_from)
  def scrape_comments_and_votes_from_facebook(choosie_post_key):
    choosie_post = CacheController.get_model(choosie_post_key)
    if not choosie_post:
      return (None, None, "[%s] is not a valid ChoosiePost key" % choosie_post_key)
    fb_post_id = choosie_post.fb_post_id
    if not fb_post_id:
      return (None, None, "[%s] doesn't have an associated Facebook post ID" % choosie_post_key)
    fb_access_token = choosie_post.get_user().fb_access_token
    json_comments = Utils.get_json_comments_from_fb_post(fb_post_id, fb_access_token)
    comments, votes = ScrapeCommentsHandler.parse_facebook_comments(json_comments)

    if choosie_post_key and (len(comments) > 0 or len(votes) > 0):
      choosie_post = CacheController.get_model(choosie_post_key)
      if choosie_post:
        choosie_post.add_scraped_comments_to_post(comments, votes)
    
    return comments, votes, None
예제 #14
0
    def post(self):
        user = CacheController.get_user_by_fb_id(self.request.get('fb_uid'))
        logging.info(self.request.get('fb_uid'))
        if user is None:
            self.error(500)
            logging.error("user not found!")
            return

        logging.info("user found!")
        logging.info("share_to_fb_param: " +
                     self.request.get("share_to_fb", default_value="off"))

        if (self.request.get("share_to_fb", default_value="off") == "on"):
            logging.info("user" + user.fb_access_token)
            logging.info("user_db" + str(self.request.get('fb_access_token')))
            logging.info("key " + str(user.key()))
            # updating user access token cause he might added publish_stream permission
            if (user.fb_access_token != str(
                    self.request.get('fb_access_token'))):
                logging.info("Changing access_token!")
                user.fb_access_token = str(self.request.get('fb_access_token'))
                user.fb_access_token_expdate = Utils.get_access_token_from_request(
                    self.request)
                user.put()
                CacheController.invalidate_user_fb_id(user.fb_uid)

        photo1_blob_key = Utils.write_file_to_blobstore(
            self.shrinkImage(self.request.get('photo1')))
        photo2_blob_key = Utils.write_file_to_blobstore(
            self.shrinkImage(self.request.get('photo2')))

        choosie_post = ChoosiePost(question=self.request.get('question'),
                                   user_fb_id=self.request.get('fb_uid'),
                                   photo1_blob_key=photo1_blob_key,
                                   photo2_blob_key=photo2_blob_key)

        # Save this post in the datastore, and also in the memcache.
        choosie_post.put()
        CacheController.set_model(choosie_post)
        logging.info("share:" +
                     self.request.get("share_to_fb", default_value="off"))
        if (self.request.get("share_to_fb") == "on"):
            logging.info("publishing!!")
            choosie_post.publish_to_facebook(self.request.host_url)
        self.redirect('/')
예제 #15
0
 def get_feed_and_cursor(cursor, limit = 10, timestamp = None):
     if not limit:
         limit = 10
     limit = int(limit)
     logging.info('Retrieving %d posts from db' % limit)
     posts = ChoosiePost.all()
     if cursor:
         posts.with_cursor(cursor)
     if timestamp:
         created_after = Utils.parse_iso_format_datetime(timestamp)
         posts.filter('created_at >', created_after)
     posts.order("-created_at")
     posts_result = []
     for post in posts.run(limit=limit):
         posts_result.append(post)
     new_cursor = posts.cursor()
     CacheController.set_multi_models(posts_result)
     return (posts_result, new_cursor)
 def build_comment_model_from_fb_comment(json_comment):
   comment = Comment(user_fb_id=json_comment["from"]["id"],
                     created_at=Utils.parse_utf_format_datetime(json_comment["created_time"]),
                     text=json_comment["message"])
   choosie_user = CacheController.get_user_by_fb_id(json_comment["from"]["id"])
   if choosie_user is None:
     comment.is_scraped = True
     comment.scraped_user_details = str(ScrapeCommentsHandler.build_user_details(json_comment))
   return comment
예제 #17
0
 def get_feed_and_cursor(cursor, limit=10, timestamp=None):
     if not limit:
         limit = 10
     limit = int(limit)
     logging.info('Retrieving %d posts from db' % limit)
     posts = ChoosiePost.all()
     if cursor:
         posts.with_cursor(cursor)
     if timestamp:
         created_after = Utils.parse_iso_format_datetime(timestamp)
         posts.filter('created_at >', created_after)
     posts.order("-created_at")
     posts_result = []
     for post in posts.run(limit=limit):
         posts_result.append(post)
     new_cursor = posts.cursor()
     CacheController.set_multi_models(posts_result)
     return (posts_result, new_cursor)
 def build_comment_model_from_fb_comment(json_comment):
   comment = Comment(user_fb_id=json_comment["from"]["id"],
                     created_at=Utils.parse_utf_format_datetime(json_comment["created_time"]),
                     text=json_comment["message"])
   choosie_user = CacheController.get_user_by_fb_id(json_comment["from"]["id"])
   if choosie_user is None:
     comment.is_scraped = True
     comment.scraped_user_details = str(ScrapeCommentsHandler.build_user_details(json_comment))
   return comment
예제 #19
0
 def get_comments_for_post(post_key):
   comments = memcache.get(post_key, namespace=COMMENTS_NAMESPACE)
   if comments is not None:
     logging.info('Skipped a data store call for comments.')
     return comments
   else:
     logging.info('Retrieving comments for [%s] from data store.' % post_key)
     post = CacheController.get_model(post_key)
     comments = Comment.all().ancestor(post)
     memcache.set(post_key, comments, namespace=COMMENTS_NAMESPACE)
     return comments
  def notify_comment_async(self, choosie_post_key, user_fb_uid, commenter_name):
    try:
      user = CacheController.get_user_by_fb_id(user_fb_uid)
      result = NotifyHandler.send_notifiction(NotifyHandler.notify_type["comment"],
                                              commenter_name,
                                              str(choosie_post_key),
                                              [user])

      logging.info("result of notifying on comment from " + commenter_name + " : "  + result)
    except Exception, e:
      logging.error("Faled to notify on new comment: %s" % e)
예제 #21
0
 def from_string_for_choosie_post(comment_str):
   # When parsing the string represantation (see to_string_for_choosie_post() above),
   # there are two options.
   as_dict = ast.literal_eval(comment_str)
   if "user_fb_id" in as_dict:
     # For option 1 (regualr, not scraped comments), we need to also get the user
     # details.
     user = CacheController.get_user_by_fb_id(as_dict["user_fb_id"])
     del as_dict["user_fb_id"]
     as_dict["user"] = user.to_short_json()
   return as_dict
예제 #22
0
 def from_string_for_choosie_post(comment_str):
     # When parsing the string represantation (see to_string_for_choosie_post() above),
     # there are two options.
     as_dict = ast.literal_eval(comment_str)
     if "user_fb_id" in as_dict:
         # For option 1 (regualr, not scraped comments), we need to also get the user
         # details.
         user = CacheController.get_user_by_fb_id(as_dict["user_fb_id"])
         del as_dict["user_fb_id"]
         as_dict["user"] = user.to_short_json()
     return as_dict
  def notify_vote_async(self, choosie_post_key, user_fb_uid, name_of_from_user):
    try:
      user = CacheController.get_user_by_fb_id(user_fb_uid)
      result = NotifyHandler.send_notifiction(NotifyHandler.notify_type["vote"],
                                              name_of_from_user,
                                              str(choosie_post_key), 
                                              [user])

      logging.info("result of notifying on vote from " + name_of_from_user + " : " +  result)
    except Exception, e:
      logging.error("Faled to notify on new vote: %s" % e)
예제 #24
0
 def get_votes_for_post(post_key):
   votes = memcache.get(post_key, namespace=VOTES_NAMESPACE)
   if votes is not None:
     logging.info('Skipped a data store call for votes.')
     return votes
   else:
     logging.info('Retrieving votes for [%s] from data store.' % post_key)
     post = CacheController.get_model(post_key)
     votes = Vote.all().ancestor(post)
     memcache.set(post_key, votes, namespace=VOTES_NAMESPACE)
     return votes
예제 #25
0
    def get(self):
        choosie_post = CacheController.get_model(self.request.get('post_key'))
        which_photo = int(self.request.get('which_photo'))
        result = {
            0: choosie_post.photo,
            1: choosie_post.photo1,
            2: choosie_post.photo2
        }[which_photo]

        self.response.headers['Content-Type'] = 'image/png'
        self.response.headers['Cache-Control'] = 'max-age=290304000, private'
        self.response.out.write(result)
예제 #26
0
 def get_votes_for_post(post_key):
     votes = memcache.get(post_key, namespace=VOTES_NAMESPACE)
     if votes is not None:
         logging.info('Skipped a data store call for votes.')
         return votes
     else:
         logging.info('Retrieving votes for [%s] from data store.' %
                      post_key)
         post = CacheController.get_model(post_key)
         votes = Vote.all().ancestor(post)
         memcache.set(post_key, votes, namespace=VOTES_NAMESPACE)
         return votes
    def notify_vote_async(self, choosie_post_key, user_fb_uid,
                          name_of_from_user):
        try:
            user = CacheController.get_user_by_fb_id(user_fb_uid)
            result = NotifyHandler.send_notifiction(
                NotifyHandler.notify_type["vote"], name_of_from_user,
                str(choosie_post_key), [user])

            logging.info("result of notifying on vote from " +
                         name_of_from_user + " : " + result)
        except Exception, e:
            logging.error("Faled to notify on new vote: %s" % e)
    def notify_comment_async(self, choosie_post_key, user_fb_uid,
                             commenter_name):
        try:
            user = CacheController.get_user_by_fb_id(user_fb_uid)
            result = NotifyHandler.send_notifiction(
                NotifyHandler.notify_type["comment"], commenter_name,
                str(choosie_post_key), [user])

            logging.info("result of notifying on comment from " +
                         commenter_name + " : " + result)
        except Exception, e:
            logging.error("Faled to notify on new comment: %s" % e)
예제 #29
0
  def get(self):
    choosie_post = CacheController.get_model(self.request.get('post_key'))
    which_photo = int(self.request.get('which_photo'))
    result = {
      0: choosie_post.photo,
      1: choosie_post.photo1,
      2: choosie_post.photo2
    }[which_photo]

    self.response.headers['Content-Type'] = 'image/png'
    self.response.headers['Cache-Control'] = 'max-age=290304000, private'
    self.response.out.write(result)
예제 #30
0
  def post(self):
    user = CacheController.get_user_by_fb_id(self.request.get('fb_uid'))
    logging.info(self.request.get('fb_uid'))
    if user is None:
       self.error(500)
       logging.error("user not found!")
       return

    logging.info("user found!")
    logging.info("share_to_fb_param: " + self.request.get("share_to_fb", default_value="off"))

    if (self.request.get("share_to_fb", default_value="off") == "on"):
      logging.info("user" + user.fb_access_token)
      logging.info("user_db" + str(self.request.get('fb_access_token')))
      logging.info("key " + str(user.key()))
      # updating user access token cause he might added publish_stream permission
      if (user.fb_access_token != str(self.request.get('fb_access_token'))):
        logging.info("Changing access_token!")
        user.fb_access_token = str(self.request.get('fb_access_token'))
        user.fb_access_token_expdate = Utils.get_access_token_from_request(self.request)
        user.put()
        CacheController.invalidate_user_fb_id(user.fb_uid)

    photo1_blob_key = Utils.write_file_to_blobstore(self.shrinkImage(self.request.get('photo1')))
    photo2_blob_key = Utils.write_file_to_blobstore(self.shrinkImage(self.request.get('photo2')))

    choosie_post = ChoosiePost(question = self.request.get('question'),
                               user_fb_id = self.request.get('fb_uid'),
                               photo1_blob_key = photo1_blob_key,
                               photo2_blob_key = photo2_blob_key)

    # Save this post in the datastore, and also in the memcache.
    choosie_post.put()
    CacheController.set_model(choosie_post)
    logging.info("share:" + self.request.get("share_to_fb", default_value="off"))
    if (self.request.get("share_to_fb") == "on"):
      logging.info("publishing!!")
      choosie_post.publish_to_facebook(self.request.host_url)  
    self.redirect('/')
    
    def add_vote_to_post(self, vote, is_new):
        db.run_in_transaction(ChoosiePost.add_vote_to_post_transaction,
                              self.key(), vote)
        logging.info("user_id" + self.user_fb_id)
        logging.info("vote_id " + vote.user_fb_id)

        if is_new:
            user = CacheController.get_user_by_fb_id(self.user_fb_id)
            if user.num_votes:
                user.num_votes += 1
            else:
                user.num_votes = 1
            user.put()
            CacheController.invalidate_user_fb_id(user.fb_uid)

        if self.user_fb_id != vote.user_fb_id and self.created_at > datetime.datetime.now(
        ) - datetime.timedelta(
                0.1
        ):  # if i didnt vote on my self and the post was uploaded less then 2.5 hours ago
            vote_from = vote.get_user().display_name()
            deferred.defer(self.notify_vote_async, self.key(), self.user_fb_id,
                           vote_from)
예제 #32
0
    def scrape_comments_and_votes_from_facebook(choosie_post_key):
        choosie_post = CacheController.get_model(choosie_post_key)
        if not choosie_post:
            return (None, None,
                    "[%s] is not a valid ChoosiePost key" % choosie_post_key)
        fb_post_id = choosie_post.fb_post_id
        if not fb_post_id:
            return (None, None,
                    "[%s] doesn't have an associated Facebook post ID" %
                    choosie_post_key)
        fb_access_token = choosie_post.get_user().fb_access_token
        json_comments = Utils.get_json_comments_from_fb_post(
            fb_post_id, fb_access_token)
        comments, votes = ScrapeCommentsHandler.parse_facebook_comments(
            json_comments)

        if choosie_post_key and (len(comments) > 0 or len(votes) > 0):
            choosie_post = CacheController.get_model(choosie_post_key)
            if choosie_post:
                choosie_post.add_scraped_comments_to_post(comments, votes)

        return comments, votes, None
  def scrape_comments_and_votes_from_facebook(choosie_post_key):
    choosie_post = CacheController.get_model(choosie_post_key)
    if not choosie_post:
      return (None, None, "[%s] is not a valid ChoosiePost key" % choosie_post_key)

    fb_post_id = choosie_post.fb_post_id
    if not fb_post_id:
      return (None, None, "[%s] doesn't have an associated Facebook post ID" % choosie_post_key)

    fb_access_token = choosie_post.get_user().fb_access_token
    json_comments, error = Utils.get_json_comments_from_fb_post(fb_post_id, fb_access_token)
    if error:
      return (None, None, "Couldn't scraped comments for post with ID [%s] (user FB UID = [%s]). Error: %s"
                          % (fb_post_id, choosie_post.fb_post_id, error))

    comments, votes = ScrapeCommentsHandler.parse_facebook_comments(json_comments, choosie_post.post_type_id)

    if choosie_post_key and (len(comments) > 0 or len(votes) > 0):
      choosie_post = CacheController.get_model(choosie_post_key)
      if choosie_post:
        choosie_post.add_scraped_comments_to_post(comments, votes)
    
    return comments, votes, None
예제 #34
0
 def post(self):
     fb_access_token = str(self.request.get("fb_access_token"))
     fb_uid = str(self.request.get("fb_uid"))
     fb_access_token_expdate = Utils.get_access_token_from_request(self.request)
     user = CacheController.get_user_by_fb_id(fb_uid)
     if user is None:
         User.create(fb_access_token, fb_access_token_expdate)
         self.response.write("User created.")
     else:
         # updating access token fields
         user.fb_access_token = fb_access_token
         user.fb_access_token_expdate = fb_access_token_expdate
         user.put()
         self.response.write("User [%s %s] logged in successfully." % (user.first_name, user.last_name))
예제 #35
0
  def from_string_for_choosie_post(vote_str, keep_shallow=False):
    as_dict = ast.literal_eval(vote_str)

    if "user_fb_id" in as_dict:
      # For option 1 (regular, not scraped comments), we need to also get the user
      # details.
      if keep_shallow:
        user = {"fb_uid": as_dict["user_fb_id"]}
      else:
        user = CacheController.get_user_by_fb_id(as_dict["user_fb_id"]).to_short_json()
      del as_dict["user_fb_id"]
      as_dict["user"] = user
    
    return as_dict
예제 #36
0
class TopicsManager:
    subscribers_controller = []
    __cache = CacheController().__get_instance__
    __security = SecurityCell().__get_instance__

    def __init__(self):
        self.update()

    def add_subscriber(self, channel, subscriber_connection, key):
        _channel = next((__channel for __channel in self.subscribers_controller
                         if __channel['channel'] == channel), None)
        if not _channel:
            raise Exception("Channel not founded")

        (_channel['subscribers']).append({
            'connection': subscriber_connection,
            'key': key
        })
        return True

    def send_message_to_subscribers(self, channel, address, message, topic):
        _channel = next((__channel for __channel in self.subscribers_controller
                         if __channel['channel'] == channel), None)

        if not _channel:
            logging.error("Channel not found")
            raise Exception("Channel not founded")

        for __channel in _channel['subscribers']:
            try:
                response = {
                    "type": "response",
                    "topic": topic,
                    "message": message
                }

                __channel['connection'].send(
                    self.__security.generate_token(response,
                                                   __channel['key']).encode())
            except:
                pass

    def update(self):
        _, channels = self.__cache.get()

        self.subscribers_controller = [{
            'channel': channel['_id'],
            'subscribers': []
        } for channel in channels]
예제 #37
0
  def post(self):
    fb_uid = str(self.request.get('fb_uid'))
    # TODO: Make sure text is Unicode
    text = self.request.get('text')

    # Since the post is taken from the cache, it might not be the most updated version
    # but that's ok, as it is only used as 'parent'
    choosie_post = CacheController.get_model(self.request.get('post_key'))
    fb_uid = self.request.get('fb_uid')
    user = CacheController.get_user_by_fb_id(fb_uid)
    if not user:
      self.response.write("Comment not added: User with fb_uid %s is not logged in." % fb_uid)
      return
      
    comment = Comment(parent=choosie_post,
                      user_fb_id=fb_uid,
                      text=text)
    comment.put()
    choosie_post.add_comment_to_post(comment)
    # Make sure the ChoosiePost's comments are invalidated in cache, so that next time
    # they are asked for, the updated are retreived.
    Comment.invalidate_comments(self.request.get('post_key'))

    self.response.write('Comment added.')
예제 #38
0
    def post(self):
        fb_uid = str(self.request.get('fb_uid'))
        # TODO: Make sure text is Unicode
        text = self.request.get('text')

        # Since the post is taken from the cache, it might not be the most updated version
        # but that's ok, as it is only used as 'parent'
        choosie_post = CacheController.get_model(self.request.get('post_key'))
        fb_uid = self.request.get('fb_uid')
        user = CacheController.get_user_by_fb_id(fb_uid)
        if not user:
            self.response.write(
                "Comment not added: User with fb_uid %s is not logged in." %
                fb_uid)
            return

        comment = Comment(parent=choosie_post, user_fb_id=fb_uid, text=text)
        comment.put()
        choosie_post.add_comment_to_post(comment)
        # Make sure the ChoosiePost's comments are invalidated in cache, so that next time
        # they are asked for, the updated are retreived.
        Comment.invalidate_comments(self.request.get('post_key'))

        self.response.write('Comment added.')
예제 #39
0
    def from_string_for_choosie_post(vote_str, keep_shallow=False):
        as_dict = ast.literal_eval(vote_str)

        if "user_fb_id" in as_dict:
            # For option 1 (regular, not scraped comments), we need to also get the user
            # details.
            if keep_shallow:
                user = {"fb_uid": as_dict["user_fb_id"]}
            else:
                user = CacheController.get_user_by_fb_id(
                    as_dict["user_fb_id"]).to_short_json()
            del as_dict["user_fb_id"]
            as_dict["user"] = user

        return as_dict
예제 #40
0
 def post(self):
     fb_access_token = str(self.request.get('fb_access_token'))
     fb_uid = str(self.request.get('fb_uid'))
     fb_access_token_expdate = Utils.get_access_token_from_request(
         self.request)
     user = CacheController.get_user_by_fb_id(fb_uid)
     if user is None:
         User.create(fb_access_token, fb_access_token_expdate)
         self.response.write('User created.')
     else:
         # updating access token fields
         user.fb_access_token = fb_access_token
         user.fb_access_token_expdate = fb_access_token_expdate
         user.put()
         self.response.write('User [%s %s] logged in successfully.' %
                             (user.first_name, user.last_name))
 def publish_dillema_on_wall(self, choosie_post_key, domain):
   try:
     choosie_post = CacheController.get_model(str(choosie_post_key))
     logging.info("publishing on wall")
     logging.info("publishing with access_token " + choosie_post.get_user().fb_access_token)
     graph = facebook.GraphAPI(choosie_post.get_user().fb_access_token)
     logging.info("type = " + str(choosie_post.post_type()))
     if choosie_post.post_type() == CHOOSIE_POST_TYPE_DILEMMA:
       pic = Utils.create_dillema_post_image(self)
       question = choosie_post.question + '\n(Start your comment with #1 or #2 to help me choose.)'
     else:
       pic = Utils.create_yesno_post_image(self)
       img1_blob_reader = blobstore.BlobReader(choosie_post.photo1_blob_key)
       question = choosie_post.question + '\n(Start your comment with #yes or #no to help me choose.)'
     picIO = StringIO(pic)
     response = graph.put_photo(picIO, question.encode('utf-8'))
     logging.info(str(response))
     choosie_post.fb_post_id = response['post_id']
     choosie_post.posted_to_fb = True
     choosie_post.put()
   except Exception, e:
     logging.error("Facebook publishing failed: %s" % e)
    def notify_friends_async(self, choosie_post_key):
        try:
            choosie_post = CacheController.get_model(str(choosie_post_key))

            logging.info("choosie post key = %s", str(choosie_post.key()))
            for user in User.all():
                logging.info("%s: device %s, uid: %s", user.name(),
                             user.device_id, user.fb_uid)

            users = User.all()
            top_list = self.top_users()
            recipients = [
                u for u in User.all()
                if ((ChoosieConfiguration.get_send_to_rest_setting() == False)
                    and (u.fb_uid in top_list) or
                    (ChoosieConfiguration.get_send_to_rest_setting() == True))
            ]

            logging.info("First selection: %s",
                         ", ".join([user.name() for user in recipients]))

            recipients = [
                u for u in recipients if u.device_id is not None
                and user.fb_uid != choosie_post.user_fb_id
            ]

            result = NotifyHandler.send_notifiction(
                NotifyHandler.notify_type["new_post"],
                self.get_user().display_name(), str(choosie_post_key),
                recipients)

            ChoosieConfiguration.set_sent_to_rest_setting(
                not ChoosieConfiguration.get_send_to_rest_setting())

            logging.info("result of notifying friends= " + result)
        except Exception, e:
            logging.error("Faled to notify friends on new post: %s" % e)
 def publish_dillema_on_wall(self, choosie_post_key, domain):
     try:
         choosie_post = CacheController.get_model(str(choosie_post_key))
         logging.info("publishing on wall")
         logging.info("publishing with access_token " +
                      choosie_post.get_user().fb_access_token)
         graph = facebook.GraphAPI(choosie_post.get_user().fb_access_token)
         logging.info("type = " + str(choosie_post.post_type()))
         if choosie_post.post_type() == CHOOSIE_POST_TYPE_DILEMMA:
             pic = Utils.create_dillema_post_image(self)
             question = choosie_post.question + '\n(Start your comment with #1 or #2 to help me choose.)'
         else:
             pic = Utils.create_yesno_post_image(self)
             img1_blob_reader = blobstore.BlobReader(
                 choosie_post.photo1_blob_key)
             question = choosie_post.question + '\n(Start your comment with #yes or #no to help me choose.)'
         picIO = StringIO(pic)
         response = graph.put_photo(picIO, question.encode('utf-8'))
         logging.info(str(response))
         choosie_post.fb_post_id = response['post_id']
         choosie_post.posted_to_fb = True
         choosie_post.put()
     except Exception, e:
         logging.error("Facebook publishing failed: %s" % e)
class SocketController:
    __instance = None
    __port = 0
    __host = ''
    __connection_pool = []
    __connections = []

    __security = SecurityCell().__get_instance__
    __cache = CacheController()
    __topics = TopicsManager()

    s = None

    def __new__(cls):
        if cls.__instance is None:
            cls.__instance = object.__new__(cls)
        return cls.__instance

    @property
    def instance(self):
        if self.__instance is None:
            self.__instance = object.__new__(self)
        return self.__instance

    def configure(self, host, port):
        """
        Configure the host for the new broker
        :param host: Personalize host for the server. Environment has more relevance
        :param port: Personalize port for the server. Environment has more relevance
        :return:
        """
        logging.basicConfig(level=logging.DEBUG,
                            format='%(threadName)s: %(message)s')
        self.__port = os.environ.get("PORT", port)
        self.__host = os.environ.get("HOST", host)
        self.s = socket.create_server(("", 5050))
        self.s.listen(20)
        logging.info(f"Server configure in {self.__host}:{self.__port}")

    def start_socket(self):
        executor = ThreadPoolExecutor()

        while True:
            connection, address = self.s.accept()
            # Verify loggin
            connection_auth = connection.recv(4096)
            auth_result, key = self.auth(connection_auth)
            if auth_result:
                logging.info(
                    f"Connection accepted from: {address} pining back")
                pinning = {"type": "response", "response": "welcome"}
                connection.send(
                    self.__security.generate_token(pinning, key).encode())

                data = json.loads(connection_auth.decode())
                if data['topic'] == "update" and data['from'] == "synchronizer":
                    executor.submit(self.__update_connection, connection,
                                    address, key)
                else:
                    executor.submit(self.__read_connection, connection,
                                    address, key)
            else:
                logging.error("Authentication failed")
                pinning = {
                    "type": "error",
                    "response": "Authentication failed"
                }
                connection.send(
                    self.__security.generate_token(pinning, key).encode())

    def auth(self, connection_auth):
        data = json.loads(connection_auth.decode())
        logging.Logger(data)
        if data['type'] == "connection":
            if data['topic'] == "update":
                if data["from"] == "synchronizer" and data[
                        'user'] == "channel_controller":
                    return True, data['defaultKey']
                else:
                    return False, None
            else:
                client = self.__cache.search_client(data['user'])
                return True, client['key']['k']
        else:
            return False, None

    def __update_connection(self, connection, address, key):
        while True:
            data = connection.recv(4096)

            if not data:
                connection.close()

            data = data.decode()
            logging.info(data)

            _key = {'k': key, 'kty': 'oct'}
            try:
                info_to_update = self.__security.verify_token(data, _key)
            except Exception as err:
                logging.error(err)

            if info_to_update['type'] == "ping":
                response = self.__security.generate_token(
                    {
                        "type": "response",
                        "response": "pong"
                    }, key)
                connection.send(response.encode())
                continue

            self.__cache.save(info_to_update['data'])

            self.__topics.update()

            response = json.dumps({
                "type": "response",
                "response": "synchronized"
            }).encode()

            response = self.__security.generate_token(response, key)

            try:
                connection.send(response.encode())
            except Exception as err:
                logging.info("Thread killed. Connection closed")
                logging.error(err)

    def __read_connection(self, connection, address, key):
        while True:
            data = connection.recv(4096)

            if not data:
                connection.close()

            data = data.decode()

            try:
                _key = {'k': key, 'kty': 'oct'}
                data = self.__security.verify_token(data, _key)
                logging.info(data)
            except Exception as err:
                logging.error(err)

            if data['type'] == "subscribe":
                channel = self.__cache.search_channel(data['topic'])
                self.__topics.add_subscriber(channel['_id'], connection, key)

                data = {
                    "type": "response",
                    "response": "Subscribe to the channel"
                }

                connection.send(
                    self.__security.generate_token(data, key).encode())

            elif data['type'] == "disconnect":
                connection.send("Connection closed".encode())
                connection.close()
                break

            elif data['type'] == "message":
                channel = self.__cache.search_channel(data['topic'])
                logging.info(channel)
                self.__topics.send_message_to_subscribers(
                    channel['_id'], address, data['message'], data['topic'])

                data = self.__security.generate_token(data, key)

                try:
                    connection.send(data.encode())
                except Exception as err:
                    logging.info("Thread killed. Connection closed")
                    logging.error(err)
            else:
                logging.info("Message type unrecognized")

    def create_new_client(self):
        pass

    def __attach_client_in_topic(self, connection, address, topic):
        pass
 def add_vote_to_post_transaction(choosie_post_key, new_vote):
     updated_post = db.get(choosie_post_key)
     updated_post.add_vote_to_post_internal(new_vote)
     updated_post.put()
     CacheController.set_model(updated_post)
 def add_comment_to_post_transaction(choosie_post_key, comment):
     updated_post = db.get(choosie_post_key)
     # updated_post.comments is a StringListProperty. We add the new comment as a string.
     updated_post.comments.append(comment.to_string_for_choosie_post())
     updated_post.put()
     CacheController.set_model(updated_post)
예제 #47
0
 def get_user(self):
   return CacheController.get_user_by_fb_id(self.user_fb_id)
예제 #48
0
 def add_comment_to_post_transaction(choosie_post_key, comment):
     updated_post = db.get(choosie_post_key)
     # updated_post.comments is a StringListProperty. We add the new comment as a string.
     updated_post.comments.append(comment.to_string_for_choosie_post())
     updated_post.put()
     CacheController.set_model(updated_post)
예제 #49
0
class NotifyHandler(webapp2.RequestHandler):
    notify_type = {"new_post": 1, "comment": 2, "vote": 3}

    def get(self):
        message = "i love soja milk"
        # users = db.GqlQuery("SELECT * FROM User WHERE device_id > :1",None)
        users = User.all()
        user_array = []
        # devices = ["APA91bHlkage-d5iZhdRAZtKS1gUy8q1LcEyGXmmhBzaGXxMTp6S5QIxQGkp8HxiTExI6cim4KngJXzamvbjzOKLrRUPKQpQqKaevHAEertE_PKKT8UjkLabSDTw8ljXYVt59k_xqIWK"]
        for user in users.run():
            # devices.append(user.device_id)
            if user.device_id is not None:
                user_array.append(user)

        result = NotifyHandler.send_notifiction(
            NotifyHandler.notify_type["new_post"], "ron", "1", user_array)

        self.response.write("result is " + result)

    @staticmethod
    def send_notifiction(notification_type, text, post_key, recipients):
        device_ids_array = [user.device_id for user in recipients]

        logging.info("Sending notification to devices: %s",
                     ", ".join(device_ids_array))
        logging.info("Sending notification to users: %s",
                     ", ".join([user.name() for user in recipients]))
        data = {
            "data": {
                "type": notification_type,
                "text": text,
                "post_key": post_key
            },
            "registration_ids": device_ids_array
        }

        result = urlfetch.fetch(
            url="https://android.googleapis.com/gcm/send",
            payload=json.dumps(data),
            method=urlfetch.POST,
            headers={
                'Content-Type': 'application/json',
                'Authorization': 'key=AIzaSyDAkpOHWW6km87yen5W9C8y1MaGn7-hQKw'
            })
        result_is_json = False

        try:
            result_data = json.loads(result.content)
            result_is_json = True
        except Exception, e:
            logging.info("It is not json. Eshhhh.")

        if not result_is_json:
            return result.content

        logging.info(result_data)

        if result_data.get("canonical_ids") is not 0:
            for index, result in enumerate(result_data["results"]):
                if result.get("registration_id") is not None:
                    logging.info(
                        "Need to change device_id for user [%s]. New ID: %s",
                        recipients[index].name(), result)
                    user = recipients[index]
                    user.device_id = result.get("registration_id")
                    user.put()
                    CacheController.invalidate_user_fb_id(user.fb_uid)

        return str(result)
예제 #50
0
  def post(self):
    user = CacheController.get_user_by_fb_id(self.request.get('fb_uid'))
    logging.info(self.request.get('fb_uid'))
    if user is None:
       self.error(500)
       logging.error("user not found!")
       return

    logging.info("user found!")
    logging.info("share_to_fb_param: " + self.request.get("share_to_fb", default_value="off"))
    debug_show_fb = self.request.get("debug_show_fb", default_value="")
    logging.info("debug_show_fb: " + debug_show_fb)
    
    post_type_id = int(self.request.get("post_type_id", default_value="1"))

    if debug_show_fb:
      img1 = images.Image(self.shrinkImage(self.request.get('photo1')))
      img2 = images.Image(self.shrinkImage(self.request.get('photo2')))
      self.response.headers['Content-Type'] = 'image/png'
      self.response.out.write(Utils.compose_two_images(img1, img2))
      return

    if self.request.get("share_to_fb", default_value="off") == "on":
      logging.info("user" + user.fb_access_token)
      logging.info("user_db" + str(self.request.get('fb_access_token')))
      logging.info("key " + str(user.key()))
      # updating user access token cause he might added publish_stream permission
      if user.fb_access_token != str(self.request.get('fb_access_token')):
        logging.info("Changing access_token!")
        user.fb_access_token = str(self.request.get('fb_access_token'))
        user.fb_access_token_expdate = Utils.get_access_token_from_request(self.request)
        user.put()
        CacheController.invalidate_user_fb_id(user.fb_uid)

    if user.num_votes:
      user.num_votes += 1
    else:
      user.num_votes = 1
    user.put()
    CacheController.invalidate_user_fb_id(user.fb_uid)
    photo1_blob_key = Utils.write_file_to_blobstore(self.shrinkImage(self.request.get('photo1')))
    if post_type_id == 1:
      photo2_blob_key = Utils.write_file_to_blobstore(self.shrinkImage(self.request.get('photo2')))
    else:
      photo2_blob_key = None
    choosie_post = ChoosiePost(question = self.request.get('question'),
                               user_fb_id = self.request.get('fb_uid'),
                               photo1_blob_key = photo1_blob_key,
                               photo2_blob_key = photo2_blob_key,
                               post_type_id = post_type_id)

    # Save this post in the datastore, and also in the memcache.
    choosie_post.put()
    CacheController.set_model(choosie_post)
    logging.info("share:" + self.request.get("share_to_fb", default_value="off"))
    if self.request.get("share_to_fb") == "on":
      logging.info("publishing!!")
      choosie_post.publish_to_facebook(self.request.host_url)  

    choosie_post.notify_friends()
    self.redirect('/')
    
예제 #51
0
 def add_vote_to_post_transaction(choosie_post_key, new_vote):
     updated_post = db.get(choosie_post_key)
     updated_post.add_vote_to_post_internal(new_vote)
     updated_post.put()
     CacheController.set_model(updated_post)
예제 #52
0
    def post(self):
        user = CacheController.get_user_by_fb_id(self.request.get('fb_uid'))
        logging.info(self.request.get('fb_uid'))
        if user is None:
            self.error(500)
            logging.error("user not found!")
            return

        logging.info("user found!")
        logging.info("share_to_fb_param: " +
                     self.request.get("share_to_fb", default_value="off"))
        debug_show_fb = self.request.get("debug_show_fb", default_value="")
        logging.info("debug_show_fb: " + debug_show_fb)

        post_type_id = int(self.request.get("post_type_id", default_value="1"))

        if debug_show_fb:
            img1 = images.Image(self.shrinkImage(self.request.get('photo1')))
            img2 = images.Image(self.shrinkImage(self.request.get('photo2')))
            self.response.headers['Content-Type'] = 'image/png'
            self.response.out.write(Utils.compose_two_images(img1, img2))
            return

        if self.request.get("share_to_fb", default_value="off") == "on":
            logging.info("user" + user.fb_access_token)
            logging.info("user_db" + str(self.request.get('fb_access_token')))
            logging.info("key " + str(user.key()))
            # updating user access token cause he might added publish_stream permission
            if user.fb_access_token != str(
                    self.request.get('fb_access_token')):
                logging.info("Changing access_token!")
                user.fb_access_token = str(self.request.get('fb_access_token'))
                user.fb_access_token_expdate = Utils.get_access_token_from_request(
                    self.request)
                user.put()
                CacheController.invalidate_user_fb_id(user.fb_uid)

        if user.num_votes:
            user.num_votes += 1
        else:
            user.num_votes = 1
        user.put()
        CacheController.invalidate_user_fb_id(user.fb_uid)
        photo1_blob_key = Utils.write_file_to_blobstore(
            self.shrinkImage(self.request.get('photo1')))
        if post_type_id == 1:
            photo2_blob_key = Utils.write_file_to_blobstore(
                self.shrinkImage(self.request.get('photo2')))
        else:
            photo2_blob_key = None
        choosie_post = ChoosiePost(question=self.request.get('question'),
                                   user_fb_id=self.request.get('fb_uid'),
                                   photo1_blob_key=photo1_blob_key,
                                   photo2_blob_key=photo2_blob_key,
                                   post_type_id=post_type_id)

        # Save this post in the datastore, and also in the memcache.
        choosie_post.put()
        CacheController.set_model(choosie_post)
        logging.info("share:" +
                     self.request.get("share_to_fb", default_value="off"))
        if self.request.get("share_to_fb") == "on":
            logging.info("publishing!!")
            choosie_post.publish_to_facebook(self.request.host_url)

        choosie_post.notify_friends()
        self.redirect('/')