from flask import Flask
import sys
import sqlite3,csv
import os
from tabulate import tabulate

class DB:
    """Class for creating an SQLite database in the same dir of this app file.
    Loads data from tasks_data.csv in the given path to tasks table.
    Retrieves data from tasks table
    """
    def __init__(self):
        self.sdb = None
        self.cur = None

    def connect(self):
        """Connect to tasks db """
        try:
            curpath = os.path.abspath(sys.modules[DB.__module__].__file__)
            os.chdir(os.path.dirname(curpath))
            self.sdb = sqlite3.connect("tasks.db")
            self.cur = self.sdb.cursor()
            print("connected")
        except Exception as e:
            print(e)

    def disconnect(self):
        """Commit Changes to tasks db and close connection"""
        try:
            self.sdb.commit()
            self.cur.close()
            self.sdb.close()
        except Exception as e:
            print(e)

    def load_data(self,filepath):
        """Load Data in the given csv file to tasks table.
        SQLite is used, so that database setup is simple,.
        Disadvantage of SQLite
            More than 15 precision is not supported, so stored as text.
            Milliseconds in timestamp  not supported, so stored as text.
        """
        try:
            self.connect()
            print("Create Table")
            self.cur.execute(f"drop table if exists tasks")
            self.cur.execute(f"create table tasks(id INT,timestamp text,temperature text,duration text)")
            print("Load data from csv to table - Iterative manner")
            with open(f'{filepath}','r') as fl:
                dict_file = csv.DictReader(fl)
                lt_rows = [(row['id'], row['timestamp'], row['temperature'], row['duration']) for row in dict_file]

            self.cur.executemany("insert into tasks VALUES (?, ?, ? , ?);", lt_rows)
            print("Create log table")
            self.cur.execute(f"drop table if exists requests")
            self.cur.execute("create table requests(id INTEGER primary key, req_time DATETIME DEFAULT CURRENT_TIMESTAMP,req varchar(10))")
            self.cur.execute("select count(*) from tasks")
            rowscount = self.cur.fetchone()[0]
            print(f"Load finished. Records count:{rowscount}")
            self.disconnect()
            return rowscount
        except Exception as e:
            print(e)

    def get_taskdata(self):
        """Return task data in html format.
        Add request record to requests table
        """
        try:
            print("get")
            self.connect()
            self.cur.execute("select * from tasks")
            data = self.cur.fetchall()
            data.insert(0,('id','timestamp','temperature','duration'))
            data = tabulate(data, tablefmt='html')

            style = ""

            self.cur.execute("insert into requests(req) values ('All')")
            requests = self.cur.execute("select count(*) from requests").fetchone()[0]
            request_number = f"Request Number : {requests}"

            data = style + "
" + request_number + "
" + data
            self.disconnect()
            return data
        except Exception as e:
            print(e)
            return(f"Error occurred: {str(e)}
Please check if load_data is run.")

#Flask app starts
#Not using ajax/jquery/html/js templates to avoid complexity
app = Flask(__name__)

@app.route('/')
def main():
    return """View Data"""

@app.route('/get_taskdata', methods=['GET'])
def get_taskdata():
    """Return data from tasks in html format
    """
    db = DB()
    data = db.get_taskdata()
    html ='Tasks Data'
    html += data
    return(html)

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=5000)


# -*- coding: utf-8 -*-
from __future__ import absolute_import
import unittest
import pytest
lupa = pytest.importorskip("lupa")

from splash.lua import lua2python, python2lua

@pytest.mark.usefixtures("lua")
class LuaPythonConversionTest(unittest.TestCase):

    def assertSurvivesConversion(self, obj):
        lua_obj = python2lua(self.lua, obj)
        py_obj = lua2python(self.lua, lua_obj)
        self.assertEqual(obj, py_obj)

    def test_numbers(self):
        self.assertSurvivesConversion(5)
        self.assertSurvivesConversion(0)
        self.assertSurvivesConversion(-3.14)

    def test_strings(self):
        self.assertSurvivesConversion("foo")
        self.assertSurvivesConversion("")

    @pytest.mark.xfail
    def test_unicode(self):
        # Does it fail because python2lua and lua2python assume
        # LuaRuntime is in play?
        self.assertSurvivesConversion(u"привет")

    def test_dict(self):
        self.assertSurvivesConversion({'x': 2, 'y': 3})

    def test_dict_empty(self):
        self.assertSurvivesConversion({})

    def test_dict_int_keys(self):
        self.assertSurvivesConversion({1: 'foo', 2: 'bar'})

    def test_dict_pyobject_key(self):
        key = object()
        self.assertSurvivesConversion({key: 'foo', 2: 'bar'})

    def test_dict_pyobject_value(self):
        value = object()
        self.assertSurvivesConversion({'foo': value, 'bar': 'bar'})

    def test_dict_recursive(self):
        dct = {}
        dct["x"] = dct
        with pytest.raises(ValueError):
            python2lua(self.lua, dct)

    def test_lua_table_in_python_container(self):
        dct = {
            "foo": "foo",
            "bar": self.lua.table_from({"egg": "spam"}),
            "baz": [self.lua.table_from({"foo": "bar"})],
        }
        value = lua2python(self.lua, dct)
        self.assertEqual(value, {
            "foo": "foo",
            "bar": {"egg": "spam"},
            "baz": [{"foo": "bar"}],
        })

    def test_object(self):
        self.assertSurvivesConversion(object())

    def test_none(self):
        self.assertSurvivesConversion(None)

    @pytest.mark.xfail
    def test_none_values(self):
        self.assertSurvivesConversion({"foo": None})

    def test_list(self):
        self.assertSurvivesConversion(["foo", "bar"])

    def test_list_empty(self):
        self.assertSurvivesConversion([])

    def test_list_recursive(self):
        lst = []
        lst.append(lst)
        with pytest.raises(ValueError):
            python2lua(self.lua, lst)

    def test_list_nested(self):
        self.assertSurvivesConversion(["foo", "bar", [1, 2, "3", 10], [], [{}]])

    @pytest.mark.xfail
    def test_list_endswith_none(self):
        # FIXME
        self.assertSurvivesConversion([1, None])
        self.assertSurvivesConversion([None])

    def test_list_with_none(self):
        self.assertSurvivesConversion(["foo", None, 2])
        self.assertSurvivesConversion(["foo", None, None, 2])
        self.assertSurvivesConversion([None, "foo", None, 2])
        self.assertSurvivesConversion([None, None, None, 2])

    def test_sparse_list(self):
        func1 = self.lua.eval("""
        function (arr)
            arr[5] = "foo"
            return arr
        end
        """)
        func2 = self.lua.eval("""
        function (arr)
            arr[100000] = "foo"
            return arr
        end
        """)
        arr = python2lua(self.lua, [1, 2])
        arr1 = lua2python(self.lua, func1(arr))
        self.assertEqual(arr1, [1, 2, None, None, "foo"])

        with pytest.raises(ValueError):
            arr2 = lua2python(self.lua, func2(arr))

    def test_list_like_tables(self):
        # List-like tables are still returned as dicts;
        # only tables which were lists originally are lists.
        tbl = self.lua.eval("{5, 6}")
        self.assertEqual(
            lua2python(self.lua, tbl),
            {1: 5, 2: 6}
        )

    def test_list_modified_incorrect(self):
        func = self.lua.eval("""
        function (arr)
           arr["foo"] = "bar"
           return arr
        end
        """)
        arr = python2lua(self.lua, [3, 4])
        arr2 = func(arr)
        with pytest.raises(ValueError):
            lua2python(self.lua, arr2)

    def test_list_modified_correct(self):
        func = self.lua.eval("""
        function (arr)
           table.insert(arr, "bar")
           return arr
        end
        """)
        arr = python2lua(self.lua, [3, 4])
        arr2 = func(arr)
        self.assertEqual(lua2python(self.lua, arr2), [3, 4, "bar"])