aboutsummaryrefslogtreecommitdiff
path: root/ihatemoney/manage.py
blob: 6343ee7c7e7083d1d4d26d25158b6ec99d559e31 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
#!/usr/bin/env python

import os
import random
import sys
import getpass

from flask_script import Manager, Command, Option
from flask_migrate import Migrate, MigrateCommand
from werkzeug.security import generate_password_hash

from ihatemoney.run import create_app
from ihatemoney.models import db, Project
from ihatemoney.utils import create_jinja_env


class GeneratePasswordHash(Command):

    """Get password from user and hash it without printing it in clear text."""

    def run(self):
        password = getpass.getpass(prompt="Password: ")
        print(generate_password_hash(password))


class GenerateConfig(Command):
    def get_options(self):
        return [
            Option(
                "config_file",
                choices=[
                    "ihatemoney.cfg",
                    "apache-vhost.conf",
                    "gunicorn.conf.py",
                    "supervisord.conf",
                    "nginx.conf",
                ],
            )
        ]

    @staticmethod
    def gen_secret_key():
        return "".join(
            [
                random.SystemRandom().choice(
                    "abcdefghijklmnopqrstuvwxyz0123456789!@#$%^&*(-_=+)"
                )
                for i in range(50)
            ]
        )

    def run(self, config_file):
        env = create_jinja_env("conf-templates", strict_rendering=True)
        template = env.get_template("%s.j2" % config_file)

        bin_path = os.path.dirname(sys.executable)
        pkg_path = os.path.abspath(os.path.dirname(__file__))

        print(
            template.render(
                pkg_path=pkg_path,
                bin_path=bin_path,
                sys_prefix=sys.prefix,
                secret_key=self.gen_secret_key(),
            )
        )


class DeleteProject(Command):
    def run(self, project_name):
        demo_project = Project.query.get(project_name)
        db.session.delete(demo_project)
        db.session.commit()


def main():
    QUIET_COMMANDS = ("generate_password_hash", "generate-config")

    exception = None
    backup_stderr = sys.stderr
    # Hack to divert stderr for commands generating content to stdout
    # to avoid confusing the user
    if len(sys.argv) > 1 and sys.argv[1] in QUIET_COMMANDS:
        sys.stderr = open(os.devnull, "w")

    try:
        app = create_app()
        Migrate(app, db)
    except Exception as e:
        exception = e

    # Restore stderr
    sys.stderr = backup_stderr

    if exception:
        raise exception

    manager = Manager(app)
    manager.add_command("db", MigrateCommand)
    manager.add_command("generate_password_hash", GeneratePasswordHash)
    manager.add_command("generate-config", GenerateConfig)
    manager.add_command("delete-project", DeleteProject)
    manager.run()


if __name__ == "__main__":
    main()