Merge branch 'master' of github.com:FinalsClub/karmaworld
[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 ### Amazon S3
72 The instructions for creating an [S3](http://aws.amazon.com/s3/) bucket may be
73 [found on Amazon.](http://docs.aws.amazon.com/AmazonS3/latest/gsg/CreatingABucket.html)
74
75 Two, separate buckets will be needed in production: one for static file hosting
76 and one as a communication bus with Filepicker.
77
78 This software uses S3 to store files which are sent to or received 
79 from Filepicker. Filepicker will need to know the S3 bucket name, access key,
80 and secret key.
81
82 Filepicker users can only make use of an S3 bucket with a paid account. For
83 development purposes, no Filepicker S3 bucket is needed. Skip all references to
84 the Filepicker S3 bucket in the development case.
85
86 The software will not need to know the S3 credentials for the Filepicker
87 bucket, because the software will upload files to the Filepicker S3 bucket
88 through Filepicker's API and it will link to or download files from the
89 Filepicker S3 bucket through Filepicker's URLs. This will be covered in the
90 Filepicker section below.
91
92 This software uses S3 for hosting static files. The software will need to
93 update static files on the S3 bucket. As such, the software will need the
94 S3 bucket name, access key, and secret key via the environment variables. This
95 is described in subsections below.
96
97 To support static hosting, `DEFAULT_FILE_STORAGE` should be set to
98 `'storages.backends.s3boto.S3BotoStorage'`, unless there is a compelling reason
99 to change it.
100
101 There are three ways to setup access to the S3 buckets depending upon speed
102 and security. The more secure, the slower it will be to setup.
103
104 #### insecure S3 access
105 For quick and dirty insecure S3 access, create a single group and a single user
106 with full access to all buckets. Full access to all buckets is insecure!
107
108 Create an 
109 [Amazon IAM group](http://docs.aws.amazon.com/IAM/latest/UserGuide/Using_CreatingAndListingGroups.html)
110 with full access to the S3 bucket. Select the "Amazon S3 Full Accesss" Policy
111 Template.
112
113 Create an
114 [Amazon IAM user](http://docs.aws.amazon.com/IAM/latest/UserGuide/Using_SettingUpUser.html).
115 Copy the credentials into the `AWS_ACCESS_KEY_ID` and `AWS_SECRET_ACCESS_KEY`
116 environment variables. Be sure to write down the access information, as it
117 will only be shown once.
118
119 #### secure S3 access
120 For secure S3 access, two users will be needed. One with access to the
121 Filepicker bucket and one with access to the static hosting bucket.
122
123 Note: this might need to be modified to prevent creation and deletion of
124 buckets?
125
126 Create an 
127 [Amazon IAM group](http://docs.aws.amazon.com/IAM/latest/UserGuide/Using_CreatingAndListingGroups.html)
128 with full access to the S3 bucket. The quick way is to select the
129 "Amazon S3 Full Accesss" Policy Template and replace `"Resource": "*"` with 
130 `"Resource": "arn:aws:s3:::<static_bucket_name>"`.
131
132 Create an
133 [Amazon IAM user](http://docs.aws.amazon.com/IAM/latest/UserGuide/Using_SettingUpUser.html).
134 Copy the credentials into the `AWS_ACCESS_KEY_ID` and `AWS_SECRET_ACCESS_KEY`
135 environment variables. Be sure to write down the access information, as it
136 will only be shown once.
137
138 Ensure the created user is a member of the group with access to the S3
139 static files bucket.
140
141 Repeat the process again, creating a group for the Filepicker bucket and
142 creating a user with access to that group. These credentials will be passed
143 on to Filepicker.
144
145 #### somewhat secure S3 access
146 Create two groups as described in the `secure S3 access` section above.
147
148 Create a single user, save the credentials as described in the
149 `insecure S3 access` section above, and pass the credentials on to Filepicker.
150
151 Add the single user to both groups.
152
153 This is less secure because if your web server or Filepicker get compromised
154 (so there are two points for potential failure), the single compromised
155 user has full access to both buckets.
156
157 ### Amazon Cloudfront CDN
158 [Cloudfront CDN](http://aws.amazon.com/cloudfront/) assists static file hosting.
159
160 Follow
161 [Amazon's instructions](http://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/GettingStarted.html)
162 to host static files out of the appropriate S3 bucket. Note that Django's static
163 file upload process has been modified to mark static files as publicly
164 assessible.
165
166 In the settings for the Cloudfront Distribution, copy the "Domain Name" from
167 General settings and set `CLOUDFRONT_DOMAIN` to it. For example, `abcdefghij.cloudfront.net`.
168
169 ### Amazon Mechanical Turk
170 Mechanical turk is employed to generate human feedback from uploaded notes.
171 This service is helpful for generating flash cards and quizzes.
172
173 This service is optional and it might cause unexpected charges when
174 deployed.  If the required environment variable is not found,
175 then no errors will occur and no mechanical turk tasks will be created, avoiding any unexpected
176 costs.
177
178 The `MTURK_HOST` environment variable is almost certainly
179 `"mechanicalturk.amazonaws.com"`.
180
181 The code will create and publish HITs on your behalf.
182
183 ### Google Drive
184 This software uses [Google Drive](https://developers.google.com/drive/) to
185 convert documents to and from various file formats.
186
187 A Google Drive service account with access to the Google Drive is required.
188 This may be done with a Google Apps account with administrative privileges, or ask
189 your business sysadmin.
190
191 Follow [Google's instructions](https://developers.google.com/drive/delegation)
192 to create a Google Drive service account.
193
194 Convert the p12 file into a Base64 encoded string for the
195 `GOOGLE_SERVICE_KEY_BASE64` environment variable. There are many ways to do
196 this. If Python is available, the
197 [binascii library](https://docs.python.org/2/library/binascii.html#binascii.b2a_base64)
198 makes this very easy:
199
200         import binascii
201         with open('file.p12', 'r') as f:
202             print binascii.b2a_base64(f.read)
203
204 Copy the contents of `client_secret_*.apps.googleusercontent.com.json` into the
205 `GOOGLE_CLIENT_SECRETS` environment variable.
206
207 ### Filepicker
208 This software uses [Filepicker.io](https://www.inkfilepicker.com/) for uploading
209 files. This requires an account with Filepicker.
210
211 Filepicker can use an additional third party file hosting site where it may
212 send uploaded files. This project, in production, uses Amazon S3 as the third
213 party. See the Amazon S3 section above for more information.  
214
215 Create a new App with Web SDK and provide the Heroku App URL for the
216 Application's URL. You'll be given an API Key for the App. Paste this into the
217 `FILEPICKER_API_KEY` environment variable.
218
219 Find the 'App Security' button on the left hand side of the web site. Make sure
220 'Use Security' is enabled. Generate a new secret key. Paste this key into the
221 `FILEPICKER_SECRET` environment variable.
222
223 If you have an upgraded plan, you can configure Filepicker to have access to
224 your Filepicker S3 bucket. Click 'Amazon S3' on the left hand side menu and
225 supply the credentials for the user with access to the Filepicker S3 bucket.
226
227 ### IndexDen
228 KarmaNotes uses IndexDen to create a searchable index of all the notes in the
229 system. Create an free IndexDen account at
230 [their homepage](http://indexden.com/). You will be given a private URL that
231 accesses your IndexDen account. This URL is visible on your dashboard (you
232 might need to scroll down).
233
234 Set the `INDEXDEN_PRIVATE_URL` environment variable to your private URL.
235
236 Set the `INDEXDEN_INDEX` environment variable to the name of the index you want
237 to use for KarmaNotes. The index will be created automatically when KarmaNotes
238 is run if it doesn't already exist. It may be created through the GUI if
239 desired.
240
241 ### Twitter
242
243 Twitter is used to post updates about new courses. Access to the Twitter API
244 will be required for this task.
245
246 If this Twitter feature is desired, the consumer key and secret as well as the
247 access token key and secret are needed by the software.
248
249 If the required environment variables are not found, then no errors will occur
250 and no tweets will be posted.
251
252 To set this up,
253 [create a new Twitter application](https://dev.twitter.com/apps/new).
254 Use your Heroku App URL for the website field. Leave the Callback field blank.
255
256 Make sure this application has read/write access. Generate an access token. Go
257 to your OAuth settings, and grab the "Consumer key", "Consumer secret",
258 "Access token", and "Access token secret". Paste these, respectively, into the
259 environment variables `TWITTER_CONSUMER_KEY`, `TWITTER_CONSUMER_SECRET`,
260 `TWITTER_ACCESS_TOKEN_KEY`, `TWITTER_ACCESS_TOKEN_SECRET`.
261
262 ### SSL Certificate
263
264 If you wish to host your system publicly, you'll need an SSL certificate
265 signed by a proper authority.
266
267 Follow [Heroku's SSL setup](https://devcenter.heroku.com/articles/ssl-endpoint)
268 to get SSL running on your server.
269
270 You may set the `SSL_REDIRECT` environment variable to `true` to make KarmaNotes
271 redirect insecure connections to secure ones.
272
273 # Local
274
275 ## Install
276
277 KarmaNotes is a Heroku application. Download the [Heroku toolbelt](https://toolbelt.heroku.com/).
278
279 Before your running it for the first time, there are
280 a few setup steps:
281   1. `virtualenv venv`
282   1. `source venv/bin/activate`
283   1. `pip install -r requirements.txt`
284   1. `pip install -r requirements-dev.txt`
285   1. `foreman run python manage.py syncdb --migrate --noinput`
286   1. `foreman run python manage.py createsuperuser`
287   1. `foreman run python manage.py fetch_usde_csv ./schools.csv`
288   1. `foreman run python manage.py import_usde_csv ./schools.csv`
289   1. `foreman run python manage.py sanitize_usde_schools`
290
291 * `fetch_usde_csv` downloads school records and stores them to `./schools.csv`. This file name
292      and location is arbitrary. As long as the same file is passed into `import_usde_csv` for
293      reading, everything should be fine.
294
295 * `fetching_usde_csv` requires `7zip` to be installed for processing compressed
296      archives. On Debian-based systems, this entails `apt-get install p7zip-full`
297
298 ## Run
299
300 Ensure environment variables are available to `foreman` by copying `.env.example`
301 to `.env` and update those variables as appropriate for your local system.
302
303 To run KarmaNotes locally, make sure you are inside your
304 virtual environment (`source venv/bin/activate`) and run `foreman start`.
305
306 `foreman` will load the `.env` file and manage running all processes in a way
307 that is similar to that of Heroku. This allows better consistency with local,
308 staging, and production deployments.
309
310 Press ctrl-C to kill foreman. Foreman will run Django's runserver command.
311 If you wish to have more control over how this is done, you can do
312 `foreman run python manage.py runserver <options>`. For running any other
313 `manage.py` commands, you should also precede them with `foreman run` like just shown.
314 This simply ensures that the environment variables from `.env` are present.
315
316 # Heroku Install
317
318 KarmaNotes is a Heroku application. Download the [Heroku toolbelt](https://toolbelt.heroku.com/).
319
320 To run KarmaNotes on Heroku, do `heroku create` and `git push heroku master` as typical
321 for a Heroku application. Set your the variable `BUILDPACK_URL` to
322 `https://github.com/FinalsClub/heroku-buildpack-karmanotes` to use a buildpack
323 designed to support KarmaNotes.
324
325 You will need to import the US Department of Education's list of accredited schools.
326    1. Fetch USDE schools with
327       `heroku run python manage.py fetch_usde_csv ./schools.csv`
328    1. Upload the schools into the database with
329       `heroku run python /manage.py import_usde_csv ./schools.csv`
330    1. Clean up redundant information with
331       `heroku run python /manage.py sanitize_usde_schools`
332
333
334 # Django Database management
335
336 ## South
337
338 We have setup Django to use
339 [south](http://south.aeracode.org/wiki/QuickStartGuide) for migrations. When
340 changing models, it is important to run
341 `foreman run python manage.py schemamigration` which will create a migration
342  to reflect the model changes into the database. These changes can be pulled
343 into the database with `foreman run python manage.py migrate`.
344
345 Sometimes the database already has a migration performed on it, but that
346 information wasn't told to south. There are subtleties to the process which
347 require looking at the south docs. As a tip, start by looking at the `--fake`
348 flag.
349
350 # Assets from Third Parties
351
352 A number of assets have been added to the repository which come from external
353 sources. It would be difficult to keep a complete list in this README and keep
354 it up to date. Software which originally came from outside parties can
355 generally be found in `karmaworld/assets`.
356
357 Additionally, all third party Python projects (downloaded and installed with
358 pip) are listed in these files:
359
360 * `requirements.txt`
361 * `requirements-dev.txt`
362
363 # Thanks
364
365 * KarmaNotes.org is a project of the FinalsClub Foundation with generous funding from the William and Flora Hewlett Foundation
366
367 * Also thanks to [rdegges](https://github.com/rdegges/django-skel) for the django-skel template