prune_captcha 1.15.1__py3-none-any.whl → 1.16.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- prune_captcha/__init__.py +1 -0
- {captcha_prune → prune_captcha}/apps.py +2 -2
- prune_captcha/static/prune_captcha/css/captcha_prune.css +23 -0
- prune_captcha/static/prune_captcha/js/captcha_prune.js +57 -0
- prune_captcha/templates/prune_captcha/captcha.html +7 -0
- {prune_captcha-1.15.1.dist-info → prune_captcha-1.16.0.dist-info}/METADATA +8 -6
- prune_captcha-1.16.0.dist-info/RECORD +10 -0
- prune_captcha-1.16.0.dist-info/top_level.txt +1 -0
- captcha_prune/__init__.py +0 -1
- prune_captcha-1.15.1.dist-info/RECORD +0 -7
- prune_captcha-1.15.1.dist-info/top_level.txt +0 -1
- {captcha_prune → prune_captcha}/utils.py +0 -0
- {prune_captcha-1.15.1.dist-info → prune_captcha-1.16.0.dist-info}/WHEEL +0 -0
@@ -0,0 +1 @@
|
|
1
|
+
default_app_config = "prune_captcha.apps.DjangoPuzzleConfig"
|
@@ -4,10 +4,10 @@ from django.core.exceptions import ImproperlyConfigured
|
|
4
4
|
|
5
5
|
|
6
6
|
class DjangoPuzzleConfig(AppConfig):
|
7
|
-
name = "
|
7
|
+
name = "prune_captcha"
|
8
8
|
|
9
9
|
def ready(self):
|
10
10
|
if not hasattr(settings, "PUZZLE_IMAGE_STATIC_PATH"):
|
11
11
|
raise ImproperlyConfigured(
|
12
|
-
"
|
12
|
+
"prune_captcha: vous devez définir PUZZLE_IMAGE_STATIC_PATH dans settings.py"
|
13
13
|
)
|
@@ -0,0 +1,23 @@
|
|
1
|
+
.puzzle-container {
|
2
|
+
position: relative;
|
3
|
+
}
|
4
|
+
|
5
|
+
.puzzle-background {
|
6
|
+
width: 100%;
|
7
|
+
height: 100%;
|
8
|
+
position: absolute;
|
9
|
+
background-repeat: no-repeat;
|
10
|
+
}
|
11
|
+
|
12
|
+
.puzzle-mask {
|
13
|
+
background-color: var(--celadon-200);
|
14
|
+
position: absolute;
|
15
|
+
z-index: 1;
|
16
|
+
}
|
17
|
+
|
18
|
+
.puzzle-piece {
|
19
|
+
border: 1px solid var(--celadon-200);
|
20
|
+
position: absolute;
|
21
|
+
background-repeat: no-repeat;
|
22
|
+
z-index: 1;
|
23
|
+
}
|
@@ -0,0 +1,57 @@
|
|
1
|
+
const puzzlePiece = document.querySelector(".puzzle-piece");
|
2
|
+
const puzzleContainer = document.querySelector(".puzzle-container");
|
3
|
+
const inputPosX = document.querySelector('input[name="pos_x_answer"]');
|
4
|
+
const inputPosY = document.querySelector('input[name="pos_y_answer"]');
|
5
|
+
|
6
|
+
inputPosX.parentElement.style.display = "none";
|
7
|
+
inputPosY.parentElement.style.display = "none";
|
8
|
+
|
9
|
+
let isDragging = false;
|
10
|
+
let offsetX = 0;
|
11
|
+
let offsetY = 0;
|
12
|
+
|
13
|
+
const fillInput = (e = undefined) => {
|
14
|
+
const pieceRect = puzzlePiece.getBoundingClientRect();
|
15
|
+
const containerRect = puzzleContainer.getBoundingClientRect();
|
16
|
+
const pieceWidth = puzzlePiece.offsetWidth;
|
17
|
+
const pieceHeight = puzzlePiece.offsetHeight;
|
18
|
+
|
19
|
+
const clientX = e === undefined ? pieceRect.left : e.clientX;
|
20
|
+
const clientY = e === undefined ? pieceRect.top : e.clientY;
|
21
|
+
|
22
|
+
let x = clientX - containerRect.left - offsetX;
|
23
|
+
let y = clientY - containerRect.top - offsetY;
|
24
|
+
|
25
|
+
x = Math.max(0, Math.min(x, containerRect.width - pieceWidth));
|
26
|
+
y = Math.max(0, Math.min(y, containerRect.height - pieceHeight));
|
27
|
+
|
28
|
+
puzzlePiece.style.left = `${x}px`;
|
29
|
+
puzzlePiece.style.top = `${y}px`;
|
30
|
+
|
31
|
+
inputPosX.value = Math.round(x);
|
32
|
+
inputPosY.value = Math.round(y);
|
33
|
+
};
|
34
|
+
fillInput();
|
35
|
+
|
36
|
+
puzzlePiece.addEventListener("mousedown", (e) => {
|
37
|
+
isDragging = true;
|
38
|
+
document.body.style.userSelect = "none";
|
39
|
+
|
40
|
+
const pieceRect = puzzlePiece.getBoundingClientRect();
|
41
|
+
|
42
|
+
offsetX = e.clientX - pieceRect.left;
|
43
|
+
offsetY = e.clientY - pieceRect.top;
|
44
|
+
});
|
45
|
+
|
46
|
+
puzzleContainer.addEventListener("mousemove", (e) => {
|
47
|
+
if (isDragging) {
|
48
|
+
fillInput(e);
|
49
|
+
}
|
50
|
+
});
|
51
|
+
|
52
|
+
puzzleContainer.addEventListener("mouseup", (e) => {
|
53
|
+
if (isDragging) {
|
54
|
+
isDragging = false;
|
55
|
+
document.body.style.userSelect = "auto";
|
56
|
+
}
|
57
|
+
});
|
@@ -0,0 +1,7 @@
|
|
1
|
+
{% load static %}
|
2
|
+
|
3
|
+
<div class="puzzle-container" style="width: {{ puzzle.width }}px; height: {{ puzzle.height }}px; background-image: url('{% static puzzle.image %}'); background-size: {{ puzzle.width }}px {{ puzzle.height }}px;">
|
4
|
+
<div class="puzzle-background" style="background-image: url('{% static puzzle.image %}'); background-size: {{ puzzle.width }}px {{ puzzle.height }}px;"></div>
|
5
|
+
<div class="puzzle-mask" style="top: {{ puzzle.pos_y_solution }}px; left: {{ puzzle.pos_x_solution }}px; width: {{ puzzle.piece_width }}px; height: {{ puzzle.piece_height }}px;"></div>
|
6
|
+
<div class="puzzle-piece" style="background-image: url('{% static puzzle.image %}'); background-size: {{ puzzle.width }}px {{ puzzle.height }}px; background-position: -{{ puzzle.pos_x_solution }}px -{{ puzzle.pos_y_solution }}px; width: calc({{ puzzle.piece_width }}px - 1px); height: calc({{ puzzle.piece_height }}px - 1px); top: {{ puzzle.piece_pos_y }}px; left: {{ puzzle.piece_pos_x }}px;"></div>
|
7
|
+
</div>
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: prune_captcha
|
3
|
-
Version: 1.
|
3
|
+
Version: 1.16.0
|
4
4
|
Summary: A tool to protect formulaire from spam.
|
5
5
|
Author-email: Arnout <bastien@prune.sh>
|
6
6
|
Project-URL: Made_by, https://prune.sh/
|
@@ -33,7 +33,7 @@ Captcha helps prevent robots from spamming using your forms.
|
|
33
33
|
Run the following command in the console:
|
34
34
|
|
35
35
|
```bash
|
36
|
-
uv add
|
36
|
+
uv add prune_captcha
|
37
37
|
```
|
38
38
|
|
39
39
|
### Updating the captcha
|
@@ -64,7 +64,7 @@ In `settings.py`, set the path to the images used for the puzzle:
|
|
64
64
|
PUZZLE_IMAGE_STATIC_PATH = "website/static/website/images/puzzles/"
|
65
65
|
```
|
66
66
|
|
67
|
-
Important: You must import the static files (css, js) present in "
|
67
|
+
Important: You must import the static files (css, js) present in "prune_captcha/static/".
|
68
68
|
|
69
69
|
### Utilisation
|
70
70
|
|
@@ -73,7 +73,7 @@ Important: You must import the static files (css, js) present in "captcha_prune/
|
|
73
73
|
- Use create_and_get_captcha to generate the captcha data:
|
74
74
|
|
75
75
|
```python
|
76
|
-
from
|
76
|
+
from prune_captcha.utils import create_and_get_captcha
|
77
77
|
```
|
78
78
|
|
79
79
|
```python
|
@@ -93,7 +93,7 @@ Important: You must import the static files (css, js) present in "captcha_prune/
|
|
93
93
|
- Include the component in your template:
|
94
94
|
|
95
95
|
```
|
96
|
-
{% include "
|
96
|
+
{% include "prune_captcha/captcha.html" %}
|
97
97
|
```
|
98
98
|
|
99
99
|
- POST request (form submission)
|
@@ -101,7 +101,7 @@ Important: You must import the static files (css, js) present in "captcha_prune/
|
|
101
101
|
- Use verify_captcha to validate the captcha:
|
102
102
|
|
103
103
|
```python
|
104
|
-
from
|
104
|
+
from prune_captcha.utils import verify_captcha
|
105
105
|
```
|
106
106
|
|
107
107
|
```python
|
@@ -116,6 +116,8 @@ Important: You must import the static files (css, js) present in "captcha_prune/
|
|
116
116
|
|
117
117
|
| Version | Date | Notes |
|
118
118
|
| ------- | ---------- | ---------------------------------- |
|
119
|
+
| 1.16.0 | 2025-05-21 | fix static |
|
120
|
+
| 1.15.2 | 2025-05-21 | fix manifest |
|
119
121
|
| 1.15.1 | 2025-05-21 | fix manifest |
|
120
122
|
| 1.15.0 | 2025-05-21 | fix manifest |
|
121
123
|
| 1.14.0 | 2025-05-21 | fix static and templates dirs |
|
@@ -0,0 +1,10 @@
|
|
1
|
+
prune_captcha/__init__.py,sha256=289nX-nsT20GUbXE9Lm4Iv6H7b7XmJyLisg9Z2MRR0k,61
|
2
|
+
prune_captcha/apps.py,sha256=imbFju15itWdZA7vPg7IRD0QnDp8FFnrEQVpjha8G7M,422
|
3
|
+
prune_captcha/utils.py,sha256=0wgRNCfmAAugFh5sw3qk-YqvNMiMZgJRtd6QlpRa-D8,1861
|
4
|
+
prune_captcha/static/prune_captcha/css/captcha_prune.css,sha256=nMBmOXSDNKcEWqq_n-tHuN3KcK8_a1o2DQS_msZ72MA,398
|
5
|
+
prune_captcha/static/prune_captcha/js/captcha_prune.js,sha256=CzQMJmBNI5-folgrQ3Fa78u-ENr9EpZ2e4OenUzNSPE,1779
|
6
|
+
prune_captcha/templates/prune_captcha/captcha.html,sha256=-gmfIfvAw_1TIGdJmOaaZA7v3VaUGM814KuistjjFzU,996
|
7
|
+
prune_captcha-1.16.0.dist-info/METADATA,sha256=KxBwPkLXtXu306J7OM7KptOpUvBkIgKN5ttKqiIiXi0,4017
|
8
|
+
prune_captcha-1.16.0.dist-info/WHEEL,sha256=zaaOINJESkSfm_4HQVc5ssNzHCPXhJm0kEUakpsEHaU,91
|
9
|
+
prune_captcha-1.16.0.dist-info/top_level.txt,sha256=v0fVjlwv7OWp7NHgpeR5Oj0xhlf81K24sP2r9DYw5Qg,14
|
10
|
+
prune_captcha-1.16.0.dist-info/RECORD,,
|
@@ -0,0 +1 @@
|
|
1
|
+
prune_captcha
|
captcha_prune/__init__.py
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
default_app_config = "captcha_prune.apps.DjangoPuzzleConfig"
|
@@ -1,7 +0,0 @@
|
|
1
|
-
captcha_prune/__init__.py,sha256=JerrqDuZCUa8pj_9pEv68rnlPsiXovRP4biKpCqyThs,61
|
2
|
-
captcha_prune/apps.py,sha256=WVAz3WWaPAgM7-Ojd_Cl2KVdcub1n-03qpnRyu2ToTo,422
|
3
|
-
captcha_prune/utils.py,sha256=0wgRNCfmAAugFh5sw3qk-YqvNMiMZgJRtd6QlpRa-D8,1861
|
4
|
-
prune_captcha-1.15.1.dist-info/METADATA,sha256=OyT_aSuiPpWQVLLxQq6vieTEQ2k-sD8NS5ujmj1auz0,3893
|
5
|
-
prune_captcha-1.15.1.dist-info/WHEEL,sha256=zaaOINJESkSfm_4HQVc5ssNzHCPXhJm0kEUakpsEHaU,91
|
6
|
-
prune_captcha-1.15.1.dist-info/top_level.txt,sha256=01HnLL5Bu66yMBCvNpNBzN0L6AxTdG1_1YFSJr3dI2w,14
|
7
|
-
prune_captcha-1.15.1.dist-info/RECORD,,
|
@@ -1 +0,0 @@
|
|
1
|
-
captcha_prune
|
File without changes
|
File without changes
|