Sign inSign up

nexusuw/paisley

By nexusuw

•Updated over 7 years ago

Text

Image
0

464

nexusuw/paisley repository overview

⁠Paisley

GOALS create custom rss feed for reddit get to choose

  • which subreddit
  • max posts per day in the feed
  • min activity rules
    • comment count
    • up count
    • up vs down ratio
  • if include comments in rss
  • if include names of comments

user will use their own rss reader (provide link: https://en.wikipedia.org/wiki/Comparison_of_feed_aggregators⁠)

feed will be unique per user (private)

design todos refresh once per day pull whole thing into db clear up posts in db after X days user accounts -> edit + create + delete feeds landing page for new folks postgres db ? to make high availablity feed fetcher will have to use queue + workers (eventually) switch feed id to guid instead of int (people cant peak at other's feeds without knowing the id)

⁠Hotel Booking Example

The Hotel Booking example app demonstrates (browse the source⁠):

  • Using an SQL (SQLite) database and configuring the Revel DB module.
  • Using the third party GORP⁠ ORM-ish library
  • Interceptors⁠ for checking that an user is logged in.
  • Using validation⁠ and displaying inline errors

Here's a quick summary of the structure

	booking/app/
		models		   # Structs and validation.
			booking.go
			hotel.go
			user.go

		controllers
			init.go    # Register all of the interceptors.
			gorp.go    # A plugin for setting up Gorp, creating tables, and managing transactions.
			app.go     # "Login" and "Register new user" pages
			hotels.go  # Hotel searching and booking

		views
			...

⁠Database Install and Setup

This example used sqlite⁠, (Alternatively can use mysql, postgres, etc.)

⁠sqlite Installation

  • The booking app uses go-sqlite3⁠ database driver, which depends on the C library
⁠Install sqlite on OSX:
  1. Install Homebrew⁠ if you don't already have it.
  2. Install pkg-config and sqlite3:
$ brew install pkgconfig sqlite3
⁠Install sqlite on Ubuntu:
$ sudo apt-get install sqlite3 libsqlite3-dev

Once SQLite is installed, it will be possible to run the booking app:

	$ revel run github.com/revel/examples/booking

⁠Database / Gorp Plugin

app/controllers/gorp.go⁠ defines GorpPlugin, which is a plugin that does a couple things:

  • OnAppStart - Uses the DB module to open a SQLite in-memory database, create the User, Booking, and Hotel tables, and insert some test records.
  • BeforeRequest - Begins a transaction and stores the Transaction on the Controller
  • AfterRequest - Commits the transaction, or panics⁠ if there was an error.
  • OnException - Rolls back the transaction

⁠Interceptors

app/controllers/init.go⁠ registers the interceptors⁠ that runs before each action:

func init() {
	revel.OnAppStart(Init)
	revel.InterceptMethod((*GorpController).Begin, revel.BEFORE)
	revel.InterceptMethod(Application.AddUser, revel.BEFORE)
	revel.InterceptMethod(Hotels.checkUser, revel.BEFORE)
	revel.InterceptMethod((*GorpController).Commit, revel.AFTER)
	revel.InterceptMethod((*GorpController).Rollback, revel.FINALLY)
}

As an example, checkUser looks up the username in the session and redirects the user to log in if they do not have a session cookie.

func (c Hotels) checkUser() revel.Result {
	if user := c.connected(); user == nil {
		c.Flash.Error("Please log in first")
		return c.Redirect(Application.Index)
	}
	return nil
}

Check out the user management code in app.go⁠

⁠Validation

The booking app does quite a bit of validation.

For example, here is the routine to validate a booking, from models/booking.go⁠:

func (booking Booking) Validate(v *revel.Validation) {
	v.Required(booking.User)
	v.Required(booking.Hotel)
	v.Required(booking.CheckInDate)
	v.Required(booking.CheckOutDate)

	v.Match(b.CardNumber, regexp.MustCompile(`\d{16}`)).
		Message("Credit card number must be numeric and 16 digits")

	v.Check(booking.NameOnCard,
		revel.Required{},
		revel.MinSize{3},
		revel.MaxSize{70},
	)
}

Revel applies the validation and records errors using the name of the validated variable (unless overridden). For example, booking.CheckInDate is required; if it evaluates to the zero date, Revel stores a ValidationError in the validation context under the key "booking.CheckInDate".

Subsequently, the Hotels/Book.html⁠ template can access them using the field⁠ helper:

{% capture ex %}{% raw %}
{{with $field := field "booking.CheckInDate" .}}
<p class="{{$field.ErrorClass}}">
    <strong>Check In Date:</strong>
    <input type="text" size="10" name="{{$field.Name}}" class="datepicker" value="{{$field.Flash}}">
    * <span class="error">{{$field.Error}}</span>
ss</p>
{{end}}
{% endraw %}{% endcapture %}
{% highlight htmldjango %}{{ex}}{% endhighlight %} 

The field⁠ template helper looks for errors in the validation context, using the field name as the key.

Tag summary

Content type

Image

Digest

Size

436.5 MB

Last updated

over 7 years ago

docker pull nexusuw/paisley