Отправка и получение tarfile через MQTT - python - PullRequest
0 голосов
/ 17 мая 2018

Я могу отправить тарбол через MQTT, используя скрипт на python, но когда я его получаю, я распаковываю его и получаю сообщение об ошибке. После отслеживания ошибки создается впечатление, что входной поток не записывает файл в архив, поэтому даже если расширение равно .tar.gz, это не фактический файл .tar.gz.

Звучит очень глупо, но в итоге возникает вопрос: «Как мне записать в файл tar ИЛИ как« получить »файл tarfile, чтобы он все еще был в правильном формате .tar.gz для последующей распаковки?»

Я посмотрел модуль tarfile здесь , и он немного помог, а также несколько вопросов здесь здесь и здесь ... но не могу точно определить решение. Стоит отметить, что каждый файл .tar.gz на самом деле представляет собой 3 файла .tar.gz, сжатых в один - не уверен, что это актуально.

Мой код:

from time import gmtime, strftime
import socket
import paho.mqtt.client as mqtt
import tarfile

today = strftime("%Y-%m-%d-%H:%M:%S", gmtime())


def on_connect(client, userdata, flags, rc):
    print("Connected with result code "+str(rc))
    client.subscribe("Backup",qos=2)

def on_message(client, userdata, msg):
    print "Topic : ", msg.topic
    f = tarfile.open("/backups/daily.%s.tar.gz" % today, "w:gz")
    f.write(msg.payload)
    f.close()


clientid = socket.gethostname()
print(clientid)
client = mqtt.Client(clientid,False)
client.on_connect = on_connect
client.on_message = on_message

client.connect("192.168.1.1", 1883, 60)

client.loop_forever()

И мое сообщение об ошибке:

Connected with result code 0
Topic :  Backups
Traceback (most recent call last):
  File "/scripts/filereceiver.py", line 37, in <module>
    client.loop_forever()
  File "/usr/local/lib/python2.7/dist-packages/paho/mqtt/client.py", line 1481, in loop_forever
    rc = self.loop(timeout, max_packets)
  File "/usr/local/lib/python2.7/dist-packages/paho/mqtt/client.py", line 1003, in loop
    rc = self.loop_read(max_packets)
  File "/usr/local/lib/python2.7/dist-packages/paho/mqtt/client.py", line 1284, in loop_read
    rc = self._packet_read()
  File "/usr/local/lib/python2.7/dist-packages/paho/mqtt/client.py", line 1849, in _packet_read
    rc = self._packet_handle()
  File "/usr/local/lib/python2.7/dist-packages/paho/mqtt/client.py", line 2309, in _packet_handle
    return self._handle_pubrel()
  File "/usr/local/lib/python2.7/dist-packages/paho/mqtt/client.py", line 2529, in _handle_pubrel
    self._handle_on_message(self._in_messages[i])
  File "/usr/local/lib/python2.7/dist-packages/paho/mqtt/client.py", line 2647, in _handle_on_message
    self.on_message(self, self._userdata, message)
  File "/root/filereceiver.py", line 25, in on_message
    f.write(msg.payload)
AttributeError: 'TarFile' object has no attribute 'write'

Я бы не подумал, что MQTT имеет к этому какое-то отношение, что в моем скрипте чего-то не хватает?

EDIT:

Это код отправки. Он работает в том смысле, что может отправлять / получать байты, и при использовании с не-tar работает хорошо. Также возможно, что проблема здесь, а не в принимающем коде, хотя мне это кажется маловероятным.

import subprocess
import paho.mqtt.client as mqtt

def on_publish(mosq, userdata, mid):
    mosq.disconnect()

client = mqtt.Client()
client.connect("192.168.1.1", 1883, 60)
client.on_publish = on_publish


#output = subprocess.check_output(['ls', '-l', ])
#print(output)

ps = subprocess.Popen(('ls', '/new/backups/ready/'), stdout=subprocess.PIPE)
output = subprocess.check_output(('head', '-1'), stdin=ps.stdout)
ps.wait()
print(output)


filename = '/new/backups/ready/'+output.rstrip()
f=open(filename, "rb")
fileContent = f.read()
byteArr = "filename" +bytearray(fileContent)
client.publish("Updates",byteArr,2)

client.loop_forever()

1 Ответ

0 голосов
/ 17 мая 2018

Нет такого метода write() для tarfile.

В этом ответе показан используемый метод добавления, поэтому я предлагаю следовать этому шаблону.

TarFile.add(name, arcname=None, recursive=True, exclude=None, filter=None) Добавьте имя файла в архив. name может быть любым типом файла (каталог, fifo, символическая ссылка и т. д.). Если задано, arcname указывает альтернативное имя для файла в архиве. Каталоги добавляются рекурсивно по умолчанию. Этого можно избежать, установив рекурсивное значение в False. Если задано исключение, это должна быть функция, которая принимает один аргумент имени файла и возвращает логическое значение. В зависимости от этого значения соответствующий файл либо исключается (True), либо добавляется (False). Если указан фильтр, это должна быть функция, которая принимает аргумент объекта TarInfo и возвращает измененный объект TarInfo. Если вместо этого возвращается None, объект TarInfo будет исключен из архива. См. Примеры для примера.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...