Skip to content

Instantly share code, notes, and snippets.

@posixpascal
Created July 25, 2010 19:51
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save posixpascal/489834 to your computer and use it in GitHub Desktop.
Save posixpascal/489834 to your computer and use it in GitHub Desktop.
#!/usr/bin/python
# -*- coding: latin1 -*-
# A batch Interpreter for Linux
import os
import time
import sys
import getpass
import urllib
import shutil
import math # For square root and pi
import ConfigParser # for reliable configs (ini-parsing eventually) :P (don't know much about ahm.. batch :P)
# libraries to rebuild PAUSE()
import termios
import fcntl
# libraries to rebuild ipconfig
import socket
import struct
import urllib2 # global ip thing :)
import array # for the listdevices() thing
# powerful libraries for my own batch-like-language.
import Image
import ImageDraw
from random import randint as rint
version = "0.1"
class Batch():
def __init__(self):
# writeDataToRam or sth else here
global pointer
global fileobj
global environment
# special vars ++ Windows global Var ;)
self.loudly = "on"
self.more_output = 0
self.sexyCode = 0
self.cLineNumber = "Display :0.0"
self.vars = (
{"%windir%":"sys/Windows/",
"%TEMP%":"sys/Windows/Temp",
"%USER%":str(getpass.getuser()),
"%ALLUSERPROFILE%":"sys/Users/public",
"%APPDATA%":"sys/Users/"+str(getpass.getuser())+"/.App_Data",
"%CLIENTNAME%":"Python Batch Interpreter",
"%COLORTERM%":"gnome-terminal", # ksh, sh, comexshell and wtf. change it if you doesn't have gnome-term.
"%CommonProgramFiles%":"sys/Programs/CommonProgramFiles/",
"%ComSpec%":"sys/Windows/syscmd.py",
"%DISPLAY%":":0.0",
"%HOMEDRIVE%":"sys/",
"%PATH%":os.getcwd(),
"%HOMEPATH%":"sys/Users/"+str(getpass.getuser())+"/",
"%LANG%":"de_DE.latin1", # dont blame me latin ;)
# the %0 var is powerful :) ->
"%0":os.getcwd()+"/"+__file__,
"%cCurrentLine%":"0", # and another very nice var :)
}
)
def version(self):
return version#0.1
def sleep(self, t = ""):
"""A feature for Batch0.2 for Python - not winBatch"""
if not t:
print "ERROR; sleep() needs at least 1 Parameter"
return 0
time.sleep(t)
def more(self, file = ""):
if not os.path.isfile(file):
print "more: Datei %s existiert nicht" % (file)
return 0
f = open(file, "r")
lines = f.readlines()
for line in lines:
print line,
if self.sexyCode == 1:
print
def mkdir(self, dirname):
if os.path.isdir(dirname):
print "{Error:Line #%s} mkdir [Dir already exists][File: %s]" % (self.cLineNumber,self.cFileName)
sys.exit(-1)
os.mkdir(dirname)
def open(self, file = ""):
if not file:
print "Syntax: %s <DATEI>" % (__file__)
return 0
if not os.path.isfile(file):
print "Datei: %s konnte nicht gefunden werden. [%s]" % (file,os.getcwd())
return 0
f = open(file, "r")
self.cLineNumber = 0
lines = f.readlines()
self.cFileName = file
for line in lines:
self.cLineNumber += 1
self.vars["%cCurrentLine%"] = str(int(self.vars["%cCurrentLine%"])+1)
lx = line.split("\n")[0] # fixes a big bug
line = lx.split(" ")
if os.path.isfile("sys/Windows/"+line[0].split("\n")[0]+".py"):
execfile("sys/Windows/"+line[0].split("\n")[0]+".py",{"ARGUMENTS":" ".join(line[1:]).replace("\n","")})
elif line[0] == "pause" or line[0] == "pause\n":
self.pause()
elif line[0] == "@echo":
if line[1] == "off":
self.loudly = "off"
else:
print self.status()
elif line[0] == "more":
self.more(line[1].split("\n")[0])
elif line[0] == "echo":
self.echo(" ".join(line[1:]))
elif line[0] == "goto":
if line[1]:
print "Goto: %s" % (line[1])
else:
print "Keine Sektion"
elif line[0] == "copy":
self.copy(self.decodevars(line[1]),self.decodevars(line[2].split("\n")[0]))
elif line[0] == "exit":
sys.exit(-1)
elif line[0] == "set":
varstring = ' '.join(line[1:])
varstring = varstring.split("=")
value = varstring[1]
var = varstring[0]
value = value.split("\n")[0]
self.set(self.decodevars(var),self.decodevars(value))
def copy(self, file,target):
shutil.copy(file,target)
if self.loudly != "off":
print "Kopiere Datei %s nach %s" % (file,target)
def imaging(self, file=""):
img = Image.new("RGB",(300,300),"#000000")
draw = ImageDraw.Draw(img)
r,g,b = rint(0,255), rint(0,255), rint(0,255)
dr = (rint(0,255) - r)/300
dg = (rint(0,255) - g)/300
db = (rint(0,255) - b)/300
for i in range(300):
r,g,b = r+dr, g+dg, b+db
draw.line((i,0,i,300),fill=(int(r),int(g),int(b)))
img.save("line.png","PNG")
def decodevars(self, text = ""):
for i in self.vars:
if i in text:
text = text.replace(i,self.vars[i])
return text
def echo(self, text = "", params = []):
"""The echo-Rebuild"""
# text = string [>> file]
if text.count(">") == 1 or text.count(">>") == 1:
if text.count(">") == 1:
os.system("echo \"%s\" > \"%s\"" % (text.split(" > ")[0],text.split(" > ")[1]))
pass
elif text.count(">>") == 1:
# text.count(">") triggered before so we don't need to retry
os.system("echo \"%s\" >> \"%s\"" % (text.split(" >> ")[0],text.split(" >> ")[1]))
pass
if not text:
print "{Error:Line #%s} echo [No Text to output][File: %s]" % (self.cLineNumber,self.cFileName)
sys.exit(-1)
return 0
if self.loudly == "on":
print "echo %s" % (text),
print self.decodevars(text)
def set(self, var, value):
#print "DEBUG: set [NOPARAM] %s zu %s" % ("%" + var + "%", value)
self.vars["%"+str(var)+"%"] = str(value)
# "%" fixes many bugs :) so you can not set HELLO="Bye" to stop posting HELLO Texts ;)
def silent(self, type = "on"):
if type == "off":
self.loudly = "off"
else:
self.loudly = type
def status(self):
return self.loudly
def clear(self):
if os.name == "posix":
os.system("clear")
else:
print "\n"*100
# sessions (new! :))
def newSession(self, sessionname = ""):
print "Konnte keine Session starten.."
print "Dies kann folgende Gruende haben:\n"
print "Sessions sind noch nicht implementiert oder verfuegbar!"
print "Die Session.uix Datei scheint veraltet zu sein"
print "Die aktuelle Konfiguration verhindert Sessions"
def saveSession(self, sessionname = ""):
"""A feature for Batch0.2 for Python - not winBatch
You can save the whole ScriptData (vars, output and so on)
You can use getSession(name) to get the Data running for YOUR Session"""
# beta: store all your arrays in a File
if self.more_output:
print "Starte Datenspeicherung - %s" % (sessionname)
d = open("session.uix","w")
d.write("[cvars]")
for item in self.vars:
value = self.vars[item]
d.write("\n" + item + "=" + value)
if self.more_output:
print "Speichere %s | WertSpiegel: %s" % (item, value)
d.write("\n[uix]\nos.name=" + str(os.name))
d.close()
if self.more_output:
print "Session stored.."
def getSession(self):
d = open("session.uix","r")
a = d.readlines()
for i in a:
if i.count("%") > 1:
self.vars[i.split("=")[0]] = i.split("=")[1].replace("\n","")
def pause(self, allow_every_key = 1):
"""The pause-Rebuild, loops til' it returns an exception"""
if allow_every_key == 1:
self.pause_text = "eine Taste"
else:
self.pause_text = "Enter"
fd = sys.stdin.fileno()
oldterm = termios.tcgetattr(fd)
newattr = termios.tcgetattr(fd)
newattr[3] = newattr[3] & ~termios.ICANON & ~termios.ECHO
termios.tcsetattr(fd, termios.TCSANOW, newattr)
oldflags = fcntl.fcntl(fd, fcntl.F_GETFL)
fcntl.fcntl(fd, fcntl.F_SETFL, oldflags | os.O_NONBLOCK)
print "Druecke %s um fortzufahren..." % (self.pause_text)
try:
while 1:
try:
if allow_every_key == 1:
c = sys.stdin.read(1)
break
else:
c = sys.stdin.read(1)
if c == "\n": break
except IOError: pass
finally:
termios.tcsetattr(fd, termios.TCSAFLUSH, oldterm)
fcntl.fcntl(fd, fcntl.F_SETFL, oldflags)
if __name__ == "__main__":# You really need this cause the UpdateManager starts itself using other__name__
B = Batch() # child born! yeah 8)
# STOP! This Code isn't finished yet.
# THE VISUAL BATCH SHELL! - THE INTERPRETER IS THE .open() Function (the .open() Function may be older)
try:
if os.path.isfile(sys.argv[1]):
if B.status() == "on":
#print "Execute Batch-File: %s" % (sys.argv[1])
d=0
B.open("example.bat")
except IndexError:
print ">> Batch %s for Linux started!\n" % (version)
prompt = ">> "
while True:
try:
d = raw_input(prompt ).split(" ")
except:
print "Programmabbruch mit STRG + C nicht möglich!\nGebe: \"exit\" ein um das Programm sanft zu beenden"
continue
if d[0] == "":
pass
elif os.path.isfile("sys/Windows/"+d[0]+".py"):
execfile("sys/Windows/"+d[0]+".py")
elif d[0] == "more" or d[0] == "type":
try:
B.more(d[1])
except IndexError:
B.more()
elif d[0] == "start":
if len(d) < 2:
B.newSession()
else:
B.open(d[1])
elif d[0] == "ipconfig\all" or d[0] == "ipconfig" and d[1] == "all":
execfile("sys/Windows/ipconfig.py")
elif d[0] == "exit":
sys.exit(-1)
#elif d[0] == "ipconfig":
# execfile("sys/Windows/ipconfig.py")
elif d[0] == "ImageProcessing":
print "Generate Image.."
B.imaging()
elif d[0] == "@echo":
# suitable output command
try:
B.silent(d[1])
except:
print "@echo =",B.status()
elif d[0] == "echo":
B.echo(" ".join(d[1:]))
elif d[0] == "pause":
B.pause()
elif d[0] == "saveSession":
B.saveSession()
elif d[0] == "getSession":
B.getSession()
elif d[0] == "cls": #clear() :)
if os.name == "posix":
os.system("clear")
else:
print "\n"*100
elif d[0] == "set":
if d[1] == "/p":
varname = d[2].split("=")[0].replace("%","")
print ">> ",
value = raw_input()
B.set(varname,value)
else:
B.set(d[1].split("=")[0],d[1].split("=")[1])
elif d[0] == "prompt":
try:
prompt = " ".join(d[1:])
except IndexError:
prompt = ">> "
else:
print "Unbekanntes Kommando: %s (Eventuell noch nicht geportet)" % (d)
pass
# Details:
man = ("""
The following applications are already ported:
prompt => Change the String in Shell-Mode
more => Read Text from File
cls => Clear the Shell-Mode Screen (works even in windows through 100 LineBreaks)
echo => Write Text to Shell-Window (even >,>> works now! =))
pause => Hold the Screen and wait for a Key (You can switch between EVERY KEY and JUST ENTER in the Config)
start => Start a new File/Session in Shell-Mode
exit => Exit the Shell-Mode Window (+Script)
copy => A simple File-Copy Script (Not many options here, but you can also do the copy %0 %0.bak shit :)
@echo => Silent/Loud-Mode (if @echo on, the Script will post a Copy of the Command which gets executed.)
Set => A minimal set Function, works like this: set %VAR%=VALUE. :) (Next feature: set /p for UserInput)
sleep => Not a feature in "shell", but a create debugging Tool.
ipconfig => Ported now! Linked /all to the default Client. :)
---------------------------------------------------------------
In the next release:
set /p => For a User Input Variable | works now ;), next thing is to port other set{} Things.
more -nLINENUMBER <file> => To just read #N Lines in File
help => The create help-Command :)
ftp => The FTP-Client (hohh...)
----------------------------------------------------------------
I can not port the following Applications cause they still need Windows:
reg (The whole Registry-Thing, I try to 'PORT' just a few Things to my Linuxbox
map (Hmm, I'm too stupid to get the network-devices.
------------------------
Not sure to port:
while (A hard way to port.. WHILEO.o)
goto (Just.. annoying ;)) """)
#!/usr/bin/env python
# -*- coding: latin1 -*-
# A small rebuild of ipconfig :)
try:
local = socket.gethostbyname(socket.gethostname())
except:
import socket
import fcntl
import struct
import array
import urllib2
# Loads a copy of socket if not already loaded by batch.py
def get_ip_address(ifname):
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
return socket.inet_ntoa(fcntl.ioctl(
s.fileno(),
0x8915, # SIOCGIFADDR
struct.pack('256s', ifname[:15])
)[20:24])
response = urllib2.urlopen("http://62.141.46.251/de.pascal.globalip.php")
def get_hw_address(ifname):
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
info = fcntl.ioctl(s.fileno(),0x8927,struct.pack('256s',ifname[:15]))
return ''.join(['%02x:' % ord(char) for char in info[18:24]])[:-1]
def all_interfaces():
max_possible = 128 # arbitrary. raise if needed.
bytes = max_possible * 32
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
names = array.array('B', '\0' * bytes)
outbytes = struct.unpack('iL', fcntl.ioctl(
s.fileno(),
0x8912, # SIOCGIFCONF
struct.pack('iL', bytes, names.buffer_info()[0])
))[0]
namestr = names.tostring()
return [namestr[i:i+32].split('\0', 1)[0] for i in range(0, outbytes, 32)]
devices = all_interfaces()#list array [network.interfaces]
print "\nLinux IP Konfiguration\n"
print "\t Hostname. . . . . . . . . . . : %s" % (socket.gethostname())
print "\t Lokale IP . . . . . . . . . . : %s" % (local)
print "\t Globale IP. . . . . . . . . . : %s" % (response.read())
print
lan_devices = 0
wlan_devices = 0
unknown_connection = 0
for d in devices:
if d == "wlan0":
wlan_devices += 1
print "WLAN Adapter %s: " % (wlan_devices)
elif d == "eth" or "lo":
lan_devices += 1
print "Ethernetadapter LAN-Verbindung %s: " % (lan_devices)
else:
unknown_connection = lan_devices+wlan_devices+unknown_connection+1
print "Unbekannte Verbindung %s: " % (unknown_connection)
print
print "\t IP-Adresse. . . . . . . . . . :",get_ip_address(d)
print "\t Mac-Adresse:. . . . . . . . . :",get_hw_address(d)
print
# Linux IP Konfiguration
# ----------------------
# Copyright: pascal
# Version: 0.1
# ----------------------
# Detect all WLAN Devices
# Loop through them and
# Post IP and MACAddr
# ----------------------
# We do as much as we can do at the moment
# I can't fetch the GLOBAL IP during.. ahm I don't know
# So I provide you a (small) php script that CAN do ;)
# Navigate to: 62.141.46.251/de.pascal.globalip.php and fetch the Source.
# ----------------------
# Coding after Coding, finally the IPConfig looks very well.
# It is not so informative but it works and you can almost read everything
#!/usr/bin/python
# -*- coding: latin1 -*-
# Rehash Script to reload the main Python Module
import os
Batch().clear()
os.system("sleep 0;batch") # sleep while sys.exit kills ya! cause we are running a /bin/bash Session
sys.exit(-1)
# This is very easy to understand.
# First, we clear the current Windows using Batch() Clear. (so you can not use python rehash.py =P)
# After that, we OPEN a System-Process (it sleeps in the background for 1 second and execute "batch")
# Remember: We have sleep and the batch running.
# Using sys.exit() Kills the current batch process.
# Now, only sleep() exists. the script sleep for 1 second and execute it self.
# :) - simple, but it works.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment