Example #1
0
File: log.go Project: icub3d/gorca
// Log is a helper function that logs the given message to appenging
// with the given priority. Accepted priorities are "debug", "info",
// "warn", "error", and "crit". Other values default to "error".
func Log(c appengine.Context, r *http.Request, priority string,
	message string, params ...interface{}) {

	message = fmt.Sprintf("[%s] [%s] [%s]: %s", r.RemoteAddr, r.Method,
		r.URL, message)

	switch priority {
	case "debug":
		c.Debugf(message, params...)

	case "info":
		c.Infof(message, params...)

	case "warn":
		c.Warningf(message, params...)

	case "error":
		c.Errorf(message, params...)

	case "crit":
		c.Criticalf(message, params...)

	default:
		c.Errorf(message, params...)
	}
}
Example #2
0
File: app.go Project: 0x7cc/rsc
func updateCacheTime(c appengine.Context, seq int64) {
	const key = rootMemcacheKey
	bseq := []byte(strconv.FormatInt(seq, 10))
	for tries := 0; tries < 10; tries++ {
		item, err := memcache.Get(c, key)
		if err != nil {
			c.Infof("memcache.Get %q: %v", key, err)
			err = memcache.Add(c, &memcache.Item{Key: key, Value: bseq})
			if err == nil {
				c.Infof("memcache.Add %q %q ok", key, bseq)
				return
			}
			c.Infof("memcache.Add %q %q: %v", key, bseq, err)
		}
		v, err := strconv.ParseInt(string(item.Value), 10, 64)
		if err != nil {
			c.Criticalf("memcache.Get %q = %q (%v)", key, item.Value, err)
			return
		}
		if v >= seq {
			return
		}
		item.Value = bseq
		err = memcache.CompareAndSwap(c, item)
		if err == nil {
			c.Infof("memcache.CAS %q %d->%d ok", key, v, seq)
			return
		}
		c.Infof("memcache.CAS %q %d->%d: %v", key, v, seq, err)
	}
	c.Criticalf("repeatedly failed to update root key")
}
Example #3
0
func mailissue(ctxt appengine.Context, kind, key string) error {
	ctxt.Infof("mailissue %s", key)
	var cl CL
	err := app.ReadData(ctxt, "CL", key, &cl)
	if err != nil {
		return nil // error already logged
	}

	if len(cl.NeedMailIssue) == 0 {
		return nil
	}

	var mailed []string
	for _, issue := range cl.NeedMailIssue {
		err := postIssueComment(ctxt, issue, "CL https://codereview.appspot.com/"+cl.CL+" mentions this issue.")
		if err != nil {
			ctxt.Criticalf("posting to issue %v: %v", issue, err)
			continue
		}
		mailed = append(mailed, issue)
	}

	err = app.Transaction(ctxt, func(ctxt appengine.Context) error {
		var old CL
		if err := app.ReadData(ctxt, "CL", key, &old); err != nil {
			return err
		}
		old.MailedIssue = append(old.MailedIssue, mailed...)
		return app.WriteData(ctxt, "CL", key, &old)
	})

	return err
}
Example #4
0
// AppEngineLogHandler sends logs to AppEngine.
// The record must contain the appengine request context.
func AppEngineLogHandler() log15.Handler {
	logFormat := log15.JsonFormat()
	return log15.FuncHandler(func(r *log15.Record) error {
		var c appengine.Context
		index := 0
		for i, e := range r.Ctx {
			if ct, ok := e.(appengine.Context); ok {
				c = ct
				index = i
				break
			}
		}
		if c == nil {
			// not in the context of a request
			return nil
		}
		r.Ctx = append(r.Ctx[:index-1], r.Ctx[index+1:]...)
		log := string(logFormat.Format(r))
		switch r.Lvl {
		case log15.LvlCrit:
			c.Criticalf(log)
		case log15.LvlError:
			c.Errorf(log)
		case log15.LvlWarn:
			c.Warningf(log)
		case log15.LvlInfo:
			c.Infof(log)
		case log15.LvlDebug:
			c.Debugf(log)
		}
		return nil
	})
}
Example #5
0
// Handler to find all questions answered/being answered by the user in URL
func userHandler(w http.ResponseWriter, r *http.Request, c appengine.Context, user stackongo.User) {
	userID, _ := strconv.Atoi(r.FormValue("id"))
	query := userData{}

	// Create and fill in a new webData struct
	tempData := newWebData()

	data.CacheLock.Lock()
	// range through the question caches golang stackongo and add if the question contains the tag
	tempData.Caches["unanswered"] = data.Caches["unanswered"]
	if userQuery, ok := data.Users[userID]; ok {
		query = userQuery
		for cacheType, cache := range data.Users[userID].Caches {
			if cacheType != "unanswered" {
				tempData.Caches[cacheType] = cache
			}
		}
		tempData.Qns = data.Qns
	}
	data.CacheLock.Unlock()
	page := template.Must(template.ParseFiles("public/template.html"))

	var userQuery = []string{
		"user",
		query.User_info.Display_name,
	}
	if err := page.Execute(w, writeResponse(user, tempData, c, userQuery)); err != nil {
		c.Criticalf("%v", err.Error())
	}
}
Example #6
0
// Handler to find all questions with specific tags
func tagHandler(w http.ResponseWriter, r *http.Request, c appengine.Context, user stackongo.User) {
	// Collect query
	tag := r.FormValue("tagSearch")
	// Create and fill in a new webData struct
	tempData := newWebData()

	data.CacheLock.Lock()
	// range through the question caches golang stackongoand add if the question contains the tag
	for cacheType, cache := range data.Caches {
		for _, question := range cache {
			if contains(question.Tags, tag) {
				tempData.Caches[cacheType] = append(tempData.Caches[cacheType], question)
			}
		}
	}
	tempData.Qns = data.Qns
	data.CacheLock.Unlock()

	page := template.Must(template.ParseFiles("public/template.html"))
	var tagQuery = []string{
		"tag",
		tag,
	}
	if err := page.Execute(w, writeResponse(user, tempData, c, tagQuery)); err != nil {
		c.Criticalf("%v", err.Error())
	}
}
Example #7
0
//This is the main tags page
//Should display a list of tags that are logged in the database
//User can either click on a tag to view any questions containing that tag or search by a specific tag
func viewTagsHandler(w http.ResponseWriter, r *http.Request, c appengine.Context, user stackongo.User) {
	//Read all tags and their counts from the db, and execute the page
	query := readTagsFromDb()
	//Format array of tags into another array, to be easier formatted on the page into a table
	//An array of tagData arrays of size 4
	var tagArray [][]tagData
	var tempTagArray []tagData
	i := 0
	for _, t := range query {
		tempTagArray = append(tempTagArray, t)
		i++
		if i == 4 {
			tagArray = append(tagArray, tempTagArray)
			i = 0
			//clear the temp array.
			tempTagArray = nil
		}
	}
	tagArray = append(tagArray, tempTagArray)
	page := template.Must(template.ParseFiles("public/viewTags.html"))
	if err := page.Execute(w, queryReply{user, tagArray}); err != nil {
		c.Criticalf("%v", err.Error())
	}

}
Example #8
0
func userPageHandler(w http.ResponseWriter, r *http.Request, c appengine.Context, user stackongo.User) {
	page := template.Must(template.ParseFiles("public/userPage.html"))
	usr, _ := strconv.Atoi(r.FormValue("userId"))
	currentUser := data.Users[usr]
	query := userData{User_info: currentUser.User_info}

	var n int
	query.Caches = make(map[string][]stackongo.Question)

	n = Min(3, len(currentUser.Caches["unanswered"]))
	if n > 0 {
		query.Caches["answered"] = currentUser.Caches["answered"][0:n]
	}
	n = Min(3, len(currentUser.Caches["pending"]))
	if n > 0 {
		query.Caches["pending"] = currentUser.Caches["pending"][0:n]
	}

	n = Min(3, len(currentUser.Caches["updating"]))
	if n > 0 {
		query.Caches["updating"] = currentUser.Caches["updating"][0:n]
	}
	if err := page.Execute(w, queryReply{user, query}); err != nil {
		c.Criticalf("%v", err.Error())
	}
}
Example #9
0
File: app.go Project: 0x7cc/rsc
func cachePathTime(c appengine.Context, path string) (t int64, err error) {
	t, err = cacheTime(c)
	if err != nil {
		return 0, err
	}

	key := fmt.Sprintf("%d,mtime,%s", t, path)
	item, err := memcache.Get(c, key)
	if err == nil {
		v, err := strconv.ParseInt(string(item.Value), 10, 64)
		if err == nil {
			if chatty {
				c.Infof("cachePathTime %q = %v", key, v)
			}
			return v, nil
		}
		c.Criticalf("memcache.Get %q = %q (%v) - deleting", key, item.Value, err)
		memcache.Delete(c, key)
	}

	var seq int64
	if fi, err := stat(c, path); err == nil {
		seq = fi.Seq
	}

	c.Infof("cachePathTime save %q = %v", key, seq)
	item = &memcache.Item{Key: key, Value: []byte(strconv.FormatInt(seq, 10))}
	if err := memcache.Set(c, item); err != nil {
		c.Criticalf("memcache.Set %q %q: %v", key, item.Value, err)
	}
	return seq, nil
}
Example #10
0
func HandleError(c appengine.Context, w http.ResponseWriter, err error) {
	w.WriteHeader(http.StatusInternalServerError)

	err2 := Layout.Execute(w, tmplt.Context{"err": err})
	if err2 != nil {
		c.Criticalf("Got error %v while serving %v", err2, err)
		return
	}
}
Example #11
0
File: app.go Project: 0x7cc/rsc
func cacheWrite(c appengine.Context, t int64, kind, name string, data []byte) error {
	mkey := fmt.Sprintf("%d,%s,%s", t, kind, name)
	if true || chatty {
		c.Infof("cacheWrite %s %d bytes", mkey, len(data))
	}
	err := memcache.Set(c, &memcache.Item{Key: mkey, Value: data})
	if err != nil {
		c.Criticalf("cacheWrite memcache.Set %q: %v", mkey, err)
	}
	return err
}
Example #12
0
func writeLogMessage(c appengine.Context, level logLevel, msg string) {
	const fmt = "%s"
	switch level {
	case levelDebug:
		c.Debugf(fmt, msg)
	case levelWarning:
		c.Warningf(fmt, msg)
	case levelError:
		c.Errorf(fmt, msg)
	case levelCritical:
		c.Criticalf(fmt, msg)
	default:
		c.Infof(fmt, msg)
	}
}
Example #13
0
// notify tries to update the CL for the given Commit with a failure message.
// If it doesn't succeed, it sends a failure email to golang-dev.
func notify(c appengine.Context, com *Commit, builder, logHash string) {
	var msg bytes.Buffer
	err := notifyTmpl.Execute(&msg, struct {
		Builder  string
		LogHash  string
		Hostname string
	}{builder, logHash, domain})
	if err != nil {
		c.Criticalf("couldn't render template: %v", err)
		return
	}
	if err := postGerritMessage(c, com, msg.String()); err != nil {
		c.Errorf("couldn't post to gerrit: %v", err)
	}
}
//TODO finish this function with the popper search parameters
func UserHasActiveSubscription(ctx appengine.Context, userKey *datastore.Key) (bool, error) {

	count, err := datastore.NewQuery(TXN_KIND).
		Ancestor(userKey).
		Filter("PaymentActivationDate>=", time.Now().AddDate(0, -6, 0)).
		Count(ctx)

	if err != nil {
		return false, err
	}

	if count > 1 {
		ctx.Criticalf(fmt.Sprintf("User has multiple (%d) active subscriptions, key: %s", count, userKey.String()))
	}

	return count > 0, nil
}
Example #15
0
func doExpire(c appengine.Context, expireTime time.Time, cursorString string) {
	query := getExpiredQuery(expireTime).KeysOnly()

	if len(cursorString) > 0 {
		if cursor, err := datastore.DecodeCursor(cursorString); err != nil {
			c.Errorf("Failed to decode cursor: %s", err)
			return
		} else {
			query = query.Start(cursor)
		}
	}

	for {
		toDelete := make([]*datastore.Key, 0, 100)

		for queryIterator := query.Run(c); ; {
			peerKey, err := queryIterator.Next(nil)
			if len(toDelete) >= 100 {
				break
			} else if err == datastore.Done {
				c.Infof("Done finding expired peers")
				break
			} else if err != nil {
				c.Criticalf("Failed to get next peer: %#v (%s)", err, err)
				return
			}

			toDelete = append(toDelete, peerKey)
		}

		deleted := len(toDelete)
		c.Infof("Deleting %d expired peers", deleted)
		if err := ds.DeleteMulti(c, toDelete); err != nil {
			c.Criticalf("Failed to delete peers: %#v (%s)", err, err)
			return
		}

		if deleted <= 0 {
			break
		}
	}

	c.Infof("Finished deleting expired peers")
}
Example #16
0
// Handler for viewing all users in the database
// Formats the response into an array of userData maps, for easier formatting onto the page.
func viewUsersHandler(w http.ResponseWriter, r *http.Request, c appengine.Context, user stackongo.User) {
	query := data.Users
	var queryArray []map[int]userData
	var tempQueryArray []userData

	for i, u := range query {
		tempQueryArray = append(tempQueryArray, u)
		if i%4 == 0 {
			queryArray = append(queryArray, tempQueryArray)
			//clear temp array
			tempQueryArray = nil
		}
	}
	queryArray = append(queryArray, tempQueryArray)
	page := template.Must(template.ParseFiles("public/viewUsers.html"))
	if err := page.Execute(w, queryReply{user, queryArray}); err != nil {
		c.Criticalf("%v", err.Error())
	}
}
Example #17
0
func GetAllUsers(ctx appengine.Context) ([]*datastore.Key, []UserDTO, error) {
	query := datastore.NewQuery(USER_KIND).
		Ancestor(userCollectionParentKey(ctx))

	count, err := query.Count(ctx)
	if err != nil {
		return nil, nil, err
	}
	if count <= 0 {
		return nil, nil, nil
	}

	users := make([]UserDTO, 0, count)
	keys, err := query.GetAll(ctx, &users)
	if err != nil {
		ctx.Criticalf("error in txn 2")
		return nil, nil, err
	}

	return keys, users, nil
}
Example #18
0
/*
	SQL Fields: Title, Body, Link, Tags, Users.
*/
func searchHandler(w http.ResponseWriter, r *http.Request, c appengine.Context, user stackongo.User) {
	//Collect query
	search := r.FormValue("search")
	//Convert to string to check ID against questions
	i, err := strconv.Atoi(search)
	searchType := ""
	if err != nil {
		i = 0
		searchType = "URL"
	} else {
		searchType = "ID"
	}
	tempData := newWebData()

	data.CacheLock.Lock()
	//Range through questions, checking URL and question ID against search term
	for cacheType, cache := range data.Caches {
		for _, question := range cache {

			if question.Question_id == i || question.Link == search || contains(question.Tags, search) ||
				strings.Contains(question.Body, search) || strings.Contains(question.Title, search) {
				tempData.Caches[cacheType] = append(tempData.Caches[cacheType], question)
			}
		}
	}

	tempData.Qns = data.Qns
	data.CacheLock.Unlock()

	page := template.Must(template.ParseFiles("public/template.html"))

	var pageQuery = []string{
		searchType,
		search,
	}
	if err := page.Execute(w, writeResponse(user, tempData, c, pageQuery)); err != nil {
		c.Criticalf("%v", err.Error())
	}

}
Example #19
0
File: app.go Project: 0x7cc/rsc
func cacheTime(c appengine.Context) (t int64, err error) {
	const key = rootMemcacheKey
	item, err := memcache.Get(c, key)
	if err == nil {
		v, err := strconv.ParseInt(string(item.Value), 10, 64)
		if err == nil {
			if chatty {
				c.Infof("cacheTime %q = %v", key, v)
			}
			return v, nil
		}
		c.Criticalf("memcache.Get %q = %q (%v) - deleting", key, item.Value, err)
		memcache.Delete(c, key)
	}
	fi, err := stat(c, "/")
	if err != nil {
		c.Criticalf("stat /: %v", err)
		return 0, err
	}
	updateCacheTime(c, fi.Seq)
	return fi.Seq, nil
}
Example #20
0
// Inital loading of DB.
func start(c appengine.Context) error {
	var err error

	loadWait = sync.NewCond(&mu)
	c.Infof("Loading db on instance " + appengine.InstanceID())
	client := createClient(c, time.Second*30)
	resp, err := client.Get(dbUrl)
	if err != nil {
		c.Criticalf("Error downloading:%s", err.Error())
		return err
	}
	defer resp.Body.Close()
	db, err = oui.Open(resp.Body)

	if err != nil {
		c.Criticalf("Error parsing:%s", err.Error())
		return err
	}
	t := time.Now().Add(time.Hour * 24)
	UpdateAt = &t
	c.Infof("Loaded, now serving...")
	loadWait.Broadcast()
	return nil
}
Example #21
0
func ParseFeed(c appengine.Context, u string, b []byte) (*Feed, []*Story) {
	if strings.TrimSpace(u) == "" {
		c.Criticalf("badurl3: %v", u)
		return nil, nil
	}
	f := Feed{Url: u}
	var s []*Story

	a := atom.Feed{}
	var atomerr, rsserr, rdferr error
	d := xml.NewDecoder(bytes.NewReader(b))
	d.CharsetReader = charset.NewReader
	if atomerr = d.Decode(&a); atomerr == nil {
		f.Title = a.Title
		if t, err := parseDate(c, &f, string(a.Updated)); err == nil {
			f.Updated = t
		}
		for _, l := range a.Link {
			if l.Rel != "self" {
				f.Link = l.Href
				break
			}
		}

		for _, i := range a.Entry {
			st := Story{
				Id:    i.ID,
				Title: i.Title,
			}
			if t, err := parseDate(c, &f, string(i.Updated)); err == nil {
				st.Updated = t
			}
			if t, err := parseDate(c, &f, string(i.Published)); err == nil {
				st.Published = t
			}
			if len(i.Link) > 0 {
				st.Link = i.Link[0].Href
			}
			if i.Author != nil {
				st.Author = i.Author.Name
			}
			if i.Content != nil {
				st.content, st.Summary = Sanitize(i.Content.Body)
			} else if i.Summary != nil {
				st.content, st.Summary = Sanitize(i.Summary.Body)
			}
			s = append(s, &st)
		}

		return parseFix(c, &f, s)
	}

	r := rssgo.Rss{}
	d = xml.NewDecoder(bytes.NewReader(b))
	d.CharsetReader = charset.NewReader
	d.DefaultSpace = "DefaultSpace"
	if rsserr = d.Decode(&r); rsserr == nil {
		f.Title = r.Title
		f.Link = r.Link
		if t, err := parseDate(c, &f, r.LastBuildDate, r.PubDate); err == nil {
			f.Updated = t
		} else {
			c.Warningf("no rss feed date: %v", f.Link)
		}

		for _, i := range r.Items {
			st := Story{
				Link:   i.Link,
				Author: i.Author,
			}
			if i.Title != "" {
				st.Title = i.Title
			} else if i.Description != "" {
				i.Title = i.Description
			}
			if i.Content != "" {
				st.content, st.Summary = Sanitize(i.Content)
			} else if i.Title != "" && i.Description != "" {
				st.content, st.Summary = Sanitize(i.Description)
			}
			if i.Guid != nil {
				st.Id = i.Guid.Guid
			}
			if t, err := parseDate(c, &f, i.PubDate, i.Date, i.Published); err == nil {
				st.Published = t
				st.Updated = t
			}

			s = append(s, &st)
		}

		return parseFix(c, &f, s)
	}

	rdf := RDF{}
	d = xml.NewDecoder(bytes.NewReader(b))
	d.CharsetReader = charset.NewReader
	if rdferr = d.Decode(&rdf); rdferr == nil {
		if rdf.Channel != nil {
			f.Title = rdf.Channel.Title
			f.Link = rdf.Channel.Link
			if t, err := parseDate(c, &f, rdf.Channel.Date); err == nil {
				f.Updated = t
			}
		}

		for _, i := range rdf.Item {
			st := Story{
				Id:     i.About,
				Title:  i.Title,
				Link:   i.Link,
				Author: i.Creator,
			}
			st.content, st.Summary = Sanitize(html.UnescapeString(i.Description))
			if t, err := parseDate(c, &f, i.Date); err == nil {
				st.Published = t
				st.Updated = t
			}
			s = append(s, &st)
		}

		return parseFix(c, &f, s)
	}

	c.Warningf("atom parse error: %s", atomerr.Error())
	c.Warningf("xml parse error: %s", rsserr.Error())
	c.Warningf("rdf parse error: %s", rdferr.Error())
	return nil, nil
}
Example #22
0
func Criticalf(context appengine.Context, logMessage string, v ...interface{}) {
	context.Criticalf("[ERROR]  "+logMessage, v)
}
Example #23
0
File: app.go Project: 0x7cc/rsc
func cacheRead(c appengine.Context, kind, name, path string) (mtime int64, data []byte, pfi *proto.FileInfo, err error) {
	for tries := 0; tries < 10; tries++ {
		t, err := cachePathTime(c, path)
		if err != nil {
			return 0, nil, nil, err
		}

		key := fmt.Sprintf("%d,%s,%s", t, kind, name)
		item, err := memcache.Get(c, key)
		var data []byte
		if item != nil {
			data = item.Value
		}
		if err != nil {
			c.Infof("memcache miss %q %v", key, err)
		} else if chatty {
			c.Infof("memcache hit %q (%d bytes)", key, len(data))
		}
		if kind != "data" {
			// Not a file; whatever memcache says is all we have.
			return t, data, nil, err
		}

		// Load stat from cache (includes negative entry).
		statkey := fmt.Sprintf("%d,stat,%s", t, name)
		var st statCacheEntry
		_, err = memcache.JSON.Get(c, statkey, &st)
		if err == nil {
			if st.Error != "" {
				if chatty {
					c.Infof("memcache hit stat error %q %q", statkey, st.Error)
				}
				err = errors.New(st.Error)
			} else {
				if chatty {
					c.Infof("memcache hit stat %q", statkey)
				}
			}
			if err != nil || data != nil {
				return t, data, st.FileInfo, err
			}
		}

		// Need stat, or maybe stat+data.
		var fi *FileInfo
		if data != nil {
			c.Infof("stat %q", name)
			fi, err = stat(c, name)
			if err == nil && fi.Seq != t {
				c.Criticalf("loaded %s but found stat %d", key, fi.Seq)
				continue
			}
		} else {
			c.Infof("read %q", name)
			fi, data, err = read(c, name)
			if err == nil && fi.Seq != t {
				c.Infof("loaded %s but found read %d", key, fi.Seq)
				t = fi.Seq
				key = fmt.Sprintf("%d,data,%s", t, name)
				statkey = fmt.Sprintf("%d,stat,%s", t, name)
			}

			// Save data to memcache.
			if err == nil {
				if true || chatty {
					c.Infof("save data in memcache %q", key)
				}
				item := &memcache.Item{Key: key, Value: data}
				if err := memcache.Set(c, item); err != nil {
					c.Criticalf("failed to cache %s: %v", key, err)
				}
			}
		}

		// Cache stat, including error.
		st = statCacheEntry{}
		if fi != nil {
			st.FileInfo = &proto.FileInfo{
				Name:    fi.Name,
				ModTime: fi.ModTime,
				Size:    fi.Size,
				IsDir:   fi.IsDir,
			}
		}
		if err != nil {
			st.Error = err.Error()
			// If this is a deadline exceeded, do not cache.
			if strings.Contains(st.Error, "Canceled") || strings.Contains(st.Error, "Deadline") {
				return t, data, st.FileInfo, err
			}
		}
		if chatty {
			c.Infof("save stat in memcache %q", statkey)
		}
		if err := memcache.JSON.Set(c, &memcache.Item{Key: statkey, Object: &st}); err != nil {
			c.Criticalf("failed to cache %s: %v", statkey, err)
		}

		// Done!
		return t, data, st.FileInfo, err
	}

	c.Criticalf("failed repeatedly in cacheRead")
	return 0, nil, nil, errors.New("cacheRead loop failed")
}
func Criticalf(c appengine.Context, format string, args ...interface{}) {
	c.Criticalf(sprintf(format, args...))
}