{"id":22602534,"url":"https://github.com/nexus-uw/paisley","last_synced_at":"2026-05-05T05:37:21.622Z","repository":{"id":151389482,"uuid":"174926711","full_name":"nexus-uw/paisley","owner":"nexus-uw","description":"webapp to create personalised private RSS feeds of subreddits to cut down on noise and clicks","archived":false,"fork":false,"pushed_at":"2019-03-18T02:25:23.000Z","size":197,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-02-03T06:38:13.312Z","etag":null,"topics":["docker","go","golang","reddit","rss"],"latest_commit_sha":null,"homepage":"","language":"HTML","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"unlicense","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/nexus-uw.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2019-03-11T04:40:03.000Z","updated_at":"2019-12-03T11:38:12.000Z","dependencies_parsed_at":null,"dependency_job_id":"36f9cd92-98dd-445f-9caf-d6f3d339e5ac","html_url":"https://github.com/nexus-uw/paisley","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nexus-uw%2Fpaisley","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nexus-uw%2Fpaisley/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nexus-uw%2Fpaisley/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nexus-uw%2Fpaisley/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/nexus-uw","download_url":"https://codeload.github.com/nexus-uw/paisley/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":246100491,"owners_count":20723469,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["docker","go","golang","reddit","rss"],"created_at":"2024-12-08T12:25:29.777Z","updated_at":"2026-05-05T05:37:21.580Z","avatar_url":"https://github.com/nexus-uw.png","language":"HTML","funding_links":[],"categories":[],"sub_categories":[],"readme":"Paisley\n=======\n\nGOALS\n create custom rss feed for reddit\n get to choose\n - which subreddit\n - max posts per day in the feed\n - min activity rules \n   - comment count\n   - up count\n   - up vs down ratio\n- if include comments in rss\n- if include names of comments\n\nuser will use their own rss reader (provide link: https://en.wikipedia.org/wiki/Comparison_of_feed_aggregators)\n\nfeed will be unique per user (private)\n\ndesign todos\nrefresh once per day\npull whole thing into db\nclear up posts in db after X days\nuser accounts -\u003e \n  edit + create + delete feeds\nlanding page for new folks\npostgres db ?\nto make high availablity feed fetcher will have to use queue + workers (eventually)\nswitch feed id to guid instead of int (people cant peak at other's feeds without knowing the id)\n\n\n\n\n\nHotel Booking Example\n===============================\n\nThe Hotel Booking example app demonstrates ([browse the source](https://github.com/revel/examples/tree/master/booking)):\n\n* Using an SQL (SQLite) database and configuring the Revel DB module.\n* Using the third party [GORP](https://github.com/coopernurse/gorp) *ORM-ish* library\n* [Interceptors](../manual/interceptors.html) for checking that an user is logged in.\n* Using [validation](../manual/validation) and displaying inline errors\n\n\nHere's a quick summary of the structure\n```\n\tbooking/app/\n\t\tmodels\t\t   # Structs and validation.\n\t\t\tbooking.go\n\t\t\thotel.go\n\t\t\tuser.go\n\n\t\tcontrollers\n\t\t\tinit.go    # Register all of the interceptors.\n\t\t\tgorp.go    # A plugin for setting up Gorp, creating tables, and managing transactions.\n\t\t\tapp.go     # \"Login\" and \"Register new user\" pages\n\t\t\thotels.go  # Hotel searching and booking\n\n\t\tviews\n\t\t\t...\n```\n\n# Database Install and Setup\nThis example used [sqlite](https://www.sqlite.org/), (Alternatively can use mysql, postgres, etc.)\n\n## sqlite Installation\n\n- The booking app uses [go-sqlite3](https://github.com/mattn/go-sqlite3) database driver, which depends on the C library\n\n### Install sqlite on OSX:\n\n1. Install [Homebrew](http://mxcl.github.com/homebrew/) if you don't already have it.\n2. Install pkg-config and sqlite3:\n\n~~~\n$ brew install pkgconfig sqlite3\n~~~\n\n### Install sqlite on Ubuntu:\n```sh\n$ sudo apt-get install sqlite3 libsqlite3-dev\n```\n\nOnce SQLite is installed, it will be possible to run the booking app:\n```sh\n\t$ revel run github.com/revel/examples/booking\n```\n\n## Database / Gorp Plugin\n\n[`app/controllers/gorp.go`](https://github.com/revel/examples/blob/master/booking/app/controllers/gorp.go) defines `GorpPlugin`, which is a plugin that does a couple things:\n\n* **`OnAppStart`** -  Uses the DB module to open a SQLite in-memory database, create the `User`, `Booking`, and `Hotel` tables, and insert some test records.\n* **BeforeRequest** -  Begins a transaction and stores the Transaction on the Controller\n* **AfterRequest** -  Commits the transaction, or [panics](https://github.com/golang/go/wiki/PanicAndRecover) if there was an error.\n* **OnException** -  Rolls back the transaction\n\n\n## Interceptors\n\n[`app/controllers/init.go`](https://github.com/revel/examples/blob/master/booking/app/controllers/init.go) \nregisters the [interceptors](../manual/interceptors.html) that runs before each action:\n\n```go\nfunc init() {\n\trevel.OnAppStart(Init)\n\trevel.InterceptMethod((*GorpController).Begin, revel.BEFORE)\n\trevel.InterceptMethod(Application.AddUser, revel.BEFORE)\n\trevel.InterceptMethod(Hotels.checkUser, revel.BEFORE)\n\trevel.InterceptMethod((*GorpController).Commit, revel.AFTER)\n\trevel.InterceptMethod((*GorpController).Rollback, revel.FINALLY)\n}\n```\n\nAs an example, `checkUser` looks up the username in the `session` and `redirect`s\nthe user to log in if they do not have a `session` cookie.\n\n```go\nfunc (c Hotels) checkUser() revel.Result {\n\tif user := c.connected(); user == nil {\n\t\tc.Flash.Error(\"Please log in first\")\n\t\treturn c.Redirect(Application.Index)\n\t}\n\treturn nil\n}\n```\n\n[Check out the user management code in app.go](https://github.com/revel/examples/blob/master/booking/app/controllers/app.go)\n\n## Validation\n\nThe booking app does quite a bit of validation.\n\nFor example, here is the routine to validate a booking, from\n[models/booking.go](https://github.com/revel/examples/blob/master/booking/app/models/booking.go):\n\n```go\nfunc (booking Booking) Validate(v *revel.Validation) {\n\tv.Required(booking.User)\n\tv.Required(booking.Hotel)\n\tv.Required(booking.CheckInDate)\n\tv.Required(booking.CheckOutDate)\n\n\tv.Match(b.CardNumber, regexp.MustCompile(`\\d{16}`)).\n\t\tMessage(\"Credit card number must be numeric and 16 digits\")\n\n\tv.Check(booking.NameOnCard,\n\t\trevel.Required{},\n\t\trevel.MinSize{3},\n\t\trevel.MaxSize{70},\n\t)\n}\n```\n\nRevel applies the validation and records errors using the name of the\nvalidated variable (unless overridden).  For example, `booking.CheckInDate` is\nrequired; if it evaluates to the zero date, Revel stores a `ValidationError` in\nthe validation context under the key \"booking.CheckInDate\".\n\nSubsequently, the\n[Hotels/Book.html](https://github.com/revel/examples/blob/master/booking/app/views/Hotels/Book.html)\ntemplate can access them using the [`field`](../manual/templates.html#field) helper:\n\n```\n{% capture ex %}{% raw %}\n{{with $field := field \"booking.CheckInDate\" .}}\n\u003cp class=\"{{$field.ErrorClass}}\"\u003e\n    \u003cstrong\u003eCheck In Date:\u003c/strong\u003e\n    \u003cinput type=\"text\" size=\"10\" name=\"{{$field.Name}}\" class=\"datepicker\" value=\"{{$field.Flash}}\"\u003e\n    * \u003cspan class=\"error\"\u003e{{$field.Error}}\u003c/span\u003e\nss\u003c/p\u003e\n{{end}}\n{% endraw %}{% endcapture %}\n{% highlight htmldjango %}{{ex}}{% endhighlight %} \n```\n\n\nThe [`field`](../manual/templates.html#field) template helper looks for errors in the validation context, using\nthe field name as the key.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnexus-uw%2Fpaisley","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fnexus-uw%2Fpaisley","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnexus-uw%2Fpaisley/lists"}