func (im *imp) LongPoll(rctx *importer.RunContext) error { clientId, secret, err := rctx.Credentials() if err != nil { return err } acctNode := rctx.AccountNode() accessToken := acctNode.Attr(importer.AcctAttrAccessToken) accessSecret := acctNode.Attr(importer.AcctAttrAccessTokenSecret) if accessToken == "" || accessSecret == "" { return errors.New("access credentials not found") } oauthClient := &oauth.Client{ TemporaryCredentialRequestURI: temporaryCredentialRequestURL, ResourceOwnerAuthorizationURI: resourceOwnerAuthorizationURL, TokenRequestURI: tokenRequestURL, Credentials: oauth.Credentials{ Token: clientId, Secret: secret, }, } accessCreds := &oauth.Credentials{ Token: accessToken, Secret: accessSecret, } form := url.Values{"with": {"user"}} req, _ := http.NewRequest("GET", "https://userstream.twitter.com/1.1/user.json", nil) req.Header.Set("Authorization", oauthClient.AuthorizationHeader(accessCreds, "GET", req.URL, form)) req.URL.RawQuery = form.Encode() req.Cancel = rctx.Context().Done() log.Printf("Beginning twitter long poll...") res, err := http.DefaultClient.Do(req) if err != nil { return err } defer res.Body.Close() if res.StatusCode != 200 { return errors.New(res.Status) } bs := bufio.NewScanner(res.Body) for bs.Scan() { line := strings.TrimSpace(bs.Text()) if line == "" || strings.HasPrefix(line, `{"friends`) { continue } log.Printf("Twitter long poll saw a tweet: %s", line) return nil } if err := bs.Err(); err != nil { return err } return errors.New("got EOF without a tweet.") }
func (imp) Run(rctx *importer.RunContext) error { clientID, secret, err := rctx.Credentials() if err != nil { return err } acctNode := rctx.AccountNode() ocfg := &oauth2.Config{ Endpoint: google.Endpoint, ClientID: clientID, ClientSecret: secret, Scopes: []string{scopeURL}, } token := decodeToken(acctNode.Attr(acctAttrOAuthToken)) baseCtx := rctx.Context() ctx := context.WithValue(baseCtx, ctxutil.HTTPClient, ocfg.Client(baseCtx, token)) root := rctx.RootNode() if root.Attr(nodeattr.Title) == "" { if err := root.SetAttr( nodeattr.Title, fmt.Sprintf("%s - Google Photos", acctNode.Attr(importer.AcctAttrName)), ); err != nil { return err } } r := &run{ RunContext: rctx, incremental: !forceFullImport && acctNode.Attr(importer.AcctAttrCompletedVersion) == runCompleteVersion, photoGate: syncutil.NewGate(3), } if err := r.importAlbums(ctx); err != nil { return err } if err := acctNode.SetAttrs(importer.AcctAttrCompletedVersion, runCompleteVersion); err != nil { return err } return nil }
func (imp) Run(ctx *importer.RunContext) error { clientId, secret, err := ctx.Credentials() if err != nil { return err } acctNode := ctx.AccountNode() ocfg := baseOAuthConfig ocfg.ClientId, ocfg.ClientSecret = clientId, secret token := decodeToken(acctNode.Attr(acctAttrOAuthToken)) transport := &oauth.Transport{ Config: &ocfg, Token: &token, Transport: notOAuthTransport(ctx.HTTPClient()), } ctx.Context = ctx.Context.New(context.WithHTTPClient(transport.Client())) root := ctx.RootNode() if root.Attr(nodeattr.Title) == "" { if err := root.SetAttr(nodeattr.Title, fmt.Sprintf("%s %s - Google/Picasa Photos", acctNode.Attr(importer.AcctAttrGivenName), acctNode.Attr(importer.AcctAttrFamilyName))); err != nil { return err } } r := &run{ RunContext: ctx, incremental: !forceFullImport && acctNode.Attr(importer.AcctAttrCompletedVersion) == runCompleteVersion, photoGate: syncutil.NewGate(3), } if err := r.importAlbums(); err != nil { return err } r.mu.Lock() anyErr := r.anyErr r.mu.Unlock() if !anyErr { if err := acctNode.SetAttrs(importer.AcctAttrCompletedVersion, runCompleteVersion); err != nil { return err } } return nil }