├── tests ├── __init__.py ├── test_models │ ├── __init__.py │ ├── test_engine │ │ ├── __init__.py │ │ ├── __pycache__ │ │ │ ├── __init__.cpython-311.pyc │ │ │ ├── __init__.cpython-38.pyc │ │ │ ├── test_file_storage.cpython-38.pyc │ │ │ └── test_file_storage.cpython-311.pyc │ │ └── test_file_storage.py │ ├── .#test_review.py │ ├── __pycache__ │ │ ├── __init__.cpython-311.pyc │ │ ├── __init__.cpython-38.pyc │ │ ├── test_city.cpython-38.pyc │ │ ├── test_user.cpython-38.pyc │ │ ├── test_city.cpython-311.pyc │ │ ├── test_place.cpython-311.pyc │ │ ├── test_place.cpython-38.pyc │ │ ├── test_review.cpython-38.pyc │ │ ├── test_state.cpython-311.pyc │ │ ├── test_state.cpython-38.pyc │ │ ├── test_user.cpython-311.pyc │ │ ├── test_amenity.cpython-311.pyc │ │ ├── test_amenity.cpython-38.pyc │ │ ├── test_review.cpython-311.pyc │ │ ├── test_base_model.cpython-311.pyc │ │ └── test_base_model.cpython-38.pyc │ ├── test_state.py │ ├── test_user.py │ ├── test_amenity.py │ ├── test_city.py │ ├── test_base_model.py │ ├── test_review.py │ └── test_place.py └── __pycache__ │ ├── __init__.cpython-38.pyc │ ├── __init__.cpython-311.pyc │ ├── test_console.cpython-311.pyc │ └── test_console.cpython-38.pyc ├── models ├── engine │ ├── __init__.py │ ├── __pycache__ │ │ ├── __init__.cpython-311.pyc │ │ └── file_storage.cpython-311.pyc │ └── file_storage.py ├── __pycache__ │ ├── city.cpython-311.pyc │ ├── user.cpython-311.pyc │ ├── place.cpython-311.pyc │ ├── review.cpython-311.pyc │ ├── state.cpython-311.pyc │ ├── __init__.cpython-311.pyc │ ├── amenity.cpython-311.pyc │ └── base_model.cpython-311.pyc ├── __init__.py ├── state.py ├── amenity.py ├── city.py ├── review.py ├── user.py ├── place.py └── base_model.py ├── web_static ├── styles │ ├── 2-common.css │ ├── 2-header.css │ ├── 3-common.css │ ├── 2-footer.css │ ├── 3-footer.css │ ├── 4-footer.css │ ├── 4-common.css │ ├── 3-header.css │ ├── 4-header.css │ ├── 7-places.css │ ├── 4-filters.css │ ├── 5-filters.css │ ├── 6-filters.css │ └── 8-places.css ├── images │ ├── icon.png │ ├── logo.png │ ├── icon_bath.png │ ├── icon_bed.png │ └── icon_group.png ├── 2-index.html ├── 0-index.html ├── 1-index.html ├── 3-index.html ├── 4-index.html ├── 5-index.html ├── 6-index.html ├── 7-index.html ├── 8-index.html ├── 100-index.html ├── 101-index.html ├── 102-index.html └── 103-index.html ├── AUTHORS ├── __pycache__ ├── console.cpython-310.pyc └── console.cpython-311.pyc ├── .vscode └── settings.json ├── Automate.sh ├── LICENSE ├── README.md └── console.py /tests/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /models/engine/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/test_models/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/test_models/test_engine/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/test_models/.#test_review.py: -------------------------------------------------------------------------------- 1 | root@dd09d64a3073.28907 -------------------------------------------------------------------------------- /web_static/styles/2-common.css: -------------------------------------------------------------------------------- 1 | body { 2 | padding: 0 3 | margin: 0 4 | } 5 | -------------------------------------------------------------------------------- /web_static/images/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Innocentsax/AirBnB_clone/HEAD/web_static/images/icon.png -------------------------------------------------------------------------------- /web_static/images/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Innocentsax/AirBnB_clone/HEAD/web_static/images/logo.png -------------------------------------------------------------------------------- /web_static/images/icon_bath.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Innocentsax/AirBnB_clone/HEAD/web_static/images/icon_bath.png -------------------------------------------------------------------------------- /web_static/images/icon_bed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Innocentsax/AirBnB_clone/HEAD/web_static/images/icon_bed.png -------------------------------------------------------------------------------- /AUTHORS: -------------------------------------------------------------------------------- 1 | # Team Members 2 | 3 | UDO INNOCENT CHARLES 4 | BEN ASMAH 5 | -------------------------------------------------------------------------------- /web_static/images/icon_group.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Innocentsax/AirBnB_clone/HEAD/web_static/images/icon_group.png -------------------------------------------------------------------------------- /web_static/styles/2-header.css: -------------------------------------------------------------------------------- 1 | header { 2 | background-color:#FF0000; 3 | height:70px; 4 | width:100%; 5 | } 6 | -------------------------------------------------------------------------------- /__pycache__/console.cpython-310.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Innocentsax/AirBnB_clone/HEAD/__pycache__/console.cpython-310.pyc -------------------------------------------------------------------------------- /__pycache__/console.cpython-311.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Innocentsax/AirBnB_clone/HEAD/__pycache__/console.cpython-311.pyc -------------------------------------------------------------------------------- /models/__pycache__/city.cpython-311.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Innocentsax/AirBnB_clone/HEAD/models/__pycache__/city.cpython-311.pyc -------------------------------------------------------------------------------- /models/__pycache__/user.cpython-311.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Innocentsax/AirBnB_clone/HEAD/models/__pycache__/user.cpython-311.pyc -------------------------------------------------------------------------------- /models/__pycache__/place.cpython-311.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Innocentsax/AirBnB_clone/HEAD/models/__pycache__/place.cpython-311.pyc -------------------------------------------------------------------------------- /models/__pycache__/review.cpython-311.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Innocentsax/AirBnB_clone/HEAD/models/__pycache__/review.cpython-311.pyc -------------------------------------------------------------------------------- /models/__pycache__/state.cpython-311.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Innocentsax/AirBnB_clone/HEAD/models/__pycache__/state.cpython-311.pyc -------------------------------------------------------------------------------- /tests/__pycache__/__init__.cpython-38.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Innocentsax/AirBnB_clone/HEAD/tests/__pycache__/__init__.cpython-38.pyc -------------------------------------------------------------------------------- /models/__pycache__/__init__.cpython-311.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Innocentsax/AirBnB_clone/HEAD/models/__pycache__/__init__.cpython-311.pyc -------------------------------------------------------------------------------- /models/__pycache__/amenity.cpython-311.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Innocentsax/AirBnB_clone/HEAD/models/__pycache__/amenity.cpython-311.pyc -------------------------------------------------------------------------------- /tests/__pycache__/__init__.cpython-311.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Innocentsax/AirBnB_clone/HEAD/tests/__pycache__/__init__.cpython-311.pyc -------------------------------------------------------------------------------- /models/__pycache__/base_model.cpython-311.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Innocentsax/AirBnB_clone/HEAD/models/__pycache__/base_model.cpython-311.pyc -------------------------------------------------------------------------------- /tests/__pycache__/test_console.cpython-311.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Innocentsax/AirBnB_clone/HEAD/tests/__pycache__/test_console.cpython-311.pyc -------------------------------------------------------------------------------- /tests/__pycache__/test_console.cpython-38.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Innocentsax/AirBnB_clone/HEAD/tests/__pycache__/test_console.cpython-38.pyc -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "[python]": { 3 | "editor.defaultFormatter": "ms-python.autopep8" 4 | }, 5 | "python.formatting.provider": "none" 6 | } 7 | -------------------------------------------------------------------------------- /models/engine/__pycache__/__init__.cpython-311.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Innocentsax/AirBnB_clone/HEAD/models/engine/__pycache__/__init__.cpython-311.pyc -------------------------------------------------------------------------------- /models/engine/__pycache__/file_storage.cpython-311.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Innocentsax/AirBnB_clone/HEAD/models/engine/__pycache__/file_storage.cpython-311.pyc -------------------------------------------------------------------------------- /tests/test_models/__pycache__/__init__.cpython-311.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Innocentsax/AirBnB_clone/HEAD/tests/test_models/__pycache__/__init__.cpython-311.pyc -------------------------------------------------------------------------------- /tests/test_models/__pycache__/__init__.cpython-38.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Innocentsax/AirBnB_clone/HEAD/tests/test_models/__pycache__/__init__.cpython-38.pyc -------------------------------------------------------------------------------- /tests/test_models/__pycache__/test_city.cpython-38.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Innocentsax/AirBnB_clone/HEAD/tests/test_models/__pycache__/test_city.cpython-38.pyc -------------------------------------------------------------------------------- /tests/test_models/__pycache__/test_user.cpython-38.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Innocentsax/AirBnB_clone/HEAD/tests/test_models/__pycache__/test_user.cpython-38.pyc -------------------------------------------------------------------------------- /tests/test_models/__pycache__/test_city.cpython-311.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Innocentsax/AirBnB_clone/HEAD/tests/test_models/__pycache__/test_city.cpython-311.pyc -------------------------------------------------------------------------------- /tests/test_models/__pycache__/test_place.cpython-311.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Innocentsax/AirBnB_clone/HEAD/tests/test_models/__pycache__/test_place.cpython-311.pyc -------------------------------------------------------------------------------- /tests/test_models/__pycache__/test_place.cpython-38.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Innocentsax/AirBnB_clone/HEAD/tests/test_models/__pycache__/test_place.cpython-38.pyc -------------------------------------------------------------------------------- /tests/test_models/__pycache__/test_review.cpython-38.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Innocentsax/AirBnB_clone/HEAD/tests/test_models/__pycache__/test_review.cpython-38.pyc -------------------------------------------------------------------------------- /tests/test_models/__pycache__/test_state.cpython-311.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Innocentsax/AirBnB_clone/HEAD/tests/test_models/__pycache__/test_state.cpython-311.pyc -------------------------------------------------------------------------------- /tests/test_models/__pycache__/test_state.cpython-38.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Innocentsax/AirBnB_clone/HEAD/tests/test_models/__pycache__/test_state.cpython-38.pyc -------------------------------------------------------------------------------- /tests/test_models/__pycache__/test_user.cpython-311.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Innocentsax/AirBnB_clone/HEAD/tests/test_models/__pycache__/test_user.cpython-311.pyc -------------------------------------------------------------------------------- /tests/test_models/__pycache__/test_amenity.cpython-311.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Innocentsax/AirBnB_clone/HEAD/tests/test_models/__pycache__/test_amenity.cpython-311.pyc -------------------------------------------------------------------------------- /tests/test_models/__pycache__/test_amenity.cpython-38.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Innocentsax/AirBnB_clone/HEAD/tests/test_models/__pycache__/test_amenity.cpython-38.pyc -------------------------------------------------------------------------------- /tests/test_models/__pycache__/test_review.cpython-311.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Innocentsax/AirBnB_clone/HEAD/tests/test_models/__pycache__/test_review.cpython-311.pyc -------------------------------------------------------------------------------- /tests/test_models/__pycache__/test_base_model.cpython-311.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Innocentsax/AirBnB_clone/HEAD/tests/test_models/__pycache__/test_base_model.cpython-311.pyc -------------------------------------------------------------------------------- /tests/test_models/__pycache__/test_base_model.cpython-38.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Innocentsax/AirBnB_clone/HEAD/tests/test_models/__pycache__/test_base_model.cpython-38.pyc -------------------------------------------------------------------------------- /models/__init__.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | """This initializes the package""" 3 | from models.engine.file_storage import FileStorage 4 | storage = FileStorage() 5 | storage.reload() 6 | -------------------------------------------------------------------------------- /tests/test_models/test_engine/__pycache__/__init__.cpython-311.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Innocentsax/AirBnB_clone/HEAD/tests/test_models/test_engine/__pycache__/__init__.cpython-311.pyc -------------------------------------------------------------------------------- /tests/test_models/test_engine/__pycache__/__init__.cpython-38.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Innocentsax/AirBnB_clone/HEAD/tests/test_models/test_engine/__pycache__/__init__.cpython-38.pyc -------------------------------------------------------------------------------- /Automate.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | echo "Hi Boss Innocent Charles, kindly Enter your commit message" 4 | read message 5 | 6 | 7 | git add . 8 | git commit -m "$message" 9 | git push 10 | -------------------------------------------------------------------------------- /tests/test_models/test_engine/__pycache__/test_file_storage.cpython-38.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Innocentsax/AirBnB_clone/HEAD/tests/test_models/test_engine/__pycache__/test_file_storage.cpython-38.pyc -------------------------------------------------------------------------------- /tests/test_models/test_engine/__pycache__/test_file_storage.cpython-311.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Innocentsax/AirBnB_clone/HEAD/tests/test_models/test_engine/__pycache__/test_file_storage.cpython-311.pyc -------------------------------------------------------------------------------- /web_static/styles/3-common.css: -------------------------------------------------------------------------------- 1 | body{ 2 | margin: 0; 3 | padding: 0; 4 | color: #484848; 5 | font-size: 14px; 6 | font-family: Circular,"Helvetica Neue",Helvetica,Arial,sans-serif; 7 | } 8 | -------------------------------------------------------------------------------- /web_static/styles/2-footer.css: -------------------------------------------------------------------------------- 1 | footer { 2 | background-color:#00FF00; 3 | height:60px; 4 | width:100%; 5 | position:fixed; 6 | bottom: 0; 7 | } 8 | 9 | p { 10 | text-align:center; 11 | line-height:30px 12 | } 13 | -------------------------------------------------------------------------------- /models/state.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | """This module creates a User class""" 3 | 4 | from models.base_model import BaseModel 5 | 6 | 7 | class State(BaseModel): 8 | """This is the class for managing state objects""" 9 | 10 | name = "" 11 | -------------------------------------------------------------------------------- /models/amenity.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | """This module creates a Amenity class""" 3 | 4 | from models.base_model import BaseModel 5 | 6 | 7 | class Amenity(BaseModel): 8 | """This is a class for managing amenity objects""" 9 | 10 | name = "" 11 | -------------------------------------------------------------------------------- /web_static/styles/3-footer.css: -------------------------------------------------------------------------------- 1 | footer { 2 | background-color: white; 3 | height:60px; 4 | width:100%; 5 | border-top: 1px solid #CCCCCC; 6 | 7 | bottom: 0; 8 | } 9 | 10 | p { 11 | text-align:center; 12 | line-height:30px; 13 | } 14 | -------------------------------------------------------------------------------- /models/city.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | """This module creates a User class""" 3 | 4 | from models.base_model import BaseModel 5 | 6 | 7 | class City(BaseModel): 8 | """This is the class for managing city objects""" 9 | 10 | state_id = "" 11 | name = "" 12 | -------------------------------------------------------------------------------- /web_static/styles/4-footer.css: -------------------------------------------------------------------------------- 1 | footer { 2 | background-color: white; 3 | height:60px; 4 | width:100%; 5 | border-top: 1px solid #CCCCCC; 6 | position:fixed; 7 | bottom: 0; 8 | } 9 | 10 | p { 11 | text-align:center; 12 | line-height:30px; 13 | } 14 | -------------------------------------------------------------------------------- /web_static/styles/4-common.css: -------------------------------------------------------------------------------- 1 | body{ 2 | margin: 0; 3 | padding: 0; 4 | color: #484848; 5 | font-size: 14px; 6 | font-family: Circular,"Helvetica Neue",Helvetica,Arial,sans-serif; 7 | } 8 | 9 | body .container{ 10 | max-width: 1000px; 11 | margin: 30px auto; 12 | } 13 | -------------------------------------------------------------------------------- /models/review.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | """This module creates a Review class""" 3 | 4 | from models.base_model import BaseModel 5 | 6 | 7 | class Review(BaseModel): 8 | """This is the class for managing review objects""" 9 | 10 | place_id = "" 11 | user_id = "" 12 | text = "" 13 | -------------------------------------------------------------------------------- /models/user.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | """This module creates a User class""" 3 | from models.base_model import BaseModel 4 | 5 | 6 | class User(BaseModel): 7 | """This is the class for managing user objects""" 8 | 9 | email = "" 10 | password = "" 11 | first_name = "" 12 | last_name = "" 13 | -------------------------------------------------------------------------------- /web_static/styles/3-header.css: -------------------------------------------------------------------------------- 1 | header { 2 | color: white; 3 | height: 70px; 4 | width: 100%; 5 | border-bottom: 1px solid #CCCCCC; 6 | 7 | } 8 | 9 | header .logo { 10 | background-image: url("../images/logo.png"); 11 | background-repeat: no-repeat; 12 | display: block; 13 | height: 100%; 14 | padding-left: 20px; 15 | } 16 | -------------------------------------------------------------------------------- /web_static/styles/4-header.css: -------------------------------------------------------------------------------- 1 | header { 2 | color: white; 3 | height: 70px; 4 | width: 100%; 5 | border-bottom: 1px solid #CCCCCC; 6 | 7 | } 8 | 9 | header .logo { 10 | background-image: url("../images/logo.png"); 11 | background-repeat: no-repeat; 12 | display: block; 13 | height: 100%; 14 | padding-left: 20px; 15 | } 16 | -------------------------------------------------------------------------------- /web_static/2-index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 |
11 |
12 |

Holberton School

13 |
14 | 15 | 16 | -------------------------------------------------------------------------------- /web_static/0-index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 |
9 |
10 |

Holberton School

11 |
12 | 13 | 14 | -------------------------------------------------------------------------------- /web_static/1-index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 9 | 10 | 11 |
12 |
13 |
14 |

Holberton School

15 |
16 | 17 | 18 | -------------------------------------------------------------------------------- /web_static/styles/7-places.css: -------------------------------------------------------------------------------- 1 | .places h1{ 2 | text-align: left: 3 | font-size: 30px; 4 | width: 100%; 5 | } 6 | 7 | .places article{ 8 | width: 390px; 9 | border: 1px solid #FF5A5F; 10 | border-radius: 4px; 11 | padding: 20px; 12 | margin: 20px; 13 | display: inline-block; 14 | text-align: center; 15 | } 16 | 17 | .places { 18 | display: flex; 19 | flex-direction: row; 20 | flex-wrap: wrap; 21 | justify-content: center; 22 | } 23 | -------------------------------------------------------------------------------- /models/place.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | """This module creates a Place class""" 3 | 4 | from models.base_model import BaseModel 5 | 6 | 7 | class Place(BaseModel): 8 | """This is the class for managing place objects""" 9 | 10 | city_id = "" 11 | user_id = "" 12 | name = "" 13 | description = "" 14 | number_rooms = 0 15 | number_bathrooms = 0 16 | max_guest = 0 17 | price_by_night = 0 18 | latitude = 0.0 19 | longitude = 0.0 20 | amenity_ids = [] 21 | -------------------------------------------------------------------------------- /web_static/3-index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 |
11 | 12 |
13 |
14 |

Holberton School

15 |
16 | 17 | 18 | -------------------------------------------------------------------------------- /web_static/styles/4-filters.css: -------------------------------------------------------------------------------- 1 | .filters{ 2 | background-color:white; 3 | height:70px; 4 | width:100%; 5 | border: 1px solid #DDDDDD; 6 | border-radius: 4px; 7 | position: relative; 8 | } 9 | 10 | button{ 11 | font-size: 18px; 12 | background-color:#FF5A5F; 13 | color: #FFFFFF; 14 | height: 48px; 15 | width: 20%; 16 | border-radius: 4px; 17 | border: none; 18 | position: absolute; 19 | right: 30px; 20 | top: 10px; 21 | } 22 | 23 | button:hover { 24 | opacity: 0.9; 25 | } 26 | -------------------------------------------------------------------------------- /web_static/4-index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 |
14 |
15 |
16 | 17 |
18 |
19 |
20 |

Holberton School

21 |
22 | 23 | 24 | -------------------------------------------------------------------------------- /web_static/5-index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 |
14 |
15 |
16 | 17 |
18 |

States

19 |

New York, Colorado...

20 |
21 |
22 |

Amenities

23 |

Air Conditioning, Kitchen...

24 |
25 |
26 |
27 |
28 |

Holberton School

29 |
30 | 31 | 32 | -------------------------------------------------------------------------------- /web_static/styles/5-filters.css: -------------------------------------------------------------------------------- 1 | .filters{ 2 | background-color:white; 3 | height:70px; 4 | width:100%; 5 | border: 1px solid #DDDDDD; 6 | border-radius: 4px; 7 | position: relative; 8 | } 9 | 10 | button{ 11 | font-size: 18px; 12 | background-color:#FF5A5F; 13 | color: #FFFFFF; 14 | height: 48px; 15 | width: 20%; 16 | border-radius: 4px; 17 | border: none; 18 | position: absolute; 19 | right: 30px; 20 | top: 10px; 21 | } 22 | 23 | button:hover { 24 | opacity: 0.9; 25 | } 26 | 27 | .filters div{ 28 | display: inline-block; 29 | position: relative; 30 | height: 100%; 31 | width: 25%; 32 | margin-left: 4%; 33 | line-height: 6px; 34 | } 35 | 36 | .locations{ 37 | border-right: 1px solid #DDDDDD; 38 | } 39 | 40 | .filters h3{ 41 | font-weight: 600; 42 | } 43 | .filters h4 { 44 | font-weight: 400; 45 | font-size: 14px; 46 | } 47 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023 INNOCENT CHARLES UDO 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /web_static/6-index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 |
14 |
15 |
16 | 17 | 18 |
19 |

States

20 |

New York, Colorado...

21 | 22 |
    23 |
  • California

  • 24 |
  • San Francisco
  • 25 |
  • New York

  • 26 |
  • Buffalo
  • 27 |
28 |
29 | 30 |
31 |

Amenities

32 |

Air Conditioning, Kitchen...

33 |
    34 |
  • Internet
  • 35 |
  • TV
  • 36 |
  • Kitchen
  • 37 |
  • Iron
  • 38 |
39 |
40 | 41 |
42 |
43 |
44 |

Holberton School

45 |
46 | 47 | 48 | -------------------------------------------------------------------------------- /web_static/styles/6-filters.css: -------------------------------------------------------------------------------- 1 | .filters{ 2 | background-color:white; 3 | height:70px; 4 | width:100%; 5 | border: 1px solid #DDDDDD; 6 | border-radius: 4px; 7 | position: relative; 8 | } 9 | 10 | button{ 11 | font-size: 18px; 12 | background-color:#FF5A5F; 13 | color: #FFFFFF; 14 | height: 48px; 15 | width: 20%; 16 | border-radius: 4px; 17 | border: none; 18 | position: absolute; 19 | right: 30px; 20 | top: 10px; 21 | } 22 | 23 | button:hover { 24 | opacity: 0.9; 25 | } 26 | 27 | .filters div{ 28 | float: left; 29 | position: relative; 30 | height: 100%; 31 | width: 25%; 32 | margin-left: 4%; 33 | line-height: 6px; 34 | } 35 | 36 | .locations{ 37 | border-right: 1px solid #DDDDDD; 38 | } 39 | 40 | .filters h3{ 41 | font-weight: 600; 42 | } 43 | .filters h4 { 44 | font-weight: 400; 45 | font-size: 14px; 46 | } 47 | 48 | 49 | .popover { 50 | background-color:#FAFAFA; 51 | width: 100%; 52 | border: 1px solid #DDDDDD; 53 | border-radius: 4px; 54 | visibility: hidden; 55 | line-height: normal; 56 | margin-top: 22px; 57 | margin-left: -41px; 58 | height: 200px; 59 | list-style-type: none; 60 | 61 | } 62 | .locations:hover .popover, .amenities:hover .popover{ 63 | visibility: visible; 64 | } 65 | 66 | .popover ul, .popover li { 67 | line-height: 160%; 68 | } 69 | .amenities .popover{ 70 | padding-top: 20px; 71 | height: 150% 72 | } 73 | -------------------------------------------------------------------------------- /web_static/7-index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 |
15 |
16 |
17 | 18 | 19 |
20 |

States

21 |

New York, Colorado...

22 | 23 |
    24 |
  • California

  • 25 |
  • San Francisco
  • 26 |
  • New York

  • 27 |
  • Buffalo
  • 28 |
29 |
30 | 31 |
32 |

Amenities

33 |

Air Conditioning, Kitchen...

34 |
    35 |
  • Internet
  • 36 |
  • TV
  • 37 |
  • Kitchen
  • 38 |
  • Iron
  • 39 |
40 |
41 |
42 |
43 |

Places

44 |

My Home

45 |

Tiny House

46 |

A Suite

47 |
48 | 49 |
50 |
51 |

Holberton School

52 |
53 | 54 | 55 | -------------------------------------------------------------------------------- /web_static/styles/8-places.css: -------------------------------------------------------------------------------- 1 | .places h1{ 2 | text-align: left; 3 | font-size: 30px; 4 | width: 100%; 5 | } 6 | 7 | .places article{ 8 | width: 390px; 9 | border: 1px solid #FF5A5F; 10 | border-radius: 4px; 11 | padding: 20px; 12 | margin: 20px; 13 | display: inline-block; 14 | text-align: center; 15 | } 16 | 17 | .places { 18 | display: flex; 19 | flex-direction: row; 20 | flex-wrap: wrap; 21 | justify-content: center; 22 | } 23 | 24 | .price_by_night { 25 | color: #FF5A5F; 26 | border: 4px solid #FF5A5F; 27 | border-radius: 50%; 28 | min-width: 60px; 29 | width: 0px; 30 | height: 60px; 31 | font-size: 30px; 32 | 33 | position: relative; 34 | bottom: 71px; 35 | left: 322px; 36 | line-height: 2; 37 | padding: 8px; 38 | } 39 | 40 | .information { 41 | height: 80px; 42 | border-top: 1px solid #DDDDDD; 43 | border-bottom: 1px solid #DDDDDD; 44 | padding-top: 10px; 45 | margin-top: -40px; 46 | 47 | } 48 | 49 | .max_guest { 50 | background-image: url("../images/icon_group.png"); 51 | background-repeat: no-repeat; 52 | width: 100px; 53 | } 54 | 55 | .number_rooms { 56 | background-image: url("../images/icon_bed.png"); 57 | background-repeat: no-repeat; 58 | width: 100px; 59 | } 60 | 61 | .number_bathrooms { 62 | background-image: url("../images/icon_bath.png"); 63 | background-repeat: no-repeat; 64 | width: 100px; 65 | 66 | } 67 | 68 | .max_guest, .number_rooms, .number_bathrooms { 69 | display: inline-block; 70 | height: 100px; 71 | background-position: 24px 20px; 72 | } 73 | 74 | 75 | .user, .description { 76 | text-align: left; 77 | padding: 5px; 78 | } 79 | -------------------------------------------------------------------------------- /models/base_model.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | """This script is the base model""" 3 | 4 | import uuid 5 | from datetime import datetime 6 | from models import storage 7 | 8 | 9 | class BaseModel: 10 | 11 | """This is the class from which all other classes will inherit""" 12 | 13 | def __init__(self, *args, **kwargs): 14 | """This initializes instance attributes 15 | 16 | Args: 17 | - *args: list of arguments 18 | - **kwargs: dict of key-values arguments 19 | """ 20 | 21 | if kwargs is not None and kwargs != {}: 22 | for key in kwargs: 23 | if key == "created_at": 24 | self.__dict__["created_at"] = datetime.strptime( 25 | kwargs["created_at"], "%Y-%m-%dT%H:%M:%S.%f") 26 | elif key == "updated_at": 27 | self.__dict__["updated_at"] = datetime.strptime( 28 | kwargs["updated_at"], "%Y-%m-%dT%H:%M:%S.%f") 29 | else: 30 | self.__dict__[key] = kwargs[key] 31 | else: 32 | self.id = str(uuid.uuid4()) 33 | self.created_at = datetime.now() 34 | self.updated_at = datetime.now() 35 | storage.new(self) 36 | 37 | def __str__(self): 38 | """Returns official string representation""" 39 | 40 | return "[{}] ({}) {}".\ 41 | format(type(self).__name__, self.id, self.__dict__) 42 | 43 | def save(self): 44 | """updates the public instance attribute updated_at""" 45 | 46 | self.updated_at = datetime.now() 47 | storage.save() 48 | 49 | def to_dict(self): 50 | """This returns a dictionary containing all keys/values of __dict__""" 51 | 52 | my_dict = self.__dict__.copy() 53 | my_dict["__class__"] = type(self).__name__ 54 | my_dict["created_at"] = my_dict["created_at"].isoformat() 55 | my_dict["updated_at"] = my_dict["updated_at"].isoformat() 56 | return my_dict 57 | -------------------------------------------------------------------------------- /web_static/8-index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 |
15 |
16 |
17 | 18 | 19 |
20 |

States

21 |

New York, Colorado...

22 | 23 |
    24 |
  • California

  • 25 |
  • San Francisco
  • 26 |
  • New York

  • 27 |
  • Buffalo
  • 28 |
29 |
30 | 31 |
32 |

Amenities

33 |

Air Conditioning, Kitchen...

34 |
    35 |
  • Internet
  • 36 |
  • TV
  • 37 |
  • Kitchen
  • 38 |
  • Iron
  • 39 |
40 |
41 |
42 |
43 |

Places

44 |

My Home

45 |
$82
46 |
47 |
2 guests
48 |
1 bedrooms
49 |
1 bathrooms
50 |
51 |
Owner: Stevie Nicks
52 |
This listing is for a private room in my house. I will be here during your stay. I live in a nice, quiet family neighborhood located near the collage campuses as well as the subway that takes you straight into the heart of downtown.
53 |
54 |

Tiny House

55 |
$65
56 |
57 |
4 guests
58 |
2 bedrooms
59 |
1 bathrooms
60 |
61 |
Owner: John Lennon
62 |
63 | This 4-bedroom tiny house is less than a 30-minute drive from Niagara Falls and is in the heart and soul of North Buffalo and one of the city's most happening neighborhoods! The apartment is in a charming, vintage home near many top-rated local restaurants and shopping boutiques. Free street parking is easily accessible.
64 | 65 |
66 |

A Suite

67 |
$190
68 |
69 |
6 guests
70 |
3 bedrooms
71 |
2 bathrooms
72 |
73 |
Owner: Janis Joplin
74 |
Wonderful 1br suite located in the heart of Elmwood Village. Elmwood village is a prime location. The apartment is within walking distance of many stores, large parks, coffee shops, restaurants, and the best bars/nightclubs Buffalo has to offer. This is the perfect location for anyone exploring Buffalo's great attractions.
75 |
76 |
77 | 78 |
79 |
80 |

Holberton School

81 |
82 | 83 | 84 | -------------------------------------------------------------------------------- /models/engine/file_storage.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | """Module for FileStorage class.""" 3 | import datetime 4 | import json 5 | import os 6 | 7 | 8 | class FileStorage: 9 | 10 | """This is the class for storing and retrieving data""" 11 | __file_path = "file.json" 12 | __objects = {} 13 | 14 | def all(self): 15 | """This returns the dictionary __objects""" 16 | return FileStorage.__objects 17 | 18 | def new(self, obj): 19 | """This sets in __objects the obj with key .id""" 20 | key = "{}.{}".format(type(obj).__name__, obj.id) 21 | FileStorage.__objects[key] = obj 22 | 23 | def save(self): 24 | """This serializes __objects to the JSON file (path: __file_path)""" 25 | with open(FileStorage.__file_path, "w", encoding="utf-8") as f: 26 | d = {k: v.to_dict() for k, v in FileStorage.__objects.items()} 27 | json.dump(d, f) 28 | 29 | def classes(self): 30 | """This returns a dictionary of valid classes and their references""" 31 | from models.base_model import BaseModel 32 | from models.user import User 33 | from models.state import State 34 | from models.city import City 35 | from models.amenity import Amenity 36 | from models.place import Place 37 | from models.review import Review 38 | 39 | classes = {"BaseModel": BaseModel, 40 | "User": User, 41 | "State": State, 42 | "City": City, 43 | "Amenity": Amenity, 44 | "Place": Place, 45 | "Review": Review} 46 | return classes 47 | 48 | def reload(self): 49 | """This reloads the stored objects""" 50 | if not os.path.isfile(FileStorage.__file_path): 51 | return 52 | with open(FileStorage.__file_path, "r", encoding="utf-8") as f: 53 | obj_dict = json.load(f) 54 | obj_dict = {k: self.classes()[v["__class__"]](**v) 55 | for k, v in obj_dict.items()} 56 | # TODO: should this overwrite or insert? 57 | FileStorage.__objects = obj_dict 58 | 59 | def attributes(self): 60 | """This returns the valid attributes and their types for classname""" 61 | attributes = { 62 | "BaseModel": 63 | {"id": str, 64 | "created_at": datetime.datetime, 65 | "updated_at": datetime.datetime}, 66 | "User": 67 | {"email": str, 68 | "password": str, 69 | "first_name": str, 70 | "last_name": str}, 71 | "State": 72 | {"name": str}, 73 | "City": 74 | {"state_id": str, 75 | "name": str}, 76 | "Amenity": 77 | {"name": str}, 78 | "Place": 79 | {"city_id": str, 80 | "user_id": str, 81 | "name": str, 82 | "description": str, 83 | "number_rooms": int, 84 | "number_bathrooms": int, 85 | "max_guest": int, 86 | "price_by_night": int, 87 | "latitude": float, 88 | "longitude": float, 89 | "amenity_ids": list}, 90 | "Review": 91 | {"place_id": str, 92 | "user_id": str, 93 | "text": str} 94 | } 95 | return attributes 96 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # AirBnB Clone - The Console 2 | 3 | 4 | 5 | ## Table of Contents 6 | 7 | * [Description](#description) 8 | * [Purpose](#purpose) 9 | * [Requirements](#requirements) 10 | * [File Structure](#file-structure) 11 | * [Usage Examples](#usage-examples) 12 | * [Bugs](#bugs) 13 | * [Authors](#authors) 14 | * [License](#license) 15 | 16 | 17 | ## Description 18 | 19 | 20 | 21 | ## Purpose 22 | 23 | The purpose of this project is to understand how to: 24 | * create a Python package 25 | * create a command interpreter using the `cmd` module 26 | * serialize and deserialize a Class 27 | * write and read a JSON file 28 | * manage `datetime` 29 | * use `*args` and `**kwargs` 30 | * handle named arguments in a function 31 | 32 | ### HTML and CSS concepts 33 | 34 | Now that you have a command interpreter for managing your AirBnB objects, it’s time to make them alive! 35 | 36 | Before developing a big and complex web application, we will build the front end step-by-step. 37 | 38 | The first step is to “design” / “sketch” / “prototype” each element: 39 | 40 | - Create simple HTML static pages 41 | - Style guide 42 | - Fake contents 43 | - No Javascript 44 | - No data loaded from anything 45 | 46 | During this project, you will learn how to manipulate HTML and CSS languages. HTML is the structure of your page, it should be the first thing to write. CSS is the styling of your page, the design. I really encourage you to fix your HTML part before starting the styling. Indeed, without any structure, you can’t apply any design. 47 | 48 | ## Learning Objectives 49 | 50 | - What is `HTML` 51 | - How to create an `HTML page` 52 | - What is a `markup language` 53 | - What is the `DOM` 54 | - What is an `element / tag` 55 | - What is an attribute 56 | - How does the browser load a webpage 57 | - What is `CSS` 58 | - How to add style to an element 59 | - What is a `class` 60 | - What is a `selector` 61 | - How to compute `CSS Specificity Value` 62 | - What are `Box properties` in `CSS` 63 | 64 | ## Requirements 65 | 66 | ### PYTHON SCRIPT REQUIREMENTS 67 | * allowed editors: `vi`, `vim`, `emacs` 68 | * the first line of all files should be exactly `#!/usr/bin/python3` 69 | * all code should use the `PEP8` style (version 1.7.*) 70 | * all files must be executable 71 | * all files will be interpreted/compiled on Ubuntu 14.04 LTS using `python3` (version 3.4.3) 72 | 73 | ### PYTHON TEST CASE REQUIREMENTS 74 | * all test files should be in the folder `tests` 75 | * all test files should be text files (extension: `.txt`) 76 | * all test files should be executed using the command `python3 -m doctest ./tests/*` 77 | * all modules should have documentation `python3 -c 'print(__import__("my_module").__doc__)'` 78 | * all functions (inside and outside of classes) should have documentation `python3 -c 'print(__import__("my_module").my_funct\ 79 | ion.__doc__)'` 80 | 81 | ### General 82 | 83 | - Allowed editors: `vi`, `vim`, `emacs` 84 | - All your files should end with a new line 85 | - A `README.md` file, at the root of the folder of the project, is mandatory 86 | - Your code should be `W3C compliant` and validate with `W3C-Validator` 87 | - All your CSS files should be in styles folder 88 | - All your images should be in images folder 89 | - You are not allowed to use `!important` and `id (#... in the CSS file)` 90 | - You are not allowed to use tags `img`, `embed` and `iframe` 91 | - You are not allowed to use `Javascript` 92 | - Current screenshots have been done on Chrome 56 or more. 93 | - No cross browsers 94 | - You have to follow all requirements but some margin/padding are missing - you should try to fit as much as you can to screenshots 95 | 96 | ## Usage Examples for console 97 | 98 | ### Interactive Mode 99 | 100 | ```python3 101 | ~/me$ ./console.py 102 | (hbnb) help 103 | 104 | Documented commands (type help ): 105 | ======================================== 106 | EOF help quit 107 | 108 | (hbnb) 109 | (hbnb) 110 | (hbnb) quit 111 | ~/me$ 112 | ``` 113 | 114 | ### Non-Interactive Mode 115 | 116 | ```python3 117 | ~/me$ echo "help" | ./console.py 118 | (hbnb) 119 | 120 | Documented commands (type help ): 121 | ======================================== 122 | EOF help quit 123 | (hbnb) 124 | 125 | ~/me$ cat test_help 126 | help 127 | ~/me$ cat test_help | ./console.py 128 | (hbnb) 129 | 130 | Documented commands (type help ): 131 | ======================================== 132 | EOF help quit 133 | (hbnb) 134 | ~/me$ 135 | ``` 136 | 137 | ## Bugs 138 | 139 | At this time, there are no known bugs. 140 | 141 | ## License 142 | 143 | **AirBnB Clone** is open source and free to download and use 144 | 145 | ## Author 146 | @ [UDO INNOCENT CHARLES](https://github.com/Innocentsax) 147 | @ [BEN ASMAH](https://github.com/drbenasmah) 148 | -------------------------------------------------------------------------------- /tests/test_models/test_engine/test_file_storage.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | """Defines unittests for models/engine/file_storage.py. 3 | 4 | Unittest classes: 5 | TestFileStorage_instantiation 6 | TestFileStorage_methods 7 | """ 8 | import os 9 | import json 10 | import models 11 | import unittest 12 | from datetime import datetime 13 | from models.base_model import BaseModel 14 | from models.engine.file_storage import FileStorage 15 | from models.user import User 16 | from models.state import State 17 | from models.place import Place 18 | from models.city import City 19 | from models.amenity import Amenity 20 | from models.review import Review 21 | 22 | 23 | class TestFileStorage_instantiation(unittest.TestCase): 24 | """Unittests for testing instantiation of the FileStorage class.""" 25 | 26 | def test_FileStorage_instantiation_no_args(self): 27 | self.assertEqual(type(FileStorage()), FileStorage) 28 | 29 | def test_FileStorage_instantiation_with_arg(self): 30 | with self.assertRaises(TypeError): 31 | FileStorage(None) 32 | 33 | def test_FileStorage_file_path_is_private_str(self): 34 | self.assertEqual(str, type(FileStorage._FileStorage__file_path)) 35 | 36 | def testFileStorage_objects_is_private_dict(self): 37 | self.assertEqual(dict, type(FileStorage._FileStorage__objects)) 38 | 39 | def test_storage_initializes(self): 40 | self.assertEqual(type(models.storage), FileStorage) 41 | 42 | 43 | class TestFileStorage_methods(unittest.TestCase): 44 | """Unittests for testing methods of the FileStorage class.""" 45 | 46 | @classmethod 47 | def setUp(self): 48 | try: 49 | os.rename("file.json", "tmp") 50 | except IOError: 51 | pass 52 | 53 | @classmethod 54 | def tearDown(self): 55 | try: 56 | os.remove("file.json") 57 | except IOError: 58 | pass 59 | try: 60 | os.rename("tmp", "file.json") 61 | except IOError: 62 | pass 63 | FileStorage._FileStorage__objects = {} 64 | 65 | def test_all(self): 66 | self.assertEqual(dict, type(models.storage.all())) 67 | 68 | def test_all_with_arg(self): 69 | with self.assertRaises(TypeError): 70 | models.storage.all(None) 71 | 72 | def test_new(self): 73 | bm = BaseModel() 74 | us = User() 75 | st = State() 76 | pl = Place() 77 | cy = City() 78 | am = Amenity() 79 | rv = Review() 80 | models.storage.new(bm) 81 | models.storage.new(us) 82 | models.storage.new(st) 83 | models.storage.new(pl) 84 | models.storage.new(cy) 85 | models.storage.new(am) 86 | models.storage.new(rv) 87 | self.assertIn("BaseModel." + bm.id, models.storage.all().keys()) 88 | self.assertIn(bm, models.storage.all().values()) 89 | self.assertIn("User." + us.id, models.storage.all().keys()) 90 | self.assertIn(us, models.storage.all().values()) 91 | self.assertIn("State." + st.id, models.storage.all().keys()) 92 | self.assertIn(st, models.storage.all().values()) 93 | self.assertIn("Place." + pl.id, models.storage.all().keys()) 94 | self.assertIn(pl, models.storage.all().values()) 95 | self.assertIn("City." + cy.id, models.storage.all().keys()) 96 | self.assertIn(cy, models.storage.all().values()) 97 | self.assertIn("Amenity." + am.id, models.storage.all().keys()) 98 | self.assertIn(am, models.storage.all().values()) 99 | self.assertIn("Review." + rv.id, models.storage.all().keys()) 100 | self.assertIn(rv, models.storage.all().values()) 101 | 102 | def test_new_with_args(self): 103 | with self.assertRaises(TypeError): 104 | models.storage.new(BaseModel(), 1) 105 | 106 | def test_new_with_None(self): 107 | with self.assertRaises(AttributeError): 108 | models.storage.new(None) 109 | 110 | def test_save(self): 111 | bm = BaseModel() 112 | us = User() 113 | st = State() 114 | pl = Place() 115 | cy = City() 116 | am = Amenity() 117 | rv = Review() 118 | models.storage.new(bm) 119 | models.storage.new(us) 120 | models.storage.new(st) 121 | models.storage.new(pl) 122 | models.storage.new(cy) 123 | models.storage.new(am) 124 | models.storage.new(rv) 125 | models.storage.save() 126 | save_text = "" 127 | with open("file.json", "r") as f: 128 | save_text = f.read() 129 | self.assertIn("BaseModel." + bm.id, save_text) 130 | self.assertIn("User." + us.id, save_text) 131 | self.assertIn("State." + st.id, save_text) 132 | self.assertIn("Place." + pl.id, save_text) 133 | self.assertIn("City." + cy.id, save_text) 134 | self.assertIn("Amenity." + am.id, save_text) 135 | self.assertIn("Review." + rv.id, save_text) 136 | 137 | def test_save_with_arg(self): 138 | with self.assertRaises(TypeError): 139 | models.storage.save(None) 140 | 141 | def test_reload(self): 142 | bm = BaseModel() 143 | us = User() 144 | st = State() 145 | pl = Place() 146 | cy = City() 147 | am = Amenity() 148 | rv = Review() 149 | models.storage.new(bm) 150 | models.storage.new(us) 151 | models.storage.new(st) 152 | models.storage.new(pl) 153 | models.storage.new(cy) 154 | models.storage.new(am) 155 | models.storage.new(rv) 156 | models.storage.save() 157 | models.storage.reload() 158 | objs = FileStorage._FileStorage__objects 159 | self.assertIn("BaseModel." + bm.id, objs) 160 | self.assertIn("User." + us.id, objs) 161 | self.assertIn("State." + st.id, objs) 162 | self.assertIn("Place." + pl.id, objs) 163 | self.assertIn("City." + cy.id, objs) 164 | self.assertIn("Amenity." + am.id, objs) 165 | self.assertIn("Review." + rv.id, objs) 166 | 167 | def test_reload_with_arg(self): 168 | with self.assertRaises(TypeError): 169 | models.storage.reload(None) 170 | 171 | 172 | if __name__ == "__main__": 173 | unittest.main() 174 | -------------------------------------------------------------------------------- /tests/test_models/test_state.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | """Defines unittests for models/state.py. 3 | 4 | Unittest classes: 5 | TestState_instantiation 6 | TestState_save 7 | TestState_to_dict 8 | """ 9 | import os 10 | import models 11 | import unittest 12 | from datetime import datetime 13 | from time import sleep 14 | from models.state import State 15 | 16 | 17 | class TestState_instantiation(unittest.TestCase): 18 | """Unittests for testing instantiation of the State class.""" 19 | 20 | def test_no_args_instantiates(self): 21 | self.assertEqual(State, type(State())) 22 | 23 | def test_new_instance_stored_in_objects(self): 24 | self.assertIn(State(), models.storage.all().values()) 25 | 26 | def test_id_is_public_str(self): 27 | self.assertEqual(str, type(State().id)) 28 | 29 | def test_created_at_is_public_datetime(self): 30 | self.assertEqual(datetime, type(State().created_at)) 31 | 32 | def test_updated_at_is_public_datetime(self): 33 | self.assertEqual(datetime, type(State().updated_at)) 34 | 35 | def test_name_is_public_class_attribute(self): 36 | st = State() 37 | self.assertEqual(str, type(State.name)) 38 | self.assertIn("name", dir(st)) 39 | self.assertNotIn("name", st.__dict__) 40 | 41 | def test_two_states_unique_ids(self): 42 | st1 = State() 43 | st2 = State() 44 | self.assertNotEqual(st1.id, st2.id) 45 | 46 | def test_two_states_different_created_at(self): 47 | st1 = State() 48 | sleep(0.05) 49 | st2 = State() 50 | self.assertLess(st1.created_at, st2.created_at) 51 | 52 | def test_two_states_different_updated_at(self): 53 | st1 = State() 54 | sleep(0.05) 55 | st2 = State() 56 | self.assertLess(st1.updated_at, st2.updated_at) 57 | 58 | def test_str_representation(self): 59 | dt = datetime.today() 60 | dt_repr = repr(dt) 61 | st = State() 62 | st.id = "123456" 63 | st.created_at = st.updated_at = dt 64 | ststr = st.__str__() 65 | self.assertIn("[State] (123456)", ststr) 66 | self.assertIn("'id': '123456'", ststr) 67 | self.assertIn("'created_at': " + dt_repr, ststr) 68 | self.assertIn("'updated_at': " + dt_repr, ststr) 69 | 70 | def test_args_unused(self): 71 | st = State(None) 72 | self.assertNotIn(None, st.__dict__.values()) 73 | 74 | def test_instantiation_with_kwargs(self): 75 | dt = datetime.today() 76 | dt_iso = dt.isoformat() 77 | st = State(id="345", created_at=dt_iso, updated_at=dt_iso) 78 | self.assertEqual(st.id, "345") 79 | self.assertEqual(st.created_at, dt) 80 | self.assertEqual(st.updated_at, dt) 81 | 82 | def test_instantiation_with_None_kwargs(self): 83 | with self.assertRaises(TypeError): 84 | State(id=None, created_at=None, updated_at=None) 85 | 86 | 87 | class TestState_save(unittest.TestCase): 88 | """Unittests for testing save method of the State class.""" 89 | 90 | @classmethod 91 | def setUp(self): 92 | try: 93 | os.rename("file.json", "tmp") 94 | except IOError: 95 | pass 96 | 97 | def tearDown(self): 98 | try: 99 | os.remove("file.json") 100 | except IOError: 101 | pass 102 | try: 103 | os.rename("tmp", "file.json") 104 | except IOError: 105 | pass 106 | 107 | def test_one_save(self): 108 | st = State() 109 | sleep(0.05) 110 | first_updated_at = st.updated_at 111 | st.save() 112 | self.assertLess(first_updated_at, st.updated_at) 113 | 114 | def test_two_saves(self): 115 | st = State() 116 | sleep(0.05) 117 | first_updated_at = st.updated_at 118 | st.save() 119 | second_updated_at = st.updated_at 120 | self.assertLess(first_updated_at, second_updated_at) 121 | sleep(0.05) 122 | st.save() 123 | self.assertLess(second_updated_at, st.updated_at) 124 | 125 | def test_save_with_arg(self): 126 | st = State() 127 | with self.assertRaises(TypeError): 128 | st.save(None) 129 | 130 | def test_save_updates_file(self): 131 | st = State() 132 | st.save() 133 | stid = "State." + st.id 134 | with open("file.json", "r") as f: 135 | self.assertIn(stid, f.read()) 136 | 137 | 138 | class TestState_to_dict(unittest.TestCase): 139 | """Unittests for testing to_dict method of the State class.""" 140 | 141 | def test_to_dict_type(self): 142 | self.assertTrue(dict, type(State().to_dict())) 143 | 144 | def test_to_dict_contains_correct_keys(self): 145 | st = State() 146 | self.assertIn("id", st.to_dict()) 147 | self.assertIn("created_at", st.to_dict()) 148 | self.assertIn("updated_at", st.to_dict()) 149 | self.assertIn("__class__", st.to_dict()) 150 | 151 | def test_to_dict_contains_added_attributes(self): 152 | st = State() 153 | st.middle_name = "Holberton" 154 | st.my_number = 98 155 | self.assertEqual("Holberton", st.middle_name) 156 | self.assertIn("my_number", st.to_dict()) 157 | 158 | def test_to_dict_datetime_attributes_are_strs(self): 159 | st = State() 160 | st_dict = st.to_dict() 161 | self.assertEqual(str, type(st_dict["id"])) 162 | self.assertEqual(str, type(st_dict["created_at"])) 163 | self.assertEqual(str, type(st_dict["updated_at"])) 164 | 165 | def test_to_dict_output(self): 166 | dt = datetime.today() 167 | st = State() 168 | st.id = "123456" 169 | st.created_at = st.updated_at = dt 170 | tdict = { 171 | 'id': '123456', 172 | '__class__': 'State', 173 | 'created_at': dt.isoformat(), 174 | 'updated_at': dt.isoformat(), 175 | } 176 | self.assertDictEqual(st.to_dict(), tdict) 177 | 178 | def test_contrast_to_dict_dunder_dict(self): 179 | st = State() 180 | self.assertNotEqual(st.to_dict(), st.__dict__) 181 | 182 | def test_to_dict_with_arg(self): 183 | st = State() 184 | with self.assertRaises(TypeError): 185 | st.to_dict(None) 186 | 187 | 188 | if __name__ == "__main__": 189 | unittest.main() 190 | -------------------------------------------------------------------------------- /tests/test_models/test_user.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | """Defines unittests for models/user.py. 3 | 4 | Unittest classes: 5 | TestUser_instantiation 6 | TestUser_save 7 | TestUser_to_dict 8 | """ 9 | import os 10 | import models 11 | import unittest 12 | from datetime import datetime 13 | from time import sleep 14 | from models.user import User 15 | 16 | 17 | class TestUser_instantiation(unittest.TestCase): 18 | """Unittests for testing instantiation of the User class.""" 19 | 20 | def test_no_args_instantiates(self): 21 | self.assertEqual(User, type(User())) 22 | 23 | def test_new_instance_stored_in_objects(self): 24 | self.assertIn(User(), models.storage.all().values()) 25 | 26 | def test_id_is_public_str(self): 27 | self.assertEqual(str, type(User().id)) 28 | 29 | def test_created_at_is_public_datetime(self): 30 | self.assertEqual(datetime, type(User().created_at)) 31 | 32 | def test_updated_at_is_public_datetime(self): 33 | self.assertEqual(datetime, type(User().updated_at)) 34 | 35 | def test_email_is_public_str(self): 36 | self.assertEqual(str, type(User.email)) 37 | 38 | def test_password_is_public_str(self): 39 | self.assertEqual(str, type(User.password)) 40 | 41 | def test_first_name_is_public_str(self): 42 | self.assertEqual(str, type(User.first_name)) 43 | 44 | def test_last_name_is_public_str(self): 45 | self.assertEqual(str, type(User.last_name)) 46 | 47 | def test_two_users_unique_ids(self): 48 | us1 = User() 49 | us2 = User() 50 | self.assertNotEqual(us1.id, us2.id) 51 | 52 | def test_two_users_different_created_at(self): 53 | us1 = User() 54 | sleep(0.05) 55 | us2 = User() 56 | self.assertLess(us1.created_at, us2.created_at) 57 | 58 | def test_two_users_different_updated_at(self): 59 | us1 = User() 60 | sleep(0.05) 61 | us2 = User() 62 | self.assertLess(us1.updated_at, us2.updated_at) 63 | 64 | def test_str_representation(self): 65 | dt = datetime.today() 66 | dt_repr = repr(dt) 67 | us = User() 68 | us.id = "123456" 69 | us.created_at = us.updated_at = dt 70 | usstr = us.__str__() 71 | self.assertIn("[User] (123456)", usstr) 72 | self.assertIn("'id': '123456'", usstr) 73 | self.assertIn("'created_at': " + dt_repr, usstr) 74 | self.assertIn("'updated_at': " + dt_repr, usstr) 75 | 76 | def test_args_unused(self): 77 | us = User(None) 78 | self.assertNotIn(None, us.__dict__.values()) 79 | 80 | def test_instantiation_with_kwargs(self): 81 | dt = datetime.today() 82 | dt_iso = dt.isoformat() 83 | us = User(id="345", created_at=dt_iso, updated_at=dt_iso) 84 | self.assertEqual(us.id, "345") 85 | self.assertEqual(us.created_at, dt) 86 | self.assertEqual(us.updated_at, dt) 87 | 88 | def test_instantiation_with_None_kwargs(self): 89 | with self.assertRaises(TypeError): 90 | User(id=None, created_at=None, updated_at=None) 91 | 92 | 93 | class TestUser_save(unittest.TestCase): 94 | """Unittests for testing save method of the class.""" 95 | 96 | @classmethod 97 | def setUp(self): 98 | try: 99 | os.rename("file.json", "tmp") 100 | except IOError: 101 | pass 102 | 103 | def tearDown(self): 104 | try: 105 | os.remove("file.json") 106 | except IOError: 107 | pass 108 | try: 109 | os.rename("tmp", "file.json") 110 | except IOError: 111 | pass 112 | 113 | def test_one_save(self): 114 | us = User() 115 | sleep(0.05) 116 | first_updated_at = us.updated_at 117 | us.save() 118 | self.assertLess(first_updated_at, us.updated_at) 119 | 120 | def test_two_saves(self): 121 | us = User() 122 | sleep(0.05) 123 | first_updated_at = us.updated_at 124 | us.save() 125 | second_updated_at = us.updated_at 126 | self.assertLess(first_updated_at, second_updated_at) 127 | sleep(0.05) 128 | us.save() 129 | self.assertLess(second_updated_at, us.updated_at) 130 | 131 | def test_save_with_arg(self): 132 | us = User() 133 | with self.assertRaises(TypeError): 134 | us.save(None) 135 | 136 | def test_save_updates_file(self): 137 | us = User() 138 | us.save() 139 | usid = "User." + us.id 140 | with open("file.json", "r") as f: 141 | self.assertIn(usid, f.read()) 142 | 143 | 144 | class TestUser_to_dict(unittest.TestCase): 145 | """Unittests for testing to_dict method of the User class.""" 146 | 147 | def test_to_dict_type(self): 148 | self.assertTrue(dict, type(User().to_dict())) 149 | 150 | def test_to_dict_contains_correct_keys(self): 151 | us = User() 152 | self.assertIn("id", us.to_dict()) 153 | self.assertIn("created_at", us.to_dict()) 154 | self.assertIn("updated_at", us.to_dict()) 155 | self.assertIn("__class__", us.to_dict()) 156 | 157 | def test_to_dict_contains_added_attributes(self): 158 | us = User() 159 | us.middle_name = "Holberton" 160 | us.my_number = 98 161 | self.assertEqual("Holberton", us.middle_name) 162 | self.assertIn("my_number", us.to_dict()) 163 | 164 | def test_to_dict_datetime_attributes_are_strs(self): 165 | us = User() 166 | us_dict = us.to_dict() 167 | self.assertEqual(str, type(us_dict["id"])) 168 | self.assertEqual(str, type(us_dict["created_at"])) 169 | self.assertEqual(str, type(us_dict["updated_at"])) 170 | 171 | def test_to_dict_output(self): 172 | dt = datetime.today() 173 | us = User() 174 | us.id = "123456" 175 | us.created_at = us.updated_at = dt 176 | tdict = { 177 | 'id': '123456', 178 | '__class__': 'User', 179 | 'created_at': dt.isoformat(), 180 | 'updated_at': dt.isoformat(), 181 | } 182 | self.assertDictEqual(us.to_dict(), tdict) 183 | 184 | def test_contrast_to_dict_dunder_dict(self): 185 | us = User() 186 | self.assertNotEqual(us.to_dict(), us.__dict__) 187 | 188 | def test_to_dict_with_arg(self): 189 | us = User() 190 | with self.assertRaises(TypeError): 191 | us.to_dict(None) 192 | 193 | 194 | if __name__ == "__main__": 195 | unittest.main() 196 | -------------------------------------------------------------------------------- /tests/test_models/test_amenity.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | """Defines unittests for models/amenity.py. 3 | 4 | Unittest classes: 5 | TestAmenity_instantiation 6 | TestAmenity_save 7 | TestAmenity_to_dict 8 | """ 9 | import os 10 | import models 11 | import unittest 12 | from datetime import datetime 13 | from time import sleep 14 | from models.amenity import Amenity 15 | 16 | 17 | class TestAmenity_instantiation(unittest.TestCase): 18 | """Unittests for testing instantiation of the Amenity class.""" 19 | 20 | def test_no_args_instantiates(self): 21 | self.assertEqual(Amenity, type(Amenity())) 22 | 23 | def test_new_instance_stored_in_objects(self): 24 | self.assertIn(Amenity(), models.storage.all().values()) 25 | 26 | def test_id_is_public_str(self): 27 | self.assertEqual(str, type(Amenity().id)) 28 | 29 | def test_created_at_is_public_datetime(self): 30 | self.assertEqual(datetime, type(Amenity().created_at)) 31 | 32 | def test_updated_at_is_public_datetime(self): 33 | self.assertEqual(datetime, type(Amenity().updated_at)) 34 | 35 | def test_name_is_public_class_attribute(self): 36 | am = Amenity() 37 | self.assertEqual(str, type(Amenity.name)) 38 | self.assertIn("name", dir(Amenity())) 39 | self.assertNotIn("name", am.__dict__) 40 | 41 | def test_two_amenities_unique_ids(self): 42 | am1 = Amenity() 43 | am2 = Amenity() 44 | self.assertNotEqual(am1.id, am2.id) 45 | 46 | def test_two_amenities_different_created_at(self): 47 | am1 = Amenity() 48 | sleep(0.05) 49 | am2 = Amenity() 50 | self.assertLess(am1.created_at, am2.created_at) 51 | 52 | def test_two_amenities_different_updated_at(self): 53 | am1 = Amenity() 54 | sleep(0.05) 55 | am2 = Amenity() 56 | self.assertLess(am1.updated_at, am2.updated_at) 57 | 58 | def test_str_representation(self): 59 | dt = datetime.today() 60 | dt_repr = repr(dt) 61 | am = Amenity() 62 | am.id = "123456" 63 | am.created_at = am.updated_at = dt 64 | amstr = am.__str__() 65 | self.assertIn("[Amenity] (123456)", amstr) 66 | self.assertIn("'id': '123456'", amstr) 67 | self.assertIn("'created_at': " + dt_repr, amstr) 68 | self.assertIn("'updated_at': " + dt_repr, amstr) 69 | 70 | def test_args_unused(self): 71 | am = Amenity(None) 72 | self.assertNotIn(None, am.__dict__.values()) 73 | 74 | def test_instantiation_with_kwargs(self): 75 | """instantiation with kwargs test method""" 76 | dt = datetime.today() 77 | dt_iso = dt.isoformat() 78 | am = Amenity(id="345", created_at=dt_iso, updated_at=dt_iso) 79 | self.assertEqual(am.id, "345") 80 | self.assertEqual(am.created_at, dt) 81 | self.assertEqual(am.updated_at, dt) 82 | 83 | def test_instantiation_with_None_kwargs(self): 84 | with self.assertRaises(TypeError): 85 | Amenity(id=None, created_at=None, updated_at=None) 86 | 87 | 88 | class TestAmenity_save(unittest.TestCase): 89 | """Unittests for testing save method of the Amenity class.""" 90 | 91 | @classmethod 92 | def setUp(self): 93 | try: 94 | os.rename("file.json", "tmp") 95 | except IOError: 96 | pass 97 | 98 | def tearDown(self): 99 | try: 100 | os.remove("file.json") 101 | except IOError: 102 | pass 103 | try: 104 | os.rename("tmp", "file.json") 105 | except IOError: 106 | pass 107 | 108 | def test_one_save(self): 109 | am = Amenity() 110 | sleep(0.05) 111 | first_updated_at = am.updated_at 112 | am.save() 113 | self.assertLess(first_updated_at, am.updated_at) 114 | 115 | def test_two_saves(self): 116 | am = Amenity() 117 | sleep(0.05) 118 | first_updated_at = am.updated_at 119 | am.save() 120 | second_updated_at = am.updated_at 121 | self.assertLess(first_updated_at, second_updated_at) 122 | sleep(0.05) 123 | am.save() 124 | self.assertLess(second_updated_at, am.updated_at) 125 | 126 | def test_save_with_arg(self): 127 | am = Amenity() 128 | with self.assertRaises(TypeError): 129 | am.save(None) 130 | 131 | def test_save_updates_file(self): 132 | am = Amenity() 133 | am.save() 134 | amid = "Amenity." + am.id 135 | with open("file.json", "r") as f: 136 | self.assertIn(amid, f.read()) 137 | 138 | 139 | class TestAmenity_to_dict(unittest.TestCase): 140 | """Unittests for testing to_dict method of the Amenity class.""" 141 | 142 | def test_to_dict_type(self): 143 | self.assertTrue(dict, type(Amenity().to_dict())) 144 | 145 | def test_to_dict_contains_correct_keys(self): 146 | am = Amenity() 147 | self.assertIn("id", am.to_dict()) 148 | self.assertIn("created_at", am.to_dict()) 149 | self.assertIn("updated_at", am.to_dict()) 150 | self.assertIn("__class__", am.to_dict()) 151 | 152 | def test_to_dict_contains_added_attributes(self): 153 | am = Amenity() 154 | am.middle_name = "Holberton" 155 | am.my_number = 98 156 | self.assertEqual("Holberton", am.middle_name) 157 | self.assertIn("my_number", am.to_dict()) 158 | 159 | def test_to_dict_datetime_attributes_are_strs(self): 160 | am = Amenity() 161 | am_dict = am.to_dict() 162 | self.assertEqual(str, type(am_dict["id"])) 163 | self.assertEqual(str, type(am_dict["created_at"])) 164 | self.assertEqual(str, type(am_dict["updated_at"])) 165 | 166 | def test_to_dict_output(self): 167 | dt = datetime.today() 168 | am = Amenity() 169 | am.id = "123456" 170 | am.created_at = am.updated_at = dt 171 | tdict = { 172 | 'id': '123456', 173 | '__class__': 'Amenity', 174 | 'created_at': dt.isoformat(), 175 | 'updated_at': dt.isoformat(), 176 | } 177 | self.assertDictEqual(am.to_dict(), tdict) 178 | 179 | def test_contrast_to_dict_dunder_dict(self): 180 | am = Amenity() 181 | self.assertNotEqual(am.to_dict(), am.__dict__) 182 | 183 | def test_to_dict_with_arg(self): 184 | am = Amenity() 185 | with self.assertRaises(TypeError): 186 | am.to_dict(None) 187 | 188 | 189 | if __name__ == "__main__": 190 | unittest.main() 191 | -------------------------------------------------------------------------------- /tests/test_models/test_city.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | """Defines unittests for models/city.py. 3 | 4 | Unittest classes: 5 | TestCity_instantiation 6 | TestCity_save 7 | TestCity_to_dict 8 | """ 9 | import os 10 | import models 11 | import unittest 12 | from datetime import datetime 13 | from time import sleep 14 | from models.city import City 15 | 16 | 17 | class TestCity_instantiation(unittest.TestCase): 18 | """Unittests for testing instantiation of the City class.""" 19 | 20 | def test_no_args_instantiates(self): 21 | self.assertEqual(City, type(City())) 22 | 23 | def test_new_instance_stored_in_objects(self): 24 | self.assertIn(City(), models.storage.all().values()) 25 | 26 | def test_id_is_public_str(self): 27 | self.assertEqual(str, type(City().id)) 28 | 29 | def test_created_at_is_public_datetime(self): 30 | self.assertEqual(datetime, type(City().created_at)) 31 | 32 | def test_updated_at_is_public_datetime(self): 33 | self.assertEqual(datetime, type(City().updated_at)) 34 | 35 | def test_state_id_is_public_class_attribute(self): 36 | cy = City() 37 | self.assertEqual(str, type(City.state_id)) 38 | self.assertIn("state_id", dir(cy)) 39 | self.assertNotIn("state_id", cy.__dict__) 40 | 41 | def test_name_is_public_class_attribute(self): 42 | cy = City() 43 | self.assertEqual(str, type(City.name)) 44 | self.assertIn("name", dir(cy)) 45 | self.assertNotIn("name", cy.__dict__) 46 | 47 | def test_two_cities_unique_ids(self): 48 | cy1 = City() 49 | cy2 = City() 50 | self.assertNotEqual(cy1.id, cy2.id) 51 | 52 | def test_two_cities_different_created_at(self): 53 | cy1 = City() 54 | sleep(0.05) 55 | cy2 = City() 56 | self.assertLess(cy1.created_at, cy2.created_at) 57 | 58 | def test_two_cities_different_updated_at(self): 59 | cy1 = City() 60 | sleep(0.05) 61 | cy2 = City() 62 | self.assertLess(cy1.updated_at, cy2.updated_at) 63 | 64 | def test_str_representation(self): 65 | dt = datetime.today() 66 | dt_repr = repr(dt) 67 | cy = City() 68 | cy.id = "123456" 69 | cy.created_at = cy.updated_at = dt 70 | cystr = cy.__str__() 71 | self.assertIn("[City] (123456)", cystr) 72 | self.assertIn("'id': '123456'", cystr) 73 | self.assertIn("'created_at': " + dt_repr, cystr) 74 | self.assertIn("'updated_at': " + dt_repr, cystr) 75 | 76 | def test_args_unused(self): 77 | cy = City(None) 78 | self.assertNotIn(None, cy.__dict__.values()) 79 | 80 | def test_instantiation_with_kwargs(self): 81 | dt = datetime.today() 82 | dt_iso = dt.isoformat() 83 | cy = City(id="345", created_at=dt_iso, updated_at=dt_iso) 84 | self.assertEqual(cy.id, "345") 85 | self.assertEqual(cy.created_at, dt) 86 | self.assertEqual(cy.updated_at, dt) 87 | 88 | def test_instantiation_with_None_kwargs(self): 89 | with self.assertRaises(TypeError): 90 | City(id=None, created_at=None, updated_at=None) 91 | 92 | 93 | class TestCity_save(unittest.TestCase): 94 | """Unittests for testing save method of the City class.""" 95 | 96 | @classmethod 97 | def setUp(self): 98 | try: 99 | os.rename("file.json", "tmp") 100 | except IOError: 101 | pass 102 | 103 | def tearDown(self): 104 | try: 105 | os.remove("file.json") 106 | except IOError: 107 | pass 108 | try: 109 | os.rename("tmp", "file.json") 110 | except IOError: 111 | pass 112 | 113 | def test_one_save(self): 114 | cy = City() 115 | sleep(0.05) 116 | first_updated_at = cy.updated_at 117 | cy.save() 118 | self.assertLess(first_updated_at, cy.updated_at) 119 | 120 | def test_two_saves(self): 121 | cy = City() 122 | sleep(0.05) 123 | first_updated_at = cy.updated_at 124 | cy.save() 125 | second_updated_at = cy.updated_at 126 | self.assertLess(first_updated_at, second_updated_at) 127 | sleep(0.05) 128 | cy.save() 129 | self.assertLess(second_updated_at, cy.updated_at) 130 | 131 | def test_save_with_arg(self): 132 | cy = City() 133 | with self.assertRaises(TypeError): 134 | cy.save(None) 135 | 136 | def test_save_updates_file(self): 137 | cy = City() 138 | cy.save() 139 | cyid = "City." + cy.id 140 | with open("file.json", "r") as f: 141 | self.assertIn(cyid, f.read()) 142 | 143 | 144 | class TestCity_to_dict(unittest.TestCase): 145 | """Unittests for testing to_dict method of the City class.""" 146 | 147 | def test_to_dict_type(self): 148 | self.assertTrue(dict, type(City().to_dict())) 149 | 150 | def test_to_dict_contains_correct_keys(self): 151 | cy = City() 152 | self.assertIn("id", cy.to_dict()) 153 | self.assertIn("created_at", cy.to_dict()) 154 | self.assertIn("updated_at", cy.to_dict()) 155 | self.assertIn("__class__", cy.to_dict()) 156 | 157 | def test_to_dict_contains_added_attributes(self): 158 | cy = City() 159 | cy.middle_name = "Holberton" 160 | cy.my_number = 98 161 | self.assertEqual("Holberton", cy.middle_name) 162 | self.assertIn("my_number", cy.to_dict()) 163 | 164 | def test_to_dict_datetime_attributes_are_strs(self): 165 | cy = City() 166 | cy_dict = cy.to_dict() 167 | self.assertEqual(str, type(cy_dict["id"])) 168 | self.assertEqual(str, type(cy_dict["created_at"])) 169 | self.assertEqual(str, type(cy_dict["updated_at"])) 170 | 171 | def test_to_dict_output(self): 172 | dt = datetime.today() 173 | cy = City() 174 | cy.id = "123456" 175 | cy.created_at = cy.updated_at = dt 176 | tdict = { 177 | 'id': '123456', 178 | '__class__': 'City', 179 | 'created_at': dt.isoformat(), 180 | 'updated_at': dt.isoformat(), 181 | } 182 | self.assertDictEqual(cy.to_dict(), tdict) 183 | 184 | def test_contrast_to_dict_dunder_dict(self): 185 | cy = City() 186 | self.assertNotEqual(cy.to_dict(), cy.__dict__) 187 | 188 | def test_to_dict_with_arg(self): 189 | cy = City() 190 | with self.assertRaises(TypeError): 191 | cy.to_dict(None) 192 | 193 | 194 | if __name__ == "__main__": 195 | unittest.main() 196 | -------------------------------------------------------------------------------- /tests/test_models/test_base_model.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | """Defines unittests for models/base_model.py. 3 | 4 | Unittest classes: 5 | TestBaseModel_instantiation 6 | TestBaseModel_save 7 | TestBaseModel_to_dict 8 | """ 9 | import os 10 | import models 11 | import unittest 12 | from datetime import datetime 13 | from time import sleep 14 | from models.base_model import BaseModel 15 | 16 | 17 | class TestBaseModel_instantiation(unittest.TestCase): 18 | """Unit tests for testing instantiation of the BaseModel class.""" 19 | 20 | def test_no_args_instantiates(self): 21 | self.assertEqual(BaseModel, type(BaseModel())) 22 | 23 | def test_new_instance_stored_in_objects(self): 24 | self.assertIn(BaseModel(), models.storage.all().values()) 25 | 26 | def test_id_is_public_str(self): 27 | self.assertEqual(str, type(BaseModel().id)) 28 | 29 | def test_created_at_is_public_datetime(self): 30 | self.assertEqual(datetime, type(BaseModel().created_at)) 31 | 32 | def test_updated_at_is_public_datetime(self): 33 | self.assertEqual(datetime, type(BaseModel().updated_at)) 34 | 35 | def test_two_models_unique_ids(self): 36 | bm1 = BaseModel() 37 | bm2 = BaseModel() 38 | self.assertNotEqual(bm1.id, bm2.id) 39 | 40 | def test_two_models_different_created_at(self): 41 | bm1 = BaseModel() 42 | sleep(0.05) 43 | bm2 = BaseModel() 44 | self.assertLess(bm1.created_at, bm2.created_at) 45 | 46 | def test_two_models_different_updated_at(self): 47 | bm1 = BaseModel() 48 | sleep(0.05) 49 | bm2 = BaseModel() 50 | self.assertLess(bm1.updated_at, bm2.updated_at) 51 | 52 | def test_str_representation(self): 53 | dt = datetime.today() 54 | dt_repr = repr(dt) 55 | bm = BaseModel() 56 | bm.id = "123456" 57 | bm.created_at = bm.updated_at = dt 58 | bmstr = bm.__str__() 59 | self.assertIn("[BaseModel] (123456)", bmstr) 60 | self.assertIn("'id': '123456'", bmstr) 61 | self.assertIn("'created_at': " + dt_repr, bmstr) 62 | self.assertIn("'updated_at': " + dt_repr, bmstr) 63 | 64 | def test_args_unused(self): 65 | bm = BaseModel(None) 66 | self.assertNotIn(None, bm.__dict__.values()) 67 | 68 | def test_instantiation_with_kwargs(self): 69 | dt = datetime.today() 70 | dt_iso = dt.isoformat() 71 | bm = BaseModel(id="345", created_at=dt_iso, updated_at=dt_iso) 72 | self.assertEqual(bm.id, "345") 73 | self.assertEqual(bm.created_at, dt) 74 | self.assertEqual(bm.updated_at, dt) 75 | 76 | def test_instantiation_with_None_kwargs(self): 77 | with self.assertRaises(TypeError): 78 | BaseModel(id=None, created_at=None, updated_at=None) 79 | 80 | def test_instantiation_with_args_and_kwargs(self): 81 | dt = datetime.today() 82 | dt_iso = dt.isoformat() 83 | bm = BaseModel("12", id="345", created_at=dt_iso, updated_at=dt_iso) 84 | self.assertEqual(bm.id, "345") 85 | self.assertEqual(bm.created_at, dt) 86 | self.assertEqual(bm.updated_at, dt) 87 | 88 | 89 | class TestBaseModel_save(unittest.TestCase): 90 | """Unit tests for testing save method of the BaseModel class.""" 91 | 92 | @classmethod 93 | def setUp(self): 94 | try: 95 | os.rename("file.json", "tmp") 96 | except IOError: 97 | pass 98 | 99 | @classmethod 100 | def tearDown(self): 101 | try: 102 | os.remove("file.json") 103 | except IOError: 104 | pass 105 | try: 106 | os.rename("tmp", "file.json") 107 | except IOError: 108 | pass 109 | 110 | def test_one_save(self): 111 | bm = BaseModel() 112 | sleep(0.05) 113 | first_updated_at = bm.updated_at 114 | bm.save() 115 | self.assertLess(first_updated_at, bm.updated_at) 116 | 117 | def test_two_saves(self): 118 | bm = BaseModel() 119 | sleep(0.05) 120 | first_updated_at = bm.updated_at 121 | bm.save() 122 | second_updated_at = bm.updated_at 123 | self.assertLess(first_updated_at, second_updated_at) 124 | sleep(0.05) 125 | bm.save() 126 | self.assertLess(second_updated_at, bm.updated_at) 127 | 128 | def test_save_with_arg(self): 129 | bm = BaseModel() 130 | with self.assertRaises(TypeError): 131 | bm.save(None) 132 | 133 | def test_save_updates_file(self): 134 | bm = BaseModel() 135 | bm.save() 136 | bmid = "BaseModel." + bm.id 137 | with open("file.json", "r") as f: 138 | self.assertIn(bmid, f.read()) 139 | 140 | 141 | class TestBaseModel_to_dict(unittest.TestCase): 142 | """Unit tests for testing to_dict method of the BaseModel class.""" 143 | 144 | def test_to_dict_type(self): 145 | bm = BaseModel() 146 | self.assertTrue(dict, type(bm.to_dict())) 147 | 148 | def test_to_dict_contains_correct_keys(self): 149 | bm = BaseModel() 150 | self.assertIn("id", bm.to_dict()) 151 | self.assertIn("created_at", bm.to_dict()) 152 | self.assertIn("updated_at", bm.to_dict()) 153 | self.assertIn("__class__", bm.to_dict()) 154 | 155 | def test_to_dict_contains_added_attributes(self): 156 | bm = BaseModel() 157 | bm.name = "Holberton" 158 | bm.my_number = 98 159 | self.assertIn("name", bm.to_dict()) 160 | self.assertIn("my_number", bm.to_dict()) 161 | 162 | def test_to_dict_datetime_attributes_are_strs(self): 163 | bm = BaseModel() 164 | bm_dict = bm.to_dict() 165 | self.assertEqual(str, type(bm_dict["created_at"])) 166 | self.assertEqual(str, type(bm_dict["updated_at"])) 167 | 168 | def test_to_dict_output(self): 169 | dt = datetime.today() 170 | bm = BaseModel() 171 | bm.id = "123456" 172 | bm.created_at = bm.updated_at = dt 173 | tdict = { 174 | 'id': '123456', 175 | '__class__': 'BaseModel', 176 | 'created_at': dt.isoformat(), 177 | 'updated_at': dt.isoformat() 178 | } 179 | self.assertDictEqual(bm.to_dict(), tdict) 180 | 181 | def test_contrast_to_dict_dunder_dict(self): 182 | bm = BaseModel() 183 | self.assertNotEqual(bm.to_dict(), bm.__dict__) 184 | 185 | def test_to_dict_with_arg(self): 186 | bm = BaseModel() 187 | with self.assertRaises(TypeError): 188 | bm.to_dict(None) 189 | 190 | 191 | if __name__ == "__main__": 192 | unittest.main() 193 | -------------------------------------------------------------------------------- /tests/test_models/test_review.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | """Defines unittests for models/review.py. 3 | 4 | Unittest classes: 5 | TestReview_instantiation 6 | TestReview_save 7 | TestReview_to_dict 8 | """ 9 | import os 10 | import models 11 | import unittest 12 | from datetime import datetime 13 | from time import sleep 14 | from models.review import Review 15 | 16 | 17 | class TestReview_instantiation(unittest.TestCase): 18 | """Unittests for testing instantiation of the Review class.""" 19 | 20 | def test_no_args_instantiates(self): 21 | self.assertEqual(Review, type(Review())) 22 | 23 | def test_new_instance_stored_in_objects(self): 24 | self.assertIn(Review(), models.storage.all().values()) 25 | 26 | def test_id_is_public_str(self): 27 | self.assertEqual(str, type(Review().id)) 28 | 29 | def test_created_at_is_public_datetime(self): 30 | self.assertEqual(datetime, type(Review().created_at)) 31 | 32 | def test_updated_at_is_public_datetime(self): 33 | self.assertEqual(datetime, type(Review().updated_at)) 34 | 35 | def test_place_id_is_public_class_attribute(self): 36 | rv = Review() 37 | self.assertEqual(str, type(Review.place_id)) 38 | self.assertIn("place_id", dir(rv)) 39 | self.assertNotIn("place_id", rv.__dict__) 40 | 41 | def test_user_id_is_public_class_attribute(self): 42 | rv = Review() 43 | self.assertEqual(str, type(Review.user_id)) 44 | self.assertIn("user_id", dir(rv)) 45 | self.assertNotIn("user_id", rv.__dict__) 46 | 47 | def test_text_is_public_class_attribute(self): 48 | rv = Review() 49 | self.assertEqual(str, type(Review.text)) 50 | self.assertIn("text", dir(rv)) 51 | self.assertNotIn("text", rv.__dict__) 52 | 53 | def test_two_reviews_unique_ids(self): 54 | rv1 = Review() 55 | rv2 = Review() 56 | self.assertNotEqual(rv1.id, rv2.id) 57 | 58 | def test_two_reviews_different_created_at(self): 59 | rv1 = Review() 60 | sleep(0.05) 61 | rv2 = Review() 62 | self.assertLess(rv1.created_at, rv2.created_at) 63 | 64 | def test_two_reviews_different_updated_at(self): 65 | rv1 = Review() 66 | sleep(0.05) 67 | rv2 = Review() 68 | self.assertLess(rv1.updated_at, rv2.updated_at) 69 | 70 | def test_str_representation(self): 71 | dt = datetime.today() 72 | dt_repr = repr(dt) 73 | rv = Review() 74 | rv.id = "123456" 75 | rv.created_at = rv.updated_at = dt 76 | rvstr = rv.__str__() 77 | self.assertIn("[Review] (123456)", rvstr) 78 | self.assertIn("'id': '123456'", rvstr) 79 | self.assertIn("'created_at': " + dt_repr, rvstr) 80 | self.assertIn("'updated_at': " + dt_repr, rvstr) 81 | 82 | def test_args_unused(self): 83 | rv = Review(None) 84 | self.assertNotIn(None, rv.__dict__.values()) 85 | 86 | def test_instantiation_with_kwargs(self): 87 | dt = datetime.today() 88 | dt_iso = dt.isoformat() 89 | rv = Review(id="345", created_at=dt_iso, updated_at=dt_iso) 90 | self.assertEqual(rv.id, "345") 91 | self.assertEqual(rv.created_at, dt) 92 | self.assertEqual(rv.updated_at, dt) 93 | 94 | def test_instantiation_with_None_kwargs(self): 95 | with self.assertRaises(TypeError): 96 | Review(id=None, created_at=None, updated_at=None) 97 | 98 | 99 | class TestReview_save(unittest.TestCase): 100 | """Unittests for testing save method of the Review class.""" 101 | 102 | @classmethod 103 | def setUp(self): 104 | try: 105 | os.rename("file.json", "tmp") 106 | except IOError: 107 | pass 108 | 109 | def tearDown(self): 110 | try: 111 | os.remove("file.json") 112 | except IOError: 113 | pass 114 | try: 115 | os.rename("tmp", "file.json") 116 | except IOError: 117 | pass 118 | 119 | def test_one_save(self): 120 | rv = Review() 121 | sleep(0.05) 122 | first_updated_at = rv.updated_at 123 | rv.save() 124 | self.assertLess(first_updated_at, rv.updated_at) 125 | 126 | def test_two_saves(self): 127 | rv = Review() 128 | sleep(0.05) 129 | first_updated_at = rv.updated_at 130 | rv.save() 131 | second_updated_at = rv.updated_at 132 | self.assertLess(first_updated_at, second_updated_at) 133 | sleep(0.05) 134 | rv.save() 135 | self.assertLess(second_updated_at, rv.updated_at) 136 | 137 | def test_save_with_arg(self): 138 | rv = Review() 139 | with self.assertRaises(TypeError): 140 | rv.save(None) 141 | 142 | def test_save_updates_file(self): 143 | rv = Review() 144 | rv.save() 145 | rvid = "Review." + rv.id 146 | with open("file.json", "r") as f: 147 | self.assertIn(rvid, f.read()) 148 | 149 | 150 | class TestReview_to_dict(unittest.TestCase): 151 | """Unittests for testing to_dict method of the Review class.""" 152 | 153 | def test_to_dict_type(self): 154 | self.assertTrue(dict, type(Review().to_dict())) 155 | 156 | def test_to_dict_contains_correct_keys(self): 157 | rv = Review() 158 | self.assertIn("id", rv.to_dict()) 159 | self.assertIn("created_at", rv.to_dict()) 160 | self.assertIn("updated_at", rv.to_dict()) 161 | self.assertIn("__class__", rv.to_dict()) 162 | 163 | def test_to_dict_contains_added_attributes(self): 164 | rv = Review() 165 | rv.middle_name = "Holberton" 166 | rv.my_number = 98 167 | self.assertEqual("Holberton", rv.middle_name) 168 | self.assertIn("my_number", rv.to_dict()) 169 | 170 | def test_to_dict_datetime_attributes_are_strs(self): 171 | rv = Review() 172 | rv_dict = rv.to_dict() 173 | self.assertEqual(str, type(rv_dict["id"])) 174 | self.assertEqual(str, type(rv_dict["created_at"])) 175 | self.assertEqual(str, type(rv_dict["updated_at"])) 176 | 177 | def test_to_dict_output(self): 178 | dt = datetime.today() 179 | rv = Review() 180 | rv.id = "123456" 181 | rv.created_at = rv.updated_at = dt 182 | tdict = { 183 | 'id': '123456', 184 | '__class__': 'Review', 185 | 'created_at': dt.isoformat(), 186 | 'updated_at': dt.isoformat(), 187 | } 188 | self.assertDictEqual(rv.to_dict(), tdict) 189 | 190 | def test_contrast_to_dict_dunder_dict(self): 191 | rv = Review() 192 | self.assertNotEqual(rv.to_dict(), rv.__dict__) 193 | 194 | def test_to_dict_with_arg(self): 195 | rv = Review() 196 | with self.assertRaises(TypeError): 197 | rv.to_dict(None) 198 | 199 | 200 | if __name__ == "__main__": 201 | unittest.main() 202 | -------------------------------------------------------------------------------- /web_static/100-index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | AirBnB clone 13 | 14 | 15 |
16 |
17 |
18 |
19 |
20 |

States

21 |

California, Arizona...

22 |
    23 |
  • Arizona:

    24 |
      25 |
    • Page
    • 26 |
    • Page2
    • 27 |
    28 |
  • 29 |
  • California:

    30 |
      31 |
    • San Francisco
    • 32 |
    • Los Altos
    • 33 |
    34 |
  • 35 |
36 |
37 |
38 |

Amenities

39 |

Internet, Kitchen...

40 |
    41 |
  • Internet
  • 42 |
  • Tv
  • 43 |
  • Kitchen
  • 44 |
  • Iron
  • 45 |
46 |
47 | 48 |
49 | 50 |
51 |

Places

52 |
53 |
54 |

My home

55 |
$80
56 |
57 |
58 |
2 Guests
59 |
1 Bedroom
60 |
1 Bathroom
61 |
62 |
63 |

Owner: John Lennon

64 |
65 |
66 |

This is a lovely 1 bathroom apartament that can accommodate 2 people. It locates at the center of Shanghai and next to subway line 1, 1 stop to People Square, 2 stops to Bund, 3 stops to Jungan Temle.

67 |
68 |
69 |

Amenities

70 |
    71 |
  • 72 |
    73 | Pet friendly 74 |
  • 75 |
  • 76 |
    77 | Tv 78 |
  • 79 |
  • 80 |
    81 | Wifi 82 |
  • 83 |
84 |
85 |
86 |

2 Reviews

87 |
    88 |
  • 89 |

    From Bob Dylan the 27th August 2022

    90 |

    Runshi is an epic host. Nothing more i can say. 5 star!

    91 |
  • 92 |
  • 93 |

    From Connor 4th August 2022

    94 |

    Higly recommended!

    95 |
  • 96 |
97 |
98 |
99 | 100 |
101 |

Tiny house

102 |
$65
103 |
104 |
4 Guests
105 |
2 Bedrooms
106 |
1 Bathroom
107 |
108 |
109 |

Owner: Addrienne

110 |
111 |
112 |

Our place is a privete, afffordable satan-alone guest house centrally located just minutes to French Quarters, downtown th Fair Grounds (Jazz Fest) and City Park. The guest house is a quaint, 400 suare ft. with a full bath, mini kitchen, & livin room. The extra high cellings make the home feel more spacious. The sofa converts to bed also. We have a hand made counter area that adds character to the room and a great porch/deck to relax on and have a glass of Merlot.

113 |
114 |
115 |

Amenities

116 |
    117 |
  • 118 |
    119 | Pet friendly 120 |
  • 121 |
122 |
123 |
124 |

1 Review

125 |
    126 |
  • 127 |

    From Max the 15th August 2022

    128 |

    Runshi is an epic host. Nothing more i can say. 5 star!

    129 |
  • 130 |
  • 131 |

    From Connor 4th August 2022

    132 |

    Higly recommended!

    133 |
  • 134 |
135 |
136 |
137 |
138 |

A suite

139 |
$190
140 |
141 |
5 Guests
142 |
3 Bedroom
143 |
2 Bathroom
144 |
145 |
146 |

Owner: Mick Jagger

147 |
148 |
149 |

First loft built by Holbies. It contains a decked terrace, jacuzzi, firepit, rabbits garden, two rooms, two balconies, entrance gate, private garden, private parking, BBQ area, AC in each bedroom, technological equipment, luxury beds, and mountain views. Ideal for architecture lovers, romantic dates, or having a good time. It is a unique space of his kind. Only pets that do not harm rabbits are allowed.

150 |
151 |
152 |

Amenities

153 |
    154 |
  • 155 |
    156 | Pet friendly 157 |
  • 158 |
  • 159 |
    160 | Tv 161 |
  • 162 |
  • 163 |
    164 | Wifi 165 |
  • 166 |
167 |
168 |
169 |

1 Review

170 |
    171 |
  • 172 |

    From Ayomide Suara the 15th August, 2022

    173 |

    I love this place. Amazing!

    174 |
  • 175 |
176 |
177 |
178 |
179 |
180 |
181 |

Best School

182 |
183 | 184 | 185 | -------------------------------------------------------------------------------- /web_static/101-index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | AirBnB clone 13 | 14 | 15 |
16 |
17 |
18 |
19 |
20 |

States

21 |

California, Arizona...

22 |
    23 |
  • Arizona:

    24 |
      25 |
    • Page
    • 26 |
    • Page2
    • 27 |
    28 |
  • 29 |
  • California:

    30 |
      31 |
    • San Francisco
    • 32 |
    • Los Altos
    • 33 |
    34 |
  • 35 |
36 |
37 |
38 |

Amenities

39 |

Internet, Kitchen...

40 |
    41 |
  • Internet
  • 42 |
  • Tv
  • 43 |
  • Kitchen
  • 44 |
  • Iron
  • 45 |
46 |
47 | 48 |
49 | 50 |
51 |

Places

52 |
53 |
54 |

My home

55 |
$80
56 |
57 |
58 |
2 Guests
59 |
1 Bedroom
60 |
1 Bathroom
61 |
62 |
63 |

Owner: John Lennon

64 |
65 |
66 |

This is a lovely 1 bathroom apartament that can accommodate 2 people. It locates at the center of Shanghai and next to subway line 1, 1 stop to People Square, 2 stops to Bund, 3 stops to Jungan Temle.

67 |
68 |
69 |

Amenities

70 |
    71 |
  • 72 |
    73 | Pet friendly 74 |
  • 75 |
  • 76 |
    77 | Tv 78 |
  • 79 |
  • 80 |
    81 | Wifi 82 |
  • 83 |
84 |
85 |
86 |

2 Reviews

87 |
    88 |
  • 89 |

    From Bob Dylan the 27th August 2022

    90 |

    Runshi is an epic host. Nothing more i can say. 5 star!

    91 |
  • 92 |
  • 93 |

    From Connor 4th August 2022

    94 |

    Higly recommended!

    95 |
  • 96 |
97 |
98 |
99 | 100 |
101 |

Tiny house

102 |
$65
103 |
104 |
4 Guests
105 |
2 Bedrooms
106 |
1 Bathroom
107 |
108 |
109 |

Owner: Addrienne

110 |
111 |
112 |

Our place is a privete, afffordable satan-alone guest house centrally located just minutes to French Quarters, downtown th Fair Grounds (Jazz Fest) and City Park. The guest house is a quaint, 400 suare ft. with a full bath, mini kitchen, & livin room. The extra high cellings make the home feel more spacious. The sofa converts to bed also. We have a hand made counter area that adds character to the room and a great porch/deck to relax on and have a glass of Merlot.

113 |
114 |
115 |

Amenities

116 |
    117 |
  • 118 |
    119 | Pet friendly 120 |
  • 121 |
122 |
123 |
124 |

1 Review

125 |
    126 |
  • 127 |

    From Max the 15th August 2022

    128 |

    Runshi is an epic host. Nothing more i can say. 5 star!

    129 |
  • 130 |
  • 131 |

    From Connor 4th August 2022

    132 |

    Higly recommended!

    133 |
  • 134 |
135 |
136 |
137 |
138 |

A suite

139 |
$190
140 |
141 |
5 Guests
142 |
3 Bedroom
143 |
2 Bathroom
144 |
145 |
146 |

Owner: Mick Jagger

147 |
148 |
149 |

First loft built by Holbies. It contains a decked terrace, jacuzzi, firepit, rabbits garden, two rooms, two balconies, entrance gate, private garden, private parking, BBQ area, AC in each bedroom, technological equipment, luxury beds, and mountain views. Ideal for architecture lovers, romantic dates, or having a good time. It is a unique space of his kind. Only pets that do not harm rabbits are allowed.

150 |
151 |
152 |

Amenities

153 |
    154 |
  • 155 |
    156 | Pet friendly 157 |
  • 158 |
  • 159 |
    160 | Tv 161 |
  • 162 |
  • 163 |
    164 | Wifi 165 |
  • 166 |
167 |
168 |
169 |

1 Review

170 |
    171 |
  • 172 |

    From Gary Moore the 13th August 2022

    173 |

    I love this place. Amazing!

    174 |
  • 175 |
176 |
177 |
178 |
179 |
180 |
181 |

Best School

182 |
183 | 184 | 185 | -------------------------------------------------------------------------------- /console.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | """Module for the entry point of the command interpreter.""" 3 | 4 | import cmd 5 | from models.base_model import BaseModel 6 | from models import storage 7 | import re 8 | import json 9 | 10 | 11 | class HBNBCommand(cmd.Cmd): 12 | 13 | """This is the Class for the command interpreter.""" 14 | 15 | prompt = "(hbnb) " 16 | 17 | def default(self, line): 18 | """Catch commands if nothing else matches then.""" 19 | # print("DEF:::", line) 20 | self._precmd(line) 21 | 22 | def _precmd(self, line): 23 | """Intercepts commands to test for class.syntax()""" 24 | # print("PRECMD:::", line) 25 | match = re.search(r"^(\w*)\.(\w+)(?:\(([^)]*)\))$", line) 26 | if not match: 27 | return line 28 | classname = match.group(1) 29 | method = match.group(2) 30 | args = match.group(3) 31 | match_uid_and_args = re.search('^"([^"]*)"(?:, (.*))?$', args) 32 | if match_uid_and_args: 33 | uid = match_uid_and_args.group(1) 34 | attr_or_dict = match_uid_and_args.group(2) 35 | else: 36 | uid = args 37 | attr_or_dict = False 38 | 39 | attr_and_value = "" 40 | if method == "update" and attr_or_dict: 41 | match_dict = re.search('^({.*})$', attr_or_dict) 42 | if match_dict: 43 | self.update_dict(classname, uid, match_dict.group(1)) 44 | return "" 45 | match_attr_and_value = re.search( 46 | '^(?:"([^"]*)")?(?:, (.*))?$', attr_or_dict) 47 | if match_attr_and_value: 48 | attr_and_value = (match_attr_and_value.group( 49 | 1) or "") + " " + (match_attr_and_value.group(2) or "") 50 | command = method + " " + classname + " " + uid + " " + attr_and_value 51 | self.onecmd(command) 52 | return command 53 | 54 | def update_dict(self, classname, uid, s_dict): 55 | """This is the helper method for update() with a dictionary.""" 56 | s = s_dict.replace("'", '"') 57 | d = json.loads(s) 58 | if not classname: 59 | print("** class name missing **") 60 | elif classname not in storage.classes(): 61 | print("** class doesn't exist **") 62 | elif uid is None: 63 | print("** instance id missing **") 64 | else: 65 | key = "{}.{}".format(classname, uid) 66 | if key not in storage.all(): 67 | print("** no instance found **") 68 | else: 69 | attributes = storage.attributes()[classname] 70 | for attribute, value in d.items(): 71 | if attribute in attributes: 72 | value = attributes[attribute](value) 73 | setattr(storage.all()[key], attribute, value) 74 | storage.all()[key].save() 75 | 76 | def do_EOF(self, line): 77 | """This handles End Of File character. 78 | """ 79 | print() 80 | return True 81 | 82 | def do_quit(self, line): 83 | """This exits the program. 84 | """ 85 | return True 86 | 87 | def emptyline(self): 88 | """This doesn't do anything on ENTER. 89 | """ 90 | pass 91 | 92 | def do_create(self, line): 93 | """This creates an instance. 94 | """ 95 | if line == "" or line is None: 96 | print("** class name missing **") 97 | elif line not in storage.classes(): 98 | print("** class doesn't exist **") 99 | else: 100 | b = storage.classes()[line]() 101 | b.save() 102 | print(b.id) 103 | 104 | def do_show(self, line): 105 | """This prints the string representation of an instance. 106 | """ 107 | if line == "" or line is None: 108 | print("** class name missing **") 109 | else: 110 | words = line.split(' ') 111 | if words[0] not in storage.classes(): 112 | print("** class doesn't exist **") 113 | elif len(words) < 2: 114 | print("** instance id missing **") 115 | else: 116 | key = "{}.{}".format(words[0], words[1]) 117 | if key not in storage.all(): 118 | print("** no instance found **") 119 | else: 120 | print(storage.all()[key]) 121 | 122 | def do_destroy(self, line): 123 | """This deletes an instance based on the class name and id. 124 | """ 125 | if line == "" or line is None: 126 | print("** class name missing **") 127 | else: 128 | words = line.split(' ') 129 | if words[0] not in storage.classes(): 130 | print("** class doesn't exist **") 131 | elif len(words) < 2: 132 | print("** instance id missing **") 133 | else: 134 | key = "{}.{}".format(words[0], words[1]) 135 | if key not in storage.all(): 136 | print("** no instance found **") 137 | else: 138 | del storage.all()[key] 139 | storage.save() 140 | 141 | def do_all(self, line): 142 | """This prints all string representation of all instances. 143 | """ 144 | if line != "": 145 | words = line.split(' ') 146 | if words[0] not in storage.classes(): 147 | print("** class doesn't exist **") 148 | else: 149 | nl = [str(obj) for key, obj in storage.all().items() 150 | if type(obj).__name__ == words[0]] 151 | print(nl) 152 | else: 153 | new_list = [str(obj) for key, obj in storage.all().items()] 154 | print(new_list) 155 | 156 | def do_count(self, line): 157 | """This counts the instances of a class. 158 | """ 159 | words = line.split(' ') 160 | if not words[0]: 161 | print("** class name missing **") 162 | elif words[0] not in storage.classes(): 163 | print("** class doesn't exist **") 164 | else: 165 | matches = [ 166 | k for k in storage.all() if k.startswith( 167 | words[0] + '.')] 168 | print(len(matches)) 169 | 170 | def do_update(self, line): 171 | """This updates an instance by adding or updating attribute. 172 | """ 173 | if line == "" or line is None: 174 | print("** class name missing **") 175 | return 176 | 177 | rex = r'^(\S+)(?:\s(\S+)(?:\s(\S+)(?:\s((?:"[^"]*")|(?:(\S)+)))?)?)?' 178 | match = re.search(rex, line) 179 | classname = match.group(1) 180 | uid = match.group(2) 181 | attribute = match.group(3) 182 | value = match.group(4) 183 | if not match: 184 | print("** class name missing **") 185 | elif classname not in storage.classes(): 186 | print("** class doesn't exist **") 187 | elif uid is None: 188 | print("** instance id missing **") 189 | else: 190 | key = "{}.{}".format(classname, uid) 191 | if key not in storage.all(): 192 | print("** no instance found **") 193 | elif not attribute: 194 | print("** attribute name missing **") 195 | elif not value: 196 | print("** value missing **") 197 | else: 198 | cast = None 199 | if not re.search('^".*"$', value): 200 | if '.' in value: 201 | cast = float 202 | else: 203 | cast = int 204 | else: 205 | value = value.replace('"', '') 206 | attributes = storage.attributes()[classname] 207 | if attribute in attributes: 208 | value = attributes[attribute](value) 209 | elif cast: 210 | try: 211 | value = cast(value) 212 | except ValueError: 213 | pass # fine, stay a string then 214 | setattr(storage.all()[key], attribute, value) 215 | storage.all()[key].save() 216 | 217 | 218 | if __name__ == '__main__': 219 | HBNBCommand().cmdloop() 220 | -------------------------------------------------------------------------------- /tests/test_models/test_place.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | """Defines unittests for models/place.py. 3 | 4 | Unittest classes: 5 | TestPlace_instantiation 6 | TestPlace_save 7 | TestPlace_to_dict 8 | """ 9 | import os 10 | import models 11 | import unittest 12 | from datetime import datetime 13 | from time import sleep 14 | from models.place import Place 15 | 16 | 17 | class TestPlace_instantiation(unittest.TestCase): 18 | """Unittests for testing instantiation of the Place class.""" 19 | 20 | def test_no_args_instantiates(self): 21 | self.assertEqual(Place, type(Place())) 22 | 23 | def test_new_instance_stored_in_objects(self): 24 | self.assertIn(Place(), models.storage.all().values()) 25 | 26 | def test_id_is_public_str(self): 27 | self.assertEqual(str, type(Place().id)) 28 | 29 | def test_created_at_is_public_datetime(self): 30 | self.assertEqual(datetime, type(Place().created_at)) 31 | 32 | def test_updated_at_is_public_datetime(self): 33 | self.assertEqual(datetime, type(Place().updated_at)) 34 | 35 | def test_city_id_is_public_class_attribute(self): 36 | pl = Place() 37 | self.assertEqual(str, type(Place.city_id)) 38 | self.assertIn("city_id", dir(pl)) 39 | self.assertNotIn("city_id", pl.__dict__) 40 | 41 | def test_user_id_is_public_class_attribute(self): 42 | pl = Place() 43 | self.assertEqual(str, type(Place.user_id)) 44 | self.assertIn("user_id", dir(pl)) 45 | self.assertNotIn("user_id", pl.__dict__) 46 | 47 | def test_name_is_public_class_attribute(self): 48 | pl = Place() 49 | self.assertEqual(str, type(Place.name)) 50 | self.assertIn("name", dir(pl)) 51 | self.assertNotIn("name", pl.__dict__) 52 | 53 | def test_description_is_public_class_attribute(self): 54 | pl = Place() 55 | self.assertEqual(str, type(Place.description)) 56 | self.assertIn("description", dir(pl)) 57 | self.assertNotIn("desctiption", pl.__dict__) 58 | 59 | def test_number_rooms_is_public_class_attribute(self): 60 | pl = Place() 61 | self.assertEqual(int, type(Place.number_rooms)) 62 | self.assertIn("number_rooms", dir(pl)) 63 | self.assertNotIn("number_rooms", pl.__dict__) 64 | 65 | def test_number_bathrooms_is_public_class_attribute(self): 66 | pl = Place() 67 | self.assertEqual(int, type(Place.number_bathrooms)) 68 | self.assertIn("number_bathrooms", dir(pl)) 69 | self.assertNotIn("number_bathrooms", pl.__dict__) 70 | 71 | def test_max_guest_is_public_class_attribute(self): 72 | pl = Place() 73 | self.assertEqual(int, type(Place.max_guest)) 74 | self.assertIn("max_guest", dir(pl)) 75 | self.assertNotIn("max_guest", pl.__dict__) 76 | 77 | def test_price_by_night_is_public_class_attribute(self): 78 | pl = Place() 79 | self.assertEqual(int, type(Place.price_by_night)) 80 | self.assertIn("price_by_night", dir(pl)) 81 | self.assertNotIn("price_by_night", pl.__dict__) 82 | 83 | def test_latitude_is_public_class_attribute(self): 84 | pl = Place() 85 | self.assertEqual(float, type(Place.latitude)) 86 | self.assertIn("latitude", dir(pl)) 87 | self.assertNotIn("latitude", pl.__dict__) 88 | 89 | def test_longitude_is_public_class_attribute(self): 90 | pl = Place() 91 | self.assertEqual(float, type(Place.longitude)) 92 | self.assertIn("longitude", dir(pl)) 93 | self.assertNotIn("longitude", pl.__dict__) 94 | 95 | def test_amenity_ids_is_public_class_attribute(self): 96 | pl = Place() 97 | self.assertEqual(list, type(Place.amenity_ids)) 98 | self.assertIn("amenity_ids", dir(pl)) 99 | self.assertNotIn("amenity_ids", pl.__dict__) 100 | 101 | def test_two_places_unique_ids(self): 102 | pl1 = Place() 103 | pl2 = Place() 104 | self.assertNotEqual(pl1.id, pl2.id) 105 | 106 | def test_two_places_different_created_at(self): 107 | pl1 = Place() 108 | sleep(0.05) 109 | pl2 = Place() 110 | self.assertLess(pl1.created_at, pl2.created_at) 111 | 112 | def test_two_places_different_updated_at(self): 113 | pl1 = Place() 114 | sleep(0.05) 115 | pl2 = Place() 116 | self.assertLess(pl1.updated_at, pl2.updated_at) 117 | 118 | def test_str_representation(self): 119 | dt = datetime.today() 120 | dt_repr = repr(dt) 121 | pl = Place() 122 | pl.id = "123456" 123 | pl.created_at = pl.updated_at = dt 124 | plstr = pl.__str__() 125 | self.assertIn("[Place] (123456)", plstr) 126 | self.assertIn("'id': '123456'", plstr) 127 | self.assertIn("'created_at': " + dt_repr, plstr) 128 | self.assertIn("'updated_at': " + dt_repr, plstr) 129 | 130 | def test_args_unused(self): 131 | pl = Place(None) 132 | self.assertNotIn(None, pl.__dict__.values()) 133 | 134 | def test_instantiation_with_kwargs(self): 135 | dt = datetime.today() 136 | dt_iso = dt.isoformat() 137 | pl = Place(id="345", created_at=dt_iso, updated_at=dt_iso) 138 | self.assertEqual(pl.id, "345") 139 | self.assertEqual(pl.created_at, dt) 140 | self.assertEqual(pl.updated_at, dt) 141 | 142 | def test_instantiation_with_None_kwargs(self): 143 | with self.assertRaises(TypeError): 144 | Place(id=None, created_at=None, updated_at=None) 145 | 146 | 147 | class TestPlace_save(unittest.TestCase): 148 | """Unittests for testing save method of the Place class.""" 149 | 150 | @classmethod 151 | def setUp(self): 152 | try: 153 | os.rename("file.json", "tmp") 154 | except IOError: 155 | pass 156 | 157 | def tearDown(self): 158 | try: 159 | os.remove("file.json") 160 | except IOError: 161 | pass 162 | try: 163 | os.rename("tmp", "file.json") 164 | except IOError: 165 | pass 166 | 167 | def test_one_save(self): 168 | pl = Place() 169 | sleep(0.05) 170 | first_updated_at = pl.updated_at 171 | pl.save() 172 | self.assertLess(first_updated_at, pl.updated_at) 173 | 174 | def test_two_saves(self): 175 | pl = Place() 176 | sleep(0.05) 177 | first_updated_at = pl.updated_at 178 | pl.save() 179 | second_updated_at = pl.updated_at 180 | self.assertLess(first_updated_at, second_updated_at) 181 | sleep(0.05) 182 | pl.save() 183 | self.assertLess(second_updated_at, pl.updated_at) 184 | 185 | def test_save_with_arg(self): 186 | pl = Place() 187 | with self.assertRaises(TypeError): 188 | pl.save(None) 189 | 190 | def test_save_updates_file(self): 191 | pl = Place() 192 | pl.save() 193 | plid = "Place." + pl.id 194 | with open("file.json", "r") as f: 195 | self.assertIn(plid, f.read()) 196 | 197 | 198 | class TestPlace_to_dict(unittest.TestCase): 199 | """Unittests for testing to_dict method of the Place class.""" 200 | 201 | def test_to_dict_type(self): 202 | self.assertTrue(dict, type(Place().to_dict())) 203 | 204 | def test_to_dict_contains_correct_keys(self): 205 | pl = Place() 206 | self.assertIn("id", pl.to_dict()) 207 | self.assertIn("created_at", pl.to_dict()) 208 | self.assertIn("updated_at", pl.to_dict()) 209 | self.assertIn("__class__", pl.to_dict()) 210 | 211 | def test_to_dict_contains_added_attributes(self): 212 | pl = Place() 213 | pl.middle_name = "Holberton" 214 | pl.my_number = 98 215 | self.assertEqual("Holberton", pl.middle_name) 216 | self.assertIn("my_number", pl.to_dict()) 217 | 218 | def test_to_dict_datetime_attributes_are_strs(self): 219 | pl = Place() 220 | pl_dict = pl.to_dict() 221 | self.assertEqual(str, type(pl_dict["id"])) 222 | self.assertEqual(str, type(pl_dict["created_at"])) 223 | self.assertEqual(str, type(pl_dict["updated_at"])) 224 | 225 | def test_to_dict_output(self): 226 | dt = datetime.today() 227 | pl = Place() 228 | pl.id = "123456" 229 | pl.created_at = pl.updated_at = dt 230 | tdict = { 231 | 'id': '123456', 232 | '__class__': 'Place', 233 | 'created_at': dt.isoformat(), 234 | 'updated_at': dt.isoformat(), 235 | } 236 | self.assertDictEqual(pl.to_dict(), tdict) 237 | 238 | def test_contrast_to_dict_dunder_dict(self): 239 | pl = Place() 240 | self.assertNotEqual(pl.to_dict(), pl.__dict__) 241 | 242 | def test_to_dict_with_arg(self): 243 | pl = Place() 244 | with self.assertRaises(TypeError): 245 | pl.to_dict(None) 246 | 247 | 248 | if __name__ == "__main__": 249 | unittest.main() 250 | -------------------------------------------------------------------------------- /web_static/102-index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | AirBnB clone 13 | 14 | 15 |
16 |
17 | 18 | 19 | 42 |
43 |
44 |
45 |
46 |
47 |

States

48 |

California, Arizona...

49 |
    50 |
  • Arizona:

    51 |
      52 |
    • Page
    • 53 |
    • Page2
    • 54 |
    55 |
  • 56 |
  • California:

    57 |
      58 |
    • San Francisco
    • 59 |
    • Los Altos
    • 60 |
    61 |
  • 62 |
63 |
64 |
65 |

Amenities

66 |

Internet, Kitchen...

67 |
    68 |
  • Internet
  • 69 |
  • Tv
  • 70 |
  • Kitchen
  • 71 |
  • Iron
  • 72 |
73 |
74 | 75 |
76 | 77 |
78 |

Places

79 |
80 |
81 |

My home

82 |
$80
83 |
84 |
85 |
2 Guests
86 |
1 Bedroom
87 |
1 Bathroom
88 |
89 |
90 |

Owner: John Lennon

91 |
92 |
93 |

This is a lovely 1 bathroom apartament that can accommodate 2 people. It locates at the center of Shanghai and next to subway line 1, 1 stop to People Square, 2 stops to Bund, 3 stops to Jungan Temle.

94 |
95 |
96 |

Amenities

97 |
    98 |
  • 99 |
    100 | Pet friendly 101 |
  • 102 |
  • 103 |
    104 | Tv 105 |
  • 106 |
  • 107 |
    108 | Wifi 109 |
  • 110 |
111 |
112 |
113 |

2 Reviews

114 |
    115 |
  • 116 |

    From Bob Dylan the 27th August 2022

    117 |

    Runshi is an epic host. Nothing more i can say. 5 star!

    118 |
  • 119 |
  • 120 |

    From Connor 4th August 2022

    121 |

    Higly recommended!

    122 |
  • 123 |
124 |
125 |
126 | 127 |
128 |

Tiny house

129 |
$65
130 |
131 |
4 Guests
132 |
2 Bedrooms
133 |
1 Bathroom
134 |
135 |
136 |

Owner: Addrienne

137 |
138 |
139 |

Our place is a privete, afffordable satan-alone guest house centrally located just minutes to French Quarters, downtown th Fair Grounds (Jazz Fest) and City Park. The guest house is a quaint, 400 suare ft. with a full bath, mini kitchen, & livin room. The extra high cellings make the home feel more spacious. The sofa converts to bed also. We have a hand made counter area that adds character to the room and a great porch/deck to relax on and have a glass of Merlot.

140 |
141 |
142 |

Amenities

143 |
    144 |
  • 145 |
    146 | Pet friendly 147 |
  • 148 |
149 |
150 |
151 |

1 Review

152 |
    153 |
  • 154 |

    From Max the 15th August 2022

    155 |

    Runshi is an epic host. Nothing more i can say. 5 star!

    156 |
  • 157 |
  • 158 |

    From Connor 4th August 2022

    159 |

    Higly recommended!

    160 |
  • 161 |
162 |
163 |
164 | 165 |
166 |

A suite

167 |
$190
168 |
169 |
5 Guests
170 |
3 Bedroom
171 |
2 Bathroom
172 |
173 |
174 |

Owner: Mick Jagger

175 |
176 |
177 |

First loft built by Holbies. It contains a decked terrace, jacuzzi, firepit, rabbits garden, two rooms, two balconies, entrance gate, private garden, private parking, BBQ area, AC in each bedroom, technological equipment, luxury beds, and mountain views. Ideal for architecture lovers, romantic dates, or having a good time. It is a unique space of his kind. Only pets that do not harm rabbits are allowed.

178 |
179 |
180 |

Amenities

181 |
    182 |
  • 183 |
    184 | Pet friendly 185 |
  • 186 |
  • 187 |
    188 | Tv 189 |
  • 190 |
  • 191 |
    192 | Wifi 193 |
  • 194 |
195 |
196 |
197 |

1 Review

198 |
    199 |
  • 200 |

    From Gary Moore the 13th August 2022

    201 |

    I love this place. Amazing!

    202 |
  • 203 |
204 |
205 |
206 | 207 |
208 |
209 |

My house

210 |
$50
211 |
212 |
213 |
2 Guests
214 |
1 Bedroom
215 |
1 Bathroom
216 |
217 |
218 |

Owner:John Seena

219 |
220 |
221 |

This is a lovely 1 bathroom apartament that can accommodate 2 people. It locates at the center of Shanghai and next to subway line 1, 1 stop to People Square, 2 stops to Bund, 3 stops to Jungan Temle.

222 |
223 |
224 |

Amenities

225 |
    226 |
  • 227 |
    228 | Pet friendly 229 |
  • 230 |
  • 231 |
    232 | Tv 233 |
  • 234 |
  • 235 |
    236 | Wifi 237 |
  • 238 |
239 |
240 |
241 |

2 Reviews

242 |
    243 |
  • 244 |

    From Bob Dylan the 27th August 2022

    245 |

    Runshi is an epic host. Nothing more i can say. 5 star!

    246 |
  • 247 |
  • 248 |

    From Connor 4th August 2022

    249 |

    Higly recommended!

    250 |
  • 251 |
252 |
253 |
254 | 255 |
256 |
257 |

Otaku rooms

258 |
$79
259 |
260 |
261 |
2 Guests
262 |
1 Bedroom
263 |
1 Bathroom
264 |
265 |
266 |

Owner: John Lennon

267 |
268 |
269 |

This is a lovely 1 bathroom apartament that can accommodate 2 people. It locates at the center of Shanghai and next to subway line 1, 1 stop to People Square, 2 stops to Bund, 3 stops to Jungan Temle.

270 |
271 |
272 |

Amenities

273 |
    274 |
  • 275 |
    276 | Pet friendly 277 |
  • 278 |
  • 279 |
    280 | Tv 281 |
  • 282 |
  • 283 |
    284 | Wifi 285 |
  • 286 |
287 |
288 |
289 |

2 Reviews

290 |
    291 |
  • 292 |

    From Bob Dylan the 27th August 2022

    293 |

    Runshi is an epic host. Nothing more i can say. 5 star!

    294 |
  • 295 |
  • 296 |

    From Connor 4th January 2021

    297 |

    Higly recommended!

    298 |
  • 299 |
300 |
301 |
302 | 303 |
304 |
305 |

Donkey Kong Country

306 |
$80
307 |
308 |
309 |
8 Guests
310 |
1 Bedroom
311 |
1 Bathroom
312 |
313 |
314 |

Owner: John Lennon

315 |
316 |
317 |

This is a lovely 1 bathroom apartament that can accommodate 2 people. It locates at the center of Shanghai and next to subway line 1, 1 stop to People Square, 2 stops to Bund, 3 stops to Jungan Temle.

318 |
319 |
320 |

Amenities

321 |
    322 |
  • 323 |
    324 | Pet friendly 325 |
  • 326 |
  • 327 |
    328 | Tv 329 |
  • 330 |
  • 331 |
    332 | Wifi 333 |
  • 334 |
335 |
336 |
337 |

2 Reviews

338 |
    339 |
  • 340 |

    From Bob Dylan the 27th August 2022

    341 |

    Runshi is an epic host. Nothing more i can say. 5 star!

    342 |
  • 343 |
  • 344 |

    From Connor 4th August 2022

    345 |

    Higly recommended!

    346 |
  • 347 |
348 |
349 |
350 | 351 |
352 |
353 |
354 |

Best School

355 |
356 | 357 | 358 | -------------------------------------------------------------------------------- /web_static/103-index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | AirBnB clone 13 | 14 | 15 |
16 | 43 |
44 |
45 | 76 | 77 |
78 |

Places

79 |
80 |
81 |

My home

82 |
$80
83 |
84 |
85 |
2 Guests
86 |
1 Bedroom
87 |
1 Bathroom
88 |
89 |
90 |

Owner: John Lennon

91 |
92 |
93 |

This is a lovely 1 bathroom apartament that can accommodate 2 people. It locates at the center of Shanghai and next to subway line 1, 1 stop to People Square, 2 stops to Bund, 3 stops to Jungan Temle.

94 |
95 |
96 |

Amenities

97 |
    98 |
  • 99 |
    100 | Pet friendly 101 |
  • 102 |
  • 103 |
    104 | Tv 105 |
  • 106 |
  • 107 |
    108 | Wifi 109 |
  • 110 |
111 |
112 |
113 |

2 Reviews

114 |
    115 |
  • 116 |

    From Bob Dylan the 27th August 2022

    117 |

    Runshi is an epic host. Nothing more i can say. 5 star!

    118 |
  • 119 |
  • 120 |

    From Connor 4th January 2021

    121 |

    Higly recommended!

    122 |
  • 123 |
124 |
125 |
126 | 127 |
128 |

Tiny house

129 |
$65
130 |
131 |
4 Guests
132 |
2 Bedrooms
133 |
1 Bathroom
134 |
135 |
136 |

Owner: Aysuarex

137 |
138 |
139 |

Our place is a privete, afffordable satan-alone guest house centrally located just minutes to French Quarters, downtown th Fair Grounds (Jazz Fest) and City Park. The guest house is a quaint, 400 suare ft. with a full bath, mini kitchen, & livin room. The extra high cellings make the home feel more spacious. The sofa converts to bed also. We have a hand made counter area that adds character to the room and a great porch/deck to relax on and have a glass of Merlot.

140 |
141 |
142 |

Amenities

143 |
    144 |
  • 145 |
    146 | Pet friendly 147 |
  • 148 |
149 |
150 |
151 |

1 Review

152 |
    153 |
  • 154 |

    From Max the 15th August 2022

    155 |

    Runshi is an epic host. Nothing more i can say. 5 star!

    156 |
  • 157 |
  • 158 |

    From Connor 4th August 2022

    159 |

    Higly recommended!

    160 |
  • 161 |
162 |
163 |
164 | 165 |
166 |

A suite

167 |
$190
168 |
169 |
5 Guests
170 |
3 Bedroom
171 |
2 Bathroom
172 |
173 |
174 |

Owner: Mick Jagger

175 |
176 |
177 |

First loft built by Holbies. It contains a decked terrace, jacuzzi, firepit, rabbits garden, two rooms, two balconies, entrance gate, private garden, private parking, BBQ area, AC in each bedroom, technological equipment, luxury beds, and mountain views. Ideal for architecture lovers, romantic dates, or having a good time. It is a unique space of his kind. Only pets that do not harm rabbits are allowed.

178 |
179 |
180 |

Amenities

181 |
    182 |
  • 183 |
    184 | Pet friendly 185 |
  • 186 |
  • 187 |
    188 | Tv 189 |
  • 190 |
  • 191 |
    192 | Wifi 193 |
  • 194 |
195 |
196 |
197 |

1 Review

198 |
    199 |
  • 200 |

    From Gary Moore the 13th August 2022

    201 |

    I love this place. Amazing!

    202 |
  • 203 |
204 |
205 |
206 | 207 |
208 |
209 |

My house

210 |
$50
211 |
212 |
213 |
2 Guests
214 |
1 Bedroom
215 |
1 Bathroom
216 |
217 |
218 |

Owner:John Seena

219 |
220 |
221 |

This is a lovely 1 bathroom apartament that can accommodate 2 people. It locates at the center of Shanghai and next to subway line 1, 1 stop to People Square, 2 stops to Bund, 3 stops to Jungan Temle.

222 |
223 |
224 |

Amenities

225 |
    226 |
  • 227 |
    228 | Pet friendly 229 |
  • 230 |
  • 231 |
    232 | Tv 233 |
  • 234 |
  • 235 |
    236 | Wifi 237 |
  • 238 |
239 |
240 |
241 |

2 Reviews

242 |
    243 |
  • 244 |

    From Bob Dylan the 27th August 2022

    245 |

    Runshi is an epic host. Nothing more i can say. 5 star!

    246 |
  • 247 |
  • 248 |

    From Connor 4th August 2022

    249 |

    Higly recommended!

    250 |
  • 251 |
252 |
253 |
254 | 255 |
256 |
257 |

Otaku rooms

258 |
$79
259 |
260 |
261 |
2 Guests
262 |
1 Bedroom
263 |
1 Bathroom
264 |
265 |
266 |

Owner: John Lennon

267 |
268 |
269 |

This is a lovely 1 bathroom apartament that can accommodate 2 people. It locates at the center of Shanghai and next to subway line 1, 1 stop to People Square, 2 stops to Bund, 3 stops to Jungan Temle.

270 |
271 |
272 |

Amenities

273 |
    274 |
  • 275 |
    276 | Pet friendly 277 |
  • 278 |
  • 279 |
    280 | Tv 281 |
  • 282 |
  • 283 |
    284 | Wifi 285 |
  • 286 |
287 |
288 |
289 |

2 Reviews

290 |
    291 |
  • 292 |

    From Bob Dylan the 27th August 2022

    293 |

    Runshi is an epic host. Nothing more i can say. 5 star!

    294 |
  • 295 |
  • 296 |

    From Connor 4th August 2022

    297 |

    Higly recommended!

    298 |
  • 299 |
300 |
301 |
302 | 303 |
304 |
305 |

Donkey Kong Country

306 |
$80
307 |
308 |
309 |
8 Guests
310 |
1 Bedroom
311 |
1 Bathroom
312 |
313 |
314 |

Owner: John Lennon

315 |
316 |
317 |

This is a lovely 1 bathroom apartament that can accommodate 2 people. It locates at the center of Shanghai and next to subway line 1, 1 stop to People Square, 2 stops to Bund, 3 stops to Jungan Temle.

318 |
319 |
320 |

Amenities

321 |
    322 |
  • 323 |
    324 | Pet friendly 325 |
  • 326 |
  • 327 |
    328 | Tv 329 |
  • 330 |
  • 331 |
    332 | Wifi 333 |
  • 334 |
335 |
336 |
337 |

2 Reviews

338 |
    339 |
  • 340 |

    From Bob Dylan the 27th August 2022

    341 |

    Runshi is an epic host. Nothing more i can say. 5 star!

    342 |
  • 343 |
  • 344 |

    From Connor 4th August 2022

    345 |

    Higly recommended!

    346 |
  • 347 |
348 |
349 |
350 | 351 |
352 |
353 | 356 | 357 | 358 | --------------------------------------------------------------------------------