Rework upvotes
Upvotes now reset the `datetime` field of the report, making it appear as if it was newly reported. They also extend the lifetime for accidents and GCUM. This introduces database migrations as well. Closes https://framagit.org/phyks/cyclassist/issues/41.
This commit is contained in:
parent
1139dc33c5
commit
a7792f5dbb
@ -143,6 +143,12 @@ python -m server
|
|||||||
|
|
||||||
to spawn the server-side part, listening on `localhost:8081`.
|
to spawn the server-side part, listening on `localhost:8081`.
|
||||||
|
|
||||||
|
### Updating
|
||||||
|
|
||||||
|
Database migrations are in the `scripts/migrations` folder, labelled by
|
||||||
|
versions. You should run them in order from your current versions to the
|
||||||
|
latest one when you upgrade.
|
||||||
|
|
||||||
### Useful scripts for dev
|
### Useful scripts for dev
|
||||||
|
|
||||||
You can run `scripts/gps_to_gpx.py` on your GPX trace to create a
|
You can run `scripts/gps_to_gpx.py` on your GPX trace to create a
|
||||||
|
41
scripts/migrations/0.3.py
Normal file
41
scripts/migrations/0.3.py
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
"""
|
||||||
|
Database migration from < 0.3 to 0.3 version.
|
||||||
|
"""
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
|
||||||
|
import peewee
|
||||||
|
|
||||||
|
SCRIPT_DIRECTORY = os.path.dirname(os.path.realpath(__file__))
|
||||||
|
sys.path.append(os.path.abspath(os.path.join(SCRIPT_DIRECTORY, '..', '..')))
|
||||||
|
|
||||||
|
from playhouse.migrate import *
|
||||||
|
|
||||||
|
from server.models import db, Report
|
||||||
|
from server.tools import UTC_now
|
||||||
|
|
||||||
|
|
||||||
|
def run_migration():
|
||||||
|
if type(db) == peewee.SqliteDatabase:
|
||||||
|
migrator = SqliteMigrator(db)
|
||||||
|
elif type(db) == peewee.MySQLDatabase:
|
||||||
|
migrator = MySQLMigrator(db)
|
||||||
|
elif type(db) == peewee.PostgresqlDatabase:
|
||||||
|
migrator = PostgresqlMigrator(db)
|
||||||
|
else:
|
||||||
|
return
|
||||||
|
|
||||||
|
migrate(
|
||||||
|
migrator.add_column('report', 'first_report_datetime',
|
||||||
|
peewee.DateTimeField(default=UTC_now)),
|
||||||
|
)
|
||||||
|
query = Report.select()
|
||||||
|
for report in query:
|
||||||
|
report.first_report_datetime = report.datetime
|
||||||
|
report.save()
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
db.connect()
|
||||||
|
run_migration()
|
@ -5,12 +5,13 @@ Models and database definition
|
|||||||
"""
|
"""
|
||||||
import os
|
import os
|
||||||
|
|
||||||
import arrow
|
|
||||||
import bottle
|
import bottle
|
||||||
import peewee
|
import peewee
|
||||||
from playhouse.db_url import connect
|
from playhouse.db_url import connect
|
||||||
from playhouse.shortcuts import model_to_dict
|
from playhouse.shortcuts import model_to_dict
|
||||||
|
|
||||||
|
from server.tools import UTC_now
|
||||||
|
|
||||||
db = connect(os.environ.get('DATABASE', 'sqlite:///reports.db'))
|
db = connect(os.environ.get('DATABASE', 'sqlite:///reports.db'))
|
||||||
|
|
||||||
|
|
||||||
@ -40,8 +41,11 @@ class Report(BaseModel):
|
|||||||
type = peewee.CharField(max_length=255)
|
type = peewee.CharField(max_length=255)
|
||||||
lat = peewee.DoubleField()
|
lat = peewee.DoubleField()
|
||||||
lng = peewee.DoubleField()
|
lng = peewee.DoubleField()
|
||||||
|
first_report_datetime = peewee.DateTimeField(
|
||||||
|
default=UTC_now
|
||||||
|
)
|
||||||
datetime = peewee.DateTimeField(
|
datetime = peewee.DateTimeField(
|
||||||
default=lambda: arrow.utcnow().replace(microsecond=0).naive
|
default=UTC_now
|
||||||
)
|
)
|
||||||
expiration_datetime = peewee.DateTimeField(null=True)
|
expiration_datetime = peewee.DateTimeField(null=True)
|
||||||
is_open = peewee.BooleanField(default=True)
|
is_open = peewee.BooleanField(default=True)
|
||||||
|
@ -10,6 +10,7 @@ import os
|
|||||||
import bottle
|
import bottle
|
||||||
|
|
||||||
from server.models import Report
|
from server.models import Report
|
||||||
|
from server.tools import UTC_now
|
||||||
from server import jsonapi
|
from server import jsonapi
|
||||||
|
|
||||||
|
|
||||||
@ -80,7 +81,7 @@ def get_reports(only_active=False):
|
|||||||
if only_active:
|
if only_active:
|
||||||
query = query.where(
|
query = query.where(
|
||||||
(Report.expiration_datetime == None) |
|
(Report.expiration_datetime == None) |
|
||||||
(Report.expiration_datetime > arrow.utcnow().replace(microsecond=0).datetime)
|
(Report.expiration_datetime > UTC_now())
|
||||||
)
|
)
|
||||||
query = query.order_by(*sorting)
|
query = query.order_by(*sorting)
|
||||||
if page_number and page_size:
|
if page_number and page_size:
|
||||||
@ -195,7 +196,7 @@ def post_report():
|
|||||||
# Handle expiration
|
# Handle expiration
|
||||||
if r.type in ['accident', 'gcum']:
|
if r.type in ['accident', 'gcum']:
|
||||||
r.expiration_datetime = (
|
r.expiration_datetime = (
|
||||||
arrow.utcnow().replace(microsecond=0).shift(hours=+1).datetime
|
arrow.get(UTC_now()).shift(hours=+1).naive
|
||||||
)
|
)
|
||||||
r.save()
|
r.save()
|
||||||
except KeyError as exc:
|
except KeyError as exc:
|
||||||
@ -228,7 +229,15 @@ def upvote_report(id):
|
|||||||
r = Report.get(Report.id == id)
|
r = Report.get(Report.id == id)
|
||||||
if not r:
|
if not r:
|
||||||
return jsonapi.JsonApiError(404, "Invalid report id.")
|
return jsonapi.JsonApiError(404, "Invalid report id.")
|
||||||
|
# Increase upvotes
|
||||||
r.upvotes += 1
|
r.upvotes += 1
|
||||||
|
# Update report datetime
|
||||||
|
r.datetime = UTC_now()
|
||||||
|
# Update expiration datetime
|
||||||
|
if r.type in ['accident', 'gcum']:
|
||||||
|
r.expiration_datetime = (
|
||||||
|
arrow.get(UTC_now()).shift(hours=+1).naive
|
||||||
|
)
|
||||||
r.save()
|
r.save()
|
||||||
|
|
||||||
return {
|
return {
|
||||||
@ -282,7 +291,7 @@ def get_stats():
|
|||||||
nb_reports = Report.select().count()
|
nb_reports = Report.select().count()
|
||||||
nb_active_reports = Report.select().where(
|
nb_active_reports = Report.select().where(
|
||||||
(Report.expiration_datetime == None) |
|
(Report.expiration_datetime == None) |
|
||||||
(Report.expiration_datetime > arrow.utcnow().replace(microsecond=0).datetime)
|
(Report.expiration_datetime > UTC_now())
|
||||||
).count()
|
).count()
|
||||||
last_added_report_datetime = Report.select().order_by(
|
last_added_report_datetime = Report.select().order_by(
|
||||||
Report.datetime.desc()
|
Report.datetime.desc()
|
||||||
|
5
server/tools.py
Normal file
5
server/tools.py
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
import arrow
|
||||||
|
|
||||||
|
|
||||||
|
def UTC_now():
|
||||||
|
return arrow.utcnow().replace(microsecond=0).naive
|
@ -85,8 +85,8 @@ export const MOCK_LOCATION_LNG_MAX = 2.392742;
|
|||||||
|
|
||||||
export const UPDATE_REPORTS_DISTANCE_THRESHOLD = 500; // in meters
|
export const UPDATE_REPORTS_DISTANCE_THRESHOLD = 500; // in meters
|
||||||
|
|
||||||
// Minimal ratio between upvotes and downvotes needed for a report to be shown
|
// Minimal number of downvotes needed for a report to be masked
|
||||||
export const REPORT_VOTES_THRESHOLD = 0.5;
|
export const REPORT_DOWNVOTES_THRESHOLD = 1;
|
||||||
|
|
||||||
export const EARTH_RADIUS = 6378137; // in meters
|
export const EARTH_RADIUS = 6378137; // in meters
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { REPORT_VOTES_THRESHOLD } from '@/constants';
|
import { REPORT_DOWNVOTES_THRESHOLD } from '@/constants';
|
||||||
|
|
||||||
export function getLastLocation(state) {
|
export function getLastLocation(state) {
|
||||||
const { gpx } = state.location;
|
const { gpx } = state.location;
|
||||||
@ -10,9 +10,9 @@ export function getLastLocation(state) {
|
|||||||
|
|
||||||
export function notDismissedReports(state) {
|
export function notDismissedReports(state) {
|
||||||
return state.reports.filter((item) => {
|
return state.reports.filter((item) => {
|
||||||
if (item.attributes.downvotes === 0) {
|
if (item.attributes.downvotes >= REPORT_DOWNVOTES_THRESHOLD) {
|
||||||
return true;
|
return false;
|
||||||
}
|
}
|
||||||
return (item.attributes.upvotes / item.attributes.downvotes) > REPORT_VOTES_THRESHOLD;
|
return true;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user