<commit_before>class Webbastic::Site
  include DataMapper::Resource

  property :id, Serial
  property :name, Text
  property :created_at, DateTime
  
  has n, :pages,  :class_name => Webbastic::Page
  has n, :layouts,  :class_name => Webbastic::Layout
  has n, :folders,  :class_name => Webbastic::ContentDir
  has 1, :default_layout, :class_name =>  Webbastic::Layout
  
  after :create, :create_defaults
  
  before :destroy, :unlink_site
  
  # =====
  #
  # Site creation
  #
  # =====
  
  def initialize(options = {})
    
    # TODO: elegant regexp for Merb.root folder
    self.name = options[:name] || sanitize_filename(Merb.root[/\/(.[^\/]*)$/,1]) 
    
    index = File.join("webby", self.name, "content", "index")
    
    unless File.exists? index
      # Generate webby app with this site parameters
      # use --force to rewrite website (avoid console prompt on overwrite)
      Webby::Apps::Generator.new.run ["--force",  # options
                                      "website",  # template
                                      path]       # path
                                      
      # rename index file, without extension
      File.rename "#{index}.txt", index
    end
  end
  
  # Create default page and layout after site has been saved
  def create_defaults
    import_layout(self.layout_dir(:absolute => true))
    import_content(self.content_dir(:absolute => true))
  end
  
  def import_layout(directory)
    Dir.new(directory).each do |path|
      next if path.match(/^\.+/)
      
      @layout = self.layouts.create :name => path
      
      # Add file content as layout content that could be modified later
      File.open(File.join(directory, path), "r") do |file|
        @layout.content = read_content(file.read)
      end
    end
  end
  
  # Follow directory path and import its files into DB
  def import_content(directory, parent_folder = nil)
    Dir.new(directory).each do |path|
      next if path.match(/^\.+/)
      
      # Create a new Webbastic::ContentDir object for every folders
      if FileTest.directory?(File.join(directory, path))
        if parent_folder
          @folder = parent_folder.children.create :name => path
        else
          @folder = self.folders.create :name => path
        end
        import_content(File.join(directory, path), @folder)
        
      # Create a new Webbastic::Page object for every files
      # and read its content to put it in a static widget
      else
        if parent_folder
          @page = parent_folder.pages.create :name => path, :layout => self.default_layout
        else
          @page = self.pages.create :name => path, :layout => self.default_layout
        end
        
        file = File.new(File.join(directory, path), "r")
        content = ""
        while (line = file.gets)
          content << line
        end
        file.close
        
        @page.add_static_content
      end
    end
  end
  
  # =====
  #
  # Site generate
  #
  # =====
  
  #
  # Generate site content base on its structure
  #
  def generate
    self.layouts.each {|layout| layout.write_file}
    self.pages.each {|page| page.write_file}
    
    Webby.site.content_dir    = self.content_dir
    Webby.site.layout_dir     = self.layout_dir
    Webby.site.template_dir   = self.template_dir
    Webby.site.output_dir     = self.output_dir
    
    # Use directory => '.' option to generate the site in output_dir
    Webby.site.page_defaults  = {'layout' => self.default_layout.relative_path,
                                 'directory' => '.',
                                 'collision' => :force}
                                 
    # returns nil if success 
    # Webby::Builder.run
    Webby::Builder.run :rebuild => true
  end
  
  # =====
  #
  # Site path
  #
  # =====
  
  def output_dir(options = {})
    options[:dir] = "generate"
    build_webby_path(options)
  end
  
  def content_dir(options = {})
    options[:dir] = "content"
    build_webby_path(options)
  end
  
  def layout_dir(options = {})
    options[:dir] = "layouts"
    build_webby_path(options)
  end
  
  def template_dir(options = {})
    options[:dir] = "templates"
    build_webby_path(options)
  end
  
  def build_webby_path(options = {})
    webby_path =  options[:absolute] ? self.absolute_path  : self.relative_path
    
    # options[:dir] contains the name of the folder to fetch
    options[:dir].nil? ? webby_path : File.join(webby_path, options[:dir])
  end
  
  def absolute_path
    if File.symlink? Merb.root
      # Symlink is used in Capistrano, go fetch webby content in shared dir
      shared_path = File.join(Merb.root, "..", "..", "shared", self.relative_path)
      
      # If not already done, move webby to shared directory
      unless File.exists? shared_path
        webby_current = File.join(Merb.root, "webby")
        webby_shared  = File.join(Merb.root, "..", "..", "shared", "webby")<commit_msg>veirfy and build path if not exists<commit_after>class Webbastic::Site
  include DataMapper::Resource

  property :id, Serial
  property :name, Text
  property :created_at, DateTime
  
  has n, :pages,  :class_name => Webbastic::Page
  has n, :layouts,  :class_name => Webbastic::Layout
  has n, :folders,  :class_name => Webbastic::ContentDir
  has 1, :default_layout, :class_name =>  Webbastic::Layout
  
  after :create, :create_defaults
  
  before :destroy, :unlink_site
  
  # =====
  #
  # Site creation
  #
  # =====
  
  def initialize(options = {})
    
    # TODO: elegant regexp for Merb.root folder
    self.name = options[:name] || sanitize_filename(Merb.root[/\/(.[^\/]*)$/,1]) 
    
    index = File.join("webby", self.name, "content", "index")
    
    unless File.exists? index
      # Generate webby app with this site parameters
      # use --force to rewrite website (avoid console prompt on overwrite)
      Webby::Apps::Generator.new.run ["--force",  # options
                                      "website",  # template
                                      path]       # path
                                      
      # rename index file, without extension
      File.rename "#{index}.txt", index
    end
  end
  
  # Create default page and layout after site has been saved
  def create_defaults
    import_layout(self.layout_dir(:absolute => true))
    import_content(self.content_dir(:absolute => true))
  end
  
  def import_layout(directory)
    Dir.new(directory).each do |path|
      next if path.match(/^\.+/)
      
      @layout = self.layouts.create :name => path
      
      # Add file content as layout content that could be modified later
      File.open(File.join(directory, path), "r") do |file|
        @layout.content = read_content(file.read)
      end
    end
  end
  
  # Follow directory path and import its files into DB
  def import_content(directory, parent_folder = nil)
    Dir.new(directory).each do |path|
      next if path.match(/^\.+/)
      
      # Create a new Webbastic::ContentDir object for every folders
      if FileTest.directory?(File.join(directory, path))
        if parent_folder
          @folder = parent_folder.children.create :name => path
        else
          @folder = self.folders.create :name => path
        end
        import_content(File.join(directory, path), @folder)
        
      # Create a new Webbastic::Page object for every files
      # and read its content to put it in a static widget
      else
        if parent_folder
          @page = parent_folder.pages.create :name => path, :layout => self.default_layout
        else
          @page = self.pages.create :name => path, :layout => self.default_layout
        end
        
        file = File.new(File.join(directory, path), "r")
        content = ""
        while (line = file.gets)
          content << line
        end
        file.close
        
        @page.add_static_content
      end
    end
  end
  
  # =====
  #
  # Site generate
  #
  # =====
  
  #
  # Generate site content base on its structure
  #
  def generate
    self.layouts.each {|layout| layout.write_file}
    self.pages.each {|page| page.write_file}
    
    Webby.site.content_dir    = self.content_dir
    Webby.site.layout_dir     = self.layout_dir
    Webby.site.template_dir   = self.template_dir
    Webby.site.output_dir     = self.output_dir
    
    # Use directory => '.' option to generate the site in output_dir
    Webby.site.page_defaults  = {'layout' => self.default_layout.relative_path,
                                 'directory' => '.',
                                 'collision' => :force}
                                 
    # returns nil if success 
    # Webby::Builder.run
    Webby::Builder.run :rebuild => true
  end
  
  # =====
  #
  # Site path
  #
  # =====
  
  def output_dir(options = {})
    options[:dir] = "generate"
    build_webby_path(options)
  end
  
  def content_dir(options = {})
    options[:dir] = "content"
    build_webby_path(options)
  end
  
  def layout_dir(options = {})
    options[:dir] = "layouts"
    build_webby_path(options)
  end
  
  def template_dir(options = {})
    options[:dir] = "templates"
    build_webby_path(options)
  end
  
  def build_webby_path(options = {})
    webby_path =  options[:absolute] ? self.absolute_path  : self.relative_path
    
    # options[:dir] contains the name of the folder to fetch
    path = options[:dir].nil? ? webby_path : File.join(webby_path, options[:dir])
    
    unless File.exists? path
      FileUtils.mkdir_p path
    end
    
    path
  end
  
  def absolute_path
    if File.symlink? Merb.root
      # Symlink is used in Capistrano, go fetch webby content in shared dir
      shared_path = File.join(Merb.root, "..", "..", "shared", self.relative_path)
      
      # If not already done, move webby to shared directory
      unless File.exists? shared_path
        webby_current = File.join(Merb.root, "webby")
        webby_shared  = File.join(Merb.root, "..", "..", "shared", "webby")
{'fraction_non_alphanumeric': 0.11327575818437437, 'fraction_numerical': 0.0004016870857601928, 'mean_word_length': 2.2271548930654568, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 39, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 10, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3053024', 'n_tokens_mistral': 3051, 'n_tokens_neox': 3013, 'n_words': 765}