def _perform_auth(self, method, context, request, **kw): "Internal method" if not getattr(request, 'gclient', None): request.gclient = {} if not getattr(request, 'gservice', None): request.gservice = {} request.gclient[self.client.__class__.__name__] = self.client request.gservice[self.service.__class__.__name__] = self.service identity = request.environ.get('repoze.who.identity') if not identity: raise Forbidden user = identity.get('user') user_domains = user.email_domains if user_domains: user_domain = user_domains[0] else: user_domain = 'default' next_url = request.url request_token = request.params.get('token') if request_token: authsub_token = AuthSubToken(scopes=self.scopes) authsub_token.set_token_string(request_token) self.service.auth_token = authsub_token self.service.UpgradeToSessionToken(token=authsub_token) user.gdata_auth_token = self.service.auth_token.get_token_string() #cleanup qs qs = dict(parse_qsl(urlparse(next_url).query)) try: del qs['auth_sub_scopes'] del qs['token'] del qs['force'] except KeyError: pass next_url = '%s?%s' % (request.path_url, urlencode(qs)) raise HTTPFound(next_url) authsub_token = AuthSubToken(user.gdata_auth_token, scopes=self.scopes) self.service.SetAuthSubToken(user.gdata_auth_token) try: self.service.AuthSubTokenInfo() except RequestError: user.gdata_auth_token = None raise AuthSubURLRedirect(next_url, self.scopes, domain=user_domain) self.client.auth_token = gAuthSubToken(user.gdata_auth_token, scopes=self.scopes) return method(context, request, **kw)
def return_(request): next = request.GET["next"] gd_client = gdata.contacts.service.ContactsService() token = AuthSubToken() token.set_token_string(request.GET["token"]) gd_client.UpgradeToSessionToken(token) query = gdata.contacts.service.ContactsQuery() query.max_results = getattr(settings, "DGCI_MAX_CONTACTS", 100) feed = gd_client.GetContactsFeed(query.ToUri()) request.session["dgci_contact_feed"] = feed return HttpResponseRedirect(next)
def setup_client(self, spreadsheet): try: from google.appengine.api import apiproxy_stub_map from google.appengine.api import urlfetch_stub apiproxy_stub_map.apiproxy.RegisterStub("urlfetch", urlfetch_stub.URLFetchServiceStub()) except: pass self.spreadsheet = spreadsheet self.client = gdata.spreadsheet.service.SpreadsheetsService() gdata.alt.appengine.run_on_appengine(self.client, store_tokens=False) self.token = AuthSubToken() self.token.set_token_string(self.token_string) self.token.scopes = lookup_scopes(self.client.service) self.client.current_token = self.token self.feed = self.client.GetSpreadsheetsFeed() self.id = GDataConnector.get_spreadsheet_id(self.feed, spreadsheet) self.worksheets = GDataConnector.get_worksheet_dictionary(self.client.GetWorksheetsFeed(self.id))
class GDataConnector(connector_interface.ConnectorInterface): @staticmethod def get_spreadsheet_id(feed, name): for spreadsheet in feed.entry: if spreadsheet.title.text == name: return spreadsheet.id.text.split("/")[-1] return None @staticmethod def get_worksheet_dictionary(feed): output = {} for worksheet in feed.entry: output[worksheet.title.text] = worksheet.id.text.split("/")[-1] return output @staticmethod def get_key_dictionary(feed, key_label="key"): output = {} for row in feed.entry: key = row.custom.get(key_label) if not key: continue output[key.text] = row return output @staticmethod def get_neutral_rows(feed): output = [] for row in feed.entry: dictionary = {} for k, v in row.custom.items(): dictionary[k] = v.text output.append(dictionary) return output def __init__(self, options, name="unknown"): self.kind_name = name self.token_string = options.get("token", AUTHSUB_TOKEN) self.spreadsheet_name = options.get("spreadsheet", SPREADSHEET) self.worksheet_name = options.get("worksheet", name) self.key_label = options.get("key_label", "key") def setup_client(self, spreadsheet): try: from google.appengine.api import apiproxy_stub_map from google.appengine.api import urlfetch_stub apiproxy_stub_map.apiproxy.RegisterStub("urlfetch", urlfetch_stub.URLFetchServiceStub()) except: pass self.spreadsheet = spreadsheet self.client = gdata.spreadsheet.service.SpreadsheetsService() gdata.alt.appengine.run_on_appengine(self.client, store_tokens=False) self.token = AuthSubToken() self.token.set_token_string(self.token_string) self.token.scopes = lookup_scopes(self.client.service) self.client.current_token = self.token self.feed = self.client.GetSpreadsheetsFeed() self.id = GDataConnector.get_spreadsheet_id(self.feed, spreadsheet) self.worksheets = GDataConnector.get_worksheet_dictionary(self.client.GetWorksheetsFeed(self.id)) def generate_import_record(self, filename, bulkload_state): if not hasattr(self, "client"): self.setup_client(self.spreadsheet_name) worksheet = self.worksheets.get(self.worksheet_name) if worksheet is None: raise WorksheetMissing( "There is no worksheet to import for %s" % self.kind_name ) # if the sheet doesn't exist raise an exception # get every row feed = self.client.GetListFeed(self.id, worksheet) rows = self.get_neutral_rows(feed) # yield each row as a dictionary for row in rows: yield row def initialize_export(self, filename, bulkload_state): if self.spreadsheet_name: SPREADSHEET = self.spreadsheet_name if hasattr(self, "client"): return self.setup_client(SPREADSHEET) worksheet = self.worksheets.get(self.worksheet_name) if worksheet != None: feed = self.client.GetListFeed(self.id, worksheet) self.key_dictionary = self.get_key_dictionary(feed, self.key_label) else: self.key_dictionary = {} def write_dict(self, dictionary): # find out which model we are writing # open/create that worksheet # make sure the worksheet has the header row worksheet = self.worksheets.get(self.worksheet_name) if worksheet is None: entry = self.client.AddWorksheet(self.worksheet_name, 2, len(dictionary), self.id) self.worksheets[self.worksheet_name] = worksheet = entry.id.text.split("/")[-1] i = 1 # FIXME: painfully slow. Could be improved with a batch submit for key in dictionary.keys(): entry = self.client.UpdateCell(row=1, col=i, inputValue=key, key=self.id, wksht_id=worksheet) i += 1 row = self.key_dictionary.get(dictionary.get(self.key_label, "")) # we know we've found the exact row if row: # FIXME: could skip the update if the feed.entry is the same as the dictionary for all key/values entry = self.client.UpdateRow(row, dictionary) else: entry = self.client.InsertRow(dictionary, self.id, worksheet) def finalize_export(self): # don't think I need to do anything? pass
def get(self): self.response.headers['Content-Type'] = 'text/html' self.response.out.write('<html><head><title>GV Scheduler</title></head><body><div id="main">') self.cal_client = gdata.calendar.service.CalendarService() # Tell the client that we are running in single user mode, and it should not # automatically try to associate the token with the current user then store # it in the datastore. gdata.alt.appengine.run_on_appengine(self.cal_client, store_tokens=False, single_user_mode=True) # Load processed events to avoid multiple calls for the same event self.processed_events = memcache.get(MEMKEY) if self.processed_events is None: self.processed_events = defaultdict(set) #logging.debug('Loaded memcache: %s' % str(self.processed_events)) # Find an AuthSub token in the current URL if we arrived at this page from an AuthSub redirect session_token = None 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. session_token = self.cal_client.upgrade_to_session_token(auth_token) # Store the token in the datastore if session_token: tkn = Token() tkn.tokenstr = session_token.get_token_string() tkn.put() #logging.debug('Storing session token: %s' % session_token) self.response.out.write('</div></body></html>') self.redirect("/") else: # Token stored in DB? tknn = (db.GqlQuery("SELECT * FROM Token ORDER BY date DESC LIMIT 1")).get() if tknn: session_token = AuthSubToken() session_token.set_token_string(tknn.tokenstr) #logging.debug('Read session token from DB: %s' % session_token) #Is this app authorized to access Google Calendar? feed_url = 'http://www.google.com/calendar/feeds/' if not session_token: # Tell the user that they need to login to authorize this app by logging in at the following URL. next = atom.url.Url('http', HOST_NAME, path='/', params={'feed_url': feed_url}) auth_sub_url = self.cal_client.GenerateAuthSubURL(next, feed_url, secure=False, session=True) self.response.out.write('<a href="%s">Please click here to authorize GVScheduler to access your Google Calendar</a>' % (auth_sub_url)) logging.error('Please visit your app URL (e.g. http://YOUR_GAE_APP_NAME.appspot.com/) to authorize access to your Google Calendar') else: #logging.debug('Found session_token: %s' % session_token) self.cal_client.SetAuthSubToken(session_token) self.response.out.write('GVScheduler is up and running - <font color=green>OK</font>...') feed = self.GetEventsFromCalendar() if feed: if feed.entry: for i, an_event in zip(xrange(len(feed.entry)), feed.entry): # Look in Title and Content of the event... combstring = an_event.title.text if an_event.title.text is not None else '' combstring += ('\n' + an_event.content.text) if an_event.content.text is not None else '' kd = self.ParseString(combstring) # Test if call needs to be placed. Entry must have "GVCall=number" in Title or in Content if ("gvcall" in kd): pn = self.FormatPhoneNumber(kd['gvcall']) starttime = an_event.when[0].start_time # Check if the call for this event was already placed if (not self.processed_events[starttime]) or (pn not in self.processed_events[starttime]): if ("gvringnumber" in kd): rn = self.FormatPhoneNumber(kd['gvringnumber']) else: rn = config.forwardingNumber if ("gvringtype" in kd): rt = kd['gvringtype'] else: rt = config.phoneType logging.info('Event: %s, Calling: %s, Ringing: %s (Type: %s)' % (an_event.title.text, pn, rn, rt)) self.GVPlaceCall(pn, rn, rt) self.processed_events[starttime].add(pn) #logging.debug('Adding to memcache: [%s] = (%s)' % (starttime, pn)) #else: # logging.debug('Skipping processed event: [%s] = (%s)' % (starttime, pn)) memcache.set(MEMKEY, self.processed_events) else: # No events fetched, clear the cache memcache.flush_all() #logging.debug('Deleting memcache...') self.response.out.write('</div></body></html>')