Skip to content

Commit

Permalink
Merge pull request #1120 from dakotabenjamin/master
Browse files Browse the repository at this point in the history
Fix for previous db issues, adds new relic, other changes in again
  • Loading branch information
dakotabenjamin committed Jun 15, 2018
2 parents a2bb60b + e7393ed commit 6a36389
Show file tree
Hide file tree
Showing 13 changed files with 99 additions and 8 deletions.
12 changes: 12 additions & 0 deletions .ebextensions/aws.config
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
commands:
create_post_dir:
command: "mkdir /opt/elasticbeanstalk/hooks/appdeploy/post"
ignoreErrors: true
files:
"/opt/elasticbeanstalk/hooks/appdeploy/post/99_upgrade_db.sh":
mode: "000755"
owner: root
group: root
content: |
#!/usr/bin/env bash
docker exec $(docker ps -q) sh -c "cd /src && python3.6 manage.py db upgrade"
2 changes: 1 addition & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,4 @@ ADD . /src
EXPOSE 8000

# Gunicorn configured for single-core machine, if more cores available increase workers using formula ((cores x 2) + 1))
CMD cd /src; gunicorn -b 0.0.0.0:8000 -w 5 --timeout 179 manage:application
CMD cd /src; NEW_RELIC_CONFIG_FILE=newrelic.ini newrelic-admin run-program gunicorn -b 0.0.0.0:8000 -w 5 --timeout 179 manage:application
26 changes: 26 additions & 0 deletions ROADMAP.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# Roadmap

## Plan

### 0-2 months
* Resolve performance and scalability issues
* Conduct user testing and a design review
* Resolve feature parity between TMv2 and TMv3
* Refactor frontend to React

### 2 - 4 months
* Add groups/organizations for improved project and team management
* Add new analytics for users, projects, groups
* Add AI/ML integration for improved mapping efficiency

### 4 - 6 months
* Improved validation methods
* Data quality feedback, integrations

## Longer term ideas/directions

- Address the overlap of TM and MapCampaigner functionalities, should they be separate tools
- Improve the connection between remote and field (not just API but workflow and engagement)
- Support moving from creating data in unmapped areas to updating areas with new imagery or information

Have an idea you'd like to see on the roadmap? Or want to help contribute to a large part of the development of the roadmap? Open up a PR with your idea, or get in touch with HOT directly -- nate@hotosm.org.
2 changes: 2 additions & 0 deletions circle.yml
Original file line number Diff line number Diff line change
Expand Up @@ -55,5 +55,7 @@ jobs:
- deploy:
name: Deploy application
command: |
pip install newrelic
newrelic-admin generate-config $NEW_RELIC_LICENSE /app/newrelic.ini
chmod +x /app/devops/ci/circleci_deploy.sh
/app/devops/ci/circleci_deploy.sh
3 changes: 2 additions & 1 deletion client/app/profile/profile.controller.js
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,8 @@
emailAddress: vm.userDetails.emailAddress,
facebookId: vm.userDetails.facebookId,
linkedinId: vm.userDetails.linkedinId,
twitterId: vm.userDetails.twitterId
twitterId: vm.userDetails.twitterId,
validation_message : vm.userDetails.validation_message
};
var resultsPromise = userService.setContactDetails(contactDetails);
resultsPromise.then(function (data) {
Expand Down
13 changes: 13 additions & 0 deletions client/app/profile/profile.html
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,11 @@ <h4>OSM details</h4>
{{ 'OSM edit history' | translate }}
</a>
</p>
<p>
<a href="http://yosmhm.neis-one.org/?{{ profileCtrl.username }}" target="_blank" rel="noopener">
{{ 'OSM heat map' | translate }}
</a>
</p>
</div>
</div>
<div class="roles pull-right">
Expand Down Expand Up @@ -145,6 +150,14 @@ <h4>OSM details</h4>
title="{{ 'Your ID is the part after https://www.linkedin.com/in/....' | translate}}"
ng-model="profileCtrl.userDetails.linkedinId"/>
</li>
<li>
<label class="form__option form__option--custom-checkbox" ng-show="profileCtrl.editDetails">
<input ng-show="profileCtrl.editDetails" type="checkbox" name="form-custom-checkbox"
ng-model="profileCtrl.userDetails.validation_message"/>
<span class="form__option__text">{{ 'Receive automated validation messages' | translate }}</span>
<span class="form__option__ui"></span>
</label>
</li>
</ul>
<div ng-show="profileCtrl.userDetails.username === profileCtrl.currentlyLoggedInUser.username">
<button class="button button--achromic" type="button"
Expand Down
1 change: 1 addition & 0 deletions migrations/alembic.ini
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
# set to 'true' to run the environment during
# the 'revision' command, regardless of autogenerate
# revision_environment = false
script_location = /src/migrations

# Custom param that enables us to specify tables to ignore when determining migrations
[alembic:exclude]
Expand Down
28 changes: 28 additions & 0 deletions migrations/versions/ac55902fcc3d_.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
"""empty message
Revision ID: ac55902fcc3d
Revises: 7d55a089b5bc
Create Date: 2018-02-25 17:42:29.388863
"""
from alembic import op
import sqlalchemy as sa


# revision identifiers, used by Alembic.
revision = 'ac55902fcc3d'
down_revision = '7d55a089b5bc'
branch_labels = None
depends_on = None


def upgrade():
# ### commands auto generated by Alembic - please adjust! ###
op.add_column('users', sa.Column('validation_message', sa.Boolean(), nullable=False, server_default=sa.true()))
# ### end Alembic commands ###


def downgrade():
# ### commands auto generated by Alembic - please adjust! ###
op.drop_column('users', 'validation_message')
# ### end Alembic commands ###
1 change: 1 addition & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -42,3 +42,4 @@ transifex-client==0.12.4
urllib3==1.21.1
webencodings==0.5.1
Werkzeug==0.12.2
newrelic==3.2.0.91
4 changes: 3 additions & 1 deletion server/models/dtos/user_dto.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
from schematics import Model
from schematics.exceptions import ValidationError
from schematics.types import StringType, IntType, EmailType, LongType
from schematics.types import StringType, IntType, EmailType, LongType, BooleanType

from schematics.types.compound import ListType, ModelType, BaseType
from server.models.dtos.stats_dto import Pagination
from server.models.postgis.statuses import MappingLevel, UserRole
Expand Down Expand Up @@ -29,6 +30,7 @@ def is_known_role(value):

class UserDTO(Model):
""" DTO for User """
validation_message = BooleanType(default=True)
id = LongType()
username = StringType()
role = StringType()
Expand Down
3 changes: 3 additions & 0 deletions server/models/postgis/user.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ class User(db.Model):
__tablename__ = "users"

id = db.Column(db.BigInteger, primary_key=True, index=True)
validation_message = db.Column(db.Boolean, default=True, nullable=False)
username = db.Column(db.String, unique=True)
role = db.Column(db.Integer, default=0, nullable=False)
mapping_level = db.Column(db.Integer, default=1, nullable=False)
Expand Down Expand Up @@ -59,6 +60,7 @@ def update(self, user_dto: UserDTO):
self.twitter_id = user_dto.twitter_id.lower() if user_dto.twitter_id else None
self.facebook_id = user_dto.facebook_id.lower() if user_dto.facebook_id else None
self.linkedin_id = user_dto.linkedin_id.lower() if user_dto.linkedin_id else None
self.validation_message = user_dto.validation_message
db.session.commit()

def set_email_verified_status(self, is_verified: bool):
Expand Down Expand Up @@ -210,6 +212,7 @@ def as_dto(self, logged_in_username: str) -> UserDTO:
user_dto.twitter_id = self.twitter_id
user_dto.linkedin_id = self.linkedin_id
user_dto.facebook_id = self.facebook_id
user_dto.validation_message = self.validation_message

if self.username == logged_in_username:
# Only return email address when logged in user is looking at their own profile
Expand Down
3 changes: 1 addition & 2 deletions server/services/mapping_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,7 @@ def generate_gpx(project_id: int, task_ids_str: str, timestamp=None):
# Create trk element
trk = ET.Element('trk')
root.append(trk)
ET.SubElement(trk, 'name').text = f'Task for project {project_id}. Do not edit outside of this box!'
ET.SubElement(trk, 'name').text = f'Task for project {project_id}. Do not edit outside of this area!'

# Construct trkseg elements
if task_ids_str is not None:
Expand All @@ -180,7 +180,6 @@ def generate_gpx(project_id: int, task_ids_str: str, timestamp=None):

# Append wpt elements to end of doc
wpt = ET.Element('wpt', attrib=dict(lon=str(point[0]), lat=str(point[1])))
ET.SubElement(wpt, 'name').text = 'Do not edit outside of this colored area!'
root.append(wpt)

xml_gpx = ET.tostring(root, encoding='utf8')
Expand Down
9 changes: 6 additions & 3 deletions server/services/messaging/message_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,10 +48,13 @@ def send_message_after_validation(validated_by: int, mapped_by: int, task_id: in
if validated_by == mapped_by:
return # No need to send a thankyou to yourself

user = UserService.get_user_by_id(mapped_by)
if user.validation_message == False:
return # No need to send validation message

text_template = get_template('validation_message_en.txt')
task_link = MessageService.get_task_link(project_id, task_id)

user = UserService.get_user_by_id(mapped_by)
text_template = text_template.replace('[USERNAME]', user.username)
text_template = text_template.replace('[TASK_LINK]', task_link)

Expand Down Expand Up @@ -97,7 +100,7 @@ def send_message_after_comment(comment_from: int, comment: str, task_id: int, pr
if len(usernames) == 0:
return # Nobody @'d so return

link = MessageService.get_task_link(project_id, task_id)
task_link = MessageService.get_task_link(project_id, task_id)
project_title = ProjectService.get_project_title(project_id)
for username in usernames:

Expand All @@ -110,7 +113,7 @@ def send_message_after_comment(comment_from: int, comment: str, task_id: int, pr
message = Message()
message.from_user_id = comment_from
message.to_user_id = user.id
message.subject = f'You were mentioned in a comment in Project {project_id}, on Task {task_id}'
message.subject = f'You were mentioned in a comment in Project {project_id} on {task_link}'
message.message = comment
message.add_message()
SMTPService.send_email_alert(user.email_address, user.username)
Expand Down

0 comments on commit 6a36389

Please sign in to comment.