Spaces:
Running
Running
Commit ·
a4a1065
1
Parent(s): c8daf53
Added email validation trigger
Browse files- 00_datamodel.ipynb +37 -32
- 01_main.ipynb +38 -21
- __pycache__/datamodel.cpython-312.pyc +0 -0
- __pycache__/main.cpython-312.pyc +0 -0
- contactdb.json +1 -1
- datamodel.py +18 -13
- main.py +14 -3
- templates/edit.html +4 -1
- templates/new.html +4 -1
00_datamodel.ipynb
CHANGED
|
@@ -471,7 +471,7 @@
|
|
| 471 |
},
|
| 472 |
{
|
| 473 |
"cell_type": "code",
|
| 474 |
-
"execution_count":
|
| 475 |
"metadata": {},
|
| 476 |
"outputs": [],
|
| 477 |
"source": [
|
|
@@ -486,13 +486,28 @@
|
|
| 486 |
" errors:ContactErrors = field(default_factory=lambda: ContactErrors())\n",
|
| 487 |
" is_valid:bool=True\n",
|
| 488 |
"\n",
|
| 489 |
-
" def
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 490 |
" self.firstname = c['firstname']\n",
|
| 491 |
" self.lastname = c['lastname']\n",
|
| 492 |
" self.phone = c['phone']\n",
|
| 493 |
" self.email = c['email']\n",
|
| 494 |
" self.id = c['id']\n",
|
| 495 |
-
"
|
|
|
|
| 496 |
"\n",
|
| 497 |
" def check_valid(self, duplicate_ok=False):\n",
|
| 498 |
" self.is_valid = True\n",
|
|
@@ -512,17 +527,7 @@
|
|
| 512 |
" self.errors.phone= \"Format phone not correct\"\n",
|
| 513 |
" else: pass\n",
|
| 514 |
"\n",
|
| 515 |
-
"
|
| 516 |
-
" self.is_valid = False\n",
|
| 517 |
-
" self.errors.email= \"Email is empty\"\n",
|
| 518 |
-
" elif not validate_email(self.email):\n",
|
| 519 |
-
" self.is_valid = False\n",
|
| 520 |
-
" self.errors.email= \"Format email not correct\"\n",
|
| 521 |
-
" elif not duplicate_ok:\n",
|
| 522 |
-
" if check_duplicates(self.email, Contacts().get_emails()):\n",
|
| 523 |
-
" self.is_valid = False\n",
|
| 524 |
-
" self.errors.email= \"Duplicated email\"\n",
|
| 525 |
-
" else: pass\n",
|
| 526 |
"\n",
|
| 527 |
" def commit(self, duplicate_ok=True):\n",
|
| 528 |
" self.check_valid(duplicate_ok=duplicate_ok)\n",
|
|
@@ -549,7 +554,7 @@
|
|
| 549 |
},
|
| 550 |
{
|
| 551 |
"cell_type": "code",
|
| 552 |
-
"execution_count":
|
| 553 |
"metadata": {},
|
| 554 |
"outputs": [
|
| 555 |
{
|
|
@@ -565,7 +570,7 @@
|
|
| 565 |
"True"
|
| 566 |
]
|
| 567 |
},
|
| 568 |
-
"execution_count":
|
| 569 |
"metadata": {},
|
| 570 |
"output_type": "execute_result"
|
| 571 |
}
|
|
@@ -580,7 +585,7 @@
|
|
| 580 |
},
|
| 581 |
{
|
| 582 |
"cell_type": "code",
|
| 583 |
-
"execution_count":
|
| 584 |
"metadata": {},
|
| 585 |
"outputs": [
|
| 586 |
{
|
|
@@ -589,7 +594,7 @@
|
|
| 589 |
"True"
|
| 590 |
]
|
| 591 |
},
|
| 592 |
-
"execution_count":
|
| 593 |
"metadata": {},
|
| 594 |
"output_type": "execute_result"
|
| 595 |
}
|
|
@@ -604,7 +609,7 @@
|
|
| 604 |
},
|
| 605 |
{
|
| 606 |
"cell_type": "code",
|
| 607 |
-
"execution_count":
|
| 608 |
"metadata": {},
|
| 609 |
"outputs": [
|
| 610 |
{
|
|
@@ -623,7 +628,7 @@
|
|
| 623 |
" 'rahuketu@gmail.com']"
|
| 624 |
]
|
| 625 |
},
|
| 626 |
-
"execution_count":
|
| 627 |
"metadata": {},
|
| 628 |
"output_type": "execute_result"
|
| 629 |
}
|
|
@@ -634,7 +639,7 @@
|
|
| 634 |
},
|
| 635 |
{
|
| 636 |
"cell_type": "code",
|
| 637 |
-
"execution_count":
|
| 638 |
"metadata": {},
|
| 639 |
"outputs": [
|
| 640 |
{
|
|
@@ -643,7 +648,7 @@
|
|
| 643 |
"Contact[[None, None], [None, None], [None, None], [None, None], [True, '']]"
|
| 644 |
]
|
| 645 |
},
|
| 646 |
-
"execution_count":
|
| 647 |
"metadata": {},
|
| 648 |
"output_type": "execute_result"
|
| 649 |
}
|
|
@@ -654,7 +659,7 @@
|
|
| 654 |
},
|
| 655 |
{
|
| 656 |
"cell_type": "code",
|
| 657 |
-
"execution_count":
|
| 658 |
"metadata": {},
|
| 659 |
"outputs": [
|
| 660 |
{
|
|
@@ -670,7 +675,7 @@
|
|
| 670 |
"True"
|
| 671 |
]
|
| 672 |
},
|
| 673 |
-
"execution_count":
|
| 674 |
"metadata": {},
|
| 675 |
"output_type": "execute_result"
|
| 676 |
}
|
|
@@ -687,7 +692,7 @@
|
|
| 687 |
},
|
| 688 |
{
|
| 689 |
"cell_type": "code",
|
| 690 |
-
"execution_count":
|
| 691 |
"metadata": {},
|
| 692 |
"outputs": [],
|
| 693 |
"source": [
|
|
@@ -698,7 +703,7 @@
|
|
| 698 |
},
|
| 699 |
{
|
| 700 |
"cell_type": "code",
|
| 701 |
-
"execution_count":
|
| 702 |
"metadata": {},
|
| 703 |
"outputs": [
|
| 704 |
{
|
|
@@ -756,7 +761,7 @@
|
|
| 756 |
" 'id': 10}]"
|
| 757 |
]
|
| 758 |
},
|
| 759 |
-
"execution_count":
|
| 760 |
"metadata": {},
|
| 761 |
"output_type": "execute_result"
|
| 762 |
}
|
|
@@ -775,7 +780,7 @@
|
|
| 775 |
},
|
| 776 |
{
|
| 777 |
"cell_type": "code",
|
| 778 |
-
"execution_count":
|
| 779 |
"metadata": {},
|
| 780 |
"outputs": [
|
| 781 |
{
|
|
@@ -788,7 +793,7 @@
|
|
| 788 |
" 'id': 1}"
|
| 789 |
]
|
| 790 |
},
|
| 791 |
-
"execution_count":
|
| 792 |
"metadata": {},
|
| 793 |
"output_type": "execute_result"
|
| 794 |
}
|
|
@@ -800,7 +805,7 @@
|
|
| 800 |
},
|
| 801 |
{
|
| 802 |
"cell_type": "code",
|
| 803 |
-
"execution_count":
|
| 804 |
"metadata": {},
|
| 805 |
"outputs": [
|
| 806 |
{
|
|
@@ -813,7 +818,7 @@
|
|
| 813 |
" 'id': 2}"
|
| 814 |
]
|
| 815 |
},
|
| 816 |
-
"execution_count":
|
| 817 |
"metadata": {},
|
| 818 |
"output_type": "execute_result"
|
| 819 |
}
|
|
@@ -824,7 +829,7 @@
|
|
| 824 |
},
|
| 825 |
{
|
| 826 |
"cell_type": "code",
|
| 827 |
-
"execution_count":
|
| 828 |
"metadata": {},
|
| 829 |
"outputs": [],
|
| 830 |
"source": [
|
|
|
|
| 471 |
},
|
| 472 |
{
|
| 473 |
"cell_type": "code",
|
| 474 |
+
"execution_count": 296,
|
| 475 |
"metadata": {},
|
| 476 |
"outputs": [],
|
| 477 |
"source": [
|
|
|
|
| 486 |
" errors:ContactErrors = field(default_factory=lambda: ContactErrors())\n",
|
| 487 |
" is_valid:bool=True\n",
|
| 488 |
"\n",
|
| 489 |
+
" def validate_contact_email(self, duplicate_ok):\n",
|
| 490 |
+
" if self.email is None or self.email == \"\":\n",
|
| 491 |
+
" self.is_valid = False\n",
|
| 492 |
+
" self.errors.email= \"Email is empty\"\n",
|
| 493 |
+
" elif not validate_email(self.email):\n",
|
| 494 |
+
" self.is_valid = False\n",
|
| 495 |
+
" self.errors.email= \"Format email not correct\"\n",
|
| 496 |
+
" elif not duplicate_ok:\n",
|
| 497 |
+
" if check_duplicates(self.email, Contacts().get_emails()):\n",
|
| 498 |
+
" self.is_valid = False\n",
|
| 499 |
+
" self.errors.email= \"Duplicated email\"\n",
|
| 500 |
+
" else: pass\n",
|
| 501 |
+
"\n",
|
| 502 |
+
"\n",
|
| 503 |
+
" def from_contacts_dict(self, c, validate=True, duplicate_ok=True):\n",
|
| 504 |
" self.firstname = c['firstname']\n",
|
| 505 |
" self.lastname = c['lastname']\n",
|
| 506 |
" self.phone = c['phone']\n",
|
| 507 |
" self.email = c['email']\n",
|
| 508 |
" self.id = c['id']\n",
|
| 509 |
+
" if validate:\n",
|
| 510 |
+
" self.check_valid(duplicate_ok=duplicate_ok)\n",
|
| 511 |
"\n",
|
| 512 |
" def check_valid(self, duplicate_ok=False):\n",
|
| 513 |
" self.is_valid = True\n",
|
|
|
|
| 527 |
" self.errors.phone= \"Format phone not correct\"\n",
|
| 528 |
" else: pass\n",
|
| 529 |
"\n",
|
| 530 |
+
" self.validate_contact_email(duplicate_ok=duplicate_ok)\n",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 531 |
"\n",
|
| 532 |
" def commit(self, duplicate_ok=True):\n",
|
| 533 |
" self.check_valid(duplicate_ok=duplicate_ok)\n",
|
|
|
|
| 554 |
},
|
| 555 |
{
|
| 556 |
"cell_type": "code",
|
| 557 |
+
"execution_count": 297,
|
| 558 |
"metadata": {},
|
| 559 |
"outputs": [
|
| 560 |
{
|
|
|
|
| 570 |
"True"
|
| 571 |
]
|
| 572 |
},
|
| 573 |
+
"execution_count": 297,
|
| 574 |
"metadata": {},
|
| 575 |
"output_type": "execute_result"
|
| 576 |
}
|
|
|
|
| 585 |
},
|
| 586 |
{
|
| 587 |
"cell_type": "code",
|
| 588 |
+
"execution_count": 298,
|
| 589 |
"metadata": {},
|
| 590 |
"outputs": [
|
| 591 |
{
|
|
|
|
| 594 |
"True"
|
| 595 |
]
|
| 596 |
},
|
| 597 |
+
"execution_count": 298,
|
| 598 |
"metadata": {},
|
| 599 |
"output_type": "execute_result"
|
| 600 |
}
|
|
|
|
| 609 |
},
|
| 610 |
{
|
| 611 |
"cell_type": "code",
|
| 612 |
+
"execution_count": 299,
|
| 613 |
"metadata": {},
|
| 614 |
"outputs": [
|
| 615 |
{
|
|
|
|
| 628 |
" 'rahuketu@gmail.com']"
|
| 629 |
]
|
| 630 |
},
|
| 631 |
+
"execution_count": 299,
|
| 632 |
"metadata": {},
|
| 633 |
"output_type": "execute_result"
|
| 634 |
}
|
|
|
|
| 639 |
},
|
| 640 |
{
|
| 641 |
"cell_type": "code",
|
| 642 |
+
"execution_count": 300,
|
| 643 |
"metadata": {},
|
| 644 |
"outputs": [
|
| 645 |
{
|
|
|
|
| 648 |
"Contact[[None, None], [None, None], [None, None], [None, None], [True, '']]"
|
| 649 |
]
|
| 650 |
},
|
| 651 |
+
"execution_count": 300,
|
| 652 |
"metadata": {},
|
| 653 |
"output_type": "execute_result"
|
| 654 |
}
|
|
|
|
| 659 |
},
|
| 660 |
{
|
| 661 |
"cell_type": "code",
|
| 662 |
+
"execution_count": 301,
|
| 663 |
"metadata": {},
|
| 664 |
"outputs": [
|
| 665 |
{
|
|
|
|
| 675 |
"True"
|
| 676 |
]
|
| 677 |
},
|
| 678 |
+
"execution_count": 301,
|
| 679 |
"metadata": {},
|
| 680 |
"output_type": "execute_result"
|
| 681 |
}
|
|
|
|
| 692 |
},
|
| 693 |
{
|
| 694 |
"cell_type": "code",
|
| 695 |
+
"execution_count": 302,
|
| 696 |
"metadata": {},
|
| 697 |
"outputs": [],
|
| 698 |
"source": [
|
|
|
|
| 703 |
},
|
| 704 |
{
|
| 705 |
"cell_type": "code",
|
| 706 |
+
"execution_count": 303,
|
| 707 |
"metadata": {},
|
| 708 |
"outputs": [
|
| 709 |
{
|
|
|
|
| 761 |
" 'id': 10}]"
|
| 762 |
]
|
| 763 |
},
|
| 764 |
+
"execution_count": 303,
|
| 765 |
"metadata": {},
|
| 766 |
"output_type": "execute_result"
|
| 767 |
}
|
|
|
|
| 780 |
},
|
| 781 |
{
|
| 782 |
"cell_type": "code",
|
| 783 |
+
"execution_count": 304,
|
| 784 |
"metadata": {},
|
| 785 |
"outputs": [
|
| 786 |
{
|
|
|
|
| 793 |
" 'id': 1}"
|
| 794 |
]
|
| 795 |
},
|
| 796 |
+
"execution_count": 304,
|
| 797 |
"metadata": {},
|
| 798 |
"output_type": "execute_result"
|
| 799 |
}
|
|
|
|
| 805 |
},
|
| 806 |
{
|
| 807 |
"cell_type": "code",
|
| 808 |
+
"execution_count": 305,
|
| 809 |
"metadata": {},
|
| 810 |
"outputs": [
|
| 811 |
{
|
|
|
|
| 818 |
" 'id': 2}"
|
| 819 |
]
|
| 820 |
},
|
| 821 |
+
"execution_count": 305,
|
| 822 |
"metadata": {},
|
| 823 |
"output_type": "execute_result"
|
| 824 |
}
|
|
|
|
| 829 |
},
|
| 830 |
{
|
| 831 |
"cell_type": "code",
|
| 832 |
+
"execution_count": 306,
|
| 833 |
"metadata": {},
|
| 834 |
"outputs": [],
|
| 835 |
"source": [
|
01_main.ipynb
CHANGED
|
@@ -9,7 +9,7 @@
|
|
| 9 |
},
|
| 10 |
{
|
| 11 |
"cell_type": "code",
|
| 12 |
-
"execution_count":
|
| 13 |
"metadata": {},
|
| 14 |
"outputs": [
|
| 15 |
{
|
|
@@ -28,7 +28,7 @@
|
|
| 28 |
},
|
| 29 |
{
|
| 30 |
"cell_type": "code",
|
| 31 |
-
"execution_count":
|
| 32 |
"metadata": {},
|
| 33 |
"outputs": [],
|
| 34 |
"source": [
|
|
@@ -41,7 +41,7 @@
|
|
| 41 |
},
|
| 42 |
{
|
| 43 |
"cell_type": "code",
|
| 44 |
-
"execution_count":
|
| 45 |
"metadata": {},
|
| 46 |
"outputs": [],
|
| 47 |
"source": [
|
|
@@ -51,7 +51,7 @@
|
|
| 51 |
},
|
| 52 |
{
|
| 53 |
"cell_type": "code",
|
| 54 |
-
"execution_count":
|
| 55 |
"metadata": {},
|
| 56 |
"outputs": [],
|
| 57 |
"source": [
|
|
@@ -62,7 +62,7 @@
|
|
| 62 |
},
|
| 63 |
{
|
| 64 |
"cell_type": "code",
|
| 65 |
-
"execution_count":
|
| 66 |
"metadata": {},
|
| 67 |
"outputs": [],
|
| 68 |
"source": [
|
|
@@ -74,7 +74,7 @@
|
|
| 74 |
},
|
| 75 |
{
|
| 76 |
"cell_type": "code",
|
| 77 |
-
"execution_count":
|
| 78 |
"metadata": {},
|
| 79 |
"outputs": [],
|
| 80 |
"source": [
|
|
@@ -90,7 +90,7 @@
|
|
| 90 |
},
|
| 91 |
{
|
| 92 |
"cell_type": "code",
|
| 93 |
-
"execution_count":
|
| 94 |
"metadata": {},
|
| 95 |
"outputs": [
|
| 96 |
{
|
|
@@ -103,7 +103,7 @@
|
|
| 103 |
" 'id': 1}"
|
| 104 |
]
|
| 105 |
},
|
| 106 |
-
"execution_count":
|
| 107 |
"metadata": {},
|
| 108 |
"output_type": "execute_result"
|
| 109 |
}
|
|
@@ -115,7 +115,7 @@
|
|
| 115 |
},
|
| 116 |
{
|
| 117 |
"cell_type": "code",
|
| 118 |
-
"execution_count":
|
| 119 |
"metadata": {},
|
| 120 |
"outputs": [],
|
| 121 |
"source": [
|
|
@@ -127,7 +127,7 @@
|
|
| 127 |
},
|
| 128 |
{
|
| 129 |
"cell_type": "code",
|
| 130 |
-
"execution_count":
|
| 131 |
"metadata": {},
|
| 132 |
"outputs": [
|
| 133 |
{
|
|
@@ -173,7 +173,7 @@
|
|
| 173 |
},
|
| 174 |
{
|
| 175 |
"cell_type": "code",
|
| 176 |
-
"execution_count":
|
| 177 |
"metadata": {},
|
| 178 |
"outputs": [
|
| 179 |
{
|
|
@@ -186,7 +186,7 @@
|
|
| 186 |
" 'id': 2}"
|
| 187 |
]
|
| 188 |
},
|
| 189 |
-
"execution_count":
|
| 190 |
"metadata": {},
|
| 191 |
"output_type": "execute_result"
|
| 192 |
}
|
|
@@ -197,7 +197,7 @@
|
|
| 197 |
},
|
| 198 |
{
|
| 199 |
"cell_type": "code",
|
| 200 |
-
"execution_count":
|
| 201 |
"metadata": {},
|
| 202 |
"outputs": [],
|
| 203 |
"source": [
|
|
@@ -218,8 +218,8 @@
|
|
| 218 |
" c.lastname = request.form['lastname']\n",
|
| 219 |
" c.phone=request.form['phone']\n",
|
| 220 |
" c.email=request.form['email']\n",
|
| 221 |
-
" c.check_valid(duplicate_ok=
|
| 222 |
-
" if c.commit(duplicate_ok=
|
| 223 |
" flash(\"Updated Contract\")\n",
|
| 224 |
" return redirect(\"/contacts/\"+str(id))\n",
|
| 225 |
" else: return render_template('edit.html', contact=c)"
|
|
@@ -227,7 +227,7 @@
|
|
| 227 |
},
|
| 228 |
{
|
| 229 |
"cell_type": "code",
|
| 230 |
-
"execution_count":
|
| 231 |
"metadata": {},
|
| 232 |
"outputs": [],
|
| 233 |
"source": [
|
|
@@ -241,7 +241,7 @@
|
|
| 241 |
},
|
| 242 |
{
|
| 243 |
"cell_type": "code",
|
| 244 |
-
"execution_count":
|
| 245 |
"metadata": {},
|
| 246 |
"outputs": [],
|
| 247 |
"source": [
|
|
@@ -255,7 +255,7 @@
|
|
| 255 |
},
|
| 256 |
{
|
| 257 |
"cell_type": "code",
|
| 258 |
-
"execution_count":
|
| 259 |
"metadata": {},
|
| 260 |
"outputs": [],
|
| 261 |
"source": [
|
|
@@ -265,7 +265,7 @@
|
|
| 265 |
},
|
| 266 |
{
|
| 267 |
"cell_type": "code",
|
| 268 |
-
"execution_count":
|
| 269 |
"metadata": {},
|
| 270 |
"outputs": [],
|
| 271 |
"source": [
|
|
@@ -277,7 +277,7 @@
|
|
| 277 |
},
|
| 278 |
{
|
| 279 |
"cell_type": "code",
|
| 280 |
-
"execution_count":
|
| 281 |
"metadata": {},
|
| 282 |
"outputs": [],
|
| 283 |
"source": [
|
|
@@ -299,7 +299,24 @@
|
|
| 299 |
},
|
| 300 |
{
|
| 301 |
"cell_type": "code",
|
| 302 |
-
"execution_count":
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 303 |
"metadata": {},
|
| 304 |
"outputs": [],
|
| 305 |
"source": [
|
|
|
|
| 9 |
},
|
| 10 |
{
|
| 11 |
"cell_type": "code",
|
| 12 |
+
"execution_count": 28,
|
| 13 |
"metadata": {},
|
| 14 |
"outputs": [
|
| 15 |
{
|
|
|
|
| 28 |
},
|
| 29 |
{
|
| 30 |
"cell_type": "code",
|
| 31 |
+
"execution_count": 29,
|
| 32 |
"metadata": {},
|
| 33 |
"outputs": [],
|
| 34 |
"source": [
|
|
|
|
| 41 |
},
|
| 42 |
{
|
| 43 |
"cell_type": "code",
|
| 44 |
+
"execution_count": 30,
|
| 45 |
"metadata": {},
|
| 46 |
"outputs": [],
|
| 47 |
"source": [
|
|
|
|
| 51 |
},
|
| 52 |
{
|
| 53 |
"cell_type": "code",
|
| 54 |
+
"execution_count": 31,
|
| 55 |
"metadata": {},
|
| 56 |
"outputs": [],
|
| 57 |
"source": [
|
|
|
|
| 62 |
},
|
| 63 |
{
|
| 64 |
"cell_type": "code",
|
| 65 |
+
"execution_count": 32,
|
| 66 |
"metadata": {},
|
| 67 |
"outputs": [],
|
| 68 |
"source": [
|
|
|
|
| 74 |
},
|
| 75 |
{
|
| 76 |
"cell_type": "code",
|
| 77 |
+
"execution_count": 33,
|
| 78 |
"metadata": {},
|
| 79 |
"outputs": [],
|
| 80 |
"source": [
|
|
|
|
| 90 |
},
|
| 91 |
{
|
| 92 |
"cell_type": "code",
|
| 93 |
+
"execution_count": 34,
|
| 94 |
"metadata": {},
|
| 95 |
"outputs": [
|
| 96 |
{
|
|
|
|
| 103 |
" 'id': 1}"
|
| 104 |
]
|
| 105 |
},
|
| 106 |
+
"execution_count": 34,
|
| 107 |
"metadata": {},
|
| 108 |
"output_type": "execute_result"
|
| 109 |
}
|
|
|
|
| 115 |
},
|
| 116 |
{
|
| 117 |
"cell_type": "code",
|
| 118 |
+
"execution_count": 35,
|
| 119 |
"metadata": {},
|
| 120 |
"outputs": [],
|
| 121 |
"source": [
|
|
|
|
| 127 |
},
|
| 128 |
{
|
| 129 |
"cell_type": "code",
|
| 130 |
+
"execution_count": 36,
|
| 131 |
"metadata": {},
|
| 132 |
"outputs": [
|
| 133 |
{
|
|
|
|
| 173 |
},
|
| 174 |
{
|
| 175 |
"cell_type": "code",
|
| 176 |
+
"execution_count": 37,
|
| 177 |
"metadata": {},
|
| 178 |
"outputs": [
|
| 179 |
{
|
|
|
|
| 186 |
" 'id': 2}"
|
| 187 |
]
|
| 188 |
},
|
| 189 |
+
"execution_count": 37,
|
| 190 |
"metadata": {},
|
| 191 |
"output_type": "execute_result"
|
| 192 |
}
|
|
|
|
| 197 |
},
|
| 198 |
{
|
| 199 |
"cell_type": "code",
|
| 200 |
+
"execution_count": 38,
|
| 201 |
"metadata": {},
|
| 202 |
"outputs": [],
|
| 203 |
"source": [
|
|
|
|
| 218 |
" c.lastname = request.form['lastname']\n",
|
| 219 |
" c.phone=request.form['phone']\n",
|
| 220 |
" c.email=request.form['email']\n",
|
| 221 |
+
" c.check_valid(duplicate_ok=False)\n",
|
| 222 |
+
" if c.commit(duplicate_ok=False):\n",
|
| 223 |
" flash(\"Updated Contract\")\n",
|
| 224 |
" return redirect(\"/contacts/\"+str(id))\n",
|
| 225 |
" else: return render_template('edit.html', contact=c)"
|
|
|
|
| 227 |
},
|
| 228 |
{
|
| 229 |
"cell_type": "code",
|
| 230 |
+
"execution_count": 39,
|
| 231 |
"metadata": {},
|
| 232 |
"outputs": [],
|
| 233 |
"source": [
|
|
|
|
| 241 |
},
|
| 242 |
{
|
| 243 |
"cell_type": "code",
|
| 244 |
+
"execution_count": 40,
|
| 245 |
"metadata": {},
|
| 246 |
"outputs": [],
|
| 247 |
"source": [
|
|
|
|
| 255 |
},
|
| 256 |
{
|
| 257 |
"cell_type": "code",
|
| 258 |
+
"execution_count": 41,
|
| 259 |
"metadata": {},
|
| 260 |
"outputs": [],
|
| 261 |
"source": [
|
|
|
|
| 265 |
},
|
| 266 |
{
|
| 267 |
"cell_type": "code",
|
| 268 |
+
"execution_count": 42,
|
| 269 |
"metadata": {},
|
| 270 |
"outputs": [],
|
| 271 |
"source": [
|
|
|
|
| 277 |
},
|
| 278 |
{
|
| 279 |
"cell_type": "code",
|
| 280 |
+
"execution_count": 43,
|
| 281 |
"metadata": {},
|
| 282 |
"outputs": [],
|
| 283 |
"source": [
|
|
|
|
| 299 |
},
|
| 300 |
{
|
| 301 |
"cell_type": "code",
|
| 302 |
+
"execution_count": 44,
|
| 303 |
+
"metadata": {},
|
| 304 |
+
"outputs": [],
|
| 305 |
+
"source": [
|
| 306 |
+
"#|export\n",
|
| 307 |
+
"@app.get(\"/contacts/<int:id>/email\")\n",
|
| 308 |
+
"def contact_email_get(id:int=0):\n",
|
| 309 |
+
" c_dict = Contacts().get(id)\n",
|
| 310 |
+
" c = Contact()\n",
|
| 311 |
+
" c.from_contacts_dict(c_dict, validate=False)\n",
|
| 312 |
+
" c.email = request.arg.get('email')\n",
|
| 313 |
+
" c.validate_contact_email(duplicate_ok=False)\n",
|
| 314 |
+
" return c.errors.email"
|
| 315 |
+
]
|
| 316 |
+
},
|
| 317 |
+
{
|
| 318 |
+
"cell_type": "code",
|
| 319 |
+
"execution_count": 46,
|
| 320 |
"metadata": {},
|
| 321 |
"outputs": [],
|
| 322 |
"source": [
|
__pycache__/datamodel.cpython-312.pyc
CHANGED
|
Binary files a/__pycache__/datamodel.cpython-312.pyc and b/__pycache__/datamodel.cpython-312.pyc differ
|
|
|
__pycache__/main.cpython-312.pyc
CHANGED
|
Binary files a/__pycache__/main.cpython-312.pyc and b/__pycache__/main.cpython-312.pyc differ
|
|
|
contactdb.json
CHANGED
|
@@ -1 +1 @@
|
|
| 1 |
-
[{"firstname":"
|
|
|
|
| 1 |
+
[{"firstname":"Jane","lastname":"Smith","phone":"555-5678","email":"jane.smith@example.com","id":1},{"firstname":"Alice","lastname":"Johnson","phone":"555-8765","email":"alice.johnson@example.com","id":2},{"firstname":"Bob","lastname":"Williams","phone":"555-4321","email":"bob.williams@example.com","id":3},{"firstname":"Charlie","lastname":"Brown","phone":"555-9876","email":"charlie.brown@example.com","id":4},{"firstname":"Diana","lastname":"Miller","phone":"555-6543","email":"diana.miller@example.com","id":5},{"firstname":"Edward","lastname":"Davis","phone":"555-3456","email":"edward.davis@example.com","id":6},{"firstname":"Fiona","lastname":"Garcia","phone":"555-6789","email":"fiona.garcia@example.com","id":7},{"firstname":"George","lastname":"Martinez","phone":"555-7890","email":"george.martinez@example.com","id":8},{"firstname":"Hannah","lastname":"Rodriguez","phone":"555-8901","email":"hannah.rodriguez@example.com","id":9}]
|
datamodel.py
CHANGED
|
@@ -100,13 +100,28 @@ class Contact:
|
|
| 100 |
errors:ContactErrors = field(default_factory=lambda: ContactErrors())
|
| 101 |
is_valid:bool=True
|
| 102 |
|
| 103 |
-
def
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 104 |
self.firstname = c['firstname']
|
| 105 |
self.lastname = c['lastname']
|
| 106 |
self.phone = c['phone']
|
| 107 |
self.email = c['email']
|
| 108 |
self.id = c['id']
|
| 109 |
-
|
|
|
|
| 110 |
|
| 111 |
def check_valid(self, duplicate_ok=False):
|
| 112 |
self.is_valid = True
|
|
@@ -126,17 +141,7 @@ class Contact:
|
|
| 126 |
self.errors.phone= "Format phone not correct"
|
| 127 |
else: pass
|
| 128 |
|
| 129 |
-
|
| 130 |
-
self.is_valid = False
|
| 131 |
-
self.errors.email= "Email is empty"
|
| 132 |
-
elif not validate_email(self.email):
|
| 133 |
-
self.is_valid = False
|
| 134 |
-
self.errors.email= "Format email not correct"
|
| 135 |
-
elif not duplicate_ok:
|
| 136 |
-
if check_duplicates(self.email, Contacts().get_emails()):
|
| 137 |
-
self.is_valid = False
|
| 138 |
-
self.errors.email= "Duplicated email"
|
| 139 |
-
else: pass
|
| 140 |
|
| 141 |
def commit(self, duplicate_ok=True):
|
| 142 |
self.check_valid(duplicate_ok=duplicate_ok)
|
|
|
|
| 100 |
errors:ContactErrors = field(default_factory=lambda: ContactErrors())
|
| 101 |
is_valid:bool=True
|
| 102 |
|
| 103 |
+
def validate_contact_email(self, duplicate_ok):
|
| 104 |
+
if self.email is None or self.email == "":
|
| 105 |
+
self.is_valid = False
|
| 106 |
+
self.errors.email= "Email is empty"
|
| 107 |
+
elif not validate_email(self.email):
|
| 108 |
+
self.is_valid = False
|
| 109 |
+
self.errors.email= "Format email not correct"
|
| 110 |
+
elif not duplicate_ok:
|
| 111 |
+
if check_duplicates(self.email, Contacts().get_emails()):
|
| 112 |
+
self.is_valid = False
|
| 113 |
+
self.errors.email= "Duplicated email"
|
| 114 |
+
else: pass
|
| 115 |
+
|
| 116 |
+
|
| 117 |
+
def from_contacts_dict(self, c, validate=True, duplicate_ok=True):
|
| 118 |
self.firstname = c['firstname']
|
| 119 |
self.lastname = c['lastname']
|
| 120 |
self.phone = c['phone']
|
| 121 |
self.email = c['email']
|
| 122 |
self.id = c['id']
|
| 123 |
+
if validate:
|
| 124 |
+
self.check_valid(duplicate_ok=duplicate_ok)
|
| 125 |
|
| 126 |
def check_valid(self, duplicate_ok=False):
|
| 127 |
self.is_valid = True
|
|
|
|
| 141 |
self.errors.phone= "Format phone not correct"
|
| 142 |
else: pass
|
| 143 |
|
| 144 |
+
self.validate_contact_email(duplicate_ok=duplicate_ok)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 145 |
|
| 146 |
def commit(self, duplicate_ok=True):
|
| 147 |
self.check_valid(duplicate_ok=duplicate_ok)
|
main.py
CHANGED
|
@@ -1,7 +1,8 @@
|
|
| 1 |
# AUTOGENERATED! DO NOT EDIT! File to edit: 01_main.ipynb.
|
| 2 |
|
| 3 |
# %% auto 0
|
| 4 |
-
__all__ = ['app', 'index', 'contacts', 'view', 'edit', 'delete', 'delete_htmx', 'contact_new_get', 'contact_new'
|
|
|
|
| 5 |
|
| 6 |
# %% 01_main.ipynb 2
|
| 7 |
import pandas as pd
|
|
@@ -50,8 +51,8 @@ def edit(id):
|
|
| 50 |
c.lastname = request.form['lastname']
|
| 51 |
c.phone=request.form['phone']
|
| 52 |
c.email=request.form['email']
|
| 53 |
-
c.check_valid(duplicate_ok=
|
| 54 |
-
if c.commit(duplicate_ok=
|
| 55 |
flash("Updated Contract")
|
| 56 |
return redirect("/contacts/"+str(id))
|
| 57 |
else: return render_template('edit.html', contact=c)
|
|
@@ -89,3 +90,13 @@ def contact_new():
|
|
| 89 |
else:
|
| 90 |
print(c)
|
| 91 |
return render_template('new.html', contact=c)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
# AUTOGENERATED! DO NOT EDIT! File to edit: 01_main.ipynb.
|
| 2 |
|
| 3 |
# %% auto 0
|
| 4 |
+
__all__ = ['app', 'index', 'contacts', 'view', 'edit', 'delete', 'delete_htmx', 'contact_new_get', 'contact_new',
|
| 5 |
+
'contact_email_get']
|
| 6 |
|
| 7 |
# %% 01_main.ipynb 2
|
| 8 |
import pandas as pd
|
|
|
|
| 51 |
c.lastname = request.form['lastname']
|
| 52 |
c.phone=request.form['phone']
|
| 53 |
c.email=request.form['email']
|
| 54 |
+
c.check_valid(duplicate_ok=False)
|
| 55 |
+
if c.commit(duplicate_ok=False):
|
| 56 |
flash("Updated Contract")
|
| 57 |
return redirect("/contacts/"+str(id))
|
| 58 |
else: return render_template('edit.html', contact=c)
|
|
|
|
| 90 |
else:
|
| 91 |
print(c)
|
| 92 |
return render_template('new.html', contact=c)
|
| 93 |
+
|
| 94 |
+
# %% 01_main.ipynb 17
|
| 95 |
+
@app.get("/contacts/<int:id>/email")
|
| 96 |
+
def contact_email_get(id:int=0):
|
| 97 |
+
c_dict = Contacts().get(id)
|
| 98 |
+
c = Contact()
|
| 99 |
+
c.from_contacts_dict(c_dict, validate=False)
|
| 100 |
+
c.email = request.arg.get('email')
|
| 101 |
+
c.validate_contact_email(duplicate_ok=False)
|
| 102 |
+
return c.errors.email
|
templates/edit.html
CHANGED
|
@@ -6,7 +6,10 @@
|
|
| 6 |
<legend>Contact Values</legend>
|
| 7 |
<p>
|
| 8 |
<label for="email">Email</label>
|
| 9 |
-
<input name="email" id="email" type="email"
|
|
|
|
|
|
|
|
|
|
| 10 |
{% if contact.errors.email %}
|
| 11 |
<span class="error">{{ contact.errors.email}}</span>
|
| 12 |
{% endif %}
|
|
|
|
| 6 |
<legend>Contact Values</legend>
|
| 7 |
<p>
|
| 8 |
<label for="email">Email</label>
|
| 9 |
+
<input name="email" id="email" type="email"
|
| 10 |
+
hx-get="'/contacts/{{contact.id}}/email"
|
| 11 |
+
hx-target="next .error"
|
| 12 |
+
placeholder="Email" value="{{contact.email or ''}}">
|
| 13 |
{% if contact.errors.email %}
|
| 14 |
<span class="error">{{ contact.errors.email}}</span>
|
| 15 |
{% endif %}
|
templates/new.html
CHANGED
|
@@ -6,7 +6,10 @@
|
|
| 6 |
<legend>Contact Values</legend>
|
| 7 |
<p>
|
| 8 |
<label for="email">Email</label>
|
| 9 |
-
<input name="email" id="email" type="email"
|
|
|
|
|
|
|
|
|
|
| 10 |
{% if contact.errors.email %}
|
| 11 |
<span class="error">{{ contact.errors.email}}</span>
|
| 12 |
{% endif %}
|
|
|
|
| 6 |
<legend>Contact Values</legend>
|
| 7 |
<p>
|
| 8 |
<label for="email">Email</label>
|
| 9 |
+
<input name="email" id="email" type="email"
|
| 10 |
+
hx-get="'/contacts/{{contact.id}}/email"
|
| 11 |
+
hx-target="next .error"
|
| 12 |
+
placeholder="Email" value="{{contact.email or ''}}">
|
| 13 |
{% if contact.errors.email %}
|
| 14 |
<span class="error">{{ contact.errors.email}}</span>
|
| 15 |
{% endif %}
|