From 9618561a142b757bd3282ab0661ca6d07fc6db77 Mon Sep 17 00:00:00 2001
From: "pre-commit-ci[bot]"
<66853113+pre-commit-ci[bot]@users.noreply.github.com>
Date: Mon, 12 Jan 2026 19:59:28 +0000
Subject: [PATCH 1/2] [pre-commit.ci] pre-commit autoupdate
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
updates:
- https://github.com/psf/black → https://github.com/psf/black-pre-commit-mirror
- [github.com/psf/black-pre-commit-mirror: 22.12.0 → 25.12.0](https://github.com/psf/black-pre-commit-mirror/compare/22.12.0...25.12.0)
- [github.com/PyCQA/flake8: 6.0.0 → 7.3.0](https://github.com/PyCQA/flake8/compare/6.0.0...7.3.0)
- [github.com/pre-commit/pre-commit-hooks: v4.4.0 → v6.0.0](https://github.com/pre-commit/pre-commit-hooks/compare/v4.4.0...v6.0.0)
---
.pre-commit-config.yaml | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
index 054163f..665ab0c 100644
--- a/.pre-commit-config.yaml
+++ b/.pre-commit-config.yaml
@@ -1,20 +1,20 @@
exclude: .+/migrations/.+\.py
repos:
- - repo: https://github.com/psf/black
- rev: 22.12.0
+ - repo: https://github.com/psf/black-pre-commit-mirror
+ rev: 25.12.0
hooks:
- id: black
language_version: python3.11
args: [--line-length=120]
- repo: https://github.com/PyCQA/flake8
- rev: 6.0.0
+ rev: 7.3.0
hooks:
- id: flake8
args: [ --max-line-length=120 ]
- repo: https://github.com/pre-commit/pre-commit-hooks
- rev: v4.4.0
+ rev: v6.0.0
hooks:
- id: check-yaml
- id: trailing-whitespace
From 3545c7ceb68834845c83c72735571d540351e9d5 Mon Sep 17 00:00:00 2001
From: "pre-commit-ci[bot]"
<66853113+pre-commit-ci[bot]@users.noreply.github.com>
Date: Mon, 12 Jan 2026 19:59:37 +0000
Subject: [PATCH 2/2] [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
---
.gitignore | 2 +-
.pre-commit-config.yaml | 2 +-
LICENSE | 2 +-
Makefile | 2 +-
README.md | 2 +-
TODO.md | 2 +-
accounts/admin.py | 1 -
manage.py | 4 ++--
requirements.txt | 8 ++++----
rewardme/settings.py | 29 ++++++++++++++---------------
rewardme/urls.py | 1 +
sample.env | 2 +-
static/src/htmx.min.js | 2 +-
static/src/output.css | 2 +-
templates/500.html | 2 +-
templates/_base.html | 2 +-
templates/index.html | 2 +-
templates/invalid_page.html | 2 +-
templates/specific_field.html | 2 +-
templates/success.html | 2 +-
templates/todo.html | 2 +-
21 files changed, 37 insertions(+), 38 deletions(-)
diff --git a/.gitignore b/.gitignore
index 74914a0..acfe9d6 100644
--- a/.gitignore
+++ b/.gitignore
@@ -162,4 +162,4 @@ cython_debug/
# django static files
staticfiles/
-static/CACHE/
\ No newline at end of file
+static/CACHE/
diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
index 665ab0c..19ba430 100644
--- a/.pre-commit-config.yaml
+++ b/.pre-commit-config.yaml
@@ -20,4 +20,4 @@ repos:
- id: trailing-whitespace
- id: end-of-file-fixer
- id: debug-statements
- - id: requirements-txt-fixer
\ No newline at end of file
+ - id: requirements-txt-fixer
diff --git a/LICENSE b/LICENSE
index 638fb55..e959fc6 100644
--- a/LICENSE
+++ b/LICENSE
@@ -6,4 +6,4 @@ Permission is hereby granted, free of charge, to any person obtaining a copy of
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
\ No newline at end of file
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/Makefile b/Makefile
index 917c0f3..6d908ee 100644
--- a/Makefile
+++ b/Makefile
@@ -10,4 +10,4 @@ migrate:
migrations:
@echo "Creating migration..."
- python manage.py makemigrations
\ No newline at end of file
+ python manage.py makemigrations
diff --git a/README.md b/README.md
index 9e8611f..c769bf3 100644
--- a/README.md
+++ b/README.md
@@ -18,4 +18,4 @@ Transaction page:
## TODO: update this file with more details
What's left to do:
-Check [TODO.md](TODO.md)
\ No newline at end of file
+Check [TODO.md](TODO.md)
diff --git a/TODO.md b/TODO.md
index ba44c54..1492937 100644
--- a/TODO.md
+++ b/TODO.md
@@ -4,4 +4,4 @@
- 3 Failed attempts and block user for 24 hours.
- Throttle OTP generation
- OTP support via third party services
-- Support multiple offers with expiry and use the latest offer to give points
\ No newline at end of file
+- Support multiple offers with expiry and use the latest offer to give points
diff --git a/accounts/admin.py b/accounts/admin.py
index 761c839..9eb38e1 100644
--- a/accounts/admin.py
+++ b/accounts/admin.py
@@ -16,4 +16,3 @@ class OTPValidationAdmin(admin.ModelAdmin):
list_display = ("destination", "otp", "valid_until", "is_validated")
list_filter = ("is_validated",)
search_fields = ("destination",)
-
diff --git a/manage.py b/manage.py
index 6b45bd6..efc7353 100755
--- a/manage.py
+++ b/manage.py
@@ -6,7 +6,7 @@
def main():
"""Run administrative tasks."""
- os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'rewardme.settings')
+ os.environ.setdefault("DJANGO_SETTINGS_MODULE", "rewardme.settings")
try:
from django.core.management import execute_from_command_line
except ImportError as exc:
@@ -18,5 +18,5 @@ def main():
execute_from_command_line(sys.argv)
-if __name__ == '__main__':
+if __name__ == "__main__":
main()
diff --git a/requirements.txt b/requirements.txt
index deb4076..a25b5d1 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -1,13 +1,13 @@
Django==4.1.5
django-compressor==4.1
+django-environ==0.9.0
django-extensions==3.2.1
+django-flags==5.0.12
django-htmx==1.13.0
django-simple-history==3.2.0
django-sms==0.6.0
djangorestframework==3.14.0
+pre-commit==2.21.0
pytailwindcss==0.1.4
requests==2.28.1
-pre-commit==2.21.0
-django-environ==0.9.0
-django-flags==5.0.12
-sentry-sdk==1.13.0
\ No newline at end of file
+sentry-sdk==1.13.0
diff --git a/rewardme/settings.py b/rewardme/settings.py
index 06955e8..933c36f 100644
--- a/rewardme/settings.py
+++ b/rewardme/settings.py
@@ -10,7 +10,6 @@
https://docs.djangoproject.com/en/4.1/ref/settings/
"""
-
import os
from pathlib import Path
@@ -28,16 +27,16 @@
# See https://docs.djangoproject.com/en/4.1/howto/deployment/checklist/
# Take environment variables from .env file
-environ.Env.read_env(os.path.join(BASE_DIR, '.env'))
+environ.Env.read_env(os.path.join(BASE_DIR, ".env"))
# SECURITY WARNING: keep the secret key used in production secret!
-SECRET_KEY = env('SECRET_KEY')
+SECRET_KEY = env("SECRET_KEY")
# SECURITY WARNING: don't run with debug turned on in production!
-DEBUG = env('DEBUG')
+DEBUG = env("DEBUG")
-ALLOWED_HOSTS = env.list('ALLOWED_HOSTS')
-CSRF_TRUSTED_ORIGINS = env.list('CSRF_TRUSTED_ORIGINS')
+ALLOWED_HOSTS = env.list("ALLOWED_HOSTS")
+CSRF_TRUSTED_ORIGINS = env.list("CSRF_TRUSTED_ORIGINS")
# Application definition
@@ -100,7 +99,7 @@
WSGI_APPLICATION = "rewardme.wsgi.application"
-if USE_SQLITE := env('USE_SQLITE'):
+if USE_SQLITE := env("USE_SQLITE"):
DATABASES = {
"default": {
"ENGINE": "django.db.backends.sqlite3",
@@ -110,7 +109,7 @@
else:
DATABASES = {
"default": {
- 'ENGINE': 'django.db.backends.postgresql',
+ "ENGINE": "django.db.backends.postgresql",
"NAME": env("DB_NAME"),
"USER": env("DB_USER"),
"PASSWORD": env("DB_PASSWORD"),
@@ -159,9 +158,9 @@
STATIC_ROOT = BASE_DIR / "staticfiles"
COMPRESS_ENABLED = True
STATICFILES_FINDERS = (
- 'django.contrib.staticfiles.finders.FileSystemFinder',
- 'django.contrib.staticfiles.finders.AppDirectoriesFinder',
- 'compressor.finders.CompressorFinder',
+ "django.contrib.staticfiles.finders.FileSystemFinder",
+ "django.contrib.staticfiles.finders.AppDirectoriesFinder",
+ "compressor.finders.CompressorFinder",
)
# Default primary key field type
@@ -185,14 +184,14 @@
)
# Sentry
-if USE_SENTRY := env.bool('USE_SENTRY', default=False):
+if USE_SENTRY := env.bool("USE_SENTRY", default=False):
import sentry_sdk
from sentry_sdk.integrations.django import DjangoIntegration
sentry_sdk.init(
- dsn=env('SENTRY_DSN'),
+ dsn=env("SENTRY_DSN"),
integrations=[DjangoIntegration()],
- traces_sample_rate=env.float('SENTRY_TRACES_SAMPLE_RATE', default=0.1),
+ traces_sample_rate=env.float("SENTRY_TRACES_SAMPLE_RATE", default=0.1),
send_default_pii=True,
- release=env('SENTRY_RELEASE'),
+ release=env("SENTRY_RELEASE"),
)
diff --git a/rewardme/urls.py b/rewardme/urls.py
index 3e819e6..5f2975b 100644
--- a/rewardme/urls.py
+++ b/rewardme/urls.py
@@ -13,6 +13,7 @@
1. Import the include() function: from django.urls import include, path
2. Add a URL to urlpatterns: path('blog/', include('blog.urls'))
"""
+
from django.contrib import admin
from django.urls import path, include
diff --git a/sample.env b/sample.env
index 92315a7..5259dc0 100644
--- a/sample.env
+++ b/sample.env
@@ -11,4 +11,4 @@ DB_HOST=
USE_SENTRY=
SENTRY_DSN=
SENTRY_SAMPLE_RATE=
-SENTRY_RELEASE
\ No newline at end of file
+SENTRY_RELEASE
diff --git a/static/src/htmx.min.js b/static/src/htmx.min.js
index 556de48..293df11 100644
--- a/static/src/htmx.min.js
+++ b/static/src/htmx.min.js
@@ -1 +1 @@
-(function(e,t){if(typeof define==="function"&&define.amd){define([],t)}else{e.htmx=e.htmx||t()}})(typeof self!=="undefined"?self:this,function(){return function(){"use strict";var W={onLoad:t,process:mt,on:X,off:F,trigger:Q,ajax:or,find:R,findAll:O,closest:N,values:function(e,t){var r=jt(e,t||"post");return r.values},remove:q,addClass:L,removeClass:T,toggleClass:H,takeClass:A,defineExtension:dr,removeExtension:vr,logAll:C,logger:null,config:{historyEnabled:true,historyCacheSize:10,refreshOnHistoryMiss:false,defaultSwapStyle:"innerHTML",defaultSwapDelay:0,defaultSettleDelay:20,includeIndicatorStyles:true,indicatorClass:"htmx-indicator",requestClass:"htmx-request",addedClass:"htmx-added",settlingClass:"htmx-settling",swappingClass:"htmx-swapping",allowEval:true,inlineScriptNonce:"",attributesToSettle:["class","style","width","height"],withCredentials:false,timeout:0,wsReconnectDelay:"full-jitter",disableSelector:"[hx-disable], [data-hx-disable]",useTemplateFragments:false,scrollBehavior:"smooth",defaultFocusScroll:false},parseInterval:v,_:e,createEventSource:function(e){return new EventSource(e,{withCredentials:true})},createWebSocket:function(e){return new WebSocket(e,[])},version:"1.8.4"};var r={addTriggerHandler:ft,bodyContains:te,canAccessLocalStorage:E,filterValues:zt,hasAttribute:o,getAttributeValue:G,getClosestMatch:h,getExpressionVars:rr,getHeaders:_t,getInputValues:jt,getInternalData:Z,getSwapSpecification:Gt,getTriggerSpecs:Xe,getTarget:oe,makeFragment:g,mergeObjects:re,makeSettleInfo:Zt,oobSwap:_,selectAndSwap:Oe,settleImmediately:At,shouldCancel:Ve,triggerEvent:Q,triggerErrorEvent:Y,withExtensions:wt};var n=["get","post","put","delete","patch"];var i=n.map(function(e){return"[hx-"+e+"], [data-hx-"+e+"]"}).join(", ");function v(e){if(e==undefined){return undefined}if(e.slice(-2)=="ms"){return parseFloat(e.slice(0,-2))||undefined}if(e.slice(-1)=="s"){return parseFloat(e.slice(0,-1))*1e3||undefined}if(e.slice(-1)=="m"){return parseFloat(e.slice(0,-1))*1e3*60||undefined}return parseFloat(e)||undefined}function f(e,t){return e.getAttribute&&e.getAttribute(t)}function o(e,t){return e.hasAttribute&&(e.hasAttribute(t)||e.hasAttribute("data-"+t))}function G(e,t){return f(e,t)||f(e,"data-"+t)}function u(e){return e.parentElement}function J(){return document}function h(e,t){while(e&&!t(e)){e=u(e)}return e?e:null}function a(e,t,r){var n=G(t,r);var i=G(t,"hx-disinherit");if(e!==t&&i&&(i==="*"||i.split(" ").indexOf(r)>=0)){return"unset"}else{return n}}function $(t,r){var n=null;h(t,function(e){return n=a(t,e,r)});if(n!=="unset"){return n}}function d(e,t){var r=e.matches||e.matchesSelector||e.msMatchesSelector||e.mozMatchesSelector||e.webkitMatchesSelector||e.oMatchesSelector;return r&&r.call(e,t)}function s(e){var t=/<([a-z][^\/\0>\x20\t\r\n\f]*)/i;var r=t.exec(e);if(r){return r[1].toLowerCase()}else{return""}}function l(e,t){var r=new DOMParser;var n=r.parseFromString(e,"text/html");var i=n.body;while(t>0){t--;i=i.firstChild}if(i==null){i=J().createDocumentFragment()}return i}function g(e){if(W.config.useTemplateFragments){var t=l("
"+e+"",0);return t.querySelector("template").content}else{var r=s(e);switch(r){case"thead":case"tbody":case"tfoot":case"colgroup":case"caption":return l("",1);case"col":return l("",2);case"tr":return l("",2);case"td":case"th":return l("",3);case"script":return l(""+e+"
",1);default:return l(e,0)}}}function ee(e){if(e){e()}}function p(e,t){return Object.prototype.toString.call(e)==="[object "+t+"]"}function m(e){return p(e,"Function")}function x(e){return p(e,"Object")}function Z(e){var t="htmx-internal-data";var r=e[t];if(!r){r=e[t]={}}return r}function y(e){var t=[];if(e){for(var r=0;r=0}function te(e){if(e.getRootNode&&e.getRootNode()instanceof ShadowRoot){return J().body.contains(e.getRootNode().host)}else{return J().body.contains(e)}}function w(e){return e.trim().split(/\s+/)}function re(e,t){for(var r in t){if(t.hasOwnProperty(r)){e[r]=t[r]}}return e}function S(e){try{return JSON.parse(e)}catch(e){St(e);return null}}function E(){var e="htmx:localStorageTest";try{localStorage.setItem(e,e);localStorage.removeItem(e);return true}catch(e){return false}}function e(e){return Qt(J().body,function(){return eval(e)})}function t(t){var e=W.on("htmx:load",function(e){t(e.detail.elt)});return e}function C(){W.logger=function(e,t,r){if(console){console.log(t,e,r)}}}function R(e,t){if(t){return e.querySelector(t)}else{return R(J(),e)}}function O(e,t){if(t){return e.querySelectorAll(t)}else{return O(J(),e)}}function q(e,t){e=D(e);if(t){setTimeout(function(){q(e)},t)}else{e.parentElement.removeChild(e)}}function L(e,t,r){e=D(e);if(r){setTimeout(function(){L(e,t)},r)}else{e.classList&&e.classList.add(t)}}function T(e,t,r){e=D(e);if(r){setTimeout(function(){T(e,t)},r)}else{if(e.classList){e.classList.remove(t);if(e.classList.length===0){e.removeAttribute("class")}}}}function H(e,t){e=D(e);e.classList.toggle(t)}function A(e,t){e=D(e);K(e.parentElement.children,function(e){T(e,t)});L(e,t)}function N(e,t){e=D(e);if(e.closest){return e.closest(t)}else{do{if(e==null||d(e,t)){return e}}while(e=e&&u(e))}}function I(e,t){if(t.indexOf("closest ")===0){return[N(e,t.substr(8))]}else if(t.indexOf("find ")===0){return[R(e,t.substr(5))]}else if(t.indexOf("next ")===0){return[k(e,t.substr(5))]}else if(t.indexOf("previous ")===0){return[M(e,t.substr(9))]}else if(t==="document"){return[document]}else if(t==="window"){return[window]}else{return J().querySelectorAll(t)}}var k=function(e,t){var r=J().querySelectorAll(t);for(var n=0;n=0;n--){var i=r[n];if(i.compareDocumentPosition(e)===Node.DOCUMENT_POSITION_FOLLOWING){return i}}};function ne(e,t){if(t){return I(e,t)[0]}else{return I(J().body,e)[0]}}function D(e){if(p(e,"String")){return R(e)}else{return e}}function P(e,t,r){if(m(t)){return{target:J().body,event:e,listener:t}}else{return{target:D(e),event:t,listener:r}}}function X(t,r,n){pr(function(){var e=P(t,r,n);e.target.addEventListener(e.event,e.listener)});var e=m(r);return e?r:n}function F(t,r,n){pr(function(){var e=P(t,r,n);e.target.removeEventListener(e.event,e.listener)});return m(r)?r:n}var ie=J().createElement("output");function j(e,t){var r=$(e,t);if(r){if(r==="this"){return[ae(e,t)]}else{var n=I(e,r);if(n.length===0){St('The selector "'+r+'" on '+t+" returned no matches!");return[ie]}else{return n}}}}function ae(e,t){return h(e,function(e){return G(e,t)!=null})}function oe(e){var t=$(e,"hx-target");if(t){if(t==="this"){return ae(e,"hx-target")}else{return ne(e,t)}}else{var r=Z(e);if(r.boosted){return J().body}else{return e}}}function B(e){var t=W.config.attributesToSettle;for(var r=0;r0){o=e.substr(0,e.indexOf(":"));t=e.substr(e.indexOf(":")+1,e.length)}else{o=e}var r=J().querySelectorAll(t);if(r){K(r,function(e){var t;var r=i.cloneNode(true);t=J().createDocumentFragment();t.appendChild(r);if(!V(o,e)){t=r}var n={shouldSwap:true,target:e,fragment:t};if(!Q(e,"htmx:oobBeforeSwap",n))return;e=n.target;if(n["shouldSwap"]){Ce(o,e,e,t,a)}K(a.elts,function(e){Q(e,"htmx:oobAfterSwap",n)})});i.parentNode.removeChild(i)}else{i.parentNode.removeChild(i);Y(J().body,"htmx:oobErrorNoTarget",{content:i})}return e}function z(e,t,r){var n=$(e,"hx-select-oob");if(n){var i=n.split(",");for(let e=0;e0){var t=n.querySelector(e.tagName+"[id='"+e.id+"']");if(t&&t!==n){var r=e.cloneNode();U(e,t);i.tasks.push(function(){U(e,r)})}}})}function ue(e){return function(){T(e,W.config.addedClass);mt(e);ht(e);fe(e);Q(e,"htmx:load")}}function fe(e){var t="[autofocus]";var r=d(e,t)?e:e.querySelector(t);if(r!=null){r.focus()}}function ce(e,t,r,n){le(e,r,n);while(r.childNodes.length>0){var i=r.firstChild;L(i,W.config.addedClass);e.insertBefore(i,t);if(i.nodeType!==Node.TEXT_NODE&&i.nodeType!==Node.COMMENT_NODE){n.tasks.push(ue(i))}}}function he(e,t){var r=0;while(r-1){var t=e.replace(/