from flask_login import session
from accept import Accept
from jinja2 import Template
from os import listdir, walk, chdir, getcwd
from os.path import isfile, join, exists
from flask import Response
from Utils import Namespace, SparqlEndpoint
import sys
from jinja2 import FileSystemLoader
from jinja2.environment import Environment
from rdflib import ConjunctiveGraph, URIRef
env = Environment()
env.loader = FileSystemLoader('.')


class JsonBasedWriter:
	settings = {}
	sparql = None
	flod = None
	basedir = "components/jsonupdates/"
	g = None

	def __init__(self, settings, app=None):
		"""Initializes class"""

		self.settings = settings
		if "sparqlUpdateEndpoint" not in self.settings or "local" not in self.settings["sparqlUpdateEndpoint"]:
			print "Sparql Update endpoint not defined. Aborting."
			exit(10)
		self.sparql = SparqlEndpoint(self.settings)
		self.flod = self.settings["flod"] if "flod" in self.settings else None
		self.graph = ConjunctiveGraph('SPARQLUpdateStore')
		self.graph.open((self.settings["endpoints"]["local"], self.settings["sparqlUpdateEndpoint"]["local"]))

	def _update(self, q):
		graphuri = URIRef('urn:any')
		try:
			g = self.graph.get_context(graphuri)
			g.update(q)
		except:
			print sys.exc_info()
			return False
		return True


	def test(self, r):
		if r["request"].method != 'POST':
			return {"accepted": False}
		file = r["localUri"].replace(self.settings["ns"]["local"], "", 1)
		if exists(self.basedir + file):
			return {"accepted": True, "url": r["localUri"]}
		return {"accepted": False}

	def execute(self, req):
		"""Serves a URI, given that the test method returned True"""
		file = req["url"].replace(self.settings["ns"]["local"], "", 1)
		if req["request"].form is None:
			return {"content": "{\"success\": false}", "status": 500, "mimetype": "application/json"}
		data = req["request"].form
		currentDir = getcwd()
		jsonService = self.basedir + file
		uri = req["url"]
		queryPath = "%s/queries/" % jsonService
		updatePath = "%s/" % jsonService
		try:
			onlyfiles = [f for f in listdir(queryPath) if isfile(join(queryPath, f)) and str(f).endswith(".query")]
		except OSError:
			print "Warning: Can't find path %s for queries." % updatePath
			onlyfiles = []
		queries = {}
		for filename in onlyfiles:
				for root, dirs, files in walk(queryPath):
					for filename in files:
						try:
							currentEndpoint = "local"
							if root.replace(queryPath, "", 1) != "":
								currentEndpoint = root.split("/").pop()
							sparqlQuery = env.get_template("%s/%s" % (root, filename))
							results = self.sparql.query(sparqlQuery.render(uri=uri, session=session, flod=self.flod, data=data))
							queries[filename.replace(".query", "")] = results["results"]["bindings"]
						except Exception, ex:
							print sys.exc_info()
							print sparqlQuery
							print ex
							return {"content": "A problem with SPARQL endpoint occurred", "status": 500}
		chdir(currentDir)
		try:
			updatefiles = [f for f in listdir(updatePath) if isfile(join(updatePath, f)) and str(f).endswith(".update")]
			for updatefile in updatefiles:
				query = env.get_template(join(updatePath, updatefile))
				out = query.render(queries=queries, uri=uri, session=session, flod=self.flod, data=data)
				if not self._update(out):
					raise Exception
		except Exception:
			print sys.exc_info()
			return {"content": "{\"success\": false}", "status": 500, "mimetype": "application/json"}
		return {"content": "{\"success\": true}", "mimetype": "application/json"}


@@ -369,16 +369,32 @@
  URIRef%0A
+import requests%0A
 env = En
@@ -1100,16 +1100,23 @@
 %22local%22%5D
+%5B%22url%22%5D
 ))%0A%0A%09def
@@ -1172,19 +1172,22 @@
 %0A%09%09try:%0A
-%09%09%09
+#self.
 g = self
@@ -1222,19 +1222,511 @@
 %0A%09%09%09
-g.update(q)
+auth = None%0A%09%09%09if %22user%22 in self.settings%5B%22sparqlUpdateEndpoint%22%5D%5B%22local%22%5D and %22pass%22 in self.settings%5B%22sparqlUpdateEndpoint%22%5D%5B%22local%22%5D:%0A%09%09%09        auth = HTTPDigestAuth(self.settings%5B%22sparqlUpdateEndpoint%22%5D%5B%22local%22%5D%5B'user'%5D, self.settings%5B%22sparqlUpdateEndpoint%22%5D%5B%22local%22%5D%5B'pass'%5D)%0A%09%09%09headers = %7B'content-type': 'application/sparql-update'%7D%0A%09%09%09r = requests.post(self.settings%5B%22sparqlUpdateEndpoint%22%5D%5B%22local%22%5D%5B%22url%22%5D, data=q, auth=auth, headers=headers)%0A%09%09%09if r.status_code %3E 299:%0A%09%09%09        return False
 %0A%09%09e
@@ -2216,30 +2216,104 @@
 )%0A%09%09
-if req%5B%22request%22%5D.form
+myForm = req%5B%22request%22%5D.form%0A%09%09myJson = req%5B%22request%22%5D.get_json()%0A%09%09if myForm is None and myJson
  is 
@@ -2417,31 +2417,69 @@
 %7D%0A%09%09
-data = req%5B%22request%22%5D.f
+if myJson is not None:%0A%09%09%09data = myJson%0A%09%09else:%0A%09%09%09data = myF
 orm%0A

Support for JSON objects, besides urlencoded forms