<commit_before>require("HTTP")
require("HTTP/src/BasicServer")

require("Calendar")

module Ocean
  # """
  # Fertilizer
  # I'll take bullshit if that's all you got
  # Some fertilizer
  # Fertilizer
  # Ooooooo
  # """
  
  import Pkg
  import Base.abspath, Base.joinpath, Base.dirname
  import HTTP
  
  export
    # App construction
    new_app,
    # Request methods
    get,
    post,
    put,
    delete,
    any,
    route,
    # Utilities for interacting with HTTP server API
    binding,
    call
  
  include("Ocean/Util.jl")
  using Util
  
  type Route
    method::String
    path::Union(String, Regex)
    opts::Dict{Any,Any}
    handler::Function
  end
  
  type App
    routes::Array{Route}
    source_dir::String
    source_path::String
    
    App() = new(Route[], "", "")
  end
  
  # Used in Extra
  const _blank_request = HTTP.Request()
  const _blank_response = HTTP.Response()
  const _blank_app = App()
  # const _blank_func = function(); end
  const _blank_func_1 = function(a); end
  # const _blank_func_2 = function(a, b); end
  # Extra stuff that goes along with the req-rep pair for route calling.
  type Extra
    params::Union(Array, Bool)
    app::App
    req::HTTP.Request
    res::HTTP.Response
    file::Function
    template::Function
    
    Extra(app::App, req::HTTP.Request, res::HTTP.Response) = new(
      false,
      app,
      req,
      res,
      _blank_func_1, # file
      _blank_func_1 # template
    )
    
    Extra() = new(_blank_app, _blank_request, _blank_response)
  end
  
  include("Ocean/Template.jl")
  
  function app()
    _app = App()
    
    #tls = task_local_storage()
    #sp = Base.get(tls, :SOURCE_PATH, nothing)
    sp = Base.source_path()
    # If sp is nothing then it's coming from the REPL and we'll just use
    # the pwd.
    # If it's a string then it's the path to the source file that originally
    # loaded everything.
    _app.source_dir  = (sp == nothing) ? pwd() : dirname(sp)
    _app.source_path = (sp == nothing) ? "(repl)" : sp
    
    return _app
  end
  # Alias for when the module is imported
  new_app = app
  
  # Utilities for working within the app
  function file(app::App, path::String)
    if begins_with(path, "/")
      p = path
    else
      p = app.source_dir*"/"*path
    end
    r = open(readall, p, "r")
    return r
  end
  
  function template(app::App, format::Symbol, path::String, data::Any)
    if format == :ejl
      
    elseif format == :mustache
      if Main.isdefined(:Mustache)
        contents = file(app, path)
        # TODO: Cache compiled version of template
        return Main.Mustache.render(contents, data)
      else
        error("Please install and require the Mustache package")
      end
      
    else
      error("Unrecognized template format " * repr(format))
    end
  end
  template(app::App, format::Symbol, path::String) = 
    format(app, format, path, Dict())
  
  function new_extra(app, req, res)
    extra = Extra(app, req, res)
    extra.file = Util.enscopen(app, file)
    extra.template = Util.enscopen(app, template)
    return extra
  end
  
  function route(app::App, _route::Route)
    push!(app.routes, _route)
  end
  function route(app::App, method::String, path::Any, opts::Dict{Any,Any}, handler::Function)
    route(app, Route(method, path, opts, handler))
  end
  # Shortcuts for creating routes.
  function get(app::App, path::Any, handler::Function)
    route(app, Route("GET", path, Dict{Any,Any}(), handler))
  end
  function post(app::App, path::Any, handler::Function)<commit_msg>Add app cache and Mustache.jl templating integration<commit_after>require("HTTP")
require("HTTP/src/BasicServer")

require("Calendar")

module Ocean
  # """
  # Fertilizer
  # I'll take bullshit if that's all you got
  # Some fertilizer
  # Fertilizer
  # Ooooooo
  # """
  
  import Pkg
  import Base.abspath, Base.joinpath, Base.dirname
  import HTTP
  
  export
    # App construction
    new_app,
    # Request methods
    get,
    post,
    put,
    delete,
    any,
    route,
    # Utilities for interacting with HTTP server API
    binding,
    call
  
  include("Ocean/Util.jl")
  using Util
  
  type Route
    method::String
    path::Union(String, Regex)
    opts::Dict{Any,Any}
    handler::Function
  end
  
  type App
    routes::Array{Route}
    source_dir::String
    source_path::String
    # NOTE: Keys that are symbols starting with "_" (eg. "_file") are reserved
    #       by Ocean.
    cache::Dict{Union(String,Symbol),Any}
    
    App() = new(Route[], "", "", Dict{Any,Any}())
  end
  
  # Used in Extra
  const _blank_request = HTTP.Request()
  const _blank_response = HTTP.Response()
  const _blank_app = App()
  # const _blank_func = function(); end
  const _blank_func_1 = function(a); end
  # const _blank_func_2 = function(a, b); end
  # Extra stuff that goes along with the req-rep pair for route calling.
  type Extra
    params::Union(Array, Bool)
    app::App
    req::HTTP.Request
    res::HTTP.Response
    file::Function
    template::Function
    
    Extra(app::App, req::HTTP.Request, res::HTTP.Response) = new(
      false,
      app,
      req,
      res,
      _blank_func_1, # file
      _blank_func_1 # template
    )
    
    Extra() = new(_blank_app, _blank_request, _blank_response)
  end
  
  include("Ocean/Template.jl")
  
  function app()
    _app = App()
    
    #tls = task_local_storage()
    #sp = Base.get(tls, :SOURCE_PATH, nothing)
    sp = Base.source_path()
    # If sp is nothing then it's coming from the REPL and we'll just use
    # the pwd.
    # If it's a string then it's the path to the source file that originally
    # loaded everything.
    _app.source_dir  = (sp == nothing) ? pwd() : dirname(sp)
    _app.source_path = (sp == nothing) ? "(repl)" : sp
    
    return _app
  end
  # Alias for when the module is imported
  new_app = app
  
  # Utilities for working within the app
  function file(app::App, path::String)
    if begins_with(path, "/")
      p = path
    else
      p = app.source_dir*"/"*path
    end
    sp = symbol("_file:" * p)
    if has(app.cache, sp)
      return app.cache[sp]
    end
    r = open(readall, p, "r")
    app.cache[sp] = r
    return r
  end
  
  function template(app::App, format::Symbol, path::String, data::Any)
    if format == :ejl
      
    elseif format == :mustache
      if Main.isdefined(:Mustache)
        contents = file(app, path)
        # TODO: Cache compiled version of template
        sp = symbol("_mustache:" * path)
        if has(app.cache, sp)
          _template = app.cache[sp]
        else
          _template = Main.Mustache.parse(contents)
          app.cache[sp] = _template
        end
        return Main.Mustache.render(_template, data)
      else
        error("Please install and require the Mustache package")
      end
      
    else
      error("Unrecognized template format " * repr(format))
    end
  end
  template(app::App, format::Symbol, path::String) = 
    format(app, format, path, Dict())
  
  function new_extra(app, req, res)
    extra = Extra(app, req, res)
    extra.file = Util.enscopen(app, file)
    extra.template = Util.enscopen(app, template)
    return extra
  end
  
  function route(app::App, _route::Route)
    push!(app.routes, _route)
  end
  function route(app::App, method::String, path::Any, opts::Dict{Any,Any}, handler::Function)
    route(app, Route(method, path, opts, handler))
  end
  # Shortcuts for creating routes.
  function get(app::App, path::Any, handler::Function)
    route(app, Route("GET", path, Dict{Any,Any}(), handler))
  end
  function post(app::App, path::Any, handler::Function)
{'fraction_non_alphanumeric': 0.11820207050190014, 'fraction_numerical': 0.00104835539247805, 'mean_word_length': 2.7726149283242707, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7338497', 'n_tokens_mistral': 2518, 'n_tokens_neox': 2491, 'n_words': 687}