diff --git a/.DS_Store b/.DS_Store index 5008ddf..12c0459 100644 Binary files a/.DS_Store and b/.DS_Store differ diff --git a/.Python b/.Python deleted file mode 120000 index 883d4b7..0000000 --- a/.Python +++ /dev/null @@ -1 +0,0 @@ -/usr/local/Cellar/python/3.6.5/Frameworks/Python.framework/Versions/3.6/Python \ No newline at end of file diff --git a/.ebignore b/.ebignore deleted file mode 100644 index 6ed9f69..0000000 --- a/.ebignore +++ /dev/null @@ -1 +0,0 @@ -virt \ No newline at end of file diff --git a/.gcloudignore b/.gcloudignore new file mode 100644 index 0000000..a987f11 --- /dev/null +++ b/.gcloudignore @@ -0,0 +1,19 @@ +# This file specifies files that are *not* uploaded to Google Cloud Platform +# using gcloud. It follows the same syntax as .gitignore, with the addition of +# "#!include" directives (which insert the entries of the given .gitignore-style +# file at that point). +# +# For more information, run: +# $ gcloud topic gcloudignore +# +.gcloudignore +# If you would like to upload your .git directory, .gitignore file or files +# from your .gitignore file, remove the corresponding line +# below: +.git +.gitignore + +# Python pycache: +__pycache__/ +# Ignored by the build system +/setup.cfg \ No newline at end of file diff --git a/.gitignore b/.gitignore index a7d4d0a..8973814 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,4 @@ - -GenJson.py -/flask_session/ +/flask_session /bin /include /lib diff --git a/.idea/SMSorder.iml b/.idea/SMSorder.iml index c8efcbb..341108b 100644 --- a/.idea/SMSorder.iml +++ b/.idea/SMSorder.iml @@ -2,7 +2,7 @@ - + diff --git a/.idea/emacs.xml b/.idea/emacs.xml new file mode 100644 index 0000000..a1e816f --- /dev/null +++ b/.idea/emacs.xml @@ -0,0 +1,6 @@ + + + + + \ No newline at end of file diff --git a/.idea/jsonSchemas.xml b/.idea/jsonSchemas.xml new file mode 100644 index 0000000..73a6c51 --- /dev/null +++ b/.idea/jsonSchemas.xml @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml index 7a5c067..7d59cbe 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -1,6 +1,6 @@ - + diff --git a/.idea/workspace.xml b/.idea/workspace.xml index 3c00da1..2cb34f6 100644 --- a/.idea/workspace.xml +++ b/.idea/workspace.xml @@ -1,5069 +1,13 @@ + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + @@ -5087,7 +31,7 @@ - + @@ -5100,23 +44,24 @@ - - + + + - + + - - + - - + + - + @@ -5131,7 +76,7 @@ - + - + - + - + - + @@ -5309,350 +254,350 @@ @@ -5673,31 +618,31 @@ \ No newline at end of file diff --git a/__pycache__/main.cpython-36.pyc b/__pycache__/main.cpython-36.pyc new file mode 100644 index 0000000..9bdd5ed Binary files /dev/null and b/__pycache__/main.cpython-36.pyc differ diff --git a/app.yaml b/app.yaml new file mode 100644 index 0000000..5206547 --- /dev/null +++ b/app.yaml @@ -0,0 +1,5 @@ +env: standard +runtime: python37 +entrypoint: gunicorn -b :$PORT main:app +runtime_config: + python_version: 3.6 diff --git a/application.py b/application.py deleted file mode 100644 index f9e60f4..0000000 --- a/application.py +++ /dev/null @@ -1,2000 +0,0 @@ -import nexmo -import logging -import logging.handlers -from wsgiref.simple_server import make_server -import pygsheets -import pandas as pd -import paypalrestsdk -from firebase import firebase -from flask import Flask, request, redirect, url_for -from werkzeug.datastructures import ImmutableOrderedMultiDict -from flask import render_template -from flask import jsonify, session, sessions -from flask import Flask, escape, request, session -from flask_session import Session -import pyrebase as fbAuth -from fpdf import FPDF -from words2num import w2n -import os -import calendar -import random -import datetime -import json -import time -import urllib.request - -sessionTime = 1000 -infoFile = open("info.json") -info = json.load(infoFile) -uid = info['uid'] -gc = pygsheets.authorize(service_file='static/CedarChatbot-70ec2d781527.json') -email = "cedarchatbot@applicationspot.gserviceaccount.com" -estName = info['uid'] -estNameStr = info['name'] -shortUID = info['shortUID'] -mainLink = "" -authentication = firebase.FirebaseAuthentication('if7swrlQM4k9cBvm0dmWqO3QsI5zjbcdbstSgq1W', 'cajohn0205@gmail.com', - extra={'id': 123}) -database = firebase.FirebaseApplication("https://cedarchatbot.firebaseio.com/", authentication=authentication) -data = (database.get("restaurants/" + uid, "/menu/items/")) -items = [] -config = { - "apiKey": "AIzaSyB2it4zPzPdn_bW9OAglTHUtclidAw307o", - "authDomain": "cedarchatbot.firebaseapp.com", - "databaseURL": "https://cedarchatbot.firebaseio.com", - "storageBucket": "cedarchatbot.appspot.com", -} -firebaseAuth = fbAuth.initialize_app(config) -auth = firebaseAuth.auth() -client = nexmo.Client(key='8558cb90', secret='PeRbp1ciHeqS8sDI') -pointAlg = "x.10" -pointThresh = 1000 -NexmoNumber = info['number'] -databse = firebase.FirebaseApplication("https://cedarrestaurants-ad912.firebaseio.com/") -promoPass = "promo-" + str(estName) -addPass = "add-" + str(estName) -remPass = "remove-" + str(estName) -fontName = "helvetica" -smsTest = "sms:13166009096?body=order" -sh = gc.open('TestRaunt') -linkOrderLong = "cedarrestaurants.us-east-2.elasticbeanstalk.com" + uid + "check" - -webLink = "sms:+" + NexmoNumber + "?body=order" -application = Flask(__name__) - - -def updateLog(): - logYM = (datetime.datetime.now().strftime("%Y-%m")) - sh = gc.open('TestRaunt') - wks = sh.worksheet_by_title(logYM + "-sales") - logData = database.get("/log/" + uid + "/", logYM) - menuItems = database.get("/restaurants/" + estName + "/menu/", "items") - numOrders = (len(database.get("/restaurants/" + estName, "/orders/")) - 1) - totalDF = pd.DataFrame() - totalArr = [] - cdrFees = logData['CedarFees'] - totalArr.append(cdrFees) - paypalFees = logData['paypalFees'] - totalArr.append(paypalFees) - totalFees = cdrFees + paypalFees - totalArr.append(totalFees) - totalRev = logData['totalRev'] - totalArr.append(totalRev) - numOrders = (len(database.get("/restaurants/" + estName, "/orders/")) - 1) - totalArr.append(numOrders) - numCard = logData['cardPay'] - totalArr.append(numCard) - Totals = pd.DataFrame() - totalDF['Totals'] = totalArr - wks.set_dataframe(totalDF, (1, 6)) - skuDict = logData['skus'] - skuKeys = list(skuDict.keys()) - SKUkeyArr = [] - SKUrev = [] - SKUnumSold = [] - SKUnames = [] - for sk in range(len(skuKeys)): - numSold = skuDict[skuKeys[sk]]["numSold"] - SKUnumSold.append(numSold) - SKUkeyArr.append(skuKeys[sk]) - for men in range(len(menuItems)): - if (menuItems[men] != None): - if ((menuItems[men]["sizes"][0][1] != -1)): - for sz in range(len(menuItems[men]["sizes"])): - if (skuKeys[sk] == str(menuItems[men]["sizes"][sz][2])): - #print("found size") - if (str(menuItems[men]["sizes"][sz][0]).lower() != "u"): - name = str(menuItems[men]["name"]).lower() - name += "-" - name += str(menuItems[men]["sizes"][sz][0]).lower() - SKUnames.append(name) - rev = menuItems[men]["sizes"][sz][1] * numSold - SKUrev.append(rev) - - else: - name = str(menuItems[men]["name"]).lower() - SKUnames.append(name) - rev = menuItems[men]["sizes"][sz][1] * numSold - SKUrev.append(rev) - break - if (len(menuItems[men]["sizes"]) - sz == 1): - for ex in range(len(menuItems[men]["extras"])): - if (skuKeys[sk] == str(menuItems[men]["extras"][ex][2])): - #print("found ex") - name = str(menuItems[men]["name"]).lower() - name += "||" - name += str(menuItems[men]["extras"][ex][0]).lower() - name += "* TOPPING " - SKUnames.append(name) - rev = float(menuItems[men]["extras"][ex][1]) * float(numSold) - SKUrev.append(rev) - break - - SKUkeysDF = pd.DataFrame() - SKUnameDF = pd.DataFrame() - SKUrevDF = pd.DataFrame() - SKUnumSoldDF = pd.DataFrame() - SKUkeysDF['SKU'] = SKUkeyArr - wks.set_dataframe(SKUkeysDF, (1, 1)) - SKUnameDF['Name'] = SKUnames - wks.set_dataframe(SKUnameDF, (1, 2)) - SKUrevDF["Revenue"] = SKUrev - wks.set_dataframe(SKUrevDF, (1, 3)) - SKUnumSoldDF["Number Sold"] = SKUnumSold - wks.set_dataframe(SKUnumSoldDF, (1, 4)) - - -def genUsr(name, number, dbIndx): - authentication = firebase.FirebaseAuthentication('if7swrlQM4k9cBvm0dmWqO3QsI5zjbcdbstSgq1W', - 'cajohn0205@gmail.com', extra={'id': 123}) - database = firebase.FirebaseApplication("https://cedarchatbot.firebaseio.com/", authentication=authentication) - UserData = database.get("/", "users") - timeStamp = datetime.datetime.today() - database.put("/users/", "/" + str(len(UserData)) + "/name", name) - database.put("/users/", "/" + str(len(UserData)) + "/number", number) - database.put("/users/", "/" + str(len(UserData)) + "/restaurants/" + estNameStr + "/" + str(0) + "/StartTime", - str(timeStamp)) - database.put("/users/", "/" + str(len(UserData)) + "/loyalty/" + str(0) + "/name/", estNameStr) - database.put("/users/", "/" + str(len(UserData)) + "/loyalty/" + str(0) + "/points/", 0) - database.put("/restaurants/" + estName + "/orders/" + str(dbIndx) + "/", "/usrIndx/", len(UserData)) - - -def genPayment(total, name, UUIDcode): - #print(UUIDcode) - #print(name) - apiurl = "http://tinyurl.com/api-create.php?url=" - paymentLink = 'https://www.sandbox.paypal.com/cgi-bin/webscr?cmd=_xclick&business=sb-ninhv43009@business.example.com¤cy_code=USD&amount=' \ - '' + str(total) + '&item_name=' + str(UUIDcode) - tinyurl = urllib.request.urlopen(apiurl + paymentLink).read() - shortLink = tinyurl.decode("utf-8") - return paymentLink - - -def getReply(msg, number): - authentication = firebase.FirebaseAuthentication('if7swrlQM4k9cBvm0dmWqO3QsI5zjbcdbstSgq1W', - 'cajohn0205@gmail.com', extra={'id': 123}) - database = firebase.FirebaseApplication("https://cedarchatbot.firebaseio.com/", authentication=authentication) - currentTime = str((float(datetime.datetime.now().hour)) + ((float(datetime.datetime.now().minute)) / 100.0)) - startHr = float(database.get("restaurants/" + uid, "/OChrs/open/")) - endHr = float(database.get("restaurants/" + uid, "/OChrs/close/")) - if (startHr <= float(currentTime) < endHr): - msg = msg.lower() - indx = 0 - DBdata = database.get("/restaurants/" + estName, "/orders") - UserData = database.get("/", "users") - if (msg == "order" or msg == "ordew" or msg == "ord" or msg == "ordet" or msg == "oderr" or msg == "ordee"): - client.send_message({ - 'from': NexmoNumber, - 'to': number, - 'text': "Hi! Welcome to " + estNameStr + ", please wait one moment..." - }) - UUID = random.randint(9999999, 100000000) - reply = "Hi, welcome to " + estNameStr + " please enter your name to continue" - database.put("/restaurants/" + estName + "/orders/" + str(len(DBdata)) + "/", "/UUID/", str(UUID)) - database.put("/restaurants/" + estName + "/orders/" + str(len(DBdata)) + "/", "/name/", "") - database.put("/restaurants/" + estName + "/orders/" + str(len(DBdata)) + "/", "/number/", str(number)) - database.put("/restaurants/" + estName + "/orders/" + str(len(DBdata)) + "/", "/stage/", 1) - database.put("/restaurants/" + estName + "/orders/" + str(len(DBdata)) + "/", "/paid/", 0) - database.put("/restaurants/" + estName + "/orders/" + str(len(DBdata)) + "/", "/cash/", "") - database.put("/restaurants/" + estName + "/orders/" + str(len(DBdata)) + "/", "/togo/", "") - database.put("/restaurants/" + estName + "/orders/" + str(len(DBdata)) + "/", "/tickSize/", 0) - database.put("/restaurants/" + estName + "/orders/" + str(len(DBdata)) + "/", "/discUsed/", 0) - database.put("/restaurants/" + estName + "/orders/" + str(len(DBdata)) + "/", "/discTotal/", 0.0) - database.put("/restaurants/" + estName + "/orders/" + str(len(DBdata)) + "/", "/discStr/", "") - database.put("/restaurants/" + estName + "/orders/" + str(len(DBdata)) + "/", "/filled/", "0") - database.put("/restaurants/" + estName + "/orders/" + str(len(DBdata)) + "/", "/linkTotal/", 0.0) - database.put("/restaurants/" + estName + "/orders/" + str(len(DBdata)) + "/", "finalOrder/", "") - database.put("/restaurants/" + estName + "/orders/" + str(len(DBdata)) + "/", "startTime/", time.time()) - UserData = database.get("/", "users") - for usr in range(len(UserData)): - if (number == UserData[usr]["number"]): - #print("found user") - timeStamp = datetime.datetime.today() - reply = "Hi " + str( - UserData[usr]["name"]) + "! welcome to " + estNameStr + " is this order or to go?" - database.put("/restaurants/" + estName + "/orders/" + str((len(DBdata))) + "/", "/name/", - str(UserData[usr]["name"])) - database.put("/restaurants/" + estName + "/orders/" + str(len(DBdata)) + "/", "/filled/", "0") - - database.put("/restaurants/" + estName + "/orders/" + str(len(DBdata)) + "/", "/stage/", 2) - database.put("/restaurants/" + estName + "/orders/" + str(len(DBdata)) + "/", "/userIndx/", usr) - numOrders = database.get("/users/" + str(usr) + "/restaurants/", estNameStr) - database.put("/restaurants/" + estName + "/orders/" + str(len(DBdata)) + "/", "/orderIndx/", - (len(numOrders))) - database.put("/restaurants/" + estName + "/orders/" + str(len(DBdata)) + "/", "startTime/", - time.time()) - database.put("/restaurants/" + estName + "/orders/" + str(len(DBdata)) + "/", "/ret/", 0) - database.put("/users/", - "/" + str(usr) + "/restaurants/" + estNameStr + "/" + str( - (len(numOrders))) + "/startTime", - str(timeStamp)) - break - if ((len(UserData) - usr) == 1): - genUsr("", number, (len(DBdata))) - database.put("/restaurants/" + estName + "/orders/" + str(len(DBdata)) + "/", "/userIndx/", - (len(UserData))) - database.put("/restaurants/" + estName + "/orders/" + str(len(DBdata)) + "/", "/orderIndx/", - 0) - database.put("/restaurants/" + estName + "/orders/" + str(len(DBdata)) + "/", "/ret/", 1) - client.send_message({ - 'from': NexmoNumber, - 'to': number, - 'text': reply - }) - return reply - else: - for db in range(len(DBdata)): - phoneNumDB = DBdata[db]['number'] - if (phoneNumDB == number): - indx = db - break - elif ((len(DBdata) - db) == 1): - #print("no msg") - return 200 - if (DBdata[indx]['stage'] == 1): - name = msg - DBdata = database.get("/restaurants/" + estName, "/orders") - database.put("/restaurants/" + estName + "/orders/" + str(indx) + "/", "/name/", str(msg).capitalize()) - database.put("/restaurants/" + estName + "/orders/" + str(indx) + "/", "/stage/", 2) - UserData = database.get("/", "users") - timeStamp = datetime.datetime.today() - database.put("/users/", "/" + str(DBdata[indx]["userIndx"]) + "/name", name) - database.put("/users/", "/" + str(DBdata[indx]["userIndx"]) + "/number", number) - database.put("/users/", - "/" + str(DBdata[indx]["userIndx"]) + "/restaurants/" + estNameStr + "/" + str( - 0) + "/StartTime", - str(timeStamp)) - database.put("/users/", "/" + str((DBdata[indx]["userIndx"])) + "/loyalty/" + estNameStr + "/points/", - 0) - reply = "is this order for-here or to-go?" - usrIndx = DBdata[indx]["userIndx"] - database.put("/users", "/" + str(DBdata[indx]["userIndx"]) + "/name", str(msg.capitalize())) - client.send_message({ - 'from': NexmoNumber, - 'to': number, - 'text': reply - }) - elif (DBdata[indx]['stage'] == 2): - if ( - msg == "for here" or msg == "fo here" or msg == "for her" or msg == "for herw" or msg == "for herr" or msg == "here"): - database.put("/restaurants/" + estName + "/orders/" + str(indx) + "/", "/stage/", 3) - database.put("/restaurants/" + estName + "/orders/" + str(indx) + "/", "/togo/", "HERE") - usrIndx = DBdata[indx]["userIndx"] - numOrders = database.get("/users/" + str(usrIndx) + "/restaurants/", estNameStr) - #print((len(numOrders))) - database.put("/users/", - "/" + str(usrIndx) + "/restaurants/" + estNameStr + "/" + str( - (len(numOrders) - 1)) + "/to-go", - str("here")) - - client.send_message({ - 'from': NexmoNumber, - 'to': number, - 'text': "-Sounds good! your order will be " + "for-here\n" + "-if you want" - " your order now enter" + ' "asap" otherwise enter your preferred time.(EX 11:15am)' - }) - else: - authentication = firebase.FirebaseAuthentication('if7swrlQM4k9cBvm0dmWqO3QsI5zjbcdbstSgq1W', - 'cajohn0205@gmail.com', extra={'id': 123}) - database = firebase.FirebaseApplication("https://cedarchatbot.firebaseio.com/", - authentication=authentication) - database.put("/restaurants/" + estName + "/orders/" + str(indx) + "/", "/togo/", "TO_GO") - database.put("/restaurants/" + estName + "/orders/" + str(indx) + "/", "/stage/", 3) - usrIndx = DBdata[indx]["userIndx"] - numOrders = database.get("/users/" + str(usrIndx) + "/restaurants/", estNameStr) - database.put("/users/", - "/" + str(usrIndx) + "/restaurants/" + estNameStr + "/" + str( - (len(numOrders) - 1)) + "/to-go", - str("to-go")) - client.send_message({ - 'from': NexmoNumber, - 'to': number, - 'text': "-Sounds good! your order will be " + "to-go\n" + "-if you want" - " your order now enter " + '"asap" otherwise enter the time your preferred time.(EX 11:15am)' - }) - elif (DBdata[indx]['stage'] == 3): - currentMenu = "" - menuIndx = 0 - authentication = firebase.FirebaseAuthentication('if7swrlQM4k9cBvm0dmWqO3QsI5zjbcdbstSgq1W', - 'cajohn0205@gmail.com', extra={'id': 123}) - database = firebase.FirebaseApplication("https://cedarchatbot.firebaseio.com/", - authentication=authentication) - data = (database.get("restaurants/" + uid, "/menu/items/")) - currentTime = str( - (float(datetime.datetime.now().hour)) + ((float(datetime.datetime.now().minute)) / 100.0)) - DBdata = database.get("/restaurants/" + estName, "orders") - MenuHrs = ((database.get("restaurants/" + uid, "/Hours/"))) - menuLink = "" - menKeys = list(MenuHrs.keys()) - for mnx in range(len(menKeys)): - startHrMn = (float(MenuHrs[menKeys[mnx]]["startHr"])) - endHrMn = (float(MenuHrs[menKeys[mnx]]["endHr"])) - if (startHrMn <= float(currentTime) < endHrMn): - #print("current menu") - #print(menKeys[mnx]) - menuIndx = mnx - currentMenu = str(menKeys[mnx]) - menuLink = str(MenuHrs[menKeys[mnx]]["link"]) - break - database.put("/restaurants/" + estName + "/orders/" + str(indx) + "/", "/time/", msg.upper()) - database.put("/restaurants/" + estName + "/orders/" + str(indx) + "/", "/stage/", 4) - usrIndx = DBdata[indx]["userIndx"] - numOrders = database.get("/users/" + str(usrIndx) + "/restaurants/", estNameStr) - #print(numOrders) - database.put("/users/", - "/" + str(usrIndx) + "/restaurants/" + estNameStr + "/" + str( - (len(numOrders) - 1)) + "/pickup-time", str(msg)) - linkOrder = database.get("/restaurants/" + estName, "/orderLink") - reply = "Got it! click this link below to view the menu and continue ordering " + str(linkOrder) - - client.send_message({ - 'from': NexmoNumber, - 'to': number, - 'text': reply - }) - #print("m0") - return reply - else: - return ("no msg") - - -@application.route('/sms', methods=['GET', 'POST']) -def inbound_sms(): - data = dict(request.form) or dict(request.args) - #print(data["text"]) - number = str(data['msisdn'][0]) - msg = str(data["text"][0]) - #print(number, msg) - getReply(msg, number) - return ('', 200) - - -@application.route('/ipn', methods=['POST']) -def ipn(): - logYM = (datetime.datetime.now().strftime("%Y-%m")) - authentication = firebase.FirebaseAuthentication('if7swrlQM4k9cBvm0dmWqO3QsI5zjbcdbstSgq1W', - 'cajohn0205@gmail.com', extra={'id': 123}) - database = firebase.FirebaseApplication("https://cedarchatbot.firebaseio.com/", authentication=authentication) - request.parameter_storage_class = ImmutableOrderedMultiDict - rsp = ((request.form)) - DBdata = database.get("/restaurants/" + estName, "orders") - for dbItems in range(len(DBdata)): - #print(rsp["item_name"]) - if (DBdata[dbItems]["UUID"] == rsp["item_name"]): - database.put("/restaurants/" + estName + "/orders/" + str(dbItems) + "/", "/paid/", 1) - database.put("/restaurants/" + estName + "/orders/" + str(dbItems) + "/", "/filled/", "1") - usrIndx = DBdata[dbItems]["userIndx"] - # ticketSize = int(DBdata[dbItems]["tickSize"]) - # startTime = float(DBdata[dbItems]["startTime"]) - number = str(DBdata[dbItems]["number"]) - duration = time.time() - float(DBdata[dbItems]["startTime"]) - numItms = len(DBdata[dbItems]["item"]) - database.put("/restaurants/" + estName + "/orders/" + str(dbItems) + "/", "tickSize/", numItms) - database.put("/restaurants/" + estName + "/orders/" + str(dbItems) + "/", "/duration/", duration) - database.put("/restaurants/" + estName + "/orders/" + str(dbItems) + "/", "/day/", - calendar.day_name[datetime.datetime.now().today().weekday()]) - database.put("/restaurants/" + estName + "/orders/" + str(dbItems) + "/", "/hour/", - int(datetime.datetime.now().hour)) - database.put("/restaurants/" + estName + "/orders/" + str(dbItems) + "/", "/month/", - (datetime.datetime.now().strftime("%m"))) - database.put("/restaurants/" + estName + "/orders/" + str(dbItems) + "/", "/date/", - (datetime.datetime.now().strftime("%d"))) - database.put("/restaurants/" + estName + "/orders/" + str(dbItems) + "/", "/year/", - (datetime.datetime.now().strftime("%Y"))) - - numOrders = database.get("/users/" + str(usrIndx) + "/restaurants/", estNameStr) - database.put("/users/", "/" + str(usrIndx) + "/email", rsp["payer_email"]) - database.put("/users/", "/" + str(usrIndx) + "/country", rsp["address_country_code"]) - database.put("/users/", "/" + str(usrIndx) + "/state", rsp["address_state"]) - database.put("/users/", "/" + str(usrIndx) + "/zipCode", rsp["address_zip"]) - database.put("/users/", "/" + str(usrIndx) + "/city", rsp["address_city"]) - database.put("/users/", "/" + str(usrIndx) + "/streetAdr", rsp["address_street"]) - logData = database.get("/log/" + uid + "/", logYM) - numCard = int(logData['cardPay']) - numCard += 1 - payPalFees = float(logData['paypalFees']) - payPalFees += float(rsp["mc_fee"]) - cdrFees = logData['CedarFees'] - cdrFees += 0.1 - database.put("/log/" + uid + "/" + logYM, "/CedarFees/", cdrFees) - totalRev = float(logData["totalRev"]) - totalRev += float((DBdata[dbItems]["linkTotal"] + 0.1) * 1.1) - database.put("/log/" + uid + "/" + logYM, "/totalRev/", totalRev) - database.put("/log/" + uid + "/" + logYM, "/cardPay/", numCard) - database.put("/restaurants/" + estName + "/orders/" + str(dbItems) + "/", "/zipCode/", rsp["address_zip"]) - database.put("/restaurants/" + estName + "/orders/" + str(dbItems) + "/", "/city/", rsp["address_city"]) - database.put("/log/" + uid + "/" + logYM, "/paypalFees/", payPalFees) - numItms = len(DBdata[dbItems]["item"]) - orderIndx = DBdata[dbItems]["orderIndx"] - usrIndx = DBdata[dbItems]["userIndx"] - ret = int(logData["retCustomers"]) - newCust = int(logData["newCustomers"]) - if (DBdata[dbItems]["ret"] == 0): - ret += 1 - database.put("/log/" + uid + "/" + logYM, "/retCustomers/", ret) - else: - newCust += 1 - database.put("/log/" + uid + "/" + logYM, "/newCustomers/", newCust) - - database.put("/users/" + str(usrIndx) + "/restaurants/" + estNameStr + "/" + str(orderIndx) + "/", "total", - ((DBdata[dbItems]["linkTotal"] + 0.1) * 1.1)) - database.put("/users/" + str(usrIndx) + "/restaurants/" + estNameStr + "/" + str(orderIndx) + "/", - "tickSize", - numItms) - database.put("/users/" + str(usrIndx) + "/restaurants/" + estNameStr + "/" + str(orderIndx) + "/", "items", - DBdata[dbItems]["item"]) - database.put("/users/" + str(usrIndx) + "/restaurants/" + estNameStr + "/" + str(orderIndx) + "/", - "duration", - duration) - #print("sending") - reply = "-Thank you for your order, you can pick it up when you arrive and skip the line \n-To order again just text " + '"order"' - updateLog() - client.send_message({ - 'from': NexmoNumber, - 'to': number, - 'text': reply - }) - database.put("/restaurants/" + estName + "/orders/" + str(dbItems) + "/", "number/", str((number) + ".")) - return (" ", 200) - - -@application.route('/' + estNameStr, methods=['GET']) -def loginPage(): - database = firebase.FirebaseApplication("https://cedarchatbot.firebaseio.com/", - authentication=authentication) - database.put("/restaurants/" + uid + "/", "loginTime", 0) - return render_template("login.html", btn=str(estNameStr), restName=estNameStr) - - -@application.route('/' + estNameStr, methods=['POST']) -def loginPageCheck(): - rsp = ((request.form)) - email = str(rsp["email"]) - pw = str(rsp["pw"]) - try: - user = auth.sign_in_with_email_and_password(str(rsp["email"]), pw) - #print(user['localId']) - authentication = firebase.FirebaseAuthentication('if7swrlQM4k9cBvm0dmWqO3QsI5zjbcdbstSgq1W', - 'cajohn0205@gmail.com', extra={'id': 123}) - fireapp = firebase.FirebaseApplication('https://cedarchatbot.firebaseio.com/', authentication=authentication) - testDB = (fireapp.get("/restaurants/", user["localId"])) - if (str(user["localId"]) == str(uid) and testDB != None): - #print("found") - database = firebase.FirebaseApplication("https://cedarchatbot.firebaseio.com/", - authentication=authentication) - database.put("/restaurants/" + uid + "/", "loginTime", time.time()) - return redirect(url_for('panel')) - else: - authentication = firebase.FirebaseAuthentication('if7swrlQM4k9cBvm0dmWqO3QsI5zjbcdbstSgq1W', - 'cajohn0205@gmail.com', extra={'id': 123}) - #print("incorrect password") - database = firebase.FirebaseApplication("https://cedarchatbot.firebaseio.com/", - authentication=authentication) - database.put("/restaurants/" + uid + "/", "loginTime", 0) - return render_template("login2.html", btn=str(estNameStr), restName=estNameStr) - except Exception: - authentication = firebase.FirebaseAuthentication('if7swrlQM4k9cBvm0dmWqO3QsI5zjbcdbstSgq1W', - 'cajohn0205@gmail.com', extra={'id': 123}) - database = firebase.FirebaseApplication("https://cedarchatbot.firebaseio.com/", - authentication=authentication) - database.put("/restaurants/" + uid + "/", "loginTime", 0) - #print("incorrect password") - return render_template("login2.html", btn=str(estNameStr), restName=estNameStr) - - -@application.route('/' + uid, methods=['GET']) -def panel(): - currentTime = time.time() - authentication = firebase.FirebaseAuthentication('if7swrlQM4k9cBvm0dmWqO3QsI5zjbcdbstSgq1W', - 'cajohn0205@gmail.com', extra={'id': 123}) - database = firebase.FirebaseApplication("https://cedarchatbot.firebaseio.com/", authentication=authentication) - lastLogin = float(database.get("/restaurants/" + uid, "loginTime")) - if ((currentTime - lastLogin) < sessionTime): - links = [] - names = [] - hours = (database.get("restaurants/" + uid, "/Hours/")) - keys = list(hours.keys()) - for menuNames in range(len(keys)): - names.append(str([keys[menuNames]][0])) - links.append(str(hours[keys[menuNames]]["link"])) - #print(links) - updateLog() - return render_template("panel.html", len=len(links), menuLinks=links, menuNames=names, restName=estNameStr, - viewOrders=(uid + "view"), addItm=(addPass), remItms=remPass, addCpn=promoPass, - signOut=estNameStr) - else: - return render_template("login.html", btn=str(estNameStr), restName=estNameStr) - - -@application.route('/' + uid + "view", methods=['GET']) -def view(): - orders = database.get("/restaurants/" + estName, "orders") - webDataDisp = [] - keys = [] - #print(orders) - for ords in range(len(orders)): - try: - filled = orders[ords]["filled"] - #print(filled) - if (filled == "1"): - UUID = orders[ords]["UUID"] - try: - subTotal = (orders[ords]["linkTotal"]) + orders[ords]["discTotal"] - except KeyError: - subTotal = (orders[ords]["linkTotal"]) - Tax = float(subTotal * 0.1) - Total = float(subTotal + float(Tax) + 0.1) - subTotalStr = ('$' + format(subTotal, ',.2f')) - TotalStr = ('$' + format(Total, ',.2f')) - TaxStr = ('$' + format(Tax, ',.2f')) - #print(TotalStr) - writeStr = str(orders[ords]["name"]) + " || " + str(orders[ords]["finalOrder"]) + " " + str( - orders[ords]["discStr"]) \ - + " || " + str(orders[ords]["togo"]) + " || " + str(orders[ords]["time"]) + " || " \ - "" + TotalStr + " || " + str( - orders[ords]["cash"]) - keys.append(UUID) - #print(writeStr) - webDataDisp.append(writeStr) - except KeyError: - #print("exec") - pass - return render_template("indexV.html", len=len(webDataDisp), webDataDisp=webDataDisp, keys=keys, - btn=str(uid + "view"), restName=estNameStr) - - -@application.route('/' + uid + "view", methods=['POST']) -def button(): - request.parameter_storage_class = ImmutableOrderedMultiDict - rsp = ((request.form)) - item = (rsp['item']) - #print(item) - orders = database.get("/restaurants/" + estName, "orders") - webDataDisp = [] - keys = [] - #print(orders) - for ords in range(len(orders)): - UUID = orders[ords]["UUID"] - if (item == UUID): - database.put("/restaurants/" + estName + "/orders/" + str(ords) + "/", "/filled/", "2") - else: - filled = orders[ords]["filled"] - if (filled == "1"): - UUID = orders[ords]["UUID"] - try: - subTotal = (orders[ords]["linkTotal"]) + orders[ords]["discTotal"] - except KeyError: - subTotal = (orders[ords]["linkTotal"]) - Tax = float(orders[ords]["linkTotal"] * 0.1) - Total = float(subTotal + float(Tax) + 0.1) - subTotalStr = ('$' + format(subTotal, ',.2f')) - TotalStr = ('$' + format(Total, ',.2f')) - TaxStr = ('$' + format(Tax, ',.2f')) - #print(TotalStr) - writeStr = str(orders[ords]["name"]) + " || " + str(orders[ords]["finalOrder"]) + " " + str( - orders[ords]["discStr"]) \ - + " || " + str(orders[ords]["togo"]) + " || " + str(orders[ords]["time"]) + " || " \ - "" + TotalStr + " || " + str( - orders[ords]["cash"]) - keys.append(UUID) - #print(writeStr) - webDataDisp.append(writeStr) - return render_template("indexV.html", len=len(webDataDisp), webDataDisp=webDataDisp, keys=keys, - btn=str(uid + "view")) - - -@application.route('/' + remPass, methods=['GET']) -def removeItemsDisp(): - currentTime = time.time() - authentication = firebase.FirebaseAuthentication('if7swrlQM4k9cBvm0dmWqO3QsI5zjbcdbstSgq1W', - 'cajohn0205@gmail.com', extra={'id': 123}) - database = firebase.FirebaseApplication("https://cedarchatbot.firebaseio.com/", authentication=authentication) - lastLogin = float(database.get("/restaurants/" + uid, "loginTime")) - #print() - if ((currentTime - lastLogin) < sessionTime): - menuItems = database.get("/restaurants/" + estName + "/menu/", "items") - #print(menuItems) - names = [] - keys = [] - for men in range(len(menuItems)): - - if (menuItems[men]["descrip"] != "REMOVEDITM!"): - names.append(menuItems[men]["name"]) - keys.append(men) - return render_template("remItems.html", len=len(names), names=names, keys=keys, btn=remPass) - else: - return render_template("login.html", btn=str(estNameStr), restName=estNameStr) - - -@application.route('/' + remPass, methods=['POST']) -def removeItems(): - currentTime = time.time() - authentication = firebase.FirebaseAuthentication('if7swrlQM4k9cBvm0dmWqO3QsI5zjbcdbstSgq1W', - 'cajohn0205@gmail.com', extra={'id': 123}) - database = firebase.FirebaseApplication("https://cedarchatbot.firebaseio.com/", authentication=authentication) - lastLogin = float(database.get("/restaurants/" + uid, "loginTime")) - if ((currentTime - lastLogin) < sessionTime): - request.parameter_storage_class = ImmutableOrderedMultiDict - rsp = ((request.form)) - item = int(rsp['item']) - names = [] - keys = [] - database.put("/restaurants/" + estName + "/menu/items/" +str(item)+"/", "descrip", "REMOVEDITM!") - database.put("/restaurants/" + estName + "/menu/items/" + str(item) + "/", "sizes/0/1", -1) - menuItems = database.get("/restaurants/" + estName + "/menu/", "items") - for men in range(len(menuItems)): - if (menuItems[men]["descrip"] != "REMOVEDITM!"): - names.append(menuItems[men]["name"]) - keys.append(men) - pdf = FPDF() - pdf.add_page() - yStart = 20 - authentication = firebase.FirebaseAuthentication('if7swrlQM4k9cBvm0dmWqO3QsI5zjbcdbstSgq1W', - 'cajohn0205@gmail.com', extra={'id': 123}) - database = firebase.FirebaseApplication("https://cedarchatbot.firebaseio.com/", authentication=authentication) - menu = (database.get("restaurants/" + uid, "/menu/items/")) - hours = (database.get("restaurants/" + uid, "/Hours/")) - #print(hours) - keys = list(hours.keys()) - for menuNames in range(len(keys)): - pdf = FPDF() - pdf.add_page() - yStart = 20 - pdf.set_font(fontName, size=24, style="BU") - text = estNameStr + " " + str([keys[menuNames]][0]) + " Menu" - pdf.multi_cell(200, 10, txt=text, align="C") - yStart += 10 - for dt in range(len(menu)): - if (menu[dt] != None): - if ((menu[dt]["sizes"][0][1] != -1)): - name = menu[dt]["name"].lower() - #print(name) - #print(menu[dt]["time"], str([keys[menuNames]][0])) - #print(menu[dt]["time"] == str([keys[menuNames]][0])) - #print(str(menu[dt]["time"]).lower() == "all") - #print("\n") - if (str(menu[dt]["time"]).lower() == "all" or str(menu[dt]["time"]).lower() == str( - [keys[menuNames]][0]).lower()): - name = menu[dt]["name"].lower() - sizes = [] - toppings = [] - for sz in range(len(menu[dt]["sizes"])): - sizes.append([str(menu[dt]["sizes"][sz][0]).lower(), menu[dt]["sizes"][sz][1]]) - if (str(menu[dt]["extras"][0][0]) != ""): - for ex in range(len(menu[dt]["extras"])): - toppings.append([str(menu[dt]["extras"][ex][0]).lower(), menu[dt]["extras"][ex][1]]) - # pdf.line(0, yStart, 500000, yStart) - pdf.set_font(fontName, size=18, style="B") - text = name - pdf.multi_cell(100, 10, txt=text, align="L") - yStart += 10 - text = "" - pdf.set_font(fontName, size=14, style="B") - if (len(sizes) > 1): - text = "-Sizes:" - pdf.multi_cell(100, 7, txt=text, align="L") - yStart += 7 - pdf.set_font(fontName, size=12, style="") - text = "" - for szs in range(len(sizes)): - text += " -" - text += sizes[szs][0] - text += " ~ $" + str(sizes[szs][1]) - pdf.multi_cell(100, 7, txt=text, align="L") - yStart += 7 - text = "" - else: - pdf.set_font(fontName, size=12, style="") - text += " ~$" + str(sizes[0][1]) - pdf.multi_cell(100, 7, txt=text, align="L") - yStart += 7 - text = "" - if (len(toppings) > 1): - pdf.set_font(fontName, size=14, style="B") - text = "-Toppings/Customizations:" - pdf.multi_cell(100, 7, txt=text, align="L") - yStart += 7 - text = "" - pdf.set_font(fontName, size=12, style="") - for ex in range(len(toppings)): - text += " -" - text += toppings[ex][0] - text += " ~ $" + str(toppings[ex][1]) - pdf.multi_cell(100, 7, txt=text, align="L") - yStart += 7 - text = "" - yStart += 7 - text = "" - fileName = "menus/" + estNameStr + "-" + str([keys[menuNames]][0]) + "-" + "menu.pdf" - pdf.output(fileName) - storage = firebaseAuth.storage() - storage.child(estNameStr + "/" + fileName).put(fileName) - #print("\n") - return redirect(url_for('panel')) - else: - return render_template("login.html", btn=str(estNameStr), restName=estNameStr) - - -@application.route('/' + addPass, methods=['GET']) -def addItmDisp(): - currentTime = time.time() - authentication = firebase.FirebaseAuthentication('if7swrlQM4k9cBvm0dmWqO3QsI5zjbcdbstSgq1W', - 'cajohn0205@gmail.com', extra={'id': 123}) - database = firebase.FirebaseApplication("https://cedarchatbot.firebaseio.com/", authentication=authentication) - lastLogin = float(database.get("/restaurants/" + uid, "loginTime")) - #print() - if ((currentTime - lastLogin) < sessionTime): - return render_template('addform.html', btn=addPass, restName=estNameStr) - else: - return render_template("login.html", btn=str(estNameStr), restName=estNameStr) - - -@application.route('/' + addPass, methods=['POST']) -def addItmForm(): - currentTime = time.time() - authentication = firebase.FirebaseAuthentication('if7swrlQM4k9cBvm0dmWqO3QsI5zjbcdbstSgq1W', - 'cajohn0205@gmail.com', extra={'id': 123}) - database = firebase.FirebaseApplication("https://cedarchatbot.firebaseio.com/", authentication=authentication) - lastLogin = float(database.get("/restaurants/" + uid, "loginTime")) - #print() - if ((currentTime - lastLogin) < sessionTime): - request.parameter_storage_class = ImmutableOrderedMultiDict - rsp = ((request.form)) - name = str(rsp['name']).lower() - numSizes = int(rsp['numSizes']) - menTime = str(rsp['time']).lower() - descrip = str(rsp['desc']).lower() + " " - #print(name) - #print(numSizes) - menuItems = database.get("/restaurants/" + estName + "/menu/", "items") - keyVal = 0 - for mmx in range(len(menuItems)): - if (menuItems[mmx] != None): - if (keyVal < mmx): - keyVal = mmx - keyVal += 1 - database.put("/restaurants/" + estName + "/menu/items/" + str(keyVal), "/name/", name) - database.put("/restaurants/" + estName + "/menu/items/" + str(keyVal), "/time/", menTime) - database.put("/restaurants/" + estName + "/menu/items/" + str(keyVal), "/descrip/", descrip) - database.put("/restaurants/" + estName + "/menu/items/" + str(keyVal), "/inp/", "inp") - database.put("/restaurants/" + estName + "/menu/items/" + str(keyVal) + "/extras/" + str(0), "/0/", "") - database.put("/restaurants/" + estName + "/menu/items/" + str(keyVal) + "/extras/" + str(0), "/1/", 0) - database.put("/restaurants/" + estName + "/menu/items/" + str(keyVal) + "/extras/" + str(0), "/2/", "") - for nn in range(numSizes): - database.put("/restaurants/" + estName + "/menu/items/" + str(keyVal) + "/sizes/" + str(nn), "/0", "") - database.put("/restaurants/" + estName + "/menu/items/" + str(keyVal) + "/sizes/" + str(nn), "/1", 0) - return render_template('addform2.html', btn=(str(addPass) + "2"), len=numSizes, restName=estNameStr) - else: - return render_template("login.html", btn=str(estNameStr), restName=estNameStr) - - -@application.route('/' + addPass + "2", methods=['POST']) -def addItmResp2(): - currentTime = time.time() - authentication = firebase.FirebaseAuthentication('if7swrlQM4k9cBvm0dmWqO3QsI5zjbcdbstSgq1W', - 'cajohn0205@gmail.com', extra={'id': 123}) - database = firebase.FirebaseApplication("https://cedarchatbot.firebaseio.com/", authentication=authentication) - lastLogin = float(database.get("/restaurants/" + uid, "loginTime")) - if ((currentTime - lastLogin) < sessionTime): - request.parameter_storage_class = ImmutableOrderedMultiDict - rsp = ((request.form)) - numExtras = rsp["numEx"] - menuItems = database.get("/restaurants/" + estName + "/menu/", "items") - for sx in range(len(menuItems)): - if (menuItems[sx] != None): - if (menuItems[sx]['inp'] == "inp"): - for ssz in range(int((len(rsp) - 1) / 3)): - szName = rsp[str(ssz)] - szPrice = rsp[str(ssz) + "a"] - sku = rsp[str(ssz) + "b"] - database.put("/restaurants/" + estName + "/menu/items/" + str(sx) + "/sizes/" + str(ssz), "/0/", - szName) - database.put("/restaurants/" + estName + "/menu/items/" + str(sx) + "/sizes/" + str(ssz), "/1/", - float(szPrice)) - database.put("/restaurants/" + estName + "/menu/items/" + str(sx) + "/sizes/" + str(ssz), "/2/", - str(sku)) - if (numExtras != ""): - for sse in range(int(numExtras)): - database.put("/restaurants/" + estName + "/menu/items/" + str(sx) + "/extras/" + str(sse), - "/0/", - "") - database.put("/restaurants/" + estName + "/menu/items/" + str(sx) + "/extras/" + str(sse), - "/1/", 0) - else: - database.put("/restaurants/" + estName + "/menu/items/" + str(sx) + "/extras/" + str(sse), - "/0/", - "") - database.put("/restaurants/" + estName + "/menu/items/" + str(sx) + "/extras/" + str(sse), - "/1/", 0) - break - return render_template('addform3.html', btn=(str(addPass) + "3"), len=int(numExtras), restName=estNameStr) - else: - return render_template("login.html", btn=str(estNameStr), restName=estNameStr) - - -@application.route('/' + addPass + "3", methods=['GET']) -def addItmForm3(): - currentTime = time.time() - authentication = firebase.FirebaseAuthentication('if7swrlQM4k9cBvm0dmWqO3QsI5zjbcdbstSgq1W', - 'cajohn0205@gmail.com', extra={'id': 123}) - database = firebase.FirebaseApplication("https://cedarchatbot.firebaseio.com/", authentication=authentication) - lastLogin = float(database.get("/restaurants/" + uid, "loginTime")) - if ((currentTime - lastLogin) < sessionTime): - menuItems = database.get("/restaurants/" + estName + "/menu/", "items") - for sx in range(len(menuItems)): - if (menuItems[sx] != None): - if (menuItems[sx]['inp'] == "inp"): - itxL = int(len(menuItems[sx]['extras'])) - return render_template('addform3.html', btn=(str(addPass) + "3"), len=itxL, restName=estNameStr) - else: - return render_template("login.html", btn=str(estNameStr), restName=estNameStr) - - -@application.route('/' + addPass + "3", methods=['POST']) -def addItmResp3(): - currentTime = time.time() - authentication = firebase.FirebaseAuthentication('if7swrlQM4k9cBvm0dmWqO3QsI5zjbcdbstSgq1W', - 'cajohn0205@gmail.com', extra={'id': 123}) - database = firebase.FirebaseApplication("https://cedarchatbot.firebaseio.com/", authentication=authentication) - lastLogin = float(database.get("/restaurants/" + uid, "loginTime")) - #print() - if ((currentTime - lastLogin) < sessionTime): - request.parameter_storage_class = ImmutableOrderedMultiDict - rsp = ((request.form)) - menuItems = database.get("/restaurants/" + estName + "/menu/", "items") - for sx in range(len(menuItems)): - if (menuItems[sx] != None): - if (menuItems[sx]['inp'] == "inp"): - for sse in range(int(len(rsp) / 3)): - exName = rsp[str(sse)] - exPrice = rsp[str(sse) + "a"] - sku = rsp[str(sse) + "b"] - database.put("/restaurants/" + estName + "/menu/items/" + str(sx) + "/extras/" + str(sse), - "/0/", - exName) - database.put("/restaurants/" + estName + "/menu/items/" + str(sx) + "/extras/" + str(sse), - "/1/", float(exPrice)) - database.put("/restaurants/" + estName + "/menu/items/" + str(sx) + "/extras/" + str(sse), - "/2/", str(sku)) - database.put("/restaurants/" + estName + "/menu/items/" + str(sx), "/inp/", "") - menu = (database.get("restaurants/" + uid, "/menu/items/")) - break - # select the first sheet - startHr = 0 - endHr = 0 - authentication = firebase.FirebaseAuthentication('if7swrlQM4k9cBvm0dmWqO3QsI5zjbcdbstSgq1W', - 'cajohn0205@gmail.com', extra={'id': 123}) - database = firebase.FirebaseApplication("https://cedarchatbot.firebaseio.com/", authentication=authentication) - menu = (database.get("restaurants/" + uid, "/menu/items/")) - hours = (database.get("restaurants/" + uid, "/Hours/")) - keys = list(hours.keys()) - for menuNames in range(len(keys)): - pdf = FPDF() - pdf.add_page() - yStart = 20 - pdf.set_font(fontName, size=24, style="BU") - text = estNameStr + " " + str([keys[menuNames]][0]) + " Menu" - pdf.multi_cell(200, 10, txt=text, align="C") - yStart += 10 - for dt in range(len(menu)): - if (menu[dt] != None): - if ((menu[dt]["sizes"][0][1] != -1)): - name = menu[dt]["name"].lower() - if (str(menu[dt]["time"]).lower() == "all" or str(menu[dt]["time"]).lower() == str( - [keys[menuNames]][0]).lower()): - name = menu[dt]["name"].lower() - sizes = [] - toppings = [] - for sz in range(len(menu[dt]["sizes"])): - sizes.append([str(menu[dt]["sizes"][sz][0]).lower(), menu[dt]["sizes"][sz][1]]) - if (str(menu[dt]["extras"][0][0]) != ""): - for ex in range(len(menu[dt]["extras"])): - toppings.append([str(menu[dt]["extras"][ex][0]).lower(), menu[dt]["extras"][ex][1]]) - # pdf.line(0, yStart, 500000, yStart) - pdf.set_font(fontName, size=18, style="B") - text = name - pdf.multi_cell(100, 10, txt=text, align="L") - yStart += 10 - text = "" - pdf.set_font(fontName, size=14, style="B") - if (len(sizes) > 1): - text = "-Sizes:" - pdf.multi_cell(100, 7, txt=text, align="L") - yStart += 7 - pdf.set_font(fontName, size=12, style="") - text = "" - for szs in range(len(sizes)): - text += " -" - text += sizes[szs][0] - text += " ~ $" + str(sizes[szs][1]) - pdf.multi_cell(100, 7, txt=text, align="L") - yStart += 7 - text = "" - else: - pdf.set_font(fontName, size=12, style="") - text += " ~$" + str(sizes[0][1]) - pdf.multi_cell(100, 7, txt=text, align="L") - yStart += 7 - text = "" - if (len(toppings) > 0): - pdf.set_font(fontName, size=14, style="B") - text = "-Toppings/Customizations:" - pdf.multi_cell(100, 7, txt=text, align="L") - yStart += 7 - text = "" - pdf.set_font(fontName, size=12, style="") - for ex in range(len(toppings)): - text += " -" - text += toppings[ex][0] - text += " ~ $" + str(toppings[ex][1]) - pdf.multi_cell(100, 7, txt=text, align="L") - yStart += 7 - text = "" - yStart += 7 - text = "" - fileName = "menus/" + estNameStr + "-" + str([keys[menuNames]][0]) + "-" + "menu.pdf" - #print(fileName) - pdf.output(fileName) - storage = firebaseAuth.storage() - storage.child(estNameStr + "/" + fileName).put(fileName) - #print("\n") - return redirect(url_for('panel')) - else: - return render_template("login.html", btn=str(estNameStr), restName=estNameStr) - - -@application.route('/' + promoPass, methods=['GET']) -def addCpn(): - currentTime = time.time() - authentication = firebase.FirebaseAuthentication('if7swrlQM4k9cBvm0dmWqO3QsI5zjbcdbstSgq1W', - 'cajohn0205@gmail.com', extra={'id': 123}) - database = firebase.FirebaseApplication("https://cedarchatbot.firebaseio.com/", authentication=authentication) - lastLogin = float(database.get("/restaurants/" + uid, "loginTime")) - #print() - if ((currentTime - lastLogin) < sessionTime): - return render_template('coupon.html', restName=estNameStr) - else: - return render_template("login.html", btn=str(estNameStr), restName=estNameStr) - - -@application.route('/' + promoPass, methods=['POST']) -def addCpnResp(): - currentTime = time.time() - authentication = firebase.FirebaseAuthentication('if7swrlQM4k9cBvm0dmWqO3QsI5zjbcdbstSgq1W', - 'cajohn0205@gmail.com', extra={'id': 123}) - database = firebase.FirebaseApplication("https://cedarchatbot.firebaseio.com/", authentication=authentication) - lastLogin = float(database.get("/restaurants/" + uid, "loginTime")) - #print() - if ((currentTime - lastLogin) < sessionTime): - request.parameter_storage_class = ImmutableOrderedMultiDict - rsp = ((request.form)) - #print(rsp) - name = rsp['name'] - item = rsp['itm'] - amt = rsp['amt'] - limit = rsp['lim'] - menuItems = database.get("/restaurants/" + estName + "/menu/", "items") - keyVal = 0 - for mmx in range(len(menuItems)): - if (menuItems[mmx] != None): - if (keyVal < mmx): - keyVal = mmx - keyVal += 1 - database.put("/restaurants/" + estName + "/menu/items/" + str(keyVal), "/name/", name) - database.put("/restaurants/" + estName + "/menu/items/" + str(keyVal), "/descrip/", " ") - database.put("/restaurants/" + estName + "/menu/items/" + str(keyVal), "/sku/", "cpn-" + name) - database.put("/restaurants/" + estName + "/menu/items/" + str(keyVal), "/sizes/0/0/", "u") - database.put("/restaurants/" + estName + "/menu/items/" + str(keyVal), "/sizes/0/1/", -1) - database.put("/restaurants/" + estName + "/menu/items/" + str(keyVal), "/extras/0/0/", item) - try: - amt = float(amt) - database.put("/restaurants/" + estName + "/menu/items/" + str(keyVal), "/extras/0/1/", amt) - except ValueError: - database.put("/restaurants/" + estName + "/menu/items/" + str(keyVal), "/extras/0/1/", amt) - database.put("/restaurants/" + estName + "/menu/items/" + str(keyVal), "/extras/1/0/", "limit") - database.put("/restaurants/" + estName + "/menu/items/" + str(keyVal), "/extras/1/1/", (limit - 1)) - menu = (database.get("restaurants/" + uid, "/menu/items/")) - return render_template('coupon.html', restName=estNameStr) - else: - return render_template("login.html", btn=str(estNameStr), restName=estNameStr) - - -@application.route("/" + uid + "check", methods=['GET']) -def loginUUID(): - return render_template("verifyCode.html", btn=str(uid + "check")) - - -@application.route('/' + uid + 'check', methods=['POST']) -def getUUID(): - request.parameter_storage_class = ImmutableOrderedMultiDict - rsp = ((request.form)) - code = rsp["tickID"] - authentication = firebase.FirebaseAuthentication('if7swrlQM4k9cBvm0dmWqO3QsI5zjbcdbstSgq1W', - 'cajohn0205@gmail.com', extra={'id': 123}) - database = firebase.FirebaseApplication("https://cedarchatbot.firebaseio.com/", authentication=authentication) - tickets = database.get("restaurants/" + uid, "/orders/") - for tx in range(len(tickets)): - if (code == tickets[tx]["number"][-4:]): - key = tx - UUID = tickets[tx]["UUID"] - session['UUID'] = UUID - session['key'] = key - return redirect(url_for('order')) - elif ((len(tickets) - tx) == 1): - return render_template("verifyCode2.html", btn=str(uid + "check")) - - -@application.route('/' + uid + 'order', methods=['GET']) -def order(): - UUID = session.get('UUID', None) - #key = session.get('key', None) - key = 0 - nameKey = session.get('nameKey', None) - itmKey = random.randint(9999, 1000000) - session['itmKey'] = itmKey - authentication = firebase.FirebaseAuthentication('if7swrlQM4k9cBvm0dmWqO3QsI5zjbcdbstSgq1W', - 'cajohn0205@gmail.com', extra={'id': 123}) - database = firebase.FirebaseApplication("https://cedarchatbot.firebaseio.com/", authentication=authentication) - data = (database.get("restaurants/" + uid, "/menu/items/")) - currentTime = str((float(datetime.datetime.now().hour)) + ((float(datetime.datetime.now().minute)) / 100.0)) - currentTotal = float(database.get("/restaurants/" + estName + "/orders/" + str(key), "/linkTotal")) - DBdata = database.get("/restaurants/" + estName, "orders") - try: - subTotal = (DBdata[key]["linkTotal"]) + DBdata[key]["discTotal"] - except KeyError: - subTotal = (DBdata[key]["linkTotal"]) - Tax = float(subTotal * 0.1) - Total = float(subTotal + float(Tax) + 0.1) - subTotalStr = ('$' + format(subTotal, ',.2f')) - TotalStr = ('$' + format(Total, ',.2f')) - TaxStr = ('$' + format(Tax, ',.2f')) - dispTotal = subTotalStr - MenuHrs = ((database.get("restaurants/" + uid, "/Hours/"))) - menKeys = list(MenuHrs.keys()) - currentMenu = "" - menuIndx = 0 - for mnx in range(len(menKeys)): - startHrMn = (float(MenuHrs[menKeys[mnx]]["startHr"])) - endHrMn = (float(MenuHrs[menKeys[mnx]]["endHr"])) - if (startHrMn <= float(currentTime) < endHrMn): - menuIndx = mnx - currentMenu = str(menKeys[mnx]) - break - authentication = firebase.FirebaseAuthentication('if7swrlQM4k9cBvm0dmWqO3QsI5zjbcdbstSgq1W', - 'cajohn0205@gmail.com', extra={'id': 123}) - database = firebase.FirebaseApplication("https://cedarchatbot.firebaseio.com/", authentication=authentication) - menuItems = database.get("/restaurants/" + estName + "/menu/", "items") - itms = database.get("/restaurants/" + estName + "/orders/" + str(key), "/item/") - currentItems = [] - currKeys = [] - if (itms != None): - dispKeys = list(itms.keys()) - for itmX in range(len(dispKeys)): - try: - if (itms[dispKeys[itmX]] != None): - wrtStr = "" - if (str(itms[dispKeys[itmX]]["size"]).lower() != "u"): - wrtStr += str(itms[dispKeys[itmX]]["size"]) - wrtStr += " " - wrtStr += str(itms[dispKeys[itmX]]["name"]) - wrtStr += " " - wrtStr += str(itms[dispKeys[itmX]]["toppings"]) - wrtStr += " " - wrtStr += str(itms[dispKeys[itmX]]["notes"]) - wrtStr += " x " - wrtStr += str(itms[dispKeys[itmX]]["qty"]) - wrtStr += " $" - wrtStr += str(itms[dispKeys[itmX]]["price"]) - currentItems.append(wrtStr) - currKeys.append(dispKeys[itmX]) - else: - wrtStr = str(itms[dispKeys[itmX]]["name"]) - wrtStr += " " - wrtStr += str(itms[dispKeys[itmX]]["toppings"]) - wrtStr += " " - wrtStr += str(itms[dispKeys[itmX]]["notes"]) - wrtStr += " x " - wrtStr += str(itms[dispKeys[itmX]]["qty"]) - wrtStr += " $" - wrtStr += str(itms[dispKeys[itmX]]["price"]) - currentItems.append(wrtStr) - currKeys.append(dispKeys[itmX]) - except KeyError: - pass - names = [] - keys = [] - descrips = [] - for men in range(len(menuItems)): - if (menuItems[men] != None and (menuItems[men]["time"] == currentMenu or menuItems[men]["time"] == "all")): - if (menuItems[men]["sizes"][0][1] != -1): - names.append(str(menuItems[men]["name"]).upper()) - descrips.append(str(menuItems[men]["descrip"]).lower()) - keys.append(men) - return render_template("mainOrder.html", len=len(names), names=names, keys=keys, btn=uid + "orderSz", - len2=(len(currentItems)),descrips=descrips ,currentItms=currentItems, currKeys=currKeys, btn2=uid + "order", - total=dispTotal, btn3=uid + "checkpayment") - - -@application.route('/' + uid + 'order', methods=['POST']) -def orderX(): - request.parameter_storage_class = ImmutableOrderedMultiDict - rsp = ((request.form)) - UUID = session.get('UUID', None) - key = session.get('key', None) - itmKey = random.randint(9999, 1000000) - session['itmKey'] = itmKey - #print(UUID, key, itmKey) - #print(rsp) - - authentication = firebase.FirebaseAuthentication('if7swrlQM4k9cBvm0dmWqO3QsI5zjbcdbstSgq1W', - 'cajohn0205@gmail.com', extra={'id': 123}) - database = firebase.FirebaseApplication("https://cedarchatbot.firebaseio.com/", authentication=authentication) - currentPrice = float( - database.get("/restaurants/" + estName + "/orders/" + str(key) + "/item/" + str((rsp["rem"])), "price")) - currentTotal = float(database.get("/restaurants/" + estName + "/orders/" + str(key), "/linkTotal")) - currentTotal -= currentPrice - DBdata = database.get("/restaurants/" + estName, "orders") - subTotal = (DBdata[key]["linkTotal"]) + DBdata[key]["discTotal"] - Tax = float(subTotal * 0.1) - Total = float(subTotal + float(Tax) + 0.15) - subTotalStr = ('$' + format(subTotal, ',.2f')) - TotalStr = ('$' + format(Total, ',.2f')) - TaxStr = ('$' + format(Tax, ',.2f')) - dispTotal = subTotalStr - database.put("/restaurants/" + estName + "/orders/" + str(key) + "/", "/linkTotal/", currentTotal) - database.delete("/restaurants/" + estName + "/orders/" + str(key) + "/item/", (rsp["rem"])) - data = (database.get("restaurants/" + uid, "/menu/items/")) - currentTime = str((float(datetime.datetime.now().hour)) + ((float(datetime.datetime.now().minute)) / 100.0)) - DBdata = database.get("/restaurants/" + estName, "orders") - MenuHrs = ((database.get("restaurants/" + uid, "/Hours/"))) - menKeys = list(MenuHrs.keys()) - currentMenu = "" - menuIndx = 0 - for mnx in range(len(menKeys)): - startHrMn = (float(MenuHrs[menKeys[mnx]]["startHr"])) - endHrMn = (float(MenuHrs[menKeys[mnx]]["endHr"])) - if (startHrMn <= float(currentTime) < endHrMn): - #print("current menu") - #print(menKeys[mnx]) - menuIndx = mnx - currentMenu = str(menKeys[mnx]) - break - session['UUID'] = UUID - session['key'] = key - authentication = firebase.FirebaseAuthentication('if7swrlQM4k9cBvm0dmWqO3QsI5zjbcdbstSgq1W', - 'cajohn0205@gmail.com', extra={'id': 123}) - database = firebase.FirebaseApplication("https://cedarchatbot.firebaseio.com/", authentication=authentication) - menuItems = database.get("/restaurants/" + estName + "/menu/", "items") - itms = database.get("/restaurants/" + estName + "/orders/" + str(key), "/item/") - currentItems = [] - currKeys = [] - finalOrd = "" - if (itms != None): - dispKeys = list(itms.keys()) - for itmX in range(len(dispKeys)): - try: - if (itms[dispKeys[itmX]] != None): - wrtStr = "" - if (str(itms[dispKeys[itmX]]["size"]).lower() != "u"): - wrtStr += str(itms[dispKeys[itmX]]["size"]) - wrtStr += " " - wrtStr += str(itms[dispKeys[itmX]]["name"]) - wrtStr += " " - wrtStr += str(itms[dispKeys[itmX]]["toppings"]) - wrtStr += " " - wrtStr += str(itms[dispKeys[itmX]]["notes"]) - wrtStr += " x " - wrtStr += str(itms[dispKeys[itmX]]["qty"]) - wrtStr += " $" - wrtStr += str(itms[dispKeys[itmX]]["price"]) - currentItems.append(wrtStr) - currKeys.append(dispKeys[itmX]) - #print(wrtStr) - else: - wrtStr = str(itms[dispKeys[itmX]]["name"]) - wrtStr += " " - wrtStr += str(itms[dispKeys[itmX]]["toppings"]) - wrtStr += " " - wrtStr += str(itms[dispKeys[itmX]]["notes"]) - wrtStr += " x " - wrtStr += str(itms[dispKeys[itmX]]["qty"]) - wrtStr += " $" - wrtStr += str(itms[dispKeys[itmX]]["price"]) - currentItems.append(wrtStr) - currKeys.append(dispKeys[itmX]) - #print(wrtStr) - except KeyError: - pass - else: - dispTotal = "$0.00" - names = [] - keys = [] - descrips = [] - #print(type(menuItems)) - for men in range(len(menuItems)): - if (menuItems[men] != None and (menuItems[men]["time"] == currentMenu or menuItems[men]["time"] == "all")): - if (menuItems[men]["sizes"][0][1] != -1): - names.append(str(menuItems[men]["name"]).upper()) - descrips.append(str(menuItems[men]["descrip"]).lower()) - keys.append(men) - return render_template("mainOrderBtn.html", len=len(names), names=names, keys=keys, btn=uid + "orderSz", - len2=(len(currentItems)), descrips=descrips ,currentItms=currentItems, total=dispTotal, currKeys=currKeys, - btn2=uid + "order", btn3=uid + "checkpayment") - - -@application.route('/' + uid + 'orderSz', methods=['POST']) -def orderNm(): - newItmKey = session.get('itmKey', None) - UUID = session.get('UUID', None) - key = session.get('key', None) - #print(UUID, key) - request.parameter_storage_class = ImmutableOrderedMultiDict - rsp = ((request.form)) - names = [] - keys = [] - prices = [] - authentication = firebase.FirebaseAuthentication('if7swrlQM4k9cBvm0dmWqO3QsI5zjbcdbstSgq1W', - 'cajohn0205@gmail.com', extra={'id': 123}) - database = firebase.FirebaseApplication("https://cedarchatbot.firebaseio.com/", authentication=authentication) - menuItems = database.get("/restaurants/" + estName + "/menu/", "items") - numItms = database.get("/restaurants/" + estName + "/orders/" + str(key), "item") - database.put("/restaurants/" + estName + "/orders/" + str(key) + "/", "/item/" + str(newItmKey) + "/name/", - str(menuItems[int(rsp['item'])]['name'].lower())) - sizes = menuItems[int(rsp['item'])]['sizes'] - for sz in range(len(sizes)): - if ((menuItems[int(rsp['item'])]['sizes'][sz][0].lower()) != "u"): - putStr = "" - putStr += str(menuItems[int(rsp['item'])]['sizes'][sz][0]).lower() - putStr += " $" - putStr += str(menuItems[int(rsp['item'])]['sizes'][sz][1]) - names.append(putStr) - keys.append(sz) - prices.append(menuItems[int(rsp['item'])]['sizes'][sz][1]) - else: - names.append("Standard") - keys.append(0) - prices.append(menuItems[int(rsp['item'])]['sizes'][sz][1]) - session['itmKey'] = newItmKey - session['nameKey'] = int(rsp['item']) - return render_template("picksize.html", len=len(prices), names=names, keys=keys, prices=prices, - btn=uid + "ordertopping") - - -@application.route('/' + uid + 'ordertopping', methods=['POST']) -def ordertp(): - request.parameter_storage_class = ImmutableOrderedMultiDict - rsp = ((request.form)) - UUID = session.get('UUID', None) - key = session.get('key', None) - itmKey = session.get('itmKey', None) - nameKey = session.get('nameKey', None) - authentication = firebase.FirebaseAuthentication('if7swrlQM4k9cBvm0dmWqO3QsI5zjbcdbstSgq1W', - 'cajohn0205@gmail.com', extra={'id': 123}) - database = firebase.FirebaseApplication("https://cedarchatbot.firebaseio.com/", authentication=authentication) - menuItems = database.get("/restaurants/" + estName + "/menu/", "items") - #print(menuItems[nameKey], "current item") - database.put("/restaurants/" + estName + "/orders/" + str(key) + "/", "/item/" + str(itmKey) + "/size/", - str(menuItems[nameKey]['sizes'][int(rsp['item'])][0].lower())) - database.put("/restaurants/" + estName + "/orders/" + str(key) + "/", "/item/" + str(itmKey) + "/price/", - float(menuItems[nameKey]['sizes'][int(rsp['item'])][1])) - skuKey = random.randint(99999, 1000000) - database.put("/restaurants/" + estName + "/orders/" + str(key) + "/", - "/item/" + str(itmKey) + "/skus/" + str(skuKey) + "/", - str(menuItems[nameKey]['sizes'][int(rsp['item'])][2])) - names = [] - keys = [] - prices = [] - authentication = firebase.FirebaseAuthentication('if7swrlQM4k9cBvm0dmWqO3QsI5zjbcdbstSgq1W', - 'cajohn0205@gmail.com', extra={'id': 123}) - database = firebase.FirebaseApplication("https://cedarchatbot.firebaseio.com/", authentication=authentication) - menuItems = database.get("/restaurants/" + estName + "/menu/", "items") - toppings = menuItems[nameKey]["extras"] - names = [] - keys = [] - for ex in range(len(toppings)): - if (toppings[ex][0] != ""): - putStr = "" - putStr += str(toppings[ex][0].lower()) - putStr += " $" - putStr += str(toppings[ex][1]) - names.append(putStr) - keys.append(ex) - #print(rsp) - return render_template("pickToppings.html", len=len(names), names=names, keys=keys, prices=prices, - btn=uid + "ordertoppingConfirm") - - -@application.route('/' + uid + 'ordertoppingConfirm', methods=['POST']) -def ConfirmItm(): - UUID = session.get('UUID', None) - key = session.get('key', None) - itmKey = session.get('itmKey', None) - nameKey = session.get('nameKey', None) - #print("nameKEY", nameKey) - request.parameter_storage_class = ImmutableOrderedMultiDict - rsp = ((request.form)) - authentication = firebase.FirebaseAuthentication('if7swrlQM4k9cBvm0dmWqO3QsI5zjbcdbstSgq1W', - 'cajohn0205@gmail.com', extra={'id': 123}) - database = firebase.FirebaseApplication("https://cedarchatbot.firebaseio.com/", authentication=authentication) - menuItems = database.get("/restaurants/" + estName + "/menu/", "items") - #print(menuItems[nameKey], "topping") - #print(rsp, "rsp") - #print(len(rsp)) - putStr = "" - addPrice = 0 - extraIndxs = [] - SKUSarr = [] - if (len(rsp) > 2): - #print(rsp["quantity"]) - #print(rsp["notes"]) - for itx in range(len(menuItems[nameKey]["extras"])): - ##print(itx) - try: - #print(rsp[str(itx)], "found") - extraIndxs.append(int(itx)) - except Exception: - #print(str(itx), "not found") - pass - #print(extraIndxs) - for exx in range(len(extraIndxs)): - putStr += str(menuItems[nameKey]["extras"][extraIndxs[exx]][0]) - #print(menuItems[nameKey]["extras"][extraIndxs[exx]]) - addPrice += float(menuItems[nameKey]["extras"][extraIndxs[exx]][1]) - addPrice = round(addPrice, 2) - putStr += " " - SKUSarr.append(str(menuItems[nameKey]["extras"][extraIndxs[exx]][2])) - skuKey = random.randint(99999, 1000000) - database.put("/restaurants/" + estName + "/orders/" + str(key) + "/", - "/item/" + str(itmKey) + "/skus/" + str(skuKey) + "/", - str(menuItems[nameKey]["extras"][extraIndxs[exx]][2])) - currentPrice = float( - database.get("/restaurants/" + estName + "/orders/" + str(key) + "/item/" + str(itmKey), "price")) - currentPrice += addPrice - round(currentPrice, 2) - database.put("/restaurants/" + estName + "/orders/" + str(key) + "/", "/item/" + str(itmKey) + "/toppings/", - putStr) - database.put("/restaurants/" + estName + "/orders/" + str(key) + "/", "/item/" + str(itmKey) + "/notes/", - putStr) - if (rsp["quantity"] == ""): - database.put("/restaurants/" + estName + "/orders/" + str(key) + "/", "/item/" + str(itmKey) + "/qty/", 1) - else: - database.put("/restaurants/" + estName + "/orders/" + str(key) + "/", "/item/" + str(itmKey) + "/qty/", - int(rsp["quantity"])) - currentPrice = currentPrice * int(rsp["quantity"]) - #print(currentPrice) - database.put("/restaurants/" + estName + "/orders/" + str(key) + "/", "/item/" + str(itmKey) + "/notes/", - rsp["notes"]) - database.put("/restaurants/" + estName + "/orders/" + str(key) + "/", "/item/" + str(itmKey) + "/price/", - currentPrice) - currentTotal = float(database.get("/restaurants/" + estName + "/orders/" + str(key), "/linkTotal")) - currentTotal += currentPrice - database.put("/restaurants/" + estName + "/orders/" + str(key) + "/", "/linkTotal/", currentTotal) - else: - currentPrice = float( - database.get("/restaurants/" + estName + "/orders/" + str(key) + "/item/" + str(itmKey), "price")) - round(currentPrice, 2) - database.put("/restaurants/" + estName + "/orders/" + str(key) + "/", "/item/" + str(itmKey) + "/toppings/", - putStr) - database.put("/restaurants/" + estName + "/orders/" + str(key) + "/", "/item/" + str(itmKey) + "/notes/", - putStr) - if (rsp["quantity"] == ""): - database.put("/restaurants/" + estName + "/orders/" + str(key) + "/", "/item/" + str(itmKey) + "/qty/", 1) - currentTotal = float(database.get("/restaurants/" + estName + "/orders/" + str(key), "/linkTotal")) - currentTotal += currentPrice - round(currentPrice, 2) - database.put("/restaurants/" + estName + "/orders/" + str(key) + "/", "/linkTotal/", currentTotal) - else: - database.put("/restaurants/" + estName + "/orders/" + str(key) + "/", "/item/" + str(itmKey) + "/qty/", - int(rsp["quantity"])) - currentPrice = currentPrice * int(rsp["quantity"]) - #print(currentPrice) - database.put("/restaurants/" + estName + "/orders/" + str(key) + "/", "/item/" + str(itmKey) + "/notes/", - rsp["notes"]) - currentPrice = float( - database.get("/restaurants/" + estName + "/orders/" + str(key) + "/item/" + str(itmKey), "price")) - round(currentPrice, 2) - currentTotal = float(database.get("/restaurants/" + estName + "/orders/" + str(key), "/linkTotal")) - currentTotal += currentPrice - database.put("/restaurants/" + estName + "/orders/" + str(key) + "/", "/linkTotal/", currentTotal) - return redirect(url_for('order')) - - -@application.route('/' + uid + 'checkpayment', methods=['POST']) -def CheckPaymentMethod(): - UUID = session.get('UUID', None) - key = session.get('key', None) - authentication = firebase.FirebaseAuthentication('if7swrlQM4k9cBvm0dmWqO3QsI5zjbcdbstSgq1W', - 'cajohn0205@gmail.com', extra={'id': 123}) - database = firebase.FirebaseApplication("https://cedarchatbot.firebaseio.com/", authentication=authentication) - itms = database.get("/restaurants/" + estName + "/orders/" + str(key), "/item/") - menuItems = database.get("/restaurants/" + estName + "/menu/", "items") - if (itms != None): - finalOrd = "" - dispKeys = list(itms.keys()) - for itmX in range(len(dispKeys)): - if (itms[dispKeys[itmX]] != None): - #print(itms[dispKeys[itmX]]) - skuKeys = list(itms[dispKeys[itmX]]["skus"].keys()) - wrtStr = "" - if (str(itms[dispKeys[itmX]]["size"]).lower() != "u"): - wrtStr += str(itms[dispKeys[itmX]]["size"]) - wrtStr += " " - #print(wrtStr) - #print(str(itms[dispKeys[itmX]]["size"])) - wrtStr += str(itms[dispKeys[itmX]]["name"]) - wrtStr += " " - wrtStr += str(itms[dispKeys[itmX]]["toppings"]) - wrtStr += " " - wrtStr += str(itms[dispKeys[itmX]]["notes"]) - wrtStr += " x " - wrtStr += str(itms[dispKeys[itmX]]["qty"]) - wrtStr += " $" - wrtStr += str(round(itms[dispKeys[itmX]]["price"], 2)) - #print(wrtStr) - finalOrd += wrtStr + " :: " - skuKeyItm = list(itms[dispKeys[itmX]]["skus"].keys()) - for skk in range(len(skuKeyItm)): - currentSkuItm = itms[dispKeys[itmX]]["skus"][skuKeyItm[skk]] - for mmn in range(len(menuItems)): - if (menuItems[mmn] != None): - if (menuItems[mmn]["sizes"][0][1] == -1 and menuItems[mmn]["descrip"] != "REMOVEDITM!"): - if (str(menuItems[mmn]["extras"][0][0]) == str(currentSkuItm)): - #print("ggbrgebrgebr") - discAmt = menuItems[mmn]["extras"][0][1] - limit = int(menuItems[mmn]["extras"][1][1]) - cpnUsed = int( - database.get("/restaurants/" + estName + "/orders/" + str(key), - "/discUsed/")) - discTotal = float( - database.get("/restaurants/" + estName + "/orders/" + str(key), - "/discTotal/")) - #print(cpnUsed, limit, discTotal) - if (cpnUsed <= limit): - try: - float(discAmt) - discAmtflt = float(discAmt) - #print(cpnUsed, limit, int(itms[dispKeys[itmX]]["qty"])) - while cpnUsed <= limit and cpnUsed <= int(itms[dispKeys[itmX]]["qty"]): - #print("iid") - discTotal -= discAmtflt - cpnUsed += 1 - except ValueError: - discAmt = discAmt[:-1] - discAmtflt = float(discAmt) - #print(discAmtflt) - #print(cpnUsed, limit, int(itms[dispKeys[itmX]]["qty"])) - while cpnUsed <= limit and cpnUsed <= int(itms[dispKeys[itmX]]["qty"]): - discTotal -= (float(discAmtflt) * ( - (float(itms[dispKeys[itmX]]["price"])) / float( - itms[dispKeys[itmX]]["qty"]))) - #print(discTotal) - cpnUsed += 1 - #print(cpnUsed) - #print(discTotal) - #print(cpnUsed) - database.put("/restaurants/" + estName + "/orders/" + str(key) + "/", - "/discUsed/", cpnUsed) - database.put("/restaurants/" + estName + "/orders/" + str(key) + "/", - "/discTotal/", discTotal) - database.put( - "/restaurants/" + estName + "/orders/" + str(key) + "/", - "/discStr/", str( - str(menuItems[mmn]["name"]) + " x " + str( - cpnUsed) + " -$" + str(float(discTotal * -1)))) - finalOrd += menuItems[mmn]["name"] + " x " + str(cpnUsed) + " -$" + str( - float( - discTotal * -1)) + " :: " - break - else: - wrtStr = str(itms[dispKeys[itmX]]["name"]) - wrtStr += " " - wrtStr += str(itms[dispKeys[itmX]]["toppings"]) - wrtStr += " " - wrtStr += str(itms[dispKeys[itmX]]["notes"]) - wrtStr += " x " - wrtStr += str(itms[dispKeys[itmX]]["qty"]) - wrtStr += " $" - wrtStr += str(round(itms[dispKeys[itmX]]["price"], 2)) - #print(wrtStr) - finalOrd += wrtStr + " :: " - skuKeyItm = list(itms[dispKeys[itmX]]["skus"].keys()) - for skk in range(len(skuKeyItm)): - currentSkuItm = itms[dispKeys[itmX]]["skus"][skuKeyItm[skk]] - for mmn in range(len(menuItems)): - if (menuItems[mmn] != None): - if (menuItems[mmn]["sizes"][0][1] == -1 and menuItems[mmn]["descrip"] != "REMOVEDITM!"): - if (str(menuItems[mmn]["extras"][0][0]) == str(currentSkuItm)): - discAmt = menuItems[mmn]["extras"][0][1] - limit = int(menuItems[mmn]["extras"][1][1]) - cpnUsed = int( - database.get("/restaurants/" + estName + "/orders/" + str(key), - "/discUsed/")) - discTotal = float( - database.get("/restaurants/" + estName + "/orders/" + str(key), - "/discTotal/")) - if (cpnUsed <= limit): - try: - float(discAmt) - discAmtflt = float(discAmt) - while cpnUsed < limit and cpnUsed < int( - itms[dispKeys[itmX]]["qty"]): - discTotal -= discAmtflt - cpnUsed += 1 - except ValueError: - discAmt = discAmt[:-1] - discAmtflt = float(discAmt) - #print(cpnUsed, limit, int(itms[dispKeys[itmX]]["qty"])) - while cpnUsed < limit and cpnUsed < int( - itms[dispKeys[itmX]]["qty"]): - #print(cpnUsed) - #print("fsfwrrw") - discTotal -= float( - float(discAmtflt) * float(itms[dispKeys[itmX]]["price"])) - #print(discTotal) - cpnUsed += 1 - #print(discTotal) - database.put("/restaurants/" + estName + "/orders/" + str(key) + "/", - "/discUsed/", cpnUsed) - database.put("/restaurants/" + estName + "/orders/" + str(key) + "/", - "/discTotal/", discTotal) - database.put( - "/restaurants/" + estName + "/orders/" + str(key) + "/", - "/discStr/", str( - str(menuItems[mmn]["name"]) + " x " + str( - cpnUsed) + ":: -$" + str(round(float(discTotal * -1), 2)))) - finalOrd += menuItems[mmn]["name"] + " x " + str( - cpnUsed) + ":: -$" + str(round(float(discTotal * -1), 2)) + " :: " - break - - DBdata = database.get("/restaurants/" + estName, "orders") - subTotal = (DBdata[key]["linkTotal"]) - subTotal += DBdata[key]["discTotal"] - #print(subTotal) - disc = (DBdata[key]["discStr"]) - Tax = float(subTotal * 0.1) - Total = float(subTotal + float(Tax) + 0.15) - subTotalStr = ('$' + format(subTotal, ',.2f')) - TotalStr = ('$' + format(Total, ',.2f')) - TaxStr = ('$' + format(Tax, ',.2f')) - return render_template("paymentMethod.html", btn=uid + "nextPay", subTotal=subTotalStr, tax=TaxStr, total=TotalStr, - CPN=disc) - - -@application.route('/' + uid + 'nextPay', methods=['POST']) -def nextPayment(): - logYM = (datetime.datetime.now().strftime("%Y-%m")) - UUID = session.get('UUID', None) - key = session.get('key', None) - dbItems = key - authentication = firebase.FirebaseAuthentication('if7swrlQM4k9cBvm0dmWqO3QsI5zjbcdbstSgq1W', - 'cajohn0205@gmail.com', extra={'id': 123}) - database = firebase.FirebaseApplication("https://cedarchatbot.firebaseio.com/", authentication=authentication) - menuItems = database.get("/restaurants/" + estName + "/menu/", "items") - logData = database.get("/log/" + uid + "/", logYM) - if (logData == None): - database.put("/log/" + uid + "/" + logYM, "/newCustomers/", 0) - database.put("/log/" + uid + "/" + logYM, "/retCustomers/", 0) - database.put("/log/" + uid + "/" + logYM, "/paypalFees/", 0.0) - database.put("/log/" + uid + "/" + logYM, "/CedarFees/", 0.0) - database.put("/log/" + uid + "/" + logYM, "/totalRev/", 0.0) - database.put("/log/" + uid + "/" + logYM, "/skus/9Null/numSold", 0) - database.put("/log/" + uid + "/" + logYM, "/skus/9Null/rev", 0) - currentTotal = float(database.get("/restaurants/" + estName + "/orders/" + str(key), "/linkTotal")) - number = str(database.get("/restaurants/" + estName + "/orders/" + str(key), "/number")) - request.parameter_storage_class = ImmutableOrderedMultiDict - rsp = ((request.form)) - #print(rsp) - finalOrd = "" - if (rsp["item"] == "yes"): - itms = database.get("/restaurants/" + estName + "/orders/" + str(key), "/item/") - itms = database.get("/restaurants/" + estName + "/orders/" + str(key), "/item/") - if (itms != None): - finalOrd = "" - dispKeys = list(itms.keys()) - for itmX in range(len(dispKeys)): - try: - if (itms[dispKeys[itmX]] != None): - #print(itms[dispKeys[itmX]]) - skuKeys = list(itms[dispKeys[itmX]]["skus"].keys()) - for sk in range(len(skuKeys)): - currentSku = database.get("/log/" + estName + "/" + str(logYM) + "/" + "skus/", - itms[dispKeys[itmX]]["skus"][skuKeys[sk]]) - if (currentSku != None): - numsold = currentSku["numSold"] + int(itms[dispKeys[itmX]]["qty"]) - rev = currentSku["rev"] + ( - float(itms[dispKeys[itmX]]["qty"]) * float(itms[dispKeys[itmX]]["price"])) - database.put("/log/" + uid + "/" + logYM, - "/skus/" + str(itms[dispKeys[itmX]]["skus"][skuKeys[sk]]) + "/rev/", rev) - database.put("/log/" + uid + "/" + logYM, - "/skus/" + str(itms[dispKeys[itmX]]["skus"][skuKeys[sk]]) + "/numSold/", - numsold) - else: - numsold = int(itms[dispKeys[itmX]]["qty"]) - rev = (float(itms[dispKeys[itmX]]["qty"]) * float(itms[dispKeys[itmX]]["price"])) - database.put("/log/" + uid + "/" + logYM, - "/skus/" + str(itms[dispKeys[itmX]]["skus"][skuKeys[sk]]) + "/rev/", rev) - database.put("/log/" + uid + "/" + logYM, - "/skus/" + str(itms[dispKeys[itmX]]["skus"][skuKeys[sk]]) + "/numSold/", - numsold) - wrtStr = "" - if (str(itms[dispKeys[itmX]]["size"]).lower() != "u"): - wrtStr += str(itms[dispKeys[itmX]]["size"]) - wrtStr += " " - #print(wrtStr) - #print(str(itms[dispKeys[itmX]]["size"])) - wrtStr += str(itms[dispKeys[itmX]]["name"]) - wrtStr += " " - wrtStr += str(itms[dispKeys[itmX]]["toppings"]) - wrtStr += " " - wrtStr += str(itms[dispKeys[itmX]]["notes"]) - wrtStr += " x " - wrtStr += str(itms[dispKeys[itmX]]["qty"]) - wrtStr += " $" - wrtStr += str(round(itms[dispKeys[itmX]]["price"], 2)) - #print(wrtStr) - finalOrd += wrtStr + " :: " - skuKeyItm = list(itms[dispKeys[itmX]]["skus"].keys()) - for skk in range(len(skuKeyItm)): - currentSkuItm = itms[dispKeys[itmX]]["skus"][skuKeyItm[skk]] - for mmn in range(len(menuItems)): - if (menuItems[mmn] != None): - if (menuItems[mmn]["sizes"][0][1] == -1 and menuItems[mmn]["descrip"] != "REMOVEDITM!"): - if (str(menuItems[mmn]["extras"][0][0]) == str(currentSkuItm)): - discAmt = menuItems[mmn]["extras"][0][1] - limit = int(menuItems[mmn]["extras"][1][1]) - cpnUsed = int( - database.get("/restaurants/" + estName + "/orders/" + str(key), - "/discUsed/")) - discTotal = float( - database.get("/restaurants/" + estName + "/orders/" + str(key), - "/discTotal/")) - if (cpnUsed <= limit): - try: - float(discAmt) - discAmtflt = float(discAmt) - while cpnUsed < limit and cpnUsed < int( - itms[dispKeys[itmX]]["qty"]): - discTotal -= discAmtflt - cpnUsed += 1 - except ValueError: - discAmt = discAmt[:-1] - discAmtflt = float(discAmt) - while cpnUsed < limit and cpnUsed < int( - itms[dispKeys[itmX]]["qty"]): - discTotal -= (float(discAmtflt) * ( - (float(itms[dispKeys[itmX]]["price"])) / float( - itms[dispKeys[itmX]]["qty"]))) - cpnUsed += 1 - database.put( - "/restaurants/" + estName + "/orders/" + str(key) + "/", - "/discUsed/", cpnUsed) - database.put( - "/restaurants/" + estName + "/orders/" + str(key) + "/", - "/discTotal/", discTotal) - database.put( - "/restaurants/" + estName + "/orders/" + str(key) + "/", - "/discStr/", str( - str(menuItems[mmn]["name"]) + " x " + str( - cpnUsed) + " -$" + str(float(discTotal * -1)))) - - finalOrd += menuItems[mmn]["name"] + " x " + str( - cpnUsed) + " -$" + str(round((discTotal * -1), 2)) + " :: " - break - else: - wrtStr = str(itms[dispKeys[itmX]]["name"]) - wrtStr += " " - wrtStr += str(itms[dispKeys[itmX]]["toppings"]) - wrtStr += " " - wrtStr += str(itms[dispKeys[itmX]]["notes"]) - wrtStr += " x " - wrtStr += str(itms[dispKeys[itmX]]["qty"]) - wrtStr += " $" - wrtStr += str(round(itms[dispKeys[itmX]]["price"], 2)) - #print(wrtStr) - finalOrd += wrtStr + " :: " - skuKeyItm = list(itms[dispKeys[itmX]]["skus"].keys()) - for skk in range(len(skuKeyItm)): - currentSkuItm = itms[dispKeys[itmX]]["skus"][skuKeyItm[skk]] - for mmn in range(len(menuItems)): - if (menuItems[mmn] != None): - if (menuItems[mmn]["sizes"][0][1] == -1 and menuItems[mmn]["descrip"] != "REMOVEDITM!"): - if (str(menuItems[mmn]["extras"][0][0]) == str(currentSkuItm)): - discAmt = menuItems[mmn]["extras"][0][1] - limit = int(menuItems[mmn]["extras"][1][1]) - cpnUsed = int( - database.get("/restaurants/" + estName + "/orders/" + str(key), - "/discUsed/")) - discTotal = float( - database.get("/restaurants/" + estName + "/orders/" + str(key), - "/discTotal/")) - if (cpnUsed <= limit): - try: - float(discAmt) - discAmtflt = float(discAmt) - while cpnUsed < limit and cpnUsed < int( - itms[dispKeys[itmX]]["qty"]): - discTotal -= discAmtflt - cpnUsed += 1 - except ValueError: - discAmt = discAmt[:-1] - discAmtflt = float(discAmt) - while cpnUsed < limit and cpnUsed < int( - itms[dispKeys[itmX]]["qty"]): - discTotal -= (float(discAmtflt) * float( - itms[dispKeys[itmX]]["price"])) - cpnUsed += 1 - database.put( - "/restaurants/" + estName + "/orders/" + str(key) + "/", - "/discUsed/", cpnUsed) - database.put( - "/restaurants/" + estName + "/orders/" + str(key) + "/", - "/discTotal/", discTotal) - database.put( - "/restaurants/" + estName + "/orders/" + str(key) + "/", - "/discStr/", str( - str(menuItems[mmn]["name"]) + " x " + str( - cpnUsed) + " -$" + str(float(discTotal * -1)))) - finalOrd += menuItems[mmn]["name"] + " x " + str( - cpnUsed) + " -$" + str(round((discTotal * -1), 2)) + " :: " - break - except KeyError: - #print("exec") - pass - #print(finalOrd) - database.put("/restaurants/" + estName + "/orders/" + str(dbItems) + "/", "finalOrder/", finalOrd) - #print("final put") - DBdata = database.get("/restaurants/" + estName, "orders") - subTotal = float(DBdata[key]["linkTotal"]) - subTotal += DBdata[dbItems]["discTotal"] - Tax = str(round((float(subTotal * 0.1), 2))) - Total = str(round((float(subTotal) + float(Tax) + 0.15), 2)) - link = str(genPayment(str(Total), "", UUID)) - session.clear() - return redirect(link) - else: - authentication = firebase.FirebaseAuthentication('if7swrlQM4k9cBvm0dmWqO3QsI5zjbcdbstSgq1W', - 'cajohn0205@gmail.com', extra={'id': 123}) - database = firebase.FirebaseApplication("https://cedarchatbot.firebaseio.com/", - authentication=authentication) - itms = database.get("/restaurants/" + estName + "/orders/" + str(key), "/item/") - finalOrd = "" - if (itms != None): - finalOrd = "" - dispKeys = list(itms.keys()) - for itmX in range(len(dispKeys)): - wrtStr = "" - if (str(itms[dispKeys[itmX]]["size"]).lower() != "u"): - wrtStr += str(itms[dispKeys[itmX]]["size"]) - wrtStr += " " - #print(wrtStr) - #print(str(itms[dispKeys[itmX]]["size"])) - wrtStr += str(itms[dispKeys[itmX]]["name"]) - wrtStr += " " - wrtStr += str(itms[dispKeys[itmX]]["toppings"]) - wrtStr += " " - wrtStr += str(itms[dispKeys[itmX]]["notes"]) - wrtStr += " x " - wrtStr += str(itms[dispKeys[itmX]]["qty"]) - wrtStr += " $" - wrtStr += str(round(itms[dispKeys[itmX]]["price"], 2)) - #print(wrtStr) - finalOrd += wrtStr + " :: " - skuKeyItm = list(itms[dispKeys[itmX]]["skus"].keys()) - for skk in range(len(skuKeyItm)): - currentSkuItm = itms[dispKeys[itmX]]["skus"][skuKeyItm[skk]] - for mmn in range(len(menuItems)): - if (menuItems[mmn] != None): - if (menuItems[mmn]["sizes"][0][1] == -1 and menuItems[mmn]["descrip"] != "REMOVEDITM!"): - if (str(menuItems[mmn]["extras"][0][0]) == str(currentSkuItm)): - discAmt = menuItems[mmn]["extras"][0][1] - limit = int(menuItems[mmn]["extras"][1][1]) - cpnUsed = int(database.get("/restaurants/" + estName + "/orders/" + str(key), - "/discUsed/")) - discTotal = float( - database.get("/restaurants/" + estName + "/orders/" + str(key), - "/discTotal/")) - if (cpnUsed <= - limit): - try: - float(discAmt) - discAmtflt = float(discAmt) - while cpnUsed < limit and cpnUsed < int(itms[dispKeys[itmX]]["qty"]): - discTotal -= discAmtflt - cpnUsed += 1 - except ValueError: - discAmt = discAmt[:-1] - discAmtflt = float(discAmt) - while cpnUsed < limit and cpnUsed < int(itms[dispKeys[itmX]]["qty"]): - discTotal -= (float(discAmtflt) * float( - itms[dispKeys[itmX]]["price"])) - #print(discTotal) - cpnUsed += 1 - database.put("/restaurants/" + estName + "/orders/" + str(key) + "/", - "/discUsed/", cpnUsed) - database.put("/restaurants/" + estName + "/orders/" + str(key) + "/", - "/discTotal/", discTotal) - database.put( - "/restaurants/" + estName + "/orders/" + str(key) + "/", - "/discStr/", str( - str(menuItems[mmn]["name"]) + " x " + str( - cpnUsed) + " -$" + str(float(discTotal * -1)))) - finalOrd += menuItems[mmn]["name"] + " x " + str(cpnUsed) + " -$" + str( - round(( - discTotal * -1), 2)) + " :: " - break - - else: - wrtStr = str(itms[dispKeys[itmX]]["name"]) - wrtStr += " " - wrtStr += str(itms[dispKeys[itmX]]["toppings"]) - wrtStr += " " - wrtStr += str(itms[dispKeys[itmX]]["notes"]) - wrtStr += " x " - wrtStr += str(itms[dispKeys[itmX]]["qty"]) - wrtStr += " $" - wrtStr += str(round(itms[dispKeys[itmX]]["price"], 2)) - #print(wrtStr) - finalOrd += wrtStr + " :: " - skuKeyItm = list(itms[dispKeys[itmX]]["skus"].keys()) - for skk in range(len(skuKeyItm)): - currentSkuItm = itms[dispKeys[itmX]]["skus"][skuKeyItm[skk]] - for mmn in range(len(menuItems)): - if (menuItems[mmn] != None): - if (menuItems[mmn]["sizes"][0][1] == -1 and menuItems[mmn]["descrip"] != "REMOVEDITM!"): - if (str(menuItems[mmn]["extras"][0][0]) == str(currentSkuItm)): - discAmt = menuItems[mmn]["extras"][0][1] - limit = int(menuItems[mmn]["extras"][1][1]) - cpnUsed = int(database.get("/restaurants/" + estName + "/orders/" + str(key), - "/discUsed/")) - discTotal = float( - database.get("/restaurants/" + estName + "/orders/" + str(key), - "/discTotal/")) - if (cpnUsed <= limit): - try: - float(discAmt) - discAmtflt = float(discAmt) - while cpnUsed < limit and cpnUsed < int(itms[dispKeys[itmX]]["qty"]): - discTotal -= discAmtflt - cpnUsed += 1 - except ValueError: - discAmt = discAmt[:-1] - discAmtflt = float(discAmt) - while cpnUsed < limit and cpnUsed < int(itms[dispKeys[itmX]]["qty"]): - #print(discAmtflt, "effee") - discTotal -= (float(discAmtflt) * float( - itms[dispKeys[itmX]]["price"])) - #print(discTotal) - cpnUsed += 1 - database.put("/restaurants/" + estName + "/orders/" + str(key) + "/", - "/discUsed/", cpnUsed) - database.put("/restaurants/" + estName + "/orders/" + str(key) + "/", - "/discTotal/", discTotal) - database.put( - "/restaurants/" + estName + "/orders/" + str(key) + "/", - "/discStr/", str( - str(menuItems[mmn]["name"]) + " x " + str( - cpnUsed) + " -$" + str(float(discTotal * -1)))) - finalOrd += menuItems[mmn]["name"] + " x " + str(cpnUsed) + " -$" + str( - round(( - discTotal * -1), 2)) + " :: " - break - if (itms[dispKeys[itmX]] != None): - #print(itms[dispKeys[itmX]]) - skuKeys = list(itms[dispKeys[itmX]]["skus"].keys()) - for sk in range(len(skuKeys)): - currentSku = database.get("/log/" + estName + "/" + str(logYM) + "/" + "skus/", - itms[dispKeys[itmX]]["skus"][skuKeys[sk]]) - if (currentSku != None): - numsold = currentSku["numSold"] + int(itms[dispKeys[itmX]]["qty"]) - rev = currentSku["rev"] + ( - float(itms[dispKeys[itmX]]["qty"]) * float(itms[dispKeys[itmX]]["price"])) - database.put("/log/" + uid + "/" + logYM, - "/skus/" + str(itms[dispKeys[itmX]]["skus"][skuKeys[sk]]) + "/rev/", rev) - database.put("/log/" + uid + "/" + logYM, - "/skus/" + str(itms[dispKeys[itmX]]["skus"][skuKeys[sk]]) + "/numSold/", - numsold) - else: - numsold = int(itms[dispKeys[itmX]]["qty"]) - rev = (float(itms[dispKeys[itmX]]["qty"]) * float(itms[dispKeys[itmX]]["price"])) - database.put("/log/" + uid + "/" + logYM, - "/skus/" + str(itms[dispKeys[itmX]]["skus"][skuKeys[sk]]) + "/rev/", rev) - database.put("/log/" + uid + "/" + logYM, - "/skus/" + str(itms[dispKeys[itmX]]["skus"][skuKeys[sk]]) + "/numSold/", - numsold) - - #print(finalOrd) - database.put("/restaurants/" + estName + "/orders/" + str(dbItems) + "/", "finalOrder/", finalOrd) - #print(finalOrd, "put") - DBdata = database.get("/restaurants/" + estName, "orders") - duration = time.time() - float(DBdata[dbItems]["startTime"]) - subTotal = float(DBdata[key]["linkTotal"]) - subTotal += DBdata[dbItems]["discTotal"] - Total = round(((subTotal + 0.15) * 1.1), 2) - numItms = len(DBdata[dbItems]["item"]) - orderIndx = DBdata[dbItems]["orderIndx"] - usrIndx = DBdata[dbItems]["userIndx"] - database.put("/users/" + str(usrIndx) + "/restaurants/" + estNameStr + "/" + str(orderIndx) + "/", "total", - Total) - database.put("/users/" + str(usrIndx) + "/restaurants/" + estNameStr + "/" + str(orderIndx) + "/", "tickSize", - numItms) - database.put("/users/" + str(usrIndx) + "/restaurants/" + estNameStr + "/" + str(orderIndx) + "/", "items", - DBdata[dbItems]["item"]) - database.put("/users/" + str(usrIndx) + "/restaurants/" + estNameStr + "/" + str(orderIndx) + "/", "duration", - duration) - database.put("/restaurants/" + estName + "/orders/" + str(dbItems) + "/", "finalOrder/", finalOrd) - database.put("/restaurants/" + estName + "/orders/" + str(dbItems) + "/", "tickSize/", numItms) - database.put("/restaurants/" + estName + "/orders/" + str(dbItems) + "/", "filled/", "1") - database.put("/restaurants/" + estName + "/orders/" + str(dbItems) + "/", "number/", str((number) + ".")) - database.put("/restaurants/" + estName + "/orders/" + str(dbItems) + "/", "endTime/", time.time()) - database.put("/restaurants/" + estName + "/orders/" + str(key) + "/", "duration/", duration) - database.put("/restaurants/" + estName + "/orders/" + str(dbItems) + "/", "/day/", - calendar.day_name[datetime.datetime.now().today().weekday()]) - database.put("/restaurants/" + estName + "/orders/" + str(dbItems) + "/", "/hour/", - int(datetime.datetime.now().hour)) - database.put("/restaurants/" + estName + "/orders/" + str(dbItems) + "/", "/month/", - (datetime.datetime.now().strftime("%m"))) - database.put("/restaurants/" + estName + "/orders/" + str(dbItems) + "/", "/date/", - (datetime.datetime.now().strftime("%d"))) - database.put("/restaurants/" + estName + "/orders/" + str(dbItems) + "/", "/year/", - (datetime.datetime.now().strftime("%Y"))) - database.put("/restaurants/" + estName + "/orders/" + str(dbItems) + "/", "cash/", "NOT PAID") - logData = database.get("/log/" + uid + "/", logYM) - cdrFees = logData['CedarFees'] - cdrFees += 0.1 - database.put("/log/" + uid + "/" + logYM, "/CedarFees/", cdrFees) - totalRev = float(logData["totalRev"]) - totalRev += float((DBdata[dbItems]["linkTotal"] + 0.15) * 1.1) - database.put("/log/" + uid + "/" + logYM, "/totalRev/", totalRev) - ret = int(logData["retCustomers"]) - newCust = int(logData["newCustomers"]) - if (DBdata[dbItems]["ret"] == 0): - ret += 1 - database.put("/log/" + uid + "/" + logYM, "/retCustomers/", ret) - else: - newCust += 1 - database.put("/log/" + uid + "/" + logYM, "/newCustomers/", newCust) - reply = "-Thank you for your order, you can pick it up and pay at the counter when you arrive \n-To order again just text " + '"order"' - updateLog() - client.send_message({ - 'from': NexmoNumber, - 'to': number, - 'text': reply - }) - session.clear() - return render_template("thankMsg.html") - - -@application.route('/') -@application.route('/index') -def mainPage(): - return " " - - -# when you run the code through terminal, this will allow Flask to work -if __name__ == '__main__': - application.secret_key = 'ssKEY' - application.config['SESSION_TYPE'] = 'filesystem' - sess = Session() - sess.init_app(application) - application.debug = True - application.run(host="0.0.0.0") diff --git a/bin/activate b/bin/activate index 1aea995..e5c9763 100644 --- a/bin/activate +++ b/bin/activate @@ -2,17 +2,14 @@ # you cannot run it directly deactivate () { - unset -f pydoc >/dev/null 2>&1 - # reset old environment variables - # ! [ -z ${VAR+_} ] returns true if VAR is declared at all - if ! [ -z "${_OLD_VIRTUAL_PATH+_}" ] ; then - PATH="$_OLD_VIRTUAL_PATH" + if [ -n "${_OLD_VIRTUAL_PATH:-}" ] ; then + PATH="${_OLD_VIRTUAL_PATH:-}" export PATH unset _OLD_VIRTUAL_PATH fi - if ! [ -z "${_OLD_VIRTUAL_PYTHONHOME+_}" ] ; then - PYTHONHOME="$_OLD_VIRTUAL_PYTHONHOME" + if [ -n "${_OLD_VIRTUAL_PYTHONHOME:-}" ] ; then + PYTHONHOME="${_OLD_VIRTUAL_PYTHONHOME:-}" export PYTHONHOME unset _OLD_VIRTUAL_PYTHONHOME fi @@ -20,18 +17,18 @@ deactivate () { # This should detect bash and zsh, which have a hash command that must # be called to get it to forget past commands. Without forgetting # past commands the $PATH changes we made may not be respected - if [ -n "${BASH-}" ] || [ -n "${ZSH_VERSION-}" ] ; then - hash -r 2>/dev/null + if [ -n "${BASH:-}" -o -n "${ZSH_VERSION:-}" ] ; then + hash -r fi - if ! [ -z "${_OLD_VIRTUAL_PS1+_}" ] ; then - PS1="$_OLD_VIRTUAL_PS1" + if [ -n "${_OLD_VIRTUAL_PS1:-}" ] ; then + PS1="${_OLD_VIRTUAL_PS1:-}" export PS1 unset _OLD_VIRTUAL_PS1 fi unset VIRTUAL_ENV - if [ ! "${1-}" = "nondestructive" ] ; then + if [ ! "$1" = "nondestructive" ] ; then # Self destruct! unset -f deactivate fi @@ -48,31 +45,32 @@ PATH="$VIRTUAL_ENV/bin:$PATH" export PATH # unset PYTHONHOME if set -if ! [ -z "${PYTHONHOME+_}" ] ; then - _OLD_VIRTUAL_PYTHONHOME="$PYTHONHOME" +# this will fail if PYTHONHOME is set to the empty string (which is bad anyway) +# could use `if (set -u; : $PYTHONHOME) ;` in bash +if [ -n "${PYTHONHOME:-}" ] ; then + _OLD_VIRTUAL_PYTHONHOME="${PYTHONHOME:-}" unset PYTHONHOME fi -if [ -z "${VIRTUAL_ENV_DISABLE_PROMPT-}" ] ; then - _OLD_VIRTUAL_PS1="${PS1-}" - if [ "x" != x ] ; then - PS1="${PS1-}" +if [ -z "${VIRTUAL_ENV_DISABLE_PROMPT:-}" ] ; then + _OLD_VIRTUAL_PS1="${PS1:-}" + if [ "x(SMSorder) " != x ] ; then + PS1="(SMSorder) ${PS1:-}" + else + if [ "`basename \"$VIRTUAL_ENV\"`" = "__" ] ; then + # special case for Aspen magic directories + # see http://www.zetadev.com/software/aspen/ + PS1="[`basename \`dirname \"$VIRTUAL_ENV\"\``] $PS1" else - PS1="(`basename \"$VIRTUAL_ENV\"`) ${PS1-}" + PS1="(`basename \"$VIRTUAL_ENV\"`)$PS1" + fi fi export PS1 fi -# Make sure to unalias pydoc if it's already there -alias pydoc 2>/dev/null >/dev/null && unalias pydoc || true - -pydoc () { - python -m pydoc "$@" -} - # This should detect bash and zsh, which have a hash command that must # be called to get it to forget past commands. Without forgetting # past commands the $PATH changes we made may not be respected -if [ -n "${BASH-}" ] || [ -n "${ZSH_VERSION-}" ] ; then - hash -r 2>/dev/null +if [ -n "${BASH:-}" -o -n "${ZSH_VERSION:-}" ] ; then + hash -r fi diff --git a/bin/activate.csh b/bin/activate.csh index 8f3d922..35cb072 100644 --- a/bin/activate.csh +++ b/bin/activate.csh @@ -1,55 +1,37 @@ # This file must be used with "source bin/activate.csh" *from csh*. # You cannot run it directly. # Created by Davide Di Blasi . +# Ported to Python 3.3 venv by Andrew Svetlov -set newline='\ -' - -alias deactivate 'test $?_OLD_VIRTUAL_PATH != 0 && setenv PATH "$_OLD_VIRTUAL_PATH:q" && unset _OLD_VIRTUAL_PATH; rehash; test $?_OLD_VIRTUAL_PROMPT != 0 && set prompt="$_OLD_VIRTUAL_PROMPT:q" && unset _OLD_VIRTUAL_PROMPT; unsetenv VIRTUAL_ENV; test "\!:*" != "nondestructive" && unalias deactivate && unalias pydoc' +alias deactivate 'test $?_OLD_VIRTUAL_PATH != 0 && setenv PATH "$_OLD_VIRTUAL_PATH" && unset _OLD_VIRTUAL_PATH; rehash; test $?_OLD_VIRTUAL_PROMPT != 0 && set prompt="$_OLD_VIRTUAL_PROMPT" && unset _OLD_VIRTUAL_PROMPT; unsetenv VIRTUAL_ENV; test "\!:*" != "nondestructive" && unalias deactivate' # Unset irrelevant variables. deactivate nondestructive setenv VIRTUAL_ENV "/Users/caleb/Documents/GitHub/SMSorder" -set _OLD_VIRTUAL_PATH="$PATH:q" -setenv PATH "$VIRTUAL_ENV:q/bin:$PATH:q" - +set _OLD_VIRTUAL_PATH="$PATH" +setenv PATH "$VIRTUAL_ENV/bin:$PATH" -if ("" != "") then - set env_name = "" -else - set env_name = '('"$VIRTUAL_ENV:t:q"') ' -endif +set _OLD_VIRTUAL_PROMPT="$prompt" -if ( $?VIRTUAL_ENV_DISABLE_PROMPT ) then - if ( $VIRTUAL_ENV_DISABLE_PROMPT == "" ) then - set do_prompt = "1" +if (! "$?VIRTUAL_ENV_DISABLE_PROMPT") then + if ("SMSorder" != "") then + set env_name = "SMSorder" else - set do_prompt = "0" - endif -else - set do_prompt = "1" -endif - -if ( $do_prompt == "1" ) then - # Could be in a non-interactive environment, - # in which case, $prompt is undefined and we wouldn't - # care about the prompt anyway. - if ( $?prompt ) then - set _OLD_VIRTUAL_PROMPT="$prompt:q" - if ( "$prompt:q" =~ *"$newline:q"* ) then - : + if (`basename "VIRTUAL_ENV"` == "__") then + # special case for Aspen magic directories + # see http://www.zetadev.com/software/aspen/ + set env_name = `basename \`dirname "$VIRTUAL_ENV"\`` else - set prompt = "$env_name:q$prompt:q" + set env_name = `basename "$VIRTUAL_ENV"` endif endif + set prompt = "[$env_name] $prompt" + unset env_name endif -unset env_name -unset do_prompt - alias pydoc python -m pydoc rehash diff --git a/bin/activate.fish b/bin/activate.fish index 3bdbad5..1d7ff0e 100644 --- a/bin/activate.fish +++ b/bin/activate.fish @@ -1,99 +1,73 @@ -# This file must be used using `source bin/activate.fish` *within a running fish ( http://fishshell.com ) session*. -# Do not run it directly. +# This file must be used with ". bin/activate.fish" *from fish* (http://fishshell.org) +# you cannot run it directly -function _bashify_path -d "Converts a fish path to something bash can recognize" - set fishy_path $argv - set bashy_path $fishy_path[1] - for path_part in $fishy_path[2..-1] - set bashy_path "$bashy_path:$path_part" - end - echo $bashy_path -end - -function _fishify_path -d "Converts a bash path to something fish can recognize" - echo $argv | tr ':' '\n' -end - -function deactivate -d 'Exit virtualenv mode and return to the normal environment.' +function deactivate -d "Exit virtualenv and return to normal shell environment" # reset old environment variables if test -n "$_OLD_VIRTUAL_PATH" - # https://github.com/fish-shell/fish-shell/issues/436 altered PATH handling - if test (echo $FISH_VERSION | tr "." "\n")[1] -lt 3 - set -gx PATH (_fishify_path $_OLD_VIRTUAL_PATH) - else - set -gx PATH $_OLD_VIRTUAL_PATH - end + set -gx PATH $_OLD_VIRTUAL_PATH set -e _OLD_VIRTUAL_PATH end - if test -n "$_OLD_VIRTUAL_PYTHONHOME" set -gx PYTHONHOME $_OLD_VIRTUAL_PYTHONHOME set -e _OLD_VIRTUAL_PYTHONHOME end if test -n "$_OLD_FISH_PROMPT_OVERRIDE" - # Set an empty local `$fish_function_path` to allow the removal of `fish_prompt` using `functions -e`. - set -l fish_function_path - - # Erase virtualenv's `fish_prompt` and restore the original. functions -e fish_prompt + set -e _OLD_FISH_PROMPT_OVERRIDE functions -c _old_fish_prompt fish_prompt functions -e _old_fish_prompt - set -e _OLD_FISH_PROMPT_OVERRIDE end set -e VIRTUAL_ENV - - if test "$argv[1]" != 'nondestructive' - # Self-destruct! - functions -e pydoc + if test "$argv[1]" != "nondestructive" + # Self destruct! functions -e deactivate - functions -e _bashify_path - functions -e _fishify_path end end -# Unset irrelevant variables. +# unset irrelevant variables deactivate nondestructive set -gx VIRTUAL_ENV "/Users/caleb/Documents/GitHub/SMSorder" -# https://github.com/fish-shell/fish-shell/issues/436 altered PATH handling -if test (echo $FISH_VERSION | tr "." "\n")[1] -lt 3 - set -gx _OLD_VIRTUAL_PATH (_bashify_path $PATH) -else - set -gx _OLD_VIRTUAL_PATH $PATH -end +set -gx _OLD_VIRTUAL_PATH $PATH set -gx PATH "$VIRTUAL_ENV/bin" $PATH -# Unset `$PYTHONHOME` if set. +# unset PYTHONHOME if set if set -q PYTHONHOME set -gx _OLD_VIRTUAL_PYTHONHOME $PYTHONHOME set -e PYTHONHOME end -function pydoc - python -m pydoc $argv -end - if test -z "$VIRTUAL_ENV_DISABLE_PROMPT" - # Copy the current `fish_prompt` function as `_old_fish_prompt`. + # fish uses a function instead of an env var to generate the prompt. + + # save the current fish_prompt function as the function _old_fish_prompt functions -c fish_prompt _old_fish_prompt + # with the original prompt function renamed, we can override with our own. function fish_prompt - # Save the current $status, for fish_prompts that display it. + # Save the return status of the last command set -l old_status $status - # Prompt override provided? - # If not, just prepend the environment name. - if test -n "" - printf '%s%s' "" (set_color normal) + # Prompt override? + if test -n "(SMSorder) " + printf "%s%s" "(SMSorder) " (set_color normal) else - printf '%s(%s) ' (set_color normal) (basename "$VIRTUAL_ENV") + # ...Otherwise, prepend env + set -l _checkbase (basename "$VIRTUAL_ENV") + if test $_checkbase = "__" + # special case for Aspen magic directories + # see http://www.zetadev.com/software/aspen/ + printf "%s[%s]%s " (set_color -b blue white) (basename (dirname "$VIRTUAL_ENV")) (set_color normal) + else + printf "%s(%s)%s" (set_color -b blue white) (basename "$VIRTUAL_ENV") (set_color normal) + end end - # Restore the original $status - echo "exit $old_status" | source + # Restore the return status of the previous command. + echo "exit $old_status" | . _old_fish_prompt end diff --git a/bin/activate.ps1 b/bin/activate.ps1 deleted file mode 100644 index bb51e77..0000000 --- a/bin/activate.ps1 +++ /dev/null @@ -1,72 +0,0 @@ -# This file must be dot sourced from PoSh; you cannot run it directly. Do this: . ./activate.ps1 - -$script:THIS_PATH = $myinvocation.mycommand.path -$script:BASE_DIR = split-path (resolve-path "$THIS_PATH/..") -Parent - -function global:deactivate([switch] $NonDestructive) -{ - if (test-path variable:_OLD_VIRTUAL_PATH) - { - $env:PATH = $variable:_OLD_VIRTUAL_PATH - remove-variable "_OLD_VIRTUAL_PATH" -scope global - } - - if (test-path function:_old_virtual_prompt) - { - $function:prompt = $function:_old_virtual_prompt - remove-item function:\_old_virtual_prompt - } - - if ($env:VIRTUAL_ENV) - { - $old_env = split-path $env:VIRTUAL_ENV -leaf - remove-item env:VIRTUAL_ENV -erroraction silentlycontinue - } - - if (!$NonDestructive) - { - # Self destruct! - remove-item function:deactivate - remove-item function:pydoc - } -} - -function global:pydoc -{ - python -m pydoc $args -} - -# unset irrelevant variables -deactivate -nondestructive - -$VIRTUAL_ENV = $BASE_DIR -$env:VIRTUAL_ENV = $VIRTUAL_ENV - -$global:_OLD_VIRTUAL_PATH = $env:PATH -$env:PATH = "$env:VIRTUAL_ENV/bin:" + $env:PATH -if (!$env:VIRTUAL_ENV_DISABLE_PROMPT) -{ - function global:_old_virtual_prompt - { - "" - } - $function:_old_virtual_prompt = $function:prompt - if ("" -ne "") - { - function global:prompt - { - # Add the custom prefix to the existing prompt - write-host "" -nonewline - & $function:_old_virtual_prompt - } - } - else - { - function global:prompt - { - # Add a prefix to the current prompt, but don't discard it. - write-host "($( split-path $env:VIRTUAL_ENV -leaf )) " -nonewline - & $function:_old_virtual_prompt - } - } -} diff --git a/bin/activate.xsh b/bin/activate.xsh deleted file mode 100644 index 92f6276..0000000 --- a/bin/activate.xsh +++ /dev/null @@ -1,46 +0,0 @@ -"""Xonsh activate script for virtualenv""" -from xonsh.tools import get_sep as _get_sep - -def _deactivate(args): - if "pydoc" in aliases: - del aliases["pydoc"] - - if ${...}.get("_OLD_VIRTUAL_PATH", ""): - $PATH = $_OLD_VIRTUAL_PATH - del $_OLD_VIRTUAL_PATH - - if ${...}.get("_OLD_VIRTUAL_PYTHONHOME", ""): - $PYTHONHOME = $_OLD_VIRTUAL_PYTHONHOME - del $_OLD_VIRTUAL_PYTHONHOME - - if "VIRTUAL_ENV" in ${...}: - del $VIRTUAL_ENV - - if "VIRTUAL_ENV_PROMPT" in ${...}: - del $VIRTUAL_ENV_PROMPT - - if "nondestructive" not in args: - # Self destruct! - del aliases["deactivate"] - - -# unset irrelevant variables -_deactivate(["nondestructive"]) -aliases["deactivate"] = _deactivate - -$VIRTUAL_ENV = r"/Users/caleb/Documents/GitHub/SMSorder" - -$_OLD_VIRTUAL_PATH = $PATH -$PATH = $PATH[:] -$PATH.add($VIRTUAL_ENV + _get_sep() + "bin", front=True, replace=True) - -if ${...}.get("PYTHONHOME", ""): - # unset PYTHONHOME if set - $_OLD_VIRTUAL_PYTHONHOME = $PYTHONHOME - del $PYTHONHOME - -$VIRTUAL_ENV_PROMPT = "" -if not $VIRTUAL_ENV_PROMPT: - del $VIRTUAL_ENV_PROMPT - -aliases["pydoc"] = ["python", "-m", "pydoc"] diff --git a/bin/activate_this.py b/bin/activate_this.py deleted file mode 100644 index 59b5d72..0000000 --- a/bin/activate_this.py +++ /dev/null @@ -1,46 +0,0 @@ -"""Activate virtualenv for current interpreter: - -Use exec(open(this_file).read(), {'__file__': this_file}). - -This can be used when you must use an existing Python interpreter, not the virtualenv bin/python. -""" -import os -import site -import sys - -try: - __file__ -except NameError: - raise AssertionError("You must use exec(open(this_file).read(), {'__file__': this_file}))") - -# prepend bin to PATH (this file is inside the bin directory) -bin_dir = os.path.dirname(os.path.abspath(__file__)) -os.environ["PATH"] = os.pathsep.join([bin_dir] + os.environ.get("PATH", "").split(os.pathsep)) - -base = os.path.dirname(bin_dir) - -# virtual env is right above bin directory -os.environ["VIRTUAL_ENV"] = base - -# add the virtual environments site-package to the host python import mechanism -IS_PYPY = hasattr(sys, "pypy_version_info") -IS_JYTHON = sys.platform.startswith("java") -if IS_JYTHON: - site_packages = os.path.join(base, "Lib", "site-packages") -elif IS_PYPY: - site_packages = os.path.join(base, "site-packages") -else: - IS_WIN = sys.platform == "win32" - if IS_WIN: - site_packages = os.path.join(base, "Lib", "site-packages") - else: - site_packages = os.path.join(base, "lib", "python{}".format(sys.version[:3]), "site-packages") - -prev = set(sys.path) -site.addsitedir(site_packages) -sys.real_prefix = sys.prefix -sys.prefix = base - -# Move the added items to the front of the path, in place -new = list(sys.path) -sys.path[:] = [i for i in new if i not in prev] + [i for i in new if i in prev] diff --git a/bin/chardetect b/bin/chardetect index 7ec40c5..b39d50c 100755 --- a/bin/chardetect +++ b/bin/chardetect @@ -1,4 +1,4 @@ -#!/Users/caleb/Documents/GitHub/SMSorder/bin/python3.6 +#!/Users/caleb/Documents/GitHub/SMSorder/bin/python3 # -*- coding: utf-8 -*- import re import sys diff --git a/bin/easy_install b/bin/easy_install index 5a7a29f..7b7fe6d 100755 --- a/bin/easy_install +++ b/bin/easy_install @@ -1,4 +1,4 @@ -#!/Users/caleb/Documents/GitHub/SMSorder/bin/python3.6 +#!/Users/caleb/Documents/GitHub/SMSorder/bin/python3 # -*- coding: utf-8 -*- import re import sys diff --git a/bin/easy_install-3.6 b/bin/easy_install-3.6 deleted file mode 100755 index 5a7a29f..0000000 --- a/bin/easy_install-3.6 +++ /dev/null @@ -1,10 +0,0 @@ -#!/Users/caleb/Documents/GitHub/SMSorder/bin/python3.6 -# -*- coding: utf-8 -*- -import re -import sys - -from setuptools.command.easy_install import main - -if __name__ == '__main__': - sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0]) - sys.exit(main()) diff --git a/bin/flask b/bin/flask index 8820dd6..3f893b7 100755 --- a/bin/flask +++ b/bin/flask @@ -1,4 +1,4 @@ -#!/Users/caleb/Documents/GitHub/SMSorder/bin/python3.6 +#!/Users/caleb/Documents/GitHub/SMSorder/bin/python3 # -*- coding: utf-8 -*- import re import sys diff --git a/bin/pip b/bin/pip index 73f57e5..b6b8e07 100755 --- a/bin/pip +++ b/bin/pip @@ -1,4 +1,4 @@ -#!/Users/caleb/Documents/GitHub/SMSorder/bin/python3.6 +#!/Users/caleb/Documents/GitHub/SMSorder/bin/python3 # -*- coding: utf-8 -*- import re import sys diff --git a/bin/pip3 b/bin/pip3 index 73f57e5..b6b8e07 100755 --- a/bin/pip3 +++ b/bin/pip3 @@ -1,4 +1,4 @@ -#!/Users/caleb/Documents/GitHub/SMSorder/bin/python3.6 +#!/Users/caleb/Documents/GitHub/SMSorder/bin/python3 # -*- coding: utf-8 -*- import re import sys diff --git a/bin/pip3.6 b/bin/pip3.6 deleted file mode 100755 index 73f57e5..0000000 --- a/bin/pip3.6 +++ /dev/null @@ -1,10 +0,0 @@ -#!/Users/caleb/Documents/GitHub/SMSorder/bin/python3.6 -# -*- coding: utf-8 -*- -import re -import sys - -from pip._internal import main - -if __name__ == '__main__': - sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0]) - sys.exit(main()) diff --git a/bin/pyjwt b/bin/pyjwt index f32684d..8ab4a35 100755 --- a/bin/pyjwt +++ b/bin/pyjwt @@ -1,4 +1,4 @@ -#!/Users/caleb/Documents/GitHub/SMSorder/bin/python3.6 +#!/Users/caleb/Documents/GitHub/SMSorder/bin/python3 # -*- coding: utf-8 -*- import re import sys diff --git a/bin/python b/bin/python index 039b719..b8a0adb 120000 --- a/bin/python +++ b/bin/python @@ -1 +1 @@ -python3.6 \ No newline at end of file +python3 \ No newline at end of file diff --git a/bin/python-config b/bin/python-config deleted file mode 100755 index 6509562..0000000 --- a/bin/python-config +++ /dev/null @@ -1,78 +0,0 @@ -#!/Users/caleb/Documents/GitHub/SMSorder/bin/python - -import sys -import getopt -import sysconfig - -valid_opts = ['prefix', 'exec-prefix', 'includes', 'libs', 'cflags', - 'ldflags', 'help'] - -if sys.version_info >= (3, 2): - valid_opts.insert(-1, 'extension-suffix') - valid_opts.append('abiflags') -if sys.version_info >= (3, 3): - valid_opts.append('configdir') - - -def exit_with_usage(code=1): - sys.stderr.write("Usage: {0} [{1}]\n".format( - sys.argv[0], '|'.join('--'+opt for opt in valid_opts))) - sys.exit(code) - -try: - opts, args = getopt.getopt(sys.argv[1:], '', valid_opts) -except getopt.error: - exit_with_usage() - -if not opts: - exit_with_usage() - -pyver = sysconfig.get_config_var('VERSION') -getvar = sysconfig.get_config_var - -opt_flags = [flag for (flag, val) in opts] - -if '--help' in opt_flags: - exit_with_usage(code=0) - -for opt in opt_flags: - if opt == '--prefix': - print(sysconfig.get_config_var('prefix')) - - elif opt == '--exec-prefix': - print(sysconfig.get_config_var('exec_prefix')) - - elif opt in ('--includes', '--cflags'): - flags = ['-I' + sysconfig.get_path('include'), - '-I' + sysconfig.get_path('platinclude')] - if opt == '--cflags': - flags.extend(getvar('CFLAGS').split()) - print(' '.join(flags)) - - elif opt in ('--libs', '--ldflags'): - abiflags = getattr(sys, 'abiflags', '') - libs = ['-lpython' + pyver + abiflags] - libs += getvar('LIBS').split() - libs += getvar('SYSLIBS').split() - # add the prefix/lib/pythonX.Y/config dir, but only if there is no - # shared library in prefix/lib/. - if opt == '--ldflags': - if not getvar('Py_ENABLE_SHARED'): - libs.insert(0, '-L' + getvar('LIBPL')) - if not getvar('PYTHONFRAMEWORK'): - libs.extend(getvar('LINKFORSHARED').split()) - print(' '.join(libs)) - - elif opt == '--extension-suffix': - ext_suffix = sysconfig.get_config_var('EXT_SUFFIX') - if ext_suffix is None: - ext_suffix = sysconfig.get_config_var('SO') - print(ext_suffix) - - elif opt == '--abiflags': - if not getattr(sys, 'abiflags', None): - exit_with_usage() - print(sys.abiflags) - - elif opt == '--configdir': - print(sysconfig.get_config_var('LIBPL')) diff --git a/bin/python3 b/bin/python3 index 039b719..79ab74b 120000 --- a/bin/python3 +++ b/bin/python3 @@ -1 +1 @@ -python3.6 \ No newline at end of file +/usr/local/bin/python3 \ No newline at end of file diff --git a/bin/python3.6 b/bin/python3.6 deleted file mode 100755 index e3969a7..0000000 Binary files a/bin/python3.6 and /dev/null differ diff --git a/bin/wheel b/bin/wheel deleted file mode 100755 index 5cb690b..0000000 --- a/bin/wheel +++ /dev/null @@ -1,10 +0,0 @@ -#!/Users/caleb/Documents/GitHub/SMSorder/bin/python3.6 -# -*- coding: utf-8 -*- -import re -import sys - -from wheel.cli import main - -if __name__ == '__main__': - sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0]) - sys.exit(main()) diff --git a/firebase/__init__.py b/firebase/__init__.py new file mode 100644 index 0000000..aeeb7c5 --- /dev/null +++ b/firebase/__init__.py @@ -0,0 +1,15 @@ +import atexit + +from .asyncx import process_pool +from firebase import * + + +@atexit.register +def close_process_pool(): + """ + Clean up function that closes and terminates the process pool + defined in the ``async`` file. + """ + process_pool.close() + process_pool.join() + process_pool.terminate() diff --git a/firebase/__pycache__/__init__.cpython-36.pyc b/firebase/__pycache__/__init__.cpython-36.pyc new file mode 100644 index 0000000..6c0faf0 Binary files /dev/null and b/firebase/__pycache__/__init__.cpython-36.pyc differ diff --git a/firebase/__pycache__/__init__.cpython-37.pyc b/firebase/__pycache__/__init__.cpython-37.pyc new file mode 100644 index 0000000..44b415f Binary files /dev/null and b/firebase/__pycache__/__init__.cpython-37.pyc differ diff --git a/firebase/__pycache__/asyncx.cpython-36.pyc b/firebase/__pycache__/asyncx.cpython-36.pyc new file mode 100644 index 0000000..f5587e0 Binary files /dev/null and b/firebase/__pycache__/asyncx.cpython-36.pyc differ diff --git a/firebase/__pycache__/asyncx.cpython-37.pyc b/firebase/__pycache__/asyncx.cpython-37.pyc new file mode 100644 index 0000000..8156223 Binary files /dev/null and b/firebase/__pycache__/asyncx.cpython-37.pyc differ diff --git a/firebase/__pycache__/decorators.cpython-36.pyc b/firebase/__pycache__/decorators.cpython-36.pyc new file mode 100644 index 0000000..3b194b8 Binary files /dev/null and b/firebase/__pycache__/decorators.cpython-36.pyc differ diff --git a/firebase/__pycache__/decorators.cpython-37.pyc b/firebase/__pycache__/decorators.cpython-37.pyc new file mode 100644 index 0000000..9847874 Binary files /dev/null and b/firebase/__pycache__/decorators.cpython-37.pyc differ diff --git a/firebase/__pycache__/firebase.cpython-36.pyc b/firebase/__pycache__/firebase.cpython-36.pyc new file mode 100644 index 0000000..7687e50 Binary files /dev/null and b/firebase/__pycache__/firebase.cpython-36.pyc differ diff --git a/firebase/__pycache__/firebase.cpython-37.pyc b/firebase/__pycache__/firebase.cpython-37.pyc new file mode 100644 index 0000000..fdcb428 Binary files /dev/null and b/firebase/__pycache__/firebase.cpython-37.pyc differ diff --git a/firebase/__pycache__/firebase_token_generator.cpython-36.pyc b/firebase/__pycache__/firebase_token_generator.cpython-36.pyc new file mode 100644 index 0000000..1ac534f Binary files /dev/null and b/firebase/__pycache__/firebase_token_generator.cpython-36.pyc differ diff --git a/firebase/__pycache__/firebase_token_generator.cpython-37.pyc b/firebase/__pycache__/firebase_token_generator.cpython-37.pyc new file mode 100644 index 0000000..9b269dc Binary files /dev/null and b/firebase/__pycache__/firebase_token_generator.cpython-37.pyc differ diff --git a/firebase/__pycache__/jsonutil.cpython-36.pyc b/firebase/__pycache__/jsonutil.cpython-36.pyc new file mode 100644 index 0000000..69742ea Binary files /dev/null and b/firebase/__pycache__/jsonutil.cpython-36.pyc differ diff --git a/firebase/__pycache__/jsonutil.cpython-37.pyc b/firebase/__pycache__/jsonutil.cpython-37.pyc new file mode 100644 index 0000000..44b51f0 Binary files /dev/null and b/firebase/__pycache__/jsonutil.cpython-37.pyc differ diff --git a/firebase/__pycache__/lazy.cpython-36.pyc b/firebase/__pycache__/lazy.cpython-36.pyc new file mode 100644 index 0000000..0bfe571 Binary files /dev/null and b/firebase/__pycache__/lazy.cpython-36.pyc differ diff --git a/firebase/__pycache__/lazy.cpython-37.pyc b/firebase/__pycache__/lazy.cpython-37.pyc new file mode 100644 index 0000000..bbffbdd Binary files /dev/null and b/firebase/__pycache__/lazy.cpython-37.pyc differ diff --git a/firebase/asyncx.py b/firebase/asyncx.py new file mode 100644 index 0000000..b343d38 --- /dev/null +++ b/firebase/asyncx.py @@ -0,0 +1,14 @@ +import multiprocessing + +from .lazy import LazyLoadProxy + +__all__ = ['process_pool'] + +_process_pool = None +def get_process_pool(size=5): + global _process_pool + if _process_pool is None: + _process_pool = multiprocessing.Pool(processes=size) + return _process_pool +process_pool = LazyLoadProxy(get_process_pool) + diff --git a/firebase/decorators.py b/firebase/decorators.py new file mode 100644 index 0000000..66d0a11 --- /dev/null +++ b/firebase/decorators.py @@ -0,0 +1,21 @@ +import requests +from functools import wraps + + +def http_connection(timeout): + """ + Decorator function that injects a requests.Session instance into + the decorated function's actual parameters if not given. + """ + def wrapper(f): + def wrapped(*args, **kwargs): + if not ('connection' in kwargs) or not kwargs['connection']: + connection = requests.Session() + kwargs['connection'] = connection + else: + connection = kwargs['connection'] + connection.timeout = timeout + connection.headers.update({'Content-type': 'application/json'}) + return f(*args, **kwargs) + return wraps(f)(wrapped) + return wrapper diff --git a/firebase/firebase.py b/firebase/firebase.py new file mode 100644 index 0000000..2f48d1f --- /dev/null +++ b/firebase/firebase.py @@ -0,0 +1,392 @@ +try: + import urlparse +except ImportError: + #py3k + from urllib import parse as urlparse + +import json + +from .firebase_token_generator import FirebaseTokenGenerator +from .decorators import http_connection + +from .asyncx import process_pool +from .jsonutil import JSONEncoder + +__all__ = ['FirebaseAuthentication', 'FirebaseApplication'] + + +@http_connection(60) +def make_get_request(url, params, headers, connection): + """ + Helper function that makes an HTTP GET request to the given firebase + endpoint. Timeout is 60 seconds. + `url`: The full URL of the firebase endpoint (DSN appended.) + `params`: Python dict that is appended to the URL like a querystring. + `headers`: Python dict. HTTP request headers. + `connection`: Predefined HTTP connection instance. If not given, it + is supplied by the `decorators.http_connection` function. + + The returning value is a Python dict deserialized by the JSON decoder. However, + if the status code is not 2x or 403, an requests.HTTPError is raised. + + connection = connection_pool.get_available_connection() + response = make_get_request('http://firebase.localhost/users', {'print': silent'}, + {'X_FIREBASE_SOMETHING': 'Hi'}, connection) + response => {'1': 'John Doe', '2': 'Jane Doe'} + """ + timeout = getattr(connection, 'timeout') + response = connection.get(url, params=params, headers=headers, timeout=timeout) + if response.ok or response.status_code == 403: + return response.json() if response.content else None + else: + response.raise_for_status() + + +@http_connection(60) +def make_put_request(url, data, params, headers, connection): + """ + Helper function that makes an HTTP PUT request to the given firebase + endpoint. Timeout is 60 seconds. + `url`: The full URL of the firebase endpoint (DSN appended.) + `data`: JSON serializable dict that will be stored in the remote storage. + `params`: Python dict that is appended to the URL like a querystring. + `headers`: Python dict. HTTP request headers. + `connection`: Predefined HTTP connection instance. If not given, it + is supplied by the `decorators.http_connection` function. + + The returning value is a Python dict deserialized by the JSON decoder. However, + if the status code is not 2x or 403, an requests.HTTPError is raised. + + connection = connection_pool.get_available_connection() + response = make_put_request('http://firebase.localhost/users', + '{"1": "Ozgur Vatansever"}', + {'X_FIREBASE_SOMETHING': 'Hi'}, connection) + response => {'1': 'Ozgur Vatansever'} or {'error': 'Permission denied.'} + """ + timeout = getattr(connection, 'timeout') + response = connection.put(url, data=data, params=params, headers=headers, + timeout=timeout) + if response.ok or response.status_code == 403: + return response.json() if response.content else None + else: + response.raise_for_status() + + +@http_connection(60) +def make_post_request(url, data, params, headers, connection): + """ + Helper function that makes an HTTP POST request to the given firebase + endpoint. Timeout is 60 seconds. + `url`: The full URL of the firebase endpoint (DSN appended.) + `data`: JSON serializable dict that will be stored in the remote storage. + `params`: Python dict that is appended to the URL like a querystring. + `headers`: Python dict. HTTP request headers. + `connection`: Predefined HTTP connection instance. If not given, it + is supplied by the `decorators.http_connection` function. + + The returning value is a Python dict deserialized by the JSON decoder. However, + if the status code is not 2x or 403, an requests.HTTPError is raised. + + connection = connection_pool.get_available_connection() + response = make_put_request('http://firebase.localhost/users/', + '{"Ozgur Vatansever"}', {'X_FIREBASE_SOMETHING': 'Hi'}, connection) + response => {u'name': u'-Inw6zol_2f5ThHwVcSe'} or {'error': 'Permission denied.'} + """ + timeout = getattr(connection, 'timeout') + response = connection.post(url, data=data, params=params, headers=headers, + timeout=timeout) + if response.ok or response.status_code == 403: + return response.json() if response.content else None + else: + response.raise_for_status() + + +@http_connection(60) +def make_patch_request(url, data, params, headers, connection): + """ + Helper function that makes an HTTP PATCH request to the given firebase + endpoint. Timeout is 60 seconds. + `url`: The full URL of the firebase endpoint (DSN appended.) + `data`: JSON serializable dict that will be stored in the remote storage. + `params`: Python dict that is appended to the URL like a querystring. + `headers`: Python dict. HTTP request headers. + `connection`: Predefined HTTP connection instance. If not given, it + is supplied by the `decorators.http_connection` function. + + The returning value is a Python dict deserialized by the JSON decoder. However, + if the status code is not 2x or 403, an requests.HTTPError is raised. + + connection = connection_pool.get_available_connection() + response = make_put_request('http://firebase.localhost/users/1', + '{"Ozgur Vatansever"}', {'X_FIREBASE_SOMETHING': 'Hi'}, connection) + response => {'Ozgur Vatansever'} or {'error': 'Permission denied.'} + """ + timeout = getattr(connection, 'timeout') + response = connection.patch(url, data=data, params=params, headers=headers, + timeout=timeout) + if response.ok or response.status_code == 403: + return response.json() if response.content else None + else: + response.raise_for_status() + + +@http_connection(60) +def make_delete_request(url, params, headers, connection): + """ + Helper function that makes an HTTP DELETE request to the given firebase + endpoint. Timeout is 60 seconds. + `url`: The full URL of the firebase endpoint (DSN appended.) + `params`: Python dict that is appended to the URL like a querystring. + `headers`: Python dict. HTTP request headers. + `connection`: Predefined HTTP connection instance. If not given, it + is supplied by the `decorators.http_connection` function. + + The returning value is NULL. However, if the status code is not 2x or 403, + an requests.HTTPError is raised. + + connection = connection_pool.get_available_connection() + response = make_put_request('http://firebase.localhost/users/1', + {'X_FIREBASE_SOMETHING': 'Hi'}, connection) + response => NULL or {'error': 'Permission denied.'} + """ + timeout = getattr(connection, 'timeout') + response = connection.delete(url, params=params, headers=headers, timeout=timeout) + if response.ok or response.status_code == 403: + return response.json() if response.content else None + else: + response.raise_for_status() + + +class FirebaseUser(object): + """ + Class that wraps the credentials of the authenticated user. Think of + this as a container that holds authentication related data. + """ + def __init__(self, email, firebase_auth_token, provider, id=None): + self.email = email + self.firebase_auth_token = firebase_auth_token + self.provider = provider + self.id = id + + +class FirebaseAuthentication(object): + """ + Class that wraps the Firebase SimpleLogin mechanism. Actually this + class does not trigger a connection, simply fakes the auth action. + + In addition, the provided email and password information is totally + useless and they never appear in the ``auth`` variable at the server. + """ + def __init__(self, secret, email, debug=False, admin=False, extra=None): + self.authenticator = FirebaseTokenGenerator(secret, debug, admin) + self.email = email + self.provider = 'password' + self.extra = (extra or {}).copy() + self.extra.update({'debug': debug, 'admin': admin, + 'email': self.email, 'provider': self.provider}) + + def get_user(self): + """ + Method that gets the authenticated user. The returning user has + the token, email and the provider data. + """ + token = self.authenticator.create_token(self.extra) + user_id = self.extra.get('id') + return FirebaseUser(self.email, token, self.provider, user_id) + + +class FirebaseApplication(object): + """ + Class that actually connects with the Firebase backend via HTTP calls. + It fully implements the RESTful specifications defined by Firebase. Data + is transmitted as in JSON format in both ways. This class needs a DSN value + that defines the base URL of the backend, and if needed, authentication + credentials are accepted and then are taken into consideration while + constructing HTTP requests. + + There are also the corresponding asynchronous versions of each HTTP method. + The async calls make use of the on-demand process pool defined under the + module `async`. + + auth = FirebaseAuthentication(FIREBASE_SECRET, 'firebase@firebase.com', 'fbpw') + firebase = FirebaseApplication('https://firebase.localhost', auth) + + That's all there is. Then you start connecting with the backend: + + json_dict = firebase.get('/users', '1', {'print': 'pretty'}) + print json_dict + {'1': 'John Doe', '2': 'Jane Doe', ...} + + Async version is: + firebase.get('/users', '1', {'print': 'pretty'}, callback=log_json_dict) + + The callback method is fed with the returning response. + """ + NAME_EXTENSION = '.json' + URL_SEPERATOR = '/' + + def __init__(self, dsn, authentication=None): + assert dsn.startswith('https://'), 'DSN must be a secure URL' + self.dsn = dsn + self.authentication = authentication + + def _build_endpoint_url(self, url, name=None): + """ + Method that constructs a full url with the given url and the + snapshot name. + + Example: + full_url = _build_endpoint_url('/users', '1') + full_url => 'http://firebase.localhost/users/1.json' + """ + if not url.endswith(self.URL_SEPERATOR): + url = url + self.URL_SEPERATOR + if name is None: + name = '' + return '%s%s%s' % (urlparse.urljoin(self.dsn, url), name, + self.NAME_EXTENSION) + + def _authenticate(self, params, headers): + """ + Method that simply adjusts authentication credentials for the + request. + `params` is the querystring of the request. + `headers` is the header of the request. + + If auth instance is not provided to this class, this method simply + returns without doing anything. + """ + if self.authentication: + user = self.authentication.get_user() + params.update({'auth': user.firebase_auth_token}) + headers.update(self.authentication.authenticator.HEADERS) + + @http_connection(60) + def get(self, url, name, connection, params=None, headers=None): + """ + Synchronous GET request. + """ + if name is None: name = '' + params = params or {} + headers = headers or {} + endpoint = self._build_endpoint_url(url, name) + self._authenticate(params, headers) + return make_get_request(endpoint, params, headers, connection=connection) + + def get_async(self, url, name, callback=None, params=None, headers=None): + """ + Asynchronous GET request with the process pool. + """ + if name is None: name = '' + params = params or {} + headers = headers or {} + endpoint = self._build_endpoint_url(url, name) + self._authenticate(params, headers) + process_pool.apply_async(make_get_request, + args=(endpoint, params, headers), callback=callback) + + @http_connection(60) + def put(self, url, name, data, connection, params=None, headers=None): + """ + Synchronous PUT request. There will be no returning output from + the server, because the request will be made with ``silent`` + parameter. ``data`` must be a JSONable value. + """ + assert name, 'Snapshot name must be specified' + params = params or {} + headers = headers or {} + endpoint = self._build_endpoint_url(url, name) + self._authenticate(params, headers) + data = json.dumps(data, cls=JSONEncoder) + return make_put_request(endpoint, data, params, headers, + connection=connection) + + def put_async(self, url, name, data, callback=None, params=None, headers=None): + """ + Asynchronous PUT request with the process pool. + """ + if name is None: name = '' + params = params or {} + headers = headers or {} + endpoint = self._build_endpoint_url(url, name) + self._authenticate(params, headers) + data = json.dumps(data, cls=JSONEncoder) + process_pool.apply_async(make_put_request, + args=(endpoint, data, params, headers), + callback=callback) + + @http_connection(60) + def post(self, url, data, connection, params=None, headers=None): + """ + Synchronous POST request. ``data`` must be a JSONable value. + """ + params = params or {} + headers = headers or {} + endpoint = self._build_endpoint_url(url, None) + self._authenticate(params, headers) + data = json.dumps(data, cls=JSONEncoder) + return make_post_request(endpoint, data, params, headers, + connection=connection) + + def post_async(self, url, data, callback=None, params=None, headers=None): + """ + Asynchronous POST request with the process pool. + """ + params = params or {} + headers = headers or {} + endpoint = self._build_endpoint_url(url, None) + self._authenticate(params, headers) + data = json.dumps(data, cls=JSONEncoder) + process_pool.apply_async(make_post_request, + args=(endpoint, data, params, headers), + callback=callback) + + @http_connection(60) + def patch(self, url, data, connection, params=None, headers=None): + """ + Synchronous POST request. ``data`` must be a JSONable value. + """ + params = params or {} + headers = headers or {} + endpoint = self._build_endpoint_url(url, None) + self._authenticate(params, headers) + data = json.dumps(data, cls=JSONEncoder) + return make_patch_request(endpoint, data, params, headers, + connection=connection) + + def patch_async(self, url, data, callback=None, params=None, headers=None): + """ + Asynchronous PATCH request with the process pool. + """ + params = params or {} + headers = headers or {} + endpoint = self._build_endpoint_url(url, None) + self._authenticate(params, headers) + data = json.dumps(data, cls=JSONEncoder) + process_pool.apply_async(make_patch_request, + args=(endpoint, data, params, headers), + callback=callback) + + @http_connection(60) + def delete(self, url, name, connection, params=None, headers=None): + """ + Synchronous DELETE request. ``data`` must be a JSONable value. + """ + if not name: name = '' + params = params or {} + headers = headers or {} + endpoint = self._build_endpoint_url(url, name) + self._authenticate(params, headers) + return make_delete_request(endpoint, params, headers, connection=connection) + + def delete_async(self, url, name, callback=None, params=None, headers=None): + """ + Asynchronous DELETE request with the process pool. + """ + if not name: name = '' + params = params or {} + headers = headers or {} + endpoint = self._build_endpoint_url(url, name) + self._authenticate(params, headers) + process_pool.apply_async(make_delete_request, + args=(endpoint, params, headers), callback=callback) diff --git a/firebase/firebase_token_generator.py b/firebase/firebase_token_generator.py new file mode 100644 index 0000000..2a3d869 --- /dev/null +++ b/firebase/firebase_token_generator.py @@ -0,0 +1,116 @@ +############################################################################## +# THE ENTIRE CODE HAS BEEN TAKEN FROM THE OFFICIAL FIREBASE GITHUB # +# REPOSITORY NAMED `firebase-token-generator-python` WITH SLIGHT # +# MODIFICATIONS. # +# # +# FOR MORE INFORMATION, PLEASE TAKE A LOOK AT THE ACTUAL REPOSITORY: # +# - https://github.com/firebase/firebase-token-generator-python # +############################################################################## +import base64 +import hashlib +import hmac +import json +import time + +__all__ = ['FirebaseTokenGenerator'] + + +class FirebaseTokenGenerator(object): + TOKEN_VERSION = 0 + TOKEN_SEP = '.' + CLAIMS_MAP = { + 'expires': 'exp', + 'notBefore': 'nbf', + 'admin': 'admin', + 'debug': 'debug', + 'simulate': 'simulate' + } + HEADERS = {'typ': 'JWT', 'alg': 'HS256'} + + def __init__(self, secret, debug=False, admin=False): + assert secret, 'Your Firebase SECRET is not valid' + self.secret = secret + self.admin = admin + self.debug = debug + + def create_token(self, data, options=None): + """ + Generates a secure authentication token. + + Our token format follows the JSON Web Token (JWT) standard: + header.claims.signature + + Where: + 1) 'header' is a stringified, base64-encoded JSON object containing version and algorithm information. + 2) 'claims' is a stringified, base64-encoded JSON object containing a set of claims: + Library-generated claims: + 'iat' -> The issued at time in seconds since the epoch as a number + 'd' -> The arbitrary JSON object supplied by the user. + User-supplied claims (these are all optional): + 'exp' (optional) -> The expiration time of this token, as a number of seconds since the epoch. + 'nbf' (optional) -> The 'not before' time before which the token should be rejected (seconds since the epoch) + 'admin' (optional) -> If set to true, this client will bypass all security rules (use this to authenticate servers) + 'debug' (optional) -> 'set to true to make this client receive debug information about security rule execution. + 'simulate' (optional, internal-only for now) -> Set to true to neuter all API operations (listens / puts + will run security rules but not actually write or return data). + 3) A signature that proves the validity of this token (see: http://tools.ietf.org/html/draft-ietf-jose-json-web-signature-07) + + For base64-encoding we use URL-safe base64 encoding. This ensures that the entire token is URL-safe + and could, for instance, be placed as a query argument without any encoding (and this is what the JWT spec requires). + + Args: + data - a json serializable object of data to be included in the token + options - An optional dictionary of additional claims for the token. Possible keys include: + a) 'expires' -- A timestamp (as a number of seconds since the epoch) denoting a time after which + this token should no longer be valid. + b) 'notBefore' -- A timestamp (as a number of seconds since the epoch) denoting a time before + which this token should be rejected by the server. + c) 'admin' -- Set to true to bypass all security rules (use this for your trusted servers). + d) 'debug' -- Set to true to enable debug mode (so you can see the results of Rules API operations) + e) 'simulate' -- (internal-only for now) Set to true to neuter all API operations (listens / puts + will run security rules but not actually write or return data) + Returns: + A signed Firebase Authentication Token + Raises: + ValueError: if an invalid key is specified in options + """ + if not options: + options = {} + options.update({'admin': self.admin, 'debug': self.debug}) + claims = self._create_options_claims(options) + claims['v'] = self.TOKEN_VERSION + claims['iat'] = int(time.mktime(time.gmtime())) + claims['d'] = data + return self._encode_token(self.secret, claims) + + def _create_options_claims(self, opts): + claims = {} + for k in opts: + if k in self.CLAIMS_MAP: + claims[k] = opts[k] + else: + raise ValueError('Unrecognized Option: %s' % k) + return claims + + def _encode(self, bytes): + encoded = base64.urlsafe_b64encode(bytes) + return encoded.decode('utf-8').replace('=', '') + + def _encode_json(self, obj): + return self._encode(json.dumps(obj).encode("utf-8")) + + def _sign(self, secret, to_sign): + def portable_bytes(s): + try: + return bytes(s, 'utf-8') + except TypeError: + return bytes(s) + return self._encode(hmac.new(portable_bytes(secret), portable_bytes(to_sign), + hashlib.sha256).digest()) + + def _encode_token(self, secret, claims): + encoded_header = self._encode_json(self.HEADERS) + encoded_claims = self._encode_json(claims) + secure_bits = '%s%s%s' % (encoded_header, self.TOKEN_SEP, encoded_claims) + sig = self._sign(secret, secure_bits) + return '%s%s%s' % (secure_bits, self.TOKEN_SEP, sig) diff --git a/firebase/jsonutil.py b/firebase/jsonutil.py new file mode 100644 index 0000000..7487c44 --- /dev/null +++ b/firebase/jsonutil.py @@ -0,0 +1,20 @@ +import datetime +import json +import decimal + +try: + total_seconds = datetime.timedelta.total_seconds +except AttributeError: + total_seconds = lambda self: ((self.days * 86400 + self.seconds) * 10 ** 6 + self.microseconds) / 10 ** 6.0 + + +class JSONEncoder(json.JSONEncoder): + def default(self, obj): + if isinstance(obj, (datetime.datetime, datetime.date)): + return obj.isoformat() + elif isinstance(obj, datetime.timedelta): + return total_seconds(obj) + elif isinstance(obj, decimal.Decimal): + return float(obj) + else: + return json.JSONEncoder.default(self, obj) diff --git a/firebase/lazy.py b/firebase/lazy.py new file mode 100644 index 0000000..4aa53a0 --- /dev/null +++ b/firebase/lazy.py @@ -0,0 +1,83 @@ + +class LazyLoadProxy(object): + # Taken from http://code.activestate.com/recipes/496741-object-proxying/ + __slots__ = ["_obj_fn", "__weakref__", "__proxy_storage"] + def __init__(self, fn, storage=None): + object.__setattr__(self, "_obj_fn", fn) + object.__setattr__(self, "__proxy_storage", storage) + + def __getattribute__(self, name): + return getattr(object.__getattribute__(self, "_obj_fn")(), name) + def __delattr__(self, name): + delattr(object.__getattribute__(self, "_obj_fn")(), name) + def __setattr__(self, name, value): + setattr(object.__getattribute__(self, "_obj_fn")(), name, value) + def __getitem__(self, index): + return object.__getattribute__(self, "_obj_fn")().__getitem__(index) + def __nonzero__(self): + return bool(object.__getattribute__(self, "_obj_fn")()) + def __str__(self): + return str(object.__getattribute__(self, "_obj_fn")()) + def __repr__(self): + return repr(object.__getattribute__(self, "_obj_fn")()) + def __len__(self): + return len(object.__getattribute__(self, "_obj_fn")()) + + _special_names = [ + '__abs__', '__add__', '__and__', '__call__', '__cmp__', '__coerce__', + '__contains__', '__delitem__', '__delslice__', '__div__', '__divmod__', + '__eq__', '__float__', '__floordiv__', '__ge__', #'__getitem__', + '__getslice__', '__gt__', '__hash__', '__hex__', '__iadd__', '__iand__', + '__idiv__', '__idivmod__', '__ifloordiv__', '__ilshift__', '__imod__', + '__imul__', '__int__', '__invert__', '__ior__', '__ipow__', '__irshift__', + '__isub__', '__iter__', '__itruediv__', '__ixor__', '__le__', #'__len__', + '__long__', '__lshift__', '__lt__', '__mod__', '__mul__', '__ne__', + '__neg__', '__oct__', '__or__', '__pos__', '__pow__', '__radd__', + '__rand__', '__rdiv__', '__rdivmod__', '__reduce__', '__reduce_ex__', + '__repr__', '__reversed__', '__rfloorfiv__', '__rlshift__', '__rmod__', + '__rmul__', '__ror__', '__rpow__', '__rrshift__', '__rshift__', '__rsub__', + '__rtruediv__', '__rxor__', '__setitem__', '__setslice__', '__sub__', + '__truediv__', '__xor__', 'next', + ] + + @classmethod + def _create_class_proxy(cls, theclass): + """creates a proxy for the given class""" + + def make_method(name): + def method(self, *args, **kw): + return getattr(object.__getattribute__(self, "_obj_fn")(), name)( + *args, **kw) + return method + + namespace = {} + for name in cls._special_names: + if hasattr(theclass, name): + namespace[name] = make_method(name) + return type("%s(%s)" % (cls.__name__, theclass.__name__), (cls,), namespace) + + def __new__(cls, obj, *args, **kwargs): + """ + creates an proxy instance referencing `obj`. (obj, *args, **kwargs) are + passed to this class' __init__, so deriving classes can define an + __init__ method of their own. + note: _class_proxy_cache is unique per deriving class (each deriving + class must hold its own cache) + """ + try: + cache = cls.__dict__["_class_proxy_cache"] + except KeyError: + cls._class_proxy_cache = cache = {} + try: + theclass = cache[obj.__class__] + except KeyError: + cache[obj.__class__] = theclass = cls._create_class_proxy(obj.__class__) + ins = object.__new__(theclass) + theclass.__init__(ins, obj, *args, **kwargs) + return ins + + +class Proxy(LazyLoadProxy): + # Taken from http://code.activestate.com/recipes/496741-object-proxying/ + def __init__(self, obj): + super(Proxy, self).__init__(lambda: obj) diff --git a/flask_session/08745025510d6009ede4dca60d0017ff b/flask_session/08745025510d6009ede4dca60d0017ff deleted file mode 100644 index 1b5fe6a..0000000 Binary files a/flask_session/08745025510d6009ede4dca60d0017ff and /dev/null differ diff --git a/flask_session/2029240f6d1128be89ddc32729463129 b/flask_session/2029240f6d1128be89ddc32729463129 deleted file mode 100644 index 7886272..0000000 Binary files a/flask_session/2029240f6d1128be89ddc32729463129 and /dev/null differ diff --git a/flask_session/28b2d2ff713d8607c83ca2b915533784 b/flask_session/28b2d2ff713d8607c83ca2b915533784 deleted file mode 100644 index a9d7309..0000000 Binary files a/flask_session/28b2d2ff713d8607c83ca2b915533784 and /dev/null differ diff --git a/flask_session/2e941f0a9674d3217881cb47232f8863 b/flask_session/2e941f0a9674d3217881cb47232f8863 deleted file mode 100644 index 917bd5a..0000000 Binary files a/flask_session/2e941f0a9674d3217881cb47232f8863 and /dev/null differ diff --git a/flask_session/3330e500917f2827cd31576a0e25fdd4 b/flask_session/3330e500917f2827cd31576a0e25fdd4 deleted file mode 100644 index 27cfe6f..0000000 Binary files a/flask_session/3330e500917f2827cd31576a0e25fdd4 and /dev/null differ diff --git a/flask_session/423241a287721e65c73c8c825cdb5cc0 b/flask_session/423241a287721e65c73c8c825cdb5cc0 deleted file mode 100644 index 0f3d824..0000000 Binary files a/flask_session/423241a287721e65c73c8c825cdb5cc0 and /dev/null differ diff --git a/flask_session/7093eb9086515176fa4acf18c271fcae b/flask_session/7093eb9086515176fa4acf18c271fcae deleted file mode 100644 index 540217c..0000000 Binary files a/flask_session/7093eb9086515176fa4acf18c271fcae and /dev/null differ diff --git a/flask_session/70d61d7d25b46c93be6e45f9aa774d76 b/flask_session/70d61d7d25b46c93be6e45f9aa774d76 deleted file mode 100644 index 1054ca0..0000000 Binary files a/flask_session/70d61d7d25b46c93be6e45f9aa774d76 and /dev/null differ diff --git a/flask_session/742026ae752643823bc96225b8caf5b0 b/flask_session/742026ae752643823bc96225b8caf5b0 deleted file mode 100644 index 438d4e6..0000000 Binary files a/flask_session/742026ae752643823bc96225b8caf5b0 and /dev/null differ diff --git a/flask_session/9453170434a156c3928c57abf07e4d15 b/flask_session/9453170434a156c3928c57abf07e4d15 deleted file mode 100644 index 0c16c82..0000000 Binary files a/flask_session/9453170434a156c3928c57abf07e4d15 and /dev/null differ diff --git a/flask_session/94a912f8b8d79d7de2e6c52c6799d736 b/flask_session/94a912f8b8d79d7de2e6c52c6799d736 deleted file mode 100644 index 832af81..0000000 Binary files a/flask_session/94a912f8b8d79d7de2e6c52c6799d736 and /dev/null differ diff --git a/flask_session/99cf419947722ecb1ca03853f61dc46a b/flask_session/99cf419947722ecb1ca03853f61dc46a deleted file mode 100644 index 57aa2dc..0000000 Binary files a/flask_session/99cf419947722ecb1ca03853f61dc46a and /dev/null differ diff --git a/flask_session/a2898f44f57374378ca18b730da5eaa9 b/flask_session/a2898f44f57374378ca18b730da5eaa9 deleted file mode 100644 index 629e642..0000000 Binary files a/flask_session/a2898f44f57374378ca18b730da5eaa9 and /dev/null differ diff --git a/flask_session/a776f137f3fa09c14a101adc4642a2eb b/flask_session/a776f137f3fa09c14a101adc4642a2eb deleted file mode 100644 index dfa9ea4..0000000 Binary files a/flask_session/a776f137f3fa09c14a101adc4642a2eb and /dev/null differ diff --git a/flask_session/b3f3a5588251446674684c153df6ae0f b/flask_session/b3f3a5588251446674684c153df6ae0f deleted file mode 100644 index f207251..0000000 Binary files a/flask_session/b3f3a5588251446674684c153df6ae0f and /dev/null differ diff --git a/flask_session/b42bc44c236be8e3228721f91063e400 b/flask_session/b42bc44c236be8e3228721f91063e400 deleted file mode 100644 index 119658a..0000000 Binary files a/flask_session/b42bc44c236be8e3228721f91063e400 and /dev/null differ diff --git a/flask_session/b63e506fe2fbd130a70e0a42e85985b0 b/flask_session/b63e506fe2fbd130a70e0a42e85985b0 deleted file mode 100644 index cb237b9..0000000 Binary files a/flask_session/b63e506fe2fbd130a70e0a42e85985b0 and /dev/null differ diff --git a/flask_session/be2d644c11a9df026ceb5c54f9c2b852 b/flask_session/be2d644c11a9df026ceb5c54f9c2b852 deleted file mode 100644 index 1188339..0000000 Binary files a/flask_session/be2d644c11a9df026ceb5c54f9c2b852 and /dev/null differ diff --git a/flask_session/c6ad5f967aec698ce8d750601320e3b3 b/flask_session/c6ad5f967aec698ce8d750601320e3b3 deleted file mode 100644 index 540217c..0000000 Binary files a/flask_session/c6ad5f967aec698ce8d750601320e3b3 and /dev/null differ diff --git a/flask_session/d795317bfb9d9f2d85838b3c4a5acc52 b/flask_session/d795317bfb9d9f2d85838b3c4a5acc52 deleted file mode 100644 index 3c2488d..0000000 Binary files a/flask_session/d795317bfb9d9f2d85838b3c4a5acc52 and /dev/null differ diff --git a/flask_session/e77723e0855b17b4ef089479c144ee90 b/flask_session/e77723e0855b17b4ef089479c144ee90 deleted file mode 100644 index b0d8c2b..0000000 Binary files a/flask_session/e77723e0855b17b4ef089479c144ee90 and /dev/null differ diff --git a/flask_session/ebad95eefaf926775f7dfe3745872b63 b/flask_session/ebad95eefaf926775f7dfe3745872b63 deleted file mode 100644 index 825800b..0000000 Binary files a/flask_session/ebad95eefaf926775f7dfe3745872b63 and /dev/null differ diff --git a/flask_session/edf6f65f0aef7b21978f5114a3f8728c b/flask_session/edf6f65f0aef7b21978f5114a3f8728c deleted file mode 100644 index 9d6c3f0..0000000 Binary files a/flask_session/edf6f65f0aef7b21978f5114a3f8728c and /dev/null differ diff --git a/flask_session/f1856e5eb4d5fca44181d55ca9ae210f b/flask_session/f1856e5eb4d5fca44181d55ca9ae210f deleted file mode 100644 index 5c4ebcd..0000000 Binary files a/flask_session/f1856e5eb4d5fca44181d55ca9ae210f and /dev/null differ diff --git a/flask_session/f5de8d3a9a940980becfb19b659f531d b/flask_session/f5de8d3a9a940980becfb19b659f531d deleted file mode 100644 index 332dff7..0000000 Binary files a/flask_session/f5de8d3a9a940980becfb19b659f531d and /dev/null differ diff --git a/images/.DS_Store b/images/.DS_Store new file mode 100644 index 0000000..76de8e2 Binary files /dev/null and b/images/.DS_Store differ diff --git a/images/icons/icon-128x128.png b/images/icons/icon-128x128.png new file mode 100755 index 0000000..4987441 Binary files /dev/null and b/images/icons/icon-128x128.png differ diff --git a/images/icons/icon-144x144.png b/images/icons/icon-144x144.png new file mode 100755 index 0000000..a09ef03 Binary files /dev/null and b/images/icons/icon-144x144.png differ diff --git a/images/icons/icon-152x152.png b/images/icons/icon-152x152.png new file mode 100755 index 0000000..ffbad6b Binary files /dev/null and b/images/icons/icon-152x152.png differ diff --git a/images/icons/icon-192x192.png b/images/icons/icon-192x192.png new file mode 100755 index 0000000..b44838c Binary files /dev/null and b/images/icons/icon-192x192.png differ diff --git a/images/icons/icon-384x384.png b/images/icons/icon-384x384.png new file mode 100755 index 0000000..ce8c0e8 Binary files /dev/null and b/images/icons/icon-384x384.png differ diff --git a/images/icons/icon-512x512.png b/images/icons/icon-512x512.png new file mode 100755 index 0000000..cc639a6 Binary files /dev/null and b/images/icons/icon-512x512.png differ diff --git a/images/icons/icon-72x72.png b/images/icons/icon-72x72.png new file mode 100755 index 0000000..b11068e Binary files /dev/null and b/images/icons/icon-72x72.png differ diff --git a/images/icons/icon-96x96.png b/images/icons/icon-96x96.png new file mode 100755 index 0000000..9d9d332 Binary files /dev/null and b/images/icons/icon-96x96.png differ diff --git a/include/python3.6m b/include/python3.6m deleted file mode 120000 index a0f3e18..0000000 --- a/include/python3.6m +++ /dev/null @@ -1 +0,0 @@ -/Library/Frameworks/Python.framework/Versions/3.6/include/python3.6m \ No newline at end of file diff --git a/info.json b/info.json index cbca6dd..e506f81 100644 --- a/info.json +++ b/info.json @@ -1,6 +1,7 @@ { "uid":"vjsoqWdhbEYIKH4q00Zrp20UFHH3", "name": "TestRaunt", - "shortUID": "572478", - "number": "13166009096" -} \ No newline at end of file + "number": "14255992978", + "gsheets":"https://docs.google.com/spreadsheets/d/14NtYvDzCWJcpclphJlxFRtJcz4VlY7syVXYcU3cm3vk/edit?usp=sharing", + "mainLink": "https://305dd008.ngrok.io" +} diff --git a/main.py b/main.py new file mode 100644 index 0000000..bfb7dbf --- /dev/null +++ b/main.py @@ -0,0 +1,345 @@ +import calendar +import datetime +import json +import random +import smtplib +import time +import uuid +import requests +import pandas as pd +import plivo +import pygsheets +import pyrebase +import pytz +from square.client import Client +import dateparser +from flask import Flask, request, session +from flask import redirect, url_for +from flask import render_template +from flask_session import Session +from flask_sslify import SSLify +from fpdf import FPDF +from werkzeug.datastructures import ImmutableOrderedMultiDict +from firebase import firebase +import sys +dbid = "d1ab1a95-ddb5-4ee4-83db-9179d37f8e78" +infoFile = open("info.json") +info = json.load(infoFile) +uid = info['uid'] +gc = pygsheets.authorize(service_file='static/CedarChatbot-70ec2d781527.json') +email = "cedarchatbot@appspot.gserviceaccount.com" +estName = info['uid'] +estNameStr = info['name'] +botNumber = info["number"] +gsheetsLink = info["gsheets"] +adminSessTime = 3599 +client = plivo.RestClient(auth_id='MAYTVHN2E1ZDY4ZDA2YZ', auth_token='ODgzZDA1OTFiMjE2ZTRjY2U4ZTVhYzNiODNjNDll') +mainLink = "" +authentication = firebase.FirebaseAuthentication('if7swrlQM4k9cBvm0dmWqO3QsI5zjbcdbstSgq1W', 'cajohn0205@gmail.com', + extra={'id': dbid}) + +database = firebase.FirebaseApplication("https://cedarchatbot.firebaseio.com/", authentication=authentication) +data = (database.get("restaurants/" + uid, "/")) +squareToken = database.get("/tokens/",estNameStr.upper()) +items = [] +config = { + "apiKey": "AIzaSyB2it4zPzPdn_bW9OAglTHUtclidAw307o", + "authDomain": "cedarchatbot.firebaseapp.com", + "databaseURL": "https://cedarchatbot.firebaseio.com", + "storageBucket": "cedarchatbot.appspot.com", +} +pyreBase= pyrebase.initialize_app(config) +auth = pyreBase.auth() +storage = pyreBase.storage() +promoPass = "promo-" + str(estName) +addPass = "add-" + str(estName) +remPass = "remove-" + str(estName) +sh = gc.open('TestRaunt') +webLink = "sms:+" + botNumber + "?body=order" +sender = 'receipts@cedarrobots.com' +emailPass = "Cedar2421!" +smtpObj = smtplib.SMTP_SSL("smtp.zoho.com", 465) +smtpObj.login(sender, emailPass) +squareClient = Client( + access_token=squareToken, + environment='production', +) +dayNames = ["MON","TUE","WED","THURS","FRI","SAT","SUN"] +global locationsPaths +locationsPaths = {} +app = Flask(__name__) +sslify = SSLify(app) +app.secret_key = 'fe71b83d-9f64-46c2-b083-3a9d29d02f5d' + +api_locations = squareClient.locations +mobile_authorization_api = squareClient.mobile_authorization +result = api_locations.list_locations() +locationsPaths = {} +# Call the success method to see if the call succeeded +def getSquare(): + if result.is_success(): + # The body property is a list of locations + locations = result.body['locations'] + # Iterate over the list + for location in locations: + if((dict(location.items())["status"]) == "ACTIVE"): + # print((dict(location.items()))) + addrNumber = "" + street = "" + for ltrAddr in range(len(dict(location.items())["address"]['address_line_1'])): + currentLtr = dict(location.items())["address"]['address_line_1'][ltrAddr] + try: + int(currentLtr) + addrNumber += currentLtr + except Exception as e: + street = dict(location.items())["address"]['address_line_1'][ltrAddr+1:len(dict(location.items())["address"]['address_line_1'])] + break + + addrP = str(addrNumber+ ","+ street+","+dict(location.items())["address"]['locality'] + "," + dict(location.items())["address"]['administrative_district_level_1'] + "," + dict(location.items())["address"]['postal_code'][:5]) + timez = dict(location.items())["timezone"] + tz = pytz.timezone(timez) + locationName = (dict(location.items())["name"]).replace(" ","-") + locationId = dict(location.items())["id"] + numb = dict(location.items())['phone_number'] + numb = numb.replace("-","") + numb = numb.replace(" ","") + numb = numb.replace("+","") + locationsPaths.update( + {locationName:{ + "id":locationId,"OCtimes":dict(location.items())["business_hours"]["periods"], + "sqEmail": dict(location.items())['business_email'], + "sqNumber": numb,"name":locationName}} ) + + +def checkLocation(location,custFlag): + try: + locationsPaths[location] + return [0,0] + except Exception as e: + if(custFlag == 0): + return [1,"pickLocation"] + elif(custFlag == 1): + return [1,"MobileStart"] + elif(custFlag == 1): + return [1, "EmployeeLocation"] + +def checkAdminToken(location): + if((idToken == database.get("restaurants/" + uid+"/"+location+"/", "LoginToken")) and (time.time() - database.get("restaurants/" + uid+"/"+location+"/", "LoginTime") < adminSessTime)): + return 0 + else: + return 1 + + +def getReply(msg, number): + authentication = firebase.FirebaseAuthentication('if7swrlQM4k9cBvm0dmWqO3QsI5zjbcdbstSgq1W', + 'cajohn0205@gmail.com', extra={'id': dbid}) + database = firebase.FirebaseApplication("https://cedarchatbot.firebaseio.com/", authentication=authentication) + SMSTimes = database.get("restaurants/" + uid + "/", "SMSTime") + closeTimeHr = int(SMSTimes["end"][0:2]) + closeTimeMin = int(SMSTimes["end"][3:5]) + openTimeHr = int(SMSTimes["start"][0:2]) + openTimeMin = int(SMSTimes["start"][3:5]) + closeCheck = float(closeTimeHr) + float(closeTimeMin/100.0) + openCheck = float(openTimeHr) + float(openTimeMin/100.0) + currentHour = float(datetime.datetime.now(tz).strftime("%H")) + currentMin = float(datetime.datetime.now(tz).strftime("%M"))/100.0 + currentTime = currentHour + currentMin + if(openCheck <= currentTime <= closeCheck): + msg = msg.lower() + msg.replace("\n", "") + msg.replace(".", "") + msg.replace(" ", "") + msg = ''.join(msg.split()) + + if (msg == "order" or msg == "ordew" or msg == "ord" or msg == "ordet" or msg == "oderr" or msg == "ordee" or ( + "ord" in msg)): + reply = "Hi welcome to "+estNameStr+"! click the link below to order \n" + str(mainLink)+"/smsinit/"+str(number) + return reply + else: + return ("no msg") + else: + return ("no msg") + + +@app.route('//admin',methods=["POST","GET"]) +def login(location): + if(checkLocation(location,0)[0] == 1): + return(redirect(url_for(checkLocation(location,0)[1]))) + return render_template("login.html", btn=str("admin2"), restName=estNameStr) + + +@app.route('//admin2', methods=["POST"]) +def loginPageCheck(location): + if(checkLocation(location,0)[0] == 1): + return(redirect(url_for(checkLocation(location,0)[1]))) + request.parameter_storage_class = ImmutableOrderedMultiDict + rsp = ((request.form)) + email = str(rsp["email"]) + pw = str(rsp["pw"]) + try: + user = auth.sign_in_with_email_and_password(str(rsp["email"]), pw) + # print(user['localId']) + authentication = firebase.FirebaseAuthentication('if7swrlQM4k9cBvm0dmWqO3QsI5zjbcdbstSgq1W', + 'cajohn0205@gmail.com', extra={'id': dbid}) + fireapp = firebase.FirebaseApplication('https://cedarchatbot.firebaseio.com/', authentication=authentication) + testDB = (fireapp.get("/restaurants/", user["localId"])) + if (str(user["localId"]) == str(uid) and testDB != None): + print("found") + database = firebase.FirebaseApplication("https://cedarchatbot.firebaseio.com/", + authentication=authentication) + + LoginToken = str((uuid.uuid4())) +"-"+str((uuid.uuid4())) + database.put("/restaurants/" + estName + "/"+location+"/", "LoginToken",LoginToken) + database.put("/restaurants/" + estName + "/"+location+"/", "LoginTime",time.time()) + session['fbToken'] = user['idToken'] + session['token'] = LoginToken + return redirect(url_for('.panel', location=location)) + else: + authentication = firebase.FirebaseAuthentication('if7swrlQM4k9cBvm0dmWqO3QsI5zjbcdbstSgq1W', + 'cajohn0205@gmail.com', extra={'id': dbid}) + print("incorrect password") + database = firebase.FirebaseApplication("https://cedarchatbot.firebaseio.com/", + authentication=authentication) + return render_template("login2.html", btn=str(estNameStr), restName=estNameStr) + except Exception: + print("exec") + authentication = firebase.FirebaseAuthentication('if7swrlQM4k9cBvm0dmWqO3QsI5zjbcdbstSgq1W', + 'cajohn0205@gmail.com', extra={'id': dbid}) + database = firebase.FirebaseApplication("https://cedarchatbot.firebaseio.com/", + authentication=authentication) + return render_template("login2.html", btn=str("admin"), restName=estNameStr) + + +@app.route('//adminpanel', methods=["GET"]) +def panel(location): + idToken = session.get('token', None) + fbToken = session.get('fbToken', None) + authentication = firebase.FirebaseAuthentication('if7swrlQM4k9cBvm0dmWqO3QsI5zjbcdbstSgq1W', + 'cajohn0205@gmail.com', extra={'id': dbid}) + database = firebase.FirebaseApplication("https://cedarchatbot.firebaseio.com/", + authentication=authentication) + if((idToken == database.get("restaurants/" + uid+"/"+location+"/", "LoginToken")) and (time.time() - database.get("restaurants/" + uid+"/"+location+"/", "LoginTime") < adminSessTime)): + return render_template("panel.html", + gcard=location+"/giftcard", + addCpn=location+"/addCoupon", + remCpn=location+"/removeCoupon", + editMenu=location+"/editMenu", + createMenu=location+"/createMenu", + importMenu=location+"/importMenu", + outStck=location+"/changestock", + promo=location+"/promoSuite", + spreadSheet=gsheetsLink) + else: + return redirect(url_for('.login', location=location)) + + +@app.route('//createMenu', methods=["POST"]) +def meun1(location): + idToken = session.get('token', None) + fbToken = session.get('fbToken', None) + authentication = firebase.FirebaseAuthentication('if7swrlQM4k9cBvm0dmWqO3QsI5zjbcdbstSgq1W', + 'cajohn0205@gmail.com', extra={'id': dbid}) + database = firebase.FirebaseApplication("https://cedarchatbot.firebaseio.com/", + authentication=authentication) + if((idToken == database.get("restaurants/" + uid+"/"+location+"/", "LoginToken")) and (time.time() - database.get("restaurants/" + uid+"/"+location+"/", "LoginTime") < adminSessTime)): + return render_template("createMenu1.html", + next=location+"/createMenu2", + back=location+"/adminpanel") + else: + return redirect(url_for('.login', location=location)) + +@app.route('//createMenu', methods=["POST"]) +def createMenu(location): + idToken = session.get('token', None) + fbToken = session.get('fbToken', None) + authentication = firebase.FirebaseAuthentication('if7swrlQM4k9cBvm0dmWqO3QsI5zjbcdbstSgq1W', + 'cajohn0205@gmail.com', extra={'id': dbid}) + database = firebase.FirebaseApplication("https://cedarchatbot.firebaseio.com/", + authentication=authentication) + if(checkAdminToken(location) == 1): + return redirect(url_for('.login', location=location)) + return render_template("createMenu1.html", + next=location+"/createMenu2", + back=location+"/adminpanel") + +@app.route('//createMenu2', methods=["POST"]) +def createMenu2(location): + idToken = session.get('token', None) + fbToken = session.get('fbToken', None) + request.parameter_storage_class = ImmutableOrderedMultiDict + rsp = ((request.form)) + menuName = rsp["Name"] + menuDays = rsp["Days"] + authentication = firebase.FirebaseAuthentication('if7swrlQM4k9cBvm0dmWqO3QsI5zjbcdbstSgq1W', + 'cajohn0205@gmail.com', extra={'id': dbid}) + database = firebase.FirebaseApplication("https://cedarchatbot.firebaseio.com/", + authentication=authentication) + if(checkAdminToken(location) == 1): + return redirect(url_for('.login', location=location)) + return render_template("createMenu1.html", + next=location+"/createMenu3", + back=location+"/adminpanel") + + + + + + + +@app.route('/admin', methods=["GET"]) +def pickLocation(): + authentication = firebase.FirebaseAuthentication('if7swrlQM4k9cBvm0dmWqO3QsI5zjbcdbstSgq1W', + 'cajohn0205@gmail.com', extra={'id': dbid}) + database = firebase.FirebaseApplication("https://cedarchatbot.firebaseio.com/", + authentication=authentication) + getSquare() + locs = [] + for lc in locationsPaths: + locs.append(locationsPaths[lc]["name"]) + return (render_template("pickLocation.html", btn="uid", locs=locs,len=len(locs))) + +@app.route('/uid', methods=["POST"]) +def pickLocation2(): + request.parameter_storage_class = ImmutableOrderedMultiDict + rsp = ((request.form)) + locationPick = rsp["location"] + authentication = firebase.FirebaseAuthentication('if7swrlQM4k9cBvm0dmWqO3QsI5zjbcdbstSgq1W', + 'cajohn0205@gmail.com', extra={'id': dbid}) + database = firebase.FirebaseApplication("https://cedarchatbot.firebaseio.com/", + authentication=authentication) + return redirect(url_for('.login', location=locationPick)) + +@app.route('/sms') +def inbound_sms(): + # Sender's phone number + from_number = request.values.get('From') + # Receiver's phone number - Plivo number + to_number = request.values.get('To') + # The text which was received + text = request.values.get('Text') + print('Message received - From: %s, To: %s, Text: %s' % (from_number, to_number, text)) + resp = getReply(text, from_number) + print(str(resp)) + if (resp != "no msg"): + client.messages.create( + src=botNumber, + dst=from_number, + text=resp + ) + return '200' + + +if __name__ == '__main__': + try: + getSquare() + print(locationsPaths) + app.secret_key = 'fe71b83d-9f64-46c2-b083-3a9d29d02f5d' + sslify = SSLify(app) + app.config['SESSION_TYPE'] = 'filesystem' + sess = Session() + sess.init_app(app) + app.permanent_session_lifetime = datetime.timedelta(minutes=200) + #app.debug = True + app.run(host="0.0.0.0", port=8888) + except KeyboardInterrupt: + sys.exit() diff --git a/manifest.json b/manifest.json new file mode 100755 index 0000000..ba034c5 --- /dev/null +++ b/manifest.json @@ -0,0 +1,53 @@ +{ + "name": "Cedar Robotics Food Ordering", + "short_name": "Order Food", + "theme_color": "#000000", + "background_color": "#ffffff", + "display": "fullscreen", + "orientation": "portrait", + "Scope": "/", + "start_url": "/vjsoqWdhbEYIKH4q00Zrp20UFHH3check", + "icons": [ + { + "src": "images/icons/icon-72x72.png", + "sizes": "72x72", + "type": "image/png" + }, + { + "src": "images/icons/icon-96x96.png", + "sizes": "96x96", + "type": "image/png" + }, + { + "src": "images/icons/icon-128x128.png", + "sizes": "128x128", + "type": "image/png" + }, + { + "src": "images/icons/icon-144x144.png", + "sizes": "144x144", + "type": "image/png" + }, + { + "src": "images/icons/icon-152x152.png", + "sizes": "152x152", + "type": "image/png" + }, + { + "src": "images/icons/icon-192x192.png", + "sizes": "192x192", + "type": "image/png" + }, + { + "src": "images/icons/icon-384x384.png", + "sizes": "384x384", + "type": "image/png" + }, + { + "src": "images/icons/icon-512x512.png", + "sizes": "512x512", + "type": "image/png" + } + ], + "splash_pages": null +} \ No newline at end of file diff --git a/menus/TestRaunt-breakfast-menu.pdf b/menus/TestRaunt-breakfast-menu.pdf index 3a45064..3e9fcc5 100644 Binary files a/menus/TestRaunt-breakfast-menu.pdf and b/menus/TestRaunt-breakfast-menu.pdf differ diff --git a/menus/TestRaunt-lunch-dinner-menu.pdf b/menus/TestRaunt-lunch-dinner-menu.pdf index 1725385..c6bfb32 100644 Binary files a/menus/TestRaunt-lunch-dinner-menu.pdf and b/menus/TestRaunt-lunch-dinner-menu.pdf differ diff --git a/printer.py b/printer.py new file mode 100644 index 0000000..345baf7 --- /dev/null +++ b/printer.py @@ -0,0 +1,10 @@ +from escpos.printer import Usb +authentication = firebase.FirebaseAuthentication('if7swrlQM4k9cBvm0dmWqO3QsI5zjbcdbstSgq1W', 'cajohn0205@gmail.com',extra={'id': "d1ab1a95-ddb5-4ee4-83db-9179d37f8e78"}) +database = firebase.FirebaseApplication("https://cedarchatbot.firebaseio.com/", authentication=authentication) + + +#0483:070b +Epson = Usb(0x0483, 0x070b, timeout=0, in_ep=0x82, out_ep=0x02) +Epson.set(align='center', width=3, height=3) +Epson.text('Jubby\n') +Epson.cut() diff --git a/pyvenv.cfg b/pyvenv.cfg new file mode 100644 index 0000000..2985335 --- /dev/null +++ b/pyvenv.cfg @@ -0,0 +1,3 @@ +home = /usr/local/bin +include-system-site-packages = false +version = 3.7.4 diff --git a/requirements.txt b/requirements.txt index 0d5921a..0ae4031 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,7 +1,6 @@ asn1crypto==0.24.0 -awsebcli==3.15.3 blessed==1.15.0 -botocore==1.12.215 +CacheControl==0.12.5 cached-property==1.5.1 cachetools==3.1.1 cement==2.8.2 @@ -12,6 +11,9 @@ Click==7.0 codename==1.1 colorama==0.3.9 cryptography==2.7 +dateparser==0.7.2 +decorator==4.4.0 +deprecation==2.0.7 docker==3.7.3 docker-compose==1.23.2 docker-pycreds==0.4.0 @@ -21,10 +23,10 @@ docutils==0.15.2 Flask==1.1.1 Flask-Session==0.3.1 Flask-SocketIO==4.2.1 +Flask-SSLify==0.1.5 Flask-WTF==0.14.2 fpdf==1.7.2 future==0.16.0 -fuzzywuzzy==0.17.0 gcloud==0.17.0 gevent==1.4.0 google-api-python-client==1.7.11 @@ -33,26 +35,34 @@ google-auth-httplib2==0.0.3 google-auth-oauthlib==0.4.0 googleapis-common-protos==1.6.0 greenlet==0.4.15 +gunicorn==19.3.0 httplib2==0.13.1 idna==2.7 +importlib-metadata==0.23 inexactsearch==1.0.2 itsdangerous==1.1.0 +jedi==0.14.1 Jinja2==2.10.1 jmespath==0.9.4 +jsonpickle==0.9.6 jsonschema==2.6.0 jws==0.1.3 +lxml==4.4.1 MarkupSafe==1.1.1 +more-itertools==7.2.0 +msgpack==0.6.1 ndg-httpsclient==0.5.1 -nexmo==2.4.0 -nltk==3.4.4 -num2words==0.5.10 numpy==1.17.0 oauth2client==3.0.0 oauthlib==3.1.0 +packaging==19.2 pandas==0.25.0 +parso==0.5.1 pathspec==0.5.9 paypalrestsdk==1.13.1 pipreqs==0.4.9 +plivo==4.3.2 +pluggy==0.13.0 protobuf==3.9.1 pusher==2.1.4 pyasn1==0.4.6 @@ -63,18 +73,20 @@ pygsheets==2.0.2 PyJWT==1.7.1 PyNaCl==1.3.0 pyOpenSSL==19.0.0 +pyparsing==2.4.2 Pyrebase==3.0.27 python-dateutil==2.8.0 python-engineio==3.9.3 -python-firebase==1.2 +python-jsonrpc-server==0.2.0 python-jwt==2.0.1 -python-Levenshtein==0.12.0 +python-language-server==0.28.3 python-shorturl==0.0.4 python-socketio==4.3.1 pytz==2019.2 PyYAML==3.13 redis==3.3.8 -requests==2.20.1 +regex==2019.8.19 +requests==2.11.1 requests-oauthlib==1.2.0 requests-toolbelt==0.7.0 rsa==4.0 @@ -82,15 +94,17 @@ semantic-version==2.5.0 silpa-common==0.3 six==1.11.0 soundex==1.1.3 +squareup==3.20190814.0 termcolor==1.1.0 texttable==0.9.1 +tzlocal==2.0.0 uritemplate==3.0.0 urllib3==1.24.3 virtualenv==16.7.4 wcwidth==0.1.7 websocket-client==0.56.0 Werkzeug==0.15.5 -words2num==0.2.3 WTForms==2.2.1 xlwt==1.3.0 yarg==0.1.9 +zipp==0.6.0 diff --git a/static/css/main.css b/static/css/main.css index 5ced90e..fab1b52 100644 --- a/static/css/main.css +++ b/static/css/main.css @@ -1,4 +1,4 @@ -body,h1,h2,h3,h4,h5,h6,button,li{font-family: "Lato", sans-serif;} +body,h1,h2,h3,h4,h5,h6,button,li{font-family: "Raleway";} body, html { height: 100%; color: white; @@ -7,8 +7,9 @@ body, html { background-color: black; } -button{ - background-color: #FFFFFF; +button { +font-family: Raleway; +background-color: #FFFFFF; border: none; color: black; padding: 5px 10px; @@ -18,7 +19,23 @@ button{ font-size: 20px; margin: 2px 2px; cursor: pointer; - border-radius: 20px; + outline: none; + text-decoration: none; + color: #000000; + background: #ffffff; + display: inline-block; + box-shadow: 0 4px 6px rgba(50, 50, 93, .11), 0 1px 3px rgba(0, 0, 0, .08); + letter-spacing: 0.025em; + text-decoration: none; + -webkit-transition: all 250ms ease; + transition: all 250ms ease; +} + +button:hover { + text-align: center; + transform: translateY(-5px); + box-shadow: 0 7px 14px rgba(50, 50, 93, .10), 0 3px 6px rgba(0, 0, 0, .08); + background-color: #d9d9d9; } dropbtn { background-color: #4CAF50; @@ -85,5 +102,83 @@ dropdown:hover .dropbtn {background-color: #3e8e41;} .centered img { width: 150px; - border-radius: 50%; -} \ No newline at end of file +} +#first { + background-color: #000000; +} +#second { + background-color: #FF8A66; +} +.section { + padding: 100px; + padding-left: 150px; +} +.section input[type="radio"], +.section input[type="checkbox"]{ + display: none; +} +.container { + margin-bottom: 10px; +} +.container label { + position: relative; +} + +/* Base styles for spans */ +.container span::before, +.container span::after { + content: ''; + position: absolute; + top: 0; + bottom: 0; + margin: auto; +} + +/* Radio buttons */ +.container span.radio:hover { + cursor: pointer; +} +.container span.radio::before { + left: -52px; + width: 45px; + height: 25px; + background-color: #c4c4c4; + border-radius: 50px; +} +.container span.radio::after { + left: -49px; + width: 17px; + height: 17px; + border-radius: 10px; + background-color: #7d7d7d; + transition: left .25s, background-color .25s; +} +input[type="radio"]:checked + label span.radio::after { + left: -27px; + background-color: #ffffff; +} + +/* Check-boxes */ +.container span.checkbox::before { + width: 27px; + height: 27px; + background-color: #000000; + left: -35px; + box-sizing: border-box; + border: 3px solid transparent; + transition: border-color .2s; +} +.container span.checkbox:hover::before { + border: 3px solid #F0FF76; +} +.container span.checkbox::after { + content: '\f00c'; + font-family: 'FontAwesome'; + left: -31px; + top: 2px; + color: transparent; + transition: color .2s; +} +input[type="checkbox"]:checked + label span.checkbox::after { + color: #62AFFF; +} diff --git a/static/css/sq-payment-form.css b/static/css/sq-payment-form.css new file mode 100644 index 0000000..3e83a9a --- /dev/null +++ b/static/css/sq-payment-form.css @@ -0,0 +1,181 @@ +.sq-field-wrapper { + display: flex; + flex-flow: row nowrap; + margin-bottom: 16px; +} + +.sq-field { + margin-bottom: 16px; + width: 100%; +} + +.sq-field:first-child { + margin-left: 0; +} + +.sq-field:last-child { + margin-right: 0; +} + +.sq-field--in-wrapper { + flex-grow: 1; + margin: 0 8px; +} + +.sq-label { + margin-bottom: 8px; + text-transform: uppercase; +} + +.sq-input { + background-color: #fff; + border-style: solid; + border-width: 1px; + overflow: hidden; + transition: border-color 0.25s ease; + width: 100%; +} + +.sq-input--focus { + background-color: #fbfdff; +} + +.sq-input--error { + background-color: #fbfdff; +} + +.sq-button { + color: #fff; + padding: 16px; + width: 100%; +} + +.sq-button:active { + color: #fff; +} +.sq-payment-form { + max-width: 100%; + padding: 20px 20px 5px; + width: 380px; +} + +.sq-label { + color: #000000; + font-size: 14px; + font-family: "Helvetica Neue", "Helvetica", sans-serif; + font-weight: 500; + letter-spacing: 0.5px; +} + +.sq-input { + border-color: #E0E2E3; + border-radius: 4px; +} + +.sq-input--focus { + border-color: #4A90E2; +} + +.sq-input--error { + border-color: #e02e2f; +} + +.sq-button { + background: #4A90E2; + border-radius: 4px; + font-size: 16px; + font-weight: 600; + letter-spacing: 1px; +} + +.sq-button:active { + background: #4A90E2; +} +.sq-wallet-divider { + margin: 24px 0; + position: relative; + text-align: center; + width: 100%; +} + +.sq-wallet-divider:after, .sq-wallet-divider::after, .sq-wallet-divider:before, .sq-wallet-divider::before { + background: #bbb; + content: ''; + display: block; + height: 1px; + left: 0; + position: absolute; + right: 0; + top: 9px; +} + +.sq-wallet-divider:after, .sq-wallet-divider::after { + right: 65%; +} + +.sq-wallet-divider:before, .sq-wallet-divider::before { + left: 65%; +} + +.sq-wallet-divider__text { + color: #bbb; + padding: 10px; + text-transform: uppercase; +} + +/* Indicates how Google Pay button will appear */ +.button-google-pay { + width: 100%; + min-height: 40px; + padding: 11px 24px; + margin-bottom: 18px; + background-color: #000; + background-image: url(data:image/svg+xml,%3Csvg%20width%3D%22103%22%20height%3D%2217%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%3E%3Cg%20fill%3D%22none%22%20fill-rule%3D%22evenodd%22%3E%3Cpath%20d%3D%22M.148%202.976h3.766c.532%200%201.024.117%201.477.35.453.233.814.555%201.085.966.27.41.406.863.406%201.358%200%20.495-.124.924-.371%201.288s-.572.64-.973.826v.084c.504.177.912.471%201.225.882.313.41.469.891.469%201.442a2.6%202.6%200%200%201-.427%201.47c-.285.43-.667.763-1.148%201.001A3.5%203.5%200%200%201%204.082%2013H.148V2.976zm3.696%204.2c.448%200%20.81-.14%201.085-.42.275-.28.413-.602.413-.966s-.133-.684-.399-.959c-.266-.275-.614-.413-1.043-.413H1.716v2.758h2.128zm.238%204.368c.476%200%20.856-.15%201.141-.448.285-.299.427-.644.427-1.036%200-.401-.147-.749-.441-1.043-.294-.294-.688-.441-1.183-.441h-2.31v2.968h2.366zm5.379.903c-.453-.518-.679-1.239-.679-2.163V5.86h1.54v4.214c0%20.579.138%201.013.413%201.302.275.29.637.434%201.085.434.364%200%20.686-.096.966-.287.28-.191.495-.446.644-.763a2.37%202.37%200%200%200%20.224-1.022V5.86h1.54V13h-1.456v-.924h-.084c-.196.336-.5.611-.91.826-.41.215-.845.322-1.302.322-.868%200-1.528-.259-1.981-.777zm9.859.161L16.352%205.86h1.722l2.016%204.858h.056l1.96-4.858H23.8l-4.41%2010.164h-1.624l1.554-3.416zm8.266-6.748h1.666l1.442%205.11h.056l1.61-5.11h1.582l1.596%205.11h.056l1.442-5.11h1.638L36.392%2013h-1.624L33.13%207.876h-.042L31.464%2013h-1.596l-2.282-7.14zm12.379-1.337a1%201%200%200%201-.301-.735%201%201%200%200%201%20.301-.735%201%201%200%200%201%20.735-.301%201%201%200%200%201%20.735.301%201%201%200%200%201%20.301.735%201%201%200%200%201-.301.735%201%201%200%200%201-.735.301%201%201%200%200%201-.735-.301zM39.93%205.86h1.54V13h-1.54V5.86zm5.568%207.098a1.967%201.967%200%200%201-.686-.406c-.401-.401-.602-.947-.602-1.638V7.218h-1.246V5.86h1.246V3.844h1.54V5.86h1.736v1.358H45.75v3.36c0%20.383.075.653.224.812.14.187.383.28.728.28.159%200%20.299-.021.42-.063.121-.042.252-.11.392-.203v1.498c-.308.14-.681.21-1.12.21-.317%200-.616-.051-.896-.154zm3.678-9.982h1.54v2.73l-.07%201.092h.07c.205-.336.511-.614.917-.833.406-.22.842-.329%201.309-.329.868%200%201.53.254%201.988.763.457.509.686%201.202.686%202.079V13h-1.54V8.688c0-.541-.142-.947-.427-1.218-.285-.27-.656-.406-1.113-.406-.345%200-.656.098-.931.294a2.042%202.042%200%200%200-.651.777%202.297%202.297%200%200%200-.238%201.029V13h-1.54V2.976zm32.35-.341v4.083h2.518c.6%200%201.096-.202%201.488-.605.403-.402.605-.882.605-1.437%200-.544-.202-1.018-.605-1.422-.392-.413-.888-.62-1.488-.62h-2.518zm0%205.52v4.736h-1.504V1.198h3.99c1.013%200%201.873.337%202.582%201.012.72.675%201.08%201.497%201.08%202.466%200%20.991-.36%201.819-1.08%202.482-.697.665-1.559.996-2.583.996h-2.485v.001zm7.668%202.287c0%20.392.166.718.499.98.332.26.722.391%201.168.391.633%200%201.196-.234%201.692-.701.497-.469.744-1.019.744-1.65-.469-.37-1.123-.555-1.962-.555-.61%200-1.12.148-1.528.442-.409.294-.613.657-.613%201.093m1.946-5.815c1.112%200%201.989.297%202.633.89.642.594.964%201.408.964%202.442v4.932h-1.439v-1.11h-.065c-.622.914-1.45%201.372-2.486%201.372-.882%200-1.621-.262-2.215-.784-.594-.523-.891-1.176-.891-1.96%200-.828.313-1.486.94-1.976s1.463-.735%202.51-.735c.892%200%201.629.163%202.206.49v-.344c0-.522-.207-.966-.621-1.33a2.132%202.132%200%200%200-1.455-.547c-.84%200-1.504.353-1.995%201.062l-1.324-.834c.73-1.045%201.81-1.568%203.238-1.568m11.853.262l-5.02%2011.53H96.42l1.864-4.034-3.302-7.496h1.635l2.387%205.749h.032l2.322-5.75z%22%20fill%3D%22%23FFF%22%2F%3E%3Cpath%20d%3D%22M75.448%207.134c0-.473-.04-.93-.116-1.366h-6.344v2.588h3.634a3.11%203.11%200%200%201-1.344%202.042v1.68h2.169c1.27-1.17%202.001-2.9%202.001-4.944%22%20fill%3D%22%234285F4%22%2F%3E%3Cpath%20d%3D%22M68.988%2013.7c1.816%200%203.344-.595%204.459-1.621l-2.169-1.681c-.603.406-1.38.643-2.29.643-1.754%200-3.244-1.182-3.776-2.774h-2.234v1.731a6.728%206.728%200%200%200%206.01%203.703%22%20fill%3D%22%2334A853%22%2F%3E%3Cpath%20d%3D%22M65.212%208.267a4.034%204.034%200%200%201%200-2.572V3.964h-2.234a6.678%206.678%200%200%200-.717%203.017c0%201.085.26%202.11.717%203.017l2.234-1.731z%22%20fill%3D%22%23FABB05%22%2F%3E%3Cpath%20d%3D%22M68.988%202.921c.992%200%201.88.34%202.58%201.008v.001l1.92-1.918c-1.165-1.084-2.685-1.75-4.5-1.75a6.728%206.728%200%200%200-6.01%203.702l2.234%201.731c.532-1.592%202.022-2.774%203.776-2.774%22%20fill%3D%22%23E94235%22%2F%3E%3C%2Fg%3E%3C%2Fsvg%3E); + background-origin: content-box; + background-position: center; + background-repeat: no-repeat; + background-size: contain; + border: 0; + border-radius: 4px; + box-shadow: 0 1px 1px 0 rgba(60, 64, 67, 0.30), 0 1px 3px 1px rgba(60, 64, 67, 0.15); + outline: 0; + cursor: pointer; + display: none; +} + + +.sq-apple-pay { + -webkit-appearance: -apple-pay-button; + border: none; + height: 48px; + margin-bottom: 12px; + width: 100%; + display: none; +} +.sq-masterpass { + background-color: #000; + background-image: url(https://masterpass.com/dyn/img/btn/global/mp_chk_btn_384x048px.svg); + background-repeat: no-repeat; + background-size: contain; + background-position: center right; + border-radius: 5px; + height: 42px; + margin-bottom: 16px; + width: 100%; + display: none; +} + +.sq-button:hover { + cursor: pointer; + background-color: #4281CB; +} + +#error { + width: 100%; + margin-top: 16px; + font-size: 14px; + color: red; + font-weight: 500; + text-align: center; + opacity: 0.8; +} diff --git a/static/css/style.css b/static/css/style.css deleted file mode 100644 index 99b8da2..0000000 --- a/static/css/style.css +++ /dev/null @@ -1,13 +0,0 @@ -body { - background-color: lightblue; -} - -h1 { - color: white; - text-align: center; -} - -p { - font-family: verdana; - font-size: 20px; -} \ No newline at end of file diff --git a/templates/Name.html b/templates/Name.html new file mode 100644 index 0000000..1e1c6aa --- /dev/null +++ b/templates/Name.html @@ -0,0 +1,62 @@ + + + + + Order Food + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ +
+

Enter Your Name

+

+ +

+
+
+

Is This Order For Here or To Go?

+
+
+ +
+
+
+ +
+
+
+ +
+
+
+
+
+
+ + diff --git a/templates/NameKiosk.html b/templates/NameKiosk.html new file mode 100644 index 0000000..b5e5ac3 --- /dev/null +++ b/templates/NameKiosk.html @@ -0,0 +1,58 @@ + + + + + Order Food + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ +
+

Enter Your Name

+

+ +

+
+
+

Is This Order For Here or To Go?

+
+
+ +
+
+
+ +
+
+
+
+
+
+ + diff --git a/templates/NameKisok.html b/templates/NameKisok.html new file mode 100644 index 0000000..b5e5ac3 --- /dev/null +++ b/templates/NameKisok.html @@ -0,0 +1,58 @@ + + + + + Order Food + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ +
+

Enter Your Name

+

+ +

+
+
+

Is This Order For Here or To Go?

+
+
+ +
+
+
+ +
+
+
+
+
+
+ + diff --git a/templates/addform.html b/templates/addform.html index b786548..cc7814c 100644 --- a/templates/addform.html +++ b/templates/addform.html @@ -3,6 +3,7 @@ Add Items + @@ -21,27 +22,30 @@ - - + + + -
-

logo

Edit {{restName}} Menu


Add Item


Enter Name

- +

Enter description for this item (optional)

+

Enter item category EX. Drinks

+ +

Enter any potential allergens or warnings EX. contains raw fish or contains peanuts

+

Enter Number Of Sizes

- -

Enter Menu for This Item Ex. Breakfast if this item is available all day enter 'all'

- + +

Enter Menu for This Item EX. Breakfast if this item is available all day enter 'all'

+

diff --git a/templates/addform2.html b/templates/addform2.html index c50d1b0..fc5d916 100644 --- a/templates/addform2.html +++ b/templates/addform2.html @@ -3,6 +3,7 @@ Add Items + @@ -21,10 +22,10 @@ - - + + + -
@@ -37,12 +38,12 @@

Add Sizes

Enter Size {{i+1}} Name (If only size enter 'u')

Enter Size {{i+1}} Price

- +

Enter SKU ID

{%endfor%}

Enter Number of Toppings

- +

diff --git a/templates/addform3.html b/templates/addform3.html index a976342..33480e5 100644 --- a/templates/addform3.html +++ b/templates/addform3.html @@ -3,6 +3,7 @@ Add Items + @@ -21,25 +22,27 @@ - - + + + -

Edit {{restName}} Menu


-

Add Toppings, Customizations, and Flavors

+

Add Toppings, Customizations, and/or Flavors


{%for i in range(0, len)%}

Enter Name For Topping/Customization #{{i+1}}

- +

Enter Price For Topping/Customization #{{i+1}}

- +

Enter SKU ID

- + +

Enter any potential warnings EX. contains peanuts or contains raw fish

+ {%endfor%}

diff --git a/templates/addgcard.html b/templates/addgcard.html new file mode 100644 index 0000000..aa724f4 --- /dev/null +++ b/templates/addgcard.html @@ -0,0 +1,47 @@ + + + + Add Gift Card + + + + + + + + + + + + + + + + + + + + + + + + + + +
+

Create Gift Card

+
+ +

Enter Card Code

+ +
+
+

Enter card value

+ +
+
+
+ +
+ + \ No newline at end of file diff --git a/templates/addgcard2.html b/templates/addgcard2.html new file mode 100644 index 0000000..062ba34 --- /dev/null +++ b/templates/addgcard2.html @@ -0,0 +1,35 @@ + + + + Add Gift Card + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+

Gift Card added

+ + \ No newline at end of file diff --git a/templates/addgcardFailed.html b/templates/addgcardFailed.html new file mode 100644 index 0000000..1afdbdb --- /dev/null +++ b/templates/addgcardFailed.html @@ -0,0 +1,35 @@ + + + + Payment Failed + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+

Your Card has been Declined try again

+ + \ No newline at end of file diff --git a/templates/checkPromo.html b/templates/checkPromo.html index 566549b..27ed1e1 100644 --- a/templates/checkPromo.html +++ b/templates/checkPromo.html @@ -1,10 +1,49 @@ - - Title + Add Coupon + + + + + + + + + + + + + + + + + + + + + + + + +

This Text will be sent to {{numUsr}} customers, please double check it for any errors or mistakes

+

+

{{name}}

+
+
+

+
+ +
+

+

+

+
+ +
+

\ No newline at end of file diff --git a/templates/coupon.html b/templates/coupon.html index 9552d64..116d832 100644 --- a/templates/coupon.html +++ b/templates/coupon.html @@ -3,6 +3,7 @@ Add Coupon + @@ -21,10 +22,10 @@ - - + + + -
@@ -34,13 +35,13 @@

Add Coupon


Enter Coupon Name Ex. halfcof

- +

Enter SKU this coupon applies to

- +

Enter Coupon Discount Ex. 50% or 2.25

- +

Enter Coupon Limit Ex. 1

- +

diff --git a/templates/dispQuote.html b/templates/dispQuote.html new file mode 100644 index 0000000..1196f2a --- /dev/null +++ b/templates/dispQuote.html @@ -0,0 +1,56 @@ + + + Order Food + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+

Delivery Fee ${{fee}}

+

+

Estimate Delivery Time {{duration}} minutes

+
+
+

Delivery Requires a minimum order of ${{minAmt}}

+
+
+

+ + +
+
+
+ +
+
+
+ +

Quote valid for next 5 minutes, may change after that

+
+
+
+ diff --git a/templates/getAddr.html b/templates/getAddr.html new file mode 100644 index 0000000..fa7f4b6 --- /dev/null +++ b/templates/getAddr.html @@ -0,0 +1,50 @@ + + + + Order Food + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+

+
+ State
+
+ City
+
+ Zip Code
+
+ Street Address
+
+ Apartment,suite,unit,etc
+
+
+

+
+

+ diff --git a/templates/getTable.html b/templates/getTable.html new file mode 100644 index 0000000..9d72eff --- /dev/null +++ b/templates/getTable.html @@ -0,0 +1,51 @@ + + + + Order Food + + + + + + + + + + + + + + + + + + + + + + + + + + +
+

Enter your table number

+
+
+
+ +
+
+ +
+
+
+

+
+ +
+

+
+
+ + \ No newline at end of file diff --git a/templates/getTime.html b/templates/getTime.html new file mode 100644 index 0000000..f59808f --- /dev/null +++ b/templates/getTime.html @@ -0,0 +1,57 @@ + + + + Order Food + + + + + + + + + + + + + + + + + + + + + + + + + + +
+

When Do you want your order?

+
+
+

+
+ +
+
+

+ +
+

Later

+ + +
+
+

+
+
+ +
+

+
+
+ + diff --git a/templates/giftcard.html b/templates/giftcard.html new file mode 100644 index 0000000..0be9039 --- /dev/null +++ b/templates/giftcard.html @@ -0,0 +1,58 @@ + + + + Order Food + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+

Enter Gift Card code

+
+
+
+ +
+
+ +
+
+
+

+
+ +
+

+
+
+ + + + \ No newline at end of file diff --git a/templates/giftcard2.html b/templates/giftcard2.html new file mode 100644 index 0000000..5e10b79 --- /dev/null +++ b/templates/giftcard2.html @@ -0,0 +1,49 @@ + + + + + Order Food + + + + + + + + + + + + + + + + + + + + + + + + + + +
+

Your New Total is ${{Total}}

+
+
+

Your gift card has ${{gcRem}} left

+
+
+

+
+ +
+

+
+
+
+


+ + \ No newline at end of file diff --git a/templates/giftcard3.html b/templates/giftcard3.html new file mode 100644 index 0000000..3c2e582 --- /dev/null +++ b/templates/giftcard3.html @@ -0,0 +1,58 @@ + + + + Order Food + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+

Oops looks like thats isn't a valid code please try again

+
+
+
+ +
+
+ +
+
+
+

+
+ +
+

+
+
+ + + + \ No newline at end of file diff --git a/templates/indexV.html b/templates/indexV.html index 4da6fdf..0fd0d44 100644 --- a/templates/indexV.html +++ b/templates/indexV.html @@ -5,6 +5,7 @@ View Orders + @@ -23,10 +24,10 @@ - - + + + -
@@ -42,6 +43,7 @@



+

{%endfor%} diff --git a/templates/kioskOpen.html b/templates/kioskOpen.html new file mode 100644 index 0000000..071bd96 --- /dev/null +++ b/templates/kioskOpen.html @@ -0,0 +1,48 @@ + + + + Order Food + + + + + + + + + + + + + + + + + + + + + + + + + + +
+

Enter your phone number to continue

+
+
+ +
+
Format: 12223334444
+
+
Please put a 1 in front of your phone number
+ +
+
+
+
we will use this phone number for verification
+ + \ No newline at end of file diff --git a/templates/login.html b/templates/login.html index 7abe718..f82bc90 100644 --- a/templates/login.html +++ b/templates/login.html @@ -4,6 +4,8 @@ Login in + + @@ -22,10 +24,10 @@ - - + + + -
diff --git a/templates/login2.html b/templates/login2.html index 0d7d8fa..34d023a 100644 --- a/templates/login2.html +++ b/templates/login2.html @@ -3,6 +3,7 @@ Login in + @@ -21,10 +22,10 @@ - - + + + -
diff --git a/templates/mainOrder.html b/templates/mainOrder.html index 7c81607..25cb1fa 100644 --- a/templates/mainOrder.html +++ b/templates/mainOrder.html @@ -3,6 +3,7 @@ Order Food + @@ -21,15 +22,15 @@ - - + + + - + + +
+
+

Click Item to change if item is in stock or out of stock

+
+

+
+ +{%for i in range(0, len)%} + +
    +

    +
    +
  • +
    +
    +

    +{%endfor%} +
+ + + \ No newline at end of file diff --git a/templates/panel.html b/templates/panel.html index 3ea5380..25a84ec 100644 --- a/templates/panel.html +++ b/templates/panel.html @@ -3,83 +3,118 @@ {{restName}} Control Panel - - - - - - - - - - - - - + + + + + + + + + + + + + + - + - - + + + - -

{{restName}} Control Panel

+

Control Panel for {{locName}}

+
+
+
+ +
+ +

-
- + + +
+

+
+
+
+


-
- + +



-
- +

+ +



-
- +

+ +

+
+
+

+
+ +
+



+

+
+ +
+

+

-

View Menus

-{%for i in range(0, len)%}

-
- -
-

-{%endfor%} +

+
+ +
+

+
+
+
+ +
+

-
- + +


+

-
- + +
-

- - +

+
+
+
- \ No newline at end of file + diff --git a/templates/payGcard.html b/templates/payGcard.html new file mode 100644 index 0000000..5aa0935 --- /dev/null +++ b/templates/payGcard.html @@ -0,0 +1,204 @@ + + + + + Checkout + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+

+
+ + +
+

Checkout

+
+ +
+ +
+ + + +
+

+ + +
+


+
+ + +

+
+
powered by Stripe©
+ \ No newline at end of file diff --git a/templates/paymentDeclined.html b/templates/paymentDeclined.html new file mode 100644 index 0000000..f3a5d38 --- /dev/null +++ b/templates/paymentDeclined.html @@ -0,0 +1,35 @@ + + + + Order Food + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+

Your Card has been Declined please see the staff or try re-entering your details

+ + \ No newline at end of file diff --git a/templates/paymentFinal.html b/templates/paymentFinal.html new file mode 100644 index 0000000..909d8d7 --- /dev/null +++ b/templates/paymentFinal.html @@ -0,0 +1,290 @@ + + + + + Order Food + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+

+
+
+ +
+
+

+ + +
+
Powered By Square ©
+ diff --git a/templates/paymentKiosk.html b/templates/paymentKiosk.html new file mode 100644 index 0000000..cfbf21a --- /dev/null +++ b/templates/paymentKiosk.html @@ -0,0 +1,72 @@ + + + + + Order Food + + + + + + + + + + + + + + + + + + + + + + + + + + +

Total

+
+
+

{{CPN}}

+
+

{{deliv}}

+
+

SubTotal::{{subTotal}}

+
+

Tax::{{tax}}

+
+

Process Fee::$0.50

+
+

Total::{{total}}

+
+
+
+

+
+ +
+

+
+
+

+
+ Email for receipt (optional)
+ +
+

How do you want to pay?

+
+ +

+ +
+

+
+
+


+ + diff --git a/templates/paymentMethod.html b/templates/paymentMethod.html index 1e87dbd..058d10b 100644 --- a/templates/paymentMethod.html +++ b/templates/paymentMethod.html @@ -3,6 +3,7 @@ Order Food + @@ -21,10 +22,10 @@ - - + + + - @@ -33,32 +34,40 @@

Total


{{CPN}}


+

{{deliv}}

+

SubTotal::{{subTotal}}


Tax::{{tax}}


-

Process Fee::$0.15

+

Process Fee::$0.50


Total::{{total}}



-

Would you like to pay now and skip the line?

-

-
- - + +

+

-
-

+

- -
+ Email for receipt (optional)
+ +
+

How do you want to pay?


+ +

+ +

-

+ +
+
+


- \ No newline at end of file + diff --git a/templates/paymentMethodKiosk.html b/templates/paymentMethodKiosk.html new file mode 100644 index 0000000..dd0322e --- /dev/null +++ b/templates/paymentMethodKiosk.html @@ -0,0 +1,72 @@ + + + + + Order Food + + + + + + + + + + + + + + + + + + + + + + + + + + +

Total

+
+
+

{{CPN}}

+
+

SubTotal::{{subTotal}}

+
+

Tax::{{tax}}

+
+

Process Fee::$0.50

+
+

Total::{{total}}

+
+
+
+

+
+ +
+

+
+
+

+
+ Email for receipt (optional)
+ +

+

How do you want to pay

+
+ +

+ +
+
+
+

+
+
+


+ + diff --git a/templates/paymentScreen.html b/templates/paymentScreen.html new file mode 100644 index 0000000..dd205fe --- /dev/null +++ b/templates/paymentScreen.html @@ -0,0 +1,49 @@ + + + + Add Items + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+

+
+ +
+

+
+
+ +
+ + \ No newline at end of file diff --git a/templates/pickAddr.html b/templates/pickAddr.html new file mode 100644 index 0000000..b03c29b --- /dev/null +++ b/templates/pickAddr.html @@ -0,0 +1,48 @@ + + + + Add Items + + + + + + + + + + + + + + + + + + + + + + + + + + +

Deliver To

+
+
+
+{%for i in range(0, len)%} +

+ +
+
+
+

+{%endfor%} +
+

+ +

+
+ diff --git a/templates/pickLocation.html b/templates/pickLocation.html new file mode 100644 index 0000000..02960dd --- /dev/null +++ b/templates/pickLocation.html @@ -0,0 +1,44 @@ + + + + + Admin Login + + + + + + + + + + + + + + + + + + + + + + + + + + +

Pick Location

+
+{%for i in range(0, len)%} +

+
+ +
+
+
+

+{%endfor%} + + diff --git a/templates/pickToppings.html b/templates/pickToppings.html index d6891e8..743f8d5 100644 --- a/templates/pickToppings.html +++ b/templates/pickToppings.html @@ -22,9 +22,9 @@ - + + - @@ -36,6 +36,8 @@

{%for i in range(0, len)%} {{names[i]}}
+

{{warns[i]}}
+

{%endfor%}
@@ -48,5 +50,9 @@

+
+
+
+
\ No newline at end of file diff --git a/templates/mainOrderBtn.html b/templates/pickcat.html similarity index 83% rename from templates/mainOrderBtn.html rename to templates/pickcat.html index a419acd..24337d4 100644 --- a/templates/mainOrderBtn.html +++ b/templates/pickcat.html @@ -3,6 +3,7 @@ Order Food + @@ -18,16 +19,15 @@ + - - + + - -
-
+
+

Tap Item to Add

-
+

-
    +

      {%for i in range(0, len)%}
      -

    • {{descrips[i]}}
    • -
      +

    • {{descrips[i]}}
      {{warns[i]}}
    • +
      {%endfor%}

    +
    +
    + +
    -
-
- - -
-
-

Items Selected

-
-

Tap an item to remove

-
- {%for j in range(0, len2)%} -

-
- -
-
-

- {%endfor%} -
-

Total {{total}}

-
-
- -
- -
-
- + - \ No newline at end of file + diff --git a/templates/picksize.html b/templates/picksize.html index 70ab9d5..12f295b 100644 --- a/templates/picksize.html +++ b/templates/picksize.html @@ -3,6 +3,7 @@ Order Food + @@ -22,9 +23,9 @@ - + + - diff --git a/templates/remItems.html b/templates/remItems.html index 8585330..a1fba54 100644 --- a/templates/remItems.html +++ b/templates/remItems.html @@ -3,6 +3,7 @@ Remove Items + @@ -21,26 +22,66 @@ - - + + + +
-

Edit {{restName}} Menu

+

Remove Items


-

Remove Items

+

Click Item to Remove


+

+
{%for i in range(0, len)%} -

+ +
    +

    - {{names[i]}} - +
  • -

    +
    +

{%endfor%} - + + \ No newline at end of file diff --git a/templates/robotDeploy.html b/templates/robotDeploy.html new file mode 100644 index 0000000..8d76364 --- /dev/null +++ b/templates/robotDeploy.html @@ -0,0 +1,58 @@ + + + + Deploy Robots + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+

Deploy Robot

+
+
+

+
+

Enter Robot Number

+ +

Enter Table Number

+ +
+
+ +
+

+ + \ No newline at end of file diff --git a/templates/sendPromo.html b/templates/sendPromo.html index 0fe30e3..445d079 100644 --- a/templates/sendPromo.html +++ b/templates/sendPromo.html @@ -1,15 +1,40 @@ - - Add Items + Add Coupon + + + + + + + + + + + + + + + + + + + + + + + + -

Add Item

+

Create Promotion

+

You have {{lim}} promotions left this billing cycle

-

Enter PromoText

- - +

Enter Text for Promotion

+ +

+
\ No newline at end of file diff --git a/templates/thankMsg.html b/templates/thankMsg.html index 9d64ace..fae9ec8 100644 --- a/templates/thankMsg.html +++ b/templates/thankMsg.html @@ -1,8 +1,9 @@ - Add Items + Order Food + @@ -21,13 +22,12 @@ - - + + + - -
-

Thank You for your Order!

+

Thank You for your Order!


We'll text you when your order is ready

\ No newline at end of file diff --git a/templates/thankMsg2.html b/templates/thankMsg2.html new file mode 100644 index 0000000..576bf26 --- /dev/null +++ b/templates/thankMsg2.html @@ -0,0 +1,35 @@ + + + + Order Food + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+

Thank You for your Order!


We'll text you when your order is ready

+ + \ No newline at end of file diff --git a/templates/verifyCode.html b/templates/verifyCode.html index 4101828..1c80908 100644 --- a/templates/verifyCode.html +++ b/templates/verifyCode.html @@ -3,6 +3,7 @@ Order Food + @@ -21,8 +22,9 @@ - - + + + @@ -31,7 +33,7 @@

Enter the last 4 digits of your phone number


- +

diff --git a/templates/verifyCode2.html b/templates/verifyCode2.html index 1216c47..93e8fea 100644 --- a/templates/verifyCode2.html +++ b/templates/verifyCode2.html @@ -3,6 +3,7 @@ Order Food + @@ -21,17 +22,18 @@ - - + + +
-

Please try again, enter the last 4 digits of your phone number or text order

+

Please try again, enter the last 4 digits of your phone number or text order to {{number}}


- +

diff --git a/templates/verifyCode3.html b/templates/verifyCode3.html new file mode 100644 index 0000000..18e345c --- /dev/null +++ b/templates/verifyCode3.html @@ -0,0 +1,43 @@ + + + + Order Food + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+

oops look like something went wrong please re-enter the last 4 digits of your phone number to continue ordering

+
+
+ + +
+
+ +
+ + \ No newline at end of file diff --git a/testFIles/info.json b/testFIles/info.json new file mode 100644 index 0000000..6e9c3d6 --- /dev/null +++ b/testFIles/info.json @@ -0,0 +1,7 @@ +{ + "uid":"vjsoqWdhbEYIKH4q00Zrp20UFHH3", + "name": "TestRaunt", + "shortUID": "572478", + "number": "14255992978", + "timezone": "America/Los_Angeles" +} \ No newline at end of file diff --git a/testFIles/testPPAL.html b/testFIles/testPPAL.html new file mode 100644 index 0000000..dbdd71f --- /dev/null +++ b/testFIles/testPPAL.html @@ -0,0 +1,42 @@ + + + + + + + + + +
+ + + + + + diff --git a/testFIles/testemail.py b/testFIles/testemail.py new file mode 100644 index 0000000..b59f1f1 --- /dev/null +++ b/testFIles/testemail.py @@ -0,0 +1,15 @@ +import smtplib +sender = 'receipts@cedarrobots.com' +emailPass = "Cedar2421!" +FROM = sender + + +smtpObj = smtplib.SMTP_SSL("smtp.zoho.com",465) +smtpObj.login(sender,emailPass) +SUBJECT = "Test email" +TEXT = "Hello" +message = 'Subject: {}\n\n{}'.format(SUBJECT, TEXT) +receivers = 'cajohn0205@gmail.com' +smtpObj.sendmail(sender, receivers, message) +smtpObj.close() +print("Successfully sent email") diff --git a/testFIles/testpostmates.py b/testFIles/testpostmates.py new file mode 100644 index 0000000..0f92849 --- /dev/null +++ b/testFIles/testpostmates.py @@ -0,0 +1,65 @@ +import requests +import datetime + +now = datetime.datetime.utcnow() # <-- get time in UTC +d = now + datetime.timedelta(minutes = 10) +dt = d.isoformat("T") + "Z" +print(now) +print(dt) +url = "https://api.postmates.com/v1/customers/cus_MMAQ2VmJNZAVOV/delivery_quotes" +addrP = "2421112, Sahalee Dr W, Sammamish, WA, 98074" +addrD = "1645, 140th Ave NE, Bellevue, WA, 98005" +payload = {"dropoff_address":addrP, + "pickup_address":addrD} +headers = { + 'Content-Type': "application/x-www-form-urlencoded", + 'Authorization': "Basic ODcwZWFiYWUtN2JiMS00MzZjLWFmNGEtMzNmYTJmZTc2ODhlOg==", + 'User-Agent': "PostmanRuntime/7.16.3", + 'Accept': "*/*", + 'Cache-Control': "no-cache", + 'Postman-Token': "55cc61b2-a3aa-42f1-81a9-62467b9199b1,a5cb9e3d-7d0c-4834-9cde-6220fb9962a7", + 'Host': "api.postmates.com", + 'Accept-Encoding': "gzip, deflate", + 'Content-Length': "145", + 'Cookie': "__cfduid=d3e5bcc883cf1529ae363dbc64fe257f61567815844", + 'Connection': "keep-alive", + 'cache-control': "no-cache" + } + + +response = requests.request("POST", url, data=payload, headers=headers) +rsp = (response.json()) +print(rsp) +print(rsp) +url = "https://api.postmates.com/v1/customers/cus_MMAQ2VmJNZAVOV/deliveries" +payload = { +"dropoff_address":addrP, +"pickup_address":addrD, +"quote_id":str(rsp["id"]), +"manifest":"Cedar Order", +"dropoff_phone_number":"17203269719", +"pickup_phone_number":"14257890099", + "dropoff_name":"Caleb John", +'pickup_name':"TestRaunt", + "dropoff_ready_dt":dt +} +headers = { + 'Content-Type': "application/x-www-form-urlencoded", + 'Authorization': "Basic ODcwZWFiYWUtN2JiMS00MzZjLWFmNGEtMzNmYTJmZTc2ODhlOg==", + 'User-Agent': "PostmanRuntime/7.16.3", + 'Accept': "*/*", + 'Cache-Control': "no-cache", + 'Postman-Token': "a8e2692f-f65e-4cfb-8658-25324016b7ca,b7421a2d-8b36-4c6e-acd2-ceb641458a58", + 'Host': "api.postmates.com", + 'Accept-Encoding': "gzip, deflate", + 'Content-Length': "517", + 'Cookie': "__cfduid=d3e5bcc883cf1529ae363dbc64fe257f61567815844", + 'Connection': "keep-alive", + 'cache-control': "no-cache", + } + +response = requests.request("POST", url, data=payload, headers=headers) + +rsp = (response.json()) +print(rsp["tracking_url"]) +print(rsp) diff --git a/testFIles/testsquare.py b/testFIles/testsquare.py new file mode 100644 index 0000000..1ad6417 --- /dev/null +++ b/testFIles/testsquare.py @@ -0,0 +1,93 @@ +from square.client import Client + +# Create an instance of the API Client +# and initialize it with the credentials +# for the Square account whose assets you want to manage + +client = Client( + access_token='EAAAEHzQywVWiysH2dLJ_MBAvkTDvkN3f5iWojFnQgnLUT-KZb-mhx6BMezxz_dA', + environment='production', +) +api_locations = client.locations +mobile_authorization_api = client.mobile_authorization +# Call list_locations method to get all locations in this Square account +result = api_locations.list_locations() +# Call the success method to see if the call succeeded +if result.is_success(): + # The body property is a list of locations + locations = result.body['locations'] + # Iterate over the list + for location in locations: + if((dict(location.items())["status"]) == "ACTIVE"): + print(dict(location.items())) + locationName = (dict(location.items())["name"]).replace(" ","-") + print(locationName) + locationId = dict(location.items())["id"] + print(dict(location.items())["business_email"]) + print(dict(location.items())) + print(locationId) + addrNumber = "" + street = "" + for ltrAddr in range(len(dict(location.items())["address"]['address_line_1'])): + currentLtr = dict(location.items())["address"]['address_line_1'][ltrAddr] + try: + int(currentLtr) + addrNumber += currentLtr + except Exception as e: + street = dict(location.items())["address"]['address_line_1'][ltrAddr+1:len(dict(location.items())["address"]['address_line_1'])] + break + + addrP = str(addrNumber+ ","+ street+","+dict(location.items())["address"]['locality'] + "," + dict(location.items())["address"]['administrative_district_level_1'] + "," + dict(location.items())["address"]['postal_code'][:5]) + timez = dict(location.items())["timezone"] + + + + + body = {} + body['location_id'] = locationId + + result = mobile_authorization_api.create_mobile_authorization_code(body) + + if result.is_success(): + print(result.body) + elif result.is_error(): + print(result.errors) + + + checkout_api = client.checkout + location_id = 'B266MPEW4JSYZ' + body = {} + body['idempotency_key'] = '86ae1696-b1e3-4328-ade2sijiyg734f6dhdnq-fqffygyqefqe' + body['order'] = {} + body['order']['reference_id'] = 'reference_id' + body['order']['line_items'] = [] + + body['order']['line_items'].append({}) + body['order']['line_items'][0]['name'] = 'Your Order From ' + body['order']['line_items'][0]['quantity'] = '1' + body['order']['line_items'][0]['base_price_money'] = {} + body['order']['line_items'][0]['base_price_money']['amount'] = 110 + body['order']['line_items'][0]['base_price_money']['currency'] = "USD" + + body['order']['line_items'].append({}) + body['order']['line_items'][1]['name'] = 'Service Fees' + body['order']['line_items'][1]['quantity'] = '1' + body['order']['line_items'][1]['base_price_money'] = {} + body['order']['line_items'][1]['base_price_money']['amount'] = 50 + body['order']['line_items'][1]['base_price_money']['currency'] = "USD" + + body['order']['taxes'] = [] + body['order']['taxes'].append({}) + body['order']['taxes'][0]['name'] = 'Sales Tax' + body['order']['taxes'][0]['percentage'] = '10' + + body['ask_for_shipping_address'] = False + body['redirect_url'] = 'https://cdrorder.serveo.net/ipn' + + result = checkout_api.create_checkout(location_id, body) + + if result.is_success(): + print(result.body["checkout"]["checkout_page_url"]) + print(result.body["checkout"]) + elif result.is_error(): + print(result.errors) diff --git a/testFIles/tickets.txt b/testFIles/tickets.txt index e69de29..04400f0 100644 --- a/testFIles/tickets.txt +++ b/testFIles/tickets.txt @@ -0,0 +1 @@ +https://www.youtube.com/watch?v=BEGJ63WUF0Y \ No newline at end of file diff --git a/testFIles/tsms.py b/testFIles/tsms.py new file mode 100644 index 0000000..e2e9174 --- /dev/null +++ b/testFIles/tsms.py @@ -0,0 +1,39 @@ +import time +from flask import Flask, request, Response +import plivo +from plivo import plivoxml +botNumber = "14255992978" +client = plivo.RestClient(auth_id='MAYTVHN2E1ZDY4ZDA2YZ', auth_token='ODgzZDA1OTFiMjE2ZTRjY2U4ZTVhYzNiODNjNDll') +app = Flask(__name__) + +def getResp(msg): + retStr = "this is a test" + " " + msg + return retStr + +@app.route('/sms',methods=['GET','POST']) +def inbound_sms(): + # Sender's phone number + from_number = request.values.get('From') + # Receiver's phone number - Plivo number + to_number = request.values.get('To') + # The text which was received + text = request.values.get('Text') + print('Message received - From: %s, To: %s, Text: %s' % (from_number, to_number, text)) + print(type(text)) + resp = "Hi Caleb! welcome to TestRaunt is this order or to go?" + response = plivoxml.ResponseElement() + response.add( + plivoxml.MessageElement( + resp, # body/The text which was received + src=to_number, # Sender's phone number + dst=from_number, # Receiver's phone Number + type='sms', + callback_url='https://61296054.ngrok.io/sms status/', + callback_method='POST')) + print(response.to_string()) # Prints the XML + return Response(response.to_string(), mimetype='application/xml') + + + +if __name__ == "__main__": + app.run(host='0.0.0.0', port=8080) \ No newline at end of file