version 1
						commit
						c5f37091d8
					
				|  | @ -0,0 +1,2 @@ | |||
| *.pyc | ||||
| *.db | ||||
|  | @ -0,0 +1,15 @@ | |||
| Flask Web Interface | ||||
| ============ | ||||
| Instalador de una interfaz web basica usando python3 y Flask | ||||
| 
 | ||||
| Contenido | ||||
| ========= | ||||
| web-interface: Sitio web básico hecho con Flask y Python. | ||||
| 
 | ||||
| Instalación | ||||
| =========== | ||||
| Para instalar el proyecto se debe ejecutar el script ``Setup.sh`` con privilegios de root.  | ||||
| 
 | ||||
| Licencia | ||||
| ======== | ||||
| El proyecto tiene licencia GPL3 para fines educacionales.  | ||||
|  | @ -0,0 +1,26 @@ | |||
| #!/bin/bash | ||||
| 
 | ||||
| apt update | ||||
| apt upgrade | ||||
| apt install -y neofetch fortunes vim python3-pip gunicorn git | ||||
| 
 | ||||
| echo "" > /etc/motd | ||||
| 
 | ||||
| echo "" >> /etc/bash.bashrc | ||||
| echo "neofetch" >> /etc/bash.bashrc | ||||
| echo "/usr/games/fortune" >> /etc/bash.bashrc | ||||
| echo "set mouse=" >> /etc/vim/vimrc | ||||
| 
 | ||||
| git clone https://dev.ilab.cl/git/pythonweb.git /srv | ||||
| 
 | ||||
| cd /srv | ||||
| pip3 install setuptools | ||||
| pip3 install -r web-interface/requirements.txt | ||||
| 
 | ||||
| systemctl stop webinterface.service | ||||
| 
 | ||||
| cp -f webinterface.service.sample /etc/systemd/system/webinterface.service | ||||
| 
 | ||||
| systemctl unmask webinterface.service | ||||
| systemctl enable webinterface.service | ||||
| systemctl start webinterface.service | ||||
|  | @ -0,0 +1,19 @@ | |||
| # -*- coding: utf-8 -*- | ||||
| from flask import Flask, request, render_template | ||||
| from user_agents import parse | ||||
| app = Flask(__name__) | ||||
| 
 | ||||
| @app.route('/') | ||||
| def home(): | ||||
|     return render_template('home.html') | ||||
| 
 | ||||
| @app.route('/about') | ||||
| def about(): | ||||
|     return render_template('license.html') | ||||
| 
 | ||||
| @app.route('/browser') | ||||
| def browser(): | ||||
|      | ||||
|     ipaddr = request.environ['REMOTE_ADDR'] | ||||
|     uadata = parse(request.user_agent.string) | ||||
|     return render_template('about.html', title='Datos del Navegador', ipaddr=ipaddr, uastr=str(uadata)) | ||||
|  | @ -0,0 +1,3 @@ | |||
| Flask==1.0 | ||||
| ua-parser==0.8.0 | ||||
| user-agents==2.0 | ||||
|  | @ -0,0 +1,80 @@ | |||
| body { | ||||
|   background: #fcfcfc; | ||||
|   color: #222222; | ||||
|   margin-top: 5rem; | ||||
| } | ||||
| 
 | ||||
| h1, h2, h3, h4, h5, h6 { | ||||
|   color: #303030; | ||||
| } | ||||
| 
 | ||||
| .bg-steel { | ||||
|   background-color: #3d3d3d; | ||||
| } | ||||
| 
 | ||||
| .site-header .navbar-nav .nav-link { | ||||
|   color: #dce6ec; | ||||
| } | ||||
| 
 | ||||
| .site-header .navbar-nav .nav-link:hover { | ||||
|   color: #ffffff; | ||||
| } | ||||
| 
 | ||||
| .site-header .navbar-nav .nav-link.active { | ||||
|   font-weight: 500; | ||||
| } | ||||
| 
 | ||||
| .content-section { | ||||
|   background: #ffffff; | ||||
|   padding: 10px 20px; | ||||
|   border: 1px solid #dddddd; | ||||
|   border-radius: 3px; | ||||
|   margin-bottom: 20px; | ||||
| } | ||||
| 
 | ||||
| .article-title { | ||||
|   color: #444444; | ||||
| } | ||||
| 
 | ||||
| a.article-title:hover { | ||||
|   color: #428bca; | ||||
|   text-decoration: none; | ||||
| } | ||||
| 
 | ||||
| .article-content { | ||||
|   white-space: pre-line; | ||||
| } | ||||
| 
 | ||||
| .article-img { | ||||
|   height: 65px; | ||||
|   width: 65px; | ||||
|   margin-right: 16px; | ||||
| } | ||||
| 
 | ||||
| .article-metadata { | ||||
|   padding-bottom: 1px; | ||||
|   margin-bottom: 4px; | ||||
|   border-bottom: 1px solid #e3e3e3 | ||||
| } | ||||
| 
 | ||||
| .article-metadata a:hover { | ||||
|   color: #333; | ||||
|   text-decoration: none; | ||||
| } | ||||
| 
 | ||||
| .article-svg { | ||||
|   width: 25px; | ||||
|   height: 25px; | ||||
|   vertical-align: middle; | ||||
| } | ||||
| 
 | ||||
| .account-img { | ||||
|   height: 125px; | ||||
|   width: 125px; | ||||
|   margin-right: 20px; | ||||
|   margin-bottom: 16px; | ||||
| } | ||||
| 
 | ||||
| .account-heading { | ||||
|   font-size: 2.5rem; | ||||
| } | ||||
|  | @ -0,0 +1,10 @@ | |||
| {% extends "layout.html" %} | ||||
| {% block content %} | ||||
|         <article class="media content-section"> | ||||
|           <div class="media-body"> | ||||
|             <legend class="border-bottom mb-4">Acerca del Navegador</legend> | ||||
|             <p class="article-content">La dirección IP de la que estás accediendo es {{ ipaddr }}. </p> | ||||
|             <p class="article-content">El navegador te identifica como: {{ uastr }}</p> | ||||
|           </div> | ||||
|         </article> | ||||
| {% endblock content %} | ||||
|  | @ -0,0 +1,15 @@ | |||
| {% extends "layout.html" %} | ||||
| {% block content %} | ||||
|         <article class="media content-section"> | ||||
| 
 | ||||
|           <div class="media-body"> | ||||
|             <legend class="border-bottom mb-4">Página de pruebas</legend> | ||||
|              | ||||
|             <p class="article-content">Este es un sitio web de prueba utilizando Flask. </p> | ||||
|             <p class="article-content">Actualmente no tiene ningún contenido ni funcionalidad, de manera que sirva como una plantilla vacía para poder mostrar el contenido deseado, o implementar una funcionalidad sin tener que partir desde cero.</p> | ||||
|           </div> | ||||
|         </article> | ||||
| <div class="d-flex justify-content-end"> | ||||
| <a href="{{ url_for('browser') }}" class="btn btn-primary btn-lg " role="button" aria-disabled="true">Ver datos del navegador</a> | ||||
| </div> | ||||
| {% endblock content %} | ||||
|  | @ -0,0 +1,73 @@ | |||
| <!DOCTYPE html> | ||||
| <html> | ||||
| <head> | ||||
|     <!-- Required meta tags --> | ||||
|     <meta charset="utf-8"> | ||||
|     <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"> | ||||
| 
 | ||||
|     <!-- Bootstrap CSS --> | ||||
|     <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous"> | ||||
|     <script src="https://kit.fontawesome.com/9797d9c6de.js" crossorigin="anonymous"></script> | ||||
| 
 | ||||
|     <link rel="stylesheet" type="text/css" href="{{ url_for('static', filename='main.css') }}"> | ||||
| 
 | ||||
|     {% if title %} | ||||
|         <title>Flask Site - {{ title }}</title> | ||||
|     {% else %} | ||||
|         <title>Flask Site</title> | ||||
|     {% endif %} | ||||
| </head> | ||||
| <body> | ||||
|     <header class="site-header"> | ||||
|       <nav class="navbar navbar-expand-md navbar-dark bg-steel fixed-top "> | ||||
|         <div class="container"> | ||||
|           <a class="navbar-brand mr-4" href="{{ url_for('home') }}">Flask App</a> | ||||
|           <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarToggle" aria-controls="navbarToggle" aria-expanded="false" aria-label="Toggle navigation"> | ||||
|             <span class="navbar-toggler-icon"></span> | ||||
|           </button> | ||||
|           <div class="collapse navbar-collapse" id="navbarToggle"> | ||||
|             <div class="navbar-nav mr-auto"> | ||||
| 
 | ||||
|             <a class="nav-item nav-link" href="{{ url_for('home') }}">Dashboard</a> | ||||
| 
 | ||||
|                | ||||
|             </div> | ||||
|             <!-- Navbar Right Side --> | ||||
|             <div class="navbar-nav"> | ||||
| 
 | ||||
|             <a class="nav-item nav-link" href="{{ url_for('browser') }}">Información del Navegador</a> | ||||
|             <a class="nav-item nav-link" href="{{ url_for('about') }}">Acerca de...</a> | ||||
| 
 | ||||
|             </div> | ||||
|           </div> | ||||
|         </div> | ||||
|       </nav> | ||||
|     </header> | ||||
|     <main role="main" class="container"> | ||||
|       <div class="row justify-content-lg-center"> | ||||
|         <div class="col-md-8"> | ||||
|           {% with messages = get_flashed_messages(with_categories=true) %} | ||||
|             {% if messages %} | ||||
|               {% for category, message in messages %} | ||||
|                 <div class="alert alert-{{ category }}"> | ||||
|                   {{  message }} | ||||
|                 </div> | ||||
|               {% endfor %} | ||||
|             {% endif %} | ||||
|           {% endwith %} | ||||
|           {% block admin %}{% endblock %} | ||||
|           {% block content %}{% endblock %} | ||||
|         </div> | ||||
| 
 | ||||
|         </div> | ||||
|       </div> | ||||
|     </main> | ||||
| 
 | ||||
| 
 | ||||
|     <!-- Optional JavaScript --> | ||||
|     <!-- jQuery first, then Popper.js, then Bootstrap JS --> | ||||
|     <script src="https://code.jquery.com/jquery-3.2.1.slim.min.js" integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN" crossorigin="anonymous"></script> | ||||
|     <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js" integrity="sha384-ApNbgh9B+Y1QKtv3Rn7W3mgPxhU9K/ScQsAP7hUibX39j7fakFPskvXusvfa0b4Q" crossorigin="anonymous"></script> | ||||
|     <script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js" integrity="sha384-JZR6Spejh4U02d8jOt6vLEHfe/JQGiRRSQQxSfFWpi1MquVdAyjUar5+76PVCmYl" crossorigin="anonymous"></script> | ||||
| </body> | ||||
| </html> | ||||
|  | @ -0,0 +1,15 @@ | |||
| {% extends "layout.html" %} | ||||
| {% block content %} | ||||
|         <article class="media content-section"> | ||||
|           <div class="media-body"> | ||||
|             <legend class="border-bottom mb-4">Sobre el licenciamiento de este código</legend> | ||||
|             <p class="article-content">Este código está licenciado bajo MIT para los usuarios de <i>i</i>Lab. Para los demás, deben conseguir una licencia especial si quieren utilizar este código con usos comerciales. Para fines educacionales se le puede conceder una licencia GPLv3 si la solicitan a israel.figueroa@ilab.cl.</p> | ||||
|           </div> | ||||
|         </article> | ||||
|         <article class="media content-section"> | ||||
|         <div class="media-body"> | ||||
|             <legend class="border-bottom mb-4">Sobre el funcionamiento</legend> | ||||
|             <p class="article-content">El código está pensado para mostrar un contenido web básico utilizando Flask y Python 3. El código incluye un instalador como servicio, que permite que el programa se inicie cada vez que prenda el sistema. </p> | ||||
|           </div> | ||||
|         </article> | ||||
| {% endblock content %} | ||||
|  | @ -0,0 +1,4 @@ | |||
| from basicweb import app | ||||
| 
 | ||||
| if __name__ == "__main__": | ||||
|         app.run() | ||||
|  | @ -0,0 +1,12 @@ | |||
| [Unit] | ||||
| Description=Sample-WebInterface | ||||
| After=network.target | ||||
| 
 | ||||
| [Service] | ||||
| User=root | ||||
| WorkingDirectory=/srv/web-interface | ||||
| ExecStart=/usr/bin/gunicorn -b 0.0.0.0:80 wsgi:app  | ||||
| Restart=always | ||||
| 
 | ||||
| [Install] | ||||
| WantedBy=multi-user.target | ||||
		Loading…
	
		Reference in New Issue