From 95647106b0fa29b926202efe7e0b11433cd4ce3a Mon Sep 17 00:00:00 2001 From: Andrei Date: Wed, 28 Mar 2018 14:35:20 +0300 Subject: [PATCH] Updated the Readmme file Changed how we built the routes. Use the handler directly and not by string --- README.md | 89 +++++++++++++++++++++++++++++++++++++++++---- appengine_config.py | 4 +- controllers/ngo.py | 10 ----- main.py | 52 ++++++++++++++------------ 4 files changed, 111 insertions(+), 44 deletions(-) diff --git a/README.md b/README.md index 6b276056..5faec69f 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,83 @@ -# README # +# 2% -Setup donezsi.eu - -1. Install google cloud python sdk -2. `git clone https://bitbucket.org/donezsieu/donezsieu.git` -3. `pip install -r requirements.txt -t ./lib` +## Setup +1. Install Google App Engine Python SDK. [Details here aici](https://cloud.google.com/appengine/docs/standard/python/download#python_linux) +2. Clone the repo: `git clone https://github.com/code4romania/redirectioneaza` +3. Install the requirements in the `lib` folder (not globally): `pip install -r requirements.txt -t ./lib` 4. `bower install` -5. `git config user.email "andrei@donezsi.eu"` -6. `git config user.name "Andrei"` \ No newline at end of file +5. To run the dev server you need to know the path to the App Engine SDK and be in the app's folder: +```sh +[path_to_sdk]/dev_appserver.py ./app.yaml --datastore_path=./datastore.db --enable_console +``` +Read more about the Local Development Server [here](https://cloud.google.com/appengine/docs/standard/python/tools/using-local-server). +Locally, App Engine has an interface for the DB found [here](http://localhost:8000/datastore) (the server needs to be running). + +## App structure +The entry point of the app is `main.py`. Here is where all the routes are defined. +The main folders are: +* `controllers` contains the handlers for each route +* `models` has the `ndb` Models and some helpers: + * `create_pdf` the logic for creating the pdf + * `email` a small wrapper over SendGrid + * `handlers` wrappers over `webapp2.RequestHandler`, they add some functionality. New handlers should inherit from `BaseHandler` or `AccountHandler`. + * `storage` contains `CloudStorage` which helps with uploading the PDFs to google cloud +* `static` all the static files: css, js, images +* `views` all the html file + email templates. New html pages should extend `base.html` + +## Bulding new handlers +New handlers should extend `BaseHandler` from `models.handlers`. The path to the html file should be set as `template_name`. The app looks in the `views` folder for it. +To send props to the view, use the dict `self.template_values`. +On the `get` method, `self.render()` should be called at the end. + +## Notes + +### Deploying +To deploy the app from the command line, run: +```sh +gcloud app deploy --no-promote ./app.yaml --version [version] +``` +`version` must be the new version of the app + +#### Testing remotely +Google offers some generous free quota for App engine apps so you can create you own app engine app [here](http://console.cloud.google.com/appengine/) and deploy it there. You need a google account (gmail, etc.) + +#### Deploying indexes +When adding new `ndb` Models with indexed properties, they will be automatically added in the local file named `index.yaml`. That file needs to be deployed every time it changes. To do that, run: +```sh +gcloud app deploy ./index.yaml +``` + +#### CSS +The app uses `LESS`. To compile the CSS, run: +```sh +cd ./static/ +lessc css/main.less > css/main.css --clean-css="--s1 --advanced --compatibility=ie8" +``` + +### Deploying CRON jobs +To deploy the new cron jobs you need to uncomment the `application` in app.yaml and change it to your app's name (this is used only in this case) +```sh +[path_to_sdk]/appcfg.py update_cron ./ +``` +### Adding dummy NGOs +When you start if you might want to add some ngos. Go to the sdk's [Console](http://localhost:8000/console) and run: +```python +from models.models import NgoEntity + +ngo = NgoEntity( + logo= "https://code4.ro/wp-content/uploads/2016/06/fb.png", + name= "Nume asociatie", + description= "O descriere", + id= "nume-asociatie", # this needs to be unique. Also used as the ngo's URL + account = "RO33BTRL3342234vvf2234234234XX", + cif = "3333223", + address = "Str. Ion Ionescu, nr 33" +) +ngo.put() +``` +You can also add ngos from the admin. + +### Read more +You can read more about the frameworks used by the app: +[webapp2](https://webapp2.readthedocs.io/en/latest/) +[jinja2](http://jinja.pocoo.org/docs/dev/templates/) diff --git a/appengine_config.py b/appengine_config.py index f9ba4e16..294ddf5b 100644 --- a/appengine_config.py +++ b/appengine_config.py @@ -54,7 +54,7 @@ DEV_DEPENDECIES_LOCATION = "/bower_components" TITLE = "donezsi.eu" -SESSION_SECRET_KEY = "JgW`l2hZa*WV+z >}{T~Snq`DD1s@S#[Z7L>~.-;]t.7y2%gU)A^?ZTDyn/~kDh}RZA:/B{Vo7cI@TeA2Dll+0M#z|{,V*8`90VaV^`Cj&" +SESSION_SECRET_KEY = "JgW`l2hZa*WV+z >}{T~Snq`DD1s@S#[Z7L>~.-;]t.7y2%gU)A^?ZTDyn/~kDh}RZA:/BVo7cI@TeA2Dll+0M#z|{,V*8`90VaV^`Cj&" # ADMIN @@ -77,7 +77,7 @@ # for https everywhere, and on subdomains, 1 year "Strict-Transport-Security": "max-age=31536000; includeSubdomains; preload", # make sure the certificate is valid - "Public-Key-Pins-Report-Only": 'pin-sha256="wuvbD/BvVfYoATqByqmg/6/XWyvmA+yeQImG75l2ous=";pin-sha256="6X0iNAQtPIjXKEVcqZBwyMcRwq1yW60549axatu3oDE=";pin-sha256="h6801m+z8v3zbgkRHpq6L29Esgfzhj89C1SyUCOQmqU=";max-age=2592000;report-uri="https://report-uri.io/report/donezsieu/reportOnly";includeSubdomains', + # "Public-Key-Pins-Report-Only": 'pin-sha256="wuvbD/BvVfYoATqByqmg/6/XWyvmA+yeQImG75l2ous=";pin-sha256="6X0iNAQtPIjXKEVcqZBwyMcRwq1yW60549axatu3oDE=";pin-sha256="h6801m+z8v3zbgkRHpq6L29Esgfzhj89C1SyUCOQmqU=";max-age=2592000;report-uri="https://report-uri.io/report/donezsieu/reportOnly";includeSubdomains', # don't allow the site to be embeded "X-Frame-Options": "Deny", diff --git a/controllers/ngo.py b/controllers/ngo.py index 17183843..0b1c6a5c 100644 --- a/controllers/ngo.py +++ b/controllers/ngo.py @@ -26,16 +26,6 @@ import json import datetime -ngo = NgoEntity( - logo= "http://images.clipartpanda.com/spinner-clipart-9cz75npcE.jpeg", - name= "Nume asoc", - description= "o descriere lunga", - id= "ssda", - account = "RO33BTRL3342234vvf2234234234XX", - cif = "3333223", - address = "Str. Ion Ionescu, nr 33" -) -# ngo.put() """ Handlers used for ngo diff --git a/main.py b/main.py index aad4d94e..50bf6ff1 100644 --- a/main.py +++ b/main.py @@ -7,9 +7,13 @@ from webapp2_extras import routes from webapp2 import Route as r +from controllers.site import * +from controllers.account_management import * +from controllers.my_account import * +from controllers.api import * +from controllers.admin import * from controllers.ngo import NgoHandler, TwoPercentHandler, TwoPercent2Handler, DonationSucces -from controllers.site import NotFoundPage, InternalErrorPage config = { 'webapp2_extras.auth': { @@ -37,43 +41,43 @@ # use string in dotted notation to be lazily imported app = webapp2.WSGIApplication([ # the public part of the app - r('/', handler="controllers.site.HomePage"), - r('/ong', handler="controllers.site.ForNgoHandler"), + r('/', handler=HomePage), + r('/ong', handler=ForNgoHandler), # backup in case of old urls. to be removed - r('/pentru-ong-uri', handler="controllers.site.ForNgoHandler"), + r('/pentru-ong-uri', handler=ForNgoHandler), - r('/asociatii', handler="controllers.site.NgoListHandler"), + r('/asociatii', handler=NgoListHandler), - r('/termeni', handler="controllers.site.TermsHandler"), - r('/TERMENI', handler="controllers.site.TermsHandler"), - r('/politica', handler="controllers.site.PolicyHandler"), + r('/termeni', handler=TermsHandler), + r('/TERMENI', handler=TermsHandler), + r('/politica', handler=PolicyHandler), # account management - r('/cont-nou', handler="controllers.account_management.SignupHandler"), - r('/login', handler="controllers.account_management.LoginHandler", name='login'), - r('/logout', handler="controllers.account_management.LogoutHandler", name='logout'), + r('/cont-nou', handler=SignupHandler), + r('/login', handler=LoginHandler, name='login'), + r('/logout', handler=LogoutHandler, name='logout'), - r('/forgot', handler="controllers.account_management.ForgotPasswordHandler", name='forgot'), + r('/forgot', handler=ForgotPasswordHandler, name='forgot'), # verification url: used for signup, and reset password - r('//-', handler="controllers.account_management.VerificationHandler", name='verification'), - r('/password', handler="controllers.account_management.SetPasswordHandler"), + r('//-', handler=VerificationHandler, name='verification'), + r('/password', handler=SetPasswordHandler), # my account - r('/contul-meu', handler="controllers.my_account.MyAccountHandler", name='contul-meu'), - r('/asociatia', handler="controllers.my_account.NgoDetailsHandler", name='asociatia'), - r('/date-cont', handler="controllers.my_account.MyAccountDetailsHandler", name='date-contul-meu'), + r('/contul-meu', handler=MyAccountHandler, name='contul-meu'), + r('/asociatia', handler=NgoDetailsHandler, name='asociatia'), + r('/date-cont', handler=MyAccountDetailsHandler, name='date-contul-meu'), - r('/api/ngo/check-url/', handler="controllers.api.CheckNgoUrl", name='api-ngo-check-url'), - r('/api/ngo/upload-url', handler="controllers.api.GetUploadUrl", name='api-ngo-upload-url'), + r('/api/ngo/check-url/', handler=CheckNgoUrl, name='api-ngo-check-url'), + r('/api/ngo/upload-url', handler=GetUploadUrl, name='api-ngo-upload-url'), # ADMIN HANDLERS - r('/admin', handler="controllers.admin.AdminHandler", name='admin'), - r('/admin/conturi', handler="controllers.admin.UserAccounts", name='admin-users'), - r('/admin/campanii', handler="controllers.admin.SendCampaign", name='admin-campanii'), - r('/admin/ong-nou', handler="controllers.admin.AdminNewNgoHandler", name='admin-ong-nou'), - r('/admin/', handler="controllers.admin.AdminNgoHandler", name='admin-ong'), + r('/admin', handler=AdminHandler, name='admin'), + r('/admin/conturi', handler=UserAccounts, name='admin-users'), + r('/admin/campanii', handler=SendCampaign, name='admin-campanii'), + r('/admin/ong-nou', handler=AdminNewNgoHandler, name='admin-ong-nou'), + r('/admin/', handler=AdminNgoHandler, name='admin-ong'), r('/', handler=NgoHandler, name="ngo-url"),