Ejemplo n.º 1
0
def build(req):
  """Builder for this format.

  Args:
    req: flask request

  Returns:
    Json containing the creative data
  """
  if "ignore" in req.files:
    pass

  current_path = os.path.dirname(__file__)

  errors = []
  v = {}
  tdir = "/tmp/" + f.get_tmp_file_name()
  index = f.file_get_contents(current_path + "/index_104-interstitial-tag.html")

  v["htmlTag"] = f.get_param("html_tag")
  v["autoclose"] = str(f.get_int_param("autoclose"))
  v["close_button"] = f.get_param("close_button")
  v["close_button_width"] = f.get_param("close_button_width")
  v["close_button_height"] = f.get_param("close_button_height")
  v["bgcolor"] = f.get_param("bgcolor")
  v["openTimeout"] = str(f.get_int_param("open_timeout")*1000)

  return {"errors": errors, "dir": tdir, "index": index, "vars": v}
Ejemplo n.º 2
0
def build(req):
    """Builder for this format.

  Args:
    req: flask request

  Returns:
    Json containing the creative data
  """
    current_path = os.path.dirname(__file__)

    errors = []
    v = {}
    if "zipfile" not in req.files:
        return {"errors": ["No uploaded file"]}

    zfile = req.files["zipfile"]
    ext = f.get_ext(req.files["zipfile"].filename)

    # unzip to temp dir
    tdir = "/tmp/" + f.get_tmp_file_name()

    if ext == "zip":
        if not f.extract_zip(zfile, tdir):
            return {"errors": ["Incorrect Zip file"]}
        else:
            index = f.file_get_contents(tdir + "/index.html")
            if not index:
                return {"errors": ["No index.html in Zip file"]}

        if index.find("<head>") < 0:
            errors.append("No <head> tag")
        if index.find("</body>") < 0:
            errors.append("No </body> tag")

        index = replace_html(index)

    else:
        index = f.file_get_contents(current_path +
                                    "/index_103-interstitial.html")
        f.save_file(req.files["zipfile"], tdir + "/image." + ext)
        v["image_ext"] = ext

    v["autoclose"] = str(f.get_int_param("autoclose"))
    v["close_button"] = f.get_param("close_button")
    v["close_button_width"] = f.get_param("close_button_width")
    v["close_button_height"] = f.get_param("close_button_height")
    v["bgcolor"] = f.get_param("bgcolor")
    v["openTimeout"] = str(f.get_int_param("open_timeout") * 1000)

    return {"errors": errors, "dir": tdir, "index": index, "vars": v}
Ejemplo n.º 3
0
def build(req):
  """Builder for this format.

  Args:
    req: flask request

  Returns:
    Json containing the creative data
  """
  errors = []
  v = {}
  tdir = "/tmp/" + f.get_tmp_file_name()

  if f.get_param("source") == "tag":
    # tag
    v["tag"] = f.get_param("tag")
    index = get_index_tag()
  else:
    # zip
    if "zipfile" not in req.files:
      return {"errors": ["No uploaded file"]}

    zfile = req.files["zipfile"]
    ext = f.get_ext(zfile.filename)
    if ext == "zip":
      if not f.extract_zip(zfile, tdir):
        return {"errors": ["Can't decompress zip file"]}

      index = f.file_get_contents(tdir + "/index.html")
      if not index:
        return {"errors": ["No index.html in Zip file"]}

      if index.find("<head>") < 0:
        return {"errors": ["No <head> tag in index.html"]}
      if index.find("</body>") < 0:
        return {"errors": ["No </body> tag in index.html"]}
    else:
      # image
      f.save_file(req.files["zipfile"], tdir + "/image." + ext)
      v["image_ext"] = ext
      index = get_index_image()

  v["autoclose"] = str(f.get_int_param("autoclose"))
  v["bgcolor"] = f.get_param("bgcolor")
  v["width"] = f.get_param("width")
  v["height"] = f.get_param("collapsed_height")

  index = replace_html(index)

  return {"errors": errors, "dir": tdir, "index": index, "vars": v}
Ejemplo n.º 4
0
def build(req):
    """Builder for this format.

  Args:
    req: flask request

  Returns:
    Json containing the creative data
  """

    errors = []
    v = {}
    tdir = "/tmp/" + f.get_tmp_file_name()
    index = get_html()

    ext = f.get_ext(req.files["videofile"].filename)
    if ext != "mp4":
        return {"errors": ["Only mp4 files allowed"]}

    f.save_file(req.files["videofile"], tdir + "/video.mp4")

    v["backgroundColor"] = f.get_param("background_color")
    v["autoclose"] = str(f.get_int_param("autoclose"))

    return {"errors": errors, "dir": tdir, "index": index, "vars": v}
Ejemplo n.º 5
0
def build(req):
    """Builder for this format.

  Args:
    req: flask request

  Returns:
    Json containing the creative data
  """
    if "ignore" in req.files:
        pass

    errors = []
    v = {}

    current_path = os.path.dirname(__file__)
    index = f.file_get_contents(current_path + "/index_102-push-tag.html")

    tdir = "/tmp/" + f.get_tmp_file_name()

    v["htmlTag"] = f.get_param("html_tag")

    v["width"] = f.get_param("width")
    v["initExpanded"] = "true" if f.get_param(
        "initial_state") == "E" else "false"
    if f.get_param("initial_state") == "E":
        v["autocloseSeconds"] = f.get_param("autoclose_seconds")
    else:
        v["autocloseSeconds"] = "0"
    v["collapsedHeight"] = f.get_param("collapsed_height")
    v["expandedHeight"] = f.get_param("expanded_height")
    v["transitionTimeMs"] = str(f.get_int_param("animated_transition") * 250)

    return {"errors": errors, "dir": tdir, "index": index, "vars": v}
Ejemplo n.º 6
0
def build(req):
    """Builder for this format.

  Args:
    req: flask request

  Returns:
    Json containing the creative data
  """
    if "ignore" in req.files:
        pass

    errors = []
    v = {}

    # unzip to temp dir
    tdir = "/tmp/" + f.get_tmp_file_name()

    # get index content
    index = """<!DOCTYPE HTML><html lang="en-us">
<head>
  <meta name="ad.size" content="width=[[width]],height=[[height]]">
</head>
<body style='margin:0'>
  [[html_tag]]
  [[clicktag_layer]]
<script>
  var clickTag = "[[clicktag_url]]";
</script>
<script data-exports-type="dclk-quick-preview">if(typeof studio !== 'undefined' && studio.Enabler) { studio.Enabler.setRushSimulatedLocalEvents(true); }</script>
</body>
</html>
   """

    v["html_tag"] = f.get_param("html_tag")

    return {"errors": errors, "dir": tdir, "index": index, "vars": v}
Ejemplo n.º 7
0
def build(req):
  """Builder for this format.

  Args:
    req: flask request

  Returns:
    Json containing the creative data
  """

  errors = []
  v = {}
  data = {"collapsed": {}, "expanded": {}}
  tdir = "/tmp/" + f.get_tmp_file_name()

  index = get_html()

  if "collapsed_zip" not in req.files:
    return {"errors": ["No collapsed file"]}
  if "expanded_zip" not in req.files:
    return {"errors": ["No expanded file"]}

  ## collapsed
  data["collapsed"]["ext"] = f.get_ext(req.files["collapsed_zip"].filename)
  if data["collapsed"]["ext"] == "zip":
    os.mkdir(tdir)
    if not f.extract_zip(req.files["collapsed_zip"], tdir + "/collapsed"):
      return {"errors": ["Wrong collapsed zip file"]}

    file_name = "index2.html"
    try:
      os.rename(tdir + "/collapsed/index.html", tdir+ "/collapsed/" + file_name)
    except os.FileNotFoundError:
      return {"errors": ["No index.html in collapsed zip"]}
  elif not data["collapsed"]["ext"]:
    return {"errors": ["No collapsed file"]}
  else:
    f.save_file(req.files["collapsed_zip"], tdir + "/collapsed."
                + data["collapsed"]["ext"])

  ## expanded
  data["expanded"]["ext"] = f.get_ext(req.files["expanded_zip"].filename)
  if data["expanded"]["ext"] == "zip":
    if not f.extract_zip(req.files["expanded_zip"], tdir + "/expanded"):
      return {"errors": ["Wrong expanded zip file"]}

    file_name = "index2.html"
    try:
      os.rename(tdir + "/expanded/index.html", tdir+ "/expanded/" + file_name)
    except os.FileNotFoundError:
      return {"errors": ["No index.html in expanded zip"]}
  elif not data["expanded"]["ext"]:
    return {"errors": ["No expanded file"]}
  else:
    f.save_file(req.files["expanded_zip"], tdir + "/expanded." + data["expanded"]["ext"])

  v["width"] = f.strtoken(f.get_param("collapsed_size"), 1, "x")
  v["expandedHeight"] = f.strtoken(f.get_param("expanded_size"), 2, "x")
  v["height"] = v["expandedHeight"]
  v["collapsedHeight"] = f.strtoken(f.get_param("collapsed_size"), 2, "x")
  v["animatedTransition"] = str(f.get_int_param("animatedTransition") * 250)

  if data["collapsed"]["ext"] == "zip":
    v["collapsedContent"] = "<iframe src='collapsed/index2.html' frameborder=0 style='width:"+v["width"]+"px;height:+"+v["collapsedHeight"]+"px' scrolling='no'></iframe>"
  else:
    v["collapsedContent"] = "<img src='collapsed."+data["collapsed"]["ext"]+"' style='border:0;width:"+v["width"]+"px;height:"+v["collapsedHeight"]+"px' />"

  if data["expanded"]["ext"] == "zip":
    v["expandedContent"] = "<iframe src='expanded/index2.html' frameborder=0 style='width:"+v["width"]+"px;height:"+v["expandedHeight"]+"px' scrolling='no'></iframe>"
  else:
    v["expandedContent"] = "<img src='expanded."+data["expanded"]["ext"]+"' style='border:0;width:"+v["width"]+"px;height:"+v["expandedHeight"]+"px' />"

  return {"errors": errors, "dir": tdir, "index": index, "vars": v}
def build(req):
  """Builder for this format.

  Args:
    req: flask request

  Returns:
    Json containing the creative data
  """

  errors = []
  v = {}
  data = {"tab": {}, "expanded": {}}
  tdir = "/tmp/" + f.get_tmp_file_name()

  index = get_html()

  if "tab_zip" not in req.files:
    return {"errors": ["No tab file"]}
  if "expanded_zip" not in req.files:
    return {"errors": ["No expanded file"]}

  ## tab
  data["tab"]["ext"] = f.get_ext(req.files["tab_zip"].filename)
  if data["tab"]["ext"] == "zip":
    os.mkdir(tdir)
    if not f.extract_zip(req.files["tab_zip"], tdir + "/tab"):
      return {"errors": ["Wrong tab zip file"]}

    file_name = "index2.html"
    try:
      os.rename(tdir + "/tab/index.html", tdir + "/tab/" + file_name)
    except os.FileNotFoundError:
      return {"errors": ["No index.html in tab zip"]}
  elif not data["tab"]["ext"]:
    return {"errors": ["No tab file"]}
  else:
    f.save_file(req.files["tab_zip"], tdir + "/tab." + data["tab"]["ext"])

  ## expanded
  data["expanded"]["ext"] = f.get_ext(req.files["expanded_zip"].filename)
  if data["expanded"]["ext"] == "zip":
    if not f.extract_zip(req.files["expanded_zip"], tdir + "/expanded"):
      return {"errors": ["Wrong expanded zip file"]}

    file_name = "index2.html"
    try:
      os.rename(tdir + "/expanded/index.html", tdir + "/expanded/" + file_name)
    except os.FileNotFoundError:
      return {"errors": ["No index.html in expanded zip"]}
  elif not data["expanded"]["ext"]:
    return {"errors": ["No expanded file"]}
  else:
    f.save_file(req.files["expanded_zip"], tdir + "/expanded." + data["expanded"]["ext"])

  v["expandMS"] = str(f.get_int_param("expand_seconds") * 1000)

  v["width"] = f.strtoken(f.get_param("size"), 1, "x")
  v["height"] = f.strtoken(f.get_param("size"), 2, "x")

  v["backgroundColor"] = f.get_param("background_color")

  v["clicktag_layer_select"] = "true" if f.get_param("clicktag_layer") else "false"

  v["tabURL"] = ""
  v["tabImage"] = ""

  if data["tab"]["ext"] == "zip":
    v["tabUrl"] = "tab/index2.html"
  else:
    v["tabImage"] = "tab."+data["tab"]["ext"]

  v["expandedURL"] = ""
  v["expandedImage"] = ""
  if data["expanded"]["ext"] == "zip":
    v["expandedURL"] = "expanded/index2.html"
  else:
    v["expandedImage"] = "expanded."+data["expanded"]["ext"]

  return {"errors": errors, "dir": tdir, "index": index, "vars": v}
Ejemplo n.º 9
0
def run(fmt, req):
  """Builder entry point.

  Dinamycally loads builder module.

  Args:
    fmt: format to build
    req: flask request

  Returns:
    Json containing the creative url for download
  """
  format_id = fmt.split("-")[0]
  format_name = fmt[4:]

  user_id = f.get_user_id(req)
  if user_id is None:
    return jsonify({"errors": ["Please login before running build process"]})

  # get creative id: formatId.userId.creativeId.zip
  new_id = db.res(
      "select ifnull(max(file_id)+1,1) id "
      "from   creatives "
      "where  user_id = %s "
      "and    format = %s", (user_id, format_id))

  ## load builder dinamically

  # run builder
  current_path = os.path.dirname(__file__)

  sys.path.append(current_path + "/formats/format_" + fmt)
  module1 = importlib.import_module("build_" + fmt)
  build = module1.build(req)

  if has_errors(build):
    return jsonify({"errors": build["errors"]})

  index = build["index"]

  ## replace standard vars
  v = {}
  if "vars" in build:
    v = build["vars"]

  v["autoclose"] = f.get_param("autoclose")
  v["close_button"] = f.get_param("close_button")
  v["close_button_width"] = f.get_param("close_button_width")
  v["close_button_height"] = f.get_param("close_button_height")
  v["bgcolor"] = f.get_param("bgcolor")

  import re
  if "width" in v:
    v["width"] = re.sub("\D", "", v["width"])
  if "height" in v:
    v["height"] = re.sub("\D", "", v["height"])

  if "width" not in v:
    if f.get_param("size"):
      v["width"] = f.get_param("size").split("x")[0]
    else:
      v["width"] = ""

  if "height" not in v:
    if f.get_param("size") and len(f.get_param("size").split("x")):
      v["height"] = f.get_param("size").split("x")[1]
    else:
      v["height"] = ""

  # clicktag_url
  clicktag_url = f.get_param("clicktag_url")
  if clicktag_url.lower()[0:4] != "http":
    clicktag_url = "http://" + clicktag_url
  v["clicktag_url"] = clicktag_url

  # clicktag_layer
  if f.get_param("clicktag_layer"):
    v["clicktag_layer"] = (
        "<div style = 'position: fixed; width: 100%; "
        "height: 100%; top: 0; overflow: hidden; z-index: 98;display: block; "
        "cursor:pointer' onclick=\"adcase_click()\" ></div>"
        "<script>function adcase_click() { window.top.postMessage({ "
        "msg: 'adcase_click', format:'" + format_name + "' }, '*'); "
        "window.open(clickTag, '_blank')}</script>")
  else:
    v["clicktag_layer"] = ""

  ## replace all vars
  for name in v:
    index = index.replace("[[" + name + "]]", str(v[name]))

  # save modified index.html
  f.file_put_contents(build["dir"] + "/index.html", index)

  # create new zipfile
  if "size" not in build:
    build["size"] = f.get_param("size")

  file_name = (
      format_name + "_" + v["width"] + "x" + v["height"] + "_u" + user_id +
      "_id" + new_id + ".zip")
  if not f.create_zip(build["dir"], "/tmp/" + str(file_name)):
    build["errors"].append("Could not create zip file")

  f.clean_tmp(build["dir"])

  # upload to storage
  destination_file = "f/" + user_id + "/" + file_name
  ad_url = f.save_to_storage("/tmp/" + file_name, destination_file)
  if not ad_url:
    build["errors"].append("Could not save to storage")

  # save creative to DB
  save_process(user_id, new_id, format_id, ad_url)

  out = {"ok": True, "ad_url": ad_url, "user_id": user_id}
  if has_errors(build):
    out["errors"] = build["errors"]

  return jsonify(out)
Ejemplo n.º 10
0
def build(req):
  """Builder for this format.

  Args:
    req: flask request

  Returns:
    Json containing the creative data
  """
  current_path = os.path.dirname(__file__)

  errors = []
  v = {}
  dcm = (f.get_int_param("dcm") == 1)
  data = {"collapsed": {}, "expanded": {}}
  tdir = "/tmp/" + f.get_tmp_file_name()

  path = current_path + "/index_101-push.html"
  index = f.file_get_contents(path)

  if "collapsed_zip" not in req.files:
    return {"errors": ["No collapsed file"]}
  if "expanded_zip" not in req.files:
    return {"errors": ["No expanded file"]}

  ## collapsed
  data["collapsed"]["ext"] = f.get_ext(req.files["collapsed_zip"].filename)
  if data["collapsed"]["ext"] == "zip":
    os.mkdir(tdir)
    if not f.extract_zip(req.files["collapsed_zip"], tdir + "/collapsed"):
      return {"errors": ["Wrong collapsed zip file"]}

    file_name = "index2.js" if dcm else "index2.html"
    try:
      os.rename(tdir + "/collapsed/index.html", tdir+"/collapsed/" + file_name)
    except os.FileNotFoundError:
      return {"errors": ["No index.html in collapsed zip"]}

    if dcm:
      change_base(tdir+"/collapsed/" + file_name, "collapsed")
  elif not data["collapsed"]["ext"]:
    return {"errors": ["No collapsed file"]}
  else: 
    f.mk_dir(tdir)
    zfile = req.files["collapsed_zip"]
    zfile.save(tdir+'/collapsed.'+data["collapsed"]["ext"])
    zfile.close()

  ## expanded
  data["expanded"]["ext"] = f.get_ext(req.files["expanded_zip"].filename)
  if data["expanded"]["ext"] == "zip":
    if not f.extract_zip(req.files["expanded_zip"], tdir + "/expanded"):
      return {"errors": ["Wrong expanded zip file"]}

    file_name = "index2.js" if dcm else "index2.html"
    try:
      os.rename(tdir + "/expanded/index.html", tdir + "/expanded/" + file_name)
    except os.FileNotFoundError:
      return {"errors": ["No index.html in expanded zip"]}

    if dcm:
      change_base(tdir+"/expanded/" + file_name, "expanded")

  elif not data["expanded"]["ext"]:
    return {"errors": ["No expanded file"]}
  else: 
    f.mk_dir(tdir)
    zfile = req.files["expanded_zip"]
    zfile.save(tdir+'/expanded.'+data["expanded"]["ext"])
    zfile.close()

  v["initExpanded"] = "true" if f.get_param("initial_state") == "E" else "false"
  if f.get_param("initial_state") == "E":
    v["autocloseSeconds"] = f.get_param("autoclose_seconds")
  else:
    v["autocloseSeconds"] = "0"
  v["width"] = f.get_param("width")
  v["height"] = f.get_param("expanded_height")

  v["collapsedHeight"] = f.get_param("collapsed_height")
  v["expandedHeight"] = f.get_param("expanded_height")
  v["transitionTimeMs"] = str(f.get_int_param("animated_transition") * 250)
  v["expandAction"] = f.get_param("expand_action")
  v["collapseSeconds"] = f.get_param("collapse_seconds")

  if data["collapsed"]["ext"] == "zip":
    if dcm:
      v["collapsedContent"] = "<iframe id='iframe_collapsed' src='' frameborder=0 style='width:"+v["width"]+"px;height:"+v["collapsedHeight"]+"}px' scrolling='no'></iframe>"
    else:
      v["collapsedContent"] = "<iframe id='iframe_collapsed' src='collapsed/index2.html' frameborder=0 style='width:"+v["width"]+"px;height:"+v["collapsedHeight"]+"px' scrolling='no'></iframe>"
  else:
    v["collapsedContent"] = "<img src='collapsed."+data["collapsed"]["ext"]+"' style='border:0;width:"+v["width"]+"px;height:"+v["collapsedHeight"]+"px' />"

  if data["expanded"]["ext"] == "zip":
    if dcm:
      v["expandedContent"] = "<iframe id='iframe_expanded' src='' frameborder=0 style='width:"+v["width"]+"px;height:"+v["expandedHeight"]+"px' scrolling='no'></iframe>"
    else:
      v["expandedContent"] = "<iframe id='iframe_expanded' src='expanded/index2.html' frameborder=0 style='width:"+v["width"]+"px;height:"+v["expandedHeight"]+"px' scrolling='no'></iframe>"
  else:
    v["expandedContent"] = "<img src='expanded."+data["expanded"]["ext"]+"' style='border:0;width:"+v["width"]+"px;height:"+v["expandedHeight"]+"px' />"

  v["dcmScript"] = ""
  if dcm:
    if data["collapsed"]["ext"] == "zip":
      v["dcmScript"] = v["dcmScript"] + "\ndcm_load('collapsed');"
    if data["expanded"]["ext"] == "zip":
      v["dcmScript"] = v["dcmScript"] + "\ndcm_load('expanded');"

  return {"errors": errors, "dir": tdir, "index": index, "vars": v}
Ejemplo n.º 11
0
def build(req):
    """Builder for this format.

  Args:
    req: flask request

  Returns:
    Json containing the creative data
  """

    errors = []
    v = {}
    data = {"inline": {}, "sticky": {}}
    tdir = "/tmp/" + f.get_tmp_file_name()

    index = get_html()

    if "inline_zip" not in req.files:
        return {"errors": ["No inline file"]}
    if "sticky_zip" not in req.files:
        return {"errors": ["No sticky file"]}

    ## inline
    data["inline"]["ext"] = f.get_ext(req.files["inline_zip"].filename)
    if data["inline"]["ext"] == "zip":
        os.mkdir(tdir)
        if not f.extract_zip(req.files["inline_zip"], tdir + "/inline"):
            return {"errors": ["Wrong inline zip file"]}

        file_name = "index2.html"
        try:
            os.rename(tdir + "/inline/index.html",
                      tdir + "/inline/" + file_name)
        except os.FileNotFoundError:
            return {"errors": ["No index.html in inline zip"]}
    elif not data["inline"]["ext"]:
        return {"errors": ["No inline file"]}
    else:
        f.save_file(req.files["inline_zip"],
                    tdir + "/inline." + data["inline"]["ext"])

    ## sticky
    data["sticky"]["ext"] = f.get_ext(req.files["sticky_zip"].filename)
    if data["sticky"]["ext"] == "zip":
        if not f.extract_zip(req.files["sticky_zip"], tdir + "/sticky"):
            return {"errors": ["Wrong sticky zip file"]}

        file_name = "index2.html"
        try:
            os.rename(tdir + "/sticky/index.html",
                      tdir + "/sticky/" + file_name)
        except os.FileNotFoundError:
            return {"errors": ["No index.html in sticky zip"]}
    elif not data["sticky"]["ext"]:
        return {"errors": ["No sticky file"]}
    else:
        f.save_file(req.files["sticky_zip"],
                    tdir + "/sticky." + data["sticky"]["ext"])

    v["width"] = f.get_param("width")

    v["inlineHeight"] = f.get_int_param("inline_height")
    v["stickyHeight"] = f.get_int_param("sticky_height")
    v["maxHeight"] = str(max(v["inlineHeight"], v["stickyHeight"]))
    v["height"] = v["maxHeight"]
    v["transitionTimeMs"] = str(f.get_int_param("animated_transition") * 250)

    v["inlinePosition"] = f.get_param("inline_position")
    v["inlinePositionDivId"] = f.get_param("inline_position_div_id")
    v["topMargin"] = f.get_param("top_margin")

    if data["inline"]["ext"] == "zip":
        v["inlineContent"] = "<iframe src='inline/index2.html' frameborder=0 style='width:" + v[
            "width"] + "px;height:" + str(
                v["inlineHeight"]) + "px' scrolling='no'></iframe>"
    else:
        v["inlineContent"] = "<img src='inline." + data["inline"][
            "ext"] + "' style='border:0;width:" + v[
                "width"] + "px;height:" + str(v["inlineHeight"]) + "px' />"

    if data["sticky"]["ext"] == "zip":
        v["stickyContent"] = "<iframe src='sticky/index2.html' frameborder=0 style='width:" + v[
            "width"] + "px;height:" + str(
                v["stickyHeight"]) + "px' scrolling='no'></iframe>"
    else:
        v["stickyContent"] = "<img src='sticky." + data["sticky"][
            "ext"] + "' style='border:0;width:" + v[
                "width"] + "px;height:" + str(v["stickyHeight"]) + "px' />"

    return {"errors": errors, "dir": tdir, "index": index, "vars": v}