2009-05-15 3 views
1

Я пытаюсь прочитать электронную таблицу из движка приложения, используя text_db и authsub.AuthSub с Text_db в движке Google App

Я прочитал http://code.google.com/appengine/articles/gdata.html и получил его на работу. Потом я прочитал http://code.google.com/p/gdata-python-client/wiki/AuthSubWithTextDB и я попытался объединить два в файле ниже (step4.py), но когда я запускаю его локально я получаю:

Traceback (most recent call last): 
    File "/home/jmvidal/share/progs/googleapps/google_appengine/google/appengine/ext/webapp/__init__.py", line 498, in __call__ 
    handler.get(*groups) 
    File "/home/jmvidal/share/progs/googleapps/google_appengine/glassboard/step4.py", line 56, in get 
    session_token = client._GetDocsClient().UpgradeToSessionToken(auth_token) #If I don't pass this argument I get a NonAuthSubToken 
    File "/home/jmvidal/share/progs/googleapps/google_appengine/glassboard/gdata/service.py", line 866, in UpgradeToSessionToken 
    self.SetAuthSubToken(self.upgrade_to_session_token(token)) 
    File "/home/jmvidal/share/progs/googleapps/google_appengine/glassboard/gdata/service.py", line 885, in upgrade_to_session_token 
    headers={'Content-Type':'application/x-www-form-urlencoded'}) 
    File "/home/jmvidal/share/progs/googleapps/google_appengine/glassboard/gdata/auth.py", line 678, in perform_request 
    return http_client.request(operation, url, data=data, headers=headers) 
    File "/home/jmvidal/share/progs/googleapps/google_appengine/glassboard/atom/http.py", line 163, in request 
    return connection.getresponse() 
    File "/home/jmvidal/share/progs/googleapps/google_appengine/google/appengine/dist/httplib.py", line 200, in getresponse 
    self._allow_truncated, self._follow_redirects) 
    File "/home/jmvidal/share/progs/googleapps/google_appengine/google/appengine/api/urlfetch.py", line 267, in fetch 
    raise DownloadError(str(e)) 
DownloadError: ApplicationError: 2 nonnumeric port: '' 

Может кто-нибудь пролить некоторый свет на это? В частности, почему исходный файл (step3.py из первой ссылки) работает, но мой вызов здесь для UpgradeToSessionToken не удается?

# step4.py 
# 
# Trying to read spreadsheets from app engine using text_db and authsub. 
# 
# Merge of this code 
# http://code.google.com/p/gdata-python-client/wiki/AuthSubWithTextDB 
# with this one 
# http://code.google.com/appengine/articles/gdata.html (step 3) 

import wsgiref.handlers 
import cgi 
from google.appengine.ext import webapp 
from google.appengine.api import users 
import atom.url 
import gdata.service 
import gdata.alt.appengine 
import gdata.spreadsheet.text_db 
import settings 


class Fetcher(webapp.RequestHandler): 

    def get(self): 
    # Write our pages title 
    self.response.out.write("""<html><head><title> 
     Google Data Feed Fetcher: read Google Data API Atom feeds</title>""") 
    self.response.out.write('</head><body>') 
    next_url = atom.url.Url('http', settings.HOST_NAME, path='/step4') 
    # Allow the user to sign in or sign out 
    if users.get_current_user(): 
     self.response.out.write('<a href="%s">Sign Out</a><br>' % (
      users.create_logout_url(str(next_url)))) 
    else: 
     self.response.out.write('<a href="%s">Sign In</a><br>' % (
      users.create_login_url(str(next_url)))) 

    # Initialize a client to talk to Google Data API services. 
# client = gdata.service.GDataService() 
# auth_url = client.GenerateAuthSubURL(
#  next_url, 
#  ('http://docs.google.com/feeds/',), secure=False, session=True) 

    client = gdata.spreadsheet.text_db.DatabaseClient() 
    auth_url = client._GetDocsClient().GenerateAuthSubURL(
     next_url, 
     ('http://spreadsheets.google.com/feeds/','http://docs.google.com/feeds/documents/'), secure=False, session=True) 

    gdata.alt.appengine.run_on_appengine(client) 

    feed_url = self.request.get('feed_url') 

    session_token = None 
    # Find the AuthSub token and upgrade it to a session token. 
    auth_token = gdata.auth.extract_auth_sub_token_from_url(self.request.uri) 
    if auth_token: 
     # Upgrade the single-use AuthSub token to a multi-use session token. 
     client._GetDocsClient().SetAuthSubToken(auth_token) 
     session_token = client._GetDocsClient().UpgradeToSessionToken(auth_token) #If I don't pass this argument I get a NonAuthSubToken 
     client._GetSpreadsheetsClient().SetAuthSubToken(client._GetDocsClient().GetAuthSubToken()) 
#  session_token = client.upgrade_to_session_token(auth_token) 
    if session_token and users.get_current_user(): 
     # If there is a current user, store the token in the datastore and 
     # associate it with the current user. Since we told the client to 
     # run_on_appengine, the add_token call will automatically store the 
     # session token if there is a current_user. 
     client.token_store.add_token(session_token) 
    elif session_token: 
     # Since there is no current user, we will put the session token 
     # in a property of the client. We will not store the token in the 
     # datastore, since we wouldn't know which user it belongs to. 
     # Since a new client object is created with each get call, we don't 
     # need to worry about the anonymous token being used by other users. 
     client.current_token = session_token 

    self.response.out.write('<div id="main">') 
    self.fetch_feed(client, feed_url) 
    self.response.out.write('</div>') 
    self.response.out.write(
     '<div id="sidebar"><div id="scopes"><h4>Request a token</h4><ul>') 
    self.response.out.write('<li><a href="%s">Google Documents</a></li>' % (auth_url)) 
    self.response.out.write('</ul></div><br/><div id="tokens">') 

    def fetch_feed(self, client, feed_url): 
    # Attempt to fetch the feed. 
    if not feed_url: 
     self.response.out.write(
      'No feed_url was specified for the app to fetch.<br/>') 
     example_url = atom.url.Url('http', settings.HOST_NAME, path='/step4', 
      params={'feed_url': 
       'http://docs.google.com/feeds/documents/private/full'} 
     ).to_string() 
     self.response.out.write('Here\'s an example query which will show the' 
      ' XML for the feed listing your Google Documents <a ' 
      'href="%s">%s</a>' % (example_url, example_url)) 
     return 
    try: 
     response = client.Get(feed_url, converter=str) 
     self.response.out.write(cgi.escape(response)) 
    except gdata.service.RequestError, request_error: 
     # If fetching fails, then tell the user that they need to login to 
     # authorize this app by logging in at the following URL. 
     if request_error[0]['status'] == 401: 
     # Get the URL of the current page so that our AuthSub request will 
     # send the user back to here. 
     next = atom.url.Url('http', settings.HOST_NAME, path='/step4', 
      params={'feed_url': feed_url}) 
     # If there is a current user, we can request a session token, otherwise 
     # we should ask for a single use token. 
     auth_sub_url = client.GenerateAuthSubURL(next, feed_url, 
      secure=False, session=True) 
     self.response.out.write('<a href="%s">' % (auth_sub_url)) 
     self.response.out.write(
      'Click here to authorize this application to view the feed</a>') 
     else: 
     self.response.out.write(
      'Something went wrong, here is the error object: %s ' % (
       str(request_error[0]))) 


def main(): 
    application = webapp.WSGIApplication([('/.*', Fetcher),], debug=True) 
    wsgiref.handlers.CGIHandler().run(application) 


if __name__ == '__main__': 
    main() 

ответ

1

Как всегда, я выясняю ответ только после отказа и прося о помощи.

нам нужно добавить еще два вызова run_on_appengine (для регистрации двух клиентов, которые клиент text_db имеет):

gdata.alt.appengine.run_on_appengine(client) 
gdata.alt.appengine.run_on_appengine(client._GetDocsClient()) 
gdata.alt.appengine.run_on_appengine(client._GetSpreadsheetsClient()) here 

Я бы ожидал, что первый вызов run_on_appengine, чтобы привести в двух других вызовов, но я думаю, нет.

О, и изменить auth_url линию:

auth_url = client._GetDocsClient().GenerateAuthSubURL(
     next_url,scope='http://spreadsheets.google.com/feeds/ http://docs.google.com/feeds/documents/', secure=False, session=True) 

Passing сферу охвата URLs в списке вызвал «маркер не имеет правильную Scope» ошибку.

Смежные вопросы