importers: add SupportsIncremental accessor

If an importer is efficient at running regularly, it returns true.

If it's not true, the UI won't allow turning on automatic runs.

Flickr doesn't set it (yet).
This commit is contained in:
Brad Fitzpatrick 2014-07-31 11:34:23 -07:00
parent b1346fa07a
commit 1ff2918602
8 changed files with 36 additions and 14 deletions

View File

@ -66,6 +66,14 @@ type imp struct {
categoryRef map[string]blob.Ref // URL -> file schema ref
}
func (*imp) SupportsIncremental() bool {
// SupportsIncremental signals to the importer host that this
// importer has been optimized to be run regularly (e.g. every 5
// minutes or half hour). If it returns false, the user must
// manually start imports.
return false
}
func (*imp) NeedsAPIKey() bool {
// This tells the importer framework that we our importer will
// be calling the {RunContext,SetupContext}.Credentials method

View File

@ -58,6 +58,8 @@ type imp struct {
func (im *imp) NeedsAPIKey() bool { return false }
func (im *imp) SupportsIncremental() bool { return true }
func (im *imp) IsAccountReady(acctNode *importer.Object) (ok bool, err error) {
if acctNode.Attr(acctAttrFeedURL) != "" {
return true, nil

View File

@ -59,6 +59,8 @@ type imp struct {
func (imp) NeedsAPIKey() bool { return true }
func (imp) SupportsIncremental() bool { return false }
func (imp) IsAccountReady(acctNode *importer.Object) (ok bool, err error) {
return acctNode.Attr(importer.AcctAttrUserName) != "" && acctNode.Attr(importer.AcctAttrAccessToken) != "", nil
}

View File

@ -84,7 +84,8 @@ type imp struct {
importer.OAuth2 // for CallbackRequestAccount and CallbackURLParameters
}
func (im *imp) NeedsAPIKey() bool { return true }
func (im *imp) NeedsAPIKey() bool { return true }
func (im *imp) SupportsIncremental() bool { return true }
func (im *imp) IsAccountReady(acctNode *importer.Object) (ok bool, err error) {
if acctNode.Attr(acctAttrUserId) != "" && acctNode.Attr(acctAttrAccessToken) != "" {

View File

@ -70,6 +70,13 @@ type Importer interface {
// can return false here.
NeedsAPIKey() bool
// SupportsIncremental reports whether this importer has been optimized
// to run efficiently in regular incremental runs. (e.g. every 5 minutes
// or half hour). Eventually all importers might support this and we'll
// make it required, in which case we might delete this option.
// For now, some importers (e.g. Flickr) don't yet support this.
SupportsIncremental() bool
// IsAccountReady reports whether the provided account node
// is configured.
IsAccountReady(acctNode *Object) (ok bool, err error)
@ -862,6 +869,9 @@ func (ia *importerAcct) delete() error {
func (ia *importerAcct) toggleAuto() error {
old := ia.acct.Attr(attrImportAuto)
if old == "" && !ia.im.impl.SupportsIncremental() {
return fmt.Errorf("Importer %q doesn't support automatic mode.", ia.im.name)
}
var new string
if old == "" {
new = "30m" // TODO: configurable?

View File

@ -30,6 +30,8 @@ type todoImp struct {
func (todoImp) NeedsAPIKey() bool { return false }
func (todoImp) SupportsIncremental() bool { return false }
func (todoImp) Run(*RunContext) error {
return errors.New("fake error from todo importer")
}

View File

@ -61,16 +61,14 @@ const (
attrPicasaId = "picasaId"
)
func init() {
importer.Register("picasa", newImporter())
}
var _ importer.ImporterSetupHTMLer = (*imp)(nil)
var _ importer.ImporterSetupHTMLer = imp{}
type imp struct {
extendedOAuth2
}
func (imp) SupportsIncremental() bool { return true }
var baseOAuthConfig = oauth.Config{
AuthURL: authURL,
TokenURL: tokenURL,
@ -85,8 +83,8 @@ var baseOAuthConfig = oauth.Config{
ApprovalPrompt: "force",
}
func newImporter() *imp {
return &imp{
func init() {
importer.Register("picasa", imp{
newExtendedOAuth2(
baseOAuthConfig,
func(ctx *context.Context) (*userInfo, error) {
@ -105,10 +103,10 @@ func newImporter() *imp {
LastName: lastName,
}, nil
}),
}
})
}
func (*imp) AccountSetupHTML(host *importer.Host) string {
func (imp) AccountSetupHTML(host *importer.Host) string {
// Picasa doesn't allow a path in the origin. Remove it.
origin := host.ImporterBaseURL()
if u, err := url.Parse(origin); err == nil {
@ -135,7 +133,6 @@ and click <b>"Create Project"</b>.</p>
// A run is our state for a given run of the importer.
type run struct {
*importer.RunContext
im *imp
incremental bool // whether we've completed a run in the past
photoGate *syncutil.Gate
@ -152,7 +149,7 @@ func (r *run) errorf(format string, args ...interface{}) {
var forceFullImport, _ = strconv.ParseBool(os.Getenv("CAMLI_PICASA_FULL_IMPORT"))
func (im *imp) Run(ctx *importer.RunContext) error {
func (imp) Run(ctx *importer.RunContext) error {
clientId, secret, err := ctx.Credentials()
if err != nil {
return err
@ -180,7 +177,6 @@ func (im *imp) Run(ctx *importer.RunContext) error {
r := &run{
RunContext: ctx,
im: im,
incremental: !forceFullImport && acctNode.Attr(importer.AcctAttrCompletedVersion) == runCompleteVersion,
photoGate: syncutil.NewGate(3),
}

View File

@ -92,7 +92,8 @@ type imp struct {
importer.OAuth1 // for CallbackRequestAccount and CallbackURLParameters
}
func (im *imp) NeedsAPIKey() bool { return true }
func (im *imp) NeedsAPIKey() bool { return true }
func (im *imp) SupportsIncremental() bool { return true }
func (im *imp) IsAccountReady(acctNode *importer.Object) (ok bool, err error) {
if acctNode.Attr(importer.AcctAttrUserID) != "" && acctNode.Attr(importer.AcctAttrAccessToken) != "" {