def handle(self, *args, **options):
        if options.get('email'):
            email = options['email']
        else:
            email = None
            while not email:
                email = input("Enter email address: ")

        if options.get('first-name'):
            first_name = options['first-name']
        else:
            default = email.split('@')[0].title()
            first_name = input("Enter first name ({0}): ".format(default)) or default

        if options.get('last-name'):
            last_name = options['last-name']
        else:
            default = email.split('@')[1].split('.')[0].title()
            last_name = input("Enter last name ({0}): ".format(default)) or default

        if options.get('username'):
            username = options['username']
        else:
            default = email.split('@')[0]
            username = input("Enter username ({0}): ".format(default)) or default

        token = generate_token(email=email, username=username,
                               first_name=first_name, last_name=last_name)
        self.stdout.write('Token:  {0}'.format(token))
Esempio n. 2
0
    def __call__(self, command, options):

        original = None
        with open(options["path"]) as data:
            original = data.read()
            fixture = json.loads(original)

        updated = {}
        for key in fixture.iterkeys():
            response = serialize_from_query(key)
            if isinstance(response, HttpResponseBadRequest):
                print response
                break
            else:
                updated[key] = response.data

        new_data = json.dumps(updated, indent=2)
        if new_data == original:
            command.stdout.write("No change!")
            return

        print "".join(difflib.unified_diff(original.splitlines(True),
                                           new_data.splitlines(True)))

        msg = ("\nThere are differences between the old an new data. "
               "Update? (yes/no): ")
        confirm = input(msg)
        while True:
            if confirm not in ('yes', 'no'):
                confirm = input('Please enter either "yes" or "no": ')
                continue
            if confirm == 'yes':
                with open(options["path"], 'w') as data:
                    data.write(new_data)
            break
    def confirm_proceed(self, prompt):
        """
        Prompts the user for yes/no confirmation to proceed.
        """
        # Ensure stdout can handle Unicode data: http://bit.ly/1C3l4eV
        locale_encoding = locale.getpreferredencoding()
        old_stdout = sys.stdout
        sys.stdout = codecs.getwriter(locale_encoding)(sys.stdout)

        # Send the confirmation prompt out to the user
        user_input = input(prompt)

        confirm = None

        while confirm is None:
            if user_input.lower() in ['y', 'yes']:
                confirm = True
            elif user_input.lower() in ['n', 'no']:
                confirm = False
            else:
                user_input = input("Invalid input. Please type 'yes', 'no', 'y' or 'n':\n")

        # Set things back to the way they were before continuing.
        sys.stdout = old_stdout

        # Pass back what the user typed
        return confirm
Esempio n. 4
0
 def ask_not_null_addition(self, field_name, model_name):
     "Adding a NOT NULL field to a model"
     choice = self._choice_input(
         "You are trying to add a non-nullable field '%s' to %s without a default;\n" % (field_name, model_name)
         + "we can't do that (the database needs something to populate existing rows).\n"
         + "Please select a fix:",
         [
             "Provide a one-off default now (will be set on all existing rows)",
             "Quit, and let me add a default in models.py",
         ],
     )
     if choice == 2:
         sys.exit(3)
     else:
         print("Please enter the default value now, as valid Python")
         print("The datetime module is available, so you can do e.g. datetime.date.today()")
         while True:
             if six.PY3:
                 # Six does not correctly abstract over the fact that
                 # py3 input returns a unicode string, while py2 raw_input
                 # returns a bytestring.
                 code = input(">>> ")
             else:
                 code = input(">>> ").decode(sys.stdin.encoding)
             if not code:
                 print("Please enter some code, or 'exit' (with no quotes) to exit.")
             elif code == "exit":
                 sys.exit(1)
             else:
                 try:
                     return eval(code, {}, {"datetime": datetime_safe})
                 except (SyntaxError, NameError) as e:
                     print("Invalid input: %s" % e)
Esempio n. 5
0
 def _boolean_input(self, question, default=None):
     result = input("%s " % question)
     if not result and default is not None:
         return default
     while len(result) < 1 or result[0].lower() not in "yn":
         result = input("Please answer yes or no: ")
     return result[0].lower() == "y"
Esempio n. 6
0
    def handle(self, *args, **options):
        tenant_model = get_tenant_model()
        # Attempt to build the instance based on specified data
        try:
            tenant = tenant_model(None, *args)
        except IndexError:
            opts = tenant_model._meta
            field_names = tuple(
                field.name for field in opts.local_fields if not field.primary_key
            )
            raise CommandError(
                "Number of args exceeds the number of fields for model %s.%s.\n"
                "Got %s when defined fields are %s." % (
                    opts.app_label,
                    opts.object_name,
                    args,
                    field_names
                )
            )

        # Full clean the instance
        try:
            tenant.full_clean()
        except ValidationError as e:
            name, messages = e.message_dict.popitem()
            raise CommandError(
                'Invalid value for field "%s": %s.' % (name, messages[0])
            )

        # Redirect the output of the schema creation logger to our stdout.
        handler = CommandLoggingHandler(
            self.stdout._out, self.stderr._out, int(options['verbosity'])
        )
        logger = logging.getLogger('tenancy')
        logger.setLevel(handler.level)
        logger.addHandler(handler)

        # Create the tenant instance and create tables
        tenant.save(force_insert=True)

        # Remove the handler associated with the schema creation logger.
        logger.removeHandler(handler)
        logger.setLevel(logging.NOTSET)

        from ...settings import TENANT_AUTH_USER_MODEL
        if options.get('interactive', True) and TENANT_AUTH_USER_MODEL:
            confirm = input(
                "\nYou just created a new tenant, which means you don't have "
                "any superusers defined.\nWould you like to create one "
                "now? (yes/no): "
            )
            while True:
                if confirm not in ('yes', 'no'):
                    confirm = input('Please enter either "yes" or "no": ')
                else:
                    if confirm == 'yes':
                        call_command('createsuperuser', tenant=tenant, **options)
                    break
Esempio n. 7
0
 def migrate_author(self, author_name):
     """
     Handle actions for migrating the authors.
     """
     action_text = (
         "The author '%s' needs to be migrated to an user:\n"
         "1. Use an existing user ?\n"
         "2. Create a new user ?\n"
         "Please select a choice: " % self.style.ITEM(author_name)
     )
     while 42:
         selection = input(smart_str(action_text))
         if selection and selection in "12":
             break
     if selection == "1":
         users = Author.objects.all()
         if users.count() == 1:
             username = users[0].get_username()
             preselected_user = username
             usernames = [username]
             usernames_display = ["[%s]" % username]
         else:
             usernames = []
             usernames_display = []
             preselected_user = None
             for user in users:
                 username = user.get_username()
                 if username == author_name:
                     usernames_display.append("[%s]" % username)
                     preselected_user = username
                 else:
                     usernames_display.append(username)
                 usernames.append(username)
         while 42:
             user_text = (
                 "1. Select your user, by typing "
                 "one of theses usernames:\n"
                 "%s or 'back'\n"
                 "Please select a choice: " % ", ".join(usernames_display)
             )
             user_selected = input(user_text)
             if user_selected in usernames:
                 break
             if user_selected == "" and preselected_user:
                 user_selected = preselected_user
                 break
             if user_selected.strip() == "back":
                 return self.migrate_author(author_name)
         return users.get(**{users[0].USERNAME_FIELD: user_selected})
     else:
         create_text = "2. Please type the email of " "the '%s' user or 'back': " % author_name
         author_mail = input(create_text)
         if author_mail.strip() == "back":
             return self.migrate_author(author_name)
         try:
             return Author.objects.create_user(author_name, author_mail)
         except IntegrityError:
             return Author.objects.get(**{Author.USERNAME_FIELD: author_name})
Esempio n. 8
0
def ask_for_confirmation(question, default=None):
    """Ask for confirmation before proceeding.
    """
    result = input('{} '.format(question))
    if not result and default is not None:
        return default
    while len(result) < 1 or result[0].lower() not in 'yn':
        result = input('Please answer yes or no: ')
    return result[0].lower() == 'y'
Esempio n. 9
0
 def migrate_author(self, author_name):
     """Handle actions for migrating the authors"""
     action_text = "The author '%s' needs to be migrated to an user:\n"\
                   "1. Use an existing user ?\n"\
                   "2. Create a new user ?\n"\
                   "Please select a choice: " % self.style.ITEM(author_name)
     while 42:
         selection = input(smart_str(action_text))
         if selection and selection in '12':
             break
     if selection == '1':
         users = Author.objects.all()
         if users.count() == 1:
             username = users[0].username
             preselected_user = username
             usernames = [username]
             usernames_display = ['[%s]' % username]
         else:
             usernames = []
             usernames_display = []
             preselected_user = None
             for user in users:
                 username = user.username
                 if username == author_name:
                     usernames_display.append('[%s]' % username)
                     preselected_user = username
                 else:
                     usernames_display.append(username)
                 usernames.append(username)
         while 42:
             user_text = "1. Select your user, by typing " \
                         "one of theses usernames:\n"\
                         "%s or 'back'\n"\
                         "Please select a choice: " % \
                         ', '.join(usernames_display)
             user_selected = input(user_text)
             if user_selected in usernames:
                 break
             if user_selected == '' and preselected_user:
                 user_selected = preselected_user
                 break
             if user_selected.strip() == 'back':
                 return self.migrate_author(author_name)
         return users.get(username=user_selected)
     else:
         create_text = "2. Please type the email of " \
                       "the '%s' user or 'back': " % author_name
         author_mail = input(create_text)
         if author_mail.strip() == 'back':
             return self.migrate_author(author_name)
         try:
             return Author.objects.create_user(author_name, author_mail)
         except IntegrityError:
             return Author.objects.get(username=author_name)
Esempio n. 10
0
    def handle_noargs(self, **options):
        global gdata_service
        try:
            from gdata import service
            gdata_service = service
        except ImportError:
            raise CommandError('You need to install the gdata '
                               'module to run this command.')

        self.verbosity = int(options.get('verbosity', 1))
        self.blogger_username = options.get('blogger_username')
        self.blogger_blog_id = options.get('blogger_blog_id')
        self.blogger_limit = int(options.get('blogger_limit'))
        self.category_title = options.get('category_title')
        self.auto_excerpt = options.get('auto-excerpt', True)

        self.write_out(self.style.TITLE(
            'Starting migration from Blogger to Zinnia %s\n' % __version__))

        if not self.blogger_username:
            self.blogger_username = input('Blogger username: '******'Invalid Blogger username')

        self.blogger_password = getpass('Blogger password: '******'Incorrect Blogger username or password')

        default_author = options.get('author')
        if default_author:
            try:
                self.default_author = Author.objects.get(
                    **{Author.USERNAME_FIELD: self.default_author})
            except Author.DoesNotExist:
                raise CommandError(
                    'Invalid Zinnia username for default author "%s"' %
                    default_author)
        else:
            self.default_author = Author.objects.all()[0]

        if not self.blogger_blog_id:
            self.select_blog_id()

        if not self.category_title:
            self.category_title = input(
                'Category title for imported entries: ')
            if not self.category_title:
                raise CommandError('Invalid category title')

        self.import_posts()
Esempio n. 11
0
 def _choice_input(self, question, choices):
     print(question)
     for i, choice in enumerate(choices):
         print(" %s) %s" % (i + 1, choice))
     result = input("Select an option: ")
     while True:
         try:
             value = int(result)
             if 0 < value <= len(choices):
                 return value
         except ValueError:
             pass
         result = input("Please select a valid option: ")
Esempio n. 12
0
def create_first_user(app, created_models, verbosity, db, **kwargs):
    if User not in created_models:
        return
    if not kwargs.get('interactive', True):
        return
    msg = ("Would you like to create a user account now? (yes/no): ")
    confirm = input(msg)
    while 1:
        if confirm not in ('yes', 'no'):
            confirm = input('Please enter either "yes" or "no": ')
            continue
        if confirm == 'yes':
            call_command("createuser", interactive=True, database=db)
        break
    def handle(self, *args, **options):
        User = get_user_model()

        if not User.objects.filter(is_superuser=True).count():
            msg = ("\nCabot doesn't have any super users defined.\n\n"
                   "Would you like to create one now? (yes/no): ")
            confirm = input(msg)
            while 1:
                if confirm not in ('yes', 'no'):
                    confirm = input('Please enter either "yes" or "no": ')
                    continue
                if confirm == 'yes':
                    call_command("createsuperuser", interactive=True)
                break
Esempio n. 14
0
def create_superuser(app, created_models, verbosity, db, **kwargs):
    from django.core.management import call_command

    if auth_app.User in created_models and kwargs.get('interactive', True):
        msg = ("\nYou just installed Django's auth system, which means you "
            "don't have any superusers defined.\nWould you like to create one "
            "now? (yes/no): ")
        confirm = input(msg)
        while 1:
            if confirm not in ('yes', 'no'):
                confirm = input('Please enter either "yes" or "no": ')
                continue
            if confirm == 'yes':
                call_command("createsuperuser", interactive=True, database=db)
            break
Esempio n. 15
0
    def handle_noargs(self, **options):
        db = options.get('database')
        connection = connections[db]
        verbosity = int(options.get('verbosity'))
        interactive = options.get('interactive')
        # The following are stealth options used by Django's internals.
        reset_sequences = options.get('reset_sequences', True)
        allow_cascade = options.get('allow_cascade', False)
        inhibit_post_migrate = options.get('inhibit_post_migrate', False)

        self.style = no_style()

        # Import the 'management' module within each installed app, to register
        # dispatcher events.
        for app_name in settings.INSTALLED_APPS:
            try:
                import_module('.management', app_name)
            except ImportError:
                pass

        sql_list = sql_flush(self.style, connection, only_django=True,
                             reset_sequences=reset_sequences,
                             allow_cascade=allow_cascade)

        if interactive:
            confirm = input("""You have requested a flush of the database.
This will IRREVERSIBLY DESTROY all data currently in the %r database,
and return each table to a fresh state.
Are you sure you want to do this?

    Type 'yes' to continue, or 'no' to cancel: """ % connection.settings_dict['NAME'])
        else:
            confirm = 'yes'

        if confirm == 'yes':
            try:
                with transaction.commit_on_success_unless_managed():
                    cursor = connection.cursor()
                    for sql in sql_list:
                        cursor.execute(sql)
            except Exception as e:
                new_msg = (
                    "Database %s couldn't be flushed. Possible reasons:\n"
                    "  * The database isn't running or isn't configured correctly.\n"
                    "  * At least one of the expected database tables doesn't exist.\n"
                    "  * The SQL was invalid.\n"
                    "Hint: Look at the output of 'django-admin.py sqlflush'. That's the SQL this command wasn't able to run.\n"
                    "The full error: %s") % (connection.settings_dict['NAME'], e)
                six.reraise(CommandError, CommandError(new_msg), sys.exc_info()[2])

            if not inhibit_post_migrate:
                self.emit_post_migrate(verbosity, interactive, db)

            # Reinstall the initial_data fixture.
            if options.get('load_initial_data'):
                # Reinstall the initial_data fixture.
                call_command('loaddata', 'initial_data', **options)

        else:
            self.stdout.write("Flush cancelled.\n")
    def handle(self, *args, **options):

        tenant = {}
        for field in self.fields:
            tenant[field.name] = options.get(field.name, None)

        saved = False

        while not saved:
            for field in self.fields:
                if not getattr(tenant, field.name, None):
                    input_msg = field.verbose_name
                    default = field.get_default()
                    if default:
                        input_msg = "%s (leave blank to use '%s')" % (input_msg, default)
                    tenant[field.name] = input(force_str('%s: ' % input_msg)) or default


            saved = self.store_tenant(**tenant)
            if not saved:
                tenant = {}
                continue

        if options.get('s', None):
            print "Create superuser for %s" % tenant['schema_name']
            call_command('createsuperuser', schema_name=tenant['schema_name'])
    def handle(self, verbosity, *args, **options):
        self.set_options(**options)
        self.createdb_if_not_exists()
        self.clear_compressor_cache()
        call_command('migrate')

        fixture = '{workdir}/{tutorial}/fixtures/myshop.json'.format(workdir=settings.WORK_DIR,
                                                                     tutorial=settings.SHOP_TUTORIAL)

        if self.interactive:
            mesg = ("\nThis will overwrite your workdir and install a new database for the django-SHOP demo: {tutorial}\n"
                    "Are you sure you want to do this?\n\n"
                    "Type 'yes' to continue, or 'no' to cancel: ").format(tutorial=settings.SHOP_TUTORIAL)
            if input(mesg) != 'yes':
                raise CommandError("SHOP initialization cancelled.")
        else:
            if os.path.isfile(fixture):
                self.stdout.write(self.style.WARNING("Can not override downloaded data in input-less mode."))
                return

        extract_to = os.path.join(settings.WORK_DIR, os.pardir)
        msg = "Downloading workdir and extracting to {}. Please wait ..."
        self.stdout.write(msg.format(extract_to))
        download_url = self.download_url.format(tutorial=settings.SHOP_TUTORIAL, version=self.version)
        response = requests.get(download_url, stream=True)
        zip_ref = zipfile.ZipFile(StringIO(response.content))
        try:
            zip_ref.extractall(extract_to, pwd=self.pwd)
        finally:
            zip_ref.close()

        call_command('loaddata', fixture)
        call_command('fix_filer_bug_965')
Esempio n. 18
0
    def _reset_token(self, account):
        service = account.service
        password = None
        auth_token = None

        while True:
            if (not password and
                service.get_reset_auth_token_requires_password()):
                password = getpass.getpass(_('Password for %s: ')
                                           % account.username)
                auth_token = None

            try:
                service.reset_auth_token(password, auth_token)

                self.stdout.write(_('Successfully reset token for %s\n')
                                  % account.username)
                break
            except TwoFactorAuthCodeRequiredError:
                auth_token = input('Enter your two-factor auth token: ')
            except AuthorizationError as e:
                self.stderr.write('%s\n' % e)
                password = None
            except Exception as e:
                self.stderr.write(_('Unexpected error: %s\n') % e)
                raise
                break
Esempio n. 19
0
 def _handle_objects_preventing_db_destruction(self, cursor, parameters, verbosity, autoclobber):
     # There are objects in the test tablespace which prevent dropping it
     # The easy fix is to drop the test user -- but are we allowed to do so?
     print("There are objects in the old test database which prevent its destruction.")
     print("If they belong to the test user, deleting the user will allow the test "
           "database to be recreated.")
     print("Otherwise, you will need to find and remove each of these objects, "
           "or use a different tablespace.\n")
     if self._test_user_create():
         if not autoclobber:
             confirm = input("Type 'yes' to delete user %s: " % parameters['user'])
         if autoclobber or confirm == 'yes':
             try:
                 if verbosity >= 1:
                     print("Destroying old test user...")
                 self._destroy_test_user(cursor, parameters, verbosity)
             except Exception as e:
                 sys.stderr.write("Got an error destroying the test user: %s\n" % e)
                 sys.exit(2)
             try:
                 if verbosity >= 1:
                     print("Destroying old test database for alias '%s'..." % self.connection.alias)
                 self._execute_test_db_destruction(cursor, parameters, verbosity)
             except Exception as e:
                 sys.stderr.write("Got an error destroying the test database: %s\n" % e)
                 sys.exit(2)
         else:
             print("Tests cancelled -- test database cannot be recreated.")
             sys.exit(1)
     else:
         print("Django is configured to use pre-existing test user '%s',"
               " and will not attempt to delete it.\n" % parameters['user'])
         print("Tests cancelled -- test database cannot be recreated.")
         sys.exit(1)
Esempio n. 20
0
    def _create_test_db(self, verbosity, autoclobber, keepdb=False):
        test_database_name = self._get_test_db_name()

        if keepdb:
            return test_database_name
        if not self.is_in_memory_db(test_database_name):
            # Erase the old test database
            if verbosity >= 1:
                print("Destroying old test database for alias %s..." % (
                    self._get_database_display_str(verbosity, test_database_name),
                ))
            if os.access(test_database_name, os.F_OK):
                if not autoclobber:
                    confirm = input(
                        "Type 'yes' if you would like to try deleting the test "
                        "database '%s', or 'no' to cancel: " % test_database_name
                    )
                if autoclobber or confirm == 'yes':
                    try:
                        os.remove(test_database_name)
                    except Exception as e:
                        sys.stderr.write("Got an error deleting the old test database: %s\n" % e)
                        sys.exit(2)
                else:
                    print("Tests cancelled.")
                    sys.exit(1)
        return test_database_name
Esempio n. 21
0
    def handle(self, *args, **options):

        tenant = {}
        for field in self.fields:
            input_value = options.get(field.name, None)
            if input_value is not None and field.name == 'domain_urls':
                tenant[field.name] = input_value.split(';')
            else:
                tenant[field.name] = input_value

        saved = False
        while not saved:
            for field in self.fields:

                if tenant.get(field.name, '') == '':
                    input_msg = field.verbose_name
                    default = field.get_default()
                    if default:
                        input_msg = "%s (leave blank to use '%s')" % (input_msg, default)

                    input_value = input(force_str('%s: ' % input_msg)) or default

                    if field.name == 'domain_urls':
                        tenant[field.name] = input_value.split(';')
                    else:
                        tenant[field.name] = input_value
            saved = self.store_tenant(**tenant)
            if not saved:
                tenant = {}
                continue

        if options.get('s', None):
            self.stdout.write("Create superuser for %s" % tenant['schema_name'])
            call_command('create_tenant_superuser', schema_name=tenant['schema_name'], interactive=True)
    def handle_noargs(self, **options):

        # Confirm the user wants to do this
        confirm = input("""You have requested to load the python.org development fixtures.
This will IRREVERSIBLY DESTROY all data currently in your local database.
Are you sure you want to do this?

    Type 'y' or 'yes' to continue, 'n' or 'no' to cancel:  """)

        if confirm in ('y', 'yes'):
            self.stdout.write("\nBeginning download, note this can take a couple of minutes...")
            r = requests.get(settings.DEV_FIXTURE_URL, stream=True)

            if r.status_code != 200:
                self.stderr.write("Unable to download file: Received status code {}".format(r.status_code))
                sys.exit(1)

            with open('/tmp/dev-fixtures.json.gz', 'wb') as f:
                for chunk in r.iter_content(chunk_size=1024):
                    f.write(chunk)
                    f.flush()

            self.stdout.write("Download complete, loading fixtures")
            call_command('loaddata', '/tmp/dev-fixtures.json')
            self.stdout.write("END: Fixtures loaded")
Esempio n. 23
0
 def handle(self, *args, **options):
     if len(args) == 3:
         try:
             instance = CourseInstance.objects.get(id=args[0])
             student = UserProfile.objects.get(id=args[1])
         except ObjectDoesNotExist:               
             raise CommandError('Given student or instance does not exist!')
         percentage = int(args[2])
         if percentage < 0 or percentage > 100:
             raise CommandError('Scale percentage must be an integer in 0-100 range!')
         confirm = input("You are about to scale the grades for student '{}'\non the course instance '{}'\nto {} %.\nType 'yes' to confirm. YOU CAN'T UNDO THIS!\n".format(student,instance,percentage))
         if confirm == 'yes':
             submissions_changed = 0
             for submission in student.submissions.all():
                 if submission.exercise.course_instance == instance:
                     original_grade = submission.grade
                     submission.scale_grade_to(percentage)
                     submission.save()
                     submissions_changed += 1
                     self.stdout.write('Submission id {}: {} => {}'.format(submission.id, original_grade, submission.grade))
             self.stdout.write('{} submission grades were changed'.format(submissions_changed))
         else:
             self.stdout.write('No grades were changed')
     else:
         raise CommandError('Invalid number of arguments!')
 def handle(self, *args, **options):
     # execute the commands if DEBUG is set to False
     if not settings.DEBUG:
         self.set_options(*args, **options)
         if options['download']:
             if options['noinput']:
                 self.download()
             else:
                 confirm = input(self.prompt.encode('utf-8'))
                 if confirm != 'yes':
                     print "Download cancelled."
                     return False
                 self.download()
         if options['unzip']:
             self.unzip()
         if options['prep']:
             self.prep()
         if options['clear']:
             self.clear()
         if options['clean']:
             self.clean()
         if options['load']:
             self.load()
     else:
         print "DEBUG is not set to False. Please change before running `downloadcalaccess`"
Esempio n. 25
0
    def _create_test_db(self, verbosity, autoclobber):
        """"
        Internal implementation - creates the test db tables.
        """
        test_database_name = self._get_test_db_name()

        self._prepare_for_test_db_ddl()
        try:
            self._create_database(test_database_name, verbosity)
            if verbosity >= 1:
                print("Database %s created..." % test_database_name)
        except Exception as e:
            sys.stderr.write("Got an error creating the test database: %s\n" % e)
            if not autoclobber:
                confirm = input("Type 'yes' if you would like to try deleting the test database '%s', or 'no' to cancel: " % test_database_name)
            if autoclobber or confirm == 'yes':
                try:
                    if verbosity >= 1:
                        print("Destroying old test database...")
                    self._destroy_test_db(test_database_name, verbosity)
                    if verbosity >= 1:
                        print("Creating test database...")
                    self._create_database(test_database_name, verbosity)
                    if verbosity >= 1:
                        print("Database %s created..." % test_database_name)
                except Exception as e:
                    sys.stderr.write("Got an error recreating the test database: %s\n" % e)
                    sys.exit(2)
            else:
                print("Tests cancelled.")
                sys.exit(1)

        return test_database_name
Esempio n. 26
0
 def ask_not_null_addition(self, field_name, model_name):
     "Adding a NOT NULL field to a model"
     choice = self._choice_input(
         "You are trying to add a non-nullable field '%s' to %s without a default;\n" % (field_name, model_name) +
         "this is not possible. Please select a fix:",
         [
             "Provide a one-off default now (will be set on all existing rows)",
             "Quit, and let me add a default in models.py",
         ]
     )
     if choice == 2:
         sys.exit(3)
     else:
         print("Please enter the default value now, as valid Python")
         print("The datetime module is available, so you can do e.g. datetime.date.today()")
         while True:
             code = input(">>> ")
             if not code:
                 print("Please enter some code, or 'exit' (with no quotes) to exit.")
             elif code == "exit":
                 sys.exit(1)
             else:
                 try:
                     return eval(code, {}, {"datetime": datetime_safe})
                 except (SyntaxError, NameError) as e:
                     print("Invalid input: %s" % e)
                 else:
                     break
Esempio n. 27
0
 def handle(self, *args, **options):
     from tinc.models import TincHost, TincAddress
     interactive = options.get('interactive')
     username = options.get('username')
     
     if not interactive:
         # validate username
         if not username:
             raise CommandError("You must use --username with --noinput.")
         try:
             username = pwd.getpwnam(username).pw_name
         except KeyError:
             raise CommandError("Username doesn't exists.")
     else:
         # Prompt for username
         # Enclose this whole thing in a try/except to trap for a
         # keyboard interrupt and exit gracefully.
         prompt_username = None
         while prompt_username is None:
             if not prompt_username:
                 input_msg = "Celeryd username"
                 if username:
                     input_msg += " (leave blank to use '%s')" % username
                 value = input(input_msg + ': ')
             if username and value == '':
                 value = username
             # validate username
             try:
                 prompt_username = pwd.getpwnam(value).pw_name
             except KeyError, e:
                 self.stderr.write("Error: %s" % e)
                 prompt_username = None
                 continue
Esempio n. 28
0
    def handle(self, *usernames, **options):
        force_yes = options['force_yes']
        local_sites = options['local_sites']

        accounts = HostingServiceAccount.objects.filter(service_name='github')

        if usernames:
            accounts = accounts.filter(username__in=usernames)

        if local_sites:
            local_site_names = local_sites.split(',')

            if local_site_names:
                accounts = accounts.filter(
                    local_site__name__in=local_site_names)

        for account in accounts:
            if force_yes:
                reset = 'y'
            else:
                if account.local_site:
                    reset_msg = _('Reset token for %s (%s) [Y/n] ') % (
                        account.local_site.name,
                        account.username)
                else:
                    reset_msg = _('Reset token for %s [Y/n] ') % (
                        account.username)

                reset = input(reset_msg)

            if reset != 'n':
                self._reset_token(account)
Esempio n. 29
0
    def get_tenant_from_options_or_interactive(self, **options):
        TenantModel = get_tenant_model()
        all_tenants = TenantModel.objects.all()

        if not all_tenants:
            raise CommandError("""There are no tenants in the system.
To learn how create a tenant, see:
https://django-multitenants.readthedocs.org/en/latest/use.html#creating-a-tenant""")

        if options.get('schema_name'):
            tenant_schema = options['schema_name']
        else:
            while True:
                tenant_schema = input(
                    "Enter Tenant Schema ('?' to list schemas): ")
                if tenant_schema == '?':
                    print(
                        '\n'.join(["%s - %s" % (t.schema_name, t.domain_url,) for t in all_tenants]))
                else:
                    break

        if tenant_schema not in [t.schema_name for t in all_tenants]:
            raise CommandError(
                "Invalid tenant schema, '%s'" % (tenant_schema,))

        return TenantModel.objects.get(schema_name=tenant_schema)
Esempio n. 30
0
    def _confirm_execute(self):
        """Prompt the user to confirm execution of an evolution.

        This will warn the user of the risks of evolving the database and
        to recommend a backup. It will then prompt for confirmation, returning
        the result.

        Returns:
            bool:
            ``True`` if the user confirmed the execution. ``False`` if the
            execution should be cancelled.
        """
        prompt = self._wrap_paragraphs(
            _('You have requested a database evolution. This will alter '
              'tables and data currently in the "%s" database, and may '
              'result in IRREVERSABLE DATA LOSS. Evolutions should be '
              '*thoroughly* reviewed prior to execution.\n'
              '\n'
              'MAKE A BACKUP OF YOUR DATABASE BEFORE YOU CONTINUE!\n'
              '\n'
              'Are you sure you want to execute the evolutions?\n'
              '\n'
              'Type "yes" to continue, or "no" to cancel:')
            % self.evolver.database_name)

        # Note that we must append a space here, rather than above, since the
        # paragraph wrapping logic will strip trailing whitespace.
        return input('%s ' % prompt).lower() == 'yes'
Esempio n. 31
0
    def handle(self, *app_labels, **options):
        days = options["days"]
        keep = options["keep"]
        force = options["force"]
        confirmation = options["confirmation"]
        manager = options.get('manager')
        database = options.get('database')
        # I don't know why verbosity is not already an int in Django?
        try:
            verbosity = int(options["verbosity"])
        except ValueError:
            raise CommandError("option -v: invalid choice: '%s' (choose from '0', '1', '2')" % options["verbosity"])

        date = None

        # Validating arguments
        if options["date"]:
            if days:
                raise CommandError("You cannot use --date and --days at the same time. They are exclusive.")

            try:
                date = datetime.datetime.strptime(options["date"], "%Y-%m-%d").date()
            except ValueError:
                raise CommandError("The date you give (%s) is not a valid date. The date should be in the ISO format (YYYY-MM-DD)." % options["date"])

        # Find the date from the days arguments.        
        elif days:
            date = datetime.datetime.now() - datetime.timedelta(days)

        # Build the queries
        revision_query = Revision.objects.using(database).all()
        
        if manager:
            revision_query = revision_query.filter(manager_slug=manager)

        if date:
            revision_query = revision_query.filter(date_created__lt=date)

        if app_labels:
            app_list = set()
            mod_list = set()
            for label in app_labels:
                try:
                    app_label, model_label = label.split(".")
                    mod_list.add((app_label, model_label))
                except ValueError:
                    # This is just an app, no model qualifier.
                    app_list.add(label)

            # Remove models that their app is already in app_list            
            for app, model in mod_list.copy():
                if app in app_list:
                    mod_list.remove((app, model))

            # Build apps/models subqueries
            subqueries = []
            if app_list:
                subqueries.append(Q(app_label__in=app_list))
            if mod_list:
                subqueries.extend([Q(app_label=app, model=model) for app, model in mod_list])
            subqueries = reduce(operator.or_, subqueries)

            if force:
                models = ContentType.objects.using(database).filter(subqueries)
                revision_query = revision_query.filter(version__content_type__in=models)
            else:
                models = ContentType.objects.using(database).exclude(subqueries)
                revision_query = revision_query.exclude(version__content_type__in=models)

        if keep:
            objs = Version.objects.using(database).all()

            # If app is specified, to speed up the loop on theses objects,
            # get only the specified subset.
            if app_labels:
                if force:
                    objs = objs.filter(content_type__in=models)
                else:
                    objs = objs.exclude(content_type__in=models)

            # Get all the objects that have more than the maximum revisions
            objs = objs.values("object_id", "content_type_id").annotate(total_ver=Count("object_id")).filter(total_ver__gt=keep)

            revisions_not_keeped = set()

            # Get all ids of the oldest revisions minus the max allowed
            # revisions for all objects.
            # Was not able to avoid this loop...
            for obj in objs:
                revisions_not_keeped.update(list(Version.objects.using(database).filter(content_type__id=obj["content_type_id"], object_id=obj["object_id"]).order_by("-revision__date_created").values_list("revision_id", flat=True)[keep:]))

            revision_query = revision_query.filter(pk__in=revisions_not_keeped)


        # Prepare message if verbose
        if verbosity > 0:
            if not date and not app_labels and not keep:
                print("All revisions will be deleted for all models.")
            else:
                date_msg = ""
                if date:
                    date_msg = " older than %s" % date.isoformat()
                models_msg = " "
                if app_labels:
                    force_msg = ""
                    if not force:
                        force_msg = " only"
                    models_msg = " having%s theses apps and models:\n- %s\n" % (force_msg, "\n- ".join(sorted(app_list.union(["%s.%s" % (app, model) for app, model in mod_list])),))
                    if date:
                        models_msg = " and" + models_msg
                keep_msg = ""
                if keep:
                    keep_msg = " keeping the %s most recent revisions of each object" % keep

                revision_count = revision_query.count()
                if revision_count:
                    version_query = Version.objects.using(database).all()
                    if date or app_labels or keep:
                        version_query = version_query.filter(revision__in=revision_query)
                    print("%s revision(s)%s%swill be deleted%s.\n%s model version(s) will be deleted." % (revision_count, date_msg, models_msg, keep_msg, version_query.count()))
                else:
                    print("No revision%s%sto delete%s.\nDone" % (date_msg, models_msg, keep_msg))
                    return


        # Ask confirmation
        if confirmation:
            choice = input("Are you sure you want to delete theses revisions? [y|N] ")
            if choice.lower() != "y":
                print("Aborting revision deletion.")
                return


        # Delete versions and revisions
        print("Deleting revisions...")
        
        try:
            revision_query.delete()
        except DatabaseError:
            # may fail on sqlite if the query is too long
            print("Delete failed. Trying again with slower method.")
            for item in revision_query:
                item.delete()
                
        print("Done")
Esempio n. 32
0
    def handle(self, **options):
        database = options['database']
        connection = connections[database]
        verbosity = options['verbosity']
        interactive = options['interactive']
        # The following are stealth options used by Django's internals.
        reset_sequences = options.get('reset_sequences', True)
        allow_cascade = options.get('allow_cascade', False)
        inhibit_post_migrate = options.get('inhibit_post_migrate', False)

        self.style = no_style()

        # Import the 'management' module within each installed app, to register
        # dispatcher events.
        for app_config in apps.get_app_configs():
            try:
                import_module('.management', app_config.name)
            except ImportError:
                pass

        sql_list = sql_flush(self.style,
                             connection,
                             only_django=True,
                             reset_sequences=reset_sequences,
                             allow_cascade=allow_cascade)

        if interactive:
            confirm = input("""You have requested a flush of the database.
This will IRREVERSIBLY DESTROY all data currently in the %r database,
and return each table to an empty state.
Are you sure you want to do this?

    Type 'yes' to continue, or 'no' to cancel: """ %
                            connection.settings_dict['NAME'])
        else:
            confirm = 'yes'

        if confirm == 'yes':
            try:
                with transaction.atomic(
                        using=database,
                        savepoint=connection.features.can_rollback_ddl):
                    with connection.cursor() as cursor:
                        for sql in sql_list:
                            cursor.execute(sql)
            except Exception as e:
                new_msg = (
                    "Database %s couldn't be flushed. Possible reasons:\n"
                    "  * The database isn't running or isn't configured correctly.\n"
                    "  * At least one of the expected database tables doesn't exist.\n"
                    "  * The SQL was invalid.\n"
                    "Hint: Look at the output of 'django-admin sqlflush'. "
                    "That's the SQL this command wasn't able to run.\n"
                    "The full error: %s") % (connection.settings_dict['NAME'],
                                             e)
                six.reraise(CommandError, CommandError(new_msg),
                            sys.exc_info()[2])

            # Empty sql_list may signify an empty database and post_migrate would then crash
            if sql_list and not inhibit_post_migrate:
                # Emit the post migrate signal. This allows individual applications to
                # respond as if the database had been migrated from scratch.
                emit_post_migrate_signal(verbosity, interactive, database)
        else:
            self.stdout.write("Flush cancelled.\n")
Esempio n. 33
0
 def handle(self, *args, **options):
     verbosity = int(options.get('verbosity', 1))
     database = options.get('database')
     email = options.get('email')
     domain = options.get('domain')
     interactive = options.get('interactive')
     send = options.get('send')
     https = options.get('https')
     sites = Site.objects.all()
     site_items = dict((str(obj.id), obj) for obj in sites)
     site = None
     if not site_items:
         raise CommandError("No site available.")
     while not email:
         if not interactive:
             raise CommandError("Missing parameter 'email'")
         email = (input(
             force_str('Enter the email address of the recipient: '))
                  or '').strip()
     if domain:
         for site in sites:
             if site.domain == domain:
                 break
         else:
             raise CommandError("A site with domain '%s' does not exist" %
                                domain)
     else:
         if len(site_items) == 1:
             site = sites[0]
         while site is None:
             if not interactive:
                 raise CommandError("Missing parameter 'domain'")
             for obj in sites:
                 self.stdout.write("[%s] %s" % (obj.id, obj.domain))
             site_id = input(force_str('Select a site: '))
             try:
                 site = site_items[site_id]
             except KeyError:
                 continue
     code = InvitationCode.objects.create_invite_code(email, site=site)
     do_send = None
     while do_send is None:
         if not interactive:
             do_send = 'y' if send else 'n'
             break
         do_send = (input(force_str('Send the code now? [y/N]'))
                    or '').strip().lower()
         do_send = do_send or 'n'
         if do_send not in 'yn':
             do_send = None
     if do_send == 'y':
         secure = None
         while secure is None:
             if not interactive:
                 secure = 'y' if https else 'n'
                 break
             secure = (input(
                 force_str('Use https for site urls in the email? [y/N]'))
                       or '').strip().lower()
             secure = secure or 'n'
             if secure not in 'yn':
                 secure = None
         protocol = 'http'
         if secure == 'y':
             protocol += 's'
         site_url = '%s://%s%s' % (protocol, site.domain, reverse("home"))
         login_url = '%s://%s%s' % (protocol, site.domain, reverse("login"))
         try:
             send_invite_code_mail(code, site_url, login_url)
         except Exception as e:
             self.stderr.write("Mail send error - %s" % e)
             return
         else:
             self.stdout.write("Mail sent to %s." % code.registered_to)
     else:
         self.stdout.write(code.short_key)
Esempio n. 34
0
    def handle(self, *args, **options):
        username = options.get('username')
        email = options.get('email')
        password = options.get('password')
        interactive = options.get('interactive')
        verbosity = int(options.get('verbosity', 1))

        # Validate initial inputs
        if username is not None:
            try:
                username = username.strip()
                validate_username(username)
            except ValidationError as e:
                self.stderr.write(e.messages[0])
                username = None

        if email is not None:
            try:
                email = email.strip()
                validate_email(email)
            except ValidationError as e:
                self.stderr.write(e.messages[0])
                email = None

        if password is not None:
            try:
                password = password.strip()
                validate_password(password)
            except ValidationError as e:
                self.stderr.write(e.messages[0])
                password = None

        if not interactive:
            if username and email and password:
                # Call User manager's create_superuser using our wrapper
                self.create_superuser(username, email, password, verbosity)
        else:
            try:
                if hasattr(self.stdin, 'isatty') and not self.stdin.isatty():
                    raise NotRunningInTTYException("Not running in a TTY")

                # Prompt for username/password, and any other required fields.
                # Enclose this whole thing in a try/except to trap for a
                # keyboard interrupt and exit gracefully.
                while not username:
                    try:
                        message = force_str("Enter displayed username: "******"Enter E-mail address: ").strip()
                        validate_email(raw_value)
                        email = raw_value
                    except ValidationError as e:
                        self.stderr.write(e.messages[0])

                while not password:
                    try:
                        raw_value = getpass("Enter password: "******"Repeat password: "******"Entered passwords are different.")
                        password = raw_value
                    except ValidationError as e:
                        self.stderr.write(e.messages[0])

                # Call User manager's create_superuser using our wrapper
                self.create_superuser(username, email, password, verbosity)

            except KeyboardInterrupt:
                self.stderr.write("\nOperation cancelled.")
                sys.exit(1)
            except NotRunningInTTYException:
                self.stdout.write(
                    "Superuser creation skipped due to not running in a TTY. "
                    "You can run `manage.py createsuperuser` in your project "
                    "to create one manually."
                )
Esempio n. 35
0
    def handle_noargs(self, **options):
        db = options.get('database')
        connection = connections[db]
        verbosity = int(options.get('verbosity'))
        interactive = options.get('interactive')
        # The following are stealth options used by Django's internals.
        reset_sequences = options.get('reset_sequences', True)
        allow_cascade = options.get('allow_cascade', False)
        inhibit_post_syncdb = options.get('inhibit_post_syncdb', False)

        self.style = no_style()

        # Import the 'management' module within each installed app, to register
        # dispatcher events.
        for app_name in settings.INSTALLED_APPS:
            try:
                import_module('.management', app_name)
            except ImportError:
                pass

        sql_list = sql_flush(self.style,
                             connection,
                             only_django=True,
                             reset_sequences=reset_sequences,
                             allow_cascade=allow_cascade)

        if interactive:
            confirm = input("""You have requested a flush of the database.
This will IRREVERSIBLY DESTROY all data currently in the %r database,
and return each table to the state it was in after syncdb.
Are you sure you want to do this?

    Type 'yes' to continue, or 'no' to cancel: """ %
                            connection.settings_dict['NAME'])
        else:
            confirm = 'yes'

        if confirm == 'yes':
            try:
                with transaction.commit_on_success_unless_managed():
                    cursor = connection.cursor()
                    for sql in sql_list:
                        cursor.execute(sql)
            except Exception as e:
                new_msg = (
                    "Database %s couldn't be flushed. Possible reasons:\n"
                    "  * The database isn't running or isn't configured correctly.\n"
                    "  * At least one of the expected database tables doesn't exist.\n"
                    "  * The SQL was invalid.\n"
                    "Hint: Look at the output of 'django-admin.py sqlflush'. That's the SQL this command wasn't able to run.\n"
                    "The full error: %s") % (connection.settings_dict['NAME'],
                                             e)
                six.reraise(CommandError, CommandError(new_msg),
                            sys.exc_info()[2])

            if not inhibit_post_syncdb:
                self.emit_post_syncdb(verbosity, interactive, db)

            # Reinstall the initial_data fixture.
            if options.get('load_initial_data'):
                # Reinstall the initial_data fixture.
                call_command('loaddata', 'initial_data', **options)

        else:
            self.stdout.write("Flush cancelled.\n")
Esempio n. 36
0
 def handle(self, *app_labels, **options):
     days = options["days"]
     keep = options["keep"]
     force = options["force"]
     interactive = options["interactive"]
     # Load admin classes.
     admin.autodiscover()
     # Check for deprecated confirmation option.
     if not options["confirmation"]:
         interactive = False
         warnings.warn(
             (
                 "--no-confirmation is deprecated, please use --no-input instead. "
                 "--no-confirmation will be removed in django-reversion 1.12.0"
             ),
             DeprecationWarning
         )
     revision_manager = RevisionManager.get_manager(options["manager"])
     database = options.get("database")
     verbosity = int(options.get("verbosity", 1))
     # Parse date.
     date = None
     if options["date"]:
         if days:
             raise CommandError("You cannot use --date and --days at the same time. They are exclusive.")
         try:
             date = datetime.datetime.strptime(options["date"], "%Y-%m-%d").date()
         except ValueError:
             raise CommandError((
                 "The date you gave (%s) is not a valid date. ",
                 "The date should be in the ISO format (YYYY-MM-DD)."
             ) % options["date"])
     # Find the date from the days arguments.
     elif days:
         date = datetime.date.today() - datetime.timedelta(days)
     # Build the queries
     revision_query = Revision.objects.using(database).filter(
         manager_slug=revision_manager._manager_slug,
     )
     if date:
         revision_query = revision_query.filter(date_created__lt=date)
     if app_labels:
         model_classes = parse_app_labels(revision_manager, app_labels)
         content_types = [
             revision_manager._get_content_type(model_class, db=database)
             for model_class
             in model_classes
         ]
         revision_query = revision_query.filter(version__content_type__in=content_types)
         if not force:
             excluded_content_types = ContentType.objects.db_manager(database).exclude(pk__in=[
                 content_type.pk
                 for content_type
                 in content_types
             ])
             revision_query = revision_query.exclude(version__content_type__in=excluded_content_types)
     # Handle keeping n versions.
     if keep:
         objs = Version.objects.using(database).filter(
             revision__manager_slug=revision_manager._manager_slug,
             revision__in=revision_query,
         )
         # Get all the objects that have more than the maximum revisions.
         objs = objs.values("object_id", "content_type_id", "db").annotate(
             total_ver=Count("object_id"),
         ).filter(total_ver__gt=keep)
         # Get all ids of the oldest revisions minus the max allowed revisions for all objects.
         revisions_not_kept = set()
         for obj in objs:
             revisions_not_kept.update(list(Version.objects.using(database).filter(
                 content_type__id=obj["content_type_id"],
                 object_id=obj["object_id"],
                 db=obj["db"],
             ).order_by("-pk").values_list("revision_id", flat=True)[keep:]))
         revision_query = revision_query.filter(pk__in=revisions_not_kept)
     revision_count = revision_query.count()
     # Ask confirmation
     if interactive:
         choice = input("Are you sure you want to delete %s revisions? [y|N] " % revision_count)
         if choice.lower() != "y":
             self.stdout.write("Aborting revision deletion.")
             return
     # Delete versions and revisions
     if verbosity >= 2:
         self.stdout.write("Deleting %s revisions..." % revision_count)
     # Delete the revisions.
     with transaction.atomic(using=database):
         revision_query.delete()
     # Final logging.
     if verbosity >= 2:
         self.stdout.write("Deleted %s revisions." % revision_count)
Esempio n. 37
0
    def handle(self, *args, **options):
        if len(args) != 1:
            raise CommandError("You must specify a filename on the command "
                               "line.")

        filename = args[0]

        if not os.path.exists(filename):
            raise CommandError("%s does not exist." % filename)

        confirm = input("""
This will wipe out your existing database prior to loading. It is highly
recommended that you have a full SQL database dump in case things go wrong.

You should only use this if you're migrating from one type of database to
another, with the same version of Review Board on each.

Are you sure you want to continue?"

Type 'yes' to continue, or 'no' to cancel: """)

        if confirm != 'yes':
            return

        apps = [app.__name__.split('.')[-2] for app in get_apps()]

        os.system('./reviewboard/manage.py reset --noinput %s' %
                  ' '.join(apps))

        transaction_setup = False

        try:
            with open(filename, 'r') as f:
                line = f.readline()

                m = re.match("^# dbdump v(\d+) - (\d+) objects$", line)
                if not m:
                    raise CommandError("Unknown dump format\n")

                version = int(m.group(1))
                totalobjs = int(m.group(2))
                i = 0
                prev_pct = -1

                if version != 1:
                    raise CommandError("Unknown dump version\n")

                transaction.commit_unless_managed()
                transaction.enter_transaction_management()
                transaction.managed(True)
                transaction_setup = True

                self.stdout.write("Importing new style dump format (v%s)" %
                                  version)
                for line in f:
                    if line[0] == "{":
                        for obj in serializers.deserialize(
                                "json", "[%s]" % line):
                            try:
                                obj.save()
                            except Exception as e:
                                self.stderr.write("Error: %s\n" % e)
                                self.stderr.write("Line %s: '%s'" % (i, line))
                    elif line[0] != "#":
                        self.stderr.write("Junk data on line %s" % i)

                    db.reset_queries()

                    i += 1
                    pct = (i * 100 / totalobjs)
                    if pct != prev_pct:
                        self.stdout.write("  [%s%%]\r" % pct)
                        self.stdout.flush()
                        prev_pct = pct

            transaction.commit()
            transaction.leave_transaction_management()
        except Exception as e:
            raise CommandError("Problem installing '%s': %s\n" % (filename, e))

            if transaction_setup:
                transaction.rollback()
                transaction.leave_transaction_management()

        self.stdout.write('\nDone.')
Esempio n. 38
0
    def handle(self, parsed_args):
        django.setup()
        management.call_command(
            "startproject", parsed_args.name, verbosity=False
        )
        path = "%(name)s/%(name)s" % {"name": parsed_args.name}
        sys.path.append(parsed_args.name)

        conn_tpl = Template(DBCONN_TPL)
        connections = {}
        if parsed_args.dburl:
            for dburl in parsed_args.dburl:
                conn_name, url = dburl.split(":", 1)
                info = dj_database_url.config(default=url)
                # In case the user fails to supply a valid database url,
                # fallback to manual mode
                if not info:
                    print("There was a problem with your database-url. \n")
                    info = self.ask_db_info(conn_name)
                # If we set this earlier, our fallback method will never
                # be triggered
                info["conn_name"] = conn_name
                connections[conn_name] = conn_tpl.render(Context(info))
        else:
            connections["default"] = conn_tpl.render(
                Context(self.ask_db_info()))

        if parsed_args.domain:
            allowed_host = parsed_args.domain
        else:
            allowed_host = input(
                "What will be the hostname used to access Modoboa? ")
            if not allowed_host:
                allowed_host = "localhost"
        extra_settings = []
        extensions = parsed_args.extensions
        if extensions:
            if "all" in extensions:
                extensions = self._get_extension_list()
            extensions = [(extension, extension.replace("-", "_"))
                          for extension in extensions]
            if not parsed_args.dont_install_extensions:
                cmd = (
                    sys.executable +
                    " -m pip install " +
                    " ".join([extension[0] for extension in extensions])
                )
                exec_cmd(cmd, capture_output=False)
            extra_settings = self.find_extra_settings(extensions)
            extensions = [extension[1] for extension in extensions]

        bower_components_dir = os.path.realpath(
            os.path.join(os.path.dirname(__file__), "../../bower_components")
        )

        mod = __import__(
            parsed_args.name, globals(), locals(), [smart_str("settings")]
        )
        tpl = self._render_template(
            "%s/settings.py.tpl" % self._templates_dir, {
                "db_connections": connections,
                "secret_key": mod.settings.SECRET_KEY,
                "name": parsed_args.name,
                "allowed_host": allowed_host,
                "lang": parsed_args.lang,
                "timezone": parsed_args.timezone,
                "bower_components_dir": bower_components_dir,
                "devmode": parsed_args.devel,
                "extensions": extensions,
                "extra_settings": extra_settings
            }
        )
        with codecs.open("%s/settings.py" % path, "w", "utf-8") as fp:
            fp.write(tpl)
        shutil.copyfile(
            "%s/urls.py.tpl" % self._templates_dir, "%s/urls.py" % path
        )
        os.mkdir("%s/media" % parsed_args.name)

        if isfile("%s/settings.pyc" % path):
            os.unlink("%s/settings.pyc" % path)
        self._exec_django_command(
            "migrate", parsed_args.name, "--noinput"
        )
        self._exec_django_command(
            "load_initial_data", parsed_args.name,
            "--admin-username", parsed_args.admin_username
        )
        if parsed_args.collectstatic:
            self._exec_django_command(
                "collectstatic", parsed_args.name, "--noinput"
            )
        self._exec_django_command(
            "set_default_site", parsed_args.name, allowed_host
        )
Esempio n. 39
0
    def handle(self, *args, **options):
        username = options.get('username', None)
        interactive = options.get('interactive')
        verbosity = int(options.get('verbosity', 1))
        database = options.get('database')

        UserModel = get_user_model()

        username_field = UserModel._meta.get_field(
            getattr(UserModel, 'USERNAME_FIELD', 'username'))
        other_fields = UserModel.REQUIRED_FIELDS

        # If not provided, create the user with an unusable password
        password = None
        other_data = {}

        # Do quick and dirty validation if --noinput
        if not interactive:
            try:
                if not username:
                    raise CommandError(
                        "You must use --username with --noinput.")
                username = username_field.clean(username, None)

                for field_name in other_fields:
                    if options.get(field_name):
                        field = UserModel._meta.get_field(field_name)
                        other_data[field_name] = field.clean(
                            options[field_name], None)
                    else:
                        raise CommandError(
                            "You must use --%s with --noinput." % field_name)
            except exceptions.ValidationError as e:
                raise CommandError('; '.join(e.messages))

        else:
            # Prompt for username/password, and any other required fields.
            # Enclose this whole thing in a try/except to trap for a
            # keyboard interrupt and exit gracefully.
            default_username = get_default_username()
            try:

                # Get a username
                while username is None:
                    username_field = UserModel._meta.get_field(
                        getattr(UserModel, 'USERNAME_FIELD', 'username'))
                    if not username:
                        input_msg = capfirst(username_field.verbose_name)
                        if default_username:
                            input_msg += " (leave blank to use '%s')" % default_username
                        raw_value = input(input_msg + ': ')

                    if default_username and raw_value == '':
                        raw_value = default_username
                    try:
                        username = username_field.clean(raw_value, None)
                    except exceptions.ValidationError as e:
                        self.stderr.write("Error: %s" % '; '.join(e.messages))
                        username = None
                        continue
                    try:
                        UserModel.objects.using(database).get(
                            **{
                                getattr(UserModel, 'USERNAME_FIELD', 'username'):
                                username
                            })
                    except UserModel.DoesNotExist:
                        pass
                    else:
                        self.stderr.write(
                            "Error: That username is already taken.")
                        username = None

                for field_name in other_fields:
                    field = UserModel._meta.get_field(field_name)
                    other_data[field_name] = options.get(field_name)
                    while other_data[field_name] is None:
                        raw_value = input(capfirst(field.verbose_name + ': '))
                        try:
                            other_data[field_name] = field.clean(
                                raw_value, None)
                        except exceptions.ValidationError as e:
                            self.stderr.write("Error: %s" %
                                              '; '.join(e.messages))
                            other_data[field_name] = None

                # Get a password
                while password is None:
                    if not password:
                        password = getpass.getpass()
                        password2 = getpass.getpass('Password (again): ')
                        if password != password2:
                            self.stderr.write(
                                "Error: Your passwords didn't match.")
                            password = None
                            continue
                    if password.strip() == '':
                        self.stderr.write(
                            "Error: Blank passwords aren't allowed.")
                        password = None
                        continue

            except KeyboardInterrupt:
                self.stderr.write("\nOperation cancelled.")
                sys.exit(1)

        UserModel.objects.db_manager(database).create_superuser(
            username=username, password=password, **other_data)
        if verbosity >= 1:
            self.stdout.write("Superuser created successfully.")
Esempio n. 40
0
    def prompt_choice(self, prompt, choices):
        """Prompt the user for a choice from a list.

        Args:
            prompt (unicode):
                The text prompting for a choice.

            choices (list of dict):
                The list of choices to present. Each entry is a dictionary
                with the following keys:

                ``text`` (:py:class:`unicode`):
                    The text for the choice.

                ``description`` (:py:class:`unicode`, optional):
                    A description of the choice.

                ``enabled`` (:py:class:`bool`, optional):
                    Whether the option is enabled/visible.

        Returns:
            object:
            The resulting choice.
        """
        self.print()
        self.print('You can type either the name or the number from the '
                   'list below.')
        self.print()

        prompt_style = self.prompt_style
        valid_choices = []
        i = 0

        for choice in choices:
            if choice.get('enabled', True):
                text = choice['text']

                self.print('%s %s %s\n' % (prompt_style(
                    '(%d)' % (i + 1)), text, choice.get('description', '')))
                valid_choices.append(text)
                i += 1

        self.print()

        prompt = self.prompt_style('%s: ' % prompt)
        choice = None

        while not choice:
            self.print(prompt, trailing_newline=False)
            choice = input()

            if choice not in valid_choices:
                try:
                    i = int(choice) - 1

                    if 0 <= i < len(valid_choices):
                        choice = valid_choices[i]
                        break
                except ValueError:
                    pass

                self.error("'%s' is not a valid option." % choice)
                choice = None

        return choice
Esempio n. 41
0
    def handle(self, **options):
        self.set_options(**options)

        message = ['\n']
        if self.dry_run:
            message.append(
                'You have activated the --dry-run option so no files will be modified.\n\n'
            )

        message.append(
            'You have requested to collect static files at the destination\n'
            'location as specified in your settings')

        if self.is_local_storage() and self.storage.location:
            destination_path = self.storage.location
            message.append(':\n\n    %s\n\n' % destination_path)
            should_warn_user = (self.storage.exists(destination_path) and any(
                self.storage.listdir(destination_path)))
        else:
            destination_path = None
            message.append('.\n\n')
            # Destination files existence not checked; play it safe and warn.
            should_warn_user = True

        if self.interactive and should_warn_user:
            if self.clear:
                message.append(
                    'This will DELETE ALL FILES in this location!\n')
            else:
                message.append('This will overwrite existing files!\n')

            message.append('Are you sure you want to do this?\n\n'
                           "Type 'yes' to continue, or 'no' to cancel: ")
            if input(''.join(message)) != 'yes':
                raise CommandError("Collecting static files cancelled.")

        collected = self.collect()
        modified_count = len(collected['modified'])
        unmodified_count = len(collected['unmodified'])
        post_processed_count = len(collected['post_processed'])

        if self.verbosity >= 1:
            template = ("\n%(modified_count)s %(identifier)s %(action)s"
                        "%(destination)s%(unmodified)s%(post_processed)s.\n")
            summary = template % {
                'modified_count':
                modified_count,
                'identifier':
                'static file' + ('' if modified_count == 1 else 's'),
                'action':
                'symlinked' if self.symlink else 'copied',
                'destination':
                (" to '%s'" % destination_path if destination_path else ''),
                'unmodified':
                (', %s unmodified' %
                 unmodified_count if collected['unmodified'] else ''),
                'post_processed':
                (collected['post_processed']
                 and ', %s post-processed' % post_processed_count or ''),
            }
            return summary
Esempio n. 42
0
    def prompt_input(self,
                     prompt,
                     prompt_type=PROMPT_TYPE_TEXT,
                     default=None,
                     optional=False,
                     strip=True,
                     validate_func=None):
        """Prompt the user for input.

        Args:
            prompt (unicode):
                The text prompting for input.

            prompt_type (unicode, optional):
                The type of input to prompt for. This is one of:

                * :py:attr:`PROMPT_TYPE_TEXT`
                * :py:attr:`PROMPT_TYPE_PASSWORD`
                * :py:attr:`PROMPT_TYPE_YES_NO`

            default (bool or unicode, optional):
                The default value to show and use, if an explicit value isn't
                provided by the user.

                For yes/no prompts, this should be a boolean. For all else,
                a string.

            optional (bool, optional):
                Whether the prompt is optional and can be skipped by omitting
                a value.

            strip (bool, optional):
                Whether to strip the provided input.

            validate_func (callable, optional):
                An optional function for determining if input is valid. This
                takes the input as a parameter and raises a
                :py:class:`django.core.exceptions.ValidationError` if invalid.

                .. code-block:: python

                   def _is_valid(value):
                       if value != 'abc':
                           raise ValidationError('bad!')

        Returns:
            unicode:
            The resulting inputted value.
        """
        if prompt_type == self.PROMPT_TYPE_YES_NO:
            if default is True:
                prompt = '%s [Y/n]' % prompt
            elif default is False:
                prompt = '%s [y/N]' % prompt
                default = False
            else:
                prompt = '%s [y/n]' % prompt
        elif default:
            self.print()
            self.print('The default is "%s"' % default)
            prompt = '%s [%s]' % (prompt, default)
        elif optional:
            prompt = '%s (optional)' % prompt

        self.print()

        prompt = self.prompt_style('%s: ' % prompt)
        value = None

        while not value:
            self.print(prompt, trailing_newline=False)
            self.stdout.flush()

            if prompt_type == self.PROMPT_TYPE_PASSWORD:
                value = getpass.getpass(str(''), stream=self.stdout)
            else:
                value = input()

            if strip:
                value = value.strip()

            if not value:
                if default:
                    value = default
                elif optional:
                    break

            if validate_func is not None:
                try:
                    validate_func(value)
                except ValidationError as e:
                    for error in e.messages:
                        self.error(error)

                    value = None
                    continue

            if prompt_type == self.PROMPT_TYPE_YES_NO:
                if isinstance(value, bool):
                    # This came from the 'default' value.
                    norm_value = value
                else:
                    assert isinstance(value, six.string_types)
                    norm_value = value.lower()

                if norm_value not in (True, False, 'y', 'n', 'yes', 'no'):
                    self.error('Must specify one of Y/y/yes or N/n/no.')
                    value = None
                    continue
                else:
                    value = norm_value in (True, 'y', 'yes')
                    break
            elif not value:
                self.error('An answer is required.')

        return value
Esempio n. 43
0
 def ask_user(self, message, default=None):
     # pylint: disable=import-error
     from django.utils.six.moves import input
     if getattr(self, 'interactive_mode', False):
         return input(message) or default
     return default
Esempio n. 44
0
    def handle(self, *args, **options):
        name = options.get('full_name', None)
        client_name = options.get('client_name', None)
        schema_name = options.get('schema_name', None)
        domain_url = options.get('domain_url', None)
        post_command = options.get('post_command', None)

        # If full-name is specified then don't prompt for any values.
        if name:
            if not client_name:
                client_name = ''.join(ch if ch.isalnum() else '-'
                                      for ch in name).lower()
            if not schema_name:
                schema_name = client_name.replace('-', '_')
            if not domain_url:
                base_domain = getattr(settings, 'TENANT_BASE_DOMAIN',
                                      'localhost')
                domain_url = '{0}.{1}'.format(client_name, base_domain)

            client = self.store_client(name=name,
                                       client_name=client_name,
                                       domain_url=domain_url,
                                       schema_name=schema_name)
            if not client:
                name = None

        while name is None:
            if not name:
                input_msg = 'Tenant name'
                name = input(force_str('%s: ' % input_msg))

            default_client_name = ''.join(ch if ch.isalnum() else '-'
                                          for ch in name).lower()
            default_schema_name = default_client_name.replace('-', '_')
            base_domain = getattr(settings, 'TENANT_BASE_DOMAIN', 'localhost')
            default_domain_url = '{0}.{1}'.format(default_client_name,
                                                  base_domain)

            while client_name is None:
                if not client_name:
                    input_msg = 'Client name'
                    input_msg = "%s (leave blank to use '%s')" % (
                        input_msg, default_client_name)
                    client_name = input(force_str(
                        '%s: ' % input_msg)) or default_client_name

            while schema_name is None:
                if not schema_name:
                    input_msg = 'Database schema name'
                    input_msg = "%s (leave blank to use '%s')" % (
                        input_msg, default_schema_name)
                    schema_name = input(force_str(
                        '%s: ' % input_msg)) or default_schema_name

            while domain_url is None:
                if not domain_url:
                    input_msg = 'Domain url'
                    input_msg = "%s (leave blank to use '%s')" % (
                        input_msg, default_domain_url)
                    domain_url = input(force_str(
                        '%s: ' % input_msg)) or default_domain_url

            client = self.store_client(name=name,
                                       client_name=client_name,
                                       domain_url=domain_url,
                                       schema_name=schema_name)
            if client is False:
                break

            if not client:
                name = None
                continue

        if client and client_name:
            self.load_fixtures(client_name=client_name)

        if client and post_command:
            call_command(post_command, *args, **options)
Esempio n. 45
0
    def _create_test_db(self, verbosity=1, autoclobber=False, keepdb=False):
        parameters = self._get_test_db_params()
        cursor = self._maindb_connection.cursor()
        if self._test_database_create():
            try:
                self._execute_test_db_creation(cursor, parameters, verbosity, keepdb)
            except Exception as e:
                # if we want to keep the db, then no need to do any of the below,
                # just return and skip it all.
                if keepdb:
                    return
                sys.stderr.write("Got an error creating the test database: %s\n" % e)
                if not autoclobber:
                    confirm = input(
                        "It appears the test database, %s, already exists. "
                        "Type 'yes' to delete it, or 'no' to cancel: " % parameters['user'])
                if autoclobber or confirm == 'yes':
                    if verbosity >= 1:
                        print("Destroying old test database for alias '%s'..." % self.connection.alias)
                    try:
                        self._execute_test_db_destruction(cursor, parameters, verbosity)
                    except DatabaseError as e:
                        if 'ORA-29857' in str(e):
                            self._handle_objects_preventing_db_destruction(cursor, parameters,
                                                                           verbosity, autoclobber)
                        else:
                            # Ran into a database error that isn't about leftover objects in the tablespace
                            sys.stderr.write("Got an error destroying the old test database: %s\n" % e)
                            sys.exit(2)
                    except Exception as e:
                        sys.stderr.write("Got an error destroying the old test database: %s\n" % e)
                        sys.exit(2)
                    try:
                        self._execute_test_db_creation(cursor, parameters, verbosity, keepdb)
                    except Exception as e:
                        sys.stderr.write("Got an error recreating the test database: %s\n" % e)
                        sys.exit(2)
                else:
                    print("Tests cancelled.")
                    sys.exit(1)

        if self._test_user_create():
            if verbosity >= 1:
                print("Creating test user...")
            try:
                self._create_test_user(cursor, parameters, verbosity, keepdb)
            except Exception as e:
                sys.stderr.write("Got an error creating the test user: %s\n" % e)
                if not autoclobber:
                    confirm = input(
                        "It appears the test user, %s, already exists. Type "
                        "'yes' to delete it, or 'no' to cancel: " % parameters['user'])
                if autoclobber or confirm == 'yes':
                    try:
                        if verbosity >= 1:
                            print("Destroying old test user...")
                        self._destroy_test_user(cursor, parameters, verbosity)
                        if verbosity >= 1:
                            print("Creating test user...")
                        self._create_test_user(cursor, parameters, verbosity, keepdb)
                    except Exception as e:
                        sys.stderr.write("Got an error recreating the test user: %s\n" % e)
                        sys.exit(2)
                else:
                    print("Tests cancelled.")
                    sys.exit(1)

        self._maindb_connection.close()  # done with main user -- test user and tablespaces created
        self._switch_to_test_user(parameters)
        return self.connection.settings_dict['NAME']
Esempio n. 46
0
def get_client_and_server_certs(username,
                                password,
                                dataset_id,
                                nc,
                                user_id=None,
                                noninteractive=False):

    # get any full-facility certificates we have for the facility
    owned_certs = (Certificate.objects.filter(id=dataset_id).get_descendants(
        include_self=True).filter(
            scope_definition_id=ScopeDefinitions.FULL_FACILITY).exclude(
                _private_key=None))

    if not user_id:  # it's a full-facility sync

        csr_scope_params = {"dataset_id": dataset_id}

        client_scope = ScopeDefinitions.FULL_FACILITY
        server_scope = ScopeDefinitions.FULL_FACILITY

    else:  # it's a single-user sync

        csr_scope_params = {"dataset_id": dataset_id, "user_id": user_id}

        if owned_certs:
            # client is the one with a full-facility cert
            client_scope = ScopeDefinitions.FULL_FACILITY
            server_scope = ScopeDefinitions.SINGLE_USER
        else:
            # server must be the one with the full-facility cert
            client_scope = ScopeDefinitions.SINGLE_USER
            server_scope = ScopeDefinitions.FULL_FACILITY

            # check for certs we own for the specific user_id for single-user syncing
            owned_certs = (Certificate.objects.filter(
                id=dataset_id).get_descendants(include_self=True).filter(
                    scope_definition_id=ScopeDefinitions.SINGLE_USER).filter(
                        scope_params__contains=user_id).exclude(
                            _private_key=None))

    # get server certificates that server has a private key for
    server_certs = nc.get_remote_certificates(dataset_id,
                                              scope_def_id=server_scope)

    # filter down to the single-user certificates for this specific user, if needed
    if server_scope == ScopeDefinitions.SINGLE_USER:
        server_certs = [
            cert for cert in server_certs if user_id in cert.scope_params
        ]

    if not server_certs:
        raise CommandError(
            "Server does not have needed certificate with scope '{}'".format(
                server_scope))
    server_cert = server_certs[0]

    # if we don't own any certs, do a csr request
    if not owned_certs:

        # prompt user for creds if not already specified
        if not username or not password:
            if noninteractive:
                raise CommandError(
                    "Server username and/or password not specified")
            else:
                username = input("Please enter username: "******"Please enter password: ")

        client_cert = nc.certificate_signing_request(
            server_cert,
            client_scope,
            csr_scope_params,
            userargs=username,
            password=password,
        )
    else:
        client_cert = owned_certs[0]

    return client_cert, server_cert, username
Esempio n. 47
0
    def handle(self, *args, **options):
        username = options.get(self.UserModel.USERNAME_FIELD, None)
        database = options.get('database')

        # If not provided, create the user with an unusable password
        password = None
        user_data = {}

        # Do quick and dirty validation if --noinput
        if not options['interactive']:
            try:
                if not username:
                    raise CommandError("You must use --%s with --noinput." %
                                       self.UserModel.USERNAME_FIELD)
                username = self.username_field.clean(username, None)

                for field_name in self.UserModel.REQUIRED_FIELDS:
                    if options.get(field_name):
                        field = self.UserModel._meta.get_field(field_name)
                        user_data[field_name] = field.clean(
                            options[field_name], None)
                    else:
                        raise CommandError(
                            "You must use --%s with --noinput." % field_name)
            except exceptions.ValidationError as e:
                raise CommandError('; '.join(e.messages))

        else:
            # Prompt for username/password, and any other required fields.
            # Enclose this whole thing in a try/except to trap for a
            # keyboard interrupt and exit gracefully.
            default_username = get_default_username()
            try:

                if hasattr(self.stdin, 'isatty') and not self.stdin.isatty():
                    raise NotRunningInTTYException("Not running in a TTY")

                # Get a username
                verbose_field_name = self.username_field.verbose_name
                while username is None:
                    if not username:
                        input_msg = capfirst(verbose_field_name)
                        if default_username:
                            input_msg = "%s (leave blank to use '%s')" % (
                                input_msg, default_username)
                        raw_value = input(force_str('%s: ' % input_msg))

                    if default_username and raw_value == '':
                        raw_value = default_username
                    try:
                        username = self.username_field.clean(raw_value, None)
                    except exceptions.ValidationError as e:
                        self.stderr.write("Error: %s" % '; '.join(e.messages))
                        username = None
                        continue
                    try:
                        self.UserModel._default_manager.db_manager(
                            database).get_by_natural_key(username)
                    except self.UserModel.DoesNotExist:
                        pass
                    else:
                        self.stderr.write("Error: That %s is already taken." %
                                          verbose_field_name)
                        username = None

                for field_name in self.UserModel.REQUIRED_FIELDS:
                    field = self.UserModel._meta.get_field(field_name)
                    user_data[field_name] = options.get(field_name)
                    while user_data[field_name] is None:
                        raw_value = input(
                            force_str('%s: ' % capfirst(field.verbose_name)))
                        try:
                            user_data[field_name] = field.clean(
                                raw_value, None)
                        except exceptions.ValidationError as e:
                            self.stderr.write("Error: %s" %
                                              '; '.join(e.messages))
                            user_data[field_name] = None

                # Get a password
                while password is None:
                    if not password:
                        password = getpass.getpass()
                        password2 = getpass.getpass(
                            force_str('Password (again): '))
                        if password != password2:
                            self.stderr.write(
                                "Error: Your passwords didn't match.")
                            password = None
                            continue
                    if password.strip() == '':
                        self.stderr.write(
                            "Error: Blank passwords aren't allowed.")
                        password = None
                        continue

            except KeyboardInterrupt:
                self.stderr.write("\nOperation cancelled.")
                sys.exit(1)

            except NotRunningInTTYException:
                self.stdout.write(
                    "Superuser creation skipped due to not running in a TTY. "
                    "You can run `manage.py createsuperuser` in your project "
                    "to create one manually.")

        if username:
            user_data[self.UserModel.USERNAME_FIELD] = username
            user_data['password'] = password
            self.UserModel._default_manager.db_manager(
                database).create_superuser(**user_data)
            if options['verbosity'] >= 1:
                self.stdout.write("Superuser created successfully.")
Esempio n. 48
0
    def handle_label(self, filename, **options):

        missing_options = []
        for k in ['generation_id', 'area_type_code', 'name_type_code', 'country_code']:
            if options[k]:
                continue
            else:
                missing_options.append(k)
        if missing_options:
            message_start = "Missing arguments " if len(missing_options) > 1 else "Missing argument "
            message = message_start + " ".join('--{0}'.format(k) for k in missing_options)
            raise CommandError(message)

        generation_id = options['generation_id']
        area_type_code = options['area_type_code']
        name_type_code = options['name_type_code']
        country_code = options['country_code']
        override_name = options['override_name']
        name_field = options['name_field']
        if not (override_name or name_field):
            name_field = 'Name'
        override_code = options['override_code']
        code_field = options['code_field']
        code_type_code = options['code_type']
        encoding = options['encoding'] or 'utf-8'

        if name_field and override_name:
            raise CommandError("You must not specify both --name_field and --override_name")
        if code_field and override_code:
            raise CommandError("You must not specify both --code_field and --override_code")

        using_code = (code_field or override_code)
        if (using_code and not code_type_code) or (not using_code and code_type_code):
            raise CommandError(
                "If you want to save a code, specify --code_type and either --code_field or --override_code")
        try:
            area_type = Type.objects.get(code=area_type_code)
        except:
            type_desc = input('Please give a description for area type code %s: ' % area_type_code)
            area_type = Type(code=area_type_code, description=type_desc)
            if options['commit']:
                area_type.save()

        try:
            name_type = NameType.objects.get(code=name_type_code)
        except:
            name_desc = input('Please give a description for name type code %s: ' % name_type_code)
            name_type = NameType(code=name_type_code, description=name_desc)
            if options['commit']:
                name_type.save()

        try:
            country = Country.objects.get(code=country_code)
        except:
            country_name = input('Please give the name for country code %s: ' % country_code)
            country = Country(code=country_code, name=country_name)
            if options['commit']:
                country.save()

        if code_type_code:
            try:
                code_type = CodeType.objects.get(code=code_type_code)
            except:
                code_desc = input('Please give a description for code type %s: ' % code_type_code)
                code_type = CodeType(code=code_type_code, description=code_desc)
                if options['commit']:
                    code_type.save()

        self.stdout.write("Importing from %s" % filename)

        if not options['commit']:
            self.stdout.write('(will not save to db as --commit not specified)')

        current_generation = Generation.objects.current()
        new_generation = Generation.objects.get(id=generation_id)

        def verbose(*args):
            if int(options['verbosity']) > 1:
                self.stdout.write(" ".join(str(a) for a in args))

        ds = DataSource(filename)
        layer = ds[0]
        if (override_name or override_code) and len(layer) > 1:
            message = (
                "Warning: you have specified an override %s and this file contains more than one feature; "
                "multiple areas with the same %s will be created")
            if override_name:
                self.stdout.write(message % ('name', 'name'))
            if override_code:
                self.stdout.write(message % ('code', 'code'))

        for feat in layer:

            if override_name:
                name = override_name
            else:
                name = None
                for nf in name_field.split(','):
                    try:
                        name = feat[nf].value
                        break
                    except:
                        pass
                if name is None:
                    choices = ', '.join(layer.fields)
                    raise CommandError(
                        "Could not find name using name field '%s' - should it be something else? "
                        "It will be one of these: %s. Specify which with --name_field" % (name_field, choices))
                try:
                    if not isinstance(name, six.text_type):
                        name = name.decode(encoding)
                except:
                    raise CommandError(
                        "Could not decode name using encoding '%s' - is it in another encoding? "
                        "Specify one with --encoding" % encoding)

            name = re.sub('\s+', ' ', name)
            if not name:
                if options['ignore_blank']:
                    continue
                raise Exception("Could not find a name to use for area")

            code = None
            if override_code:
                code = override_code
            elif code_field:
                try:
                    code = feat[code_field].value
                except:
                    choices = ', '.join(layer.fields)
                    raise CommandError(
                        "Could not find code using code field '%s' - should it be something else? "
                        "It will be one of these: %s. Specify which with --code_field" % (code_field, choices))

            self.stdout.write("  looking at '%s'%s" % (name, (' (%s)' % code) if code else ''))

            g = None
            if hasattr(feat, 'geom'):
                g = feat.geom.transform(settings.MAPIT_AREA_SRID, clone=True)

            try:
                if options['new']:  # Always want a new area
                    raise Area.DoesNotExist
                if code:
                    matching_message = "code %s of code type %s" % (code, code_type)
                    areas = Area.objects.filter(codes__code=code, codes__type=code_type).order_by('-generation_high')
                else:
                    matching_message = "name %s of area type %s" % (name, area_type)
                    areas = Area.objects.filter(name=name, type=area_type).order_by('-generation_high')
                if len(areas) == 0:
                    verbose("    the area was not found - creating a new one")
                    raise Area.DoesNotExist
                m = areas[0]
                verbose("    found the area")
                if options['preserve']:
                    # Find whether we need to create a new Area:
                    previous_geos_geometry = m.polygons.aggregate(Collect('polygon'))['polygon__collect']
                    if m.generation_high < current_generation.id:
                        # Then it was missing in current_generation:
                        verbose("    area existed previously, but was missing from", current_generation)
                        raise Area.DoesNotExist
                    elif g is None:
                        if previous_geos_geometry is not None:
                            verbose("    area is now empty")
                            raise Area.DoesNotExist
                        else:
                            verbose("    the area has remained empty")
                    elif previous_geos_geometry is None:
                        # It was empty in the previous generation:
                        verbose("    area was empty in", current_generation)
                        raise Area.DoesNotExist
                    else:
                        # Otherwise, create a new Area unless the
                        # polygons were the same in current_generation:
                        previous_geos_geometry = previous_geos_geometry.simplify(tolerance=0)
                        new_geos_geometry = g.geos.simplify(tolerance=0)
                        create_new_area = not previous_geos_geometry.equals(new_geos_geometry)
                        p = previous_geos_geometry.sym_difference(new_geos_geometry).area / previous_geos_geometry.area
                        verbose("    change in area is:", "%.03f%%" % (100 * p,))
                        if create_new_area:
                            verbose("    the area", m, "has changed, creating a new area due to --preserve")
                            raise Area.DoesNotExist
                        else:
                            verbose("    the area remained the same")
                else:
                    # If --preserve is not specified, the code or the name must be unique:
                    if len(areas) > 1:
                        raise Area.MultipleObjectsReturned(
                            "There was more than one area with %s, and --preserve was not specified" % (
                                matching_message,))

            except Area.DoesNotExist:
                m = Area(
                    name=name,
                    type=area_type,
                    country=country,
                    # parent_area=parent_area,
                    generation_low=new_generation,
                    generation_high=new_generation,
                )
                if options['use_code_as_id'] and code:
                    m.id = int(code)

            # check that we are not about to skip a generation
            if m.generation_high and current_generation and m.generation_high.id < current_generation.id:
                raise Exception("Area %s found, but not in current generation %s" % (m, current_generation))
            m.generation_high = new_generation

            if options['fix_invalid_polygons'] and g is not None:
                # Make a GEOS geometry only to check for validity:
                geos_g = g.geos
                if not geos_g.valid:
                    geos_g = fix_invalid_geos_geometry(geos_g)
                    if geos_g is None:
                        self.stdout.write("The geometry for area %s was invalid and couldn't be fixed" % name)
                        g = None
                    else:
                        g = geos_g.ogr

            poly = [g] if g is not None else []

            if options['commit']:
                m.save()
                m.names.update_or_create(type=name_type, defaults={'name': name})
                if code:
                    m.codes.update_or_create(type=code_type, defaults={'code': code})
                save_polygons({m.id: (m, poly)})
Esempio n. 49
0
    def _create_test_db(self, verbosity=1, autoclobber=False):
        TEST_NAME = self._test_database_name()
        TEST_USER = self._test_database_user()
        TEST_PASSWD = self._test_database_passwd()
        TEST_TBLSPACE = self._test_database_tblspace()
        TEST_TBLSPACE_TMP = self._test_database_tblspace_tmp()

        parameters = {
            'dbname': TEST_NAME,
            'user': TEST_USER,
            'password': TEST_PASSWD,
            'tblspace': TEST_TBLSPACE,
            'tblspace_temp': TEST_TBLSPACE_TMP,
        }

        cursor = self.connection.cursor()
        if self._test_database_create():
            try:
                self._execute_test_db_creation(cursor, parameters, verbosity)
            except Exception as e:
                sys.stderr.write(
                    "Got an error creating the test database: %s\n" % e)
                if not autoclobber:
                    confirm = input(
                        "It appears the test database, %s, already exists. Type 'yes' to delete it, or 'no' to cancel: "
                        % TEST_NAME)
                if autoclobber or confirm == 'yes':
                    try:
                        if verbosity >= 1:
                            print("Destroying old test database '%s'..." %
                                  self.connection.alias)
                        self._execute_test_db_destruction(
                            cursor, parameters, verbosity)
                        self._execute_test_db_creation(cursor, parameters,
                                                       verbosity)
                    except Exception as e:
                        sys.stderr.write(
                            "Got an error recreating the test database: %s\n" %
                            e)
                        sys.exit(2)
                else:
                    print("Tests cancelled.")
                    sys.exit(1)

        if self._test_user_create():
            if verbosity >= 1:
                print("Creating test user...")
            try:
                self._create_test_user(cursor, parameters, verbosity)
            except Exception as e:
                sys.stderr.write("Got an error creating the test user: %s\n" %
                                 e)
                if not autoclobber:
                    confirm = input(
                        "It appears the test user, %s, already exists. Type 'yes' to delete it, or 'no' to cancel: "
                        % TEST_USER)
                if autoclobber or confirm == 'yes':
                    try:
                        if verbosity >= 1:
                            print("Destroying old test user...")
                        self._destroy_test_user(cursor, parameters, verbosity)
                        if verbosity >= 1:
                            print("Creating test user...")
                        self._create_test_user(cursor, parameters, verbosity)
                    except Exception as e:
                        sys.stderr.write(
                            "Got an error recreating the test user: %s\n" % e)
                        sys.exit(2)
                else:
                    print("Tests cancelled.")
                    sys.exit(1)

        real_settings = settings.DATABASES[self.connection.alias]
        real_settings['SAVED_USER'] = self.connection.settings_dict[
            'SAVED_USER'] = self.connection.settings_dict['USER']
        real_settings['SAVED_PASSWORD'] = self.connection.settings_dict[
            'SAVED_PASSWORD'] = self.connection.settings_dict['PASSWORD']
        real_test_settings = real_settings['TEST']
        test_settings = self.connection.settings_dict['TEST']
        real_test_settings['USER'] = real_settings['USER'] = test_settings[
            'USER'] = self.connection.settings_dict['USER'] = TEST_USER
        real_settings['PASSWORD'] = self.connection.settings_dict[
            'PASSWORD'] = TEST_PASSWD

        return self.connection.settings_dict['NAME']
Esempio n. 50
0
def update_contenttypes(app,
                        created_models,
                        verbosity=2,
                        db=DEFAULT_DB_ALIAS,
                        **kwargs):
    """
        Django's default update_contenttypes relies on many inconsistent queries which causes problems
        with syncdb. This monkeypatch replaces it with a version that does look ups on unique constraints
        which are slightly better protected from eventual consistency issues by the context cache.
    """
    if verbosity >= 2:
        print(
            "Running Djangae version of update_contenttypes on {}".format(app))

    try:
        get_model('contenttypes', 'ContentType')
    except UnavailableApp:
        return

    if hasattr(router, "allow_syncdb"):
        if not router.allow_syncdb(db, ContentType):
            return
    else:
        if not router.allow_migrate(db, ContentType):
            return

    ContentType.objects.clear_cache()
    app_models = get_models(app)
    if not app_models:
        return
    # They all have the same app_label, get the first one.
    app_label = app_models[0]._meta.app_label
    app_models = dict((model._meta.model_name, model) for model in app_models)

    created_or_existing_pks = []
    created_or_existing_by_unique = {}

    for (model_name, model) in six.iteritems(app_models):
        # Go through get_or_create any models that we want to keep
        ct, created = ContentType.objects.get_or_create(
            app_label=app_label,
            model=model_name,
            defaults={"name": smart_text(model._meta.verbose_name_raw)})

        if verbosity >= 2 and created:
            print("Adding content type '%s | %s'" % (ct.app_label, ct.model))

        created_or_existing_pks.append(ct.pk)
        created_or_existing_by_unique[(app_label, model_name)] = ct.pk

    # Now lets see if we should remove any

    to_remove = [
        x for x in ContentType.objects.filter(app_label=app_label)
        if x.pk not in created_or_existing_pks
    ]

    # Now it's possible that our get_or_create failed because of consistency issues and we create a duplicate.
    # Then the original appears in the to_remove and we remove the original. This is bad. So here we go through the
    # to_remove list, and if we created the content type just now, we delete that one, and restore the original in the
    # cache
    for ct in to_remove:
        unique = (ct.app_label, ct.model)
        if unique in created_or_existing_by_unique:
            # We accidentally created a duplicate above due to HRD issues, delete the one we created
            ContentType.objects.get(
                pk=created_or_existing_by_unique[unique]).delete()
            created_or_existing_by_unique[unique] = ct.pk
            ct.save()  # Recache this one in the context cache

    to_remove = [
        x for x in to_remove
        if (x.app_label, x.model) not in created_or_existing_by_unique
    ]

    # Now, anything left should actually be a stale thing. It's still possible we missed some but they'll get picked up
    # next time. Confirm that the content type is stale before deletion.
    if to_remove:
        if kwargs.get('interactive', False):
            content_type_display = '\n'.join(
                ['    %s | %s' % (x.app_label, x.model) for x in to_remove])
            ok_to_delete = input(
                """The following content types are stale and need to be deleted:

%s

Any objects related to these content types by a foreign key will also
be deleted. Are you sure you want to delete these content types?
If you're unsure, answer 'no'.

    Type 'yes' to continue, or 'no' to cancel: """ % content_type_display)
        else:
            ok_to_delete = False

        if ok_to_delete == 'yes':
            for ct in to_remove:
                if verbosity >= 2:
                    print("Deleting stale content type '%s | %s'" %
                          (ct.app_label, ct.model))
                ct.delete()
        else:
            if verbosity >= 2:
                print("Stale content types remain.")
Esempio n. 51
0
def upgrade_database():
    """Perform an upgrade of the database.

    This will prompt the user for confirmation, with instructions on what
    will happen. If the database is using SQLite3, it will be backed up
    automatically, making a copy that contains the current timestamp.
    Otherwise, the user will be prompted to back it up instead.

    Returns:
        bool:
        ``True`` if the user has confirmed the upgrade. ``False`` if they
        have not.
    """
    from django.conf import settings
    from django.utils.six.moves import input

    database = settings.DATABASES['default']
    db_name = database['NAME']
    backup_db_name = None

    # See if we can make a backup of the database.
    if ('--no-backup' not in sys.argv and
        database['ENGINE'] == 'django.db.backends.sqlite3' and
        os.path.exists(db_name)):
        # Make a copy of the database.
        backup_db_name = '%s.%s' % (
            db_name,
            datetime.now().strftime('%Y%m%d.%H%M%S'))

        try:
            shutil.copy(db_name, backup_db_name)
        except Exception as e:
            sys.stderr.write('Unable to make a backup of your database at '
                             '%s: %s\n\n'
                             % (db_name, e))
            backup_db_name = None

    if '--noinput' in sys.argv:
        if backup_db_name:
            print (
                'Your existing database has been backed up to\n'
                '%s\n'
                % backup_db_name
            )

        perform_upgrade = True
    else:
        message = (
            'You are about to upgrade your database, which cannot be undone.'
            '\n\n'
        )

        if backup_db_name:
            message += (
                'Your existing database has been backed up to\n'
                '%s'
                % backup_db_name
            )
        else:
            message += 'PLEASE MAKE A BACKUP BEFORE YOU CONTINUE!'

        message += '\n\nType "yes" to continue or "no" to cancel: '

        perform_upgrade = input(message).lower() in ('yes', 'y')

        print('\n')

    if perform_upgrade:
        print(
            '===========================================================\n'
            'Performing the database upgrade. Any "unapplied evolutions"\n'
            'will be handled automatically.\n'
            '===========================================================\n'
        )

        commands = [
            ['syncdb', '--noinput'],
            ['evolve', '--noinput']
        ]

        for command in commands:
            execute_from_command_line([sys.argv[0]] + command)
    else:
        print('The upgrade has been cancelled.\n')
        sys.exit(1)
Esempio n. 52
0
 def ask_user(self, message, default=None):
     if getattr(self, 'interactive_mode', False):
         return input(message)
     return default
Esempio n. 53
0
    def handle(self, *args, **options):
        HOSTS = settings.ES_CONNECTIONS[
            settings.DESIGNSAFE_ENVIRONMENT]['hosts']
        es_client = elasticsearch.Elasticsearch(HOSTS,
                                                http_auth=settings.ES_AUTH)
        index = options.get('index')
        cleanup = options.get('cleanup')
        swap_only = options.get('swap-only')

        index_config = settings.ES_INDICES[index]

        default_index_alias = index_config['alias']
        reindex_index_alias = default_index_alias + '-reindex'

        if not swap_only:
            confirm = eval(
                input(
                    'This will delete any documents in the index "{}" and recreate the index. Continue? (Y/n) '
                    .format(reindex_index_alias)))
            if confirm != 'Y':
                raise SystemExit
            # Set up a fresh reindexing alias.
            setup_index(index_config, force=True, reindex=True)

        try:
            default_index_name = list(
                Index(default_index_alias,
                      using=es_client).get_alias().keys())[0]
            reindex_index_name = list(
                Index(reindex_index_alias,
                      using=es_client).get_alias().keys())[0]
        except Exception as e:
            self.stdout.write(
                'Unable to lookup required indices by alias. Have you set up both a default and a reindexing index?'
            )
            raise SystemExit

        if not swap_only:
            # Reindex file metadata from the default index to the reindexing index
            elasticsearch.helpers.reindex(es_client, default_index_name,
                                          reindex_index_name)

        alias_body = {
            'actions': [
                {
                    'remove': {
                        'index': default_index_name,
                        'alias': default_index_alias
                    }
                },
                {
                    'remove': {
                        'index': reindex_index_name,
                        'alias': reindex_index_alias
                    }
                },
                {
                    'add': {
                        'index': default_index_name,
                        'alias': reindex_index_alias
                    }
                },
                {
                    'add': {
                        'index': reindex_index_name,
                        'alias': default_index_alias
                    }
                },
            ]
        }
        # Swap the aliases of the default and reindexing aliases.
        es_client.indices.update_aliases(alias_body)

        # Re-initialize the new reindexing index to save space.
        if cleanup:
            reindex_index_name = list(
                Index(reindex_index_alias,
                      using=es_client).get_alias().keys())[0]
            Index(reindex_index_name, using=es_client).delete(ignore=404)
Esempio n. 54
0
def update_contenttypes(app,
                        created_models,
                        verbosity=2,
                        db=DEFAULT_DB_ALIAS,
                        **kwargs):
    """
    Creates content types for models in the given app, removing any model
    entries that no longer have a matching model class.
    """
    try:
        get_model('contenttypes', 'ContentType')
    except UnavailableApp:
        return

    if not router.allow_migrate(db, ContentType):
        return

    ContentType.objects.clear_cache()
    app_models = get_models(app)
    if not app_models:
        return
    # They all have the same app_label, get the first one.
    app_label = app_models[0]._meta.app_label
    app_models = dict((model._meta.model_name, model) for model in app_models)

    # Get all the content types
    content_types = dict(
        (ct.model, ct)
        for ct in ContentType.objects.using(db).filter(app_label=app_label))
    to_remove = [
        ct for (model_name, ct) in six.iteritems(content_types)
        if model_name not in app_models
    ]

    cts = [
        ContentType(
            name=smart_text(model._meta.verbose_name_raw),
            app_label=app_label,
            model=model_name,
        ) for (model_name, model) in six.iteritems(app_models)
        if model_name not in content_types
    ]
    ContentType.objects.using(db).bulk_create(cts)
    if verbosity >= 2:
        for ct in cts:
            print("Adding content type '%s | %s'" % (ct.app_label, ct.model))

    # Confirm that the content type is stale before deletion.
    if to_remove:
        if kwargs.get('interactive', False):
            content_type_display = '\n'.join(
                '    %s | %s' % (ct.app_label, ct.model) for ct in to_remove)
            ok_to_delete = input(
                """The following content types are stale and need to be deleted:

%s

Any objects related to these content types by a foreign key will also
be deleted. Are you sure you want to delete these content types?
If you're unsure, answer 'no'.

    Type 'yes' to continue, or 'no' to cancel: """ % content_type_display)
        else:
            ok_to_delete = False

        if ok_to_delete == 'yes':
            for ct in to_remove:
                if verbosity >= 2:
                    print("Deleting stale content type '%s | %s'" %
                          (ct.app_label, ct.model))
                ct.delete()
        else:
            if verbosity >= 2:
                print("Stale content types remain.")
 def handle(self, *args, **options):
     logfile = options.get('logfile')
     if logfile:
         handler = logging.FileHandler(logfile)
     else:
         handler = logging.StreamHandler()
     handler.setLevel(logging.INFO)
     handler.setFormatter(formatter)
     logger.addHandler(handler)
     if acquire_lock():
         try:
             if not options.get('filename'):
                 raise CommandError(
                     'You must provide path to csv-file. Use -f option.')
             path_to_file = os.path.normpath(options.get('filename'))
             if not os.path.exists(path_to_file):
                 raise CommandError('File not found')
             if os.path.isdir(path_to_file):
                 raise CommandError('%s is a directory' % path_to_file)
             with open(path_to_file, 'rb') as csvfile:
                 try:
                     dialect = csv.Sniffer().sniff(csvfile.read(2048),
                                                   delimiters=';')
                     csvfile.seek(0)
                     data = csv.DictReader(
                         csvfile,
                         fieldnames=['old_path', 'new_path'],
                         dialect=dialect)
                 except csv.Error:
                     mess = 'Incorrect file format'
                     logger.error(mess)
                     raise CommandError(mess)
                 with transaction.commit_on_success():
                     try:
                         for i, row in enumerate(data):
                             old_path = row['old_path']
                             new_path = row['new_path']
                             if not old_path.startswith("/"):
                                 mess = 'LINE: %s. Invalid url: %s' % (
                                     i + 1, old_path)
                                 logger.error(mess)
                                 raise Exception(mess)
                             if not new_path.startswith("/"):
                                 mess = 'LINE: %s. Invalid url: %s' % (
                                     i + 1, new_path)
                                 logger.error(mess)
                                 raise Exception(mess)
                             redirect, created = Redirect.objects.get_or_create(
                                 site_id=settings.SITE_ID,
                                 old_path=old_path)
                             if created:
                                 redirect.new_path = new_path
                                 redirect.save()
                             else:
                                 if redirect.new_path != new_path:
                                     change = ""
                                     if not options.get('change'):
                                         self.stdout.write(
                                             '\nRedirect %s exist. Change to %s ---> %s ?:\n'
                                             % (redirect.__unicode__(),
                                                old_path, new_path))
                                         change = input(
                                             '"y" for Yes or "n" for No (leave blank for "n"): '
                                         )
                                     if change == "y" or options.get(
                                             'change'):
                                         redirect.new_path = new_path
                                         redirect.save()
                     except DatabaseError:
                         mess = 'Error in transaction. Please repeat import'
                         logger.error(mess)
                         raise
             logger.info('Import completed successfully')
         finally:
             release_lock()
     else:
         logger.error(
             'Redirects is already being imported. Please repeat later')
Esempio n. 56
0
def get_input(text):
    return input(text).strip()
Esempio n. 57
0
def update_contenttypes(app_config,
                        verbosity=2,
                        interactive=True,
                        using=DEFAULT_DB_ALIAS,
                        apps=global_apps,
                        **kwargs):
    """
    Creates content types for models in the given app, removing any model
    entries that no longer have a matching model class.
    """
    if not app_config.models_module:
        return

    app_label = app_config.label
    try:
        app_config = apps.get_app_config(app_label)
        ContentType = apps.get_model('contenttypes', 'ContentType')
    except LookupError:
        return

    if not router.allow_migrate_model(using, ContentType):
        return

    ContentType.objects.clear_cache()
    # Always clear the global content types cache.
    if apps is not global_apps:
        global_apps.get_model('contenttypes',
                              'ContentType').objects.clear_cache()

    app_models = {
        model._meta.model_name: model
        for model in app_config.get_models()
    }

    if not app_models:
        return

    # Get all the content types
    content_types = {
        ct.model: ct
        for ct in ContentType.objects.using(using).filter(app_label=app_label)
    }
    to_remove = [
        ct for (model_name, ct) in six.iteritems(content_types)
        if model_name not in app_models
    ]

    cts = [
        ContentType(
            app_label=app_label,
            model=model_name,
        ) for (model_name, model) in six.iteritems(app_models)
        if model_name not in content_types
    ]
    ContentType.objects.using(using).bulk_create(cts)
    if verbosity >= 2:
        for ct in cts:
            print("Adding content type '%s | %s'" % (ct.app_label, ct.model))

    # Confirm that the content type is stale before deletion.
    if to_remove:
        if interactive:
            content_type_display = '\n'.join(
                '    %s | %s' % (ct.app_label, ct.model) for ct in to_remove)
            ok_to_delete = input(
                """The following content types are stale and need to be deleted:

%s

Any objects related to these content types by a foreign key will also
be deleted. Are you sure you want to delete these content types?
If you're unsure, answer 'no'.

    Type 'yes' to continue, or 'no' to cancel: """ % content_type_display)
        else:
            ok_to_delete = False

        if ok_to_delete == 'yes':
            for ct in to_remove:
                if verbosity >= 2:
                    print("Deleting stale content type '%s | %s'" %
                          (ct.app_label, ct.model))
                ct.delete()
        else:
            if verbosity >= 2:
                print("Stale content types remain.")