import_package.py 8.68 KB
Newer Older
Janez K's avatar
Janez K committed
1
from unicodedata import category
2
from django.core.management.base import BaseCommand, CommandError
3
from workflows.models import Category, AbstractWidget, AbstractInput, AbstractOutput, AbstractOption, Widget
4
from django.core import serializers
Janez K's avatar
Janez K committed
5 6 7 8 9 10 11
from optparse import make_option
import uuid
import os
import sys
from django.conf import settings
import json
from .export_package import serialize_category, serialize_widget
12
from django.core.management.color import color_style
Janez K's avatar
Janez K committed
13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30

def parsewidgetdata(widget_data):
    widget = None
    inputs = []
    outputs = []
    options = []
    for i in widget_data:
        if i['model']=='workflows.abstractwidget':
            widget = i
        elif i['model']=='workflows.abstractinput':
            inputs.append(i)
        elif i['model']=='workflows.abstractoutput':
            outputs.append(i)
        elif i['model']=='workflows.abstractoption':
            options.append(i)
        else:
            raise CommandError("Wrong data in widget files!")
    return widget, inputs, outputs, options
31

Janez K's avatar
Janez K committed
32
def import_package(package_name,writer):
33
    style = color_style()
Janez K's avatar
Janez K committed
34 35
    package_directory = os.path.join(os.path.dirname(os.path.realpath(__file__)),'../../'+package_name+"/package_data/")
    widgets_directory = os.path.join(package_directory,"widgets")
36
    deprecated_widgets_directory = os.path.join(package_directory,"deprecated_widgets")
Janez K's avatar
Janez K committed
37
    categories_directory = os.path.join(package_directory,"categories")        
38

Janez K's avatar
Janez K committed
39 40
    if not os.path.exists(package_directory) or not os.path.exists(widgets_directory) or not os.path.exists(categories_directory):
        raise CommandError("Cannot find package data. Are you sure this package has been exported already?")
41

42 43 44 45
    try:
        deprecated_widgets_files = os.listdir(deprecated_widgets_directory)
    except:
        deprecated_widgets_files = []
Janez K's avatar
Janez K committed
46 47
    widget_files = os.listdir(widgets_directory)
    category_files = os.listdir(categories_directory)
48

Janez K's avatar
Janez K committed
49
    writer.write(' > Importing categories\n')
50

Janez K's avatar
Janez K committed
51
    global_change = False
52

Janez K's avatar
Janez K committed
53 54 55 56 57 58 59
    for category_file in category_files:
        cfilepath = os.path.join(categories_directory,category_file)
        c_file = open(cfilepath,'r')
        c_data = json.loads(c_file.read())
        c_file.close()
        uid = c_data['fields']['uid']
        created = False
60
        try:
Janez K's avatar
Janez K committed
61 62 63 64 65 66 67 68 69
            c = Category.objects.get(uid=uid)
        except Category.DoesNotExist:
            created = True
            c = Category(uid=uid)
        old_c_data = serialize_category(c)
        if old_c_data != c_data:
            global_change = True
            if created:
                writer.write('   + Creating category '+str(c_data['fields']['name'])+'\n')
70
            else:
Janez K's avatar
Janez K committed
71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86
                writer.write('   + Updating category '+str(c_data['fields']['name'])+'\n')
            for field in c_data['fields'].keys():
                if field != 'parent':
                    setattr(c,field,c_data['fields'][field])
                else:
                    parent = None
                    if c_data['fields']['parent'] != None:
                        try:
                            parent = Category.objects.get(uid=c_data['fields']['parent'])
                        except Category.DoesNotExist:
                            parent = Category(uid=c_data['fields']['parent'],name="Temporary category name")
                            parent.save()
                    c.parent = parent
            c.save()

    if not global_change:
87 88
        #writer.write("    No changes detected in the categories.\n")
        pass
Janez K's avatar
Janez K committed
89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109

    global_change = False

    writer.write(' > Importing widgets\n')

    for widget_file in widget_files:
        wfilepath = os.path.join(widgets_directory,widget_file)
        w_file = open(wfilepath,'r')
        w_data = json.loads(w_file.read())
        w_file.close()
        widget, inputs, outputs, options = parsewidgetdata(w_data)
        created = False
        try:
            aw = AbstractWidget.objects.get(uid=widget['fields']['uid'],package=package_name)
        except AbstractWidget.DoesNotExist:
            aw = AbstractWidget(uid=widget['fields']['uid'],package=package_name)
            created = True
        if w_data != serialize_widget(aw):
            global_change = True
            if created:
                writer.write('   + Creating widget '+str(widget['fields']['name'])+'\n')
110
            else:
Janez K's avatar
Janez K committed
111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127
                writer.write('   + Updating widget '+str(widget['fields']['name'])+'\n')
            for field in widget['fields'].keys():
                if field != 'category':
                    setattr(aw,field,widget['fields'][field])
                else:
                    aw.category = Category.objects.get(uid=widget['fields']['category'])
            aw.save()
            for inp in inputs:
                try:
                    i = AbstractInput.objects.get(uid=inp['fields']['uid'])
                except AbstractInput.DoesNotExist:
                    i = AbstractInput(uid=inp['fields']['uid'])
                for field in inp['fields'].keys():
                    if field != 'widget':
                        setattr(i,field,inp['fields'][field])
                i.widget = aw
                i.save()
Janez K's avatar
Janez K committed
128 129
            # find stale inputs
            stale_ais = AbstractInput.objects.filter(widget=aw).exclude(uid__in=[inp['fields']['uid'] for inp in inputs])
130 131 132
            if stale_ais:
                stale_ais.delete()
                writer.write("     - Removing stale inputs\n")
Janez K's avatar
Janez K committed
133 134 135 136 137 138 139 140 141 142
            for out in outputs:
                try:
                    o = AbstractOutput.objects.get(uid=out['fields']['uid'])
                except AbstractOutput.DoesNotExist:
                    o = AbstractOutput(uid=out['fields']['uid'])
                for field in out['fields'].keys():
                    if field != 'widget':
                        setattr(o,field,out['fields'][field])
                o.widget = aw
                o.save()
143 144 145 146
            stale_aos = AbstractOutput.objects.filter(widget=aw).exclude(uid__in=[out['fields']['uid'] for out in outputs])
            if stale_aos:
                stale_aos.delete()
                writer.write("     - Removing stale outputs\n")
Janez K's avatar
Janez K committed
147 148 149 150 151 152 153 154 155 156 157
            for option in options:
                try:
                    o = AbstractOption.objects.get(uid=option['fields']['uid'])
                except AbstractOption.DoesNotExist:
                    o = AbstractOption(uid=option['fields']['uid'])
                for field in option['fields'].keys():
                    if field != 'abstract_input':
                        setattr(o,field,option['fields'][field])
                    else:
                        o.abstract_input = AbstractInput.objects.get(uid=option['fields']['abstract_input'])
                o.save()
158 159 160 161
            stale_os = AbstractOption.objects.filter(abstract_input__widget=aw).exclude(uid__in=[o['fields']['uid'] for o in options])
            if stale_os:
                stale_os.delete()
                writer.write("     - Removing stale options\n")
Janez K's avatar
Janez K committed
162

163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180
    if deprecated_widgets_files:
        for deprecated_widget_file in deprecated_widgets_files:
            wfilepath = os.path.join(deprecated_widgets_directory,deprecated_widget_file)
            w_file = open(wfilepath,'r')
            w_data = json.loads(w_file.read())
            w_file.close()
            widget, inputs, outputs, options = parsewidgetdata(w_data)
            created = False
            try:
                aw = AbstractWidget.objects.get(uid=widget['fields']['uid'],package=package_name)
                if Widget.objects.filter(abstract_widget=aw).count()==0:
                    writer.write('   - Removing widget '+str(widget['fields']['name'])+'\n')
                    aw.delete()
                else:
                    writer.write(style.ERROR('   - The widget '+str(widget['fields']['name'])+' is still used in workflows. It was not removed, but it is deprecated!\n'))
            except AbstractWidget.DoesNotExist:
                pass

Janez K's avatar
Janez K committed
181
    if not global_change:
182 183
        #writer.write("    No changes detected in the widgets.\n")
        pass
Janez K's avatar
Janez K committed
184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204



class Command(BaseCommand):
    args = 'package_name'
    help = 'Imports the package "package_name".'

    def handle(self, *args, **options):
        if (len(args) < 1):
            raise CommandError('Argument "package_name" is required.')

        package_name = args[0]

        if 'workflows.'+package_name not in settings.INSTALLED_APPS:
            raise CommandError("Package not found in INSTALLED_APPS.")

        writer = self.stdout

        import_package(package_name,writer)

        writer.write('Thanks for using the new import command. You rock.\n')