Python Threading.timer() - python

I'm trying to perform a function after a time interval.
The time interval is controlled from Ftp server Notepad file.
The user updates notepad file which updates the time interval after some time.
But it is not working it reads the data from the notepad file on startup and the threading.timer use old time it doesn't update Code even the data in notepad file is changed by us
def Dataflow():
try:
ftp = FTP('Domain')
ftp.login('username', 'password')
ftp.cwd('/directory where notepad file is saved')
server_file='control.txt' #The Text file that will control the data flow
local_file=r'C:\Users\Public\flow.txt' #The Local location of file which will catch data
ftp.retrbinary('RETR ' + server_file , open(local_file, 'wb').write) # To download the Dataflow rate from the notepad in ftp server
local_file = open(r'C:\Users\Public\flow.txt','r')
temp_store = int(local_file.read(20)) #storing the data of notepad file in variable
local_file.close(); ftp.close()
return temp_store
except:
pass
def function():
do something
time = threading.timer(Dataflow(), function)
time.start()

Related

how can i update a python file by comparing it to a file hosted on my rasbery pi?

I am attempting to make a program update itself to the newest version that I have made. E.g. I added a new functionality to it. It would be useful for me to be able to upload the updated file to a central location like my Raspberry Pi and have the program update itself across all of my computers without updating each one individually.
I have made the bellow code, but it does not work. It can recognize when the file is up-to-date but running the new program it downloads fails, it successfully downloads and deletes itself, but the new program is not run, with no error messages being shown.
Update test.py:
#updaterV1.py
import time
import requests
import os
import hashlib
time.sleep(5)
cwd = os.getcwd()
URL = r"http://[rasberry pi's ip]/update%20files/dev/hash.txt"
hash_path = os.path.join(cwd,"remote hash.txt")
with open (hash_path, "wb") as f:
f.write(requests.get(URL).content)
with open(hash_path,"r") as hash_file:
remotehash = (hash_file.readline()).strip()
os.remove(hash_path)
hasher = hashlib.sha256()
with open(__file__, 'rb') as self_file:
selfunhashed = self_file.read()
hasher.update(selfunhashed)
selfhash = hasher.hexdigest()
print(selfhash)
print(remotehash)
if (selfhash == remotehash):
print("program is up to date")
input()
else:
update_path = os.path.join(cwd,"temp name update.py")
URL = r"http://[rasberry pi's ip]/update%20files/dev/update.py"
with open (update_path, "wb") as f:
f.write(requests.get(URL).content)
with open(update_path,"r") as f:
name = f.readline().strip()
name = name[1:] #use the 1st line as "#name.py" not "# name"
update_path = os.path.join(cwd,name)
try:
os.remove(update_path)
except:
pass
os.rename(os.path.join(cwd,"temp name update.py"),update_path)
os.system("python \""+update_path+"\"")
print("removing self file now")
os.remove(__file__)
It uses a separate TXT file with the hash of the program stored in the same folder to check the remote files hash without downloading the actual file to hash it locally.

write on FTP file without overwrite previous text ftplib python [duplicate]

I'm appending values to a log file every 6th second. Every 30 sec I'm transferring this log to an FTP server as a file. But instead of transfering the whole file, I just want to append the collected data to the file on my server. I haven't been able to figure out how to open the server file and then append the values.
My code so far:
session = ftplib.FTP(authData[0],authData[1],authData[2])
session.cwd("//"+serverCatalog()+"//") # open server catalog
file = open(fileName(),'rb')
with open(fileName(), 'rb') as f:
f = f.readlines()
for line in f:
collected = line
# In some way open server file, write lines to it
session.storbinary('STOR ' + fileName(), open(fileName(), 'a'), 1024)
file.close()
session.quit()
Instead, do I have to download the server file open and append, then send it back?
Above was my question, the full solution is below:
session.cwd("//"+serverCatalog()+"//") # open server catalog
localfile = open("logfile.txt",'rb')
session.storbinary('APPE serverfile.txt', localfile)
localfile.close()
Use APPE instead of STOR.
Source: http://www.gossamer-threads.com/lists/python/python/22960 (link to web.archive.org)

Writing to data in Python to a local file and uploading to FTP at the same time does not work

I have this weird issue with my code on Raspberry Pi 4.
from gpiozero import CPUTemperature
from datetime import datetime
import ftplib
cpu = CPUTemperature()
now = datetime.now()
time = now.strftime('%H:%M:%S')
# Save data to file
f = open('/home/pi/temp/temp.txt', 'a+')
f.write(str(time) + ' - Temperature is: ' + str(cpu.temperature) + ' C\n')
# Login and store file to FTP server
ftp = ftplib.FTP('10.0.0.2', 'username', 'pass')
ftp.cwd('AiDisk_a1/usb/temperature_logs')
ftp.storbinary('STOR temp.txt', f)
# Close file and connection
ftp.close()
f.close()
When I have this code, script doesn't write anything to the .txt file and file that is transferred to FTP server has size of 0 bytes.
When I remove this part of code, script is writing to the file just fine.
# Login and store file to FTP server
ftp = ftplib.FTP('10.0.0.2', 'username', 'pass')
ftp.cwd('AiDisk_a1/usb/temperature_logs')
ftp.storbinary('STOR temp.txt', f)
...
ftp.close()
I also tried to write some random text to the file and run the script, and the file transferred normally.
Do you have any idea, what am I missing?
After you write the file, the file pointer is at the end. So if you pass file handle to FTP, it reads nothing. Hence nothing is uploaded.
I do not have a direct explanation for the fact the local file ends up empty. But the strange way of combining "append" mode and reading may be the reason. I do not even see a+ mode defined in open function documentation.
If you want to both append data to a local file and FTP, I suggest your either:
Append the data to the file – Seek back to the original position – And upload the appended file contents.
Write the data to memory and then separately 1) dump the in-memory data to a file and 2) upload it.

How to loop through csv file in Python/Django

I created a management command and there I want to download the csv file from ftp and update the database if necessary.
The code that I have is as follows:
class Command(BaseCommand):
#staticmethod
def update_database(row):
code = row['CODE']
vat_number = row['BTWNR']
if code != "" and vat_number != "":
# pdb.set_trace()
print("Code: {0} --- BTW: {1}").format(code, vat_number)
def read_file(self):
path_to_relations_csv_file = "{0}/{1}".format(destination, file_name)
with open(path_to_relations_csv_file) as csvfile:
relations_reader = csv.DictReader(csvfile, delimiter=';')
for row in relations_reader:
self.update_database(row)
def handle(self, *args, **options):
# Open ftp connection
ftp = ftplib.FTP(ftp_host, ftp_username, ftp_password)
try:
ftp.cwd(source) # Goes to remote folder where the relations file is
os.chdir(destination) # Goes to local folder where the relations file will be downloaded
print("Switched to the directory successful. Current directory: {}".format(destination))
except OSError:
pass
except ftplib.error_perm:
print("Error: could not change to {0}".format(source))
sys.exit("Ending Application")
try:
# Get the file
relations = open(file_name, "wb") # Opens the remote file
ftp.retrbinary('RETR {0}'.format(file_name), relations.write) # Writes to the local file
print("File {0} downloaded successfully.".format(file_name))
relations.close() # Closes the local file
print("Local file closed.")
ftp.quit() # Closes the ftp connection
print("FTP Connection quited.")
try:
self.read_file()
except:
print("Error: Unable to read the file.")
except:
print("Error: File {0} could not be downloaded.".format(file_name))
But in read_file method the for loop gives me the error. If I place pdb.set_trace()before for loop I can see that relations_reader is <csv.DictReader object at 0x10e67a6a0>, thus it seems ok, but if I try to loop over it it goes to the except and it execute print("Error: Unable to read the file.")
The path are correct.
If the same code is executed as a separated file with python file_name.py and not as command with python manage.py file_name everything works fine.
Any idea what am I doing wrong?
The iterator should return strings, not bytes (did you open the file in text mode?) means you need to open the CSV in other ways, than the way you do.
To solve, change the opening mode, and the encoding, to the one it fits your csv file
open(path_to_relations_csv_file, "rt", encoding='utf-8') as csvfile:

Accesing a file in a ftp server

I have made a program, and there is a function where it gets a text file called news_2014.txt from a ftp server. I currently have this code:
def getnews():
server = 'my ftp server ip'
ftp= ftplib.FTP(server)
username = 'news2'
password = ' '
ftp.login(username,password)
filename = 'ftp://my ftp server ip/news/news_2014.txt'
path = 'news'
ftp.cwd(path)
ftp.retrlines('RETR' + filename, open(filename, "w").open)
I wanna make so the program displays the lines using readlines onto a Tkinter label. But if I try calling the top function, it says:
IOError: [Errno 22] invalid mode ('w') or filename: 'ftp://news/news_2014.txt'
RETR wants just the remote path name, not a URL. Similarly, you cannot open a URL; you need to pass it a valid local filename.
Changing it to filename = 'news_2014.txt' should fix this problem trivially.
The retrlines method retrieves the lines and optionally performs a callback. You have specified a callback to open a local file for writing, but that's hardly something you want to do for each retrieved line. Try this instead:
textlines = []
ftp.retrlines('RETR ' + filename, textlines.append)
then display the contents of textlines. (Notice the space between the RETR command and its argument, too.)
I would argue that the example in the documentation is confusing for a newcomer. Someone should file a bug report.

Categories