automate actions with cron and the new api odoo - cron

I want to automate an action and here is the code that I'm using:
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data noupdate="1">
<record id="ir_cron_scheduler_demo_action" model="ir.cron">
<field name="name">Demo scheduler</field>
<field name="user_id" ref="base.user_root"/>
<field name="interval_number">2</field>
<field name="interval_type">minutes</field>
<field name="numbercall">-1</field>
<field eval="False" name="doall"/>
<field eval="'note.admin'" name="model"/>
<field eval="'process_demo_scheduler_queue'" name="function"/>
</record>
</data>
</openerp>
#api.model
def process_demo_scheduler_queue(self):
for note in self.env['note.admin']:
if datetime.strptime(note.date, DEFAULT_SERVER_DATETIME_FORMAT).date() == datetime.now().date():
note.write({'is_visible': True})
What I want to do is to set the value is_visible on True when the field note.date == current date
here is the log on server:
2016-05-25 01:20:17,658 3680 INFO test3 werkzeug: 127.0.0.1 - -
[25/May/2016 01:20:17] "POST
/web/dataset/call_kw/note.admin/message_get_subscription_data
HTTP/1.1" 200 -
but it is not working!
SOLVED:
#api.model
def process_demo_scheduler_queue(self):
notes = self.search([('date', '=', fields.Date.today())])
notes.write({'is_visible': True})

You have to write like below code,
#api.model
def process_demo_scheduler_queue(self):
for note in self.env['note.admin'].search([]):
if datetime.strptime(note.date, DEFAULT_SERVER_DATETIME_FORMAT).date() == datetime.now().date():
note.write({'is_visible': True})

First you have to search for all notes in your database, and second try to use odoo's date logic:
#api.model
def process_demo_scheduler_queue(self):
for note in self.search([]):
if note.date == openerp.fields.Date.context_today(self):
note.is_visible = True
Or maybe faster:
#api.model
def process_demo_scheduler_queue(self):
notes = self.search([('date', '=', openerp.fields.Date.context_today(self))])
notes.write({'is_visible': True})

Related

Parsing XML to text file using python

I have a source section in an XML from which I am trying to fetch the values in this way to a text file.
source1, ipset-1, IPSet, true
source2, ipset-2, IPSet, true
XML section:
<sources excluded="false">
<source>
<name>source1</name>
<value>ipset-1</value>
<type>IPSet</type>
<isValid>true</isValid>
</source>
<source>
<name>source2</name>
<value>ipset-2</value>
<type>IPSet</type>
<isValid>true</isValid>
</source>
</sources>
Currently, my code gives me everything in one line.
import xml.etree.ElementTree as ET
tree = ET.fromstring(xml_file)
for node in tree.iter('source'):
print('\n')
with open("source.txt", "a") as file:
for elem in node.iter():
if not elem.tag==node.tag:
file.write("{},".format(elem.text))
print("{}: {}".format(elem.tag, elem.text))
A solution using beautifulsoup:
from bs4 import BeautifulSoup
xml_doc = """
<sources excluded="false">
<source>
<name>source1</name>
<value>ipset-1</value>
<type>IPSet</type>
<isValid>true</isValid>
</source>
<source>
<name>source2</name>
<value>ipset-2</value>
<type>IPSet</type>
<isValid>true</isValid>
</source>
</sources>
"""
soup = BeautifulSoup(xml_doc, "lxml")
with open("source.txt", "w") as f_out:
for tag in soup.select("source"):
print(",".join(t.text for t in tag.select("*")), file=f_out)
Creates source.txt:
source1,ipset-1,IPSet,true
source2,ipset-2,IPSet,true

'list' object has not attribute 'get' Python3.8 while getting info from XML

So I'm trying to extract info from an XML file but I keep getting this error:
AttributeError: 'list' object has no attribute 'get'
My Code:
from xml.etree import ElementTree as ET
file = ET.parse('db1.xml')
drug = file.findall('drugbank/drug/products')
f = []
for x in drug:
f.append(x.text)
return f
My XML:
<?xml version="1.0" encoding="UTF-8"?>
<drugbank xmlns="http://www.drugbank.ca" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.drugbank.ca http://www.drugbank.ca/docs/drugbank.xsd" version="5.1" exported-on="2019-07-02">
<drug type="biotech" created="2005-06-13" updated="2019-06-04">
<products>
<product>
<name>Refludan</name>
<labeller>Bayer</labeller>
<ndc-id/>
<ndc-product-code/>
<dpd-id>02240996</dpd-id>
<ema-product-code/>
<ema-ma-number/>
<started-marketing-on>2000-01-31</started-marketing-on>
<ended-marketing-on>2013-07-26</ended-marketing-on>
<dosage-form>Powder, for solution</dosage-form>
<strength>50 mg</strength>
<route>Intravenous</route>
<fda-application-number/>
<generic>false</generic>
<over-the-counter>false</over-the-counter>
<approved>true</approved>
<country>Canada</country>
<source>DPD</source>
</product>
</products>
</drug>
</drugbank>
I also tried using drug = file.findall('drugbank/drug/products/name') instead of drug = file.findall('drugbank/drug/products') but it still gave the same error.
I found the issue . Use this code to get the names of your products :
import xml.etree.ElementTree as ET
xml_str = '''<?xml version="1.0" encoding="UTF-8"?>
<drugbank xmlns="http://www.drugbank.ca" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.drugbank.ca http://www.drugbank.ca/docs/drugbank.xsd" version="5.1" exported-on="2019-07-02">
<drug type="biotech" created="2005-06-13" updated="2019-06-04">
<products>
<product>
<name>Refludan</name>
<labeller>Bayer</labeller>
<ndc-id/>
<ndc-product-code/>
<dpd-id>02240996</dpd-id>
<ema-product-code/>
<ema-ma-number/>
<started-marketing-on>2000-01-31</started-marketing-on>
<ended-marketing-on>2013-07-26</ended-marketing-on>
<dosage-form>Powder, for solution</dosage-form>
<strength>50 mg</strength>
<route>Intravenous</route>
<fda-application-number/>
<generic>false</generic>
<over-the-counter>false</over-the-counter>
<approved>true</approved>
<country>Canada</country>
<source>DPD</source>
</product>
</products>
</drug>
</drugbank>
'''
root = ET.fromstring(xml_str)
# print(root.findall('{http://www.drugbank.ca}drug'))
ns = {'drug_bank': 'http://www.drugbank.ca'}
for drug in root.findall('drug_bank:drug', ns):
for products in drug.findall('drug_bank:products', ns):
for product in products.findall('drug_bank:product', ns):
for nametag in product.findall('drug_bank:name', ns):
print(nametag.text)
Output : Refludan
Explanation :
First I printed root and got this :
<Element '{http://www.drugbank.ca}drugbank' at 0x7f688ffc0770>
So I realised this was Namespace-XML-pattern to be used.
Here is the link to help you understand the topic - https://docs.python.org/3/library/xml.etree.elementtree.html#parsing-xml-with-namespaces

Python 2.7 to 3.6 Code porting issue --copying xml data to list

emphasized textHi , I am currently Porting a Piece of code from python 2.7 to python 3.6 , The Code involves dumping data from xml into a list the codes looks as below
import os
import xml.etree.ElementTree as ET
regs_list = []
tree = ET.parse("test.xml")
root = tree.getroot()
for reg in root:
regs_list.append(reg)
for i in range(len(regs_list)):
print (regs_list[i].attrib["name"])
if not (regs_list[i].find("field") == None):
for regs_list[i].field in regs_list[i]:
print (regs_list[i].field.attrib["first_bit"])
The XML looks like this
<register offset="0x4" width="4" defaultValue="0x100000" name="statuscommand" desc="STATUSCOMMAND- Status and Command ">
<field first_bit="30" last_bit="31" WH="ROOO" flask="0xc0000000" name="reserved0" desc=""/>
<field first_bit="29" last_bit="29" WH="1CWRH flask="0x20000000" name="rma" desc=""/>
<field first_bit="28" last_bit="28" WH="1CWRH flask="0x10000000" name="rta" desc=""/>
</register>
<register offset="0x8" width="4" defaultValue="0x8050100" name="reve" desc="REVCLASSCODE - Revision ID and Class Code">
<field first_bit="8" last_bit="31" WH="ROOO" flask="0xffffff00" name="class_codes" desc=""/>
<field first_bit="0" last_bit="7" WH="ROOO" flask="0xff" name="rid" desc=""/>
</register>
This Code works perfectly fine in python 2.7 , we are able to dump both parent (Register) and child (field) into the list regs_list , But in 3.6 we get an error as below
3.6 output "
for regs_list[i].field in regs_list[i]:
AttributeError: 'xml.etree.ElementTree.Element' object has no attribute 'field'
2.7 output
Parent and child parsed and dumped in the list without error
Is there a difference in the way xml.etree.ElementTree.Element and lists work in 3.6 and 2.7 ??

Caught: java.lang.StackOverflowError JsonBuilder closure

I've been trying to read an xml file and convert it to json using groovy's JsonBuilder. The problem is that when I print with
def builder = new JsonBuilder(jsonObject)
println builder.toPrettyString()
I got a Caught: java.lang.StackOverflowError
Here is the whole stacktrace
Exception in thread "main" java.lang.StackOverflowError
at groovy.json.JsonOutput.writeObject(JsonOutput.java:259)
at groovy.json.JsonOutput.writeIterator(JsonOutput.java:442)
at groovy.json.JsonOutput.writeObject(JsonOutput.java:272)
at groovy.json.JsonOutput.writeIterator(JsonOutput.java:442)
at groovy.json.JsonOutput.writeObject(JsonOutput.java:272)
at groovy.json.JsonOutput.writeIterator(JsonOutput.java:442)
at groovy.json.JsonOutput.writeObject(JsonOutput.java:272)
at groovy.json.JsonOutput.writeIterator(JsonOutput.java:442)
at groovy.json.JsonOutput.writeObject(JsonOutput.java:272)
at groovy.json.JsonOutput.writeIterator(JsonOutput.java:442)
at groovy.json.JsonOutput.writeObject(JsonOutput.java:272)
at groovy.json.JsonOutput.writeIterator(JsonOutput.java:442)
at groovy.json.JsonOutput.writeObject(JsonOutput.java:272)
at groovy.json.JsonOutput.writeIterator(JsonOutput.java:442)
Here the code.
package firstgroovyproject
import groovy.json.JsonBuilder
class XmlToJsonII {
static void main(def args){
def carRecords = '''
<records>
<car name='HSV Maloo' make='Holden' year='2006'>
<countries>
<country>
Austria
</country>
<country>
Spain
</country>
</countries>
<record type='speed'>Production Pickup Truck with speed of 271kph
</record>
</car>
<car name='P50' make='Peel' year='1962'>
<countries>
<country>
Monaco
</country>
</countries>
<record type='size'>Smallest Street-Legal Car at 99cm wide and 59 kg
in weight</record>
</car>
<car name='Royale' make='Bugatti' year='1931'>
<record type='price'>Most Valuable Car at $15 million</record>
<countries>
<country>
Italia
</country>
</countries>
</car>
<car name='Seat' make='Ibiza' year='1985'>
<record type='price'>barato</record>
<countries>
<country>
Spain
</country>
</countries>
</car>
</records>
'''
def xmlRecords = new XmlSlurper().parseText(carRecords)
def jsonObject = [:]
jsonObject.records = []
def records = jsonObject.records
xmlRecords.car.each {xmlCar ->
records.add([
countries:
xmlCar.countries.children().each{ country ->
println "country : ${country.text()}"
[country: country.text()]
},
])
}
def builder = new JsonBuilder(jsonObject)
println builder.toPrettyString()
//println builder.toString()
}
}
tl;dr: Your second (inner) each should be a collect instead.
The real answer: The return value of each is the original Iterable that invoked it. In this case that would be the XML object collection defined by the expression xmlCar.countries.children(). Since the objects in that collection contain references back to their own parents your JSON build causes an infinite regress that results in a stack overflow.
This doesn't happen with your first (outer) use of each, because you are not using the return value. Instead you are adding to a preexisting list (records).
By changing the second (inner) each into a collect, you are still iterating through the children of the countries elements. However, instead of returning the original XML children (the result of each) you are compiling and returning a list of maps of the form [country:"country_string_from_xml"], which seems to be the desired behavior.
Confusing each and collect is a common rookie mistake in Groovy... which only made it all the more galling when it happened to ME last week. :-)

Groovy - Use XmlSlurper with a dynamic path

Is it possible to access a node of Xml using an arbitary path?
Eg: Given the xml:
<records>
<bike name='Chopper' />
<car name='HSV Maloo' make='Holden' year='2006'>
<country>Australia</country>
<record type='speed'>Production Pickup Truck with speed of 271kph</record>
</car>
<car name='P50' make='Peel' year='1962'>
<country>Isle of Man</country>
<record type='size'>Smallest Street-Legal Car at 99cm wide and 59 kg in weight</record>
</car>
</records>
How do I access the contents of the xml using an arbitrary path, provided as a string -- eg:
XmlSlurper xml = new XmlSlurper.parse(theXml)
assert xml['bike.#name'] == 'Chopper'
assert xml['car[0].country'] == 'Australia'
One method is to use the Eval.x static method to evaluate a String;
def xml = '''| <records>
| <bike name='Chopper' />
| <car name='HSV Maloo' make='Holden' year='2006'>
| <country>Australia</country>
| <record type='speed'>Production Pickup Truck with speed of 271kph</record>
| </car>
| <car name='P50' make='Peel' year='1962'>
| <country>Isle of Man</country>
| <record type='size'>Smallest Street-Legal Car at 99cm wide and 59 kg in weight</record>
| </car>
| </records>'''.stripMargin()
// Make our GPathResult
def slurper = new XmlSlurper().parseText( xml )
// Define our tests
def tests = [
[ query:'bike.#name', expected:'Chopper' ],
[ query:'car[0].country', expected:'Australia' ]
]
// For each test
tests.each { test ->
// assert that we get the expected result
assert Eval.x( slurper, "x.$test.query" ) == test.expected
}

Resources