From 0855b0a9997d82b895395bfc337c87779580cd91 Mon Sep 17 00:00:00 2001 From: Richa Agarwal Date: Tue, 15 Sep 2015 23:50:14 -0700 Subject: [PATCH] Updating documentation to not depend on Scribd for document hosting --- .env.example | 3 +- Procfile | 2 +- docs/admin.md | 42 +++++++++--------- docs/redeploy.md | 41 ++++++++--------- docs/responder.md | 44 +++++++++---------- public_records_portal/ResponsePresenter.py | 10 +---- public_records_portal/__init__.py | 5 +-- public_records_portal/filters.py | 5 +-- public_records_portal/models.py | 2 +- public_records_portal/prr.py | 37 +++------------- public_records_portal/scribd_helpers.py | 12 ++--- .../templates/_response_widget.html | 23 +--------- public_records_portal/templates/admin.html | 4 +- requirements.txt | 3 +- tests.py | 11 +---- 15 files changed, 87 insertions(+), 157 deletions(-) diff --git a/.env.example b/.env.example index c5839882..3fbd246a 100644 --- a/.env.example +++ b/.env.example @@ -1,10 +1,9 @@ ENVIRONMENT=LOCAL APPLICATION_URL=http://127.0.0.1:5000/ -HOST_URL='https://www.scribd.com/doc/' DATABASE_URL=postgresql://localhost/recordtrac AGENCY_NAME='Your agency name' SECRET_KEY='change this before deploying to production' DEFAULT_OWNER_EMAIL=citystaff@city.gov DEFAULT_OWNER_REASON='Open records coordinator' DAYS_TO_FULFILL=10 -DAYS_AFTER_EXTENSION=14 \ No newline at end of file +DAYS_AFTER_EXTENSION=14 diff --git a/Procfile b/Procfile index 8099c0f3..ba597f26 100644 --- a/Procfile +++ b/Procfile @@ -1 +1 @@ -web: newrelic-admin run-program gunicorn -w 3 -t 360 public_records_portal.prflask:app \ No newline at end of file +web: gunicorn -w 3 -t 360 public_records_portal.prflask:app diff --git a/docs/admin.md b/docs/admin.md index 62d945fe..f77b449e 100644 --- a/docs/admin.md +++ b/docs/admin.md @@ -1,6 +1,6 @@ # RecordTrac's Admin Features -## Description +## Description RecordTrac’s administrative controls allows the users to: @@ -10,35 +10,33 @@ RecordTrac’s administrative controls allows the users to: * [Edit or remove a question or answer](#how-to-remove-or-edit-a-question-and-answer-exchange) * [Update your RecordTrac website text and more](#updating-website-text) -The administrative controls allows the user to permanently delete records, requests, and notes from the database. Because of this, administrative access should be restricted to a small number of users. +The administrative controls allows the user to permanently delete records, requests, and notes from the database. Because of this, administrative access should be restricted to a small number of users. ## Best Practices Content should only be removed or edited if sensitive or confidential information is revealed. If this happens, you should: -* Edit the message to indicate why it needs to be removed. +* Edit the message to indicate why it needs to be removed. * Notify the requester why their post or answer was removed. -* Provide guidance to the requester on how they can get the record they need. +* Provide guidance to the requester on how they can get the record they need. -If a staff member enters information incorrectly, simply add a note explaining the mistake. +If a staff member enters information incorrectly, simply add a note explaining the mistake. -If a member of the public enters incorrect information, the requester (or a staff member) can add a note correcting the mistake. +If a member of the public enters incorrect information, the requester (or a staff member) can add a note correcting the mistake. Sometimes it’s necessary to create a new request. If a new request must be created, we suggest you do the following: * Create a new request with the proper information. * In the old request, include a note explaining what is wrong with it and a link to the new request. * Close out the old request. -* In the new request, reference and/or provide a link to the old request. +* In the new request, reference and/or provide a link to the old request. -Although RecordTrac has a spam filter, every once in a while it may receive spam. When confronted with spam, close the request with a note indicating why it is not a public records request. If there is a large amount of spam requests, it is appropriate to simply remove the spam. - -If a record needs to be removed. It not only has to be deleted on RecordTrac, it has to be removed from Scribd as well. +Although RecordTrac has a spam filter, every once in a while it may receive spam. When confronted with spam, close the request with a note indicating why it is not a public records request. If there is a large amount of spam requests, it is appropriate to simply remove the spam. ## How to Remove or Edit a Request -To remove or edit a request, visit `[records.youragency.gov]/admin/requestview`. +To remove or edit a request, visit `[records.youragency.gov]/admin/requestview`. ![admin_edit_request](/docs/images/admin_request.png "admin_edit_request") @@ -53,7 +51,7 @@ Clicking on the trashcan icon permanently deletes an entire request. ![admin_delete_request](/docs/images/admin_delete_request.png "admin_delete_request") -Clicking on the pencil icon will allow you to edit a request. +Clicking on the pencil icon will allow you to edit a request. ![admin_edit_request](/docs/images/admin_edit_request.png "admin_edit_request") @@ -63,17 +61,17 @@ To remove a record, visit `[records.youragency.gov]/admin/recordreview`. ![admin_remove_record](/docs/images/admin_record.png "admin_remove_record") -You can only remove a record, not "edit" any of the fields. Records include web links, uploaded electronic documents, and instructions on how to view or pick up copies of a record. +You can only remove a record, not "edit" any of the fields. Records include web links, uploaded electronic documents, and instructions on how to view or pick up copies of a record. A description of the fields in the table displayed can be found below: * ID: Unique ID assigned to each request. -* Filename: Name of electronic record uploaded to RecordTrac. +* Filename: Name of electronic record uploaded to RecordTrac. * URL: Web address provided to requester. -* Download URL: Web address where you can automatically download the record. +* Download URL: Web address where you can automatically download the record. * Access: Instructions on how to view or pick up copies of a record -Click on the trashcan icon to permanently delete the record from RecordTrac. You must also delete the record from the hosted location. For example, if you are using Scribd, it must be deleted from the Scribd account. +Click on the trashcan icon to permanently delete the record from RecordTrac. You must also delete the record from the hosted location. ![admin_delete_record](/docs/images/admin_delete_record.png "admin_delete_record") @@ -87,9 +85,9 @@ A description of the fields in the table displayed can be found below: * ID: Unique ID assigned to each request. * Text: Entire text of the note. -* Date Created: The date the note was created. +* Date Created: The date the note was created. -Click on the trashcan icon to permanently delete the note from RecordTrac. +Click on the trashcan icon to permanently delete the note from RecordTrac. ![admin_delete_note](/docs/images/admin_delete_note.png "admin_delete_note") @@ -107,14 +105,14 @@ A description of the fields in the table displayed can be found below: * ID: Unique ID assigned to each request. * Question: Entire text of the question asked by agency staff. -* Answer: Entire response of question provided by member of the public. +* Answer: Entire response of question provided by member of the public. * Date Created: The date the exchange was created Clicking on the trashcan icon permanently deletes the entire question and answer exchange. ![admin_delete_qa](/docs/images/admin_delete_qa.png "admin_delete_qa") -Clicking on the pencil icon will allow you to edit the text of the question and answer exchange. +Clicking on the pencil icon will allow you to edit the text of the question and answer exchange. ![admin_edit_qa](/docs/images/admin_edit_qa.png "admin_edit_qa") @@ -137,7 +135,7 @@ There is a quick way for adminstrators to check on the status of the application If the status is 'ok,' it means the app is working properly and users should not encounter any problems. -The number next to SendGrid is the percentage of its email quota the application has used this month. If it is close to 100, then the agency is close to hitting its email quotas for the month and may be charged for each additional email. +The number next to SendGrid is the percentage of its email quota the application has used this month. If it is close to 100, then the agency is close to hitting its email quotas for the month and may be charged for each additional email. -The dependencies section lists additional web applications used by RecordTrac. Askismet is the spam filter. Scribd is where all uploaded documents are hosted. SendGrid sends out the email notifications and Postgres is where all of the data is stored. +The dependencies section lists additional web applications used by RecordTrac. Askismet is the spam filter. SendGrid sends out the email notifications and Postgres is where all of the data is stored. diff --git a/docs/redeploy.md b/docs/redeploy.md index cf1511b8..e94d37fc 100644 --- a/docs/redeploy.md +++ b/docs/redeploy.md @@ -1,26 +1,26 @@ -#How to create a new RecordTrac app for your agency +#How to create a new RecordTrac app for your agency ## Groundwork -To redeploy RecordTrac, you need support from key stakeholders _within_ government. The administrator or elected official in charge of overseeing public records request must agree to use this system, and instruct their colleagues to do so. +To redeploy RecordTrac, you need support from key stakeholders _within_ government. The administrator or elected official in charge of overseeing public records request must agree to use this system, and instruct their colleagues to do so. -RecordTrac assumes there is a contact for a given municipality or department within the municipality to handle public records requests. If a government agency has no process at all in place, but is interested in using the system, they could start with one ‘champion’ that is knowledgeable about who has access to different records. The champion can then route requests to the proper parties within government who may have the documents or information a requester needs. +RecordTrac assumes there is a contact for a given municipality or department within the municipality to handle public records requests. If a government agency has no process at all in place, but is interested in using the system, they could start with one ‘champion’ that is knowledgeable about who has access to different records. The champion can then route requests to the proper parties within government who may have the documents or information a requester needs. ## Best Practices RecordTrac is flexible and could complement almost any governmental agency's process for fulfilling records requests. There are however, best practices a governmental agency should adopt to really leverage the power of RecordTrac. Here is a good starting set: -* Track all public records requests through RecordTrac, even if you originally received it over the phone, by email, fax, or mail. +* Track all public records requests through RecordTrac, even if you originally received it over the phone, by email, fax, or mail. * Don't reveal sensitive information in your message or upload documents that haven't been thoroughly redacted. Everything you do on the site is immediately viewable to the public. * Upload scanned copies of the [redacted] records to RecordTrac. This prevents you from answering the same public records request multiple times. It provides proof you responded to the request. -* Communicate with everyone through RecordTrac. (Only take conversations offline if it involves confidential or sensitive information.) +* Communicate with everyone through RecordTrac. (Only take conversations offline if it involves confidential or sensitive information.) * Make your messages or the documents you upload understood by everyone--not just the requester. You can do this by doing the following: * Explain all acronyms used. - * Give each uploaded document a unique name. - * If you have to enter a request on behalf of a member of the public, describe the request and/or include a copy of it in your response. + * Give each uploaded document a unique name. + * If you have to enter a request on behalf of a member of the public, describe the request and/or include a copy of it in your response. * Review requests no later than two business days after you receive them. @@ -37,7 +37,7 @@ After the initial deployment, RecordTrac will need ongoing maintenance. This can * Python development * Front end development (HTML, CSS, JavaScript) -Using the recommended deployment instructions below, the hosting and third-party services should total about $100 per month. Maintenance service costs are in addition to the hosting costs, and may depend on location and skill. +Using the recommended deployment instructions below, the hosting and third-party services should total about $100 per month. Maintenance service costs are in addition to the hosting costs, and may depend on location and skill. If you have problems using RecordTrac, please [open an issue on GitHub](https://github.com/codeforamerica/recordtrac/issues) and let us know what problems or difficulties you encountered in as much detail as you can. @@ -73,7 +73,7 @@ Create the postgres database: Access the Heroku command line: $ heroku run bash - + Create the database tables: $ python db_setup.py @@ -82,11 +82,11 @@ Technically, that is all you need to get an instance of RecordTrac running with #### Set basic environment variables -* **Agency name**: +* **Agency name**: Set `AGENCY_NAME` to the name of your agency, which is used across the site (ex. "City of Oakland"). -* **Agency logos**: -`LOGO_ON_WHITE_URL`, `LOGO_ON_BLACK_URL` are used across the site but appear blank if none are supplied. The "LOGO_ON_WHITE" is used for general in-page representation, primarily the landing page. The "LOGO_ON_BLACK" is used for the navbar. We recommend using an image with a transparent background. While these logos are not technically required, it is strongly encouraged as they help communicate this application is an official agency website. Here's an example image of [LOGO_ON_WHITE](/public_records_portal/static/examples/logo.png "LOGO_ON_WHITE") and [LOGO_ON_BLACK](/public_records_portal/static/examples/logo_black.png "LOGO_ON_BLACK"). +* **Agency logos**: +`LOGO_ON_WHITE_URL`, `LOGO_ON_BLACK_URL` are used across the site but appear blank if none are supplied. The "LOGO_ON_WHITE" is used for general in-page representation, primarily the landing page. The "LOGO_ON_BLACK" is used for the navbar. We recommend using an image with a transparent background. While these logos are not technically required, it is strongly encouraged as they help communicate this application is an official agency website. Here's an example image of [LOGO_ON_WHITE](/public_records_portal/static/examples/logo.png "LOGO_ON_WHITE") and [LOGO_ON_BLACK](/public_records_portal/static/examples/logo_black.png "LOGO_ON_BLACK"). * **Default point of contact**: `DEFAULT_OWNER_EMAIL` will be the person that gets contacted about new requests if a department is not selected by the requester, or if no liaisons information is supplied to the application. It is a required field. @@ -98,7 +98,7 @@ Set `AGENCY_NAME` to the name of your agency, which is used across the site (ex. The `APPLICATION_URL` specifies where you will host RecordTrac on, e.g. `records.youragency.gov`. It is used in e-mail communication and to generate links automatically, so it must be accurate. This can also be the Heroku provided URL to start. It is a required field. * **Environment**: -The `ENVIRONMENT` field must be set to `PRODUCTION` once the application is ready to go live. This will enable e-mail notifications, spam filters, and document uploads to Scribd. +The `ENVIRONMENT` field must be set to `PRODUCTION` once the application is ready to go live. This will enable e-mail notifications and spam filters. #### Set up additional services @@ -109,7 +109,8 @@ Set up [Recaptcha](http://www.google.com/recaptcha/intro/) and [Akismet](http:// Sign up for an account with [SendGrid](https://sendgrid.com/user/signup). Set `DEFAULT_MAIL_SENDER` to the e-mail address that you would like to show up in the 'To' field (e.g. `records-donotreply@agency.gov`), set `MAIL_USERNAME` to the SendGrid username you choose, and `MAIL_PASSWORD` to the SendGrid password. We assume your monthly email limit is 40,000 sends (Sendgrid's Bronze account level), but you can change this by setting the `SENDGRID_MONTHLY_LIMIT`. * **Document hosting**: -By default, `HOST_URL` is set to point to Scribd, but if you decide to host documents internally, you would update this field. If using Scribd, you will need to set `SCRIBD_API_KEY` and `SCRIBD_API_SECRET` after setting up a [Scribd developer account](http://www.scribd.com/developers). +In the past, RecordTrac was set up to use the Scribd API for hosting documents, but Scribd no longer offers new API accounts. Currently, RecordTrac offers no service for hosting documents, although you can still find the Scribd functions in the codebase for reference. We recommend that an agency be set up to host documents independently of RecordTrac, and provide a URL to the document instead. + #### Connect your agency's staff data * **Users**: @@ -125,7 +126,7 @@ In order for RecordTrac to route a request to the appropriate contact, a list of Once the environment variables are set in Heroku, run `python db_users.py` from the Heroku command line to populate the database with this information. If you do not wish to connect your staff data at this time, you can still run `python db_users.py` and it will create a user with the provided `DEFAULT_OWNER_EMAIL` and `DEFAULT_OWNER_REASON`. -### Additional Setup +### Additional Setup Here is additional functionality that is not *required* for a functional instance of RecordTrac, but may be useful. @@ -134,7 +135,7 @@ To schedule tasks, use Heroku add-ons to add a scheduler. To keep staff data up to date, we recommend maintaining the CSVs (outside of the RecordTrac application), which the application will simply pull from. The task that pulls data from the CSVs to RecordTrac is `python db_users.py`, and can be set as frequently as you'd like. To send e-mail notifications to staff for when a request is due soon or overdue, set up a task `python send_notifications.py` that runs nightly. * **Admin list**: -This will enable access to the admin panel of the application. Set `LIST_OF_ADMINS` with a comma separated list of e-mail addresses, e.g. `person1@agency.gov,person2@agency.gov`. +This will enable access to the admin panel of the application. Set `LIST_OF_ADMINS` with a comma separated list of e-mail addresses, e.g. `person1@agency.gov,person2@agency.gov`. * **Extensions**: By default, RecordTrac allows agency staff to extend the request's due date. If your agency does not allow extensions, they must be manually disabled by removing the relevant code in `_response_widget.html` and `manage_request_city.html`. @@ -146,7 +147,7 @@ You can update these variables to reflect your agency's policy. By default, the The Flask application requires a `SECRET_KEY` to be set - though a not-so-secret one is provided by default, you can randomly generate a key [here](randomkeygen.com). * **Feedback form**: -You can hook the application up to a Google feedback form by setting the `GOOGLE_FEEDBACK_FORM_ID` to the form ID corresponding to a Google spreadsheet. +You can hook the application up to a Google feedback form by setting the `GOOGLE_FEEDBACK_FORM_ID` to the form ID corresponding to a Google spreadsheet. A complete list of environment variables used in the application can be found in `/public_records_portal/__init__.py`. These must be configured in Heroku either via the command line (See examples [here](https://devcenter.heroku.com/articles/config-vars)) or their web interface in `dashboard.heroku.com/apps/[yourappname]/settings` @@ -154,14 +155,14 @@ Add an additional [web dyno](https://www.heroku.com/pricing) so that the app is ### Updating website copy -The installation uses a generic set of defaults for email and website copy. To change these to better reflect your agency's laws and policies, update the copy through the .json files or HTML templates must be modified. +The installation uses a generic set of defaults for email and website copy. To change these to better reflect your agency's laws and policies, update the copy through the .json files or HTML templates must be modified. Most of the copy for RecordTrac can be found in the following .json files: -* **Actions.json**: These describe the actions a member of the public can take to submit a request, as well as the actions to be taken by a agency employee. The text from this file is used for the website's copy. It tells users what will happen when they use a particular feature and who will be able to view the messages or documents uploaded. +* **Actions.json**: These describe the actions a member of the public can take to submit a request, as well as the actions to be taken by a agency employee. The text from this file is used for the website's copy. It tells users what will happen when they use a particular feature and who will be able to view the messages or documents uploaded. * **Emails.json**: This houses the subject lines for the email notifications that RecordTrac sends out. -All of the HTML files are stored in the `/public_records_portal/templates` folder. The names of the files are mostly self-explanatory. For example to edit the About page at http://records.oaklandnet.com/about, you must modify the 'about.html' file. +All of the HTML files are stored in the `/public_records_portal/templates` folder. The names of the files are mostly self-explanatory. For example to edit the About page at http://records.oaklandnet.com/about, you must modify the 'about.html' file. ### Updating public URL diff --git a/docs/responder.md b/docs/responder.md index 572095f7..9abc5527 100644 --- a/docs/responder.md +++ b/docs/responder.md @@ -1,8 +1,8 @@ -# How to use RecordTrac as an agency employee +# How to use RecordTrac as an agency employee ## Search for a record -RecordTrac displays all current and past records requests at `records.[youragency].gov/requests`. +RecordTrac displays all current and past records requests at `records.[youragency].gov/requests`. ![staff_table](/docs/images/staff_table.png "staff_table") @@ -11,12 +11,12 @@ The table displays the following information: * '#': Each request is assigned a unique number. You can easily track requests with this number by visiting `records.[youragency].gov/track]`. * Received: This shows the date the request was received. If a request wasn't originally submitted through RecordTrac, it may take agency employees a day or two to enter it into the system. * Request: This is the message sent to the agency by a member of the public. Sometimes agnecy employees will enter a request on behalf of an individual. If the requested document contains confidential information that may violate the security or privacy of a requester, the public will only see a short description of the document. -* Department: The agency department where the point of contact works. Multiple departments may be involved in one request, but the Point of Contact's department will only be displayed. -* Point of Contact: The 'Point of Contact' is the employee responsible for providing the requester with the information they need. Sometimes agency employees from several departments will be needed to respond to one public records request. They will be added as Helpers, but they will not be displayed on this particular web page. +* Department: The agency department where the point of contact works. Multiple departments may be involved in one request, but the Point of Contact's department will only be displayed. +* Point of Contact: The 'Point of Contact' is the employee responsible for providing the requester with the information they need. Sometimes agency employees from several departments will be needed to respond to one public records request. They will be added as Helpers, but they will not be displayed on this particular web page. *☟ NOTE: Requesters are not able to search by or view the following two columns. ☟* -* Due: This shows the date the request is due. The date is calculated from an admin-configured response time. +* Due: This shows the date the request is due. The date is calculated from an admin-configured response time. * Requester: The requester's name, if provided by the requester. If no name was provided, it will display as "N/A". ### Manage your request list @@ -46,19 +46,19 @@ Agency staff can also sort the requests by: * Request number (#) * Date the request was received -* Request text +* Request text * Due date ## Make a new request -Agency staff can create a request on behalf of a requester. +Agency staff can create a request on behalf of a requester. ![staff_new_request](/docs/images/staff_new_request.png "staff_new_request") -* Some contact information is optional, although we strongly encourage the requester to provide an email address as this is the only way they can receive status updates on their request. +* Some contact information is optional, although we strongly encourage the requester to provide an email address as this is the only way they can receive status updates on their request. * There is no limit to the amount of text a requester can put in the request field. -* Requesters are able to enter the department they want the request sent to or the type of document they need. -* The department or document type field is used to select which person initially receives the request. -* If a department is not selected, the request is automatically routed to an agency employee who will route it for the requester. +* Requesters are able to enter the department they want the request sent to or the type of document they need. +* The department or document type field is used to select which person initially receives the request. +* If a department is not selected, the request is automatically routed to an agency employee who will route it for the requester. ### Responder-specific fields @@ -84,7 +84,7 @@ An agency employee can send the request to another individual in the official di ![add_helper](/docs/images/add_helper.png "add_helper") -Sometimes more than one person is needed to fulfill a request or it involves multiple departments. Click on 'Helpers' to notify additional staff of this request. The staff member will be alerted via email that they are expected to respond to this request. The helpers will be able to add documents and send messages to the requester via RecordTrac. +Sometimes more than one person is needed to fulfill a request or it involves multiple departments. Click on 'Helpers' to notify additional staff of this request. The staff member will be alerted via email that they are expected to respond to this request. The helpers will be able to add documents and send messages to the requester via RecordTrac. ### Ask a Question @@ -98,10 +98,8 @@ An agency employee can ask questions about this particular records request. The Documents stored on a computer can be uploaded. The requester will be notified via email every time a record is uploaded. The documents will be posted online for everyone to view. -You must name every record you upload. +You must name every record you upload. -Records are displayed online via Scribd. Supported file types are the following: -'txt', 'pdf', 'doc', 'ps', 'rtf', 'epub', 'key', 'odt', 'odp', 'ods', 'odg', 'odf', 'sxw', 'sxc', 'sxi', 'sxd', 'ppt', 'pps', 'xls', 'zip', 'docx', 'pptx', 'ppsx', 'xlsx', 'tif', 'tiff' ### Add a Link to Another Website @@ -109,7 +107,7 @@ Records are displayed online via Scribd. Supported file types are the following: An agency employee can respond to a request by providing a link to where the document or information is stored online. The requester will be notified via email about this link. This web address will be posted online for everyone to view. -You must name each link you post. +You must name each link you post. ### Add An Offline Record @@ -118,7 +116,7 @@ You must name each link you post. Some records cannot be uploaded to the website and requesters will have to be told when and where to pick up copies of it. The requester will be notified via email about this message. This message will be posted online for everyone to view. -You must provide a name for the instructions you post. +You must provide a name for the instructions you post. Below is an example of a posted message: @@ -141,13 +139,13 @@ Notify a requester if additional time is needed to fulfill their public records ![close_request](/docs/images/close_request.png "close_request") -To close out a request, staff can edit a message already provided to them. An email is then sent to the requester notifying them the request is closed. The status of the request will also change. +To close out a request, staff can edit a message already provided to them. An email is then sent to the requester notifying them the request is closed. The status of the request will also change. Example list of reasons a request can be closed. These may vary between agencies: * Fulfilled: "We released all of the requested documents." * Fulfilled - Private Documents Not Uploaded: "We cannot upload your document online. The records contains sensitive information only you can view." -* Fulfilled - Information Redacted: "We released all of the requested documents. Personal information, such as home addresses, telephone numbers, and credit card numbers, were removed from the documents to protect the privacy or identity of another individual. +* Fulfilled - Information Redacted: "We released all of the requested documents. Personal information, such as home addresses, telephone numbers, and credit card numbers, were removed from the documents to protect the privacy or identity of another individual. * Not a public records request: "This is not a public records request. For more general information please contact..." * Record Does Not Exist: "The record you asked for does not exist." * Contact another agency: "We don't have the records you requested. We suggest you submit a public records request to..." @@ -168,13 +166,13 @@ Allows you to re-open a request after it is closed. This makes it possible for y ![responses](/docs/images/responses.png "responses") -All responses are displayed in chronological order. Each response includes the time it was uploaded and who uploaded the document or sent the message. +All responses are displayed in chronological order. Each response includes the time it was uploaded and who uploaded the document or sent the message. #### What is Unique to the Agency View -There are two views in RecordTrac: the agency employee view and the public view. +There are two views in RecordTrac: the agency employee view and the public view. -Agency employees are the only users able to upload records, extend a request, close a request, and correspond with the requester through RecordTrac. +Agency employees are the only users able to upload records, extend a request, close a request, and correspond with the requester through RecordTrac. Only agency employees can view: @@ -196,7 +194,7 @@ The Point of Contact and Helpers for a request recieve an email notification whe ### Tutorial RecordTrac's tutorial shows agency employees how to successfully manage a public records request with RecordTrac. The tutorial was created to quickly on-board new employees who are responsible for fulfilling public records requests. Only agency staff who are logged into RecordTrac are able to view the tutorial. -You can view the tutorial by going to `records.[youragency].gov/tutorial`. +You can view the tutorial by going to `records.[youragency].gov/tutorial`. ## [Admin](/docs/admin.md) diff --git a/public_records_portal/ResponsePresenter.py b/public_records_portal/ResponsePresenter.py index cfd1a3aa..eb56a7ef 100644 --- a/public_records_portal/ResponsePresenter.py +++ b/public_records_portal/ResponsePresenter.py @@ -9,7 +9,6 @@ from models import Record, Note -import scribd_helpers class ResponsePresenter: def __init__(self, record = None, note = None): @@ -39,7 +38,7 @@ def __init__(self, record = None, note = None): elif self.type=="extension": self.icon = "icon-calendar icon-large" - + def get_update_url(self): return self.update_url @@ -66,14 +65,9 @@ def display_text(self): return "Name of Record: %s
How to Access Record: %s" %(self.response.description, self.response.access) elif self.type == "document": download_url = self.response.download_url - if not download_url: - download_url = scribd_helpers.get_scribd_download_url(doc_id = self.response.doc_id, record_id = self.response.id) - if not download_url: - download_url = "This document is still being uploaded, but it will be available shortly." return """ %(description)s - - """ %{"download_url": download_url, "description": self.response.description, "scribd_url": self.response.url} + """ %{"download_url": download_url, "description": self.response.description} elif self.type == "note": return self.response.text elif self.type == "link": diff --git a/public_records_portal/__init__.py b/public_records_portal/__init__.py index fe881232..17160e32 100644 --- a/public_records_portal/__init__.py +++ b/public_records_portal/__init__.py @@ -38,7 +38,6 @@ def set_bool_env(key, default = None): set_env(key = 'DEFAULT_OWNER_EMAIL', default = 'recordtrac@codeforamerica.org') set_env(key = 'DEFAULT_OWNER_REASON', default = 'Open government coordinator' ) -set_env(key = 'HOST_URL', default = 'https://www.scribd.com/doc/') # Where the documents/record uploads are hosted set_env(key = 'AGENCY_NAME', default = 'Your agency name') # e.g. City of Oakland set_env(key = 'SECRET_KEY', default = 'Change this to something super secret') # Flask application's secret key @@ -58,8 +57,6 @@ def set_bool_env(key, default = None): 'SENDGRID_MONTHLY_LIMIT', # Your SendGrid Monthly Limit 'LIST_OF_ADMINS', # Defines who has admin access (/admin) with a comma delimited list of e-mail addresses. i.e. 'richa@codeforamerica.org,cris@codeforamerica.org' 'SECRET_KEY', # Flask app secret key - 'SCRIBD_API_KEY', - 'SCRIBD_API_SECRET', 'AKISMET_KEY', # Used for spam filtering 'RECAPTCHA_PUBLIC_KEY', 'RECAPTCHA_PRIVATE_KEY', @@ -71,7 +68,7 @@ def set_bool_env(key, default = None): 'LOGO_ON_WHITE_URL', # The path/URL at which a logo (on a white background) of the agency is hosted. (.png or .jpg) 'LOGO_ON_BLACK_URL', # The path/URL at which a logo (on a black background) of the agency is hosted. (.png or .jpg) 'TESTING', # Set if you are running tests. Primarily used to ignore @login_requireds when running tests. - 'SHOULD_UPLOAD' # Set if you want to test uploading documents to the specified host (currently Scribd) + 'SHOULD_UPLOAD' # Set if you want to test uploading documents to the specified host ] for envvar in envvars: set_env(key = envvar) diff --git a/public_records_portal/filters.py b/public_records_portal/filters.py index 66999f24..dbeb1ced 100644 --- a/public_records_portal/filters.py +++ b/public_records_portal/filters.py @@ -7,10 +7,9 @@ """ -from public_records_portal import app, gravatar, prr, notifications, helpers, scribd_helpers, db_helpers +from public_records_portal import app, gravatar, prr, notifications, helpers, db_helpers # Register your filter here! -app.jinja_env.filters['get_scribd_download_url'] = scribd_helpers.get_scribd_download_url app.jinja_env.filters['due_date'] = notifications.due_date app.jinja_env.filters['get_obj'] = db_helpers.get_obj app.jinja_env.filters['get_objs'] = db_helpers.get_objs @@ -25,4 +24,4 @@ app.jinja_env.filters['tutorial'] = helpers.tutorial app.jinja_env.filters['new_lines'] = helpers.new_lines app.jinja_env.filters['display_staff_participant'] = helpers.display_staff_participant -app.jinja_env.filters['timestamp'] = helpers.timestamp \ No newline at end of file +app.jinja_env.filters['timestamp'] = helpers.timestamp diff --git a/public_records_portal/models.py b/public_records_portal/models.py index ffcf147f..14a3d5c6 100644 --- a/public_records_portal/models.py +++ b/public_records_portal/models.py @@ -314,7 +314,7 @@ class Record(db.Model): id = db.Column(db.Integer, primary_key = True) date_created = db.Column(db.DateTime) user_id = db.Column(db.Integer, db.ForeignKey('user.id')) # The user who uploaded the record, right now only city staff can - doc_id = db.Column(db.Integer) # The document ID. Currently using Scribd API to upload documents. + doc_id = db.Column(db.Integer) # The document ID, if document hosting has been integrated. request_id = db.Column(db.Integer, db.ForeignKey('request.id')) # The request this record was uploaded for description = db.Column(db.String(400)) # A short description of what the record is. filename = db.Column(db.String(400)) # The original name of the file being uploaded. diff --git a/public_records_portal/prr.py b/public_records_portal/prr.py index 318293e3..c0ec21a0 100644 --- a/public_records_portal/prr.py +++ b/public_records_portal/prr.py @@ -16,7 +16,6 @@ from ResponsePresenter import ResponsePresenter from RequestPresenter import RequestPresenter from notifications import generate_prr_emails -import scribd_helpers from spam import is_spam import logging import csv @@ -38,13 +37,13 @@ def add_resource(resource, request_body, current_user_id = None): return add_offline_record(int(fields['request_id']), fields['record_description'], fields['record_access'], current_user_id) elif 'link_url' in fields and fields['link_url'] != "": return add_link(request_id = int(fields['request_id']), url = fields['link_url'], description = fields['record_description'], user_id = current_user_id) - else: - document = None - try: - document = request.files['record'] - except: - app.logger.info("\n\nNo file passed in") - return upload_record(request_id = int(fields['request_id']), document = document, description = fields['record_description'], user_id = current_user_id) + # else: + # document = None + # try: + # document = request.files['record'] + # except: + # app.logger.info("\n\nNo file passed in") + # return upload_record(request_id = int(fields['request_id']), document = document, description = fields['record_description'], user_id = current_user_id) elif "qa" in resource: return ask_a_question(request_id = int(fields['request_id']), user_id = current_user_id, question = fields['question_text']) elif "owner" in resource: @@ -73,13 +72,10 @@ def update_resource(resource, request_body): update_obj(attribute = "text", val = fields['request_text'], obj_type = "Request", obj_id = fields['request_id']) elif "note_text" in resource: update_obj(attribute = "text", val = fields['note_text'], obj_type = "Note", obj_id = fields['response_id']) - # Need to store note text somewhere else (or just do delete here as well) elif "note_delete" in resource: - # Need to store note somewhere else remove_obj("Note", int(fields['response_id'])) elif "record_delete" in resource: remove_obj("Record", int(fields['record_id'])) - # Need to store record somewhere else and prompt them to delete from Scribd as well, if they'd like else: return False @@ -109,25 +105,6 @@ def add_note(request_id, text, user_id = None, passed_spam_filter = False): return False - -### @export "upload_record" -def upload_record(request_id, description, user_id, document = None): - """ Creates a record with upload/download attributes """ - try: - doc_id, filename = scribd_helpers.upload_file(document = document, request_id = request_id) - except: - return "The upload timed out, please try again." - if doc_id == False: - return "Extension type '%s' is not allowed." % filename - else: - if str(doc_id).isdigit(): - record_id = create_record(doc_id = doc_id, request_id = request_id, user_id = user_id, description = description, filename = filename, url = app.config['HOST_URL'] + doc_id) - change_request_status(request_id, "A response has been added.") - generate_prr_emails(request_id = request_id, notification_type = "City response added") - add_staff_participant(request_id = request_id, user_id = user_id) - return record_id - return "There was an issue with your upload." - ### @export "add_offline_record" def add_offline_record(request_id, description, access, user_id): """ Creates a record with offline attributes """ diff --git a/public_records_portal/scribd_helpers.py b/public_records_portal/scribd_helpers.py index fc4a92d5..10400d3e 100644 --- a/public_records_portal/scribd_helpers.py +++ b/public_records_portal/scribd_helpers.py @@ -40,9 +40,9 @@ def upload(document, filename, API_KEY, API_SECRET, description): name = filename, progress_callback=progress, req_buffer = tempfile.TemporaryFile() - ) - doc.description = description - doc.save() + ) + doc.description = description + doc.save() doc_id = doc.id return doc_id except scribd.ResponseError, err: @@ -68,7 +68,7 @@ def get_scribd_download_url(doc_id, record_id = None): def set_scribd_download_url(download_url, record_id): update_obj('download_url', download_url, obj_type = 'Record', obj_id = record_id) -def scribd_batch_download(): +def scribd_batch_download(): req = Request.query.all() for record in req.records: if record.download_url: @@ -101,7 +101,7 @@ def update_descriptions(API_KEY, API_SECRET): @timeout(seconds=20) -def upload_file(document, request_id): +def upload_file(document, request_id): # Uploads file to scribd.com and returns doc ID. File can be accessed at scribd.com/doc/id if not should_upload(): return '1', None # Don't need to do real uploads locally @@ -119,4 +119,4 @@ def upload_file(document, request_id): ### @export "allowed_file" def allowed_file(filename): ext = filename.rsplit('.', 1)[1] - return ext in ALLOWED_EXTENSIONS, ext \ No newline at end of file + return ext in ALLOWED_EXTENSIONS, ext diff --git a/public_records_portal/templates/_response_widget.html b/public_records_portal/templates/_response_widget.html index f7e039c9..2806b678 100644 --- a/public_records_portal/templates/_response_widget.html +++ b/public_records_portal/templates/_response_widget.html @@ -47,28 +47,7 @@
- -
-
-
-
-
- - -
- - Select file - Change - - - Remove -
-
-
-
-
-
- +
diff --git a/public_records_portal/templates/admin.html b/public_records_portal/templates/admin.html index f6d85b4a..179d04e1 100644 --- a/public_records_portal/templates/admin.html +++ b/public_records_portal/templates/admin.html @@ -48,6 +48,4 @@
Best Practices to Consider

Although RecordTrac has a spam filter, every once in a while it may receive spam. When confronted with spam, close the request with a note indicating why it is not a public records request. If there is a large amount of spam requests, it is appropriate to simply remove the spam.

-

If a record needs to be removed. It not only has to be deleted on RecordTrac, it has to be removed from Scribd as well.

- -{% endblock %} \ No newline at end of file +{% endblock %} diff --git a/requirements.txt b/requirements.txt index 1fb90e5e..979c6976 100644 --- a/requirements.txt +++ b/requirements.txt @@ -7,7 +7,6 @@ Jinja2==2.6 SQLAlchemy==0.9.3 Werkzeug==0.8.3 psycopg2==2.4.6 -https://python-scribd.googlecode.com/files/python-scribd-1.2.0.zip sendgrid==0.1.3 gunicorn==0.17.4 requests==1.1.0 @@ -19,4 +18,4 @@ pytz==2012d anyjson newrelic git+https://github.com/garbados/flask-browserid.git -validate-email==1.2 \ No newline at end of file +validate-email==1.2 diff --git a/tests.py b/tests.py index 9ddb6a63..6d1489c0 100644 --- a/tests.py +++ b/tests.py @@ -62,15 +62,6 @@ def test_public_add_note(self): assert note_text in page.data # Tests for adding a record: - # --- - - # This doesn't test Scribd, but tests the rest of the workflow: - def test_upload_record(self): - request_id = self.submit_request(text=self.random_content('request'), email = 'richa@richa.com') - record_description = self.random_content('record') - fields = dict(request_id = request_id, record_description = record_description) - page = self.submit_generic(fields = fields, endpoint = "add_a_record") - assert record_description in page.data def test_add_note(self): request_id = self.submit_request(text=self.random_content('request'), email = 'richa@richa.com') @@ -150,4 +141,4 @@ def submit_generic(self, fields, endpoint = ""): return self.app.post('/%s' % (endpoint), data = fields, follow_redirects= True) if __name__ == '__main__': - unittest.main() \ No newline at end of file + unittest.main()