removing unused variable
[oweals/karmaworld.git] / README.md
1 # KarmaWorld
2 __Description__: A django application for sharing and uploading class notes.
3
4 __Copyright__: FinalsClub, a 501c3 non-profit organization
5
6 __License__: GPLv3 except where otherwise noted
7
8 __Contact__: info@karmanotes.org
9
10 v3.0 of the karmanotes.org website from the FinalsClub Foundation
11
12 # Purpose
13
14 KarmaNotes is an online database of college lecture notes.  KarmaNotes empowers college students to participate in the free exchange of knowledge. 
15
16 # Pre-Installation
17
18 ## Code
19
20 Before doing anything, you'll need the code. Grab it from github.
21
22 Clone the project from the central repo using your github account:
23
24     git clone git@github.com:FinalsClub/karmaworld.git
25
26 If you aren't using a system setup for github, then grab the project with
27 this command instead:
28
29     git clone https://github.com/FinalsClub/karmaworld.git
30
31 Generally speaking, this will create a subdirectory called `karmaworld` under
32 the directory where the `git` command was run. This git repository directory
33 will be referred to herein as `{project_root}`.
34
35 There might be some confusion as the git repository's directory will likely be
36 called `karmaworld` (this is `{project_root}`), but there is also a `karmaworld`
37 directory underneath that (`{project_root}/karmaworld`) alongside files like
38 `fabfile.py` (`{project_root}/fabfile.py`) and `README.md`
39 (`{project_root}/README.md`).
40
41 ## External Service Dependencies
42
43 Notice: This software makes use of external third party services which require
44 accounts to access the service APIs. Without these third parties available,
45 this software may require considerable overhaul. These services have
46 API keys, credentials, and other information that you must provide to KarmaNotes
47 as environment variables. The best way to persist these environment variables is
48 by using a `.env` file. Copy `.env.example` to `.env` and populate the fields as
49 required.
50
51 ### Heroku
52 This project has chosen to use [Heroku](www.heroku.com) to host the Django and
53 celery software. While not a hard requirement, the more up-to-date parts of this
54 documentation will operate assuming Heroku is in use.
55
56 See README.heroku for more information.
57
58
59 ### Celery Queue
60 Celery uses the Apache Message Queueing Protocol for passing messages to its workers.
61
62 For production, we recommend using Heroku's CloudAMQP add-on, getting your own CloudAMQP account, or
63 running a queueing system on your own. The `CLOUDAMQP_URL` environment variable must be set correctly
64 for KarmaNotes to be able to use Celery. The `CELERY_QUEUE_NAME` environment variable
65 must be set to the name of the queue you wish to use. Settings this to something unique
66 allows multiple instances of KarmaNotes (or some other software) to share the same queueing server.
67
68 For development on localhost, `RabbitMQ` is the default for `djcelery` and is well supported. Ensure
69 `RabbitMQ` is installed for local development.
70
71 ### Postgresql RDBMS
72
73 PostgreSQL is not necessarily required; other RDBMS could probably be fit into
74 place. However, the code was largely written assuming PostgreSQL will be used.
75 Change to another system with the caveat that it might take some work.
76
77 There are many cloud providers which provide PostgreSQL databases. Heroku has
78 an add-on for providing a PostgreSQL database. Ensure something like this
79 is made available and installed to the app.
80
81 For local development, ensure a PostgreSQL is running on localhost or is
82 otherwise accessible.
83
84 ### Amazon S3
85 The instructions for creating an [S3](http://aws.amazon.com/s3/) bucket may be
86 [found on Amazon.](http://docs.aws.amazon.com/AmazonS3/latest/gsg/CreatingABucket.html)
87
88 Two, separate buckets will be needed in production: one for static file hosting
89 and one as a communication bus with Filepicker.
90
91 This software uses S3 to store files which are sent to or received 
92 from Filepicker. Filepicker will need to know the S3 bucket name, access key,
93 and secret key.
94
95 Filepicker users can only make use of an S3 bucket with a paid account. For
96 development purposes, no Filepicker S3 bucket is needed. Skip all references to
97 the Filepicker S3 bucket in the development case.
98
99 The software will not need to know the S3 credentials for the Filepicker
100 bucket, because the software will upload files to the Filepicker S3 bucket
101 through Filepicker's API and it will link to or download files from the
102 Filepicker S3 bucket through Filepicker's URLs. This will be covered in the
103 Filepicker section below.
104
105 This software uses S3 for hosting static files. The software will need to
106 update static files on the S3 bucket. As such, the software will need the
107 S3 bucket name, access key, and secret key via the environment variables. This
108 is described in subsections below.
109
110 To support static hosting, `DEFAULT_FILE_STORAGE` should be set to
111 `'storages.backends.s3boto.S3BotoStorage'`, unless there is a compelling reason
112 to change it.
113
114 There are three ways to setup access to the S3 buckets depending upon speed
115 and security. The more secure, the slower it will be to setup.
116
117 #### insecure S3 access
118 For quick and dirty insecure S3 access, create a single group and a single user
119 with full access to all buckets. Full access to all buckets is insecure!
120
121 Create an 
122 [Amazon IAM group](http://docs.aws.amazon.com/IAM/latest/UserGuide/Using_CreatingAndListingGroups.html)
123 with full access to the S3 bucket. Select the "Amazon S3 Full Accesss" Policy
124 Template.
125
126 Create an
127 [Amazon IAM user](http://docs.aws.amazon.com/IAM/latest/UserGuide/Using_SettingUpUser.html).
128 Copy the credentials into the `AWS_ACCESS_KEY_ID` and `AWS_SECRET_ACCESS_KEY`
129 environment variables. Be sure to write down the access information, as it
130 will only be shown once.
131
132 #### secure S3 access
133 For secure S3 access, two users will be needed. One with access to the
134 Filepicker bucket and one with access to the static hosting bucket.
135
136 Note: this might need to be modified to prevent creation and deletion of
137 buckets?
138
139 Create an 
140 [Amazon IAM group](http://docs.aws.amazon.com/IAM/latest/UserGuide/Using_CreatingAndListingGroups.html)
141 with full access to the S3 bucket. The quick way is to select the
142 "Amazon S3 Full Accesss" Policy Template and replace `"Resource": "*"` with 
143 `"Resource": "arn:aws:s3:::<static_bucket_name>"`.
144
145 Create an
146 [Amazon IAM user](http://docs.aws.amazon.com/IAM/latest/UserGuide/Using_SettingUpUser.html).
147 Copy the credentials into the `AWS_ACCESS_KEY_ID` and `AWS_SECRET_ACCESS_KEY`
148 environment variables. Be sure to write down the access information, as it
149 will only be shown once.
150
151 Ensure the created user is a member of the group with access to the S3
152 static files bucket.
153
154 Repeat the process again, creating a group for the Filepicker bucket and
155 creating a user with access to that group. These credentials will be passed
156 on to Filepicker.
157
158 #### somewhat secure S3 access
159 Create two groups as described in the `secure S3 access` section above.
160
161 Create a single user, save the credentials as described in the
162 `insecure S3 access` section above, and pass the credentials on to Filepicker.
163
164 Add the single user to both groups.
165
166 This is less secure because if your web server or Filepicker get compromised
167 (so there are two points for potential failure), the single compromised
168 user has full access to both buckets.
169
170 ### Amazon Cloudfront CDN
171 [Cloudfront CDN](http://aws.amazon.com/cloudfront/) assists static file hosting.
172
173 Follow
174 [Amazon's instructions](http://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/GettingStarted.html)
175 to host static files out of the appropriate S3 bucket. Note that Django's static
176 file upload process has been modified to mark static files as publicly
177 assessible.
178
179 In the settings for the Cloudfront Distribution, copy the "Domain Name" from
180 General settings and set `CLOUDFRONT_DOMAIN` to it. For example, `abcdefghij.cloudfront.net`.
181
182 ### Amazon Mechanical Turk
183 Mechanical turk is employed to generate human feedback from uploaded notes.
184 This service is helpful for generating flash cards and quizzes.
185
186 This service is optional and it might cause unexpected charges when
187 deployed.  If the required environment variable is not found,
188 then no errors will occur and no mechanical turk tasks will be created, avoiding any unexpected
189 costs.
190
191 The `MTURK_HOST` environment variable is almost certainly
192 `"mechanicalturk.amazonaws.com"`.
193
194 The code will create and publish HITs on your behalf.
195
196 ### Google Drive
197 This software uses [Google Drive](https://developers.google.com/drive/) to
198 convert documents to and from various file formats.
199
200 A Google Drive service account with access to the Google Drive is required.
201 This may be done with a Google Apps account with administrative privileges, or ask
202 your business sysadmin.
203
204 Follow [Google's instructions](https://developers.google.com/drive/delegation)
205 to create a Google Drive service account.
206
207 Convert the p12 file into a Base64 encoded string for the
208 `GOOGLE_SERVICE_KEY_BASE64` environment variable. There are many ways to do
209 this. If Python is available, the
210 [binascii library](https://docs.python.org/2/library/binascii.html#binascii.b2a_base64)
211 makes this very easy:
212
213         import binascii
214         with open('file.p12', 'r') as f:
215             print binascii.b2a_base64(f.read)
216
217 Copy the contents of `client_secret_*.apps.googleusercontent.com.json` into the
218 `GOOGLE_CLIENT_SECRETS` environment variable.
219
220 ### Filepicker
221 This software uses [Filepicker.io](https://www.inkfilepicker.com/) for uploading
222 files. This requires an account with Filepicker.
223
224 Filepicker can use an additional third party file hosting site where it may
225 send uploaded files. This project, in production, uses Amazon S3 as the third
226 party. See the Amazon S3 section above for more information.  
227
228 Create a new App with Web SDK and provide the Heroku App URL for the
229 Application's URL. You'll be given an API Key for the App. Paste this into the
230 `FILEPICKER_API_KEY` environment variable.
231
232 Find the 'App Security' button on the left hand side of the web site. Make sure
233 'Use Security' is enabled. Generate a new secret key. Paste this key into the
234 `FILEPICKER_SECRET` environment variable.
235
236 If you have an upgraded plan, you can configure Filepicker to have access to
237 your Filepicker S3 bucket. Click 'Amazon S3' on the left hand side menu and
238 supply the credentials for the user with access to the Filepicker S3 bucket.
239
240 ### IndexDen
241 KarmaNotes uses IndexDen to create a searchable index of all the notes in the
242 system. Create an free IndexDen account at
243 [their homepage](http://indexden.com/). You will be given a private URL that
244 accesses your IndexDen account. This URL is visible on your dashboard (you
245 might need to scroll down).
246
247 Set the `INDEXDEN_PRIVATE_URL` environment variable to your private URL.
248
249 Set the `INDEXDEN_INDEX` environment variable to the name of the index you want
250 to use for KarmaNotes. The index will be created automatically when KarmaNotes
251 is run if it doesn't already exist. It may be created through the GUI if
252 desired.
253
254 ### Twitter
255
256 Twitter is used to post updates about new courses. Access to the Twitter API
257 will be required for this task.
258
259 If this Twitter feature is desired, the consumer key and secret as well as the
260 access token key and secret are needed by the software.
261
262 If the required environment variables are not found, then no errors will occur
263 and no tweets will be posted.
264
265 To set this up,
266 [create a new Twitter application](https://dev.twitter.com/apps/new).
267 Use your Heroku App URL for the website field. Leave the Callback field blank.
268
269 Make sure this application has read/write access. Generate an access token. Go
270 to your OAuth settings, and grab the "Consumer key", "Consumer secret",
271 "Access token", and "Access token secret". Paste these, respectively, into the
272 environment variables `TWITTER_CONSUMER_KEY`, `TWITTER_CONSUMER_SECRET`,
273 `TWITTER_ACCESS_TOKEN_KEY`, `TWITTER_ACCESS_TOKEN_SECRET`.
274
275 ### SSL Certificate
276
277 If you wish to host your system publicly, you'll need an SSL certificate
278 signed by a proper authority.
279
280 Follow [Heroku's SSL setup](https://devcenter.heroku.com/articles/ssl-endpoint)
281 to get SSL running on your server.
282
283 You may set the `SSL_REDIRECT` environment variable to `true` to make KarmaNotes
284 redirect insecure connections to secure ones.
285
286 # Local
287
288 ## Configuring foreman
289
290 KarmaNotes is a Heroku application and makes use of a Procfie. To use the
291 Procfile locally, we recommend using `foreman`. To install `foreman` and other
292 Heroku tools, install the [Heroku toolbelt](https://toolbelt.heroku.com/).
293
294 Ensure environment variables are available to `foreman` by copying
295 `.env.example` to `.env` and update those variables as appropriate for your
296 local system.
297
298 ## Install
299
300   1. `virtualenv venv`
301   1. `source venv/bin/activate`
302   1. `pip install -r requirements.txt`
303     * on Debian systems, some packages are required for pip to succeed:
304     * `apt-get install python-dev libpython-dev python-psycopg2 libmemcached-devlibffi-dev libssl-dev postgresql-server-dev-X.Y`
305   1. `pip install -r requirements-dev.txt`
306   1. `foreman run python manage.py syncdb --migrate --noinput`
307   1. `foreman run python manage.py createsuperuser`
308   1. `foreman run python manage.py fetch_usde_csv ./schools.csv`
309   1. `foreman run python manage.py import_usde_csv ./schools.csv`
310   1. `foreman run python manage.py sanitize_usde_schools`
311
312 * `fetch_usde_csv` downloads school records and stores them to `./schools.csv`. This file name
313      and location is arbitrary. As long as the same file is passed into `import_usde_csv` for
314      reading, everything should be fine.
315
316 * `fetching_usde_csv` requires `7zip` to be installed for processing compressed
317      archives. On Debian-based systems, this entails `apt-get install p7zip-full`
318
319 ## Run
320
321 Make sure you are inside your virtual environment (`source venv/bin/activate`).
322
323 If the code has changed or this is the first run, make sure any modified static
324 files get compressed with `foreman run python manage.py compress`. Static files
325 then need to be uploaded correctly with `foreman run python manage.py
326 collectstatic`.
327
328 Run `foreman start`.  `foreman` will load the `.env` file and manage running all
329 processes in a way that is similar to that of Heroku. This allows better
330 consistency with local, staging, and production deployments.
331
332 Press ctrl-C to kill foreman. Foreman will run Django's runserver command.
333 If you wish to have more control over how this is done, you can do
334 `foreman run python manage.py runserver <options>`. For running any other
335 `manage.py` commands, you should also precede them with `foreman run` like just shown.
336 This simply ensures that the environment variables from `.env` are present.
337
338 # Heroku Install
339
340 KarmaNotes is a Heroku application. Download the [Heroku toolbelt](https://toolbelt.heroku.com/).
341
342 To run KarmaNotes on Heroku, do `heroku create` and `git push heroku master` as typical
343 for a Heroku application. Set your the variable `BUILDPACK_URL` to
344 `https://github.com/FinalsClub/heroku-buildpack-karmanotes` to use a buildpack
345 designed to support KarmaNotes.
346
347 You will need to import the US Department of Education's list of accredited schools.
348    1. Fetch USDE schools with
349       `heroku run python manage.py fetch_usde_csv ./schools.csv`
350    1. Upload the schools into the database with
351       `heroku run python /manage.py import_usde_csv ./schools.csv`
352    1. Clean up redundant information with
353       `heroku run python /manage.py sanitize_usde_schools`
354
355
356 # Django Database management
357
358 ## South
359
360 We have setup Django to use
361 [south](http://south.aeracode.org/wiki/QuickStartGuide) for migrations. When
362 changing models, it is important to run
363 `foreman run python manage.py schemamigration` which will create a migration
364  to reflect the model changes into the database. These changes can be pulled
365 into the database with `foreman run python manage.py migrate`.
366
367 Sometimes the database already has a migration performed on it, but that
368 information wasn't told to south. There are subtleties to the process which
369 require looking at the south docs. As a tip, start by looking at the `--fake`
370 flag.
371
372 # Assets from Third Parties
373
374 A number of assets have been added to the repository which come from external
375 sources. It would be difficult to keep a complete list in this README and keep
376 it up to date. Software which originally came from outside parties can
377 generally be found in `karmaworld/assets`.
378
379 Additionally, all third party Python projects (downloaded and installed with
380 pip) are listed in these files:
381
382 * `requirements.txt`
383 * `requirements-dev.txt`
384
385 # Thanks
386
387 * KarmaNotes.org is a project of the FinalsClub Foundation with generous funding from the William and Flora Hewlett Foundation
388
389 * Also thanks to [rdegges](https://github.com/rdegges/django-skel) for the django-skel template