from functools import lru_cache

from django.core.management.base import BaseCommand, CommandError
from django.db import transaction

from events.models import Event, Keyword, KeywordSet, DataSource

HELSINKI_KEYWORD_SET_DATA = {
    'id': 'helsinki:topics',
    'name_en': 'Helsinki topics',
    'name_fi': 'Helsinki-aihepiirit',
    'name_sv': 'Helsingfors-teman',
    'data_source_id': 'helsinki',
    'usage': KeywordSet.KEYWORD,
}

HELSINKI_KEYWORD_IDS = [
    'yso:p1235', #elokuvat
    'yso:p1947', #hyvinvointi
    'yso:p14004', #keskustelu
    'yso:p11185', #konsertit
    'yso:p360', #kulttuuritapahtumat
    'yso:p2739', #kuvataide
    'yso:p316', #leikkiminen
    'yso:p916', #liikunta
    'yso:p15875', #luennot
    'yso:p1808', #musiikki
    'yso:p5121', #näyttelyt
    'yso:p2149', #opastus
    'yso:p10727', #osallistuminen
    'yso:p6062', #pelit
    'yso:p3670', #ruoka
    'yso:p1278', #tanssi
    'yso:p2625', #teatteritaide
    'yso:p19245', #työpajat
    'yso:p2771', #ulkoilu
    'yso:p965' #urheilu
]

class Command(BaseCommand):
    help = "Creates Helsinki topics keyword set."

    @lru_cache()
    def get_keyword_obj(self, keyword_id):
        try:
            keyword = Keyword.objects.get(id=keyword_id)
        except Keyword.DoesNotExist:
            raise CommandError('keyword "%s" does not exist' % keyword_id)
        return keyword

    @transaction.atomic()
    def create_helsinki_topics_keyword_set(self):
        self.stdout.write('creating Helsinki topics keyword set...')

        # create the set itself
        keyword_set, created = KeywordSet.objects.update_or_create(
            id=HELSINKI_KEYWORD_SET_DATA['id'],
            defaults=HELSINKI_KEYWORD_SET_DATA
        )
        if created:
            self.stdout.write('created keyword set "%s"' % HELSINKI_KEYWORD_SET_DATA['id'])
        else:
            self.stdout.write('keyword set "%s" already exist' % HELSINKI_KEYWORD_SET_DATA['id'])

        # add the keywords to the set
        existing_keywords = set(keyword_set.keywords.all())
        for keyword_id in HELSINKI_KEYWORD_IDS:
            keyword = self.get_keyword_obj(keyword_id)

            if keyword not in existing_keywords:
                keyword_set.keywords.add(keyword)
                existing_keywords.add(keyword)
                self.stdout.write('added %s (%s) to the keyword set' % (keyword.name, keyword_id))

    def handle(self, *args, **options):
        # Helsinki data source must be created if missing. Note that it is not necessarily the system data source.
        # If we are creating it, it *may* still be the system data source, so it must be user editable!
        helsinki_data_source_defaults = {'user_editable': True}
        DataSource.objects.get_or_create(id=HELSINKI_KEYWORD_SET_DATA['data_source_id'],
                                         defaults=helsinki_data_source_defaults)
        self.create_helsinki_topics_keyword_set()
        self.stdout.write('all done')

@@ -156,15 +156,8 @@
 port
- Event,
  Key
@@ -185,16 +185,16 @@
 aSource%0A
+
 %0AHELSINK
@@ -465,17 +465,19 @@
 p1235', 
-#
+ # 
 elokuvat
@@ -493,18 +493,20 @@
 :p1947',
+ 
  #
+ 
 hyvinvoi
@@ -527,17 +527,19 @@
 14004', 
-#
+ # 
 keskuste
@@ -559,17 +559,19 @@
 11185', 
-#
+ # 
 konserti
@@ -588,17 +588,19 @@
 :p360', 
-#
+ # 
 kulttuur
@@ -627,18 +627,20 @@
 :p2739',
+ 
  #
+ 
 kuvataid
@@ -657,17 +657,19 @@
 :p316', 
-#
+ # 
 leikkimi
@@ -688,17 +688,19 @@
 :p916', 
-#
+ # 
 liikunta
@@ -718,17 +718,19 @@
 15875', 
-#
+ # 
 luennot%0A
@@ -745,18 +745,20 @@
 :p1808',
+ 
  #
+ 
 musiikki
@@ -774,18 +774,20 @@
 :p5121',
+ 
  #
+ 
 n%C3%A4yttely
@@ -805,17 +805,19 @@
 p2149', 
-#
+ # 
 opastus%0A
@@ -834,17 +834,19 @@
 10727', 
-#
+ # 
 osallist
@@ -869,17 +869,19 @@
 p6062', 
-#
+ # 
 pelit%0A  
@@ -894,18 +894,20 @@
 :p3670',
+ 
  #
+ 
 ruoka%0A  
@@ -920,18 +920,20 @@
 :p1278',
+ 
  #
+ 
 tanssi%0A 
@@ -948,17 +948,19 @@
 p2625', 
-#
+ # 
 teatteri
@@ -983,17 +983,19 @@
 19245', 
-#
+ # 
 ty%C3%B6pajat
@@ -1012,17 +1012,19 @@
 p2771', 
-#
+ # 
 ulkoilu%0A
@@ -1038,17 +1038,19 @@
 o:p965' 
-#
+ # 
 urheilu%0A
@@ -1052,16 +1052,17 @@
 eilu%0A%5D%0A%0A
+%0A
 class Co

Fix helsinki_topics flake8