# frozen_string_literal: true require_relative "volumen/version" require_relative "volumen/frontmatter" require_relative "volumen/markdown" require_relative "volumen/post" require_relative "volumen/store" require_relative "volumen/config" require_relative "volumen/password" require_relative "volumen/users" # volumen is a small, file-based Markdown blog engine. # # Posts are plain `.md` files with a TOML frontmatter block delimited by # `+++`. The engine exposes them as a JSON API and ships a server-rendered # admin with a Markdown source editor and a visual editor. # # The Sinatra app (`Volumen::Server`) and the CLI (`Volumen::CLI`) are loaded # on demand to keep the core library light. module Volumen CLEANUP_INTERVAL = 300 # seconds between full sweeps of login_attempts def self.login_attempts @login_attempts ||= {} end def self.reset_login_attempts! @login_attempts = {} @last_cleanup = nil end def self.sweep_login_attempts! now = Time.now.to_f return if @last_cleanup && (now - @last_cleanup) < CLEANUP_INTERVAL cutoff = now - Volumen::Server::LOGIN_WINDOW login_attempts.each_value { |timestamps| timestamps.select! { |t| t > cutoff } } login_attempts.delete_if { |_ip, timestamps| timestamps.empty? } @last_cleanup = now end end