Arquivo de agosto, 2014

Como sabemos o servidor de apresentação do sistema SAP, possui varias funções que permitem comunicação com o servidor de aplicações, como por exemplo, importar e exportar arquivos do lado cliente, entre suas varias outras funções, o servidor de apresentação nos permite também executar programas externos.

WS_EXECUTE é um módulo de função padrão disponível nos sistemas R/3 da SAP, dependendo da versão e nível de release. Esta função é responsável por executar qualquer programa não SAP, por exemplo, um editor, uma calculadora ou qualquer outro programa de sua escolha. WS_EXECUTE executa um programa no servidor de apresentação, podendo também utilizar parâmetros comuns para se comunicar com o executável.

Contudo o sistema SAP possui grande quantidade de funções obsoletas que ainda funcionam por compatibilidade com versões de programas mais antigos, a função WS_EXECUTE é uma delas, você pode substituir esta função pela classe CL_GUI_FRONTEND_SERVICES.

Abaixo vamos criar um programa baseado na brincadeira Simon disse, neste caso nosso programa passara mensagens através de parâmetros para um executável criado em uma outra linguagem de programação, o executável receberá a mensagem e a exibira em seu formulário.

Para a versão mais recente deste procedimento utilize CL_GUI_FRONTEND_SERVICES: Serviços de Frontend SAP

 

Comunicando-se com um programa C# através de parâmetros

1 – Primeiro precisamos criar um programa C# utilizando a IDE Visual Studio. Arraste para o formulário dois componentes Label, um componente PictureBox, 2 Componentes Panel e um componente Richtextbox. A captura dos parâmetros será executada no evento SHOWN do formulário. Utilize a figura abaixo para modelar o design do seu programa:

Visual Studio - Design

Visual Studio – Design

2 – Crie um novo programa Abap e utilize o código abaixo. Entre com um ou mais parâmetros separados por espaço na caixa de texto do sistema SAP e pressione o botão executar na barra de tarefas. Dê permissão para o servidor de apresentação executar o programa:

Parâmetros - Abap

Parâmetros – Abap

3 – Você receberá uma mensagem de acordo com o resultado apresentado pelo servidor de apresentação:

Resultado

Resultado

4 – Pronto o programa C# será executado e receberá os parâmetros enviados que serão mostrados em uma caixa de texto. Visto que o ambiente do .NET Framework nos retorna um ARRAY contendo, primeiro o caminho e o nome do executável e sequencialmente todos os parâmetros enviados:

Programa C# - Parâmetros

Programa C# – Parâmetros

Exemplo:

Neste exemplo escrevemos dois programas em linguagens de programação diferentes e conseguimos uma comunicação entre eles por meio de parâmetros, este simples exemplo nos mostra inúmeras possibilidades de comunicação entre um programa ABAP e programas externos sem utilizar as funções de RFC da SAP.

C#

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace CsSap
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Shown(object sender, EventArgs e)
        {
            // Recupera e exibi parâmetros enviados para o executavel
            string[] args = Environment.GetCommandLineArgs();
            richTextBox1.AppendText(string.Format("{0}", String.Join(", ", args)));      
           
            // TODO: Criar funcionalidades para os parâmetros recebidos.
        }

    }
}

Abap

Função WS_EXECUTE:

*&---------------------------------------------------------------------*
*& Report  ZSAPDISSE
*&
*&---------------------------------------------------------------------*
*& Desenvolvimento Aberto
*& SAP Disse: WS_EXECUTE
*&---------------------------------------------------------------------*

REPORT  ZSAPDISSE.

* cria parametro para os parametros do executavel
PARAMETER SAPDISSE TYPE c LENGTH 70.

* declara variavel para o caminho do executavel
DATA programa TYPE string.

programa = 'C:\Desenvolvimento Aberto\temp\CsSap.exe'.

* Chama função que executa um executavel
CALL FUNCTION 'WS_EXECUTE'
  EXPORTING
    PROGRAM            = programa
    COMMANDLINE        = SAPDISSE
    INFORM             = ' '
  EXCEPTIONS
    FRONTEND_ERROR     = 1
    NO_BATCH           = 2
    PROG_NOT_FOUND     = 3
    ILLEGAL_OPTION     = 4
    GUI_REFUSE_EXECUTE = 5
    OTHERS             = 6.

* verifica estado da execução
CASE SY-SUBRC.
  WHEN 1.
    WRITE: / 'ERRO NO FRONTEND!'.
  WHEN 2.
    WRITE: / 'NO BATCH!'.
  WHEN 3.
    WRITE: / 'PROGRAMA NÃO ECONTRADO!'.
  WHEN 4.
    WRITE: / 'OPÇÃO ILEGAL!'.
  WHEN 5.
    WRITE: / 'SAP GUI SE RECUSOU A EXECUTAR O PROGRAMA!'.
  WHEN 6.
    WRITE: / 'OUTROS ERROS!'.
  WHEN OTHERS.
    WRITE: / 'PROGRAMA EXECUTADO COM SUCESSO!!!!'.
    MESSAGE 'Programa executado com sucesso!' TYPE 'S'.
ENDCASE.

Classe CL_GUI_FRONTEND_SERVICES:

*&---------------------------------------------------------------------*
*& Report  ZSAPDISSE_FES
*&
*&---------------------------------------------------------------------*
*& Desenvolvimento Aberto
*& CL_GUI_FRONTEND_SERVICES
*&---------------------------------------------------------------------*

REPORT  ZSAPDISSE_FES.

* cria parametro para os parametros do executavel
PARAMETER SAPDISSE TYPE string.

* declara variavel para o caminho do executavel
DATA programa TYPE string.

programa = 'C:\Desenvolvimento Aberto\temp\CsSap.exe'.

* Executa método de classe
CL_GUI_FRONTEND_SERVICES=>EXECUTE(
  exporting
    APPLICATION            =     programa
    PARAMETER              =     sapdisse
  exceptions
    CNTL_ERROR             = 1
    ERROR_NO_GUI           = 2
    BAD_PARAMETER          = 3
    FILE_NOT_FOUND         = 4
    PATH_NOT_FOUND         = 5
    FILE_EXTENSION_UNKNOWN = 6
    ERROR_EXECUTE_FAILED   = 7
    SYNCHRONOUS_FAILED     = 8
    NOT_SUPPORTED_BY_GUI   = 9
    OTHERS                 = 10 ).

* verifica estado da execução
CASE SY-SUBRC.
  WHEN 1.
    WRITE: / 'ERRO CNTL!'.
  WHEN 2.
    WRITE: / 'ERRO NO FRONTEND!!'.
  WHEN 3.
    WRITE: / 'ERRO NO PARAMETRO!'.
  WHEN 4.
    WRITE: / 'PROGRAMA NÃO ECONTRADO!'.
  WHEN 5.
    WRITE: / 'CAMINHO NÃO ECONTRADO!'.
  WHEN 6.
    WRITE: / 'EXTENSÃO DESCONHECIDA!'.
  WHEN 7.
    WRITE: / 'ERRO DE EXECUÇÃO!'.
  WHEN 8.
    WRITE: / 'FALHA NA SINCRONIZAÇÃO!'.
  WHEN 9.
    WRITE: / 'NÃO SUPORTADO PELO GUI!'.
  WHEN 10.
    WRITE: / 'OUTROS!'.
  WHEN OTHERS.
    WRITE: / 'PROGRAMA EXECUTADO COM SUCESSO!!!!'.
    MESSAGE 'Programa executado com sucesso!' TYPE 'S'.
ENDCASE.

 

Para ler dados a partir do servidor de apresentação para uma tabela interna usando um diálogo de usuário, use a função de Upload. Para ler dados a partir do servidor de apresentação para uma tabela interna sem o uso de uma caixa de diálogo do usuário, use a função WS_UPLOAD. Para mais informações, consulte a documentação do módulo de função (SE37).

Contudo o sistema SAP possui grande quantidade de funções obsoletas que ainda funcionam por compatibilidade com versões de programas mais antigos, a função Upload é uma delas, você pode substituir esta função pela função chamada GUI_UPLOAD.

GUI_UPLOAD: Função GUI_UPLOAD

Importando arquivo do Excel para uma tabela interna

1 – Para utilizar este exemplo, primeiro crie uma planilha comum com três colunas do tipo xls:

Open Office Calc

Open Office Calc

2 – Exporte a planilha para um arquivo texto separado por tabulações:

Texto - separados por tab

Texto – separados por tab

3 – Utilize o código abaixo para importar o arquivo para uma tabela interna:

Tabela Interna

Tabela Interna

 

Exemplo:

Neste exemplo importamos dados de um arquivo texto separado por tabs de uma planilha no formato xls.

Abap

Function : UPLOAD

*&---------------------------------------------------------------------*
*& Report  ZDATASERVER3
*&
*&---------------------------------------------------------------------*
*& Desenvolvimento Aberto
*& Servidor de Apresentação - Upload
*&---------------------------------------------------------------------*

REPORT  ZDATASERVER3.

* Declara variaveis
DATA: FNOME(128), FTIPO(3), FTAMANHO TYPE I.

* Cria tabela
TYPES: BEGIN OF LINE,
  COL1(10) TYPE C,
  COL2(10) TYPE C,
  COL3(20) TYPE C,
END OF LINE.

* Cria e declara tabela interna
TYPES ITAB TYPE LINE OCCURS 10.
DATA: LIN TYPE LINE,
TAB TYPE ITAB.

* Chama a função de Upload
CALL FUNCTION 'UPLOAD'
  EXPORTING
    CODEPAGE            = 'IBM'
    FILENAME            = 'C:\Desenvolvimento Aberto\temp\Plan001.txt'
    FILETYPE            = 'DAT'
    ITEM                = 'Lê arquivo txt separado por tab exportado do Excel'
  IMPORTING
    FILESIZE            = FTAMANHO
    ACT_FILENAME        = FNOME
    ACT_FILETYPE        = FTIPO
  TABLES
    DATA_TAB            = TAB
  EXCEPTIONS
    CONVERSION_ERROR    = 1
    INVALID_TABLE_WIDTH = 2
    INVALID_TYPE        = 3.

* Imprime dados na tela
WRITE: 'SY-SUBRC:', SY-SUBRC,
/ 'Name :', (60) FNOME,
/ 'Type :', FTIPO,
/ 'Size :', FTAMANHO.

SKIP 2.

WRITE / 'Conteudo do Arquivo .TXT:'.

SKIP.

LOOP AT TAB INTO LIN.
  WRITE: / LIN-COL1, LIN-COL2 COLOR 4 INVERSE, LIN-COL3 COLOR 3 INVERSE.
ENDLOOP.

Function : GUI_UPLOAD

*&---------------------------------------------------------------------*
*& Report  ZDATASERVER4
*&
*&---------------------------------------------------------------------*
*& Desenvolvimento Aberto
*& GUI_UPLOAD
*&---------------------------------------------------------------------*

REPORT  ZDATASERVER4.

* Declara variaveis
DATA: FTAMANHO TYPE I.

* Cria tabela
TYPES: BEGIN OF LINE,
  COL1(10) TYPE C,
  COL2(10) TYPE C,
  COL3(20) TYPE C,
END OF LINE.

* Cria e declara tabela interna
TYPES ITAB TYPE LINE OCCURS 10.
DATA: LIN TYPE LINE,
TAB TYPE ITAB.

* Chama função GUI_UPLOAD
CALL FUNCTION 'GUI_UPLOAD'
  exporting
    FILENAME                = 'C:\Desenvolvimento Aberto\temp\Plan001.txt'
    FILETYPE                = 'DAT'
  importing
    FILELENGTH              = FTAMANHO
  tables
    DATA_TAB                = TAB
  exceptions
    FILE_OPEN_ERROR         = 1
    FILE_READ_ERROR         = 2
    INVALID_TYPE            = 3.

* Imprime dados na tela
WRITE: 'SY-SUBRC:', SY-SUBRC,
     / 'Size :', FTAMANHO.

SKIP 2.

WRITE / 'Conteudo do Arquivo .TXT:'.

SKIP.

LOOP AT TAB INTO LIN.
  WRITE: / LIN-COL1, LIN-COL2 COLOR 4 INVERSE, LIN-COL3 COLOR 3 INVERSE.
ENDLOOP.

Para gravar dados a partir de uma tabela interna para o servidor de apresentação usando um diálogo de usuário, use a função de Download. Para gravar dados de uma tabela interna para o servidor de apresentação sem o uso de uma caixa de diálogo do usuário, use a função WS_DOWNLOAD. Para mais informações, consulte a documentação do módulo de função (SE37).

Contudo o sistema SAP possui grande quantidade de funções obsoletas que ainda funcionam por compatibilidade com versões de programas mais antigos, a função Download é uma delas, você pode substituir esta função pela função chamada GUI_DOWNLOAD.

Exporta para XLS

Exporta para XLS

GUI_DOWNLOAD: http://help.sap.com/saphelp_nw70ehp2/helpdata/de/c7/5ab8ec178c44a8aacd1dcac3460db8/content.htm

Exemplo:

Neste exemplo extraímos dados de uma tabela interna em um arquivo Excel e o salvamos no computador local.

Abap

Function : DOWNLOAD

*&---------------------------------------------------------------------*
*& Report  ZDATASERVER
*&
*&---------------------------------------------------------------------*
*& Desenvolvimento Aberto
*& Escreve dados no servidor de apresentação
*&---------------------------------------------------------------------*

REPORT  ZDATASERVER.

* Declara Variáveis
DATA: FNOME(128), FTIPO(3), FTAMANHO TYPE I.

* Cria tabela com duas colunas
TYPES: BEGIN OF LINE,
  COL1 TYPE I,
  COL2 TYPE I,
END OF LINE.

* Cria Tabela temporaria
TYPES ITAB TYPE LINE OCCURS 15.
DATA: LIN  TYPE LINE, TAB TYPE ITAB.

* Cria e adiciona dados a tabela
DO 15 TIMES.
  LIN-COL1 = SY-INDEX.
  LIN-COL2 = SY-INDEX ** 2.
  APPEND LIN TO TAB.
ENDDO.

* Chama a função de download
* Dat cria tipo do Excel
CALL FUNCTION 'DOWNLOAD'
  EXPORTING
    CODEPAGE            = 'IBM'
    FILENAME            = 'C:\Desenvolvimento Aberto\temp\Planilha.xls'
    FILETYPE            = 'DAT'
    ITEM                = 'Teste Excel'
  IMPORTING
    ACT_FILENAME        = FNOME
    ACT_FILETYPE        = FTIPO
    FILESIZE            = FTAMANHO
  TABLES
    DATA_TAB            = TAB
  EXCEPTIONS
    INVALID_FILESIZE    = 1
    INVALID_TABLE_WIDTH = 2
    INVALID_TYPE        = 3.

* Imprime resultado
WRITE: 'SY-SUBRC:', SY-SUBRC,
     / 'Nome :', (60) FNOME,
     / 'Tipo :', FTIPO,
     / 'Tamanho :', FTAMANHO.

WRITE : / 'Conteudo do arquivo:', /.
LOOP AT tab INTO lin.
   WRITE : / LIN-COL1 COLOR 3 INVERSE,
             LIN-COL2 COLOR 3 INVERSE.
ENDLOOP.

Function : GUI_DOWNLOAD

*&---------------------------------------------------------------------*
*& Report  ZDATASERVER2
*&
*&---------------------------------------------------------------------*
*& Desenvolvimento Aberto
*& GUI_DOWNLOAD
*&---------------------------------------------------------------------*

REPORT  ZDATASERVER2.
* Declara Variáveis
DATA:  FTAMANHO TYPE I.

* Cria tabela com duas colunas
TYPES: BEGIN OF LINE,
  COL1 TYPE I,
  COL2 TYPE I,
END OF LINE.

* Cria Tabela temporaria
TYPES ITAB TYPE LINE OCCURS 15.
DATA: LIN  TYPE LINE, TAB TYPE ITAB.

* Cria e adiciona dados a tabela
DO 15 TIMES.
  LIN-COL1 = SY-INDEX.
  LIN-COL2 = SY-INDEX ** 2.
  APPEND LIN TO TAB.
ENDDO.

* Chama a função de download
* Dat cria tipo do Excel
CALL FUNCTION 'GUI_DOWNLOAD'
  EXPORTING
    FILENAME   = 'C:\Desenvolvimento Aberto\temp\Planilha2.xls'
    FILETYPE   = 'DAT'
  IMPORTING
    FILELENGTH = FTAMANHO
  TABLES
    DATA_TAB   = TAB.

* Imprime resultado
WRITE: 'SY-SUBRC:', SY-SUBRC,
     / 'Tamanho :', FTAMANHO.

WRITE : / 'Conteudo do arquivo:', /.
LOOP AT tab INTO lin.
  WRITE : / LIN-COL1 COLOR 3 INVERSE,
            LIN-COL2 COLOR 3 INVERSE.
ENDLOOP.

Wget – Como Clonar Sites – C – Linux

Publicado: 7 de agosto de 2014 em Hacking

Você sabe que o mundo da internet é recheado de perigos e os mais comuns são os vírus, worms, malwares e cavalos de troia, estes são pequenos programas criados para causar algum dano ao computador, seja apagando dados, capturando informações ou alterando o funcionamento normal da máquina. Com o combate intensivo a estas enfermidades, as empresas de antivírus atualizam constantemente nossos computadores com vacinas e proteções contra estas pragas virtuais, sendo assim desenvolvedores mal intencionados encontram outras formas, muitas vezes até mais simples para conseguir enganar e prejudicar o usuário final, e nem sempre o perigo vem da construção de complexos códigos e programas mirabolantes, e a forma mais fácil de roubar dados de um usuário é fazer com que o próprio usuário os entregue.

Cuidado com seus dados pessoais

Por este motivo tenha cuidado ao alimentar dados pessoais, mesmo em sites conhecidos, pois agora você vai aprender como é fácil cair em uma armadilha que pode custar muito caro. Se você é um aficionado por tecnologia e gosta de saber como as coisas são feitas realmente, você pode simular a clonagem de um site no seu computador.

Vamos criar um clone em um servidor web padrão instalado em nosso sistema operacional. Tudo que precisamos é um sistema operacional Linux padrão, um servidor web, e conhecimento básico na linguagem de scripts HTML. Isso! e nada mais!

WGet

GNU Wget é um programa livre, de fonte aberto, escrito com a poderosa linguagem de programação que propicia o download de dados da web. É parte do projeto GNU. Seu nome deriva de World Wide Web e get. Ele suporta os protocolos HTTP, HTTPS e FTP. A instalação padrão do Ubuntu já contempla este programa. O Wget possui vários parâmetros e você pode efetuar downloads específicos ou até mesmo de sites inteiros. Na verdade este programa é muito útil, porem pode ser usado por usuários mal intencionados para clonar sites.

Pagina oficial: https://www.gnu.org/software/wget/

Manual: Wget Manual

 

Como Clonar Um Site

1 – Primeiro você precisa de um servidor web instalado em seu computador, você pode usar o servidor gratuito Apache2, caso você queira saber como instalar e configurar o servidor Apache em Linux, clique aqui.

Site Windows - Original

Site Windows – Original

 

2 – Faremos um teste na pagina oficial do Windows 8. Após instalar e configurar o Apache, crie uma pasta qualquer no diretório de sua preferencia, abra o terminal do Linux na pasta que você criou e digite o seguinte comando:


wget -S http://windows.microsoft.com/pt-br/windows/home

Wget - Terminal

Wget – Terminal

 

3 – Após o download você pode renomear a pagina baixada para index.html e modifica-la como bem entender no editor de sua preferencia, caso queira usar o padrão Linux, use o GEdit. Copie o arquivo baixado e modificado para o diretório www do Apache, abra o browser e digite localhost:

Site - Windows - Clonado - Localhost

Site – Windows – Clonado – Localhost

 

Pronto! Como você pode ver localhost é o servidor web do computador local, um servidor web como qualquer outro onde os sites são hospedados, geralmente desenvolvedores mal intencionados utilizam um domínio muito parecido com o domínio utilizado pelo site que foi clonado, tentando enganar os usuários mais desatentos, estes sites são hospedados em servidores web de outros países dificultando assim sua completa identificação.

Quase sempre estes sites coletam informações pessoais como numero de cartão de crédito, senhas, contas bancarias e outros dados relevantes que possam causar algum tipo de prejuízo ao usuário dos sites originais, outras vezes estes sites servem apenas para contaminar o computador do usuário com vírus ou outros tipo softwares que podem resultar em controle total do computador. Assim que seu objetivo é alcançado estes sites simplesmente desaparecem.

 

Exemplo:

Neste exemplo utilizamos o programa wget pré-instalado no Linux para clonar a pagina índice do site do Windows, modificamos o HTML da pagina e a colamos em um servidor web de testes no computador local. Visto que a pagina clonada possui os links originais e é totalmente utilizável.

Caso você queira aprender como funciona este programa você pode baixar o código fonte deste link:
Wget source code: http://ftp.gnu.org/gnu/wget/

C

Use o código abaixo para conhecer os parâmetros disponibilizados pelo programa wget de um ponto de vista do desenvolvedor.

Main.c

/* Command line parsing.
   Copyright (C) 1995, 1996, 1997, 1998 Free Software Foundation, Inc.

This file is part of Wget.

This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */

#include <config.h>

#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#ifdef HAVE_UNISTD_H
# include <unistd.h>
#endif /* HAVE_UNISTD_H */
#include <sys/types.h>
#ifdef HAVE_STRING_H
# include <string.h>
#else
# include <strings.h>
#endif /* HAVE_STRING_H */
#ifdef HAVE_SIGNAL_H
# include <signal.h>
#endif
#ifdef HAVE_NLS
#ifdef HAVE_LOCALE_H
# include <locale.h>
#endif /* HAVE_LOCALE_H */
#endif /* HAVE_NLS */

#define OPTIONS_DEFINED_HERE	/* for options.h */

#include "wget.h"
#include "utils.h"
#include "getopt.h"
#include "init.h"
#include "retr.h"
#include "recur.h"
#include "host.h"

#ifndef PATH_SEPARATOR
# define PATH_SEPARATOR '/'
#endif

extern char *version_string;

#ifndef errno
extern int errno;
#endif

struct options opt;

/* From log.c.  */
void log_init PARAMS ((const char *, int));
void log_close PARAMS ((void));
void redirect_output PARAMS ((const char *));

static RETSIGTYPE redirect_output_signal PARAMS ((int));

const char *exec_name;

/* Initialize I18N.  The initialization amounts to invoking
   setlocale(), bindtextdomain() and textdomain().
   Does nothing if NLS is disabled or missing.  */
static void
i18n_initialize (void)
{
  /* If HAVE_NLS is defined, assume the existence of the three
     functions invoked here.  */
#ifdef HAVE_NLS
  /* Set the current locale.  */
  /* Here we use LC_MESSAGES instead of LC_ALL, for two reasons.
     First, message catalogs are all of I18N Wget uses anyway.
     Second, setting LC_ALL has a dangerous potential of messing
     things up.  For example, when in a foreign locale, Solaris
     strptime() fails to handle international dates correctly, which
     makes http_atotm() malfunction.  */
  setlocale (LC_MESSAGES, "");
  /* Set the text message domain.  */
  bindtextdomain ("wget", LOCALEDIR);
  textdomain ("wget");
#endif /* HAVE_NLS */
}

/* Print the usage message.  */
static void
print_usage (void)
{
  printf (_("Usage: %s [OPTION]... [URL]...\n"), exec_name);
}

/* Print the help message, describing all the available options.  If
   you add an option, be sure to update this list.  */
static void
print_help (void)
{
  printf (_("GNU Wget %s, a non-interactive network retriever.\n"),
	  version_string);
  print_usage ();
  /* Had to split this in parts, so the #@@#%# Ultrix compiler and cpp
     don't bitch.  Also, it makes translation much easier.  */
  printf ("%s%s%s%s%s%s%s%s%s%s", _("\
\n\
Mandatory arguments to long options are mandatory for short options too.\n\
\n"), _("\
Startup:\n\
  -V,  --version           display the version of Wget and exit.\n\
  -h,  --help              print this help.\n\
  -b,  --background        go to background after startup.\n\
  -e,  --execute=COMMAND   execute a `.wgetrc\' command.\n\
\n"), _("\
Logging and input file:\n\
  -o,  --output-file=FILE     log messages to FILE.\n\
  -a,  --append-output=FILE   append messages to FILE.\n\
  -d,  --debug                print debug output.\n\
  -q,  --quiet                quiet (no output).\n\
  -v,  --verbose              be verbose (this is the default).\n\
  -nv, --non-verbose          turn off verboseness, without being quiet.\n\
  -i,  --input-file=FILE      read URL-s from file.\n\
  -F,  --force-html           treat input file as HTML.\n\
\n"), _("\
Download:\n\
  -t,  --tries=NUMBER           set number of retries to NUMBER (0 unlimits).\n\
  -O   --output-document=FILE   write documents to FILE.\n\
  -nc, --no-clobber             don\'t clobber existing files.\n\
  -c,  --continue               restart getting an existing file.\n\
       --dot-style=STYLE        set retrieval display style.\n\
  -N,  --timestamping           don\'t retrieve files if older than local.\n\
  -S,  --server-response        print server response.\n\
       --spider                 don\'t download anything.\n\
  -T,  --timeout=SECONDS        set the read timeout to SECONDS.\n\
  -w,  --wait=SECONDS           wait SECONDS between retrievals.\n\
  -Y,  --proxy=on/off           turn proxy on or off.\n\
  -Q,  --quota=NUMBER           set retrieval quota to NUMBER.\n\
\n"),  _("\
Directories:\n\
  -nd  --no-directories            don\'t create directories.\n\
  -x,  --force-directories         force creation of directories.\n\
  -nH, --no-host-directories       don\'t create host directories.\n\
  -P,  --directory-prefix=PREFIX   save files to PREFIX/...\n\
       --cut-dirs=NUMBER           ignore NUMBER remote directory components.\n\
\n"), _("\
HTTP options:\n\
       --http-user=USER      set http user to USER.\n\
       --http-passwd=PASS    set http password to PASS.\n\
  -C,  --cache=on/off        (dis)allow server-cached data (normally allowed).\n\
       --ignore-length       ignore `Content-Length\' header field.\n\
       --header=STRING       insert STRING among the headers.\n\
       --proxy-user=USER     set USER as proxy username.\n\
       --proxy-passwd=PASS   set PASS as proxy password.\n\
  -s,  --save-headers        save the HTTP headers to file.\n\
  -U,  --user-agent=AGENT    identify as AGENT instead of Wget/VERSION.\n\
\n"), _("\
FTP options:\n\
       --retr-symlinks   retrieve FTP symbolic links.\n\
  -g,  --glob=on/off     turn file name globbing on or off.\n\
       --passive-ftp     use the \"passive\" transfer mode.\n\
\n"), _("\
Recursive retrieval:\n\
  -r,  --recursive             recursive web-suck -- use with care!.\n\
  -l,  --level=NUMBER          maximum recursion depth (0 to unlimit).\n\
       --delete-after          delete downloaded files.\n\
  -k,  --convert-links         convert non-relative links to relative.\n\
  -m,  --mirror                turn on options suitable for mirroring.\n\
  -nr, --dont-remove-listing   don\'t remove `.listing\' files.\n\
\n"), _("\
Recursive accept/reject:\n\
  -A,  --accept=LIST                list of accepted extensions.\n\
  -R,  --reject=LIST                list of rejected extensions.\n\
  -D,  --domains=LIST               list of accepted domains.\n\
       --exclude-domains=LIST       comma-separated list of rejected domains.\n\
  -L,  --relative                   follow relative links only.\n\
       --follow-ftp                 follow FTP links from HTML documents.\n\
  -H,  --span-hosts                 go to foreign hosts when recursive.\n\
  -I,  --include-directories=LIST   list of allowed directories.\n\
  -X,  --exclude-directories=LIST   list of excluded directories.\n\
  -nh, --no-host-lookup             don\'t DNS-lookup hosts.\n\
  -np, --no-parent                  don\'t ascend to the parent directory.\n\
\n"), _("Mail bug reports and suggestions to <bug-wget@gnu.org>.\n"));
}

int
main (int argc, char *const *argv)
{
  char **url, **t;
  int i, c, nurl, status, append_to_log;

  static struct option long_options[] =
  {
    { "background", no_argument, NULL, 'b' },
    { "continue", no_argument, NULL, 'c' },
    { "convert-links", no_argument, NULL, 'k' },
    { "debug", no_argument, NULL, 'd' },
    { "dont-remove-listing", no_argument, NULL, 21 },
    { "email-address", no_argument, NULL, 'E' }, /* undocumented (debug) */
    { "follow-ftp", no_argument, NULL, 14 },
    { "force-directories", no_argument, NULL, 'x' },
    { "force-hier", no_argument, NULL, 'x' }, /* obsolete */
    { "force-html", no_argument, NULL, 'F'},
    { "help", no_argument, NULL, 'h' },
    { "ignore-length", no_argument, NULL, 10 },
    { "mirror", no_argument, NULL, 'm' },
    { "no-clobber", no_argument, NULL, 13 },
    { "no-directories", no_argument, NULL, 19 },
    { "no-host-directories", no_argument, NULL, 20 },
    { "no-host-lookup", no_argument, NULL, 22 },
    { "no-parent", no_argument, NULL, 5 },
    { "non-verbose", no_argument, NULL, 18 },
    { "passive-ftp", no_argument, NULL, 11 },
    { "quiet", no_argument, NULL, 'q' },
    { "recursive", no_argument, NULL, 'r' },
    { "relative", no_argument, NULL, 'L' },
    { "retr-symlinks", no_argument, NULL, 9 },
    { "save-headers", no_argument, NULL, 's' },
    { "server-response", no_argument, NULL, 'S' },
    { "span-hosts", no_argument, NULL, 'H' },
    { "spider", no_argument, NULL, 4 },
    { "timestamping", no_argument, NULL, 'N' },
    { "verbose", no_argument, NULL, 'v' },
    { "version", no_argument, NULL, 'V' },

    { "accept", required_argument, NULL, 'A' },
    { "append-output", required_argument, NULL, 'a' },
    { "backups", required_argument, NULL, 23 }, /* undocumented */
    { "base", required_argument, NULL, 'B' },
    { "cache", required_argument, NULL, 'C' },
    { "cut-dirs", required_argument, NULL, 17 },
    { "delete-after", no_argument, NULL, 8 },
    { "directory-prefix", required_argument, NULL, 'P' },
    { "domains", required_argument, NULL, 'D' },
    { "dot-style", required_argument, NULL, 6 },
    { "execute", required_argument, NULL, 'e' },
    { "exclude-directories", required_argument, NULL, 'X' },
    { "exclude-domains", required_argument, NULL, 12 },
    { "glob", required_argument, NULL, 'g' },
    { "header", required_argument, NULL, 3 },
    { "htmlify", required_argument, NULL, 7 },
    { "http-passwd", required_argument, NULL, 2 },
    { "http-user", required_argument, NULL, 1 },
    { "include-directories", required_argument, NULL, 'I' },
    { "input-file", required_argument, NULL, 'i' },
    { "level", required_argument, NULL, 'l' },
    { "no", required_argument, NULL, 'n' },
    { "output-document", required_argument, NULL, 'O' },
    { "output-file", required_argument, NULL, 'o' },
    { "proxy", required_argument, NULL, 'Y' },
    { "proxy-passwd", required_argument, NULL, 16 },
    { "proxy-user", required_argument, NULL, 15 },
    { "quota", required_argument, NULL, 'Q' },
    { "reject", required_argument, NULL, 'R' },
    { "timeout", required_argument, NULL, 'T' },
    { "tries", required_argument, NULL, 't' },
    { "user-agent", required_argument, NULL, 'U' },
    { "use-proxy", required_argument, NULL, 'Y' },
    { "wait", required_argument, NULL, 'w' },
    { 0, 0, 0, 0 }
  };

  i18n_initialize ();

  append_to_log = 0;

  /* Construct the name of the executable, without the directory part.  */
  exec_name = strrchr (argv[0], PATH_SEPARATOR);
  if (!exec_name)
    exec_name = argv[0];
  else
    ++exec_name;

#ifdef WINDOWS
  windows_main_junk (&argc, (char **) argv, (char **) &exec_name);
#endif

  initialize ();

  while ((c = getopt_long (argc, argv, "\
hVqvdksxmNWrHSLcFbEY:g:T:U:O:l:n:i:o:a:t:D:A:R:P:B:e:Q:X:I:w:",
			   long_options, (int *)0)) != EOF)
    {
      switch (c)
	{
	  /* Options without arguments: */
	case 4:
	  setval ("spider", "on");
	  break;
	case 5:
	  setval ("noparent", "on");
	  break;
	case 8:
	  setval ("deleteafter", "on");
	  break;
	case 9:
	  setval ("retrsymlinks", "on");
	  break;
	case 10:
	  setval ("ignorelength", "on");
	  break;
	case 11:
	  setval ("passiveftp", "on");
	  break;
	case 13:
	  setval ("noclobber", "on");
	  break;
	case 14:
	  setval ("followftp", "on");
	  break;
	case 17:
	  setval ("cutdirs", optarg);
	  break;
	case 18:
	  setval ("verbose", "off");
	  break;
	case 19:
	  setval ("dirstruct", "off");
	  break;
	case 20:
	  setval ("addhostdir", "off");
	  break;
	case 21:
	  setval ("removelisting", "off");
	  break;
	case 22:
	  setval ("simplehostcheck", "on");
	  break;
	case 'b':
	  setval ("background", "on");
	  break;
	case 'c':
	  setval ("continue", "on");
	  break;
	case 'd':
#ifdef DEBUG
	  setval ("debug", "on");
#else  /* not DEBUG */
	  fprintf (stderr, _("%s: debug support not compiled in.\n"),
		   exec_name);
#endif /* not DEBUG */
	  break;
	case 'E':
	  /* For debugging purposes.  */
	  printf ("%s\n", ftp_getaddress ());
	  exit (0);
	  break;
	case 'F':
	  setval ("forcehtml", "on");
	  break;
	case 'H':
	  setval ("spanhosts", "on");
	  break;
	case 'h':
	  print_help ();
#ifdef WINDOWS
	  ws_help (exec_name);
#endif
	  exit (0);
	  break;
	case 'k':
	  setval ("convertlinks", "on");
	  break;
	case 'L':
	  setval ("relativeonly", "on");
	  break;
	case 'm':
	  setval ("mirror", "on");
	  break;
	case 'N':
	  setval ("timestamping", "on");
	  break;
	case 'S':
	  setval ("serverresponse", "on");
	  break;
	case 's':
	  setval ("saveheaders", "on");
	  break;
	case 'q':
	  setval ("quiet", "on");
	  break;
	case 'r':
	  setval ("recursive", "on");
	  break;
	case 'V':
	  printf ("GNU Wget %s\n\n", version_string);
	  printf ("%s", _("\
Copyright (C) 1995, 1996, 1997, 1998 Free Software Foundation, Inc.\n\
This program is distributed in the hope that it will be useful,\n\
but WITHOUT ANY WARRANTY; without even the implied warranty of\n\
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\
GNU General Public License for more details.\n"));
	  printf (_("\nWritten by Hrvoje Niksic <hniksic@srce.hr>.\n"));
	  exit (0);
	  break;
	case 'v':
	  setval ("verbose", "on");
	  break;
	case 'x':
	  setval ("dirstruct", "on");
	  break;

	  /* Options accepting an argument: */
	case 1:
	  setval ("httpuser", optarg);
	  break;
	case 2:
	  setval ("httppasswd", optarg);
	  break;
	case 3:
	  setval ("header", optarg);
	  break;
	case 6:
	  setval ("dotstyle", optarg);
	  break;
	case 7:
	  setval ("htmlify", optarg);
	  break;
	case 12:
	  setval ("excludedomains", optarg);
	  break;
	case 15:
	  setval ("proxyuser", optarg);
	  break;
	case 16:
	  setval ("proxypasswd", optarg);
	  break;
	case 23:
	  setval ("backups", optarg);
	  break;
	case 'A':
	  setval ("accept", optarg);
	  break;
	case 'a':
	  setval ("logfile", optarg);
	  append_to_log = 1;
	  break;
	case 'B':
	  setval ("base", optarg);
	  break;
	case 'C':
	  setval ("cache", optarg);
	  break;
	case 'D':
	  setval ("domains", optarg);
	  break;
	case 'e':
	  {
	    char *com, *val;
	    if (parse_line (optarg, &com, &val))
	      {
		if (!setval (com, val))
		  exit (1);
	      }
	    else
	      {
		fprintf (stderr, _("%s: %s: invalid command\n"), exec_name,
			 optarg);
		exit (1);
	      }
	    free (com);
	    free (val);
	  }
	  break;
	case 'g':
	  setval ("glob", optarg);
	  break;
	case 'I':
	  setval ("includedirectories", optarg);
	  break;
	case 'i':
	  setval ("input", optarg);
	  break;
	case 'l':
	  setval ("reclevel", optarg);
	  break;
	case 'n':
	  {
	    /* #### The n? options are utter crock!  */
	    char *p;

	    for (p = optarg; *p; p++)
	      switch (*p)
		{
		case 'v':
		  setval ("verbose", "off");
		  break;
		case 'h':
		  setval ("simplehostcheck", "on");
		  break;
		case 'H':
		  setval ("addhostdir", "off");
		  break;
		case 'd':
		  setval ("dirstruct", "off");
		  break;
		case 'c':
		  setval ("noclobber", "on");
		  break;
		case 'r':
		  setval ("removelisting", "off");
		  break;
		case 'p':
		  setval ("noparent", "on");
		  break;
		default:
		  printf (_("%s: illegal option -- `-n%c'\n"), exec_name, *p);
		  print_usage ();
		  printf ("\n");
		  printf (_("Try `%s --help\' for more options.\n"), exec_name);
		  exit (1);
		}
	    break;
	  }
	case 'O':
	  setval ("outputdocument", optarg);
	  break;
	case 'o':
	  setval ("logfile", optarg);
	  break;
	case 'P':
	  setval ("dirprefix", optarg);
	  break;
	case 'Q':
	  setval ("quota", optarg);
	  break;
	case 'R':
	  setval ("reject", optarg);
	  break;
	case 'T':
	  setval ("timeout", optarg);
	  break;
	case 't':
	  setval ("tries", optarg);
	  break;
	case 'U':
	  setval ("useragent", optarg);
	  break;
	case 'w':
	  setval ("wait", optarg);
	  break;
	case 'X':
	  setval ("excludedirectories", optarg);
	  break;
	case 'Y':
	  setval ("useproxy", optarg);
	  break;

	case '?':
	  print_usage ();
	  printf ("\n");
	  printf (_("Try `%s --help' for more options.\n"), exec_name);
	  exit (0);
	  break;
	}
    }
  if (opt.verbose == -1)
    opt.verbose = !opt.quiet;

  /* Sanity checks.  */
  if (opt.verbose && opt.quiet)
    {
      printf (_("Can't be verbose and quiet at the same time.\n"));
      print_usage ();
      exit (1);
    }
  if (opt.timestamping && opt.noclobber)
    {
      printf (_("\
Can't timestamp and not clobber old files at the same time.\n"));
      print_usage ();
      exit (1);
    }
  nurl = argc - optind;
  if (!nurl && !opt.input_filename)
    {
      /* No URL specified.  */
      printf (_("%s: missing URL\n"), exec_name);
      print_usage ();
      printf ("\n");
      /* #### Something nicer should be printed here -- similar to the
	 pre-1.5 `--help' page.  */
      printf (_("Try `%s --help' for more options.\n"), exec_name);
      exit (1);
    }

  if (opt.background)
    fork_to_background ();

  /* Allocate basic pointer.  */
  url = ALLOCA_ARRAY (char *, nurl + 1);
  /* Fill in the arguments.  */
  for (i = 0; i < nurl; i++, optind++)
    {
      char *irix4_cc_needs_this;
      STRDUP_ALLOCA (irix4_cc_needs_this, argv[optind]);
      url[i] = irix4_cc_needs_this;
    }
  url[i] = NULL;

  /* Change the title of console window on Windows.  #### I think this
     statement should belong to retrieve_url().  --hniksic.  */
#ifdef WINDOWS
  ws_changetitle (*url, nurl);
#endif

  /* Initialize logging.  */
  log_init (opt.lfilename, append_to_log);

  DEBUGP (("DEBUG output created by Wget %s on %s.\n\n", version_string,
	   OS_TYPE));
  /* Open the output filename if necessary.  */
  if (opt.output_document)
    {
      if (HYPHENP (opt.output_document))
	opt.dfp = stdout;
      else
	{
	  opt.dfp = fopen (opt.output_document, "wb");
	  if (opt.dfp == NULL)
	    {
	      perror (opt.output_document);
	      exit (1);
	    }
	}
    }

#ifdef WINDOWS
  ws_startup ();
#endif

  /* Setup the signal handler to redirect output when hangup is
     received.  */
#ifdef HAVE_SIGNAL
  if (signal(SIGHUP, SIG_IGN) != SIG_IGN)
    signal(SIGHUP, redirect_output_signal);
  /* ...and do the same for SIGUSR1.  */
  signal (SIGUSR1, redirect_output_signal);
  /* Writing to a closed socket normally signals SIGPIPE, and the
     process exits.  What we want is to ignore SIGPIPE and just check
     for the return value of write().  */
  signal (SIGPIPE, SIG_IGN);
#endif /* HAVE_SIGNAL */

  status = RETROK;		/* initialize it, just-in-case */
  recursive_reset ();
  /* Retrieve the URLs from argument list.  */
  for (t = url; *t; t++)
    {
      char *filename, *new_file;
      int dt;

      status = retrieve_url (*t, &filename, &new_file, NULL, &dt);
      if (opt.recursive && status == RETROK && (dt & TEXTHTML))
	status = recursive_retrieve (filename, new_file ? new_file : *t);
      FREE_MAYBE (new_file);
      FREE_MAYBE (filename);
    }

  /* And then from the input file, if any.  */
  if (opt.input_filename)
    {
      int count;
      status = retrieve_from_file (opt.input_filename, opt.force_html, &count);
      if (!count)
	logprintf (LOG_NOTQUIET, _("No URLs found in %s.\n"),
		   opt.input_filename);
    }
  /* Print the downloaded sum.  */
  if (opt.recursive
      || nurl > 1
      || (opt.input_filename && opt.downloaded != 0))
    {
      logprintf (LOG_NOTQUIET,
		 _("\nFINISHED --%s--\nDownloaded: %s bytes in %d files\n"),
		 time_str (NULL), legible (opt.downloaded), opt.numurls);
      /* Print quota warning, if exceeded.  */
      if (opt.quota && opt.downloaded > opt.quota)
	logprintf (LOG_NOTQUIET,
		   _("Download quota (%s bytes) EXCEEDED!\n"),
		   legible (opt.quota));
    }
  if (opt.convert_links)
    {
      convert_all_links ();
    }
  log_close ();
  cleanup ();
  if (status == RETROK)
    return 0;
  else
    return 1;
}

/* Hangup signal handler.  When wget receives SIGHUP or SIGUSR1, it
   will proceed operation as usual, trying to write into a log file.
   If that is impossible, the output will be turned off.  */

#ifdef HAVE_SIGNAL
static RETSIGTYPE
redirect_output_signal (int sig)
{
  char tmp[100];
  signal (sig, redirect_output_signal);
  /* Please note that the double `%' in `%%s' is intentional, because
     redirect_output passes tmp through printf.  */
  sprintf (tmp, _("%s received, redirecting output to `%%s'.\n"),
	   (sig == SIGHUP ? "SIGHUP" :
	    (sig == SIGUSR1 ? "SIGUSR1" :
	     "WTF?!")));
  redirect_output (tmp);
}
#endif /* HAVE_SIGNAL */

Um Symbol em português símbolo, são objetos que representam os nomes e algumas Strings dentro do interpretador Ruby. Eles são gerados usando o caractere : (dois pontos). Lembrando que Ruby é uma linguagem puramente orientada a objeto, os símbolos são objetos instanciados da classe Symbol, entretanto o uso mais comum para um símbolo é dentro dos objetos da classe Hash.

Um Hash é uma coleção como dicionário de chaves únicas e seus valores. Também chamados de Arrays associativos, eles são semelhantes aos Arrays comuns, mas onde uma matriz usa inteiros como seu índice, um Hash permite a utilização de qualquer tipo de objeto.

Ruby - Symbol e Hash

Ruby – Symbol e Hash

Exemplo:

Neste exemplo utilizamos símbolos e imprimimos seus IDs de objetos e os utilizamos dentro de tipos hash no qual podemos os referenciar como dicionário contendo chaves e valores.

Ruby

# Desenvolvimento Aberto
# Simbolos-hash.rb

# Lembre-se que Ruby é uma linguagem
# Puramente orientada a objeto
puts "IDs dos objetos Simbolos:"
puts :beatles.object_id 
puts :rollinsStones.object_id

# Para atribuir num valor ao simbolo
# usa-se um hash 
puts "\nConteudo de um hash:"
bandas = {:beatles => "Come together", :rollinsStones => "Satisfaction" }
puts bandas 

# Você pode utilizar um hash referenciando seus sibolos
puts "\nMinhas musicas:"
puts bandas[:beatles]
puts bandas[:rollinsStones]

 

 

A linguagem de programação Ruby possui uma instrução “mágica” que suspende as regras da Orientação a Objeto, ligando blocos de procedimento a um método ou uma função, esta incomum instrução chamada Yield, permite que métodos sejam chamados como um argumento implícito e permitindo que os blocos tenham seus próprios argumentos, ou seja Yield passa para o método o conteúdo de um bloco quando interligados através de suas sintaxes, podendo ainda trocar parâmetros entre si.

Ruby - Yield

Ruby – Yield

Exemplo:

Neste exemplo criamos duas funções e dois blocos no qual interagem entre si através da instrução Yield.

Ruby

# Desenvolvimento Aberto
# Block-yield.rb

# cria uma função padrão
def funcao
  # Esta instrução fornce uma conexão com um bloco
  puts "Yield conecta um bloco a uma function"
  puts "podendo substituir o conteudo do metodo"
  puts "O bloco executa:"
  yield
end

# função com parametros
def parametros
  yield "Desenvolvimento Aberto"
end

# O bloco será executado no lugar do yield
funcao {
  puts "Desenvolvimento"
  puts "Aberto"
}

# passa um parametro
parametros { |x| puts "imprime o valor do campo yield: #{x}"}

HTML5 ou Hypertext Markup Language, versão 5 é uma linguagem para estruturação e apresentação de conteúdo para a World Wide Web e é uma tecnologia chave da Internet, está na quinta versão da linguagem HTML. Esta nova versão traz consigo importantes mudanças quanto ao papel do HTML no mundo da Web, através de novas funcionalidades como semântica e acessibilidade.

Claro, houve mudanças na linguagem HTML em si. Algumas Tags foram adicionadas em comparação ao padrão HTML 4, e um número considerável também foram excluídas. Provavelmente o maior ajuste para aqueles que usaram ​​o HTML4 não é realmente o HTML em si, mas a relação entre a mudança de HTML e CSS. Em HTML5 (como em HTML), a linguagem de marcação descreve o que significam os vários elementos. CSS é usado para descrever como as coisas se parecem.

CSS3 é a mais nova versão das famosas Cascading Style Sheets ou simplesmente CSS, onde se define estilos para páginas web com efeitos de transição, imagem, e outros, que dão um estilo novo às páginas Web 2.0 em todos os aspectos de design do layout. A principal função do CSS3 é abolir as imagens de plano de fundo, bordas arredondadas, apresentar transições e efeitos para criar animações de vários tipos, como um simples relógio de ponteiros.

Google Cloud - HTML5 e CSS3

Google Cloud – HTML5 e CSS3

Computação nas Nuvens

Agora que você já sabe como funciona a tecnologia Cloud do Google App Engine e como o funciona o ambiente de SandBox no qual nossa aplicação Python roda, vamos nos aprofundar um pouco mais nas linguagens de scripts para a Web, pois não há como existir computação nas nuvens sem a boa e velha linguagem de scripts chamada HTML. Em sua versão mais recente o HTML5 possui como uma melhor amiga, a linguagem de scripts que também ganhou uma cara nova e é chamada de CSS3.

Entretanto na arquitetura Cloud as coisas são um pouco diferentes do que são em um servidor web padrão, como por exemplo, os diretórios da web, em um servidor web você possui um diretório pré-estabelecido no qual pode utilizar, criando subdiretórios para scripts, imagens entre outros arquivos e apenas os referenciar utilizando scripts do qual você já esta acostumado.

Na tecnologia Cloud do Google quem comanda toda a aplicação é um arquivo YAML, então os scripts que, por exemplo chamam uma imagem em uma pagina HTML, só podem encontrar a imagem se ela ou o diretório onde a imagem se encontra estiver declarado nos handlers do arquivo que manipula a aplicação, como podemos ver nos códigos abaixo.

Diretórios Google Cloud App

  1. A imagem open-source.jpg que você vê na pagina esta localizada dentro de uma pasta chamada static na raiz da aplicação, você pode perceber que a tag “img src” é utilizada sem o caractere “/” fazendo referencia a um diretório, quem controla onde as imagens serão encontradas é a instrução handlers do arquivo yaml.
  2.  O ícone favicon.ico (16×16) utilizado pelo navegador se encontra na raiz da aplicação junto com o arquivo main.py, mais uma vez quem controla este ícone é a instrução handlers do arquivo yaml.

 

Multi Plataforma

Considerando que nossa aplicação roda em um navegador web, você pode utiliza-la de um sistema operacional de sua preferencia.

Você pode ver esta aplicação direto das nuvens: http://devabertolinux.appspot.com/

Para configurar sua primeira aplicação Google Cloud Linux: Hello World Google Cloud App Engine

Para Windows e Mac utilize o Google Cloud App Engine Launcher: Instalação e Hello World

Exemplo:

Neste exemplo criamos uma aplicação padrão no Google Cloud Engine, e utilizamos para programação a linguagem Python e através delas criamos uma variável no qual atribuímos um script contendo HTML5 e CSS3 para criar nossa pagina.

Yaml

application: devabertolinux
version: 1
runtime: python27
api_version: 1
threadsafe: yes

handlers:
- url: /favicon\.ico
  static_files: favicon.ico
  upload: favicon\.ico

- url: /(.*\.(gif|png|jpg))$
  static_files: static/\1
  upload: static/.*\.(gif|png|jpg)$

- url: .*
  script: main.app

libraries:
- name: webapp2
  version: "2.5.2"

Python

#!/usr/bin/env python
#
#########################################
# Desevolvimento Aberto
#########################################
# E-mail: desenvolvimento.aberto@live.com
#
# Cloud Computing
# Python - HTML5 - CSS3 - Javascript
# main.py

import webapp2

devhtml = """
<!DOCTYPE HTML>
<html>
  <head>
     <title>Cloud - Desenvolvimento Aberto - Google APP Engine</title>
        <style type = "text/css">
           body { background-color: white; }
           h1   { color: #191970; }
           h3   { color: #53868B; }
           p    { color: #27408B; }
        </style>
  </head>
<body>
 <h1>Desenvolvimento Aberto</h1>
   <h3>Cloud Computing - HTML5 - CSS3 - Javascript</h3>
   <p>
     <img src = "open-source.jpg" alt = "Open Source" />
   </p>
   <h2>C&oacute;digo Aberto de melhor qualidade</h2>
     <p>Desenvolvimento Aberto &eacute; formado para educar sobre e defender</br>
        os benef&iacute;cios do c&oacute;digo aberto e de construir pontes entre os</br>
        diferentes c&iacute;rculos eleitorais na comunidade de c&oacute;digo aberto.</p>
</body>
</html>
"""

class MainHandler(webapp2.RequestHandler):
    def get(self):
        self.response.write(devhtml)

app = webapp2.WSGIApplication([
    ('/', MainHandler)
], debug=True)

 

O Google App Engine permite que você construa aplicações web nos mesmos sistemas escaláveis ​​que as aplicações criadas pelo Google.  Os aplicativos App Engine são fáceis de construir, fácil de manter e fácil de escalar. Com o Google App Engine, não há servidores para manter. Se você acabou de fazer upload de seu aplicativo, ele está pronto para servir a seus usuários.

Ao contrario do Windows e Mac o Linux não possui o Google App Engine Launcher, deste modo todo o manuseio, incluindo compilação, servidor, e  deploy deve ser feito pelo terminal do Linux, por outro lado o Linux já contempla por default todas as ferramentas no qual usaremos, como a instalação do Python 2.7.x e o editor GEdit para a programação Python, então só nos resta baixar o Google App Engine SDK que pode ser baixado clicando aqui.

Computação nas Nuvens

O conceito de computação em nuvem em inglês, Cloud Computing, refere-se à utilização da memória e da capacidade de armazenamento e cálculo de computadores e servidores compartilhados e interligados por meio da Internet, seguindo o princípio da computação em grade.

O armazenamento de dados é feito em serviços que poderão ser acessados de qualquer lugar do mundo, a qualquer hora, não havendo necessidade de instalação de programas ou de armazenar dados. O acesso a programas, serviços e arquivos é remoto, através da Internet – daí a alusão à nuvem. O uso desse modelo (ambiente) é mais viável do que o uso de unidades físicas.

SandBox

O SandBox, em português, caixa de areia (onde as crianças brincam e o gato faz caca, nem precisa explicar, não é?), é um ambiente de desenvolvimento utilizado para desenvolvimentos primários, existem vários tipos de ambiente SandBox e geralmente estão associados a uma metodologia de desenvolvimento. Por exemplo, desenvolvimento de grandes aplicações, uma equipe de desenvolvedores podem utilizar o ambiente de SandBox para criar e testar aplicações sem risco de interferir com a configuração do ambiente de desenvolvimento oficial, após a aplicação ser testada ela passa para um ambiente DEV oficial e o ambiente de SandBox é descartado, sendo constantemente atualizado com uma copia do ambiente de desenvolvimento da empresa. Em desenvolvimento para a web, as empresas que permitem programação em seus ambientes, disponibilizam um ambiente de SandBox para que o usuário aprenda a criar aplicações utilizando virtualizações dos seus ambientes de desenvolvimento, porem sem interferir nos mesmos.

Para permitir que o Google App Engine distribua os pedidos para aplicações em vários servidores web, e para evitar uma aplicação de interferir com a outra, o aplicativo é executado em um ambiente de sandboxrestrito.

Google SandBox Python: https://developers.google.com/appengine/docs/python/#Python_The_sandbox

O que você deve saber sobre o Google Cloud

  • O nome da aplicação é chamado de AppID e deve ser único para não haver colisão de nome na web.
  • As boas praticas recomendam criar nomes de aplicação e diretórios utilizando caracteres minúsculos.
  • O servidor web local do Google App Engine é baseado na tecnologia Apache.
  • As portas locais não devem colidir com outras portas em uso por algum servidor web em seu computador.
  • O Linux não possui a ferramenta Google App Engine Launcher e toda sua manipulação deve ser feita pelo terminal.

 

Programando nas nuvens com o Google App Engine

1 – Para desencargo de consciência,  precisamos testar se já possuímos a versão do Python 2.7.x já instalada, use o comando:


/usr/bin/env python -V

Versão Python

Versão Python

2 – Descompacte o arquivo baixado na sua pasta Home do sistema operacional, que em português chama-se Pasta Pessoal, crie uma nova pasta para nossa aplicação, chame de GoogleApp, deste modo você terá duas pastas adicionais em seu diretório home do Linux, a pasta do SDK chamada google_appengine e GoogleApp na qual iremos criar nossos arquivos fonte.

Descompactar arquivo Zip

Descompactar arquivo Zip

3 – Uma App Cloud do Google é composta de basicamente de dois arquivos, um de extensão yaml que contem os parâmetros de sua aplicação, incluindo o seu AppID e de um arquivo .py que contem o programa de código Python. Use o GEdit do Linux e crie os arquivos app.yaml e main.py e utilize o código abaixo para escrever cada arquivo:

Código Fonte

Código Fonte

4 – Com os arquivos criados no diretório GoogleApp no qual criamos anteriormente, precisamos iniciar o servidor local, utilize a linha abaixo para iniciar o servidor:


~/google_appengine/dev_appserver.py ~/GoogleApp/

Inicia Servidor - App Engine

Inicia Servidor – App Engine

5 – Com o servidor iniciado, abra o seu navegador web e digite o seguinte endereço: http://localhost:8080/

Localhost - porta: 8080

Localhost – porta: 8080

6 – Abra uma outra aba no navegador e digite o endereço do Google App Engine para que possamos criar nosso projeto nos servidores Cloud do Google, já presumimos que você tenha uma conta do Google: https://appengine.google.com/

Google Cloud - Aplicação

Google Cloud – Aplicação

7 – Coloque o nome de sua App de acordo com o conceito de AppID do Google Cloud, este nome deve ser o mesmo contido no seu arquivo app.yaml e deve ser único, preencha uma descrição e clique em criar aplicação:

Cloud - AppID

Cloud – AppID

8 – Vamos efetuar um Deploy para os servidores do Google, isto significa que vamos compilar o programa Python e efetuar um Upload para as nuvens, utilize o seguinte comando para efetuar este procedimento, e-mail e senha serão requeridos:


~/google_appengine/appcfg.py update ~/GoogleApp/

Deploy - nuvens

Deploy – nuvens

9 – Agora é só testar o endereço de sua aplicação nos servidores Cloud do Google, o endereço é composto de sua AppID + .appspot.com:

App Google Cloud

App Google Cloud

Exemplo:

Neste exemplo criamos uma aplicação nas nuvens utilizando a tecnologia Cloud do Google e a linguagem de programação Python:

Utilize este link para ver a aplicação nas nuvens: http://damyapplinux.appspot.com/

Yaml

application: damyapplinux
version: 1
runtime: python27
api_version: 1
threadsafe: yes

handlers:
- url: /favicon\.ico
  static_files: favicon.ico
  upload: favicon\.ico

- url: .*
  script: main.app

libraries:
- name: webapp2
  version: "2.5.2"

Python

#!/usr/bin/env python
#
# Copyright 2007 Google Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
import webapp2

class MainHandler(webapp2.RequestHandler):
    def get(self):
        self.response.write('<h1>Desenvolvimento Aberto</h1>' + \
                            '</br>Hello world!</br>' + \
                            '<strong>' + \
                            '<font size="3" color="#8A2BE2">Google App Engine!</font>' + \
                            '</strong>')

app = webapp2.WSGIApplication([
    ('/', MainHandler)
], debug=True)

 

O conceito de computação em nuvem em inglês, Cloud Computing, refere-se à utilização da memória e da capacidade de armazenamento e cálculo de computadores e servidores compartilhados e interligados por meio da Internet, seguindo o princípio da computação em grade.

O armazenamento de dados é feito em serviços que poderão ser acessados de qualquer lugar do mundo, a qualquer hora, não havendo necessidade de instalação de programas ou de armazenar dados. O acesso a programas, serviços e arquivos é remoto, através da Internet – daí a alusão à nuvem. O uso desse modelo (ambiente) é mais viável do que o uso de unidades físicas.

SandBox

O SandBox, em português, caixa de areia (onde as crianças brincam e o gato faz caca, nem precisa explicar, não é?), é um ambiente de desenvolvimento utilizado para desenvolvimentos primários, existem vários tipos de ambiente SandBox e geralmente estão associados a uma metodologia de desenvolvimento. Por exemplo, desenvolvimento de grandes aplicações, uma equipe de desenvolvedores podem utilizar o ambiente de SandBox para criar e testar aplicações sem risco de interferir com a configuração do ambiente de desenvolvimento oficial, após a aplicação ser testada ela passa para um ambiente DEV oficial e o ambiente de SandBox é descartado, sendo constantemente atualizado com uma copia do ambiente de desenvolvimento da empresa. Em desenvolvimento para a web, as empresas que permitem programação em seus ambientes, disponibilizam um ambiente de SandBox para que o usuário aprenda a criar aplicações utilizando virtualizações dos seus ambientes de desenvolvimento, porem sem interferir nos mesmos.

Para permitir que o Google App Engine distribua os pedidos para aplicações em vários servidores web, e para evitar uma aplicação de interferir com a outra, o aplicativo é executado em um ambiente de sandboxrestrito.

Google SandBox Python: https://developers.google.com/appengine/docs/python/#Python_The_sandbox

Editor de Código – Python

Você pode utilizar qualquer editor de texto ou IDE para criar suas aplicações Python, recomendamos que para Windows você utilize o editor open source chamado Notepad++ que pode ser baixado clicando aqui.

 

O que você deve saber sobre o Google Cloud

  • O nome da aplicação é chamado de AppID e deve ser único para não haver colisão de nome na web.
  • As boas praticas recomendam criar nomes de aplicação e diretórios utilizando caracteres minúsculos.
  • O servidor web local do Google App Engine é baseado na tecnologia Apache.
  • As portas locais não devem colidir com outras portas em uso por algum servidor web em seu computador.

 

Cloud Google – Criando uma aplicação: Hello World App

Agora que você já sabe os princípios do conceito de programação nas nuvens, vamos criar nosso primeiro programa Cloud, presumimos que você já tenha instalado em seu computador o Google App Engine e a versão do Python 2.7.x.

1- Abra o Google App Engine Launcher, no menu File clique em Create New Application, escolha o nome da aplicação e um diretório para os arquivos de código fonte que serão gerados automaticamente:

AppID

AppID

2 – Dê um duplo clique na sua aplicação, e uma janela o questionara da porta local para o servidor web do App Engine, as portas não devem colidir, escolha uma porta e clique em Update:

Update - Porta

Update – Porta

3 – Com sua aplicação selecionada clique no botão Run e espere até que o ícone da aplicação fique verde:

Run - Ok - verde

Run – Ok – verde

4 – Agora seu servidor web local esta rodando e sua aplicação pode ser testada. Os códigos fontes foram gerados no diretório local que você escolheu quando criou sua aplicação, entre no diretório e abra o arquivo chamado main.py no editor Notepad++:

Notepad++ - Python

Notepad++ – Python

5 – O Google App Engine cria aplicações no modelo MVC, utilize o código abaixo para modificar o código gerado automaticamente, salve e clique no botão Browser, sua aplicação será aberta localmente no seu navegador web:

App - Local

App – Local

6 – Tudo Ok localmente, agora vamos utilizar os servidores Cloud do Google para hospedar nossa aplicação. Você precisa de uma conta do Google, crie caso ainda não tenha, clique no botão Dashbord para criar sua aplicação nos servidores do Google, preencha seu AppID (nome da Aplicação), concorde com os termos de serviço e clique no botão criar:

Dashbord - Google

Dashbord – Google

 

7 – Após criar sua App no ambiente Cloud do Google, clique no botão Deploy para efetuar o Upload do seu programa para as nuvens, forneça o seu e-mail e sua senha para autenticação:

Deploy - Google Cloud

Deploy – Google Cloud

8 – Pronto! Sua App já esta nas nuvens. você pode testar chamando o endereço de sua aplicação no navegador, o endereço é formado pelo AppId mais o caminho do SandBox do Google:

App - Nas Nuvens

App – Nas Nuvens

Exemplo:

Neste programa criamos uma aplicação nas nuvens utilizando a linguagem de programação Python e a tecnologia Cloud dos servidores do Google.

Se você tem uma conta no Google você pode ver esta aplicação clicando aqui:  http://daengineapp01.appspot.com/

Python

main.py

#!/usr/bin/env python
#
# Copyright 2007 Google Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
import webapp2

class MainHandler(webapp2.RequestHandler):
    def get(self):
        self.response.write('<h1>Desenvolvimento Aberto</h1>' + \
		                    '</br>Hello world!</br>' + \
							'<p><strong>' + \
							'<font size="3" color="#8A2BE2">Google App Engine!</font>' + \
							'</p></strong>')

app = webapp2.WSGIApplication([
    ('/', MainHandler)
], debug=True)

O Google App Engine permite que você construa aplicações web nos mesmos sistemas escaláveis ​​que as aplicações criadas pelo Google.  Os aplicativos App Engine são fáceis de construir, fácil de manter e fácil de escalar. Com o Google App Engine, não há servidores para manter. Se você acabou de fazer upload de seu aplicativo, ele está pronto para servir a seus usuários.

Porque Python ?

Você pode estar se perguntando: Google App Engine também suporta Java e Go, Porque não esses idiomas?”. Para a experiência de aprendizagem mais rápida, Python é a melhor escolha para os novos programadores (é usado para ensinar as crianças como codificar), e também popular com veteranos. Aqui está uma boa explicação para desenvolvedores experientes comparando Python com uma linguagem estaticamente tipada, como C# ou Java ou C++. Ou seja o Google utiliza Python em muitas de suas aplicações e esta apostando nesta linguagem e em futuros desenvolvedores das categorias de base.

Python 2.7.8: https://www.python.org/download

Google App Engine for Python: https://developers.google.com/appengine/downloads#Google_App_Engine_SDK_for_Python

Instalando o Google App Engine

1- Após baixar o arquivo com a extensão MSI, você pode o executar como administrador do sistema, caso você não tenha o Python instalado em seu computador o próprio instalador o ajudara a efetuar a instalação:

Download Python

Download Python

2 – Aceite o termo de licença e clique em next:

Licença

Licença

3 – Escolha o local de instalação e as opções de atalhos do aplicativo, caso mude a instalação você precisa configurar o caminho mais tarde na aba preferencias:

Local da instalação

Local da instalação

4 – Após as opções configuradas clique em instalar:

Instalar

Instalar

5 – Aguarde o progresso da instalação:

Progresso

Progresso

6 – Clique em Finish para concluir a instalação:

Concluir

Concluir

7 – Após a instalação abra o Google App Engine, um aviso será mostrado em um janela dizendo que o sistema não sabe onde encontrar a instalação do Python, você precisa configurar o caminho do executável do Python. No menu Edit, Preferences, inclua os dados na opção Python Path:

Instalação do Python

Instalação do Python

Pronto! agora você precisa fechar e abrir novamente o Google App Engine e já estará apto a criar seu primeiro programa com a tecnologia Cloud.

Como criar minha primeira Aplicação Google nas nuvens?

Para criar sua primeira aplicação nas nuvens utilizando Python e a tecnologia Googleclique aqui.