diff --git a/Pipfile b/Pipfile
index 667320ad3..783e88c32 100644
--- a/Pipfile
+++ b/Pipfile
@@ -5,49 +5,52 @@ verify_ssl = true
[dev-packages]
kegbot = {editable = true,path = "."}
+black = "*"
+flake8 = "*"
+pytest = "*"
+pytest-django = "*"
+requests-mock = "*"
+sphinx-issues = "*"
+sphinx = "*"
+vcrpy = "*"
[packages]
celery = "*"
coloredlogs = "*"
-dj-database-url = "==0.4.2"
-django-bootstrap-pagination = "==1.6.2"
-django-crispy-forms = "==1.6.1"
-django-imagekit = "==4.0.1"
-django-redis = "==4.8.0"
-django-registration = "==2.2"
-flake8 = "*"
+dj-database-url = "*"
+django-bootstrap-pagination = "*"
+django-crispy-forms = "*"
+django-imagekit = "*"
+django-redis = "*"
+django-registration = "*"
foursquare = "==1!2016.9.12"
gunicorn = "*"
httplib2 = "*"
isodate = "*"
-jsonfield = "==2.0.2"
-mock = "==2.0.0"
+jsonfield = "*"
oauthlib = "*"
pilkit = "*"
protobuf = "*"
python-gflags = "*"
pytz = "*"
redis = "*"
-requests-mock = "*"
requests-oauthlib = "*"
requests = "*"
tweepy = "*"
-vcrpy = "*"
-whitenoise = "==3.3.0"
-Django = "==1.11.28"
+whitenoise = "*"
+Django = "<3"
Pillow = "*"
PyYAML = "*"
mysqlclient = "*"
-sphinx = "*"
-pytest = "*"
-pytest-django = "*"
future = "*"
addict = "*"
kegbot-api = "*"
-sphinx-issues = "*"
[scripts]
kegbot = "python bin/kegbot"
[requires]
python_version = "3"
+
+[pipenv]
+allow_prereleases = true
diff --git a/Pipfile.lock b/Pipfile.lock
index 4b0f0dc2a..8e1810b5d 100644
--- a/Pipfile.lock
+++ b/Pipfile.lock
@@ -1,7 +1,7 @@
{
"_meta": {
"hash": {
- "sha256": "5b0a850ab15e85dde013b893e32e9fc6d14ed73ba13c1e7848caa391316c78ad"
+ "sha256": "1ad179d4d352c8e52c63726c61db3bed01b5683fa696dfb9c8f5c7b4294ba3c2"
},
"pipfile-spec": 6,
"requires": {
@@ -24,13 +24,6 @@
"index": "pypi",
"version": "==2.2.1"
},
- "alabaster": {
- "hashes": [
- "sha256:446438bdcca0e05bd45ea2de1668c1d9b032e1a9154c2c259092d77031ddd359",
- "sha256:a661d72d58e6ea8a57f7a86e37d86716863ee5e92788398526d58b26a4e4dc02"
- ],
- "version": "==0.7.12"
- },
"amqp": {
"hashes": [
"sha256:6e649ca13a7df3faacdc8bbb280aa9a6602d22fd9d545336077e573a1f4ff3b8",
@@ -38,20 +31,6 @@
],
"version": "==2.5.2"
},
- "attrs": {
- "hashes": [
- "sha256:08a96c641c3a74e44eb59afb61a24f2cb9f4d7188748e76ba4bb5edfa3cb7d1c",
- "sha256:f7b7ce16570fe9965acd6d30101a28f62fb4a7f9e926b3bbc9b61f8b04247e72"
- ],
- "version": "==19.3.0"
- },
- "babel": {
- "hashes": [
- "sha256:1aac2ae2d0d8ea368fa90906567f5c08463d98ade155c0c4bfedd6a0f7160e38",
- "sha256:d670ea0b10f8b723672d3a6abeb87b565b244da220d76b4dba1b66269ec152d4"
- ],
- "version": "==2.8.0"
- },
"billiard": {
"hashes": [
"sha256:26fd494dc3251f8ce1f5559744f18aeed427fdaf29a75d7baae26752a5d3816f",
@@ -89,21 +68,28 @@
"index": "pypi",
"version": "==14.0"
},
+ "confusable-homoglyphs": {
+ "hashes": [
+ "sha256:3b4a0d9fa510669498820c91a0bfc0c327568cecec90648cf3819d4a6fc6a751",
+ "sha256:e3ce611028d882b74a5faa69e3cbb5bd4dcd9f69936da6e73d33eda42c917944"
+ ],
+ "version": "==3.2.0"
+ },
"dj-database-url": {
"hashes": [
- "sha256:a6832d8445ee9d788c5baa48aef8130bf61fdc442f7d9a548424d25cd85c9f08",
- "sha256:e16d94c382ea0564c48038fa7fe8d9c890ef1ab1a8ec4cb48e732c124b9482fd"
+ "sha256:4aeaeb1f573c74835b0686a2b46b85990571159ffc21aa57ecd4d1e1cb334163",
+ "sha256:851785365761ebe4994a921b433062309eb882fedd318e1b0fcecc607ed02da9"
],
"index": "pypi",
- "version": "==0.4.2"
+ "version": "==0.5.0"
},
"django": {
"hashes": [
- "sha256:a3b01cdff845a43830d7ccacff55e0b8ff08305a4cbf894517a686e53ba3ad2d",
- "sha256:b33ce35f47f745fea6b5aa3cf3f4241069803a3712d423ac748bd673a39741eb"
+ "sha256:1226168be1b1c7efd0e66ee79b0e0b58b2caa7ed87717909cd8a57bb13a7079a",
+ "sha256:9a4635813e2d498a3c01b10c701fe4a515d76dd290aaa792ccb65ca4ccb6b038"
],
"index": "pypi",
- "version": "==1.11.28"
+ "version": "==2.2.10"
},
"django-appconf": {
"hashes": [
@@ -114,63 +100,43 @@
},
"django-bootstrap-pagination": {
"hashes": [
- "sha256:5dc2280cc8254bd87ec9534e5f2af0867bfa481b270b3e29ed86ddb22a74cfa7"
+ "sha256:47e742679cf109e12f10ae09d5263433f94440818cf7b023e90a3f5252849639",
+ "sha256:69d826d92217325611cb86e49944d8261e3c92eaa4deafea5a605d79fd363883"
],
"index": "pypi",
- "version": "==1.6.2"
+ "version": "==1.7.1"
},
"django-crispy-forms": {
"hashes": [
- "sha256:18e904c7bd55c45201739cb343272767ff820263a1fca40a7b388006ce94910c",
- "sha256:c894f3a44e111ae6c6226c67741d96d120adb942de41dc8b2a991b87de7ff9c0"
+ "sha256:0afc0ba730f52a13c02bfbd0e1423af4577a337d73a8a0ef96f2cbbc5f345ffa",
+ "sha256:2db711ce31f6f9ef42c16829cc3636e3819f97c1b22a3b706afed679bc417e88"
],
"index": "pypi",
- "version": "==1.6.1"
+ "version": "==1.8.1"
},
"django-imagekit": {
"hashes": [
- "sha256:68182a9c946b013cd30eb04fb43371c29e255bce99a1dfe3af27b981c3780c39",
- "sha256:ed6c68b0efe87a1f21696f37eff4e1366ec25ebfcdd8b0614f7df45f904c6b1e"
+ "sha256:304c3379f6a5cac387e47ace11195a603ad3cb01e3e951b45489824d25b00359",
+ "sha256:6ec0afb77cdf52cd453c9fc2c10ef350d111edfd6ce53c5977aa8a0e22cee00c"
],
"index": "pypi",
- "version": "==4.0.1"
+ "version": "==4.0.2"
},
"django-redis": {
"hashes": [
- "sha256:5229da5b07ccb8d3e3e9ee098c0b7c03e20eba48634bc456697dd73d62c68b19",
- "sha256:9660332cf9de5689a7ebbe0c623c4a0de79e0916a6ae867b5d0b94759bba46c9"
+ "sha256:a5b1e3ffd3198735e6c529d9bdf38ca3fcb3155515249b98dc4d966b8ddf9d2b",
+ "sha256:e1aad4cc5bd743d8d0b13d5cae0cef5410eaace33e83bff5fc3a139ad8db50b4"
],
"index": "pypi",
- "version": "==4.8.0"
+ "version": "==4.11.0"
},
"django-registration": {
"hashes": [
- "sha256:14ffa4c07ad902afaa1d096ea241282b76724348b8b7518cecad617870178283"
+ "sha256:071dce4f4348ff1da338a0a09bda8e34d44c001ab569777e4c88ee21ce5c499e",
+ "sha256:2437a098e6e06983e4b4b442680b1c49a2e979f1a0ef3a504beb3a84ff36131d"
],
"index": "pypi",
- "version": "==2.2"
- },
- "docutils": {
- "hashes": [
- "sha256:0c5b78adfbf7762415433f5515cd5c9e762339e23369dbe8000d84a4bf4ab3af",
- "sha256:c2de3a60e9e7d07be26b7f2b00ca0309c207e06c100f9cc2a94931fc75a478fc"
- ],
- "version": "==0.16"
- },
- "entrypoints": {
- "hashes": [
- "sha256:589f874b313739ad35be6e0cd7efde2a4e9b6fea91edcc34e58ecbb8dbe56d19",
- "sha256:c70dd71abe5a8c85e55e12c19bd91ccfeec11a6e99044204511f9ed547d48451"
- ],
- "version": "==0.3"
- },
- "flake8": {
- "hashes": [
- "sha256:45681a117ecc81e870cbf1262835ae4af5e7a8b08e40b944a8a6e6b895914cfb",
- "sha256:49356e766643ad15072a789a20915d3c91dc89fd313ccd71802303fd67e4deca"
- ],
- "index": "pypi",
- "version": "==3.7.9"
+ "version": "==3.1"
},
"foursquare": {
"hashes": [
@@ -216,13 +182,6 @@
],
"version": "==2.9"
},
- "imagesize": {
- "hashes": [
- "sha256:6965f19a6a2039c7d48bca7dba2473069ff854c36ae6f19d2cde309d998228a1",
- "sha256:b1f6b5a4eab1f73479a50fb79fcf729514a900c341d8503d62a62dbc4127a2b1"
- ],
- "version": "==1.2.0"
- },
"importlib-metadata": {
"hashes": [
"sha256:06f5b3a99029c7134207dd882428a66992a9de2bef7c2b699b5641f9886c3302",
@@ -239,20 +198,13 @@
"index": "pypi",
"version": "==0.6.0"
},
- "jinja2": {
- "hashes": [
- "sha256:93187ffbc7808079673ef52771baa950426fd664d3aad1d0fa3e95644360e250",
- "sha256:b0eaf100007721b5c16c1fc1eecb87409464edc10469ddc9a22a27a99123be49"
- ],
- "version": "==2.11.1"
- },
"jsonfield": {
"hashes": [
- "sha256:a0a7fdee736ff049059409752b045281a225610fecbda9b9bd588ba976493c12",
- "sha256:beb1cd4850d6d6351c32daefcb826c01757744e9c863228a642f87a1a4acb834"
+ "sha256:7e4e84597de21eeaeeaaa7cc5da08c61c48a9b64d0c446b2d71255d01812887a",
+ "sha256:df857811587f252b97bafba42e02805e70a398a7a47870bc6358a0308dd689ed"
],
"index": "pypi",
- "version": "==2.0.2"
+ "version": "==3.1.0"
},
"kegbot-api": {
"hashes": [
@@ -268,6 +220,312 @@
],
"version": "==4.6.7"
},
+ "mysqlclient": {
+ "hashes": [
+ "sha256:4c82187dd6ab3607150fbb1fa5ef4643118f3da122b8ba31c3149ddd9cf0cb39",
+ "sha256:9e6080a7aee4cc6a06b58b59239f20f1d259c1d2fddf68ddeed242d2311c7087",
+ "sha256:f3fdaa9a38752a3b214a6fe79d7cae3653731a53e577821f9187e67cbecb2e16",
+ "sha256:f646f8d17d02be0872291f258cce3813497bc7888cd4712a577fd1e719b2f213"
+ ],
+ "index": "pypi",
+ "version": "==1.4.6"
+ },
+ "oauthlib": {
+ "hashes": [
+ "sha256:bee41cc35fcca6e988463cacc3bcb8a96224f470ca547e697b604cc697b2f889",
+ "sha256:df884cd6cbe20e32633f1db1072e9356f53638e4361bef4e8b03c9127c9328ea"
+ ],
+ "index": "pypi",
+ "version": "==3.1.0"
+ },
+ "pilkit": {
+ "hashes": [
+ "sha256:ddb30c2f0198a147e56b151476c3bb9fe045fbfd5b0a0fa2a3148dba62d1559f"
+ ],
+ "index": "pypi",
+ "version": "==2.0"
+ },
+ "pillow": {
+ "hashes": [
+ "sha256:0a628977ac2e01ca96aaae247ec2bd38e729631ddf2221b4b715446fd45505be",
+ "sha256:4d9ed9a64095e031435af120d3c910148067087541131e82b3e8db302f4c8946",
+ "sha256:54ebae163e8412aff0b9df1e88adab65788f5f5b58e625dc5c7f51eaf14a6837",
+ "sha256:5bfef0b1cdde9f33881c913af14e43db69815c7e8df429ceda4c70a5e529210f",
+ "sha256:5f3546ceb08089cedb9e8ff7e3f6a7042bb5b37c2a95d392fb027c3e53a2da00",
+ "sha256:5f7ae9126d16194f114435ebb79cc536b5682002a4fa57fa7bb2cbcde65f2f4d",
+ "sha256:62a889aeb0a79e50ecf5af272e9e3c164148f4bd9636cc6bcfa182a52c8b0533",
+ "sha256:7406f5a9b2fd966e79e6abdaf700585a4522e98d6559ce37fc52e5c955fade0a",
+ "sha256:8453f914f4e5a3d828281a6628cf517832abfa13ff50679a4848926dac7c0358",
+ "sha256:87269cc6ce1e3dee11f23fa515e4249ae678dbbe2704598a51cee76c52e19cda",
+ "sha256:875358310ed7abd5320f21dd97351d62de4929b0426cdb1eaa904b64ac36b435",
+ "sha256:8ac6ce7ff3892e5deaab7abaec763538ffd011f74dc1801d93d3c5fc541feee2",
+ "sha256:91b710e3353aea6fc758cdb7136d9bbdcb26b53cefe43e2cba953ac3ee1d3313",
+ "sha256:9d2ba4ed13af381233e2d810ff3bab84ef9f18430a9b336ab69eaf3cd24299ff",
+ "sha256:a62ec5e13e227399be73303ff301f2865bf68657d15ea50b038d25fc41097317",
+ "sha256:ab76e5580b0ed647a8d8d2d2daee170e8e9f8aad225ede314f684e297e3643c2",
+ "sha256:bf4003aa538af3f4205c5fac56eacaa67a6dd81e454ffd9e9f055fff9f1bc614",
+ "sha256:bf598d2e37cf8edb1a2f26ed3fb255191f5232badea4003c16301cb94ac5bdd0",
+ "sha256:c18f70dc27cc5d236f10e7834236aff60aadc71346a5bc1f4f83a4b3abee6386",
+ "sha256:c5ed816632204a2fc9486d784d8e0d0ae754347aba99c811458d69fcdfd2a2f9",
+ "sha256:dc058b7833184970d1248135b8b0ab702e6daa833be14035179f2acb78ff5636",
+ "sha256:ff3797f2f16bf9d17d53257612da84dd0758db33935777149b3334c01ff68865"
+ ],
+ "index": "pypi",
+ "version": "==7.0.0"
+ },
+ "protobuf": {
+ "hashes": [
+ "sha256:0bae429443cc4748be2aadfdaf9633297cfaeb24a9a02d0ab15849175ce90fab",
+ "sha256:24e3b6ad259544d717902777b33966a1a069208c885576254c112663e6a5bb0f",
+ "sha256:310a7aca6e7f257510d0c750364774034272538d51796ca31d42c3925d12a52a",
+ "sha256:52e586072612c1eec18e1174f8e3bb19d08f075fc2e3f91d3b16c919078469d0",
+ "sha256:73152776dc75f335c476d11d52ec6f0f6925774802cd48d6189f4d5d7fe753f4",
+ "sha256:7774bbbaac81d3ba86de646c39f154afc8156717972bf0450c9dbfa1dc8dbea2",
+ "sha256:82d7ac987715d8d1eb4068bf997f3053468e0ce0287e2729c30601feb6602fee",
+ "sha256:8eb9c93798b904f141d9de36a0ba9f9b73cc382869e67c9e642c0aba53b0fc07",
+ "sha256:adf0e4d57b33881d0c63bb11e7f9038f98ee0c3e334c221f0858f826e8fb0151",
+ "sha256:c40973a0aee65422d8cb4e7d7cbded95dfeee0199caab54d5ab25b63bce8135a",
+ "sha256:c77c974d1dadf246d789f6dad1c24426137c9091e930dbf50e0a29c1fcf00b1f",
+ "sha256:dd9aa4401c36785ea1b6fff0552c674bdd1b641319cb07ed1fe2392388e9b0d7",
+ "sha256:e11df1ac6905e81b815ab6fd518e79be0a58b5dc427a2cf7208980f30694b956",
+ "sha256:e2f8a75261c26b2f5f3442b0525d50fd79a71aeca04b5ec270fc123536188306",
+ "sha256:e512b7f3a4dd780f59f1bf22c302740e27b10b5c97e858a6061772668cd6f961",
+ "sha256:ef2c2e56aaf9ee914d3dccc3408d42661aaf7d9bb78eaa8f17b2e6282f214481",
+ "sha256:fac513a9dc2a74b99abd2e17109b53945e364649ca03d9f7a0b96aa8d1807d0a",
+ "sha256:fdfb6ad138dbbf92b5dbea3576d7c8ba7463173f7d2cb0ca1bd336ec88ddbd80"
+ ],
+ "index": "pypi",
+ "version": "==3.11.3"
+ },
+ "pysocks": {
+ "hashes": [
+ "sha256:08e69f092cc6dbe92a0fdd16eeb9b9ffbc13cadfe5ca4c7bd92ffb078b293299",
+ "sha256:2725bd0a9925919b9b51739eea5f9e2bae91e83288108a9ad338b2e3a4435ee5",
+ "sha256:3f8804571ebe159c380ac6de37643bb4685970655d3bba243530d6558b799aa0"
+ ],
+ "version": "==1.7.1"
+ },
+ "python-gflags": {
+ "hashes": [
+ "sha256:40ae131e899ef68e9e14aa53ca063839c34f6a168afe622217b5b875492a1ee2"
+ ],
+ "index": "pypi",
+ "version": "==3.1.2"
+ },
+ "pytz": {
+ "hashes": [
+ "sha256:1c557d7d0e871de1f5ccd5833f60fb2550652da6be2693c1e02300743d21500d",
+ "sha256:b02c06db6cf09c12dd25137e563b31700d3b80fcc4ad23abb7a315f2789819be"
+ ],
+ "index": "pypi",
+ "version": "==2019.3"
+ },
+ "pyyaml": {
+ "hashes": [
+ "sha256:059b2ee3194d718896c0ad077dd8c043e5e909d9180f387ce42012662a4946d6",
+ "sha256:1cf708e2ac57f3aabc87405f04b86354f66799c8e62c28c5fc5f88b5521b2dbf",
+ "sha256:24521fa2890642614558b492b473bee0ac1f8057a7263156b02e8b14c88ce6f5",
+ "sha256:4fee71aa5bc6ed9d5f116327c04273e25ae31a3020386916905767ec4fc5317e",
+ "sha256:70024e02197337533eef7b85b068212420f950319cc8c580261963aefc75f811",
+ "sha256:74782fbd4d4f87ff04159e986886931456a1894c61229be9eaf4de6f6e44b99e",
+ "sha256:940532b111b1952befd7db542c370887a8611660d2b9becff75d39355303d82d",
+ "sha256:cb1f2f5e426dc9f07a7681419fe39cee823bb74f723f36f70399123f439e9b20",
+ "sha256:dbbb2379c19ed6042e8f11f2a2c66d39cceb8aeace421bfc29d085d93eda3689",
+ "sha256:e3a057b7a64f1222b56e47bcff5e4b94c4f61faac04c7c4ecb1985e18caa3994",
+ "sha256:e9f45bd5b92c7974e59bcd2dcc8631a6b6cc380a904725fce7bc08872e691615"
+ ],
+ "index": "pypi",
+ "version": "==5.3"
+ },
+ "redis": {
+ "hashes": [
+ "sha256:0dcfb335921b88a850d461dc255ff4708294943322bd55de6cfd68972490ca1f",
+ "sha256:b205cffd05ebfd0a468db74f0eedbff8df1a7bfc47521516ade4692991bb0833"
+ ],
+ "index": "pypi",
+ "version": "==3.4.1"
+ },
+ "requests": {
+ "hashes": [
+ "sha256:43999036bfa82904b6af1d99e4882b560e5e2c68e5c4b0aa03b655f3d7d73fee",
+ "sha256:b3f43d496c6daba4493e7c431722aeb7dbc6288f52a6e04e7b6023b0247817e6"
+ ],
+ "index": "pypi",
+ "version": "==2.23.0"
+ },
+ "requests-oauthlib": {
+ "hashes": [
+ "sha256:7f71572defaecd16372f9006f33c2ec8c077c3cfa6f5911a9a90202beb513f3d",
+ "sha256:b4261601a71fd721a8bd6d7aa1cc1d6a8a93b4a9f5e96626f8e4d91e8beeaa6a"
+ ],
+ "index": "pypi",
+ "version": "==1.3.0"
+ },
+ "six": {
+ "hashes": [
+ "sha256:236bdbdce46e6e6a3d61a337c0f8b763ca1e8717c03b369e87a7ec7ce1319c0a",
+ "sha256:8f3cd2e254d8f793e7f3d6d9df77b92252b52637291d0f0da013c76ea2724b6c"
+ ],
+ "version": "==1.14.0"
+ },
+ "sqlparse": {
+ "hashes": [
+ "sha256:40afe6b8d4b1117e7dff5504d7a8ce07d9a1b15aeeade8a2d10f130a834f8177",
+ "sha256:7c3dca29c022744e95b547e867cee89f4fce4373f3549ccd8797d8eb52cdb873"
+ ],
+ "version": "==0.3.0"
+ },
+ "tweepy": {
+ "hashes": [
+ "sha256:8abd828ba51a85a2b5bb7373715d6d3bb32d18ac624e3a4db02e4ef8ab48316b",
+ "sha256:ecc7f200c86127903017e48824efd008734814e95f3e8e9b45ce0f4120dd08db"
+ ],
+ "index": "pypi",
+ "version": "==3.8.0"
+ },
+ "urllib3": {
+ "hashes": [
+ "sha256:2f3db8b19923a873b3e5256dc9c2dedfa883e33d87c690d9c7913e1f40673cdc",
+ "sha256:87716c2d2a7121198ebcb7ce7cccf6ce5e9ba539041cfbaeecfb641dc0bf6acc"
+ ],
+ "version": "==1.25.8"
+ },
+ "vine": {
+ "hashes": [
+ "sha256:133ee6d7a9016f177ddeaf191c1f58421a1dcc6ee9a42c58b34bed40e1d2cd87",
+ "sha256:ea4947cc56d1fd6f2095c8d543ee25dad966f78692528e68b4fada11ba3f98af"
+ ],
+ "version": "==1.3.0"
+ },
+ "whitenoise": {
+ "hashes": [
+ "sha256:0f9137f74bd95fa54329ace88d8dc695fbe895369a632e35f7a136e003e41d73",
+ "sha256:62556265ec1011bd87113fb81b7516f52688887b7a010ee899ff1fd18fd22700"
+ ],
+ "index": "pypi",
+ "version": "==5.0.1"
+ },
+ "zipp": {
+ "hashes": [
+ "sha256:12248a63bbdf7548f89cb4c7cda4681e537031eda29c02ea29674bc6854460c2",
+ "sha256:7c0f8e91abc0dc07a5068f315c52cb30c66bfbc581e5b50704c8a2f6ebae794a"
+ ],
+ "version": "==3.0.0"
+ }
+ },
+ "develop": {
+ "alabaster": {
+ "hashes": [
+ "sha256:446438bdcca0e05bd45ea2de1668c1d9b032e1a9154c2c259092d77031ddd359",
+ "sha256:a661d72d58e6ea8a57f7a86e37d86716863ee5e92788398526d58b26a4e4dc02"
+ ],
+ "version": "==0.7.12"
+ },
+ "appdirs": {
+ "hashes": [
+ "sha256:9e5896d1372858f8dd3344faf4e5014d21849c756c8d5701f78f8a103b372d92",
+ "sha256:d8b24664561d0d34ddfaec54636d502d7cea6e29c3eaf68f3df6180863e2166e"
+ ],
+ "version": "==1.4.3"
+ },
+ "attrs": {
+ "hashes": [
+ "sha256:08a96c641c3a74e44eb59afb61a24f2cb9f4d7188748e76ba4bb5edfa3cb7d1c",
+ "sha256:f7b7ce16570fe9965acd6d30101a28f62fb4a7f9e926b3bbc9b61f8b04247e72"
+ ],
+ "version": "==19.3.0"
+ },
+ "babel": {
+ "hashes": [
+ "sha256:1aac2ae2d0d8ea368fa90906567f5c08463d98ade155c0c4bfedd6a0f7160e38",
+ "sha256:d670ea0b10f8b723672d3a6abeb87b565b244da220d76b4dba1b66269ec152d4"
+ ],
+ "version": "==2.8.0"
+ },
+ "black": {
+ "hashes": [
+ "sha256:1b30e59be925fafc1ee4565e5e08abef6b03fe455102883820fe5ee2e4734e0b",
+ "sha256:c2edb73a08e9e0e6f65a0e6af18b059b8b1cdd5bef997d7a0b181df93dc81539"
+ ],
+ "index": "pypi",
+ "version": "==19.10b0"
+ },
+ "certifi": {
+ "hashes": [
+ "sha256:017c25db2a153ce562900032d5bc68e9f191e44e9a0f762f373977de9df1fbb3",
+ "sha256:25b64c7da4cd7479594d035c08c2d809eb4aab3a26e5a990ea98cc450c320f1f"
+ ],
+ "version": "==2019.11.28"
+ },
+ "chardet": {
+ "hashes": [
+ "sha256:84ab92ed1c4d4f16916e05906b6b75a6c0fb5db821cc65e70cbd64a3e2a5eaae",
+ "sha256:fc323ffcaeaed0e0a02bf4d117757b98aed530d9ed4531e3e15460124c106691"
+ ],
+ "version": "==3.0.4"
+ },
+ "click": {
+ "hashes": [
+ "sha256:2335065e6395b9e67ca716de5f7526736bfa6ceead690adf616d925bdc622b13",
+ "sha256:5b94b49521f6456670fdb30cd82a4eca9412788a93fa6dd6df72c94d5a8ff2d7"
+ ],
+ "version": "==7.0"
+ },
+ "docutils": {
+ "hashes": [
+ "sha256:0c5b78adfbf7762415433f5515cd5c9e762339e23369dbe8000d84a4bf4ab3af",
+ "sha256:c2de3a60e9e7d07be26b7f2b00ca0309c207e06c100f9cc2a94931fc75a478fc"
+ ],
+ "version": "==0.16"
+ },
+ "entrypoints": {
+ "hashes": [
+ "sha256:589f874b313739ad35be6e0cd7efde2a4e9b6fea91edcc34e58ecbb8dbe56d19",
+ "sha256:c70dd71abe5a8c85e55e12c19bd91ccfeec11a6e99044204511f9ed547d48451"
+ ],
+ "version": "==0.3"
+ },
+ "flake8": {
+ "hashes": [
+ "sha256:45681a117ecc81e870cbf1262835ae4af5e7a8b08e40b944a8a6e6b895914cfb",
+ "sha256:49356e766643ad15072a789a20915d3c91dc89fd313ccd71802303fd67e4deca"
+ ],
+ "index": "pypi",
+ "version": "==3.7.9"
+ },
+ "idna": {
+ "hashes": [
+ "sha256:7588d1c14ae4c77d74036e8c22ff447b26d0fde8f007354fd48a7814db15b7cb",
+ "sha256:a068a21ceac8a4d63dbfd964670474107f541babbd2250d61922f029858365fa"
+ ],
+ "version": "==2.9"
+ },
+ "imagesize": {
+ "hashes": [
+ "sha256:6965f19a6a2039c7d48bca7dba2473069ff854c36ae6f19d2cde309d998228a1",
+ "sha256:b1f6b5a4eab1f73479a50fb79fcf729514a900c341d8503d62a62dbc4127a2b1"
+ ],
+ "version": "==1.2.0"
+ },
+ "importlib-metadata": {
+ "hashes": [
+ "sha256:06f5b3a99029c7134207dd882428a66992a9de2bef7c2b699b5641f9886c3302",
+ "sha256:b97607a1a18a5100839aec1dc26a1ea17ee0d93b20b0f008d80a5a050afb200b"
+ ],
+ "markers": "python_version < '3.8'",
+ "version": "==1.5.0"
+ },
+ "jinja2": {
+ "hashes": [
+ "sha256:c10142f819c2d22bdcd17548c46fa9b77cf4fda45097854c689666bf425e7484",
+ "sha256:c922560ac46888d47384de1dbdc3daaa2ea993af4b26a436dec31fa2c19ec668"
+ ],
+ "version": "==3.0.0a1"
+ },
+ "kegbot": {
+ "editable": true,
+ "path": "."
+ },
"markupsafe": {
"hashes": [
"sha256:00bc623926325b26bb9605ae9eae8a215691f33cae5df11ca5424f06f2d1f473",
@@ -313,14 +571,6 @@
],
"version": "==0.6.1"
},
- "mock": {
- "hashes": [
- "sha256:5ce3c71c5545b472da17b72268978914d0252980348636840bd34a00b5cc96c1",
- "sha256:b158b6df76edd239b8208d481dc46b6afd45a846b7812ff0ce58971cf5bc8bba"
- ],
- "index": "pypi",
- "version": "==2.0.0"
- },
"more-itertools": {
"hashes": [
"sha256:5dd8bcf33e5f9513ffa06d5ad33d78f31e1931ac9a18f33d37e77a180d393a7c",
@@ -350,24 +600,6 @@
],
"version": "==4.7.5"
},
- "mysqlclient": {
- "hashes": [
- "sha256:4c82187dd6ab3607150fbb1fa5ef4643118f3da122b8ba31c3149ddd9cf0cb39",
- "sha256:9e6080a7aee4cc6a06b58b59239f20f1d259c1d2fddf68ddeed242d2311c7087",
- "sha256:f3fdaa9a38752a3b214a6fe79d7cae3653731a53e577821f9187e67cbecb2e16",
- "sha256:f646f8d17d02be0872291f258cce3813497bc7888cd4712a577fd1e719b2f213"
- ],
- "index": "pypi",
- "version": "==1.4.6"
- },
- "oauthlib": {
- "hashes": [
- "sha256:bee41cc35fcca6e988463cacc3bcb8a96224f470ca547e697b604cc697b2f889",
- "sha256:df884cd6cbe20e32633f1db1072e9356f53638e4361bef4e8b03c9127c9328ea"
- ],
- "index": "pypi",
- "version": "==3.1.0"
- },
"packaging": {
"hashes": [
"sha256:170748228214b70b672c581a3dd610ee51f733018650740e98c7df862a583f73",
@@ -375,47 +607,12 @@
],
"version": "==20.1"
},
- "pbr": {
- "hashes": [
- "sha256:139d2625547dbfa5fb0b81daebb39601c478c21956dc57e2e07b74450a8c506b",
- "sha256:61aa52a0f18b71c5cc58232d2cf8f8d09cd67fcad60b742a60124cb8d6951488"
- ],
- "version": "==5.4.4"
- },
- "pilkit": {
- "hashes": [
- "sha256:ddb30c2f0198a147e56b151476c3bb9fe045fbfd5b0a0fa2a3148dba62d1559f"
- ],
- "index": "pypi",
- "version": "==2.0"
- },
- "pillow": {
+ "pathspec": {
"hashes": [
- "sha256:0a628977ac2e01ca96aaae247ec2bd38e729631ddf2221b4b715446fd45505be",
- "sha256:4d9ed9a64095e031435af120d3c910148067087541131e82b3e8db302f4c8946",
- "sha256:54ebae163e8412aff0b9df1e88adab65788f5f5b58e625dc5c7f51eaf14a6837",
- "sha256:5bfef0b1cdde9f33881c913af14e43db69815c7e8df429ceda4c70a5e529210f",
- "sha256:5f3546ceb08089cedb9e8ff7e3f6a7042bb5b37c2a95d392fb027c3e53a2da00",
- "sha256:5f7ae9126d16194f114435ebb79cc536b5682002a4fa57fa7bb2cbcde65f2f4d",
- "sha256:62a889aeb0a79e50ecf5af272e9e3c164148f4bd9636cc6bcfa182a52c8b0533",
- "sha256:7406f5a9b2fd966e79e6abdaf700585a4522e98d6559ce37fc52e5c955fade0a",
- "sha256:8453f914f4e5a3d828281a6628cf517832abfa13ff50679a4848926dac7c0358",
- "sha256:87269cc6ce1e3dee11f23fa515e4249ae678dbbe2704598a51cee76c52e19cda",
- "sha256:875358310ed7abd5320f21dd97351d62de4929b0426cdb1eaa904b64ac36b435",
- "sha256:8ac6ce7ff3892e5deaab7abaec763538ffd011f74dc1801d93d3c5fc541feee2",
- "sha256:91b710e3353aea6fc758cdb7136d9bbdcb26b53cefe43e2cba953ac3ee1d3313",
- "sha256:9d2ba4ed13af381233e2d810ff3bab84ef9f18430a9b336ab69eaf3cd24299ff",
- "sha256:a62ec5e13e227399be73303ff301f2865bf68657d15ea50b038d25fc41097317",
- "sha256:ab76e5580b0ed647a8d8d2d2daee170e8e9f8aad225ede314f684e297e3643c2",
- "sha256:bf4003aa538af3f4205c5fac56eacaa67a6dd81e454ffd9e9f055fff9f1bc614",
- "sha256:bf598d2e37cf8edb1a2f26ed3fb255191f5232badea4003c16301cb94ac5bdd0",
- "sha256:c18f70dc27cc5d236f10e7834236aff60aadc71346a5bc1f4f83a4b3abee6386",
- "sha256:c5ed816632204a2fc9486d784d8e0d0ae754347aba99c811458d69fcdfd2a2f9",
- "sha256:dc058b7833184970d1248135b8b0ab702e6daa833be14035179f2acb78ff5636",
- "sha256:ff3797f2f16bf9d17d53257612da84dd0758db33935777149b3334c01ff68865"
+ "sha256:163b0632d4e31cef212976cf57b43d9fd6b0bac6e67c26015d611a647d5e7424",
+ "sha256:562aa70af2e0d434367d9790ad37aed893de47f1693e4201fd1d3dca15d19b96"
],
- "index": "pypi",
- "version": "==7.0.0"
+ "version": "==0.7.0"
},
"pluggy": {
"hashes": [
@@ -424,30 +621,6 @@
],
"version": "==0.13.1"
},
- "protobuf": {
- "hashes": [
- "sha256:0bae429443cc4748be2aadfdaf9633297cfaeb24a9a02d0ab15849175ce90fab",
- "sha256:24e3b6ad259544d717902777b33966a1a069208c885576254c112663e6a5bb0f",
- "sha256:310a7aca6e7f257510d0c750364774034272538d51796ca31d42c3925d12a52a",
- "sha256:52e586072612c1eec18e1174f8e3bb19d08f075fc2e3f91d3b16c919078469d0",
- "sha256:73152776dc75f335c476d11d52ec6f0f6925774802cd48d6189f4d5d7fe753f4",
- "sha256:7774bbbaac81d3ba86de646c39f154afc8156717972bf0450c9dbfa1dc8dbea2",
- "sha256:82d7ac987715d8d1eb4068bf997f3053468e0ce0287e2729c30601feb6602fee",
- "sha256:8eb9c93798b904f141d9de36a0ba9f9b73cc382869e67c9e642c0aba53b0fc07",
- "sha256:adf0e4d57b33881d0c63bb11e7f9038f98ee0c3e334c221f0858f826e8fb0151",
- "sha256:c40973a0aee65422d8cb4e7d7cbded95dfeee0199caab54d5ab25b63bce8135a",
- "sha256:c77c974d1dadf246d789f6dad1c24426137c9091e930dbf50e0a29c1fcf00b1f",
- "sha256:dd9aa4401c36785ea1b6fff0552c674bdd1b641319cb07ed1fe2392388e9b0d7",
- "sha256:e11df1ac6905e81b815ab6fd518e79be0a58b5dc427a2cf7208980f30694b956",
- "sha256:e2f8a75261c26b2f5f3442b0525d50fd79a71aeca04b5ec270fc123536188306",
- "sha256:e512b7f3a4dd780f59f1bf22c302740e27b10b5c97e858a6061772668cd6f961",
- "sha256:ef2c2e56aaf9ee914d3dccc3408d42661aaf7d9bb78eaa8f17b2e6282f214481",
- "sha256:fac513a9dc2a74b99abd2e17109b53945e364649ca03d9f7a0b96aa8d1807d0a",
- "sha256:fdfb6ad138dbbf92b5dbea3576d7c8ba7463173f7d2cb0ca1bd336ec88ddbd80"
- ],
- "index": "pypi",
- "version": "==3.11.3"
- },
"py": {
"hashes": [
"sha256:5e27081401262157467ad6e7f851b7aa402c5852dbcb3dae06768434de5752aa",
@@ -483,14 +656,6 @@
],
"version": "==2.4.6"
},
- "pysocks": {
- "hashes": [
- "sha256:08e69f092cc6dbe92a0fdd16eeb9b9ffbc13cadfe5ca4c7bd92ffb078b293299",
- "sha256:2725bd0a9925919b9b51739eea5f9e2bae91e83288108a9ad338b2e3a4435ee5",
- "sha256:3f8804571ebe159c380ac6de37643bb4685970655d3bba243530d6558b799aa0"
- ],
- "version": "==1.7.1"
- },
"pytest": {
"hashes": [
"sha256:0d5fe9189a148acc3c3eb2ac8e1ac0742cb7618c084f3d228baaec0c254b318d",
@@ -507,13 +672,6 @@
"index": "pypi",
"version": "==3.8.0"
},
- "python-gflags": {
- "hashes": [
- "sha256:40ae131e899ef68e9e14aa53ca063839c34f6a168afe622217b5b875492a1ee2"
- ],
- "index": "pypi",
- "version": "==3.1.2"
- },
"pytz": {
"hashes": [
"sha256:1c557d7d0e871de1f5ccd5833f60fb2550652da6be2693c1e02300743d21500d",
@@ -539,13 +697,31 @@
"index": "pypi",
"version": "==5.3"
},
- "redis": {
- "hashes": [
- "sha256:0dcfb335921b88a850d461dc255ff4708294943322bd55de6cfd68972490ca1f",
- "sha256:b205cffd05ebfd0a468db74f0eedbff8df1a7bfc47521516ade4692991bb0833"
- ],
- "index": "pypi",
- "version": "==3.4.1"
+ "regex": {
+ "hashes": [
+ "sha256:01b2d70cbaed11f72e57c1cfbaca71b02e3b98f739ce33f5f26f71859ad90431",
+ "sha256:046e83a8b160aff37e7034139a336b660b01dbfe58706f9d73f5cdc6b3460242",
+ "sha256:113309e819634f499d0006f6200700c8209a2a8bf6bd1bdc863a4d9d6776a5d1",
+ "sha256:200539b5124bc4721247a823a47d116a7a23e62cc6695744e3eb5454a8888e6d",
+ "sha256:25f4ce26b68425b80a233ce7b6218743c71cf7297dbe02feab1d711a2bf90045",
+ "sha256:269f0c5ff23639316b29f31df199f401e4cb87529eafff0c76828071635d417b",
+ "sha256:5de40649d4f88a15c9489ed37f88f053c15400257eeb18425ac7ed0a4e119400",
+ "sha256:7f78f963e62a61e294adb6ff5db901b629ef78cb2a1cfce3cf4eeba80c1c67aa",
+ "sha256:82469a0c1330a4beb3d42568f82dffa32226ced006e0b063719468dcd40ffdf0",
+ "sha256:8c2b7fa4d72781577ac45ab658da44c7518e6d96e2a50d04ecb0fd8f28b21d69",
+ "sha256:974535648f31c2b712a6b2595969f8ab370834080e00ab24e5dbb9d19b8bfb74",
+ "sha256:99272d6b6a68c7ae4391908fc15f6b8c9a6c345a46b632d7fdb7ef6c883a2bbb",
+ "sha256:9b64a4cc825ec4df262050c17e18f60252cdd94742b4ba1286bcfe481f1c0f26",
+ "sha256:9e9624440d754733eddbcd4614378c18713d2d9d0dc647cf9c72f64e39671be5",
+ "sha256:9ff16d994309b26a1cdf666a6309c1ef51ad4f72f99d3392bcd7b7139577a1f2",
+ "sha256:b33ebcd0222c1d77e61dbcd04a9fd139359bded86803063d3d2d197b796c63ce",
+ "sha256:bba52d72e16a554d1894a0cc74041da50eea99a8483e591a9edf1025a66843ab",
+ "sha256:bed7986547ce54d230fd8721aba6fd19459cdc6d315497b98686d0416efaff4e",
+ "sha256:c7f58a0e0e13fb44623b65b01052dae8e820ed9b8b654bb6296bc9c41f571b70",
+ "sha256:d58a4fa7910102500722defbde6e2816b0372a4fcc85c7e239323767c74f5cbc",
+ "sha256:f1ac2dc65105a53c1c2d72b1d3e98c2464a133b4067a51a3d2477b28449709a0"
+ ],
+ "version": "==2020.2.20"
},
"requests": {
"hashes": [
@@ -563,14 +739,6 @@
"index": "pypi",
"version": "==1.7.0"
},
- "requests-oauthlib": {
- "hashes": [
- "sha256:7f71572defaecd16372f9006f33c2ec8c077c3cfa6f5911a9a90202beb513f3d",
- "sha256:b4261601a71fd721a8bd6d7aa1cc1d6a8a93b4a9f5e96626f8e4d91e8beeaa6a"
- ],
- "index": "pypi",
- "version": "==1.3.0"
- },
"six": {
"hashes": [
"sha256:236bdbdce46e6e6a3d61a337c0f8b763ca1e8717c03b369e87a7ec7ce1319c0a",
@@ -643,13 +811,38 @@
],
"version": "==1.1.3"
},
- "tweepy": {
- "hashes": [
- "sha256:8abd828ba51a85a2b5bb7373715d6d3bb32d18ac624e3a4db02e4ef8ab48316b",
- "sha256:ecc7f200c86127903017e48824efd008734814e95f3e8e9b45ce0f4120dd08db"
- ],
- "index": "pypi",
- "version": "==3.8.0"
+ "toml": {
+ "hashes": [
+ "sha256:229f81c57791a41d65e399fc06bf0848bab550a9dfd5ed66df18ce5f05e73d5c",
+ "sha256:235682dd292d5899d361a811df37e04a8828a5b1da3115886b73cf81ebc9100e"
+ ],
+ "version": "==0.10.0"
+ },
+ "typed-ast": {
+ "hashes": [
+ "sha256:0666aa36131496aed8f7be0410ff974562ab7eeac11ef351def9ea6fa28f6355",
+ "sha256:0c2c07682d61a629b68433afb159376e24e5b2fd4641d35424e462169c0a7919",
+ "sha256:249862707802d40f7f29f6e1aad8d84b5aa9e44552d2cc17384b209f091276aa",
+ "sha256:24995c843eb0ad11a4527b026b4dde3da70e1f2d8806c99b7b4a7cf491612652",
+ "sha256:269151951236b0f9a6f04015a9004084a5ab0d5f19b57de779f908621e7d8b75",
+ "sha256:4083861b0aa07990b619bd7ddc365eb7fa4b817e99cf5f8d9cf21a42780f6e01",
+ "sha256:498b0f36cc7054c1fead3d7fc59d2150f4d5c6c56ba7fb150c013fbc683a8d2d",
+ "sha256:4e3e5da80ccbebfff202a67bf900d081906c358ccc3d5e3c8aea42fdfdfd51c1",
+ "sha256:6daac9731f172c2a22ade6ed0c00197ee7cc1221aa84cfdf9c31defeb059a907",
+ "sha256:715ff2f2df46121071622063fc7543d9b1fd19ebfc4f5c8895af64a77a8c852c",
+ "sha256:73d785a950fc82dd2a25897d525d003f6378d1cb23ab305578394694202a58c3",
+ "sha256:8c8aaad94455178e3187ab22c8b01a3837f8ee50e09cf31f1ba129eb293ec30b",
+ "sha256:8ce678dbaf790dbdb3eba24056d5364fb45944f33553dd5869b7580cdbb83614",
+ "sha256:aaee9905aee35ba5905cfb3c62f3e83b3bec7b39413f0a7f19be4e547ea01ebb",
+ "sha256:bcd3b13b56ea479b3650b82cabd6b5343a625b0ced5429e4ccad28a8973f301b",
+ "sha256:c9e348e02e4d2b4a8b2eedb48210430658df6951fa484e59de33ff773fbd4b41",
+ "sha256:d205b1b46085271b4e15f670058ce182bd1199e56b317bf2ec004b6a44f911f6",
+ "sha256:d43943ef777f9a1c42bf4e552ba23ac77a6351de620aa9acf64ad54933ad4d34",
+ "sha256:d5d33e9e7af3b34a40dc05f498939f0ebf187f07c385fd58d591c533ad8562fe",
+ "sha256:fc0fea399acb12edbf8a628ba8d2312f583bdbdb3335635db062fa98cf71fca4",
+ "sha256:fe460b922ec15dd205595c9b5b99e2f056fd98ae8f9f56b888e7a17dc2b757e7"
+ ],
+ "version": "==1.4.1"
},
"urllib3": {
"hashes": [
@@ -666,13 +859,6 @@
"index": "pypi",
"version": "==4.0.2"
},
- "vine": {
- "hashes": [
- "sha256:133ee6d7a9016f177ddeaf191c1f58421a1dcc6ee9a42c58b34bed40e1d2cd87",
- "sha256:ea4947cc56d1fd6f2095c8d543ee25dad966f78692528e68b4fada11ba3f98af"
- ],
- "version": "==1.3.0"
- },
"wcwidth": {
"hashes": [
"sha256:8fd29383f539be45b20bd4df0dc29c20ba48654a41e661925e612311e9f3c603",
@@ -680,14 +866,6 @@
],
"version": "==0.1.8"
},
- "whitenoise": {
- "hashes": [
- "sha256:1d62a003a0ab747de96da45c831cbb512dcb7f69c1ef0bd20b1cd4ae45d8a0c4",
- "sha256:d098327276de6fd189398a7bcb95789d1bb2d41b3e011eeae4562f6b1a107dd4"
- ],
- "index": "pypi",
- "version": "==3.3.0"
- },
"wrapt": {
"hashes": [
"sha256:0ec40d9fd4ec9f9e3ff9bdd12dbd3535f4085949f4db93025089d7a673ea94e8"
@@ -724,11 +902,5 @@
],
"version": "==3.0.0"
}
- },
- "develop": {
- "kegbot": {
- "editable": true,
- "path": "."
- }
}
}
diff --git a/README.md b/README.md
index b661cb1e3..f61c01ccc 100644
--- a/README.md
+++ b/README.md
@@ -46,12 +46,6 @@ This software is offered under the **GPLv2** license. Your use of
Kegbot Server constitutes your agreement to that license. Please see
``LICENSE.txt`` for the full license.
-Code and documentation are **Copyright 2014 Bevbot LLC**,
-unless otherwise noted. Graphics and images distributed with Kegbot,
-such as the Kegbot logo, are also copyrighted works of Bevbot LLC
-unless otherwise noted, and may not be reused without permission.
-
-
## Contributing
We love getting patches! Send us a pull request, or hop on to IRC if
diff --git a/bin/kegbot b/bin/kegbot
index 5787d1860..51cec1c69 100755
--- a/bin/kegbot
+++ b/bin/kegbot
@@ -1,6 +1,6 @@
#!/usr/bin/env python
#
-# Copyright 2010 Mike Wakerly
+# Copyright 2014 Kegbot Project contributors
#
# This file is part of the Pykeg package of the Kegbot project.
# For more information on Pykeg or Kegbot, see http://kegbot.org/
diff --git a/bin/setup-kegbot.py b/bin/setup-kegbot.py
index 91aa43ebb..aab0fbbe4 100755
--- a/bin/setup-kegbot.py
+++ b/bin/setup-kegbot.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python
#
-# Copyright 2014 Bevbot LLC, All Rights Reserved
+# Copyright 2014 Kegbot Project contributors
#
# This file is part of the Pykeg package of the Kegbot project.
# For more information on Pykeg or Kegbot, see http://kegbot.org/
diff --git a/deploy/travis/local_settings.py b/deploy/travis/local_settings.py
deleted file mode 100644
index c2a2cf914..000000000
--- a/deploy/travis/local_settings.py
+++ /dev/null
@@ -1,29 +0,0 @@
-# Kegbot local settings, for travis-ci.org build
-
-import os
-
-HOME = os.environ['HOME']
-
-DEBUG = True
-TEMPLATE_DEBUG = DEBUG
-
-DATABASES = {
- 'default': {
- 'ENGINE': 'django.db.backends.mysql',
- 'NAME': 'kegbot_travis_test',
- 'HOST': '',
- 'USER': 'root',
- 'PASSWORD': '',
- 'OPTIONS': {
- 'init_command': 'SET default_storage_engine=INNODB'}}}
-
-KEGBOT_ROOT = HOME + '/kegbot-data'
-
-MEDIA_ROOT = KEGBOT_ROOT + '/media'
-
-STATIC_ROOT = KEGBOT_ROOT + '/static'
-
-SECRET_KEY = 'testkey'
-
-EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend'
-EMAIL_FROM_ADDRESS = 'no-reply@example.com'
diff --git a/docs/source/release-notes/changelog.rst b/docs/source/release-notes/changelog.rst
index b100f2b5d..d9c62a760 100644
--- a/docs/source/release-notes/changelog.rst
+++ b/docs/source/release-notes/changelog.rst
@@ -44,10 +44,9 @@ For a detailed look at what's new in version 1.3, see :ref:`version-13-release-n
**Other Changes**
-* Internal: Upgraded to Django 1.11.
+* Upgraded to Python 3 and Django 2.
* Internal: Improved static file serving (:issue:`368`)
* Internal: Developer tests now use ``pytest``
-* Upgraded to Python 3.
Version 1.2.3 (2015-01-12)
--------------------------
diff --git a/docs/source/settings.rst b/docs/source/settings.rst
index 3890e1b20..055204338 100644
--- a/docs/source/settings.rst
+++ b/docs/source/settings.rst
@@ -30,6 +30,10 @@ These values can be set in the shell environment of the server program.
**Example:** ``mysql://kegbot@localhost/kegbot``
+.. data:: KEGBOT_EMAIL_FROM_ADDRESS
+
+ The "From:" address to use in emails from the system. No default.
+
.. data:: KEGBOT_REDIS_URL
URL to the Kegbot Redis instance, in the format ``redis://:PASSWORD@HOST:PORT/DATABASE``. ``PASSWORD`` and ``PORT`` are optional.
diff --git a/pykeg/backend/__init__.py b/pykeg/backend/__init__.py
index 40c632858..867288a3e 100644
--- a/pykeg/backend/__init__.py
+++ b/pykeg/backend/__init__.py
@@ -1,4 +1,4 @@
-# Copyright 2014 Bevbot LLC, All Rights Reserved
+# Copyright 2014 Kegbot Project contributors
#
# This file is part of the Pykeg package of the Kegbot project.
# For more information on Pykeg or Kegbot, see http://kegbot.org/
diff --git a/pykeg/backend/backends.py b/pykeg/backend/backends.py
index ebf97be29..707be4bc4 100644
--- a/pykeg/backend/backends.py
+++ b/pykeg/backend/backends.py
@@ -1,4 +1,4 @@
-# Copyright 2014 Bevbot LLC, All Rights Reserved
+# Copyright 2014 Kegbot Project contributors
#
# This file is part of the Pykeg package of the Kegbot project.
# For more information on Pykeg or Kegbot, see http://kegbot.org/
diff --git a/pykeg/backend/backends_test.py b/pykeg/backend/backends_test.py
index d1266081f..df9e7c842 100644
--- a/pykeg/backend/backends_test.py
+++ b/pykeg/backend/backends_test.py
@@ -1,4 +1,4 @@
-# Copyright 2014 Bevbot LLC, All Rights Reserved
+# Copyright 2014 Kegbot Project contributors
#
# This file is part of the Pykeg package of the Kegbot project.
# For more information on Pykeg or Kegbot, see http://kegbot.org/
@@ -45,17 +45,17 @@ def setUp(self):
def test_delete_keg(self):
site = models.KegbotSite.get()
original_stats = site.get_stats()
- self.assertEquals(755, original_stats['total_pours'])
+ self.assertEqual(755, original_stats['total_pours'])
keg = models.Keg.objects.get(pk=2)
keg_stats = keg.get_stats()
keg_drinks = keg.drinks.all()
- self.assertEquals(185, len(keg_drinks))
+ self.assertEqual(185, len(keg_drinks))
self.backend.cancel_keg(keg)
stats = site.get_stats()
- self.assertEquals(755 - 185, stats['total_pours'])
- self.assertEquals(original_stats['total_volume_ml'] - keg_stats['total_volume_ml'],
+ self.assertEqual(755 - 185, stats['total_pours'])
+ self.assertEqual(original_stats['total_volume_ml'] - keg_stats['total_volume_ml'],
stats['total_volume_ml'])
@@ -79,20 +79,20 @@ def test_drink_management(self):
style_name=FAKE_BEER_STYLE)
self.assertIsNotNone(keg)
- self.assertEquals(0, keg.served_volume())
+ self.assertEqual(0, keg.served_volume())
drink = self.backend.record_drink(METER_NAME, ticks=2200)
self.assertIsNotNone(drink)
- self.assertEquals(2200, drink.ticks)
+ self.assertEqual(2200, drink.ticks)
self.assertAlmostEqual(1000.0, drink.volume_ml, places=3)
keg = models.Keg.objects.get(pk=keg.id)
self.assertAlmostEqual(1000.0, keg.served_volume(), places=3)
- self.assertEquals('', drink.shout)
- self.assertEquals(0, drink.duration)
+ self.assertEqual('', drink.shout)
+ self.assertEqual(0, drink.duration)
drink = self.backend.record_drink(METER_NAME, ticks=1100)
keg = models.Keg.objects.get(pk=keg.id)
self.assertIsNotNone(drink)
- self.assertEquals(1100, drink.ticks)
+ self.assertEqual(1100, drink.ticks)
self.assertAlmostEqual(500.0, drink.volume_ml, places=3)
self.assertAlmostEqual(1500.0, keg.served_volume(), places=3)
@@ -100,7 +100,7 @@ def test_drink_management(self):
drink = self.backend.record_drink(METER_NAME, ticks=1100, volume_ml=1)
keg = models.Keg.objects.get(pk=keg.id)
self.assertIsNotNone(drink)
- self.assertEquals(1100, drink.ticks)
+ self.assertEqual(1100, drink.ticks)
self.assertAlmostEqual(1.0, drink.volume_ml, places=3)
self.assertAlmostEqual(1501.0, keg.served_volume(), places=3)
@@ -108,7 +108,7 @@ def test_drink_management(self):
user = models.User.objects.create(username='testy')
drink = self.backend.record_drink(METER_NAME, ticks=2200, username=user.username)
self.assertIsNotNone(drink)
- self.assertEquals(user, drink.user)
+ self.assertEqual(user, drink.user)
def test_drink_cancel(self):
"""Tests cancelling drinks."""
@@ -116,14 +116,14 @@ def test_drink_cancel(self):
beverage_type='beer', producer_name=FAKE_BREWER_NAME,
style_name=FAKE_BEER_STYLE)
self.assertIsNotNone(keg)
- self.assertEquals(0, keg.served_volume())
+ self.assertEqual(0, keg.served_volume())
for i in range(10):
self.backend.record_drink(METER_NAME, ticks=1, volume_ml=100)
drinks = list(models.Drink.objects.all().order_by('id'))
keg = models.Keg.objects.get(pk=keg.id)
- self.assertEquals(10, len(drinks))
+ self.assertEqual(10, len(drinks))
self.assertAlmostEqual(1000.0, keg.served_volume(), places=3)
cancel_drink = drinks[-1]
@@ -133,18 +133,18 @@ def test_drink_cancel(self):
self.backend.cancel_drink(drinks[-1])
drinks = list(models.Drink.objects.all().order_by('id'))
keg = models.Keg.objects.get(pk=keg.id)
- self.assertEquals(9, len(drinks))
+ self.assertEqual(9, len(drinks))
self.assertAlmostEqual(900.0, keg.served_volume(), places=3)
session = models.DrinkingSession.objects.get(id=session.id)
self.assertAlmostEqual(session.get_stats().total_volume_ml, 900.0, places=3)
keg = models.Keg.objects.get(pk=keg.id)
- self.assertEquals(0, keg.spilled_ml)
+ self.assertEqual(0, keg.spilled_ml)
self.backend.cancel_drink(drinks[-1], spilled=True)
keg = models.Keg.objects.get(pk=keg.id)
drinks = list(models.Drink.objects.all().order_by('id'))
- self.assertEquals(8, len(drinks))
+ self.assertEqual(8, len(drinks))
self.assertAlmostEqual(800.0, keg.served_volume(), places=3)
self.assertAlmostEqual(100.0, keg.spilled_ml, places=3)
@@ -154,7 +154,7 @@ def test_drink_cancel(self):
for d in other_drinks:
self.backend.cancel_drink(d)
- self.assertEquals(first_drink.volume_ml, first_drink.session.volume_ml)
+ self.assertEqual(first_drink.volume_ml, first_drink.session.volume_ml)
session_id = first_drink.session.id
self.backend.cancel_drink(first_drink)
@@ -162,14 +162,14 @@ def test_drink_cancel(self):
with self.assertRaises(models.DrinkingSession.DoesNotExist):
models.DrinkingSession.objects.get(pk=session_id)
- self.assertEquals(num_sessions - 1, models.DrinkingSession.objects.all().count())
+ self.assertEqual(num_sessions - 1, models.DrinkingSession.objects.all().count())
def test_reassign_drink_with_photo(self):
keg = self.backend.start_keg(METER_NAME, beverage_name=FAKE_BEER_NAME,
beverage_type='beer', producer_name=FAKE_BREWER_NAME,
style_name=FAKE_BEER_STYLE)
self.assertIsNotNone(keg)
- self.assertEquals(0, keg.served_volume())
+ self.assertEqual(0, keg.served_volume())
drink = self.backend.record_drink(METER_NAME, ticks=1, volume_ml=100,
photo='foo')
@@ -181,8 +181,8 @@ def test_reassign_drink_with_photo(self):
user = self.backend.create_new_user('blort', email='blort@example.com')
updated_drink = self.backend.assign_drink(drink, user)
- self.assertEquals(user, updated_drink.user)
- self.assertEquals(user, updated_drink.picture.user)
+ self.assertEqual(user, updated_drink.user)
+ self.assertEqual(user, updated_drink.picture.user)
def test_keg_management(self):
"""Tests adding and removing kegs."""
@@ -191,7 +191,7 @@ def test_keg_management(self):
# No beer types yet.
qs = models.Beverage.objects.filter(name=FAKE_BEER_NAME)
- self.assertEquals(len(qs), 0, "Beverage already exists")
+ self.assertEqual(len(qs), 0, "Beverage already exists")
# Tap the keg.
keg = self.backend.start_keg(METER_NAME, beverage_name=FAKE_BEER_NAME,
@@ -200,18 +200,18 @@ def test_keg_management(self):
self.assertIsNotNone(keg)
self.assertTrue(keg.is_on_tap())
- self.assertEquals(keg.current_tap, tap, "Tap did not become active.")
+ self.assertEqual(keg.current_tap, tap, "Tap did not become active.")
tap = keg.current_tap
self.assertTrue(keg.current_tap.is_active())
# Check that the beer type was created.
qs = models.Beverage.objects.filter(name=FAKE_BEER_NAME)
- self.assertEquals(len(qs), 1, "Expected a single new Beverage.")
+ self.assertEqual(len(qs), 1, "Expected a single new Beverage.")
beverage = qs[0]
brewer = beverage.producer
style = beverage.style
- self.assertEquals(brewer.name, FAKE_BREWER_NAME)
- self.assertEquals(style, FAKE_BEER_STYLE)
+ self.assertEqual(brewer.name, FAKE_BREWER_NAME)
+ self.assertEqual(style, FAKE_BEER_STYLE)
# Now activate a new keg.
keg = self.backend.end_keg(tap.current_keg)
@@ -227,15 +227,15 @@ def test_keg_management(self):
self.assertTrue(new_keg.is_on_tap())
# Ensure the beer type was reused.
- self.assertEquals(new_keg.type, beverage)
+ self.assertEqual(new_keg.type, beverage)
# Deactivate, and activate a new keg again by name.
self.backend.end_keg(tap.current_keg)
new_keg_2 = self.backend.start_keg(METER_NAME, beverage_name='Other Beer',
beverage_type='beer', producer_name=FAKE_BREWER_NAME,
style_name=FAKE_BEER_STYLE)
- self.assertEquals(new_keg_2.type.producer, keg.type.producer)
- self.assertEquals(new_keg_2.type.style, keg.type.style)
+ self.assertEqual(new_keg_2.type.producer, keg.type.producer)
+ self.assertEqual(new_keg_2.type.style, keg.type.style)
self.assertNotEquals(new_keg_2.type, keg.type)
# New brewer, identical beer name == new beer type.
@@ -248,7 +248,7 @@ def test_keg_management(self):
producer_name='Other Brewer',
style_name=FAKE_BEER_STYLE)
self.assertNotEquals(new_keg_3.type.producer, keg.type.producer)
- self.assertEquals(new_keg_3.type.name, keg.type.name)
+ self.assertEqual(new_keg_3.type.name, keg.type.name)
self.assertNotEquals(new_keg_3.type, keg.type)
def test_meters(self):
@@ -275,20 +275,20 @@ def test_toggles(self):
@override_settings(KEGBOT_BASE_URL='http://example.com:8000//')
def test_urls(self):
- self.assertEquals('http://example.com:8000', self.backend.get_base_url())
+ self.assertEqual('http://example.com:8000', self.backend.get_base_url())
keg = self.backend.start_keg(METER_NAME, beverage_name=FAKE_BEER_NAME,
beverage_type='beer', producer_name=FAKE_BREWER_NAME,
style_name=FAKE_BEER_STYLE)
- self.assertEquals('http://example.com:8000/kegs/{}'.format(keg.id), keg.full_url())
+ self.assertEqual('http://example.com:8000/kegs/{}'.format(keg.id), keg.full_url())
drink = self.backend.record_drink(METER_NAME, ticks=1, volume_ml=100,
photo='foo')
- self.assertEquals('http://example.com:8000/d/{}'.format(drink.id), drink.short_url())
- self.assertEquals('http://example.com:8000/s/{}'.format(drink.session.id),
+ self.assertEqual('http://example.com:8000/d/{}'.format(drink.id), drink.short_url())
+ self.assertEqual('http://example.com:8000/s/{}'.format(drink.session.id),
drink.session.short_url())
start = drink.session.start_time
datepart = '{}/{}/{}'.format(start.year, start.month, start.day)
- self.assertEquals('http://example.com:8000/sessions/{}/{}'.format(datepart,
+ self.assertEqual('http://example.com:8000/sessions/{}/{}'.format(datepart,
drink.session.id), drink.session.full_url())
diff --git a/pykeg/backend/exceptions.py b/pykeg/backend/exceptions.py
index 1d1d4713a..b5ae9ce0b 100644
--- a/pykeg/backend/exceptions.py
+++ b/pykeg/backend/exceptions.py
@@ -1,4 +1,4 @@
-# Copyright 2014 Bevbot LLC, All Rights Reserved
+# Copyright 2014 Kegbot Project contributors
#
# This file is part of the Pykeg package of the Kegbot project.
# For more information on Pykeg or Kegbot, see http://kegbot.org/
diff --git a/pykeg/backend/signals.py b/pykeg/backend/signals.py
index e4335174f..8f73a39b3 100644
--- a/pykeg/backend/signals.py
+++ b/pykeg/backend/signals.py
@@ -1,4 +1,4 @@
-# Copyright 2014 Bevbot LLC, All Rights Reserved
+# Copyright 2014 Kegbot Project contributors
#
# This file is part of the Pykeg package of the Kegbot project.
# For more information on Pykeg or Kegbot, see http://kegbot.org/
diff --git a/pykeg/backup/backup.py b/pykeg/backup/backup.py
index 5b2c41b8b..1bd897296 100644
--- a/pykeg/backup/backup.py
+++ b/pykeg/backup/backup.py
@@ -1,4 +1,4 @@
-# Copyright 2014 Bevbot LLC, All Rights Reserved
+# Copyright 2014 Kegbot Project contributors
#
# This file is part of the Pykeg package of the Kegbot project.
# For more information on Pykeg or Kegbot, see http://kegbot.org/
diff --git a/pykeg/backup/backup_test.py b/pykeg/backup/backup_test.py
index 3df1f5b56..be5bbb83a 100644
--- a/pykeg/backup/backup_test.py
+++ b/pykeg/backup/backup_test.py
@@ -1,4 +1,4 @@
-# Copyright 2014 Bevbot LLC, All Rights Reserved
+# Copyright 2014 Kegbot Project contributors
#
# This file is part of the Pykeg package of the Kegbot project.
# For more information on Pykeg or Kegbot, see http://kegbot.org/
@@ -62,9 +62,9 @@ def assertMetadata(self, backup_dir, when=None, site_name='My Kegbot',
metadata_json = kbjson.loads(open(metadata_file).read())
self.assertEqual(when, metadata_json[backup.META_CREATED_TIME])
- self.assertEquals(site_name, metadata_json[backup.META_SERVER_NAME])
- self.assertEquals(num_media_files, metadata_json[backup.META_NUM_MEDIA_FILES])
- self.assertEquals(get_version(), metadata_json[backup.META_SERVER_VERSION])
+ self.assertEqual(site_name, metadata_json[backup.META_SERVER_NAME])
+ self.assertEqual(num_media_files, metadata_json[backup.META_NUM_MEDIA_FILES])
+ self.assertEqual(get_version(), metadata_json[backup.META_SERVER_VERSION])
def test_create_backup_tree_empty_site(self):
# Create a backup of an empty system.
diff --git a/pykeg/backup/exceptions.py b/pykeg/backup/exceptions.py
index d51c3ef7b..951c6e2ba 100644
--- a/pykeg/backup/exceptions.py
+++ b/pykeg/backup/exceptions.py
@@ -1,4 +1,4 @@
-# Copyright 2014 Bevbot LLC, All Rights Reserved
+# Copyright 2014 Kegbot Project contributors
#
# This file is part of the Pykeg package of the Kegbot project.
# For more information on Pykeg or Kegbot, see http://kegbot.org/
diff --git a/pykeg/backup/mysql.py b/pykeg/backup/mysql.py
index 1fa986a42..45ce07889 100644
--- a/pykeg/backup/mysql.py
+++ b/pykeg/backup/mysql.py
@@ -1,4 +1,4 @@
-# Copyright 2014 Bevbot LLC, All Rights Reserved
+# Copyright 2014 Kegbot Project contributors
#
# This file is part of the Pykeg package of the Kegbot project.
# For more information on Pykeg or Kegbot, see http://kegbot.org/
diff --git a/pykeg/backup/postgres.py b/pykeg/backup/postgres.py
index 7c0f307f9..47195d6c4 100644
--- a/pykeg/backup/postgres.py
+++ b/pykeg/backup/postgres.py
@@ -1,4 +1,4 @@
-# Copyright 2014 Bevbot LLC, All Rights Reserved
+# Copyright 2014 Kegbot Project contributors
#
# This file is part of the Pykeg package of the Kegbot project.
# For more information on Pykeg or Kegbot, see http://kegbot.org/
diff --git a/pykeg/config.py b/pykeg/config.py
index a7d799d7c..8490a9de3 100644
--- a/pykeg/config.py
+++ b/pykeg/config.py
@@ -97,6 +97,7 @@ def is_setup():
Setting('KEGBOT_ENV', 'test' if IS_RUNNING_PYTEST else ENV_DEBUG)
+Setting('KEGBOT_EMAIL_FROM_ADDRESS', '')
Setting('KEGBOT_DATA_DIR', '/kegbot-data')
Setting('KEGBOT_IN_DOCKER', False, typefn=boolstr)
Setting('KEGBOT_SECRET_KEY', 'not-configured')
diff --git a/pykeg/contrib/foursquare/client.py b/pykeg/contrib/foursquare/client.py
index 1fbb27216..d028bddcb 100644
--- a/pykeg/contrib/foursquare/client.py
+++ b/pykeg/contrib/foursquare/client.py
@@ -1,4 +1,4 @@
-# Copyright 2017 Bevbot LLC, All Rights Reserved
+# Copyright 2017 Kegbot Project contributors
#
# This file is part of the Pykeg package of the Kegbot project.
# For more information on Pykeg or Kegbot, see http://kegbot.org/
diff --git a/pykeg/contrib/foursquare/forms.py b/pykeg/contrib/foursquare/forms.py
index 2086ccb71..fdbce43a1 100644
--- a/pykeg/contrib/foursquare/forms.py
+++ b/pykeg/contrib/foursquare/forms.py
@@ -1,4 +1,4 @@
-# Copyright 2014 Bevbot LLC, All Rights Reserved
+# Copyright 2014 Kegbot Project contributors
#
# This file is part of the Pykeg package of the Kegbot project.
# For more information on Pykeg or Kegbot, see http://kegbot.org/
diff --git a/pykeg/contrib/foursquare/foursquare_test.py b/pykeg/contrib/foursquare/foursquare_test.py
index 86d97d1b6..26beff408 100644
--- a/pykeg/contrib/foursquare/foursquare_test.py
+++ b/pykeg/contrib/foursquare/foursquare_test.py
@@ -1,4 +1,4 @@
-# Copyright 2014 Bevbot LLC, All Rights Reserved
+# Copyright 2014 Kegbot Project contributors
#
# This file is part of the Pykeg package of the Kegbot project.
# For more information on Pykeg or Kegbot, see http://kegbot.org/
@@ -18,7 +18,7 @@
"""Unittests for Foursquare plugin."""
-from mock import patch
+from unittest.mock import patch
from django.test import TransactionTestCase
from django.utils import timezone
@@ -59,7 +59,7 @@ def test_plugin(self):
'foo': 'bar'
}
self.plugin.save_user_profile(self.user, fake_profile)
- self.assertEquals(fake_profile, self.plugin.get_user_profile(self.user))
+ self.assertEqual(fake_profile, self.plugin.get_user_profile(self.user))
def test_drink_poured(self):
self.plugin.save_user_token(self.user, '')
diff --git a/pykeg/contrib/foursquare/plugin.py b/pykeg/contrib/foursquare/plugin.py
index 585484634..ec7fded98 100644
--- a/pykeg/contrib/foursquare/plugin.py
+++ b/pykeg/contrib/foursquare/plugin.py
@@ -1,4 +1,4 @@
-# Copyright 2014 Bevbot LLC, All Rights Reserved
+# Copyright 2014 Kegbot Project contributors
#
# This file is part of the Pykeg package of the Kegbot project.
# For more information on Pykeg or Kegbot, see http://kegbot.org/
diff --git a/pykeg/contrib/foursquare/tasks.py b/pykeg/contrib/foursquare/tasks.py
index 00b3534f9..6613d6497 100644
--- a/pykeg/contrib/foursquare/tasks.py
+++ b/pykeg/contrib/foursquare/tasks.py
@@ -1,4 +1,4 @@
-# Copyright 2014 Bevbot LLC, All Rights Reserved
+# Copyright 2014 Kegbot Project contributors
#
# This file is part of the Pykeg package of the Kegbot project.
# For more information on Pykeg or Kegbot, see http://kegbot.org/
diff --git a/pykeg/contrib/foursquare/views.py b/pykeg/contrib/foursquare/views.py
index f6a596123..a1d442e2a 100644
--- a/pykeg/contrib/foursquare/views.py
+++ b/pykeg/contrib/foursquare/views.py
@@ -1,4 +1,4 @@
-# Copyright 2014 Bevbot LLC, All Rights Reserved
+# Copyright 2014 Kegbot Project contributors
#
# This file is part of the Pykeg package of the Kegbot project.
# For more information on Pykeg or Kegbot, see http://kegbot.org/
@@ -18,7 +18,7 @@
from builtins import str
from django.contrib import messages
-from django.core.urlresolvers import reverse
+from django.urls import reverse
from django.shortcuts import redirect
from django.contrib.auth.decorators import login_required
from django.shortcuts import render
diff --git a/pykeg/contrib/twitter/client.py b/pykeg/contrib/twitter/client.py
index 93263db07..e9a0bbb43 100644
--- a/pykeg/contrib/twitter/client.py
+++ b/pykeg/contrib/twitter/client.py
@@ -1,4 +1,4 @@
-# Copyright 2017 Bevbot LLC, All Rights Reserved
+# Copyright 2017 Kegbot Project contributors
#
# This file is part of the Pykeg package of the Kegbot project.
# For more information on Pykeg or Kegbot, see http://kegbot.org/
diff --git a/pykeg/contrib/twitter/client_test.py b/pykeg/contrib/twitter/client_test.py
index 580e0cc58..8b7bff643 100644
--- a/pykeg/contrib/twitter/client_test.py
+++ b/pykeg/contrib/twitter/client_test.py
@@ -1,4 +1,4 @@
-# Copyright 2017 Bevbot LLC, All Rights Reserved
+# Copyright 2017 Kegbot Project contributors
#
# This file is part of the Pykeg package of the Kegbot project.
# For more information on Pykeg or Kegbot, see http://kegbot.org/
diff --git a/pykeg/contrib/twitter/forms.py b/pykeg/contrib/twitter/forms.py
index 719f1781c..24aee0948 100644
--- a/pykeg/contrib/twitter/forms.py
+++ b/pykeg/contrib/twitter/forms.py
@@ -1,4 +1,4 @@
-# Copyright 2014 Bevbot LLC, All Rights Reserved
+# Copyright 2014 Kegbot Project contributors
#
# This file is part of the Pykeg package of the Kegbot project.
# For more information on Pykeg or Kegbot, see http://kegbot.org/
diff --git a/pykeg/contrib/twitter/plugin.py b/pykeg/contrib/twitter/plugin.py
index ad5af765b..aad78f2e9 100644
--- a/pykeg/contrib/twitter/plugin.py
+++ b/pykeg/contrib/twitter/plugin.py
@@ -1,4 +1,4 @@
-# Copyright 2014 Bevbot LLC, All Rights Reserved
+# Copyright 2014 Kegbot Project contributors
#
# This file is part of the Pykeg package of the Kegbot project.
# For more information on Pykeg or Kegbot, see http://kegbot.org/
diff --git a/pykeg/contrib/twitter/plugin_test.py b/pykeg/contrib/twitter/plugin_test.py
index 2e1ce6e98..49c993aeb 100644
--- a/pykeg/contrib/twitter/plugin_test.py
+++ b/pykeg/contrib/twitter/plugin_test.py
@@ -1,4 +1,4 @@
-# Copyright 2014 Bevbot LLC, All Rights Reserved
+# Copyright 2014 Kegbot Project contributors
#
# This file is part of the Pykeg package of the Kegbot project.
# For more information on Pykeg or Kegbot, see http://kegbot.org/
@@ -43,9 +43,9 @@ def test_plugin(self):
plugin.KEY_TWITTER_ID: '4',
}
self.plugin.save_site_profile('1', '2', '3', '4')
- self.assertEquals(fake_profile, self.plugin.get_site_profile())
+ self.assertEqual(fake_profile, self.plugin.get_site_profile())
self.plugin.remove_site_profile()
- self.assertEquals({}, self.plugin.get_site_profile())
+ self.assertEqual({}, self.plugin.get_site_profile())
self.plugin.save_site_profile('1', '2', '3', '4')
def test_get_site_twitter_settings_form(self):
@@ -65,12 +65,12 @@ def test_get_site_twitter_settings_form(self):
'drink_poured_template': '$DRINKER poured $VOLUME of $BEER on $SITENAME.',
'user_drink_poured_template': 'Just poured $VOLUME of $BEER on $SITENAME. #kegbot',
}
- self.assertEquals(expected, dict(settings_form.initial))
+ self.assertEqual(expected, dict(settings_form.initial))
def test_truncate_tweet(self):
msg = 'x' * 138 + 'x'
truncated = plugin.truncate_tweet(msg)
- self.assertEquals(msg, truncated)
+ self.assertEqual(msg, truncated)
longer_msg = 'x' * 138 + ' xxxx'
truncated = plugin.truncate_tweet(longer_msg)
diff --git a/pykeg/contrib/twitter/tasks.py b/pykeg/contrib/twitter/tasks.py
index 482cb41ce..25b870f0c 100644
--- a/pykeg/contrib/twitter/tasks.py
+++ b/pykeg/contrib/twitter/tasks.py
@@ -1,4 +1,4 @@
-# Copyright 2014 Bevbot LLC, All Rights Reserved
+# Copyright 2014 Kegbot Project contributors
#
# This file is part of the Pykeg package of the Kegbot project.
# For more information on Pykeg or Kegbot, see http://kegbot.org/
diff --git a/pykeg/contrib/twitter/views.py b/pykeg/contrib/twitter/views.py
index a8d73afae..073de2b62 100644
--- a/pykeg/contrib/twitter/views.py
+++ b/pykeg/contrib/twitter/views.py
@@ -1,4 +1,4 @@
-# Copyright 2014 Bevbot LLC, All Rights Reserved
+# Copyright 2014 Kegbot Project contributors
#
# This file is part of the Pykeg package of the Kegbot project.
# For more information on Pykeg or Kegbot, see http://kegbot.org/
@@ -18,7 +18,7 @@
from builtins import str
from django.contrib import messages
-from django.core.urlresolvers import reverse
+from django.urls import reverse
from django.shortcuts import redirect
from pykeg.web.decorators import staff_member_required
from django.contrib.auth.decorators import login_required
diff --git a/pykeg/contrib/untappd/client.py b/pykeg/contrib/untappd/client.py
index b1a577b47..916095596 100644
--- a/pykeg/contrib/untappd/client.py
+++ b/pykeg/contrib/untappd/client.py
@@ -1,4 +1,4 @@
-# Copyright 2017 Bevbot LLC, All Rights Reserved
+# Copyright 2017 Kegbot Project contributors
#
# This file is part of the Pykeg package of the Kegbot project.
# For more information on Pykeg or Kegbot, see http://kegbot.org/
diff --git a/pykeg/contrib/untappd/forms.py b/pykeg/contrib/untappd/forms.py
index acfd221c4..0a561c7f0 100644
--- a/pykeg/contrib/untappd/forms.py
+++ b/pykeg/contrib/untappd/forms.py
@@ -1,4 +1,4 @@
-# Copyright 2014 Bevbot LLC, All Rights Reserved
+# Copyright 2014 Kegbot Project contributors
#
# This file is part of the Pykeg package of the Kegbot project.
# For more information on Pykeg or Kegbot, see http://kegbot.org/
diff --git a/pykeg/contrib/untappd/plugin.py b/pykeg/contrib/untappd/plugin.py
index a346fdf0b..b56331705 100644
--- a/pykeg/contrib/untappd/plugin.py
+++ b/pykeg/contrib/untappd/plugin.py
@@ -1,4 +1,4 @@
-# Copyright 2014 Bevbot LLC, All Rights Reserved
+# Copyright 2014 Kegbot Project contributors
#
# This file is part of the Pykeg package of the Kegbot project.
# For more information on Pykeg or Kegbot, see http://kegbot.org/
diff --git a/pykeg/contrib/untappd/tasks.py b/pykeg/contrib/untappd/tasks.py
index 96bd45914..f0997343b 100644
--- a/pykeg/contrib/untappd/tasks.py
+++ b/pykeg/contrib/untappd/tasks.py
@@ -1,4 +1,4 @@
-# Copyright 2014 Bevbot LLC, All Rights Reserved
+# Copyright 2014 Kegbot Project contributors
#
# This file is part of the Pykeg package of the Kegbot project.
# For more information on Pykeg or Kegbot, see http://kegbot.org/
diff --git a/pykeg/contrib/untappd/untappd_test.py b/pykeg/contrib/untappd/untappd_test.py
index dbac8d1ab..209bdc78d 100644
--- a/pykeg/contrib/untappd/untappd_test.py
+++ b/pykeg/contrib/untappd/untappd_test.py
@@ -1,4 +1,4 @@
-# Copyright 2014 Bevbot LLC, All Rights Reserved
+# Copyright 2014 Kegbot Project contributors
#
# This file is part of the Pykeg package of the Kegbot project.
# For more information on Pykeg or Kegbot, see http://kegbot.org/
@@ -18,7 +18,7 @@
"""Unittests for Untappd plugin."""
-from mock import patch
+from unittest.mock import patch
from django.test import TransactionTestCase
from django.utils import timezone
@@ -61,7 +61,7 @@ def test_plugin(self):
'foo': 'bar'
}
self.plugin.save_user_profile(self.user, fake_profile)
- self.assertEquals(fake_profile, self.plugin.get_user_profile(self.user))
+ self.assertEqual(fake_profile, self.plugin.get_user_profile(self.user))
def test_drink_poured_no_foursquare(self):
self.plugin.save_user_token(self.user, 'fake-token')
diff --git a/pykeg/contrib/untappd/views.py b/pykeg/contrib/untappd/views.py
index df42e973f..e6b16671f 100644
--- a/pykeg/contrib/untappd/views.py
+++ b/pykeg/contrib/untappd/views.py
@@ -1,4 +1,4 @@
-# Copyright 2014 Bevbot LLC, All Rights Reserved
+# Copyright 2014 Kegbot Project contributors
#
# This file is part of the Pykeg package of the Kegbot project.
# For more information on Pykeg or Kegbot, see http://kegbot.org/
@@ -17,7 +17,7 @@
# along with Pykeg. If not, see .
from django.contrib import messages
-from django.core.urlresolvers import reverse
+from django.urls import reverse
from django.shortcuts import redirect
from pykeg.web.decorators import staff_member_required
from django.contrib.auth.decorators import login_required
diff --git a/pykeg/contrib/webhook/forms.py b/pykeg/contrib/webhook/forms.py
index cdca831be..d87dccb93 100644
--- a/pykeg/contrib/webhook/forms.py
+++ b/pykeg/contrib/webhook/forms.py
@@ -1,4 +1,4 @@
-# Copyright 2014 Bevbot LLC, All Rights Reserved
+# Copyright 2014 Kegbot Project contributors
#
# This file is part of the Pykeg package of the Kegbot project.
# For more information on Pykeg or Kegbot, see http://kegbot.org/
diff --git a/pykeg/contrib/webhook/plugin.py b/pykeg/contrib/webhook/plugin.py
index 045bb089a..377035b3e 100644
--- a/pykeg/contrib/webhook/plugin.py
+++ b/pykeg/contrib/webhook/plugin.py
@@ -1,4 +1,4 @@
-# Copyright 2014 Bevbot LLC, All Rights Reserved
+# Copyright 2014 Kegbot Project contributors
#
# This file is part of the Pykeg package of the Kegbot project.
# For more information on Pykeg or Kegbot, see http://kegbot.org/
diff --git a/pykeg/contrib/webhook/tasks.py b/pykeg/contrib/webhook/tasks.py
index 30c58c031..acbf34083 100644
--- a/pykeg/contrib/webhook/tasks.py
+++ b/pykeg/contrib/webhook/tasks.py
@@ -1,4 +1,4 @@
-# Copyright 2014 Bevbot LLC, All Rights Reserved
+# Copyright 2014 Kegbot Project contributors
#
# This file is part of the Pykeg package of the Kegbot project.
# For more information on Pykeg or Kegbot, see http://kegbot.org/
diff --git a/pykeg/contrib/webhook/views.py b/pykeg/contrib/webhook/views.py
index 61ae872b0..66bd6ce1b 100644
--- a/pykeg/contrib/webhook/views.py
+++ b/pykeg/contrib/webhook/views.py
@@ -1,4 +1,4 @@
-# Copyright 2014 Bevbot LLC, All Rights Reserved
+# Copyright 2014 Kegbot Project contributors
#
# This file is part of the Pykeg package of the Kegbot project.
# For more information on Pykeg or Kegbot, see http://kegbot.org/
diff --git a/pykeg/core/admin.py b/pykeg/core/admin.py
index 03f181332..d5386b661 100644
--- a/pykeg/core/admin.py
+++ b/pykeg/core/admin.py
@@ -1,4 +1,4 @@
-# Copyright 2014 Bevbot LLC, All Rights Reserved
+# Copyright 2014 Kegbot Project contributors
#
# This file is part of the Pykeg package of the Kegbot project.
# For more information on Pykeg or Kegbot, see http://kegbot.org/
diff --git a/pykeg/core/cache.py b/pykeg/core/cache.py
index 5295396db..9da6ac215 100644
--- a/pykeg/core/cache.py
+++ b/pykeg/core/cache.py
@@ -1,4 +1,4 @@
-# Copyright 2014 Bevbot LLC, All Rights Reserved
+# Copyright 2014 Kegbot Project contributors
#
# This file is part of the Pykeg package of the Kegbot project.
# For more information on Pykeg or Kegbot, see http://kegbot.org/
diff --git a/pykeg/core/cache_test.py b/pykeg/core/cache_test.py
index 76fd2c074..31e3b29a5 100644
--- a/pykeg/core/cache_test.py
+++ b/pykeg/core/cache_test.py
@@ -1,4 +1,4 @@
-# Copyright 2014 Bevbot LLC, All Rights Reserved
+# Copyright 2014 Kegbot Project contributors
#
# This file is part of the Pykeg package of the Kegbot project.
# For more information on Pykeg or Kegbot, see http://kegbot.org/
@@ -32,31 +32,31 @@ def test_basics(self):
cache = KegbotCache(generation_fn=lambda: 100)
# keyname, get, set
- self.assertEquals('kb:foo', cache.keyname('foo'))
- self.assertEquals(None, django_cache.get('kb:foo'))
- self.assertEquals(123, django_cache.get('kb:foo', 123))
+ self.assertEqual('kb:foo', cache.keyname('foo'))
+ self.assertEqual(None, django_cache.get('kb:foo'))
+ self.assertEqual(123, django_cache.get('kb:foo', 123))
cache.set('foo', 'bar')
- self.assertEquals('bar', django_cache.get('kb:foo'))
+ self.assertEqual('bar', django_cache.get('kb:foo'))
# generation
- self.assertEquals(None, django_cache.get(cache.generation_key))
+ self.assertEqual(None, django_cache.get(cache.generation_key))
gen = cache.get_generation()
- self.assertEquals(100, gen)
- self.assertEquals('kb:foo:100', cache.gen_keyname('foo'))
- self.assertEquals(100, django_cache.get(cache.generation_key))
+ self.assertEqual(100, gen)
+ self.assertEqual('kb:foo:100', cache.gen_keyname('foo'))
+ self.assertEqual(100, django_cache.get(cache.generation_key))
cache.gen_set('test', 555)
- self.assertEquals(555, cache.gen_get('test'))
+ self.assertEqual(555, cache.gen_get('test'))
cache.update_generation()
- self.assertEquals(101, cache.get_generation())
- self.assertEquals(None, cache.gen_get('test'))
+ self.assertEqual(101, cache.get_generation())
+ self.assertEqual(None, cache.gen_get('test'))
@override_settings(KEGBOT_CACHE_PREFIX='other')
def test_prefix_other(self):
"""Verifies settings.KEGBOT_CACHE_PREFIX is respected."""
cache = KegbotCache(generation_fn=lambda: 100)
- self.assertEquals('other:foo', cache.keyname('foo'))
- self.assertEquals('other:foo:100', cache.gen_keyname('foo'))
+ self.assertEqual('other:foo', cache.keyname('foo'))
+ self.assertEqual('other:foo:100', cache.gen_keyname('foo'))
def test_generation_update(self):
"""Tests updating the generation succeeds even when missing."""
diff --git a/pykeg/core/checkin.py b/pykeg/core/checkin.py
index 720a1601a..5119e076b 100644
--- a/pykeg/core/checkin.py
+++ b/pykeg/core/checkin.py
@@ -1,4 +1,4 @@
-# Copyright 2014 Bevbot LLC, All Rights Reserved
+# Copyright 2014 Kegbot Project contributors
#
# This file is part of the Pykeg package of the Kegbot project.
# For more information on Pykeg or Kegbot, see http://kegbot.org/
diff --git a/pykeg/core/checkin_test.py b/pykeg/core/checkin_test.py
index 84e337a27..5c9e0c436 100644
--- a/pykeg/core/checkin_test.py
+++ b/pykeg/core/checkin_test.py
@@ -1,4 +1,4 @@
-# Copyright 2014 Bevbot LLC, All Rights Reserved
+# Copyright 2014 Kegbot Project contributors
#
# This file is part of the Pykeg package of the Kegbot project.
# For more information on Pykeg or Kegbot, see http://kegbot.org/
@@ -20,8 +20,7 @@
from django.test import TransactionTestCase
-from mock import Mock
-from mock import patch
+from unittest.mock import Mock, patch
from pykeg.core import checkin
from pykeg.core import models
@@ -57,4 +56,4 @@ def test_checkin(self):
timeout=1.23)
site = models.KegbotSite.get()
- self.assertEquals('new-regid', site.registration_id)
+ self.assertEqual('new-regid', site.registration_id)
diff --git a/pykeg/core/defaults.py b/pykeg/core/defaults.py
index a2d252058..107c564e1 100644
--- a/pykeg/core/defaults.py
+++ b/pykeg/core/defaults.py
@@ -1,4 +1,4 @@
-# Copyright 2014 Bevbot LLC, All Rights Reserved
+# Copyright 2014 Kegbot Project contributors
#
# This file is part of the Pykeg package of the Kegbot project.
# For more information on Pykeg or Kegbot, see http://kegbot.org/
diff --git a/pykeg/core/kb_common.py b/pykeg/core/kb_common.py
index d999d3a7a..77ca633ed 100644
--- a/pykeg/core/kb_common.py
+++ b/pykeg/core/kb_common.py
@@ -1,4 +1,4 @@
-# Copyright 2014 Bevbot LLC, All Rights Reserved
+# Copyright 2014 Kegbot Project contributors
#
# This file is part of the Pykeg package of the Kegbot project.
# For more information on Pykeg or Kegbot, see http://kegbot.org/
diff --git a/pykeg/core/keg_sizes.py b/pykeg/core/keg_sizes.py
index 3b7cea19f..6c9ed669f 100644
--- a/pykeg/core/keg_sizes.py
+++ b/pykeg/core/keg_sizes.py
@@ -1,4 +1,4 @@
-# Copyright 2014 Bevbot LLC, All Rights Reserved
+# Copyright 2014 Kegbot Project contributors
#
# This file is part of the Pykeg package of the Kegbot project.
# For more information on Pykeg or Kegbot, see http://kegbot.org/
diff --git a/pykeg/core/management/commands/backup.py b/pykeg/core/management/commands/backup.py
index 35640e6a5..dc4e4e0cc 100644
--- a/pykeg/core/management/commands/backup.py
+++ b/pykeg/core/management/commands/backup.py
@@ -1,4 +1,5 @@
-# Copyright 2014 Bevbot LLC, All Rights Reserved
+from __future__ import print_function
+# Copyright 2014 Kegbot Project contributors
#
# This file is part of the Pykeg package of the Kegbot project.
# For more information on Pykeg or Kegbot, see http://kegbot.org/
@@ -38,9 +39,9 @@ def handle(self, **options):
path = location
if hasattr(storage, 'location'):
path = os.path.join(storage.location, path)
- print 'Backup complete!'
- print 'Path: {}'.format(path)
+ print('Backup complete!')
+ print('Path: {}'.format(path))
try:
- print 'URL: {}'.format(storage.url(location))
+ print('URL: {}'.format(storage.url(location)))
except (NotImplementedError, UnknownBaseUrlException):
pass
diff --git a/pykeg/core/management/commands/common.py b/pykeg/core/management/commands/common.py
index 98c2a9123..c2f01f75a 100644
--- a/pykeg/core/management/commands/common.py
+++ b/pykeg/core/management/commands/common.py
@@ -1,4 +1,5 @@
-# Copyright 2014 Bevbot LLC, All Rights Reserved
+from __future__ import print_function
+# Copyright 2014 Kegbot Project contributors
#
# This file is part of the Pykeg package of the Kegbot project.
# For more information on Pykeg or Kegbot, see http://kegbot.org/
@@ -16,6 +17,7 @@
# You should have received a copy of the GNU General Public License
# along with Pykeg. If not, see .
+from builtins import object
import os
import signal
import sys
@@ -46,7 +48,7 @@ def progbar(title, pos, total, width=40):
def check_and_create_pid_file(pid_file):
if os.path.exists(pid_file):
- print 'Error: already running ({})'.format(pid_file)
+ print('Error: already running ({})'.format(pid_file))
sys.exit(1)
f = open(pid_file, 'w')
diff --git a/pykeg/core/management/commands/create_api_key.py b/pykeg/core/management/commands/create_api_key.py
index 7eb142568..5ff39a50e 100644
--- a/pykeg/core/management/commands/create_api_key.py
+++ b/pykeg/core/management/commands/create_api_key.py
@@ -1,4 +1,5 @@
-# Copyright 2014 Bevbot LLC, All Rights Reserved
+from __future__ import print_function
+# Copyright 2014 Kegbot Project contributors
#
# This file is part of the Pykeg package of the Kegbot project.
# For more information on Pykeg or Kegbot, see http://kegbot.org/
@@ -31,4 +32,4 @@ def handle(self, *args, **options):
raise CommandError('Must specify description')
key = models.ApiKey.objects.create(description=args[0])
- print key.key
+ print(key.key)
diff --git a/pykeg/core/management/commands/erase.py b/pykeg/core/management/commands/erase.py
index d9fbf89a0..9a514b34f 100644
--- a/pykeg/core/management/commands/erase.py
+++ b/pykeg/core/management/commands/erase.py
@@ -1,4 +1,5 @@
-# Copyright 2014 Bevbot LLC, All Rights Reserved
+from __future__ import print_function
+# Copyright 2014 Kegbot Project contributors
#
# This file is part of the Pykeg package of the Kegbot project.
# For more information on Pykeg or Kegbot, see http://kegbot.org/
@@ -16,6 +17,7 @@
# You should have received a copy of the GNU General Public License
# along with Pykeg. If not, see .
+from builtins import input
from django.conf import settings
from django.core.management.base import BaseCommand
from pykeg.backup import backup
@@ -27,25 +29,25 @@ class Command(BaseCommand):
help = u'Erases all data in the current Kegbot system.'
def handle(self, *args, **options):
- print 'WARNING!'
- print ''
- print ' ************************************************************************'
- print ' This command erases ALL tables and media files in the Kegbot system, and '
- print ' CANNOT BE UNDONE.'
- print ''
- print ' Database: {}'.format(settings.DATABASES['default']['NAME'])
- print ' Media: {}'.format(settings.MEDIA_ROOT)
- print ' ************************************************************************'
- print ''
- print 'Are you SURE you want to continue? '
- print ''
+ print('WARNING!')
+ print('')
+ print(' ************************************************************************')
+ print(' This command erases ALL tables and media files in the Kegbot system, and ')
+ print(' CANNOT BE UNDONE.')
+ print('')
+ print(' Database: {}'.format(settings.DATABASES['default']['NAME']))
+ print(' Media: {}'.format(settings.MEDIA_ROOT))
+ print(' ************************************************************************')
+ print('')
+ print('Are you SURE you want to continue? ')
+ print('')
try:
- response = raw_input('Type ERASE to continue, anything else to abort: ')
+ response = input('Type ERASE to continue, anything else to abort: ')
except KeyboardInterrupt:
response = ''
- print ''
+ print('')
if response.strip() != 'ERASE':
- print 'Aborted.'
+ print('Aborted.')
sys.exit(1)
backup.erase()
diff --git a/pykeg/core/management/commands/kb_regen_events.py b/pykeg/core/management/commands/kb_regen_events.py
index 9ab4cf2f1..1af1901cd 100644
--- a/pykeg/core/management/commands/kb_regen_events.py
+++ b/pykeg/core/management/commands/kb_regen_events.py
@@ -1,4 +1,5 @@
-# Copyright 2014 Bevbot LLC, All Rights Reserved
+from __future__ import print_function
+# Copyright 2014 Kegbot Project contributors
#
# This file is part of the Pykeg package of the Kegbot project.
# For more information on Pykeg or Kegbot, see http://kegbot.org/
@@ -31,7 +32,7 @@ def handle(self, *args, **options):
progbar('clear events', 0, num_events)
events.delete()
progbar('clear events', num_events, num_events)
- print ''
+ print('')
pos = 0
drinks = models.Drink.objects.all()
@@ -40,6 +41,6 @@ def handle(self, *args, **options):
pos += 1
progbar('create new events', pos, count)
models.SystemEvent.build_events_for_drink(d)
- print ''
+ print('')
- print 'done!'
+ print('done!')
diff --git a/pykeg/core/management/commands/regen_stats.py b/pykeg/core/management/commands/regen_stats.py
index d88be40d2..fb114b01c 100644
--- a/pykeg/core/management/commands/regen_stats.py
+++ b/pykeg/core/management/commands/regen_stats.py
@@ -1,4 +1,5 @@
-# Copyright 2014 Bevbot LLC, All Rights Reserved
+from __future__ import print_function
+# Copyright 2014 Kegbot Project contributors
#
# This file is part of the Pykeg package of the Kegbot project.
# For more information on Pykeg or Kegbot, see http://kegbot.org/
@@ -39,5 +40,5 @@ def cb(results, self=self):
stats.invalidate_all()
stats.rebuild_from_id(0, cb=cb)
- print ''
- print 'done!'
+ print('')
+ print('done!')
diff --git a/pykeg/core/management/commands/rename_user.py b/pykeg/core/management/commands/rename_user.py
index 71f52905b..e40ae4342 100644
--- a/pykeg/core/management/commands/rename_user.py
+++ b/pykeg/core/management/commands/rename_user.py
@@ -1,4 +1,5 @@
-# Copyright 2014 Bevbot LLC, All Rights Reserved
+from __future__ import print_function
+# Copyright 2014 Kegbot Project contributors
#
# This file is part of the Pykeg package of the Kegbot project.
# For more information on Pykeg or Kegbot, see http://kegbot.org/
@@ -46,4 +47,4 @@ def handle(self, *args, **options):
user.username = to_username
user.save()
- print '"{}" has been renamed "{}"'.format(from_username, to_username)
+ print('"{}" has been renamed "{}"'.format(from_username, to_username))
diff --git a/pykeg/core/management/commands/restore.py b/pykeg/core/management/commands/restore.py
index fcf437421..c210dacb7 100644
--- a/pykeg/core/management/commands/restore.py
+++ b/pykeg/core/management/commands/restore.py
@@ -1,4 +1,4 @@
-# Copyright 2014 Bevbot LLC, All Rights Reserved
+# Copyright 2014 Kegbot Project contributors
#
# This file is part of the Pykeg package of the Kegbot project.
# For more information on Pykeg or Kegbot, see http://kegbot.org/
diff --git a/pykeg/core/management/commands/run_all.py b/pykeg/core/management/commands/run_all.py
index ef9cf0077..4a677da5a 100644
--- a/pykeg/core/management/commands/run_all.py
+++ b/pykeg/core/management/commands/run_all.py
@@ -1,4 +1,4 @@
-# Copyright 2014 Bevbot LLC, All Rights Reserved
+# Copyright 2014 Kegbot Project contributors
#
# This file is part of the Pykeg package of the Kegbot project.
# For more information on Pykeg or Kegbot, see http://kegbot.org/
diff --git a/pykeg/core/management/commands/run_workers.py b/pykeg/core/management/commands/run_workers.py
index 4dd30d309..2a2a3c7e7 100644
--- a/pykeg/core/management/commands/run_workers.py
+++ b/pykeg/core/management/commands/run_workers.py
@@ -1,4 +1,4 @@
-# Copyright 2014 Bevbot LLC, All Rights Reserved
+# Copyright 2014 Kegbot Project contributors
#
# This file is part of the Pykeg package of the Kegbot project.
# For more information on Pykeg or Kegbot, see http://kegbot.org/
diff --git a/pykeg/core/management/commands/upgrade.py b/pykeg/core/management/commands/upgrade.py
index fb61faaa2..b99d51848 100644
--- a/pykeg/core/management/commands/upgrade.py
+++ b/pykeg/core/management/commands/upgrade.py
@@ -1,4 +1,5 @@
-# Copyright 2014 Bevbot LLC, All Rights Reserved
+from __future__ import print_function
+# Copyright 2014 Kegbot Project contributors
#
# This file is part of the Pykeg package of the Kegbot project.
# For more information on Pykeg or Kegbot, see http://kegbot.org/
@@ -16,6 +17,7 @@
# You should have received a copy of the GNU General Public License
# along with Pykeg. If not, see .
+from builtins import str
from distutils.version import StrictVersion
import sys
@@ -41,7 +43,7 @@
def run(cmd, args=[]):
cmdname = cmd.__module__.split('.')[-1]
arg_str = ' '.join('%s' % a for a in args)
- print '--- Running command: %s %s' % (cmdname, arg_str)
+ print('--- Running command: %s %s' % (cmdname, arg_str))
cmd.run_from_argv([sys.argv[0], cmdname] + args)
@@ -62,30 +64,30 @@ def handle(self, *args, **options):
force = options.get('force')
if installed_version is None:
- print 'Kegbot is not installed; run setup-kegbot.py first.'
+ print('Kegbot is not installed; run setup-kegbot.py first.')
sys.exit(1)
if installed_version == app_version and not force:
- print 'Version {} already installed.'.format(installed_version)
+ print('Version {} already installed.'.format(installed_version))
return
if installed_version > app_version:
- print 'Installed version {} is newer than app version {}'.format(
- installed_version, app_version)
+ print('Installed version {} is newer than app version {}'.format(
+ installed_version, app_version))
sys.exit(1)
if installed_version < MINIMUM_INSTALLED_VERSION:
- print ''
- print 'ERROR: This version of Kegbot can only upgrade systems running on version'
- print 'v{} or newer. Please install Kegbot v{} and run `kegbot upgrade` again.'.format(
- MINIMUM_INSTALLED_VERSION, MINIMUM_INSTALLED_VERSION)
- print '(Existing version: {})'.format(installed_version)
- print ''
- print 'More help: https://github.com/Kegbot/kegbot-server/wiki/Upgrading-Old-Versions'
- print ''
+ print('')
+ print('ERROR: This version of Kegbot can only upgrade systems running on version')
+ print('v{} or newer. Please install Kegbot v{} and run `kegbot upgrade` again.'.format(
+ MINIMUM_INSTALLED_VERSION, MINIMUM_INSTALLED_VERSION))
+ print('(Existing version: {})'.format(installed_version))
+ print('')
+ print('More help: https://github.com/Kegbot/kegbot-server/wiki/Upgrading-Old-Versions')
+ print('')
sys.exit(1)
- print 'Upgrading from {} to {}'.format(installed_version, app_version)
+ print('Upgrading from {} to {}'.format(installed_version, app_version))
self.do_version_upgrades(installed_version)
run(migrate.Command(), args=['--noinput', '-v', '0'])
@@ -106,9 +108,9 @@ def handle(self, *args, **options):
except (checkin.CheckinError, Exception):
pass
- print ''
- print 'Upgrade complete!'
+ print('')
+ print('Upgrade complete!')
def do_version_upgrades(self, installed_version):
if installed_version.version < (1, 2, 0):
- print 'Upgrading from v1.1.x'
+ print('Upgrading from v1.1.x')
diff --git a/pykeg/core/managers.py b/pykeg/core/managers.py
index e3e57274c..ec25b9e00 100644
--- a/pykeg/core/managers.py
+++ b/pykeg/core/managers.py
@@ -1,4 +1,4 @@
-# Copyright 2014 Bevbot LLC, All Rights Reserved
+# Copyright 2014 Kegbot Project contributors
#
# This file is part of the Pykeg package of the Kegbot project.
# For more information on Pykeg or Kegbot, see http://kegbot.org/
diff --git a/pykeg/core/migrations/0001_initial.py b/pykeg/core/migrations/0001_initial.py
index 9a555a93b..4c5e4f4a0 100644
--- a/pykeg/core/migrations/0001_initial.py
+++ b/pykeg/core/migrations/0001_initial.py
@@ -63,7 +63,7 @@ class Migration(migrations.Migration):
('enabled', models.BooleanField(default=True, help_text=b'Whether this token is considered active.')),
('created_time', models.DateTimeField(help_text=b'Date token was first added to the system.', auto_now_add=True)),
('expire_time', models.DateTimeField(help_text=b'Date after which token is treated as disabled.', null=True, blank=True)),
- ('user', models.ForeignKey(related_name='tokens', blank=True, to=settings.AUTH_USER_MODEL, help_text=b'User in possession of and authenticated by this token.', null=True)),
+ ('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='tokens', blank=True, to=settings.AUTH_USER_MODEL, help_text=b'User in possession of and authenticated by this token.', null=True)),
],
options={
},
@@ -176,7 +176,7 @@ class Migration(migrations.Migration):
('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
('port_name', models.CharField(help_text=b'Controller-specific data port name for this meter.', max_length=128)),
('ticks_per_ml', models.FloatField(default=2.724, help_text=b'Flow meter pulses per mL of fluid. Common values: 2.724 (FT330-RJ), 5.4 (SF800)')),
- ('controller', models.ForeignKey(related_name='meters', to='core.Controller', help_text=b'Controller that owns this meter.')),
+ ('controller', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='meters', to='core.Controller', help_text=b'Controller that owns this meter.')),
],
options={
},
@@ -187,7 +187,7 @@ class Migration(migrations.Migration):
fields=[
('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
('port_name', models.CharField(help_text=b'Controller-specific data port name for this toggle.', max_length=128)),
- ('controller', models.ForeignKey(related_name='toggles', to='core.Controller', help_text=b'Controller that owns this toggle.')),
+ ('controller', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='toggles', to='core.Controller', help_text=b'Controller that owns this toggle.')),
],
options={
},
@@ -272,7 +272,7 @@ class Migration(migrations.Migration):
('session_started', models.BooleanField(default=False, help_text=b'Sent when a new drinking session starts.')),
('keg_volume_low', models.BooleanField(default=False, help_text=b'Sent when a keg becomes low.')),
('keg_ended', models.BooleanField(default=False, help_text=b'Sent when a keg has been taken offline.')),
- ('user', models.ForeignKey(help_text=b'User for these settings.', to=settings.AUTH_USER_MODEL)),
+ ('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, help_text=b'User for these settings.', to=settings.AUTH_USER_MODEL)),
],
options={
},
@@ -287,7 +287,7 @@ class Migration(migrations.Migration):
('caption', models.TextField(help_text=b'Caption for the picture, if any.', null=True, blank=True)),
('keg', models.ForeignKey(related_name='pictures', on_delete=django.db.models.deletion.SET_NULL, blank=True, to='core.Keg', help_text=b'Keg this picture was taken with, if any.', null=True)),
('session', models.ForeignKey(related_name='pictures', on_delete=django.db.models.deletion.SET_NULL, blank=True, to='core.DrinkingSession', help_text=b'Session this picture was taken with, if any.', null=True)),
- ('user', models.ForeignKey(related_name='pictures', blank=True, to=settings.AUTH_USER_MODEL, help_text=b'User that owns/uploaded this picture', null=True)),
+ ('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='pictures', blank=True, to=settings.AUTH_USER_MODEL, help_text=b'User that owns/uploaded this picture', null=True)),
],
options={
},
@@ -312,10 +312,10 @@ class Migration(migrations.Migration):
('time', models.DateTimeField(default=django.utils.timezone.now)),
('stats', pykeg.core.jsonfield.JSONField()),
('is_first', models.BooleanField(default=False, help_text=b'True if this is the most first record for the view.')),
- ('drink', models.ForeignKey(to='core.Drink')),
- ('keg', models.ForeignKey(related_name='stats', to='core.Keg', null=True)),
- ('session', models.ForeignKey(related_name='stats', to='core.DrinkingSession', null=True)),
- ('user', models.ForeignKey(related_name='stats', to=settings.AUTH_USER_MODEL, null=True)),
+ ('drink', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='core.Drink')),
+ ('keg', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='stats', to='core.Keg', null=True)),
+ ('session', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='stats', to='core.DrinkingSession', null=True)),
+ ('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='stats', to=settings.AUTH_USER_MODEL, null=True)),
],
options={
'get_latest_by': 'id',
@@ -328,10 +328,10 @@ class Migration(migrations.Migration):
('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
('kind', models.CharField(help_text=b'Type of event.', max_length=255, choices=[(b'drink_poured', b'Drink poured'), (b'session_started', b'Session started'), (b'session_joined', b'User joined session'), (b'keg_tapped', b'Keg tapped'), (b'keg_volume_low', b'Keg volume low'), (b'keg_ended', b'Keg ended')])),
('time', models.DateTimeField(help_text=b'Time of the event.')),
- ('drink', models.ForeignKey(related_name='events', blank=True, to='core.Drink', help_text=b'Drink involved in the event, if any.', null=True)),
- ('keg', models.ForeignKey(related_name='events', blank=True, to='core.Keg', help_text=b'Keg involved in the event, if any.', null=True)),
- ('session', models.ForeignKey(related_name='events', blank=True, to='core.DrinkingSession', help_text=b'Session involved in the event, if any.', null=True)),
- ('user', models.ForeignKey(related_name='events', blank=True, to=settings.AUTH_USER_MODEL, help_text=b'User responsible for the event, if any.', null=True)),
+ ('drink', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='events', blank=True, to='core.Drink', help_text=b'Drink involved in the event, if any.', null=True)),
+ ('keg', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='events', blank=True, to='core.Keg', help_text=b'Keg involved in the event, if any.', null=True)),
+ ('session', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='events', blank=True, to='core.DrinkingSession', help_text=b'Session involved in the event, if any.', null=True)),
+ ('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='events', blank=True, to=settings.AUTH_USER_MODEL, help_text=b'User responsible for the event, if any.', null=True)),
],
options={
'ordering': ('-id',),
@@ -366,7 +366,7 @@ class Migration(migrations.Migration):
migrations.AddField(
model_name='thermolog',
name='sensor',
- field=models.ForeignKey(to='core.ThermoSensor'),
+ field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='core.ThermoSensor'),
preserve_default=True,
),
migrations.AlterUniqueTogether(
@@ -396,7 +396,7 @@ class Migration(migrations.Migration):
migrations.AddField(
model_name='flowtoggle',
name='tap',
- field=models.OneToOneField(related_name='toggle', null=True, blank=True, to='core.KegTap', help_text=b'Tap to which this toggle is currently bound.'),
+ field=models.OneToOneField(on_delete=django.db.models.deletion.SET_NULL, related_name='toggle', null=True, blank=True, to='core.KegTap', help_text=b'Tap to which this toggle is currently bound.'),
preserve_default=True,
),
migrations.AlterUniqueTogether(
@@ -406,7 +406,7 @@ class Migration(migrations.Migration):
migrations.AddField(
model_name='flowmeter',
name='tap',
- field=models.OneToOneField(related_name='meter', null=True, blank=True, to='core.KegTap', help_text=b'Tap to which this meter is currently bound.'),
+ field=models.OneToOneField(on_delete=django.db.models.deletion.SET_NULL, related_name='meter', null=True, blank=True, to='core.KegTap', help_text=b'Tap to which this meter is currently bound.'),
preserve_default=True,
),
migrations.AlterUniqueTogether(
@@ -434,7 +434,7 @@ class Migration(migrations.Migration):
migrations.AddField(
model_name='drink',
name='user',
- field=models.ForeignKey(related_name='drinks', editable=False, to=settings.AUTH_USER_MODEL, help_text=b'User responsible for this Drink, or None if anonymous/unknown.'),
+ field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='drinks', editable=False, to=settings.AUTH_USER_MODEL, help_text=b'User responsible for this Drink, or None if anonymous/unknown.'),
preserve_default=True,
),
migrations.AddField(
@@ -446,13 +446,13 @@ class Migration(migrations.Migration):
migrations.AddField(
model_name='beverage',
name='picture',
- field=models.ForeignKey(blank=True, to='core.Picture', help_text=b'Label image.', null=True),
+ field=models.ForeignKey(on_delete=django.db.models.deletion.SET_NULL, blank=True, to='core.Picture', help_text=b'Label image.', null=True),
preserve_default=True,
),
migrations.AddField(
model_name='beverage',
name='producer',
- field=models.ForeignKey(to='core.BeverageProducer'),
+ field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='core.BeverageProducer'),
preserve_default=True,
),
migrations.AlterUniqueTogether(
@@ -462,13 +462,13 @@ class Migration(migrations.Migration):
migrations.AddField(
model_name='apikey',
name='device',
- field=models.ForeignKey(to='core.Device', help_text=b'Device this key is associated with.', null=True),
+ field=models.ForeignKey(on_delete=django.db.models.deletion.SET_NULL, to='core.Device', help_text=b'Device this key is associated with.', null=True),
preserve_default=True,
),
migrations.AddField(
model_name='apikey',
name='user',
- field=models.ForeignKey(blank=True, to=settings.AUTH_USER_MODEL, help_text=b'User receiving API access.', null=True),
+ field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, blank=True, to=settings.AUTH_USER_MODEL, help_text=b'User receiving API access.', null=True),
preserve_default=True,
),
migrations.AddField(
diff --git a/pykeg/core/models.py b/pykeg/core/models.py
index 853ef0ea1..0d1450af3 100644
--- a/pykeg/core/models.py
+++ b/pykeg/core/models.py
@@ -1,5 +1,5 @@
# -*- coding: latin-1 -*-
-# Copyright 2014 Bevbot LLC, All Rights Reserved
+# Copyright 2014 Kegbot Project contributors
#
# This file is part of the Pykeg package of the Kegbot project.
# For more information on Pykeg or Kegbot, see http://kegbot.org/
@@ -36,7 +36,7 @@
from django.conf import settings
from django.contrib.auth.models import AbstractBaseUser
from django.contrib.auth.models import UserManager
-from django.core.urlresolvers import reverse, reverse_lazy
+from django.urls import reverse, reverse_lazy
from django.core import validators
from django.core.cache import cache
from django.core.files.storage import default_storage
@@ -362,7 +362,7 @@ def can_invite(self, user):
if self.registration_mode == 'public':
return True
if self.registration_mode == 'member-invite-only':
- return not user.is_anonymous()
+ return not user.is_anonymous
if self.registration_mode == 'staff-invite-only':
return user.is_staff
return False
@@ -378,8 +378,10 @@ class ApiKey(models.Model):
"""Grants access to certain API endpoints to a user via a secret key."""
user = models.ForeignKey(User, blank=True, null=True,
+ on_delete=models.CASCADE,
help_text='User receiving API access.')
device = models.ForeignKey(Device, null=True,
+ on_delete=models.SET_NULL,
help_text='Device this key is associated with.')
key = models.CharField(max_length=127, editable=False, unique=True,
default=get_default_api_key,
@@ -464,7 +466,7 @@ class Beverage(models.Model):
name = models.CharField(max_length=255,
help_text='Name of the beverage, such as "Potrero Pale".')
- producer = models.ForeignKey(BeverageProducer)
+ producer = models.ForeignKey(BeverageProducer, on_delete=models.PROTECT)
beverage_type = models.CharField(max_length=32,
choices=TYPES,
@@ -474,7 +476,7 @@ class Beverage(models.Model):
description = models.TextField(blank=True, null=True,
help_text='Free-form description of the beverage.')
- picture = models.ForeignKey('Picture', blank=True, null=True,
+ picture = models.ForeignKey('Picture', blank=True, null=True, on_delete=models.SET_NULL,
help_text='Label image.')
vintage_year = models.DateField(
blank=True,
@@ -605,11 +607,12 @@ def __str__(self):
class FlowMeter(models.Model):
class Meta(object):
unique_together = ('controller', 'port_name')
- controller = models.ForeignKey(Controller, related_name='meters',
+ controller = models.ForeignKey(Controller, related_name='meters', on_delete=models.CASCADE,
help_text='Controller that owns this meter.')
port_name = models.CharField(max_length=128,
help_text='Controller-specific data port name for this meter.')
tap = models.OneToOneField(KegTap, blank=True, null=True,
+ on_delete=models.SET_NULL,
related_name='meter',
help_text='Tap to which this meter is currently bound.')
ticks_per_ml = models.FloatField(
@@ -659,12 +662,13 @@ def get_from_meter_name(cls, meter_name):
class FlowToggle(models.Model):
class Meta(object):
unique_together = ('controller', 'port_name')
- controller = models.ForeignKey(Controller, related_name='toggles',
+ controller = models.ForeignKey(Controller, related_name='toggles', on_delete=models.CASCADE,
help_text='Controller that owns this toggle.')
port_name = models.CharField(max_length=128,
help_text='Controller-specific data port name for this toggle.')
tap = models.OneToOneField(KegTap, blank=True, null=True,
related_name='toggle',
+ on_delete=models.SET_NULL,
help_text='Tap to which this toggle is currently bound.')
def toggle_name(self):
@@ -884,6 +888,7 @@ class Meta(object):
User,
related_name='drinks',
editable=False,
+ on_delete=models.PROTECT,
help_text='User responsible for this Drink, or None if anonymous/unknown.')
keg = models.ForeignKey(Keg, related_name='drinks',
on_delete=models.PROTECT, editable=False,
@@ -944,6 +949,7 @@ class Meta(object):
help_text='A secret value necessary to authenticate with this token.')
user = models.ForeignKey(User, blank=True, null=True,
related_name='tokens',
+ on_delete=models.CASCADE,
help_text='User in possession of and authenticated by this token.')
enabled = models.BooleanField(default=True,
help_text='Whether this token is considered active.')
@@ -1173,7 +1179,7 @@ class Meta(object):
get_latest_by = 'time'
ordering = ('-time',)
- sensor = models.ForeignKey(ThermoSensor)
+ sensor = models.ForeignKey(ThermoSensor, on_delete=models.CASCADE)
temp = models.FloatField()
time = models.DateTimeField()
@@ -1202,15 +1208,15 @@ class Stats(models.Model):
"""
time = models.DateTimeField(default=timezone.now)
stats = JSONField(dump_kwargs={'cls': kbjson.JSONEncoder})
- drink = models.ForeignKey(Drink)
+ drink = models.ForeignKey(Drink, on_delete=models.CASCADE)
is_first = models.BooleanField(default=False,
help_text='True if this is the most first record for the view.')
# Any combination of these fields is allowed.
- user = models.ForeignKey(User, related_name='stats', null=True)
- keg = models.ForeignKey(Keg, related_name='stats', null=True)
- session = models.ForeignKey(DrinkingSession, related_name='stats', null=True)
+ user = models.ForeignKey(User, related_name='stats', null=True, on_delete=models.CASCADE)
+ keg = models.ForeignKey(Keg, related_name='stats', null=True, on_delete=models.CASCADE)
+ session = models.ForeignKey(DrinkingSession, related_name='stats', null=True, on_delete=models.CASCADE)
class Meta(object):
get_latest_by = 'id'
@@ -1272,16 +1278,16 @@ class Meta(object):
kind = models.CharField(max_length=255, choices=KINDS,
help_text='Type of event.')
time = models.DateTimeField(help_text='Time of the event.')
- user = models.ForeignKey(User, blank=True, null=True,
+ user = models.ForeignKey(User, blank=True, null=True, on_delete=models.SET_NULL,
related_name='events',
help_text='User responsible for the event, if any.')
- drink = models.ForeignKey(Drink, blank=True, null=True,
+ drink = models.ForeignKey(Drink, blank=True, null=True, on_delete=models.CASCADE,
related_name='events',
help_text='Drink involved in the event, if any.')
- keg = models.ForeignKey(Keg, blank=True, null=True,
+ keg = models.ForeignKey(Keg, blank=True, null=True, on_delete=models.CASCADE,
related_name='events',
help_text='Keg involved in the event, if any.')
- session = models.ForeignKey(DrinkingSession, blank=True, null=True,
+ session = models.ForeignKey(DrinkingSession, blank=True, null=True, on_delete=models.CASCADE,
related_name='events',
help_text='Session involved in the event, if any.')
@@ -1409,10 +1415,10 @@ class Picture(models.Model):
help_text='Time/date of image capture')
caption = models.TextField(blank=True, null=True,
help_text='Caption for the picture, if any.')
- user = models.ForeignKey(User, blank=True, null=True,
+ user = models.ForeignKey(User, blank=True, null=True, on_delete=models.CASCADE,
related_name='pictures',
help_text='User that owns/uploaded this picture')
- keg = models.ForeignKey(Keg, blank=True, null=True,
+ keg = models.ForeignKey(Keg, blank=True, null=True,
related_name='pictures',
on_delete=models.SET_NULL,
help_text='Keg this picture was taken with, if any.')
@@ -1467,6 +1473,7 @@ class Meta(object):
unique_together = ('user', 'backend')
user = models.ForeignKey(User,
+ on_delete=models.CASCADE,
help_text='User for these settings.')
backend = models.CharField(max_length=255,
help_text='Notification backend (dotted path) for these settings.')
diff --git a/pykeg/core/models_test.py b/pykeg/core/models_test.py
index 0ff4ccdba..56960ce5b 100644
--- a/pykeg/core/models_test.py
+++ b/pykeg/core/models_test.py
@@ -1,4 +1,4 @@
-# Copyright 2014 Bevbot LLC, All Rights Reserved
+# Copyright 2014 Kegbot Project contributors
#
# This file is part of the Pykeg package of the Kegbot project.
# For more information on Pykeg or Kegbot, see http://kegbot.org/
diff --git a/pykeg/core/stats.py b/pykeg/core/stats.py
index 51ad3ef6d..d85ab3e59 100644
--- a/pykeg/core/stats.py
+++ b/pykeg/core/stats.py
@@ -1,4 +1,4 @@
-# Copyright 2014 Bevbot LLC, All Rights Reserved
+# Copyright 2014 Kegbot Project contributors
#
# This file is part of the Pykeg package of the Kegbot project.
# For more information on Pykeg or Kegbot, see http://kegbot.org/
diff --git a/pykeg/core/stats_test.py b/pykeg/core/stats_test.py
index f74590d54..ec53ae4bd 100644
--- a/pykeg/core/stats_test.py
+++ b/pykeg/core/stats_test.py
@@ -1,4 +1,4 @@
-# Copyright 2014 Bevbot LLC, All Rights Reserved
+# Copyright 2014 Kegbot Project contributors
#
# This file is part of the Pykeg package of the Kegbot project.
# For more information on Pykeg or Kegbot, see http://kegbot.org/
@@ -57,7 +57,7 @@ def setUp(self):
def testStuff(self):
site = models.KegbotSite.get()
stats = site.get_stats()
- self.assertEquals(stats, {})
+ self.assertEqual(stats, {})
now = make_datetime(2012, 1, 2, 12, 00)
self.maxDiff = None
@@ -155,24 +155,24 @@ def test_cancel_and_reassign(self):
pour_time=now)
drinks.append(d)
- self.assertEquals(600, self.users[0].get_stats().total_volume_ml)
- self.assertEquals(200, self.users[1].get_stats().total_volume_ml)
- self.assertEquals(200, self.users[2].get_stats().total_volume_ml)
+ self.assertEqual(600, self.users[0].get_stats().total_volume_ml)
+ self.assertEqual(200, self.users[1].get_stats().total_volume_ml)
+ self.assertEqual(200, self.users[2].get_stats().total_volume_ml)
- self.assertEquals(1000, models.KegbotSite.get().get_stats().total_volume_ml)
+ self.assertEqual(1000, models.KegbotSite.get().get_stats().total_volume_ml)
self.backend.cancel_drink(drinks[0])
- self.assertEquals(500, self.users[0].get_stats().total_volume_ml)
- self.assertEquals(200, self.users[1].get_stats().total_volume_ml)
- self.assertEquals(200, self.users[2].get_stats().total_volume_ml)
- self.assertEquals(900, models.KegbotSite.get().get_stats().total_volume_ml)
+ self.assertEqual(500, self.users[0].get_stats().total_volume_ml)
+ self.assertEqual(200, self.users[1].get_stats().total_volume_ml)
+ self.assertEqual(200, self.users[2].get_stats().total_volume_ml)
+ self.assertEqual(900, models.KegbotSite.get().get_stats().total_volume_ml)
self.backend.assign_drink(drinks[1], self.users[0])
- self.assertEquals(700, self.users[0].get_stats().total_volume_ml)
- self.assertEquals({}, self.users[1].get_stats())
- self.assertEquals(200, self.users[2].get_stats().total_volume_ml)
- self.assertEquals(900, models.KegbotSite.get().get_stats().total_volume_ml)
- self.assertEquals(900, drinks[1].session.get_stats().total_volume_ml)
+ self.assertEqual(700, self.users[0].get_stats().total_volume_ml)
+ self.assertEqual({}, self.users[1].get_stats())
+ self.assertEqual(200, self.users[2].get_stats().total_volume_ml)
+ self.assertEqual(900, models.KegbotSite.get().get_stats().total_volume_ml)
+ self.assertEqual(900, drinks[1].session.get_stats().total_volume_ml)
# Start a new session.
now = make_datetime(2013, 1, 2, 12, 00)
@@ -185,11 +185,11 @@ def test_cancel_and_reassign(self):
pour_time=now)
drinks.append(d)
- self.assertEquals(1300, self.users[0].get_stats().total_volume_ml)
- self.assertEquals(200, self.users[1].get_stats().total_volume_ml)
- self.assertEquals(400, self.users[2].get_stats().total_volume_ml)
- self.assertEquals(1900, models.KegbotSite.get().get_stats().total_volume_ml)
- self.assertEquals(1000, drinks[-1].session.get_stats().total_volume_ml)
+ self.assertEqual(1300, self.users[0].get_stats().total_volume_ml)
+ self.assertEqual(200, self.users[1].get_stats().total_volume_ml)
+ self.assertEqual(400, self.users[2].get_stats().total_volume_ml)
+ self.assertEqual(1900, models.KegbotSite.get().get_stats().total_volume_ml)
+ self.assertEqual(1000, drinks[-1].session.get_stats().total_volume_ml)
# Delete all stats for some intermediate drinks.
models.Stats.objects.filter(drink=drinks[-1]).delete()
@@ -200,8 +200,8 @@ def test_cancel_and_reassign(self):
drinks.append(d)
# Intermediate stats are generated.
- self.assertEquals(3011, models.KegbotSite.get().get_stats().total_volume_ml)
- self.assertEquals(2111, drinks[-1].session.get_stats().total_volume_ml)
+ self.assertEqual(3011, models.KegbotSite.get().get_stats().total_volume_ml)
+ self.assertEqual(2111, drinks[-1].session.get_stats().total_volume_ml)
def test_timezone_awareness(self):
site = models.KegbotSite.get()
@@ -227,10 +227,10 @@ def test_timezone_awareness(self):
volume_ml=volume_ml,
pour_time=now)
drinks.append(d)
- self.assertEquals('US/Pacific', d.session.timezone)
+ self.assertEqual('US/Pacific', d.session.timezone)
stats = site.get_stats()
# Assert that stats are recorded for Sunday (day = 0) rather than
# UTC's monday (day = 1).
- self.assertEquals({'0': 1000.0}, stats.volume_by_day_of_week)
- self.assertEquals(600, self.users[0].get_stats().total_volume_ml)
+ self.assertEqual({'0': 1000.0}, stats.volume_by_day_of_week)
+ self.assertEqual(600, self.users[0].get_stats().total_volume_ml)
diff --git a/pykeg/core/tasks.py b/pykeg/core/tasks.py
index 0e4e99349..93b504d51 100644
--- a/pykeg/core/tasks.py
+++ b/pykeg/core/tasks.py
@@ -1,4 +1,4 @@
-# Copyright 2014 Bevbot LLC, All Rights Reserved
+# Copyright 2014 Kegbot Project contributors
#
# This file is part of the Pykeg package of the Kegbot project.
# For more information on Pykeg or Kegbot, see http://kegbot.org/
diff --git a/pykeg/core/tests.py b/pykeg/core/tests.py
index 4ade4c514..7dfb1f0ce 100644
--- a/pykeg/core/tests.py
+++ b/pykeg/core/tests.py
@@ -1,4 +1,4 @@
-# Copyright 2014 Bevbot LLC, All Rights Reserved
+# Copyright 2014 Kegbot Project contributors
#
# This file is part of the Pykeg package of the Kegbot project.
# For more information on Pykeg or Kegbot, see http://kegbot.org/
diff --git a/pykeg/core/testutils.py b/pykeg/core/testutils.py
index 9951c8f48..cd2b8e216 100644
--- a/pykeg/core/testutils.py
+++ b/pykeg/core/testutils.py
@@ -1,4 +1,4 @@
-# Copyright 2014 Bevbot LLC, All Rights Reserved
+# Copyright 2014 Kegbot Project contributors
#
# This file is part of the Pykeg package of the Kegbot project.
# For more information on Pykeg or Kegbot, see http://kegbot.org/
diff --git a/pykeg/core/time_series.py b/pykeg/core/time_series.py
index c294de5d3..281c8473c 100644
--- a/pykeg/core/time_series.py
+++ b/pykeg/core/time_series.py
@@ -1,4 +1,4 @@
-# Copyright 2014 Bevbot LLC, All Rights Reserved
+# Copyright 2014 Kegbot Project contributors
#
# This file is part of the Pykeg package of the Kegbot project.
# For more information on Pykeg or Kegbot, see http://kegbot.org/
diff --git a/pykeg/core/util.py b/pykeg/core/util.py
index 5dc0b8d09..943fb6b65 100644
--- a/pykeg/core/util.py
+++ b/pykeg/core/util.py
@@ -1,4 +1,4 @@
-# Copyright 2014 Bevbot LLC, All Rights Reserved
+# Copyright 2014 Kegbot Project contributors
#
# This file is part of the Pykeg package of the Kegbot project.
# For more information on Pykeg or Kegbot, see http://kegbot.org/
@@ -80,10 +80,7 @@ def get_plugin_template_dirs(plugin_list):
pkg = pkgutil.get_loader(plugin_module)
if not pkg:
raise ImproperlyConfigured('Cannot find plugin "%s"' % plugin)
- if not hasattr(pkg, 'filename'):
- # TODO(mikey): Resolve breakage.
- continue
- template_dir = os.path.join(os.path.dirname(pkg.filename), 'templates')
+ template_dir = os.path.join(os.path.dirname(pkg.path), 'templates')
if os.path.isdir(template_dir):
if not six.PY3:
template_dir = template_dir.decode(fs_encoding)
diff --git a/pykeg/core/util_test.py b/pykeg/core/util_test.py
index 5e75f03cc..eaf648b34 100644
--- a/pykeg/core/util_test.py
+++ b/pykeg/core/util_test.py
@@ -1,4 +1,4 @@
-# Copyright 2014 Bevbot LLC, All Rights Reserved
+# Copyright 2014 Kegbot Project contributors
#
# This file is part of the Pykeg package of the Kegbot project.
# For more information on Pykeg or Kegbot, see http://kegbot.org/
diff --git a/pykeg/notification/__init__.py b/pykeg/notification/__init__.py
index 13ef5b736..85f5bc5de 100644
--- a/pykeg/notification/__init__.py
+++ b/pykeg/notification/__init__.py
@@ -1,4 +1,4 @@
-# Copyright 2014 Bevbot LLC, All Rights Reserved
+# Copyright 2014 Kegbot Project contributors
#
# This file is part of the Pykeg package of the Kegbot project.
# For more information on Pykeg or Kegbot, see http://kegbot.org/
diff --git a/pykeg/notification/backends/base.py b/pykeg/notification/backends/base.py
index d7d527d16..02894ac4e 100644
--- a/pykeg/notification/backends/base.py
+++ b/pykeg/notification/backends/base.py
@@ -1,4 +1,4 @@
-# Copyright 2014 Bevbot LLC, All Rights Reserved
+# Copyright 2014 Kegbot Project contributors
#
# This file is part of the Pykeg package of the Kegbot project.
# For more information on Pykeg or Kegbot, see http://kegbot.org/
@@ -19,7 +19,8 @@
"""Base notification module."""
-class BaseNotificationBackend:
+from builtins import object
+class BaseNotificationBackend(object):
"""Base class for notification backend implementations."""
def name(self):
raise NotImplementedError
diff --git a/pykeg/notification/backends/email.py b/pykeg/notification/backends/email.py
index 03570753a..2e09f3e16 100644
--- a/pykeg/notification/backends/email.py
+++ b/pykeg/notification/backends/email.py
@@ -1,4 +1,4 @@
-# Copyright 2014 Bevbot LLC, All Rights Reserved
+# Copyright 2014 Kegbot Project contributors
#
# This file is part of the Pykeg package of the Kegbot project.
# For more information on Pykeg or Kegbot, see http://kegbot.org/
diff --git a/pykeg/notification/backends/email_test.py b/pykeg/notification/backends/email_test.py
index a51522fbf..15b2bc728 100644
--- a/pykeg/notification/backends/email_test.py
+++ b/pykeg/notification/backends/email_test.py
@@ -1,4 +1,4 @@
-# Copyright 2014 Bevbot LLC, All Rights Reserved
+# Copyright 2014 Kegbot Project contributors
#
# This file is part of the Pykeg package of the Kegbot project.
# For more information on Pykeg or Kegbot, see http://kegbot.org/
@@ -29,7 +29,7 @@
@override_settings(KEGBOT_BACKEND='pykeg.core.testutils.TestBackend')
@override_settings(EMAIL_BACKEND='django.core.mail.backends.locmem.EmailBackend')
-@override_settings(EMAIL_FROM_ADDRESS='test-from@example')
+@override_settings(DEFAULT_FROM_EMAIL='test-from@example')
class EmailNotificationBackendTestCase(TestCase):
def setUp(self):
self.backend = get_kegbot_backend()
@@ -49,7 +49,7 @@ def setUp(self):
def test_keg_tapped(self):
self.prefs.keg_tapped = True
self.prefs.save()
- self.assertEquals(0, len(mail.outbox))
+ self.assertEqual(0, len(mail.outbox))
keg = self.backend.start_keg(
defaults.METER_NAME_0,
@@ -57,13 +57,13 @@ def test_keg_tapped(self):
beverage_type='beer',
producer_name='Unknown',
style_name='Unknown')
- self.assertEquals(1, len(mail.outbox))
+ self.assertEqual(1, len(mail.outbox))
msg = mail.outbox[0]
- self.assertEquals('[My Kegbot] New keg tapped: Keg %s: Unknown by Unknown' % keg.id,
+ self.assertEqual('[My Kegbot] New keg tapped: Keg %s: Unknown by Unknown' % keg.id,
msg.subject)
- self.assertEquals(['test@example'], msg.to)
- self.assertEquals('test-from@example', msg.from_email)
+ self.assertEqual(['test@example'], msg.to)
+ self.assertEqual('test-from@example', msg.from_email)
expected_body_plain = '''A new keg of Unknown by Unknown was just tapped on My Kegbot!
@@ -89,25 +89,25 @@ def test_keg_tapped(self):
http://localhost:1234/account.
''' % (keg.id,)
- self.assertEquals(1, len(msg.alternatives))
+ self.assertEqual(1, len(msg.alternatives))
self.assertMultiLineEqual(expected_body_html, msg.alternatives[0][0])
- self.assertEquals('text/html', msg.alternatives[0][1])
+ self.assertEqual('text/html', msg.alternatives[0][1])
def test_session_started(self):
self.prefs.session_started = True
self.prefs.save()
- self.assertEquals(0, len(mail.outbox))
+ self.assertEqual(0, len(mail.outbox))
self.backend.start_keg(defaults.METER_NAME_0, beverage_name='Unknown',
beverage_type='beer', producer_name='Unknown', style_name='Unknown')
drink = self.backend.record_drink(defaults.METER_NAME_0, ticks=500)
- self.assertEquals(1, len(mail.outbox))
+ self.assertEqual(1, len(mail.outbox))
msg = mail.outbox[0]
- self.assertEquals('[My Kegbot] A new session (session %s) has started.' % (
+ self.assertEqual('[My Kegbot] A new session (session %s) has started.' % (
drink.session.id,), msg.subject)
- self.assertEquals(['test@example'], msg.to)
- self.assertEquals('test-from@example', msg.from_email)
+ self.assertEqual(['test@example'], msg.to)
+ self.assertEqual('test-from@example', msg.from_email)
expected_body_plain = '''A new session was just kicked off on My Kegbot.
@@ -132,14 +132,14 @@ def test_session_started(self):
http://localhost:1234/account.
''' % (drink.session.id,)
- self.assertEquals(1, len(msg.alternatives))
+ self.assertEqual(1, len(msg.alternatives))
self.assertMultiLineEqual(expected_body_html, msg.alternatives[0][0])
- self.assertEquals('text/html', msg.alternatives[0][1])
+ self.assertEqual('text/html', msg.alternatives[0][1])
def test_keg_volume_low(self):
self.prefs.keg_volume_low = True
self.prefs.save()
- self.assertEquals(0, len(mail.outbox))
+ self.assertEqual(0, len(mail.outbox))
keg = self.backend.start_keg(
defaults.METER_NAME_0,
@@ -149,13 +149,13 @@ def test_keg_volume_low(self):
style_name='Unknown')
self.backend.record_drink(defaults.METER_NAME_0, ticks=500,
volume_ml=keg.full_volume_ml * (1 - kb_common.KEG_VOLUME_LOW_PERCENT))
- self.assertEquals(1, len(mail.outbox))
+ self.assertEqual(1, len(mail.outbox))
msg = mail.outbox[0]
- self.assertEquals('[My Kegbot] Volume low on keg %s (Unknown by Unknown)' % keg.id,
+ self.assertEqual('[My Kegbot] Volume low on keg %s (Unknown by Unknown)' % keg.id,
msg.subject)
- self.assertEquals(['test@example'], msg.to)
- self.assertEquals('test-from@example', msg.from_email)
+ self.assertEqual(['test@example'], msg.to)
+ self.assertEqual('test-from@example', msg.from_email)
expected_body_plain = '''Keg %s (Unknown by Unknown) is 15.0%% full.
@@ -180,14 +180,14 @@ def test_keg_volume_low(self):
http://localhost:1234/account.
''' % (keg.id, keg.id)
- self.assertEquals(1, len(msg.alternatives))
+ self.assertEqual(1, len(msg.alternatives))
self.assertMultiLineEqual(expected_body_html, msg.alternatives[0][0])
- self.assertEquals('text/html', msg.alternatives[0][1])
+ self.assertEqual('text/html', msg.alternatives[0][1])
def test_keg_ended(self):
self.prefs.keg_ended = True
self.prefs.save()
- self.assertEquals(0, len(mail.outbox))
+ self.assertEqual(0, len(mail.outbox))
keg = self.backend.start_keg(
defaults.METER_NAME_0,
@@ -195,14 +195,14 @@ def test_keg_ended(self):
beverage_type='beer',
producer_name='Unknown',
style_name='Unknown')
- self.assertEquals(0, len(mail.outbox))
+ self.assertEqual(0, len(mail.outbox))
self.backend.end_keg(keg)
- self.assertEquals(1, len(mail.outbox))
+ self.assertEqual(1, len(mail.outbox))
msg = mail.outbox[0]
- self.assertEquals('[My Kegbot] Keg ended: Keg %s: Unknown by Unknown' % keg.id, msg.subject)
- self.assertEquals(['test@example'], msg.to)
- self.assertEquals('test-from@example', msg.from_email)
+ self.assertEqual('[My Kegbot] Keg ended: Keg %s: Unknown by Unknown' % keg.id, msg.subject)
+ self.assertEqual(['test@example'], msg.to)
+ self.assertEqual('test-from@example', msg.from_email)
expected_body_plain = '''Keg %s of Unknown by Unknown was just finished on My Kegbot.
@@ -228,6 +228,6 @@ def test_keg_ended(self):
http://localhost:1234/account.
''' % (keg.id, keg.id)
- self.assertEquals(1, len(msg.alternatives))
+ self.assertEqual(1, len(msg.alternatives))
self.assertMultiLineEqual(expected_body_html, msg.alternatives[0][0])
- self.assertEquals('text/html', msg.alternatives[0][1])
+ self.assertEqual('text/html', msg.alternatives[0][1])
diff --git a/pykeg/notification/notification_test.py b/pykeg/notification/notification_test.py
index 37a4efa57..bf4e1040e 100644
--- a/pykeg/notification/notification_test.py
+++ b/pykeg/notification/notification_test.py
@@ -1,4 +1,4 @@
-# Copyright 2014 Bevbot LLC, All Rights Reserved
+# Copyright 2014 Kegbot Project contributors
#
# This file is part of the Pykeg package of the Kegbot project.
# For more information on Pykeg or Kegbot, see http://kegbot.org/
@@ -57,7 +57,7 @@ class StandaloneNotificationTestCase(TestCase):
])
def test_get_backends(self):
backends = notification.get_backends()
- self.assertEquals(2, len(backends))
+ self.assertEqual(2, len(backends))
self.assertIsInstance(backends[0], TestBackendA, 'Expected TestBackendA obj')
self.assertIsInstance(backends[1], TestBackendB, 'Expected TestBackendB obj')
@@ -92,7 +92,7 @@ def notify(self, event, user):
backends = [CaptureBackend()]
captured = CaptureBackend.captured
- self.assertEquals(0, len(captured))
+ self.assertEqual(0, len(captured))
prefs = models.NotificationSettings.objects.create(
user=self.user,
@@ -104,36 +104,36 @@ def notify(self, event, user):
event = SystemEvent(kind=SystemEvent.KEG_TAPPED)
notification.handle_single_event(event, backends)
- self.assertEquals(0, len(captured))
+ self.assertEqual(0, len(captured))
prefs.keg_tapped = True
prefs.save()
notification.handle_single_event(event, backends)
- self.assertEquals(1, len(captured))
+ self.assertEqual(1, len(captured))
del captured[:]
event = SystemEvent(kind=SystemEvent.SESSION_STARTED)
notification.handle_single_event(event, backends)
- self.assertEquals(0, len(captured))
+ self.assertEqual(0, len(captured))
prefs.session_started = True
prefs.save()
notification.handle_single_event(event, backends)
- self.assertEquals(1, len(captured))
+ self.assertEqual(1, len(captured))
del captured[:]
event = SystemEvent(kind=SystemEvent.KEG_ENDED)
notification.handle_single_event(event, backends)
- self.assertEquals(0, len(captured))
+ self.assertEqual(0, len(captured))
prefs.keg_ended = True
prefs.save()
notification.handle_single_event(event, backends)
- self.assertEquals(1, len(captured))
+ self.assertEqual(1, len(captured))
del captured[:]
event = SystemEvent(kind=SystemEvent.KEG_VOLUME_LOW)
notification.handle_single_event(event, backends)
- self.assertEquals(0, len(captured))
+ self.assertEqual(0, len(captured))
prefs.keg_volume_low = True
prefs.save()
notification.handle_single_event(event, backends)
- self.assertEquals(1, len(captured))
+ self.assertEqual(1, len(captured))
del captured[:]
diff --git a/pykeg/plugin/datastore.py b/pykeg/plugin/datastore.py
index 6b0a9a1b4..a33352561 100644
--- a/pykeg/plugin/datastore.py
+++ b/pykeg/plugin/datastore.py
@@ -1,4 +1,4 @@
-# Copyright 2014 Bevbot LLC, All Rights Reserved
+# Copyright 2014 Kegbot Project contributors
#
# This file is part of the Pykeg package of the Kegbot project.
# For more information on Pykeg or Kegbot, see http://kegbot.org/
diff --git a/pykeg/plugin/datastore_test.py b/pykeg/plugin/datastore_test.py
index 5938107d4..7867cbd88 100644
--- a/pykeg/plugin/datastore_test.py
+++ b/pykeg/plugin/datastore_test.py
@@ -1,4 +1,4 @@
-# Copyright 2014 Bevbot LLC, All Rights Reserved
+# Copyright 2014 Kegbot Project contributors
#
# This file is part of the Pykeg package of the Kegbot project.
# For more information on Pykeg or Kegbot, see http://kegbot.org/
diff --git a/pykeg/plugin/plugin.py b/pykeg/plugin/plugin.py
index 78c51841f..1ed806729 100644
--- a/pykeg/plugin/plugin.py
+++ b/pykeg/plugin/plugin.py
@@ -1,4 +1,4 @@
-# Copyright 2014 Bevbot LLC, All Rights Reserved
+# Copyright 2014 Kegbot Project contributors
#
# This file is part of the Pykeg package of the Kegbot project.
# For more information on Pykeg or Kegbot, see http://kegbot.org/
diff --git a/pykeg/plugin/util.py b/pykeg/plugin/util.py
index 10e802d35..7c6235ccc 100644
--- a/pykeg/plugin/util.py
+++ b/pykeg/plugin/util.py
@@ -1,4 +1,4 @@
-# Copyright 2014 Bevbot LLC, All Rights Reserved
+# Copyright 2014 Kegbot Project contributors
#
# This file is part of the Pykeg package of the Kegbot project.
# For more information on Pykeg or Kegbot, see http://kegbot.org/
diff --git a/pykeg/proto/protolib.py b/pykeg/proto/protolib.py
index e4be16e9c..ce60f945f 100644
--- a/pykeg/proto/protolib.py
+++ b/pykeg/proto/protolib.py
@@ -1,4 +1,4 @@
-# Copyright 2014 Bevbot LLC, All Rights Reserved
+# Copyright 2014 Kegbot Project contributors
#
# This file is part of the Pykeg package of the Kegbot project.
# For more information on Pykeg or Kegbot, see http://kegbot.org/
diff --git a/pykeg/settings.py b/pykeg/settings.py
index 06f9b3a7c..969db49b4 100644
--- a/pykeg/settings.py
+++ b/pykeg/settings.py
@@ -36,6 +36,7 @@
'pykeg.web.kegweb',
'pykeg.web.setup_wizard',
+ 'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.humanize',
@@ -275,7 +276,7 @@
# E-mail
EMAIL_BACKEND = 'django.core.mail.backends.dummy.EmailBackend'
-EMAIL_FROM_ADDRESS = ''
+DEFAULT_FROM_EMAIL = KEGBOT['KEGBOT_EMAIL_FROM_ADDRESS']
EMAIL_SUBJECT_PREFIX = ''
# Imagekit
@@ -310,9 +311,3 @@
# Override any user-specified timezone: As of Kegbot 0.9.12, this is
# specified in site settings.
TIME_ZONE = 'UTC'
-
-# Update email addresses.
-DEFAULT_FROM_EMAIL = EMAIL_FROM_ADDRESS
-
-if KEGBOT_ENABLE_ADMIN:
- INSTALLED_APPS += ('django.contrib.admin',)
diff --git a/pykeg/util/bugreport.py b/pykeg/util/bugreport.py
index 310620a23..a027a5bd6 100644
--- a/pykeg/util/bugreport.py
+++ b/pykeg/util/bugreport.py
@@ -1,5 +1,5 @@
from __future__ import print_function
-# Copyright 2014 Bevbot LLC, All Rights Reserved
+# Copyright 2014 Kegbot Project contributors
#
# This file is part of the Pykeg package of the Kegbot project.
# For more information on Pykeg or Kegbot, see http://kegbot.org/
diff --git a/pykeg/util/email.py b/pykeg/util/email.py
index e50d28b08..2c9a04984 100644
--- a/pykeg/util/email.py
+++ b/pykeg/util/email.py
@@ -1,4 +1,4 @@
-# Copyright 2014 Bevbot LLC, All Rights Reserved
+# Copyright 2014 Kegbot Project contributors
#
# This file is part of the Pykeg package of the Kegbot project.
# For more information on Pykeg or Kegbot, see http://kegbot.org/
@@ -31,9 +31,9 @@
def build_message(to_address, template_name, context):
- from_address = getattr(settings, 'EMAIL_FROM_ADDRESS', None)
+ from_address = getattr(settings, 'DEFAULT_FROM_EMAIL', None)
if not from_address:
- logger.error('EMAIL_FROM_ADDRESS is not available; aborting!')
+ logger.error('DEFAULT_FROM_EMAIL is not available; aborting!')
return None
template = get_template(template_name)
diff --git a/pykeg/util/email_test.py b/pykeg/util/email_test.py
index 01e7eff68..aa99bede6 100644
--- a/pykeg/util/email_test.py
+++ b/pykeg/util/email_test.py
@@ -1,4 +1,4 @@
-# Copyright 2015 Bevbot LLC, All Rights Reserved
+# Copyright 2015 Kegbot Project contributors
#
# This file is part of the Pykeg package of the Kegbot project.
# For more information on Pykeg or Kegbot, see http://kegbot.org/
diff --git a/pykeg/util/runner.py b/pykeg/util/runner.py
index 9a31b4e03..15d8e1666 100644
--- a/pykeg/util/runner.py
+++ b/pykeg/util/runner.py
@@ -1,4 +1,4 @@
-# Copyright 2014 Bevbot LLC
+# Copyright 2014 Kegbot Project contributors
#
# This file is part of the Pykeg package of the Kegbot project.
# For more information on Pykeg or Kegbot, see http://kegbot.org/
diff --git a/pykeg/web/account/urls.py b/pykeg/web/account/urls.py
index dd3551a24..e2219b424 100644
--- a/pykeg/web/account/urls.py
+++ b/pykeg/web/account/urls.py
@@ -1,15 +1,18 @@
from django.conf.urls import url
from pykeg.plugin import util
-from pykeg.web.account.views import password_change
-from pykeg.web.account.views import password_change_done
from pykeg.web.account import views
+from django.contrib.auth.views import (
+ PasswordChangeView,
+ PasswordChangeDoneView,
+)
+
urlpatterns = [
url(r'^$', views.account_main, name='kb-account-main'),
url(r'^activate/(?P[0-9a-zA-Z]+)/$', views.activate_account, name='activate-account'),
- url(r'^password/done/$', password_change_done, name='password_change_done'),
- url(r'^password/$', password_change, name='password_change'),
+ url(r'^password/done/$', PasswordChangeDoneView.as_view(), name='password_change_done'),
+ url(r'^password/$', PasswordChangeView.as_view(), name='password_change'),
url(r'^profile/$', views.edit_profile, name='account-profile'),
url(r'^invite/$', views.invite, name='account-invite'),
url(r'^confirm-email/(?P.+)$', views.confirm_email, name='account-confirm-email'),
diff --git a/pykeg/web/account/views.py b/pykeg/web/account/views.py
index 25564cadb..6735997f6 100644
--- a/pykeg/web/account/views.py
+++ b/pykeg/web/account/views.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python
#
-# Copyright 2014 Bevbot LLC, All Rights Reserved
+# Copyright 2014 Kegbot Project contributors
#
# This file is part of the Pykeg package of the Kegbot project.
# For more information on Pykeg or Kegbot, see http://kegbot.org/
@@ -25,13 +25,11 @@
from django.contrib.auth import login as auth_login
from django.contrib.auth import authenticate
from django.contrib.auth.decorators import login_required
-from django.core.urlresolvers import reverse
+from django.urls import reverse
from django.shortcuts import render
from django.shortcuts import redirect
from django.views.decorators.cache import never_cache
from django.views.decorators.http import require_POST
-from django.contrib.auth.views import password_change as password_change_orig
-from django.contrib.auth.views import password_change_done as password_change_done_orig
from pykeg.core import models
from pykeg.util import email
@@ -198,16 +196,6 @@ def regenerate_api_key(request):
return redirect('kb-account-main')
-def password_change(request, *args, **kwargs):
- kwargs['template_name'] = 'account/password_change.html'
- kwargs['post_change_redirect'] = reverse('password_change_done')
- return password_change_orig(request, *args, **kwargs)
-
-
-def password_change_done(request):
- return password_change_done_orig(request, 'account/password_change_done.html')
-
-
@login_required
def plugin_settings(request, plugin_name):
plugin = request.plugins.get(plugin_name, None)
diff --git a/pykeg/web/api/api_test.py b/pykeg/web/api/api_test.py
index fb79e8bde..dc54f7ee3 100644
--- a/pykeg/web/api/api_test.py
+++ b/pykeg/web/api/api_test.py
@@ -1,4 +1,4 @@
-# Copyright 2014 Bevbot LLC, All Rights Reserved
+# Copyright 2014 Kegbot Project contributors
#
# This file is part of the Pykeg package of the Kegbot project.
# For more information on Pykeg or Kegbot, see http://kegbot.org/
@@ -20,7 +20,7 @@
from builtins import str
from django.core import mail
-from django.core.urlresolvers import reverse
+from django.urls import reverse
from django.test import TransactionTestCase
from django.test.utils import override_settings
from pykeg.core import models
@@ -227,7 +227,7 @@ def test_record_drink_usernames(self):
self.assertEqual(data.meta.result, 'ok')
@override_settings(EMAIL_BACKEND='django.core.mail.backends.locmem.EmailBackend')
- @override_settings(EMAIL_FROM_ADDRESS='test-from@example')
+ @override_settings(DEFAULT_FROM_EMAIL='test-from@example')
def test_registration(self):
response, data = self.post(
'new-user/', data={'username': 'newuser', 'email': 'foo@example.com'})
diff --git a/pykeg/web/api/devicelink.py b/pykeg/web/api/devicelink.py
index 2e8045e9c..193f8de17 100644
--- a/pykeg/web/api/devicelink.py
+++ b/pykeg/web/api/devicelink.py
@@ -1,4 +1,4 @@
-# Copyright 2014 Bevbot LLC, All Rights Reserved
+# Copyright 2014 Kegbot Project contributors
#
# This file is part of the Pykeg package of the Kegbot project.
# For more information on Pykeg or Kegbot, see http://kegbot.org/
diff --git a/pykeg/web/api/devicelink_test.py b/pykeg/web/api/devicelink_test.py
index 4998c50af..6df3171ff 100644
--- a/pykeg/web/api/devicelink_test.py
+++ b/pykeg/web/api/devicelink_test.py
@@ -1,4 +1,4 @@
-# Copyright 2014 Bevbot LLC, All Rights Reserved
+# Copyright 2014 Kegbot Project contributors
#
# This file is part of the Pykeg package of the Kegbot project.
# For more information on Pykeg or Kegbot, see http://kegbot.org/
diff --git a/pykeg/web/api/forms.py b/pykeg/web/api/forms.py
index 08f7eb280..1498396f6 100644
--- a/pykeg/web/api/forms.py
+++ b/pykeg/web/api/forms.py
@@ -1,4 +1,4 @@
-# Copyright 2014 Bevbot LLC, All Rights Reserved
+# Copyright 2014 Kegbot Project contributors
#
# This file is part of the Pykeg package of the Kegbot project.
# For more information on Pykeg or Kegbot, see http://kegbot.org/
diff --git a/pykeg/web/api/middleware.py b/pykeg/web/api/middleware.py
index ef77fe5b0..4fb949bbf 100644
--- a/pykeg/web/api/middleware.py
+++ b/pykeg/web/api/middleware.py
@@ -1,4 +1,4 @@
-# Copyright 2014 Bevbot LLC, All Rights Reserved
+# Copyright 2014 Kegbot Project contributors
#
# This file is part of the Pykeg package of the Kegbot project.
# For more information on Pykeg or Kegbot, see http://kegbot.org/
@@ -82,7 +82,7 @@ def process_view(self, request, view_func, view_args, view_kwargs):
else:
# API request to non-whitelisted path, in non-public site privacy mode.
# Demand API key.
- if privacy == 'members' and not request.user.is_authenticated():
+ if privacy == 'members' and not request.user.is_authenticated:
need_auth = True
elif privacy == 'staff' and not request.user.is_staff:
need_auth = True
diff --git a/pykeg/web/api/urls.py b/pykeg/web/api/urls.py
index 84b179f24..91de0d37d 100644
--- a/pykeg/web/api/urls.py
+++ b/pykeg/web/api/urls.py
@@ -1,4 +1,4 @@
-# Copyright 2014 Bevbot LLC, All Rights Reserved
+# Copyright 2014 Kegbot Project contributors
#
# This file is part of the Pykeg package of the Kegbot project.
# For more information on Pykeg or Kegbot, see http://kegbot.org/
diff --git a/pykeg/web/api/util.py b/pykeg/web/api/util.py
index 17a0ebd65..9f07ac14c 100644
--- a/pykeg/web/api/util.py
+++ b/pykeg/web/api/util.py
@@ -1,4 +1,4 @@
-# Copyright 2014 Bevbot LLC, All Rights Reserved
+# Copyright 2014 Kegbot Project contributors
#
# This file is part of the Pykeg package of the Kegbot project.
# For more information on Pykeg or Kegbot, see http://kegbot.org/
diff --git a/pykeg/web/api/views.py b/pykeg/web/api/views.py
index 378d00ddd..61dc05bee 100644
--- a/pykeg/web/api/views.py
+++ b/pykeg/web/api/views.py
@@ -1,4 +1,4 @@
-# Copyright 2014 Bevbot LLC, All Rights Reserved
+# Copyright 2014 Kegbot Project contributors
#
# This file is part of the Pykeg package of the Kegbot project.
# For more information on Pykeg or Kegbot, see http://kegbot.org/
@@ -313,7 +313,7 @@ def get_keg_sizes(request):
# Deprecated endpoint.
ret = []
fake_id = 0
- for size_name, volume_ml in keg_sizes.VOLUMES_ML.items():
+ for size_name, volume_ml in list(keg_sizes.VOLUMES_ML.items()):
ret.append({
'volume_ml': volume_ml,
'id': fake_id,
diff --git a/pykeg/web/auth/__init__.py b/pykeg/web/auth/__init__.py
index 317548db1..938677448 100644
--- a/pykeg/web/auth/__init__.py
+++ b/pykeg/web/auth/__init__.py
@@ -1,4 +1,4 @@
-# Copyright 2014 Bevbot LLC, All Rights Reserved
+# Copyright 2014 Kegbot Project contributors
#
# This file is part of the Pykeg package of the Kegbot project.
# For more information on Pykeg or Kegbot, see http://kegbot.org/
diff --git a/pykeg/web/auth/local.py b/pykeg/web/auth/local.py
index 002570e09..8a43d441a 100644
--- a/pykeg/web/auth/local.py
+++ b/pykeg/web/auth/local.py
@@ -1,4 +1,4 @@
-# Copyright 2014 Bevbot LLC, All Rights Reserved
+# Copyright 2014 Kegbot Project contributors
#
# This file is part of the Pykeg package of the Kegbot project.
# For more information on Pykeg or Kegbot, see http://kegbot.org/
diff --git a/pykeg/web/charts/charts.py b/pykeg/web/charts/charts.py
index 0a416595d..71ce0cb4c 100644
--- a/pykeg/web/charts/charts.py
+++ b/pykeg/web/charts/charts.py
@@ -1,4 +1,4 @@
-# Copyright 2014 Bevbot LLC, All Rights Reserved
+# Copyright 2014 Kegbot Project contributors
#
# This file is part of the Pykeg package of the Kegbot project.
# For more information on Pykeg or Kegbot, see http://kegbot.org/
@@ -122,7 +122,7 @@ def chart_volume_by_weekday(stats, *args, **kwargs):
if not volmap:
raise ChartError('Daily volumes unavailable')
- for weekday, volume_ml in vols.items():
+ for weekday, volume_ml in list(vols.items()):
volmap[int(weekday)] += format_volume(volume_ml, kwargs)[0]
return _weekday_chart_common(volmap)
@@ -130,7 +130,7 @@ def chart_volume_by_weekday(stats, *args, **kwargs):
def chart_sessions_by_weekday(stats, *args, **kwargs):
data = stats.get('volume_by_day_of_week', {})
weekdays = [0] * 7
- for weekday, volume_ml in data.items():
+ for weekday, volume_ml in list(data.items()):
weekdays[int(weekday)] += format_volume(volume_ml, kwargs)[0]
return _weekday_chart_common(weekdays)
@@ -177,7 +177,7 @@ def chart_users_by_volume(stats, *args, **kwargs):
raise ChartError('no data')
data = []
- for username, volume in vols.items():
+ for username, volume in list(vols.items()):
if not username:
username = 'Guest'
volume, units = format_volume(volume, kwargs)
diff --git a/pykeg/web/kbregistration/forms.py b/pykeg/web/kbregistration/forms.py
index e90365cef..1919b0056 100644
--- a/pykeg/web/kbregistration/forms.py
+++ b/pykeg/web/kbregistration/forms.py
@@ -1,4 +1,4 @@
-# Copyright 2014 Bevbot LLC, All Rights Reserved
+# Copyright 2014 Kegbot Project contributors
#
# This file is part of the Pykeg package of the Kegbot project.
# For more information on Pykeg or Kegbot, see http://kegbot.org/
@@ -79,7 +79,7 @@ def save(self, domain_override=None,
# a password marked as unusable
if not user.has_usable_password():
continue
- from_email = getattr(settings, 'EMAIL_FROM_ADDRESS', from_email)
+ from_email = settings.DEFAULT_FROM_EMAIL or from_email
be = get_kegbot_backend()
base_url = be.get_base_url()
diff --git a/pykeg/web/kbregistration/registration_test.py b/pykeg/web/kbregistration/registration_test.py
index 6aba34e61..553f880b6 100644
--- a/pykeg/web/kbregistration/registration_test.py
+++ b/pykeg/web/kbregistration/registration_test.py
@@ -1,4 +1,4 @@
-# Copyright 2014 Bevbot LLC, All Rights Reserved
+# Copyright 2014 Kegbot Project contributors
#
# This file is part of the Pykeg package of the Kegbot project.
# For more information on Pykeg or Kegbot, see http://kegbot.org/
@@ -39,19 +39,20 @@ def setUp(self):
self.user.save()
@override_settings(EMAIL_BACKEND='django.core.mail.backends.locmem.EmailBackend')
- @override_settings(EMAIL_FROM_ADDRESS='test-from@example')
+ @override_settings(DEFAULT_FROM_EMAIL='test-from@example')
def test_notifications(self):
response = self.client.get('/accounts/password/reset/')
self.assertContains(response, "Reset Password", status_code=200)
- self.assertEquals(0, len(mail.outbox))
+ self.assertEqual(0, len(mail.outbox))
response = self.client.post('/accounts/password/reset/', data={'email': 'test@example.com'},
follow=True)
self.assertContains(response, 'E-Mail Sent', status_code=200)
- self.assertEquals(1, len(mail.outbox))
+ self.assertEqual(1, len(mail.outbox))
msg = mail.outbox[0]
- self.assertEquals('Password reset on My Kegbot', msg.subject)
- self.assertEquals(['test@example.com'], msg.to)
- self.assertEquals('test-from@example', msg.from_email)
+ # TODO(mikey): Customize subject with `kbsite.title`
+ self.assertEqual('Password reset', msg.subject)
+ self.assertEqual(['test@example.com'], msg.to)
+ self.assertEqual('test-from@example', msg.from_email)
diff --git a/pykeg/web/kbregistration/urls.py b/pykeg/web/kbregistration/urls.py
index 3efbec2ed..80a418571 100644
--- a/pykeg/web/kbregistration/urls.py
+++ b/pykeg/web/kbregistration/urls.py
@@ -1,32 +1,39 @@
from django.conf.urls import include
from django.conf.urls import url
-from django.contrib.auth import views as auth_views
from pykeg.web.kbregistration.forms import PasswordResetForm
from pykeg.web.kbregistration import views
+from django.contrib.auth.views import (
+ PasswordResetView,
+ PasswordResetConfirmView,
+ PasswordResetDoneView,
+ PasswordResetCompleteView,
+ PasswordChangeView,
+ PasswordChangeDoneView,
+)
urlpatterns = [
url(r'^register/?$',
views.register,
name='registration_register'),
url(r'^password/change/$',
- auth_views.password_change,
+ PasswordChangeView.as_view(),
name='password_change'),
url(r'^password/change/done/$',
- auth_views.password_change_done,
+ PasswordChangeDoneView.as_view(),
name='password_change_done'),
url(r'^password/reset/$',
- auth_views.password_reset,
+ PasswordResetView.as_view(),
kwargs={'password_reset_form': PasswordResetForm},
name='password_reset'),
url(r'^password/reset/done/$',
- auth_views.password_reset_done,
+ PasswordResetDoneView.as_view(),
name='password_reset_done'),
url(r'^password/reset/complete/$',
- auth_views.password_reset_complete,
+ PasswordResetCompleteView.as_view(),
name='password_reset_complete'),
url(r'^password/reset/confirm/(?P[0-9A-Za-z]+)-(?P.+)/$',
- auth_views.password_reset_confirm,
+ PasswordResetConfirmView.as_view(),
name='password_reset_confirm'),
- url('', include('registration.auth_urls')),
+ url('', include('django.contrib.auth.urls')),
]
diff --git a/pykeg/web/kbregistration/views.py b/pykeg/web/kbregistration/views.py
index f63bbdc6f..cb6e820d9 100644
--- a/pykeg/web/kbregistration/views.py
+++ b/pykeg/web/kbregistration/views.py
@@ -1,4 +1,4 @@
-# Copyright 2014 Bevbot LLC, All Rights Reserved
+# Copyright 2014 Kegbot Project contributors
#
# This file is part of the Pykeg package of the Kegbot project.
# For more information on Pykeg or Kegbot, see http://kegbot.org/
diff --git a/pykeg/web/kegadmin/templates/kegadmin/dashboard.html b/pykeg/web/kegadmin/templates/kegadmin/dashboard.html
index 289c4146a..752001886 100644
--- a/pykeg/web/kegadmin/templates/kegadmin/dashboard.html
+++ b/pykeg/web/kegadmin/templates/kegadmin/dashboard.html
@@ -38,8 +38,7 @@ Warning: Debug Mode
Warning: E-Mail Configuration Problem
E-mail is not properly configured; no mails will be sent. Please
read the docs
- for more information (hint: set EMAIL_BACKEND
and
- EMAIL_FROM_ADDRESS
in local_settings.py
).
+ for more information.
{% endif %}
diff --git a/pykeg/web/kegadmin/templates/kegadmin/email.html b/pykeg/web/kegadmin/templates/kegadmin/email.html
index 415fd9994..4d277baee 100644
--- a/pykeg/web/kegadmin/templates/kegadmin/email.html
+++ b/pykeg/web/kegadmin/templates/kegadmin/email.html
@@ -11,8 +11,7 @@
Warning!
E-mail is not properly configured; no mails will be sent. Please
read the docs
- for more information (hint: set EMAIL_BACKEND
and
- EMAIL_FROM_ADDRESS
in local_settings.py
).
+ for more information.
{% else %}
Test E-mail Configuration
diff --git a/pykeg/web/kegadmin/views.py b/pykeg/web/kegadmin/views.py
index 4137e234d..2590ec750 100644
--- a/pykeg/web/kegadmin/views.py
+++ b/pykeg/web/kegadmin/views.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python
#
-# Copyright 2014 Bevbot LLC, All Rights Reserved
+# Copyright 2014 Kegbot Project contributors
#
# This file is part of the Pykeg package of the Kegbot project.
# For more information on Pykeg or Kegbot, see http://kegbot.org/
@@ -68,7 +68,7 @@ def dashboard(request):
email_backend = getattr(settings, 'EMAIL_BACKEND', None)
email_configured = email_backend and email_backend != 'django.core.mail.backends.dummy.EmailBackend'
- email_configured = email_configured and bool(getattr(settings, 'EMAIL_FROM_ADDRESS', None))
+ email_configured = email_configured and settings.DEFAULT_FROM_EMAIL
context['email_configured'] = email_configured
@@ -168,7 +168,7 @@ def email(request):
email_backend = getattr(settings, 'EMAIL_BACKEND', None)
email_configured = email_backend and email_backend != 'django.core.mail.backends.dummy.EmailBackend'
- email_configured = email_configured and bool(getattr(settings, 'EMAIL_FROM_ADDRESS', None))
+ email_configured = email_configured and settings.DEFAULT_FROM_EMAIL
if request.method == 'POST':
if 'send_test_email' in request.POST:
@@ -259,14 +259,14 @@ def workers(request):
if not pings and 'error' not in context:
context['error'] = 'No response from workers. Not running?'
else:
- for k, v in pings.items():
+ for k, v in list(pings.items()):
status[k] = {
'status': 'ok' if v.get('ok') else 'unknown',
}
- for k, v in stats.items():
+ for k, v in list(stats.items()):
if k in status:
status[k]['stats'] = v
- for k, v in queues.items():
+ for k, v in list(queues.items()):
if k in status:
status[k]['active_queues'] = v
diff --git a/pykeg/web/kegweb/kbstorage.py b/pykeg/web/kegweb/kbstorage.py
index 2201ca7fa..b8c2eac1b 100644
--- a/pykeg/web/kegweb/kbstorage.py
+++ b/pykeg/web/kegweb/kbstorage.py
@@ -1,4 +1,4 @@
-# Copyright 2014 Bevbot LLC, All Rights Reserved
+# Copyright 2014 Kegbot Project contributors
#
# This file is part of the Pykeg package of the Kegbot project.
# For more information on Pykeg or Kegbot, see http://kegbot.org/
diff --git a/pykeg/web/kegweb/kegweb_test.py b/pykeg/web/kegweb/kegweb_test.py
index ed41c42a7..3b2fce639 100644
--- a/pykeg/web/kegweb/kegweb_test.py
+++ b/pykeg/web/kegweb/kegweb_test.py
@@ -1,4 +1,4 @@
-# Copyright 2014 Bevbot LLC, All Rights Reserved
+# Copyright 2014 Kegbot Project contributors
#
# This file is part of the Pykeg package of the Kegbot project.
# For more information on Pykeg or Kegbot, see http://kegbot.org/
@@ -22,7 +22,7 @@
from django.core import mail
from django.test import TransactionTestCase
from django.test.utils import override_settings
-from django.core.urlresolvers import reverse
+from django.urls import reverse
from pykeg.backend import get_kegbot_backend
from pykeg.core import models
@@ -38,18 +38,18 @@ def setUp(self):
def testBasicEndpoints(self):
for endpoint in ('/kegs/', '/stats/', '/drinkers/guest/', '/drinkers/guest/sessions/'):
response = self.client.get(endpoint)
- self.assertEquals(200, response.status_code)
+ self.assertEqual(200, response.status_code)
for endpoint in ('/sessions/',):
response = self.client.get(endpoint)
- self.assertEquals(404, response.status_code)
+ self.assertEqual(404, response.status_code)
b = get_kegbot_backend()
keg = b.start_keg('kegboard.flow0', beverage_name='Unknown', producer_name='Unknown',
beverage_type='beer', style_name='Unknown')
self.assertIsNotNone(keg)
response = self.client.get('/kegs/')
- self.assertEquals(200, response.status_code)
+ self.assertEqual(200, response.status_code)
d = b.record_drink('kegboard.flow0', ticks=100)
drink_id = d.id
@@ -86,7 +86,7 @@ def test_privacy(self):
}
def test_urls(expect_fail, urls=urls):
- for url, expected_content in urls.items():
+ for url, expected_content in list(urls.items()):
response = self.client.get(url)
if expect_fail:
self.assertNotContains(response, expected_content, status_code=401,
@@ -178,7 +178,7 @@ def test_activation(self):
self.assertIsNone(user.activation_key)
@override_settings(EMAIL_BACKEND='django.core.mail.backends.locmem.EmailBackend')
- @override_settings(EMAIL_FROM_ADDRESS='test-from@example')
+ @override_settings(DEFAULT_FROM_EMAIL='test-from@example')
def test_registration(self):
kbsite = models.KegbotSite.get()
self.assertEqual('public', kbsite.privacy)
@@ -234,7 +234,7 @@ def test_registration(self):
status_code=200)
@override_settings(EMAIL_BACKEND='django.core.mail.backends.locmem.EmailBackend')
- @override_settings(EMAIL_FROM_ADDRESS='test-from@example')
+ @override_settings(DEFAULT_FROM_EMAIL='test-from@example')
def test_registration_with_invite(self):
kbsite = models.KegbotSite.get()
kbsite.registration_mode = 'staff-invite-online'
diff --git a/pykeg/web/kegweb/signals.py b/pykeg/web/kegweb/signals.py
index f7c2335c1..b34b61e11 100644
--- a/pykeg/web/kegweb/signals.py
+++ b/pykeg/web/kegweb/signals.py
@@ -1,4 +1,4 @@
-# Copyright 2014 Bevbot LLC, All Rights Reserved
+# Copyright 2014 Kegbot Project contributors
#
# This file is part of the Pykeg package of the Kegbot project.
# For more information on Pykeg or Kegbot, see http://kegbot.org/
diff --git a/pykeg/web/kegweb/templatetags/kegweblib.py b/pykeg/web/kegweb/templatetags/kegweblib.py
index 86a4fefff..a28637ebf 100644
--- a/pykeg/web/kegweb/templatetags/kegweblib.py
+++ b/pykeg/web/kegweb/templatetags/kegweblib.py
@@ -1,4 +1,4 @@
-# Copyright 2014 Bevbot LLC, All Rights Reserved
+# Copyright 2014 Kegbot Project contributors
#
# This file is part of the Pykeg package of the Kegbot project.
# For more information on Pykeg or Kegbot, see http://kegbot.org/
@@ -16,10 +16,11 @@
# You should have received a copy of the GNU General Public License
# along with Pykeg. If not, see .
+from builtins import str
import pytz
from django.conf import settings
-from django.core.urlresolvers import reverse
+from django.urls import reverse
from django.template import Library
from django.template import Node
from django.template import VariableDoesNotExist
@@ -394,7 +395,7 @@ def render(self, context):
}
chart_data = chart_base
- for k, v in chart_result.items():
+ for k, v in list(chart_result.items()):
if k not in chart_data:
chart_data[k] = v
elif isinstance(v, dict):
diff --git a/pykeg/web/kegweb/views.py b/pykeg/web/kegweb/views.py
index 58a843820..1ae86b1d8 100644
--- a/pykeg/web/kegweb/views.py
+++ b/pykeg/web/kegweb/views.py
@@ -1,4 +1,4 @@
-# Copyright 2014 Bevbot LLC, All Rights Reserved
+# Copyright 2014 Kegbot Project contributors
#
# This file is part of the Pykeg package of the Kegbot project.
# For more information on Pykeg or Kegbot, see http://kegbot.org/
@@ -65,7 +65,7 @@ def system_stats(request):
}
top_drinkers = []
- for username, vol in stats.get('volume_by_drinker', {}).items():
+ for username, vol in list(stats.get('volume_by_drinker', {}).items()):
try:
user = models.User.objects.get(username=username)
except models.User.DoesNotExist:
diff --git a/pykeg/web/middleware.py b/pykeg/web/middleware.py
index 93b604bf5..ac92aa8e3 100644
--- a/pykeg/web/middleware.py
+++ b/pykeg/web/middleware.py
@@ -1,4 +1,4 @@
-# Copyright 2014 Bevbot LLC, All Rights Reserved
+# Copyright 2014 Kegbot Project contributors
#
# This file is part of the Pykeg package of the Kegbot project.
# For more information on Pykeg or Kegbot, see http://kegbot.org/
@@ -176,7 +176,7 @@ def process_view(self, request, view_func, view_args, view_kwargs):
return render(request, 'kegweb/staff_only.html', status=401)
return None
elif privacy == 'members':
- if not request.user.is_authenticated() or not request.user.is_active:
+ if not request.user.is_authenticated or not request.user.is_active:
return render(request, 'kegweb/members_only.html', status=401)
return None
diff --git a/pykeg/web/setup_wizard/forms.py b/pykeg/web/setup_wizard/forms.py
index e7cbae784..7791d0977 100644
--- a/pykeg/web/setup_wizard/forms.py
+++ b/pykeg/web/setup_wizard/forms.py
@@ -1,4 +1,4 @@
-# Copyright 2014 Bevbot LLC, All Rights Reserved
+# Copyright 2014 Kegbot Project contributors
#
# This file is part of the Pykeg package of the Kegbot project.
# For more information on Pykeg or Kegbot, see http://kegbot.org/
diff --git a/pykeg/web/setup_wizard/setup_wizard_tests.py b/pykeg/web/setup_wizard/setup_wizard_tests.py
index 5a44373f6..619c0fa5d 100644
--- a/pykeg/web/setup_wizard/setup_wizard_tests.py
+++ b/pykeg/web/setup_wizard/setup_wizard_tests.py
@@ -1,4 +1,4 @@
-# Copyright 2014 Bevbot LLC, All Rights Reserved
+# Copyright 2014 Kegbot Project contributors
#
# This file is part of the Pykeg package of the Kegbot project.
# For more information on Pykeg or Kegbot, see http://kegbot.org/
diff --git a/pykeg/web/setup_wizard/urls.py b/pykeg/web/setup_wizard/urls.py
index e362a1cb9..73ed41d59 100644
--- a/pykeg/web/setup_wizard/urls.py
+++ b/pykeg/web/setup_wizard/urls.py
@@ -1,4 +1,4 @@
-# Copyright 2014 Bevbot LLC, All Rights Reserved
+# Copyright 2014 Kegbot Project contributors
#
# This file is part of the Pykeg package of the Kegbot project.
# For more information on Pykeg or Kegbot, see http://kegbot.org/
diff --git a/pykeg/web/setup_wizard/views.py b/pykeg/web/setup_wizard/views.py
index 9bcfe6165..b42d1f553 100644
--- a/pykeg/web/setup_wizard/views.py
+++ b/pykeg/web/setup_wizard/views.py
@@ -1,4 +1,4 @@
-# Copyright 2014 Bevbot LLC, All Rights Reserved
+# Copyright 2014 Kegbot Project contributors
#
# This file is part of the Pykeg package of the Kegbot project.
# For more information on Pykeg or Kegbot, see http://kegbot.org/
diff --git a/pykeg/web/tasks.py b/pykeg/web/tasks.py
index c4fe1bd3e..13f5fece4 100644
--- a/pykeg/web/tasks.py
+++ b/pykeg/web/tasks.py
@@ -1,4 +1,4 @@
-# Copyright 2014 Bevbot LLC, All Rights Reserved
+# Copyright 2014 Kegbot Project contributors
#
# This file is part of the Pykeg package of the Kegbot project.
# For more information on Pykeg or Kegbot, see http://kegbot.org/
diff --git a/pykeg/web/templates/admin/login.html b/pykeg/web/templates/admin/login.html
index 554331900..38db84c31 100644
--- a/pykeg/web/templates/admin/login.html
+++ b/pykeg/web/templates/admin/login.html
@@ -14,7 +14,7 @@
name="tweet-form-submit">Log In
- (did you forget your username or password?)
+ (did you forget your username or password?)
diff --git a/pykeg/web/templates/base.html b/pykeg/web/templates/base.html
index cb6a285cd..32676c741 100644
--- a/pykeg/web/templates/base.html
+++ b/pykeg/web/templates/base.html
@@ -78,7 +78,7 @@
{% if SSO_LOGOUT_URL %}
Logout
{% else %}
- Logout
+ Logout
{% endif %}
@@ -118,9 +118,7 @@ {% block pagetitle %}{% endblock %}
Powered by
Kegbot™{% if user.is_staff %}, version {{ VERSION }}{% endif %}
—
- © 2003-2014 Bevbot LLC
- —
- Charts by Highcharts
+ © 2003-2020 Kegbot Project contributors
diff --git a/pykeg/web/templates/registration/login.html b/pykeg/web/templates/registration/login.html
index 554331900..38db84c31 100644
--- a/pykeg/web/templates/registration/login.html
+++ b/pykeg/web/templates/registration/login.html
@@ -14,7 +14,7 @@
name="tweet-form-submit">Log In
- (did you forget your username or password?)
+ (did you forget your username or password?)
diff --git a/pykeg/web/templates/registration/password_reset_subject.txt b/pykeg/web/templates/registration/password_reset_subject.txt
new file mode 100644
index 000000000..5c3cb4b72
--- /dev/null
+++ b/pykeg/web/templates/registration/password_reset_subject.txt
@@ -0,0 +1,3 @@
+{% load i18n %}{% autoescape off %}
+{% blocktrans %}Password reset{% endblocktrans %}
+{% endautoescape %}
diff --git a/pykeg/web/urls.py b/pykeg/web/urls.py
index 6bedf4166..762451837 100644
--- a/pykeg/web/urls.py
+++ b/pykeg/web/urls.py
@@ -1,4 +1,4 @@
-# Copyright 2014 Bevbot LLC, All Rights Reserved
+# Copyright 2014 Kegbot Project contributors
#
# This file is part of the Pykeg package of the Kegbot project.
# For more information on Pykeg or Kegbot, see http://kegbot.org/
diff --git a/setup.py b/setup.py
index 33805d291..d89b080ab 100755
--- a/setup.py
+++ b/setup.py
@@ -8,7 +8,7 @@
from setuptools import setup, find_packages
-VERSION = '1.2.3'
+VERSION = '1.3.0b1'
DOCLINES = __doc__.split('\n')
SHORT_DESCRIPTION = DOCLINES[0]
@@ -19,8 +19,8 @@
version=VERSION,
description=SHORT_DESCRIPTION,
long_description=LONG_DESCRIPTION,
- author='Bevbot LLC',
- author_email='info@bevbot.com',
+ author='Kegbot Project',
+ author_email='info@kegbot.org',
url='https://kegbot.org/',
packages=find_packages(),
scripts=[