├── .gitignore ├── LICENSE ├── README.md ├── notekeeper ├── accounts │ ├── __init__.py │ ├── admin.py │ ├── apps.py │ ├── migrations │ │ └── __init__.py │ ├── models.py │ ├── static │ │ ├── css │ │ │ ├── b4_sidebar.css │ │ │ ├── custom.css │ │ │ └── tagsinput.css │ │ ├── img │ │ │ └── logo.png │ │ └── js │ │ │ ├── b4_sidebar.js │ │ │ └── tagsinput.js │ ├── templates │ │ ├── base.html │ │ ├── change_password.html │ │ ├── index.html │ │ ├── messages.html │ │ ├── navbar.html │ │ ├── registration │ │ │ └── login.html │ │ ├── registration_base.html │ │ └── signup.html │ ├── templatetags │ │ ├── active.py │ │ └── tags.py │ ├── tests.py │ └── views.py ├── manage.py ├── notekeeper │ ├── __init__.py │ ├── settings.py │ ├── urls.py │ └── wsgi.py └── notes │ ├── __init__.py │ ├── admin.py │ ├── apps.py │ ├── migrations │ ├── 0001_initial.py │ ├── 0002_auto_20191127_1317.py │ ├── 0003_auto_20191202_1846.py │ ├── 0004_auto_20191202_1919.py │ ├── 0005_auto_20200222_0823.py │ ├── 0006_auto_20200222_0837.py │ ├── 0007_auto_20200222_0845.py │ ├── 0008_auto_20200308_1804.py │ ├── 0009_auto_20200310_1516.py │ └── __init__.py │ ├── models.py │ ├── templates │ ├── modals │ │ ├── delete_note_modal.html │ │ └── edit_note_modal.html │ ├── note_as_pdf.html │ ├── note_details.html │ ├── notes.html │ ├── shared_note.html │ └── tags.html │ ├── templatetags │ ├── active.py │ └── tags.py │ ├── tests.py │ ├── urls.py │ └── views.py ├── requirements.txt └── results └── working.gif /.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | *$py.class 5 | 6 | # C extensions 7 | *.so 8 | *.vscode 9 | 10 | # Distribution / packaging 11 | .Python 12 | build/ 13 | develop-eggs/ 14 | dist/ 15 | downloads/ 16 | eggs/ 17 | .eggs/ 18 | lib/ 19 | lib64/ 20 | parts/ 21 | sdist/ 22 | var/ 23 | wheels/ 24 | *.egg-info/ 25 | .installed.cfg 26 | *.egg 27 | MANIFEST 28 | 29 | # PyInstaller 30 | # Usually these files are written by a python script from a template 31 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 32 | *.manifest 33 | *.spec 34 | 35 | # Installer logs 36 | pip-log.txt 37 | pip-delete-this-directory.txt 38 | 39 | # Unit test / coverage reports 40 | htmlcov/ 41 | .tox/ 42 | .coverage 43 | .coverage.* 44 | .cache 45 | nosetests.xml 46 | coverage.xml 47 | *.cover 48 | .hypothesis/ 49 | .pytest_cache/ 50 | 51 | # Translations 52 | *.mo 53 | *.pot 54 | 55 | # Django stuff: 56 | *.log 57 | local_settings.py 58 | db.sqlite3 59 | media/ 60 | 61 | # Flask stuff: 62 | instance/ 63 | .webassets-cache 64 | 65 | # Scrapy stuff: 66 | .scrapy 67 | 68 | # Sphinx documentation 69 | docs/_build/ 70 | 71 | # PyBuilder 72 | target/ 73 | 74 | # Jupyter Notebook 75 | .ipynb_checkpoints 76 | 77 | # pyenv 78 | .python-version 79 | 80 | # celery beat schedule file 81 | celerybeat-schedule 82 | 83 | # SageMath parsed files 84 | *.sage.py 85 | 86 | # Environments 87 | .env 88 | .venv 89 | env/ 90 | venv/ 91 | ENV/ 92 | env.bak/ 93 | venv.bak/ 94 | 95 | # Spyder project settings 96 | .spyderproject 97 | .spyproject 98 | 99 | # Rope project settings 100 | .ropeproject 101 | 102 | # mkdocs documentation 103 | /site 104 | 105 | # mypy 106 | .mypy_cache/ 107 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 Omkar Pathak 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # django-notekeeper 2 | A pretty easy django notes app. Have a note save it! 3 | 4 | ### Built with :heart: and :coffee: by [`Omkar Pathak`](http://www.omkarpathak.in/) 5 | 6 | ## Features 7 | 8 | - CRUD notes 9 | - Copies selected text automatically 10 | - Easily share 11 | - Download note as PDF 12 | - Beautiful yet simple UI 13 | - Encrypted Data so that no one can phish it! ([using django-cryptography](https://github.com/georgemarshall/django-cryptography)) 14 | 15 | # Installation 16 | 17 | - Clone the repository 18 | 19 | ```bash 20 | git clone https://github.com/OmkarPathak/django-notekeeper.git 21 | ``` 22 | 23 | - Install Dependencies 24 | 25 | ```bash 26 | cd django-notekeeper 27 | pip install -r requirements.txt 28 | ``` 29 | 30 | - Create a file names `.env` in the folder where your `settings.py` file is present. Enter following information in your .env file 31 | 32 | ``` 33 | SECRET_KEY= 34 | ``` 35 | 36 | - Run django migrations 37 | 38 | ```bash 39 | python manage.py migrate 40 | ``` 41 | 42 | - Run django server 43 | 44 | ```bash 45 | python manage.py runserver 46 | ``` 47 | 48 | # Working 49 | 50 | ![working](results/working.gif) 51 | 52 | # Encryption of all your note contents 53 | 54 | ![Imgur](https://i.imgur.com/aADlcho.png) 55 | 56 | # Donation 57 | 58 | If you have found my softwares to be of any use to you, do consider helping me pay my internet bills. This would encourage me to create many such softwares :) 59 | 60 | | PayPal | Donate via PayPal! | 61 | |:-------------------------------------------:|:-------------------------------------------------------------:| 62 | | ₹ (INR) | Donate via Instamojo | 63 | -------------------------------------------------------------------------------- /notekeeper/accounts/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OmkarPathak/django-notekeeper/fe08a4368a94b3e443cb286144fadd3e8fad03a4/notekeeper/accounts/__init__.py -------------------------------------------------------------------------------- /notekeeper/accounts/admin.py: -------------------------------------------------------------------------------- 1 | from django.contrib import admin 2 | 3 | # Register your models here. 4 | -------------------------------------------------------------------------------- /notekeeper/accounts/apps.py: -------------------------------------------------------------------------------- 1 | from django.apps import AppConfig 2 | 3 | 4 | class AccountsConfig(AppConfig): 5 | name = 'accounts' 6 | -------------------------------------------------------------------------------- /notekeeper/accounts/migrations/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OmkarPathak/django-notekeeper/fe08a4368a94b3e443cb286144fadd3e8fad03a4/notekeeper/accounts/migrations/__init__.py -------------------------------------------------------------------------------- /notekeeper/accounts/models.py: -------------------------------------------------------------------------------- 1 | from django.db import models 2 | from django.contrib.auth.forms import UserCreationForm 3 | from django import forms 4 | from django.contrib.auth.models import User 5 | 6 | # Create your models here. 7 | class SignUpForm(UserCreationForm): 8 | first_name = forms.CharField(max_length=32) 9 | last_name = forms.CharField(max_length=32) 10 | email = forms.EmailField(max_length=64) 11 | 12 | class Meta(UserCreationForm.Meta): 13 | model = User 14 | fields = UserCreationForm.Meta.fields + ('first_name', 'last_name', 'email',) 15 | 16 | def save(self, commit=True): 17 | user = super(SignUpForm, self).save(commit=False) 18 | user.first_name = self.cleaned_data["first_name"] 19 | user.last_name = self.cleaned_data["last_name"] 20 | user.email = self.cleaned_data["email"] 21 | if commit: 22 | user.save() 23 | return user -------------------------------------------------------------------------------- /notekeeper/accounts/static/css/b4_sidebar.css: -------------------------------------------------------------------------------- 1 | body{position:relative}.overlay,.sideMenu{position:fixed;bottom:0}.overlay{top:0;left:-100%;right:100%;margin:auto;background-color:rgba(0,0,0,.5);z-index:998;transition:all ease 0.2s}.overlay.open{left:0;right:0}.sidebarNavigation{margin-bottom:0;z-index:999;justify-content:flex-start}.sidebarNavigation .leftNavbarToggler{margin-right:10px;order:-1}.sideMenu{left:-100%;top:52px;transition:all ease 0.5s;overflow:hidden;width:100%;z-index:999;max-width:80%;margin-bottom:0;padding:1rem}.sideMenu.open{left:0;display:block;overflow-y:auto}.sideMenu ul{margin:0;padding:0 15px} 2 | 3 | #sidebar { 4 | width: inherit; 5 | min-width: 300px; 6 | max-width: 300px; 7 | background-color:#f5f5f5; 8 | float: left; 9 | height:100vh; 10 | position:relative; 11 | overflow-y:auto; 12 | overflow-x:hidden; 13 | } 14 | 15 | #main { 16 | height:100%; 17 | overflow:auto; 18 | } 19 | 20 | /* 21 | * off Canvas sidebar 22 | * -------------------------------------------------- 23 | */ 24 | @media screen and (max-width: 768px) { 25 | .row-offcanvas { 26 | position: relative; 27 | -webkit-transition: all 0.25s ease-out; 28 | -moz-transition: all 0.25s ease-out; 29 | transition: all 0.25s ease-out; 30 | width:calc(100% + 300px); 31 | } 32 | 33 | .row-offcanvas-left 34 | { 35 | left: -300px; 36 | } 37 | 38 | .row-offcanvas-left.active { 39 | left: 0; 40 | } 41 | 42 | .sidebar-offcanvas { 43 | position: absolute; 44 | top: 0; 45 | } 46 | } 47 | 48 | .row-offcanvas { 49 | height:100%; 50 | } 51 | 52 | .nav-pills > .nav-item > .nav-link{ 53 | border-radius: 0; 54 | } 55 | 56 | #book_delete{ 57 | display: none; 58 | } 59 | 60 | #book_details:hover #book_delete{ 61 | display: block; 62 | } 63 | 64 | #search_book{ 65 | margin: 0; 66 | padding-bottom: 0; 67 | padding-right: 0; 68 | padding-top: 0; 69 | line-height: 2.5; 70 | border-radius: 0; 71 | } 72 | 73 | .ui-autocomplete { 74 | position: absolute; 75 | top: 0; 76 | left: 0; 77 | right: 0; 78 | z-index: 1; 79 | float: left; 80 | display: none; 81 | padding: 4px 0; 82 | list-style: none; 83 | background-color: #ffffff; 84 | border-color: #ccc; 85 | border-color: rgba(0, 0, 0, 0.2); 86 | border-style: solid; 87 | border-width: 1px; 88 | -webkit-border-radius: 5px; 89 | -moz-border-radius: 5px; 90 | border-radius: 0; 91 | -webkit-box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2); 92 | -moz-box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2); 93 | box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2); 94 | -webkit-background-clip: padding-box; 95 | -moz-background-clip: padding; 96 | background-clip: padding-box; 97 | *border-right-width: 2px; 98 | *border-bottom-width: 2px; 99 | max-width: 265px; 100 | } 101 | 102 | .ui-menu-item > a.ui-corner-all { 103 | display: block; 104 | padding: 3px 15px; 105 | clear: both; 106 | font-weight: normal; 107 | line-height: 18px; 108 | color: #555555; 109 | white-space: nowrap; 110 | text-decoration: none; 111 | } 112 | 113 | .ui-state-hover, .ui-state-active { 114 | color: #ffffff; 115 | text-decoration: none; 116 | background-color: #0088cc; 117 | border-radius: 0px; 118 | -webkit-border-radius: 0px; 119 | -moz-border-radius: 0px; 120 | background-image: none; 121 | } 122 | 123 | #book-homepage .card{ 124 | border-radius: 0px; 125 | box-shadow: 5px 8px 8px gray; 126 | } 127 | 128 | @media only screen and (max-width: 768px){ 129 | .col-sm-12{ 130 | margin-bottom: 5%; 131 | } 132 | } -------------------------------------------------------------------------------- /notekeeper/accounts/static/css/custom.css: -------------------------------------------------------------------------------- 1 | #sidebar{ 2 | background-color: #f5f5f5; 3 | padding-top: 1%; 4 | } 5 | .ui-menu-item 6 | { 7 | width:100%; 8 | white-space: nowrap; 9 | overflow: hidden; 10 | text-overflow: ellipsis; 11 | } 12 | .leftNavbarToggler{ 13 | margin-right:10px; 14 | order:-1 15 | } 16 | .nav-pills > .nav-item > .nav-link{ 17 | border-radius: 0; 18 | } 19 | .card { 20 | /* Add shadows to create the "card" effect */ 21 | box-shadow: 0 4px 4px 0 rgba(0,0,0,0.2); 22 | transition: 0.3s; 23 | } 24 | /* On mouse-over, add a deeper shadow */ 25 | .card:hover { 26 | box-shadow: 0 8px 16px 0 rgba(0,0,0,0.2); 27 | } 28 | 29 | #note_details{ 30 | border-bottom: 0.1px solid lightgray; 31 | } 32 | 33 | /* remove modal border */ 34 | .modal-content { 35 | -webkit-border-radius: 0px !important; 36 | -moz-border-radius: 0px !important; 37 | border-radius: 0px !important; 38 | } 39 | 40 | .asteriskField{ 41 | color: red; 42 | } 43 | 44 | /* Absolute Center Spinner */ 45 | .loader { 46 | position: fixed; 47 | z-index: 999; 48 | height: 2em; 49 | width: 2em; 50 | overflow: visible; 51 | margin: auto; 52 | top: 0; 53 | left: 0; 54 | bottom: 0; 55 | right: 0; 56 | } 57 | 58 | /* Transparent Overlay */ 59 | .loader:before { 60 | content: ''; 61 | display: block; 62 | position: fixed; 63 | top: 0; 64 | left: 0; 65 | width: 100%; 66 | height: 100%; 67 | background-color: rgba(0,0,0,0.3); 68 | } 69 | 70 | /* :not(:required) hides these rules from IE9 and below */ 71 | .loader:not(:required) { 72 | /* hide "loader..." text */ 73 | font: 0/0 a; 74 | color: transparent; 75 | text-shadow: none; 76 | background-color: transparent; 77 | border: 0; 78 | } 79 | 80 | .loader:not(:required):after { 81 | content: ''; 82 | display: block; 83 | font-size: 10px; 84 | width: 1em; 85 | height: 1em; 86 | margin-top: -0.5em; 87 | -webkit-animation: spinner 1500ms infinite linear; 88 | -moz-animation: spinner 1500ms infinite linear; 89 | -ms-animation: spinner 1500ms infinite linear; 90 | -o-animation: spinner 1500ms infinite linear; 91 | animation: spinner 1500ms infinite linear; 92 | border-radius: 0.5em; 93 | -webkit-box-shadow: rgba(0, 0, 0, 0.75) 1.5em 0 0 0, rgba(0, 0, 0, 0.75) 1.1em 1.1em 0 0, rgba(0, 0, 0, 0.75) 0 1.5em 0 0, rgba(0, 0, 0, 0.75) -1.1em 1.1em 0 0, rgba(0, 0, 0, 0.5) -1.5em 0 0 0, rgba(0, 0, 0, 0.5) -1.1em -1.1em 0 0, rgba(0, 0, 0, 0.75) 0 -1.5em 0 0, rgba(0, 0, 0, 0.75) 1.1em -1.1em 0 0; 94 | box-shadow: rgba(0, 0, 0, 0.75) 1.5em 0 0 0, rgba(0, 0, 0, 0.75) 1.1em 1.1em 0 0, rgba(0, 0, 0, 0.75) 0 1.5em 0 0, rgba(0, 0, 0, 0.75) -1.1em 1.1em 0 0, rgba(0, 0, 0, 0.75) -1.5em 0 0 0, rgba(0, 0, 0, 0.75) -1.1em -1.1em 0 0, rgba(0, 0, 0, 0.75) 0 -1.5em 0 0, rgba(0, 0, 0, 0.75) 1.1em -1.1em 0 0; 95 | } 96 | 97 | /* Animation */ 98 | 99 | @-webkit-keyframes spinner { 100 | 0% { 101 | -webkit-transform: rotate(0deg); 102 | -moz-transform: rotate(0deg); 103 | -ms-transform: rotate(0deg); 104 | -o-transform: rotate(0deg); 105 | transform: rotate(0deg); 106 | } 107 | 100% { 108 | -webkit-transform: rotate(360deg); 109 | -moz-transform: rotate(360deg); 110 | -ms-transform: rotate(360deg); 111 | -o-transform: rotate(360deg); 112 | transform: rotate(360deg); 113 | } 114 | } 115 | @-moz-keyframes spinner { 116 | 0% { 117 | -webkit-transform: rotate(0deg); 118 | -moz-transform: rotate(0deg); 119 | -ms-transform: rotate(0deg); 120 | -o-transform: rotate(0deg); 121 | transform: rotate(0deg); 122 | } 123 | 100% { 124 | -webkit-transform: rotate(360deg); 125 | -moz-transform: rotate(360deg); 126 | -ms-transform: rotate(360deg); 127 | -o-transform: rotate(360deg); 128 | transform: rotate(360deg); 129 | } 130 | } 131 | @-o-keyframes spinner { 132 | 0% { 133 | -webkit-transform: rotate(0deg); 134 | -moz-transform: rotate(0deg); 135 | -ms-transform: rotate(0deg); 136 | -o-transform: rotate(0deg); 137 | transform: rotate(0deg); 138 | } 139 | 100% { 140 | -webkit-transform: rotate(360deg); 141 | -moz-transform: rotate(360deg); 142 | -ms-transform: rotate(360deg); 143 | -o-transform: rotate(360deg); 144 | transform: rotate(360deg); 145 | } 146 | } 147 | @keyframes spinner { 148 | 0% { 149 | -webkit-transform: rotate(0deg); 150 | -moz-transform: rotate(0deg); 151 | -ms-transform: rotate(0deg); 152 | -o-transform: rotate(0deg); 153 | transform: rotate(0deg); 154 | } 155 | 100% { 156 | -webkit-transform: rotate(360deg); 157 | -moz-transform: rotate(360deg); 158 | -ms-transform: rotate(360deg); 159 | -o-transform: rotate(360deg); 160 | transform: rotate(360deg); 161 | } 162 | } 163 | .CodeMirror, .CodeMirror-scroll { 164 | min-height: 150px; 165 | } 166 | 167 | .codehilite .hll { background-color: #ffffcc } 168 | .codehilite { background: #f8f8f8; } 169 | .codehilite .c { color: #408080; font-style: italic } /* Comment */ 170 | .codehilite .err { border: 1px solid #FF0000 } /* Error */ 171 | .codehilite .k { color: #008000; font-weight: bold } /* Keyword */ 172 | .codehilite .o { color: #666666 } /* Operator */ 173 | .codehilite .ch { color: #408080; font-style: italic } /* Comment.Hashbang */ 174 | .codehilite .cm { color: #408080; font-style: italic } /* Comment.Multiline */ 175 | .codehilite .cp { color: #BC7A00 } /* Comment.Preproc */ 176 | .codehilite .cpf { color: #408080; font-style: italic } /* Comment.PreprocFile */ 177 | .codehilite .c1 { color: #408080; font-style: italic } /* Comment.Single */ 178 | .codehilite .cs { color: #408080; font-style: italic } /* Comment.Special */ 179 | .codehilite .gd { color: #A00000 } /* Generic.Deleted */ 180 | .codehilite .ge { font-style: italic } /* Generic.Emph */ 181 | .codehilite .gr { color: #FF0000 } /* Generic.Error */ 182 | .codehilite .gh { color: #000080; font-weight: bold } /* Generic.Heading */ 183 | .codehilite .gi { color: #00A000 } /* Generic.Inserted */ 184 | .codehilite .go { color: #888888 } /* Generic.Output */ 185 | .codehilite .gp { color: #000080; font-weight: bold } /* Generic.Prompt */ 186 | .codehilite .gs { font-weight: bold } /* Generic.Strong */ 187 | .codehilite .gu { color: #800080; font-weight: bold } /* Generic.Subheading */ 188 | .codehilite .gt { color: #0044DD } /* Generic.Traceback */ 189 | .codehilite .kc { color: #008000; font-weight: bold } /* Keyword.Constant */ 190 | .codehilite .kd { color: #008000; font-weight: bold } /* Keyword.Declaration */ 191 | .codehilite .kn { color: #008000; font-weight: bold } /* Keyword.Namespace */ 192 | .codehilite .kp { color: #008000 } /* Keyword.Pseudo */ 193 | .codehilite .kr { color: #008000; font-weight: bold } /* Keyword.Reserved */ 194 | .codehilite .kt { color: #B00040 } /* Keyword.Type */ 195 | .codehilite .m { color: #666666 } /* Literal.Number */ 196 | .codehilite .s { color: #BA2121 } /* Literal.String */ 197 | .codehilite .na { color: #7D9029 } /* Name.Attribute */ 198 | .codehilite .nb { color: #008000 } /* Name.Builtin */ 199 | .codehilite .nc { color: #0000FF; font-weight: bold } /* Name.Class */ 200 | .codehilite .no { color: #880000 } /* Name.Constant */ 201 | .codehilite .nd { color: #AA22FF } /* Name.Decorator */ 202 | .codehilite .ni { color: #999999; font-weight: bold } /* Name.Entity */ 203 | .codehilite .ne { color: #D2413A; font-weight: bold } /* Name.Exception */ 204 | .codehilite .nf { color: #0000FF } /* Name.Function */ 205 | .codehilite .nl { color: #A0A000 } /* Name.Label */ 206 | .codehilite .nn { color: #0000FF; font-weight: bold } /* Name.Namespace */ 207 | .codehilite .nt { color: #008000; font-weight: bold } /* Name.Tag */ 208 | .codehilite .nv { color: #19177C } /* Name.Variable */ 209 | .codehilite .ow { color: #AA22FF; font-weight: bold } /* Operator.Word */ 210 | .codehilite .w { color: #bbbbbb } /* Text.Whitespace */ 211 | .codehilite .mb { color: #666666 } /* Literal.Number.Bin */ 212 | .codehilite .mf { color: #666666 } /* Literal.Number.Float */ 213 | .codehilite .mh { color: #666666 } /* Literal.Number.Hex */ 214 | .codehilite .mi { color: #666666 } /* Literal.Number.Integer */ 215 | .codehilite .mo { color: #666666 } /* Literal.Number.Oct */ 216 | .codehilite .sa { color: #BA2121 } /* Literal.String.Affix */ 217 | .codehilite .sb { color: #BA2121 } /* Literal.String.Backtick */ 218 | .codehilite .sc { color: #BA2121 } /* Literal.String.Char */ 219 | .codehilite .dl { color: #BA2121 } /* Literal.String.Delimiter */ 220 | .codehilite .sd { color: #BA2121; font-style: italic } /* Literal.String.Doc */ 221 | .codehilite .s2 { color: #BA2121 } /* Literal.String.Double */ 222 | .codehilite .se { color: #BB6622; font-weight: bold } /* Literal.String.Escape */ 223 | .codehilite .sh { color: #BA2121 } /* Literal.String.Heredoc */ 224 | .codehilite .si { color: #BB6688; font-weight: bold } /* Literal.String.Interpol */ 225 | .codehilite .sx { color: #008000 } /* Literal.String.Other */ 226 | .codehilite .sr { color: #BB6688 } /* Literal.String.Regex */ 227 | .codehilite .s1 { color: #BA2121 } /* Literal.String.Single */ 228 | .codehilite .ss { color: #19177C } /* Literal.String.Symbol */ 229 | .codehilite .bp { color: #008000 } /* Name.Builtin.Pseudo */ 230 | .codehilite .fm { color: #0000FF } /* Name.Function.Magic */ 231 | .codehilite .vc { color: #19177C } /* Name.Variable.Class */ 232 | .codehilite .vg { color: #19177C } /* Name.Variable.Global */ 233 | .codehilite .vi { color: #19177C } /* Name.Variable.Instance */ 234 | .codehilite .vm { color: #19177C } /* Name.Variable.Magic */ 235 | .codehilite .il { color: #666666 } /* Literal.Number.Integer.Long */ 236 | -------------------------------------------------------------------------------- /notekeeper/accounts/static/css/tagsinput.css: -------------------------------------------------------------------------------- 1 | /* 2 | * bootstrap-tagsinput v0.8.0 3 | * 4 | */ 5 | 6 | .bootstrap-tagsinput { 7 | background-color: #fff; 8 | border: 1px solid #ccc; 9 | box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); 10 | display: inline-block; 11 | padding: 4px 6px; 12 | color: #555; 13 | vertical-align: middle; 14 | border-radius: 4px; 15 | width: 100%; 16 | line-height: 22px; 17 | cursor: text; 18 | } 19 | .bootstrap-tagsinput input { 20 | border: none; 21 | box-shadow: none; 22 | outline: none; 23 | background-color: transparent; 24 | padding: 0 6px; 25 | margin: 0; 26 | width: auto; 27 | max-width: inherit; 28 | } 29 | .bootstrap-tagsinput.form-control input::-moz-placeholder { 30 | color: #777; 31 | opacity: 1; 32 | } 33 | .bootstrap-tagsinput.form-control input:-ms-input-placeholder { 34 | color: #777; 35 | } 36 | .bootstrap-tagsinput.form-control input::-webkit-input-placeholder { 37 | color: #777; 38 | } 39 | .bootstrap-tagsinput input:focus { 40 | border: none; 41 | box-shadow: none; 42 | } 43 | .bootstrap-tagsinput .badge { 44 | margin: 2px 0; 45 | padding:5px 8px; 46 | } 47 | .bootstrap-tagsinput .badge [data-role="remove"] { 48 | margin-left: 8px; 49 | cursor: pointer; 50 | } 51 | .bootstrap-tagsinput .badge [data-role="remove"]:after { 52 | content: "×"; 53 | padding: 0px 4px; 54 | background-color:rgba(0, 0, 0, 0.1); 55 | border-radius:50%; 56 | font-size:13px 57 | } 58 | .bootstrap-tagsinput .badge [data-role="remove"]:hover:after { 59 | 60 | background-color:rgba(0, 0, 0, 0.62);} 61 | .bootstrap-tagsinput .badge [data-role="remove"]:hover:active { 62 | box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125); 63 | } 64 | 65 | .tt-menu { 66 | position: absolute; 67 | top: 100%; 68 | left: 0; 69 | z-index: 1000; 70 | display: none; 71 | float: left; 72 | min-width: 160px; 73 | padding: 5px 0; 74 | margin: 2px 0 0; 75 | list-style: none; 76 | font-size: 14px; 77 | background-color: #ffffff; 78 | border: 1px solid #cccccc; 79 | border: 1px solid rgba(0, 0, 0, 0.15); 80 | border-radius: 4px; 81 | -webkit-box-shadow: 0 6px 12px rgba(0, 0, 0, 0.175); 82 | box-shadow: 0 6px 12px rgba(0, 0, 0, 0.175); 83 | background-clip: padding-box; 84 | cursor: pointer; 85 | } 86 | 87 | .tt-suggestion { 88 | display: block; 89 | padding: 3px 20px; 90 | clear: both; 91 | font-weight: normal; 92 | line-height: 1.428571429; 93 | color: #333333; 94 | white-space: nowrap; 95 | } 96 | 97 | .tt-suggestion:hover, 98 | .tt-suggestion:focus { 99 | color: #ffffff; 100 | text-decoration: none; 101 | outline: 0; 102 | background-color: #428bca; 103 | } 104 | -------------------------------------------------------------------------------- /notekeeper/accounts/static/img/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OmkarPathak/django-notekeeper/fe08a4368a94b3e443cb286144fadd3e8fad03a4/notekeeper/accounts/static/img/logo.png -------------------------------------------------------------------------------- /notekeeper/accounts/static/js/b4_sidebar.js: -------------------------------------------------------------------------------- 1 | window.onload=function(){window.jQuery?$(document).ready(function(){$(".sidebarNavigation .navbar-collapse").hide().clone().appendTo("body").removeAttr("class").addClass("sideMenu").show(),$("body").append("
"),$(".sideMenu").addClass($(".sidebarNavigation").attr("data-sidebarClass")),$(".navbar-toggle, .navbar-toggler").on("click",function(){$(".sideMenu, .overlay").toggleClass("open"),$(".overlay").on("click",function(){$(this).removeClass("open"),$(".sideMenu").removeClass("open")})}),$("body").on("click",".sideMenu.open .nav-item",function(){$(this).hasClass("dropdown")||$(".sideMenu, .overlay").toggleClass("open")}),$(window).resize(function(){$(".navbar-toggler").is(":hidden")?$(".sideMenu, .overlay").hide():$(".sideMenu, .overlay").show()})}):console.log("sidebarNavigation Requires jQuery")}; -------------------------------------------------------------------------------- /notekeeper/accounts/static/js/tagsinput.js: -------------------------------------------------------------------------------- 1 | /* 2 | * bootstrap-tagsinput v0.8.0 3 | * 4 | */ 5 | 6 | (function ($) { 7 | "use strict"; 8 | 9 | var defaultOptions = { 10 | tagClass: function(item) { 11 | return 'badge badge-info'; 12 | }, 13 | focusClass: 'focus', 14 | itemValue: function(item) { 15 | return item ? item.toString() : item; 16 | }, 17 | itemText: function(item) { 18 | return this.itemValue(item); 19 | }, 20 | itemTitle: function(item) { 21 | return null; 22 | }, 23 | freeInput: true, 24 | addOnBlur: true, 25 | maxTags: undefined, 26 | maxChars: undefined, 27 | confirmKeys: [13, 44], 28 | delimiter: ',', 29 | delimiterRegex: null, 30 | cancelConfirmKeysOnEmpty: false, 31 | onTagExists: function(item, $tag) { 32 | $tag.hide().fadeIn(); 33 | }, 34 | trimValue: false, 35 | allowDuplicates: false, 36 | triggerChange: true, 37 | editOnBackspace: false 38 | }; 39 | 40 | /** 41 | * Constructor function 42 | */ 43 | function TagsInput(element, options) { 44 | this.isInit = true; 45 | this.itemsArray = []; 46 | 47 | this.$element = $(element); 48 | this.$element.addClass('sr-only'); 49 | 50 | this.isSelect = (element.tagName === 'SELECT'); 51 | this.multiple = (this.isSelect && element.hasAttribute('multiple')); 52 | this.objectItems = options && options.itemValue; 53 | this.placeholderText = element.hasAttribute('placeholder') ? this.$element.attr('placeholder') : ''; 54 | this.inputSize = Math.max(1, this.placeholderText.length); 55 | 56 | this.$container = $('
'); 57 | this.$input = $('').appendTo(this.$container); 58 | 59 | this.$element.before(this.$container); 60 | 61 | this.build(options); 62 | this.isInit = false; 63 | } 64 | 65 | TagsInput.prototype = { 66 | constructor: TagsInput, 67 | 68 | /** 69 | * Adds the given item as a new tag. Pass true to dontPushVal to prevent 70 | * updating the elements val() 71 | */ 72 | add: function(item, dontPushVal, options) { 73 | var self = this; 74 | 75 | if (self.options.maxTags && self.itemsArray.length >= self.options.maxTags) 76 | return; 77 | 78 | // Ignore falsey values, except false 79 | if (item !== false && !item) 80 | return; 81 | 82 | // Trim value 83 | if (typeof item === "string" && self.options.trimValue) { 84 | item = $.trim(item); 85 | } 86 | 87 | // Throw an error when trying to add an object while the itemValue option was not set 88 | if (typeof item === "object" && !self.objectItems) 89 | throw("Can't add objects when itemValue option is not set"); 90 | 91 | // Ignore strings only containg whitespace 92 | if (item.toString().match(/^\s*$/)) 93 | return; 94 | 95 | // If SELECT but not multiple, remove current tag 96 | if (self.isSelect && !self.multiple && self.itemsArray.length > 0) 97 | self.remove(self.itemsArray[0]); 98 | 99 | if (typeof item === "string" && this.$element[0].tagName === 'INPUT') { 100 | var delimiter = (self.options.delimiterRegex) ? self.options.delimiterRegex : self.options.delimiter; 101 | var items = item.split(delimiter); 102 | if (items.length > 1) { 103 | for (var i = 0; i < items.length; i++) { 104 | this.add(items[i], true); 105 | } 106 | 107 | if (!dontPushVal) 108 | self.pushVal(self.options.triggerChange); 109 | return; 110 | } 111 | } 112 | 113 | var itemValue = self.options.itemValue(item), 114 | itemText = self.options.itemText(item), 115 | tagClass = self.options.tagClass(item), 116 | itemTitle = self.options.itemTitle(item); 117 | 118 | // Ignore items allready added 119 | var existing = $.grep(self.itemsArray, function(item) { return self.options.itemValue(item) === itemValue; } )[0]; 120 | if (existing && !self.options.allowDuplicates) { 121 | // Invoke onTagExists 122 | if (self.options.onTagExists) { 123 | var $existingTag = $(".badge", self.$container).filter(function() { return $(this).data("item") === existing; }); 124 | self.options.onTagExists(item, $existingTag); 125 | } 126 | return; 127 | } 128 | 129 | // if length greater than limit 130 | if (self.items().toString().length + item.length + 1 > self.options.maxInputLength) 131 | return; 132 | 133 | // raise beforeItemAdd arg 134 | var beforeItemAddEvent = $.Event('beforeItemAdd', { item: item, cancel: false, options: options}); 135 | self.$element.trigger(beforeItemAddEvent); 136 | if (beforeItemAddEvent.cancel) 137 | return; 138 | 139 | // register item in internal array and map 140 | self.itemsArray.push(item); 141 | 142 | // add a tag element 143 | 144 | var $tag = $('' + htmlEncode(itemText) + ''); 145 | $tag.data('item', item); 146 | self.findInputWrapper().before($tag); 147 | 148 | // Check to see if the tag exists in its raw or uri-encoded form 149 | var optionExists = ( 150 | $('option[value="' + encodeURIComponent(itemValue).replace(/"/g, '\\"') + '"]', self.$element).length || 151 | $('option[value="' + htmlEncode(itemValue).replace(/"/g, '\\"') + '"]', self.$element).length 152 | ); 153 | 154 | // add