README
¶
go read
a google reader clone built with go on app engine and angularjs
setting up a local dev environment
- Install Python 2.7 and make sure it is in your
PATH
. (Google App Engine doesn't yet work with Python 3.) - Install Git and Mercurial and make sure
git
andhg
are in yourPATH
. - Install the Go App Engine SDK.
- Set your
GOPATH
(to something like/home/user
), and make sure it's a directory that exists. (Note: set this on your machine's environment, not in the go.bat file.) - Further commands use
goapp
which lives in thego_appengine
directory from the SDK. Make sure it's in yourPATH
. - Download goread and dependencies by running:
goapp get -d github.com/mjibson/goread
. You may get messages about unrecognized imports. Ignore them. cd $GOPATH/src/github.com/mjibson/goread/app
.- Copy
app.sample.yaml
toapp.yaml
. - In the
goread
directory (cd ..
from the command above), copysettings.go.dist
tosettings.go
. - From the
app
directory, start the app withgoapp serve
. (On Windows, you may need to do this instead:python C:\go_appengine\dev_appserver.py app.yaml
.) - View at localhost:8080, admin console at localhost:8000.
developer notes
- Press
alt+c
to show the miniprofiler window. - Press
c
to clear all feeds and stories, remove all your subscriptions, and reset your unread date.
self host on production app engine servers
- Set up a local dev environment as described above.
- Create a new app engine application.
- In
app.yaml
, change the first line to contain the name of the application you just created. - From the
app
directory, deploy withgoapp deploy
.
Documentation
¶
Index ¶
- Constants
- Variables
- func Account(c mpg.Context, w http.ResponseWriter, r *http.Request)
- func AddSubscription(c mpg.Context, w http.ResponseWriter, r *http.Request)
- func AdminDateFormats(c mpg.Context, w http.ResponseWriter, r *http.Request)
- func AdminFeed(c mpg.Context, w http.ResponseWriter, r *http.Request)
- func AdminStats(c mpg.Context, w http.ResponseWriter, r *http.Request)
- func AdminSubHub(c mpg.Context, w http.ResponseWriter, r *http.Request)
- func AdminUpdateFeed(c mpg.Context, w http.ResponseWriter, r *http.Request)
- func AdminUser(c mpg.Context, w http.ResponseWriter, r *http.Request)
- func AllFeeds(c mpg.Context, w http.ResponseWriter, r *http.Request)
- func AllFeedsOpml(c mpg.Context, w http.ResponseWriter, r *http.Request)
- func Autodiscover(b []byte) (string, error)
- func Charge(c mpg.Context, w http.ResponseWriter, r *http.Request)
- func ClearFeeds(c mpg.Context, w http.ResponseWriter, r *http.Request)
- func ClearRead(c mpg.Context, w http.ResponseWriter, r *http.Request)
- func DeleteAccount(c mpg.Context, w http.ResponseWriter, r *http.Request)
- func DeleteBlobs(c mpg.Context, w http.ResponseWriter, r *http.Request)
- func DeleteOldFeed(c mpg.Context, w http.ResponseWriter, r *http.Request)
- func DeleteOldFeeds(c mpg.Context, w http.ResponseWriter, r *http.Request)
- func ExportOpml(c mpg.Context, w http.ResponseWriter, r *http.Request)
- func FeedHistory(c mpg.Context, w http.ResponseWriter, r *http.Request)
- func FindIcon(b []byte) (string, error)
- func GetContents(c mpg.Context, w http.ResponseWriter, r *http.Request)
- func GetFeed(c mpg.Context, w http.ResponseWriter, r *http.Request)
- func GetStars(c mpg.Context, w http.ResponseWriter, r *http.Request)
- func ImportOpml(c mpg.Context, w http.ResponseWriter, r *http.Request)
- func ImportOpmlTask(c mpg.Context, w http.ResponseWriter, r *http.Request)
- func ListFeeds(c mpg.Context, w http.ResponseWriter, r *http.Request)
- func LoginGoogle(c mpg.Context, w http.ResponseWriter, r *http.Request)
- func Logout(c mpg.Context, w http.ResponseWriter, r *http.Request)
- func Main(c mpg.Context, w http.ResponseWriter, r *http.Request)
- func MarkRead(c mpg.Context, w http.ResponseWriter, r *http.Request)
- func MarkUnread(c mpg.Context, w http.ResponseWriter, r *http.Request)
- func ParseFeed(c appengine.Context, contentType, origUrl, fetchUrl string, body []byte) (*Feed, []*Story, error)
- func RegisterHandlers(r *mux.Router)
- func SaveOptions(c mpg.Context, w http.ResponseWriter, r *http.Request)
- func SetStar(c mpg.Context, w http.ResponseWriter, r *http.Request)
- func SubscribeCallback(c mpg.Context, w http.ResponseWriter, r *http.Request)
- func SubscribeFeed(c mpg.Context, w http.ResponseWriter, r *http.Request)
- func TestAtom(c mpg.Context, w http.ResponseWriter, r *http.Request)
- func Uncheckout(c mpg.Context, w http.ResponseWriter, r *http.Request)
- func UpdateFeed(c mpg.Context, w http.ResponseWriter, r *http.Request)
- func UpdateFeedLast(c mpg.Context, w http.ResponseWriter, r *http.Request)
- func UpdateFeeds(c mpg.Context, w http.ResponseWriter, r *http.Request)
- func UploadOpml(c mpg.Context, w http.ResponseWriter, r *http.Request)
- func UploadUrl(c mpg.Context, w http.ResponseWriter, r *http.Request)
- type Feed
- type Image
- type Includes
- type Log
- type Opml
- type OpmlOutline
- type Plan
- type Read
- type Stories
- type Story
- type StoryContent
- type StripeCustomer
- type StripeError
- type User
- type UserCharge
- type UserData
- type UserOpml
- type UserStar
- type UserStarFeed
Constants ¶
View Source
const ( AFree = iota ADev APaid )
View Source
const IDX_COL = "c"
View Source
const IMPORT_LIMIT = 10
Variables ¶
View Source
var ( ErrNoRssLink = errors.New("No rss link found") ErrNoIcon = errors.New("No icon found") )
Functions ¶
func AddSubscription ¶
func AdminDateFormats ¶
func AdminStats ¶
func AdminSubHub ¶
func AdminUpdateFeed ¶
func AllFeedsOpml ¶
func Autodiscover ¶
func ClearFeeds ¶
func DeleteAccount ¶
func DeleteBlobs ¶
func DeleteOldFeed ¶
func DeleteOldFeeds ¶
func ExportOpml ¶
func FeedHistory ¶
func FindIcon ¶
Returns the href attribute of a <link rel="shortcut icon"> tag or error if not found.
func GetContents ¶
func ImportOpml ¶
func ImportOpmlTask ¶
func LoginGoogle ¶
func MarkUnread ¶
func RegisterHandlers ¶
func SaveOptions ¶
func SubscribeCallback ¶
func SubscribeFeed ¶
Task used to subscribe a feed to push.
func Uncheckout ¶
func UpdateFeed ¶
func UpdateFeedLast ¶
func UpdateFeeds ¶
func UploadOpml ¶
Types ¶
type Feed ¶
type Feed struct { Url string `datastore:"-" goon:"id"` Title string `datastore:"t,noindex"` Updated time.Time `datastore:"u,noindex" json:"-"` Date time.Time `datastore:"d,noindex" json:"-"` Checked time.Time `datastore:"c,noindex"` NextUpdate time.Time `datastore:"n"` Link string `datastore:"l,noindex" json:"-"` Hub string `datastore:"h,noindex" json:"-"` Errors int `datastore:"e,noindex"` Image string `datastore:"i,noindex"` ImageDate time.Time `datastore:"g,noindex"` Subscribed time.Time `datastore:"s,noindex" json:"-"` Average time.Duration `datastore:"a,noindex" json:"-"` LastViewed time.Time `datastore:"v" json:"-"` NoAds bool `datastore:"o,noindex" json:"-"` // contains filtered or unexported fields }
func (*Feed) IsSubscribed ¶
type Includes ¶
type Includes struct { Angular string BootstrapCss string BootstrapJs string FontAwesome string Jquery string JqueryUI string Underscore string MiniProfiler template.HTML User *User Messages []string GoogleAnalyticsId string GoogleAnalyticsHost string SubURL string IsDev bool IsAdmin bool StripeKey string StripePlans []Plan }
type Opml ¶
type Opml struct { XMLName string `xml:"opml"` Version string `xml:"version,attr"` Title string `xml:"head>title"` Outline []*OpmlOutline `xml:"body>outline"` }
type OpmlOutline ¶
type OpmlOutline struct { Outline []*OpmlOutline `xml:"outline" json:",omitempty"` Title string `xml:"title,attr,omitempty" json:",omitempty"` XmlUrl string `xml:"xmlUrl,attr,omitempty" json:",omitempty"` Type string `xml:"type,attr,omitempty" json:",omitempty"` Text string `xml:"text,attr,omitempty" json:",omitempty"` HtmlUrl string `xml:"htmlUrl,attr,omitempty" json:",omitempty"` }
type Story ¶
type Story struct { Id string `datastore:"-" goon:"id"` Parent *datastore.Key `datastore:"-" goon:"parent" json:"-"` Title string `datastore:"t,noindex"` Link string `datastore:"l,noindex"` Created time.Time `datastore:"c"` Published time.Time `datastore:"p,noindex" json:"-"` Updated time.Time `datastore:"u,noindex" json:"-"` Date int64 `datastore:"e,noindex"` Author string `datastore:"a,noindex" json:",omitempty"` Summary string `datastore:"s,noindex"` MediaContent string `datastore:"m,noindex" json:",omitempty"` // contains filtered or unexported fields }
parent: Feed, key: story ID
type StoryContent ¶
type StoryContent struct { Id int64 `datastore:"-" goon:"id"` Parent *datastore.Key `datastore:"-" goon:"parent"` Content string `datastore:"c,noindex"` Compressed []byte `datastore:"z,noindex"` // contains filtered or unexported fields }
parent: Story, key: 1
type StripeCustomer ¶
type StripeCustomer struct { Id string `json:"id"` Created int64 `json:"created"` Card struct { Last4 string `json:"last4"` } `json:"active_card"` Subscription struct { Plan struct { Interval string `json:"interval"` Id string `json:"id"` Amount int `json:"amount"` } `json:"plan"` End int64 `json:"current_period_end"` } `json:"subscription"` }
type StripeError ¶
type StripeError struct { Error struct { Message string `json:"message"` } `json:"error"` }
type User ¶
type User struct { Id string `datastore:"-" goon:"id"` Email string `datastore:"e"` Messages []string `datastore:"m,noindex"` Read time.Time `datastore:"r"` Options string `datastore:"o,noindex"` Account int `datastore:"a"` Created time.Time `datastore:"d"` Until time.Time `datastore:"u"` // contains filtered or unexported fields }
type UserCharge ¶
type UserCharge struct { Id int64 `datastore:"-" goon:"id"` Parent *datastore.Key `datastore:"-" goon:"parent"` Customer string `datastore:"c,noindex" json:"-"` Created time.Time `datastore:"r,noindex"` Last4 string `datastore:"l,noindex" json:"-"` Next time.Time `datastore:"n,noindex"` Amount int `datastore:"a,noindex"` Interval string `datastore:"i,noindex"` Plan string `datastore:"p,noindex"` // contains filtered or unexported fields }
parent: User, key: 1
type UserData ¶
type UserData struct { Id string `datastore:"-" goon:"id"` Parent *datastore.Key `datastore:"-" goon:"parent"` Opml []byte `datastore:"o,noindex"` Read []byte `datastore:"r,noindex"` // contains filtered or unexported fields }
parent: User, key: "data"
type UserOpml ¶
type UserOpml struct { Id int64 `datastore:"-" goon:"id"` Parent *datastore.Key `datastore:"-" goon:"parent"` Opml []byte `datastore:"o,noindex"` Compressed []byte `datastore:"z,noindex"` // contains filtered or unexported fields }
parent: User, key: time.Now().UnixNano()
type UserStar ¶
type UserStar struct { Id string `datastore:"-" goon:"id"` Parent *datastore.Key `datastore:"-" goon:"parent"` Created time.Time `datastore:"c"` // contains filtered or unexported fields }
parent: UserStarFeed, key: Story.Key.Encode()
type UserStarFeed ¶
Source Files
¶
Directories
¶
Path | Synopsis |
---|---|
_third_party
|
|
code.google.com/p/go-charset/charset
The charset package implements translation between character sets.
|
The charset package implements translation between character sets. |
code.google.com/p/go-charset/data
The data package embeds all the charset data files as Go data.
|
The data package embeds all the charset data files as Go data. |
github.com/MiniProfiler/go/miniprofiler
Package miniprofiler is a simple but effective mini-profiler for websites.
|
Package miniprofiler is a simple but effective mini-profiler for websites. |
github.com/MiniProfiler/go/miniprofiler_gae
Package miniprofiler_gae is a simple but effective mini-profiler for app engine.
|
Package miniprofiler_gae is a simple but effective mini-profiler for app engine. |
github.com/golang/protobuf/proto
Package proto converts data structures to and from the wire format of protocol buffers.
|
Package proto converts data structures to and from the wire format of protocol buffers. |
github.com/gorilla/context
Package context stores values shared during a request lifetime.
|
Package context stores values shared during a request lifetime. |
github.com/gorilla/mux
Package gorilla/mux implements a request router and dispatcher.
|
Package gorilla/mux implements a request router and dispatcher. |
github.com/mjibson/appstats
Package appstats profiles the RPC performance of Google App Engine applications.
|
Package appstats profiles the RPC performance of Google App Engine applications. |
github.com/mjibson/goon
Package goon provides an autocaching interface to the app engine datastore similar to the python NDB package.
|
Package goon provides an autocaching interface to the app engine datastore similar to the python NDB package. |
golang.org/x/net/html
Package html implements an HTML5-compliant tokenizer and parser.
|
Package html implements an HTML5-compliant tokenizer and parser. |
golang.org/x/net/html/atom
Package atom provides integer codes (also known as atoms) for a fixed set of frequently occurring HTML strings: tag names and attribute keys such as "p" and "id".
|
Package atom provides integer codes (also known as atoms) for a fixed set of frequently occurring HTML strings: tag names and attribute keys such as "p" and "id". |
golang.org/x/net/html/charset
Package charset provides common text encodings for HTML documents.
|
Package charset provides common text encodings for HTML documents. |
golang.org/x/text/cldr
Package cldr provides a parser for LDML and related XML formats.
|
Package cldr provides a parser for LDML and related XML formats. |
golang.org/x/text/encoding
Package encoding defines an interface for character encodings, such as Shift JIS and Windows 1252, that can convert to and from UTF-8.
|
Package encoding defines an interface for character encodings, such as Shift JIS and Windows 1252, that can convert to and from UTF-8. |
golang.org/x/text/encoding/charmap
Package charmap provides simple character encodings such as IBM Code Page 437 and Windows 1252.
|
Package charmap provides simple character encodings such as IBM Code Page 437 and Windows 1252. |
golang.org/x/text/encoding/japanese
Package japanese provides Japanese encodings such as EUC-JP and Shift JIS.
|
Package japanese provides Japanese encodings such as EUC-JP and Shift JIS. |
golang.org/x/text/encoding/korean
Package korean provides Korean encodings such as EUC-KR.
|
Package korean provides Korean encodings such as EUC-KR. |
golang.org/x/text/encoding/simplifiedchinese
Package simplifiedchinese provides Simplified Chinese encodings such as GBK.
|
Package simplifiedchinese provides Simplified Chinese encodings such as GBK. |
golang.org/x/text/encoding/traditionalchinese
Package traditionalchinese provides Traditional Chinese encodings such as Big5.
|
Package traditionalchinese provides Traditional Chinese encodings such as Big5. |
golang.org/x/text/encoding/unicode
Package unicode provides Unicode encodings such as UTF-16.
|
Package unicode provides Unicode encodings such as UTF-16. |
golang.org/x/text/transform
Package transform provides reader and writer wrappers that transform the bytes passing through as well as various transformations.
|
Package transform provides reader and writer wrappers that transform the bytes passing through as well as various transformations. |
Package atom defines XML data structures for an Atom feed.
|
Package atom defines XML data structures for an Atom feed. |
Click to show internal directories.
Click to hide internal directories.