Skip to content

Commit

Permalink
#558 - Added basic user preferences. Next - need to add validation fo…
Browse files Browse the repository at this point in the history
…r the inputs and design the settings modal.
  • Loading branch information
aviklai committed Mar 8, 2016
1 parent 904e53e commit 7d9204e
Show file tree
Hide file tree
Showing 7 changed files with 248 additions and 22 deletions.
43 changes: 43 additions & 0 deletions alembic/versions/2438f7d83478_add_user_preferences.py
@@ -0,0 +1,43 @@
"""add user preferences
Revision ID: 2438f7d83478
Revises: 40f5c56adfee
Create Date: 2016-03-08 21:20:42.234353
"""

# revision identifiers, used by Alembic.
revision = '2438f7d83478'
down_revision = '40f5c56adfee'
branch_labels = None
depends_on = None

from alembic import op
import sqlalchemy as sa


def upgrade():
op.create_table(
'general_preferences',
sa.Column('user_id', sa.Integer, sa.ForeignKey('users.id'), primary_key=True),
sa.Column('minimum_displayed_severity', sa.Integer, nullable=True),
sa.Column('resource_type', sa.String(64), nullable=True),
)

op.create_table(
'report_preferences',
sa.Column('user_id', sa.Integer, sa.ForeignKey('users.id'), primary_key=True),
sa.Column('line_number', sa.Integer, primary_key=True),
sa.Column('historical_report', sa.Boolean, default=False),
sa.Column('how_many_months_back', sa.Integer, nullable=True),
sa.Column('latitude', sa.Float),
sa.Column('longitude', sa.Float),
sa.Column('radius', sa.Float),
sa.Column('minimum_severity', sa.Integer),
)


def downgrade():
op.drop_table('report_preferences')
op.drop_table('general_preferences')

52 changes: 50 additions & 2 deletions main.py
Expand Up @@ -364,9 +364,57 @@ def updatebyemail():
db_session.commit()
return jsonify(respo='Subscription saved', )
else:
return jsonify(respo='Subscription already exist', )

return jsonify(respo='Subscription already exist')

@app.route("/preferences", methods=('GET', 'POST'))
def update_preferences():
if not current_user.is_authenticated:
return jsonify(respo='user not authenticated')
cur_id = current_user.get_id()
cur_user = db_session.query(User).filter(User.id == cur_id).first()
if cur_user is None:
return jsonify(respo='user not found')
cur_report_preferences = db_session.query(ReportPreferences).filter(User.id == cur_id).first()
if request.method == "GET":
if cur_report_preferences is None:
return jsonify(lat='', lon='', distance='', accident_severity='0', history_report=False)
else:
return jsonify(lat=cur_report_preferences.latitude, lon=cur_report_preferences.longitude, distance=cur_report_preferences.radius, \
accident_severity=cur_report_preferences.minimum_severity, history_report=cur_report_preferences.historical_report)
else:
jsonData = request.get_json(force=True)
lat = jsonData['lat']
lon = jsonData['lon']
distance = jsonData['distance']
accident_severity = jsonData['accident_severity']
history_report = jsonData['history_report']

cur_general_preferences = db_session.query(GeneralPreferences).filter(User.id == cur_id).first()
if cur_general_preferences is None:
general_pref = GeneralPreferences(user_id = cur_id, minimum_displayed_severity = accident_severity)
db_session.add(general_pref)
db_session.commit()
else:
cur_general_preferences.minimum_displayed_severity = accident_severity
db_session.add(cur_general_preferences)
db_session.commit()

if cur_report_preferences is None:
report_pref = ReportPreferences(user_id = cur_id, line_number=1,historical_report=history_report,\
latitude=lat,longitude=lon, radius=distance, minimum_severity=accident_severity)
db_session.add(report_pref)
db_session.commit()
else:
cur_report_preferences.historical_report = history_report
cur_report_preferences.latitude = lat
cur_report_preferences.longitude = lon
cur_report_preferences.radius = distance
cur_report_preferences.minimum_severity = accident_severity
db_session.add(cur_general_preferences)
db_session.commit()
return jsonify(respo='ok', )


class LoginFormAdmin(form.Form):
username = fields.StringField(validators=[validators.required()])
password = fields.PasswordField(validators=[validators.required()])
Expand Down
37 changes: 37 additions & 0 deletions models.py
Expand Up @@ -529,6 +529,43 @@ def is_anonymous(self):
def get_id(self):
return self.id

class GeneralPreferences(Base):
__tablename__ = "general_preferences"
user_id = Column(Integer(), ForeignKey('users.id'), primary_key=True)
minimum_displayed_severity = Column(Integer(), nullable=True)
resource_type = Column(String(64), nullable=True)

def serialize(self):
return {
"user_id": self.user_id,
"minimum_displayed_severity": self.minimum_displayed_severity,
"resource_type": self.resource_type
}

class ReportPreferences(Base):
__tablename__ = "report_preferences"
user_id = Column(Integer(), ForeignKey('users.id'), primary_key=True)
line_number = Column(Integer(), primary_key=True)
historical_report = Column(Boolean(), default=False)
how_many_months_back = Column(Integer(), nullable=True)
latitude = Column(Float())
longitude = Column(Float())
radius = Column(Float())
minimum_severity = Column(Integer())

def serialize(self):
return {
"user_id": self.user_id,
"line_number": self.line_number,
"historical_report": self.historical_report,
"how_many_months_back": self.how_many_months_back,
"latitude": self.latitude,
"longitude": self.longitude,
"radius": self.radius,
"minimum_severity": self.minimum_severity
}



def init_db():
from database import engine
Expand Down
Binary file added static/img/settings.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
5 changes: 4 additions & 1 deletion static/js/app.js
Expand Up @@ -761,7 +761,10 @@ $(function () {
if (this.createDialog) this.createDialog.close();
this.createDialog = new LoginDialog().render();
},

preferencesDialogLoad: function () {
if (this.createDialog) this.createDialog.close();
this.createDialog = new PreferencesDialog().render();
},
featuresSubscriptionDialog : function(type, event) {
if (this.createDialog) this.createDialog.close();
this.createDialog = new FeatureDialog({
Expand Down
46 changes: 46 additions & 0 deletions static/js/preferencesdialog.js
@@ -0,0 +1,46 @@
/**
* Created by Avik on 07-Mar-16.
*/
var PreferencesDialog = Backbone.View.extend({
className: "preferences-dialog",
events: {
"click .save-button": "submit",
"click .close-button": "close"
},
render: function () {
self = this;
self.$el.append($("#preferences-dialog-template").html());
$(document.body).append(self.$el);
$.get("preferences", function (data) {
self.$el.find("#prefLat").val(data["lat"]);
self.$el.find("#prefLon").val(data["lon"]);
self.$el.find("#prefDistance").val(data["distance"]);
self.$el.find("#prefAccidentSeverity").val(data["accident_severity"]);
if (data["history_report"] == true) {
self.$el.find("#prefHistoryReportTrue").prop('checked', true);
} else {
self.$el.find("#prefHistoryReportTrue").prop('checked', false);
}
self.$el.find("#prefHistoryReportTrue")
self.modal = self.$el.find(".modal");
self.modal.modal("show");
return self;
});

},
close: function () {
this.modal.modal("hide");
},
submit: function () {
var lat = this.$el.find("#prefLat").val();
var lon = this.$el.find("#prefLon").val();
var distance = this.$el.find("#prefDistance").val();
var accident_severity = this.$el.find("#prefAccidentSeverity :selected").val();
var history_report = this.$el.find("#prefHistoryReportTrue").is(":checked");
$.post("preferences", JSON.stringify({ 'lat': lat, 'lon': lon, 'distance': distance, 'accident_severity': accident_severity, 'history_report': history_report }), 'json');
this.close();
}
});



87 changes: 68 additions & 19 deletions templates/index.html
Expand Up @@ -55,28 +55,34 @@
<span class="fb-logout"><a class="btn" style="margin-top: 0">יציאה</a></span>
</div>
</div>
<!--<i class="fa fa-bars" style="border-right: 1px solid #ddd; padding-right: 8px; border-left: 1px solid #ddd; padding-left: 8px;margin-right: 102px; font-size: 18px; line-height: 100%; vertical-align: middle; cursor: pointer"></i>-->
<div class="navbar-brand">
<a class="brand" href="/"> beta <img class="brand-img" src="/static/img/anyway.png">
</a>
<div class="toggle-wrapper">
<div id="toggle-sidebar" class="on" onclick="toggle(this)">
<div class="one"></div>
<div class="two"></div>
<div class="three"></div>
<div style="float: left;">
{% if current_user.is_authenticated %}
<img src="../static/img/settings.png" onclick="app.preferencesDialogLoad()" width="16" style="padding-left: 5px; cursor: pointer" />
{% endif %}
</div>
<!--<i class="fa fa-bars" style="border-right: 1px solid #ddd; padding-right: 8px; border-left: 1px solid #ddd; padding-left: 8px;margin-right: 102px; font-size: 18px; line-height: 100%; vertical-align: middle; cursor: pointer"></i>-->
<div class="navbar-brand">
<a class="brand" href="/">
beta <img class="brand-img" src="/static/img/anyway.png">
</a>
<div class="toggle-wrapper">
<div id="toggle-sidebar" class="on" onclick="toggle(this)">
<div class="one"></div>
<div class="two"></div>
<div class="three"></div>
</div>
</div>
</div>
<script>
function toggle(div){
if (div.getAttribute('class') == 'on'){
div.className = '';
}else{
div.className = 'on';
<script>
function toggle(div){
if (div.getAttribute('class') == 'on'){
div.className = '';
}else{
div.className = 'on';
}
}
}
</script>
</script>
</div>
</div>
</div>
</div>

<div class="main main-close"
Expand Down Expand Up @@ -418,6 +424,7 @@ <h2> {{ gettext('Hi') + ' ' + current_user.nickname }}</h2>
<a class="btn btn-social-icon btn-facebook" href="{{ url_for('logout') }}">{{ gettext('Logout') }}
<span class="fa fa-sign-out"></span>
</a>
<br/>
{% else %}
<a class="btn btn-social-icon btn-facebook" href="{{ url_for('oauth_authorize', provider='facebook') }}">{{ gettext('Login with Facebook') }}
<span class="fa fa-facebook"></span>
Expand All @@ -438,6 +445,47 @@ <h3>OR</h3>
</div>
</div>

<div id="preferences-dialog-template" style="display: none" dir="rtl">
<div class="modal hide fade">
<!-- Modal content-->
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal">&times;</button>
<h4 class="modal-title">העדפות:</h4>
</div>
<div class="modal-body" style="max-height: 800px;">
<form role="form" id="prefForm">
<div class="form-group">
<label for="prefLat">מיקום מועדף</label>
<label for="prefLat" class="sr-only">קו רוחב:</label>
<input id="prefLat" class="form-control input-group-lg" type="text" name="prefLat" style="max-width: 200px" />
<label for="prefLon" class="sr-only">קו אורך:</label>
<input id="prefLon" class="form-control input-group-lg" type="text" name="prefLon" style="max-width: 200px" />
</div>
<hr />
<div class="form-group">
<label for="prefDistance">המרחק מהמיקום</label>
<input class="form-control" id="prefDistance" type="text">
</div>
<div class="form-group">
<label for="prefAccidentSeverity">חומרת התאונות</label>
<select id="prefAccidentSeverity">
<option id="prefFatal" value="0">קטלנית</option>
<option id="prefSevere" value="1">חמורה</option>
<option id="prefLight" value="2">קלה</option>
</select>
</div>
<div class="form-group">
<label>דוח היסטורי &nbsp;<input type="checkbox" class="form-control" value="prefHistoryWanted" id="prefHistoryReportTrue" style="display: inline" /></label>
</div>
</form>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">סגירה</button>
<button type="button" class="btn btn-primary save-button" data-dismiss="modal">שליחה</button>
</div>
</div>
</div>

<div id="sidebar-template" style="display: none">
<div class="filter-description">
<div id="filter-string">
Expand Down Expand Up @@ -909,6 +957,7 @@ <h3>OR</h3>
"js/marker.js",
"js/clusterView.js",
"js/featuredialog.js",
"js/preferencesdialog.js",
"js/logindialog.js",
"js/sidebar.js",
"js/contextmenu.js",
Expand Down

0 comments on commit 7d9204e

Please sign in to comment.