Import and Export extended

This commit is contained in:
Dirk Alders 2020-09-01 12:37:25 +02:00
parent 1a03a45134
commit c46a60ed88
4 changed files with 199 additions and 29 deletions

View File

@ -1,4 +1,7 @@
KEY_USERDATA_VERSION = 'version'
KEY_USERDATA_FAVOURITE = 'favourite' KEY_USERDATA_FAVOURITE = 'favourite'
KEY_USERDATA_TAGS = 'tag' KEY_USERDATA_TAGS = 'tag'
KEY_USER_PROFILE = 'userprofile'
KEY_THEME_BOTTOMBAR = 'bottombar'
KEY_THEME_SETTINGS = 'settings'
KEY_USERDATA_UPLOAD = 'upload' KEY_USERDATA_UPLOAD = 'upload'
KEY_ACCESS_DATA = 'access_data'

View File

@ -1,11 +1,17 @@
from django.contrib.auth.models import User from django.contrib.auth.models import User
from django.core.management.base import BaseCommand from django.core.management.base import BaseCommand
import json import json
from pygal.models import Tag from themes.models import GetSettings
from themes.models import BottomBar
from users.models import UserProfile
from pygal.models import Item, Tag
from ._private import KEY_USERDATA_VERSION from ._private import KEY_THEME_SETTINGS
from ._private import KEY_THEME_BOTTOMBAR
from ._private import KEY_USER_PROFILE
from ._private import KEY_USERDATA_FAVOURITE from ._private import KEY_USERDATA_FAVOURITE
from ._private import KEY_USERDATA_TAGS from ._private import KEY_USERDATA_TAGS
from ._private import KEY_ACCESS_DATA
class Command(BaseCommand): class Command(BaseCommand):
@ -13,25 +19,55 @@ class Command(BaseCommand):
def handle(self, *args, **options): def handle(self, *args, **options):
data = {} data = {}
data[KEY_USERDATA_VERSION] = 1 #
# Access
#
if KEY_ACCESS_DATA not in data:
data[KEY_ACCESS_DATA] = {}
# public_access
data[KEY_ACCESS_DATA][''] = [item.rel_path for item in Item.objects.filter(public_access=True)]
# user_access
for u in User.objects.all():
data[KEY_ACCESS_DATA][u.username] = {}
data[KEY_ACCESS_DATA][u.username]['read_access'] = [item.rel_path for item in u.read_access.all()]
data[KEY_ACCESS_DATA][u.username]['modify_access'] = [item.rel_path for item in u.modify_access.all()]
#
# Favourites
#
if KEY_USERDATA_FAVOURITE not in data:
data[KEY_USERDATA_FAVOURITE] = {}
for user in User.objects.all(): for user in User.objects.all():
favourites = user.favourite_of.all() favourites = user.favourite_of.all()
if len(favourites) > 0: if len(favourites) > 0:
if KEY_USERDATA_FAVOURITE not in data:
data[KEY_USERDATA_FAVOURITE] = {}
data[KEY_USERDATA_FAVOURITE][user.username] = [i.rel_path for i in favourites] data[KEY_USERDATA_FAVOURITE][user.username] = [i.rel_path for i in favourites]
#
# Tags
#
if KEY_USERDATA_TAGS not in data:
data[KEY_USERDATA_TAGS] = {}
for tag in Tag.objects.all(): for tag in Tag.objects.all():
if KEY_USERDATA_TAGS not in data: tag_key = tag.export_key()
data[KEY_USERDATA_TAGS] = {} if tag_key not in data[KEY_USERDATA_TAGS]:
if tag.item.rel_path not in data[KEY_USERDATA_TAGS]: data[KEY_USERDATA_TAGS][tag_key] = []
data[KEY_USERDATA_TAGS][tag.item.rel_path] = [] data[KEY_USERDATA_TAGS][tag.export_key()].append(tag.export_data())
tagdata = {} #
tagdata['text'] = tag.text # Settings
if tag.has_valid_coordinates: #
tagdata['topleft_x'] = tag.topleft_x s = GetSettings()
tagdata['topleft_y'] = tag.topleft_y data[KEY_THEME_SETTINGS] = s.export_data()
tagdata['bottomright_x'] = tag.bottomright_x #
tagdata['bottomright_y'] = tag.bottomright_y # Bottombar
data[KEY_USERDATA_TAGS][tag.item.rel_path].append(tagdata) #
if KEY_THEME_BOTTOMBAR not in data:
data[KEY_THEME_BOTTOMBAR] = []
for bb_entry in BottomBar.objects.all():
data[KEY_THEME_BOTTOMBAR].append(bb_entry.export_data())
#
# Userprofile
#
if KEY_USER_PROFILE not in data:
data[KEY_USER_PROFILE] = {}
for profile in UserProfile.objects.all():
data[KEY_USER_PROFILE][profile.export_key()] = profile.export_data()
self.stdout.write(json.dumps(data, indent=4, sort_keys=True)) self.stdout.write(json.dumps(data, indent=4, sort_keys=True))

View File

@ -1,12 +1,17 @@
from django.contrib.auth.models import User from django.contrib.auth.models import User
from django.core.management.base import BaseCommand from django.core.management.base import BaseCommand
import json import json
from pygal.models import Item, Tag from pygal.models import Item, Tag, TagExist
from themes.models import GetSettings, SettingExist, BottomBar, BottomBarExist
import os import os
from ._private import KEY_USERDATA_VERSION
from ._private import KEY_USERDATA_FAVOURITE from ._private import KEY_USERDATA_FAVOURITE
from ._private import KEY_USERDATA_TAGS from ._private import KEY_USERDATA_TAGS
from ._private import KEY_USER_PROFILE
from ._private import KEY_THEME_SETTINGS
from ._private import KEY_THEME_BOTTOMBAR
from users.models import UserProfile, UserprofilerExist
from pygal.management.commands._private import KEY_ACCESS_DATA
class Command(BaseCommand): class Command(BaseCommand):
@ -25,10 +30,6 @@ class Command(BaseCommand):
try: try:
with open(fn, 'r') as fh: with open(fn, 'r') as fh:
data = json.load(fh) data = json.load(fh)
try:
version = data.pop(KEY_USERDATA_VERSION)
except KeyError:
version = 1
except PermissionError: except PermissionError:
self.error_skipped_file(fn, 'file permission') self.error_skipped_file(fn, 'file permission')
except json.decoder.JSONDecodeError: except json.decoder.JSONDecodeError:
@ -42,8 +43,75 @@ class Command(BaseCommand):
cnt_success = 0 cnt_success = 0
cnt_already_exist = 0 cnt_already_exist = 0
cnt_user_missing = 0 cnt_user_missing = 0
missing_users = []
cnt_item_missing = 0 cnt_item_missing = 0
if section == KEY_USERDATA_FAVOURITE: #
# Access
#
if section == KEY_ACCESS_DATA:
for username in data[section]:
if username == '':
# public_access
for rel_path in data[section][username]:
cnt_all_datasets += 1
try:
item = Item.objects.get(rel_path=rel_path)
except User.DoesNotExist:
cnt_item_missing += 1
else:
if item.public_access:
cnt_already_exist += 1
else:
item.public_access = True
item.save()
cnt_success += 1
else:
try:
user = User.objects.get(username=username)
except User.DoesNotExist:
user = None
# read_access
for rel_path in data[section][username]['read_access']:
cnt_all_datasets += 1
if user is None:
cnt_user_missing += 1
if username not in missing_users:
missing_users.append(username)
else:
try:
item = Item.objects.get(rel_path=rel_path)
except User.DoesNotExist:
cnt_item_missing += 1
else:
if user in item.read_access.all():
cnt_already_exist += 1
else:
item.read_access.add(user)
item.save()
cnt_success += 1
# modify_access
for rel_path in data[section][username]['modify_access']:
cnt_all_datasets += 1
if user is None:
cnt_user_missing += 1
if username not in missing_users:
missing_users.append(username)
else:
try:
item = Item.objects.get(rel_path=rel_path)
except User.DoesNotExist:
cnt_item_missing += 1
else:
if user in item.modify_access.all():
cnt_already_exist += 1
else:
item.modify_access.add(user)
item.save()
cnt_success += 1
#
# Favourites
#
elif section == KEY_USERDATA_FAVOURITE:
for username in data[section]: for username in data[section]:
try: try:
user = User.objects.get(username=username) user = User.objects.get(username=username)
@ -53,6 +121,8 @@ class Command(BaseCommand):
cnt_all_datasets += 1 cnt_all_datasets += 1
if user is None: if user is None:
cnt_user_missing += 1 cnt_user_missing += 1
if username not in missing_users:
missing_users.append(username)
try: try:
i = Item.objects.get(rel_path=rel_path) i = Item.objects.get(rel_path=rel_path)
except Item.DoesNotExist: except Item.DoesNotExist:
@ -60,9 +130,12 @@ class Command(BaseCommand):
else: else:
if user in i.favourite_of.all(): if user in i.favourite_of.all():
cnt_already_exist += 1 cnt_already_exist += 1
else: elif user is not None:
cnt_success += 1 cnt_success += 1
i.favourite_of.add(user) i.favourite_of.add(user)
#
# Tags
#
elif section == KEY_USERDATA_TAGS: elif section == KEY_USERDATA_TAGS:
for rel_path in data[section]: for rel_path in data[section]:
cnt_all_datasets += len(data[section][rel_path]) cnt_all_datasets += len(data[section][rel_path])
@ -72,12 +145,53 @@ class Command(BaseCommand):
cnt_item_missing += len(data[section][rel_path]) cnt_item_missing += len(data[section][rel_path])
else: else:
for tag_data in data[section][rel_path]: for tag_data in data[section][rel_path]:
if len(Tag.objects.filter(item=i, text=tag_data['text'])) > 0: if TagExist(i, tag_data):
cnt_already_exist += 1 cnt_already_exist += 1
else: else:
tag_data['item'] = i tag_data['item'] = i
Tag(**tag_data).save() Tag(**tag_data).save()
cnt_success += 1 cnt_success += 1
#
# Settings
#
elif section == KEY_THEME_SETTINGS:
cnt_all_datasets = 1
if SettingExist(data[section]):
cnt_already_exist += 1
else:
s = GetSettings()
s.import_data(data[section])
cnt_success += 1
#
# Bottombar
#
elif section == KEY_THEME_BOTTOMBAR:
cnt_all_datasets = len(data[section])
for bb_entry_import in data[section]:
if BottomBarExist(bb_entry_import):
cnt_already_exist += 1
else:
bb_entry = BottomBar()
bb_entry.import_data(bb_entry_import)
cnt_success += 1
#
# Userprofile
#
elif section == KEY_USER_PROFILE:
cnt_all_datasets = len(data[section])
for username in data[section]:
if UserprofilerExist(username, data[section][username]):
cnt_already_exist += 1
else:
try:
user = User.objects.get(username=username)
except User.DoesNotExist:
cnt_user_missing += 1
missing_users.append(username)
else:
profile = UserProfile(user=user)
profile.import_data(data[section][username])
cnt_success += 1
else: else:
self.stdout.write(self.style.ERROR(' Section unknown!')) self.stdout.write(self.style.ERROR(' Section unknown!'))
# #
@ -93,6 +207,6 @@ class Command(BaseCommand):
self.stdout.write(style(' %5d %s(s) successfully added.' % (cnt_success, section))) self.stdout.write(style(' %5d %s(s) successfully added.' % (cnt_success, section)))
self.stdout.write(style(' %5d %s(s) already set correctly.' % (cnt_already_exist, section))) self.stdout.write(style(' %5d %s(s) already set correctly.' % (cnt_already_exist, section)))
if cnt_user_missing > 0: if cnt_user_missing > 0:
self.stdout.write(self.style.ERROR(' %5d %s(s) not added, because the target user does not exist.' % (cnt_user_missing, section))) self.stdout.write(self.style.ERROR(' %5d %s(s) not added, because the target user(s) %s do(es) not exist.' % (cnt_user_missing, section, repr(missing_users))))
if cnt_item_missing > 0: if cnt_item_missing > 0:
self.stdout.write(self.style.ERROR(' %5d %s(s) not added, because the target item does not exist.' % (cnt_item_missing, section))) self.stdout.write(self.style.ERROR(' %5d %s(s) not added, because the target item does not exist. Try python manage.py rebuild_cache to create items, if you import to a scratch database.' % (cnt_item_missing, section)))

View File

@ -447,6 +447,10 @@ class Item(models.Model):
return 'Item: %s' % self.rel_path return 'Item: %s' % self.rel_path
def TagExist(item, data):
return len(Tag.objects.filter(item=item, text=data['text'])) > 0
class Tag(models.Model): class Tag(models.Model):
item = models.ForeignKey(Item, on_delete=models.CASCADE) item = models.ForeignKey(Item, on_delete=models.CASCADE)
text = models.CharField(max_length=100) text = models.CharField(max_length=100)
@ -468,3 +472,16 @@ class Tag(models.Model):
"""the url to the Django admin interface for the model instance""" """the url to the Django admin interface for the model instance"""
info = (self._meta.app_label, self._meta.model_name) info = (self._meta.app_label, self._meta.model_name)
return reverse('admin:%s_%s_change' % info, args=(self.pk,)) return reverse('admin:%s_%s_change' % info, args=(self.pk,))
def export_key(self):
return self.item.rel_path
def export_data(self):
rv = {}
rv['text'] = self.text
if self.has_valid_coordinates:
rv['topleft_x'] = self.topleft_x
rv['topleft_y'] = self.topleft_y
rv['bottomright_x'] = self.bottomright_x
rv['bottomright_y'] = self.bottomright_y
return rv