instalar node js en ubuntu

sudo apt-get install nodejs

sudo apt-get install nodejs-legacy

Finalmente, podemos instalar el gestor de paquetes npm con el comando:
sudo apt-get install npm

google map api styling

se puede modificar el mapa que por default nos muestra google,

podemos definir un array con los estilos a aplicar, por ejemplo

var styles = [
          {
            featureType: 'road.highway',
            elementType: 'geometry.stroke',
            stylers: [
              { color: '#efe9e4' },
              { lightness: -40 }
            ]
          },{
            featureType: 'transit.station',
            stylers: [
              { weight: 9 },
              { hue: '#e85113' }
            ]
          }
        ];

y luego asignarselo al map

map = new google.maps.Map(document.getElementById('map'), {
  center: {lat: -34.619108, lng: -58.43131},
  zoom: 15,
  styles: styles,
 
  });

se pueden descargar distintos estilos para mapas desde esta pagina

google map api creando una marca mark

dentro de la function initMap, agregamos el sgt codigo

 <script>
      var map;
      function initMap() {
        map = new google.maps.Map(document.getElementById('map'), {
          center: {lat: -34.619108, lng: -58.43131},
          zoom: 15
        });


        var tienda_de_cafe={lat:-34.619214,lng:-58.434158};
        var marker =new google.maps.Marker(
        {
        position: tienda_de_cafe,
        map:map,
        title: 'La Tienda de Cafe!'
        });
      }
    </script>

cuando pasemos el mouse por arriba del Mark (globo rojo) se mostrara el texto "La Tienda de Cafe!"



podemos ademas agregar information sobre ese punto y que aparezca cuando clickeamos sobre el.

var infoWinfow=new google.maps.InfoWindow(
        {content:'Vení a conocernos, disfrutá de la experiencia que tenemos para brindarte. Y llevate a tu casa el mejor café del mundo. '});

        marker.addListener('click',function(){
        infoWinfow.open(map,this);
        });


Se puede hacer lo mismo para varios puntos a la vez

var locations=[{title:'punto 1',location:{lat:-34.622628,lng:-58.43234}},{title:'punto 2',location:{lat:-34.615105,lng:-58.428648} },{title:'punto 3',location:{lat:-34.615928,lng:-58.430953}}
  ];
        
        var infoWinfowCommon=new google.maps.InfoWindow();
           
  for (var i = locations.length - 1; i >= 0; i--) {
  var marker =new google.maps.Marker(
  {
  position: locations[i].location,
  map:map,
  title: locations[i].title
  });
           
            populateInfoWindow(marker,infoWinfowCommon);
  }

donde:

function populateInfoWindow(marker,infoWindow){
  if(infoWindow.marker!=marker){
      marker.addListener('click',function(){
            infoWindow.marker = marker;
          infoWindow.setContent(marker.title);
      infoWindow.open(map,marker);
      infoWindow.addListener('closeclick',function(){
                     this.marker=null;
      });
        });
  }
 
  }




google map api configuracion proyecto

1) ir a https://console.developers.google.com

2) click en el combo de proyectos en la esquina superior izquierda

3) click en + para crear uno nuevo

4) escribir el nombre de tu proyecto y click en el boton "create"

click en el boton  de "Enable Apis"


(verificar que el combo superior este en tu nuevo proyecto)
5) click en Maps Javascript Api , click en el boton "enable"

*******************

desplegar el menu de la izquierda, ir a APIS

y habilitar:

roads api

maps static api

street view api

places api

geocoding api

directions api

distance matrix api

geolocation api

maps elevation api

timezone api

ir al menu Credentials de cualquiera de las Apis
click en Create Credentials y generar una Credential del tipo Api Key...esta se usara para todas las apis habilitadas en el proyecto

darle un nombre que describa la intencion con la que sera usada, por ejemplo:

maps_api_udacity_course


nuestra primera aplicacion,
por simplicidad lo haremos en una sola pagina web.

en la seccion de head, agregaremos el sgt codigo

<style>
      /* Always set the map height explicitly to define the size of the div
       * element that contains the map. */
      #map {
        height: 100%;
      }
      /* Optional: Makes the sample page fill the window. */
      html, body {
        height: 100%;
        margin: 0;
        padding: 0;
      }
    </style>

<script>
      var map;
      function initMap() {
        map = new google.maps.Map(document.getElementById('map'), {
          center: {lat: -34.619108, lng: -58.43131},
          zoom: 15
        });
      }
    </script>



<body>

<div id="map"></div>
   <script src="https://maps.googleapis.com/maps/api/js?key=TU_API_KEY&callback=initMap"
    async defer></script>

</body>


el rsultado sera un mapa con un zoom de 15 teniendo como centro las coordenadas dadas.

tip:
para obtener las coordenadas de una determinada direccion usar la siguiente
pagina

https://google-developers.appspot.com/maps/documentation/utils/geocoder






laravel 5.6 Politicas de acceso Policies

vamos a hacer uso de las clases policy de laravel para programar accesos
hacia algunas funcionalidades del sitio

entonces la idea final es que un usuario pueda editar/actualizar sus propios datos
y tambien que un usuario con rol admin pueda hacerlo para cualquiera.

1) crear la clase UserPolicy

php artisan make:policy UserPolicy

este comando creara la clase app/policies/UserPolicy.php

2) registrar la relacion del modelo User con la clase UserPolicy

ir a app/Providers/AuthServiceProvider.php

protected $policies = [
        'App\User' => 'App\Policies\UserPolicy',
    ];

3) en UserPolicy.php crear la function before, que se llamara antes de cualquier otra declarada en la clase. Aqui se evaluara si el usuario logueado es admin y si es verdadero devuelve true, salteando la evaluacion de las otras funciones. De lo contrario, llama a la function correspondiente para que haga la evaluacion de si el usuario logueado es el mismo que se quiere editar/actualizar.



 public function before($user,$ability){
        if($user->hasRoles(['admin'])){
            return true;
        }
    }

    public function edit(User $authUser, User $user){
        return ($authUser->id == $user->id);
    }
    public function update(User $authUser, User $user){
        return ($authUser->id == $user->id);
    }
    public function destroy(User $authUser, User $user){
        return ($authUser->id == $user->id);
    }


4)en UserController exceptuar la validacion para los casos de edit y update

public function __construct(){
       //$this->middleware(['auth','checkRoles:admin,moderador']);
        $this->middleware('auth');
        $this->middleware('checkRoles:admin,moderador',['except'=>['edit','update']]);
    }

5)en UserController llamar desde las functiones de edit y update
a la function authorize para que dispare las validaciones del UserPolicy

public function edit($id)
    {
        $user = User::findOrFail($id);

        $this->authorize($user);

        return view('users.edit',compact('user'));
    }

    public function update(UpdateUserRequest $request, $id)
    {
        $user = User::findOrFail($id);

        $this->authorize($user);
       

        $user->update($request->all())  ;
        return redirect()->route('users.index');

    }



laravel 5.6 accion de editar validar user

vamos a crear una validacion para que al editar no se pueda poner un nombre en blanco ni usar un email que ya exista


php artisan make:request UserUpdateRequest

Vamos a app/Http/Requests/UserUpdateRequest.php

   public function authorize()
    {
        return true;
    }

    /**
     * Get the validation rules that apply to the request.
     *
     * @return array
     */
    public function rules()
    {
        return [
            'name' => 'required',
            'email' => 'required'
        ];
    }

y ahora se validara que ambos campos tengan algun valor.

mejoremos la validacion del campo email, le agregaremos que tenga un formato valido de email y que ademas no sea igual a otro email que ya exista en la tabla

    'email' => 'required | email | unique:users,email'

esta ultima validacion tiene el problema de que si no modificamos el email nos va a dar un error pues
va a detectar que el email ya existe...pues compara con el del mismo usuario ..cosa que debemos evitar enviando un tercer parametro con el ID del usuario que se esta actualizando para que no lo tome en cuenta al momento de la evaluacion.

el id lo vamos a obtener de la route

'email' => 'required | email | unique:users,email,'.$this->route('user')

donde user es el nombre del parametro de nuestra route para el update.


     

laravel 5.6 eloquent relaciones many to many

vamos a hacer que un usuario pueda tener varios roles
entonces creamos la tabla (por convencion en singular y en orden alfabetico)

php artisan make:migration create_user_role_table

en este caso no lo hicimos en orden alfabetico, pero no importa, se le debe indicar el nombre de la tabla al momento de definir la relacion

entonces en User.php

    public function roles(){
        return $this->belongsToMany(Role::class,'user_role');
    }

    public function hasRoles(array $roles)
    {
        foreach ($roles as $role) {
            foreach ($this->roles as $userRole) {
              if($userRole->name == $role){
                return true;
              }
            }
        }
        return false;
    }


en la vista views/user/index.blade,php
..
<td>
@foreach($user->roles as $role)
{{$role->display_name}}
@endforeach
</td>
..

docker exec ejecutar comandos contra contenedores



vamos a crear un nuevo contenedor de ubuntu y le vamos a poner de nombre my_ubuntu

docker run -it --name my-ubuntu ubuntu


entonces desde otra terminal podemos hacer referencia a este contenedor que esta corriendo y ejecutar sobre el algun comando, por ejemplo:

israelb@amco-israelb:~$docker exec my_ubuntu echo hola
hola



vamos ahora a crear un contenedor a partir de la imagen python

israelb@amco-israelb:~$docker run -it python
Unable to find image 'python:latest' locally
latest: Pulling from library/python
f2b6b4884fc8: Already exists 
4fb899b4df21: Pull complete 
74eaa8be7221: Pull complete 
2d6e98fe4040: Pull complete 
414666f7554d: Pull complete 
7e765f6e07f8: Pull complete 
6f02823cd02e: Pull complete 
9dcc4ba372fa: Pull complete 
Digest: sha256:d0aeebb21e5db79b702f315336f34ee4b1ab1bd9aa66d08b32bbc7a7e4c9c078
Status: Downloaded newer image for python:latest
Python 3.6.5 (default, Mar 31 2018, 01:15:58) 
[GCC 4.9.2] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>>


automaticamente nos abre el prompt de pyhton para poder ingresar sentencias python

print('hola')
hola

quit()

si se quisiera hacer otras operaciones sobre ese contenedor se puede desde otra terminal

ejecutar 

docker exec -it mi_python bash

entonces asi ingreso al modo bash del contenedor
ademas desde aqui puedo lanzar distintos comandos
como
pwd
ls -l
incluso entrar al modo python con python

israelb@amco-israelb:~$docker exec -it mi_python ls
bin   dev  home  lib64 mnt  proc  run srv  tmp  var
boot  etc  lib media opt  root  sbin  sys  usr
israelb@amco-israelb:~$docker exec -it mi_python date
Tue May  1 22:34:00 UTC 2018
israelb@amco-israelb:~$




docker borrar imagenes y contenedores


para borrar contenedores lo podemos hacer refiriendonos a ellos a traves de sus IDs o de sus nombres (generados)

por ejemplo

si del sgt listado

israelb@amco-israelb:~$docker ps -a
CONTAINER ID        IMAGE           COMMAND               CREATED     STATUS  PORTS                    NAMES
42c642ff303e        ubuntu                         "/bin/bash"            2 hours ago    Exited (0) 15 seconds ago       sleepy_goodall
e7f3e0ce783e        ubuntu                         "/bin/bash"            4 hours ago    Exited (0) About an hour ago naughty_ardinghelli

para borrar el primero

docker rm 42c

y para borrar el segundo

docker rm naughty_ardinghelli

en este ultimo caso, debemos escribir todo el nombre


similarmente, se borran imagenes

israelb@amco-israelb:~$docker images
REPOSITORY                     TAG                 IMAGE ID            CREATED             SIZE
nginx                          latest              ae513a47849c        32 hours ago        109MB

este imagen se podria borrar

usando 

docker rmi nginx
o
docker rmi ae5

sin embargo, en este caso la imagen tiene un contenedor asociado

israelb@amco-israelb:~$docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS    PORTS               NAMES
f4ce76987b11        nginx               "nginx -g 'daemon of…"   2 hours ago         Up 2 hours          80/tcp              sad_wozniak

por lo que habria que borrar primero ese contenedor y luego la imagen.



docker crear un repositorio

debemos tener creada una cuenta en docker hub

nos logueamos

Create Repository

  1. Choose a namespace (Required) por default sera nuestro nombre de usuario
  2. Add a repository name (Required) -> nombre del repositorio, p.e: r1
  3. Add a short description
  4. Add markdown to the full description field
  5. Set it to be a private or public repository

luego se creara con el sgt nombre

israelbazan76/r1

docker tags y pulls

analicemos los repositorios desde el cual obtenemos las imagenes.

ir a https://hub.docker.com

busquemos "ubuntu" y veamos los detalles
veremos algo asi, en el link de Repo Info:

Supported tags and respective Dockerfile links


en el lado izquierdo estan las versiones y al lado los distintos tags por los que se pueden identificar.
al ejecutar docker run por default se busca la version que tenga el tag latest,
pero si quisieramos usar otra version, habria que indicarla del sgt modo:

docker pull ubuntu:trusty

donde:

pull - a diferencia de run , pull solo descarga la imagen sin crear el contenedor


para ver todos los tags y mayor informacion sobre ellos hacemos click en tags

Tag Name                            Compressed Size       Last Updated
xenial                                          43 MB               19 hours ago
xenial-20180417                         43 MB              19 hours ago
16.04                                           43 MB             9 hours ago






docker crear contenedor en modo background

docker run -d nginx

donde :
-d significa que sera ejecutado en modo detached o desacoplado o en background

israelb@amco-israelb:~$docker run -d nginx
Unable to find image 'nginx:latest' locally
latest: Pulling from library/nginx
f2aa67a397c4: Pull complete
3c091c23e29d: Pull complete
4a99993b8636: Pull complete
Digest: sha256:0fb320e2a1b1620b4905facb3447e3d84ad36da0b2c8aa8fe3a5a81d1187b884
Status: Downloaded newer image for nginx:latest
f4ce76987b114abd26ba9d664dcd2127e65b4dbd6eaa3d8353fc23e46a0cd2bd
israelb@amco-israelb:~$


como vemos luego de ejecutar el contenedor seguimos en el prompt del sistema
si hacemos docker ps, veremos que el contenedor de nginx esta presente

israelb@amco-israelb:~$docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS         PORTS           NAMES
f4ce76987b11        nginx               "nginx -g 'daemon of…"   6 minutes ago       Up 6 minutes        80/tcp            sad_wozniak


docker crear contenedor interactivo


docker run -it ubuntu

donde:

-it : indica que entre al contenedor de modo interactivo(si es que esto es posible) y muestre la salida por el terminal
ubuntu: es una imagen donde hay una version pequeña de ubuntu

Unable to find image 'ubuntu:latest' locally
latest: Pulling from library/ubuntu
a48c500ed24e: Pull complete
1e1de00ff7e1: Pull complete
0330ca45a200: Pull complete
471db38bcfbf: Pull complete
0b4aba487617: Pull complete
Digest: sha256:c8c275751219dadad8fa56b3ac41ca6cb22219ff117ca98fe82b42f24e1ba64e
Status: Downloaded newer image for ubuntu:latest
root@e7f3e0ce783e:/#

como no tenemos la imagen ubuntu localmente se descarga y finalmente nos coloca el prompt dentro del contenedor esperando por, en este caso, algun comando de ubuntu

por ejemplo si hacemos ls -l

root@e7f3e0ce783e:/# ls -l
total 64
drwxr-xr-x   2 root root 4096 Apr 26 21:17 bin
drwxr-xr-x   2 root root 4096 Apr 24 08:34 boot
drwxr-xr-x   5 root root  360 May  1 17:37 dev
drwxr-xr-x   1 root root 4096 May  1 17:37 etc
drwxr-xr-x   2 root root 4096 Apr 24 08:34 home
drwxr-xr-x   8 root root 4096 Apr 26 21:16 lib
drwxr-xr-x   2 root root 4096 Apr 26 21:16 lib64
drwxr-xr-x   2 root root 4096 Apr 26 21:16 media
drwxr-xr-x   2 root root 4096 Apr 26 21:16 mnt
drwxr-xr-x   2 root root 4096 Apr 26 21:16 opt
dr-xr-xr-x 226 root root    0 May  1 17:37 proc
drwx------   2 root root 4096 Apr 26 21:17 root
drwxr-xr-x   1 root root 4096 Apr 27 23:28 run
drwxr-xr-x   1 root root 4096 Apr 27 23:28 sbin
drwxr-xr-x   2 root root 4096 Apr 26 21:16 srv
dr-xr-xr-x  13 root root    0 May  1 17:37 sys
drwxrwxrwt   2 root root 4096 Apr 26 21:17 tmp
drwxr-xr-x   1 root root 4096 Apr 26 21:16 usr
drwxr-xr-x   1 root root 4096 Apr 26 21:17 var

nos mostrara archivos del contenedor , no de nuestra maquina.

desde otra terminal, podemos ver el contenedor que actualmente esta corriendo con docker ps

israelb@amco-israelb:~$docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
e7f3e0ce783e        ubuntu              "/bin/bash"         About an hour ago   Up About an hour                        naughty_ardinghelli

efectivamente, es el de ubuntu el que esta arriba.

si desde la terminal de ubuntu hacemos exit, se cerrara el contenedor y volveremos al prompt de nuestro sistema

root@e7f3e0ce783e:/# exit
exit
israelb@amco-israelb:~$

si hacemos docker ps ya no veremos ningun contenedor corriendo.

para volver a levantarlo hacemos

docker start -i e7f3e0ce783e

donde:
e7f3e0ce783e es el ID del contenedor de ubuntu

no es necesario escribir todo el ID, normalmente con las 3 primeras letras es suficiente

docker start -i e7f


Si ejecutara desde otra terminal

docker run -it ubuntu

docker crea OTRO contenedor a partir de la imagen ubuntu.
es decir, que a partir de una misma imagen, uno podria tener ejecutandose todos los contenedores que quisiera, de hecho si ahora ejecutamos desde otra terminal docker ps, obtendremos

israelb@amco-israelb:~$docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
42c642ff303e        ubuntu              "/bin/bash"         19 seconds ago      Up 17 seconds                           sleepy_goodall
e7f3e0ce783e        ubuntu              "/bin/bash"         2 hours ago         Up 41 minutes                           naughty_ardinghelli

los 2 contenedores que actualmente estan arriba






docker crear primer contenedor

docker run hello-world

lo que hace es:
-el cliente docker se contacta con el daemon
-el daemon busca la imagen hello-world localmente
-como no la encuentra va a docker-hub y descarga la imagen
-crea el container a partir de la imagen descargada
-ejecuta el container

este container de ejemplo lo unico que hace es mostrar un texto.

ahora comprobaremos si es que esta la imagen hello -world

ejecutamos el comando

run images

REPOSITORY                     TAG                 IMAGE ID            CREATED             SIZE
hello-world                    latest              e38bc07ac18e        2 weeks ago         1.85kB

para ver los contenedores que estan corriendo (running)

docker ps

CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES

no nos muestra nada ya que el contanedor creado por la imagen hello-world luego de ejecutarse se ha detenido.

podemos listar todos los contenedores asi:

docker ps -a

CONTAINER ID   IMAGE  COMMAND   CREATED     STATUS                     PORTS     NAMES
4ab81cbeff9c        hello-world  "/hello"     13 minutes ago  Exited (0) 13 minutes ago  priceless_borg

container id = id del contenedor
image = imagen que creó el contenedor
command = comando ejecutado en el contenedor
created = cuando fue ejecutado
status = Estado de la ejecucion ..Exited(0) el 0 significa que no hubo errores
names= nombre aleatorio que se asigna cada vez que se lance un contenedor


recordar que:

un contenedor no se elimina, se queda en estado detenido.

otros comandos interesantes:

docker ps -l

nos lista el ultimo contenedor sobre el que se hizo alguna operacion

CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS                      PORTS               NAMES
4ab81cbeff9c        hello-world         "/hello"            25 minutes ago      Exited (0) 25 minutes ago                       priceless_borg

docker ps -n 4

los ultimos 4 contenedores sobre los que se hizo alguna operacion

docker ps -a -q

lista los IDs de todos los contenedores

docker ps -a -f "name=swagger"

filtra por alguna condicion, por ejemplo los contenedores que tengan en su name la cadena swagger

linux ubuntu mint actualizar chrome

 desde una terminal: $ sudo apt update $ sudo apt install google-chrome-stable