This commit is contained in:
smilerz 2021-09-05 11:17:28 -05:00
parent 738387ccf0
commit d1556f69c2
29 changed files with 184 additions and 204 deletions

View File

@ -61,12 +61,12 @@ with scopes_disabled():
model = Recipe
fields = ['name', 'keywords', 'foods', 'internal']
class FoodFilter(django_filters.FilterSet):
name = django_filters.CharFilter(lookup_expr='icontains')
# class FoodFilter(django_filters.FilterSet):
# name = django_filters.CharFilter(lookup_expr='icontains')
class Meta:
model = Food
fields = ['name']
# class Meta:
# model = Food
# fields = ['name']
class ShoppingListFilter(django_filters.FilterSet):

View File

@ -6,12 +6,11 @@ from django.utils.translation import gettext_lazy as _
from django_scopes import scopes_disabled
from django_scopes.forms import SafeModelChoiceField, SafeModelMultipleChoiceField
from emoji_picker.widgets import EmojiPickerTextInput
from treebeard.forms import MoveNodeForm
from hcaptcha.fields import hCaptchaField
from .models import (Comment, Food, InviteLink, Keyword, MealPlan, Recipe,
RecipeBook, RecipeBookEntry, Storage, Sync, Unit, User,
UserPreference, SupermarketCategory, MealType, Space,
UserPreference, MealType, Space,
SearchPreference)
@ -219,31 +218,31 @@ class CommentForm(forms.ModelForm):
}
class KeywordForm(MoveNodeForm):
class Meta:
model = Keyword
fields = ('name', 'icon', 'description')
exclude = ('sib_order', 'parent', 'path', 'depth', 'numchild')
widgets = {'icon': EmojiPickerTextInput}
# class KeywordForm(MoveNodeForm):
# class Meta:
# model = Keyword
# fields = ('name', 'icon', 'description')
# exclude = ('sib_order', 'parent', 'path', 'depth', 'numchild')
# widgets = {'icon': EmojiPickerTextInput}
class FoodForm(forms.ModelForm):
# class FoodForm(forms.ModelForm):
def __init__(self, *args, **kwargs):
space = kwargs.pop('space')
super().__init__(*args, **kwargs)
self.fields['recipe'].queryset = Recipe.objects.filter(space=space).all()
self.fields['supermarket_category'].queryset = SupermarketCategory.objects.filter(space=space).all()
# def __init__(self, *args, **kwargs):
# space = kwargs.pop('space')
# super().__init__(*args, **kwargs)
# self.fields['recipe'].queryset = Recipe.objects.filter(space=space).all()
# self.fields['supermarket_category'].queryset = SupermarketCategory.objects.filter(space=space).all()
class Meta:
model = Food
fields = ('name', 'description', 'ignore_shopping', 'recipe', 'supermarket_category')
widgets = {'recipe': SelectWidget}
# class Meta:
# model = Food
# fields = ('name', 'description', 'ignore_shopping', 'recipe', 'supermarket_category')
# widgets = {'recipe': SelectWidget}
field_classes = {
'recipe': SafeModelChoiceField,
'supermarket_category': SafeModelChoiceField,
}
# field_classes = {
# 'recipe': SafeModelChoiceField,
# 'supermarket_category': SafeModelChoiceField,
# }
class StorageForm(forms.ModelForm):

View File

@ -1 +0,0 @@
<!DOCTYPE html><html lang=""><head><meta charset="utf-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width,initial-scale=1"><title>Vue App</title><link href="css/chunk-vendors.css" rel="preload" as="style"><link href="css/food_list_view.css" rel="preload" as="style"><link href="js/chunk-vendors.js" rel="preload" as="script"><link href="js/food_list_view.js" rel="preload" as="script"><link href="css/chunk-vendors.css" rel="stylesheet"><link rel="icon" type="image/png" sizes="32x32" href="img/icons/favicon-32x32.png"><link rel="icon" type="image/png" sizes="16x16" href="img/icons/favicon-16x16.png"><link rel="manifest" href="manifest.json"><meta name="theme-color" content="#4DBA87"><meta name="apple-mobile-web-app-capable" content="yes"><meta name="apple-mobile-web-app-status-bar-style" content="black"><meta name="apple-mobile-web-app-title" content="Recipes"><link rel="apple-touch-icon" href="img/icons/apple-touch-icon-152x152.png"><link rel="mask-icon" href="img/icons/safari-pinned-tab.svg" color="#4DBA87"><meta name="msapplication-TileImage" content="img/icons/msapplication-icon-144x144.png"><meta name="msapplication-TileColor" content="#000000"></head><body><div id="app"></div><script src="js/chunk-vendors.js"></script></body></html>

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1 @@
<!DOCTYPE html><html lang=""><head><meta charset="utf-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width,initial-scale=1"><title>Vue App</title><link href="css/chunk-vendors.css" rel="preload" as="style"><link href="css/model_list_view.css" rel="preload" as="style"><link href="js/chunk-vendors.js" rel="preload" as="script"><link href="js/model_list_view.js" rel="preload" as="script"><link href="css/chunk-vendors.css" rel="stylesheet"><link rel="icon" type="image/png" sizes="32x32" href="img/icons/favicon-32x32.png"><link rel="icon" type="image/png" sizes="16x16" href="img/icons/favicon-16x16.png"><link rel="manifest" href="manifest.json"><meta name="theme-color" content="#4DBA87"><meta name="apple-mobile-web-app-capable" content="yes"><meta name="apple-mobile-web-app-status-bar-style" content="black"><meta name="apple-mobile-web-app-title" content="Recipes"><link rel="apple-touch-icon" href="img/icons/apple-touch-icon-152x152.png"><link rel="mask-icon" href="img/icons/safari-pinned-tab.svg" color="#4DBA87"><meta name="msapplication-TileImage" content="img/icons/msapplication-icon-144x144.png"><meta name="msapplication-TileColor" content="#000000"></head><body><div id="app"></div><script src="js/chunk-vendors.js"></script></body></html>

View File

@ -52,13 +52,13 @@ class RecipeTable(tables.Table):
)
class IngredientTable(tables.Table):
id = tables.LinkColumn('edit_food', args=[A('id')])
# class IngredientTable(tables.Table):
# id = tables.LinkColumn('edit_food', args=[A('id')])
class Meta:
model = Keyword
template_name = 'generic/table_template.html'
fields = ('id', 'name')
# class Meta:
# model = Keyword
# template_name = 'generic/table_template.html'
# fields = ('id', 'name')
class StorageTable(tables.Table):

View File

@ -2,9 +2,8 @@
{% load render_bundle from webpack_loader %}
{% load static %}
{% load i18n %}
{% load l10n %}
{% comment %} TODO Can this be combined with Keyword template? {% endcomment %}
{% block title %}{% trans 'Food' %}{% endblock %}
{% comment %} {% load l10n %} {% endcomment %}
{% block title %}{{ title }}{% endblock %}
{% block content_fluid %}
@ -17,15 +16,15 @@
{% block script %}
{% if debug %}
{% comment %} {% if debug %}
<script src="{% url 'js_reverse' %}"></script>
{% else %}
<script src="{% static 'django_js_reverse/reverse.js' %}"></script>
{% endif %}
{% endif %} {% endcomment %}
<script type="application/javascript">
window.IMAGE_PLACEHOLDER = "{% static 'assets/recipe_no_image.svg' %}"
</script>
{% render_bundle 'food_list_view' %}
{% render_bundle 'model_list_view' %}
{% endblock %}

File diff suppressed because one or more lines are too long

View File

@ -11,7 +11,7 @@ from cookbook.helper import dal
from .models import (Comment, Food, InviteLink, Keyword, MealPlan, Recipe,
RecipeBook, RecipeBookEntry, RecipeImport, ShoppingList,
Storage, Sync, SyncLog, get_model_name)
from .views import api, data, delete, edit, import_export, lists, trees, new, views, telegram
from .views import api, data, delete, edit, import_export, lists, new, views, telegram
router = routers.DefaultRouter()
router.register(r'user-name', api.UserNameViewSet, basename='username')
@ -87,7 +87,7 @@ urlpatterns = [
path('edit/recipe/convert/<int:pk>/', edit.convert_recipe, name='edit_convert_recipe'),
path('edit/storage/<int:pk>/', edit.edit_storage, name='edit_storage'),
path('edit/ingredient/', edit.edit_ingredients, name='edit_food'), # TODO is this still needed?
path('edit/ingredient/', edit.edit_ingredients, name='edit_food'), # TODO deprecate?
path('delete/recipe-source/<int:pk>/', delete.delete_recipe_source, name='delete_recipe_source'),
@ -176,12 +176,12 @@ for m in generic_models:
)
)
tree_models = [Keyword, Food]
for m in tree_models:
vue_models = [Keyword, Food]
for m in vue_models:
py_name = get_model_name(m)
url_name = py_name.replace('_', '-')
if c := getattr(trees, py_name, None):
if c := getattr(lists, py_name, None):
urlpatterns.append(
path(
f'list/{url_name}/', c, name=f'list_{py_name}'

View File

@ -9,7 +9,7 @@ from django.views.generic import DeleteView
from cookbook.helper.permission_helper import (GroupRequiredMixin,
OwnerRequiredMixin,
group_required)
from cookbook.models import (Comment, InviteLink, Keyword, MealPlan, Recipe,
from cookbook.models import (Comment, InviteLink, MealPlan, Recipe,
RecipeBook, RecipeBookEntry, RecipeImport,
Storage, Sync)
from cookbook.provider.dropbox import Dropbox
@ -73,16 +73,16 @@ class SyncDelete(GroupRequiredMixin, DeleteView):
return context
class KeywordDelete(GroupRequiredMixin, DeleteView):
groups_required = ['user']
template_name = "generic/delete_template.html"
model = Keyword
success_url = reverse_lazy('list_keyword')
# class KeywordDelete(GroupRequiredMixin, DeleteView):
# groups_required = ['user']
# template_name = "generic/delete_template.html"
# model = Keyword
# success_url = reverse_lazy('list_keyword')
def get_context_data(self, **kwargs):
context = super(KeywordDelete, self).get_context_data(**kwargs)
context['title'] = _("Keyword")
return context
# def get_context_data(self, **kwargs):
# context = super(KeywordDelete, self).get_context_data(**kwargs)
# context['title'] = _("Keyword")
# return context
class StorageDelete(GroupRequiredMixin, DeleteView):

View File

@ -10,14 +10,14 @@ from django.views.generic import UpdateView
from django.views.generic.edit import FormMixin
from django_scopes import scopes_disabled
from cookbook.forms import (CommentForm, ExternalRecipeForm, FoodForm,
FoodMergeForm, KeywordForm, MealPlanForm,
from cookbook.forms import (CommentForm, ExternalRecipeForm,
FoodMergeForm, MealPlanForm,
RecipeBookForm, StorageForm, SyncForm,
UnitMergeForm)
from cookbook.helper.permission_helper import (GroupRequiredMixin,
OwnerRequiredMixin,
group_required)
from cookbook.models import (Comment, Food, Ingredient, Keyword, MealPlan,
from cookbook.models import (Comment, Ingredient, MealPlan,
MealType, Recipe, RecipeBook, RecipeImport,
Storage, Sync, UserPreference)
from cookbook.provider.dropbox import Dropbox
@ -86,38 +86,38 @@ class SyncUpdate(GroupRequiredMixin, UpdateView, SpaceFormMixing):
return context
class KeywordUpdate(GroupRequiredMixin, UpdateView):
groups_required = ['user']
template_name = "generic/edit_template.html"
model = Keyword
form_class = KeywordForm
# class KeywordUpdate(GroupRequiredMixin, UpdateView):
# groups_required = ['user']
# template_name = "generic/edit_template.html"
# model = Keyword
# form_class = KeywordForm
# TODO add msg box
# # TODO add msg box
def get_success_url(self):
return reverse('list_keyword')
# def get_success_url(self):
# return reverse('list_keyword')
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['title'] = _("Keyword")
return context
# def get_context_data(self, **kwargs):
# context = super().get_context_data(**kwargs)
# context['title'] = _("Keyword")
# return context
class FoodUpdate(GroupRequiredMixin, UpdateView, SpaceFormMixing):
groups_required = ['user']
template_name = "generic/edit_template.html"
model = Food
form_class = FoodForm
# class FoodUpdate(GroupRequiredMixin, UpdateView, SpaceFormMixing):
# groups_required = ['user']
# template_name = "generic/edit_template.html"
# model = Food
# form_class = FoodForm
# TODO add msg box
# # TODO add msg box
def get_success_url(self):
return reverse('edit_food', kwargs={'pk': self.object.pk})
# def get_success_url(self):
# return reverse('edit_food', kwargs={'pk': self.object.pk})
def get_context_data(self, **kwargs):
context = super(FoodUpdate, self).get_context_data(**kwargs)
context['title'] = _("Food")
return context
# def get_context_data(self, **kwargs):
# context = super(FoodUpdate, self).get_context_data(**kwargs)
# context['title'] = _("Food")
# return context
@group_required('admin')
@ -279,6 +279,7 @@ class ExternalRecipeUpdate(GroupRequiredMixin, UpdateView, SpaceFormMixing):
return context
# TODO deprecate
@group_required('user')
def edit_ingredients(request):
if request.method == "POST":

View File

@ -5,11 +5,11 @@ from django.shortcuts import render
from django.utils.translation import gettext as _
from django_tables2 import RequestConfig
from cookbook.filters import FoodFilter, ShoppingListFilter
from cookbook.filters import ShoppingListFilter
from cookbook.helper.permission_helper import group_required
from cookbook.models import (Food, InviteLink, RecipeImport,
from cookbook.models import (InviteLink, RecipeImport,
ShoppingList, Storage, SyncLog)
from cookbook.tables import (ImportLogTable, IngredientTable, InviteLinkTable,
from cookbook.tables import (ImportLogTable, InviteLinkTable,
RecipeImportTable, ShoppingListTable, StorageTable)
@ -40,18 +40,18 @@ def recipe_import(request):
)
@group_required('user')
def food(request):
f = FoodFilter(request.GET, queryset=Food.objects.filter(space=request.space).all().order_by('pk'))
# @group_required('user')
# def food(request):
# f = FoodFilter(request.GET, queryset=Food.objects.filter(space=request.space).all().order_by('pk'))
table = IngredientTable(f.qs)
RequestConfig(request, paginate={'per_page': 25}).configure(table)
# table = IngredientTable(f.qs)
# RequestConfig(request, paginate={'per_page': 25}).configure(table)
return render(
request,
'generic/list_template.html',
{'title': _("Ingredients"), 'table': table, 'filter': f}
)
# return render(
# request,
# 'generic/list_template.html',
# {'title': _("Ingredients"), 'table': table, 'filter': f}
# )
@group_required('user')
@ -101,3 +101,13 @@ def invite_link(request):
'table': table,
'create_url': 'new_invite_link'
})
@group_required('user')
def keyword(request):
return render(request, 'model/keyword_template.html', {"title": _("Keywords")})
@group_required('user')
def food(request):
return render(request, 'generic/model_template.html', {"title": _("Foods")})

View File

@ -12,11 +12,11 @@ from django.urls import reverse, reverse_lazy
from django.utils.translation import gettext as _
from django.views.generic import CreateView
from cookbook.forms import (ImportRecipeForm, InviteLinkForm, KeywordForm,
from cookbook.forms import (ImportRecipeForm, InviteLinkForm,
MealPlanForm, RecipeBookForm, Storage, StorageForm)
from cookbook.helper.permission_helper import (GroupRequiredMixin,
group_required)
from cookbook.models import (InviteLink, Keyword, MealPlan, MealType, Recipe,
from cookbook.models import (InviteLink, MealPlan, MealType, Recipe,
RecipeBook, RecipeImport, ShareLink, Step, UserPreference)
from cookbook.views.edit import SpaceFormMixing
@ -60,22 +60,22 @@ def share_link(request, pk):
return HttpResponseRedirect(reverse('view_recipe', kwargs={'pk': pk, 'share': link.uuid}))
class KeywordCreate(GroupRequiredMixin, CreateView):
groups_required = ['user']
template_name = "generic/new_template.html"
model = Keyword
form_class = KeywordForm
success_url = reverse_lazy('list_keyword')
# class KeywordCreate(GroupRequiredMixin, CreateView):
# groups_required = ['user']
# template_name = "generic/new_template.html"
# model = Keyword
# form_class = KeywordForm
# success_url = reverse_lazy('list_keyword')
def form_valid(self, form):
form.cleaned_data['space'] = self.request.space
form.save()
return HttpResponseRedirect(reverse('list_keyword'))
# def form_valid(self, form):
# form.cleaned_data['space'] = self.request.space
# form.save()
# return HttpResponseRedirect(reverse('list_keyword'))
def get_context_data(self, **kwargs):
context = super(KeywordCreate, self).get_context_data(**kwargs)
context['title'] = _("Keyword")
return context
# def get_context_data(self, **kwargs):
# context = super(KeywordCreate, self).get_context_data(**kwargs)
# context['title'] = _("Keyword")
# return context
class StorageCreate(GroupRequiredMixin, CreateView):

View File

@ -1,13 +0,0 @@
from django.shortcuts import render
from cookbook.helper.permission_helper import group_required
@group_required('user')
def keyword(request):
return render(request, 'model/keyword_template.html', {})
@group_required('user')
def food(request):
return render(request, 'model/food_template.html', {})

View File

@ -67,7 +67,7 @@ import GenericModalForm from "@/components/Modals/GenericModalForm";
Vue.use(BootstrapVue)
export default {
name: 'FoodListView', // TODO: make generic name
name: 'ModelListView', // TODO: make generic name
mixins: [CardMixin, ToastMixin, ApiMixin],
components: {GenericHorizontalCard, GenericSplitLists, GenericModalForm},
data() {
@ -85,7 +85,8 @@ export default {
}
},
mounted() {
this.this_model = this.Models.FOOD //TODO: mounted method to calcuate
let path = (window.location.pathname).split('/')
this.this_model = this.Models[path[path.length - 2].toUpperCase()]
},
methods: {
// this.genericAPI inherited from ApiMixin

View File

@ -1,5 +1,5 @@
import Vue from 'vue'
import App from './FoodListView'
import App from './ModelListView'
import i18n from '@/i18n'
Vue.config.productionTip = false

View File

@ -96,7 +96,6 @@
</template>
<script>
import Vue from 'vue' // maybe not needed?
import 'bootstrap-vue/dist/bootstrap-vue.css'
import _debounce from 'lodash/debounce'
import InfiniteLoading from 'vue-infinite-loading';

View File

@ -29,8 +29,8 @@ const pages = {
entry: './src/apps/KeywordListView/main.js',
chunks: ['chunk-vendors']
},
'food_list_view': {
entry: './src/apps/FoodListView/main.js',
'model_list_view': {
entry: './src/apps/ModelListView/main.js',
chunks: ['chunk-vendors']
},
}

View File

@ -1,2 +1 @@
{"status":"done","chunks":{"recipe_search_view":["css/chunk-vendors.css","js/chunk-vendors.js","js/recipe_search_view.js"],"recipe_view":["css/chunk-vendors.css","js/chunk-vendors.js","js/recipe_view.js"],"offline_view":["css/chunk-vendors.css","js/chunk-vendors.js","js/offline_view.js"],"import_response_view":["css/chunk-vendors.css","js/chunk-vendors.js","js/import_response_view.js"],"supermarket_view":["css/chunk-vendors.css","js/chunk-vendors.js","js/supermarket_view.js"],"user_file_view":["css/chunk-vendors.css","js/chunk-vendors.js","js/user_file_view.js"],"keyword_list_view":["css/chunk-vendors.css","js/chunk-vendors.js","css/keyword_list_view.css","js/keyword_list_view.js"]},"assets":{"../../templates/sw.js":{"name":"../../templates/sw.js","path":"../../templates/sw.js"},"css/chunk-vendors.css":{"name":"css/chunk-vendors.css","path":"css/chunk-vendors.css"},"js/chunk-vendors.js":{"name":"js/chunk-vendors.js","path":"js/chunk-vendors.js"},"js/import_response_view.js":{"name":"js/import_response_view.js","path":"js/import_response_view.js"},"css/keyword_list_view.css":{"name":"css/keyword_list_view.css","path":"css/keyword_list_view.css"},"js/keyword_list_view.js":{"name":"js/keyword_list_view.js","path":"js/keyword_list_view.js"},"js/offline_view.js":{"name":"js/offline_view.js","path":"js/offline_view.js"},"js/recipe_search_view.js":{"name":"js/recipe_search_view.js","path":"js/recipe_search_view.js"},"js/recipe_view.js":{"name":"js/recipe_view.js","path":"js/recipe_view.js"},"js/supermarket_view.js":{"name":"js/supermarket_view.js","path":"js/supermarket_view.js"},"js/user_file_view.js":{"name":"js/user_file_view.js","path":"js/user_file_view.js"},"recipe_search_view.html":{"name":"recipe_search_view.html","path":"recipe_search_view.html"},"recipe_view.html":{"name":"recipe_view.html","path":"recipe_view.html"},"offline_view.html":{"name":"offline_view.html","path":"offline_view.html"},"import_response_view.html":{"name":"import_response_view.html","path":"import_response_view.html"},"supermarket_view.html":{"name":"supermarket_view.html","path":"supermarket_view.html"},"user_file_view.html":{"name":"user_file_view.html","path":"user_file_view.html"},"keyword_list_view.html":{"name":"keyword_list_view.html","path":"keyword_list_view.html"},"manifest.json":{"name":"manifest.json","path":"manifest.json"}}}
{"status":"done","chunks":{"recipe_search_view":["css/chunk-vendors.css","js/chunk-vendors.js","js/recipe_search_view.js"],"recipe_view":["css/chunk-vendors.css","js/chunk-vendors.js","js/recipe_view.js"],"offline_view":["css/chunk-vendors.css","js/chunk-vendors.js","js/offline_view.js"],"import_response_view":["css/chunk-vendors.css","js/chunk-vendors.js","js/import_response_view.js"],"supermarket_view":["css/chunk-vendors.css","js/chunk-vendors.js","js/supermarket_view.js"],"user_file_view":["css/chunk-vendors.css","js/chunk-vendors.js","js/user_file_view.js"],"keyword_list_view":["css/chunk-vendors.css","js/chunk-vendors.js","css/keyword_list_view.css","js/keyword_list_view.js"],"model_list_view":["css/chunk-vendors.css","js/chunk-vendors.js","css/model_list_view.css","js/model_list_view.js"]},"assets":{"../../templates/sw.js":{"name":"../../templates/sw.js","path":"../../templates/sw.js"},"css/chunk-vendors.css":{"name":"css/chunk-vendors.css","path":"css/chunk-vendors.css"},"js/chunk-vendors.js":{"name":"js/chunk-vendors.js","path":"js/chunk-vendors.js"},"js/import_response_view.js":{"name":"js/import_response_view.js","path":"js/import_response_view.js"},"css/keyword_list_view.css":{"name":"css/keyword_list_view.css","path":"css/keyword_list_view.css"},"js/keyword_list_view.js":{"name":"js/keyword_list_view.js","path":"js/keyword_list_view.js"},"css/model_list_view.css":{"name":"css/model_list_view.css","path":"css/model_list_view.css"},"js/model_list_view.js":{"name":"js/model_list_view.js","path":"js/model_list_view.js"},"js/offline_view.js":{"name":"js/offline_view.js","path":"js/offline_view.js"},"js/recipe_search_view.js":{"name":"js/recipe_search_view.js","path":"js/recipe_search_view.js"},"js/recipe_view.js":{"name":"js/recipe_view.js","path":"js/recipe_view.js"},"js/supermarket_view.js":{"name":"js/supermarket_view.js","path":"js/supermarket_view.js"},"js/user_file_view.js":{"name":"js/user_file_view.js","path":"js/user_file_view.js"},"recipe_search_view.html":{"name":"recipe_search_view.html","path":"recipe_search_view.html"},"recipe_view.html":{"name":"recipe_view.html","path":"recipe_view.html"},"offline_view.html":{"name":"offline_view.html","path":"offline_view.html"},"import_response_view.html":{"name":"import_response_view.html","path":"import_response_view.html"},"supermarket_view.html":{"name":"supermarket_view.html","path":"supermarket_view.html"},"user_file_view.html":{"name":"user_file_view.html","path":"user_file_view.html"},"keyword_list_view.html":{"name":"keyword_list_view.html","path":"keyword_list_view.html"},"model_list_view.html":{"name":"model_list_view.html","path":"model_list_view.html"},"manifest.json":{"name":"manifest.json","path":"manifest.json"}}}