Angel "Java" Lopez

NET, Java, PHP y Desarrollo de Software

This Blog

Syndication

Search

Tags

Community

Email Notifications

Archives

.NET

ASP.NET

Windows Form

VB.NET

C#

Sitios

Blogs

December 2012 - Posts

CobolScript (3) Plantillas

Anterior Post 
Siguiente Post 

Me gusta tener un motor de plantillas en los lenguajes que implemento, así que agregué uno a mi proyecto de código abierto CobolScript, un compilador COBOL a JavaScript. El primer ejemplo:

https://github.com/ajlopez/CobolScript/tree/master/samples/template

El código:

<#
data division.
working-storage section.
01 n.

procedure division.
#>
Factorial
---------

<#
perform show-factorial varying n from 1 to 10.

show-factorial.
local result.
perform factorial using n giving result.
#>
${n}!= ${result}
<#
.
factorial using n.
local m.
if n = 1 then return n.
subtract 1 from n giving m.
perform factorial using m giving m.
multiply n by m.
return m.
#>

El archivo plantilla es compilado a COBOL transformando cada texto en un comando DISPLAY … WITH NO ADVANCING (los saltos de línea ya están en el texto). El código entre <# y #> se copia tal cual en el programa COBOL. Cada expresión entre ${ y } se expande como otro parámetro al comando DISPLAY. Entonces, luego de compilar todo el texto a COBOL, CobolScript compila el resultado a JavaScript. La sintaxis de la plantillas es, entonces, una especie de “syntax sugar”.

La salida del programa anterior:

Factorial
---------

1!= 1
2!= 2
3!= 6
4!= 24
5!= 120
6!= 720
7!= 5040
8!= 40320
9!= 362880
10!= 3628800

Podría usar las plantillas para generar archivos de texto, y entonces, implementar generación de código en CobolScript, así como lo hice en AjGenesis (tanto en la variante clásica en .NET, como en Ruby o JavaScript/NodeJs). Antes de eso, ya tengo una implementación de páginas dinámicas basadas en este motor de plantillas (sí, páginas dinámicas en CobolScript, cosas vederes Sancho ;-). Pero es tema para otro post.

Nos leemos!

Angel “Java” Lopez
http://www.ajlopez.com
http://twitter.com/ajlopez

Posted Sun, Dec 30 2012 16:22 by lopez | 1 comment(s)

AjTalk en C# (3) Environments

Anterior Post

Hace unas semanas, agregué el soporte de environments (ambiente, entorno) a mi proyecto de código abierto AjTalk, una máquina virtual Smalltalk escrita en C# (hay otras versiones, en Java y en JavaScript). ¿Qué es un environment en mi jerga? Es un diccionario, donde puedo guardar artefactos por nombre, un directorio. Por ejemplo, para guardar clases por nombre. La variable global Smalltalk es un environment clásico. Pero en un Smalltalk clásico, todas las clases definidas van a parar a ese diccionario global, lo que puede dar lugar a colisión de nombres. La forma normal de solucionar (p.ej. en Squeak y Pharo) es agregarle un prefijo (de dos letras) a cada clase de nuestra librería. Pero yo quiero tener el soporte de tener otros environments, como pasa con los namespaces de .NET o los package de Java. Smalltalk clásico también tiene los llamados pool dictionary, pero hasta donde sé, son para usar desde una clase y sus derivados. Yo quiero tener la noción de paquete: todas estas clases se ven entre sí, pero no están en el environment del tope, en Smalltalk, sino en un environment dedicado a mi librería. Agregué una implementación inicial, con estos tests:

https://github.com/ajlopez/AjTalk/blob/master/Src/AjTalk.Tests/AssertTests/EnvironmentTests.st

Al comienzo, verifico que Smalltalk es un ambiente, un environment y es el actual:

"Current environment is Smalltalk"
[Environment current == Smalltalk] assert.

Puedo crear nuevos entornos:

env := Environment new: #MyEnvironment.

Automáticamente, el nuevo entorno se registra/agrega al entorno actual, en este caso, a Smalltalk:

"The new environment was defined as global at Smalltalk"

[(Smalltalk at: #MyEnvironment) isNil not] assert.
[(Smalltalk at: #MyEnvironment) == MyEnvironment] assert.
[(Smalltalk at: #MyEnvironment) == env] assert.

[MyEnvironment isNil not] assert.
[MyEnvironment == env] assert.

Cada nuevo entorno tiene automáticamente una entrada Smalltalk que apunta al original global:

"Dotted expression syntax sugar for MyEnvironment at: #Smalltalk"

[MyEnvironment.Smalltalk == Smalltalk] assert.

Podemos pasar a tener un nuevo entorno actual:

env setCurrent.

"Current environment check"

[Environment current == env] assert.
[Environment current == Smalltalk.MyEnvironment] assert.

Y ahora, la característica principal de lo que quería implementar, de ahora en más, las definiciones de clases (sin cambiar el código de su definición) quedan registradas en el entorno actual:

"Define a class at current env environment, no change to syntax"

Object subclass:#MyClass
    instanceVariableNames:''
    classVariableNames:''
    poolDictionaries:''
    category:''
.

[(env at: #MyClass) isNil not] assert.
[(Smalltalk at: #MyClass) isNil] assert.

Ortogonal a esto de environments, implementé además módulos (algo apareció en el post anterior): una forma de buscar y leer archivos file out, y ejecutarlos dentro de un nuevo entorno. Esto es similar al import de Python, y algo menos parecido, al require de Node.js/CommonJS. Bueno, pero eso es tema para otro post ;-)

Nos leemos!

Angel “Java” Lopez
http://www.ajlopez.com
http://twitter.com/ajlopez

Posted Thu, Dec 27 2012 17:10 by lopez | with no comments

CobolScript (2) Primera Función, Factorial

Anterior Post 
Siguiente Post 

JavaScript es manteca en mis manos ;-). Estuve trabajando en mi proyecto CobolScript, compiladr de COBOL a JavaScript, que puede ejecutarse en el navegador o en Node.js.

Agregué soporte de funciones definidaspor el usuario, con parámetros, argumentos a pasar, y hasta variables locales. El primer ejemplo fue el clásico factorial recursivo:

https://github.com/ajlopez/CobolScript/blob/master/samples/factorial/factorial.cob

Pueden ejecutarlo en ese directorio, con la línea de comando:

node run factorial.cob

data division.
working-storage section.
01 n.

procedure division.
perform show-factorial varying n from 1 to 10.

show-factorial local result.
perform factorial using n giving result.
display n "! = " result.

factorial using n local m.
if n = 1 then return n.
subtract 1 from n giving m.
perform factorial using m giving m.
multiply n by m.
return m.

Le agregué nueva sintaxis:

- performusing … Para llamar a un procedimiento local pasando argumentos.

- <proc> using …  El procedimiento declara sus argumentos.

- <proc> local(s) … El procedimiento declara sus variables locales (actualización: removido, ahora hay comando local(s)… directamente en el código del procedimiento).

- performgiving <var>…  Puedo especificar que el valor de retorno del procedimiento (internamente, es una función JavaScript) sea guardado en una o varias variables.

- return (expr)  El procedimiento puede retornar en cualquier momento, con un resultado opcional. Me falta implementar el clásico exit de COBOL.

Le agregué soporte de plantillas, páginas web dinámicas, y acceso a objetos JavaScript/Node.js nativos. Pero eso ya es tema para otro post.

Nos leemos!

Angel “Java” Lopez
http://www.ajlopez.com
http://twitter.com/ajlopez

Posted Tue, Dec 25 2012 12:52 by lopez | 1 comment(s)

CobolScript (1) Compilador COBOL a JavaScript/Node.js

Siguiente Post

Ayer, comencé un nuevo proyecto en mi cuenta de GitHub:

https://github.com/ajlopez/CobolScript

Es un compilador que lee COBOL y compila a JavaScript. Es un “work in progress”, pero el clásico “Hello, world” está ya corriendo:

https://github.com/ajlopez/CobolScript/blob/master/samples/hello/hello.cobs

DISPLAY "HELLO, WORLD".

Lo pueden ejecutar escribiendo desde ese directorio en la línea de comando:

node run hello.cobs

Un ejemplo más completo:

https://github.com/ajlopez/CobolScript/blob/master/samples/hellopgm/hello.cob

IDENTIFICATION DIVISION.
    PROGRAM-ID. HELLO.
    AUTHOR. A.J.LOPEZ.
    INSTALLATION. TEST.
    DATE-WRITTEN. 2012-12-22.
    DATE-COMPILED. 2012-12-22.
ENVIRONMENT DIVISION.
    CONFIGURATION SECTION.
        SOURCE-COMPUTER. NODE.
        OBJECT-COMPUTER. NODE.
DATA DIVISION.
PROCEDURE DIVISION.
    DISPLAY "HELLO, WORLD".

Ejecutemos en ese directorio:

node run hello.cob

Actualización: pasé los ejemplos de arriba a minúsculas. Me comentaron que los COBOL modernos aceptan mayúsculas y minúsculas, así que voy a tratar de seguir escribiendo ejemplos pero en minúsculas.

Hoy sigo con este trabajo, implementando variantes de verbos como move, add, subtract, etc.. todo escrito usando TDD (Test-Driven Development). Tengo varias cosas que agregar como soporte de formato en los items (“picture”), la file section, y en algún momento, quiero agregar comandos SQL. También pienso poner páginas dinámicas ejecutadas en un servidor web soportado por Node.js. El código está armado de forma tal que también pueda ejecutarse en el navegador.

Nos leemos!

Angel “Java” Lopez
http://www.ajlopez.com
http://twitter.com/ajlopez

Posted Sun, Dec 23 2012 15:16 by lopez | 1 comment(s)

Computación en el Recuerdo (1) Requisitos de un Lenguaje de Programación

En un mundo con Internet, tablets, lenguajes funcionales y cloud computing, es bueno volver la vista atrás y ver todo en perspectiva. Hoy, en mis lecturas, me encuentro con este fragmento:

…definimos ahora los requisitos de un lenguaje de programación para problemas originados en los campos de la economía y de la administración.

1. Debe ser posible indicar cómodamente en qué unidades periféricas se encuentran los diferentes archivos, y cómo los registros se almacenan físicamente en el medio de almacenamiento, por ejemplo cuántos registros forman un bloque en cinta magnética.

2. Debe ser fácil describir la transferencia de registros entre la memoria central y las unidades periféricas, por ejemplo la lectora de tarjetas perforadas, la impresora de líneas y la memoria auxiliar.

3. Debe ser posible referirse a los datos individuales de un registro. Por lo tanto, debe ser posible describir las propiedades de los datos incluidos en el registro y cómo se agrupan para formar un registro.

4. Debe ser posible presentar los datos de salida, de modo que sea fácil su lectura.

5. Es necesario que se puedan describir operaciones aritm^ticas con números y operaciones lógicas, por ejemplo comparación de números. Además, también debe ser posible trabajar con datos no numéricos, por ejemplo nombres.

Concluye:

El COBOL satisface todos estos requirimientos

Fuente: Sección 2.3 del libro “COBOL” de Torgil Ekman y Kenneth Nilsson, publicado acá en Argentina por la editorial El Ateneo. Lo leía a fines de los setenta, principios de los ochenta. Y encontro guardadas, dentro de algunas páginas, algunos de mis primeros cursogramas ;-)

Estoy por comenzar un code-kata (espero que este fin de semana): un intérprete/compilador a JavaScript (browser y Node.js), de COBOL. Cosas veredes, Sancho!

Nos leemos!

Angel “Java” Lopez
http://www.ajlopez.com
http://twitter.com/ajlopez

Posted Fri, Dec 21 2012 16:26 by lopez | with no comments

Primeras Ideas para un Motor de Reglas de Claims

Estoy bucando aplicaciones para los lenguajes de scripting que fui armando. Quiero usar AjLang, el núcleo de AjSharp, escrito en C#. Un caso de uso podría ser un motor de reglas de claims. Para que se entienda lo que tengo en mente, relativo a la seguridad federada, ver:

The Role of the Claims Engine
The Role of the Claim Rule Language
The Role of Claim Rules
The Role of the Claims Pipeline
The Role of Claims

Dado un conjunto de claims de entrada, el sistema podría producir un conjunto de claims de salida, usando reglas definidas por el usuario. Una regla podría escribirse en un lenguaje como:

rule RuleEmail
   description “….”
when
   claim cmail
   cmail in InputClaims
   cmail.Type == “email” 
   cmail.Value.EndsWith(
“@acme.com”)
then
   claim cname = new Claim(…. )
   // more cname processing, maybe extracting a value from email
   OutputClaims.Add(cname)
end rule

Algo como lo que ya tengo en mi ejemplo https://github.com/ajlopez/AjRools/blob/master/Src/AjRools.Expert/AjRools.Expert.Tests/Files/SimpleRule.txt pero más orientado a la sintaxis de C# (vean que en el ejemplo de arriba uso el nativo .EndsWith para un string).

Si hubiera omitido el “cmail in InputClaims”, el claim sería buscado en todos los conjuntos de claims que se hayan declarado.

Un item adicional: tener una interfaz web para explorar y editar reglas.

Las reglas se ejecutarían en un orden. Podría tener conjuntos de reglas, para agrupar las que tienen que ser ejecutadas en un momento del proceso. Por ejemplo, tener un conjunto de reglas a aplicar cuando llegue un conjunto de claims provisto por tal Identity Provider, como Windows Live, Yahoo, etc. O un conjunto de reglas a aplicar por Relying Party, cada uno siendo una application: el sistem contable, el sistema de recursos humanos, finanzas, etc..

En la parte “then”, las funciones adicionales serían invocadas. Estas funciones podrían ser agregadas por el desarrollador en el ambiente del motor de reglas, posiblemente cargando una DLL provista por él mismo. De esta manera, las acciones disponibles se podrían extender por código. Habría un conjunto de acciones inicial, como crear un nuevo claim. La parte “when” tiene predicados (funciones que dan verdadero o false) que también podrían ser extendidos por código. Predicados y acciones que podrían estar desde el principio: comparar una propiedad con un valor, crear un nuevo claim, cambiar una propiedad de un claim u objeto, agregar un claim a un conjunto existente, como el de InputClaims, OutputClaims o cualquier otro definido por el programador.

Algo para decidir: ¿qué pasa si hay DOS o más claims que satisfacen una cláusula when? ¿debería la regla dispararse una sola vez? ¿o una vez por cada claim disponible? Recuerdo el operador de corten en Prolog, pero me imagino que debe haber algo más simple. Tendré que explorar los casos de uso.

No tengo tiempo asignado para esto.

Nos leemos!

Angel “Java” Lopez
http://www.ajlopez.com
http://twitter.com/ajlopez

Posted Wed, Dec 19 2012 16:17 by lopez | with no comments

AjTalk en C# (2): Un Simple Servidor Web

Anterior Post 
Siguiente Post 

Estoy trabajando completando mi máquina virtual Smalltalk, escrita en C#, el AjTalk, el repositorio en https://github.com/ajlopez/AjTalk . Hace unas semanas, escribí un ejemplo de simple servidor web, basado en mi trabajo previo en PythonSharp (1) Un servidor web mínimo. El código de este nuevo servidor en:

https://github.com/ajlopez/AjTalk/blob/master/Src/AjTalk.Console/Programs/WebServer.st

Object subclass: #WebServer
	instanceVariableNames: 'root listener bytes'
	classVariableNames: ''
	poolDictionaries: ''
	category: ''
!

!WebServer class methods!

new
	^self basicNew initialize
! !

!WebServer methods!

initialize
	bytes := @System.Array !!CreateInstance: @System.Byte with: 1024 * 16.
	listener := @System.Net.HttpListener !!new.
	listener !!Prefixes !!Add: 'http://*:8000/'.
	root := 'c:/apache-tomcat-6.0.18/webapps/docs'.
	@System.Console !!WriteLine: 'initialize'
!

process: context
	| filename input nbytes |
	filename := context !!Request !!Url !!AbsolutePath.
	
	@System.Console !!WriteLine: filename.
	
	(filename = '' or: [filename = '/']) ifTrue: [filename := 'index.html'].
	
	(filename !!StartsWith: '/') ifTrue: [filename := filename !!Substring: 1].
	@System.Console !!WriteLine: filename.
	
	filename := @System.IO.Path !!Combine: root with: filename.

	@System.Console !!WriteLine: filename.	
	
	(@System.IO.File !!Exists: filename) 
	ifFalse: [ context !!Response !!Abort. ]
	ifTrue: [		
		input := @System.IO.FileStream !!new: filename with: @System.IO.FileMode !!Open.
		[[nbytes := input !!Read: bytes with: 0 with: bytes !!Length] value > 0] whileTrue: [
			context !!Response !!OutputStream !!Write: bytes with: 0 with: nbytes.
		].
		
		input !!Close.
		
		context !!Response !!OutputStream !!Close
	]
!

start
	listener !!Start.
	@System.Console !!WriteLine: 'start'.
	[true] whileTrue: [
		| context |
		@System.Console !!WriteLine: 'get context'.
		context := listener !!GetContext.
		@System.Console !!WriteLine: 'new request'.
		self process: context.
	].
	@System.Console !!WriteLine: 'end start'
! !

WebServer new start
!

Como el anterior, es una prueba de concepto, “quick and dirty”, para mostrar que puedo reutilizar las clases de .NET. Pueden lanzarlo desde el programa de consola de AjTalk (el resultado de compilar el proyecto AjTalk.Console):

ajtalk lib\Library.st Programs\WebServer.st

El resultado en http://localhost:8000 (jeje, reusando unas páginas estáticas que tengo en mi disco local):

Luego escribí un ejemplo más claro y modular en

https://github.com/ajlopez/AjTalk/blob/master/Src/AjTalk.Console/Programs/WebSiteTomcat.st

Module import: #Web.

!

| server |

server := Web.Server new
	root: 'c:/apache-tomcat-6.0.18/webapps/docs';
	addPrefix: 'http://*:8000/';
	start
!

Pero ahí estoy usando Module import:, algo que implementé basado en lo que hice de PythonSharp import para cargar programas. Pero esa lógica ya es tema para otro post.

Nos leemos!

Angel “Java” Lopez
http://www.ajlopez.com
http://twitter.com/ajlopez

Posted Mon, Dec 17 2012 16:45 by lopez | 1 comment(s)

AjTalk en C# (1): Una imagen mínima, con Hello, World

Siguiente Post

Si leen este blog (y tienen la paciencia de seguirme en Twitter ;-), ya saben que, luego de PyCon 2012 Argentina, he estado ocupado trabajando en mi máquina virtual Smalltalk AjTalk, escrita en C#:

https://github.com/ajlopez/AjTalk

He aquí un pequeño Hello, World:

nil subclass:#Object
	instanceVariableNames:''
	classVariableNames:''
	poolDictionaries:''
	category:'Kernel-Objects'
!

Object subclass:#Program
	instanceVariableNames:''
	classVariableNames:''
	poolDictionaries:''
	category:'Kernel-Objects'
!

!Program class methods!

main @System.Console writeLine: 'Hello, world'! !

En el repo:

https://github.com/ajlopez/AjTalk/blob/master/Src/AjTalk.Console/Programs/HelloWorld.st

Podría ser menor, pero necesito el Program main como punto de entrada de una imagen grabada en disco. El programa que genera la imagen es

ajtalk Programas/HelloWorld.st –s hello.im

y se lanza la imagen con

ajtalk hello.im

De esta forma, AjTalk busca una variable global Program con un método main, y si existe, es invocado luego de la carga.

La notación del nombre con @ para @System.Console es la forma que tiene AjTalk de referirse a tipos nativos de .NET.

Noten que no cargo toda la librería de clases, solamente las que necesito para ejecutar este Hello, world. AjTalk puede manejar varias máquinas en memoria, cada una de las cuales tiene sus propias clases y métodos. Aún más: le he agregado que una máquina virtual pueda operar sobre otra, y hasta “prestarle” sus métodos. De esta manera, puedo tener una máquina A con todas las clases de desarrollo, y manejar desde ahí el contenido de la máquina B. Puedo entonces producir imágenes mínimas. En vez de tener una sola y gran imagen en memoria, y hacer toda clase de contorsiones para reducirla, mis máquinas YA NACEN livianas por diseño. Esto es un ejemplo de “pensar fuera de la caja”: por décadas, los desarrolladores Smalltalk pensaron siempre en tener una sola imagen, y se metieron en el problema de COMO hacerla decrecer. Mi aproximación al problema es distinta: cada máquina va creciendo desde lo mínimo, y si es necesario usar algo (algún método compile: por ejemplo), lo provee otra máquina, sin que tenga que crecer la primera.

Tengo que escribir más sobre lo que le agregué a esta versión. Por ejemplo: objetos remotos (revisitado), métodos por objeto, procesos, semáforos, múltiples threads, acceso a tipos nativos, grabar/leer imágenes, un AST interno, visitors para recorrer ese árbol, generación de código para JavaScript, módulos (a la import de Python o el require de Node.js), ambientes (como espacios de nombre, para evitar la colisión de nombres), y bastante más (como tener un Process que pueda ser suspendido y reanudado en cualquier momento, quizás llegue a call con continuations).

Nos leemos!

Angel “Java” Lopez
http://www.ajlopez.com
http://twitter.com/ajlopez

Posted Fri, Dec 14 2012 12:50 by lopez | 1 comment(s)

Node.js en Buenos Aires

Hoy voy a dar un curso de todo un día, gracias al Microsoft Users Group de Argentina. El post de hoy está dedicado a compartir el material y enlaces que vamos a usar.

Primero, la presentación está en http://sdrv.ms/Rqy1IV

Usamos los instaladores de http://nodejs.org/ donde tomamos Node.js y en los instaladores actuales, también viene incluido el manejador de paquetes NPM https://npmjs.org/ así que no necesitamos bajarlo aparte, ya viene en Node.

Vamos a bajar varios ejemplos de GitHub. Pueden usar http://git-scm.com/ o bajarse .zips desde el sitio.

Los ejemplos que muestro están en:

https://github.com/ajlopez/NodeSamples

También visitamos:

https://github.com/ajlopez/Cellular un simple autómata celular
https://github.com/ajlopez/SimpleGA algoritmos genéticos, con ejemplo distribuido usando Socket.IO (ver SimpleGA (1) Algoritmos Genéticos en Javascript/Node.js)

Vamos a usar Express: http://expressjs.com/

Espero mostrar Geddy: http://geddyjs.org/

Y al final, veremos Socket.IO: http://socket.io/ 

Como base de datos NoSQL, estoy usando MongoDb: http://www.mongodb.org/

Con Express y MongoDb, vamos a probar el ejemplo de blog (aparte de otros más sencillos): https://github.com/ajlopez/NodeSamples/tree/master/Express/Blog basado en el ejemplo original de http://howtonode.org/express-mongodb

Con Socket.IO, usaremos ejemplos simples de https://github.com/ajlopez/NodeSamples/tree/master/SocketIO

Como ejemplo más completo, con MongoDB, Express, y Socket.IO para analizar el tráfico en tiempo real, uso el ejemplo Nodecellar

https://github.com/ccoenraets/nodecellar

Leer los post de su autor:

http://coenraets.org/blog/2012/10/nodecellar-sample-application-with-backbone-js-twitter-bootstrap-node-js-express-and-mongodb/
http://coenraets.org/blog/2012/10/real-time-web-analytics-with-node-js-and-socket-io/
http://coenraets.org/blog/2012/10/creating-a-rest-api-using-node-js-express-and-mongodb/

Si no pudieron asistir a este curso, algunos detalles adicionales de ejecución de estos ejemplos en mi post Node.Js, Express y Socket.IO en UdADev 2012, Cuenca, Ecuador.

Enlaces que he ido coleccionando y me parecieron interesantes:

http://delicious.com/ajlopez/nodejs
http://delicious.com/ajlopez/nodejs+tutorial
http://delicious.com/ajlopez/express
http://delicious.com/ajlopez/express+tutorial
http://delicious.com/ajlopez/socketio
http://delicious.com/ajlopez/socketio+tutorial

Nos leemos!

Angel “Java” Lopez
http://www.ajlopez.com
http://twitter.com/ajlopez

Posted Thu, Dec 13 2012 8:06 by lopez | 1 comment(s)

PythonSharp (1) Un servidor web mínimo

El mes pasado (Noviembre 2012) presenté mi trabajo con PythonSharp en PyCon 2012 Argentina (ver post), un intérprete Python 3.x que estoy escribiendo en C#. Como en otras de mis implementaciones, éste puede acceder a tipos nativos, para poder aprovechar lo que brinda una librería de clases ya implementada. Como prueba de concepto, escribí un ejemplo de servidor web mínimo:

from System import Array, Byte
from System.Net import HttpListener
from System.IO import Path, FileStream, FileMode, File

root = "c:/apache-tomcat-6.0.18/webapps/docs"

bytes = Array.CreateInstance(Byte,1024)

listener = HttpListener()
listener.Prefixes.Add("http://*:8000/")

def process(context):
    filename = context.Request.Url.AbsolutePath
    if not filename or filename == '/':
        filename = "index.html"
    if filename[0] == '/':
        filename = filename[1:]
    print(filename)
    filename = Path.Combine(root, filename)
    print(filename)
    if not File.Exists(filename):
        context.Response.Abort()
        return
    input = FileStream(filename, FileMode.Open)
    bytes = Array.CreateInstance(Byte, 1024 * 16)
    nbytes = input.Read(bytes, 0, bytes.Length)
    while nbytes>0:
        context.Response.OutputStream.Write(bytes, 0, nbytes)
        nbytes = input.Read(bytes, 0, bytes.Length)
    input.Close()
    context.Response.OutputStream.Close()

listener.Start()

while True:
    context = listener.GetContext()
    print("new request")
    process(context)
        

Vean el archivo en el repo:

https://github.com/ajlopez/PythonSharp/blob/master/Src/PythonSharp.Console/examples/httpserver.py

Para ejecutar el ejemplo, hay que compilar la solución, y el proyecto PythonSharp.Console produce entonces un programa de consola pysh.exe. Pueden cambiar el valor de la variable root, que apunta en el ejemplo de arriba a mi disco local, donde tengo unos archivos estáticos con la documentación de un servidor Tomcat ;-) . Ejecutando pysh Programs\httpserver.py, se levanta el servidor, al que pueden como http://localhost:8080

 

El código de este servidor mínimo se basa en mis anteriores ejemplos:

A Minimal Http Server In C#

A Minimal Http Server in Java

Como ven en el código, puedo importar namespaces .NET y manejarlos como si fueran módulos de Python. Estoy trabajando con .NET 3.5 (me gusta mantener al mínimo los requerimientos) así que no pude aprovechar otros métodos para copiar un archivo a la corriente de salida de la respuesta web, vean:

Best way to copy between two Stream instances

Ahora, pasé a trabajar en tener la misma implementación para mi AjTalk, una Smalltalk Virtual Machine en C#. Ya lo tengo andando, pero eso es tema para otro post.

Nos leemos!

Angel “Java” Lopez
http://www.ajlopez.com
http://twitter.com/ajlopez

Posted Sat, Dec 8 2012 14:38 by lopez | 2 comment(s)

Resoluciones del Nuevo Mes: Diciembre 2012

Parece mentira, llegó el último mes de este año. Bueno, es tiempo de escribir las resoluciones de Diciembre, primero un repaso de las de Noviembre:

- Trabajar en PythonSharp [completo] ver repo
- Dar una charla Implementando Python en PyCon 2012 (Argentina) [completo] ver post
- Trabajar en AjTalk para Java [pending]
- Trabajar en AjTalk para Javascript [pending]
- Trabajar en BasicScript (lo quiero usar como ejemplo en mi proyecto Game Server) [partial] solamente demos y diseño
- Comenzar a pasar a Markdown mi tutorial de Java en español [partial] solo organizar el material
- Comenzar a escribir en Markdown lo que muestro en mi curso de Node.js [pending]

En vez de trabajar en el AjTalk de Java o de JavaScript, estuve trabajando bastante en la versión C#

- Trabajar en AjTalk para C# [completo] see repo

Voy a dar un curso de Node.js, y algún podcast, mis nuevas resoluciones:

- Trabajar en PythonSharp
- Trabajar en AjTalk para C#
- Dar un curso de todo un día de Node.js
- Participar de un podcast sobre Generación de Código
- Comenzar a pasar a Markdown mi tutorial de Java

Agrego:

- Nuevo proyecto en PHP, propiedades inmobiliarias

Espero escribir posts sobre lo nuevo que agregué en AjTalk de C#, ejemplos, etc. Ahora puede leer y grabar imágenes, tiene un ejemplo de web server mínimo, estoy agregando soporte de Traits, tiene un simple assert para hacer TDD simple, environments e import de paquetes, y tutti li fiocci ;-)

Nos leemos!

Angel “Java” Lopez
http://www.ajlopez.com
http://twitter.com/ajlopez

Posted Tue, Dec 4 2012 17:45 by lopez | 1 comment(s)