Exemple #1
0
  def __getattr__(self, name):
    """Overridden to pass auth_entity to :class:`granary.googleplus.GooglePlus`."""
    if name == 'gr_source' and self.auth_entity:
      self.gr_source = gr_googleplus.GooglePlus(auth_entity=self.auth_entity.get())
      return self.gr_source

    return getattr(super(GooglePlusPage, self), name)
Exemple #2
0
 def setUp(self):
     super(GooglePlusTest, self).setUp()
     self.auth_entity = oauth_googleplus.GooglePlusAuth(
         id='my_string_id',
         user_json=json.dumps({
             'displayName': 'Bob',
         }),
         creds_json=CREDS_JSON)
     self.googleplus = googleplus.GooglePlus(auth_entity=self.auth_entity)
Exemple #3
0
  def get(self):
    """Handles an API GET.

    Request path is of the form /site/user_id/group_id/app_id/activity_id ,
    where each element except site is an optional string object id.
    """
    # parse path
    args = urllib.unquote(self.request.path).strip('/').split('/')
    if not args or len(args) > MAX_PATH_LEN:
      raise exc.HTTPNotFound('Expected 1-%d path elements; found %d' %
                             (MAX_PATH_LEN, len(args)))

    # make source instance
    site = args.pop(0)
    if site == 'twitter':
      src = twitter.Twitter(
        access_token_key=util.get_required_param(self, 'access_token_key'),
        access_token_secret=util.get_required_param(self, 'access_token_secret'))
    elif site == 'facebook':
      src = facebook.Facebook(
        access_token=util.get_required_param(self, 'access_token'))
    elif site == 'flickr':
      src = flickr.Flickr(
        access_token_key=util.get_required_param(self, 'access_token_key'),
        access_token_secret=util.get_required_param(self, 'access_token_secret'))
    elif site == 'instagram':
      src = instagram.Instagram(
        access_token=util.get_required_param(self, 'access_token'))
    elif site == 'google+':
      auth_entity = util.get_required_param(self, 'auth_entity')
      src = googleplus.GooglePlus(auth_entity=ndb.Key(urlsafe=auth_entity).get())
    else:
      src_cls = source.sources.get(site)
      if not src_cls:
        raise exc.HTTPNotFound('Unknown site %r' % site)
      src = src_cls(**self.request.params)

    # handle default path elements
    args = [None if a in defaults else a
            for a, defaults in zip(args, PATH_DEFAULTS)]
    user_id = args[0] if args else None

    # fetch actor if necessary
    actor = None
    if self.request.get('format') == 'atom':
      # atom needs actor
      args = [None if a in defaults else a  # handle default path elements
              for a, defaults in zip(args, PATH_DEFAULTS)]
      user_id = args[0] if args else None
      actor = src.get_actor(user_id) if src else {}

    # get activities and write response
    response = src.get_activities_response(*args, **self.get_kwargs())
    self.write_response(response, actor=actor)
Exemple #4
0
  def get(self):
    try:
      cookie = 'SID=%(SID)s; SSID=%(SSID)s; HSID=%(HSID)s' % self.request.params
    except KeyError:
      return self.abort(400, 'Query parameters SID, SSID, and HSID are required')

    logging.info('Fetching with Cookie: %s', cookie)
    resp = urllib2.urlopen(urllib2.Request(
      'https://plus.google.com/',
      headers={
        'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.10; rv:39.0) Gecko/20100101 Firefox/39.0',
        'Cookie': cookie,
      }),
      timeout=60)
    body = resp.read().decode('utf-8')
    logging.info('Response: %s', resp.getcode())

    host_url = self.request.host_url + '/'
    if resp.getcode() in (401, 403) or 'href="https://accounts.google.com/Logout' not in body:
      self.response.headers['Content-Type'] = 'application/atom+xml'
      self.response.out.write(atom.activities_to_atom([{
        'object': {
          'url': self.request.url,
          'content': 'Your plusstreamfeed (Google+ Atom feed) cookie isn\'t working. <a href="%s">Click here to regenerate your feed!</a>' % host_url,
          },
        }], {}, title='plusstreamfeed (Google+ Atom feed)',
        host_url=host_url, request_url=self.request.path_url))
      return
    elif resp.getcode() != 200:
      return self.abort(502, "Google+ fetch failed")

    actor = {}
    name_email = re.compile(r'title="Google Account: ([^"]+)"').search(body)
    if name_email:
      logging.info('Logged in for user %s', name_email.group(1))
      actor = {'displayName': name_email.group(1)}
    else:
      logging.warning("Couldn't determine Google user!")

    activities = [
      a for a in googleplus.GooglePlus(None, None).html_to_activities(body)
      if a.get('verb') != 'like'
    ]

    self.response.headers['Content-Type'] = 'application/atom+xml'
    self.response.out.write(atom.activities_to_atom(
      activities, actor, title='plusstreamfeed (Google+ Atom feed)',
      host_url=host_url, request_url=self.request.path_url,
      xml_base='https://plus.google.com/'))
Exemple #5
0
 def setUp(self):
   super(GooglePlusTest, self).setUp()
   self.auth_entity = oauth_googleplus.GooglePlusAuth(
     id='my_string_id',
     user_json=json.dumps({
         'displayName': 'Bob',
         }),
     creds_json=json.dumps({
         'access_token': 'my token',
         'client_id': appengine_config.GOOGLE_CLIENT_ID,
         'client_secret': appengine_config.GOOGLE_CLIENT_SECRET,
         'refresh_token': 'my refresh token',
         'token_expiry': '',
         'token_uri': '',
         'user_agent': '',
         'invalid': '',
         }))
   self.googleplus = googleplus.GooglePlus(auth_entity=self.auth_entity)
Exemple #6
0
  def test_live(self):
    resp = requests.get(URL)
    resp.raise_for_status()

    activities = googleplus.GooglePlus().html_to_activities(resp.text)
    self.assertEqual(10, len(activities))

    import json; print json.dumps(activities, indent=2)

    found = set()
    for a in activities:
      self.assertTrue(a['actor'])
      for field in 'id', 'url':
        self.assertTrue(a['object'][field], field)
      for field in 'content', 'replies', 'tags', 'image':
        if a['object'].get(field):
          found.add(field)

    for field in 'content', 'replies', 'tags', 'image':
      self.assertIn(field, found)
Exemple #7
0
    def get(self):
        """Handles an API GET.

    Request path is of the form /site/user_id/group_id/app_id/activity_id ,
    where each element except site is an optional string object id.
    """
        # parse path
        args = urllib.unquote(self.request.path).strip('/').split('/')
        if not args or len(args) > MAX_PATH_LEN:
            raise exc.HTTPNotFound('Expected 1-%d path elements; found %d' %
                                   (MAX_PATH_LEN, len(args)))

        # make source instance
        site = args.pop(0)
        if site == 'twitter':
            src = twitter.Twitter(access_token_key=util.get_required_param(
                self, 'access_token_key'),
                                  access_token_secret=util.get_required_param(
                                      self, 'access_token_secret'))
        elif site == 'facebook':
            src = facebook.Facebook(
                access_token=util.get_required_param(self, 'access_token'))
        elif site == 'flickr':
            src = flickr.Flickr(access_token_key=util.get_required_param(
                self, 'access_token_key'),
                                access_token_secret=util.get_required_param(
                                    self, 'access_token_secret'))
        elif site == 'instagram':
            src = instagram.Instagram(scrape=True)
        elif site == 'google+':
            auth_entity = util.get_required_param(self, 'auth_entity')
            src = googleplus.GooglePlus(auth_entity=ndb.Key(
                urlsafe=auth_entity).get())
        else:
            src_cls = source.sources.get(site)
            if not src_cls:
                raise exc.HTTPNotFound('Unknown site %r' % site)
            src = src_cls(**self.request.params)

        # decode tag URI ids
        for i, arg in enumerate(args):
            parsed = util.parse_tag_uri(arg)
            if parsed:
                domain, id = parsed
                if domain != src.DOMAIN:
                    raise exc.HTTPBadRequest(
                        'Expected domain %s in tag URI %s, found %s' %
                        (src.DOMAIN, arg, domain))
                args[i] = id

        # check if request is cached
        cache = self.request.get('cache', '').lower() != 'false'
        if cache:
            cache_key = 'R %s' % self.request.path
            cached = memcache.get(cache_key)
            if cached:
                logging.info('Serving cached response %r', cache_key)
                self.write_response(cached['response'],
                                    actor=cached['actor'],
                                    url=src.BASE_URL)
                return

        # handle default path elements
        args = [
            None if a in defaults else a
            for a, defaults in zip(args, PATH_DEFAULTS)
        ]
        user_id = args[0] if args else None

        # get activities (etc)
        try:
            if len(args) >= 2 and args[1] == '@blocks':
                response = {'items': src.get_blocklist()}
            else:
                response = src.get_activities_response(*args,
                                                       **self.get_kwargs(src))
        except (NotImplementedError, ValueError) as e:
            self.abort(400, str(e))
            # other exceptions are handled by webutil.handlers.handle_exception(),
            # which uses interpret_http_exception(), etc.

        # fetch actor if necessary
        actor = response.get('actor')
        if not actor and self.request.get('format') == 'atom':
            # atom needs actor
            args = [
                None if a in defaults else a  # handle default path elements
                for a, defaults in zip(args, PATH_DEFAULTS)
            ]
            user_id = args[0] if args else None
            actor = src.get_actor(user_id) if src else {}

        self.write_response(response, actor=actor, url=src.BASE_URL)

        # cache response
        if cache:
            logging.info('Caching response in %r', cache_key)
            memcache.set(cache_key, {
                'response': response,
                'actor': actor
            }, src.RESPONSE_CACHE_TIME)