The Myshell

Stato
Discussione chiusa ad ulteriori risposte.

fojeaf

Utente Silver
3 Marzo 2008
235
8
0
95
come magari alcuni di voi già sapranno sono molti mesi che sono impegnato col progetto per la creazione della myshell, una shell che consetisse di fare tantissime cose da una linea di comando, il tutto multi-piattaforma. Il progetto si è arenato causa i miei continui impegni etc. Quindi vi pubblico il sorgente della 1.0.1 Beta 24 (l'ultima). Se qualcuno vuole fornirmi funzioni o comandi, o anche darmi l'idea di cosa aggiungere, ciò sarà bene accetto ed ovviamente sarete inseriti fra gli autori. Il progetto, opensource è sotto licenza GNU/GPL 3.

Codice:
# -*- coding: iso-8859-1 -*-
#!/usr/bin/python
# Author: Malex
# License: GNU/GPL 3
import os
import sys #per file con estensione .mysh  (futuro progetto)
import zipfile
import zlib
import string
import socket
import platform
import time
import hashlib
import shelve
import random

###############################
def getos():
    return platform.system()
###############################

mod_doc="""Shell documentation:
goto <path>  change you current working directory to path
execute <file> launch the file, if the file as particular extension excute launch it with particular programms (see ?execute)
exit close the shell
turn off -t  (-t is an optional arugument) shut down the computer in -t second (max 99). if -t is not indicated, the shout down will be appended in 48 seconds
edit <file>  edit an ascii file
show <file>  show you the content of a file
?<command>  (<command> is an optional argument) show the documentation of the command, if command is not given show the shell documentation
help    show th shell documentation
cut <name> <path>   a shortcut is created with name as name ad path as redirect
zip <file> -de (-de is an optional argument) if -de is indicated, decopmpress a zip file, else compress the file to a zip file
url <url>   open the url in the predefined browser
gz <file> -de (opzional paramether) if -de is indicated, decompress the gz file, else compress the file into a gzfile
info    this command show some information about your actual system, like OS, architecture etc.
pass    run the Malex Password Safer (note that the password safer of the myshell is the same of the other, so you have to use the same password
"""
commands=["goto","execute","url","turn off","edit","cut","?","help","zip","exit"]

goto_doc="""goto is a command you can use to change your current directory. If the directory given
does not exists, will be printed an error message. If you do not give any paramether, nothing will happen.
Instead of a directory you can give a special paramether, like the command
goto -back y
With this command you will return to the mother directory.
Other special paramethers:
goto -disk y         you will go to the directory of your current disk (for example C:/ )
"""

zip_doc="""
"""

doc_dict={0 : goto_doc}

__author__="Malex"
__version__="1.0.1 Beta 26"
__license__="""
You can modify it. You cannot earn money by it. You must indicate the original author, Malex
"""
#################################

def _compress(self,file_name,compression_level=6):
    f=file(file_name,'r')
    data_compressed=zlib.compress(f.read(),compression_level)
    f.close()
    f=file(file_name+'.gz','w')
    f.write(datacompressed)
    f.close()
def _decompress(self,filename):
    f=file(filename,'r')
    data=zlib.decompress(f.read())
    f.close()
    f=file(filename[:-3],'w')
    f.write(data)
    f.close()
##################################
def pars(value):
    val=[f for f in value]
    fin=[]
    for i in val:
        if i=="/":
            fin.append("\\")
        else:
            fin.append(i)
    fin="".join(fin)
    return fin

class folder:
    def setValue(self,value):
        if os.access(value,0):
            self.__value=value
        else:
            print "La directory non esiste, inserire una directory corretta"
            self.__value=self.getValue()
    def getValue(self):
        return self.__value
    def delValue(self):
        del self.__value
    def __init__(self):
        self.__value=None
        self.setValue("C:/")
    def __str__(self):
        return self.getValue()
    value=property(getValue,setValue,delValue,"")

class database:
    def __init__(self,data_file):
        self.data=shelve.open(data_file,writeback=True)
    def add(self,key,value):
        self.data[key]=value
        return self.data
    def delete(self,key,value=""):
        del self.data[key]
        return self.data
    def modify(self,key,nvalue):
        self.data[key]=nvalue
        return self.data
    def read(self,key):
        return self.data[key]
    def getkey(self,value):
        for i in self.data.keys():
            if self.data[i]==value:
                return i
            else:
                continue
        return -1

##############################
# Malex Password Safer

def pass_safe():
    doc="""
? or help |  show you the documentation
-cr string | crypt the string
-de hash | decrypt the string if there is in the database
-options | you can modify the options
exit | close the programm
"""
    if platform.system()=="Windows":
        data=database("C:\\WINDOWS\\imp.db")
    elif platform.system()=="Linux":
        data=database("/bin/imp.db")
    try:
        usage=int(data.read('usage'))
        usage+=1
        data.modify('usage',str(usage))
        p=raw_input("Insert the password ")
        if hashlib.sha512(p).hexdigest()==data.read("password"):
            print "Correct Password. Logged in successful"
        else:
            print "The password is incorrect, the programm will be closed."
            return
    except KeyError:
        data.add('usage','1')
        pas=raw_input("Now you must insert a password for this programm. ")
        check=raw_input("Please retype the password to check it ")
        if pas==check:
            data.add("password",hashlib.sha512(pas).hexdigest())
        else:
            print "The passwords tou entered do not match. The programm will be close"
            data.delete('usage')
    while True:
        what=raw_input("Now enter what you want to do (enter ? or help for a list of commands) ")
        if what=="?" or what=="help":
            print doc
        elif what=="-options":
            print "Ok, what do you want to modify? (-password)?"
            act=raw_input()
            if act=="-password":
                print "Ok, please enter the previsuos password"
                old=raw_input()
                if not old==data.read("password"):
                    print "Sorry, but the password is wrong"
                    return
                else:
                    del old
                    print "Now enter the new password"
                    new=raw_input()
                    print "Please confirm the password you entered"
                    ch=raw_input()
                    if ch==new:
                        print "Ok, your password is changed"
                        data.modify("password",new)
                    else:
                        print "Sorry, but the two passowords do not match."
                        del ch,new
                continue
            else:
                print "At the moment there aren't any other options, please check if a new version is aviable"
                del act
                continue
        elif what=="exit":
            print "Goodbye"
            return
        elif what[0:3]=="-cr":
            print "Ok now a password will be created from the string given, to decrypt use -de "
            ran=random.randint(1,128)
            a=[f for f in what[4:]]
            lis=[]
            for i in a:
                ch=ord(i)
                if ch<=ran:
                    ch+=25
                ch-=ran
                while ch<=32:
                    ch+=ran
                    ran=random.randint(1,128)
                    ch-=ran
                lis.append(chr(ch))
            st="".join(lis)
            data.add(str(what[4:]),st)
            print st
        elif what[0:3]=="-de":
            print "The password for this keyword are "
            print data.read(str(what[4:]))
        else:
            continue

#############################
class comman:
    def action(self):
        global sta
        if self.comando=="":
            return
        if self.comando[0]=="?" or self.comando=="help":
            if self.comando=="?" or self.comando=="help":
                print mod_doc
            else:
                try:
                    global commands
                    commands.index(self.comando[1:])
                    print doc_dict[commands.index(self.comando[1:])]
                except ValueError:
                    print "The command %s does not exist. Type ? or help to view the list of the commands." % (self.comando[1:])
        elif self.comando[0:6]=="prompt":
            string=self.comando[6:]
            os.system("start"+string)
        elif self.comando[0:4]=="goto":
            before=sta
            if self.comando=="goto -back y":
                temp=sta.split('/')
                del temp[-2]
                temp='/'.join(temp)
                sta=temp
            elif self.comando=="goto -disk y":
                sta=sta[0:3]
            elif self.comando[5]=="C":
                sta=self.comando[5:]
            else:
                sta=(before+(self.comando[5:])+"/")
            if not os.access(sta,0):
                print "The directory %s does not exists" % (sta)
                sta=before
        elif self.comando=="pass":
            pass_safe()
        elif self.comando=="turn off":
            check=os.popen("shutdown"+" ".join((self.comando.split(" ")[2:]))).read()
            if check[9:17]=="shutdown":
                check=check[0:9]+"turn off"+check[17:]
            print check
        elif self.comando[0:3]=="zip":
            if self.comando[4:6]=="-de":
                self.comando=self.comando[0:3]+self.comando[8:]
                if self.comando[4]=="C":
                    pass
                else:
                    self.comando=self.comando[0:3]+sta+self.comando[4:]
                if not zipfile.is_zipfile(self.comando[4:]):
                    print "Il file digitato non è zip, per favore riutilizza correttamente il comando."
                    print zip_doc
        elif self.comando[0:7]=="execute":
            if self.comando[7:10]=="C:/":
                location=pars(self.comando[7:])
            else:
                location=pars(sta)+pars(self.comando[8:])
            print location
            a,o=os.popen2(location)
            try:
                print a.read()
            except IOError:
                pass
            pass
        elif self.comando[0:2]=="gz":
            print "command non avaible yet, please check if a newer version of myshell is avaible"
        elif self.comando=="info":
            print """Architecture: %s
Operative System: %s
Release: %s
Python version: %s
""" % (platform.architecture(),platform.system(),platform.release(),platform.python_version())
        elif self.comando[0:6]=="socket":
            sock=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
            if not len(self.comando)==6:
                try:
                    get=self.comando[7:].split(",")
                    host=get[0]
                    port=int(get[1])
                except IndexError:
                    print "Incorrect request, type ?socket for the usage of command 'socket'"
                    return -1
            else:
                host=raw_input("Insert the hostname ")
                port=int(raw_input("Insert the port number "))
            sock.connect((host,port))
            yn=raw_input("Accepting connections? (Y/N) ")
            if yn=="Y" or yn=="y":
                boo=True
                conn,add=sock.accept()
                var=conn.recv(1024)
            while True:
                com=raw_input("Insert a socket command ")
                if com=="close":
                    sock.close()
                    break
                elif com[0:4]=="send":
                    sock.send(com[5:])
                elif com[0:5]=="print":
                    if not boo:
                        print "No accept connection"
                        continue

    def __init__(self,valore):
        self.comando=valore
################################
sta=folder()
sta="C:/"
while True:
    var=raw_input(str(sta)+" ")
    if var=="exit":
        sys.exit()
    else:
        e=comman(var)
        e.action()

il codice è un po' frammentato, cercherò di dargli col tempo un po' di "restyling"

EDIT (beta 24): ho eliminato quelle bruttissime strutture get/set/del grazie al metodo property e corretto un piccolo bug. Ora il comando goto funziona alla perfezione!

EDIT (beta 25): inserito il Malex Password Safer e la classe Database per futuri utilizi, non è stata testata, segnalatemi eventuali bug del Safer

EDIT (beta 26) sistemati alcuni gravi bug, ora il Safer è funzionante al 100%. La funzione di gestione socket per ora nn va, ed è in fase di sviluppo. Inoltre sto riscrivendo la funzione execute usando popen2 in modo da gestire tutto dalla shell senza aprire a parte il cmd. nella beta 27 sarà inoltre presente il comando equivalente a dir.
per una migliore lettura: http://pastebin.com/f447f9c05
 
RE: Aiuto per myshell

probabilmente una ca22ata ma io metterei uno spazio altrimenti i comandi vengono attaccati alla directory (ad esempio nel goto)...
 
RE: Aiuto per myshell

beh in eftti meglio, inoltre metto un messaggio di errore quando il goto nn va a buon fine, e tolgo la riscrittura del comando ;)

sto lavorando per terminare gli altri comandi previsti :asd:
 
RE: Aiuto per myshell

che lavoro immane... Poi magari si può provare a farlo con semplice interfaccia (io sono bloccato alle classi specifiche delle gui argh) [ot]poi ho anche un progetto per symbian in mente quindi sono abbastanza fermo con pythoncard :)[/ot]
 
RE: Aiuto per myshell

chiaramente il progetto sarebbe POI di fare anche una vera e propria shell grafica che interagisca con questa, ma prima ho ancora molto altro da fare. cmq ho quasi terminato la produzione del comando turn off per windows, per linux e mac dovrò cercare il comando quale sia

EDIT: è stato + facile del previsto, ho eliminato le 85 righe di codice che avevo scritto e mi rifaccio direttamente a shutdown.exe per ora, sia benetto os.popen
 
RE: Aiuto per myshell

sempre sia lodato... Mi è venuto in mente che potresti aggiungere un ftp uploader e un mail sender (es. Smtp)
 
RE: Aiuto per myshell

uhm all'ftp ci avevo pensato (sono già all'opera....) ma all'e-mail sender no, ottima idea. così ho la scusa per studiarmi le librerie per le email......
 
RE: Aiuto per myshell

mi si è accesa una lampadina... Integrare un convertitore (es. Md5, Sha etc etc) e il tuo password safer (ne hai fatto uno giusto? ;))
 
RE: Aiuto per myshell

sì, il password safer lo stavo già adattando (fra i miei 1000 impegni :asd: ), mentre al convertitore non avevo pensato. e visto che ci sono inserirò anche un convertitore per le misure.........

inserita la beta 25 col password safer ;) ho risolto il problema che avevo, mi perdevo in un bicchier d'acqua, alla fine bastava sostituire l' exit() con un banale return ed integrare il tutto come funzione (e con questo fanno 325 righe di codice scritte a mano di mio pugno)
 
RE: Aiuto per myshell

325 righe?!? Argh... Bravo XD
Adesso devo dare un'occhiata più approfondita al source perché mi interessa capire come fai a distinguere le opzioni dei comandi
 
RE: Aiuto per myshell

semplicemente si può fare con:

gli indici se sei sicuro che l'opzione sia in una determinata posizione.

str.find() se nn ti da -1 vuol dire che c'è, e ti da anche l'indice per vedere quale valore gli è stato assegnato ;)
 
modificato parecchio, soprattutto nel resstyling che appena possibile verrà portato a termine. Lo scritta troppo a tratti e in molti punti il codice risulta illegibile.........
 
Fischia Malex non sapevo di questa tua opera. Davvero affascinante! Se vai avanti a integrare sempre più roba prima o poi diventerà un sistema operativo xD
 
il sistema operativo in futuro sarei tentato di farlo, ma nn sono abbstanza bravo e cmq sarebbe una mezza perdita di tempo. intanto mi faccio una bella shell, che a volte è perfino + veloce del cmd...... ed ovviamente la uso :asd:
 
Solo una cosa prova i tasti direzionali, dovrebbero spostare il puntatore secondo me, poi sotto linux quel C:/ non mi piace :(, anche il completamento automatico col TAB manca...qualcosa in più ce la metterei
ma potrebbe diventare carina come cosa
 
prima di passare ad integrare nuove cose ho deciso di dare una sistemata al tutto:

1) aggiungere le documentazioni dei vari comandi funzionanti.
2) estrarre i procedimenti dal metodo action, creando nuove funzioni, e lasciando ad esso solo la valutazione della stringa.
3) aggiungere il semplice comando dir
4) sistemare un paio di problemini avuti con linux
5) tentare di completare funzioni lasciate in sospeso
6) provare a dare un'accelerata al tutto (nn è che sia lenta, però sempre meglio ottimizzare).
 
Stato
Discussione chiusa ad ulteriori risposte.