made the open data importer its own component

This commit is contained in:
vabene1111 2023-05-05 16:33:30 +02:00
parent 12da77f037
commit 86fd0dcab1
6 changed files with 161 additions and 47 deletions

View File

@ -110,8 +110,8 @@ class OpenDataImporter:
for f in Food.objects.filter(space=self.request.space).filter(name__in=identifier_list).values_list('id', 'name', 'plural_name'):
existing_objects_flat.append(f[1])
existing_objects_flat.append(f[2])
existing_objects['name'] = f
existing_objects['plural_name'] = f
existing_objects[f[1]] = f
existing_objects[f[2]] = f
self._update_slug_cache(Unit, 'unit')
self._update_slug_cache(FoodPropertyType, 'property')
@ -159,7 +159,7 @@ class OpenDataImporter:
update_field_list = ['open_data_slug', ]
update_list.append(Food(id=existing_food_id, open_data_slug=k, ))
foods = Food.load_bulk(insert_list, None)
Food.load_bulk(insert_list, None)
Food.objects.bulk_update(update_list, update_field_list)
self._update_slug_cache(Food, 'food')
@ -187,7 +187,7 @@ class OpenDataImporter:
FoodProperty.objects.bulk_create(food_property_list, ignore_conflicts=True, unique_fields=('space', 'food', 'property_type',))
Automation.objects.bulk_create(alias_list, ignore_conflicts=True, unique_fields=('space', 'param_1', 'param_2',))
return foods
return insert_list + update_list
def import_conversion(self):
datatype = 'conversion'

View File

@ -1428,9 +1428,7 @@ class ImportOpenData(APIView):
return Response(metadata)
def post(self, request, *args, **kwargs):
# serializer load data ?
# TODO validate data
# TODO add option to handle merging of existing data (merge, override, ignore)
print(request.data)
selected_version = request.data['selected_version']
selected_datatypes = request.data['selected_datatypes']

View File

@ -51,14 +51,14 @@
<td>{{ us.user.username }}</td>
<td>
<generic-multiselect
class="input-group-text m-0 p-0"
@change="us.groups = $event.val; updateUserSpace(us)"
label="name"
:initial_selection="us.groups"
:model="Models.GROUP"
style="flex-grow: 1; flex-shrink: 1; flex-basis: 0"
:limit="10"
:multiple="true"
class="input-group-text m-0 p-0"
@change="us.groups = $event.val; updateUserSpace(us)"
label="name"
:initial_selection="us.groups"
:model="Models.GROUP"
style="flex-grow: 1; flex-shrink: 1; flex-basis: 0"
:limit="10"
:multiple="true"
/>
</td>
<td>
@ -90,14 +90,14 @@
<td>{{ il.email }}</td>
<td>
<generic-multiselect
class="input-group-text m-0 p-0"
@change="il.group = $event.val;"
label="name"
:initial_single_selection="il.group"
:model="Models.GROUP"
style="flex-grow: 1; flex-shrink: 1; flex-basis: 0"
:limit="10"
:multiple="false"
class="input-group-text m-0 p-0"
@change="il.group = $event.val;"
label="name"
:initial_single_selection="il.group"
:model="Models.GROUP"
style="flex-grow: 1; flex-shrink: 1; flex-basis: 0"
:limit="10"
:multiple="false"
/>
</td>
<td><input type="date" v-model="il.valid_until" class="form-control"></td>
@ -164,6 +164,15 @@
</div>
</div>
<div class="row">
<div class="col-md-12">
<h4>{{ $t('Open_Data_Import') }}</h4>
<open-data-import-component></open-data-import-component>
</div>
</div>
<div class="row mt-4">
<div class="col col-12">
<h4 class="mt-2"><i class="fas fa-trash"></i> {{ $t('Delete') }}</h4>
@ -198,6 +207,7 @@ import GenericMultiselect from "@/components/GenericMultiselect";
import GenericModalForm from "@/components/Modals/GenericModalForm";
import axios from "axios";
import VueClipboard from 'vue-clipboard2'
import OpenDataImportComponent from "@/components/OpenDataImportComponent.vue";
Vue.use(VueClipboard)
@ -206,7 +216,7 @@ Vue.use(BootstrapVue)
export default {
name: "SpaceManageView",
mixins: [ResolveUrlMixin, ToastMixin, ApiMixin],
components: {GenericMultiselect, GenericModalForm},
components: {GenericMultiselect, GenericModalForm, OpenDataImportComponent},
data() {
return {
ACTIVE_SPACE_ID: window.ACTIVE_SPACE_ID,
@ -239,7 +249,7 @@ export default {
if (link) {
content = localStorage.BASE_PATH + this.resolveDjangoUrl('view_invite', inviteLink.uuid)
}
this.$copyText(content)
this.$copyText(content)
},
loadInviteLinks: function () {
let apiFactory = new ApiApiFactory()

View File

@ -1,47 +1,41 @@
<template>
<div id="app">
Import Component
<div v-id="metadata !== undefined">
<beta-warning></beta-warning>
<div v-if="metadata !== undefined">
{{ $t('Data_Import_Info') }}
<select class="form-control" v-model="selected_version">
<option v-for="v in metadata.versions" v-bind:key="v">{{ v }}</option>
</select>
<select class="form-control">
<option>{{$t('Metric')}}</option>
<option>{{$t('Imperial')}}</option>
</select>
<b-checkbox v-model="update_existing" class="mt-1">{{ $t('Update_Existing_Data') }}</b-checkbox>
<b-checkbox v-model="use_metric" class="mt-1">{{ $t('Use_Metric') }}</b-checkbox>
<select class="form-control">
<option selected>{{$t('Ignore')}}</option>
<option>{{$t('Merge')}}</option>
<option>{{$t('Replace')}}</option>
</select>
<div v-if="selected_version !== undefined">
<div v-if="selected_version !== undefined" class="mt-3">
<table class="table">
<tr>
<th>{{ $t('Datatype') }}</th>
<th>{{ $t('Number of Objects') }}</th>
<th>{{ $t('Imported') }}</th>
</tr>
<tr v-for="d in metadata.datatypes" v-bind:key="d">
<td>{{ d }}</td>
<td>{{ $t(d.charAt(0).toUpperCase() + d.slice(1)) }}</td>
<td>{{ metadata[selected_version][d] }}</td>
<td>
<template v-if="import_count !== undefined">{{ import_count[d] }}</template>
</td>
</tr>
</table>
<button class="btn btn-success" @click="doImport">{{ $t('Import') }}</button>
</div>
<div v-if="response_data !== undefined">
{{response_data}}
</div>
</div>
</div>
</template>
@ -53,6 +47,7 @@ import {BootstrapVue} from "bootstrap-vue"
import "bootstrap-vue/dist/bootstrap-vue.css"
import {ApiMixin, resolveDjangoUrl, StandardToasts} from "@/utils/utils";
import axios from "axios";
import BetaWarning from "@/components/BetaWarning.vue";
Vue.use(BootstrapVue)
@ -61,12 +56,14 @@ Vue.use(BootstrapVue)
export default {
name: "TestView",
mixins: [ApiMixin],
components: {},
components: {BetaWarning},
data() {
return {
metadata: undefined,
selected_version: undefined,
response_data: undefined,
update_existing: true,
use_metric: true,
import_count: undefined,
}
},
mounted() {
@ -80,12 +77,18 @@ export default {
},
methods: {
doImport: function () {
axios.post(resolveDjangoUrl('api_import_open_data'), {'selected_version': this.selected_version, 'selected_datatypes': this.metadata.datatypes}).then(r => {
axios.post(resolveDjangoUrl('api_import_open_data'), {
'selected_version': this.selected_version,
'selected_datatypes': this.metadata.datatypes,
'update_existing': this.update_existing,
'use_metric': this.use_metric,
}).then(r => {
StandardToasts.makeStandardToast(this, StandardToasts.SUCCESS_CREATE)
this.import_count = r.data
}).catch(err => {
StandardToasts.makeStandardToast(this, StandardToasts.FAIL_CREATE, err)
})
}
},
},
}
</script>

View File

@ -0,0 +1,94 @@
<template>
<div>
<beta-warning></beta-warning>
<div v-if="metadata !== undefined">
{{ $t('Data_Import_Info') }}
<a href="https://github.com/TandoorRecipes/open-tandoor-data" target="_blank" rel="noreferrer nofollow">{{$t('Learn_More')}}</a>
<select class="form-control" v-model="selected_version">
<option v-for="v in metadata.versions" v-bind:key="v">{{ v }}</option>
</select>
<b-checkbox v-model="update_existing" class="mt-1">{{ $t('Update_Existing_Data') }}</b-checkbox>
<b-checkbox v-model="use_metric" class="mt-1">{{ $t('Use_Metric') }}</b-checkbox>
<div v-if="selected_version !== undefined" class="mt-3">
<table class="table">
<tr>
<th>{{ $t('Datatype') }}</th>
<th>{{ $t('Number of Objects') }}</th>
<th>{{ $t('Imported') }}</th>
</tr>
<tr v-for="d in metadata.datatypes" v-bind:key="d">
<td>{{ $t(d.charAt(0).toUpperCase() + d.slice(1)) }}</td>
<td>{{ metadata[selected_version][d] }}</td>
<td>
<template v-if="import_count !== undefined">{{ import_count[d] }}</template>
</td>
</tr>
</table>
<button class="btn btn-success" @click="doImport">{{ $t('Import') }}</button>
</div>
</div>
</div>
</template>
<script>
import Vue from "vue"
import {BootstrapVue} from "bootstrap-vue"
import "bootstrap-vue/dist/bootstrap-vue.css"
import {ApiMixin, resolveDjangoUrl, StandardToasts} from "@/utils/utils";
import axios from "axios";
import BetaWarning from "@/components/BetaWarning.vue";
Vue.use(BootstrapVue)
export default {
name: "OpenDataImportComponent",
mixins: [ApiMixin],
components: {BetaWarning},
data() {
return {
metadata: undefined,
selected_version: undefined,
update_existing: true,
use_metric: true,
import_count: undefined,
}
},
mounted() {
this.$i18n.locale = window.CUSTOM_LOCALE
axios.get(resolveDjangoUrl('api_import_open_data')).then(r => {
this.metadata = r.data
}).catch(err => {
StandardToasts.makeStandardToast(this, StandardToasts.FAIL_FETCH, err)
})
},
methods: {
doImport: function () {
axios.post(resolveDjangoUrl('api_import_open_data'), {
'selected_version': this.selected_version,
'selected_datatypes': this.metadata.datatypes,
'update_existing': this.update_existing,
'use_metric': this.use_metric,
}).then(r => {
StandardToasts.makeStandardToast(this, StandardToasts.SUCCESS_CREATE)
this.import_count = r.data
}).catch(err => {
StandardToasts.makeStandardToast(this, StandardToasts.FAIL_CREATE, err)
})
},
},
}
</script>

View File

@ -78,6 +78,13 @@
"reusable_help_text": "Should the invite link be usable for more than one user.",
"open_data_help_text": "The Tandoor Open Data project provides community contributed data for Tandoor. This field is filled automatically when importing it and allows updates in the future.",
"Open_Data_Slug": "Open Data Slug",
"Open_Data_Import": "Open Data Import",
"Data_Import_Info": "Enhance your Space by importing a community curated list of foods, units and more to improve your recipe collection.",
"Update_Existing_Data": "Update Existing Data",
"Use_Metric": "Use Metric Units",
"Learn_More": "Learn More",
"Datatype": "Datatype",
"Number of Objects": "Number of Objects",
"Add_Step": "Add Step",
"Keywords": "Keywords",
"Books": "Books",
@ -163,6 +170,8 @@
"merge_title": "Merge {type}",
"move_title": "Move {type}",
"Food": "Food",
"Property": "Property",
"Conversion": "Conversion",
"Original_Text": "Original Text",
"Recipe_Book": "Recipe Book",
"del_confirmation_tree": "Are you sure that you want to delete {source} and all of it's children?",