Add statistics about the instance under the About section.
This commit is contained in:
parent
aca68fb2e3
commit
d2bae9e532
@ -17,7 +17,11 @@ could know the location of the displayed map.
|
||||
|
||||
The data collected by https://cyclo.phyks.me/ is available under an
|
||||
[ODbL](https://opendatacommons.org/licenses/odbl/) license. You can get the
|
||||
most up to date JSON dump of available reports at https://cyclo.phyks.me/api/v1/reports.
|
||||
most up to date JSON dump of available reports at
|
||||
https://cyclo.phyks.me/api/v1/reports.
|
||||
|
||||
Statistics about the instance can be fetched at
|
||||
https://cyclo.phyks.me/api/v1/stats.
|
||||
|
||||
## Hosting your own
|
||||
|
||||
@ -78,6 +82,9 @@ python -m server
|
||||
|
||||
It is better to use a dedicated `virtualenv` if you can :)
|
||||
|
||||
API routes are all listed within `server/routes.py` file, with documentation
|
||||
strings.
|
||||
|
||||
#### Useful environment variables
|
||||
|
||||
You can pass a few environment variables to the `python -m server` command to
|
||||
|
@ -264,3 +264,34 @@ def downvote_report(id):
|
||||
return {
|
||||
"data": r.to_json()
|
||||
}
|
||||
|
||||
|
||||
@bottle.route('/api/v1/stats', ["GET", "OPTIONS"])
|
||||
def get_stats():
|
||||
"""
|
||||
API v1 GET stats about this instance.
|
||||
|
||||
Example::
|
||||
|
||||
GET /api/v1/states
|
||||
"""
|
||||
# Handle CORS
|
||||
if bottle.request.method == 'OPTIONS':
|
||||
return {}
|
||||
|
||||
nb_reports = Report.select().count()
|
||||
nb_active_reports = Report.select().where(
|
||||
(Report.expiration_datetime == None) |
|
||||
(Report.expiration_datetime > arrow.utcnow().replace(microsecond=0).datetime)
|
||||
).count()
|
||||
last_added_report_datetime = Report.select().order_by(
|
||||
Report.datetime.desc()
|
||||
).get().datetime
|
||||
|
||||
return {
|
||||
"data": {
|
||||
"nb_reports": nb_reports,
|
||||
"nb_active_reports": nb_active_reports,
|
||||
"last_added_report_datetime": last_added_report_datetime
|
||||
}
|
||||
}
|
||||
|
@ -36,6 +36,16 @@ export function getActiveReports() {
|
||||
});
|
||||
}
|
||||
|
||||
export function getStats() {
|
||||
return fetch(`${BASE_URL}api/v1/stats`)
|
||||
.then(response => response.json())
|
||||
.then(response => response.data)
|
||||
.catch((exc) => {
|
||||
console.error(`Unable to fetch stats: ${exc}.`);
|
||||
throw exc;
|
||||
});
|
||||
}
|
||||
|
||||
export function downvote(id) {
|
||||
return fetch(`${BASE_URL}api/v1/reports/${id}/downvote`, {
|
||||
method: 'POST',
|
||||
|
@ -12,7 +12,7 @@
|
||||
{{ report.label }}
|
||||
</v-flex>
|
||||
<v-flex xs12 class="secondLine">
|
||||
{{ $t('reportCard.Reported') }} {{ report.fromNow }}
|
||||
{{ $t('reportCard.Reported', { fromNow: report.fromNow }) }}
|
||||
</v-flex>
|
||||
</v-layout>
|
||||
</v-flex>
|
||||
|
@ -1,7 +1,12 @@
|
||||
{
|
||||
"about": {
|
||||
"availableReportsTitle": "The available reports so far are:",
|
||||
"license": "It is released under an <a href=\"https://opensource.org/licenses/MIT\">MIT license</a> (<a href=\"https://framagit.org/phyks/cyclassist\">source code</a>). Icons are based on creations from Wikimedia, Vecteezy, Pixabay or Flaticon. Sounds are based on CC0 works from <a href=\"https://freesound.org/\">freesound.org</a>. The map background is using tiles from <a href=\"https://carto.com/location-data-services/basemaps/\">Carto.com</a> or <a href=\"http://thunderforest.com/\">Thunderforest</a>, thanks to <a href=\"https://www.openstreetmap.org/copyright\">OpenStreetMap contributors</a> and <a href=\"http://leafletjs.com/\">Leaflet</a>. Collected reports are available under <a href=\"https://opendatacommons.org/licenses/odbl/\">ODbL license</a>. Manual location picking uses the awesome API from <a href=\"https://adresse.data.gouv.fr\">adresse.data.gouv.fr</a>.",
|
||||
"lastReportAdded": "Last report added {fromNow}.",
|
||||
"license": "License",
|
||||
"licenseDescription": "It is released under an <a href=\"https://opensource.org/licenses/MIT\">MIT license</a> (<a href=\"https://framagit.org/phyks/cyclassist\">source code</a>). Icons are based on creations from Wikimedia, Vecteezy, Pixabay or Flaticon. Sounds are based on CC0 works from <a href=\"https://freesound.org/\">freesound.org</a>. The map background is using tiles from <a href=\"https://carto.com/location-data-services/basemaps/\">Carto.com</a> or <a href=\"http://thunderforest.com/\">Thunderforest</a>, thanks to <a href=\"https://www.openstreetmap.org/copyright\">OpenStreetMap contributors</a> and <a href=\"http://leafletjs.com/\">Leaflet</a>. Collected reports are available under <a href=\"https://opendatacommons.org/licenses/odbl/\">ODbL license</a>. Manual location picking uses the awesome API from <a href=\"https://adresse.data.gouv.fr\">adresse.data.gouv.fr</a>.",
|
||||
"nbActiveReports": "No active report. | One active report. | {nbActiveReports} active reports.",
|
||||
"nbReports": "No report. | One report. | {nbReports} reports.",
|
||||
"stats": "Stats",
|
||||
"summary": "This app lets you track and share issues with bike lanes.",
|
||||
"usage": "How to use",
|
||||
"usageDescription": "Use the button in the lower right corner to add a new report at your current location. To add a report elsewhere, do a click where you want the report to be shown. Press on a marker on the map to display more informations and report the problem as being still there or solved."
|
||||
@ -61,7 +66,7 @@
|
||||
"vibrate": "Vibrate"
|
||||
},
|
||||
"reportCard": {
|
||||
"Reported": "Reported"
|
||||
"Reported": "Reported {fromNow}."
|
||||
},
|
||||
"reportDialog": {
|
||||
"unableToSendDescription": "There was a network issue preventing from sending the latest report.",
|
||||
|
@ -10,18 +10,52 @@
|
||||
<h2 class="body-2">{{ $t('about.availableReportsTitle') }}</h2>
|
||||
<ReportsDescription></ReportsDescription>
|
||||
|
||||
<p class="mt-3" v-html="$t('about.license')"></p>
|
||||
<h2 class="body-2 mt-3">{{ $t('about.stats') }}</h2>
|
||||
<v-progress-circular indeterminate v-if="!stats"></v-progress-circular>
|
||||
<ul v-else>
|
||||
<li>{{ $tc('about.nbActiveReports', stats.nb_active_reports, { nbActiveReports: stats.nb_active_reports }) }}</li>
|
||||
<li>{{ $tc('about.nbReports', stats.nb_reports, { nbReports: stats.nb_reports }) }}</li>
|
||||
<li>{{ $t('about.lastReportAdded', { fromNow: stats.last_added_report_datetime }) }}</li>
|
||||
</ul>
|
||||
|
||||
<h2 class="body-2 mt-3">{{ $t('about.license') }}</h2>
|
||||
<p v-html="$t('about.licenseDescription')"></p>
|
||||
</v-flex>
|
||||
</v-layout>
|
||||
</v-container>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import moment from 'moment';
|
||||
|
||||
import { getStats } from '@/api';
|
||||
|
||||
import ReportsDescription from '@/components/ReportsDescription.vue';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
ReportsDescription,
|
||||
},
|
||||
created() {
|
||||
this.fetchData();
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
stats: null,
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
fetchData() {
|
||||
getStats().then((stats) => {
|
||||
this.stats = stats;
|
||||
this.stats.last_added_report_datetime = (
|
||||
moment(this.stats.last_added_report_datetime).fromNow()
|
||||
);
|
||||
});
|
||||
},
|
||||
},
|
||||
watch: {
|
||||
$route: 'fetchData',
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
@ -12,6 +12,7 @@ import VGrid from 'vuetify/es5/components/VGrid';
|
||||
import VIcon from 'vuetify/es5/components/VIcon';
|
||||
import VList from 'vuetify/es5/components/VList';
|
||||
import VMenu from 'vuetify/es5/components/VMenu';
|
||||
import VProgressCircular from 'vuetify/es5/components/VProgressCircular';
|
||||
import VProgressLinear from 'vuetify/es5/components/VProgressLinear';
|
||||
import VSelect from 'vuetify/es5/components/VSelect';
|
||||
import VSwitch from 'vuetify/es5/components/VSwitch';
|
||||
@ -32,6 +33,7 @@ Vue.use(Vuetify, {
|
||||
VIcon,
|
||||
VList,
|
||||
VMenu,
|
||||
VProgressCircular,
|
||||
VProgressLinear,
|
||||
VSelect,
|
||||
VSwitch,
|
||||
|
Loading…
Reference in New Issue
Block a user