func addSource( trailk *context.Context, c appengine.Context, keyTool *key.Tool, fetcher *urlfetch.Fetcher, data *sourceAddData) (*datastore.Key, error) { var s *source.Source switch data.Type { case "Source": s = source.NewSources(trailk, c, keyTool).Make("Source") case "Reference": s = source.NewSources(trailk, c, keyTool).Make("Reference") default: return nil, errors.New("Unknown source type") } if len(data.Name) < config.Source_NameMinLen { return nil, errors.New(fmt.Sprintf( "Source name can't be shorter than %d", config.Source_NameMinLen)) } else if len(data.Name) > config.Source_NameMaxLen { return nil, errors.New(fmt.Sprintf( "Source name can't be longer than %d", config.Source_NameMaxLen)) } if len(data.URL) < config.Source_URLMinLen { return nil, errors.New(fmt.Sprintf( "Source URL can't be shorter than %d", config.Source_URLMinLen)) } else if len(data.URL) > config.Source_URLMaxLen { return nil, errors.New(fmt.Sprintf( "Source URL can't be longer than %d", config.Source_URLMaxLen)) } matched, matchErr := regexp.MatchString( "([a-z0-9]+)://([a-zA-Z0-9.-_/]+)", data.URL) if matchErr != nil { return nil, errors.New(fmt.Sprintf( "Source URL contains invalid format: %v", matchErr)) } if !matched { return nil, errors.New("Source URL contains invalid format") } _, fetchErr := fetcher.Get(data.URL, config.Benchmark_ConnectionTimeoutMax) if fetchErr != nil { return nil, errors.New(fmt.Sprintf( "Sorry, we can't access to the URL. Error: %v", fetchErr)) } s.Name = data.Name s.URL = data.URL s.Updated = trailk.Time().Now() s.Sampled = 0 return s.Insert() }