Skip to content

Commit

Permalink
initial port to go111
Browse files Browse the repository at this point in the history
  • Loading branch information
mblakele committed Mar 17, 2020
1 parent 25da1c0 commit 068e16f
Show file tree
Hide file tree
Showing 20 changed files with 565 additions and 440 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
TODO
app.yaml
d
goread
pw
settings.go
update
24 changes: 20 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@

a google reader clone built with go on app engine and angularjs

The [original goread project](https://github.com/mjibson/goread/issues)
has been archived. This is a fork, updated for compatibility with go111
by [Michael Blakeley](https://github.com/mblakele).

## setting up a local dev environment

1. Install [Python 2.7](http://www.python.org/download/releases/2.7.5/) and make sure it is in your `PATH`. (Google App Engine doesn't yet work with Python 3.)
Expand All @@ -13,17 +17,29 @@ a google reader clone built with go on app engine and angularjs
1. `cd $GOPATH/src/github.com/mjibson/goread/app`.
1. Copy `app.sample.yaml` to `app.yaml`.
1. In the `goread` directory (`cd ..` from the command above), copy `settings.go.dist` to `settings.go`.
1. From the `app` directory, start the app with `goapp serve`. (On Windows, you may need to do this instead: `python C:\go_appengine\dev_appserver.py app.yaml`.)

### running locally

1. `(cd app && dev_appserver.py app.yaml)` (On Windows, you may need `python C:\go_appengine\dev_appserver.py app.yaml`)
1. View at [localhost:8080](http://localhost:8080), admin console at [localhost:8000](http://localhost:8000).

## developer notes
### resetting the local environment

1. Press `alt+c` to show the miniprofiler window.
1. Press `c` to clear all feeds and stories, remove all your subscriptions, and reset your unread date.

## self host on production app engine servers

1. Set up a local dev environment as described above.
1. Create a [new app engine application](https://cloud.google.com/console?getstarted=https://appengine.google.com).
1. In `app.yaml`, change the first line to contain the name of the application you just created.
1. From the `app` directory, deploy with `goapp deploy`.
1. Deploy: `(cd app && gcloud app deploy deploy && gcloud app deploy cron.yaml)`

### other useful commands

```
(cd app && gcloud app deploy --no-promote)
(cd app && gcloud app deploy)
(cd app && gcloud app deploy cron.yaml)
gcloud app logs tail -s default
gcloud app browse
```
34 changes: 21 additions & 13 deletions admin.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/

package goapp
package goread

import (
"encoding/json"
Expand All @@ -24,14 +24,15 @@ import (
"strings"
"time"

"appengine/datastore"
"appengine/memcache"
"google.golang.org/appengine/datastore"
"google.golang.org/appengine/log"
"google.golang.org/appengine/memcache"

mpg "github.com/MiniProfiler/go/miniprofiler_gae"
"github.com/mjibson/goon"
)

func AllFeedsOpml(c mpg.Context, w http.ResponseWriter, r *http.Request) {
func AllFeedsOpml(w http.ResponseWriter, r *http.Request) {
c := r.Context()
gn := goon.FromContext(c)
q := datastore.NewQuery(gn.Kind(&Feed{})).KeysOnly()
keys, _ := gn.GetAll(q, nil)
Expand Down Expand Up @@ -62,14 +63,16 @@ func feedsToOpml(feeds []*Feed) []byte {
return b
}

func AllFeeds(c mpg.Context, w http.ResponseWriter, r *http.Request) {
func AllFeeds(w http.ResponseWriter, r *http.Request) {
c := r.Context()
gn := goon.FromContext(c)
q := datastore.NewQuery(gn.Kind(&Feed{})).KeysOnly()
keys, _ := gn.GetAll(q, nil)
templates.ExecuteTemplate(w, "admin-all-feeds.html", keys)
}

func AdminFeed(c mpg.Context, w http.ResponseWriter, r *http.Request) {
func AdminFeed(w http.ResponseWriter, r *http.Request) {
c := r.Context()
gn := goon.FromContext(c)
f := Feed{Url: r.FormValue("f")}
if err := gn.Get(&f); err != nil {
Expand Down Expand Up @@ -117,7 +120,8 @@ func AdminFeed(c mpg.Context, w http.ResponseWriter, r *http.Request) {
})
}

func AdminUpdateFeed(c mpg.Context, w http.ResponseWriter, r *http.Request) {
func AdminUpdateFeed(w http.ResponseWriter, r *http.Request) {
c := r.Context()
url := r.FormValue("f")
if feed, stories, err := fetchFeed(c, url, url); err == nil {
updateFeed(c, url, feed, stories, true, false, false)
Expand All @@ -127,7 +131,8 @@ func AdminUpdateFeed(c mpg.Context, w http.ResponseWriter, r *http.Request) {
}
}

func AdminSubHub(c mpg.Context, w http.ResponseWriter, r *http.Request) {
func AdminSubHub(w http.ResponseWriter, r *http.Request) {
c := r.Context()
gn := goon.FromContext(c)
f := Feed{Url: r.FormValue("f")}
if err := gn.Get(&f); err != nil {
Expand All @@ -139,7 +144,8 @@ func AdminSubHub(c mpg.Context, w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "subscribed")
}

func AdminDateFormats(c mpg.Context, w http.ResponseWriter, r *http.Request) {
func AdminDateFormats(w http.ResponseWriter, r *http.Request) {
c := r.Context()
type df struct {
URL, Format string
}
Expand All @@ -158,7 +164,8 @@ func AdminDateFormats(c mpg.Context, w http.ResponseWriter, r *http.Request) {
}
}

func AdminStats(c mpg.Context, w http.ResponseWriter, r *http.Request) {
func AdminStats(w http.ResponseWriter, r *http.Request) {
c := r.Context()
gn := goon.FromContext(c)
uc, _ := datastore.NewQuery(gn.Kind(&User{})).Count(c)
templates.ExecuteTemplate(w, "admin-stats.html", struct {
Expand All @@ -168,7 +175,8 @@ func AdminStats(c mpg.Context, w http.ResponseWriter, r *http.Request) {
})
}

func AdminUser(c mpg.Context, w http.ResponseWriter, r *http.Request) {
func AdminUser(w http.ResponseWriter, r *http.Request) {
c := r.Context()
gn := goon.FromContext(c)
q := datastore.NewQuery(gn.Kind(&User{})).Limit(1)
q = q.Filter("e =", r.FormValue("u"))
Expand Down Expand Up @@ -199,7 +207,7 @@ func AdminUser(c mpg.Context, w http.ResponseWriter, r *http.Request) {
serveError(w, err)
return
}
c.Infof("opml updated")
log.Infof(c, "opml updated")
}
q = datastore.NewQuery(gn.Kind(&Log{})).Ancestor(k)
_, err = gn.GetAll(q, &h)
Expand Down
25 changes: 25 additions & 0 deletions app/.gcloudignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# This file specifies files that are *not* uploaded to Google Cloud Platform
# using gcloud. It follows the same syntax as .gitignore, with the addition of
# "#!include" directives (which insert the entries of the given .gitignore-style
# file at that point).
#
# For more information, run:
# $ gcloud topic gcloudignore
#
.gcloudignore
# If you would like to upload your .git directory, .gitignore file or files
# from your .gitignore file, remove the corresponding line
# below:
.git
.gitignore

# Binaries for programs and plugins
*.exe
*.exe~
*.dll
*.so
*.dylib
# Test binary, build with `go test -c`
*.test
# Output of the go coverage tool, specifically when used with LiteIDE
*.out
9 changes: 8 additions & 1 deletion app/app.go
Original file line number Diff line number Diff line change
@@ -1,15 +1,22 @@
package app
package main

import (
"net/http"

"github.com/gorilla/mux"

app "github.com/mjibson/goread"

"google.golang.org/appengine"
)

func init() {
router := mux.NewRouter()
app.RegisterHandlers(router)
http.Handle("/", router)
}

/* compatibility for go111 */
func main() {
appengine.Main()
}
17 changes: 7 additions & 10 deletions app/app.sample.yaml
Original file line number Diff line number Diff line change
@@ -1,7 +1,4 @@
application: go-read
version: 1
runtime: go
api_version: go1
runtime: go111

automatic_scaling:
min_idle_instances: 1
Expand All @@ -20,27 +17,27 @@ handlers:

- url: /login/google
login: required
script: _go_app
script: auto
secure: always

- url: /user/.*
login: required
script: _go_app
script: auto
secure: always

- url: /task/.*
login: admin
script: _go_app
script: auto
secure: always

- url: /admin/.*
login: admin
script: _go_app
script: auto
secure: always

- url: /push
script: _go_app
script: auto

- url: /.*
script: _go_app
script: auto
secure: always
6 changes: 5 additions & 1 deletion app/cron.yaml
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
cron:
- description: hourly feed update
url: /tasks/update-feeds
schedule: every 2 minutes
schedule: every 5 minutes
# enable as needed, to cleanup obsolete datastore entities
#- description: datastore cleanup
# url: /tasks/datastore-cleanup
# schedule: every 60 minutes
20 changes: 8 additions & 12 deletions app/index.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,18 @@ indexes:

# AUTOGENERATED

# This index.yaml is automatically updated whenever the dev_appserver
# detects that a new type of query is run. If you want to manage the
# index.yaml file manually, remove the above marker line (the line
# saying "# AUTOGENERATED"). If you want to manage some indexes
# manually, move them above the marker line. The index.yaml file is
# automatically uploaded to the admin console when you next deploy
# your application using appcfg.py.
# This index.yaml is automatically updated whenever the Cloud Datastore
# emulator detects that a new type of query is run. If you want to manage the
# index.yaml file manually, remove the "# AUTOGENERATED" marker line above.
# If you want to manage some indexes manually, move them above the marker line.

- kind: S
- kind: "S"
ancestor: yes
properties:
- name: c
- name: "c"
direction: desc

- kind: US
- kind: "US"
ancestor: yes
properties:
- name: c
- name: "c"
direction: desc
13 changes: 11 additions & 2 deletions app/static/js/site.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,18 @@ goReadAppModule.controller('GoreadCtrl', function($scope, $http, $timeout, $wind
$scope.importOpml = function() {
$scope.shown = 'feeds';
$scope.loading++;
$('#import-opml-form').ajaxForm({
$scope.http('GET', $('#import-opml-form').attr('data-upload-url'))
.then(processImport);
};

function processImport(data) {
var f = $('#import-opml-form');
f.prop('action', data.data);
f.ajaxSubmit({
clearForm: true,
error: function(jqXHR, textStatus, errorThrown) {
$scope.showMessage(jqXHR.responseText);
$scope.$apply();
},
success: function() {
$scope.loaded();
Expand All @@ -47,9 +55,10 @@ goReadAppModule.controller('GoreadCtrl', function($scope, $http, $timeout, $wind
" Don't reorganize your feeds" +
" until it's completed importing." +
" Refresh to see its progress.");
$scope.$apply();
}
});
};
}

$scope.loaded = function() {
$scope.loading--;
Expand Down
4 changes: 2 additions & 2 deletions app/templates/base.html
Original file line number Diff line number Diff line change
Expand Up @@ -460,13 +460,13 @@ <h4><a href="javascript:window.location=%22http://www.goread.io/user/add-subscri

<div class="row top-margin" ng-show="shown == 'import-opml' || nothing()">
<div class="col-md-offset-2 col-md-8">
<form id="import-opml-form" enctype="multipart/form-data" method="POST" action="{{url "import-opml"}}">
<form id="import-opml-form" enctype="multipart/form-data" method="POST" data-upload-url="{{url "upload-url"}}">
<legend>Upload OPML file</legend>
<div class="form-group">
<input type="file" name="file">
</div>
<button ng-click="importOpml()" type="submit" class="btn btn-default">upload</button>
</form>
<button ng-click="importOpml()" class="btn btn-default">upload</button>
</div>
</div>

Expand Down
2 changes: 1 addition & 1 deletion autodiscover.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/

package goapp
package goread

import (
"bytes"
Expand Down
Loading

0 comments on commit 068e16f

Please sign in to comment.