Guest User

Untitled

a guest
Mar 22nd, 2018
137
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 2.98 KB | None | 0 0
  1. #!/usr/bin/env python
  2. # -*- coding: utf-8 -*-
  3.  
  4. import struct
  5. import ftplib
  6. import zipfile
  7. import StringIO
  8.  
  9. loxoneMiniServerIP = '192.168.178.255' # IP address of the Loxone Miniserver
  10. adminUsername = '<ADMIN_USERNAME>'
  11. adminPassword = '<ADMIN_PASSWORD>'
  12.  
  13. ftp = ftplib.FTP(loxoneMiniServerIP)
  14. ftp.login(adminUsername, adminPassword)
  15.  
  16. data = []
  17. def handle_binary(more_data):
  18. data.append(more_data)
  19.  
  20. resp = ftp.retrbinary("RETR /backup/sps_new.zip", callback=handle_binary)
  21. data = "".join(data)
  22.  
  23. zf = zipfile.ZipFile(StringIO.StringIO(data))
  24. with zf.open('sps0.LoxCC') as f:
  25. header, = struct.unpack('<L', f.read(4))
  26. if header == 0xaabbccee: # magic word to detect a compressed file
  27. compressedSize,header3,header4, = struct.unpack('<LLL', f.read(12))
  28. # header3 is roughly the length of the uncompressed data, but it is a bit higher
  29. # header4 could be a checksum, I don't know
  30. data = f.read(compressedSize)
  31. index = 0
  32. resultStr = ''
  33. while index<len(data):
  34. # the first byte contains the number of bytes to copy in the upper
  35. # nibble. If this nibble is 15, then another byte follows with
  36. # the remainder of bytes to copy. (Comment: it might be possible that
  37. # it follows the same scheme as below, which means: if more than
  38. # 255+15 bytes need to be copied, another 0xff byte follows and so on)
  39. byte, = struct.unpack('<B', data[index:index+1])
  40. index += 1
  41. copyBytes = byte >> 4
  42. byte &= 0xf
  43. if copyBytes == 15:
  44. copyBytes += ord(data[index])
  45. index += 1
  46. if copyBytes > 0:
  47. resultStr += data[index:index+copyBytes]
  48. index += copyBytes
  49. if index >= len(data):
  50. break
  51. # Reference to data which already was copied into the result.
  52. # bytesBack is the offset from the end of the string
  53. bytesBack, = struct.unpack('<H', data[index:index+2])
  54. index += 2
  55. # the number of bytes to be transferred is at least 4 plus the lower
  56. # nibble of the package header.
  57. bytesBackCopied = 4 + byte
  58. if byte == 15:
  59. # if the header was 15, then more than 19 bytes need to be copied.
  60. while True:
  61. val, = struct.unpack('<B', data[index:index+1])
  62. bytesBackCopied += val
  63. index += 1
  64. if val != 0xff:
  65. break
  66. # Duplicating the last byte in the buffer multiple times is possible,
  67. # so we need to account for that.
  68. while bytesBackCopied > 0:
  69. if -bytesBack+1 == 0:
  70. resultStr += resultStr[-bytesBack:]
  71. else:
  72. resultStr += resultStr[-bytesBack:-bytesBack+1]
  73. bytesBackCopied -= 1
  74. with open('Project.Loxone', "w") as f:
  75. f.write(resultStr)
Add Comment
Please, Sign In to add comment