' unless @menu == ''
+ end
+
+ # Метод, отвечающий требует ли данный запрос доступа по паролю или нет
+ def is_authorized_action?()
+ return true
+ end
+
+ # Установка значение controller/action
+ def set_action()
+ params = @cgi.params
+ @action = params['action'][0].to_sym if @action.nil?
+ @controller = (params.has_key?('controller') ?
+ params['controller'][0].to_sym :
+ self.class.to_sym) if @controller.nil?
+ end
+
+ # Проверяет где искать метод (в текущем контроллере или нет)
+ def my_action?()
+ return @controller.to_s + 'Controller' == self.class.to_s
+ end
+
+ # Формирование html документа
+ def response()
+ render_layout('header', :rb) +
+ @html +
+ render_layout('footer', :rb)
+ end
+
+ # Формирование только содержимого тела html документа
+ def response_withot_layout()
+ @html
+ end
+
+ # Конструктор
+ def initialize(cgi = nil, session = nil, action = nil, controller = nil)
+ @action = action
+ @controller = controller
+ @db = DbDriver.instance()
+ @cgi = cgi unless cgi.nil?
+ @session = session unless session.nil?
+
+ before_filters().each{ |f| self.send(f.to_s) }
+
+ if my_action?()
+ @html = self.send(@action.to_s)
+ else
+ c = eval(@controller.to_s + 'Controller').new(@cgi, @session, @action,
+ @controller)
+ @html = c.response_withot_layout()
+ end
+
+ after_filters().each{ |f| self.send(f.to_s) }
+ DbDriver.close()
+ end
+
+ # Загружает html-код из файла в строку
+ def render_template(name, mode = :rb)
+ if mode == :rb
+ f = File.new("templates/#{Convertors.class_name_to_controller_dir(@controller)}/#{name}.rb")
+ html = eval(f.read)
+ f.close
+ return html
+ else
+ f = File.new("templates/#{@controller}/#{name}")
+ html = f.read
+ f.close
+ return html
+ end
+ end
+
+ # Загружает html-код из файла, лежащего в папке layout, в строку
+ def render_layout(name, mode = :html)
+ if mode == :rb
+ f = File.new("templates/layout/#{name}.rb")
+ html = eval(f.read)
+ f.close
+ return html
+ else
+ f = File.new("templates/layout/#{name}.html")
+ html = f.read
+ f.close
+ return html
+ end
+ end
+
+ # Возвращает списки элементов меню
+ def Controller.actions(user)
+ []
+ end
+
+ # Выбирает из параметров только параметры с именем вида: prefix[имя]
+ def filter_for_params(prefix = 'item')
+ keys = @cgi.params.keys.select{ |k| k =~ /^#{prefix}/ }.map do
+ |k| k.gsub(/^#{prefix}\[(.*)\]$/, '\1')
+ end
+ params = {}
+ keys.each{ |k| params[k] = @cgi.params["#{prefix}[#{k}]"] }
+ return params
+ end
+end
+
+# Подключение всех *_controller.rb
+Dir[File.join(File.dirname(__FILE__), '', "*.rb")].each do |f|
+ require f if File.basename(f) != 'controller.rb'
+end
+
diff --git a/lib/controllers/flights_controller.rb b/lib/controllers/flights_controller.rb
new file mode 100644
index 0000000..e929f8b
--- /dev/null
+++ b/lib/controllers/flights_controller.rb
@@ -0,0 +1,81 @@
+class FlightsController < Controller
+ def is_authorized_action?()
+ !([:departure_list, :arrival_list].include?(@action))
+ end
+
+ def list()
+ @items = Flight.find_all(@db)
+ render_template(@action)
+ end
+
+ def departure_list()
+ @items = Flight.find_all(@db, true)
+ @header = 'Вылетающие рейсы'
+ render_template('easy_list')
+ end
+
+ def arrival_list()
+ @items = Flight.find_all(@db, false)
+ @header = 'Прилетающие рейсы'
+ render_template('easy_list')
+ end
+
+ def edit()
+ if @cgi.params.has_key?('is_commit')
+ params = filter_for_params()
+ if params.has_key?('id') and params['id'][0] != ''
+ @item = Flight.find_first(@db, params['id'][0])
+ @header = 'Редактирование информации о рейсе'
+ @message = 'Информация о рейсе записана'
+ if @item.nil?
+ @item = Flight.new
+ @header = 'Внесение новой информации о рейсах'
+ @message = 'Информация о новом рейсе внесена в БД'
+ end
+ else
+ @item = Flight.new
+ @header = 'Внесение новой информации о рейсах'
+ @message = 'Информация о новом рейсе внесена в БД'
+ end
+ params.each do |k, v|
+ @item[k] = v[0] if k != 'id' and v != ''
+ end
+ @item.save(@db)
+ else
+ if @cgi.params.has_key?('id')
+ @item = Flight.find_first(@db, @cgi.params['id'][0])
+ @header = 'Редактирование информации о рейсе'
+ if @item.nil?
+ @item = Flight.new
+ @header = 'Внесение новой информации о рейсах'
+ end
+ else
+ @item = Flight.new
+ @header = 'Внесение новой информации о рейсах'
+ end
+ end
+ render_template('edit')
+ end
+
+ def destroy()
+ if @cgi.params.has_key?('id') and @cgi.params['id'][0] != ''
+ @item = Flight.find_first(@db, @cgi.params['id'][0])
+ unless @item.nil?
+ @item.destroy(@db)
+ @message = 'Объект удален!'
+ else
+ @message = 'Объект не найден!'
+ end
+ end
+ render_template(@action)
+ end
+
+ def FlightsController.actions(user)
+ result = [[:departure_list, 'Вылетающие рейсы'],
+ [:arrival_list, 'Прилетающие рейсы']]
+ unless user.nil?
+ result += [[:list, 'Все рейсы']]
+ end
+ result
+ end
+end
diff --git a/lib/controllers/helper.rb b/lib/controllers/helper.rb
new file mode 100644
index 0000000..185b9a7
--- /dev/null
+++ b/lib/controllers/helper.rb
@@ -0,0 +1,22 @@
+module Helper
+ def companies_select(name, selected)
+ ""
+ end
+
+ def is_departure_select(name, selected = true)
+ options = {:true => 'отлетающий', :false => 'прилетающий'}
+ ""
+ end
+end
diff --git a/lib/convertors.rb b/lib/convertors.rb
new file mode 100644
index 0000000..bd60f36
--- /dev/null
+++ b/lib/convertors.rb
@@ -0,0 +1,25 @@
+module Convertors
+ def Convertors.controller_file_to_class_name(file)
+ File.basename(file)[0..-14].split(/_/).map{ |i| i.capitalize }.join
+ end
+
+ def Convertors.controller_file_to_full_class_name(file)
+ File.basename(file)[0..-4].split(/_/).map{ |i| i.capitalize }.join
+ end
+
+ def Convertors.controller_file_to_dir(file)
+ File.basename(file)[0..-14]
+ end
+
+ def Convertors.full_class_name_to_dir(class_name)
+ Convertors.class_name_to_controller_dir(File.basename(class_name.to_s)[0..-11])
+ end
+
+ def Convertors.class_name_to_controller_file(class_name)
+ class_name.to_s.gsub(/(\W)/, '_\1').downcase + '_controller.rb'
+ end
+
+ def Convertors.class_name_to_controller_dir(class_name)
+ class_name.to_s.gsub(/(\W)/, '_\1').downcase
+ end
+end
diff --git a/lib/db_core/create_database.rb b/lib/db_core/create_database.rb
new file mode 100644
index 0000000..f48500c
--- /dev/null
+++ b/lib/db_core/create_database.rb
@@ -0,0 +1,85 @@
+require 'db_core/db_driver'
+
+# Подключает все файлы db_core/model/*.rb
+Dir[File.join(File.dirname(__FILE__), 'models', "*.rb")].each do |f|
+ require(f)
+end
+
+class CreateDatabase
+ # Используемые модели
+ MODELS = [Terminal, CheckInDesk, Company, Flight,
+ CheckInDeskFlight, FlightTerminal, FlightStatus, User]
+ CREATE_OK = 1 + MODELS.size
+
+ def initialize()
+ end
+
+ # Создание пустой БД и всех таблиц. Внимание! БД сначала удаляется!
+ def create
+ creation_counter = 0
+ @db_empty = DbDriver.empty_connection()
+ creation_counter += self.drop_db()
+ creation_counter += self.create_db()
+ creation_counter += self.create_tables()
+ @db_empty.disconnect()
+ return creation_counter
+ end
+
+ # Создание пустой БД
+ def create_db()
+ begin
+ @db_empty.do("CREATE DATABASE aero")
+ return 1
+ rescue DBI::ProgrammingError => e
+ return 0
+ end
+ end
+
+ # Удаление БД
+ def drop_db()
+ begin
+ @db_empty.do("DROP DATABASE aero")
+ return 1
+ rescue DBI::ProgrammingError => e
+ return 0
+ end
+ end
+
+ # См. константу MODELS
+ def models()
+ MODELS
+ end
+
+ # Создание всех таблиц
+ def create_tables()
+ creation_counter = 0
+ db = DbDriver.instance()
+ self.models.each do |cls|
+ creation_counter += 1 if cls.create_table(db)
+ end
+ DbDriver.close()
+ return creation_counter
+ end
+
+ # Тестовое добавление данных
+ def insert_test_data()
+ db = DbDriver.instance()
+ c = Company.new
+ c[:name] = 'Сибирь'
+ c[:code] = 'SB'
+ c[:description] = 'Авиакомпания "Сибирь" - Россия'
+ c.save(db)
+ f = Flight.new
+ f[:code] = (c[:code] + '00001')
+ f[:arrival_date] = '2009-10-10 10:00:00'
+ f[:departure_date] = '2009-10-10 22:00:00'
+ f[:arrival_place] = 'Лондон'
+ f[:departure_place] = 'Москва'
+ f[:arrival_airport] = 'Хитроу'
+ f[:departure_airport] = 'Внуково'
+ f[:is_departure] = true
+ f[:company_id] = c[:id]
+ f.save(db)
+ DbDriver.close()
+ end
+end
diff --git a/lib/db_core/db_driver.rb b/lib/db_core/db_driver.rb
new file mode 100644
index 0000000..66ae593
--- /dev/null
+++ b/lib/db_core/db_driver.rb
@@ -0,0 +1,42 @@
+require 'rubygems'
+require 'dbi'
+require 'singleton'
+
+class DbDriver
+ include Singleton
+
+ HOST = 'localhost'
+ PORT = 5432
+ USER = 'worker'
+ PASSWORD = 'worker'
+ DBNAME = 'aero'
+ DBEMPTYNAME = 'template1'
+
+ # Возвращает указатель на установленное соединение
+ def DbDriver.instance()
+ if @connection.nil? or !@connection.connected?
+ DbDriver.connect()
+ end
+ return @connection
+ end
+
+ # Устанавливает соединение с БД
+ def DbDriver.connect()
+ @connection = DBI.connect("dbi:Pg:dbname=#{DBNAME};host=#{HOST};port=#{PORT}",
+ USER, PASSWORD, 'AutoCommit' => true, 'pg_client_encoding' => 'UTF-8')
+ end
+
+ # Устанавливает соединение с пустым репозиторием (необходимо для createdb)
+ def DbDriver.empty_connection()
+ if @empty_connection.nil? or !@empty_connection.connected?
+ @empty_connection = DBI.connect("dbi:Pg:dbname=#{DBEMPTYNAME};host=#{HOST};port=#{PORT}",
+ USER, PASSWORD, 'AutoCommit' => true, 'pg_client_encoding' => 'UTF-8')
+ end
+ return @empty_connection
+ end
+
+ # Закрывает соединение с БД
+ def DbDriver.close()
+ @connection.disconnect if @connection.connected?
+ end
+end
\ No newline at end of file
diff --git a/lib/db_core/models/check_in_desk.rb b/lib/db_core/models/check_in_desk.rb
new file mode 100644
index 0000000..16586d2
--- /dev/null
+++ b/lib/db_core/models/check_in_desk.rb
@@ -0,0 +1,18 @@
+require 'db_core/models/model'
+
+class CheckInDesk < Model
+ def CheckInDesk.create_table(connection)
+ begin
+ connection.do("
+CREATE TABLE check_in_desks(
+ id serial PRIMARY KEY,
+ name varchar(16) UNIQUE NOT NULL,
+ description text
+) WITH OIDS
+ ")
+ return true
+ rescue DBI::ProgrammingError => e
+ return false
+ end
+ end
+end
diff --git a/lib/db_core/models/check_in_desk_flight.rb b/lib/db_core/models/check_in_desk_flight.rb
new file mode 100644
index 0000000..7f0f287
--- /dev/null
+++ b/lib/db_core/models/check_in_desk_flight.rb
@@ -0,0 +1,20 @@
+require 'db_core/models/model'
+
+class CheckInDeskFlight < Model
+ def CheckInDeskFlight.create_table(connection)
+ begin
+ connection.do("
+CREATE TABLE check_id_desk_flights(
+ id serial PRIMARY KEY,
+ flight_id integer REFERENCES flights(id) NOT NULL,
+ check_in_desk_id integer REFERENCES check_in_desks(id) NOT NULL,
+ info text,
+ UNIQUE(flight_id, check_in_desk_id)
+) WITH OIDS
+ ")
+ return true
+ rescue DBI::ProgrammingError => e
+ return false
+ end
+ end
+end
diff --git a/lib/db_core/models/company.rb b/lib/db_core/models/company.rb
new file mode 100644
index 0000000..77f4044
--- /dev/null
+++ b/lib/db_core/models/company.rb
@@ -0,0 +1,35 @@
+require 'db_core/models/model'
+
+class Company < Model
+ def Company.create_table(connection)
+ begin
+ connection.do("
+CREATE TABLE companies(
+ id serial PRIMARY KEY,
+ name text UNIQUE NOT NULL,
+ code varchar(8) UNIQUE NOT NULL,
+ description text
+) WITH OIDS
+ ")
+ return true
+ rescue DBI::ProgrammingError => e
+ return false
+ end
+ end
+
+ def Company.table_name()
+ return 'companies'
+ end
+
+ def initialize(attributes = {})
+ @attributes = {
+ :id => nil,
+ :name => nil,
+ :code => nil,
+ :description => nil
+ }
+ attributes.each do |k, v|
+ @attributes[k] = v
+ end
+ end
+end
diff --git a/lib/db_core/models/flight.rb b/lib/db_core/models/flight.rb
new file mode 100644
index 0000000..675df16
--- /dev/null
+++ b/lib/db_core/models/flight.rb
@@ -0,0 +1,88 @@
+require 'db_core/models/model'
+
+class Flight < Model
+ attr_reader :company
+ attr_writer :company
+
+ def Flight.create_table(connection)
+ begin
+ connection.do("
+CREATE TABLE flights(
+ id serial PRIMARY KEY,
+ code varchar(16) UNIQUE NOT NULL,
+ arrival_date timestamp NOT NULL,
+ departure_date timestamp NOT NULL,
+ arrival_place text NOT NULL,
+ departure_place text NOT NULL,
+ arrival_airport text NOT NULL,
+ departure_airport text NOT NULL,
+ company_id integer REFERENCES companies(id) NOT NULL,
+ is_departure boolean NOT NULL DEFAULT true
+) WITH OIDS
+ ")
+ return true
+ rescue DBI::ProgrammingError => e
+ return false
+ end
+ end
+
+ def initialize(attributes = {})
+ @company = nil
+ @attributes = {
+ :id => nil,
+ :code => nil,
+ :arrival_date => nil,
+ :departure_date => nil,
+ :arrival_place => nil,
+ :departure_place => nil,
+ :arrival_airport => nil,
+ :departure_airport => nil,
+ :company_id => nil,
+ :is_departure => nil
+ }
+ attributes.each do |k, v|
+ @attributes[k.to_sym] = v unless v.nil? or v == ''
+ end
+ end
+
+ def company_name()
+ @company.nil? ? ' ' : @company[:name]
+ end
+
+ def Flight.find_all(connection, departure = nil)
+ query = []
+ res = []
+ if departure.nil?
+ query = ["SELECT * FROM flights
+ ORDER BY departure_place, departure_date"]
+ else
+ query = ["SELECT * FROM flights
+ WHERE is_departure = ?
+ ORDER BY departure_place, departure_date", departure]
+ end
+ connection.select_all(*query) do |r|
+ f = self.new
+ r.column_names.each do |c|
+ f[c.to_sym] = r[c]
+ end
+ f.company = Company.find_first(connection,
+ f[:company_id]) unless f[:company_id].nil?
+ res << f
+ end
+ return res
+ end
+
+ def Flight.find_first(connection, id)
+ id = id.to_i
+ query = ["SELECT * FROM #{table_name()} WHERE id = ?", id]
+ r = connection.select_one(*query)
+ return nil if r.nil?
+ f = self.new
+ r.column_names.each do |c|
+ f[c.to_sym] = r[c]
+ end
+ f.company = Company.find_first(connection,
+ f[:company_id]) unless f[:company_id].nil?
+ return f
+ end
+end
diff --git a/lib/db_core/models/flight_status.rb b/lib/db_core/models/flight_status.rb
new file mode 100644
index 0000000..00a11f5
--- /dev/null
+++ b/lib/db_core/models/flight_status.rb
@@ -0,0 +1,22 @@
+require 'db_core/models/model'
+
+class FlightStatus < Model
+ STATUSES = {0 => 'отменен', 1 => 'задержан', 2 => 'вылетел', 3 => 'сел'}
+
+ def FlightStatus.create_table(connection)
+ begin
+ connection.do("
+CREATE TABLE flight_statuses(
+ id serial PRIMARY KEY,
+ flight_id integer REFERENCES flights(id) NOT NULL,
+ status_id integer NOT NULL CONSTRAINT status_id_ck CHECK(status_id in(0, 1, 2, 3)),
+ event_date timestamp NOT NULL,
+ UNIQUE(flight_id, event_date)
+) WITH OIDS
+ ")
+ return true
+ rescue DBI::ProgrammingError => e
+ return false
+ end
+ end
+end
diff --git a/lib/db_core/models/flight_terminal.rb b/lib/db_core/models/flight_terminal.rb
new file mode 100644
index 0000000..23d2394
--- /dev/null
+++ b/lib/db_core/models/flight_terminal.rb
@@ -0,0 +1,20 @@
+require 'db_core/models/model'
+
+class FlightTerminal < Model
+ def FlightTerminal.create_table(connection)
+ begin
+ connection.do("
+CREATE TABLE flight_terminals(
+ id serial PRIMARY KEY,
+ flight_id integer REFERENCES flights(id) NOT NULL,
+ terminal_id integer REFERENCES terminals(id) NOT NULL,
+ info text,
+ UNIQUE(flight_id, terminal_id)
+) WITH OIDS
+ ")
+ return true
+ rescue DBI::ProgrammingError => e
+ return false
+ end
+ end
+end
diff --git a/lib/db_core/models/model.rb b/lib/db_core/models/model.rb
new file mode 100644
index 0000000..bd510b2
--- /dev/null
+++ b/lib/db_core/models/model.rb
@@ -0,0 +1,94 @@
+class Model
+ # Описывает какие поля не надо преобразовывать в NULL
+ def Model.not_needs_to_set_null()
+ []
+ end
+
+ # Метод, создающий в БД таблицу, описывающую модель
+ def Model.create_table(connection)
+ return false
+ end
+
+ # Имя таблицы, описывающей модель
+ def table_name()
+ self.class.table_name()
+ end
+
+ # См. table_name()
+ def Model.table_name()
+ self.to_s.gsub(/(\W)/, '_\1').downcase + 's'
+ end
+
+ # Конструктор
+ def initialize(attributes = {})
+ @attributes = {}
+ end
+
+ # Позволяет обращаться к полям объекта, минуя @attributes
+ def [](name)
+ @attributes[name.to_sym]
+ end
+
+ # Позволяет присваивать полям объекта значения, минуя @attributes
+ def []=(name, value)
+ if value == '' and !Model.not_needs_to_set_null().include?(name.to_sym)
+ value = nil
+ end
+ @attributes[name.to_sym] = value
+ end
+
+ # Синхронизирует объет с БД
+ def save(connection)
+ query = ''
+ params = []
+ if self[:id].nil?
+ query = "INSERT INTO #{self.table_name()}(" +
+ (@attributes.keys - [:id]).join(', ') + ') VALUES(' +
+ (@attributes.keys - [:id]).map{ |k| '?' }.join(', ') + ') RETURNING id'
+ params = (@attributes.keys - [:id]).map{ |k| self[k] }
+ else
+ query = "UPDATE #{self.table_name()} SET " +
+ (@attributes.keys - [:id]).map{ |k| "#{k} = ?" }.join(', ') +
+ ' WHERE id = ? RETURNING id'
+ params = (@attributes.keys - [:id]).map{ |k| self[k] } << self[:id]
+ end
+ rs = connection.select_one(query, *params)
+ self[:id] = rs[0].to_i
+ end
+
+ # Достает из БД все объекты данного вида
+ def Model.find_all(connection)
+ query = []
+ res = []
+ query = ["SELECT * FROM #{table_name()}"]
+ connection.select_all(*query) do |r|
+ o = self.new
+ r.column_names.each do |c|
+ o[c.to_sym] = r[c]
+ end
+ res << o
+ end
+ return res
+ end
+
+ # Достает из БД объект по его id
+ def Model.find_first(connection, id)
+ id = id.to_i
+ query = ["SELECT * FROM #{table_name()} WHERE id = ?", id]
+ r = connection.select_one(*query)
+ return nil if r.nil?
+ o = self.new
+ r.column_names.each do |c|
+ o[c.to_sym] = r[c]
+ end
+ return o
+ end
+
+ # Удаляет объект в БД
+
+ def destroy(connection)
+ unless self[:id].nil?
+ connection.do("DELETE FROM #{table_name()} WHERE id = ?", self[:id])
+ end
+ end
+end
diff --git a/lib/db_core/models/terminal.rb b/lib/db_core/models/terminal.rb
new file mode 100644
index 0000000..b5e5ecf
--- /dev/null
+++ b/lib/db_core/models/terminal.rb
@@ -0,0 +1,19 @@
+require 'db_core/models/model'
+
+class Terminal < Model
+ def Terminal.create_table(connection)
+ begin
+ connection.do("
+CREATE TABLE terminals(
+ id serial PRIMARY KEY,
+ name varchar(8) UNIQUE NOT NULL,
+ description text,
+ needs_bus boolean NOT NULL DEFAULT false
+) WITH OIDS
+ ")
+ return true
+ rescue DBI::ProgrammingError => e
+ return false
+ end
+ end
+end
diff --git a/lib/db_core/models/user.rb b/lib/db_core/models/user.rb
new file mode 100644
index 0000000..12ba6a7
--- /dev/null
+++ b/lib/db_core/models/user.rb
@@ -0,0 +1,34 @@
+# To change this template, choose Tools | Templates
+# and open the template in the editor.
+
+class User < Model
+ def User.create_table(connection)
+ begin
+ connection.do("
+CREATE TABLE users(
+ id serial PRIMARY KEY,
+ login varchar(16) UNIQUE NOT NULL,
+ password varchar(16) NOT NULL,
+ info text
+) WITH OIDS
+ ")
+ return true
+ rescue DBI::ProgrammingError => e
+ return false
+ end
+ end
+
+ def User.check_user(connection, login, password)
+ id = connection.select_one("
+SELECT id FROM users WHERE login = ? and password = ?
+ ", login, password)
+ return (id.size > 0)
+ end
+
+ def User.create_admin(connection)
+ connection.do("
+INSERT INTO users(login, password, info)
+ VALUES('admin', 'qwerty', 'Администратор системы')
+ ")
+ end
+end
diff --git a/lib/stylesheets/aero.css b/lib/stylesheets/aero.css
new file mode 100644
index 0000000..6030846
--- /dev/null
+++ b/lib/stylesheets/aero.css
@@ -0,0 +1,96 @@
+table.layout {
+ border: none;
+ width: 800px;
+}
+
+table.layout thead tr th {
+ background-color: #BBDDFF;
+ color: Blue;
+ padding: 5px 5px 5px 5px;
+ text-align: center;
+ vertical-align: middle;
+ border-bottom: 1px Solid Blue;
+ font-size: x-large;
+}
+
+table.layout tbody tr th {
+ background-color: #BBDDFF;
+ color: Blue;
+ padding: 5px 5px 5px 5px;
+ text-align: left;
+ vertical-align: top;
+ border-right: 1px Solid Blue;
+ width: 200px;
+}
+
+table.layout tbody tr th ul{
+ padding: 6px;
+ list-style-type: none;
+}
+
+table.layout tbody tr th ul li{
+ background-color: #EEFFFF;
+ padding: 5px 5px 5px 5px;
+ width: 180px;
+ margin: 5px 5px 5px 5px;
+ border: 1px Solid #8888FF;
+}
+
+table.layout tbody tr th ul li a:link, table.layout tbody tr th ul li a:visited{
+ text-decoration: none;
+ color: #2200FF;
+ font-weight: normal;
+}
+
+table.layout tbody tr th ul li a:hover, table.layout tbody tr th ul li a:active{
+ text-decoration: none;
+ color: #557788;
+ font-weight: normal;
+}
+
+table.layout tbody tr td {
+ padding: 10px 10px 10px 10px;
+ text-align: center;
+ vertical-align: middle;
+}
+
+table.list{
+ margin-left: auto;
+ margin-right: auto;
+ border: 1px Solid Blue;
+}
+
+table.list thead tr{
+ background-color: #BBDDFF;
+}
+
+table.list thead tr th{
+ border: none;
+ text-align: center;
+ vertical-align: middle;
+ font-size: medium;
+}
+
+table.list tbody tr th{
+ text-align: left;
+ vertical-align: middle;
+ font-size: medium;
+}
+
+table.list tfoot tr th{
+ border-width: 1px 0px 0px 0px;
+ border-style: solid none none none;
+ border-color: Blue;
+ text-align: center;
+ vertical-align: middle;
+ font-size: medium;
+ background-color: white;
+}
+
+table.list tbody tr.list1{
+ background-color: #EEEEFF;
+}
+
+table.list tbody tr.list0{
+ background-color: #DDDDFF;
+}
diff --git a/lib/templates/auth/login.rb b/lib/templates/auth/login.rb
new file mode 100644
index 0000000..071057a
--- /dev/null
+++ b/lib/templates/auth/login.rb
@@ -0,0 +1,27 @@
+"
+
+"
diff --git a/lib/templates/auth/logout.rb b/lib/templates/auth/logout.rb
new file mode 100644
index 0000000..b0e321a
--- /dev/null
+++ b/lib/templates/auth/logout.rb
@@ -0,0 +1,3 @@
+"
+
Выход осуществлен!
+"
\ No newline at end of file
diff --git a/lib/templates/flights/destroy.rb b/lib/templates/flights/destroy.rb
new file mode 100644
index 0000000..94fcd9f
--- /dev/null
+++ b/lib/templates/flights/destroy.rb
@@ -0,0 +1,4 @@
+"
+
+"
\ No newline at end of file
diff --git a/lib/templates/flights/edit.rb b/lib/templates/flights/edit.rb
new file mode 100644
index 0000000..b133d32
--- /dev/null
+++ b/lib/templates/flights/edit.rb
@@ -0,0 +1,65 @@
+"
+