Mercurial and Git clients can push and pull from this alias URL to interact with this repository. You can change to which repository an alias points by going to the Aliases link on the project page.
#!/usr/bin/env pythonimportgetoptimportosimportreimportpickleimportselectimportsocketimportsysimportthreadingclassRedisError(object):def__init__(self,message):self.message=message def __repr__(self):
return '<RedisError(%s)>' % self.message
-class RedisBadValueError(RedisError):- def __init__(self):- super(RedisBadValueError, self).__init__('Operation against a key holding the wrong kind of value')-class RedisConstant(object):
def __init__(self, type):
self.type = type
def__repr__(self): return '<RedisConstant(%s)>' % self.type
EMPTY_SCALAR = RedisConstant('EmptyScalar')
-EMPTY_ARRAY = RedisConstant('EmptyArray')
+EMPTY_LIST = RedisConstant('EmptyList')
+BAD_VALUE = RedisError('Operation against a key holding the wrong kind of value')class RedisClient(object):
def__init__(self,socket):self.socket=socketself.wfile=socket.makefile('wb')self.rfile=socket.makefile('rb')self.db=Noneself.table=NoneclassMiniRedis(threading.Thread):def__init__(self,host='127.0.0.1',port=56784,logging=False,db_file=None):super(MiniRedis,self).__init__()self.host=hostself.port=portself.logging=loggingself.halt=Trueself.tables={}self.clients={}self.db_file=db_fileself.load()deflog(self,client,s):ifself.logging:who='%s:%s'%client.socket.getpeername()ifclientelse'SERVER'print'%s: %s'%(who,s)defselect(self,client,db):ifdbnotinself.tables:self.tables[db]={}client.db=dbclient.table=self.tables[db]defsave(self):ifself.db_file:withopen(self.db_file,'wb')asf:pickle.dump(self.tables,f,pickle.HIGHEST_PROTOCOL)self.log(None,'saved database to "%s"'%self.db_file)defload(self):ifself.db_fileandos.path.lexists(self.db_file):withopen(self.db_file,'rb')asf:self.tables=pickle.load(f)self.log(None,'loaded database from file "%s"'%self.db_file)defhandle_set(self,client,key,data):client.table[key]=dataself.log(client,'SET %s -> %s'%(key,data))returnTrue def handle_get(self, client, key):
data = client.table.get(key, None)
if isinstance(data, list):
- return RedisBadValueError()+ return BAD_VALUE if data != None:
data = str(data)
else:
data=EMPTY_SCALARself.log(client,'GET %s -> %s'%(key,data))returndatadefhandle_del(self,client,key):self.log(client,'DEL %s'%key)ifkeynotinclient.table:return0delclient.table[key]return1defhandle_lpush(self,client,key,data): if key not in client.table:
client.table[key] = []
elif not isinstance(client.table[key], list):
- return RedisBadValueError()+ return BAD_VALUE client.table[key].insert(0, data)
self.log(client, 'LPUSH %s %s' % (key, data))
return True
defhandle_rpop(self,client,key): if key not in client.table:
return EMPTY_SCALAR
if not isinstance(client.table[key], list):
- return RedisBadValueError()+ return BAD_VALUE if len(client.table[key]) > 0:
data = client.table[key].pop()
else:
data=EMPTY_SCALARself.log(client,'LPOP %s -> %s'%(key,data))returndatadefhandle_keys(self,client,pattern):r=re.compile(pattern.replace('*','.*'))self.log(client,'KEYS %s'%pattern)return' '.join(kforkinclient.table.keys()ifr.search(k))defhandle_incr(self,client,key):returnself.handle_incrby(client,key,1)defhandle_incrby(self,client,key,by):try:client.table[key]=int(client.table[key])client.table[key]+=int(by)except(KeyError,TypeError,ValueError):client.table[key]=1self.log(client,'INCRBY %s%s -> %s'%(key,by,client.table[key]))returnclient.table[key]defhandle_flushdb(self,client):self.log(client,'FLUSHDB')client.table.clear()returnTruedefhandle_select(self,client,db):db=int(db)self.select(client,db)self.log(client,'SELECT %s'%db)returnTruedefhandle_quit(self,client):self.log(client,'QUIT')client.socket.shutdown(socket.SHUT_RDWR)client.socket.close()delself.clients[client.socket]returnFalsedefhandle_shutdown(self,client):self.log(client,'SHUTDOWN')self.halt=TruereturnTruedefhandle_save(self,client):self.save()self.log(client,'SAVE')returnTruedefunwrap_set(self,client,line):key,length=line.split()data=client.rfile.read(int(length))client.rfile.read(2)# throw out newlinereturnself.handle_set(key,client,data)defunwrap_get(self,client,line):key=line.strip()returnself.handle_get(client,key)defunwrap_del(self,client,line):key=line.strip()returnself.handle_del(client,key)defunwrap_lpush(self,client,line):key,length=line.split()data=client.rfile.read(int(length))client.rfile.read(2)# throw out newlinereturnself.handle_lpush(client,key,data)defunwrap_rpop(self,client,line):key=line.strip()returnself.handle_rpop(client,key)defunwrap_keys(self,client,line):pattern=line.strip()returnself.handle_keys(client,pattern)defunwrap_incrby(self,client,line):key,by=line.split()returnself.handle_incrby(client,key,by)defunwrap_flushdb(self,client,line):returnself.handle_flushdb(client)defunwrap_select(self,client,line):db=line.strip()returnself.handle_select(client,db)defunwrap_quit(self,client,line):returnself.handle_quit(client)defunwrap_shutdown(self,client,line):returnself.handle_shutdown(client)defhandle_normal(self,client,line):command,_,rest=line.partition(' ')returngetattr(self,'unwrap_'+command.strip().lower())(client,rest)defhandle_multibulk(self,client,line):items=int(line[1:].strip())args=[]forxinxrange(0,items):length=int(client.rfile.readline().strip()[1:])args.append(client.rfile.read(length))client.rfile.read(2)# throw out newlinecommand=args[0].lower()returngetattr(self,'handle_'+command)(client,*args[1:])defhandle(self,client):line=client.rfile.readline()ifnotline:self.log(client,'client disconnected')delself.clients[client.socket]client.socket.close()returnifline[0]=='*':o=self.handle_multibulk(client,line)else:o=self.handle_normal(client,line)self.dump(client,o)defdump(self,client,o):nl='\r\n'ifisinstance(o,bool):ifo:client.wfile.write('+OK\r\n') # Show nothing for a false return; that means be quiet
elif o == EMPTY_SCALAR:
client.wfile.write('$-1\r\n')
- elif o == EMPTY_ARRAY:
+ elif o == EMPTY_LIST:
client.wfile.write('*-1\r\n')
elif isinstance(o, int):
client.wfile.write(':' + str(o) + nl)
elifisinstance(o,str):client.wfile.write('$'+str(len(o))+nl)client.wfile.write(o+nl)elifisinstance(o,list):client.wfile.write('*'+len(o))forvalino:self.dump(client,val)elifisinstance(o,RedisError):client.wfile.write('-ERR %s\r\n'%o.message)else:client.wfile.write('return type not yet implemented\r\n')client.wfile.flush()defstop(self):self.halt=Trueself.join()defrun(self):self.halt=Falseserver=socket.socket(socket.AF_INET,socket.SOCK_STREAM)server.bind((self.host,self.port))server.listen(5)whilenotself.halt:readable,_,_=select.select([server]+self.clients.keys(),[],[],1.0)forsockinreadable:ifsock==server:(client_socket,address)=server.accept()client=RedisClient(client_socket)self.clients[client_socket]=clientself.log(client,'client connected')self.select(client,0)else:try:self.handle(self.clients[sock])exceptException,e:self.log(client,'exception: %s'%e)self.handle_quit(client)forclient_socketinself.clients.iterkeys():client_socket.close()self.clients.clear()server.close()server=Nonedefmain(args):host,port,logging='127.0.0.1',56784,Trueopts,args=getopt.getopt(args,'h:p:l')foro,ainopts:ifo=='-h':host=aelifo=='-p':port=int(a)elifo=='-l':logging=Trueprint'Launching MiniRedis on %s:%s'%(host,port)m=MiniRedis(host=host,port=port,logging=logging,db_file='miniredis.db')m.start()m.join()print'Stopped'if__name__=='__main__':main(sys.argv[1:])
Attach a Trello Card
Add a tag
Your session has expired
You are no longer logged in. Please log in and try your request again.
Filter RSS Feed
This RSS feed URL allows you to see the contents of your current filter using any feed reader.
This link includes a special authentication token. If you share the URL with anyone else, they can see this RSS feed's activity. You can disable these tokens when needed.
Your current filter is unsaved; changing it won't affect this RSS feed.