<commit_before>// Copyright 2012 The Gorilla Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package sessions

import (
	"fmt"
	"net/http"
	"time"

	"appengine"
	"appengine/datastore"
	"appengine/memcache"

	"code.google.com/p/gorilla/sessions"
)

type baseSessionStore struct {
	// List of encoders registered for this store.
	encoders []sessions.SessionEncoder
}

// Encoders returns the encoders for this store.
func (s *baseSessionStore) Encoders() []sessions.SessionEncoder {
	return s.encoders
}

// SetEncoders sets a group of encoders in the store.
func (s *baseSessionStore) SetEncoders(encoders ...sessions.SessionEncoder) {
	s.encoders = encoders
}

// ----------------------------------------------------------------------------
// DatastoreSessionStore
// ----------------------------------------------------------------------------

type Session struct {
	Date  datastore.Time
	Value []byte
}

// DatastoreSessionStore stores session data in App Engine's datastore.
type DatastoreSessionStore struct {
	baseSessionStore
}

// Load loads a session for the given key.
func (s *DatastoreSessionStore) Load(r *http.Request, key string,
	info *sessions.SessionInfo) {
	data := sessions.GetCookie(s, r, key)
	if sidval, ok := data["sid"]; ok {
		// Cleanup session data.
		sid := sidval.(string)
		for k, _ := range data {
			delete(data, k)
		}
		// Get session from datastore and deserialize it.
		c := appengine.NewContext(r)
		var session Session
		key := datastore.NewKey(c, "Session", sessionKey(sid), 0, nil)
		if err := datastore.Get(c, key, &session); err == nil {
			data, _ = sessions.DeserializeSessionData(session.Value)
		}
	}
	info.Data = data
}

// Save saves the session in the response.
func (s *DatastoreSessionStore) Save(r *http.Request, w http.ResponseWriter,
	key string, info *sessions.SessionInfo) (flag bool, err error) {
	sid, serialized, error := getIdAndData(info)
	if error != nil {
		err = error
		return
	}

	// Save the session.
	c := appengine.NewContext(r)
	entityKey := datastore.NewKey(c, "Session", sessionKey(sid), 0, nil)
	_, err = datastore.Put(appengine.NewContext(r), entityKey, &Session{
		Date:  datastore.SecondsToTime(time.Now()),
		Value: serialized,
	})
	if err != nil {
		return
	}

	return sessions.SetCookie(s, w, key, cloneInfo(info, sid))
}

// ----------------------------------------------------------------------------
// MemcacheSessionStore
// ----------------------------------------------------------------------------

// MemcacheSessionStore stores session data in App Engine's memcache.
type MemcacheSessionStore struct {
	baseSessionStore
}<commit_msg>appengine/sessions: datastore.Time to time.Time. Thnanks, <NAME>.<commit_after>// Copyright 2012 The Gorilla Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package sessions

import (
	"fmt"
	"net/http"
	"time"

	"appengine"
	"appengine/datastore"
	"appengine/memcache"

	"code.google.com/p/gorilla/sessions"
)

type baseSessionStore struct {
	// List of encoders registered for this store.
	encoders []sessions.SessionEncoder
}

// Encoders returns the encoders for this store.
func (s *baseSessionStore) Encoders() []sessions.SessionEncoder {
	return s.encoders
}

// SetEncoders sets a group of encoders in the store.
func (s *baseSessionStore) SetEncoders(encoders ...sessions.SessionEncoder) {
	s.encoders = encoders
}

// ----------------------------------------------------------------------------
// DatastoreSessionStore
// ----------------------------------------------------------------------------

type Session struct {
	Date  time.Time
	Value []byte
}

// DatastoreSessionStore stores session data in App Engine's datastore.
type DatastoreSessionStore struct {
	baseSessionStore
}

// Load loads a session for the given key.
func (s *DatastoreSessionStore) Load(r *http.Request, key string,
	info *sessions.SessionInfo) {
	data := sessions.GetCookie(s, r, key)
	if sidval, ok := data["sid"]; ok {
		// Cleanup session data.
		sid := sidval.(string)
		for k, _ := range data {
			delete(data, k)
		}
		// Get session from datastore and deserialize it.
		c := appengine.NewContext(r)
		var session Session
		key := datastore.NewKey(c, "Session", sessionKey(sid), 0, nil)
		if err := datastore.Get(c, key, &session); err == nil {
			data, _ = sessions.DeserializeSessionData(session.Value)
		}
	}
	info.Data = data
}

// Save saves the session in the response.
func (s *DatastoreSessionStore) Save(r *http.Request, w http.ResponseWriter,
	key string, info *sessions.SessionInfo) (flag bool, err error) {
	sid, serialized, error := getIdAndData(info)
	if error != nil {
		err = error
		return
	}

	// Save the session.
	c := appengine.NewContext(r)
	entityKey := datastore.NewKey(c, "Session", sessionKey(sid), 0, nil)
	_, err = datastore.Put(appengine.NewContext(r), entityKey, &Session{
		Date:  time.Now(),
		Value: serialized,
	})
	if err != nil {
		return
	}

	return sessions.SetCookie(s, w, key, cloneInfo(info, sid))
}

// ----------------------------------------------------------------------------
// MemcacheSessionStore
// ----------------------------------------------------------------------------

// MemcacheSessionStore stores session data in App Engine's memcache.
type MemcacheSessionStore struct {
	baseSessionStore
}
{'fraction_non_alphanumeric': 0.217040029379361, 'fraction_numerical': 0.0022034520749173708, 'mean_word_length': 2.4257861635220124, 'pattern_counts': {'":': 0, '<': 4, '<?xml version=': 0, '>': 4, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5261299', 'n_tokens_mistral': 1695, 'n_tokens_neox': 1631, 'n_words': 485}