Browse Source

Source formatted with Black

pull/230/head
Pēteris Caune 6 years ago
parent
commit
cdfc9840a7
No known key found for this signature in database GPG Key ID: E28D7679E9A9EDE2
207 changed files with 2053 additions and 1921 deletions
  1. +57
    -34
      hc/accounts/admin.py
  2. +1
    -5
      hc/accounts/backends.py
  3. +8
    -5
      hc/accounts/forms.py
  4. +1
    -4
      hc/accounts/management/commands/senddeletionnotices.py
  5. +23
    -9
      hc/accounts/migrations/0001_initial.py
  6. +4
    -6
      hc/accounts/migrations/0002_profile_ping_log_limit.py
  7. +4
    -6
      hc/accounts/migrations/0003_profile_token.py
  8. +4
    -6
      hc/accounts/migrations/0004_profile_api_key.py
  9. +25
    -13
      hc/accounts/migrations/0005_auto_20160509_0801.py
  10. +9
    -7
      hc/accounts/migrations/0006_profile_current_team.py
  11. +4
    -6
      hc/accounts/migrations/0007_profile_check_limit.py
  12. +3
    -7
      hc/accounts/migrations/0008_profile_bill_to.py
  13. +5
    -11
      hc/accounts/migrations/0009_auto_20170714_1734.py
  14. +4
    -6
      hc/accounts/migrations/0010_profile_team_limit.py
  15. +5
    -7
      hc/accounts/migrations/0011_profile_sort.py
  16. +13
    -8
      hc/accounts/migrations/0012_auto_20171014_1002.py
  17. +2
    -7
      hc/accounts/migrations/0013_remove_profile_team_access_allowed.py
  18. +9
    -7
      hc/accounts/migrations/0014_auto_20171227_1530.py
  19. +5
    -7
      hc/accounts/migrations/0015_auto_20181029_1858.py
  20. +2
    -9
      hc/accounts/migrations/0016_remove_profile_bill_to.py
  21. +39
    -14
      hc/accounts/migrations/0017_auto_20190112_1426.py
  22. +2
    -6
      hc/accounts/migrations/0018_auto_20190112_1426.py
  23. +4
    -6
      hc/accounts/migrations/0019_project_badge_key.py
  24. +2
    -6
      hc/accounts/migrations/0020_auto_20190112_1950.py
  25. +4
    -6
      hc/accounts/migrations/0021_auto_20190112_2005.py
  26. +7
    -7
      hc/accounts/migrations/0022_auto_20190114_0857.py
  27. +4
    -15
      hc/accounts/migrations/0023_auto_20190117_1419.py
  28. +3
    -11
      hc/accounts/migrations/0024_auto_20190119_1540.py
  29. +2
    -9
      hc/accounts/migrations/0025_remove_member_team.py
  30. +7
    -9
      hc/accounts/migrations/0026_auto_20190204_2042.py
  31. +4
    -6
      hc/accounts/migrations/0027_profile_deletion_notice_date.py
  32. +12
    -17
      hc/accounts/models.py
  33. +0
    -1
      hc/accounts/tests/test_add_project.py
  34. +0
    -1
      hc/accounts/tests/test_admin.py
  35. +0
    -1
      hc/accounts/tests/test_change_email.py
  36. +0
    -1
      hc/accounts/tests/test_check_token.py
  37. +0
    -1
      hc/accounts/tests/test_close_account.py
  38. +6
    -26
      hc/accounts/tests/test_login.py
  39. +0
    -1
      hc/accounts/tests/test_notifications.py
  40. +2
    -3
      hc/accounts/tests/test_profile.py
  41. +7
    -4
      hc/accounts/tests/test_project.py
  42. +0
    -1
      hc/accounts/tests/test_project_model.py
  43. +0
    -1
      hc/accounts/tests/test_remove_project.py
  44. +0
    -1
      hc/accounts/tests/test_set_password.py
  45. +0
    -1
      hc/accounts/tests/test_signup.py
  46. +0
    -1
      hc/accounts/tests/test_team_access_middleware.py
  47. +0
    -1
      hc/accounts/tests/test_unsubscribe_reports.py
  48. +21
    -28
      hc/accounts/urls.py
  49. +31
    -30
      hc/accounts/views.py
  50. +48
    -37
      hc/api/admin.py
  51. +5
    -0
      hc/api/decorators.py
  52. +4
    -3
      hc/api/management/commands/prunenotifications.py
  53. +1
    -1
      hc/api/management/commands/prunepings.py
  54. +3
    -2
      hc/api/management/commands/prunepingsslow.py
  55. +1
    -1
      hc/api/management/commands/prunetokenbucket.py
  56. +9
    -9
      hc/api/management/commands/sendalerts.py
  57. +10
    -10
      hc/api/management/commands/sendreports.py
  58. +1
    -1
      hc/api/management/commands/settelegramwebhook.py
  59. +12
    -9
      hc/api/management/commands/smtpd.py
  60. +20
    -9
      hc/api/migrations/0001_initial.py
  61. +29
    -14
      hc/api/migrations/0002_auto_20150616_0732.py
  62. +7
    -9
      hc/api/migrations/0003_auto_20150616_1249.py
  63. +8
    -10
      hc/api/migrations/0004_auto_20150616_1319.py
  64. +10
    -7
      hc/api/migrations/0005_auto_20150630_2021.py
  65. +4
    -6
      hc/api/migrations/0006_check_grace.py
  66. +18
    -12
      hc/api/migrations/0007_ping.py
  67. +4
    -6
      hc/api/migrations/0008_auto_20150801_1213.py
  68. +8
    -10
      hc/api/migrations/0009_auto_20150801_1250.py
  69. +34
    -11
      hc/api/migrations/0010_channel.py
  70. +20
    -11
      hc/api/migrations/0011_notification.py
  71. +13
    -7
      hc/api/migrations/0012_auto_20150930_1922.py
  72. +14
    -7
      hc/api/migrations/0013_auto_20151001_2029.py
  73. +4
    -6
      hc/api/migrations/0014_auto_20151019_2039.py
  74. +3
    -6
      hc/api/migrations/0015_auto_20151022_1008.py
  75. +14
    -7
      hc/api/migrations/0016_auto_20151030_1107.py
  76. +15
    -7
      hc/api/migrations/0017_auto_20151117_1032.py
  77. +2
    -9
      hc/api/migrations/0018_remove_ping_body.py
  78. +4
    -6
      hc/api/migrations/0019_check_tags.py
  79. +3
    -7
      hc/api/migrations/0020_check_n_pings.py
  80. +3
    -7
      hc/api/migrations/0021_ping_n.py
  81. +4
    -9
      hc/api/migrations/0022_auto_20160130_2042.py
  82. +3
    -6
      hc/api/migrations/0023_auto_20160131_1919.py
  83. +16
    -7
      hc/api/migrations/0024_auto_20160203_2227.py
  84. +16
    -7
      hc/api/migrations/0025_auto_20160216_1214.py
  85. +3
    -7
      hc/api/migrations/0026_auto_20160415_1824.py
  86. +30
    -15
      hc/api/migrations/0027_auto_20161213_1059.py
  87. +20
    -8
      hc/api/migrations/0028_auto_20170305_1907.py
  88. +4
    -6
      hc/api/migrations/0029_auto_20170507_1251.py
  89. +4
    -6
      hc/api/migrations/0030_check_last_ping_body.py
  90. +4
    -6
      hc/api/migrations/0031_auto_20170509_1320.py
  91. +20
    -7
      hc/api/migrations/0032_auto_20170608_1158.py
  92. +21
    -7
      hc/api/migrations/0033_auto_20170714_1715.py
  93. +22
    -7
      hc/api/migrations/0034_auto_20171227_1530.py
  94. +23
    -7
      hc/api/migrations/0035_auto_20171229_2008.py
  95. +2
    -9
      hc/api/migrations/0036_auto_20180116_2243.py
  96. +4
    -6
      hc/api/migrations/0037_auto_20180127_1215.py
  97. +5
    -7
      hc/api/migrations/0038_auto_20180318_1306.py
  98. +2
    -9
      hc/api/migrations/0039_remove_check_last_ping_body.py
  99. +4
    -8
      hc/api/migrations/0040_auto_20180517_1336.py
  100. +3
    -7
      hc/api/migrations/0041_check_desc.py

+ 57
- 34
hc/accounts/admin.py View File

@ -20,35 +20,58 @@ class Fieldset:
class ProfileFieldset(Fieldset):
name = "User Profile"
fields = ("email", "current_project", "reports_allowed",
"next_report_date", "nag_period", "next_nag_date",
"deletion_notice_date",
"token", "sort")
fields = (
"email",
"current_project",
"reports_allowed",
"next_report_date",
"nag_period",
"next_nag_date",
"deletion_notice_date",
"token",
"sort",
)
class TeamFieldset(Fieldset):
name = "Team"
fields = ("team_limit", "check_limit", "ping_log_limit", "sms_limit",
"sms_sent", "last_sms_date")
fields = (
"team_limit",
"check_limit",
"ping_log_limit",
"sms_limit",
"sms_sent",
"last_sms_date",
)
@admin.register(Profile)
class ProfileAdmin(admin.ModelAdmin):
class Media:
css = {
'all': ('css/admin/profiles.css',)
}
css = {"all": ("css/admin/profiles.css",)}
readonly_fields = ("user", "email")
raw_id_fields = ("current_project", )
raw_id_fields = ("current_project",)
search_fields = ["id", "user__email"]
list_per_page = 50
list_select_related = ("user", )
list_display = ("id", "email", "engagement", "date_joined", "last_login",
"projects", "invited", "sms", "reports_allowed")
list_filter = ("user__date_joined", "user__last_login",
"reports_allowed", "check_limit")
list_select_related = ("user",)
list_display = (
"id",
"email",
"engagement",
"date_joined",
"last_login",
"projects",
"invited",
"sms",
"reports_allowed",
)
list_filter = (
"user__date_joined",
"user__last_login",
"reports_allowed",
"check_limit",
)
fieldsets = (ProfileFieldset.tuple(), TeamFieldset.tuple())
@ -83,23 +106,21 @@ class ProfileAdmin(admin.ModelAdmin):
@mark_safe
def email(self, obj):
s = escape(obj.user.email)
if obj.plan:
return "<span title='%s'>%s</span>" % (obj.plan, s)
s = escape(obj.user.email)
if obj.plan:
return "<span title='%s'>%s</span>" % (obj.plan, s)
return s
return s
def last_login(self, obj):
return obj.user.last_login
return obj.user.last_login
def date_joined(self, obj):
return obj.user.date_joined
return obj.user.date_joined
@mark_safe
def projects(self, obj):
return render_to_string("admin/profile_list_projects.html", {
"profile": obj
})
return render_to_string("admin/profile_list_projects.html", {"profile": obj})
def invited(self, obj):
return "%d of %d" % (obj.num_members, obj.team_limit)
@ -111,14 +132,12 @@ class ProfileAdmin(admin.ModelAdmin):
@admin.register(Project)
class ProjectAdmin(admin.ModelAdmin):
readonly_fields = ("code", "owner")
list_select_related = ("owner", )
list_select_related = ("owner",)
list_display = ("id", "name_", "users", "engagement", "switch")
search_fields = ["id", "name", "owner__email"]
class Media:
css = {
'all': ('css/admin/projects.css',)
}
css = {"all": ("css/admin/projects.css",)}
def get_queryset(self, request):
qs = super(ProjectAdmin, self).get_queryset(request)
@ -138,9 +157,7 @@ class ProjectAdmin(admin.ModelAdmin):
if obj.num_members == 0:
return obj.owner.email
else:
return render_to_string("admin/project_list_team.html", {
"project": obj
})
return render_to_string("admin/project_list_team.html", {"project": obj})
def email(self, obj):
return obj.owner.email
@ -173,8 +190,14 @@ class ProjectAdmin(admin.ModelAdmin):
class HcUserAdmin(UserAdmin):
actions = ["send_report"]
list_display = ('id', 'email', 'engagement', 'date_joined', 'last_login',
'is_staff')
list_display = (
"id",
"email",
"engagement",
"date_joined",
"last_login",
"is_staff",
)
list_display_links = ("id", "email")
list_filter = ("last_login", "date_joined", "is_staff", "is_active")


+ 1
- 5
hc/accounts/backends.py View File

@ -3,11 +3,9 @@ from hc.accounts.models import Profile
class BasicBackend(object):
def get_user(self, user_id):
try:
q = User.objects.select_related("profile",
"profile__current_project")
q = User.objects.select_related("profile", "profile__current_project")
return q.get(pk=user_id)
except User.DoesNotExist:
@ -16,7 +14,6 @@ class BasicBackend(object):
# Authenticate against the token in user's profile.
class ProfileBackend(BasicBackend):
def authenticate(self, request=None, username=None, token=None):
try:
profiles = Profile.objects.select_related("user")
@ -31,7 +28,6 @@ class ProfileBackend(BasicBackend):
class EmailBackend(BasicBackend):
def authenticate(self, request=None, username=None, password=None):
try:
user = User.objects.get(email=username)


+ 8
- 5
hc/accounts/forms.py View File

@ -6,7 +6,6 @@ from hc.api.models import TokenBucket
class LowercaseEmailField(forms.EmailField):
def clean(self, value):
value = super(LowercaseEmailField, self).clean(value)
return value.lower()
@ -15,12 +14,16 @@ class LowercaseEmailField(forms.EmailField):
class AvailableEmailForm(forms.Form):
# Call it "identity" instead of "email"
# to avoid some of the dumber bots
identity = LowercaseEmailField(error_messages={'required': 'Please enter your email address.'})
identity = LowercaseEmailField(
error_messages={"required": "Please enter your email address."}
)
def clean_identity(self):
v = self.cleaned_data["identity"]
if User.objects.filter(email=v).exists():
raise forms.ValidationError("An account with this email address already exists.")
raise forms.ValidationError(
"An account with this email address already exists."
)
return v
@ -48,8 +51,8 @@ class PasswordLoginForm(forms.Form):
password = forms.CharField()
def clean(self):
username = self.cleaned_data.get('email')
password = self.cleaned_data.get('password')
username = self.cleaned_data.get("email")
password = self.cleaned_data.get("password")
if username and password:
if not TokenBucket.authorize_login_password(username):


+ 1
- 4
hc/accounts/management/commands/senddeletionnotices.py View File

@ -51,10 +51,7 @@ class Command(BaseCommand):
profile.deletion_notice_date = now()
profile.save()
ctx = {
"email": profile.user.email,
"support_email": settings.SUPPORT_EMAIL
}
ctx = {"email": profile.user.email, "support_email": settings.SUPPORT_EMAIL}
emails.deletion_notice(profile.user.email, ctx)
# Throttle so we don't send too many emails at once:
time.sleep(1)


+ 23
- 9
hc/accounts/migrations/0001_initial.py View File

@ -7,18 +7,32 @@ from django.conf import settings
class Migration(migrations.Migration):
dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
]
dependencies = [migrations.swappable_dependency(settings.AUTH_USER_MODEL)]
operations = [
migrations.CreateModel(
name='Profile',
name="Profile",
fields=[
('id', models.AutoField(auto_created=True, serialize=False, verbose_name='ID', primary_key=True)),
('next_report_date', models.DateTimeField(null=True, blank=True)),
('reports_allowed', models.BooleanField(default=True)),
('user', models.OneToOneField(blank=True, to=settings.AUTH_USER_MODEL, null=True, on_delete=models.CASCADE)),
(
"id",
models.AutoField(
auto_created=True,
serialize=False,
verbose_name="ID",
primary_key=True,
),
),
("next_report_date", models.DateTimeField(null=True, blank=True)),
("reports_allowed", models.BooleanField(default=True)),
(
"user",
models.OneToOneField(
blank=True,
to=settings.AUTH_USER_MODEL,
null=True,
on_delete=models.CASCADE,
),
),
],
),
)
]

+ 4
- 6
hc/accounts/migrations/0002_profile_ping_log_limit.py View File

@ -6,14 +6,12 @@ from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('accounts', '0001_initial'),
]
dependencies = [("accounts", "0001_initial")]
operations = [
migrations.AddField(
model_name='profile',
name='ping_log_limit',
model_name="profile",
name="ping_log_limit",
field=models.IntegerField(default=100),
),
)
]

+ 4
- 6
hc/accounts/migrations/0003_profile_token.py View File

@ -7,14 +7,12 @@ from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('accounts', '0002_profile_ping_log_limit'),
]
dependencies = [("accounts", "0002_profile_ping_log_limit")]
operations = [
migrations.AddField(
model_name='profile',
name='token',
model_name="profile",
name="token",
field=models.CharField(blank=True, max_length=128),
),
)
]

+ 4
- 6
hc/accounts/migrations/0004_profile_api_key.py View File

@ -7,14 +7,12 @@ from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('accounts', '0003_profile_token'),
]
dependencies = [("accounts", "0003_profile_token")]
operations = [
migrations.AddField(
model_name='profile',
name='api_key',
model_name="profile",
name="api_key",
field=models.CharField(blank=True, max_length=128),
),
)
]

+ 25
- 13
hc/accounts/migrations/0005_auto_20160509_0801.py View File

@ -11,34 +11,46 @@ class Migration(migrations.Migration):
dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
('accounts', '0004_profile_api_key'),
("accounts", "0004_profile_api_key"),
]
operations = [
migrations.CreateModel(
name='Member',
name="Member",
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
(
"id",
models.AutoField(
auto_created=True,
primary_key=True,
serialize=False,
verbose_name="ID",
),
)
],
),
migrations.AddField(
model_name='profile',
name='team_access_allowed',
model_name="profile",
name="team_access_allowed",
field=models.BooleanField(default=False),
),
migrations.AddField(
model_name='profile',
name='team_name',
model_name="profile",
name="team_name",
field=models.CharField(blank=True, max_length=200),
),
migrations.AddField(
model_name='member',
name='team',
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='accounts.Profile'),
model_name="member",
name="team",
field=models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE, to="accounts.Profile"
),
),
migrations.AddField(
model_name='member',
name='user',
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL),
model_name="member",
name="user",
field=models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL
),
),
]

+ 9
- 7
hc/accounts/migrations/0006_profile_current_team.py View File

@ -8,14 +8,16 @@ import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('accounts', '0005_auto_20160509_0801'),
]
dependencies = [("accounts", "0005_auto_20160509_0801")]
operations = [
migrations.AddField(
model_name='profile',
name='current_team',
field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, to='accounts.Profile'),
),
model_name="profile",
name="current_team",
field=models.ForeignKey(
null=True,
on_delete=django.db.models.deletion.SET_NULL,
to="accounts.Profile",
),
)
]

+ 4
- 6
hc/accounts/migrations/0007_profile_check_limit.py View File

@ -7,14 +7,12 @@ from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('accounts', '0006_profile_current_team'),
]
dependencies = [("accounts", "0006_profile_current_team")]
operations = [
migrations.AddField(
model_name='profile',
name='check_limit',
model_name="profile",
name="check_limit",
field=models.IntegerField(default=20),
),
)
]

+ 3
- 7
hc/accounts/migrations/0008_profile_bill_to.py View File

@ -7,14 +7,10 @@ from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('accounts', '0007_profile_check_limit'),
]
dependencies = [("accounts", "0007_profile_check_limit")]
operations = [
migrations.AddField(
model_name='profile',
name='bill_to',
field=models.TextField(blank=True),
),
model_name="profile", name="bill_to", field=models.TextField(blank=True)
)
]

+ 5
- 11
hc/accounts/migrations/0009_auto_20170714_1734.py View File

@ -7,24 +7,18 @@ from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('accounts', '0008_profile_bill_to'),
]
dependencies = [("accounts", "0008_profile_bill_to")]
operations = [
migrations.AddField(
model_name='profile',
name='last_sms_date',
model_name="profile",
name="last_sms_date",
field=models.DateTimeField(blank=True, null=True),
),
migrations.AddField(
model_name='profile',
name='sms_limit',
field=models.IntegerField(default=0),
model_name="profile", name="sms_limit", field=models.IntegerField(default=0)
),
migrations.AddField(
model_name='profile',
name='sms_sent',
field=models.IntegerField(default=0),
model_name="profile", name="sms_sent", field=models.IntegerField(default=0)
),
]

+ 4
- 6
hc/accounts/migrations/0010_profile_team_limit.py View File

@ -7,14 +7,12 @@ from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('accounts', '0009_auto_20170714_1734'),
]
dependencies = [("accounts", "0009_auto_20170714_1734")]
operations = [
migrations.AddField(
model_name='profile',
name='team_limit',
model_name="profile",
name="team_limit",
field=models.IntegerField(default=2),
),
)
]

+ 5
- 7
hc/accounts/migrations/0011_profile_sort.py View File

@ -7,14 +7,12 @@ from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('accounts', '0010_profile_team_limit'),
]
dependencies = [("accounts", "0010_profile_team_limit")]
operations = [
migrations.AddField(
model_name='profile',
name='sort',
field=models.CharField(default='created', max_length=20),
),
model_name="profile",
name="sort",
field=models.CharField(default="created", max_length=20),
)
]

+ 13
- 8
hc/accounts/migrations/0012_auto_20171014_1002.py View File

@ -8,19 +8,24 @@ from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('accounts', '0011_profile_sort'),
]
dependencies = [("accounts", "0011_profile_sort")]
operations = [
migrations.AddField(
model_name='profile',
name='nag_period',
field=models.DurationField(choices=[(datetime.timedelta(0), 'Disabled'), (datetime.timedelta(0, 3600), 'Hourly'), (datetime.timedelta(1), 'Daily')], default=datetime.timedelta(0)),
model_name="profile",
name="nag_period",
field=models.DurationField(
choices=[
(datetime.timedelta(0), "Disabled"),
(datetime.timedelta(0, 3600), "Hourly"),
(datetime.timedelta(1), "Daily"),
],
default=datetime.timedelta(0),
),
),
migrations.AddField(
model_name='profile',
name='next_nag_date',
model_name="profile",
name="next_nag_date",
field=models.DateTimeField(blank=True, null=True),
),
]

+ 2
- 7
hc/accounts/migrations/0013_remove_profile_team_access_allowed.py View File

@ -7,13 +7,8 @@ from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('accounts', '0012_auto_20171014_1002'),
]
dependencies = [("accounts", "0012_auto_20171014_1002")]
operations = [
migrations.RemoveField(
model_name='profile',
name='team_access_allowed',
),
migrations.RemoveField(model_name="profile", name="team_access_allowed")
]

+ 9
- 7
hc/accounts/migrations/0014_auto_20171227_1530.py View File

@ -9,14 +9,16 @@ import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('accounts', '0013_remove_profile_team_access_allowed'),
]
dependencies = [("accounts", "0013_remove_profile_team_access_allowed")]
operations = [
migrations.AlterField(
model_name='member',
name='user',
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='memberships', to=settings.AUTH_USER_MODEL),
),
model_name="member",
name="user",
field=models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE,
related_name="memberships",
to=settings.AUTH_USER_MODEL,
),
)
]

+ 5
- 7
hc/accounts/migrations/0015_auto_20181029_1858.py View File

@ -5,19 +5,17 @@ from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('accounts', '0014_auto_20171227_1530'),
]
dependencies = [("accounts", "0014_auto_20171227_1530")]
operations = [
migrations.AddField(
model_name='profile',
name='api_key_id',
model_name="profile",
name="api_key_id",
field=models.CharField(blank=True, max_length=128),
),
migrations.AddField(
model_name='profile',
name='api_key_readonly',
model_name="profile",
name="api_key_readonly",
field=models.CharField(blank=True, max_length=128),
),
]

+ 2
- 9
hc/accounts/migrations/0016_remove_profile_bill_to.py View File

@ -5,13 +5,6 @@ from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('accounts', '0015_auto_20181029_1858'),
]
dependencies = [("accounts", "0015_auto_20181029_1858")]
operations = [
migrations.RemoveField(
model_name='profile',
name='bill_to',
),
]
operations = [migrations.RemoveField(model_name="profile", name="bill_to")]

+ 39
- 14
hc/accounts/migrations/0017_auto_20190112_1426.py View File

@ -10,29 +10,54 @@ class Migration(migrations.Migration):
dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
('accounts', '0016_remove_profile_bill_to'),
("accounts", "0016_remove_profile_bill_to"),
]
operations = [
migrations.CreateModel(
name='Project',
name="Project",
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('code', models.UUIDField(default=uuid.uuid4, editable=False, unique=True)),
('name', models.CharField(blank=True, max_length=200)),
('api_key', models.CharField(blank=True, max_length=128)),
('api_key_readonly', models.CharField(blank=True, max_length=128)),
('owner', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
(
"id",
models.AutoField(
auto_created=True,
primary_key=True,
serialize=False,
verbose_name="ID",
),
),
(
"code",
models.UUIDField(default=uuid.uuid4, editable=False, unique=True),
),
("name", models.CharField(blank=True, max_length=200)),
("api_key", models.CharField(blank=True, max_length=128)),
("api_key_readonly", models.CharField(blank=True, max_length=128)),
(
"owner",
models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE,
to=settings.AUTH_USER_MODEL,
),
),
],
),
migrations.AddField(
model_name='member',
name='project',
field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, to='accounts.Project'),
model_name="member",
name="project",
field=models.ForeignKey(
null=True,
on_delete=django.db.models.deletion.CASCADE,
to="accounts.Project",
),
),
migrations.AddField(
model_name='profile',
name='current_project',
field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, to='accounts.Project'),
model_name="profile",
name="current_project",
field=models.ForeignKey(
null=True,
on_delete=django.db.models.deletion.SET_NULL,
to="accounts.Project",
),
),
]

+ 2
- 6
hc/accounts/migrations/0018_auto_20190112_1426.py View File

@ -28,10 +28,6 @@ def create_projects(apps, schema_editor):
class Migration(migrations.Migration):
dependencies = [
('accounts', '0017_auto_20190112_1426'),
]
dependencies = [("accounts", "0017_auto_20190112_1426")]
operations = [
migrations.RunPython(create_projects, migrations.RunPython.noop),
]
operations = [migrations.RunPython(create_projects, migrations.RunPython.noop)]

+ 4
- 6
hc/accounts/migrations/0019_project_badge_key.py View File

@ -5,14 +5,12 @@ from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('accounts', '0018_auto_20190112_1426'),
]
dependencies = [("accounts", "0018_auto_20190112_1426")]
operations = [
migrations.AddField(
model_name='project',
name='badge_key',
model_name="project",
name="badge_key",
field=models.CharField(blank=True, max_length=150, null=True),
),
)
]

+ 2
- 6
hc/accounts/migrations/0020_auto_20190112_1950.py View File

@ -12,10 +12,6 @@ def set_badge_key(apps, schema_editor):
class Migration(migrations.Migration):
dependencies = [
('accounts', '0019_project_badge_key'),
]
dependencies = [("accounts", "0019_project_badge_key")]
operations = [
migrations.RunPython(set_badge_key, migrations.RunPython.noop),
]
operations = [migrations.RunPython(set_badge_key, migrations.RunPython.noop)]

+ 4
- 6
hc/accounts/migrations/0021_auto_20190112_2005.py View File

@ -5,14 +5,12 @@ from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('accounts', '0020_auto_20190112_1950'),
]
dependencies = [("accounts", "0020_auto_20190112_1950")]
operations = [
migrations.AlterField(
model_name='project',
name='badge_key',
model_name="project",
name="badge_key",
field=models.CharField(max_length=150, unique=True),
),
)
]

+ 7
- 7
hc/accounts/migrations/0022_auto_20190114_0857.py View File

@ -6,14 +6,14 @@ import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('accounts', '0021_auto_20190112_2005'),
]
dependencies = [("accounts", "0021_auto_20190112_2005")]
operations = [
migrations.AlterField(
model_name='member',
name='project',
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='accounts.Project'),
),
model_name="member",
name="project",
field=models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE, to="accounts.Project"
),
)
]

+ 4
- 15
hc/accounts/migrations/0023_auto_20190117_1419.py View File

@ -5,21 +5,10 @@ from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('accounts', '0022_auto_20190114_0857'),
]
dependencies = [("accounts", "0022_auto_20190114_0857")]
operations = [
migrations.RemoveField(
model_name='profile',
name='api_key',
),
migrations.RemoveField(
model_name='profile',
name='api_key_id',
),
migrations.RemoveField(
model_name='profile',
name='api_key_readonly',
),
migrations.RemoveField(model_name="profile", name="api_key"),
migrations.RemoveField(model_name="profile", name="api_key_id"),
migrations.RemoveField(model_name="profile", name="api_key_readonly"),
]

+ 3
- 11
hc/accounts/migrations/0024_auto_20190119_1540.py View File

@ -5,17 +5,9 @@ from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('accounts', '0023_auto_20190117_1419'),
]
dependencies = [("accounts", "0023_auto_20190117_1419")]
operations = [
migrations.RemoveField(
model_name='profile',
name='current_team',
),
migrations.RemoveField(
model_name='profile',
name='team_name',
),
migrations.RemoveField(model_name="profile", name="current_team"),
migrations.RemoveField(model_name="profile", name="team_name"),
]

+ 2
- 9
hc/accounts/migrations/0025_remove_member_team.py View File

@ -5,13 +5,6 @@ from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('accounts', '0024_auto_20190119_1540'),
]
dependencies = [("accounts", "0024_auto_20190119_1540")]
operations = [
migrations.RemoveField(
model_name='member',
name='team',
),
]
operations = [migrations.RemoveField(model_name="member", name="team")]

+ 7
- 9
hc/accounts/migrations/0026_auto_20190204_2042.py View File

@ -6,24 +6,22 @@ import uuid
class Migration(migrations.Migration):
dependencies = [
('accounts', '0025_remove_member_team'),
]
dependencies = [("accounts", "0025_remove_member_team")]
operations = [
migrations.AlterField(
model_name='project',
name='api_key',
model_name="project",
name="api_key",
field=models.CharField(blank=True, db_index=True, max_length=128),
),
migrations.AlterField(
model_name='project',
name='api_key_readonly',
model_name="project",
name="api_key_readonly",
field=models.CharField(blank=True, db_index=True, max_length=128),
),
migrations.AlterField(
model_name='project',
name='code',
model_name="project",
name="code",
field=models.UUIDField(default=uuid.uuid4, unique=True),
),
]

+ 4
- 6
hc/accounts/migrations/0027_profile_deletion_notice_date.py View File

@ -5,14 +5,12 @@ from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('accounts', '0026_auto_20190204_2042'),
]
dependencies = [("accounts", "0026_auto_20190204_2042")]
operations = [
migrations.AddField(
model_name='profile',
name='deletion_notice_date',
model_name="profile",
name="deletion_notice_date",
field=models.DateTimeField(blank=True, null=True),
),
)
]

+ 12
- 17
hc/accounts/models.py View File

@ -15,9 +15,11 @@ from hc.lib import emails
NO_NAG = timedelta()
NAG_PERIODS = ((NO_NAG, "Disabled"),
(timedelta(hours=1), "Hourly"),
(timedelta(days=1), "Daily"))
NAG_PERIODS = (
(NO_NAG, "Disabled"),
(timedelta(hours=1), "Hourly"),
(timedelta(days=1), "Daily"),
)
def month(dt):
@ -90,26 +92,20 @@ class Profile(models.Model):
ctx = {
"button_text": "Sign In",
"button_url": settings.SITE_ROOT + path,
"inviting_project": inviting_project
"inviting_project": inviting_project,
}
emails.login(self.user.email, ctx)
def send_set_password_link(self):
token = self.prepare_token("set-password")
path = reverse("hc-set-password", args=[token])
ctx = {
"button_text": "Set Password",
"button_url": settings.SITE_ROOT + path
}
ctx = {"button_text": "Set Password", "button_url": settings.SITE_ROOT + path}
emails.set_password(self.user.email, ctx)
def send_change_email_link(self):
token = self.prepare_token("change-email")
path = reverse("hc-change-email", args=[token])
ctx = {
"button_text": "Change Email",
"button_url": settings.SITE_ROOT + path
}
ctx = {"button_text": "Change Email", "button_url": settings.SITE_ROOT + path}
emails.change_email(self.user.email, ctx)
def projects(self):
@ -140,6 +136,7 @@ class Profile(models.Model):
project_ids = self.projects().values("id")
from hc.api.models import Check
return Check.objects.filter(project_id__in=project_ids)
def send_report(self, nag=False):
@ -168,10 +165,7 @@ class Profile(models.Model):
unsub_url = self.reports_unsub_url()
headers = {
"List-Unsubscribe": unsub_url,
"X-Bounce-Url": unsub_url
}
headers = {"List-Unsubscribe": unsub_url, "X-Bounce-Url": unsub_url}
ctx = {
"checks": checks,
@ -181,7 +175,7 @@ class Profile(models.Model):
"notifications_url": self.notifications_url(),
"nag": nag,
"nag_period": self.nag_period.total_seconds(),
"num_down": num_down
"num_down": num_down,
}
emails.report(self.user.email, ctx, headers)
@ -228,6 +222,7 @@ class Project(models.Model):
def num_checks_available(self):
from hc.api.models import Check
num_used = Check.objects.filter(project__owner=self.owner).count()
return self.owner_profile.check_limit - num_used


+ 0
- 1
hc/accounts/tests/test_add_project.py View File

@ -3,7 +3,6 @@ from hc.test import BaseTestCase
class RemoveProjectTestCase(BaseTestCase):
def setUp(self):
super(RemoveProjectTestCase, self).setUp()


+ 0
- 1
hc/accounts/tests/test_admin.py View File

@ -2,7 +2,6 @@ from hc.test import BaseTestCase
class AccountsAdminTestCase(BaseTestCase):
def setUp(self):
super(AccountsAdminTestCase, self).setUp()


+ 0
- 1
hc/accounts/tests/test_change_email.py View File

@ -4,7 +4,6 @@ from hc.test import BaseTestCase
class ChangeEmailTestCase(BaseTestCase):
def test_it_shows_form(self):
self.profile.token = make_password("foo", "change-email")
self.profile.save()


+ 0
- 1
hc/accounts/tests/test_check_token.py View File

@ -3,7 +3,6 @@ from hc.test import BaseTestCase
class CheckTokenTestCase(BaseTestCase):
def setUp(self):
super(CheckTokenTestCase, self).setUp()
self.profile.token = make_password("secret-token", "login")


+ 0
- 1
hc/accounts/tests/test_close_account.py View File

@ -6,7 +6,6 @@ from mock import patch
class CloseAccountTestCase(BaseTestCase):
@patch("hc.payments.models.Subscription.cancel")
def test_it_works(self, mock_cancel):
Check.objects.create(project=self.project, tags="foo a-B_1 baz@")


+ 6
- 26
hc/accounts/tests/test_login.py View File

@ -6,7 +6,6 @@ from hc.test import BaseTestCase
class LoginTestCase(BaseTestCase):
def setUp(self):
super(LoginTestCase, self).setUp()
self.checks_url = "/projects/%s/checks/" % self.project.code
@ -63,11 +62,7 @@ class LoginTestCase(BaseTestCase):
self.assertIn("login", self.profile.token)
def test_it_handles_password(self):
form = {
"action": "login",
"email": "[email protected]",
"password": "password"
}
form = {"action": "login", "email": "[email protected]", "password": "password"}
r = self.client.post("/accounts/login/", form)
self.assertRedirects(r, self.checks_url)
@ -79,11 +74,7 @@ class LoginTestCase(BaseTestCase):
obj.tokens = 0
obj.save()
form = {
"action": "login",
"email": "[email protected]",
"password": "password"
}
form = {"action": "login", "email": "[email protected]", "password": "password"}
r = self.client.post("/accounts/login/", form)
self.assertContains(r, "Too many attempts")
@ -91,27 +82,16 @@ class LoginTestCase(BaseTestCase):
def test_it_handles_password_login_with_redirect(self):
check = Check.objects.create(project=self.project)
form = {
"action": "login",
"email": "[email protected]",
"password": "password"
}
form = {"action": "login", "email": "[email protected]", "password": "password"}
samples = [
"/integrations/add_slack/",
"/checks/%s/details/" % check.code
]
samples = ["/integrations/add_slack/", "/checks/%s/details/" % check.code]
for s in samples:
r = self.client.post("/accounts/login/?next=%s" % s, form)
self.assertRedirects(r, s)
def test_it_handles_bad_next_parameter(self):
form = {
"action": "login",
"email": "[email protected]",
"password": "password"
}
form = {"action": "login", "email": "[email protected]", "password": "password"}
r = self.client.post("/accounts/login/?next=/evil/", form)
self.assertRedirects(r, self.checks_url)
@ -120,7 +100,7 @@ class LoginTestCase(BaseTestCase):
form = {
"action": "login",
"email": "[email protected]",
"password": "wrong password"
"password": "wrong password",
}
r = self.client.post("/accounts/login/", form)


+ 0
- 1
hc/accounts/tests/test_notifications.py View File

@ -5,7 +5,6 @@ from hc.test import BaseTestCase
class NotificationsTestCase(BaseTestCase):
def test_it_saves_reports_allowed_true(self):
self.profile.reports_allowed = False
self.profile.save()


+ 2
- 3
hc/accounts/tests/test_profile.py View File

@ -8,7 +8,6 @@ from hc.api.models import Check
class ProfileTestCase(BaseTestCase):
def test_it_sends_set_password_link(self):
self.client.login(username="[email protected]", password="password")
@ -38,7 +37,7 @@ class ProfileTestCase(BaseTestCase):
self.assertEqual(len(mail.outbox), 1)
message = mail.outbox[0]
self.assertEqual(message.subject, 'Monthly Report')
self.assertEqual(message.subject, "Monthly Report")
self.assertIn("Test Check", message.body)
def test_it_skips_report_if_no_pings(self):
@ -76,7 +75,7 @@ class ProfileTestCase(BaseTestCase):
self.assertEqual(len(mail.outbox), 1)
message = mail.outbox[0]
self.assertEqual(message.subject, 'Reminder: 1 check still down')
self.assertEqual(message.subject, "Reminder: 1 check still down")
self.assertIn("Test Check", message.body)
def test_it_skips_nag_if_none_down(self):


+ 7
- 4
hc/accounts/tests/test_project.py View File

@ -72,8 +72,9 @@ class ProjectTestCase(BaseTestCase):
members = self.project.member_set.all()
self.assertEqual(members.count(), 2)
member = Member.objects.get(project=self.project,
user__email="[email protected]")
member = Member.objects.get(
project=self.project, user__email="[email protected]"
)
profile = member.user.profile
self.assertEqual(profile.current_project, self.project)
@ -81,8 +82,10 @@ class ProjectTestCase(BaseTestCase):
self.assertFalse(member.user.project_set.exists())
# And an email should have been sent
subj = ("You have been invited to join"
" Alice&#39;s Project on %s" % settings.SITE_NAME)
subj = (
"You have been invited to join"
" Alice&#39;s Project on %s" % settings.SITE_NAME
)
self.assertEqual(mail.outbox[0].subject, subj)
@override_settings(SECRET_KEY="test-secret")


+ 0
- 1
hc/accounts/tests/test_project_model.py View File

@ -4,7 +4,6 @@ from hc.api.models import Check
class ProjectModelTestCase(BaseTestCase):
def test_num_checks_available_handles_multiple_projects(self):
# One check in Alice's primary project:
Check.objects.create(project=self.project)


+ 0
- 1
hc/accounts/tests/test_remove_project.py View File

@ -3,7 +3,6 @@ from hc.test import BaseTestCase
class RemoveProjectTestCase(BaseTestCase):
def setUp(self):
super(RemoveProjectTestCase, self).setUp()


+ 0
- 1
hc/accounts/tests/test_set_password.py View File

@ -2,7 +2,6 @@ from hc.test import BaseTestCase
class SetPasswordTestCase(BaseTestCase):
def test_it_shows_form(self):
token = self.profile.prepare_token("set-password")


+ 0
- 1
hc/accounts/tests/test_signup.py View File

@ -8,7 +8,6 @@ from django.conf import settings
class SignupTestCase(TestCase):
def test_it_sends_link(self):
form = {"identity": "[email protected]"}


+ 0
- 1
hc/accounts/tests/test_team_access_middleware.py View File

@ -4,7 +4,6 @@ from hc.accounts.models import Profile
class TeamAccessMiddlewareTestCase(TestCase):
def test_it_handles_missing_profile(self):
user = User(username="ned", email="[email protected]")
user.set_password("password")


+ 0
- 1
hc/accounts/tests/test_unsubscribe_reports.py View File

@ -6,7 +6,6 @@ from hc.test import BaseTestCase
class UnsubscribeReportsTestCase(BaseTestCase):
def test_it_unsubscribes(self):
self.profile.next_report_date = now()
self.profile.nag_period = td(hours=1)


+ 21
- 28
hc/accounts/urls.py View File

@ -2,32 +2,25 @@ from django.urls import path
from hc.accounts import views
urlpatterns = [
path('login/', views.login, name="hc-login"),
path('logout/', views.logout, name="hc-logout"),
path('signup/', views.signup, name="hc-signup"),
path('login_link_sent/',
views.login_link_sent, name="hc-login-link-sent"),
path('link_sent/',
views.link_sent, name="hc-link-sent"),
path('check_token/<slug:username>/<slug:token>/',
views.check_token, name="hc-check-token"),
path('profile/', views.profile, name="hc-profile"),
path('profile/notifications/', views.notifications, name="hc-notifications"),
path('close/', views.close, name="hc-close"),
path('unsubscribe_reports/<str:username>/',
views.unsubscribe_reports, name="hc-unsubscribe-reports"),
path('set_password/<slug:token>/',
views.set_password, name="hc-set-password"),
path('change_email/done/',
views.change_email_done, name="hc-change-email-done"),
path('change_email/<slug:token>/',
views.change_email, name="hc-change-email"),
path("login/", views.login, name="hc-login"),
path("logout/", views.logout, name="hc-logout"),
path("signup/", views.signup, name="hc-signup"),
path("login_link_sent/", views.login_link_sent, name="hc-login-link-sent"),
path("link_sent/", views.link_sent, name="hc-link-sent"),
path(
"check_token/<slug:username>/<slug:token>/",
views.check_token,
name="hc-check-token",
),
path("profile/", views.profile, name="hc-profile"),
path("profile/notifications/", views.notifications, name="hc-notifications"),
path("close/", views.close, name="hc-close"),
path(
"unsubscribe_reports/<str:username>/",
views.unsubscribe_reports,
name="hc-unsubscribe-reports",
),
path("set_password/<slug:token>/", views.set_password, name="hc-set-password"),
path("change_email/done/", views.change_email_done, name="hc-change-email-done"),
path("change_email/<slug:token>/", views.change_email, name="hc-change-email"),
]

+ 31
- 30
hc/accounts/views.py View File

@ -9,28 +9,39 @@ from django.contrib.auth import authenticate
from django.contrib.auth.decorators import login_required
from django.contrib.auth.models import User
from django.core import signing
from django.http import (HttpResponseForbidden, HttpResponseBadRequest,
HttpResponseNotFound)
from django.http import (
HttpResponseForbidden,
HttpResponseBadRequest,
HttpResponseNotFound,
)
from django.shortcuts import get_object_or_404, redirect, render
from django.utils.timezone import now
from django.urls import resolve, Resolver404
from django.views.decorators.csrf import csrf_exempt
from django.views.decorators.http import require_POST
from hc.accounts.forms import (ChangeEmailForm, PasswordLoginForm,
InviteTeamMemberForm, RemoveTeamMemberForm,
ReportSettingsForm, SetPasswordForm,
ProjectNameForm, AvailableEmailForm,
EmailLoginForm)
from hc.accounts.forms import (
ChangeEmailForm,
PasswordLoginForm,
InviteTeamMemberForm,
RemoveTeamMemberForm,
ReportSettingsForm,
SetPasswordForm,
ProjectNameForm,
AvailableEmailForm,
EmailLoginForm,
)
from hc.accounts.models import Profile, Project, Member
from hc.api.models import Channel, Check, TokenBucket
from hc.payments.models import Subscription
NEXT_WHITELIST = ("hc-checks",
"hc-details",
"hc-log",
"hc-channels",
"hc-add-slack",
"hc-add-pushover")
NEXT_WHITELIST = (
"hc-checks",
"hc-details",
"hc-log",
"hc-channels",
"hc-add-slack",
"hc-add-pushover",
)
def _is_whitelisted(path):
@ -92,7 +103,7 @@ def login(request):
form = PasswordLoginForm()
magic_form = EmailLoginForm()
if request.method == 'POST':
if request.method == "POST":
if request.POST.get("action") == "login":
form = PasswordLoginForm(request.POST)
if form.is_valid():
@ -115,7 +126,7 @@ def login(request):
"page": "login",
"form": form,
"magic_form": magic_form,
"bad_link": bad_link
"bad_link": bad_link,
}
return render(request, "accounts/login.html", ctx)
@ -182,11 +193,7 @@ def check_token(request, username, token):
def profile(request):
profile = request.profile
ctx = {
"page": "profile",
"profile": profile,
"my_projects_status": "default"
}
ctx = {"page": "profile", "profile": profile, "my_projects_status": "default"}
if request.method == "POST":
if "change_email" in request.POST:
@ -198,8 +205,7 @@ def profile(request):
elif "leave_project" in request.POST:
code = request.POST["code"]
try:
project = Project.objects.get(code=code,
member__user=request.user)
project = Project.objects.get(code=code, member__user=request.user)
except Project.DoesNotExist:
return HttpResponseBadRequest()
@ -253,7 +259,7 @@ def project(request, code):
"show_api_keys": "show_api_keys" in request.GET,
"project_name_status": "default",
"api_status": "default",
"team_status": "default"
"team_status": "default",
}
if request.method == "POST":
@ -308,8 +314,7 @@ def project(request, code):
farewell_user.profile.current_project = None
farewell_user.profile.save()
Member.objects.filter(project=project,
user=farewell_user).delete()
Member.objects.filter(project=project, user=farewell_user).delete()
ctx["team_member_removed"] = form.cleaned_data["email"]
ctx["team_status"] = "info"
@ -335,11 +340,7 @@ def project(request, code):
def notifications(request):
profile = request.profile
ctx = {
"status": "default",
"page": "profile",
"profile": profile
}
ctx = {"status": "default", "page": "profile", "profile": profile}
if request.method == "POST":
form = ReportSettingsForm(request.POST)


+ 48
- 37
hc/api/admin.py View File

@ -9,18 +9,23 @@ from hc.lib.date import format_duration
@admin.register(Check)
class ChecksAdmin(admin.ModelAdmin):
class Media:
css = {
'all': ('css/admin/checks.css',)
}
css = {"all": ("css/admin/checks.css",)}
search_fields = ["name", "code", "project__owner__email"]
raw_id_fields = ("project", )
list_display = ("id", "name_tags", "email", "created", "n_pings",
"timeout_schedule", "status", "last_start", "last_ping")
list_filter = ("status", "kind", "last_ping",
"last_start")
raw_id_fields = ("project",)
list_display = (
"id",
"name_tags",
"email",
"created",
"n_pings",
"timeout_schedule",
"status",
"last_start",
"last_ping",
)
list_filter = ("status", "kind", "last_ping", "last_start")
actions = ["send_alert"]
@ -60,14 +65,10 @@ class ChecksAdmin(admin.ModelAdmin):
class SchemeListFilter(admin.SimpleListFilter):
title = "Scheme"
parameter_name = 'scheme'
parameter_name = "scheme"
def lookups(self, request, model_admin):
return (
('http', "HTTP"),
('https', "HTTPS"),
('email', "Email"),
)
return (("http", "HTTP"), ("https", "HTTPS"), ("email", "Email"))
def queryset(self, request, queryset):
if self.value():
@ -77,7 +78,7 @@ class SchemeListFilter(admin.SimpleListFilter):
class MethodListFilter(admin.SimpleListFilter):
title = "Method"
parameter_name = 'method'
parameter_name = "method"
methods = ["HEAD", "GET", "POST", "PUT", "DELETE"]
def lookups(self, request, model_admin):
@ -91,7 +92,7 @@ class MethodListFilter(admin.SimpleListFilter):
class KindListFilter(admin.SimpleListFilter):
title = "Kind"
parameter_name = 'kind'
parameter_name = "kind"
kinds = ["start", "fail"]
def lookups(self, request, model_admin):
@ -112,8 +113,10 @@ class LargeTablePaginator(Paginator):
def _get_estimate(self):
try:
cursor = connection.cursor()
cursor.execute("SELECT reltuples FROM pg_class WHERE relname = %s",
[self.object_list.query.model._meta.db_table])
cursor.execute(
"SELECT reltuples FROM pg_class WHERE relname = %s",
[self.object_list.query.model._meta.db_table],
)
return int(cursor.fetchone()[0])
except:
return 0
@ -138,18 +141,17 @@ class LargeTablePaginator(Paginator):
# (i.e. is of type list).
self._count = len(self.object_list)
return self._count
count = property(_get_count)
@admin.register(Ping)
class PingsAdmin(admin.ModelAdmin):
search_fields = ("owner__name", "owner__code")
readonly_fields = ("owner", )
list_select_related = ("owner", )
list_display = ("id", "created", "owner", "scheme", "method",
"ua")
list_filter = ("created", SchemeListFilter, MethodListFilter,
KindListFilter)
readonly_fields = ("owner",)
list_select_related = ("owner",)
list_display = ("id", "created", "owner", "scheme", "method", "ua")
list_filter = ("created", SchemeListFilter, MethodListFilter, KindListFilter)
paginator = LargeTablePaginator
show_full_result_count = False
@ -158,15 +160,19 @@ class PingsAdmin(admin.ModelAdmin):
@admin.register(Channel)
class ChannelsAdmin(admin.ModelAdmin):
class Media:
css = {
'all': ('css/admin/channels.css',)
}
css = {"all": ("css/admin/channels.css",)}
search_fields = ["value", "project__owner__email"]
list_display = ("id", "name", "email", "formatted_kind", "value",
"num_notifications")
list_filter = ("kind", )
raw_id_fields = ("project", "checks", )
list_display = (
"id",
"name",
"email",
"formatted_kind",
"value",
"num_notifications",
)
list_filter = ("kind",)
raw_id_fields = ("project", "checks")
def get_queryset(self, request):
qs = super().get_queryset(request)
@ -196,8 +202,14 @@ class ChannelsAdmin(admin.ModelAdmin):
class NotificationsAdmin(admin.ModelAdmin):
search_fields = ["owner__name", "owner__code", "channel__value"]
list_select_related = ("owner", "channel")
list_display = ("id", "created", "check_status", "owner",
"channel_kind", "channel_value")
list_display = (
"id",
"created",
"check_status",
"owner",
"channel_kind",
"channel_value",
)
list_filter = ("created", "check_status", "channel__kind")
def channel_kind(self, obj):
@ -209,6 +221,5 @@ class NotificationsAdmin(admin.ModelAdmin):
@admin.register(Flip)
class FlipsAdmin(admin.ModelAdmin):
list_display = ("id", "created", "processed", "owner", "old_status",
"new_status")
raw_id_fields = ("owner", )
list_display = ("id", "created", "processed", "owner", "old_status", "new_status")
raw_id_fields = ("owner",)

+ 5
- 0
hc/api/decorators.py View File

@ -28,6 +28,7 @@ def authorize(f):
return error("wrong api key", 401)
return f(request, *args, **kwds)
return wrapper
@ -50,6 +51,7 @@ def authorize_read(f):
return error("wrong api key", 401)
return f(request, *args, **kwds)
return wrapper
@ -80,7 +82,9 @@ def validate_json(schema=None):
return error("json validation error: %s" % e)
return f(request, *args, **kwds)
return wrapper
return decorator
@ -106,4 +110,5 @@ def cors(*methods):
return response
return wrapper
return decorator

+ 4
- 3
hc/api/management/commands/prunenotifications.py View File

@ -5,7 +5,7 @@ from hc.api.models import Notification, Check
class Command(BaseCommand):
help = 'Prune stored notifications'
help = "Prune stored notifications"
def handle(self, *args, **options):
total = 0
@ -13,8 +13,9 @@ class Command(BaseCommand):
q = Check.objects.filter(n_pings__gt=100)
q = q.annotate(min_ping_date=Min("ping__created"))
for check in q:
qq = Notification.objects.filter(owner_id=check.id,
created__lt=check.min_ping_date)
qq = Notification.objects.filter(
owner_id=check.id, created__lt=check.min_ping_date
)
num_deleted, _ = qq.delete()
total += num_deleted


+ 1
- 1
hc/api/management/commands/prunepings.py View File

@ -6,7 +6,7 @@ from hc.api.models import Ping
class Command(BaseCommand):
help = 'Prune pings based on limits in user profiles'
help = "Prune pings based on limits in user profiles"
def handle(self, *args, **options):
# Create any missing user profiles


+ 3
- 2
hc/api/management/commands/prunepingsslow.py View File

@ -29,7 +29,8 @@ class Command(BaseCommand):
q = q.filter(n__gt=0)
n_pruned, _ = q.delete()
self.stdout.write("Pruned %d pings for check %s (%s)" %
(n_pruned, check.id, check.name))
self.stdout.write(
"Pruned %d pings for check %s (%s)" % (n_pruned, check.id, check.name)
)
return "Done!"

+ 1
- 1
hc/api/management/commands/prunetokenbucket.py View File

@ -6,7 +6,7 @@ from hc.api.models import TokenBucket
class Command(BaseCommand):
help = 'Prune pings based on limits in user profiles'
help = "Prune pings based on limits in user profiles"
def handle(self, *args, **options):


+ 9
- 9
hc/api/management/commands/sendalerts.py View File

@ -35,23 +35,23 @@ def notify_on_thread(flip_id, stdout):
class Command(BaseCommand):
help = 'Sends UP/DOWN email alerts'
help = "Sends UP/DOWN email alerts"
def add_arguments(self, parser):
parser.add_argument(
'--no-loop',
action='store_false',
dest='loop',
"--no-loop",
action="store_false",
dest="loop",
default=True,
help='Do not keep running indefinitely in a 2 second wait loop',
help="Do not keep running indefinitely in a 2 second wait loop",
)
parser.add_argument(
'--no-threads',
action='store_false',
dest='use_threads',
"--no-threads",
action="store_false",
dest="use_threads",
default=False,
help='Send alerts synchronously, without using threads',
help="Send alerts synchronously, without using threads",
)
def process_one_flip(self, use_threads=True):


+ 10
- 10
hc/api/management/commands/sendreports.py View File

@ -9,13 +9,13 @@ from hc.api.models import Check
def num_pinged_checks(profile):
q = Check.objects.filter(user_id=profile.user.id,)
q = Check.objects.filter(user_id=profile.user.id)
q = q.filter(last_ping__isnull=False)
return q.count()
class Command(BaseCommand):
help = 'Send due monthly reports and nags'
help = "Send due monthly reports and nags"
tmpl = "Sent monthly report to %s"
def pause(self):
@ -23,11 +23,11 @@ class Command(BaseCommand):
def add_arguments(self, parser):
parser.add_argument(
'--loop',
action='store_true',
dest='loop',
"--loop",
action="store_true",
dest="loop",
default=False,
help='Keep running indefinitely in a 300 second wait loop',
help="Keep running indefinitely in a 300 second wait loop",
)
def handle_one_monthly_report(self):
@ -48,8 +48,9 @@ class Command(BaseCommand):
# A sort of optimistic lock. Try to update next_report_date,
# and if does get modified, we're in drivers seat:
qq = Profile.objects.filter(id=profile.id,
next_report_date=profile.next_report_date)
qq = Profile.objects.filter(
id=profile.id, next_report_date=profile.next_report_date
)
num_updated = qq.update(next_report_date=month_after)
if num_updated != 1:
@ -72,8 +73,7 @@ class Command(BaseCommand):
if profile is None:
return False
qq = Profile.objects.filter(id=profile.id,
next_nag_date=profile.next_nag_date)
qq = Profile.objects.filter(id=profile.id, next_nag_date=profile.next_nag_date)
num_updated = qq.update(next_nag_date=now + profile.nag_period)
if num_updated != 1:


+ 1
- 1
hc/api/management/commands/settelegramwebhook.py View File

@ -16,7 +16,7 @@ class Command(BaseCommand):
form = {
"url": settings.SITE_ROOT + reverse("hc-telegram-webhook"),
"allowed_updates": ["message"]
"allowed_updates": ["message"],
}
url = SETWEBHOOK_TMPL % settings.TELEGRAM_TOKEN


+ 12
- 9
hc/api/management/commands/smtpd.py View File

@ -7,7 +7,9 @@ from django.core.management.base import BaseCommand
from django.db import connections
from hc.api.models import Check
RE_UUID = re.compile("^[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-4[a-fA-F0-9]{3}-[8|9|aA|bB][a-fA-F0-9]{3}-[a-fA-F0-9]{12}$")
RE_UUID = re.compile(
"^[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-4[a-fA-F0-9]{3}-[8|9|aA|bB][a-fA-F0-9]{3}-[a-fA-F0-9]{12}$"
)
class Listener(SMTPServer):
@ -15,7 +17,9 @@ class Listener(SMTPServer):
self.stdout = stdout
super(Listener, self).__init__(localaddr, None, decode_data=False)
def process_message(self, peer, mailfrom, rcpttos, data, mail_options=None, rcpt_options=None):
def process_message(
self, peer, mailfrom, rcpttos, data, mail_options=None, rcpt_options=None
):
# get a new db connection in case the old one has timed out:
connections.close_all()
@ -53,13 +57,12 @@ class Command(BaseCommand):
help = "Listen for ping emails"
def add_arguments(self, parser):
parser.add_argument("--host",
help="ip address to listen on, default 0.0.0.0",
default="0.0.0.0")
parser.add_argument('--port',
help="port to listen on, default 25",
type=int,
default=25)
parser.add_argument(
"--host", help="ip address to listen on, default 0.0.0.0", default="0.0.0.0"
)
parser.add_argument(
"--port", help="port to listen on, default 25", type=int, default=25
)
def handle(self, host, port, *args, **options):
listener = Listener((host, port), self.stdout)


+ 20
- 9
hc/api/migrations/0001_initial.py View File

@ -8,18 +8,29 @@ from django.conf import settings
class Migration(migrations.Migration):
dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
]
dependencies = [migrations.swappable_dependency(settings.AUTH_USER_MODEL)]
operations = [
migrations.CreateModel(
name='Check',
name="Check",
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, verbose_name='ID', serialize=False)),
('code', models.UUIDField(default=uuid.uuid4, editable=False)),
('last_ping', models.DateTimeField(null=True, blank=True)),
('user', models.ForeignKey(to=settings.AUTH_USER_MODEL, on_delete=models.CASCADE)),
(
"id",
models.AutoField(
auto_created=True,
primary_key=True,
verbose_name="ID",
serialize=False,
),
),
("code", models.UUIDField(default=uuid.uuid4, editable=False)),
("last_ping", models.DateTimeField(null=True, blank=True)),
(
"user",
models.ForeignKey(
to=settings.AUTH_USER_MODEL, on_delete=models.CASCADE
),
),
],
),
)
]

+ 29
- 14
hc/api/migrations/0002_auto_20150616_0732.py View File

@ -7,29 +7,44 @@ import datetime
class Migration(migrations.Migration):
dependencies = [
('api', '0001_initial'),
]
dependencies = [("api", "0001_initial")]
operations = [
migrations.AddField(
model_name='check',
name='alert_after',
model_name="check",
name="alert_after",
field=models.DateTimeField(null=True, blank=True),
),
migrations.AddField(
model_name='check',
name='enabled',
field=models.BooleanField(default=True),
model_name="check", name="enabled", field=models.BooleanField(default=True)
),
migrations.AddField(
model_name='check',
name='status',
field=models.CharField(max_length=6, choices=[('up', 'Up'), ('down', 'Down'), ('new', 'New')], default='new'),
model_name="check",
name="status",
field=models.CharField(
max_length=6,
choices=[("up", "Up"), ("down", "Down"), ("new", "New")],
default="new",
),
),
migrations.AddField(
model_name='check',
name='timeout',
field=models.DurationField(choices=[(datetime.timedelta(0, 300), '5 minutes'), (datetime.timedelta(0, 600), '10 minutes'), (datetime.timedelta(0, 1800), '30 minutes'), (datetime.timedelta(0, 3600), '1 hour'), (datetime.timedelta(0, 7200), '2 hours'), (datetime.timedelta(0, 21600), '6 hours'), (datetime.timedelta(0, 43200), '12 hours'), (datetime.timedelta(1), '1 day'), (datetime.timedelta(2), '2 days'), (datetime.timedelta(7), '1 week'), (datetime.timedelta(14), '2 weeks')], default=datetime.timedelta(1)),
model_name="check",
name="timeout",
field=models.DurationField(
choices=[
(datetime.timedelta(0, 300), "5 minutes"),
(datetime.timedelta(0, 600), "10 minutes"),
(datetime.timedelta(0, 1800), "30 minutes"),
(datetime.timedelta(0, 3600), "1 hour"),
(datetime.timedelta(0, 7200), "2 hours"),
(datetime.timedelta(0, 21600), "6 hours"),
(datetime.timedelta(0, 43200), "12 hours"),
(datetime.timedelta(1), "1 day"),
(datetime.timedelta(2), "2 days"),
(datetime.timedelta(7), "1 week"),
(datetime.timedelta(14), "2 weeks"),
],
default=datetime.timedelta(1),
),
),
]

+ 7
- 9
hc/api/migrations/0003_auto_20150616_1249.py View File

@ -7,24 +7,22 @@ import datetime
class Migration(migrations.Migration):
dependencies = [
('api', '0002_auto_20150616_0732'),
]
dependencies = [("api", "0002_auto_20150616_0732")]
operations = [
migrations.AddField(
model_name='check',
name='name',
model_name="check",
name="name",
field=models.CharField(max_length=100, blank=True),
),
migrations.AlterField(
model_name='check',
name='alert_after',
model_name="check",
name="alert_after",
field=models.DateTimeField(editable=False, null=True, blank=True),
),
migrations.AlterField(
model_name='check',
name='timeout',
model_name="check",
name="timeout",
field=models.DurationField(default=datetime.timedelta(1)),
),
]

+ 8
- 10
hc/api/migrations/0004_auto_20150616_1319.py View File

@ -8,19 +8,17 @@ import datetime
class Migration(migrations.Migration):
dependencies = [
('api', '0003_auto_20150616_1249'),
]
dependencies = [("api", "0003_auto_20150616_1249")]
operations = [
migrations.RemoveField(
model_name='check',
name='enabled',
),
migrations.RemoveField(model_name="check", name="enabled"),
migrations.AddField(
model_name='check',
name='created',
field=models.DateTimeField(auto_now_add=True, default=datetime.datetime(2015, 6, 16, 13, 19, 17, 218278, tzinfo=utc)),
model_name="check",
name="created",
field=models.DateTimeField(
auto_now_add=True,
default=datetime.datetime(2015, 6, 16, 13, 19, 17, 218278, tzinfo=utc),
),
preserve_default=False,
),
]

+ 10
- 7
hc/api/migrations/0005_auto_20150630_2021.py View File

@ -7,14 +7,17 @@ from django.conf import settings
class Migration(migrations.Migration):
dependencies = [
('api', '0004_auto_20150616_1319'),
]
dependencies = [("api", "0004_auto_20150616_1319")]
operations = [
migrations.AlterField(
model_name='check',
name='user',
field=models.ForeignKey(blank=True, to=settings.AUTH_USER_MODEL, null=True, on_delete=models.CASCADE),
),
model_name="check",
name="user",
field=models.ForeignKey(
blank=True,
to=settings.AUTH_USER_MODEL,
null=True,
on_delete=models.CASCADE,
),
)
]

+ 4
- 6
hc/api/migrations/0006_check_grace.py View File

@ -7,14 +7,12 @@ import datetime
class Migration(migrations.Migration):
dependencies = [
('api', '0005_auto_20150630_2021'),
]
dependencies = [("api", "0005_auto_20150630_2021")]
operations = [
migrations.AddField(
model_name='check',
name='grace',
model_name="check",
name="grace",
field=models.DurationField(default=datetime.timedelta(0, 3600)),
),
)
]

+ 18
- 12
hc/api/migrations/0007_ping.py View File

@ -6,21 +6,27 @@ from django.db import models, migrations
class Migration(migrations.Migration):
dependencies = [
('api', '0006_check_grace'),
]
dependencies = [("api", "0006_check_grace")]
operations = [
migrations.CreateModel(
name='Ping',
name="Ping",
fields=[
('id', models.AutoField(primary_key=True, serialize=False, auto_created=True, verbose_name='ID')),
('created', models.DateTimeField(auto_now_add=True)),
('remote_addr', models.GenericIPAddressField()),
('method', models.CharField(max_length=10)),
('ua', models.CharField(max_length=100, blank=True)),
('body', models.TextField(blank=True)),
('owner', models.ForeignKey(to='api.Check', on_delete=models.CASCADE)),
(
"id",
models.AutoField(
primary_key=True,
serialize=False,
auto_created=True,
verbose_name="ID",
),
),
("created", models.DateTimeField(auto_now_add=True)),
("remote_addr", models.GenericIPAddressField()),
("method", models.CharField(max_length=10)),
("ua", models.CharField(max_length=100, blank=True)),
("body", models.TextField(blank=True)),
("owner", models.ForeignKey(to="api.Check", on_delete=models.CASCADE)),
],
),
)
]

+ 4
- 6
hc/api/migrations/0008_auto_20150801_1213.py View File

@ -6,14 +6,12 @@ from django.db import models, migrations
class Migration(migrations.Migration):
dependencies = [
('api', '0007_ping'),
]
dependencies = [("api", "0007_ping")]
operations = [
migrations.AlterField(
model_name='ping',
name='ua',
model_name="ping",
name="ua",
field=models.CharField(max_length=200, blank=True),
),
)
]

+ 8
- 10
hc/api/migrations/0009_auto_20150801_1250.py View File

@ -6,24 +6,22 @@ from django.db import models, migrations
class Migration(migrations.Migration):
dependencies = [
('api', '0008_auto_20150801_1213'),
]
dependencies = [("api", "0008_auto_20150801_1213")]
operations = [
migrations.AddField(
model_name='ping',
name='scheme',
field=models.CharField(max_length=10, default='http'),
model_name="ping",
name="scheme",
field=models.CharField(max_length=10, default="http"),
),
migrations.AlterField(
model_name='ping',
name='method',
model_name="ping",
name="method",
field=models.CharField(blank=True, max_length=10),
),
migrations.AlterField(
model_name='ping',
name='remote_addr',
model_name="ping",
name="remote_addr",
field=models.GenericIPAddressField(blank=True, null=True),
),
]

+ 34
- 11
hc/api/migrations/0010_channel.py View File

@ -10,21 +10,44 @@ class Migration(migrations.Migration):
dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
('api', '0009_auto_20150801_1250'),
("api", "0009_auto_20150801_1250"),
]
operations = [
migrations.CreateModel(
name='Channel',
name="Channel",
fields=[
('id', models.AutoField(primary_key=True, auto_created=True, verbose_name='ID', serialize=False)),
('code', models.UUIDField(editable=False, default=uuid.uuid4)),
('created', models.DateTimeField(auto_now_add=True)),
('kind', models.CharField(choices=[('email', 'Email'), ('webhook', 'Webhook'), ('pd', 'PagerDuty')], max_length=20)),
('value', models.CharField(max_length=200, blank=True)),
('email_verified', models.BooleanField(default=False)),
('checks', models.ManyToManyField(to='api.Check')),
('user', models.ForeignKey(to=settings.AUTH_USER_MODEL, on_delete=models.CASCADE)),
(
"id",
models.AutoField(
primary_key=True,
auto_created=True,
verbose_name="ID",
serialize=False,
),
),
("code", models.UUIDField(editable=False, default=uuid.uuid4)),
("created", models.DateTimeField(auto_now_add=True)),
(
"kind",
models.CharField(
choices=[
("email", "Email"),
("webhook", "Webhook"),
("pd", "PagerDuty"),
],
max_length=20,
),
),
("value", models.CharField(max_length=200, blank=True)),
("email_verified", models.BooleanField(default=False)),
("checks", models.ManyToManyField(to="api.Check")),
(
"user",
models.ForeignKey(
to=settings.AUTH_USER_MODEL, on_delete=models.CASCADE
),
),
],
),
)
]

+ 20
- 11
hc/api/migrations/0011_notification.py View File

@ -6,20 +6,29 @@ from django.db import models, migrations
class Migration(migrations.Migration):
dependencies = [
('api', '0010_channel'),
]
dependencies = [("api", "0010_channel")]
operations = [
migrations.CreateModel(
name='Notification',
name="Notification",
fields=[
('id', models.AutoField(serialize=False, auto_created=True, verbose_name='ID', primary_key=True)),
('check_status', models.CharField(max_length=6)),
('created', models.DateTimeField(auto_now_add=True)),
('status', models.IntegerField(default=0)),
('channel', models.ForeignKey(to='api.Channel', on_delete=models.CASCADE)),
('owner', models.ForeignKey(to='api.Check', on_delete=models.CASCADE)),
(
"id",
models.AutoField(
serialize=False,
auto_created=True,
verbose_name="ID",
primary_key=True,
),
),
("check_status", models.CharField(max_length=6)),
("created", models.DateTimeField(auto_now_add=True)),
("status", models.IntegerField(default=0)),
(
"channel",
models.ForeignKey(to="api.Channel", on_delete=models.CASCADE),
),
("owner", models.ForeignKey(to="api.Check", on_delete=models.CASCADE)),
],
),
)
]

+ 13
- 7
hc/api/migrations/0012_auto_20150930_1922.py View File

@ -6,14 +6,20 @@ from django.db import models, migrations
class Migration(migrations.Migration):
dependencies = [
('api', '0011_notification'),
]
dependencies = [("api", "0011_notification")]
operations = [
migrations.AlterField(
model_name='channel',
name='kind',
field=models.CharField(choices=[('email', 'Email'), ('webhook', 'Webhook'), ('slack', 'Slack'), ('pd', 'PagerDuty')], max_length=20),
),
model_name="channel",
name="kind",
field=models.CharField(
choices=[
("email", "Email"),
("webhook", "Webhook"),
("slack", "Slack"),
("pd", "PagerDuty"),
],
max_length=20,
),
)
]

+ 14
- 7
hc/api/migrations/0013_auto_20151001_2029.py View File

@ -6,14 +6,21 @@ from django.db import models, migrations
class Migration(migrations.Migration):
dependencies = [
('api', '0012_auto_20150930_1922'),
]
dependencies = [("api", "0012_auto_20150930_1922")]
operations = [
migrations.AlterField(
model_name='channel',
name='kind',
field=models.CharField(max_length=20, choices=[('email', 'Email'), ('webhook', 'Webhook'), ('hipchat', 'HipChat'), ('slack', 'Slack'), ('pd', 'PagerDuty')]),
),
model_name="channel",
name="kind",
field=models.CharField(
max_length=20,
choices=[
("email", "Email"),
("webhook", "Webhook"),
("hipchat", "HipChat"),
("slack", "Slack"),
("pd", "PagerDuty"),
],
),
)
]

+ 4
- 6
hc/api/migrations/0014_auto_20151019_2039.py View File

@ -7,14 +7,12 @@ import uuid
class Migration(migrations.Migration):
dependencies = [
('api', '0013_auto_20151001_2029'),
]
dependencies = [("api", "0013_auto_20151001_2029")]
operations = [
migrations.AlterField(
model_name='check',
name='code',
model_name="check",
name="code",
field=models.UUIDField(default=uuid.uuid4, db_index=True, editable=False),
),
)
]

+ 3
- 6
hc/api/migrations/0015_auto_20151022_1008.py View File

@ -6,13 +6,10 @@ from django.db import models, migrations
class Migration(migrations.Migration):
dependencies = [
('api', '0014_auto_20151019_2039'),
]
dependencies = [("api", "0014_auto_20151019_2039")]
operations = [
migrations.AlterIndexTogether(
name='check',
index_together=set([('status', 'user', 'alert_after')]),
),
name="check", index_together=set([("status", "user", "alert_after")])
)
]

+ 14
- 7
hc/api/migrations/0016_auto_20151030_1107.py View File

@ -6,14 +6,21 @@ from django.db import models, migrations
class Migration(migrations.Migration):
dependencies = [
('api', '0015_auto_20151022_1008'),
]
dependencies = [("api", "0015_auto_20151022_1008")]
operations = [
migrations.AlterField(
model_name='check',
name='status',
field=models.CharField(default='new', max_length=6, choices=[('up', 'Up'), ('down', 'Down'), ('new', 'New'), ('paused', 'Paused')]),
),
model_name="check",
name="status",
field=models.CharField(
default="new",
max_length=6,
choices=[
("up", "Up"),
("down", "Down"),
("new", "New"),
("paused", "Paused"),
],
),
)
]

+ 15
- 7
hc/api/migrations/0017_auto_20151117_1032.py View File

@ -6,14 +6,22 @@ from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('api', '0016_auto_20151030_1107'),
]
dependencies = [("api", "0016_auto_20151030_1107")]
operations = [
migrations.AlterField(
model_name='channel',
name='kind',
field=models.CharField(choices=[('email', 'Email'), ('webhook', 'Webhook'), ('hipchat', 'HipChat'), ('slack', 'Slack'), ('pd', 'PagerDuty'), ('po', 'Pushover')], max_length=20),
),
model_name="channel",
name="kind",
field=models.CharField(
choices=[
("email", "Email"),
("webhook", "Webhook"),
("hipchat", "HipChat"),
("slack", "Slack"),
("pd", "PagerDuty"),
("po", "Pushover"),
],
max_length=20,
),
)
]

+ 2
- 9
hc/api/migrations/0018_remove_ping_body.py View File

@ -6,13 +6,6 @@ from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('api', '0017_auto_20151117_1032'),
]
dependencies = [("api", "0017_auto_20151117_1032")]
operations = [
migrations.RemoveField(
model_name='ping',
name='body',
),
]
operations = [migrations.RemoveField(model_name="ping", name="body")]

+ 4
- 6
hc/api/migrations/0019_check_tags.py View File

@ -6,14 +6,12 @@ from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('api', '0018_remove_ping_body'),
]
dependencies = [("api", "0018_remove_ping_body")]
operations = [
migrations.AddField(
model_name='check',
name='tags',
model_name="check",
name="tags",
field=models.CharField(max_length=500, blank=True),
),
)
]

+ 3
- 7
hc/api/migrations/0020_check_n_pings.py View File

@ -7,14 +7,10 @@ from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('api', '0019_check_tags'),
]
dependencies = [("api", "0019_check_tags")]
operations = [
migrations.AddField(
model_name='check',
name='n_pings',
field=models.IntegerField(default=0),
),
model_name="check", name="n_pings", field=models.IntegerField(default=0)
)
]

+ 3
- 7
hc/api/migrations/0021_ping_n.py View File

@ -7,14 +7,10 @@ from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('api', '0020_check_n_pings'),
]
dependencies = [("api", "0020_check_n_pings")]
operations = [
migrations.AddField(
model_name='ping',
name='n',
field=models.IntegerField(null=True),
),
model_name="ping", name="n", field=models.IntegerField(null=True)
)
]

+ 4
- 9
hc/api/migrations/0022_auto_20160130_2042.py View File

@ -7,18 +7,13 @@ from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('api', '0021_ping_n'),
]
dependencies = [("api", "0021_ping_n")]
operations = [
migrations.RemoveField(
model_name='notification',
name='status',
),
migrations.RemoveField(model_name="notification", name="status"),
migrations.AddField(
model_name='notification',
name='error',
model_name="notification",
name="error",
field=models.CharField(blank=True, max_length=200),
),
]

+ 3
- 6
hc/api/migrations/0023_auto_20160131_1919.py View File

@ -7,13 +7,10 @@ from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('api', '0022_auto_20160130_2042'),
]
dependencies = [("api", "0022_auto_20160130_2042")]
operations = [
migrations.AlterModelOptions(
name='notification',
options={'get_latest_by': 'created'},
),
name="notification", options={"get_latest_by": "created"}
)
]

+ 16
- 7
hc/api/migrations/0024_auto_20160203_2227.py View File

@ -7,14 +7,23 @@ from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('api', '0023_auto_20160131_1919'),
]
dependencies = [("api", "0023_auto_20160131_1919")]
operations = [
migrations.AlterField(
model_name='channel',
name='kind',
field=models.CharField(choices=[(b'email', b'Email'), (b'webhook', b'Webhook'), (b'hipchat', b'HipChat'), (b'slack', b'Slack'), (b'pd', b'PagerDuty'), (b'po', b'Pushover'), (b'victorops', b'VictorOps')], max_length=20),
),
model_name="channel",
name="kind",
field=models.CharField(
choices=[
(b"email", b"Email"),
(b"webhook", b"Webhook"),
(b"hipchat", b"HipChat"),
(b"slack", b"Slack"),
(b"pd", b"PagerDuty"),
(b"po", b"Pushover"),
(b"victorops", b"VictorOps"),
],
max_length=20,
),
)
]

+ 16
- 7
hc/api/migrations/0025_auto_20160216_1214.py View File

@ -7,14 +7,23 @@ from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('api', '0024_auto_20160203_2227'),
]
dependencies = [("api", "0024_auto_20160203_2227")]
operations = [
migrations.AlterField(
model_name='channel',
name='kind',
field=models.CharField(choices=[('email', 'Email'), ('webhook', 'Webhook'), ('hipchat', 'HipChat'), ('slack', 'Slack'), ('pd', 'PagerDuty'), ('po', 'Pushover'), ('victorops', 'VictorOps')], max_length=20),
),
model_name="channel",
name="kind",
field=models.CharField(
choices=[
("email", "Email"),
("webhook", "Webhook"),
("hipchat", "HipChat"),
("slack", "Slack"),
("pd", "PagerDuty"),
("po", "Pushover"),
("victorops", "VictorOps"),
],
max_length=20,
),
)
]

+ 3
- 7
hc/api/migrations/0026_auto_20160415_1824.py View File

@ -7,14 +7,10 @@ from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('api', '0025_auto_20160216_1214'),
]
dependencies = [("api", "0025_auto_20160216_1214")]
operations = [
migrations.AlterField(
model_name='channel',
name='value',
field=models.TextField(blank=True),
),
model_name="channel", name="value", field=models.TextField(blank=True)
)
]

+ 30
- 15
hc/api/migrations/0027_auto_20161213_1059.py View File

@ -7,29 +7,44 @@ from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('api', '0026_auto_20160415_1824'),
]
dependencies = [("api", "0026_auto_20160415_1824")]
operations = [
migrations.AddField(
model_name='check',
name='kind',
field=models.CharField(choices=[('simple', 'Simple'), ('cron', 'Cron')], default='simple', max_length=10),
model_name="check",
name="kind",
field=models.CharField(
choices=[("simple", "Simple"), ("cron", "Cron")],
default="simple",
max_length=10,
),
),
migrations.AddField(
model_name='check',
name='schedule',
field=models.CharField(default='* * * * *', max_length=100),
model_name="check",
name="schedule",
field=models.CharField(default="* * * * *", max_length=100),
),
migrations.AddField(
model_name='check',
name='tz',
field=models.CharField(default='UTC', max_length=36),
model_name="check",
name="tz",
field=models.CharField(default="UTC", max_length=36),
),
migrations.AlterField(
model_name='channel',
name='kind',
field=models.CharField(choices=[('email', 'Email'), ('webhook', 'Webhook'), ('hipchat', 'HipChat'), ('slack', 'Slack'), ('pd', 'PagerDuty'), ('po', 'Pushover'), ('pushbullet', 'Pushbullet'), ('opsgenie', 'OpsGenie'), ('victorops', 'VictorOps')], max_length=20),
model_name="channel",
name="kind",
field=models.CharField(
choices=[
("email", "Email"),
("webhook", "Webhook"),
("hipchat", "HipChat"),
("slack", "Slack"),
("pd", "PagerDuty"),
("po", "Pushover"),
("pushbullet", "Pushbullet"),
("opsgenie", "OpsGenie"),
("victorops", "VictorOps"),
],
max_length=20,
),
),
]

+ 20
- 8
hc/api/migrations/0028_auto_20170305_1907.py View File

@ -8,19 +8,31 @@ import uuid
class Migration(migrations.Migration):
dependencies = [
('api', '0027_auto_20161213_1059'),
]
dependencies = [("api", "0027_auto_20161213_1059")]
operations = [
migrations.AddField(
model_name='notification',
name='code',
model_name="notification",
name="code",
field=models.UUIDField(default=None, editable=False, null=True),
),
migrations.AlterField(
model_name='channel',
name='kind',
field=models.CharField(choices=[('email', 'Email'), ('webhook', 'Webhook'), ('hipchat', 'HipChat'), ('slack', 'Slack'), ('pd', 'PagerDuty'), ('po', 'Pushover'), ('pushbullet', 'Pushbullet'), ('opsgenie', 'OpsGenie'), ('victorops', 'VictorOps'), ('discord', 'Discord')], max_length=20),
model_name="channel",
name="kind",
field=models.CharField(
choices=[
("email", "Email"),
("webhook", "Webhook"),
("hipchat", "HipChat"),
("slack", "Slack"),
("pd", "PagerDuty"),
("po", "Pushover"),
("pushbullet", "Pushbullet"),
("opsgenie", "OpsGenie"),
("victorops", "VictorOps"),
("discord", "Discord"),
],
max_length=20,
),
),
]

+ 4
- 6
hc/api/migrations/0029_auto_20170507_1251.py View File

@ -8,14 +8,12 @@ import uuid
class Migration(migrations.Migration):
dependencies = [
('api', '0028_auto_20170305_1907'),
]
dependencies = [("api", "0028_auto_20170305_1907")]
operations = [
migrations.AlterField(
model_name='notification',
name='code',
model_name="notification",
name="code",
field=models.UUIDField(default=uuid.uuid4, editable=False, null=True),
),
)
]

+ 4
- 6
hc/api/migrations/0030_check_last_ping_body.py View File

@ -7,14 +7,12 @@ from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('api', '0029_auto_20170507_1251'),
]
dependencies = [("api", "0029_auto_20170507_1251")]
operations = [
migrations.AddField(
model_name='check',
name='last_ping_body',
model_name="check",
name="last_ping_body",
field=models.CharField(blank=True, max_length=1000),
),
)
]

+ 4
- 6
hc/api/migrations/0031_auto_20170509_1320.py View File

@ -7,14 +7,12 @@ from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('api', '0030_check_last_ping_body'),
]
dependencies = [("api", "0030_check_last_ping_body")]
operations = [
migrations.AlterField(
model_name='check',
name='last_ping_body',
model_name="check",
name="last_ping_body",
field=models.CharField(blank=True, max_length=10000),
),
)
]

+ 20
- 7
hc/api/migrations/0032_auto_20170608_1158.py View File

@ -7,14 +7,27 @@ from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('api', '0031_auto_20170509_1320'),
]
dependencies = [("api", "0031_auto_20170509_1320")]
operations = [
migrations.AlterField(
model_name='channel',
name='kind',
field=models.CharField(choices=[('email', 'Email'), ('webhook', 'Webhook'), ('hipchat', 'HipChat'), ('slack', 'Slack'), ('pd', 'PagerDuty'), ('po', 'Pushover'), ('pushbullet', 'Pushbullet'), ('opsgenie', 'OpsGenie'), ('victorops', 'VictorOps'), ('discord', 'Discord'), ('telegram', 'Telegram')], max_length=20),
),
model_name="channel",
name="kind",
field=models.CharField(
choices=[
("email", "Email"),
("webhook", "Webhook"),
("hipchat", "HipChat"),
("slack", "Slack"),
("pd", "PagerDuty"),
("po", "Pushover"),
("pushbullet", "Pushbullet"),
("opsgenie", "OpsGenie"),
("victorops", "VictorOps"),
("discord", "Discord"),
("telegram", "Telegram"),
],
max_length=20,
),
)
]

+ 21
- 7
hc/api/migrations/0033_auto_20170714_1715.py View File

@ -7,14 +7,28 @@ from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('api', '0032_auto_20170608_1158'),
]
dependencies = [("api", "0032_auto_20170608_1158")]
operations = [
migrations.AlterField(
model_name='channel',
name='kind',
field=models.CharField(choices=[('email', 'Email'), ('webhook', 'Webhook'), ('hipchat', 'HipChat'), ('slack', 'Slack'), ('pd', 'PagerDuty'), ('po', 'Pushover'), ('pushbullet', 'Pushbullet'), ('opsgenie', 'OpsGenie'), ('victorops', 'VictorOps'), ('discord', 'Discord'), ('telegram', 'Telegram'), ('sms', 'SMS')], max_length=20),
),
model_name="channel",
name="kind",
field=models.CharField(
choices=[
("email", "Email"),
("webhook", "Webhook"),
("hipchat", "HipChat"),
("slack", "Slack"),
("pd", "PagerDuty"),
("po", "Pushover"),
("pushbullet", "Pushbullet"),
("opsgenie", "OpsGenie"),
("victorops", "VictorOps"),
("discord", "Discord"),
("telegram", "Telegram"),
("sms", "SMS"),
],
max_length=20,
),
)
]

+ 22
- 7
hc/api/migrations/0034_auto_20171227_1530.py View File

@ -7,14 +7,29 @@ from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('api', '0033_auto_20170714_1715'),
]
dependencies = [("api", "0033_auto_20170714_1715")]
operations = [
migrations.AlterField(
model_name='channel',
name='kind',
field=models.CharField(choices=[('email', 'Email'), ('webhook', 'Webhook'), ('hipchat', 'HipChat'), ('slack', 'Slack'), ('pd', 'PagerDuty'), ('pagertree', 'PagerTree'), ('po', 'Pushover'), ('pushbullet', 'Pushbullet'), ('opsgenie', 'OpsGenie'), ('victorops', 'VictorOps'), ('discord', 'Discord'), ('telegram', 'Telegram'), ('sms', 'SMS')], max_length=20),
),
model_name="channel",
name="kind",
field=models.CharField(
choices=[
("email", "Email"),
("webhook", "Webhook"),
("hipchat", "HipChat"),
("slack", "Slack"),
("pd", "PagerDuty"),
("pagertree", "PagerTree"),
("po", "Pushover"),
("pushbullet", "Pushbullet"),
("opsgenie", "OpsGenie"),
("victorops", "VictorOps"),
("discord", "Discord"),
("telegram", "Telegram"),
("sms", "SMS"),
],
max_length=20,
),
)
]

+ 23
- 7
hc/api/migrations/0035_auto_20171229_2008.py View File

@ -7,14 +7,30 @@ from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('api', '0034_auto_20171227_1530'),
]
dependencies = [("api", "0034_auto_20171227_1530")]
operations = [
migrations.AlterField(
model_name='channel',
name='kind',
field=models.CharField(choices=[('email', 'Email'), ('webhook', 'Webhook'), ('hipchat', 'HipChat'), ('slack', 'Slack'), ('pd', 'PagerDuty'), ('pagertree', 'PagerTree'), ('po', 'Pushover'), ('pushbullet', 'Pushbullet'), ('opsgenie', 'OpsGenie'), ('victorops', 'VictorOps'), ('discord', 'Discord'), ('telegram', 'Telegram'), ('sms', 'SMS'), ('zendesk', 'Zendesk')], max_length=20),
),
model_name="channel",
name="kind",
field=models.CharField(
choices=[
("email", "Email"),
("webhook", "Webhook"),
("hipchat", "HipChat"),
("slack", "Slack"),
("pd", "PagerDuty"),
("pagertree", "PagerTree"),
("po", "Pushover"),
("pushbullet", "Pushbullet"),
("opsgenie", "OpsGenie"),
("victorops", "VictorOps"),
("discord", "Discord"),
("telegram", "Telegram"),
("sms", "SMS"),
("zendesk", "Zendesk"),
],
max_length=20,
),
)
]

+ 2
- 9
hc/api/migrations/0036_auto_20180116_2243.py View File

@ -7,13 +7,6 @@ from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('api', '0035_auto_20171229_2008'),
]
dependencies = [("api", "0035_auto_20171229_2008")]
operations = [
migrations.AlterIndexTogether(
name='check',
index_together=set([]),
),
]
operations = [migrations.AlterIndexTogether(name="check", index_together=set([]))]

+ 4
- 6
hc/api/migrations/0037_auto_20180127_1215.py View File

@ -7,14 +7,12 @@ from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('api', '0036_auto_20180116_2243'),
]
dependencies = [("api", "0036_auto_20180116_2243")]
operations = [
migrations.AlterField(
model_name='ping',
name='id',
model_name="ping",
name="id",
field=models.BigAutoField(primary_key=True, serialize=False),
),
)
]

+ 5
- 7
hc/api/migrations/0038_auto_20180318_1306.py View File

@ -7,19 +7,17 @@ from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('api', '0037_auto_20180127_1215'),
]
dependencies = [("api", "0037_auto_20180127_1215")]
operations = [
migrations.AddField(
model_name='check',
name='has_confirmation_link',
model_name="check",
name="has_confirmation_link",
field=models.BooleanField(default=False),
),
migrations.AddField(
model_name='ping',
name='body',
model_name="ping",
name="body",
field=models.CharField(blank=True, max_length=10000, null=True),
),
]

+ 2
- 9
hc/api/migrations/0039_remove_check_last_ping_body.py View File

@ -7,13 +7,6 @@ from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('api', '0038_auto_20180318_1306'),
]
dependencies = [("api", "0038_auto_20180318_1306")]
operations = [
migrations.RemoveField(
model_name='check',
name='last_ping_body',
),
]
operations = [migrations.RemoveField(model_name="check", name="last_ping_body")]

+ 4
- 8
hc/api/migrations/0040_auto_20180517_1336.py View File

@ -5,19 +5,15 @@ from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('api', '0039_remove_check_last_ping_body'),
]
dependencies = [("api", "0039_remove_check_last_ping_body")]
operations = [
migrations.AddField(
model_name='check',
name='last_ping_was_fail',
model_name="check",
name="last_ping_was_fail",
field=models.NullBooleanField(default=False),
),
migrations.AddField(
model_name='ping',
name='fail',
field=models.NullBooleanField(default=False),
model_name="ping", name="fail", field=models.NullBooleanField(default=False)
),
]

+ 3
- 7
hc/api/migrations/0041_check_desc.py View File

@ -5,14 +5,10 @@ from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('api', '0040_auto_20180517_1336'),
]
dependencies = [("api", "0040_auto_20180517_1336")]
operations = [
migrations.AddField(
model_name='check',
name='desc',
field=models.TextField(blank=True),
),
model_name="check", name="desc", field=models.TextField(blank=True)
)
]

Some files were not shown because too many files changed in this diff

Loading…
Cancel
Save