# Internet Application Technologies - 2020 ![image](https://drive.google.com/uc?export=view&id=1MXftxMzVE_y5H3VF5RB7C9dyDyGTai7a) <div style="text-align: justify"> <p style="font-size: 20px"><b>Room / House Rental Internet Application - Airbnb like App</b></p> <p style="font-size: 18px"><b>Professor: Chamodrakas Ioannis</b></p> :::info <p style="font-size: 20px"><b>Students</b></p> Lepidas Nikolaos 1115201600090</br> Lamprinos Nikos 1115201600088 ::: <p style="font-size: 20px">Contents</p> </div> [ToC] # Introduction <div style="text-align: justify"> The aim of this project is to develop a room / house rental application (airbnb like application). Users will be able to access it via web browser. Essentially the application supports 4 user roles; the administrator, the host, the renter and of course the anonymous / guest. Next, we will explain in detail and report all our assumptions in relation to the project's description. In the technical part of the web application we decided to use Javascript Web Framework <b>Angular 10</b> (Front-end) and <b>Flask & Python</b> (Back-end). The Back-end is a REST API. --- </div> # Requirements / Installation <div style="text-align: justify"> Requirements in order to install and run the app in Ubuntu: ## Front-end * Install nvm (node version manager): ``` sudo apt update sudo apt install build-essential checkinstall libssl-dev curl -o- https/:/raw.githubusercontent.com/creationix/nvm/v0.35.1/install.sh | bash nvm --version nvm ls nvm ls-remote nvm install version ``` * Node.js - v12.18.2 * npm (node package manager) - v6.14.5 (npm is installed with Node.js by default). Also update npm to the latest: ``` npm install -g npm@latest ``` * Install the Angular CLI: ``` npm install -g @angular/cli ``` * Angular when we start working on project: v10.0.4 * Leaflet: open-source JavaScript library for mobile-friendly interactive maps ``` npm install leaflet ``` * Google API - Autocomplete address / places (free for 3 months after registration) ``` npm install ngx-google-places-autocomplete ``` ## Back-end * Flask In order to install Flask you can follow instructions from Flask's Documentation. :::info https://flask.palletsprojects.com/en/1.1.x/installation/ ::: We basically have to create a python3 environment. ``` mkdir myproject cd myproject python3 -m venv venv ``` or ``` mkdir myproject cd myproject conda create --name venv python=3.7 ``` Then just install Flask: ``` pip install Flask ``` * Other modules ``` sudo apt install default-libmysqlclient-dev pip install Flask-MySQLdb pip install Flask-Cors pip install xmltodict pip install numpy ``` * Database In order to create and add data in our `airbnb` database you have to run the following commands: ``` mysql -u user -ppassword < ./db/db.sql mysql -u user -ppassword airbnb < ./db/users.sql mysql -u user -ppassword airbnb < ./db/apartments.sql mysql -u user -ppassword airbnb < ./db/reservations.sql ``` We have actually created a bash script that does exactly this; called install_db.sh :::info If you don't want to have in plain text the password inside the script you can run every command with just -p (not using password) and add the password when prompted to. ::: ## Running the app For the Front-end you just have to type: ``` ng serve -o ``` This command will open a browser at https://localhost:4200/. For the Back-end you have to run the following commands: ``` export FLASK_APP=backend.py export FLASK_ENV=development flask run --cert=cert.pem --key=key.pem ``` The server will start running at https://localhost:5000/. All the endpoints are under this url. :::info Since we have created a REST API we don't have to run the Back-end at the same machine as the Front-end. In our development process we actually have used ngrok and http tunnels so as to develop front and back separately. ::: </div> --- # Front-end Web Development <div style="text-align: justify"> ### Home / Welcome page (Login) ![image](https://drive.google.com/uc?export=view&id=1LfS3PH_CLChf1qjAaotnd_0MhK6Dr60n) The first page that loads for a user is this page· the welcome page. From this page user can register to the app as renter, host or both. Also, user can login to his/her account by giving username and password. These http requests are encrypted by SSL protocol (SSL certificate). Finally, the most important part is the search form. A user can search for apartments to rent by giving location, date range and number of guests to live there. Before we begin coding, we visited a lot of airbnb like sites in order to have a pattern for our project. So we decided to place our menu-bar together with header in the same component. ### Registration «page» ![image](https://drive.google.com/uc?export=view&id=1pbiDmSib3a_t8e0bQ-Bb0RM00pc8rSPZ) Registration process doesn't take place on a new page. We decided to have a modal form (as for login process). A new user can give username, password, confirmation of password, name, surname, email, phone, role(s). There is no possibility for the user to upload a photo profile cause this is our design point of view. User can upload profile image on edit-profile page after logging in to their account. This is actually an approach that we also saw on others sites. If username is in use by another account a dialog box is displayed in order to inform user and urge him/her to use an alternative. If the user after the successful registration has (also) selected the role of the host, a message (dialog box) is displayed informing him/her that the approval of his/her application for registration in the application with the role of the host is pending. In each case user can login the application if he/she has (<b>also</b>) selected the role of the renter. ### Administrator ![image](https://drive.google.com/uc?export=view&id=1WrIcSxQCmCiR9x07UWHH8JATQmZyXjjy) ![image](https://drive.google.com/uc?export=view&id=1vCvE7Qgxq4pWsZ6kFq3lmbZu7nAjZd_R) After the successful installation of the application a user with the privileges of administrator is created in our database. When admin logins he/she is automatically being navigated to admin-panel page. From this panel he can browse the user list and export the whole site to JSON or/and XML. Also, admin can browse from users list to a user's profile card in order to accept/decline his/her as host in application. ### Search results ![image](https://drive.google.com/uc?export=view&id=1QnNEANvr3mweADOyjAkFPc-xFZwEa0c-) <div style="text-align: center; font-size: 14px;">main_part_of_search_results</div></br> ![image](https://drive.google.com/uc?export=view&id=1RG6O76pJwKLlVTY0xYSXB4yxT3mPR-PM) <div style="text-align: center; font-size: 14px;">pagination_of_search_results</div></br> ![image](https://drive.google.com/uc?export=view&id=1G5NdVKllQ64FpDkKYXnkxJOF5mpqK4bP) <div style="text-align: center; font-size: 14px;">filtering_of_search_results</div></br> After a successful search request, the user will browse in this page a list of available apartments. Apartments in this list are displayed in ascending order. There is also paging available in case the results are over 10. Filtering is an extra feature on this page. ### Room details ![image](https://drive.google.com/uc?export=view&id=1JRtNTsFtnHF2urTQu1mDX6o_xoAcVcZ_) ![image](https://drive.google.com/uc?export=view&id=1lkW5Wdcc0kJ_u4ZA5WkbvT8Y6kNFb_rT) ![image](https://drive.google.com/uc?export=view&id=1MV8s6WOhaL0DRed0C9jhXG3Hl5o5wYMM) From search results page, user can click on an apartment in order to proceed to a page with more details about it. The user can browse a lot of images, price, renter rules, description, reviews, location info and map of apartment, host's details. Also, he/she can book a reservation for the apartment he chosen. ### Host ![image](https://drive.google.com/uc?export=view&id=1kdRN1Rvo0QiSLBlijQpIFXqCZTrkhs-X) When a host login he/she automatically navigated to view-rooms page. There, he/she browse his/her rooms to rent. By clicking on an apartment, user can edit some of the info about the apartment (and) upload/remove images. Also user can add a new room (by clicking «Add room» on navbar). User have to enter location of the apartment (using address autocomplete input field of Google API). After giving extra info about the apartment (if all fields are valid), it is ready to be rented! ### Edit profile ![image](https://drive.google.com/uc?export=view&id=1skI7_yXyhmfnBTLb8aF9rUJF0XWQvBRY) ![image](https://drive.google.com/uc?export=view&id=17OHOVHWIXcV76l6eAf9Sm56g4bUB58Cs) ![image](https://drive.google.com/uc?export=view&id=1AQIknasGibZ4gYNTV2jVp7GReA6hEnIV) Each user can navigate to edit-profile using navbar. User can edit name, surname, email, phone, photo profile, password. ### Chat Users can send messages to each other. Most common use of chat is between a renter and a host, when the first wants to ask things about an apartment of the second. Every user can browse to message list using navbar. </div> --- # Back-end Web Development <div style="text-align: justify"> As we said before, the Back-end is a REST API that was created with python and Flask framework. There are many endpoints that the Front-end can reach and send requests to. </div> ## Common Endpoint Work <div style="text-align: justify"> In almost every endpoint the work that we do is identical. We get data from the Front-end mostly in json format, make queries to the database and return results. For example, when a user searches for apartments we get the parameters from the search-form and we query the database to find the available apartments. After that we return the results in json format and the Front-end is responsible to create a view for them. </div> ## Database <div style="text-align: justify"> The database is a very important part of the implementation. We decided to use MySQL because we were more familiar with and the relational approach seemed to be the right path. The schema was created with workbench and is shown in the image below. </div><br> ![image](https://drive.google.com/uc?export=view&id=1IWLyk5apcL2CHdF45_8QbhLJLNJ45G3Y) As you can see it is a simple schema created specifically for the purposes of this project. # Bonus <div style="text-align: justify"> For the bonus part we had to implement a recommendation algorithm in order to predict and show apartments that the user would likely opt for. We implemented from scratch Matrix Factorization with Gradient descent which is a collaborative recommendation algorithm. We have the code for the bonus below. </div><br> ```python= import numpy as np class MatrixFactorization(): def __init__(self, R, K, h): """ We perform matrix factorization with gradient descent to predict empty entries in Rating matrix. Arguments: - R (ndarray) : User-Item rating - K (int) : number of latent features - h (float) : learning rate """ self.R = R self.num_users, self.num_items = R.shape self.K = K self.h = h def train(self): # Initialize user and latent feature matrix self.V = np.random.uniform(size=(self.num_users, self.K)) # Initialize latent feature and item matrix self.F = np.random.uniform(size=(self.K, self.num_items)) known = np.count_nonzero(self.R) rmse_prev = -2 rmse = -1 while (rmse != rmse_prev): xs, ys = self.R.nonzero() total_square_error = 0 for i, j in zip(xs, ys): #compute error_ij error_ij = self.R[i,j] - self.V[i,:].dot(self.F[:,j]) #update V and F arrays self.V[i,:] += self.h * 2 * error_ij * self.F[:,j] self.F[:,j] += self.h * 2 * error_ij * self.V[i,:] total_square_error += pow(error_ij, 2) #calculate RMSE rmse_prev = rmse rmse = np.sqrt(total_square_error / known) def predicted_matrix(self): return self.V.dot(self.F) ``` <div style="text-align: justify"> After some experiments we decided that the best way to run the algorithm is to use 2 latent features (K = 2) and the learning rate to be 0.001 (h = 0.001). </div><br> :::info We have to admit that the bonus was one of the most interesting things in this project! ::: # Extras <div style="text-align: justify"> It was difficult at the end to use the dataset provided for the project because we had to make many changes in the application. We didn't have the time for something like that but we wanted to create more features to show as we want the best result! After all it was really fun improving the app. </div> ## Message List <div style="text-align: justify"> We added "My messages" feature in order for a logged in user to access his/her messages. </div><br> ![image](https://drive.google.com/uc?export=view&id=1-hf3bGS-0ymfgbuRs_-XQljZkec795x2) <div style="text-align: justify"> We also tried to improve the UI of the chat box! </div><br> ![image](https://drive.google.com/uc?export=view&id=1DVPx9IwAkin66OBRqnH1D_tYebutgZhr) ## Google API - Autocomplete address <div style="text-align: justify"> We used Google's API for Autocomplete address in order to improve the user experience when a host wants to add a new apartment/room. </div><br> ![image](https://drive.google.com/uc?export=view&id=1MEEZsaxfoH_TBN1a_CHkUoQPEg_hXu7E) <div style="text-align: justify"> After finding the address the api returns to us all the information that we need. </div><br> ![image](https://drive.google.com/uc?export=view&id=1prJrPuL8Igkm5A7QZoPg53HpOZ-kf5th) ## Reservation List <div style="text-align: justify"> We added "My reservations" feature in order for a logged in user to access his/her reservations. </div><br> ![image](https://drive.google.com/uc?export=view&id=11HWk5K3c4ib-qVDLSGWsAFhT5noacLcI) ## Remove apartment images <div style="text-align: justify"> We impemented deleting multiple apartment images in edit-room. </div><br> ![image](https://drive.google.com/uc?export=view&id=1W6IvqbnVz00QsjeFLrhbix6LnCqRVT9y)