<commit_before># -*- coding: utf-8 -*-
"""
Detect new translatable fields in all models and sync database structure.

You will need to execute this command in two cases:

    1. When you add new languages to settings.LANGUAGES.
    2. When you add new translatable fields to your models.

Credits: Heavily inspired by django-transmeta's sync_transmeta_db command.
"""
from django import VERSION
from django.core.management.base import BaseCommand
from django.core.management.color import no_style
from django.db import connection
from django.utils.six import moves

from modeltranslation.settings import AVAILABLE_LANGUAGES
from modeltranslation.translator import translator
from modeltranslation.utils import build_localized_fieldname


def ask_for_confirmation(sql_sentences, model_full_name, interactive):
    print('\nSQL to synchronize "%s" schema:' % model_full_name)
    for sentence in sql_sentences:
        print('   %s' % sentence)
    while True:
        prompt = '\nAre you sure that you want to execute the previous SQL: (y/n) [n]: '
        if interactive:
            answer = moves.input(prompt).strip()
        else:
            answer = 'y'
        if answer == '':
            return False
        elif answer not in ('y', 'n', 'yes', 'no'):
            print('Please answer yes or no')
        elif answer == 'y' or answer == 'yes':
            return True
        else:
            return False


def print_missing_langs(missing_langs, field_name, model_name):
    print('Missing languages in "%s" field from "%s" model: %s' % (
        field_name, model_name, ", ".join(missing_langs)))


class Command(BaseCommand):
    help = ('Detect new translatable fields or new available languages and'
            ' sync database structure. Does not remove columns of removed'
            ' languages or undeclared fields.')

    if VERSION < (1, 8):
        from optparse import make_option
        option_list = BaseCommand.option_list + (
            make_option('--noinput', action='store_false', dest='interactive', default=True,
                        help='Do NOT prompt the user for input of any kind.'),
        )
    else:
        def add_arguments(self, parser):
            parser.add_argument('--noinput', action='store_false', dest='interactive', default=True,
                                help='Do NOT prompt the user for input of any kind.'),

    def handle(self, *args, **options):
        """
        Command execution.
        """
        self.cursor = connection.cursor()
        self.introspection = connection.introspection
        self.interactive = options['interactive']

        found_missing_fields = False
        models = translator.get_registered_models(abstract=False)
        for model in models:
            db_table = model._meta.db_table
            model_name = model._meta.model_name
            model_full_name = '%s.%s' % (model._meta.app_label, model_name)
            opts = translator.get_options_for_model(model)
            for field_name, fields in opts.local_fields.items():
                # Take `db_column` attribute into account
                field = list(fields)[0]
                column_name = field.db_column if field.db_column else field_name
                missing_langs = list(self.get_missing_languages(column_name, db_table))
                if missing_langs:
                    found_missing_fields = True
                    print_missing_langs(missing_langs, field_name, model_full_name)
                    sql_sentences = self.get_sync_sql(field_name, missing_langs, model)
                    execute_sql = ask_for_confirmation(
                        sql_sentences, model_full_name, self.interactive)
                    if execute_sql:
                        print('Executing SQL...')
                        for sentence in sql_sentences:
                            self.cursor.execute(sentence)
                        print('Done')
                    else:
                        print('SQL not executed')

        if not found_missing_fields:
            print('No new translatable fields detected')

    def get_table_fields(self, db_table):
        """
        Gets table fields from schema.
        """
        db_table_desc = self.introspection.get_table_description(self.cursor, db_table)
        return [t[0] for t in db_table_desc]

    def get_missing_languages(self, field_name, db_table):
        """<commit_msg>fix error in handling proxy model<commit_after># -*- coding: utf-8 -*-
"""
Detect new translatable fields in all models and sync database structure.

You will need to execute this command in two cases:

    1. When you add new languages to settings.LANGUAGES.
    2. When you add new translatable fields to your models.

Credits: Heavily inspired by django-transmeta's sync_transmeta_db command.
"""
from django import VERSION
from django.core.management.base import BaseCommand
from django.core.management.color import no_style
from django.db import connection
from django.utils.six import moves

from modeltranslation.settings import AVAILABLE_LANGUAGES
from modeltranslation.translator import translator
from modeltranslation.utils import build_localized_fieldname


def ask_for_confirmation(sql_sentences, model_full_name, interactive):
    print('\nSQL to synchronize "%s" schema:' % model_full_name)
    for sentence in sql_sentences:
        print('   %s' % sentence)
    while True:
        prompt = '\nAre you sure that you want to execute the previous SQL: (y/n) [n]: '
        if interactive:
            answer = moves.input(prompt).strip()
        else:
            answer = 'y'
        if answer == '':
            return False
        elif answer not in ('y', 'n', 'yes', 'no'):
            print('Please answer yes or no')
        elif answer == 'y' or answer == 'yes':
            return True
        else:
            return False


def print_missing_langs(missing_langs, field_name, model_name):
    print('Missing languages in "%s" field from "%s" model: %s' % (
        field_name, model_name, ", ".join(missing_langs)))


class Command(BaseCommand):
    help = ('Detect new translatable fields or new available languages and'
            ' sync database structure. Does not remove columns of removed'
            ' languages or undeclared fields.')

    if VERSION < (1, 8):
        from optparse import make_option
        option_list = BaseCommand.option_list + (
            make_option('--noinput', action='store_false', dest='interactive', default=True,
                        help='Do NOT prompt the user for input of any kind.'),
        )
    else:
        def add_arguments(self, parser):
            parser.add_argument('--noinput', action='store_false', dest='interactive', default=True,
                                help='Do NOT prompt the user for input of any kind.'),

    def handle(self, *args, **options):
        """
        Command execution.
        """
        self.cursor = connection.cursor()
        self.introspection = connection.introspection
        self.interactive = options['interactive']

        found_missing_fields = False
        models = translator.get_registered_models(abstract=False)
        for model in models:
            db_table = model._meta.db_table
            model_name = model._meta.model_name
            model_full_name = '%s.%s' % (model._meta.app_label, model_name)
            opts = translator.get_options_for_model(model)
            for field_name, fields in opts.local_fields.items():
                # Take `db_column` attribute into account
                try:
                    field = list(fields)[0]
                except IndexError:
                    # Ignore IndexError for ProxyModel
                    # maybe there is better way to handle this
                    continue
                column_name = field.db_column if field.db_column else field_name
                missing_langs = list(self.get_missing_languages(column_name, db_table))
                if missing_langs:
                    found_missing_fields = True
                    print_missing_langs(missing_langs, field_name, model_full_name)
                    sql_sentences = self.get_sync_sql(field_name, missing_langs, model)
                    execute_sql = ask_for_confirmation(
                        sql_sentences, model_full_name, self.interactive)
                    if execute_sql:
                        print('Executing SQL...')
                        for sentence in sql_sentences:
                            self.cursor.execute(sentence)
                        print('Done')
                    else:
                        print('SQL not executed')

        if not found_missing_fields:
            print('No new translatable fields detected')

    def get_table_fields(self, db_table):
        """
        Gets table fields from schema.
        """
        db_table_desc = self.introspection.get_table_description(self.cursor, db_table)
        return [t[0] for t in db_table_desc]

    def get_missing_languages(self, field_name, db_table):
        """
{'fraction_non_alphanumeric': 0.08402249421104863, 'fraction_numerical': 0.0015437203660822582, 'mean_word_length': 2.204946996466431, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5011409', 'n_tokens_mistral': 2416, 'n_tokens_neox': 2334, 'n_words': 705}