예제 #1
0
파일: game.go 프로젝트: f4rez/Cronos
func GetGames(c appengine.Context, ids []int) ([]Game, []*datastore.Key, error) {
	c.Infof("ids: %v", ids)
	games := make([]Game, len(ids), len(ids))
	keys := make([]*datastore.Key, len(ids), len(ids))
	for i, value := range ids {
		key, err2 := getKeyForIndex(c, value)
		keys[i] = key
		if err2 != nil {
			c.Infof("Error gettingGameKey: %v", err2)
			return games, keys, err2
		}
	}
	err := datastore.GetMulti(c, keys, games)
	if err != nil {
		c.Infof("Error getting games: %v, keys: %v", err, keys)
		return games, keys, err
	}

	for i, g := range games {
		temp := make([]Round, 5, 5)
		temp2 := g.RoundsJson
		err2 := json.Unmarshal(temp2, &temp)
		if err2 != nil {
			c.Infof("Error converting Json %v", err2)
			return games, nil, err2
		}
		g.Rounds = temp
		games[i] = g
	}
	return games, keys, nil

}
예제 #2
0
// Retrieves all the in-progress stories for the given author.
func inProgressStories(c appengine.Context, author string) []InProgressStory {

	q := datastore.NewQuery("StoryAuthor").
		Filter("Author =", author).
		KeysOnly()

	keys, err := q.GetAll(c, nil)
	if err != nil {
		panic(&appError{err, "Failed to fetch in-progress story authors", 500})
	}

	storyKeys := make([]*datastore.Key, len(keys))

	for i, key := range keys {
		storyKeys[i] = key.Parent()
	}
	stories := make([]Story, len(keys))
	if err := datastore.GetMulti(c, storyKeys, stories); err != nil {
		panic(&appError{err, "Failed to fetch in-progress stories", 500})
	}
	sort.Sort(byTime(stories))

	inProgress := make([]InProgressStory, len(keys))
	for i, story := range stories {
		inProgress[i] = story.InProgress(author)
		inProgress[i].RewriteAuthors(nameFunc(c))
	}

	return inProgress
}
예제 #3
0
파일: main.go 프로젝트: samthor/withsrv
// listState retrieves the state of every list owned by this user, in the form
// of a map between list ID and its current state.
func listState(c appengine.Context, user *model.User) (out map[string]*string, err error) {
	out = make(map[string]*string)

	// Load current state from memcache, if possible.
	// TODO: ... do this.

	// Try to load the remaining keys from datastore.
	db := make([]model.List, len(user.Sub))
	keys := make([]*datastore.Key, len(user.Sub))
	for i, sub := range user.Sub {
		keys[i] = datastore.NewKey(c, "List", sub, 0, nil)
	}
	err = datastore.GetMulti(c, keys, db)
	if err != nil {
		return
	}
	for i := 0; i < len(db); i++ {
		// TODO: return output even if we see errors.
		state := db[i].State()
		out[db[i].Id] = &state
	}

	// Success!
	return
}
예제 #4
0
func userHandler(w http.ResponseWriter, r *http.Request) {
	ctx := appengine.NewContext(r)
	uu := user.Current(ctx)
	if verifyLogin(ctx, uu, w, r) {
		return
	}
	u := GetUser(ctx, uu.ID)
	if u == nil {
		ctx.Infof("unknown user, going to /start")
		http.Redirect(w, r, "/start", http.StatusSeeOther)
		return
	}

	repos, _, err := newClient(ctx, u.GitHubToken).Repositories.List("", &github.RepositoryListOptions{
		Type: "all",
	})
	if err != nil {
		ctx.Errorf("listing repos: %v", err)
		renderError(w, "Error listing repos")
		return
	}

	type data struct {
		Repo     github.Repository
		Disabled bool
		Branch   string
	}
	d := []data{}

	keys := []*datastore.Key{}
	for _, r := range repos {
		keys = append(keys, datastore.NewKey(ctx, "Repo", *r.FullName, 0, nil))
	}
	repoEntities := make([]Repo, len(keys))
	if err := datastore.GetMulti(ctx, keys, repoEntities); err != nil {
		if me, ok := err.(appengine.MultiError); ok {
			for i, e := range me {
				var disabled = e == nil
				var branch = ""
				if e == nil {
					branch = repoEntities[i].Branch
				}
				d = append(d, data{Repo: repos[i], Disabled: disabled, Branch: branch})
			}
		} else {
			ctx.Errorf("getmulti: %v", err)
			renderError(w, "Error retrieving repos")
			return
		}
	} else {
		// all repos are disabled
		for _, r := range repos {
			d = append(d, data{Repo: r, Disabled: true})
		}
	}

	if err := userTmpl.Execute(w, d); err != nil {
		ctx.Errorf("executing template: %v", err)
	}
}
예제 #5
0
func recentCommentsHandler(p *PageRequest) (err error) {
	q := datastore.NewQuery("Comment").Order("-Created").Limit(100)
	var comments []Comment
	commentKeys, err := q.GetAll(p.c, &comments)
	// get the radars for each comment
	radarKeys := make([]*datastore.Key, len(comments), len(comments))
	for i, comment := range comments {
		radarKeys[i] = datastore.NewKey(p.c, "Radar", "", comment.RadarNumber, nil)
	}
	radars := make([]Radar, len(comments), len(comments))
	err = datastore.GetMulti(p.c, radarKeys, radars)
	if err != nil {
		return err
	}
	for i, _ := range comments {
		comments[i].Radar = &radars[i]
		comments[i].Key = commentKeys[i]
		comments[i].Number = comments[i].Key.IntID()
	}
	if err == nil {
		p.Set("Comments", comments)
		p.Set("Title", "Recent Comments")
		err = p.Template("templates/comments.html")
		err = p.Template("templates/comment.html")
	}
	return
}
예제 #6
0
func queueGet(w http.ResponseWriter, r *http.Request) {
	c := appengine.NewContext(r)

	userId := r.FormValue("UserId")
	q := datastore.NewQuery("queueplayer").Filter("UserId =", userId).Order("-Timestamp").KeysOnly()
	keys, err := q.GetAll(c, nil)
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}

	gameKeys := make([]*datastore.Key, len(keys))
	for i, k := range keys {
		gameKeys[i] = k.Parent()
	}

	games := make([]Game, len(keys))
	err = datastore.GetMulti(c, gameKeys, games)
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}

	for i, k := range keys {
		games[i].Id = k.Parent().Encode()
	}

	data, err := json.Marshal(games)
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}
	w.Write(data)
}
예제 #7
0
// GetMulti is a batch version of Get. Cached values are returned from memcache, uncached values are returned from
// datastore and memcached for next time.
//
// dst must be a []S, []*S, []I or []P, for some struct type S, some interface type I, or some non-interface
// non-pointer type P such that P or *P implements PropertyLoadSaver. If an []I, each element must be a valid
// dst for Get: it must be a struct pointer or implement PropertyLoadSaver.
//
// As a special case, PropertyList is an invalid type for dst, even though a PropertyList is a slice of structs.
// It is treated as invalid to avoid being mistakenly passed when []PropertyList was intended.
func GetMulti(c appengine.Context, key []*datastore.Key, dst interface{}) error {
	if len(key) == 0 {
		return nil
	}
	// check cache
	encodedKeys := encodeKeys(key)
	itemMap, errm := memcache.GetMulti(c, encodedKeys)
	if len(itemMap) != len(key) {
		// TODO benchmark loading all vs loading missing
		// load from datastore
		errd := datastore.GetMulti(c, key, dst)
		if Debug {
			c.Debugf("reading from datastore: %#v", dst)
		}
		if errd != nil {
			return errd
		}
		// cache for next time
		errm = cache(key, dst, c)
	} else {
		errm = decodeItems(key, itemMap, dst)
		if Debug {
			c.Debugf("reading from memcache: %#v", dst)
		}
	}
	return errm
}
예제 #8
0
파일: gae.go 프로젝트: DaviWei/utils-1
func GetMulti(c PersistenceContext, ids []key.Key, src interface{}) (err error) {
	dsIds := make([]*datastore.Key, len(ids))
	for index, id := range ids {
		dsIds[index] = gaekey.ToGAE(c, id)
	}
	getErr := datastore.GetMulti(c, dsIds, src)
	merr, isMerr := getErr.(appengine.MultiError)
	if !isMerr && getErr != nil {
		err = getErr
		return
	}
	srcVal := reflect.ValueOf(src)
	for index, id := range ids {
		if !isMerr || merr[index] == nil {
			el := srcVal.Index(index)
			for el.Kind() == reflect.Ptr {
				el = el.Elem()
			}
			el.FieldByName("Id").Set(reflect.ValueOf(id))
			if err = runProcess(c, el.Addr().Interface(), AfterLoadName, nil); err != nil {
				return
			}
		}
	}
	if isMerr && merr != nil {
		err = merr
	}
	return
}
예제 #9
0
func (d *DatastoreStorage) GetArchivedPosts(req *http.Request, datespec string) []blogplus.Activity {
	c := appengine.NewContext(req)
	datespecKey := datastore.NewKey(c, datespecKind, datespec, 0, nil)
	q := datastore.NewQuery(activityRef).Ancestor(datespecKey)
	t := q.Run(c)
	var keys []*datastore.Key
	for {
		var de DatespecEntity
		_, err := t.Next(&de)
		if err == datastore.Done {
			break
		}
		if err != nil {
			c.Errorf("query error:%#v", err)
			break
		}
		keys = append(keys, de.Id)
	}
	aelist := make([]ActivityEntity, len(keys))
	err := datastore.GetMulti(c, keys, aelist)
	if err != nil {
		c.Errorf("get multi error:%#v", err)
		return nil
	}
	var posts []blogplus.Activity
	for _, ae := range aelist {
		post, err := blogplus.DecodeActivity(ae.Post)
		if err != nil {
			c.Errorf("decode error:%#v", err)
			continue
		}
		posts = append(posts, post)
	}
	return posts
}
예제 #10
0
func (a *AppUser) GetBoards(c appengine.Context) (Boards []Board, err error) {
	Boards = make([]Board, len(a.BoardIDs))

	err = datastore.GetMulti(c, getIntKeys(c, "Board", a.BoardIDs...), Boards)

	return
}
예제 #11
0
파일: datastore.go 프로젝트: speedland/wcg
func (d *Driver) GetMulti(key []*datastore.Key, dst interface{}) error {
	var keyLen = len(key)
	var fromIdx, toIdx int
	var v = reflect.ValueOf(dst)
	// TODO: split multiple goroutine
	for {
		fromIdx = toIdx
		toIdx = fromIdx + 999
		if toIdx > keyLen {
			toIdx = keyLen
		}
		_keys := key[fromIdx:toIdx]
		_data := v.Slice(fromIdx, toIdx).Interface()
		d.logOps(opRead, len(_keys), "GetMulti")
		if err := datastore.GetMulti(d.ctx, _keys, _data); err != nil {
			return err
		}
		v1 := reflect.ValueOf(_data)
		for i := 0; i < toIdx-fromIdx; i += 1 {
			v.Index(fromIdx + i).Set(v1.Index(i))
		}
		if toIdx == keyLen {
			break
		}
	}
	return nil
}
예제 #12
0
파일: polly.go 프로젝트: broady/Polly
func fetchOptions(c appengine.Context, poll *Poll) ([]*Option, os.Error) {
	dst := make([]interface{}, poll.Options)
	options := make([]*Option, poll.Options)
	keys := make([]*datastore.Key, poll.Options)

	pollKey := datastore.NewKey(c, "poll", "", poll.Id, nil)
	for i := range keys {
		keys[i] = datastore.NewKey(c, "option", "", int64(i+1), pollKey)
		dst[i] = new(Option)
	}
	err := datastore.GetMulti(c, keys, dst)
	if err != nil {
		return nil, err
	}
	for i := range dst {
		opt, ok := dst[i].(*Option)
		if ok {
			options[i] = opt
			opt.Poll = pollKey
			opt.Id = keys[i].IntID()
		}
	}

	return options, err
}
예제 #13
0
func updateProfileEntities(
	context appengine.Context,
	profiles map[string]*Profile,
	generation string,
	kind string,
	count int) {
	// collect keys and new profile values into arrays
	keys := make([]*datastore.Key, 0)
	newvalues := make([]*Profile, 0)
	for username, profile := range profiles {
		key := datastore.NewKey(context, "Profile", username, 0, nil)
		keys = append(keys, key)
		newvalues = append(newvalues, profile)
	}
	// get all of the old profile values
	oldvalues := make([]*Profile, len(keys))
	err := datastore.GetMulti(context, keys, oldvalues)
	// if the old values are from the current generation, add their counts into the new values
	for i := 0; i < len(keys); i++ {
		if (oldvalues[i] != nil) && (oldvalues[i].Generation == generation) {
			newvalues[i].RadarCount += oldvalues[i].RadarCount
			newvalues[i].CommentCount += oldvalues[i].CommentCount
		}
	}
	// store all of the new values
	_, err = datastore.PutMulti(context, keys, newvalues)
	if err == nil {
		context.Infof("Updated %d profiles for %d %s", len(profiles), count, kind)
	} else {
		context.Infof("Error updating %d profiles for %d %s (%v)", len(profiles), count, kind, err)
	}
}
예제 #14
0
파일: user.go 프로젝트: samolds/principia
// Returns simulations favorited by and comments from the user id passed in the url
func InteractionsHandler(w http.ResponseWriter, r *http.Request) {
	vars := mux.Vars(r)
	userKeyName := vars["userID"]
	ctx := appengine.NewContext(r)
	var simulations []models.SimulationData
	var comments []models.CommentData

	// Check to see if the page user is the same as the logged in user
	userIsOwner := utils.IsOwner(userKeyName, ctx)

	// Only get favorited and commented information if it's the proper user
	// Don't display interaction data to any user except for the user who owns it
	if userIsOwner {
		// Get 50 of the most recent ratings made by the logged in user
		var ratingKeys []*datastore.Key
		var ratingObjs []models.Rating
		q := datastore.NewQuery("Rating").KeysOnly().Filter("AuthorKeyName =", userKeyName).Order("-CreationDate").Limit(50)
		ratingKeys, err := q.GetAll(ctx, ratingObjs)

		// Get the parent keys of the ratings made (these are the keys of the simulations the ratings were for)
		var simulationRateKeys []*datastore.Key
		for _, key := range ratingKeys {
			simulationRateKeys = append(simulationRateKeys, key.Parent())
		}

		// Get all of the simulation objects from the simulation keys
		simulationRateObjs := make([]models.Simulation, len(simulationRateKeys))
		err = datastore.GetMulti(ctx, simulationRateKeys, simulationRateObjs)
		if err != nil {
			controllers.ErrorHandler(w, r, err.Error(), http.StatusInternalServerError)
			return
		}

		// Build the proper simulation data objects from the simulation models
		simulations, err = utils.BuildSimulationDataSlice(ctx, simulationRateObjs, simulationRateKeys)
		if err != nil {
			controllers.ErrorHandler(w, r, "Could not load user simulations: "+err.Error(), http.StatusInternalServerError)
			return
		}

		// Get 50 of the most recent comments made by the logged in user
		q = datastore.NewQuery("Comment").Filter("AuthorKeyName =", userKeyName).Order("-CreationDate").Limit(50)
		comments, err = utils.GetCommentDataSlice(r, q)
		if err != nil {
			controllers.ErrorHandler(w, r, "Error fetching comments: "+err.Error(), http.StatusInternalServerError)
			return
		}
	}

	data := map[string]interface{}{
		"simulations":  simulations,
		"comments":     comments,
		"userIsOwner":  false,
		"userOwnsPage": userIsOwner,
	}

	controllers.BaseHandler(w, r, "user/interactions", data)
}
예제 #15
0
func (builder *stepsBuilder) LoadBatchFromDatastore(context appengine.Context) stream.EachFn {
	return func(data stream.T) {
		batch := data.(*DatastoreBatch)
		if err := datastore.GetMulti(context, batch.Keys, batch.Items); err != nil {
			if _, missingField := err.(*datastore.ErrFieldMismatch); !missingField {
				panic(err)
			}
		}
	}
}
예제 #16
0
파일: scribe.go 프로젝트: elegios/Scribe
func projectTop(e env, projectId string) bool {
	e.w.Header().Set("Content-type", "text/html; charset=utf-8")
	userKey, done := getUser(e)
	if done {
		return true
	}

	snapshot, snapshotKey, done := getLastSnapshot(e, userKey, projectId)
	if done {
		return true
	}

	nodes := make([]Node, len(snapshot.Nodes))
	nodeKeys := make([]*datastore.Key, 0, len(snapshot.Nodes))
	for _, k := range snapshot.Nodes {
		nodeKeys = append(nodeKeys, datastore.NewKey(e.ctx, "node", "", k, snapshotKey))
	}
	if err := datastore.GetMulti(e.ctx, nodeKeys, nodes); err != nil {
		e.w.WriteHeader(http.StatusInternalServerError)
		fmt.Fprintf(e.w, `Could not load all nodes in the snapshot`)
		log.Println("Error loading nodes in snapshot", err)
		return true
	}

	treeToSend := make(map[string]interface{})
	for i, node := range nodes {
		id := strconv.FormatInt(nodeKeys[i].IntID(), 10)
		val := map[string]interface{}{
			"name": node.Name,
		}
		if node.Folder {
			val["collapsed"] = node.Collapsed
			if node.Children != nil {
				val["children"] = node.Children
			} else {
				val["children"] = make([]int64, 0, 0)
			}
		}
		treeToSend[id] = val
	}
	treeToSend["root"] = snapshot.Top

	fmt.Fprintf(e.w, `<html><head><link rel="stylesheet" type="text/css" href="static/site.css" /></head><body>`)
	fmt.Fprintf(e.w, `<script type="text/javascript">var StartingContent=null;function countWords(t){var c=0;t.replace(/\S+/g,function(){c++});return c};var StartingTree=`)
	if err := json.NewEncoder(e.w).Encode(treeToSend); err != nil {
		e.w.WriteHeader(http.StatusInternalServerError)
		fmt.Fprintf(e.w, "Could not generate json from the tree")
		log.Println("Error generating json from tree", err)
		return true
	}
	fmt.Fprintf(e.w, `</script><div id="app"></div><script type="text/javascript" src="static/client.js"></script>`)
	fmt.Fprintf(e.w, `<script type="text/javascript">window.onload=function(){scribe.core.run()}</script>`)
	fmt.Fprintf(e.w, `</body></html>`)
	return true
}
예제 #17
0
func (dai Person_dai) GetMulti(c appengine.Context, keys []*datastore.Key) ([]*Person, error) {
	// batch get.
	var entities = make([]*Person, len(keys))

	//TODO: if have not such entity for any-one key?
	err := datastore.GetMulti(c, keys, entities)
	if err != nil {
		return nil, err
	}
	return entities, nil
}
예제 #18
0
func (ctx *Context) GetVendorMulti(keys []*datastore.Key) ([]*Vendor, error) {
	vendors := make([]*Vendor, len(keys))

	for idx, _ := range vendors {
		vendors[idx] = new(Vendor)
	}

	err := datastore.GetMulti(ctx.c, keys, vendors)

	return vendors, err
}
예제 #19
0
파일: load.go 프로젝트: nelsam/atomicgames
// Load multiple datastore values into a slice of models
func GetModels(ctx appengine.Context, keys []*datastore.Key, modelSlice []models.Model) error {
	err := datastore.GetMulti(ctx, keys, modelSlice)
	var (
		index int
		model models.Model
	)
	for index, model = range modelSlice {
		model.SetKey(keys[index])
	}
	return err
}
예제 #20
0
func (ctx *Context) GetCompanyMulti(keys []*datastore.Key) ([]*Company, error) {
	companies := make([]*Company, len(keys))

	for idx, _ := range companies {
		companies[idx] = new(Company)
	}

	err := datastore.GetMulti(ctx.c, keys, companies)

	return companies, err

}
예제 #21
0
파일: nuts.go 프로젝트: AlekSi/gonuts.io
func nutsHandler(c appengine.Context, w http.ResponseWriter, r *http.Request) {
	d := make(ContentData)
	apiCall := r.Header.Get("Accept") == "application/json"

	// TODO: no need to load all, then render all - replace with chunking
	var nuts []gonuts.Nut
	var err error
	var title string
	vendor := r.URL.Query().Get(":vendor")
	q := r.URL.Query().Get("q")
	if vendor != "" {
		title = fmt.Sprintf("%s's Nuts", vendor)
		_, err = datastore.NewQuery("Nut").Filter("Vendor=", vendor).Order("Name").GetAll(c, &nuts)
	} else if q == "" {
		title = "All Nuts"
		_, err = datastore.NewQuery("Nut").Order("Vendor").Order("Name").GetAll(c, &nuts)
	} else {
		title = fmt.Sprintf("Search %q", q)
		res, err := gonuts.SearchIndex(c, q)
		gonuts.LogError(c, err)
		keys := make([]*datastore.Key, len(res))
		for i, pair := range res {
			keys[i] = gonuts.NutKey(c, pair[0], pair[1])
		}
		nuts = make([]gonuts.Nut, len(keys))
		err = datastore.GetMulti(c, keys, nuts)
	}
	gonuts.LogError(c, err)
	d["Nuts"] = nuts
	status := http.StatusOK
	if len(nuts) == 0 {
		status = http.StatusNotFound
	}

	if apiCall {
		d["Message"] = title
		ServeJSON(w, status, d)
		return
	}

	var content bytes.Buffer
	gonuts.PanicIfErr(Base.ExecuteTemplate(&content, "nuts.html", d))

	bd := BaseData{
		Tabtitle: title,
		Title:    title,
		Content:  template.HTML(content.String()),
	}

	w.WriteHeader(status)
	gonuts.PanicIfErr(Base.Execute(w, &bd))
}
예제 #22
0
func GetBoard(c appengine.Context, i int64) (board *Board, err error) {
	k := datastore.NewKey(c, "Board", "", i, nil)
	board = new(Board)

	if err := datastore.Get(c, k, board); err != nil {
		return nil, err
	}

	board.Scales = make([]Scale, len(board.ScaleIDs))
	err = datastore.GetMulti(c, getIntKeys(c, "Scale", board.ScaleIDs...), board.Scales)

	return board, err
}
예제 #23
0
func (db *DocDB) GetMulti(ids []string, docs interface{}) ErrorSlice {
	if len(ids) == 0 {
		return nil
	}

	keys := make([]*datastore.Key, len(ids))
	for i, id := range ids {
		keys[i] = datastore.NewKey(db.c, db.kind, id, 0, nil)
	}

	err := datastore.GetMulti(db.c, keys, docs)
	return ErrorSliceFromError(err, len(ids))
}
예제 #24
0
파일: feedme.go 프로젝트: eaburns/feedme
func handleManage(w http.ResponseWriter, r *http.Request) {
	if r.Method != "GET" {
		http.NotFound(w, r)
		return
	}

	c := appengine.NewContext(r)

	var page struct {
		Title  string
		User   UserInfo
		Logout string
		Feeds  feedList
	}
	page.Title = "Feeds"

	var err error
	page.User, err = getUser(c)
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}

	infos := make([]FeedInfo, len(page.User.Feeds))
	err = fixMissingFieldError(datastore.GetMulti(c, page.User.Feeds, infos))
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}

	for i := range infos {
		page.Feeds = append(page.Feeds, feedListEntry{
			Title:      infos[i].Title,
			Url:        infos[i].Url,
			LastFetch:  infos[i].LastFetch,
			EncodedKey: page.User.Feeds[i].Encode(),
		})
	}

	sort.Sort(page.Feeds)

	page.Logout, err = user.LogoutURL(c, "/")
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}

	if err := templates.ExecuteTemplate(w, "manage.html", page); err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
	}
}
예제 #25
0
func (s Season) GetPlayers(c appengine.Context) []*Player {
	var players []*Player = make([]*Player, len(s.Players), len(s.Players))
	//Have to do this because appengine is f*****g stupid and requires the entity to exist
	//prior to loading.
	for index := 0; index < len(players); index++ {
		players[index] = new(Player)
	}
	err := datastore.GetMulti(c, s.Players, players)
	if err != nil {
		c.Errorf(err.Error())
		c.Errorf("Error loading players: '%v'", err)
		panic(err)
	}
	return players
}
예제 #26
0
func updateCountsHandler(w http.ResponseWriter, r *http.Request) {
	c := aeContext(r)
	client := urlfetch.Client(c)
	twitterChans := make([]chan int, len(shareUrls))
	plusOnesChans := make([]chan int, len(shareUrls))
	plusCommentsChans := make([]chan int, len(shareUrls))
	for i, shareUrl := range shareUrls {
		twitterChans[i] = fetchTwitterCountAsync(client, shareUrl)
		plusOnesChans[i] = fetchPlusOnesAsync(client, shareUrl)
		plusCommentsChans[i] = fetchPlusCommentsAsync(client, shareUrl)
	}
	fbCounts := <-fetchFacebookCountsAsync(client, shareUrls)
	shareKeys := make([]*datastore.Key, len(shareUrls))
	for i, shareUrl := range shareUrls {
		shareKeys[i] = datastore.NewKey(c, "Share", shareUrl, 0, nil)
	}
	shares := make([]Share, len(shareUrls))
	if err := datastore.GetMulti(c, shareKeys, shares); err != nil {
		log.Printf("GetMulti failed: %v", err.Error())
	}
	for i, shareUrl := range shareUrls {
		shares[i].Url = shareUrl
		shares[i].PlusOnes = max(shares[i].PlusOnes, <-plusOnesChans[i])
		shares[i].PlusComments = max(shares[i].PlusComments, <-plusCommentsChans[i])
		shares[i].TwitterCount = max(shares[i].TwitterCount, <-twitterChans[i])
		shares[i].FacebookCount = max(shares[i].FacebookCount, fbCounts[i])
	}
	var page Page
	page.Path = "/page/counts.json"
	page.ContentType = "application/json"
	page.Payload, _ = json.Marshal(shares)
	err := func() error {
		if _, err := datastore.PutMulti(c, shareKeys, shares); err != nil {
			return err
		}
		pageKey := datastore.NewKey(c, "Page", page.Path, 0, nil)
		if _, err := datastore.Put(c, pageKey, &page); err != nil {
			return err
		}
		return nil
	}()
	if err != nil {
		log.Println(err.Error())
		http.Error(w, "FAIL", http.StatusInternalServerError)
		return
	}
	fmt.Fprintln(w, "OK")
}
예제 #27
0
파일: question.go 프로젝트: f4rez/Cronos
func GetQuestions(c appengine.Context) ([]Question, []*datastore.Key, error) {
	question := make([]Question, NUMBER_OF_QUESTIONS)
	keys := make([]*datastore.Key, NUMBER_OF_QUESTIONS)
	max, _ := GetCountQuestions(c)
	max--
	values := getRandomValues(c, NUMBER_OF_QUESTIONS, max)
	for i, value := range values {
		keys[i], _ = getKeyForIndex(c, value)
	}
	err := datastore.GetMulti(c, keys, question)
	if err != nil {
		c.Infof("Error in GetQuestions: %v", err)
		return question, keys, err
	}
	return question, keys, nil
}
예제 #28
0
func (db *Db) GetStories(ids []int, includeComments bool) ([]*Story, error) {
	keys := make([]*datastore.Key, 0, len(ids))

	for _, id := range ids {
		keys = append(keys, db.keyForStory(id))
	}

	stories := make([]*Story, len(ids))
	err := datastore.GetMulti(db.context, keys, stories)
	if err_entries, ok := err.(appengine.MultiError); ok {
		removed := 0
		for i, err_entry := range err_entries {
			if err_entry != nil {
				stories = append(stories[:i-removed], stories[i+1-removed:]...)
				removed++
			}
		}
	}

	if len(stories) == 0 {
		return nil, err
	} else {
		if includeComments {
			for _, story := range stories {
				for _, commentId := range story.Kids {
					comment, cErr := db.GetComment(commentId)
					if cErr == nil {
						story.Comments = append(story.Comments, comment)
					}
				}
			}
		}

		idToIndexMap := make(map[int]int)
		for index, value := range ids {
			idToIndexMap[value] = index
		}

		fn := func(t1, t2 *Story) bool {
			return idToIndexMap[t1.ID] < idToIndexMap[t2.ID]
		}

		SortBy(fn).Sort(stories)

		return stories, nil
	}
}
예제 #29
0
파일: question.go 프로젝트: f4rez/Cronos
func GetQuestionsWithID(c appengine.Context, ids []int) ([]Question, error) {
	question := make([]Question, NUMBER_OF_QUESTIONS)
	keys := make([]*datastore.Key, NUMBER_OF_QUESTIONS)
	for i, value := range ids {
		key, err2 := getKeyForIndex(c, value)
		if err2 != nil {
			return question, err2
		} else {
			keys[i] = key
		}
	}
	err := datastore.GetMulti(c, keys, question)
	if err != nil {
		return question, err
	}
	return question, nil

}
예제 #30
0
파일: storage.go 프로젝트: orian/camlistore
func (sto *appengineStorage) StatBlobs(dest chan<- blobref.SizedBlobRef, blobs []*blobref.BlobRef, wait time.Duration) error {
	ctx := sto.ctx
	if ctx == nil {
		loan := ctxPool.Get()
		defer loan.Return()
		ctx = loan
	}

	var (
		keys = make([]*datastore.Key, 0, len(blobs))
		out  = make([]interface{}, 0, len(blobs))
		errs = make([]error, len(blobs))
	)
	for _, br := range blobs {
		keys = append(keys, sto.memKey(ctx, br))
		out = append(out, new(memEnt))
	}
	err := datastore.GetMulti(ctx, keys, out)
	if merr, ok := err.(appengine.MultiError); ok {
		errs = []error(merr)
		err = nil
	}
	if err != nil {
		return err
	}
	for i, br := range blobs {
		thisErr := errs[i]
		if thisErr == datastore.ErrNoSuchEntity {
			continue
		}
		if thisErr != nil {
			err = errs[i] // just return last one found?
			continue
		}
		ent := out[i].(*memEnt)
		size, err := ent.size()
		if err == nil {
			dest <- blobref.SizedBlobRef{br, size}
		} else {
			ctx.Warningf("skipping corrupt blob %s: %v", br, err)
		}
	}
	return err
}