diff --git a/.gitignore b/.gitignore new file mode 100644 index 000000000000..f2df68e3d16d --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +__pycache__/ +versions/*.tgz diff --git a/0-setup_web_static.sh b/0-setup_web_static.sh new file mode 100755 index 000000000000..55573561edb0 --- /dev/null +++ b/0-setup_web_static.sh @@ -0,0 +1,31 @@ +#!/usr/bin/env bash +# Set up web servers for the deployment of web_static + +if ! command -v nginx > /dev/null 2>&1; then + sudo apt-get update + sudo apt-get install -y nginx +fi + +sudo mkdir -p /data/ +sudo mkdir -p /data/web_static/ +sudo mkdir -p /data/web_static/releases/ +sudo mkdir -p /data/web_static/shared/ +sudo mkdir -p /data/web_static/releases/test/ +echo "hello fab!" > /data/web_static/releases/test/index.html + +Target="/data/web_static/releases/test/" +Sym_link="/data/web_static/current" + +if [ -L "$Sym_link" ]; then + sudo rm "$Sym_link" +fi + +sudo ln -s "$Target" "$Sym_link" + +sudo chown -R ubuntu:ubuntu /data + +sudo sed -i "51i\ \tlocation /hbnb_static{\n \ +\t\talias /data/web_static/current/;\n\ +\t}" /etc/nginx/sites-enabled/default + +sudo service nginx restart diff --git a/1-pack_web_static.py b/1-pack_web_static.py new file mode 100755 index 000000000000..d285e1948e4c --- /dev/null +++ b/1-pack_web_static.py @@ -0,0 +1,25 @@ +#!/usr/bin/python3 +""" Fabric script that generates a .tgz archive +""" +import os +from fabric.api import local +import datetime + + +def do_pack(): + """ function to create .tgz archive """ + + time_stamp = datetime.datetime.now().strftime("%Y%m%d%H%M%S") + if not os.path.exists('./versions'): + os.mkdir('./versions') + archive_name = "web_static_" + time_stamp + res = local("tar -czf versions/{}.tgz web_static".format(archive_name)) + print("Packing web_static to versions/{}.tgz".format(archive_name)) + if res.succeeded: + size = os.path.getsize("versions/{}.tgz".format(archive_name)) + print("web_static packed: versions/{}.tgz -> {}Bytes".format( + archive_name, size)) + full_path = "versions/{}.tgz".format(archive_name) + return full_path + else: + return None diff --git a/2-do_deploy_web_static.py b/2-do_deploy_web_static.py new file mode 100755 index 000000000000..7c06afb44813 --- /dev/null +++ b/2-do_deploy_web_static.py @@ -0,0 +1,34 @@ +#!/usr/bin/python3 +""" Fabric script that generates a .tgz archive +from the contents of the web_static +""" +import os +from fabric.api import env, run, put, sudo +import datetime + +env.hosts = ['100.26.152.53', '35.174.208.133'] + + +def do_deploy(archive_path): + """ function to deploy archive """ + if archive_path: + a_name = os.path.basename(archive_path) + a_folder_name = a_name.split('.')[0] + path = "/data/web_static/releases/" + + put(archive_path, "/tmp") + # Uncompress the archive + run("mkdir -p /data/web_static/releases/{}".format(a_folder_name)) + run("tar -xzf /tmp/{} -C /data/web_static/releases/{}".format( + a_name, a_folder_name)) + run("rm /tmp/{}".format(a_name)) + run("mv {0}{1}/web_static/* {0}{1}".format(path, a_folder_name)) + run("rm -rf /data/web_static/releases/{}/web_static".format( + a_folder_name)) + run("rm /data/web_static/current") + + run("ln -s {0}{1}/ /data/web_static/current".format( + path, a_folder_name)) + return True + else: + return False diff --git a/3-deploy_web_static.py b/3-deploy_web_static.py new file mode 100755 index 000000000000..eb929dc2a775 --- /dev/null +++ b/3-deploy_web_static.py @@ -0,0 +1,62 @@ +#!/usr/bin/python3 +""" Fabric script that creates and distributes an archive +to web servers +""" +import os +from fabric.api import local, env, put, sudo, runs_once, run +import datetime + +env.hosts = ['100.26.152.53', '35.174.208.133'] + +@runs_once +def do_pack(): + """ function to create .tgz archive """ + + time_stamp = datetime.datetime.now().strftime("%Y%m%d%H%M%S") + if not os.path.exists('./versions'): + os.mkdir('./versions') + archive_name = "web_static_" + time_stamp + res = local("tar -czf versions/{}.tgz web_static".format(archive_name)) + print("Packing web_static to versions/{}.tgz".format(archive_name)) + if res.succeeded: + size = os.path.getsize("versions/{}.tgz".format(archive_name)) + print("web_static packed: versions/{}.tgz -> {}Bytes".format( + archive_name, size)) + full_path = "versions/{}.tgz".format(archive_name) + return full_path + else: + return None + + +def do_deploy(archive_path): + """ function to deploy archive """ + if archive_path: + a_name = os.path.basename(archive_path) + a_folder_name = a_name.split('.')[0] + path = "/data/web_static/releases/" + + put(archive_path, "/tmp") + # Uncompress the archive + run("mkdir -p /data/web_static/releases/{}".format(a_folder_name)) + run("tar -xzf /tmp/{} -C /data/web_static/releases/{}".format( + a_name, a_folder_name)) + run("rm /tmp/{}".format(a_name)) + run("mv {0}{1}/web_static/* {0}{1}".format(path, a_folder_name)) + run("rm -rf /data/web_static/releases/{}/web_static".format( + a_folder_name)) + run("rm /data/web_static/current") + + run("ln -s {0}{1}/ /data/web_static/current".format( + path, a_folder_name)) + return True + else: + return False + + +def deploy(): + """ function handle full deployment """ + path = do_pack() + if path is not None: + result = do_deploy(path) + return result + return False diff --git a/7-dump.sql b/7-dump.sql new file mode 100644 index 000000000000..4187e014887b --- /dev/null +++ b/7-dump.sql @@ -0,0 +1,95 @@ +-- MySQL dump 10.13 Distrib 5.7.8-rc, for Linux (x86_64) +-- +-- Host: localhost Database: hbnb_dev_db +-- ------------------------------------------------------ +-- Server version 5.7.8-rc + +/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; +/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; +/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */; +/*!40101 SET NAMES utf8 */; +/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */; +/*!40103 SET TIME_ZONE='+00:00' */; +/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */; +/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */; +/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */; +/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; + +-- Drop database +DROP DATABASE IF EXISTS hbnb_dev_db; + +-- Create database + user if doesn't exist +CREATE DATABASE IF NOT EXISTS hbnb_dev_db; +CREATE USER IF NOT EXISTS 'hbnb_dev'@'localhost'; +SET PASSWORD FOR 'hbnb_dev'@'localhost' = 'hbnb_dev_pwd'; +GRANT ALL ON hbnb_dev_db.* TO 'hbnb_dev'@'localhost'; +GRANT SELECT ON performance_schema.* TO 'hbnb_dev'@'localhost'; +FLUSH PRIVILEGES; + +USE hbnb_dev_db; + +-- +-- Table structure for table `cities` +-- + +DROP TABLE IF EXISTS `cities`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `cities` ( + `id` varchar(60) NOT NULL, + `created_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + `updated_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + `name` varchar(128) NOT NULL, + `state_id` varchar(60) NOT NULL, + PRIMARY KEY (`id`), + KEY `state_id` (`state_id`), + CONSTRAINT `cities_ibfk_1` FOREIGN KEY (`state_id`) REFERENCES `states` (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `cities` +-- + +LOCK TABLES `cities` WRITE; +/*!40000 ALTER TABLE `cities` DISABLE KEYS */; +INSERT INTO `cities` VALUES ('521a55f4-7d82-47d9-b54c-a76916479545','2017-03-25 19:42:40','2017-03-25 19:42:40','Akron','421a55f4-7d82-47d9-b54c-a76916479545'),('521a55f4-7d82-47d9-b54c-a76916479546','2017-03-25 19:42:40','2017-03-25 19:42:40','Douglas','421a55f4-7d82-47d9-b54c-a76916479546'),('521a55f4-7d82-47d9-b54c-a76916479547','2017-03-25 19:42:40','2017-03-25 19:42:40','San Francisco','421a55f4-7d82-47d9-b54c-a76916479547'),('521a55f4-7d82-47d9-b54c-a76916479548','2017-03-25 19:42:41','2017-03-25 19:42:41','Denver','421a55f4-7d82-47d9-b54c-a76916479548'),('521a55f4-7d82-47d9-b54c-a76916479549','2017-03-25 19:42:41','2017-03-25 19:42:41','Miami','421a55f4-7d82-47d9-b54c-a76916479549'),('521a55f4-7d82-47d9-b54c-a76916479551','2017-03-25 19:42:41','2017-03-25 19:42:41','Honolulu','421a55f4-7d82-47d9-b54c-a76916479551'),('521a55f4-7d82-47d9-b54c-a76916479552','2017-03-25 19:42:41','2017-03-25 19:42:41','Chicago','421a55f4-7d82-47d9-b54c-a76916479552'),('521a55f4-7d82-47d9-b54c-a76916479554','2017-03-25 19:42:41','2017-03-25 19:42:41','New Orleans','421a55f4-7d82-47d9-b54c-a76916479554'),('521a55f4-7d82-47d9-b54c-a76916479555','2017-03-25 19:42:41','2017-03-25 19:42:41','Saint Paul','421a55f4-7d82-47d9-b54c-a76916479555'),('521a55f4-7d82-47d9-b54c-a76916479556','2017-03-25 19:42:41','2017-03-25 19:42:41','Jackson','421a55f4-7d82-47d9-b54c-a76916479556'),('521a55f4-7d82-47d9-b54c-a76916479557','2017-03-25 19:42:41','2017-03-25 19:42:41','Portland','421a55f4-7d82-47d9-b54c-a76916479557'),('531a55f4-7d82-47d9-b54c-a76916479545','2017-03-25 19:42:40','2017-03-25 19:42:40','Babbie','421a55f4-7d82-47d9-b54c-a76916479545'),('531a55f4-7d82-47d9-b54c-a76916479546','2017-03-25 19:42:40','2017-03-25 19:42:40','Kearny','421a55f4-7d82-47d9-b54c-a76916479546'),('531a55f4-7d82-47d9-b54c-a76916479547','2017-03-25 19:42:40','2017-03-25 19:42:40','San Jose','421a55f4-7d82-47d9-b54c-a76916479547'),('531a55f4-7d82-47d9-b54c-a76916479549','2017-03-25 19:42:41','2017-03-25 19:42:41','Orlando','421a55f4-7d82-47d9-b54c-a76916479549'),('531a55f4-7d82-47d9-b54c-a76916479551','2017-03-25 19:42:41','2017-03-25 19:42:41','Kailua','421a55f4-7d82-47d9-b54c-a76916479551'),('531a55f4-7d82-47d9-b54c-a76916479552','2017-03-25 19:42:41','2017-03-25 19:42:41','Peoria','421a55f4-7d82-47d9-b54c-a76916479552'),('531a55f4-7d82-47d9-b54c-a76916479554','2017-03-25 19:42:41','2017-03-25 19:42:41','Baton rouge','421a55f4-7d82-47d9-b54c-a76916479554'),('531a55f4-7d82-47d9-b54c-a76916479556','2017-03-25 19:42:41','2017-03-25 19:42:41','Tupelo','421a55f4-7d82-47d9-b54c-a76916479556'),('531a55f4-7d82-47d9-b54c-a76916479557','2017-03-25 19:42:41','2017-03-25 19:42:41','Eugene','421a55f4-7d82-47d9-b54c-a76916479557'),('541a55f4-7d82-47d9-b54c-a76916479545','2017-03-25 19:42:40','2017-03-25 19:42:40','Calera','421a55f4-7d82-47d9-b54c-a76916479545'),('541a55f4-7d82-47d9-b54c-a76916479546','2017-03-25 19:42:40','2017-03-25 19:42:40','Tempe','421a55f4-7d82-47d9-b54c-a76916479546'),('541a55f4-7d82-47d9-b54c-a76916479547','2017-03-25 19:42:40','2017-03-25 19:42:40','Fremont','421a55f4-7d82-47d9-b54c-a76916479547'),('541a55f4-7d82-47d9-b54c-a76916479551','2017-03-25 19:42:41','2017-03-25 19:42:41','Pearl city','421a55f4-7d82-47d9-b54c-a76916479551'),('541a55f4-7d82-47d9-b54c-a76916479552','2017-03-25 19:42:41','2017-03-25 19:42:41','Naperville','421a55f4-7d82-47d9-b54c-a76916479552'),('541a55f4-7d82-47d9-b54c-a76916479554','2017-03-25 19:42:41','2017-03-25 19:42:41','Lafayette','421a55f4-7d82-47d9-b54c-a76916479554'),('541a55f4-7d82-47d9-b54c-a76916479556','2017-03-25 19:42:41','2017-03-25 19:42:41','Meridian','421a55f4-7d82-47d9-b54c-a76916479556'),('551a55f4-7d82-47d9-b54c-a76916479545','2017-03-25 19:42:40','2017-03-25 19:42:40','Fairfield','421a55f4-7d82-47d9-b54c-a76916479545'),('551a55f4-7d82-47d9-b54c-a76916479547','2017-03-25 19:42:40','2017-03-25 19:42:40','Napa','421a55f4-7d82-47d9-b54c-a76916479547'),('551a55f4-7d82-47d9-b54c-a76916479552','2017-03-25 19:42:41','2017-03-25 19:42:41','Urbana','421a55f4-7d82-47d9-b54c-a76916479552'),('561a55f4-7d82-47d9-b54c-a76916479547','2017-03-25 19:42:40','2017-03-25 19:42:40','Sonoma','421a55f4-7d82-47d9-b54c-a76916479547'),('561a55f4-7d82-47d9-b54c-a76916479552','2017-03-25 19:42:41','2017-03-25 19:42:41','Joliet','421a55f4-7d82-47d9-b54c-a76916479552'); +/*!40000 ALTER TABLE `cities` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `states` +-- + +DROP TABLE IF EXISTS `states`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `states` ( + `id` varchar(60) NOT NULL, + `created_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + `updated_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + `name` varchar(128) NOT NULL, + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `states` +-- + +LOCK TABLES `states` WRITE; +/*!40000 ALTER TABLE `states` DISABLE KEYS */; +INSERT INTO `states` VALUES ('421a55f4-7d82-47d9-b54c-a76916479545','2017-03-25 19:42:40','2017-03-25 19:42:40','Alabama'),('421a55f4-7d82-47d9-b54c-a76916479546','2017-03-25 19:42:40','2017-03-25 19:42:40','Arizona'),('421a55f4-7d82-47d9-b54c-a76916479547','2017-03-25 19:42:40','2017-03-25 19:42:40','California'),('421a55f4-7d82-47d9-b54c-a76916479548','2017-03-25 19:42:40','2017-03-25 19:42:40','Colorado'),('421a55f4-7d82-47d9-b54c-a76916479549','2017-03-25 19:42:40','2017-03-25 19:42:40','Florida'),('421a55f4-7d82-47d9-b54c-a76916479550','2017-03-25 19:42:40','2017-03-25 19:42:40','Georgia'),('421a55f4-7d82-47d9-b54c-a76916479551','2017-03-25 19:42:40','2017-03-25 19:42:40','Hawaii'),('421a55f4-7d82-47d9-b54c-a76916479552','2017-03-25 19:42:40','2017-03-25 19:42:40','Illinois'),('421a55f4-7d82-47d9-b54c-a76916479553','2017-03-25 19:42:40','2017-03-25 19:42:40','Indiana'),('421a55f4-7d82-47d9-b54c-a76916479554','2017-03-25 19:42:40','2017-03-25 19:42:40','Louisiana'),('421a55f4-7d82-47d9-b54c-a76916479555','2017-03-25 19:42:40','2017-03-25 19:42:40','Minnesota'),('421a55f4-7d82-47d9-b54c-a76916479556','2017-03-25 19:42:40','2017-03-25 19:42:40','Mississippi'),('421a55f4-7d82-47d9-b54c-a76916479557','2017-03-25 19:42:40','2017-03-25 19:42:40','Oregon'); +/*!40000 ALTER TABLE `states` ENABLE KEYS */; +UNLOCK TABLES; +/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */; + +/*!40101 SET SQL_MODE=@OLD_SQL_MODE */; +/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */; +/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */; +/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */; +/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */; +/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; +/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; + +-- Dump completed on 2017-03-25 19:42:51 diff --git a/7-states_list.sql b/7-states_list.sql new file mode 100644 index 000000000000..4187e014887b --- /dev/null +++ b/7-states_list.sql @@ -0,0 +1,95 @@ +-- MySQL dump 10.13 Distrib 5.7.8-rc, for Linux (x86_64) +-- +-- Host: localhost Database: hbnb_dev_db +-- ------------------------------------------------------ +-- Server version 5.7.8-rc + +/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; +/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; +/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */; +/*!40101 SET NAMES utf8 */; +/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */; +/*!40103 SET TIME_ZONE='+00:00' */; +/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */; +/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */; +/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */; +/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; + +-- Drop database +DROP DATABASE IF EXISTS hbnb_dev_db; + +-- Create database + user if doesn't exist +CREATE DATABASE IF NOT EXISTS hbnb_dev_db; +CREATE USER IF NOT EXISTS 'hbnb_dev'@'localhost'; +SET PASSWORD FOR 'hbnb_dev'@'localhost' = 'hbnb_dev_pwd'; +GRANT ALL ON hbnb_dev_db.* TO 'hbnb_dev'@'localhost'; +GRANT SELECT ON performance_schema.* TO 'hbnb_dev'@'localhost'; +FLUSH PRIVILEGES; + +USE hbnb_dev_db; + +-- +-- Table structure for table `cities` +-- + +DROP TABLE IF EXISTS `cities`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `cities` ( + `id` varchar(60) NOT NULL, + `created_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + `updated_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + `name` varchar(128) NOT NULL, + `state_id` varchar(60) NOT NULL, + PRIMARY KEY (`id`), + KEY `state_id` (`state_id`), + CONSTRAINT `cities_ibfk_1` FOREIGN KEY (`state_id`) REFERENCES `states` (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `cities` +-- + +LOCK TABLES `cities` WRITE; +/*!40000 ALTER TABLE `cities` DISABLE KEYS */; +INSERT INTO `cities` VALUES ('521a55f4-7d82-47d9-b54c-a76916479545','2017-03-25 19:42:40','2017-03-25 19:42:40','Akron','421a55f4-7d82-47d9-b54c-a76916479545'),('521a55f4-7d82-47d9-b54c-a76916479546','2017-03-25 19:42:40','2017-03-25 19:42:40','Douglas','421a55f4-7d82-47d9-b54c-a76916479546'),('521a55f4-7d82-47d9-b54c-a76916479547','2017-03-25 19:42:40','2017-03-25 19:42:40','San Francisco','421a55f4-7d82-47d9-b54c-a76916479547'),('521a55f4-7d82-47d9-b54c-a76916479548','2017-03-25 19:42:41','2017-03-25 19:42:41','Denver','421a55f4-7d82-47d9-b54c-a76916479548'),('521a55f4-7d82-47d9-b54c-a76916479549','2017-03-25 19:42:41','2017-03-25 19:42:41','Miami','421a55f4-7d82-47d9-b54c-a76916479549'),('521a55f4-7d82-47d9-b54c-a76916479551','2017-03-25 19:42:41','2017-03-25 19:42:41','Honolulu','421a55f4-7d82-47d9-b54c-a76916479551'),('521a55f4-7d82-47d9-b54c-a76916479552','2017-03-25 19:42:41','2017-03-25 19:42:41','Chicago','421a55f4-7d82-47d9-b54c-a76916479552'),('521a55f4-7d82-47d9-b54c-a76916479554','2017-03-25 19:42:41','2017-03-25 19:42:41','New Orleans','421a55f4-7d82-47d9-b54c-a76916479554'),('521a55f4-7d82-47d9-b54c-a76916479555','2017-03-25 19:42:41','2017-03-25 19:42:41','Saint Paul','421a55f4-7d82-47d9-b54c-a76916479555'),('521a55f4-7d82-47d9-b54c-a76916479556','2017-03-25 19:42:41','2017-03-25 19:42:41','Jackson','421a55f4-7d82-47d9-b54c-a76916479556'),('521a55f4-7d82-47d9-b54c-a76916479557','2017-03-25 19:42:41','2017-03-25 19:42:41','Portland','421a55f4-7d82-47d9-b54c-a76916479557'),('531a55f4-7d82-47d9-b54c-a76916479545','2017-03-25 19:42:40','2017-03-25 19:42:40','Babbie','421a55f4-7d82-47d9-b54c-a76916479545'),('531a55f4-7d82-47d9-b54c-a76916479546','2017-03-25 19:42:40','2017-03-25 19:42:40','Kearny','421a55f4-7d82-47d9-b54c-a76916479546'),('531a55f4-7d82-47d9-b54c-a76916479547','2017-03-25 19:42:40','2017-03-25 19:42:40','San Jose','421a55f4-7d82-47d9-b54c-a76916479547'),('531a55f4-7d82-47d9-b54c-a76916479549','2017-03-25 19:42:41','2017-03-25 19:42:41','Orlando','421a55f4-7d82-47d9-b54c-a76916479549'),('531a55f4-7d82-47d9-b54c-a76916479551','2017-03-25 19:42:41','2017-03-25 19:42:41','Kailua','421a55f4-7d82-47d9-b54c-a76916479551'),('531a55f4-7d82-47d9-b54c-a76916479552','2017-03-25 19:42:41','2017-03-25 19:42:41','Peoria','421a55f4-7d82-47d9-b54c-a76916479552'),('531a55f4-7d82-47d9-b54c-a76916479554','2017-03-25 19:42:41','2017-03-25 19:42:41','Baton rouge','421a55f4-7d82-47d9-b54c-a76916479554'),('531a55f4-7d82-47d9-b54c-a76916479556','2017-03-25 19:42:41','2017-03-25 19:42:41','Tupelo','421a55f4-7d82-47d9-b54c-a76916479556'),('531a55f4-7d82-47d9-b54c-a76916479557','2017-03-25 19:42:41','2017-03-25 19:42:41','Eugene','421a55f4-7d82-47d9-b54c-a76916479557'),('541a55f4-7d82-47d9-b54c-a76916479545','2017-03-25 19:42:40','2017-03-25 19:42:40','Calera','421a55f4-7d82-47d9-b54c-a76916479545'),('541a55f4-7d82-47d9-b54c-a76916479546','2017-03-25 19:42:40','2017-03-25 19:42:40','Tempe','421a55f4-7d82-47d9-b54c-a76916479546'),('541a55f4-7d82-47d9-b54c-a76916479547','2017-03-25 19:42:40','2017-03-25 19:42:40','Fremont','421a55f4-7d82-47d9-b54c-a76916479547'),('541a55f4-7d82-47d9-b54c-a76916479551','2017-03-25 19:42:41','2017-03-25 19:42:41','Pearl city','421a55f4-7d82-47d9-b54c-a76916479551'),('541a55f4-7d82-47d9-b54c-a76916479552','2017-03-25 19:42:41','2017-03-25 19:42:41','Naperville','421a55f4-7d82-47d9-b54c-a76916479552'),('541a55f4-7d82-47d9-b54c-a76916479554','2017-03-25 19:42:41','2017-03-25 19:42:41','Lafayette','421a55f4-7d82-47d9-b54c-a76916479554'),('541a55f4-7d82-47d9-b54c-a76916479556','2017-03-25 19:42:41','2017-03-25 19:42:41','Meridian','421a55f4-7d82-47d9-b54c-a76916479556'),('551a55f4-7d82-47d9-b54c-a76916479545','2017-03-25 19:42:40','2017-03-25 19:42:40','Fairfield','421a55f4-7d82-47d9-b54c-a76916479545'),('551a55f4-7d82-47d9-b54c-a76916479547','2017-03-25 19:42:40','2017-03-25 19:42:40','Napa','421a55f4-7d82-47d9-b54c-a76916479547'),('551a55f4-7d82-47d9-b54c-a76916479552','2017-03-25 19:42:41','2017-03-25 19:42:41','Urbana','421a55f4-7d82-47d9-b54c-a76916479552'),('561a55f4-7d82-47d9-b54c-a76916479547','2017-03-25 19:42:40','2017-03-25 19:42:40','Sonoma','421a55f4-7d82-47d9-b54c-a76916479547'),('561a55f4-7d82-47d9-b54c-a76916479552','2017-03-25 19:42:41','2017-03-25 19:42:41','Joliet','421a55f4-7d82-47d9-b54c-a76916479552'); +/*!40000 ALTER TABLE `cities` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `states` +-- + +DROP TABLE IF EXISTS `states`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `states` ( + `id` varchar(60) NOT NULL, + `created_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + `updated_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + `name` varchar(128) NOT NULL, + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `states` +-- + +LOCK TABLES `states` WRITE; +/*!40000 ALTER TABLE `states` DISABLE KEYS */; +INSERT INTO `states` VALUES ('421a55f4-7d82-47d9-b54c-a76916479545','2017-03-25 19:42:40','2017-03-25 19:42:40','Alabama'),('421a55f4-7d82-47d9-b54c-a76916479546','2017-03-25 19:42:40','2017-03-25 19:42:40','Arizona'),('421a55f4-7d82-47d9-b54c-a76916479547','2017-03-25 19:42:40','2017-03-25 19:42:40','California'),('421a55f4-7d82-47d9-b54c-a76916479548','2017-03-25 19:42:40','2017-03-25 19:42:40','Colorado'),('421a55f4-7d82-47d9-b54c-a76916479549','2017-03-25 19:42:40','2017-03-25 19:42:40','Florida'),('421a55f4-7d82-47d9-b54c-a76916479550','2017-03-25 19:42:40','2017-03-25 19:42:40','Georgia'),('421a55f4-7d82-47d9-b54c-a76916479551','2017-03-25 19:42:40','2017-03-25 19:42:40','Hawaii'),('421a55f4-7d82-47d9-b54c-a76916479552','2017-03-25 19:42:40','2017-03-25 19:42:40','Illinois'),('421a55f4-7d82-47d9-b54c-a76916479553','2017-03-25 19:42:40','2017-03-25 19:42:40','Indiana'),('421a55f4-7d82-47d9-b54c-a76916479554','2017-03-25 19:42:40','2017-03-25 19:42:40','Louisiana'),('421a55f4-7d82-47d9-b54c-a76916479555','2017-03-25 19:42:40','2017-03-25 19:42:40','Minnesota'),('421a55f4-7d82-47d9-b54c-a76916479556','2017-03-25 19:42:40','2017-03-25 19:42:40','Mississippi'),('421a55f4-7d82-47d9-b54c-a76916479557','2017-03-25 19:42:40','2017-03-25 19:42:40','Oregon'); +/*!40000 ALTER TABLE `states` ENABLE KEYS */; +UNLOCK TABLES; +/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */; + +/*!40101 SET SQL_MODE=@OLD_SQL_MODE */; +/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */; +/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */; +/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */; +/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */; +/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; +/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; + +-- Dump completed on 2017-03-25 19:42:51 diff --git a/AUTHORS b/AUTHORS index 6fb53b5277cf..7caa80837b2c 100644 --- a/AUTHORS +++ b/AUTHORS @@ -2,3 +2,4 @@ Ezra Nobrega Justin Majetich +Ayebidun Ezekiel , diff --git a/__init__.py b/__init__.py new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/__pycache__/1-pack_web_static.cpython-35.pyc b/__pycache__/1-pack_web_static.cpython-35.pyc new file mode 100644 index 000000000000..41a0a53769fd Binary files /dev/null and b/__pycache__/1-pack_web_static.cpython-35.pyc differ diff --git a/__pycache__/2-do_deploy_web_static.cpython-35.pyc b/__pycache__/2-do_deploy_web_static.cpython-35.pyc new file mode 100644 index 000000000000..d8b7fc6fdf74 Binary files /dev/null and b/__pycache__/2-do_deploy_web_static.cpython-35.pyc differ diff --git a/__pycache__/3-deploy_web_static.cpython-35.pyc b/__pycache__/3-deploy_web_static.cpython-35.pyc new file mode 100644 index 000000000000..aaedb8a2322e Binary files /dev/null and b/__pycache__/3-deploy_web_static.cpython-35.pyc differ diff --git a/console.py b/console.py index 13a8af68e930..17cdb3bdc0de 100755 --- a/console.py +++ b/console.py @@ -2,6 +2,7 @@ """ Console Module """ import cmd import sys +import datetime from models.base_model import BaseModel from models.__init__ import storage from models.user import User @@ -73,7 +74,7 @@ def precmd(self, line): pline = pline[2].strip() # pline is now str if pline: # check for *args or **kwargs - if pline[0] is '{' and pline[-1] is'}'\ + if pline[0] == '{' and pline[-1] == '}'\ and type(eval(pline)) is dict: _args = pline else: @@ -115,21 +116,43 @@ def emptyline(self): def do_create(self, args): """ Create an object of any class""" + import os + from models.engine.db_storage import DBStorage + from models.engine.file_storage import FileStorage if not args: - print("** class name missing **") + print(" class name missing ") return - elif args not in HBNBCommand.classes: - print("** class doesn't exist **") + arr = args.split(' ') + if arr[0] not in HBNBCommand.classes: + print(" class doesn't exist ") return - new_instance = HBNBCommand.classes[args]() + kwargs = {} + for arg in arr[1:]: + key_value = arg.split("=") + key, value = key_value + if value.startswith('"') and value.endswith('"'): + value = value.strip('"').replace('_', ' ') + value = value.replace("\\", '"') + else: + try: + value = int(value) + except ValueError: + try: + value = float(value) + except ValueError: + pass + kwargs[key] = value + new_instance = HBNBCommand.classes[arr[0]]() + new_instance.__dict__.update(kwargs) + storage.reload() + storage.new(new_instance) storage.save() print(new_instance.id) - storage.save() def help_create(self): """ Help information for the create method """ print("Creates a class of any type") - print("[Usage]: create \n") + print("[Usage]: create ...\n") def do_show(self, args): """ Method to show an individual object """ @@ -187,7 +210,7 @@ def do_destroy(self, args): key = c_name + "." + c_id try: - del(storage.all()[key]) + del (storage.all()[key]) storage.save() except KeyError: print("** no instance found **") @@ -206,14 +229,24 @@ def do_all(self, args): if args not in HBNBCommand.classes: print("** class doesn't exist **") return - for k, v in storage._FileStorage__objects.items(): + # args is in string format + cls = HBNBCommand.classes.get(args) + wanted_dic = {} + for k, v in storage.all(cls).items(): if k.split('.')[0] == args: - print_list.append(str(v)) + _dict = BaseModel.to_dict(v) + obj = cls() + obj.__dict__ = _dict + print_list.append(str(obj)) else: - for k, v in storage._FileStorage__objects.items(): - print_list.append(str(v)) + for _, v in storage.all().items(): + _dict = BaseModel.to_dict(v) + obj = cls() + obj.__dict__ = _dict + print_list.append(str(obj)) - print(print_list) + print("[{}]".format(", ".join(print_list))) + # print(print_list) def help_all(self): """ Help information for the all command """ @@ -272,7 +305,7 @@ def do_update(self, args): args.append(v) else: # isolate args args = args[2] - if args and args[0] is '\"': # check for quoted arg + if args and args[0] == '\"': # check for quoted arg second_quote = args.find('\"', 1) att_name = args[1:second_quote] args = args[second_quote + 1:] @@ -280,10 +313,10 @@ def do_update(self, args): args = args.partition(' ') # if att_name was not quoted arg - if not att_name and args[0] is not ' ': + if not att_name and args[0] != ' ': att_name = args[0] # check for quoted val arg - if args[2] and args[2][0] is '\"': + if args[2] and args[2][0] == '\"': att_val = args[2][1:args[2].find('\"', 1)] # if att_val was not quoted arg @@ -320,5 +353,6 @@ def help_update(self): print("Updates an object with new information") print("Usage: update \n") + if __name__ == "__main__": HBNBCommand().cmdloop() diff --git a/fabfile.py b/fabfile.py new file mode 100755 index 000000000000..fedbcf6c7a45 --- /dev/null +++ b/fabfile.py @@ -0,0 +1,22 @@ +#!/usr/bin/python3 +""" Fabric script that generates a .tgz archive from the contents of the web_static +""" +import os +from fabric.api import local +import datetime + +def do_pack(): + """ function to create .tgz archive """ + + time_stamp = datetime.datetime.now().strftime("%Y%m%d%H%M%S") + if os.path.exists('./versions'): + os.mkdir('./versions') + archive_name = "web_static_{}.tgz".format(time_stamp) + local("tar -cvzf versions/{} web_static".format(archive_name)) + print("Packing web_static to versions/{}.tgz".format(archive_name)) + if os.path.getsize("versions/{}".format(archive_name)): + size = os.path.getsize("versions/{}.tgz".format(archive_name)) + print("web_static packed: versions/{} -> {}Bytes".format(archive_name, size)) + return archive_name + else: + return None diff --git a/file.json b/file.json new file mode 100644 index 000000000000..e14ddb52139e --- /dev/null +++ b/file.json @@ -0,0 +1 @@ +{"State.b938c3d3-101b-47b4-a690-4d2bfda7d8db": {"id": "b938c3d3-101b-47b4-a690-4d2bfda7d8db", "name": "California", "created_at": "2024-07-31T21:48:38.782136", "updated_at": "2024-07-31T21:48:38.782200", "__class__": "State"}, "State.6f379894-c574-4167-ac88-8b8a7f2420d9": {"id": "6f379894-c574-4167-ac88-8b8a7f2420d9", "name": "Arizona", "created_at": "2024-07-31T21:48:38.785208", "updated_at": "2024-07-31T21:48:38.785265", "__class__": "State"}, "City.944f8d2b-a687-4a55-914b-614d86de3bc8": {"id": "944f8d2b-a687-4a55-914b-614d86de3bc8", "state_id": "b938c3d3-101b-47b4-a690-4d2bfda7d8db", "name": "Napa", "created_at": "2024-07-31T21:48:38.787563", "updated_at": "2024-07-31T21:48:38.787613", "__class__": "City"}, "City.ca10f623-e056-4f3f-b38f-4b0f3ea226b5": {"id": "ca10f623-e056-4f3f-b38f-4b0f3ea226b5", "state_id": "b938c3d3-101b-47b4-a690-4d2bfda7d8db", "name": "Sonoma", "created_at": "2024-07-31T21:48:38.792337", "updated_at": "2024-07-31T21:48:38.792377", "__class__": "City"}, "City.f077358b-a571-4bc4-b21b-fa7e406ff773": {"id": "f077358b-a571-4bc4-b21b-fa7e406ff773", "state_id": "6f379894-c574-4167-ac88-8b8a7f2420d9", "name": "Page", "created_at": "2024-07-31T21:48:38.796834", "updated_at": "2024-07-31T21:48:38.796877", "__class__": "City"}} \ No newline at end of file diff --git a/install_conf b/install_conf new file mode 100755 index 000000000000..34a400847d25 --- /dev/null +++ b/install_conf @@ -0,0 +1,15 @@ +#!/usr/bin/bash + +pip3 uninstall Fabric +sudo apt-get install libffi-dev +sudo apt-get install libssl-dev +sudo apt-get install build-essential +sudo apt-get install python3.4-dev +sudo apt-get install libpython3-dev +pip3 install pyparsing +pip3 install appdirs +pip3 install setuptools==40.1.0 +pip3 install cryptography==2.8 +pip3 install bcrypt==3.1.7 +pip3 install PyNaCl==1.3.0 +pip3 install Fabric3==1.14.post1 diff --git a/main.py b/main.py new file mode 100644 index 000000000000..966344547532 --- /dev/null +++ b/main.py @@ -0,0 +1,33 @@ +#!/usr/bin/python3 +""" + Test cities access from a state +""" +from models import storage +from models.state import State +from models.city import City + +""" + Objects creations +""" +state_1 = State(name="California") +print("New state: {}".format(state_1)) +state_1.save() +state_2 = State(name="Arizona") +print("New state: {}".format(state_2)) +state_2.save() + +city_1_1 = City(state_id=state_1.id, name="Napa") +print("New city: {} in the state: {}".format(city_1_1, state_1)) +city_1_1.save() +city_1_2 = City(state_id=state_1.id, name="Sonoma") +print("New city: {} in the state: {}".format(city_1_2, state_1)) +city_1_2.save() +city_2_1 = City(state_id=state_2.id, name="Page") +print("New city: {} in the state: {}".format(city_2_1, state_2)) +city_2_1.save() + +print("") +all_states = storage.all(State) +for state_id, state in all_states.items(): + for city in state.cities: + print("Find the city {} in the state {}".format(city, state)) diff --git a/main_place_amenities.py b/main_place_amenities.py new file mode 100644 index 000000000000..b2dd91e3231a --- /dev/null +++ b/main_place_amenities.py @@ -0,0 +1,49 @@ +#!/usr/bin/python3 +""" Test link Many-To-Many Place <> Amenity +""" +from models.base_model import BaseModel +from models.amenity import Amenity +from models.place import Place +from models.review import Review +from models.user import User +from models.city import City +from models.state import State + +# creation of a State +state = State(name="California") +state.save() + +# creation of a City +city = City(state_id=state.id, name="San Francisco") +city.save() + +# creation of a User +user = User(email="john@snow.com", password="johnpwd") +user.save() + +# creation of 2 Places +place_1 = Place(user_id=user.id, city_id=city.id, name="House 1") +place_1.save() +place_2 = Place(user_id=user.id, city_id=city.id, name="House 2") +place_2.save() + +# creation of 3 various Amenity +amenity_1 = Amenity(name="Wifi") +amenity_1.save() +amenity_2 = Amenity(name="Cable") +amenity_2.save() +amenity_3 = Amenity(name="Oven") +amenity_3.save() + +# link place_1 with 2 amenities +place_1.amenities.append(amenity_1) +place_1.amenities.append(amenity_2) + +# link place_2 with 3 amenities +place_2.amenities.append(amenity_1) +place_2.amenities.append(amenity_2) +place_2.amenities.append(amenity_3) + +storage.save() + +print("OK") diff --git a/models/__init__.py b/models/__init__.py old mode 100644 new mode 100755 index d3765c2bc603..b7b641f2b965 --- a/models/__init__.py +++ b/models/__init__.py @@ -1,7 +1,12 @@ #!/usr/bin/python3 """This module instantiates an object of class FileStorage""" -from models.engine.file_storage import FileStorage +import os +if os.getenv('HBNB_TYPE_STORAGE') == 'db': + from models.engine.db_storage import DBStorage + storage = DBStorage() +else: + from models.engine.file_storage import FileStorage + storage = FileStorage() -storage = FileStorage() storage.reload() diff --git a/models/__pycache__/__init__.cpython-310.pyc b/models/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 000000000000..a6068ffff77f Binary files /dev/null and b/models/__pycache__/__init__.cpython-310.pyc differ diff --git a/models/__pycache__/amenity.cpython-310.pyc b/models/__pycache__/amenity.cpython-310.pyc new file mode 100644 index 000000000000..373a213c59b9 Binary files /dev/null and b/models/__pycache__/amenity.cpython-310.pyc differ diff --git a/models/__pycache__/base_model.cpython-310.pyc b/models/__pycache__/base_model.cpython-310.pyc new file mode 100644 index 000000000000..5a1d543ed9f0 Binary files /dev/null and b/models/__pycache__/base_model.cpython-310.pyc differ diff --git a/models/__pycache__/city.cpython-310.pyc b/models/__pycache__/city.cpython-310.pyc new file mode 100644 index 000000000000..bec47744eedc Binary files /dev/null and b/models/__pycache__/city.cpython-310.pyc differ diff --git a/models/__pycache__/place.cpython-310.pyc b/models/__pycache__/place.cpython-310.pyc new file mode 100644 index 000000000000..da211f0ed0b7 Binary files /dev/null and b/models/__pycache__/place.cpython-310.pyc differ diff --git a/models/__pycache__/review.cpython-310.pyc b/models/__pycache__/review.cpython-310.pyc new file mode 100644 index 000000000000..1de3eabe42e8 Binary files /dev/null and b/models/__pycache__/review.cpython-310.pyc differ diff --git a/models/__pycache__/state.cpython-310.pyc b/models/__pycache__/state.cpython-310.pyc new file mode 100644 index 000000000000..4585e67b36c5 Binary files /dev/null and b/models/__pycache__/state.cpython-310.pyc differ diff --git a/models/__pycache__/user.cpython-310.pyc b/models/__pycache__/user.cpython-310.pyc new file mode 100644 index 000000000000..a15c707bd8fd Binary files /dev/null and b/models/__pycache__/user.cpython-310.pyc differ diff --git a/models/amenity.py b/models/amenity.py old mode 100644 new mode 100755 index a181095e4170..2c4abb0a12d7 --- a/models/amenity.py +++ b/models/amenity.py @@ -1,7 +1,14 @@ #!/usr/bin/python3 """ State Module for HBNB project """ -from models.base_model import BaseModel +from models.base_model import BaseModel, Base +from sqlalchemy import Column, String +from sqlalchemy.orm import relationship -class Amenity(BaseModel): - name = "" +class Amenity(BaseModel, Base): + """ The amenity model class """ + __tablename__ = "amenities" + name = Column(String(128), nullable=False) + # place_amenities = relationship("Place", secondary="place_amenity", + # back_populates="amenities") + diff --git a/models/base_model.py b/models/base_model.py old mode 100644 new mode 100755 index 4856e9de421f..5354978da477 --- a/models/base_model.py +++ b/models/base_model.py @@ -2,35 +2,58 @@ """This module defines a base class for all models in our hbnb clone""" import uuid from datetime import datetime +from sqlalchemy.ext.declarative import declarative_base +from sqlalchemy import Column, Integer, String, DateTime +import os + + +if os.getenv('HBNB_TYPE_STORAGE') == 'db' : + Base = declarative_base() +else: + Base = object class BaseModel: """A base class for all hbnb models""" + id = Column(String(60), + nullable=False, + primary_key=True) + created_at = Column(DateTime, + nullable=False, + default=datetime.now()) + updated_at = Column(DateTime, + nullable=False, + default=datetime.now()) + def __init__(self, *args, **kwargs): """Instatntiates a new model""" + self.id = str(uuid.uuid4()) if not kwargs: - from models import storage - self.id = str(uuid.uuid4()) self.created_at = datetime.now() self.updated_at = datetime.now() - storage.new(self) else: - kwargs['updated_at'] = datetime.strptime(kwargs['updated_at'], - '%Y-%m-%dT%H:%M:%S.%f') - kwargs['created_at'] = datetime.strptime(kwargs['created_at'], - '%Y-%m-%dT%H:%M:%S.%f') - del kwargs['__class__'] - self.__dict__.update(kwargs) + for key, value in kwargs.items(): + if key == "created_at" or key == "updated_at": + value = datetime.strptime(value, "%Y-%m-%dT%H:%M:%S.%f") + if key != "__class__": + setattr(self, key, value) + if 'created_at' not in kwargs: + self.created_at = datetime.now() + if 'updated_at' not in kwargs: + self.updated_at = datetime.now() def __str__(self): """Returns a string representation of the instance""" cls = (str(type(self)).split('.')[-1]).split('\'')[0] - return '[{}] ({}) {}'.format(cls, self.id, self.__dict__) + + filtered_dict = {key: value for key, value in self.__dict__.items() if key not in ['_sa_instance_state', 'cities', '__class__']} + return '[{}] ({}) {}'.format(cls, self.id, filtered_dict) def save(self): """Updates updated_at with current time when instance is changed""" from models import storage self.updated_at = datetime.now() + storage.new(self) storage.save() def to_dict(self): @@ -41,4 +64,20 @@ def to_dict(self): (str(type(self)).split('.')[-1]).split('\'')[0]}) dictionary['created_at'] = self.created_at.isoformat() dictionary['updated_at'] = self.updated_at.isoformat() + + if '_sa_instance_state' in dictionary: + del dictionary['_sa_instance_state'] + # del dictionary['__class__'] return dictionary + + def delete(self): + """ delete current instance from storage """ + for key, value in self.__objects.items(): + flag = False + if value.id == self.id: + flag = True + wanted_key = key + break + if flag: + del self.__objects[wanted_key] + self.save() \ No newline at end of file diff --git a/models/city.py b/models/city.py old mode 100644 new mode 100755 index b9b4fe221502..b43c8e84b034 --- a/models/city.py +++ b/models/city.py @@ -1,9 +1,18 @@ #!/usr/bin/python3 """ City Module for HBNB project """ -from models.base_model import BaseModel +from models.base_model import BaseModel, Base +from sqlalchemy import Column, String, ForeignKey +from sqlalchemy.orm import relationship -class City(BaseModel): + +class City(BaseModel, Base): """ The city class, contains state ID and name """ - state_id = "" - name = "" + __tablename__ = "cities" + name = Column(String(128), + nullable=False) + state_id = Column(String(60), + ForeignKey('states.id'), + nullable=False) + state = relationship("State", back_populates="cities") + places = relationship("Place", back_populates="cities", cascade="all, delete") \ No newline at end of file diff --git a/models/engine/__init__.py b/models/engine/__init__.py old mode 100644 new mode 100755 diff --git a/models/engine/__pycache__/__init__.cpython-310.pyc b/models/engine/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 000000000000..772bca95a13a Binary files /dev/null and b/models/engine/__pycache__/__init__.cpython-310.pyc differ diff --git a/models/engine/__pycache__/db_storage.cpython-310.pyc b/models/engine/__pycache__/db_storage.cpython-310.pyc new file mode 100644 index 000000000000..bc7f877667de Binary files /dev/null and b/models/engine/__pycache__/db_storage.cpython-310.pyc differ diff --git a/models/engine/__pycache__/file_storage.cpython-310.pyc b/models/engine/__pycache__/file_storage.cpython-310.pyc new file mode 100644 index 000000000000..fe053e90cf6e Binary files /dev/null and b/models/engine/__pycache__/file_storage.cpython-310.pyc differ diff --git a/models/engine/db_storage.py b/models/engine/db_storage.py new file mode 100755 index 000000000000..cc1a514f754b --- /dev/null +++ b/models/engine/db_storage.py @@ -0,0 +1,87 @@ +#!/usr/bin/python3 +""" Database storage for airbnb project +here we can see the magic of ORM +""" +from sqlalchemy import create_engine, MetaData +from sqlalchemy.orm import sessionmaker, scoped_session +import os + + +class DBStorage: + """ This class manages dbstorage for airbnb project """ + __engine = None + __session = None + + def __init__(self): + """ this class constructor """ + user = os.getenv('HBNB_MYSQL_USER') + pwd = os.getenv('HBNB_MYSQL_PWD') + host = os.getenv('HBNB_MYSQL_HOST') + db = os.getenv('HBNB_MYSQL_DB') + self.__engine = create_engine( + 'mysql+mysqldb://{}:{}@{}:3306/{}'.format( + user, pwd, host, db), + pool_pre_ping=True + ) + + if os.getenv('HBNB_ENV') == 'test': + metadata = MetaData() + metadata.reflect(bind=self.__engine) + metadata.drop_all(bind=self.__engine) + + def all(self, cls=None): + """ query on current db session """ + from models.user import User + from models.place import Place + from models.review import Review + from models.city import City + from models.amenity import Amenity + from models.state import State + new_dict = {} + classes = { + 'User': User, + 'State': State, + 'City': City, + 'Amenity': Amenity, + 'Place': Place, + 'Review': Review + } + if cls: + if type(cls) is str: + cls = classes.get(cls) + filter_query = self.__session.query(cls).all() + for obj in filter_query: + key = "{}.{}".format(obj.__class__.__name__, obj.id) + new_dict[key] = obj + else: + for key, value in classes.items(): + filter_query = self.__session.query(value).all() + for obj in filter_query: + key = "{}.{}".format(obj.__class__.__name__, obj.id) + new_dict[key] = obj + return new_dict + + def new(self, obj): + """ add obj to db session """ + self.__session.add(obj) + + def save(self): + """ save changes to db permanently """ + self.__session.commit() + + def delete(self, obj=None): + """ delete obj(row) from db """ + if obj is not None: + self.__session.delete() + + def reload(self): + """ create tables in the Database """ + from models.base_model import Base + Base.metadata.create_all(self.__engine) + sess_factory = sessionmaker(bind=self.__engine, expire_on_commit=False) + Session = scoped_session(sess_factory) + self.__session = Session + + def close(self): + """close method ro manage resources""" + self.__session.remove() diff --git a/models/engine/file_storage.py b/models/engine/file_storage.py old mode 100644 new mode 100755 index 6f5d7f8d4680..5d9591de4f76 --- a/models/engine/file_storage.py +++ b/models/engine/file_storage.py @@ -4,13 +4,35 @@ class FileStorage: - """This class manages storage of hbnb models in JSON format""" + """This class manages FileStorage of hbnb models in JSON format""" __file_path = 'file.json' __objects = {} - def all(self): + def all(self, cls=None): """Returns a dictionary of models currently in storage""" - return FileStorage.__objects + from models.user import User + from models.place import Place + from models.review import Review + from models.city import City + from models.amenity import Amenity + from models.state import State + new_dict = {} + classes = { + 'User': User, + 'State': State, + 'City': City, + 'Amenity': Amenity, + 'Place': Place, + 'Review': Review + } + if cls: + new_dict = {} + for key, value in self.__objects.items(): + if type(value) is cls: + new_dict[key] = value + return new_dict + else: + return FileStorage.__objects def new(self, obj): """Adds new object to storage dictionary""" @@ -45,6 +67,23 @@ def reload(self): with open(FileStorage.__file_path, 'r') as f: temp = json.load(f) for key, val in temp.items(): - self.all()[key] = classes[val['__class__']](**val) + self.all()[key] = classes[val['__class__']](**val) except FileNotFoundError: pass + + def delete(self, obj=None): + """ delete object """ + if obj is not None: + for key, value in self.__objects.items(): + flag = False + if value == obj: + flag = True + wanted_key = key + break + if flag: + del self.__objects[wanted_key] + self.save() + + def close(self): + """ close method""" + self.reload() diff --git a/models/place.py b/models/place.py old mode 100644 new mode 100755 index 5221e8210d17..717af2fd47b4 --- a/models/place.py +++ b/models/place.py @@ -1,18 +1,73 @@ #!/usr/bin/python3 """ Place Module for HBNB project """ -from models.base_model import BaseModel +import os +from models.base_model import BaseModel, Base +from sqlalchemy import Column, String, Integer, ForeignKey, Float, Table +from sqlalchemy.orm import relationship +from sqlalchemy.ext.declarative import declarative_base -class Place(BaseModel): +# place_amenity = Table('place_amenity', Base.metadata, +# Column('place_id', +# String(60), +# ForeignKey('places.id'), +# nullable=False, +# primary_key=True), +# Column('amenity_id', +# String(60), +# ForeignKey('amenities.id'), +# nullable=False, +# primary_key=True) +# ) + + +class Place(BaseModel, Base): """ A place to stay """ - city_id = "" - user_id = "" - name = "" - description = "" - number_rooms = 0 - number_bathrooms = 0 - max_guest = 0 - price_by_night = 0 - latitude = 0.0 - longitude = 0.0 + __tablename__ = 'places' + city_id = Column(String(60), ForeignKey('cities.id'), nullable=False) + user_id = Column(String(60), ForeignKey('users.id'), nullable=False) + name = Column(String(128), nullable=False) + description = Column(String(1024), nullable=True) + number_rooms = Column(Integer, nullable=False, default=0) + number_bathrooms = Column(Integer, nullable=False, default=0) + max_guest = Column(Integer, nullable=False, default=0) + price_by_night = Column(Integer, nullable=False, default=0) + latitude = Column(Float, nullable=True) + longitude = Column(Float, nullable=True) amenity_ids = [] + user = relationship("User", back_populates="places") + cities = relationship("City", back_populates="places") + + + if os.getenv('HBNB_TYPE_STORAGE') == 'db': + reviews = relationship("Review", back_populates="place", cascade="all, delete") + # amenities = relationship("Amenity", secondary="place_amenity", + # back_populates="place_amenities", + # viewonly=False) + else: + @property + def reviews(self): + """ review getter attribut for Filestorage """ + from models.engine.file_storage import FileStorage + review_list = [] + for _, v in FileStorage.__objects.items(): + if v.place_id == self.id: + review_list.append(v) + return review_list + + @property + def amenities(self): + """ amenities getter attribute for Filestorage """ + from models.engine.file_storage import FileStorage + amenity_list = [] + for _, v in FileStorage.__objects.items(): + for id in self.amenity_ids: + if v.id == id: + amenity_list.append(v) + return amenity_list + + @amenities.setter + def amenities(self, obj): + """ amenities setter attribute """ + if type(obj) == "Amenity": + self.amenity_ids.append(obj.id) diff --git a/models/review.py b/models/review.py old mode 100644 new mode 100755 index c487d90d34f0..0c3b85c81372 --- a/models/review.py +++ b/models/review.py @@ -1,10 +1,20 @@ #!/usr/bin/python3 """ Review module for the HBNB project """ -from models.base_model import BaseModel +from models.base_model import BaseModel, Base +from sqlalchemy import Column, String, ForeignKey +from sqlalchemy.orm import relationship -class Review(BaseModel): +class Review(BaseModel, Base): """ Review classto store review information """ - place_id = "" - user_id = "" - text = "" + __tablename__ = 'reviews' + place_id = Column(String(60), + ForeignKey('places.id'), + nullable=False) + user_id = Column(String(60), + ForeignKey('users.id'), + nullable=False) + text = Column(String(1024), + nullable=False) + user = relationship("User", back_populates="reviews") + place = relationship("Place", back_populates="reviews") diff --git a/models/state.py b/models/state.py old mode 100644 new mode 100755 index 583f041f07e4..575b918f7341 --- a/models/state.py +++ b/models/state.py @@ -1,8 +1,33 @@ #!/usr/bin/python3 """ State Module for HBNB project """ -from models.base_model import BaseModel +from models.base_model import BaseModel, Base +from models.city import City +from sqlalchemy import Column, String +from sqlalchemy.orm import relationship +from models import storage +import os -class State(BaseModel): +class State(BaseModel, Base): """ State class """ - name = "" + print(type(Base)) + if os.getenv('HBNB_TYPE_STORAGE') == 'db': + __tablename__ = "states" + name = Column(String(128), + nullable=False) + cities = relationship("City", + back_populates="state", + cascade="all, delete") + else: + name = '' + + if not os.getenv('HBNB_TYPE_STORAGE') == 'db': + @property + def cities(self): + """ getter attribut for FileStorage linked + between State and City """ + list_city = [] + for city in storage.all(City).values(): + if city.state_id == self.id: + list_city.append(city) + return list_city diff --git a/models/user.py b/models/user.py old mode 100644 new mode 100755 index 4b54a6d24120..b1babdbb7b6d --- a/models/user.py +++ b/models/user.py @@ -1,11 +1,16 @@ #!/usr/bin/python3 """This module defines a class User""" -from models.base_model import BaseModel +from models.base_model import BaseModel, Base +from sqlalchemy import Column, String +from sqlalchemy.orm import relationship -class User(BaseModel): - """This class defines a user by various attributes""" - email = '' - password = '' - first_name = '' - last_name = '' +class User(BaseModel, Base): + """This class defines a user model from HBNB models """ + __tablename__ = 'users' + email = Column(String(128), nullable=False) + password = Column(String(128), nullable=False) + first_name = Column(String(128)) + last_name = Column(String(128)) + places = relationship('Place', back_populates='user', cascade="all, delete") + reviews = relationship('Review', back_populates='user', cascade="all, delete") \ No newline at end of file diff --git a/setup_mysql_dev.sql b/setup_mysql_dev.sql new file mode 100644 index 000000000000..8d582f694ab2 --- /dev/null +++ b/setup_mysql_dev.sql @@ -0,0 +1,5 @@ +-- MySQL setup developement +CREATE DATABASE IF NOT EXISTS `hbnb_dev_db`; +CREATE USER IF NOT EXISTS 'hbnb_dev'@'localhost' IDENTIFIED BY 'hbnb_dev_pwd'; +GRANT ALL PRIVILEGES ON `hbnb_dev_db`.* TO 'hbnb_dev'@'localhost'; +GRANT SELECT ON `performance_schema`.* TO 'hbnb_dev'@'localhost'; diff --git a/setup_mysql_test.sql b/setup_mysql_test.sql new file mode 100644 index 000000000000..edafe4be30eb --- /dev/null +++ b/setup_mysql_test.sql @@ -0,0 +1,5 @@ +-- MySQL setup developement for test +CREATE DATABASE IF NOT EXISTS `hbnb_test_db`; +CREATE USER IF NOT EXISTS 'hbnb_test'@'localhost' IDENTIFIED BY 'hbnb_test_pwd'; +GRANT ALL PRIVILEGES ON `hbnb_test_db`.* TO 'hbnb_test'@'localhost'; +GRANT SELECT ON `performance_schema`.* TO 'hbnb_test'@'localhost'; diff --git a/versions/web_static_20240715203346.tgz b/versions/web_static_20240715203346.tgz new file mode 100644 index 000000000000..ac5a6f90f540 Binary files /dev/null and b/versions/web_static_20240715203346.tgz differ diff --git a/web_flask/0-hello_route.py b/web_flask/0-hello_route.py new file mode 100644 index 000000000000..3279590ff8ec --- /dev/null +++ b/web_flask/0-hello_route.py @@ -0,0 +1,15 @@ +#!/usr/bin/python3 +""" python script that starts a Flask +web application +""" +from flask import Flask +app = Flask(__name__) + + +@app.route("/", strict_slashes=False) +def hello(): + return "Hello HBNB!" + + +if __name__ == "__main__": + app.run(host='0.0.0.0', port=5000) diff --git a/web_flask/1-hbnb_route.py b/web_flask/1-hbnb_route.py new file mode 100644 index 000000000000..fe2812100ca7 --- /dev/null +++ b/web_flask/1-hbnb_route.py @@ -0,0 +1,20 @@ +#!/usr/bin/python3 +""" python script that starts a Flask +web application +""" +from flask import Flask +app = Flask(__name__) + + +@app.route("/", strict_slashes=False) +def hello(): + return "Hello HBNB!" + + +@app.route("/hbnb", strict_slashes=False) +def hbnb(): + return "HBNB" + + +if __name__ == "__main__": + app.run(host='0.0.0.0', port=5000) diff --git a/web_flask/10-hbnb_filters.py b/web_flask/10-hbnb_filters.py new file mode 100644 index 000000000000..5d0d4560b209 --- /dev/null +++ b/web_flask/10-hbnb_filters.py @@ -0,0 +1,26 @@ +#!/usr/bin/python3 +""" python script that starts a Flask +web application +""" +from models import storage +from models.state import State +from flask import Flask, abort, render_template +app = Flask(__name__) + + +@app.route("/hbnb_filters", strict_slashes=False) +def States(): + """ state route """ + new_dict = storage.all("State") + states = list(new_dict.values()) + return render_template("10-hbnb_filters.html", states=states) + + +@app.teardown_appcontext +def teardown_db(exception): + """close the database connection """ + storage.close() + + +if __name__ == "__main__": + app.run(host='0.0.0.0', port=5000) diff --git a/web_flask/2-c_route.py b/web_flask/2-c_route.py new file mode 100644 index 000000000000..909960d3cfcf --- /dev/null +++ b/web_flask/2-c_route.py @@ -0,0 +1,26 @@ +#!/usr/bin/python3 +""" python script that starts a Flask +web application +""" +from flask import Flask +app = Flask(__name__) + + +@app.route("/", strict_slashes=False) +def hello(): + return "Hello HBNB!" + + +@app.route("/hbnb", strict_slashes=False) +def hbnb(): + return "HBNB" + + +@app.route("/c/", strict_slashes=False) +def C(txt): + txt = txt.replace("_", " ") + return "C {}".format(txt) + + +if __name__ == "__main__": + app.run(host='0.0.0.0', port=5000) diff --git a/web_flask/3-python_route.py b/web_flask/3-python_route.py new file mode 100644 index 000000000000..b4838f52b177 --- /dev/null +++ b/web_flask/3-python_route.py @@ -0,0 +1,33 @@ +#!/usr/bin/python3 +""" python script that starts a Flask +web application +""" +from flask import Flask +app = Flask(__name__) + + +@app.route("/", strict_slashes=False) +def hello(): + return "Hello HBNB!" + + +@app.route("/hbnb", strict_slashes=False) +def hbnb(): + return "HBNB" + + +@app.route("/c/", strict_slashes=False) +def C(txt): + txt = txt.replace("_", " ") + return "C {}".format(txt) + + +@app.route("/python/", defaults={'txt': 'is cool'}) +@app.route("/python/", strict_slashes=False) +def Python(txt): + txt = txt.replace("_", " ") + return "Python {}".format(txt) + + +if __name__ == "__main__": + app.run(host='0.0.0.0', port=5000) diff --git a/web_flask/4-number_route.py b/web_flask/4-number_route.py new file mode 100644 index 000000000000..bb60a07a7aa0 --- /dev/null +++ b/web_flask/4-number_route.py @@ -0,0 +1,42 @@ +#!/usr/bin/python3 +""" python script that starts a Flask +web application +""" +from flask import Flask, abort +app = Flask(__name__) + + +@app.route("/", strict_slashes=False) +def hello(): + return "Hello HBNB!" + + +@app.route("/hbnb", strict_slashes=False) +def hbnb(): + return "HBNB" + + +@app.route("/c/", strict_slashes=False) +def C(txt): + txt = txt.replace("_", " ") + return "C {}".format(txt) + + +@app.route("/python/", defaults={'txt': 'is cool'}) +@app.route("/python/", strict_slashes=False) +def Python(txt): + txt = txt.replace("_", " ") + return "Python {}".format(txt) + + +@app.route("/number/", strict_slashes=False) +def Number(n): + try: + n = int(n) + return "{} is a number".format(n) + except ValueError: + abort(404) + + +if __name__ == "__main__": + app.run(host='0.0.0.0', port=5000) diff --git a/web_flask/5-number_template.py b/web_flask/5-number_template.py new file mode 100644 index 000000000000..10301e437d80 --- /dev/null +++ b/web_flask/5-number_template.py @@ -0,0 +1,51 @@ +#!/usr/bin/python3 +""" python script that starts a Flask +web application +""" +from flask import Flask, abort, render_template +app = Flask(__name__) + + +@app.route("/", strict_slashes=False) +def hello(): + return "Hello HBNB!" + + +@app.route("/hbnb", strict_slashes=False) +def hbnb(): + return "HBNB" + + +@app.route("/c/", strict_slashes=False) +def C(txt): + txt = txt.replace("_", " ") + return "C {}".format(txt) + + +@app.route("/python/", defaults={'txt': 'is cool'}) +@app.route("/python/", strict_slashes=False) +def Python(txt): + txt = txt.replace("_", " ") + return "Python {}".format(txt) + + +@app.route("/number/", strict_slashes=False) +def Number(n): + try: + n = int(n) + return "{} is a number".format(n) + except ValueError: + abort(404) + + +@app.route("/number_template/", strict_slashes=False) +def Number_template(n): + try: + n = int(n) + return render_template('5-number.html', n=n) + except ValueError: + abort(404) + + +if __name__ == "__main__": + app.run(host='0.0.0.0', port=5000) diff --git a/web_flask/6-number_odd_or_even.py b/web_flask/6-number_odd_or_even.py new file mode 100644 index 000000000000..a333f339a958 --- /dev/null +++ b/web_flask/6-number_odd_or_even.py @@ -0,0 +1,60 @@ +#!/usr/bin/python3 +""" python script that starts a Flask +web application +""" +from flask import Flask, abort, render_template +app = Flask(__name__) + + +@app.route("/", strict_slashes=False) +def hello(): + return "Hello HBNB!" + + +@app.route("/hbnb", strict_slashes=False) +def hbnb(): + return "HBNB" + + +@app.route("/c/", strict_slashes=False) +def C(txt): + txt = txt.replace("_", " ") + return "C {}".format(txt) + + +@app.route("/python/", defaults={'txt': 'is cool'}) +@app.route("/python/", strict_slashes=False) +def Python(txt): + txt = txt.replace("_", " ") + return "Python {}".format(txt) + + +@app.route("/number/", strict_slashes=False) +def Number(n): + try: + n = int(n) + return "{} is a number".format(n) + except ValueError: + abort(404) + + +@app.route("/number_template/", strict_slashes=False) +def Number_template(n): + try: + n = int(n) + return render_template('5-number.html', n=n) + except ValueError: + abort(404) + + +@app.route("/number_odd_or_even/", strict_slashes=False) +def Number_odd_even(n): + try: + n = int(n) + return render_template('6-number_odd_or_even.html', n=n) + except ValueError: + abort(404) + + +if __name__ == "__main__": + app.run(host='0.0.0.0', port=5000) diff --git a/web_flask/7-states_list.py b/web_flask/7-states_list.py new file mode 100755 index 000000000000..e9750fc14db2 --- /dev/null +++ b/web_flask/7-states_list.py @@ -0,0 +1,26 @@ +#!/usr/bin/python3 +""" python script that starts a Flask +web application +""" +from models import storage +from models.state import State +from flask import Flask, abort, render_template +app = Flask(__name__) + + +@app.route('/states_list', strict_slashes=False) +def State(): + """ state route """ + new_dict = storage.all("State") + states = list(new_dict.values()) + return render_template("7-states_list.html", states=states) + + +@app.teardown_appcontext +def teardown_db(exception): + """close the database connection """ + storage.close() + + +if __name__ == "__main__": + app.run(host='0.0.0.0', port=5000) diff --git a/web_flask/8-cities_by_states.py b/web_flask/8-cities_by_states.py new file mode 100755 index 000000000000..5fcdaab620b7 --- /dev/null +++ b/web_flask/8-cities_by_states.py @@ -0,0 +1,26 @@ +#!/usr/bin/python3 +""" python script that starts a Flask +web application +""" +from models import storage +from models.state import State +from flask import Flask, abort, render_template +app = Flask(__name__) + + +@app.route('/cities_by_states', strict_slashes=False) +def State_city(): + """ state route """ + new_dict = storage.all("State") + states = list(new_dict.values()) + return render_template("8-cities_by_states.html", states=states) + + +@app.teardown_appcontext +def teardown_db(exception): + """close the database connection """ + storage.close() + + +if __name__ == "__main__": + app.run(host='0.0.0.0', port=5000) diff --git a/web_flask/9-states.py b/web_flask/9-states.py new file mode 100644 index 000000000000..adbacaf8653a --- /dev/null +++ b/web_flask/9-states.py @@ -0,0 +1,35 @@ +#!/usr/bin/python3 +""" python script that starts a Flask +web application +""" +from models import storage +from models.state import State +from flask import Flask, abort, render_template +app = Flask(__name__) + + +@app.route("/states", strict_slashes=False) +def States(): + """ state route """ + new_dict = storage.all("State") + states = list(new_dict.values()) + return render_template("9-states.html", states=states) + + +@app.route('/states/', strict_slashes=False) +def State_city(id): + """ state_city route """ + new_dict = storage.all("State") + states = list(new_dict.values()) + state = next((state for state in states if state.id == id), None) + return render_template("9-states.html", states=[state], id=id) + + +@app.teardown_appcontext +def teardown_db(exception): + """close the database connection """ + storage.close() + + +if __name__ == "__main__": + app.run(host='0.0.0.0', port=5000) diff --git a/web_flask/README.md b/web_flask/README.md new file mode 100644 index 000000000000..7493fd0c2979 --- /dev/null +++ b/web_flask/README.md @@ -0,0 +1 @@ +flask_application \ No newline at end of file diff --git a/web_flask/__init__.py b/web_flask/__init__.py new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/web_flask/static/images/logo.png b/web_flask/static/images/logo.png new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/web_flask/static/styles/3-footer.css b/web_flask/static/styles/3-footer.css new file mode 100644 index 000000000000..bdc217cc78ca --- /dev/null +++ b/web_flask/static/styles/3-footer.css @@ -0,0 +1,10 @@ +footer { + position: fixed; + bottom: 0; + background-color: white; + height: 60px; + width: 100%; + text-align: center; + line-height: 30px; + border-top: 1px solid #CCCCCC; +} diff --git a/web_flask/static/styles/3-header.css b/web_flask/static/styles/3-header.css new file mode 100644 index 000000000000..d28e9cf83e1d --- /dev/null +++ b/web_flask/static/styles/3-header.css @@ -0,0 +1,18 @@ +header { + background-color: white; + height: 70px; + width: 100%; + + border-bottom: 1px solid #CCCCCC; +} + +#header_logo { + height: 100%; + width: 142px; + + background-image: url("../images/logo.png"); + background-repeat: no-repeat; + background-position: center; + + margin-left: 20px; +} diff --git a/web_flask/static/styles/4-common.css b/web_flask/static/styles/4-common.css new file mode 100644 index 000000000000..f70c884eacb9 --- /dev/null +++ b/web_flask/static/styles/4-common.css @@ -0,0 +1,13 @@ +body { + margin:0px; + padding:0px; + + color: #484848; + font-size: 14px; + font-family: Circular,"Helvetica Neue",Helvetica,Arial,sans-serif; +} + +.container { + max-width: 1000px; + margin: 30px auto; +} diff --git a/web_flask/static/styles/6-filters.css b/web_flask/static/styles/6-filters.css new file mode 100644 index 000000000000..14d620e0e75b --- /dev/null +++ b/web_flask/static/styles/6-filters.css @@ -0,0 +1,101 @@ +.filters { + display: block; + background-color: white; + height: 70px; + width: 100%; + border: 1px solid #DDDDDD; + border-radius: 4px; +} + +.locations { + display: inline; + vertical-align: middle; + float: left; + height: 100%; + width: 25%; + + line-height: 20px; + border-right: 1px solid #DDDDDD; +} + +.filter_amenities { + display: inline; + vertical-align: middle; + height: 100%; + float: left; + width: 25%; + + line-height: 20px; +} + +.popover { + list-style-type: none; + display: none; + background-color: #FAFAFA; + width: 100%; + + margin-left: -1px; + margin-top: 8px; + padding: 25px 0px; + + border: 1px solid #DDDDDD; + border-radius: 4px; +} + +.locations:hover .popover { + display: inline-block; +} + +.filter_amenities:hover .popover { + display: inline-block; +} + +ul { + list-style-type: none; + padding: 0px; + padding-bottom: 20px; +} + +li { +} + +h2 { + font-size: 16px; + padding-left: 30px; + margin: 0px; +} + +h3 { + font-weight: 600; + margin-top: 12px; + margin-bottom: 5px; + padding-left: 45px; +} + +h4 { + font-size: 14px; + font-weight: 400; + margin-top: 5px; + margin-bottom: 5px; + padding-left: 45px; +} + +button { + color: #FFFFFF; + font-size: 18px; + + height: 48px; + width: 20%; + background-color: #FF5A5F; + border-style: none; + border-radius: 4px; + + float: right; + margin-top: 11px; + margin-bottom: 11px; + margin-right: 30px; +} + +button:hover { + opacity: 90%; +} diff --git a/web_flask/templates/10-hbnb_filters.html b/web_flask/templates/10-hbnb_filters.html new file mode 100644 index 000000000000..2e4eee80cf76 --- /dev/null +++ b/web_flask/templates/10-hbnb_filters.html @@ -0,0 +1,28 @@ + + + + HBNB + + + {% if not id %} +

States

+
    + {% for state in states %} +
  • {{ state.id }}: {{ state.name }}
  • + {% endfor %} +
+ {% else %} + {% if states[0] %} +

State

+

Cities

+
    + {% for city in states[0].cities %} +
  • {{ city.id }}: {{ city.name }}
  • + {% endfor %} +
+ {% else %} +

Not found!

+ {% endif %} + {% endif %} + + diff --git a/web_flask/templates/5-number.html b/web_flask/templates/5-number.html new file mode 100644 index 000000000000..57887ff74693 --- /dev/null +++ b/web_flask/templates/5-number.html @@ -0,0 +1,9 @@ + + + + HBNB + + +

Number: {{ n }}

+ + diff --git a/web_flask/templates/6-number_odd_or_even.html b/web_flask/templates/6-number_odd_or_even.html new file mode 100644 index 000000000000..f65238a6fbe5 --- /dev/null +++ b/web_flask/templates/6-number_odd_or_even.html @@ -0,0 +1,13 @@ + + + + HBNB + + + {% if n % 2 == 0 %} +

Number: {{ n }} is even

+ {% else %} +

Number: {{ n }} is odd

+ {% endif %} + + diff --git a/web_flask/templates/7-states_list.html b/web_flask/templates/7-states_list.html new file mode 100644 index 000000000000..5b2bbfa9941b --- /dev/null +++ b/web_flask/templates/7-states_list.html @@ -0,0 +1,14 @@ + + + + HBNB + + +

States

+
    + {% for state in states %} +
  • {{ state.id }}: {{ state.name }}
  • + {% endfor %} +
+ + diff --git a/web_flask/templates/8-cities_by_states.html b/web_flask/templates/8-cities_by_states.html new file mode 100644 index 000000000000..ad93f2744df0 --- /dev/null +++ b/web_flask/templates/8-cities_by_states.html @@ -0,0 +1,20 @@ + + + + HBNB + + +

States

+
    + {% for state in states %} +
  • {{ state.id }}: {{ state.name }} +
      + {% for city in state.cities %} +
    • {{ city.id }}: {{ city.name }}
    • + {% endfor %} +
    +
  • + {% endfor %} +
+ + diff --git a/web_flask/templates/9-states.html b/web_flask/templates/9-states.html new file mode 100644 index 000000000000..2e4eee80cf76 --- /dev/null +++ b/web_flask/templates/9-states.html @@ -0,0 +1,28 @@ + + + + HBNB + + + {% if not id %} +

States

+
    + {% for state in states %} +
  • {{ state.id }}: {{ state.name }}
  • + {% endfor %} +
+ {% else %} + {% if states[0] %} +

State

+

Cities

+
    + {% for city in states[0].cities %} +
  • {{ city.id }}: {{ city.name }}
  • + {% endfor %} +
+ {% else %} +

Not found!

+ {% endif %} + {% endif %} + +