diff --git a/.dir-locals.el b/.dir-locals.el index c3aab4f..0aebc24 100644 --- a/.dir-locals.el +++ b/.dir-locals.el @@ -1,8 +1,6 @@ ;;; Directory Local Variables ;;; For more information see (info "(emacs) Directory Variables") -((python-mode - (pyvenv-activate . "~/git_repos/projects/network_inventory/venv/") - (eval progn - (setenv "DJANGO_SETTINGS_MODULE" "network_inventory.settings.local") - (setenv "PYTEST_ADDOPTS" "-n 4 --nomigrations")))) +((eval progn + (setenv "DJANGO_SETTINGS_MODULE" "network_inventory.settings.local") + (setenv "PYTEST_ADDOPTS" "-n 4 --nomigrations")))) diff --git a/.flake8 b/.flake8 index 8a89f61..ea5280d 100644 --- a/.flake8 +++ b/.flake8 @@ -4,5 +4,5 @@ exclude = __init__.py, *cache*, venv/, - manage.py, - network_inventory/settings/* + src/manage.py, + src/network_inventory/settings/* diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml deleted file mode 100644 index 00f7194..0000000 --- a/.github/workflows/codeql.yml +++ /dev/null @@ -1,74 +0,0 @@ -# For most projects, this workflow file will not need changing; you simply need -# to commit it to your repository. -# -# You may wish to alter this file to override the set of languages analyzed, -# or to provide custom queries or build logic. -# -# ******** NOTE ******** -# We have attempted to detect the languages in your repository. Please check -# the `language` matrix defined below to confirm you have the correct set of -# supported CodeQL languages. -# -name: "CodeQL" - -on: - push: - branches: [ "master", "dev" ] - pull_request: - # The branches below must be a subset of the branches above - branches: [ "master", "dev" ] - schedule: - - cron: '27 23 * * 0' - -jobs: - analyze: - name: Analyze - runs-on: ubuntu-latest - permissions: - actions: read - contents: read - security-events: write - - strategy: - fail-fast: false - matrix: - language: [ 'javascript', 'python' ] - # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby' ] - # Learn more about CodeQL language support at https://aka.ms/codeql-docs/language-support - - steps: - - name: Checkout repository - uses: actions/checkout@v3 - - # Initializes the CodeQL tools for scanning. - - name: Initialize CodeQL - uses: github/codeql-action/init@v2 - with: - languages: ${{ matrix.language }} - # If you wish to specify custom queries, you can do so here or in a config file. - # By default, queries listed here will override any specified in a config file. - # Prefix the list here with "+" to use these queries and those in the config file. - - # Details on CodeQL's query packs refer to : https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs - # queries: security-extended,security-and-quality - - - # Autobuild attempts to build any compiled languages (C/C++, C#, Go, or Java). - # If this step fails, then you should remove it and run the build manually (see below) - - name: Autobuild - uses: github/codeql-action/autobuild@v2 - - # ℹī¸ Command-line programs to run using the OS shell. - # 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun - - # If the Autobuild fails above, remove it and uncomment the following three lines. - # modify them (or add more) to build your code if your project, please refer to the EXAMPLE below for guidance. - - # - run: | - # echo "Run, Build Application using script" - # ./location_of_script_within_repo/buildscript.sh - - - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@v2 - with: - category: "/language:${{matrix.language}}" diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 28f92fa..bc3bdcf 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -9,24 +9,15 @@ jobs: tests: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 - - name: Set up Python 3.9 - uses: actions/setup-python@v2 + - uses: actions/checkout@v3 + - uses: cachix/install-nix-action@v18 + - uses: cachix/cachix-action@v12 with: - python-version: 3.9 - - name: Install dependencies + name: networkinventory + authToken: '${{ secrets.CACHIX_AUTH_TOKEN }}' + - name: Test run: | - python -m pip install --upgrade pip - pip install -r requirements/local.txt - - name: Lint with flake8 - run: | - # stop the build if there are Python syntax errors or undefined names - flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics - # exit-zero treats all errors as warnings. The GitHub editor is 127 chars wide - flake8 . --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics - - name: Test with pytest - run: | - pytest -nauto --ds=network_inventory.settings.ram_test --nomigrations + nix flake check -L -j auto publish: # Ensure test job passes before pushing image. @@ -36,13 +27,16 @@ jobs: if: github.event_name == 'push' steps: - - uses: actions/checkout@v2 - - - name: "Remove any .pyc files" - run: find . \( -name __pycache__ -o -name "*.pyc" \) -delete - - - name: Build image - run: docker build . --file Dockerfile --tag $IMAGE_NAME + - uses: actions/checkout@v3 + - uses: cachix/install-nix-action@v18 + - uses: cachix/cachix-action@v12 + with: + name: networkinventory + authToken: '${{ secrets.CACHIX_AUTH_TOKEN }}' + - name: Buid container + run: | + nix build .#container + docker load < result - name: Log into registry run: echo "${{ secrets.GITHUB_TOKEN }}" | docker login ghcr.io -u ${{ github.actor }} --password-stdin diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index fec7449..00ab79f 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -4,6 +4,7 @@ on: pull_request: # The branches below must be a subset of the branches above branches: [ "master", "dev" ] + workflow_dispatch: env: IMAGE_NAME: network_inventory @@ -14,10 +15,10 @@ jobs: steps: - uses: actions/checkout@v3 - uses: cachix/install-nix-action@v18 - - name: Linting + - uses: cachix/cachix-action@v12 + with: + name: networkinventory + authToken: '${{ secrets.CACHIX_AUTH_TOKEN }}' + - name: Test run: | - nix develop --command flake8 . --count --show-source --statistics - - - name: Testing - run: | - nix develop --command pytest --ds=network_inventory.settings.ram_test -nauto --nomigrations --cov=. + nix flake check -L -j auto diff --git a/.gitignore b/.gitignore index e5b8f45..b0ca371 100644 --- a/.gitignore +++ b/.gitignore @@ -175,7 +175,8 @@ migrations/ htmlcov/ .second_run -/static +/src/static .idea/ db_data .direnv +/result diff --git a/Makefile b/Makefile index 684b90d..651eaf3 100644 --- a/Makefile +++ b/Makefile @@ -7,6 +7,7 @@ run: setup ( \ find . -name __pycache__ -o -name "*.pyc" -delete; \ sudo iptables -I INPUT -p tcp --dport 8000 -j ACCEPT; \ + cd src/; \ python manage.py runserver 0.0.0.0:8000; \ ) @@ -14,6 +15,7 @@ run: setup setup: ( \ docker-compose -f docker-compose-development.yml up -d; \ + cd src/; \ if [ -f .second_run ]; then \ sleep 2; \ python manage.py collectstatic --noinput; \ @@ -47,7 +49,6 @@ setup: venv: nix build .#venv -o venv - .PHONY: clean clean: docker-compose -f docker-compose-development.yml down -v @@ -67,12 +68,6 @@ init: python manage.py loaddata network_inventory.yaml; \ ) -.PHONY: test -test: - ( \ - pytest --ds=network_inventory.settings.ram_test -nauto --nomigrations --cov=. --cov-report=html; \ - ) - .PHONY: debug debug: ( \ diff --git a/README.md b/README.md index 5254d12..0d74f6a 100644 --- a/README.md +++ b/README.md @@ -12,26 +12,28 @@ inventory over my various servers and other network equipment. and `DJANGO_SECRET_KEY` variables to something secure. 3. Run `docker-compose up` and connect to http://localhost -### Local Development Setup +## Development Setup -The local setup is mainly intended to run the tests quickly. I recommend that -you use the Docker setup if you want to interact with the website. +There are two ways to work on this project. +For the first one you will need to install the Nix package manager[^1]. +Afterwards you can enter the development environment with `nix develop`. -1. Run `make local` to create the virtual environment for development. - You're now all set to start developing. +For the other way you have to install poetry[^2] and then run `poetry shell` to +enter the virtual environment. -### Docker Development Setup +Please note that I will only use and test the first method. -This is very similar to the production setup with the difference that the image -for the `web` application gets built locally instead of getting pulled from -Dockerhub. +[^1]: https://nixos.org/download.html -1. Run `make` to start the server. You can access it - at http://localhost . You're now all set to start working. -2. If you want to have some example data to work with run the command `make - init` after you successfully run `make`. +[^2]: https://python-poetry.org -#### Environment Variables +After you've entered the development environment with either method you can +start the server with `make`. This will start a PostgreSQL database running +inside a docker container and start the Django development server. +You can then access it in the browser under the FQDN of your computer. E.g. +`mypc.domain.local`. + +## Environment Variables To customise the application in the Docker container you can use environment variables in the docker-compose.yml file. Currently the following variables are diff --git a/core/static/core/js/htmx.js b/core/static/core/js/htmx.js deleted file mode 100644 index 6094f10..0000000 --- a/core/static/core/js/htmx.js +++ /dev/null @@ -1 +0,0 @@ -(function(e,t){if(typeof define==="function"&&define.amd){define([],t)}else{e.htmx=t()}})(typeof self!=="undefined"?self:this,function(){return function(){"use strict";var D={onLoad:t,process:rt,on:N,off:I,trigger:lt,ajax:$t,find:w,findAll:S,closest:O,values:function(e,t){var r=Ot(e,t||"post");return r.values},remove:E,addClass:C,removeClass:R,toggleClass:q,takeClass:L,defineExtension:Qt,removeExtension:er,logAll:b,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,attributesToSettle:["class","style","width","height"],withCredentials:false,timeout:0,wsReconnectDelay:"full-jitter",disableSelector:"[hx-disable], [data-hx-disable]",useTemplateFragments:false,scrollBehavior:"smooth"},parseInterval:h,_:e,createEventSource:function(e){return new EventSource(e,{withCredentials:true})},createWebSocket:function(e){return new WebSocket(e,[])},version:"1.6.1"};var r=["get","post","put","delete","patch"];var n=r.map(function(e){return"[hx-"+e+"], [data-hx-"+e+"]"}).join(", ");function h(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}return parseFloat(e)||undefined}function c(e,t){return e.getAttribute&&e.getAttribute(t)}function s(e,t){return e.hasAttribute&&(e.hasAttribute(t)||e.hasAttribute("data-"+t))}function F(e,t){return c(e,t)||c(e,"data-"+t)}function l(e){return e.parentElement}function P(){return document}function d(e,t){if(t(e)){return e}else if(l(e)){return d(l(e),t)}else{return null}}function X(e,t){var r=null;d(e,function(e){return r=F(e,t)});if(r!=="unset"){return r}}function v(e,t){var r=e.matches||e.matchesSelector||e.msMatchesSelector||e.mozMatchesSelector||e.webkitMatchesSelector||e.oMatchesSelector;return r&&r.call(e,t)}function i(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 o(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=P().createDocumentFragment()}return i}function u(e){if(D.config.useTemplateFragments){var t=o("",0);return t.querySelector("template").content}else{var r=i(e);switch(r){case"thead":case"tbody":case"tfoot":case"colgroup":case"caption":return o(""+e+"
",1);case"col":return o(""+e+"
",2);case"tr":return o(""+e+"
",2);case"td":case"th":return o(""+e+"
",3);case"script":return o("
"+e+"
",1);default:return o(e,0)}}}function U(e){if(e){e()}}function a(e,t){return Object.prototype.toString.call(e)==="[object "+t+"]"}function f(e){return a(e,"Function")}function g(e){return a(e,"Object")}function j(e){var t="htmx-internal-data";var r=e[t];if(!r){r=e[t]={}}return r}function p(e){var t=[];if(e){for(var r=0;r=0}function z(e){return P().body.contains(e)}function y(e){return e.trim().split(/\s+/)}function V(e,t){for(var r in t){if(t.hasOwnProperty(r)){e[r]=t[r]}}return e}function x(e){try{return JSON.parse(e)}catch(e){ut(e);return null}}function e(e){return Ut(P().body,function(){return eval(e)})}function t(t){var e=D.on("htmx:load",function(e){t(e.detail.elt)});return e}function b(){D.logger=function(e,t,r){if(console){console.log(t,e,r)}}}function w(e,t){if(t){return e.querySelector(t)}else{return w(P(),e)}}function S(e,t){if(t){return e.querySelectorAll(t)}else{return S(P(),e)}}function E(e,t){e=H(e);if(t){setTimeout(function(){E(e)},t)}else{e.parentElement.removeChild(e)}}function C(e,t,r){e=H(e);if(r){setTimeout(function(){C(e,t)},r)}else{e.classList&&e.classList.add(t)}}function R(e,t,r){e=H(e);if(r){setTimeout(function(){R(e,t)},r)}else{if(e.classList){e.classList.remove(t);if(e.classList.length===0){e.removeAttribute("class")}}}}function q(e,t){e=H(e);e.classList.toggle(t)}function L(e,t){e=H(e);B(e.parentElement.children,function(e){R(e,t)});C(e,t)}function O(e,t){e=H(e);if(e.closest){return e.closest(t)}else{do{if(e==null||v(e,t)){return e}}while(e=e&&l(e))}}function T(e,t){if(t.indexOf("closest ")===0){return[O(e,t.substr(8))]}else if(t.indexOf("find ")===0){return[w(e,t.substr(5))]}else if(t==="document"){return[document]}else if(t==="window"){return[window]}else{return P().querySelectorAll(t)}}function A(e,t){if(t){return T(e,t)[0]}else{return T(P().body,e)[0]}}function H(e){if(a(e,"String")){return w(e)}else{return e}}function k(e,t,r){if(f(t)){return{target:P().body,event:e,listener:t}}else{return{target:H(e),event:t,listener:r}}}function N(t,r,n){rr(function(){var e=k(t,r,n);e.target.addEventListener(e.event,e.listener)});var e=f(r);return e?r:n}function I(t,r,n){rr(function(){var e=k(t,r,n);e.target.removeEventListener(e.event,e.listener)});return f(r)?r:n}function _(e){var t=d(e,function(e){return F(e,"hx-target")!==null});if(t){var r=F(t,"hx-target");if(r==="this"){return t}else{return A(e,r)}}else{var n=j(e);if(n.boosted){return P().body}else{return e}}}function M(e){var t=D.config.attributesToSettle;for(var r=0;r0){i=e.substr(0,e.indexOf(":"));n=e.substr(e.indexOf(":")+1,e.length)}else{i=e}var o=P().querySelector(n);if(o){var a;a=P().createDocumentFragment();a.appendChild(t);if(!$(i,o)){a=t}le(i,o,o,a,r)}else{t.parentNode.removeChild(t);ot(P().body,"htmx:oobErrorNoTarget",{content:t})}return e}function Z(e,r){B(S(e,"[hx-swap-oob], [data-hx-swap-oob]"),function(e){var t=F(e,"hx-swap-oob");if(t!=null){J(t,e,r)}})}function G(e){B(S(e,"[hx-preserve], [data-hx-preserve]"),function(e){var t=F(e,"id");var r=P().getElementById(t);if(r!=null){e.parentNode.replaceChild(r,e)}})}function K(n,e,i){B(e.querySelectorAll("[id]"),function(e){if(e.id&&e.id.length>0){var t=n.querySelector(e.tagName+"[id='"+e.id+"']");if(t&&t!==n){var r=e.cloneNode();W(e,t);i.tasks.push(function(){W(e,r)})}}})}function Y(e){return function(){R(e,D.config.addedClass);rt(e);Ke(e);Q(e);lt(e,"htmx:load")}}function Q(e){var t="[autofocus]";var r=v(e,t)?e:e.querySelector(t);if(r!=null){r.focus()}}function ee(e,t,r,n){K(e,r,n);while(r.childNodes.length>0){var i=r.firstChild;C(i,D.config.addedClass);e.insertBefore(i,t);if(i.nodeType!==Node.TEXT_NODE&&i.nodeType!==Node.COMMENT_NODE){n.tasks.push(Y(i))}}}function te(t){var e=j(t);if(e.webSocket){e.webSocket.close()}if(e.sseEventSource){e.sseEventSource.close()}if(e.listenerInfos){B(e.listenerInfos,function(e){if(t!==e.on){e.on.removeEventListener(e.trigger,e.listener)}})}if(t.children){B(t.children,function(e){te(e)})}}function re(e,t,r){if(e.tagName==="BODY"){return se(e,t,r)}else{var n=e.previousSibling;ee(l(e),e,t,r);if(n==null){var i=l(e).firstChild}else{var i=n.nextSibling}j(e).replacedWith=i;r.elts=[];while(i&&i!==e){if(i.nodeType===Node.ELEMENT_NODE){r.elts.push(i)}i=i.nextElementSibling}te(e);l(e).removeChild(e)}}function ne(e,t,r){return ee(e,e.firstChild,t,r)}function ie(e,t,r){return ee(l(e),e,t,r)}function oe(e,t,r){return ee(e,null,t,r)}function ae(e,t,r){return ee(l(e),e.nextSibling,t,r)}function se(e,t,r){var n=e.firstChild;ee(e,n,t,r);if(n){while(n.nextSibling){te(n.nextSibling);e.removeChild(n.nextSibling)}te(n);e.removeChild(n)}}function ue(e,t){var r=X(e,"hx-select");if(r){var n=P().createDocumentFragment();B(t.querySelectorAll(r),function(e){n.appendChild(e)});t=n}return t}function le(e,t,r,n,i){switch(e){case"none":return;case"outerHTML":re(r,n,i);return;case"afterbegin":ne(r,n,i);return;case"beforebegin":ie(r,n,i);return;case"beforeend":oe(r,n,i);return;case"afterend":ae(r,n,i);return;default:var o=tr(t);for(var a=0;a-1){var t=e.replace(/]*>|>)([\s\S]*?)<\/svg>/gim,"");var r=t.match(/]*>|>)([\s\S]*?)<\/title>/im);if(r){return r[2]}}}function ce(e,t,r,n,i){var o=fe(n);if(o){var a=w("title");if(a){a.innerHTML=o}else{window.document.title=o}}var s=u(n);if(s){Z(s,i);s=ue(r,s);G(s);return le(e,r,t,s,i)}}function he(e,t,r){var n=e.getResponseHeader(t);if(n.indexOf("{")===0){var i=x(n);for(var o in i){if(i.hasOwnProperty(o)){var a=i[o];if(!g(a)){a={value:a}}lt(r,o,a)}}}else{lt(r,n,[])}}var de=/\s/;var ve=/[\s,]/;var ge=/[_$a-zA-Z]/;var pe=/[_$a-zA-Z0-9]/;var me=['"',"'","/"];var ye=/[^\s]/;function xe(e){var t=[];var r=0;while(r0){var a=t[0];if(a==="]"){n--;if(n===0){if(o===null){i=i+"true"}t.shift();i+=")})";try{var s=Ut(e,function(){return Function(i)()},function(){return true});s.source=i;return s}catch(e){ot(P().body,"htmx:syntax:error",{error:e,source:i});return null}}}else if(a==="["){n++}if(be(a,o,r)){i+="(("+r+"."+a+") ? ("+r+"."+a+") : (window."+a+"))"}else{i=i+a}o=t.shift()}}}function Se(e,t){var r="";while(e.length>0&&!e[0].match(t)){r+=e.shift()}return r}var Ee="input, textarea, select";function Ce(e){var t=F(e,"hx-trigger");var r=[];if(t){var n=xe(t);do{Se(n,ye);var i=n.length;var o=Se(n,/[,\[\s]/);if(o!==""){if(o==="every"){var a={trigger:"every"};Se(n,ye);a.pollInterval=h(Se(n,/[,\[\s]/));Se(n,ye);var s=we(e,n,"event");if(s){a.eventFilter=s}r.push(a)}else if(o.indexOf("sse:")===0){r.push({trigger:"sse",sseEvent:o.substr(4)})}else{var u={trigger:o};var s=we(e,n,"event");if(s){u.eventFilter=s}while(n.length>0&&n[0]!==","){Se(n,ye);var l=n.shift();if(l==="changed"){u.changed=true}else if(l==="once"){u.once=true}else if(l==="consume"){u.consume=true}else if(l==="delay"&&n[0]===":"){n.shift();u.delay=h(Se(n,ve))}else if(l==="from"&&n[0]===":"){n.shift();let e=Se(n,ve);if(e==="closest"||e==="find"){n.shift();e+=" "+Se(n,ve)}u.from=e}else if(l==="target"&&n[0]===":"){n.shift();u.target=Se(n,ve)}else if(l==="throttle"&&n[0]===":"){n.shift();u.throttle=h(Se(n,ve))}else if(l==="queue"&&n[0]===":"){n.shift();u.queue=Se(n,ve)}else if((l==="root"||l==="threshold")&&n[0]===":"){n.shift();u[l]=Se(n,ve)}else{ot(e,"htmx:syntax:error",{token:n.shift()})}}r.push(u)}}if(n.length===i){ot(e,"htmx:syntax:error",{token:n.shift()})}Se(n,ye)}while(n[0]===","&&n.shift())}if(r.length>0){return r}else if(v(e,"form")){return[{trigger:"submit"}]}else if(v(e,Ee)){return[{trigger:"change"}]}else{return[{trigger:"click"}]}}function Re(e){j(e).cancelled=true}function qe(e,t,r,n){var i=j(e);i.timeout=setTimeout(function(){if(z(e)&&i.cancelled!==true){if(!He(n,it("hx:poll:trigger",{triggerSpec:n}))){Zt(t,r,e)}qe(e,t,F(e,"hx-"+t),n)}},n.pollInterval)}function Le(e){return location.hostname===e.hostname&&c(e,"href")&&c(e,"href").indexOf("#")!==0}function Oe(t,r,e){if(t.tagName==="A"&&Le(t)&&t.target===""||t.tagName==="FORM"){r.boosted=true;var n,i;if(t.tagName==="A"){n="get";i=c(t,"href");r.pushURL=true}else{var o=c(t,"method");n=o?o.toLowerCase():"get";if(n==="get"){r.pushURL=true}i=c(t,"action")}e.forEach(function(e){ke(t,n,i,r,e,true)})}}function Te(e,t){if(e.type==="submit"||e.type==="click"){if(t.tagName==="FORM"){return true}if(v(t,'input[type="submit"], button')&&O(t,"form")!==null){return true}if(t.tagName==="A"&&t.href&&(t.getAttribute("href")==="#"||t.getAttribute("href").indexOf("#")!==0)){return true}}return false}function Ae(e,t){return j(e).boosted&&e.tagName==="A"&&t.type==="click"&&(t.ctrlKey||t.metaKey)}function He(e,t){var r=e.eventFilter;if(r){try{return r(t)!==true}catch(e){ot(P().body,"htmx:eventFilter:error",{error:e,source:r.source});return true}}return false}function ke(o,a,s,e,u,l){var t;if(u.from){t=T(o,u.from)}else{t=[o]}B(t,function(n){var i=function(e){if(!z(o)){n.removeEventListener(u.trigger,i);return}if(Ae(o,e)){return}if(l||Te(e,o)){e.preventDefault()}if(He(u,e)){return}var t=j(e);t.triggerSpec=u;if(t.handledFor==null){t.handledFor=[]}var r=j(o);if(t.handledFor.indexOf(o)<0){t.handledFor.push(o);if(u.consume){e.stopPropagation()}if(u.target&&e.target){if(!v(e.target,u.target)){return}}if(u.once){if(r.triggeredOnce){return}else{r.triggeredOnce=true}}if(u.changed){if(r.lastValue===o.value){return}else{r.lastValue=o.value}}if(r.delayed){clearTimeout(r.delayed)}if(r.throttle){return}if(u.throttle){if(!r.throttle){Zt(a,s,o,e);r.throttle=setTimeout(function(){r.throttle=null},u.throttle)}}else if(u.delay){r.delayed=setTimeout(function(){Zt(a,s,o,e)},u.delay)}else{Zt(a,s,o,e)}}};if(e.listenerInfos==null){e.listenerInfos=[]}e.listenerInfos.push({trigger:u.trigger,listener:i,on:n});n.addEventListener(u.trigger,i)})}var Ne=false;var Ie=null;function Me(){if(!Ie){Ie=function(){Ne=true};window.addEventListener("scroll",Ie);setInterval(function(){if(Ne){Ne=false;B(P().querySelectorAll("[hx-trigger='revealed'],[data-hx-trigger='revealed']"),function(e){De(e)})}},200)}}function De(e){if(!s(e,"data-hx-revealed")&&m(e)){e.setAttribute("data-hx-revealed","true");var t=j(e);if(t.initialized){Zt(t.verb,t.path,e)}else{e.addEventListener("htmx:afterProcessNode",function(){Zt(t.verb,t.path,e)},{once:true})}}}function Fe(e,t,r){var n=y(r);for(var i=0;i=0){var t=je(n);setTimeout(function(){Pe(s,r,n+1)},t)}};t.onopen=function(e){n=0};j(s).webSocket=t;t.addEventListener("message",function(e){if(Xe(s)){return}var t=e.data;st(s,function(e){t=e.transformResponse(t,null,s)});var r=Ft(s);var n=u(t);var i=p(n.children);for(var o=0;o0){lt(l,"htmx:validation:halted",i);return}t.send(JSON.stringify(u));if(Te(e,l)){e.preventDefault()}})}else{ot(l,"htmx:noWebSocketSourceError")}}function je(e){var t=D.config.wsReconnectDelay;if(typeof t==="function"){return t(e)}if(t==="full-jitter"){var r=Math.min(e,6);var n=1e3*Math.pow(2,r);return n*Math.random()}ut('htmx.config.wsReconnectDelay must either be a function or the string "full-jitter"')}function Be(e,t,r){var n=y(r);for(var i=0;iD.config.historyCacheSize){i.shift()}while(i.length>0){try{localStorage.setItem("htmx-history-cache",JSON.stringify(i));break}catch(e){ot(P().body,"htmx:historyCacheError",{cause:e,cache:i});i.shift()}}}function dt(e){var t=x(localStorage.getItem("htmx-history-cache"))||[];for(var r=0;r=200&&this.status<400){lt(P().body,"htmx:historyCacheMissLoad",i);var e=u(this.response);e=e.querySelector("[hx-history-elt],[data-hx-history-elt]")||e;var t=ct();var r=Ft(t);se(t,e,r);mt(r.tasks);ft=n;lt(P().body,"htmx:historyRestore",{path:n})}else{ot(P().body,"htmx:historyCacheMissLoadError",i)}};e.send()}function xt(e){gt();e=e||location.pathname+location.search;var t=dt(e);if(t){var r=u(t.content);var n=ct();var i=Ft(n);se(n,r,i);mt(i.tasks);document.title=t.title;window.scrollTo(0,t.scroll);ft=e;lt(P().body,"htmx:historyRestore",{path:e})}else{if(D.config.refreshOnHistoryMiss){window.location.reload(true)}else{yt(e)}}}function bt(e){var t=X(e,"hx-push-url");return t&&t!=="false"||j(e).boosted&&j(e).pushURL}function wt(e){var t=X(e,"hx-push-url");return t==="true"||t==="false"?null:t}function St(e){var t=X(e,"hx-indicator");if(t){var r=T(e,t)}else{r=[e]}B(r,function(e){e.classList["add"].call(e.classList,D.config.requestClass)});return r}function Et(e){B(e,function(e){e.classList["remove"].call(e.classList,D.config.requestClass)})}function Ct(e,t){for(var r=0;r=0}function Mt(e){var t=X(e,"hx-swap");var r={swapStyle:j(e).boosted?"innerHTML":D.config.defaultSwapStyle,swapDelay:D.config.defaultSwapDelay,settleDelay:D.config.defaultSettleDelay};if(j(e).boosted&&!It(e)){r["show"]="top"}if(t){var n=y(t);if(n.length>0){r["swapStyle"]=n[0];for(var i=1;i0?s.join(":"):null;r["scroll"]=u;r["scrollTarget"]=l}if(o.indexOf("show:")===0){var f=o.substr(5);var s=f.split(":");var c=s.pop();var l=s.length>0?s.join(":"):null;r["show"]=c;r["showTarget"]=l}}}}return r}function Dt(t,r,n){var i=null;st(r,function(e){if(i==null){i=e.encodeParameters(t,n,r)}});if(i!=null){return i}else{if(X(r,"hx-encoding")==="multipart/form-data"||v(r,"form")&&c(r,"enctype")==="multipart/form-data"){return Ht(n)}else{return At(n)}}}function Ft(e){return{tasks:[],elts:[e]}}function Pt(e,t){var r=e[0];var n=e[e.length-1];if(t.scroll){var i=null;if(t.scrollTarget){i=A(r,t.scrollTarget)}if(t.scroll==="top"&&(r||i)){i=i||r;i.scrollTop=0}if(t.scroll==="bottom"&&(n||i)){i=i||n;i.scrollTop=i.scrollHeight}}if(t.show){var i=null;if(t.showTarget){var o=t.showTarget;if(t.showTarget==="window"){o="body"}i=A(r,o)}if(t.show==="top"&&(r||i)){i=i||r;i.scrollIntoView({block:"start",behavior:D.config.scrollBehavior})}if(t.show==="bottom"&&(n||i)){i=i||n;i.scrollIntoView({block:"end",behavior:D.config.scrollBehavior})}}}function Xt(e,t,r,n){if(n==null){n={}}if(e==null){return n}var i=F(e,t);if(i){var o=i.trim();var a=r;if(o.indexOf("javascript:")===0){o=o.substr(11);a=true}else if(o.indexOf("js:")===0){o=o.substr(3);a=true}if(o.indexOf("{")!==0){o="{"+o+"}"}var s;if(a){s=Ut(e,function(){return Function("return ("+o+")")()},{})}else{s=x(o)}for(var u in s){if(s.hasOwnProperty(u)){if(n[u]==null){n[u]=s[u]}}}}return Xt(l(e),t,r,n)}function Ut(e,t,r){if(D.config.allowEval){return t()}else{ot(e,"htmx:evalDisallowedError");return r}}function jt(e,t){return Xt(e,"hx-vars",true,t)}function Bt(e,t){return Xt(e,"hx-vals",false,t)}function zt(e){return V(jt(e),Bt(e))}function Vt(t,r,n){if(n!==null){try{t.setRequestHeader(r,n)}catch(e){t.setRequestHeader(r,encodeURIComponent(n));t.setRequestHeader(r+"-URI-AutoEncoded","true")}}}function _t(t){if(t.responseURL&&typeof URL!=="undefined"){try{var e=new URL(t.responseURL);return e.pathname+e.search}catch(e){ot(P().body,"htmx:badResponseUrl",{url:t.responseURL})}}}function Wt(e,t){return e.getAllResponseHeaders().match(t)}function $t(e,t,r){e=e.toLowerCase();if(r){if(r instanceof Element||a(r,"String")){return Zt(e,t,null,null,{targetOverride:H(r),returnPromise:true})}else{return Zt(e,t,H(r.source),r.event,{handler:r.handler,headers:r.headers,values:r.values,targetOverride:H(r.target),returnPromise:true})}}else{return Zt(e,t,null,null,{returnPromise:true})}}function Jt(e){var t=[];while(e){t.push(e);e=e.parentElement}return t}function Zt(e,t,n,r,i){var o=null;var a=null;i=i!=null?i:{};if(i.returnPromise&&typeof Promise!=="undefined"){var s=new Promise(function(e,t){o=e;a=t})}if(n==null){n=P().body}var u=i.handler||Gt;if(!z(n)){return}var l=i.targetOverride||_(n);if(l==null){ot(n,"htmx:targetError",{target:F(n,"hx-target")});return}var f=j(n);if(f.requestInFlight){var c="last";if(r){var h=j(r);if(h&&h.triggerSpec&&h.triggerSpec.queue){c=h.triggerSpec.queue}}if(f.queuedRequests==null){f.queuedRequests=[]}if(c==="first"&&f.queuedRequests.length===0){f.queuedRequests.push(function(){Zt(e,t,n,r,i)})}else if(c==="all"){f.queuedRequests.push(function(){Zt(e,t,n,r,i)})}else if(c==="last"){f.queuedRequests=[];f.queuedRequests.push(function(){Zt(e,t,n,r,i)})}return}else{f.requestInFlight=true}var d=function(){f.requestInFlight=false;if(f.queuedRequests!=null&&f.queuedRequests.length>0){var e=f.queuedRequests.shift();e()}};var v=X(n,"hx-prompt");if(v){var g=prompt(v);if(g===null||!lt(n,"htmx:prompt",{prompt:g,target:l})){U(o);d();return s}}var p=X(n,"hx-confirm");if(p){if(!confirm(p)){U(o);d();return s}}var m=new XMLHttpRequest;var y=kt(n,l,g);if(i.headers){y=V(y,i.headers)}var x=Ot(n,e);var b=x.errors;var w=x.values;if(i.values){w=V(w,i.values)}var S=zt(n);var E=V(w,S);var C=Nt(E,n);if(e!=="get"&&X(n,"hx-encoding")==null){y["Content-Type"]="application/x-www-form-urlencoded; charset=UTF-8"}if(t==null||t===""){t=P().location.href}var R=Xt(n,"hx-request");var q={parameters:C,unfilteredParameters:E,headers:y,target:l,verb:e,errors:b,withCredentials:i.credentials||R.credentials||D.config.withCredentials,timeout:i.timeout||R.timeout||D.config.timeout,path:t,triggeringEvent:r};if(!lt(n,"htmx:configRequest",q)){U(o);d();return s}t=q.path;e=q.verb;y=q.headers;C=q.parameters;b=q.errors;if(b&&b.length>0){lt(n,"htmx:validation:halted",q);U(o);d();return s}var L=t.split("#");var O=L[0];var T=L[1];if(e==="get"){var A=O;var H=Object.keys(C).length!==0;if(H){if(A.indexOf("?")<0){A+="?"}else{A+="&"}A+=At(C);if(T){A+="#"+T}}m.open("GET",A,true)}else{m.open(e.toUpperCase(),t,true)}m.overrideMimeType("text/html");m.withCredentials=q.withCredentials;m.timeout=q.timeout;if(R.noHeaders){}else{for(var k in y){if(y.hasOwnProperty(k)){var N=y[k];Vt(m,k,N)}}}var I={xhr:m,target:l,requestConfig:q,pathInfo:{path:t,finalPath:A,anchor:T}};m.onload=function(){try{var e=Jt(n);u(n,I);Et(M);lt(n,"htmx:afterRequest",I);lt(n,"htmx:afterOnLoad",I);if(!z(n)){var t=null;while(e.length>0&&t==null){var r=e.shift();if(z(r)){t=r}}if(t){lt(t,"htmx:afterRequest",I);lt(t,"htmx:afterOnLoad",I)}}U(o);d()}catch(e){ot(n,"htmx:onLoadError",V({error:e},I));throw e}};m.onerror=function(){Et(M);ot(n,"htmx:afterRequest",I);ot(n,"htmx:sendError",I);U(a);d()};m.onabort=function(){Et(M);ot(n,"htmx:afterRequest",I);ot(n,"htmx:sendAbort",I);U(a);d()};m.ontimeout=function(){Et(M);ot(n,"htmx:afterRequest",I);ot(n,"htmx:timeout",I);U(a);d()};if(!lt(n,"htmx:beforeRequest",I)){U(o);d();return s}var M=St(n);B(["loadstart","loadend","progress","abort"],function(t){B([m,m.upload],function(e){e.addEventListener(t,function(e){lt(n,"htmx:xhr:"+t,{lengthComputable:e.lengthComputable,loaded:e.loaded,total:e.total})})})});lt(n,"htmx:beforeSend",I);m.send(e==="get"?null:Dt(m,n,C));return s}function Gt(a,s){var u=s.xhr;var l=s.target;if(!lt(a,"htmx:beforeOnLoad",s))return;if(Wt(u,/HX-Trigger:/i)){he(u,"HX-Trigger",a)}if(Wt(u,/HX-Push:/i)){var f=u.getResponseHeader("HX-Push")}if(Wt(u,/HX-Redirect:/i)){window.location.href=u.getResponseHeader("HX-Redirect");return}if(Wt(u,/HX-Refresh:/i)){if("true"===u.getResponseHeader("HX-Refresh")){location.reload();return}}if(Wt(u,/HX-Retarget:/i)){s.target=P().querySelector(u.getResponseHeader("HX-Retarget"))}var c=bt(a)||f;var e=u.status>=200&&u.status<400&&u.status!==204;var h=u.response;var t=u.status>=400;var r=V({shouldSwap:e,serverResponse:h,isError:t},s);if(!lt(l,"htmx:beforeSwap",r))return;l=r.target;h=r.serverResponse;t=r.isError;s.failed=t;s.successful=!t;if(r.shouldSwap){if(u.status===286){Re(a)}st(a,function(e){h=e.transformResponse(h,u,a)});if(c){gt()}var d=Mt(a);l.classList.add(D.config.swappingClass);var n=function(){try{var e=document.activeElement;var t={};try{t={elt:e,start:e?e.selectionStart:null,end:e?e.selectionEnd:null}}catch(e){}var r=Ft(l);ce(d.swapStyle,l,a,h,r);if(t.elt&&!z(t.elt)&&t.elt.id){var n=document.getElementById(t.elt.id);if(n){if(t.start&&n.setSelectionRange){n.setSelectionRange(t.start,t.end)}n.focus()}}l.classList.remove(D.config.swappingClass);B(r.elts,function(e){if(e.classList){e.classList.add(D.config.settlingClass)}lt(e,"htmx:afterSwap",s)});if(s.pathInfo.anchor){location.hash=s.pathInfo.anchor}if(Wt(u,/HX-Trigger-After-Swap:/i)){var i=a;if(!z(a)){i=P().body}he(u,"HX-Trigger-After-Swap",i)}var o=function(){B(r.tasks,function(e){e.call()});B(r.elts,function(e){if(e.classList){e.classList.remove(D.config.settlingClass)}lt(e,"htmx:afterSettle",s)});if(c){var e=f||wt(a)||_t(u)||s.pathInfo.finalPath||s.pathInfo.path;pt(e);lt(P().body,"htmx:pushedIntoHistory",{path:e})}Pt(r.elts,d);if(Wt(u,/HX-Trigger-After-Settle:/i)){var t=a;if(!z(a)){t=P().body}he(u,"HX-Trigger-After-Settle",t)}};if(d.settleDelay>0){setTimeout(o,d.settleDelay)}else{o()}}catch(e){ot(a,"htmx:swapError",s);throw e}};if(d.swapDelay>0){setTimeout(n,d.swapDelay)}else{n()}}if(t){ot(a,"htmx:responseError",V({error:"Response Status Error Code "+u.status+" from "+s.pathInfo.path},s))}}var Kt={};function Yt(){return{onEvent:function(e,t){return true},transformResponse:function(e,t,r){return e},isInlineSwap:function(e){return false},handleSwap:function(e,t,r,n){return false},encodeParameters:function(e,t,r){return null}}}function Qt(e,t){Kt[e]=V(Yt(),t)}function er(e){delete Kt[e]}function tr(e,r,n){if(e==undefined){return r}if(r==undefined){r=[]}if(n==undefined){n=[]}var t=F(e,"hx-ext");if(t){B(t.split(","),function(e){e=e.replace(/ /g,"");if(e.slice(0,7)=="ignore:"){n.push(e.slice(7));return}if(n.indexOf(e)<0){var t=Kt[e];if(t&&r.indexOf(t)<0){r.push(t)}}})}return tr(l(e),r,n)}function rr(e){if(P().readyState!=="loading"){e()}else{P().addEventListener("DOMContentLoaded",e)}}function nr(){if(D.config.includeIndicatorStyles!==false){P().head.insertAdjacentHTML("beforeend","")}}function ir(){var e=P().querySelector('meta[name="htmx-config"]');if(e){return x(e.content)}else{return null}}function or(){var e=ir();if(e){D.config=V(D.config,e)}}rr(function(){or();nr();var e=P().body;rt(e);window.onpopstate=function(e){if(e.state&&e.state.htmx){xt()}};setTimeout(function(){lt(e,"htmx:load",{})},0)});return D}()}); \ No newline at end of file diff --git a/flake.lock b/flake.lock index 3114d91..c1964b2 100644 --- a/flake.lock +++ b/flake.lock @@ -32,11 +32,11 @@ }, "nixpkgs": { "locked": { - "lastModified": 1668765800, - "narHash": "sha256-rC40+/W6Hio7b/RsY8SvQPKNx4WqNcTgfYv8cUMAvJk=", + "lastModified": 1670242877, + "narHash": "sha256-jBLh7dRHnbfvPPA9znOC6oQfKrCPJ0El8Zoe0BqnCjQ=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "52b2ac8ae18bbad4374ff0dd5aeee0fdf1aea739", + "rev": "6e51c97f1c849efdfd4f3b78a4870e6aa2da4198", "type": "github" }, "original": { @@ -54,17 +54,16 @@ ] }, "locked": { - "lastModified": 1668892083, - "narHash": "sha256-AKK36evl0fHsOIAgKmtwon1LfH0WKn55+J2Yv2dXGPk=", - "owner": "Nebucatnetzer", + "lastModified": 1670326426, + "narHash": "sha256-I5IscrjGuCbvpFIRoiappUwBBOq8OODvGLkapnn/ECA=", + "owner": "nix-community", "repo": "poetry2nix", - "rev": "283a1398ee9c080c8c3310c8fd1aa937f6e84b62", + "rev": "293dd5c31167540193bf2b66cec636eecd1fc788", "type": "github" }, "original": { - "owner": "Nebucatnetzer", + "owner": "nix-community", "repo": "poetry2nix", - "rev": "283a1398ee9c080c8c3310c8fd1aa937f6e84b62", "type": "github" } }, diff --git a/flake.nix b/flake.nix index 82bdac8..f58279b 100644 --- a/flake.nix +++ b/flake.nix @@ -4,27 +4,21 @@ nixpkgs.url = github:NixOS/nixpkgs/nixos-unstable; flake-utils.url = github:numtide/flake-utils; poetry2nix = { - url = "github:Nebucatnetzer/poetry2nix?rev=283a1398ee9c080c8c3310c8fd1aa937f6e84b62"; + url = "github:nix-community/poetry2nix"; inputs.nixpkgs.follows = "nixpkgs"; }; }; outputs = { self, nixpkgs, flake-utils, poetry2nix }: { - overlay = nixpkgs.lib.composeManyExtensions [ + overlays.default = nixpkgs.lib.composeManyExtensions [ poetry2nix.overlay (final: prev: { - inventory = prev.poetry2nix.mkPoetryEnv { + inventoryEnv = prev.poetry2nix.mkPoetryEnv { + projectDir = ./.; + }; + inventoryPackage = prev.poetry2nix.mkPoetryApplication { projectDir = ./.; - overrides = prev.poetry2nix.defaultPoetryOverrides.extend - (self: super: { - python-monkey-business = super.python-monkey-business.overridePythonAttrs - ( - old: { - buildInputs = (old.buildInputs or [ ]) ++ [ super.setuptools ]; - } - ); - }); }; }) ]; @@ -32,20 +26,151 @@ let pkgs = import nixpkgs { inherit system; - overlays = [ self.overlay ]; + overlays = [ self.overlays.default ]; + }; + src = with pkgs.lib; + cleanSource (cleanSourceWith { + filter = name: type: + let + baseName = baseNameOf (toString name); + in + !(builtins.elem baseName [ + ".coverage" + ".coveragerc" + ".dir-locals.el" + ".direnv" + ".git" + ".github" + ".env" + ".envrc" + ".flake8" + ".gitignore" + ".gitlab-ci.yml" + "docker-compose.yaml" + "flake.lock" + "flake.nix" + "Makefile" + "poetry.lock" + "poetry.toml" + "pyproject.toml" + "pytest.ini" + "*.pyc" + ]); + src = ./.; + }); + inventory = pkgs.stdenv.mkDerivation { + inherit src; + version = "latest"; + pname = "network-inventory"; + installPhase = '' + mkdir -p $out + cp -r ./src $out/code + ''; }; in - { - devShell = pkgs.mkShell { + rec { + devShells.default = pkgs.mkShell { buildInputs = [ pkgs.gnumake - pkgs.inventory + pkgs.inventoryEnv pkgs.poetry + pkgs.python310Packages.pip ]; shellHook = '' export DJANGO_SETTINGS_MODULE=network_inventory.settings.local ''; }; - packages.venv = pkgs.inventory; + checks = { + lint = pkgs.stdenv.mkDerivation { + dontPatch = true; + dontConfigure = true; + dontBuild = true; + dontInstall = true; + doCheck = true; + name = "lint"; + src = ./.; + checkInputs = [ pkgs.inventoryEnv ]; + checkPhase = '' + mkdir -p $out + flake8 . --count --show-source --statistics + ''; + }; + tests = pkgs.stdenv.mkDerivation { + dontPatch = true; + dontConfigure = true; + dontBuild = true; + dontInstall = true; + doCheck = true; + name = "test"; + src = ./.; + checkInputs = [ pkgs.inventoryEnv ]; + checkPhase = '' + mkdir -p $out + pytest --ds=network_inventory.settings.ram_test \ + -nauto \ + --nomigrations \ + --cov=./src \ + ./src + ''; + }; + }; + packages = { + venv = pkgs.inventoryEnv; + container = pkgs.dockerTools.buildImage { + name = "network-inventory"; + tag = "latest"; + created = "now"; + copyToRoot = pkgs.buildEnv { + name = "image-root"; + paths = [ + pkgs.bashInteractive + pkgs.coreutils + pkgs.inventoryEnv + inventory + (pkgs.writeShellScriptBin "start-inventory" '' + cd /code + if [ -f .second_run ]; then + sleep 2 + ${pkgs.python3}/bin/python manage.py collectstatic --noinput + ${pkgs.python3}/bin/python manage.py makemigrations + ${pkgs.python3}/bin/python manage.py migrate + else + ${pkgs.python3}/bin/python manage.py collectstatic --noinput + ${pkgs.python3}/bin/python manage.py makemigrations backups + ${pkgs.python3}/bin/python manage.py makemigrations computers + ${pkgs.python3}/bin/python manage.py makemigrations core + ${pkgs.python3}/bin/python manage.py makemigrations customers + ${pkgs.python3}/bin/python manage.py makemigrations devices + ${pkgs.python3}/bin/python manage.py makemigrations licenses + ${pkgs.python3}/bin/python manage.py makemigrations nets + ${pkgs.python3}/bin/python manage.py makemigrations softwares + ${pkgs.python3}/bin/python manage.py makemigrations users + ${pkgs.python3}/bin/python manage.py makemigrations + ${pkgs.python3}/bin/python manage.py migrate + ${pkgs.python3}/bin/python manage.py loaddata backups + ${pkgs.python3}/bin/python manage.py loaddata computers + ${pkgs.python3}/bin/python manage.py loaddata core + ${pkgs.python3}/bin/python manage.py loaddata devices + ${pkgs.python3}/bin/python manage.py loaddata nets + ${pkgs.python3}/bin/python manage.py loaddata softwares + ${pkgs.python3}/bin/python manage.py shell -c "from django.contrib.auth import get_user_model; User = get_user_model(); User.objects.create_superuser('admin', 'admin@example.com', 'password')" + touch .second_run + fi + ${pkgs.python310Packages.gunicorn}/bin/gunicorn network_inventory.wsgi:application --reload --bind 0.0.0.0:8000 --workers 3 + '') + ]; + }; + config = { + Cmd = [ "start-inventory" ]; + Env = [ + "POSTGRES_DB=network_inventory" + "DJANGO_SETTINGS_MODULE=network_inventory.settings.production" + "PYTHONPATH=/lib/python3.10:/lib/python3.10/site-packages" + ]; + }; + }; + default = packages.container; + }; })); } + diff --git a/poetry.lock b/poetry.lock index b20335a..b343988 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1,3 +1,11 @@ +[[package]] +name = "appdirs" +version = "1.4.4" +description = "A small Python module for determining appropriate platform-specific dirs, e.g. a \"user data dir\"." +category = "dev" +optional = false +python-versions = "*" + [[package]] name = "asgiref" version = "3.5.2" @@ -7,7 +15,7 @@ optional = false python-versions = ">=3.7" [package.extras] -tests = ["pytest", "pytest-asyncio", "mypy (>=0.800)"] +tests = ["mypy (>=0.800)", "pytest", "pytest-asyncio"] [[package]] name = "astroid" @@ -34,10 +42,55 @@ optional = false python-versions = ">=3.5" [package.extras] -dev = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "mypy (>=0.900,!=0.940)", "pytest-mypy-plugins", "zope.interface", "furo", "sphinx", "sphinx-notfound-page", "pre-commit", "cloudpickle"] -docs = ["furo", "sphinx", "zope.interface", "sphinx-notfound-page"] -tests = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "mypy (>=0.900,!=0.940)", "pytest-mypy-plugins", "zope.interface", "cloudpickle"] -tests_no_zope = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "mypy (>=0.900,!=0.940)", "pytest-mypy-plugins", "cloudpickle"] +dev = ["cloudpickle", "coverage[toml] (>=5.0.2)", "furo", "hypothesis", "mypy (>=0.900,!=0.940)", "pre-commit", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "sphinx", "sphinx-notfound-page", "zope.interface"] +docs = ["furo", "sphinx", "sphinx-notfound-page", "zope.interface"] +tests = ["cloudpickle", "coverage[toml] (>=5.0.2)", "hypothesis", "mypy (>=0.900,!=0.940)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "zope.interface"] +tests-no-zope = ["cloudpickle", "coverage[toml] (>=5.0.2)", "hypothesis", "mypy (>=0.900,!=0.940)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins"] + +[[package]] +name = "autopep8" +version = "2.0.0" +description = "A tool that automatically formats Python code to conform to the PEP 8 style guide" +category = "dev" +optional = false +python-versions = "*" + +[package.dependencies] +pycodestyle = ">=2.9.1" +tomli = "*" + +[[package]] +name = "black" +version = "22.10.0" +description = "The uncompromising code formatter." +category = "dev" +optional = false +python-versions = ">=3.7" + +[package.dependencies] +click = ">=8.0.0" +mypy-extensions = ">=0.4.3" +pathspec = ">=0.9.0" +platformdirs = ">=2" +tomli = {version = ">=1.1.0", markers = "python_full_version < \"3.11.0a7\""} +typing-extensions = {version = ">=3.10.0.0", markers = "python_version < \"3.10\""} + +[package.extras] +colorama = ["colorama (>=0.4.3)"] +d = ["aiohttp (>=3.7.4)"] +jupyter = ["ipython (>=7.8.0)", "tokenize-rt (>=3.2.0)"] +uvloop = ["uvloop (>=0.15.2)"] + +[[package]] +name = "click" +version = "8.1.3" +description = "Composable command line interface toolkit" +category = "dev" +optional = false +python-versions = ">=3.7" + +[package.dependencies] +colorama = {version = "*", markers = "platform_system == \"Windows\""} [[package]] name = "colorama" @@ -161,8 +214,8 @@ python-versions = ">=3.6" python-monkey-business = ">=1.0.0" [package.extras] -dev = ["black", "flake8", "pytest", "pytest-cov", "pytest-xdist", "pytest-django", "pillow", "dj-database-url", "django-selenosis", "selenium"] -test = ["pytest", "pytest-cov", "pytest-xdist", "pytest-django", "pillow", "dj-database-url", "django-selenosis", "selenium"] +dev = ["Pillow", "black", "dj-database-url", "django-selenosis", "flake8", "pytest", "pytest-cov", "pytest-django", "pytest-xdist", "selenium"] +test = ["Pillow", "dj-database-url", "django-selenosis", "pytest", "pytest-cov", "pytest-django", "pytest-xdist", "selenium"] [[package]] name = "django-tables2" @@ -213,16 +266,16 @@ python-dateutil = ">=2.4" [[package]] name = "flake8" -version = "5.0.4" +version = "6.0.0" description = "the modular source code checker: pep8 pyflakes and co" category = "dev" optional = false -python-versions = ">=3.6.1" +python-versions = ">=3.8.1" [package.dependencies] mccabe = ">=0.7.0,<0.8.0" -pycodestyle = ">=2.9.0,<2.10.0" -pyflakes = ">=2.5.0,<2.6.0" +pycodestyle = ">=2.10.0,<2.11.0" +pyflakes = ">=3.0.0,<3.1.0" [[package]] name = "gunicorn" @@ -232,6 +285,9 @@ category = "main" optional = false python-versions = ">=3.5" +[package.dependencies] +setuptools = ">=3.0" + [package.extras] eventlet = ["eventlet (>=0.24.1)"] gevent = ["gevent (>=1.4.0)"] @@ -255,10 +311,26 @@ optional = false python-versions = ">=3.6.1,<4.0" [package.extras] -pipfile_deprecated_finder = ["pipreqs", "requirementslib"] -requirements_deprecated_finder = ["pipreqs", "pip-api"] colors = ["colorama (>=0.4.3,<0.5.0)"] +pipfile-deprecated-finder = ["pipreqs", "requirementslib"] plugins = ["setuptools"] +requirements-deprecated-finder = ["pip-api", "pipreqs"] + +[[package]] +name = "jedi" +version = "0.18.2" +description = "An autocompletion tool for Python that can be used for text editors." +category = "dev" +optional = false +python-versions = ">=3.6" + +[package.dependencies] +parso = ">=0.8.0,<0.9.0" + +[package.extras] +docs = ["Jinja2 (==2.11.3)", "MarkupSafe (==1.1.1)", "Pygments (==2.8.1)", "alabaster (==0.7.12)", "babel (==2.9.1)", "chardet (==4.0.0)", "commonmark (==0.8.1)", "docutils (==0.17.1)", "future (==0.18.2)", "idna (==2.10)", "imagesize (==1.2.0)", "mock (==1.0.1)", "packaging (==20.9)", "pyparsing (==2.4.7)", "pytz (==2021.1)", "readthedocs-sphinx-ext (==2.1.4)", "recommonmark (==0.5.0)", "requests (==2.25.1)", "six (==1.15.0)", "snowballstemmer (==2.1.0)", "sphinx (==1.8.5)", "sphinx-rtd-theme (==0.4.3)", "sphinxcontrib-serializinghtml (==1.1.4)", "sphinxcontrib-websupport (==1.2.4)", "urllib3 (==1.26.4)"] +qa = ["flake8 (==3.8.3)", "mypy (==0.782)"] +testing = ["Django (<3.1)", "attrs", "colorama", "docopt", "pytest (<7.0.0)"] [[package]] name = "lazy-object-proxy" @@ -290,6 +362,14 @@ Faker = ">=5.4.0,<12.1" [package.extras] tests = ["Django (>=3.0)", "Flask (>=1.0)", "Marshmallow (>=3.9)", "SQLAlchemy (>=1.1.4)", "flask-sqlalchemy (>=2.1)", "mongoengine (>=0.10.1)", "peewee (>=3.7.0)", "pony (>=0.7)", "psycopg2-binary (>=2.8.4)", "pytest"] +[[package]] +name = "mypy-extensions" +version = "0.4.3" +description = "Experimental type system extensions for programs checked with the mypy typechecker." +category = "dev" +optional = false +python-versions = "*" + [[package]] name = "packaging" version = "21.3" @@ -301,6 +381,26 @@ python-versions = ">=3.6" [package.dependencies] pyparsing = ">=2.0.2,<3.0.5 || >3.0.5" +[[package]] +name = "parso" +version = "0.8.3" +description = "A Python Parser" +category = "dev" +optional = false +python-versions = ">=3.6" + +[package.extras] +qa = ["flake8 (==3.8.3)", "mypy (==0.782)"] +testing = ["docopt", "pytest (<6.0.0)"] + +[[package]] +name = "pathspec" +version = "0.10.2" +description = "Utility library for gitignore style pattern matching of file paths." +category = "dev" +optional = false +python-versions = ">=3.7" + [[package]] name = "pep8" version = "1.7.1" @@ -318,8 +418,8 @@ optional = false python-versions = ">=3.7" [package.extras] -docs = ["furo (>=2022.9.29)", "proselint (>=0.13)", "sphinx-autodoc-typehints (>=1.19.4)", "sphinx (>=5.3)"] -test = ["appdirs (==1.4.4)", "pytest-cov (>=4)", "pytest-mock (>=3.10)", "pytest (>=7.2)"] +docs = ["furo (>=2022.9.29)", "proselint (>=0.13)", "sphinx (>=5.3)", "sphinx-autodoc-typehints (>=1.19.4)"] +test = ["appdirs (==1.4.4)", "pytest (>=7.2)", "pytest-cov (>=4)", "pytest-mock (>=3.10)"] [[package]] name = "pluggy" @@ -351,7 +451,7 @@ python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" [[package]] name = "pycodestyle" -version = "2.9.1" +version = "2.10.0" description = "Python style guide checker" category = "dev" optional = false @@ -359,7 +459,7 @@ python-versions = ">=3.6" [[package]] name = "pyflakes" -version = "2.5.0" +version = "3.0.1" description = "passive checker of Python programs" category = "dev" optional = false @@ -367,14 +467,14 @@ python-versions = ">=3.6" [[package]] name = "pylint" -version = "2.15.6" +version = "2.15.8" description = "python code static checker" category = "dev" optional = false python-versions = ">=3.7.2" [package.dependencies] -astroid = ">=2.12.12,<=2.14.0-dev0" +astroid = ">=2.12.13,<=2.14.0-dev0" colorama = {version = ">=0.4.5", markers = "sys_platform == \"win32\""} dill = ">=0.2" isort = ">=4.2.5,<6" @@ -397,7 +497,7 @@ optional = false python-versions = ">=3.6.8" [package.extras] -diagrams = ["railroad-diagrams", "jinja2"] +diagrams = ["jinja2", "railroad-diagrams"] [[package]] name = "pytest" @@ -432,7 +532,7 @@ coverage = {version = ">=5.2.1", extras = ["toml"]} pytest = ">=4.6" [package.extras] -testing = ["fields", "hunter", "process-tests", "six", "pytest-xdist", "virtualenv"] +testing = ["fields", "hunter", "process-tests", "pytest-xdist", "six", "virtualenv"] [[package]] name = "pytest-django" @@ -447,7 +547,7 @@ pytest = ">=5.4.0" [package.extras] docs = ["sphinx", "sphinx-rtd-theme"] -testing = ["django", "django-configurations (>=2.0)"] +testing = ["Django", "django-configurations (>=2.0)"] [[package]] name = "pytest-forked" @@ -463,11 +563,11 @@ pytest = ">=3.10" [[package]] name = "pytest-xdist" -version = "3.0.2" -description = "pytest xdist plugin for distributed testing and loop-on-failing modes" +version = "3.1.0" +description = "pytest xdist plugin for distributed testing, most importantly across multiple CPUs" category = "dev" optional = false -python-versions = ">=3.6" +python-versions = ">=3.7" [package.dependencies] execnet = ">=1.1" @@ -509,12 +609,13 @@ optional = false python-versions = ">=3.7" [package.dependencies] +appdirs = {version = ">=1.4.4", optional = true, markers = "extra == \"global\""} packaging = ">=21.3" tomli = {version = ">=2.0", markers = "python_version < \"3.11\""} [package.extras] -doc = ["tabulate (>=0.8.9)", "sphinx (>=4.5.0)"] -gen_docs = ["sphinx (>=4.5.0)", "sphinx-autodoc-typehints (>=1.18.1)", "sphinx-rtd-theme (>=1.0.0)", "pytoolconfig"] +doc = ["sphinx (>=4.5.0)", "tabulate (>=0.8.9)"] +gen-docs = ["pytoolconfig[doc]", "sphinx (>=4.5.0)", "sphinx-autodoc-typehints (>=1.18.1)", "sphinx-rtd-theme (>=1.0.0)"] global = ["appdirs (>=1.4.4)"] validation = ["pydantic (>=1.7.4)"] @@ -528,18 +629,31 @@ python-versions = ">=3.6" [[package]] name = "rope" -version = "1.4.0" +version = "1.5.1" description = "a python refactoring library..." category = "dev" optional = false python-versions = ">=3.7" [package.dependencies] -pytoolconfig = ">=1.2.2" +pytoolconfig = {version = ">=1.2.2", extras = ["global"]} [package.extras] -dev = ["pytest (>=7.0.1)", "pytest-timeout (>=2.1.0)", "build (>=0.7.0)"] -doc = ["pytoolconfig", "sphinx (>=4.5.0)", "sphinx-autodoc-typehints (>=1.18.1)", "sphinx-rtd-theme (>=1.0.0)"] +dev = ["build (>=0.7.0)", "pytest (>=7.0.1)", "pytest-timeout (>=2.1.0)"] +doc = ["pytoolconfig[doc]", "sphinx (>=4.5.0)", "sphinx-autodoc-typehints (>=1.18.1)", "sphinx-rtd-theme (>=1.0.0)"] + +[[package]] +name = "setuptools" +version = "65.6.0" +description = "Easily download, build, install, upgrade, and uninstall Python packages" +category = "main" +optional = false +python-versions = ">=3.7" + +[package.extras] +docs = ["furo", "jaraco.packaging (>=9)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-hoverxref (<2)", "sphinx-inline-tabs", "sphinx-notfound-page (==0.8.3)", "sphinx-reredirects", "sphinxcontrib-towncrier"] +testing = ["build[virtualenv]", "filelock (>=3.4.0)", "flake8 (<5)", "flake8-2020", "ini2toml[lite] (>=0.9)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "pip (>=19.1)", "pip-run (>=8.8)", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=1.3)", "pytest-flake8", "pytest-mypy (>=0.9.1)", "pytest-perf", "pytest-timeout", "pytest-xdist", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel"] +testing-integration = ["build[virtualenv]", "filelock (>=3.4.0)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "pytest", "pytest-enabler", "pytest-xdist", "tomli", "virtualenv (>=13.0.0)", "wheel"] [[package]] name = "six" @@ -608,9 +722,13 @@ python-versions = "*" [metadata] lock-version = "1.1" python-versions = "^3.9" -content-hash = "2df46002260c10992a8076be9cc26c13473e016f2a404aeed750c8eda149828d" +content-hash = "497467f8cce845c8f08bbbdc259f9faaf212af95639356eff39ad0240a0f22b6" [metadata.files] +appdirs = [ + {file = "appdirs-1.4.4-py2.py3-none-any.whl", hash = "sha256:a841dacd6b99318a741b166adb07e19ee71a274450e68237b4650ca1055ab128"}, + {file = "appdirs-1.4.4.tar.gz", hash = "sha256:7d5d0167b2b1ba821647616af46a749d1c653740dd0d2415100fe26e27afdf41"}, +] asgiref = [ {file = "asgiref-3.5.2-py3-none-any.whl", hash = "sha256:1d2880b792ae8757289136f1db2b7b99100ce959b2aa57fd69dab783d05afac4"}, {file = "asgiref-3.5.2.tar.gz", hash = "sha256:4a29362a6acebe09bf1d6640db38c1dc3d9217c68e6f9f6204d72667fc19a424"}, @@ -623,6 +741,37 @@ attrs = [ {file = "attrs-22.1.0-py2.py3-none-any.whl", hash = "sha256:86efa402f67bf2df34f51a335487cf46b1ec130d02b8d39fd248abfd30da551c"}, {file = "attrs-22.1.0.tar.gz", hash = "sha256:29adc2665447e5191d0e7c568fde78b21f9672d344281d0c6e1ab085429b22b6"}, ] +autopep8 = [ + {file = "autopep8-2.0.0-py2.py3-none-any.whl", hash = "sha256:ad924b42c2e27a1ac58e432166cc4588f5b80747de02d0d35b1ecbd3e7d57207"}, + {file = "autopep8-2.0.0.tar.gz", hash = "sha256:8b1659c7f003e693199f52caffdc06585bb0716900bbc6a7442fd931d658c077"}, +] +black = [ + {file = "black-22.10.0-1fixedarch-cp310-cp310-macosx_11_0_x86_64.whl", hash = "sha256:5cc42ca67989e9c3cf859e84c2bf014f6633db63d1cbdf8fdb666dcd9e77e3fa"}, + {file = "black-22.10.0-1fixedarch-cp311-cp311-macosx_11_0_x86_64.whl", hash = "sha256:5d8f74030e67087b219b032aa33a919fae8806d49c867846bfacde57f43972ef"}, + {file = "black-22.10.0-1fixedarch-cp37-cp37m-macosx_10_16_x86_64.whl", hash = "sha256:197df8509263b0b8614e1df1756b1dd41be6738eed2ba9e9769f3880c2b9d7b6"}, + {file = "black-22.10.0-1fixedarch-cp38-cp38-macosx_10_16_x86_64.whl", hash = "sha256:2644b5d63633702bc2c5f3754b1b475378fbbfb481f62319388235d0cd104c2d"}, + {file = "black-22.10.0-1fixedarch-cp39-cp39-macosx_11_0_x86_64.whl", hash = "sha256:e41a86c6c650bcecc6633ee3180d80a025db041a8e2398dcc059b3afa8382cd4"}, + {file = "black-22.10.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:2039230db3c6c639bd84efe3292ec7b06e9214a2992cd9beb293d639c6402edb"}, + {file = "black-22.10.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:14ff67aec0a47c424bc99b71005202045dc09270da44a27848d534600ac64fc7"}, + {file = "black-22.10.0-cp310-cp310-win_amd64.whl", hash = "sha256:819dc789f4498ecc91438a7de64427c73b45035e2e3680c92e18795a839ebb66"}, + {file = "black-22.10.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:5b9b29da4f564ba8787c119f37d174f2b69cdfdf9015b7d8c5c16121ddc054ae"}, + {file = "black-22.10.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b8b49776299fece66bffaafe357d929ca9451450f5466e997a7285ab0fe28e3b"}, + {file = "black-22.10.0-cp311-cp311-win_amd64.whl", hash = "sha256:21199526696b8f09c3997e2b4db8d0b108d801a348414264d2eb8eb2532e540d"}, + {file = "black-22.10.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1e464456d24e23d11fced2bc8c47ef66d471f845c7b7a42f3bd77bf3d1789650"}, + {file = "black-22.10.0-cp37-cp37m-win_amd64.whl", hash = "sha256:9311e99228ae10023300ecac05be5a296f60d2fd10fff31cf5c1fa4ca4b1988d"}, + {file = "black-22.10.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:fba8a281e570adafb79f7755ac8721b6cf1bbf691186a287e990c7929c7692ff"}, + {file = "black-22.10.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:915ace4ff03fdfff953962fa672d44be269deb2eaf88499a0f8805221bc68c87"}, + {file = "black-22.10.0-cp38-cp38-win_amd64.whl", hash = "sha256:444ebfb4e441254e87bad00c661fe32df9969b2bf224373a448d8aca2132b395"}, + {file = "black-22.10.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:974308c58d057a651d182208a484ce80a26dac0caef2895836a92dd6ebd725e0"}, + {file = "black-22.10.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:72ef3925f30e12a184889aac03d77d031056860ccae8a1e519f6cbb742736383"}, + {file = "black-22.10.0-cp39-cp39-win_amd64.whl", hash = "sha256:432247333090c8c5366e69627ccb363bc58514ae3e63f7fc75c54b1ea80fa7de"}, + {file = "black-22.10.0-py3-none-any.whl", hash = "sha256:c957b2b4ea88587b46cf49d1dc17681c1e672864fd7af32fc1e9664d572b3458"}, + {file = "black-22.10.0.tar.gz", hash = "sha256:f513588da599943e0cde4e32cc9879e825d58720d6557062d1098c5ad80080e1"}, +] +click = [ + {file = "click-8.1.3-py3-none-any.whl", hash = "sha256:bb4d8133cb15a609f44e8213d9b391b0809795062913b383c62be0ee95b1db48"}, + {file = "click-8.1.3.tar.gz", hash = "sha256:7682dc8afb30297001674575ea00d1814d808d6a36af415a82bd481d37ba7b8e"}, +] colorama = [ {file = "colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6"}, {file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"}, @@ -732,8 +881,8 @@ faker = [ {file = "Faker-12.0.1.tar.gz", hash = "sha256:aa7103805ae793277abbb85da9f6f05e76a1a295a9384a8e17c2fba2b3a690cb"}, ] flake8 = [ - {file = "flake8-5.0.4-py2.py3-none-any.whl", hash = "sha256:7a1cf6b73744f5806ab95e526f6f0d8c01c66d7bbe349562d22dfca20610b248"}, - {file = "flake8-5.0.4.tar.gz", hash = "sha256:6fbe320aad8d6b95cec8b8e47bc933004678dc63095be98528b7bdd2a9f510db"}, + {file = "flake8-6.0.0-py2.py3-none-any.whl", hash = "sha256:3833794e27ff64ea4e9cf5d410082a8b97ff1a06c16aa3d2027339cd0f1195c7"}, + {file = "flake8-6.0.0.tar.gz", hash = "sha256:c61007e76655af75e6785a931f452915b371dc48f56efd765247c8fe68f2b181"}, ] gunicorn = [ {file = "gunicorn-20.1.0-py3-none-any.whl", hash = "sha256:9dcc4547dbb1cb284accfb15ab5667a0e5d1881cc443e0677b4882a4067a807e"}, @@ -747,6 +896,10 @@ isort = [ {file = "isort-5.10.1-py3-none-any.whl", hash = "sha256:6f62d78e2f89b4500b080fe3a81690850cd254227f27f75c3a0c491a1f351ba7"}, {file = "isort-5.10.1.tar.gz", hash = "sha256:e8443a5e7a020e9d7f97f1d7d9cd17c88bcb3bc7e218bf9cf5095fe550be2951"}, ] +jedi = [ + {file = "jedi-0.18.2-py2.py3-none-any.whl", hash = "sha256:203c1fd9d969ab8f2119ec0a3342e0b49910045abe6af0a3ae83a5764d54639e"}, + {file = "jedi-0.18.2.tar.gz", hash = "sha256:bae794c30d07f6d910d32a7048af09b5a39ed740918da923c6b780790ebac612"}, +] lazy-object-proxy = [ {file = "lazy-object-proxy-1.8.0.tar.gz", hash = "sha256:c219a00245af0f6fa4e95901ed28044544f50152840c5b6a3e7b2568db34d156"}, {file = "lazy_object_proxy-1.8.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:4fd031589121ad46e293629b39604031d354043bb5cdf83da4e93c2d7f3389fe"}, @@ -776,10 +929,22 @@ mixer = [ {file = "mixer-7.2.2-py3-none-any.whl", hash = "sha256:8089b8e2d00288c77e622936198f5dd03c8ac1603a1530a4f870dc213363b2ae"}, {file = "mixer-7.2.2.tar.gz", hash = "sha256:9b3f1a261b56d8f2394f39955f83adbc7ff3ab4bb1065ebfec19a10d3e8501e0"}, ] +mypy-extensions = [ + {file = "mypy_extensions-0.4.3-py2.py3-none-any.whl", hash = "sha256:090fedd75945a69ae91ce1303b5824f428daf5a028d2f6ab8a299250a846f15d"}, + {file = "mypy_extensions-0.4.3.tar.gz", hash = "sha256:2d82818f5bb3e369420cb3c4060a7970edba416647068eb4c5343488a6c604a8"}, +] packaging = [ {file = "packaging-21.3-py3-none-any.whl", hash = "sha256:ef103e05f519cdc783ae24ea4e2e0f508a9c99b2d4969652eed6a2e1ea5bd522"}, {file = "packaging-21.3.tar.gz", hash = "sha256:dd47c42927d89ab911e606518907cc2d3a1f38bbd026385970643f9c5b8ecfeb"}, ] +parso = [ + {file = "parso-0.8.3-py2.py3-none-any.whl", hash = "sha256:c001d4636cd3aecdaf33cbb40aebb59b094be2a74c556778ef5576c175e19e75"}, + {file = "parso-0.8.3.tar.gz", hash = "sha256:8c07be290bb59f03588915921e29e8a50002acaf2cdc5fa0e0114f91709fafa0"}, +] +pathspec = [ + {file = "pathspec-0.10.2-py3-none-any.whl", hash = "sha256:88c2606f2c1e818b978540f73ecc908e13999c6c3a383daf3705652ae79807a5"}, + {file = "pathspec-0.10.2.tar.gz", hash = "sha256:8f6bf73e5758fd365ef5d58ce09ac7c27d2833a8d7da51712eac6e27e35141b0"}, +] pep8 = [ {file = "pep8-1.7.1-py2.py3-none-any.whl", hash = "sha256:b22cfae5db09833bb9bd7c8463b53e1a9c9b39f12e304a8d0bba729c501827ee"}, {file = "pep8-1.7.1.tar.gz", hash = "sha256:fe249b52e20498e59e0b5c5256aa52ee99fc295b26ec9eaa85776ffdb9fe6374"}, @@ -870,16 +1035,16 @@ py = [ {file = "py-1.11.0.tar.gz", hash = "sha256:51c75c4126074b472f746a24399ad32f6053d1b34b68d2fa41e558e6f4a98719"}, ] pycodestyle = [ - {file = "pycodestyle-2.9.1-py2.py3-none-any.whl", hash = "sha256:d1735fc58b418fd7c5f658d28d943854f8a849b01a5d0a1e6f3f3fdd0166804b"}, - {file = "pycodestyle-2.9.1.tar.gz", hash = "sha256:2c9607871d58c76354b697b42f5d57e1ada7d261c261efac224b664affdc5785"}, + {file = "pycodestyle-2.10.0-py2.py3-none-any.whl", hash = "sha256:8a4eaf0d0495c7395bdab3589ac2db602797d76207242c17d470186815706610"}, + {file = "pycodestyle-2.10.0.tar.gz", hash = "sha256:347187bdb476329d98f695c213d7295a846d1152ff4fe9bacb8a9590b8ee7053"}, ] pyflakes = [ - {file = "pyflakes-2.5.0-py2.py3-none-any.whl", hash = "sha256:4579f67d887f804e67edb544428f264b7b24f435b263c4614f384135cea553d2"}, - {file = "pyflakes-2.5.0.tar.gz", hash = "sha256:491feb020dca48ccc562a8c0cbe8df07ee13078df59813b83959cbdada312ea3"}, + {file = "pyflakes-3.0.1-py2.py3-none-any.whl", hash = "sha256:ec55bf7fe21fff7f1ad2f7da62363d749e2a470500eab1b555334b67aa1ef8cf"}, + {file = "pyflakes-3.0.1.tar.gz", hash = "sha256:ec8b276a6b60bd80defed25add7e439881c19e64850afd9b346283d4165fd0fd"}, ] pylint = [ - {file = "pylint-2.15.6-py3-none-any.whl", hash = "sha256:15060cc22ed6830a4049cf40bc24977744df2e554d38da1b2657591de5bcd052"}, - {file = "pylint-2.15.6.tar.gz", hash = "sha256:25b13ddcf5af7d112cf96935e21806c1da60e676f952efb650130f2a4483421c"}, + {file = "pylint-2.15.8-py3-none-any.whl", hash = "sha256:ea82cd6a1e11062dc86d555d07c021b0fb65afe39becbe6fe692efd6c4a67443"}, + {file = "pylint-2.15.8.tar.gz", hash = "sha256:ec4a87c33da054ab86a6c79afa6771dc8765cb5631620053e727fcf3ef8cbed7"}, ] pyparsing = [ {file = "pyparsing-3.0.9-py3-none-any.whl", hash = "sha256:5026bae9a10eeaefb61dab2f09052b9f4307d44aee4eda64b309723d8d206bbc"}, @@ -902,8 +1067,8 @@ pytest-forked = [ {file = "pytest_forked-1.4.0-py3-none-any.whl", hash = "sha256:bbbb6717efc886b9d64537b41fb1497cfaf3c9601276be8da2cccfea5a3c8ad8"}, ] pytest-xdist = [ - {file = "pytest-xdist-3.0.2.tar.gz", hash = "sha256:688da9b814370e891ba5de650c9327d1a9d861721a524eb917e620eec3e90291"}, - {file = "pytest_xdist-3.0.2-py3-none-any.whl", hash = "sha256:9feb9a18e1790696ea23e1434fa73b325ed4998b0e9fcb221f16fd1945e6df1b"}, + {file = "pytest-xdist-3.1.0.tar.gz", hash = "sha256:40fdb8f3544921c5dfcd486ac080ce22870e71d82ced6d2e78fa97c2addd480c"}, + {file = "pytest_xdist-3.1.0-py3-none-any.whl", hash = "sha256:70a76f191d8a1d2d6be69fc440cdf85f3e4c03c08b520fd5dc5d338d6cf07d89"}, ] python-dateutil = [ {file = "python-dateutil-2.8.2.tar.gz", hash = "sha256:0123cacc1627ae19ddf3c27a5de5bd67ee4586fbdd6440d9748f8abb483d3e86"}, @@ -960,8 +1125,12 @@ pyyaml = [ {file = "PyYAML-6.0.tar.gz", hash = "sha256:68fb519c14306fec9720a2a5b45bc9f0c8d1b9c72adf45c37baedfcd949c35a2"}, ] rope = [ - {file = "rope-1.4.0-py3-none-any.whl", hash = "sha256:27c122389fa5cdffa00c24aa6c63704e0933650dbc7d4d4002537947d6cfb7b7"}, - {file = "rope-1.4.0.tar.gz", hash = "sha256:7d5a34235ff4a242b71f249b5617a9c54112e145ba4701a41e2f4f96942e5899"}, + {file = "rope-1.5.1-py3-none-any.whl", hash = "sha256:d0514b3cddb1a9e103a040756fb53674828d73df70282b7d7d783a220b0354d8"}, + {file = "rope-1.5.1.tar.gz", hash = "sha256:9761758c222df9466f08232bc046d182960ffa881c1c53bca9fafff210e8da7c"}, +] +setuptools = [ + {file = "setuptools-65.6.0-py3-none-any.whl", hash = "sha256:6211d2f5eddad8757bd0484923ca7c0a6302ebc4ab32ea5e94357176e0ca0840"}, + {file = "setuptools-65.6.0.tar.gz", hash = "sha256:d1eebf881c6114e51df1664bc2c9133d022f78d12d5f4f665b9191f084e2862d"}, ] six = [ {file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"}, diff --git a/pyproject.toml b/pyproject.toml index dd802de..689226f 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -7,6 +7,9 @@ version = "0.1.0" description = "" authors = ["Andreas Zweili "] license = "GPLv3" +packages = [ + { include = "src" }, +] [tool.poetry.dependencies] python = "^3.9" @@ -24,17 +27,20 @@ psycopg2-binary = "^2.9.5" PyYAML = "^6.0" [tool.poetry.dev-dependencies] +autopep8 = "^2.0.0" +black = "^22.10.0" coverage = "^6.5.0" -flake8 = "^5.0.4" +flake8 = "^6.0.0" +jedi = "^0.18.2" mixer = "^7.2.2" pep8 = "^1.7.1" -pylint = "^2.15.5" +pylint = "^2.15.8" pytest = "^7.2.0" pytest-cov = "^4.0.0" pytest-django = "^4.5.2" pytest-forked = "^1.4.0" -pytest-xdist = "^3.0.2" -rope = "^1.4.0" +pytest-xdist = "^3.1.0" +rope = "^1.5.1" yapf = "^0.32.0" [build-system] diff --git a/run.sh b/run.sh index 4c8f3c1..666f240 100755 --- a/run.sh +++ b/run.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash if [ -f .second_run ]; then sleep 2 python manage.py collectstatic --noinput diff --git a/backups/__init__.py b/src/backups/__init__.py similarity index 100% rename from backups/__init__.py rename to src/backups/__init__.py diff --git a/backups/admin.py b/src/backups/admin.py similarity index 100% rename from backups/admin.py rename to src/backups/admin.py diff --git a/backups/apps.py b/src/backups/apps.py similarity index 100% rename from backups/apps.py rename to src/backups/apps.py diff --git a/backups/decorators.py b/src/backups/decorators.py similarity index 100% rename from backups/decorators.py rename to src/backups/decorators.py diff --git a/backups/fixtures/backups.yaml b/src/backups/fixtures/backups.yaml similarity index 100% rename from backups/fixtures/backups.yaml rename to src/backups/fixtures/backups.yaml diff --git a/backups/models/__init__.py b/src/backups/models/__init__.py similarity index 100% rename from backups/models/__init__.py rename to src/backups/models/__init__.py diff --git a/backups/models/backup.py b/src/backups/models/backup.py similarity index 100% rename from backups/models/backup.py rename to src/backups/models/backup.py diff --git a/backups/models/notification.py b/src/backups/models/notification.py similarity index 100% rename from backups/models/notification.py rename to src/backups/models/notification.py diff --git a/backups/tables.py b/src/backups/tables.py similarity index 100% rename from backups/tables.py rename to src/backups/tables.py diff --git a/backups/templates/backups/backup_confirm_delete.html b/src/backups/templates/backups/backup_confirm_delete.html similarity index 100% rename from backups/templates/backups/backup_confirm_delete.html rename to src/backups/templates/backups/backup_confirm_delete.html diff --git a/backups/templates/backups/backup_create.html b/src/backups/templates/backups/backup_create.html similarity index 100% rename from backups/templates/backups/backup_create.html rename to src/backups/templates/backups/backup_create.html diff --git a/backups/templates/backups/backup_details.html b/src/backups/templates/backups/backup_details.html similarity index 100% rename from backups/templates/backups/backup_details.html rename to src/backups/templates/backups/backup_details.html diff --git a/backups/templates/backups/backup_list.html b/src/backups/templates/backups/backup_list.html similarity index 100% rename from backups/templates/backups/backup_list.html rename to src/backups/templates/backups/backup_list.html diff --git a/backups/tests/test_backup.py b/src/backups/tests/test_backup.py similarity index 100% rename from backups/tests/test_backup.py rename to src/backups/tests/test_backup.py diff --git a/backups/tests/test_backup_detail_view.py b/src/backups/tests/test_backup_detail_view.py similarity index 100% rename from backups/tests/test_backup_detail_view.py rename to src/backups/tests/test_backup_detail_view.py diff --git a/backups/tests/test_backup_form_view.py b/src/backups/tests/test_backup_form_view.py similarity index 100% rename from backups/tests/test_backup_form_view.py rename to src/backups/tests/test_backup_form_view.py diff --git a/backups/tests/test_customer_backup_table_view.py b/src/backups/tests/test_customer_backup_table_view.py similarity index 100% rename from backups/tests/test_customer_backup_table_view.py rename to src/backups/tests/test_customer_backup_table_view.py diff --git a/backups/urls.py b/src/backups/urls.py similarity index 100% rename from backups/urls.py rename to src/backups/urls.py diff --git a/backups/views.py b/src/backups/views.py similarity index 100% rename from backups/views.py rename to src/backups/views.py diff --git a/computers/__init__.py b/src/computers/__init__.py similarity index 100% rename from computers/__init__.py rename to src/computers/__init__.py diff --git a/computers/admin.py b/src/computers/admin.py similarity index 100% rename from computers/admin.py rename to src/computers/admin.py diff --git a/computers/apps.py b/src/computers/apps.py similarity index 100% rename from computers/apps.py rename to src/computers/apps.py diff --git a/computers/filters.py b/src/computers/filters.py similarity index 100% rename from computers/filters.py rename to src/computers/filters.py diff --git a/computers/fixtures/computers.yaml b/src/computers/fixtures/computers.yaml similarity index 100% rename from computers/fixtures/computers.yaml rename to src/computers/fixtures/computers.yaml diff --git a/computers/forms.py b/src/computers/forms.py similarity index 100% rename from computers/forms.py rename to src/computers/forms.py diff --git a/computers/models/__init__.py b/src/computers/models/__init__.py similarity index 100% rename from computers/models/__init__.py rename to src/computers/models/__init__.py diff --git a/computers/models/computer.py b/src/computers/models/computer.py similarity index 100% rename from computers/models/computer.py rename to src/computers/models/computer.py diff --git a/computers/models/cpu.py b/src/computers/models/cpu.py similarity index 100% rename from computers/models/cpu.py rename to src/computers/models/cpu.py diff --git a/computers/models/disk.py b/src/computers/models/disk.py similarity index 100% rename from computers/models/disk.py rename to src/computers/models/disk.py diff --git a/computers/models/gpu.py b/src/computers/models/gpu.py similarity index 100% rename from computers/models/gpu.py rename to src/computers/models/gpu.py diff --git a/computers/models/raid.py b/src/computers/models/raid.py similarity index 100% rename from computers/models/raid.py rename to src/computers/models/raid.py diff --git a/computers/models/ram.py b/src/computers/models/ram.py similarity index 100% rename from computers/models/ram.py rename to src/computers/models/ram.py diff --git a/computers/static/inventory/css/inventory.css b/src/computers/static/inventory/css/inventory.css similarity index 100% rename from computers/static/inventory/css/inventory.css rename to src/computers/static/inventory/css/inventory.css diff --git a/computers/static/inventory/js/sorttable.js b/src/computers/static/inventory/js/sorttable.js similarity index 100% rename from computers/static/inventory/js/sorttable.js rename to src/computers/static/inventory/js/sorttable.js diff --git a/computers/tables.py b/src/computers/tables.py similarity index 100% rename from computers/tables.py rename to src/computers/tables.py diff --git a/computers/templates/computers/all_computers.html b/src/computers/templates/computers/all_computers.html similarity index 100% rename from computers/templates/computers/all_computers.html rename to src/computers/templates/computers/all_computers.html diff --git a/computers/templates/computers/computer_create.html b/src/computers/templates/computers/computer_create.html similarity index 100% rename from computers/templates/computers/computer_create.html rename to src/computers/templates/computers/computer_create.html diff --git a/computers/templates/computers/computer_details.html b/src/computers/templates/computers/computer_details.html similarity index 100% rename from computers/templates/computers/computer_details.html rename to src/computers/templates/computers/computer_details.html diff --git a/computers/templates/computers/computer_list.html b/src/computers/templates/computers/computer_list.html similarity index 100% rename from computers/templates/computers/computer_list.html rename to src/computers/templates/computers/computer_list.html diff --git a/computers/templates/computers/computer_update.html b/src/computers/templates/computers/computer_update.html similarity index 100% rename from computers/templates/computers/computer_update.html rename to src/computers/templates/computers/computer_update.html diff --git a/computers/templates/computers/cpu_relation_create.html b/src/computers/templates/computers/cpu_relation_create.html similarity index 100% rename from computers/templates/computers/cpu_relation_create.html rename to src/computers/templates/computers/cpu_relation_create.html diff --git a/computers/templates/computers/cronjob_details.html b/src/computers/templates/computers/cronjob_details.html similarity index 100% rename from computers/templates/computers/cronjob_details.html rename to src/computers/templates/computers/cronjob_details.html diff --git a/computers/templates/computers/cronjob_list.html b/src/computers/templates/computers/cronjob_list.html similarity index 100% rename from computers/templates/computers/cronjob_list.html rename to src/computers/templates/computers/cronjob_list.html diff --git a/computers/templates/computers/disk_relation_create.html b/src/computers/templates/computers/disk_relation_create.html similarity index 100% rename from computers/templates/computers/disk_relation_create.html rename to src/computers/templates/computers/disk_relation_create.html diff --git a/computers/templates/computers/gpu_relation_create.html b/src/computers/templates/computers/gpu_relation_create.html similarity index 100% rename from computers/templates/computers/gpu_relation_create.html rename to src/computers/templates/computers/gpu_relation_create.html diff --git a/computers/templates/computers/raid_create.html b/src/computers/templates/computers/raid_create.html similarity index 100% rename from computers/templates/computers/raid_create.html rename to src/computers/templates/computers/raid_create.html diff --git a/computers/templates/computers/ram_relation_create.html b/src/computers/templates/computers/ram_relation_create.html similarity index 100% rename from computers/templates/computers/ram_relation_create.html rename to src/computers/templates/computers/ram_relation_create.html diff --git a/computers/templates/computers/relation_confirm_delete.html b/src/computers/templates/computers/relation_confirm_delete.html similarity index 100% rename from computers/templates/computers/relation_confirm_delete.html rename to src/computers/templates/computers/relation_confirm_delete.html diff --git a/computers/templates/computers/software_relation_create.html b/src/computers/templates/computers/software_relation_create.html similarity index 100% rename from computers/templates/computers/software_relation_create.html rename to src/computers/templates/computers/software_relation_create.html diff --git a/computers/tests/test_computer.py b/src/computers/tests/test_computer.py similarity index 100% rename from computers/tests/test_computer.py rename to src/computers/tests/test_computer.py diff --git a/computers/tests/test_computer_detail_view.py b/src/computers/tests/test_computer_detail_view.py similarity index 100% rename from computers/tests/test_computer_detail_view.py rename to src/computers/tests/test_computer_detail_view.py diff --git a/computers/tests/test_computer_form.py b/src/computers/tests/test_computer_form.py similarity index 100% rename from computers/tests/test_computer_form.py rename to src/computers/tests/test_computer_form.py diff --git a/computers/tests/test_computer_form_views.py b/src/computers/tests/test_computer_form_views.py similarity index 100% rename from computers/tests/test_computer_form_views.py rename to src/computers/tests/test_computer_form_views.py diff --git a/computers/tests/test_computer_list_view.py b/src/computers/tests/test_computer_list_view.py similarity index 100% rename from computers/tests/test_computer_list_view.py rename to src/computers/tests/test_computer_list_view.py diff --git a/computers/tests/test_customer_computer_table_view.py b/src/computers/tests/test_customer_computer_table_view.py similarity index 100% rename from computers/tests/test_customer_computer_table_view.py rename to src/computers/tests/test_customer_computer_table_view.py diff --git a/computers/urls.py b/src/computers/urls.py similarity index 100% rename from computers/urls.py rename to src/computers/urls.py diff --git a/computers/views.py b/src/computers/views.py similarity index 100% rename from computers/views.py rename to src/computers/views.py diff --git a/conftest.py b/src/conftest.py similarity index 100% rename from conftest.py rename to src/conftest.py diff --git a/core/__init__.py b/src/core/__init__.py similarity index 100% rename from core/__init__.py rename to src/core/__init__.py diff --git a/core/admin.py b/src/core/admin.py similarity index 100% rename from core/admin.py rename to src/core/admin.py diff --git a/core/apps.py b/src/core/apps.py similarity index 100% rename from core/apps.py rename to src/core/apps.py diff --git a/core/fixtures/core.yaml b/src/core/fixtures/core.yaml similarity index 100% rename from core/fixtures/core.yaml rename to src/core/fixtures/core.yaml diff --git a/core/models/__init__.py b/src/core/models/__init__.py similarity index 100% rename from core/models/__init__.py rename to src/core/models/__init__.py diff --git a/core/models/calendar.py b/src/core/models/calendar.py similarity index 100% rename from core/models/calendar.py rename to src/core/models/calendar.py diff --git a/core/models/category.py b/src/core/models/category.py similarity index 100% rename from core/models/category.py rename to src/core/models/category.py diff --git a/core/models/company.py b/src/core/models/company.py similarity index 100% rename from core/models/company.py rename to src/core/models/company.py diff --git a/core/models/time.py b/src/core/models/time.py similarity index 100% rename from core/models/time.py rename to src/core/models/time.py diff --git a/core/models/user.py b/src/core/models/user.py similarity index 100% rename from core/models/user.py rename to src/core/models/user.py diff --git a/core/static/core/css/bootstrap-grid.css b/src/core/static/core/css/bootstrap-grid.css similarity index 100% rename from core/static/core/css/bootstrap-grid.css rename to src/core/static/core/css/bootstrap-grid.css diff --git a/core/static/core/css/bootstrap-grid.css.map b/src/core/static/core/css/bootstrap-grid.css.map similarity index 100% rename from core/static/core/css/bootstrap-grid.css.map rename to src/core/static/core/css/bootstrap-grid.css.map diff --git a/core/static/core/css/bootstrap-grid.min.css b/src/core/static/core/css/bootstrap-grid.min.css similarity index 100% rename from core/static/core/css/bootstrap-grid.min.css rename to src/core/static/core/css/bootstrap-grid.min.css diff --git a/core/static/core/css/bootstrap-grid.min.css.map b/src/core/static/core/css/bootstrap-grid.min.css.map similarity index 100% rename from core/static/core/css/bootstrap-grid.min.css.map rename to src/core/static/core/css/bootstrap-grid.min.css.map diff --git a/core/static/core/css/bootstrap-reboot.css b/src/core/static/core/css/bootstrap-reboot.css similarity index 100% rename from core/static/core/css/bootstrap-reboot.css rename to src/core/static/core/css/bootstrap-reboot.css diff --git a/core/static/core/css/bootstrap-reboot.css.map b/src/core/static/core/css/bootstrap-reboot.css.map similarity index 100% rename from core/static/core/css/bootstrap-reboot.css.map rename to src/core/static/core/css/bootstrap-reboot.css.map diff --git a/core/static/core/css/bootstrap-reboot.min.css b/src/core/static/core/css/bootstrap-reboot.min.css similarity index 100% rename from core/static/core/css/bootstrap-reboot.min.css rename to src/core/static/core/css/bootstrap-reboot.min.css diff --git a/core/static/core/css/bootstrap-reboot.min.css.map b/src/core/static/core/css/bootstrap-reboot.min.css.map similarity index 100% rename from core/static/core/css/bootstrap-reboot.min.css.map rename to src/core/static/core/css/bootstrap-reboot.min.css.map diff --git a/core/static/core/css/bootstrap.css b/src/core/static/core/css/bootstrap.css similarity index 100% rename from core/static/core/css/bootstrap.css rename to src/core/static/core/css/bootstrap.css diff --git a/core/static/core/css/bootstrap.css.map b/src/core/static/core/css/bootstrap.css.map similarity index 100% rename from core/static/core/css/bootstrap.css.map rename to src/core/static/core/css/bootstrap.css.map diff --git a/core/static/core/css/bootstrap.min.css b/src/core/static/core/css/bootstrap.min.css similarity index 100% rename from core/static/core/css/bootstrap.min.css rename to src/core/static/core/css/bootstrap.min.css diff --git a/core/static/core/css/bootstrap.min.css.map b/src/core/static/core/css/bootstrap.min.css.map similarity index 100% rename from core/static/core/css/bootstrap.min.css.map rename to src/core/static/core/css/bootstrap.min.css.map diff --git a/core/static/core/css/material-icons.css b/src/core/static/core/css/material-icons.css similarity index 100% rename from core/static/core/css/material-icons.css rename to src/core/static/core/css/material-icons.css diff --git a/core/static/core/fonts/MaterialIcons-Regular.eot b/src/core/static/core/fonts/MaterialIcons-Regular.eot similarity index 100% rename from core/static/core/fonts/MaterialIcons-Regular.eot rename to src/core/static/core/fonts/MaterialIcons-Regular.eot diff --git a/core/static/core/fonts/MaterialIcons-Regular.ttf b/src/core/static/core/fonts/MaterialIcons-Regular.ttf similarity index 100% rename from core/static/core/fonts/MaterialIcons-Regular.ttf rename to src/core/static/core/fonts/MaterialIcons-Regular.ttf diff --git a/core/static/core/fonts/MaterialIcons-Regular.woff b/src/core/static/core/fonts/MaterialIcons-Regular.woff similarity index 100% rename from core/static/core/fonts/MaterialIcons-Regular.woff rename to src/core/static/core/fonts/MaterialIcons-Regular.woff diff --git a/core/static/core/fonts/MaterialIcons-Regular.woff2 b/src/core/static/core/fonts/MaterialIcons-Regular.woff2 similarity index 100% rename from core/static/core/fonts/MaterialIcons-Regular.woff2 rename to src/core/static/core/fonts/MaterialIcons-Regular.woff2 diff --git a/core/static/core/img/favicon.ico b/src/core/static/core/img/favicon.ico similarity index 100% rename from core/static/core/img/favicon.ico rename to src/core/static/core/img/favicon.ico diff --git a/src/core/static/core/js/htmx.js b/src/core/static/core/js/htmx.js new file mode 100644 index 0000000..556de48 --- /dev/null +++ b/src/core/static/core/js/htmx.js @@ -0,0 +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("",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(""+e+"
",1);case"col":return l(""+e+"
",2);case"tr":return l(""+e+"
",2);case"td":case"th":return l(""+e+"
",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(/]*>|>)([\s\S]*?)<\/svg>/gim,"");var r=t.match(/]*>|>)([\s\S]*?)<\/title>/im);if(r){return r[2]}}}function Oe(e,t,r,n,i){i.title=Re(n);var a=g(n);if(a){z(r,a,i);a=Ee(r,a);se(a);return Ce(e,r,t,a,i)}}function qe(e,t,r){var n=e.getResponseHeader(t);if(n.indexOf("{")===0){var i=S(n);for(var a in i){if(i.hasOwnProperty(a)){var o=i[a];if(!x(o)){o={value:o}}Q(r,a,o)}}}else{Q(r,n,[])}}var Le=/\s/;var Te=/[\s,]/;var He=/[_$a-zA-Z]/;var Ae=/[_$a-zA-Z0-9]/;var Ne=['"',"'","/"];var Ie=/[^\s]/;function ke(e){var t=[];var r=0;while(r0){var o=t[0];if(o==="]"){n--;if(n===0){if(a===null){i=i+"true"}t.shift();i+=")})";try{var s=Qt(e,function(){return Function(i)()},function(){return true});s.source=i;return s}catch(e){Y(J().body,"htmx:syntax:error",{error:e,source:i});return null}}}else if(o==="["){n++}if(Me(o,a,r)){i+="(("+r+"."+o+") ? ("+r+"."+o+") : (window."+o+"))"}else{i=i+o}a=t.shift()}}}function c(e,t){var r="";while(e.length>0&&!e[0].match(t)){r+=e.shift()}return r}var Pe="input, textarea, select";function Xe(e){var t=G(e,"hx-trigger");var r=[];if(t){var n=ke(t);do{c(n,Ie);var f=n.length;var i=c(n,/[,\[\s]/);if(i!==""){if(i==="every"){var a={trigger:"every"};c(n,Ie);a.pollInterval=v(c(n,/[,\[\s]/));c(n,Ie);var o=De(e,n,"event");if(o){a.eventFilter=o}r.push(a)}else if(i.indexOf("sse:")===0){r.push({trigger:"sse",sseEvent:i.substr(4)})}else{var s={trigger:i};var o=De(e,n,"event");if(o){s.eventFilter=o}while(n.length>0&&n[0]!==","){c(n,Ie);var l=n.shift();if(l==="changed"){s.changed=true}else if(l==="once"){s.once=true}else if(l==="consume"){s.consume=true}else if(l==="delay"&&n[0]===":"){n.shift();s.delay=v(c(n,Te))}else if(l==="from"&&n[0]===":"){n.shift();var u=c(n,Te);if(u==="closest"||u==="find"||u==="next"||u==="previous"){n.shift();u+=" "+c(n,Te)}s.from=u}else if(l==="target"&&n[0]===":"){n.shift();s.target=c(n,Te)}else if(l==="throttle"&&n[0]===":"){n.shift();s.throttle=v(c(n,Te))}else if(l==="queue"&&n[0]===":"){n.shift();s.queue=c(n,Te)}else if((l==="root"||l==="threshold")&&n[0]===":"){n.shift();s[l]=c(n,Te)}else{Y(e,"htmx:syntax:error",{token:n.shift()})}}r.push(s)}}if(n.length===f){Y(e,"htmx:syntax:error",{token:n.shift()})}c(n,Ie)}while(n[0]===","&&n.shift())}if(r.length>0){return r}else if(d(e,"form")){return[{trigger:"submit"}]}else if(d(e,'input[type="button"]')){return[{trigger:"click"}]}else if(d(e,Pe)){return[{trigger:"change"}]}else{return[{trigger:"click"}]}}function Fe(e){Z(e).cancelled=true}function je(e,t,r){var n=Z(e);n.timeout=setTimeout(function(){if(te(e)&&n.cancelled!==true){if(!ze(r,yt("hx:poll:trigger",{triggerSpec:r,target:e}))){t(e)}je(e,t,r)}},r.pollInterval)}function Be(e){return location.hostname===e.hostname&&f(e,"href")&&f(e,"href").indexOf("#")!==0}function Ue(t,r,e){if(t.tagName==="A"&&Be(t)&&(t.target===""||t.target==="_self")||t.tagName==="FORM"){r.boosted=true;var n,i;if(t.tagName==="A"){n="get";i=f(t,"href")}else{var a=f(t,"method");n=a?a.toLowerCase():"get";if(n==="get"){}i=f(t,"action")}e.forEach(function(e){We(t,function(e){lr(n,i,t,e)},r,e,true)})}}function Ve(e,t){if(e.type==="submit"||e.type==="click"){if(t.tagName==="FORM"){return true}if(d(t,'input[type="submit"], button')&&N(t,"form")!==null){return true}if(t.tagName==="A"&&t.href&&(t.getAttribute("href")==="#"||t.getAttribute("href").indexOf("#")!==0)){return true}}return false}function _e(e,t){return Z(e).boosted&&e.tagName==="A"&&t.type==="click"&&(t.ctrlKey||t.metaKey)}function ze(e,t){var r=e.eventFilter;if(r){try{return r(t)!==true}catch(e){Y(J().body,"htmx:eventFilter:error",{error:e,source:r.source});return true}}return false}function We(a,o,e,s,l){var t;if(s.from){t=I(a,s.from)}else{t=[a]}K(t,function(n){var i=function(e){if(!te(a)){n.removeEventListener(s.trigger,i);return}if(_e(a,e)){return}if(l||Ve(e,a)){e.preventDefault()}if(ze(s,e)){return}var t=Z(e);t.triggerSpec=s;if(t.handledFor==null){t.handledFor=[]}var r=Z(a);if(t.handledFor.indexOf(a)<0){t.handledFor.push(a);if(s.consume){e.stopPropagation()}if(s.target&&e.target){if(!d(e.target,s.target)){return}}if(s.once){if(r.triggeredOnce){return}else{r.triggeredOnce=true}}if(s.changed){if(r.lastValue===a.value){return}else{r.lastValue=a.value}}if(r.delayed){clearTimeout(r.delayed)}if(r.throttle){return}if(s.throttle){if(!r.throttle){o(a,e);r.throttle=setTimeout(function(){r.throttle=null},s.throttle)}}else if(s.delay){r.delayed=setTimeout(function(){o(a,e)},s.delay)}else{o(a,e)}}};if(e.listenerInfos==null){e.listenerInfos=[]}e.listenerInfos.push({trigger:s.trigger,listener:i,on:n});n.addEventListener(s.trigger,i)})}var Ge=false;var Je=null;function $e(){if(!Je){Je=function(){Ge=true};window.addEventListener("scroll",Je);setInterval(function(){if(Ge){Ge=false;K(J().querySelectorAll("[hx-trigger='revealed'],[data-hx-trigger='revealed']"),function(e){Ze(e)})}},200)}}function Ze(t){if(!o(t,"data-hx-revealed")&&b(t)){t.setAttribute("data-hx-revealed","true");var e=Z(t);if(e.initHash){Q(t,"revealed")}else{t.addEventListener("htmx:afterProcessNode",function(e){Q(t,"revealed")},{once:true})}}}function Ke(e,t,r){var n=w(r);for(var i=0;i=0){var t=tt(n);setTimeout(function(){Ye(s,r,n+1)},t)}};t.onopen=function(e){n=0};Z(s).webSocket=t;t.addEventListener("message",function(e){if(Qe(s)){return}var t=e.data;wt(s,function(e){t=e.transformResponse(t,null,s)});var r=Zt(s);var n=g(t);var i=y(n.children);for(var a=0;a0){Q(u,"htmx:validation:halted",i);return}t.send(JSON.stringify(l));if(Ve(e,u)){e.preventDefault()}})}else{Y(u,"htmx:noWebSocketSourceError")}}function tt(e){var t=W.config.wsReconnectDelay;if(typeof t==="function"){return t(e)}if(t==="full-jitter"){var r=Math.min(e,6);var n=1e3*Math.pow(2,r);return n*Math.random()}St('htmx.config.wsReconnectDelay must either be a function or the string "full-jitter"')}function rt(e,t,r){var n=w(r);for(var i=0;iW.config.historyCacheSize){i.shift()}while(i.length>0){try{localStorage.setItem("htmx-history-cache",JSON.stringify(i));break}catch(e){Y(J().body,"htmx:historyCacheError",{cause:e,cache:i});i.shift()}}}function Ot(e){if(!E()){return null}var t=S(localStorage.getItem("htmx-history-cache"))||[];for(var r=0;r=200&&this.status<400){Q(J().body,"htmx:historyCacheMissLoad",o);var e=g(this.response);e=e.querySelector("[hx-history-elt],[data-hx-history-elt]")||e;var t=Ct();var r=Zt(t);var n=Re(this.response);if(n){var i=R("title");if(i){i.innerHTML=n}else{window.document.title=n}}Se(t,e,r);At(r.tasks);Et=a;Q(J().body,"htmx:historyRestore",{path:a,cacheMiss:true,serverResponse:this.response})}else{Y(J().body,"htmx:historyCacheMissLoadError",o)}};e.send()}function It(e){Lt();e=e||location.pathname+location.search;var t=Ot(e);if(t){var r=g(t.content);var n=Ct();var i=Zt(n);Se(n,r,i);At(i.tasks);document.title=t.title;window.scrollTo(0,t.scroll);Et=e;Q(J().body,"htmx:historyRestore",{path:e,item:t})}else{if(W.config.refreshOnHistoryMiss){window.location.reload(true)}else{Nt(e)}}}function kt(e){var t=j(e,"hx-indicator");if(t==null){t=[e]}K(t,function(e){var t=Z(e);t.requestCount=(t.requestCount||0)+1;e.classList["add"].call(e.classList,W.config.requestClass)});return t}function Mt(e){K(e,function(e){var t=Z(e);t.requestCount=(t.requestCount||0)-1;if(t.requestCount===0){e.classList["remove"].call(e.classList,W.config.requestClass)}})}function Dt(e,t){for(var r=0;r=0}function Gt(e,t){var r=t?t:$(e,"hx-swap");var n={swapStyle:Z(e).boosted?"innerHTML":W.config.defaultSwapStyle,swapDelay:W.config.defaultSwapDelay,settleDelay:W.config.defaultSettleDelay};if(Z(e).boosted&&!Wt(e)){n["show"]="top"}if(r){var i=w(r);if(i.length>0){n["swapStyle"]=i[0];for(var a=1;a0?l.join(":"):null;n["scroll"]=f;n["scrollTarget"]=u}if(o.indexOf("show:")===0){var c=o.substr(5);var l=c.split(":");var h=l.pop();var u=l.length>0?l.join(":"):null;n["show"]=h;n["showTarget"]=u}if(o.indexOf("focus-scroll:")===0){var d=o.substr("focus-scroll:".length);n["focusScroll"]=d=="true"}}}}return n}function Jt(e){return $(e,"hx-encoding")==="multipart/form-data"||d(e,"form")&&f(e,"enctype")==="multipart/form-data"}function $t(t,r,n){var i=null;wt(r,function(e){if(i==null){i=e.encodeParameters(t,n,r)}});if(i!=null){return i}else{if(Jt(r)){return Vt(n)}else{return Ut(n)}}}function Zt(e){return{tasks:[],elts:[e]}}function Kt(e,t){var r=e[0];var n=e[e.length-1];if(t.scroll){var i=null;if(t.scrollTarget){i=ne(r,t.scrollTarget)}if(t.scroll==="top"&&(r||i)){i=i||r;i.scrollTop=0}if(t.scroll==="bottom"&&(n||i)){i=i||n;i.scrollTop=i.scrollHeight}}if(t.show){var i=null;if(t.showTarget){var a=t.showTarget;if(t.showTarget==="window"){a="body"}i=ne(r,a)}if(t.show==="top"&&(r||i)){i=i||r;i.scrollIntoView({block:"start",behavior:W.config.scrollBehavior})}if(t.show==="bottom"&&(n||i)){i=i||n;i.scrollIntoView({block:"end",behavior:W.config.scrollBehavior})}}}function Yt(e,t,r,n){if(n==null){n={}}if(e==null){return n}var i=G(e,t);if(i){var a=i.trim();var o=r;if(a==="unset"){return null}if(a.indexOf("javascript:")===0){a=a.substr(11);o=true}else if(a.indexOf("js:")===0){a=a.substr(3);o=true}if(a.indexOf("{")!==0){a="{"+a+"}"}var s;if(o){s=Qt(e,function(){return Function("return ("+a+")")()},{})}else{s=S(a)}for(var l in s){if(s.hasOwnProperty(l)){if(n[l]==null){n[l]=s[l]}}}}return Yt(u(e),t,r,n)}function Qt(e,t,r){if(W.config.allowEval){return t()}else{Y(e,"htmx:evalDisallowedError");return r}}function er(e,t){return Yt(e,"hx-vars",true,t)}function tr(e,t){return Yt(e,"hx-vals",false,t)}function rr(e){return re(er(e),tr(e))}function nr(t,r,n){if(n!==null){try{t.setRequestHeader(r,n)}catch(e){t.setRequestHeader(r,encodeURIComponent(n));t.setRequestHeader(r+"-URI-AutoEncoded","true")}}}function ir(t){if(t.responseURL&&typeof URL!=="undefined"){try{var e=new URL(t.responseURL);return e.pathname+e.search}catch(e){Y(J().body,"htmx:badResponseUrl",{url:t.responseURL})}}}function ar(e,t){return e.getAllResponseHeaders().match(t)}function or(e,t,r){e=e.toLowerCase();if(r){if(r instanceof Element||p(r,"String")){return lr(e,t,null,null,{targetOverride:D(r),returnPromise:true})}else{return lr(e,t,D(r.source),r.event,{handler:r.handler,headers:r.headers,values:r.values,targetOverride:D(r.target),swapOverride:r.swap,returnPromise:true})}}else{return lr(e,t,null,null,{returnPromise:true})}}function sr(e){var t=[];while(e){t.push(e);e=e.parentElement}return t}function lr(e,t,n,r,i,f){var c=null;var h=null;i=i!=null?i:{};if(i.returnPromise&&typeof Promise!=="undefined"){var d=new Promise(function(e,t){c=e;h=t})}if(n==null){n=J().body}var v=i.handler||fr;if(!te(n)){return}var g=i.targetOverride||oe(n);if(g==null||g==ie){Y(n,"htmx:targetError",{target:G(n,"hx-target")});return}if(!f){var p=function(){return lr(e,t,n,r,i,true)};var m={target:g,elt:n,path:t,verb:e,triggeringEvent:r,etc:i,issueRequest:p};if(Q(n,"htmx:confirm",m)===false){return}}var x=n;var a=Z(n);var y=$(n,"hx-sync");var b=null;var w=false;if(y){var S=y.split(":");var E=S[0].trim();if(E==="this"){x=ae(n,"hx-sync")}else{x=ne(n,E)}y=(S[1]||"drop").trim();a=Z(x);if(y==="drop"&&a.xhr&&a.abortable!==true){return}else if(y==="abort"){if(a.xhr){return}else{w=true}}else if(y==="replace"){Q(x,"htmx:abort")}else if(y.indexOf("queue")===0){var C=y.split(" ");b=(C[1]||"last").trim()}}if(a.xhr){if(a.abortable){Q(x,"htmx:abort")}else{if(b==null){if(r){var R=Z(r);if(R&&R.triggerSpec&&R.triggerSpec.queue){b=R.triggerSpec.queue}}if(b==null){b="last"}}if(a.queuedRequests==null){a.queuedRequests=[]}if(b==="first"&&a.queuedRequests.length===0){a.queuedRequests.push(function(){lr(e,t,n,r,i)})}else if(b==="all"){a.queuedRequests.push(function(){lr(e,t,n,r,i)})}else if(b==="last"){a.queuedRequests=[];a.queuedRequests.push(function(){lr(e,t,n,r,i)})}return}}var o=new XMLHttpRequest;a.xhr=o;a.abortable=w;var s=function(){a.xhr=null;a.abortable=false;if(a.queuedRequests!=null&&a.queuedRequests.length>0){var e=a.queuedRequests.shift();e()}};var O=$(n,"hx-prompt");if(O){var q=prompt(O);if(q===null||!Q(n,"htmx:prompt",{prompt:q,target:g})){ee(c);s();return d}}var L=$(n,"hx-confirm");if(L){if(!confirm(L)){ee(c);s();return d}}var T=_t(n,g,q);if(i.headers){T=re(T,i.headers)}var H=jt(n,e);var A=H.errors;var N=H.values;if(i.values){N=re(N,i.values)}var I=rr(n);var k=re(N,I);var M=zt(k,n);if(e!=="get"&&!Jt(n)){T["Content-Type"]="application/x-www-form-urlencoded"}if(t==null||t===""){t=J().location.href}var D=Yt(n,"hx-request");var P=Z(n).boosted;var l={boosted:P,parameters:M,unfilteredParameters:k,headers:T,target:g,verb:e,errors:A,withCredentials:i.credentials||D.credentials||W.config.withCredentials,timeout:i.timeout||D.timeout||W.config.timeout,path:t,triggeringEvent:r};if(!Q(n,"htmx:configRequest",l)){ee(c);s();return d}t=l.path;e=l.verb;T=l.headers;M=l.parameters;A=l.errors;if(A&&A.length>0){Q(n,"htmx:validation:halted",l);ee(c);s();return d}var X=t.split("#");var F=X[0];var j=X[1];var B=null;if(e==="get"){B=F;var U=Object.keys(M).length!==0;if(U){if(B.indexOf("?")<0){B+="?"}else{B+="&"}B+=Ut(M);if(j){B+="#"+j}}o.open("GET",B,true)}else{o.open(e.toUpperCase(),t,true)}o.overrideMimeType("text/html");o.withCredentials=l.withCredentials;o.timeout=l.timeout;if(D.noHeaders){}else{for(var V in T){if(T.hasOwnProperty(V)){var _=T[V];nr(o,V,_)}}}var u={xhr:o,target:g,requestConfig:l,etc:i,boosted:P,pathInfo:{requestPath:t,finalRequestPath:B||t,anchor:j}};o.onload=function(){try{var e=sr(n);u.pathInfo.responsePath=ir(o);v(n,u);Mt(z);Q(n,"htmx:afterRequest",u);Q(n,"htmx:afterOnLoad",u);if(!te(n)){var t=null;while(e.length>0&&t==null){var r=e.shift();if(te(r)){t=r}}if(t){Q(t,"htmx:afterRequest",u);Q(t,"htmx:afterOnLoad",u)}}ee(c);s()}catch(e){Y(n,"htmx:onLoadError",re({error:e},u));throw e}};o.onerror=function(){Mt(z);Y(n,"htmx:afterRequest",u);Y(n,"htmx:sendError",u);ee(h);s()};o.onabort=function(){Mt(z);Y(n,"htmx:afterRequest",u);Y(n,"htmx:sendAbort",u);ee(h);s()};o.ontimeout=function(){Mt(z);Y(n,"htmx:afterRequest",u);Y(n,"htmx:timeout",u);ee(h);s()};if(!Q(n,"htmx:beforeRequest",u)){ee(c);s();return d}var z=kt(n);K(["loadstart","loadend","progress","abort"],function(t){K([o,o.upload],function(e){e.addEventListener(t,function(e){Q(n,"htmx:xhr:"+t,{lengthComputable:e.lengthComputable,loaded:e.loaded,total:e.total})})})});Q(n,"htmx:beforeSend",u);o.send(e==="get"?null:$t(o,n,M));return d}function ur(e,t){var r=t.xhr;var n=null;var i=null;if(ar(r,/HX-Push:/i)){n=r.getResponseHeader("HX-Push");i="push"}else if(ar(r,/HX-Push-Url:/i)){n=r.getResponseHeader("HX-Push-Url");i="push"}else if(ar(r,/HX-Replace-Url:/i)){n=r.getResponseHeader("HX-Replace-Url");i="replace"}if(n){if(n==="false"){return{}}else{return{type:i,path:n}}}var a=t.pathInfo.finalRequestPath;var o=t.pathInfo.responsePath;var s=$(e,"hx-push-url");var f=$(e,"hx-replace-url");var c=Z(e).boosted;var l=null;var u=null;if(s){l="push";u=s}else if(f){l="replace";u=f}else if(c){l="push";u=o||a}if(u){if(u==="false"){return{}}if(u==="true"){u=o||a}if(t.pathInfo.anchor&&u.indexOf("#")===-1){u=u+"#"+t.pathInfo.anchor}return{type:l,path:u}}else{return{}}}function fr(s,l){var u=l.xhr;var f=l.target;var n=l.etc;if(!Q(s,"htmx:beforeOnLoad",l))return;if(ar(u,/HX-Trigger:/i)){qe(u,"HX-Trigger",s)}if(ar(u,/HX-Location:/i)){Lt();var e=u.getResponseHeader("HX-Location");var c;if(e.indexOf("{")===0){c=S(e);e=c["path"];delete c["path"]}or("GET",e,c).then(function(){Tt(e)});return}if(ar(u,/HX-Redirect:/i)){location.href=u.getResponseHeader("HX-Redirect");return}if(ar(u,/HX-Refresh:/i)){if("true"===u.getResponseHeader("HX-Refresh")){location.reload();return}}if(ar(u,/HX-Retarget:/i)){l.target=J().querySelector(u.getResponseHeader("HX-Retarget"))}var h=ur(s,l);var i=u.status>=200&&u.status<400&&u.status!==204;var d=u.response;var t=u.status>=400;var r=re({shouldSwap:i,serverResponse:d,isError:t},l);if(!Q(f,"htmx:beforeSwap",r))return;f=r.target;d=r.serverResponse;t=r.isError;l.failed=t;l.successful=!t;if(r.shouldSwap){if(u.status===286){Fe(s)}wt(s,function(e){d=e.transformResponse(d,u,s)});if(h.type){Lt()}var a=n.swapOverride;if(ar(u,/HX-Reswap:/i)){a=u.getResponseHeader("HX-Reswap")}var c=Gt(s,a);f.classList.add(W.config.swappingClass);var o=function(){try{var e=document.activeElement;var t={};try{t={elt:e,start:e?e.selectionStart:null,end:e?e.selectionEnd:null}}catch(e){}var n=Zt(f);Oe(c.swapStyle,f,s,d,n);if(t.elt&&!te(t.elt)&&t.elt.id){var r=document.getElementById(t.elt.id);var i={preventScroll:c.focusScroll!==undefined?!c.focusScroll:!W.config.defaultFocusScroll};if(r){if(t.start&&r.setSelectionRange){r.setSelectionRange(t.start,t.end)}r.focus(i)}}f.classList.remove(W.config.swappingClass);K(n.elts,function(e){if(e.classList){e.classList.add(W.config.settlingClass)}Q(e,"htmx:afterSwap",l)});if(ar(u,/HX-Trigger-After-Swap:/i)){var a=s;if(!te(s)){a=J().body}qe(u,"HX-Trigger-After-Swap",a)}var o=function(){K(n.tasks,function(e){e.call()});K(n.elts,function(e){if(e.classList){e.classList.remove(W.config.settlingClass)}Q(e,"htmx:afterSettle",l)});if(h.type){if(h.type==="push"){Tt(h.path);Q(J().body,"htmx:pushedIntoHistory",{path:h.path})}else{Ht(h.path);Q(J().body,"htmx:replacedInHistory",{path:h.path})}}if(l.pathInfo.anchor){var e=R("#"+l.pathInfo.anchor);if(e){e.scrollIntoView({block:"start",behavior:"auto"})}}if(n.title){var t=R("title");if(t){t.innerHTML=n.title}else{window.document.title=n.title}}Kt(n.elts,c);if(ar(u,/HX-Trigger-After-Settle:/i)){var r=s;if(!te(s)){r=J().body}qe(u,"HX-Trigger-After-Settle",r)}};if(c.settleDelay>0){setTimeout(o,c.settleDelay)}else{o()}}catch(e){Y(s,"htmx:swapError",l);throw e}};if(c.swapDelay>0){setTimeout(o,c.swapDelay)}else{o()}}if(t){Y(s,"htmx:responseError",re({error:"Response Status Error Code "+u.status+" from "+l.pathInfo.requestPath},l))}}var cr={};function hr(){return{init:function(e){return null},onEvent:function(e,t){return true},transformResponse:function(e,t,r){return e},isInlineSwap:function(e){return false},handleSwap:function(e,t,r,n){return false},encodeParameters:function(e,t,r){return null}}}function dr(e,t){if(t.init){t.init(r)}cr[e]=re(hr(),t)}function vr(e){delete cr[e]}function gr(e,r,n){if(e==undefined){return r}if(r==undefined){r=[]}if(n==undefined){n=[]}var t=G(e,"hx-ext");if(t){K(t.split(","),function(e){e=e.replace(/ /g,"");if(e.slice(0,7)=="ignore:"){n.push(e.slice(7));return}if(n.indexOf(e)<0){var t=cr[e];if(t&&r.indexOf(t)<0){r.push(t)}}})}return gr(u(e),r,n)}function pr(e){if(J().readyState!=="loading"){e()}else{J().addEventListener("DOMContentLoaded",e)}}function mr(){if(W.config.includeIndicatorStyles!==false){J().head.insertAdjacentHTML("beforeend","")}}function xr(){var e=J().querySelector('meta[name="htmx-config"]');if(e){return S(e.content)}else{return null}}function yr(){var e=xr();if(e){W.config=re(W.config,e)}}pr(function(){yr();mr();var e=J().body;mt(e);var t=J().querySelectorAll("[hx-trigger='restored'],[data-hx-trigger='restored']");e.addEventListener("htmx:abort",function(e){var t=e.target;var r=Z(t);if(r&&r.xhr){r.xhr.abort()}});window.onpopstate=function(e){if(e.state&&e.state.htmx){It();K(t,function(e){Q(e,"htmx:restored",{document:J(),triggerEvent:Q})})}};setTimeout(function(){Q(e,"htmx:load",{})},0)});return W}()}); \ No newline at end of file diff --git a/core/tables.py b/src/core/tables.py similarity index 100% rename from core/tables.py rename to src/core/tables.py diff --git a/core/templates/core/base.html b/src/core/templates/core/base.html similarity index 100% rename from core/templates/core/base.html rename to src/core/templates/core/base.html diff --git a/core/templates/core/partials/modal.html b/src/core/templates/core/partials/modal.html similarity index 100% rename from core/templates/core/partials/modal.html rename to src/core/templates/core/partials/modal.html diff --git a/core/templates/registration/login.html b/src/core/templates/registration/login.html similarity index 100% rename from core/templates/registration/login.html rename to src/core/templates/registration/login.html diff --git a/core/templatetags/__init__.py b/src/core/templatetags/__init__.py similarity index 100% rename from core/templatetags/__init__.py rename to src/core/templatetags/__init__.py diff --git a/core/templatetags/core_extras.py b/src/core/templatetags/core_extras.py similarity index 100% rename from core/templatetags/core_extras.py rename to src/core/templatetags/core_extras.py diff --git a/core/tests/__init__.py b/src/core/tests/__init__.py similarity index 100% rename from core/tests/__init__.py rename to src/core/tests/__init__.py diff --git a/core/tests/helper.py b/src/core/tests/helper.py similarity index 100% rename from core/tests/helper.py rename to src/core/tests/helper.py diff --git a/core/tests/test_get_all_objects_for_allowed_customers.py b/src/core/tests/test_get_all_objects_for_allowed_customers.py similarity index 100% rename from core/tests/test_get_all_objects_for_allowed_customers.py rename to src/core/tests/test_get_all_objects_for_allowed_customers.py diff --git a/core/tests/test_get_object_with_view_permission.py b/src/core/tests/test_get_object_with_view_permission.py similarity index 100% rename from core/tests/test_get_object_with_view_permission.py rename to src/core/tests/test_get_object_with_view_permission.py diff --git a/core/tests/test_get_objects_for_customer.py b/src/core/tests/test_get_objects_for_customer.py similarity index 100% rename from core/tests/test_get_objects_for_customer.py rename to src/core/tests/test_get_objects_for_customer.py diff --git a/core/tests/test_templatetags.py b/src/core/tests/test_templatetags.py similarity index 100% rename from core/tests/test_templatetags.py rename to src/core/tests/test_templatetags.py diff --git a/core/urls.py b/src/core/urls.py similarity index 100% rename from core/urls.py rename to src/core/urls.py diff --git a/core/utils.py b/src/core/utils.py similarity index 100% rename from core/utils.py rename to src/core/utils.py diff --git a/customers/__init__.py b/src/customers/__init__.py similarity index 100% rename from customers/__init__.py rename to src/customers/__init__.py diff --git a/customers/admin.py b/src/customers/admin.py similarity index 100% rename from customers/admin.py rename to src/customers/admin.py diff --git a/customers/apps.py b/src/customers/apps.py similarity index 100% rename from customers/apps.py rename to src/customers/apps.py diff --git a/customers/decorators.py b/src/customers/decorators.py similarity index 100% rename from customers/decorators.py rename to src/customers/decorators.py diff --git a/customers/forms.py b/src/customers/forms.py similarity index 100% rename from customers/forms.py rename to src/customers/forms.py diff --git a/customers/models.py b/src/customers/models.py similarity index 100% rename from customers/models.py rename to src/customers/models.py diff --git a/customers/tables.py b/src/customers/tables.py similarity index 100% rename from customers/tables.py rename to src/customers/tables.py diff --git a/customers/templates/customers/customer_confirm_delete.html b/src/customers/templates/customers/customer_confirm_delete.html similarity index 100% rename from customers/templates/customers/customer_confirm_delete.html rename to src/customers/templates/customers/customer_confirm_delete.html diff --git a/customers/templates/customers/customer_create.html b/src/customers/templates/customers/customer_create.html similarity index 100% rename from customers/templates/customers/customer_create.html rename to src/customers/templates/customers/customer_create.html diff --git a/customers/templates/customers/customer_details.html b/src/customers/templates/customers/customer_details.html similarity index 100% rename from customers/templates/customers/customer_details.html rename to src/customers/templates/customers/customer_details.html diff --git a/customers/templates/customers/customer_list.html b/src/customers/templates/customers/customer_list.html similarity index 100% rename from customers/templates/customers/customer_list.html rename to src/customers/templates/customers/customer_list.html diff --git a/customers/templates/customers/partials/customer_create.html b/src/customers/templates/customers/partials/customer_create.html similarity index 100% rename from customers/templates/customers/partials/customer_create.html rename to src/customers/templates/customers/partials/customer_create.html diff --git a/customers/templates/customers/partials/location_create.html b/src/customers/templates/customers/partials/location_create.html similarity index 100% rename from customers/templates/customers/partials/location_create.html rename to src/customers/templates/customers/partials/location_create.html diff --git a/customers/templates/customers/partials/location_response.html b/src/customers/templates/customers/partials/location_response.html similarity index 100% rename from customers/templates/customers/partials/location_response.html rename to src/customers/templates/customers/partials/location_response.html diff --git a/customers/tests/test_customer.py b/src/customers/tests/test_customer.py similarity index 100% rename from customers/tests/test_customer.py rename to src/customers/tests/test_customer.py diff --git a/customers/tests/test_customer_detail_view.py b/src/customers/tests/test_customer_detail_view.py similarity index 100% rename from customers/tests/test_customer_detail_view.py rename to src/customers/tests/test_customer_detail_view.py diff --git a/customers/tests/test_customer_form_views.py b/src/customers/tests/test_customer_form_views.py similarity index 100% rename from customers/tests/test_customer_form_views.py rename to src/customers/tests/test_customer_form_views.py diff --git a/customers/tests/test_customer_list_view.py b/src/customers/tests/test_customer_list_view.py similarity index 100% rename from customers/tests/test_customer_list_view.py rename to src/customers/tests/test_customer_list_view.py diff --git a/customers/tests/test_location_form.py b/src/customers/tests/test_location_form.py similarity index 100% rename from customers/tests/test_location_form.py rename to src/customers/tests/test_location_form.py diff --git a/customers/tests/test_location_form_view.py b/src/customers/tests/test_location_form_view.py similarity index 100% rename from customers/tests/test_location_form_view.py rename to src/customers/tests/test_location_form_view.py diff --git a/customers/urls.py b/src/customers/urls.py similarity index 100% rename from customers/urls.py rename to src/customers/urls.py diff --git a/customers/views.py b/src/customers/views.py similarity index 100% rename from customers/views.py rename to src/customers/views.py diff --git a/devices/__init__.py b/src/devices/__init__.py similarity index 100% rename from devices/__init__.py rename to src/devices/__init__.py diff --git a/devices/admin.py b/src/devices/admin.py similarity index 100% rename from devices/admin.py rename to src/devices/admin.py diff --git a/devices/apps.py b/src/devices/apps.py similarity index 100% rename from devices/apps.py rename to src/devices/apps.py diff --git a/devices/decorators.py b/src/devices/decorators.py similarity index 100% rename from devices/decorators.py rename to src/devices/decorators.py diff --git a/devices/fixtures/devices.yaml b/src/devices/fixtures/devices.yaml similarity index 100% rename from devices/fixtures/devices.yaml rename to src/devices/fixtures/devices.yaml diff --git a/devices/forms.py b/src/devices/forms.py similarity index 100% rename from devices/forms.py rename to src/devices/forms.py diff --git a/devices/models/__init__.py b/src/devices/models/__init__.py similarity index 100% rename from devices/models/__init__.py rename to src/devices/models/__init__.py diff --git a/devices/models/device.py b/src/devices/models/device.py similarity index 100% rename from devices/models/device.py rename to src/devices/models/device.py diff --git a/devices/models/warranty.py b/src/devices/models/warranty.py similarity index 100% rename from devices/models/warranty.py rename to src/devices/models/warranty.py diff --git a/devices/tables.py b/src/devices/tables.py similarity index 100% rename from devices/tables.py rename to src/devices/tables.py diff --git a/devices/templates/devices/device_confirm_delete.html b/src/devices/templates/devices/device_confirm_delete.html similarity index 100% rename from devices/templates/devices/device_confirm_delete.html rename to src/devices/templates/devices/device_confirm_delete.html diff --git a/devices/templates/devices/device_create.html b/src/devices/templates/devices/device_create.html similarity index 100% rename from devices/templates/devices/device_create.html rename to src/devices/templates/devices/device_create.html diff --git a/devices/templates/devices/device_details.html b/src/devices/templates/devices/device_details.html similarity index 100% rename from devices/templates/devices/device_details.html rename to src/devices/templates/devices/device_details.html diff --git a/devices/templates/devices/device_details_block.html b/src/devices/templates/devices/device_details_block.html similarity index 100% rename from devices/templates/devices/device_details_block.html rename to src/devices/templates/devices/device_details_block.html diff --git a/devices/templates/devices/device_in_net_confirm_delete.html b/src/devices/templates/devices/device_in_net_confirm_delete.html similarity index 100% rename from devices/templates/devices/device_in_net_confirm_delete.html rename to src/devices/templates/devices/device_in_net_confirm_delete.html diff --git a/devices/templates/devices/device_in_net_create.html b/src/devices/templates/devices/device_in_net_create.html similarity index 100% rename from devices/templates/devices/device_in_net_create.html rename to src/devices/templates/devices/device_in_net_create.html diff --git a/devices/templates/devices/device_in_net_update.html b/src/devices/templates/devices/device_in_net_update.html similarity index 100% rename from devices/templates/devices/device_in_net_update.html rename to src/devices/templates/devices/device_in_net_update.html diff --git a/devices/templates/devices/device_list.html b/src/devices/templates/devices/device_list.html similarity index 100% rename from devices/templates/devices/device_list.html rename to src/devices/templates/devices/device_list.html diff --git a/devices/templates/devices/device_update.html b/src/devices/templates/devices/device_update.html similarity index 100% rename from devices/templates/devices/device_update.html rename to src/devices/templates/devices/device_update.html diff --git a/devices/templates/devices/ip_block.html b/src/devices/templates/devices/ip_block.html similarity index 100% rename from devices/templates/devices/ip_block.html rename to src/devices/templates/devices/ip_block.html diff --git a/devices/templates/devices/manufacturer_details.html b/src/devices/templates/devices/manufacturer_details.html similarity index 100% rename from devices/templates/devices/manufacturer_details.html rename to src/devices/templates/devices/manufacturer_details.html diff --git a/devices/templates/devices/partials/device_category_create.html b/src/devices/templates/devices/partials/device_category_create.html similarity index 100% rename from devices/templates/devices/partials/device_category_create.html rename to src/devices/templates/devices/partials/device_category_create.html diff --git a/devices/templates/devices/partials/device_category_response.html b/src/devices/templates/devices/partials/device_category_response.html similarity index 100% rename from devices/templates/devices/partials/device_category_response.html rename to src/devices/templates/devices/partials/device_category_response.html diff --git a/devices/templates/devices/warranties_list.html b/src/devices/templates/devices/warranties_list.html similarity index 100% rename from devices/templates/devices/warranties_list.html rename to src/devices/templates/devices/warranties_list.html diff --git a/devices/templates/devices/warranty_block.html b/src/devices/templates/devices/warranty_block.html similarity index 100% rename from devices/templates/devices/warranty_block.html rename to src/devices/templates/devices/warranty_block.html diff --git a/devices/templates/devices/warranty_confirm_delete.html b/src/devices/templates/devices/warranty_confirm_delete.html similarity index 100% rename from devices/templates/devices/warranty_confirm_delete.html rename to src/devices/templates/devices/warranty_confirm_delete.html diff --git a/devices/templates/devices/warranty_create.html b/src/devices/templates/devices/warranty_create.html similarity index 100% rename from devices/templates/devices/warranty_create.html rename to src/devices/templates/devices/warranty_create.html diff --git a/devices/templates/devices/warranty_update.html b/src/devices/templates/devices/warranty_update.html similarity index 100% rename from devices/templates/devices/warranty_update.html rename to src/devices/templates/devices/warranty_update.html diff --git a/devices/tests/test_connected_device_detail_view.py b/src/devices/tests/test_connected_device_detail_view.py similarity index 100% rename from devices/tests/test_connected_device_detail_view.py rename to src/devices/tests/test_connected_device_detail_view.py diff --git a/devices/tests/test_customer_device_table_view.py b/src/devices/tests/test_customer_device_table_view.py similarity index 100% rename from devices/tests/test_customer_device_table_view.py rename to src/devices/tests/test_customer_device_table_view.py diff --git a/devices/tests/test_device.py b/src/devices/tests/test_device.py similarity index 100% rename from devices/tests/test_device.py rename to src/devices/tests/test_device.py diff --git a/devices/tests/test_device_category_form_views.py b/src/devices/tests/test_device_category_form_views.py similarity index 100% rename from devices/tests/test_device_category_form_views.py rename to src/devices/tests/test_device_category_form_views.py diff --git a/devices/tests/test_device_detail_view.py b/src/devices/tests/test_device_detail_view.py similarity index 100% rename from devices/tests/test_device_detail_view.py rename to src/devices/tests/test_device_detail_view.py diff --git a/devices/tests/test_device_form.py b/src/devices/tests/test_device_form.py similarity index 100% rename from devices/tests/test_device_form.py rename to src/devices/tests/test_device_form.py diff --git a/devices/tests/test_device_form_views.py b/src/devices/tests/test_device_form_views.py similarity index 100% rename from devices/tests/test_device_form_views.py rename to src/devices/tests/test_device_form_views.py diff --git a/devices/tests/test_warranty_form.py b/src/devices/tests/test_warranty_form.py similarity index 100% rename from devices/tests/test_warranty_form.py rename to src/devices/tests/test_warranty_form.py diff --git a/devices/tests/test_warranty_list.py b/src/devices/tests/test_warranty_list.py similarity index 100% rename from devices/tests/test_warranty_list.py rename to src/devices/tests/test_warranty_list.py diff --git a/devices/urls.py b/src/devices/urls.py similarity index 100% rename from devices/urls.py rename to src/devices/urls.py diff --git a/devices/views.py b/src/devices/views.py similarity index 100% rename from devices/views.py rename to src/devices/views.py diff --git a/licenses/__init__.py b/src/licenses/__init__.py similarity index 100% rename from licenses/__init__.py rename to src/licenses/__init__.py diff --git a/licenses/admin.py b/src/licenses/admin.py similarity index 100% rename from licenses/admin.py rename to src/licenses/admin.py diff --git a/licenses/apps.py b/src/licenses/apps.py similarity index 100% rename from licenses/apps.py rename to src/licenses/apps.py diff --git a/licenses/models.py b/src/licenses/models.py similarity index 100% rename from licenses/models.py rename to src/licenses/models.py diff --git a/licenses/tables.py b/src/licenses/tables.py similarity index 100% rename from licenses/tables.py rename to src/licenses/tables.py diff --git a/licenses/templates/licenses/license_block.html b/src/licenses/templates/licenses/license_block.html similarity index 100% rename from licenses/templates/licenses/license_block.html rename to src/licenses/templates/licenses/license_block.html diff --git a/licenses/templates/licenses/license_confirm_delete.html b/src/licenses/templates/licenses/license_confirm_delete.html similarity index 100% rename from licenses/templates/licenses/license_confirm_delete.html rename to src/licenses/templates/licenses/license_confirm_delete.html diff --git a/licenses/templates/licenses/license_list.html b/src/licenses/templates/licenses/license_list.html similarity index 100% rename from licenses/templates/licenses/license_list.html rename to src/licenses/templates/licenses/license_list.html diff --git a/licenses/templates/licenses/license_with_computer_confirm_delete.html b/src/licenses/templates/licenses/license_with_computer_confirm_delete.html similarity index 100% rename from licenses/templates/licenses/license_with_computer_confirm_delete.html rename to src/licenses/templates/licenses/license_with_computer_confirm_delete.html diff --git a/licenses/templates/licenses/license_with_computer_create.html b/src/licenses/templates/licenses/license_with_computer_create.html similarity index 100% rename from licenses/templates/licenses/license_with_computer_create.html rename to src/licenses/templates/licenses/license_with_computer_create.html diff --git a/licenses/tests/test_customer_license_table_view.py b/src/licenses/tests/test_customer_license_table_view.py similarity index 100% rename from licenses/tests/test_customer_license_table_view.py rename to src/licenses/tests/test_customer_license_table_view.py diff --git a/licenses/tests/test_license.py b/src/licenses/tests/test_license.py similarity index 100% rename from licenses/tests/test_license.py rename to src/licenses/tests/test_license.py diff --git a/licenses/tests/test_license_form_view.py b/src/licenses/tests/test_license_form_view.py similarity index 100% rename from licenses/tests/test_license_form_view.py rename to src/licenses/tests/test_license_form_view.py diff --git a/licenses/urls.py b/src/licenses/urls.py similarity index 100% rename from licenses/urls.py rename to src/licenses/urls.py diff --git a/licenses/views.py b/src/licenses/views.py similarity index 100% rename from licenses/views.py rename to src/licenses/views.py diff --git a/manage.py b/src/manage.py old mode 100755 new mode 100644 similarity index 100% rename from manage.py rename to src/manage.py diff --git a/nets/__init__.py b/src/nets/__init__.py similarity index 100% rename from nets/__init__.py rename to src/nets/__init__.py diff --git a/nets/admin.py b/src/nets/admin.py similarity index 100% rename from nets/admin.py rename to src/nets/admin.py diff --git a/nets/apps.py b/src/nets/apps.py similarity index 100% rename from nets/apps.py rename to src/nets/apps.py diff --git a/nets/decorators.py b/src/nets/decorators.py similarity index 100% rename from nets/decorators.py rename to src/nets/decorators.py diff --git a/nets/fixtures/nets.yaml b/src/nets/fixtures/nets.yaml similarity index 100% rename from nets/fixtures/nets.yaml rename to src/nets/fixtures/nets.yaml diff --git a/nets/models.py b/src/nets/models.py similarity index 100% rename from nets/models.py rename to src/nets/models.py diff --git a/nets/tables.py b/src/nets/tables.py similarity index 100% rename from nets/tables.py rename to src/nets/tables.py diff --git a/nets/templates/nets/net_confirm_delete.html b/src/nets/templates/nets/net_confirm_delete.html similarity index 100% rename from nets/templates/nets/net_confirm_delete.html rename to src/nets/templates/nets/net_confirm_delete.html diff --git a/nets/templates/nets/net_details.html b/src/nets/templates/nets/net_details.html similarity index 100% rename from nets/templates/nets/net_details.html rename to src/nets/templates/nets/net_details.html diff --git a/nets/templates/nets/net_list.html b/src/nets/templates/nets/net_list.html similarity index 100% rename from nets/templates/nets/net_list.html rename to src/nets/templates/nets/net_list.html diff --git a/nets/tests/test_models/test_net.py b/src/nets/tests/test_models/test_net.py similarity index 100% rename from nets/tests/test_models/test_net.py rename to src/nets/tests/test_models/test_net.py diff --git a/nets/tests/test_views/test_customer_net_table_view.py b/src/nets/tests/test_views/test_customer_net_table_view.py similarity index 100% rename from nets/tests/test_views/test_customer_net_table_view.py rename to src/nets/tests/test_views/test_customer_net_table_view.py diff --git a/nets/tests/test_views/test_net_detail_view.py b/src/nets/tests/test_views/test_net_detail_view.py similarity index 100% rename from nets/tests/test_views/test_net_detail_view.py rename to src/nets/tests/test_views/test_net_detail_view.py diff --git a/nets/urls.py b/src/nets/urls.py similarity index 100% rename from nets/urls.py rename to src/nets/urls.py diff --git a/nets/views.py b/src/nets/views.py similarity index 100% rename from nets/views.py rename to src/nets/views.py diff --git a/network_inventory.yaml b/src/network_inventory.yaml similarity index 100% rename from network_inventory.yaml rename to src/network_inventory.yaml diff --git a/network_inventory/__init__.py b/src/network_inventory/__init__.py similarity index 100% rename from network_inventory/__init__.py rename to src/network_inventory/__init__.py diff --git a/network_inventory/settings/__init__.py b/src/network_inventory/settings/__init__.py similarity index 100% rename from network_inventory/settings/__init__.py rename to src/network_inventory/settings/__init__.py diff --git a/network_inventory/settings/base.py b/src/network_inventory/settings/base.py similarity index 100% rename from network_inventory/settings/base.py rename to src/network_inventory/settings/base.py diff --git a/network_inventory/settings/docker.py b/src/network_inventory/settings/docker.py similarity index 100% rename from network_inventory/settings/docker.py rename to src/network_inventory/settings/docker.py diff --git a/network_inventory/settings/local.py b/src/network_inventory/settings/local.py similarity index 100% rename from network_inventory/settings/local.py rename to src/network_inventory/settings/local.py diff --git a/network_inventory/settings/production.py b/src/network_inventory/settings/production.py similarity index 100% rename from network_inventory/settings/production.py rename to src/network_inventory/settings/production.py diff --git a/network_inventory/settings/ram_test.py b/src/network_inventory/settings/ram_test.py similarity index 100% rename from network_inventory/settings/ram_test.py rename to src/network_inventory/settings/ram_test.py diff --git a/network_inventory/urls.py b/src/network_inventory/urls.py similarity index 100% rename from network_inventory/urls.py rename to src/network_inventory/urls.py diff --git a/network_inventory/wsgi.py b/src/network_inventory/wsgi.py similarity index 100% rename from network_inventory/wsgi.py rename to src/network_inventory/wsgi.py diff --git a/softwares/__init__.py b/src/softwares/__init__.py similarity index 100% rename from softwares/__init__.py rename to src/softwares/__init__.py diff --git a/softwares/admin.py b/src/softwares/admin.py similarity index 100% rename from softwares/admin.py rename to src/softwares/admin.py diff --git a/softwares/apps.py b/src/softwares/apps.py similarity index 100% rename from softwares/apps.py rename to src/softwares/apps.py diff --git a/softwares/fixtures/softwares.yaml b/src/softwares/fixtures/softwares.yaml similarity index 100% rename from softwares/fixtures/softwares.yaml rename to src/softwares/fixtures/softwares.yaml diff --git a/softwares/models/__init__.py b/src/softwares/models/__init__.py similarity index 100% rename from softwares/models/__init__.py rename to src/softwares/models/__init__.py diff --git a/softwares/models/os.py b/src/softwares/models/os.py similarity index 100% rename from softwares/models/os.py rename to src/softwares/models/os.py diff --git a/softwares/models/services.py b/src/softwares/models/services.py similarity index 100% rename from softwares/models/services.py rename to src/softwares/models/services.py diff --git a/softwares/models/software.py b/src/softwares/models/software.py similarity index 100% rename from softwares/models/software.py rename to src/softwares/models/software.py diff --git a/users/__init__.py b/src/users/__init__.py similarity index 100% rename from users/__init__.py rename to src/users/__init__.py diff --git a/users/admin.py b/src/users/admin.py similarity index 100% rename from users/admin.py rename to src/users/admin.py diff --git a/users/apps.py b/src/users/apps.py similarity index 100% rename from users/apps.py rename to src/users/apps.py diff --git a/users/decorators.py b/src/users/decorators.py similarity index 100% rename from users/decorators.py rename to src/users/decorators.py diff --git a/users/models/__init__.py b/src/users/models/__init__.py similarity index 100% rename from users/models/__init__.py rename to src/users/models/__init__.py diff --git a/users/models/groups.py b/src/users/models/groups.py similarity index 100% rename from users/models/groups.py rename to src/users/models/groups.py diff --git a/users/models/mailalias.py b/src/users/models/mailalias.py similarity index 100% rename from users/models/mailalias.py rename to src/users/models/mailalias.py diff --git a/users/models/user.py b/src/users/models/user.py similarity index 100% rename from users/models/user.py rename to src/users/models/user.py diff --git a/users/tables.py b/src/users/tables.py similarity index 100% rename from users/tables.py rename to src/users/tables.py diff --git a/users/templates/groups/group_confirm_delete.html b/src/users/templates/groups/group_confirm_delete.html similarity index 100% rename from users/templates/groups/group_confirm_delete.html rename to src/users/templates/groups/group_confirm_delete.html diff --git a/users/templates/groups/group_details.html b/src/users/templates/groups/group_details.html similarity index 100% rename from users/templates/groups/group_details.html rename to src/users/templates/groups/group_details.html diff --git a/users/templates/groups/group_list.html b/src/users/templates/groups/group_list.html similarity index 100% rename from users/templates/groups/group_list.html rename to src/users/templates/groups/group_list.html diff --git a/users/templates/users/user_confirm_delete.html b/src/users/templates/users/user_confirm_delete.html similarity index 100% rename from users/templates/users/user_confirm_delete.html rename to src/users/templates/users/user_confirm_delete.html diff --git a/users/templates/users/user_details.html b/src/users/templates/users/user_details.html similarity index 100% rename from users/templates/users/user_details.html rename to src/users/templates/users/user_details.html diff --git a/users/templates/users/user_list.html b/src/users/templates/users/user_list.html similarity index 100% rename from users/templates/users/user_list.html rename to src/users/templates/users/user_list.html diff --git a/users/tests/test_customer_group_table_view.py b/src/users/tests/test_customer_group_table_view.py similarity index 100% rename from users/tests/test_customer_group_table_view.py rename to src/users/tests/test_customer_group_table_view.py diff --git a/users/tests/test_customer_user_table_view.py b/src/users/tests/test_customer_user_table_view.py similarity index 100% rename from users/tests/test_customer_user_table_view.py rename to src/users/tests/test_customer_user_table_view.py diff --git a/users/tests/test_group_detail_view.py b/src/users/tests/test_group_detail_view.py similarity index 100% rename from users/tests/test_group_detail_view.py rename to src/users/tests/test_group_detail_view.py diff --git a/users/tests/test_user.py b/src/users/tests/test_user.py similarity index 100% rename from users/tests/test_user.py rename to src/users/tests/test_user.py diff --git a/users/tests/test_user_detail_view.py b/src/users/tests/test_user_detail_view.py similarity index 100% rename from users/tests/test_user_detail_view.py rename to src/users/tests/test_user_detail_view.py diff --git a/users/urls.py b/src/users/urls.py similarity index 100% rename from users/urls.py rename to src/users/urls.py diff --git a/users/views.py b/src/users/views.py similarity index 100% rename from users/views.py rename to src/users/views.py