1
1
Fork 0

Moving on

dev
Jan Kužílek 5 years ago
parent 67091af854
commit f0641be55c

@ -10,12 +10,16 @@ rope = "*"
[packages] [packages]
flask = "*" flask = "*"
sqlalchemy = "*"
flask-sqlalchemy = "*" flask-sqlalchemy = "*"
flask-migrate = "*" flask-migrate = "*"
alembic = "*"
pillow = "*" pillow = "*"
psycopg2 = "*" psycopg2 = "*"
flask-login = "*"
flask-wtf = "*"
flask-assets = "*"
pyscss = "*"
libsass = "*"
cssmin = "*"
[requires] [requires]
python_version = "3.7" python_version = "3.8"

292
Pipfile.lock generated

@ -1,11 +1,11 @@
{ {
"_meta": { "_meta": {
"hash": { "hash": {
"sha256": "3f46403e414b456bf1041f33aefa6fe65adfd30537269cdb23e8c055f3fec29d" "sha256": "2b4208c857a995a746d67b2b523ebd5caface2c836881c0b549e9474d200c507"
}, },
"pipfile-spec": 6, "pipfile-spec": 6,
"requires": { "requires": {
"python_version": "3.7" "python_version": "3.8"
}, },
"sources": [ "sources": [
{ {
@ -18,10 +18,9 @@
"default": { "default": {
"alembic": { "alembic": {
"hashes": [ "hashes": [
"sha256:4a4811119efbdc5259d1f4c8f6de977b36ad3bcc919f59a29c2960c5ef9149e4" "sha256:49277bb7242192bbb9eac58fed4fe02ec6c3a2a4b4345d2171197459266482b2"
], ],
"index": "pypi", "version": "==1.3.1"
"version": "==1.1.0"
}, },
"click": { "click": {
"hashes": [ "hashes": [
@ -30,6 +29,13 @@
], ],
"version": "==7.0" "version": "==7.0"
}, },
"cssmin": {
"hashes": [
"sha256:e012f0cc8401efcf2620332339011564738ae32be8c84b2e43ce8beaec1067b6"
],
"index": "pypi",
"version": "==0.2.0"
},
"flask": { "flask": {
"hashes": [ "hashes": [
"sha256:13f9f196f330c7c2c5d7a5cf91af894110ca0215ac051b5844701f2bfd934d52", "sha256:13f9f196f330c7c2c5d7a5cf91af894110ca0215ac051b5844701f2bfd934d52",
@ -38,6 +44,20 @@
"index": "pypi", "index": "pypi",
"version": "==1.1.1" "version": "==1.1.1"
}, },
"flask-assets": {
"hashes": [
"sha256:6031527b89fb3509d1581d932affa5a79dd348cfffb58d0aef99a43461d47847"
],
"index": "pypi",
"version": "==0.12"
},
"flask-login": {
"hashes": [
"sha256:c815c1ac7b3e35e2081685e389a665f2c74d7e077cb93cecabaea352da4752ec"
],
"index": "pypi",
"version": "==0.4.1"
},
"flask-migrate": { "flask-migrate": {
"hashes": [ "hashes": [
"sha256:6fb038be63d4c60727d5dfa5f581a6189af5b4e2925bc378697b4f0a40cfb4e1", "sha256:6fb038be63d4c60727d5dfa5f581a6189af5b4e2925bc378697b4f0a40cfb4e1",
@ -48,11 +68,19 @@
}, },
"flask-sqlalchemy": { "flask-sqlalchemy": {
"hashes": [ "hashes": [
"sha256:0c9609b0d72871c540a7945ea559c8fdf5455192d2db67219509aed680a3d45a", "sha256:0078d8663330dc05a74bc72b3b6ddc441b9a744e2f56fe60af1a5bfc81334327",
"sha256:8631bbea987bc3eb0f72b1f691d47bd37ceb795e73b59ab48586d76d75a7c605" "sha256:6974785d913666587949f7c2946f7001e4fa2cb2d19f4e69ead02e4b8f50b33d"
], ],
"index": "pypi", "index": "pypi",
"version": "==2.4.0" "version": "==2.4.1"
},
"flask-wtf": {
"hashes": [
"sha256:5d14d55cfd35f613d99ee7cba0fc3fbbe63ba02f544d349158c14ca15561cc36",
"sha256:d9a9e366b32dcbb98ef17228e76be15702cd2600675668bca23f63a7947fd5ac"
],
"index": "pypi",
"version": "==0.14.2"
}, },
"itsdangerous": { "itsdangerous": {
"hashes": [ "hashes": [
@ -63,10 +91,32 @@
}, },
"jinja2": { "jinja2": {
"hashes": [ "hashes": [
"sha256:065c4f02ebe7f7cf559e49ee5a95fb800a9e4528727aec6f24402a5374c65013", "sha256:74320bb91f31270f9551d46522e33af46a80c3d619f4a4bf42b3164d30b5911f",
"sha256:14dd6caf1527abb21f08f86c784eac40853ba93edb79552aa1e4b8aef1b61c7b" "sha256:9fe95f19286cfefaa917656583d020be14e7859c6b0252588391e47db34527de"
],
"version": "==2.10.3"
},
"libsass": {
"hashes": [
"sha256:003a65b4facb4c5dbace53fb0f70f61c5aae056a04b4d112a198c3c9674b31f2",
"sha256:0fd8b4337b3b101c6e6afda9112cc0dc4bacb9133b59d75d65968c7317aa3272",
"sha256:338e9ae066bf1fde874e335324d5355c52d2081d978b4f74fc59536564b35b08",
"sha256:4dcfd561fb100250b89496e1362b96f2cc804f689a59731eb0f94f9a9e144f4a",
"sha256:50778d4be269a021ba2bf42b5b8f6ff3704ab96a82175a052680bddf3ba7cc9f",
"sha256:6a51393d75f6e3c812785b0fa0b7d67c54258c28011921f204643b55f7355ec0",
"sha256:74acd9adf506142699dfa292f0e569fdccbd9e7cf619e8226f7117de73566e32",
"sha256:81a013a4c2a614927fd1ef7a386eddabbba695cbb02defe8f31cf495106e974c",
"sha256:845a9573b25c141164972d498855f4ad29367c09e6d76fad12955ad0e1c83013",
"sha256:8b5b6d1a7c4ea1d954e0982b04474cc076286493f6af2d0a13c2e950fbe0be95",
"sha256:9b59afa0d755089c4165516400a39a289b796b5612eeef5736ab7a1ebf96a67c",
"sha256:a7e685466448c9b1bf98243339793978f654a1151eb5c975f09b83c7a226f4c1",
"sha256:c93df526eeef90b1ea4799c1d33b6cd5aea3e9f4633738fb95c1287c13e6b404",
"sha256:e318f06f06847ff49b1f8d086ac9ebce1e63404f7ea329adab92f4f16ba0e00e",
"sha256:fc5f8336750f76f1bfae82f7e9e89ae71438d26fc4597e3ab4c05ca8fcd41d8a",
"sha256:fcb7ab4dc81889e5fc99cafbc2017bc76996f9992fc6b175f7a80edac61d71df"
], ],
"version": "==2.10.1" "index": "pypi",
"version": "==0.19.4"
}, },
"mako": { "mako": {
"hashes": [ "hashes": [
@ -109,59 +159,72 @@
}, },
"pillow": { "pillow": {
"hashes": [ "hashes": [
"sha256:0804f77cb1e9b6dbd37601cee11283bba39a8d44b9ddb053400c58e0c0d7d9de", "sha256:047d9473cf68af50ac85f8ee5d5f21a60f849bc17d348da7fc85711287a75031",
"sha256:0ab7c5b5d04691bcbd570658667dd1e21ca311c62dcfd315ad2255b1cd37f64f", "sha256:0f66dc6c8a3cc319561a633b6aa82c44107f12594643efa37210d8c924fc1c71",
"sha256:0b3e6cf3ea1f8cecd625f1420b931c83ce74f00c29a0ff1ce4385f99900ac7c4", "sha256:12c9169c4e8fe0a7329e8658c7e488001f6b4c8e88740e76292c2b857af2e94c",
"sha256:365c06a45712cd723ec16fa4ceb32ce46ad201eb7bbf6d3c16b063c72b61a3ed", "sha256:248cffc168896982f125f5c13e9317c059f74fffdb4152893339f3be62a01340",
"sha256:38301fbc0af865baa4752ddae1bb3cbb24b3d8f221bf2850aad96b243306fa03", "sha256:27faf0552bf8c260a5cee21a76e031acaea68babb64daf7e8f2e2540745082aa",
"sha256:3aef1af1a91798536bbab35d70d35750bd2884f0832c88aeb2499aa2d1ed4992", "sha256:285edafad9bc60d96978ed24d77cdc0b91dace88e5da8c548ba5937c425bca8b",
"sha256:3fe0ab49537d9330c9bba7f16a5f8b02da615b5c809cdf7124f356a0f182eccd", "sha256:384b12c9aa8ef95558abdcb50aada56d74bc7cc131dd62d28c2d0e4d3aadd573",
"sha256:45a619d5c1915957449264c81c008934452e3fd3604e36809212300b2a4dab68", "sha256:38950b3a707f6cef09cd3cbb142474357ad1a985ceb44d921bdf7b4647b3e13e",
"sha256:49f90f147883a0c3778fd29d3eb169d56416f25758d0f66775db9184debc8010", "sha256:4aad1b88933fd6dc2846552b89ad0c74ddbba2f0884e2c162aa368374bf5abab",
"sha256:571b5a758baf1cb6a04233fb23d6cf1ca60b31f9f641b1700bfaab1194020555", "sha256:4ac6148008c169603070c092e81f88738f1a0c511e07bd2bb0f9ef542d375da9",
"sha256:5ac381e8b1259925287ccc5a87d9cf6322a2dc88ae28a97fe3e196385288413f", "sha256:4deb1d2a45861ae6f0b12ea0a786a03d19d29edcc7e05775b85ec2877cb54c5e",
"sha256:6153db744a743c0c8c91b8e3b9d40e0b13a5d31dbf8a12748c6d9bfd3ddc01ad", "sha256:59aa2c124df72cc75ed72c8d6005c442d4685691a30c55321e00ed915ad1a291",
"sha256:6fd63afd14a16f5d6b408f623cc2142917a1f92855f0df997e09a49f0341be8a", "sha256:5a47d2123a9ec86660fe0e8d0ebf0aa6bc6a17edc63f338b73ea20ba11713f12",
"sha256:70acbcaba2a638923c2d337e0edea210505708d7859b87c2bd81e8f9902ae826", "sha256:5cc901c2ab9409b4b7ac7b5bcc3e86ac14548627062463da0af3b6b7c555a871",
"sha256:70b1594d56ed32d56ed21a7fbb2a5c6fd7446cdb7b21e749c9791eac3a64d9e4", "sha256:6c1db03e8dff7b9f955a0fb9907eb9ca5da75b5ce056c0c93d33100a35050281",
"sha256:76638865c83b1bb33bcac2a61ce4d13c17dba2204969dedb9ab60ef62bede686", "sha256:7ce80c0a65a6ea90ef9c1f63c8593fcd2929448613fc8da0adf3e6bfad669d08",
"sha256:7b2ec162c87fc496aa568258ac88631a2ce0acfe681a9af40842fc55deaedc99", "sha256:809c19241c14433c5d6135e1b6c72da4e3b56d5c865ad5736ab99af8896b8f41",
"sha256:7cee2cef07c8d76894ebefc54e4bb707dfc7f258ad155bd61d87f6cd487a70ff", "sha256:83792cb4e0b5af480588601467c0764242b9a483caea71ef12d22a0d0d6bdce2",
"sha256:7d16d4498f8b374fc625c4037742fbdd7f9ac383fd50b06f4df00c81ef60e829", "sha256:846fa202bd7ee0f6215c897a1d33238ef071b50766339186687bd9b7a6d26ac5",
"sha256:b50bc1780681b127e28f0075dfb81d6135c3a293e0c1d0211133c75e2179b6c0", "sha256:9f5529fc02009f96ba95bea48870173426879dc19eec49ca8e08cd63ecd82ddb",
"sha256:bd0582f831ad5bcad6ca001deba4568573a4675437db17c4031939156ff339fa", "sha256:a423c2ea001c6265ed28700df056f75e26215fd28c001e93ef4380b0f05f9547",
"sha256:cfd40d8a4b59f7567620410f966bb1f32dc555b2b19f82a91b147fac296f645c", "sha256:ac4428094b42907aba5879c7c000d01c8278d451a3b7cccd2103e21f6397ea75",
"sha256:e3ae410089de680e8f84c68b755b42bc42c0ceb8c03dbea88a5099747091d38e", "sha256:b1ae48d87f10d1384e5beecd169c77502fcc04a2c00a4c02b85f0a94b419e5f9",
"sha256:e9046e559c299b395b39ac7dbf16005308821c2f24a63cae2ab173bd6aa11616", "sha256:bf4e972a88f8841d8fdc6db1a75e0f8d763e66e3754b03006cbc3854d89f1cb1",
"sha256:ef6be704ae2bc8ad0ebc5cb850ee9139493b0fc4e81abcc240fb392a63ebc808", "sha256:c6414f6aad598364aaf81068cabb077894eb88fed99c6a65e6e8217bab62ae7a",
"sha256:f8dc19d92896558f9c4317ee365729ead9d7bbcf2052a9a19a3ef17abbb8ac5b" "sha256:c710fcb7ee32f67baf25aa9ffede4795fd5d93b163ce95fdc724383e38c9df96",
"sha256:c7be4b8a09852291c3c48d3c25d1b876d2494a0a674980089ac9d5e0d78bd132",
"sha256:c9e5ffb910b14f090ac9c38599063e354887a5f6d7e6d26795e916b4514f2c1a",
"sha256:e0697b826da6c2472bb6488db4c0a7fa8af0d52fa08833ceb3681358914b14e5",
"sha256:e9a3edd5f714229d41057d56ac0f39ad9bdba6767e8c888c951869f0bdd129b0"
], ],
"index": "pypi", "index": "pypi",
"version": "==6.1.0" "version": "==6.2.1"
}, },
"psycopg2": { "psycopg2": {
"hashes": [ "hashes": [
"sha256:128d0fa910ada0157bba1cb74a9c5f92bb8a1dca77cf91a31eb274d1f889e001", "sha256:4212ca404c4445dc5746c0d68db27d2cbfb87b523fe233dc84ecd24062e35677",
"sha256:227fd46cf9b7255f07687e5bde454d7d67ae39ca77e170097cdef8ebfc30c323", "sha256:47fc642bf6f427805daf52d6e52619fe0637648fe27017062d898f3bf891419d",
"sha256:2315e7f104681d498ccf6fd70b0dba5bce65d60ac92171492bfe228e21dcc242", "sha256:72772181d9bad1fa349792a1e7384dde56742c14af2b9986013eb94a240f005b",
"sha256:4b5417dcd2999db0f5a891d54717cfaee33acc64f4772c4bc574d4ff95ed9d80", "sha256:8396be6e5ff844282d4d49b81631772f80dabae5658d432202faf101f5283b7c",
"sha256:640113ddc943522aaf71294e3f2d24013b0edd659b7820621492c9ebd3a2fb0b", "sha256:893c11064b347b24ecdd277a094413e1954f8a4e8cdaf7ffbe7ca3db87c103f0",
"sha256:897a6e838319b4bf648a574afb6cabcb17d0488f8c7195100d48d872419f4457", "sha256:92a07dfd4d7c325dd177548c4134052d4842222833576c8391aab6f74038fc3f",
"sha256:8dceca81409898c870e011c71179454962dec152a1a6b86a347f4be74b16d864", "sha256:965c4c93e33e6984d8031f74e51227bd755376a9df6993774fd5b6fb3288b1f4",
"sha256:b1b8e41da09a0c3ef0b3d4bb72da0dde2abebe583c1e8462973233fd5ad0235f", "sha256:9ab75e0b2820880ae24b7136c4d230383e07db014456a476d096591172569c38",
"sha256:cb407fccc12fc29dc331f2b934913405fa49b9b75af4f3a72d0f50f57ad2ca23", "sha256:b0845e3bdd4aa18dc2f9b6fb78fbd3d9d371ad167fd6d1b7ad01c0a6cdad4fc6",
"sha256:d3a27550a8185e53b244ad7e79e307594b92fede8617d80200a8cce1fba2c60f", "sha256:dca2d7203f0dfce8ea4b3efd668f8ea65cd2b35112638e488a4c12594015f67b",
"sha256:f0e6b697a975d9d3ccd04135316c947dd82d841067c7800ccf622a8717e98df1" "sha256:ed686e5926929887e2c7ae0a700e32c6129abb798b4ad2b846e933de21508151",
"sha256:ef6df7e14698e79c59c7ee7cf94cd62e5b869db369ed4b1b8f7b729ea825712a",
"sha256:f898e5cc0a662a9e12bde6f931263a1bbd350cfb18e1d5336a12927851825bb6"
],
"index": "pypi",
"version": "==2.8.4"
},
"pyscss": {
"hashes": [
"sha256:14a25c33c221a66bb1f000a6a067f376528d3df2f9333cee9c95709a9280cdb0"
], ],
"index": "pypi", "index": "pypi",
"version": "==2.8.3" "version": "==1.3.5"
}, },
"python-dateutil": { "python-dateutil": {
"hashes": [ "hashes": [
"sha256:7e6584c74aeed623791615e26efd690f29817a27c73085b78e4bad02493df2fb", "sha256:73ebfe9dbf22e832286dafa60473e4cd239f8592f699aa5adaf10050e6e1823c",
"sha256:c89805f6f4d64db21ed966fda138f8a5ed7a4fdbc1a8ee329ce1b74e3c74da9e" "sha256:75bb3f31ea686f1197762692a9ee6a7550b59fc6ca3a1f4b5d7e32fb98e2da2a"
], ],
"version": "==2.8.0" "version": "==2.8.1"
}, },
"python-editor": { "python-editor": {
"hashes": [ "hashes": [
@ -173,17 +236,22 @@
}, },
"six": { "six": {
"hashes": [ "hashes": [
"sha256:3350809f0555b11f552448330d0b52d5f24c91a322ea4a15ef22629740f3761c", "sha256:1f1b7d42e254082a9db6279deae68afb421ceba6158efa6131de7b3003ee93fd",
"sha256:d16a0141ec1a18405cd4ce8b4613101da75da0e9a7aec5bdd4fa804d0e0eba73" "sha256:30f610279e8b2578cab6db20741130331735c781b56053c59c4076da27f06b66"
], ],
"version": "==1.12.0" "version": "==1.13.0"
}, },
"sqlalchemy": { "sqlalchemy": {
"hashes": [ "hashes": [
"sha256:2f8ff566a4d3a92246d367f2e9cd6ed3edeef670dcd6dda6dfdc9efed88bcd80" "sha256:afa5541e9dea8ad0014251bc9d56171ca3d8b130c9627c6cb3681cff30be3f8a"
], ],
"index": "pypi", "version": "==1.3.11"
"version": "==1.3.8" },
"webassets": {
"hashes": [
"sha256:e7d9c8887343123fd5b32309b33167428cb1318cdda97ece12d0907fd69d38db"
],
"version": "==0.12.1"
}, },
"werkzeug": { "werkzeug": {
"hashes": [ "hashes": [
@ -191,15 +259,22 @@
"sha256:e5f4a1f98b52b18a93da705a7458e55afb26f32bff83ff5d19189f92462d65c4" "sha256:e5f4a1f98b52b18a93da705a7458e55afb26f32bff83ff5d19189f92462d65c4"
], ],
"version": "==0.16.0" "version": "==0.16.0"
},
"wtforms": {
"hashes": [
"sha256:0cdbac3e7f6878086c334aa25dc5a33869a3954e9d1e015130d65a69309b3b61",
"sha256:e3ee092c827582c50877cdbd49e9ce6d2c5c1f6561f849b3b068c1b8029626f1"
],
"version": "==2.2.1"
} }
}, },
"develop": { "develop": {
"astroid": { "astroid": {
"hashes": [ "hashes": [
"sha256:6560e1e1749f68c64a4b5dee4e091fce798d2f0d84ebe638cf0e0585a343acf4", "sha256:71ea07f44df9568a75d0f354c49143a4575d90645e9fead6dfb52c26a85ed13a",
"sha256:b65db1bbaac9f9f4d190199bb8680af6f6f84fd3769a5ea883df8a91fe68b4c4" "sha256:840947ebfa8b58f318d42301cf8c0a20fd794a33b61cc4638e28e9e61ba32f42"
], ],
"version": "==2.2.5" "version": "==2.3.3"
}, },
"click": { "click": {
"hashes": [ "hashes": [
@ -218,11 +293,11 @@
}, },
"flask-sqlalchemy": { "flask-sqlalchemy": {
"hashes": [ "hashes": [
"sha256:0c9609b0d72871c540a7945ea559c8fdf5455192d2db67219509aed680a3d45a", "sha256:0078d8663330dc05a74bc72b3b6ddc441b9a744e2f56fe60af1a5bfc81334327",
"sha256:8631bbea987bc3eb0f72b1f691d47bd37ceb795e73b59ab48586d76d75a7c605" "sha256:6974785d913666587949f7c2946f7001e4fa2cb2d19f4e69ead02e4b8f50b33d"
], ],
"index": "pypi", "index": "pypi",
"version": "==2.4.0" "version": "==2.4.1"
}, },
"isort": { "isort": {
"hashes": [ "hashes": [
@ -240,33 +315,36 @@
}, },
"jinja2": { "jinja2": {
"hashes": [ "hashes": [
"sha256:065c4f02ebe7f7cf559e49ee5a95fb800a9e4528727aec6f24402a5374c65013", "sha256:74320bb91f31270f9551d46522e33af46a80c3d619f4a4bf42b3164d30b5911f",
"sha256:14dd6caf1527abb21f08f86c784eac40853ba93edb79552aa1e4b8aef1b61c7b" "sha256:9fe95f19286cfefaa917656583d020be14e7859c6b0252588391e47db34527de"
], ],
"version": "==2.10.1" "version": "==2.10.3"
}, },
"lazy-object-proxy": { "lazy-object-proxy": {
"hashes": [ "hashes": [
"sha256:02b260c8deb80db09325b99edf62ae344ce9bc64d68b7a634410b8e9a568edbf", "sha256:0c4b206227a8097f05c4dbdd323c50edf81f15db3b8dc064d08c62d37e1a504d",
"sha256:18f9c401083a4ba6e162355873f906315332ea7035803d0fd8166051e3d402e3", "sha256:194d092e6f246b906e8f70884e620e459fc54db3259e60cf69a4d66c3fda3449",
"sha256:1f2c6209a8917c525c1e2b55a716135ca4658a3042b5122d4e3413a4030c26ce", "sha256:1be7e4c9f96948003609aa6c974ae59830a6baecc5376c25c92d7d697e684c08",
"sha256:2f06d97f0ca0f414f6b707c974aaf8829c2292c1c497642f63824119d770226f", "sha256:4677f594e474c91da97f489fea5b7daa17b5517190899cf213697e48d3902f5a",
"sha256:616c94f8176808f4018b39f9638080ed86f96b55370b5a9463b2ee5c926f6c5f", "sha256:48dab84ebd4831077b150572aec802f303117c8cc5c871e182447281ebf3ac50",
"sha256:63b91e30ef47ef68a30f0c3c278fbfe9822319c15f34b7538a829515b84ca2a0", "sha256:5541cada25cd173702dbd99f8e22434105456314462326f06dba3e180f203dfd",
"sha256:77b454f03860b844f758c5d5c6e5f18d27de899a3db367f4af06bec2e6013a8e", "sha256:59f79fef100b09564bc2df42ea2d8d21a64fdcda64979c0fa3db7bdaabaf6239",
"sha256:83fe27ba321e4cfac466178606147d3c0aa18e8087507caec78ed5a966a64905", "sha256:8d859b89baf8ef7f8bc6b00aa20316483d67f0b1cbf422f5b4dc56701c8f2ffb",
"sha256:84742532d39f72df959d237912344d8a1764c2d03fe58beba96a87bfa11a76d8", "sha256:9254f4358b9b541e3441b007a0ea0764b9d056afdeafc1a5569eee1cc6c1b9ea",
"sha256:874ebf3caaf55a020aeb08acead813baf5a305927a71ce88c9377970fe7ad3c2", "sha256:9651375199045a358eb6741df3e02a651e0330be090b3bc79f6d0de31a80ec3e",
"sha256:9f5caf2c7436d44f3cec97c2fa7791f8a675170badbfa86e1992ca1b84c37009", "sha256:97bb5884f6f1cdce0099f86b907aa41c970c3c672ac8b9c8352789e103cf3156",
"sha256:a0c8758d01fcdfe7ae8e4b4017b13552efa7f1197dd7358dc9da0576f9d0328a", "sha256:9b15f3f4c0f35727d3a0fba4b770b3c4ebbb1fa907dbcc046a1d2799f3edd142",
"sha256:a4def978d9d28cda2d960c279318d46b327632686d82b4917516c36d4c274512", "sha256:a2238e9d1bb71a56cd710611a1614d1194dc10a175c1e08d75e1a7bcc250d442",
"sha256:ad4f4be843dace866af5fc142509e9b9817ca0c59342fdb176ab6ad552c927f5", "sha256:a6ae12d08c0bf9909ce12385803a543bfe99b95fe01e752536a60af2b7797c62",
"sha256:ae33dd198f772f714420c5ab698ff05ff900150486c648d29951e9c70694338e", "sha256:ca0a928a3ddbc5725be2dd1cf895ec0a254798915fb3a36af0964a0a4149e3db",
"sha256:b4a2b782b8a8c5522ad35c93e04d60e2ba7f7dcb9271ec8e8c3e08239be6c7b4", "sha256:cb2c7c57005a6804ab66f106ceb8482da55f5314b7fcb06551db1edae4ad1531",
"sha256:c462eb33f6abca3b34cdedbe84d761f31a60b814e173b98ede3c81bb48967c4f", "sha256:d74bb8693bf9cf75ac3b47a54d716bbb1a92648d5f781fc799347cfc95952383",
"sha256:fd135b8d35dfdcdb984828c84d695937e58cc5f49e1c854eb311c4d6aa03f4f1" "sha256:d945239a5639b3ff35b70a88c5f2f491913eb94871780ebfabb2568bd58afc5a",
], "sha256:eba7011090323c1dadf18b3b689845fd96a61ba0a1dfbd7f24b921398affc357",
"version": "==1.4.2" "sha256:efa1909120ce98bbb3777e8b6f92237f5d5c8ea6758efea36a473e1d38f7d3e4",
"sha256:f3900e8a5de27447acbf900b4750b0ddfd7ec1ea7fbaf11dfa911141bc522af0"
],
"version": "==1.4.3"
}, },
"markupsafe": { "markupsafe": {
"hashes": [ "hashes": [
@ -310,11 +388,11 @@
}, },
"pylint": { "pylint": {
"hashes": [ "hashes": [
"sha256:5d77031694a5fb97ea95e828c8d10fc770a1df6eb3906067aaed42201a8a6a09", "sha256:3db5468ad013380e987410a8d6956226963aed94ecb5f9d3a28acca6d9ac36cd",
"sha256:723e3db49555abaf9bf79dc474c6b9e2935ad82230b10c1138a71ea41ac0fff1" "sha256:886e6afc935ea2590b462664b161ca9a5e40168ea99e5300935f6591ad467df4"
], ],
"index": "pypi", "index": "pypi",
"version": "==2.3.1" "version": "==2.4.4"
}, },
"pylint-flask-sqlalchemy": { "pylint-flask-sqlalchemy": {
"hashes": [ "hashes": [
@ -335,38 +413,16 @@
}, },
"six": { "six": {
"hashes": [ "hashes": [
"sha256:3350809f0555b11f552448330d0b52d5f24c91a322ea4a15ef22629740f3761c", "sha256:1f1b7d42e254082a9db6279deae68afb421ceba6158efa6131de7b3003ee93fd",
"sha256:d16a0141ec1a18405cd4ce8b4613101da75da0e9a7aec5bdd4fa804d0e0eba73" "sha256:30f610279e8b2578cab6db20741130331735c781b56053c59c4076da27f06b66"
], ],
"version": "==1.12.0" "version": "==1.13.0"
}, },
"sqlalchemy": { "sqlalchemy": {
"hashes": [ "hashes": [
"sha256:2f8ff566a4d3a92246d367f2e9cd6ed3edeef670dcd6dda6dfdc9efed88bcd80" "sha256:afa5541e9dea8ad0014251bc9d56171ca3d8b130c9627c6cb3681cff30be3f8a"
], ],
"index": "pypi", "version": "==1.3.11"
"version": "==1.3.8"
},
"typed-ast": {
"hashes": [
"sha256:18511a0b3e7922276346bcb47e2ef9f38fb90fd31cb9223eed42c85d1312344e",
"sha256:262c247a82d005e43b5b7f69aff746370538e176131c32dda9cb0f324d27141e",
"sha256:2b907eb046d049bcd9892e3076c7a6456c93a25bebfe554e931620c90e6a25b0",
"sha256:354c16e5babd09f5cb0ee000d54cfa38401d8b8891eefa878ac772f827181a3c",
"sha256:4e0b70c6fc4d010f8107726af5fd37921b666f5b31d9331f0bd24ad9a088e631",
"sha256:630968c5cdee51a11c05a30453f8cd65e0cc1d2ad0d9192819df9978984529f4",
"sha256:66480f95b8167c9c5c5c87f32cf437d585937970f3fc24386f313a4c97b44e34",
"sha256:71211d26ffd12d63a83e079ff258ac9d56a1376a25bc80b1cdcdf601b855b90b",
"sha256:95bd11af7eafc16e829af2d3df510cecfd4387f6453355188342c3e79a2ec87a",
"sha256:bc6c7d3fa1325a0c6613512a093bc2a2a15aeec350451cbdf9e1d4bffe3e3233",
"sha256:cc34a6f5b426748a507dd5d1de4c1978f2eb5626d51326e43280941206c209e1",
"sha256:d755f03c1e4a51e9b24d899561fec4ccaf51f210d52abdf8c07ee2849b212a36",
"sha256:d7c45933b1bdfaf9f36c579671fec15d25b06c8398f113dab64c18ed1adda01d",
"sha256:d896919306dd0aa22d0132f62a1b78d11aaf4c9fc5b3410d3c666b818191630a",
"sha256:ffde2fbfad571af120fcbfbbc61c72469e72f550d676c3342492a9dfdefb8f12"
],
"markers": "implementation_name == 'cpython'",
"version": "==1.4.0"
}, },
"werkzeug": { "werkzeug": {
"hashes": [ "hashes": [

@ -3,16 +3,21 @@ import os
from flask import Flask from flask import Flask
from flask_sqlalchemy import SQLAlchemy from flask_sqlalchemy import SQLAlchemy
from flask_migrate import Migrate from flask_migrate import Migrate
from flask_login import LoginManager
from flask_assets import Environment as AssetsEnvironment, Bundle as AssetsBundle
db = SQLAlchemy() db = SQLAlchemy()
migrate = Migrate() migrate = Migrate()
login = LoginManager()
assets = AssetsEnvironment()
def create_app(): def create_app():
app = Flask(__name__) app = Flask(__name__)
app.config.from_mapping( app.config.from_mapping(
#SQLALCHEMY_DATABASE_URI='sqlite:///{}'.format(os.path.join(app.instance_path, 'yadc.db')) SECRET_KEY='dev',
SQLALCHEMY_DATABASE_URI='postgresql://{}:{}@{}:{}/{}'.format('yadc', 'omegalul', 'localhost', 5432, 'yadc') #SQLALCHEMY_DATABASE_URI='sqlite:///{}'.format(os.path.join(app.instance_path, 'yadc.db')),
SQLALCHEMY_DATABASE_URI='postgresql://{}:{}@{}:{}/{}'.format('yadc', 'omegalul', 'localhost', 5432, 'yadc'),
) )
try: try:
@ -22,8 +27,17 @@ def create_app():
db.init_app(app) db.init_app(app)
migrate.init_app(app, db) migrate.init_app(app, db)
login.init_app(app)
assets.init_app(app)
from yadc import main, auth
app.register_blueprint(main.bp)
app.register_blueprint(auth.bp)
login.login_view = 'auth.login'
#assets.url = app.static_url_path
scss = AssetsBundle('default.scss', filters='libsass', output='all.css')
assets.register('scss_all', scss)
from yadc import models from yadc import models

@ -0,0 +1,40 @@
from flask import request
from flask_wtf import FlaskForm
from wtforms import StringField, PasswordField, BooleanField, SubmitField
from wtforms.validators import DataRequired
from flask_login import current_user, login_user, logout_user
from werkzeug.urls import url_parse
from yadc.models import User
class LoginForm(FlaskForm):
username = StringField('Username', validators=[DataRequired()])
password = PasswordField('Password', validators=[DataRequired()])
remember_me = BooleanField('Remember me')
submit = SubmitField('Log In')
from flask import Blueprint, render_template, flash, redirect, url_for
bp = Blueprint('auth', __name__)
@bp.route('/login', methods=['GET', 'POST'])
def login():
form = LoginForm()
if form.validate_on_submit():
#flash('Login requested for user {}, remember_me={}'.format(form.username.data, form.remember_me.data))
user = User.query.filter_by(username=form.username.data).first()
if user is None or not user.check_password(form.password.data):
flash('Invalid username or password.')
return redirect(url_for('auth.login'))
login_user(user, remember=form.remember_me.data)
nextpg = request.args.get('next')
if not nextpg and url_parse(nextpg).netloc != '':
nextpg = url_for('main.index')
#flash('Logged in as {}'.format(user.username))
return redirect(nextpg)
return render_template('login.html', form=form)
@bp.route('/logout')
def logout():
logout_user()
return redirect(url_for('main.index'))

@ -0,0 +1,40 @@
from flask import Blueprint, render_template, flash, redirect
from flask_login import login_required
bp = Blueprint('main', __name__)
@bp.route('/index')
def index():
return render_template('index.html')
@bp.route('/humm')
@login_required
def humm():
return render_template('index.html')
@bp.route('/')
@bp.route('/post')
def post():
return render_template('index.html')
pass
@bp.route('/post/show/<id>')
def post_show(id):
return render_template('post.html')
pass
@bp.route('/post/new')
@bp.route('/post/create')
@bp.route('/post/upload')
@login_required
def post_upload():
pass
@bp.route('/user/show/<username>')
def user_profile(username):
pass
@bp.route('/user/settings')
@login_required
def user_settings():
pass

@ -1,7 +1,10 @@
import enum import enum
from datetime import datetime from datetime import datetime
from yadc import db from flask_login import UserMixin
from werkzeug.security import check_password_hash, generate_password_hash
from yadc import db, login
class OP_LEVEL(enum.Enum): class OP_LEVEL(enum.Enum):
@ -32,12 +35,11 @@ class TAG_CATEGORY(enum.Enum):
character = 4 character = 4
copyright = 5 copyright = 5
class User(db.Model): class User(UserMixin, db.Model):
id = db.Column(db.Integer, primary_key=True) id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String(128), unique=True, nullable=False) username = db.Column(db.String(128), unique=True, nullable=False)
email = db.Column(db.String(256), unique=True) email = db.Column(db.String(256), unique=True)
pass_hash = db.Column(db.String(128)) pass_hash = db.Column(db.String(128))
pass_salt = db.Column(db.String(128))
op_level = db.Column(db.Enum(OP_LEVEL), default=OP_LEVEL.user, nullable=False) op_level = db.Column(db.Enum(OP_LEVEL), default=OP_LEVEL.user, nullable=False)
created = db.Column(db.DateTime, default=datetime.now()) created = db.Column(db.DateTime, default=datetime.now())
updated = db.Column(db.DateTime, default=datetime.now()) updated = db.Column(db.DateTime, default=datetime.now())
@ -46,6 +48,19 @@ class User(db.Model):
#authored_posts = db.relationship('Post', back_populates='author') #authored_posts = db.relationship('Post', back_populates='author')
#approved_posts = db.relationship('Post', back_populates='approver') #approved_posts = db.relationship('Post', back_populates='approver')
def __repr__(self):
return '<User {}>'.format(self.username)
def create_password(self, password):
self.pass_hash = generate_password_hash(password, salt_length=16)
def check_password(self, password):
return check_password_hash(self.pass_hash, password)
@login.user_loader
def load_user(id):
return User.query.get(int(id))
post_tags = db.Table('post_tags', db.metadata, post_tags = db.Table('post_tags', db.metadata,
db.Column('post_id', db.Integer, db.ForeignKey('post.id')), db.Column('post_id', db.Integer, db.ForeignKey('post.id')),
db.Column('tag_id', db.Integer, db.ForeignKey('tag.id')) db.Column('tag_id', db.Integer, db.ForeignKey('tag.id'))
@ -92,5 +107,3 @@ class Comment(db.Model):
user = db.relationship('User', backref=db.backref('comments', lazy=True)) user = db.relationship('User', backref=db.backref('comments', lazy=True))
# THINK ABOUT LAZY LOADING # THINK ABOUT LAZY LOADING

@ -0,0 +1,567 @@
@charset "UTF-8";
// _ _ _ _ _
// (_) | | | | | (_)
// _ _ __ ___| |_ _ __| | ___ _ __ ___ ___ __| |_ __ _
// | | '_ \ / __| | | | |/ _` |/ _ \ | '_ ` _ \ / _ \/ _` | |/ _` |
// | | | | | (__| | |_| | (_| | __/ | | | | | | __/ (_| | | (_| |
// |_|_| |_|\___|_|\__,_|\__,_|\___| |_| |_| |_|\___|\__,_|_|\__,_|
//
// Simple, elegant and maintainable media queries in Sass
// v1.4.9
//
// http://include-media.com
//
// Authors: Eduardo Boucas (@eduardoboucas)
// Hugo Giraudel (@hugogiraudel)
//
// This project is licensed under the terms of the MIT license
////
/// include-media library public configuration
/// @author Eduardo Boucas
/// @access public
////
///
/// Creates a list of global breakpoints
///
/// @example scss - Creates a single breakpoint with the label `phone`
/// $breakpoints: ('phone': 320px);
///
$breakpoints: (
'phone': 320px,
'tablet': 768px,
'desktop': 1024px
) !default;
///
/// Creates a list of static expressions or media types
///
/// @example scss - Creates a single media type (screen)
/// $media-expressions: ('screen': 'screen');
///
/// @example scss - Creates a static expression with logical disjunction (OR operator)
/// $media-expressions: (
/// 'retina2x': '(-webkit-min-device-pixel-ratio: 2), (min-resolution: 192dpi)'
/// );
///
$media-expressions: (
'screen': 'screen',
'print': 'print',
'handheld': 'handheld',
'landscape': '(orientation: landscape)',
'portrait': '(orientation: portrait)',
'retina2x': '(-webkit-min-device-pixel-ratio: 2), (min-resolution: 192dpi), (min-resolution: 2dppx)',
'retina3x': '(-webkit-min-device-pixel-ratio: 3), (min-resolution: 350dpi), (min-resolution: 3dppx)'
) !default;
///
/// Defines a number to be added or subtracted from each unit when declaring breakpoints with exclusive intervals
///
/// @example scss - Interval for pixels is defined as `1` by default
/// @include media('>128px') {}
///
/// /* Generates: */
/// @media (min-width: 129px) {}
///
/// @example scss - Interval for ems is defined as `0.01` by default
/// @include media('>20em') {}
///
/// /* Generates: */
/// @media (min-width: 20.01em) {}
///
/// @example scss - Interval for rems is defined as `0.1` by default, to be used with `font-size: 62.5%;`
/// @include media('>2.0rem') {}
///
/// /* Generates: */
/// @media (min-width: 2.1rem) {}
///
$unit-intervals: (
'px': 1,
'em': 0.01,
'rem': 0.1,
'': 0
) !default;
///
/// Defines whether support for media queries is available, useful for creating separate stylesheets
/// for browsers that don't support media queries.
///
/// @example scss - Disables support for media queries
/// $im-media-support: false;
/// @include media('>=tablet') {
/// .foo {
/// color: tomato;
/// }
/// }
///
/// /* Generates: */
/// .foo {
/// color: tomato;
/// }
///
$im-media-support: true !default;
///
/// Selects which breakpoint to emulate when support for media queries is disabled. Media queries that start at or
/// intercept the breakpoint will be displayed, any others will be ignored.
///
/// @example scss - This media query will show because it intercepts the static breakpoint
/// $im-media-support: false;
/// $im-no-media-breakpoint: 'desktop';
/// @include media('>=tablet') {
/// .foo {
/// color: tomato;
/// }
/// }
///
/// /* Generates: */
/// .foo {
/// color: tomato;
/// }
///
/// @example scss - This media query will NOT show because it does not intercept the desktop breakpoint
/// $im-media-support: false;
/// $im-no-media-breakpoint: 'tablet';
/// @include media('>=desktop') {
/// .foo {
/// color: tomato;
/// }
/// }
///
/// /* No output */
///
$im-no-media-breakpoint: 'desktop' !default;
///
/// Selects which media expressions are allowed in an expression for it to be used when media queries
/// are not supported.
///
/// @example scss - This media query will show because it intercepts the static breakpoint and contains only accepted media expressions
/// $im-media-support: false;
/// $im-no-media-breakpoint: 'desktop';
/// $im-no-media-expressions: ('screen');
/// @include media('>=tablet', 'screen') {
/// .foo {
/// color: tomato;
/// }
/// }
///
/// /* Generates: */
/// .foo {
/// color: tomato;
/// }
///
/// @example scss - This media query will NOT show because it intercepts the static breakpoint but contains a media expression that is not accepted
/// $im-media-support: false;
/// $im-no-media-breakpoint: 'desktop';
/// $im-no-media-expressions: ('screen');
/// @include media('>=tablet', 'retina2x') {
/// .foo {
/// color: tomato;
/// }
/// }
///
/// /* No output */
///
$im-no-media-expressions: ('screen', 'portrait', 'landscape') !default;
////
/// Cross-engine logging engine
/// @author Hugo Giraudel
/// @access private
////
///
/// Log a message either with `@error` if supported
/// else with `@warn`, using `feature-exists('at-error')`
/// to detect support.
///
/// @param {String} $message - Message to log
///
@function im-log($message) {
@if feature-exists('at-error') {
@error $message;
} @else {
@warn $message;
$_: noop();
}
@return $message;
}
///
/// Wrapper mixin for the log function so it can be used with a more friendly
/// API than `@if im-log('..') {}` or `$_: im-log('..')`. Basically, use the function
/// within functions because it is not possible to include a mixin in a function
/// and use the mixin everywhere else because it's much more elegant.
///
/// @param {String} $message - Message to log
///
@mixin log($message) {
@if im-log($message) {}
}
///
/// Function with no `@return` called next to `@warn` in Sass 3.3
/// to trigger a compiling error and stop the process.
///
@function noop() {}
///
/// Determines whether a list of conditions is intercepted by the static breakpoint.
///
/// @param {Arglist} $conditions - Media query conditions
///
/// @return {Boolean} - Returns true if the conditions are intercepted by the static breakpoint
///
@function im-intercepts-static-breakpoint($conditions...) {
$no-media-breakpoint-value: map-get($breakpoints, $im-no-media-breakpoint);
@if not $no-media-breakpoint-value {
@if im-log('`#{$im-no-media-breakpoint}` is not a valid breakpoint.') {}
}
@each $condition in $conditions {
@if not map-has-key($media-expressions, $condition) {
$operator: get-expression-operator($condition);
$prefix: get-expression-prefix($operator);
$value: get-expression-value($condition, $operator);
@if ($prefix == 'max' and $value <= $no-media-breakpoint-value) or
($prefix == 'min' and $value > $no-media-breakpoint-value) {
@return false;
}
} @else if not index($im-no-media-expressions, $condition) {
@return false;
}
}
@return true;
}
////
/// Parsing engine
/// @author Hugo Giraudel
/// @access private
////
///
/// Get operator of an expression
///
/// @param {String} $expression - Expression to extract operator from
///
/// @return {String} - Any of `>=`, `>`, `<=`, `<`, ``, ``
///
@function get-expression-operator($expression) {
@each $operator in ('>=', '>', '<=', '<', '', '') {
@if str-index($expression, $operator) {
@return $operator;
}
}
// It is not possible to include a mixin inside a function, so we have to
// rely on the `im-log(..)` function rather than the `log(..)` mixin. Because
// functions cannot be called anywhere in Sass, we need to hack the call in
// a dummy variable, such as `$_`. If anybody ever raise a scoping issue with
// Sass 3.3, change this line in `@if im-log(..) {}` instead.
$_: im-log('No operator found in `#{$expression}`.');
}
///
/// Get dimension of an expression, based on a found operator
///
/// @param {String} $expression - Expression to extract dimension from
/// @param {String} $operator - Operator from `$expression`
///
/// @return {String} - `width` or `height` (or potentially anything else)
///
@function get-expression-dimension($expression, $operator) {
$operator-index: str-index($expression, $operator);
$parsed-dimension: str-slice($expression, 0, $operator-index - 1);
$dimension: 'width';
@if str-length($parsed-dimension) > 0 {
$dimension: $parsed-dimension;
}
@return $dimension;
}
///
/// Get dimension prefix based on an operator
///
/// @param {String} $operator - Operator
///
/// @return {String} - `min` or `max`
///
@function get-expression-prefix($operator) {
@return if(index(('<', '<=', ''), $operator), 'max', 'min');
}
///
/// Get value of an expression, based on a found operator
///
/// @param {String} $expression - Expression to extract value from
/// @param {String} $operator - Operator from `$expression`
///
/// @return {Number} - A numeric value
///
@function get-expression-value($expression, $operator) {
$operator-index: str-index($expression, $operator);
$value: str-slice($expression, $operator-index + str-length($operator));
@if map-has-key($breakpoints, $value) {
$value: map-get($breakpoints, $value);
} @else {
$value: to-number($value);
}
$interval: map-get($unit-intervals, unit($value));
@if not $interval {
// It is not possible to include a mixin inside a function, so we have to
// rely on the `im-log(..)` function rather than the `log(..)` mixin. Because
// functions cannot be called anywhere in Sass, we need to hack the call in
// a dummy variable, such as `$_`. If anybody ever raise a scoping issue with
// Sass 3.3, change this line in `@if im-log(..) {}` instead.
$_: im-log('Unknown unit `#{unit($value)}`.');
}
@if $operator == '>' {
$value: $value + $interval;
} @else if $operator == '<' {
$value: $value - $interval;
}
@return $value;
}
///
/// Parse an expression to return a valid media-query expression
///
/// @param {String} $expression - Expression to parse
///
/// @return {String} - Valid media query
///
@function parse-expression($expression) {
// If it is part of $media-expressions, it has no operator
// then there is no need to go any further, just return the value
@if map-has-key($media-expressions, $expression) {
@return map-get($media-expressions, $expression);
}
$operator: get-expression-operator($expression);
$dimension: get-expression-dimension($expression, $operator);
$prefix: get-expression-prefix($operator);
$value: get-expression-value($expression, $operator);
@return '(#{$prefix}-#{$dimension}: #{$value})';
}
///
/// Slice `$list` between `$start` and `$end` indexes
///
/// @access private
///
/// @param {List} $list - List to slice
/// @param {Number} $start [1] - Start index
/// @param {Number} $end [length($list)] - End index
///
/// @return {List} Sliced list
///
@function slice($list, $start: 1, $end: length($list)) {
@if length($list) < 1 or $start > $end {
@return ();
}
$result: ();
@for $i from $start through $end {
$result: append($result, nth($list, $i));
}
@return $result;
}
////
/// String to number converter
/// @author Hugo Giraudel
/// @access private
////
///
/// Casts a string into a number
///
/// @param {String | Number} $value - Value to be parsed
///
/// @return {Number}
///
@function to-number($value) {
@if type-of($value) == 'number' {
@return $value;
} @else if type-of($value) != 'string' {
$_: im-log('Value for `to-number` should be a number or a string.');
}
$first-character: str-slice($value, 1, 1);
$result: 0;
$digits: 0;
$minus: ($first-character == '-');
$numbers: ('0': 0, '1': 1, '2': 2, '3': 3, '4': 4, '5': 5, '6': 6, '7': 7, '8': 8, '9': 9);
// Remove +/- sign if present at first character
@if ($first-character == '+' or $first-character == '-') {
$value: str-slice($value, 2);
}
@for $i from 1 through str-length($value) {
$character: str-slice($value, $i, $i);
@if not (index(map-keys($numbers), $character) or $character == '.') {
@return to-length(if($minus, -$result, $result), str-slice($value, $i))
}
@if $character == '.' {
$digits: 1;
} @else if $digits == 0 {
$result: $result * 10 + map-get($numbers, $character);
} @else {
$digits: $digits * 10;
$result: $result + map-get($numbers, $character) / $digits;
}
}
@return if($minus, -$result, $result);
}
///
/// Add `$unit` to `$value`
///
/// @param {Number} $value - Value to add unit to
/// @param {String} $unit - String representation of the unit
///
/// @return {Number} - `$value` expressed in `$unit`
///
@function to-length($value, $unit) {
$units: ('px': 1px, 'cm': 1cm, 'mm': 1mm, '%': 1%, 'ch': 1ch, 'pc': 1pc, 'in': 1in, 'em': 1em, 'rem': 1rem, 'pt': 1pt, 'ex': 1ex, 'vw': 1vw, 'vh': 1vh, 'vmin': 1vmin, 'vmax': 1vmax);
@if not index(map-keys($units), $unit) {
$_: im-log('Invalid unit `#{$unit}`.');
}
@return $value * map-get($units, $unit);
}
///
/// This mixin aims at redefining the configuration just for the scope of
/// the call. It is helpful when having a component needing an extended
/// configuration such as custom breakpoints (referred to as tweakpoints)
/// for instance.
///
/// @author Hugo Giraudel
///
/// @param {Map} $tweakpoints [()] - Map of tweakpoints to be merged with `$breakpoints`
/// @param {Map} $tweak-media-expressions [()] - Map of tweaked media expressions to be merged with `$media-expression`
///
/// @example scss - Extend the global breakpoints with a tweakpoint
/// @include media-context(('custom': 678px)) {
/// .foo {
/// @include media('>phone', '<=custom') {
/// // ...
/// }
/// }
/// }
///
/// @example scss - Extend the global media expressions with a custom one
/// @include media-context($tweak-media-expressions: ('all': 'all')) {
/// .foo {
/// @include media('all', '>phone') {
/// // ...
/// }
/// }
/// }
///
/// @example scss - Extend both configuration maps
/// @include media-context(('custom': 678px), ('all': 'all')) {
/// .foo {
/// @include media('all', '>phone', '<=custom') {
/// // ...
/// }
/// }
/// }
///
@mixin media-context($tweakpoints: (), $tweak-media-expressions: ()) {
// Save global configuration
$global-breakpoints: $breakpoints;
$global-media-expressions: $media-expressions;
// Update global configuration
$breakpoints: map-merge($breakpoints, $tweakpoints) !global;
$media-expressions: map-merge($media-expressions, $tweak-media-expressions) !global;
@content;
// Restore global configuration
$breakpoints: $global-breakpoints !global;
$media-expressions: $global-media-expressions !global;
}
////
/// include-media public exposed API
/// @author Eduardo Boucas
/// @access public
////
///
/// Generates a media query based on a list of conditions
///
/// @param {Arglist} $conditions - Media query conditions
///
/// @example scss - With a single set breakpoint
/// @include media('>phone') { }
///
/// @example scss - With two set breakpoints
/// @include media('>phone', '<=tablet') { }
///
/// @example scss - With custom values
/// @include media('>=358px', '<850px') { }
///
/// @example scss - With set breakpoints with custom values
/// @include media('>desktop', '<=1350px') { }
///
/// @example scss - With a static expression
/// @include media('retina2x') { }
///
/// @example scss - Mixing everything
/// @include media('>=350px', '<tablet', 'retina3x') { }
///
@mixin media($conditions...) {
@if ($im-media-support and length($conditions) == 0) or
(not $im-media-support and im-intercepts-static-breakpoint($conditions...)) {
@content;
} @else if ($im-media-support and length($conditions) > 0) {
@media #{unquote(parse-expression(nth($conditions, 1)))} {
// Recursive call
@include media(slice($conditions, 2)...) {
@content;
}
}
}
}

@ -0,0 +1,356 @@
@import "_include-media";
$breakpoints: (tablet: 560px, desktop: 900px);
* {
box-sizing: border-box;
}
$bg-color: #222; //#20141f;
$text-color: #fff;
$a-color: #fff;
$ahover-color: #909090;
$header-bg-color: #111;
$nav-bg-color: #222d;//#20141fd0;
$nav-bg-color_hover: #333;//#20141fa0;
$desktop-width: 560px;
@mixin mobile {
@media only screen and (max-width: #{$desktop-width - 1px}) {
@content;
}
}
@mixin desktop {
@media only screen and (min-width: #{$desktop-width}) {
@content;
}
}
body {
margin: 0;
font-family: Verdana, Geneva, Tahoma, sans-serif;
//font-size: 14px;
background-color: $bg-color;
color: $text-color;
}
a {
color: $a-color;
text-decoration: none;
}
a:hover {
color: $ahover-color;
text-decoration: none;
}
header {
display: flex;
align-items: baseline;
padding: 0 10px;
background-color: $header-bg-color;
> a.logo {
font-size: 2em;
margin: 6px;
}
// @include mobile { font-size: 1.3em; }
// @include desktop { font-size: 1.1em; }
@include media("<tablet") { position: relative; }
> nav {
flex-grow: 1;
display: flex;
> ._overlay {
display: none;
}
@include media("<tablet") {
display: none;
&._drop {
display: flex;
flex-flow: column nowrap;
position: absolute;
margin: 0;
top: 100%;
left: 0;
right: 0;
z-index: 10;
background-color: $nav-bg-color;
}
> a, a#user-menu, .user_dropdown > a {
padding: 12px;
padding-left: 24px;
//text-align: center;
&:hover, &:active {
background-color: $nav-bg-color_hover;
}
}
.user {
&::before {
content: "";
display: block;
border-top: 1px solid grey;
margin: 2px 12px;
}
#user-menu {
display: block;
}
.user_dropdown {
display: flex;
flex-flow: column nowrap;
}
}
> ._overlay {
display: block;
position: fixed;
width: 100%;
height: 100%;
z-index: -1;
background-color: #0006;
@at-root {
html.oh { overflow: hidden; }
}
}
}
@include media(">=tablet") {
margin: 0px 5px;
align-items: center;
> * {
margin: 0 5px;
padding: 6px 0;
}
> .user {
padding: 0;
margin-left: auto;
margin-right: 0;
#user-menu {
display: block;
padding: 6px 10px; //replication of nav/*
}
position: relative;
.user_dropdown {
//display: none;
opacity: .1; // BOI DAT HACK
height: 0;
width: 0;
overflow: hidden;
a {
padding: 10px;
}
a:hover {
background-color: $nav-bg-color_hover;
}
}
&:hover > .user_dropdown {
display: flex;
flex-flow: column nowrap;
position: absolute;
margin: 0;
top: 100%;
left: 0;
right: 0;
z-index: 10;
background-color: $nav-bg-color;
opacity: 1; // BOI DAT HACK
height: unset;
width: unset;
transition: .2s ease;
}
}
}
}
> #nav-menu {
display: none;
@include media("<tablet") {
display: block;
margin: 5px;
margin-left: auto;
padding: 0 2px;
align-self: center;
font-size: 2em;
cursor: pointer;
}
}
}
.main_wrap {
// margin: 0 auto;
max-width: 1200px;
display: flex;
padding: 8px;
h4 {
margin: 0;
margin-bottom: 10px;
font-size: 1.4em;
}
@include media("<desktop") {
flex-flow: column nowrap;
// section {
// margin: 0 10px;
// }
}
@include media(">=desktop") {
flex-flow: row nowrap;
}
> section.tag_panel {
flex-shrink: 0;
article.tags {
// @include media(">=desktop") {
// margin-left: 10px;
// margin-top: 10px;
// }
padding: 10px;
.tag_container {
display: flex;
> span {
margin: 2px 2px;
padding: 6px 12px;
//text-align: center;
border-radius: 4px;
background-color: #0005;
> .fa-tag {
font-size: .9em;
margin-right: 2px;
}
> .count {
// display: none;
font-size: .8em;
}
// > a {
// display: block;
// }
}
}
@include media("<desktop") {
.tag_container {
flex-flow: row wrap;
}
}
@include media(">=desktop") {
.tag_container {
flex-flow: column nowrap;
align-items: start;
}
}
}
}
overflow: hidden;
> section.content {
.posts {
display: flex;
flex-flow: row wrap;
// margin-left: -4px;
// margin-right: -4px;
// margin-left: 0;
// margin-right: 0;
// margin: 0;
// padding: 8px;
// margin: 0 8px;
// @include media(">=desktop") {
// margin-right: 8px;
// margin-top: 8px;
// }
&::after {
content: "";
flex: /*10000*/350 0 350px;
}
> figure {
position: relative;
margin: 8px;
img {
display: block;
width: 100%;
height: 100%;
border-radius: 4px;
transition: .2s ease;
}
&:hover img {
opacity: .7;
}
}
}
.pagin {
margin: 10px auto;
display: flex;
flex-flow: row nowrap;
justify-content: center;
> a {
display: block;
background-color: #0005;
padding: 8px 12px;
margin: 0 2px;
}
}
}
}
footer {
padding: 10px;
// background-color: $header-bg-color;
text-align: center;
}

@ -0,0 +1,254 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<!--<link rel="stylesheet" href="{{ url_for('static', filename='default.css')}}">-->
{% assets "scss_all" %}
<link rel="stylesheet" href="{{ ASSET_URL }}">
{% endassets %}
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
<title>YaDc</title>
</head>
<body>
<header>
<a href="#" class="logo">
<span>YaDc</span>
</a>
<nav id="main-nav">
<a href="#">Posts</a>
<a href="#">Threads</a>
<a href="#">Upload</a>
<div class="user">
<a href="#" id="user-menu">KuxaBeast</a>
<!--<span class="user fa fa-user"></span>-->
<div class="user_dropdown">
<a href="#">Profile</a>
<a href="#">Settings</a>
<a href="#">Log out</a>
</div>
</div>
<div class="_overlay"></div>
</nav>
<span id="nav-menu" class="fa fa-bars"></span>
</header>
<div class="main_wrap">
<section class="tag_panel">
<article class="tags">
<h4>Tags</h4>
<div class="tag_container">
<span>
<span class="fa fa-tag"></span>
<a href="#">neko</a>
<span class="count">10</span>
</span>
<span>
<span class="fa fa-tag"></span>
<a href="#">works</a>
<span class="count">2</span>
</span>
<span>
<span class="fa fa-tag"></span>
<a href="#">anime</a>
<span class="count">4</span>
</span>
<span>
<span class="fa fa-tag"></span>
<a href="#">manga</a>
<span class="count">7</span>
</span>
<span>
<span class="fa fa-tag"></span>
<a href="#">original</a>
<span class="count">5</span>
</span>
<span>
<span class="fa fa-tag"></span>
<a href="#">azur lane</a>
<span class="count">5</span>
</span>
<span>
<span class="fa fa-tag"></span>
<a href="#">figure</a>
<span class="count">5</span>
</span>
<span>
<span class="fa fa-tag"></span>
<a href="#">touhou</a>
<span class="count">5</span>
</span>
<span>
<span class="fa fa-tag"></span>
<a href="#">photoshop</a>
<span class="count">5</span>
</span>
<span>
<span class="fa fa-tag"></span>
<a href="#">close</a>
<span class="count">5</span>
</span>
<span>
<span class="fa fa-tag"></span>
<a href="#">cropped</a>
<span class="count">5</span>
</span>
<span>
<span class="fa fa-tag"></span>
<a href="#">waifu2x</a>
<span class="count">5</span>
</span>
</div>
</article>
</section>
<section class="content">
<div class="posts">
<figure style="flex: 307.87 1 307.87px;">
<a href="#">
<img src="static/ryuzu/916993.png" alt="">
</a>
<!--<div class="thumb-info">
<span>RyuZU²</span>
<span>1920x1080</span>
<span>1.5M</span>
</div>-->
</figure>
<figure style="flex: 309.68 1 309.68px;">
<img src="static/ryuzu/916500.jpg" alt="">
</figure>
<figure style="flex: 157.98 1 157.98px;">
<img src="static/pixiv/illust_76819896_20191017_131929.jpg" alt="">
</figure>
<figure style="flex: 391.11 1 391.11px;">
<img src="static/ryuzu/916132.png" alt="">
</figure>
<figure style="flex: 220.00 1 220.00px;">
<img src="static/pixiv/illust_75885180_20191105_174853.jpg" alt="">
</figure>
<figure style="flex: 334.97 1 334.97px;">
<img src="static/ryuzu/916486.png" alt="">
</figure>
<figure style="flex: 155.53 1 155.53px;">
<img src="static/pixiv/illust_71840908_20191117_162206.png" alt="">
</figure>
<figure style="flex: 391.11 1 391.11px;">
<img src="static/ryuzu/916269.jpg" alt="">
</figure>
<figure style="flex: 131.98 1 131.98px;">
<img src="static/pixiv/illust_72206228_20191026_131238.jpg" alt="">
</figure>
<figure style="flex: 391.11 1 391.11px;">
<img src="static/ryuzu/916234.png" alt="">
</figure>
<figure style="flex: 157.75 1 157.75px;">
<img src="static/pixiv/illust_66441619_20191117_162011.png" alt="">
</figure>
<figure style="flex: 340.92 1 340.92px;">
<img src="static/ryuzu/917345.png" alt="">
</figure>
<figure style="flex: 155.28 1 155.28px;">
<img src="static/pixiv/illust_71851314_20191017_131351.jpg" alt="">
</figure>
<figure style="flex: 356.46 1 356.46px;">
<img src="static/ryuzu/917364.png" alt="">
</figure>
<figure style="flex: 155.55 1 155.55px;">
<img src="static/pixiv/illust_74700365_20191026_131807.jpg" alt="">
</figure>
<figure style="flex: 391.11 1 391.11px;">
<img src="static/ryuzu/916232.png" alt="">
</figure>
<figure style="flex: 229.12 1 229.12px;">
<img src="static/pixiv/illust_73298123_20191017_131918.jpg" alt="">
</figure>
<figure style="flex: 318.79 1 318.79px;">
<img src="static/ryuzu/917571.png" alt="">
</figure>
<figure style="flex: 155.56 1 155.56px;">
<img src="static/pixiv/illust_72068885_20191017_131812.jpg" alt="">
</figure>
<figure style="flex: 361.95 1 361.95px;">
<img src="static/ryuzu/917362.png" alt="">
</figure>
<figure style="flex: 329.28 1 329.28px;">
<img src="static/pixiv/illust_74981463_20191010_180604.png" alt="">
</figure>
<figure style="flex: 201.44 1 201.44px;">
<img src="static/pixiv/illust_73112550_20191017_132201.jpg" alt="">
</figure>
<figure style="flex: 134.56 1 134.56px;">
<img src="static/pixiv/illust_58205189_20191117_161917.jpg" alt="">
</figure>
<figure style="flex: 170.19 1 170.19px;">
<img src="static/pixiv/illust_75746945_20191026_131754.png" alt="">
</figure>
<figure style="flex: 155.54 1 155.54px;">
<img src="static/pixiv/illust_77361639_20191026_131342.png" alt="">
</figure>
<figure style="flex: 220.00 1 220.00px;">
<img src="static/pixiv/illust_76970188_20191105_175035.jpg" alt="">
</figure>
<figure style="flex: 134.89 1 134.89px;">
<img src="static/pixiv/illust_77544221_20191117_162451.png" alt="">
</figure>
<figure style="flex: 171.16 1 171.16px;">
<img src="static/pixiv/illust_76606724_20191027_110006.png" alt="">
</figure>
<figure style="flex: 107.11 1 107.11px;">
<img src="static/pixiv/illust_71850098_20191017_131539.jpg" alt="">
</figure>
<figure style="flex: 220.99 1 220.99px;">
<img src="static/pixiv/illust_76418587_20191027_110252.png" alt="">
</figure>
<figure style="flex: 155.78 1 155.78px;">
<img src="static/pixiv/illust_76629400_20191026_131307.jpg" alt="">
</figure>
</div>
<div class="pagin">
<a href="#"><span class="fa fa-chevron-left"></span></a>
<a href="#">1</a>
<a href="#">2</a>
<a href="#">3</a>
<a href="#">4</a>
<a href="#">5</a>
<a href="#"><span class="fa fa-chevron-right"></span></a>
</div>
</section>
</div>
<footer>
Produced by KuxaBeast
</footer>
<script>
let nav_menu = document.querySelectorAll("#nav-menu, nav#main-nav > ._overlay")
let nav_menu_event = function(ev) {
let drop = document.getElementById("main-nav")
let html = document.getElementsByTagName('html')[0]
if (!drop.classList.contains("_drop")) {
drop.classList.add("_drop")
html.classList.add("oh")
window.scrollTo(0, 0);
} else {
drop.classList.remove("_drop")
html.classList.remove("oh")
}
}
nav_menu.forEach(element => {
element.addEventListener('click', nav_menu_event)
});
document.getElementById("user-menu").addEventListener('click', (ev) => {
let drop = document.getElementsByClassName("user_dropdown")[0]
if (!drop.classList.contains("_drop")) {
drop.classList.add("_drop")
} else {
drop.classList.remove("_drop")
}
})
</script>
</body>
</html>

@ -0,0 +1,144 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<!--<link rel="stylesheet" href="{{ url_for('static', filename='default.css')}}">-->
{% assets "scss_all" %}
<link rel="stylesheet" href="{{ ASSET_URL }}">
{% endassets %}
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
<title>YaDc</title>
</head>
<body>
<header>
<a href="#" class="logo">
<span>YaDc</span>
</a>
<nav id="main-nav">
<a href="#">Posts</a>
<a href="#">Threads</a>
<a href="#">Upload</a>
<div class="user">
<a href="#" id="user-menu">KuxaBeast</a>
<!--<span class="user fa fa-user"></span>-->
<div class="user_dropdown">
<a href="#">Profile</a>
<a href="#">Settings</a>
<a href="#">Log out</a>
</div>
</div>
<div class="_overlay"></div>
</nav>
<span id="nav-menu" class="fa fa-bars"></span>
</header>
<div class="main_wrap">
<section class="tag_panel">
<article class="tags">
<h4>Tags</h4>
<div class="tag_container">
<span>
<span class="fa fa-tag"></span>
<a href="#">neko</a>
<span class="count">10</span>
</span>
<span>
<span class="fa fa-tag"></span>
<a href="#">works</a>
<span class="count">2</span>
</span>
<span>
<span class="fa fa-tag"></span>
<a href="#">anime</a>
<span class="count">4</span>
</span>
<span>
<span class="fa fa-tag"></span>
<a href="#">manga</a>
<span class="count">7</span>
</span>
<span>
<span class="fa fa-tag"></span>
<a href="#">original</a>
<span class="count">5</span>
</span>
<span>
<span class="fa fa-tag"></span>
<a href="#">azur lane</a>
<span class="count">5</span>
</span>
<span>
<span class="fa fa-tag"></span>
<a href="#">figure</a>
<span class="count">5</span>
</span>
<span>
<span class="fa fa-tag"></span>
<a href="#">touhou</a>
<span class="count">5</span>
</span>
<span>
<span class="fa fa-tag"></span>
<a href="#">photoshop</a>
<span class="count">5</span>
</span>
<span>
<span class="fa fa-tag"></span>
<a href="#">close</a>
<span class="count">5</span>
</span>
<span>
<span class="fa fa-tag"></span>
<a href="#">cropped</a>
<span class="count">5</span>
</span>
<span>
<span class="fa fa-tag"></span>
<a href="#">waifu2x</a>
<span class="count">5</span>
</span>
</div>
</article>
</section>
<section class="content">
</section>
</div>
<footer>
Produced by KuxaBeast
</footer>
<script>
let nav_menu = document.querySelectorAll("#nav-menu, nav#main-nav > ._overlay")
let nav_menu_event = function(ev) {
let drop = document.getElementById("main-nav")
let html = document.getElementsByTagName('html')[0]
if (!drop.classList.contains("_drop")) {
drop.classList.add("_drop")
html.classList.add("oh")
window.scrollTo(0, 0);
} else {
drop.classList.remove("_drop")
html.classList.remove("oh")
}
}
nav_menu.forEach(element => {
element.addEventListener('click', nav_menu_event)
});
document.getElementById("user-menu").addEventListener('click', (ev) => {
let drop = document.getElementsByClassName("user_dropdown")[0]
if (!drop.classList.contains("_drop")) {
drop.classList.add("_drop")
} else {
drop.classList.remove("_drop")
}
})
</script>
</body>
</html>
Loading…
Cancel
Save