Manual:API Python3: Difference between revisions

From MikroTik Wiki
Jump to navigation Jump to search
No edit summary
Line 169: Line 169:
==See also==
==See also==
[[Manual:API|API]]
[[Manual:API|API]]
[[Category:API|A]]
[[Category:Manual|A]]

Revision as of 13:21, 3 August 2011

Summary

Since python language have introduced changes to syntax when going from 2.x to 3.x some adjustments had to be made for old code from API.

Code for Python3

 #!/usr/bin/python
 
 import sys, posix, time, binascii, socket, select
 import hashlib
 
 class ApiRos:
   "Routeros api"
   def __init__(self, sk):
       self.sk = sk
       self.currenttag = 0
 
   def login(self, username, pwd):
       for repl, attrs in self.talk(["/login"]):
           chal = binascii.unhexlify((attrs['=ret']).encode('UTF-8'))
       md = hashlib.md5()
       md.update(b'\x00')
       md.update(pwd.encode('UTF-8'))
       md.update(chal)
       self.talk(["/login", "=name=" + username,
                  "=response=00" + binascii.hexlify(md.digest()).decode('UTF-8') ])
 
   def talk(self, words):
       if self.writeSentence(words) == 0: return
       r = []
       while 1:
           i = self.readSentence();
           if len(i) == 0: continue
           reply = i[0]
           attrs = {}
           for w in i[1:]:
               j = w.find('=', 1)
               if (j == -1):
                   attrs[w] = 
               else:
                   attrs[w[:j]] = w[j+1:]
           r.append((reply, attrs))
           if reply == '!done': return r
 
   def writeSentence(self, words):
       ret = 0
       for w in words:
           self.writeWord(w)
           ret += 1
       self.writeWord()
       return ret
 
   def readSentence(self):
       r = []
       while 1:
           w = self.readWord()
           if w == : return r
           r.append(w)
           
   def writeWord(self, w):
       print(("<<< " + w))
       self.writeLen(len(w))
       self.writeStr(w)
 
   def readWord(self):
       ret = self.readStr(self.readLen())
       print((">>> " + ret))
       return ret
 
   def writeLen(self, l):
       if l < 0x80:
           self.writeStr(chr(l))
       elif l < 0x4000:
           l |= 0x8000
           self.writeStr(chr((l >> 8) & 0xFF))
           self.writeStr(chr(l & 0xFF))
       elif l < 0x200000:
           l |= 0xC00000
           self.writeStr(chr((l >> 16) & 0xFF))
           self.writeStr(chr((l >> 8) & 0xFF))
           self.writeStr(chr(l & 0xFF))
       elif l < 0x10000000:        
           l |= 0xE0000000         
           self.writeStr(chr((l >> 24) & 0xFF))
           self.writeStr(chr((l >> 16) & 0xFF))
           self.writeStr(chr((l >> 8) & 0xFF))
           self.writeStr(chr(l & 0xFF))
       else:                       
           self.writeStr(chr(0xF0))
           self.writeStr(chr((l >> 24) & 0xFF))
           self.writeStr(chr((l >> 16) & 0xFF))
           self.writeStr(chr((l >> 8) & 0xFF))
           self.writeStr(chr(l & 0xFF))
 
   def readLen(self):              
       c = ord(self.readStr(1))    
       if (c & 0x80) == 0x00:      
           pass                    
       elif (c & 0xC0) == 0x80:    
           c &= ~0xC0              
           c <<= 8                 
           c += ord(self.readStr(1))    
       elif (c & 0xE0) == 0xC0:    
           c &= ~0xE0              
           c <<= 8                 
           c += ord(self.readStr(1))    
           c <<= 8                 
           c += ord(self.readStr(1))    
       elif (c & 0xF0) == 0xE0:    
           c &= ~0xF0              
           c <<= 8                 
           c += ord(self.readStr(1))    
           c <<= 8                 
           c += ord(self.readStr(1))    
           c <<= 8                 
           c += ord(self.readStr(1))    
       elif (c & 0xF8) == 0xF0:    
           c = ord(self.readStr(1))     
           c <<= 8                 
           c += ord(self.readStr(1))    
           c <<= 8                 
           c += ord(self.readStr(1))    
           c <<= 8                 
           c += ord(self.readStr(1))    
       return c                    
 
   def writeStr(self, str):        
       n = 0;                      
       while n < len(str):         
           r = self.sk.send(bytes(str[n:], 'UTF-8'))
           if r == 0: raise RuntimeError("connection closed by remote end")
           n += r                  
 
   def readStr(self, length):      
       ret =                     
       while len(ret) < length:    
           s = self.sk.recv(length - len(ret)).decode('UTF-8')
           if s == : raise RuntimeError("connection closed by remote end")
           ret += s
       return ret
 
 def main():
   s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
   s.connect((sys.argv[1], 8728))  
   apiros = ApiRos(s);             
   apiros.login(sys.argv[2], sys.argv[3]);
 
   inputsentence = []
 
   while 1:
       r = select.select([s, sys.stdin], [], [], None)
       if s in r[0]:
           # something to read in socket, read sentence
           x = apiros.readSentence()
 
       if sys.stdin in r[0]:
           # read line from input and strip off newline
           l = sys.stdin.readline()
           l = l[:-1]
 
           # if empty line, send sentence and start with new
           # otherwise append to input sentence
           if l == :
               apiros.writeSentence(inputsentence)
               inputsentence = []
           else:
               inputsentence.append(l)
 
 if __name__ == '__main__':
   main()

See also

API