# -*- coding: utf-8 -*-
import os
from importlib import import_module

from django.db import migrations
from django.db.migrations.loader import MigrationLoader
from django.db.migrations.operations.base import Operation
from djangae.contrib.contenttypes.models import SimulatedContentTypeManager


class PatchMigrationsOperation(Operation):

    def database_forwards(self, app_label, schema_editor, from_state, to_state):
        pass

    def database_backwards(self, app_label, schema_editor, from_state, to_state):
        pass

    def state_forwards(self, app_label, state):
        """ Patch manager on ModelState during migrations """
        contenttype = state.models[('contenttypes', 'contenttype')]
        contenttype.managers[0] = ('objects', SimulatedContentTypeManager(model=contenttype))


def get_installed_app_labels_with_migrations():
    """ Get the app labels, because settings.INSTALLED_APPS doesn't necessarily give us the labels.
        Remove django.contrib.contenttypes because we want it to run before us.
        Return list of tuples like ('admin', '__first__')
    """
    from django.apps import apps
    apps_with_migrations = []
    for app in apps.get_app_configs():
        if app.label == 'contenttypes':
            continue  # Ignore the contenttypes app

        migrations_module = MigrationLoader.migrations_module(app.label)
        try:
            module = import_module(migrations_module)
        except ImportError:
            continue

        if not hasattr(module, "__path__"):
            continue

        # Make sure there are python files in the migration folder
        has_files = bool(x for x in os.listdir(module.__path__[0]) if x.endswith(".py"))
        if not has_files:
            continue

        apps_with_migrations.append(app.label)

    return [(x, '__first__') for x in apps_with_migrations]


class Migration(migrations.Migration):

    run_before = get_installed_app_labels_with_migrations()

    dependencies = [
        ('contenttypes', '__first__')
    ]

    operations = [
        PatchMigrationsOperation(),
    ]

# -*- coding: utf-8 -*-
import os
from importlib import import_module

from django.db import migrations
from django.db.migrations.loader import MigrationLoader
from django.db.migrations.operations.base import Operation
from djangae.contrib.contenttypes.models import SimulatedContentTypeManager


class PatchMigrationsOperation(Operation):

    def database_forwards(self, app_label, schema_editor, from_state, to_state):
        pass

    def database_backwards(self, app_label, schema_editor, from_state, to_state):
        pass

    def state_forwards(self, app_label, state):
        """ Patch manager on ModelState during migrations """
        contenttype = state.models[('contenttypes', 'contenttype')]
        contenttype.managers[0] = ('objects', SimulatedContentTypeManager(model=contenttype))


def get_installed_app_labels_with_migrations():
    """ Get the app labels, because settings.INSTALLED_APPS doesn't necessarily give us the labels.
        Remove django.contrib.contenttypes because we want it to run before us.
        Return list of tuples like ('admin', '__first__')
    """
    from django.apps import apps
    apps_with_migrations = []
    for app in apps.get_app_configs():
        if app.label == 'contenttypes':
            continue  # Ignore the contenttypes app

        migrations_module = MigrationLoader.migrations_module(app.label)
        try:
            module = import_module(migrations_module)
        except ImportError:
            continue

        if not hasattr(module, "__path__"):
            continue

        # Make sure there are python files in the migration folder
        has_files = any(x for x in os.listdir(module.__path__[0]) if x.endswith(".py"))
        if not has_files:
            continue

        apps_with_migrations.append(app.label)

    return [(x, '__first__') for x in apps_with_migrations]


class Migration(migrations.Migration):

    run_before = get_installed_app_labels_with_migrations()

    dependencies = [
        ('contenttypes', '__first__')
    ]

    operations = [
        PatchMigrationsOperation(),
    ]

Improve efficiency of contenttype migration detection by using `any` instead of `bool` on generator.