I've written a python script to run certain cron jobs and using crontab for the same.
Following is the code snippet:
import os
import inspect
from crontab import CronTab
def add_cron_job(scripts_list,frequency):
my_cron = CronTab(user='simrat')
for script in scripts_list:
if not cron_exists(my_cron,script):
command = 'python {}'.format(script)
job = my_cron.new(command=command, comment=script)
job.minute.every(frequency)
my_cron.write()
def cron_exists(my_cron, script):
for job in my_cron:
if job.comment == script:
return True
return False
if __name__ == "__main__":
#Frequency of every 1 minute
test_script = ['test1.py', 'test2.py']
add_cron_job(test_script,1)
#Frequency of every 1 day
test_script2 = ['test3.py']
add_cron_job(test_script2,1440)
Following is the output of 'crontab -e' (notice additional spaces added)
* * * * * python test1.py # test1.py
* * * * * python test2.py # test2.py
*/1440 * * * * python test3.py # test3.py
When I re-run the python cron_job script, it somehow disables the last cron_job(test3.py) and following is the output of crontab file:
* * * * * python test1.py # test1.py
* * * * * python test2.py # test2.py
# DISABLED LINE
# */1440 * * * * python test3.py # test3.py
*/1440 * * * * python test3.py # test3.py
along with an error it throws on console:
No handlers could be found for logger "crontab"
So my question is 3 fold:
Why is additional space at the top of the command when running my_cron.write()?
Why does it disable the last cron job instead of ignoring it as it already exists (def cron_exits should have taken care of that)
What's the signifance of the error thrown?
I ran you code and got following error in second run:
'1440', not in 0-59 for Minutes
I changed 1440 to 14 and ran code multiple times. And found same code every time (without deleting)
* * * * * python test1.py # test1.py
* * * * * python test2.py # test2.py
*/14 * * * * python test3.py # test3.py
I have not read complete CronTab code but it is clear that they have put some validator during reading existing cron commands but they are not validating it during writing.
Also i called add_cron_job with different arguments and found each time my_cron.write() is called it is adding a new line. This is not a bug but a feature.
Finally
No handlers could be found for logger "crontab" is logging issue. Try this Crontab Logger issue
Related
I would like to ask for help to modify/edit the mesh of a Part Instance (under Assembly).
I have tried (code below), but it is not possible because of the tuple:
mdb.models[modelName].rootAssembly.instances[instanceName].nodes[i].coordinates[0] = newCoordXYZ[0] # for x
mdb.models[modelName].rootAssembly.instances[instanceName].nodes[i].coordinates[1] = newCoordXYZ[1] # for y
mdb.models[modelName].rootAssembly.instances[instanceName].nodes[i].coordinates[2] = newCoordXYZ[2] # for z
TypeError: 'tuple' object does not support item assignment
Or, if possible, to directly add/assign the mesh (which is already stored in a variable - newCoordXYZ) to the geometry in the Assembly module!?
Any idea/suggestion is more than welcomed!
PS: I know that the modification of the mesh can be easily done in the Part Module (mesh dependent) with the editNode() command.
partName = mdb.models[modelName].parts[partName]
partName.editNode(nodes=partName.nodes,coordinates=newCoordXYZ)
EDIT 01:
comment
I'm not sure, I might make so trivial mistake.
I still obtain the following error: AttributeError: 'PartInstance' object has no attribute 'editNode', which is in agreement with the documentation:
The documentation says:
Abaqus > Scripting Reference > Python commands > Assembly commands > Assembly object:
Access
import assembly
mdb.models[name].rootAssembly
Abaqus > Scripting Reference > Python commands > Assembly commands > PartInstance object:
Access
import assembly
mdb.models[name].rootAssembly.allinstances
mdb.models[name].rootAssembly.instances[name]
and
Abaqus > Scripting Reference > Python commands > Edit mesh commands > Assembly object: editNode(...)
This method changes the coordinates of the given nodes on a part instance.
Abaqus > Scripting Reference > Python commands > Edit mesh commands > Part object
has no editNode(...) cmd
So, by using this cmd: mdb.models[name].rootAssembly.instances[name] I cannot use editNode()...
py code
################################## LIBRARY #############################
from datetime import date
from part import *
from material import *
from section import *
from assembly import *
from step import *
from interaction import *
from load import *
from mesh import *
from optimization import *
from job import *
from sketch import *
from visualization import *
from connectorBehavior import *
import regionToolset
import assembly
import visualization
import os
import datetime
import shutil
from odbAccess import *
import time
import numpy
import numpy as np
import re
import meshEdit
############### Add textFileName with new coord (+ imp )######################
fileNameImp = open("out_newCoordX_Imp.txt","r")
impVect = fileNameImp.readlines()
fileNameImp.close()
####################### Add modelName and instanceName #######################
modelName = 'Model-1'
instanceName = 'Part-1-1'
assemblyInstance = mdb.models[modelName].rootAssembly.instances[instanceName]
newCoordXYZ = numpy.zeros((len(assemblyInstance.nodes),3))
for i in assemblyInstance.nodes:
newCoordXYZ[i.label-1][0] = float(impVect[i.label-1])
newCoordXYZ[i.label-1][1] = i.coordinates[1]
newCoordXYZ[i.label-1][2] = i.coordinates[2]
assemblyInstance.editNode(nodes=assemblyInstance.nodes,coordinates=newCoordXYZ)
The same way you do it for the part, you should do it for assembly instance:
assemblyInstance = mdb.models[modelName].rootAssembly.instances[instanceName]
assemblyInstance.editNode(nodes=assemblyInstance.nodes,coordinates=newCoordXYZ)
Make sure to make your instance independent!
I have made a file named updatefield.py content is
from FrontEnd.views import UpdateField
def my_scheduler():
# add logic
UpdateField()
I have put it inside my project root with manage.py file
And my settings.py file is like
CRONJOBS = [
('* * * * *', 'Ravi.updatefield.my_scheduler')
]
Installed apps
'django_cron',
'django_crontab',
After executing command python manage.py crontab add I got
adding cronjob: (33083f0c14f7cccdc5851431976adcbb) -> ('* * * * *', 'Ravi.updatefield.my_scheduler')
But its not running Right now . And noting is appearing on my terminal my function is this
def UpdateField(request):
print('hi')
return HttpResponse('hello world')
The following works as expected:
python /usr/share/str8RED/manage.py getLiveResults
However, nothing happens when I use the following cronjob:
*/1 * * * * python /usr/share/str8RED/manage.py getLiveResults
Using the link below I have managed to create a error log:
http://matthewwittering.com/blog/django-tips/running-a-django-management-commands-with-crontab.html
This informs me that:
Traceback (most recent call last):
File "/usr/share/str8RED/manage.py", line 8, in <module>
from django.core.management import execute_from_command_line
ImportError: No module named django.core.management
I can get cronjab working and running every minute with echo "Hello World". Any help would be appreciated, many thanks, Alan.
Contents of getLiveResults.py:
from django.core.management import BaseCommand
from straightred.models import StraightredTeam
from straightred.xmlsoccer import XmlSoccer
#The class must be named Command, and subclass BaseCommand
class Command(BaseCommand):
# Show this when the user types help
help = "My test command"
# A command must define handle()
def handle(self, *args, **options):
xmlsoccer = XmlSoccer(api_key='XYZ', use_demo=False)
teams = xmlsoccer.call_api(method='GetAllTeamsByLeagueAndSeason',
seasonDateString='1617',
league='English League Championship')
numberOfTeamsUpdated = 0
for team in teams:
if '{http://xmlsoccer.com/Team}Team_Id' in team.keys():
teamUpdate = StraightredTeam(teamid=team['{http://xmlsoccer.com/Team}Team_Id'],
teamname=team['{http://xmlsoccer.com/Team}Name'],
country=team['{http://xmlsoccer.com/Team}Country'],
stadium=team['{http://xmlsoccer.com/Team}Stadium'],
homepageurl=team['{http://xmlsoccer.com/Team}HomePageURL'],
wikilink=team['{http://xmlsoccer.com/Team}WIKILink'],
currentteam=1)
teamUpdate.save()
numberOfTeamsUpdated = numberOfTeamsUpdated + 1
self.stdout.write("Hello world!")
If you are using virtual env, then you need to activate the environment,
maybe something like:
*/1 * * * * /usr/share/str8RED/.env/bin/python /usr/share/str8RED/manage.py getLiveResults
I need to run this file:
from apps.base.models import Event
from apps.base.models import ProfileActiveUntil
from django.template import Context
from django.db.models import Q
import datetime
from django.core.mail import EmailMultiAlternatives
from bonzer.settings import SITE_HOST
import smtplib
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from bonzer.settings import send_mail, BONZER_MAIL, BONZER_MAIL_SMTP, BONZER_MAIL_USER, BONZER_MAIL_PASS, BONZER_MAIL_USETLS
today = datetime.date.today()
monthAgo = today + datetime.timedelta(days=1)
monthAgoMinusOneDay = today + datetime.timedelta(days=2)
events = Event.objects.all()
ProfileActiveUntils = ProfileActiveUntil.objects.filter(Q(active_until__range=(monthAgo, monthAgoMinusOneDay)))
msg = MIMEMultipart('alternative')
msg['Subject'] = "Novim dogodivscinam naproti"
msg['From'] = BONZER_MAIL
msg['To'] = 'jjag3r#gmail.com'
text = u'bla'
html = u'bla'
send_mail(msg_to=msg['To'], msg_subject=msg['Subject'], msg_html=html, msg_text=text)
I execute it like this: */2 * * * * /usr/local/bin/python2.7 /home/nezap/webapps/bonzer/bonzer/apps/base/alert.py
But I get error: No module named apps.base.models.
Important fact is that I can't install virtualenv on server because I don't have permissions. Also I'm kind of newbie on this stuff so I don't have a lot of skills on servers or python.
Thank you.
cron does not read rc shell files so you need to define the enviroment variable PYTHONPATH to include the location of the apps package and all other module files that are required by the script.
PYTHONPATH=/usr/local/lib/python2.7:/usr/lib/python2.7
*/2 * * * * /usr/local/bin/python2.7 /home/nezap/webapps/bonzer/bonzer/apps/base/alert.pyr
I would assume this is a problem with your cwd (current working directory). An easy way to test this would be to go to the root (cd /) then run:
python2.7 /home/nezap/webapps/bonzer/bonzer/apps/base/alert.py
You should get the same error. The path you will want to use will depend on the place where you normally run the script from. I would guess it would either be:
/home/nezap/webapps/bonzer/bonzer/apps/base
or
/home/nezap/webapps/bonzer/bonzer/
So your solution would either be:
*/2 * * * * cd /home/nezap/webapps/bonzer/bonzer/apps/base && /usr/local/bin/python2.7 ./alert.py
or
*/2 * * * * cd /home/nezap/webapps/bonzer/bonzer && /usr/local/bin/python2.7 ./apps/base/alert.py
basically you are telling cron to change directory to that path, then if that works(the &&) run the following command.
How Would i Go About Adding a File To launch when it see that's it's the due_date? I've try'd quite i few different method's from Google but i'm still having a hard time figuring it out. currently it's set to wait 36 hours after launching the .py file.
any help would be great and it'd get this monkey off my back for good!
import datetime
import croniter
import crontab
import time
c = croniter.croniter("0 9,10,11 * * TUE")
next_due_date = c.get_next(datetime.datetime)
while True:
now = datetime.datetime.now()
if now > next_due_date:
do_something(line.py)
time.sleep(60 * 60 * 36)
else:
time.sleep(60 * 60 * 2)
If it's a .exe you can just use os.system("myexecutable.exe") after launching the python
import datetime
import croniter
import crontab
import time
c = croniter.croniter("0 9,10,11 * * TUE")
next_due_date = c.get_next(datetime.datetime)
while True:
now = datetime.datetime.now()
if now > next_due_date:
do_something(line.py) # Edit: fixed tabbing; just in case it wasn't tabbed in
# your script
# Use os.system to run the exe
os.system("myexecutable.exe")
time.sleep(60 * 60 * 36)
else:
time.sleep(60) # Edit: I always find that it's better to have a smaller
# sleep time
You can also use the subprocess module so you can halt the script or track if the exe is still running instead.