Create DOORS attribute for section heading - scripting

How can I create a DOORS attribute “SectionHeading” to display the section number + title that an object falls under?
Example (each line here is a DOORS object):
Section 3.1 XXX Requirements
Req100 System shall do this… (where this object is under Section 3.1 in DOORS)
Section 3.1.1 YYY Sub-requirements
Req234 System shall do this sub-thing…. (where this object is under Section 3.1.1)
Req368 System shall do this other sub-thing… (where this object is also under Section 3.1.1)
Section 3.1.1.1 ZZZ Sub-requirements
Req555 System shall do this sub-thing….(where this object is under Section 3.1.1.1)
Req123 System shall do this other sub-thing… (where this object is under Section 3.1.1.1)
Req580 System shall do this other sub-thing… (where this object is under Section 3.1.1.1)
I want to create an attribute called “SectionHeading” to show:
Req100, SectionHeading: “3.1 XXX Requirements”
Req234, SectionHeading: “3.1.1 YYY Sub-requirements”
Req368, SectionHeading: “3.1.1 YYY Sub-requirements”
Req555, SectionHeading: “3.1.1.1 ZZZ Sub-requirements”
Req123, SectionHeading: “3.1.1.1 ZZZ Sub-requirements”
Req580, SectionHeading: “3.1.1.1 ZZZ Sub-requirements”
I don’t want to create links within a module from an object to its section header (though this would probably give me what I need).

You need to create a DXL attribute and the code should look like this:
Object o = parent(obj)
if(!null o)
{
obj."NAME_OF_YOUR_ATTRIBUTE" = number(o) " " o."Object Heading" ""
}

Related

Form and process list of string with Lua plugin on very old Lua 2.5

I'm trying to write lua plugin to extract and place some metadata from HTML page. It's a plugin for soupault static site generator and it requires lua version 2.5 for work. So no closures and no for loops in particular.
It is no sense to load you how this generator works because plugin exists as a small standalone file .lua and plugs in during the running of generator.
What is significant are the methods used by the plugin. These are used at the input and output of the plugin.
And more importantly, it is how to form and process the list of extracted tags with lua language.
Input data in the body of html page:
<site-meta-data>
#+title: post 1 title
#+subtitle: Post 1 subtitle
#+description: Post 1 decription
#+author: Billy
#+date: 2021-11-03
#+datepublished: 2021-06-02
#+usertags: inventory,errand
#+summary: Post 1 summary
#+id: 1-test1com
</site-meta-data>
And these are steps that plugin should take:
get strings between <site-meta-data></site-meta-data> tags into the
list get string from the list & split by first colon eg.
string.match(destination_number, "(.-):"))
create variable name as first word before colon and without #+ (eg. title)
create conditions for the next operation on this variable. If variable name which is
created from the string = current name, eg. meta_tag = title, insert
metatag with value or insert new tag with extracted value after
parent tag. I'll write by myself which tags should be inserted.
after processing of the list remove all between <site-meta-data></site-meta-data> including
itself.
As being near zero in lua scripting I just wrote the scratch of the script.
all_meta_tags = HTML.select_one(page, "site-meta-data")
all_meta_tags = HTML.parse(page, "site-meta-data")
print(all_meta_tags)
local index = 1
while all_meta_tags[index] do
meta_tag_line = all_meta_tags[index]
meta_tag = string.match(meta_tag_line, "(.-):")
meta_tag_content = string.match(meta_tag_line, ":(.*)")
meta_tag_content = strlower(String.trim(meta_tag_content))
meta_tag = Regex.replace(meta_tag, "#+", "")
if (meta_tag == "title") then
HTML.append_child(page, HTML.create_string('<meta name="title" content="value..">'))
elseif (meta_tag == 'subtitle') then
HTML.append_child(page, HTML.create_string('...'))
elseif (meta_tag == 'description') then
HTML.append_child(page, HTML.create_string('<meta name="description" content="meta_tag_value">'))
elseif (meta_tag == 'author') then
HTML.append_child(page, HTML.create_string('author...'))
elseif (meta_tag == 'date') then
HTML.append_child(page, HTML.create_string('<meta name="date" content="meta_tag_content">'))
end
index = index + 1
end
HTML.delete(HTML.select_one(page, "site-meta-data"))
Please, help me to modify the script to accomplish the above task. I'll correct what tags it should place.
Since version 4.0 soupault supports a pre-parse hook. So it's now possible to reimplement various types of front matter with that hook. The plugin should always put the rendered HTML before the page body. Plugin can be written as this example.
[hooks.pre-parse]
file = "hooks/org-mode-metadata.lua"
template = """
<h1 id="post-title">{{title}}</h1>
...

Override translation from original module

How can I override translation of default_code field?
in inherited Product Template and Product Product, I added fields
default_code = fields.Char(
string='Articul',
related='product_variant_ids.default_code')
and
default_code = fields.Char(
'Articul', select=True)
string changes in the English version but if I change to my language then I get an original translation.
So i tried to copy a part from original modules translation and add it to my po file like this.
#. module: product
#: model:ir.model.fields,field_description:product.field_product_product_default_code
#: model:ir.model.fields,field_description:product.field_product_template_default_code
msgid "Articul"
msgstr "Articulas"
it works but when I want to update my file with Poedit I getting an error
2018 m. liepos 30 d. 15:43:37: /tmp/poedituUNIro/1input.po:1023: duplicate message definition...
2018 m. liepos 30 d. 15:43:37: /tmp/poedituUNIro/1input.po:169: ...this is the location of the first definition
2018 m. liepos 30 d. 15:43:37: msgmerge: found 1 fatal error
2018 m. liepos 30 d. 15:43:37: Entries in the catalog are probably incorrect.
2018 m. liepos 30 d. 15:43:37: Updating the catalog failed. Click on 'Details >>' for details.
No need to redeclare the field string!
Export the translation file from the add-ons you want to override.
Translate it using POEeit or similar.
Drop the translation file inside a i18n_extra folder in the addon. E.g.: addon/i18n_extra/fr.pot
Update the addon.
With that system, a submodule is able to override translations from parent modules.

Show whether a module has or not at least 1 baseline

I have a folder with a bunch of formal modules and I want to know which ones have at least 1 baseline. I started trying something like this:
Item icurr
Folder scr = current Folder
Baseline b = baseline(1, 0, null)
for icurr in scr do
{
if( baselineExists(icurr, b) )
{
print name(icurr)
}
}
The problem with this code is that baselineExists() only accepts a Module object as first parameter and when I declare icurr to Module instead of Item the for loop this does not recognize any module.
I think that it easiest to use the for baseline in module loop.
Loop through all your items, either with using for item in folder (Items in sub-folders are not included, you will need a recursive function that loops through all found folders) or using for item in project (which will automatically traverse recursively all contained folders and projects).
For every item, check if it is a (formal) module using if 'Formal' == type i then {}. If so, get a module variable from the item. Usually, I do this using Module m = read (fullName i, false, true); if !null m then....
Then, when you have opened the module, use code like
Baseline b = null
for b in m do {break} // stop loop at first found baseline
if (!null b) {
print "found a baseline in module " fullName(m) ": " major(b) "." minor(b) " ("suffix(b)")\n"
}
Don't forget to close each module after the evaluation or the script will use a lot of memory

QTP Unable to differentiate Web Table in Application

I am a beginner in QTP and I am working on an application where there are two different web tables displayed.
The second web table is detail description of the first web table so it displays when we select a row in the first web table.
In other words, Each row in the first table is selectable and when selected corresponds to the second web table
Web table 1 contains something like below for a user
RelationShip | Name
Father | AAA
Mother | BBB
Brother | CCC
Sister | DDD
Sister2 | EEE
Web Table 2 Contains detailed information for each row in Web Table 1 as I earlier mentioned. SO for Father, the below table is reflected
Details
Name | AAA
Age | 50
Relationship | Father
and so on
Second User might/might not have brother/sister.
The problem now I am facing is retrieving data from second web table for different entity of first one since all the property of the web table are similar expect the below property
"html ID" which corresponds to - "DetailParty_randomno"
This random number is the one which defines the uniqueness of the second web table, which can be retrieved from the first web table though it isn't found in the properties section when we use the Object spy.
I can see this random number when I view the source code of the page. It's displayed as value entity in the tr tag
Value entity looks like "Party_randomno"
<tr style="background-color:yellow" value="Party_1" onclick="Call peoplehighlight("Party_1")" language="vbscript">
My question is if there a way to retrieve this value for each row and then use it in identifying the second web table?
However I did try to read from second table by hard coding "html id" in webtable property to see if it's being read but it didn't work
So my second question is with respect to the correctness of the below descriptive programming code. Is there something else I need to include/exclude in the WebTable property to find uniqueness.
I also did my research and found that it's useful to use index but I am not aware on how to find the index of a web table? Also the index changes for each user I am searching and hence I need to find the index of the table during run time before using it
BrowserName = Browser("micClass:=Browser").GetROProperty("name")
PageName= Browser("micClass:=Browser").Page("micClass:=Page")GetROProperty("name")
Set desc = Description.Create()
desc("html tag").Value = "tr"
Set Rows = Browser("B").Page("P").Webtable("WT").ChildObjects(desc)
RoCounter = Rows.Count-1
For valuecount = 0 To RoCounter
id= rows(i).Object.GetAttribute("value")
Next
'When the right ID is got, parsing it in the below for WT2 Identification
Set ObjTable = Browser("name:="&Browsername).Page("name:="& Pagename).WebTable("class:=Web_Table", "html id:=Detail"&id)
Update
I was able to get the value from the source code using Motti's code. needed to tweak a little and my descriptive programming had spaces between name and : so the objetct wasn't being recognized. It's solved now.
When looking at the description you gave to your WebTable I find it hard to see what you're trying to achieve. class in QTP is mapped to the html className property are you sure that Web_Table is correct className? Also there is (AFAIK) no class name property in QTP, if you mean the test object type then there's no need to add it since you already said that the object is a WebTable.
To answer your question, in order to add indexing you just add "index:=1" to the smart identification (or in the description if you're using the object repository), note that index is zero based so 1 is the second object that matches the description (if there are more than one, if there is only one the index is ignored).
In order to get the random number you can try something like this (untested)
Set desc = Description.Create()
desc("html tag").Value = "tr"
Set rows = Browser("B").Page("P").WebTable("T").ChildObjects(desc)
For i = 0 To rows.Count - 1
id = rows(i).GetROProperty("value") ' Or whatever you need here
Next

What would be the best way to parse this file?

I was just wondering if anyone knew of a good way that I could parse the file at the bottom of the post.
I have a database setup with the correct tables for each section eg Refferal Table,Caller Table,Location Table. Each table has the same columns that are show in the file below
I would really like something that is fairly genetic so if the file layout changes it won't mess me around to much. At the moment I am just reading the file in a line at a time and just using a case statement to check which section i'm in.
Is anyone able to help me with this?
PS. I am using VB but C# or anything else will be fine, also the x's in the document are just personal info I have blanked
Thanks,
Nathan
File:--->
DIAL BEFORE YOU DIG
Call 1100, Fax 1300 652 077
PO Box 7710 MELBOURNE, VIC 8004
Utilities are requested to respond within 2 working days and reference the Sequence number.
[REFFERAL DETAILS]
FROM= Dial Before You Dig - Web
TO= Technical Services
UTILITY ID= xxxxxx
COMPANY= {Company Name}
ENQUIRY DATE= 02/10/2008 13:53
COMMENCEMENT DATE= 06/10/2008
SEQUENCE NO= xxxxxxxxx
PLANNING= No
[CALLER DETAILS]
CUSTOMER ID= 403552
CONTACT NAME= {Name of Contact}
CONTACT HOURS= 0
COMPANY= Underground Utility Locating
ADDRESS= {Address}
SUBURB= {Suburb}
STATE= {State}
POSTCODE= 4350
TELEPHONE= xxxxxxxxxx
MOBILE= xxxxxxxxxx
FAX TYPE= Private
FAX NUMBER= xxxxxxxxxx
PUBLIC ADDRESS= xxxxxxxxxx
PUBLIC TELEPHONE=
EMAIL ADDRESS= {Email Address}
[LOCATION DETAILS]
ADDRESS= {Location Address}
SUBURB= {Location Suburb}
STATE= xxx
POSTCODE= xxx
DEPOSITED PLAN NO= 0
SECTION & HUNDRED NO= 0
PROPERTY PHONE NO=
SIDE OF STREET= B
INTERSECTION= xxxxxx
DISTANCE= 0-200m B
ACTIVITY CODE= 15
ACTIVITY DESCRIPTION= xxxxxxxxxxxxxxxxxx
MAP TYPE= StateGrid
MAP REF= Q851_63
MAP PAGE=
MAP GRID 1=
MAP GRID 2=
MAP GRID 3=
MAP GRID 4=
MAP GRID 5=
GPS X COORD=
GPS Y COORD=
PRIVATE/ROAD/BOTH= B
TRAFFIC AFFECTED= No
NOTIFICATION NO= 3082321
MESSAGE= entire intersection of Allora-Clifton rd , Hillside
rd and merivale st
MOCSMESSAGE= Digsafe generated referral
Notice: Please DO NOT REPLY TO THIS EMAIL as it has been automatically generated and replies are not monitored. Should you wish to advise Dial Before You Dig of any issues with this enquiry, please Call 1100
(See attached file: 3082321_LLGDA94.GML)
Google has the answers, once you know that the file-format is called '.ini'
Edit: That is, it's an .ini plus some extra leading/trailing gunk.
You could read each line of the file sequentially. Each line is essentially a name value pair. Place each value in a map (hash table) keyed by name. Use a map for each section. When done parsing the file you'll have maps containing all the name value pairs. Iterate over each map and populate your database tables.
I would head to Python for any type of string parsing like this. I'm not sure how much of this information you want to retain, but I would perhaps use Python's split() function to split on = to get rid of the equals sign, then strip the whitespace out of the second piece of the pie.
First, I would mask out the header/footer info I know I don't need, then do something akin to the following:
Let's take a chunk and save it in test1.txt:
ADDRESS= {Location Address}
SUBURB= {Location Suburb}
STATE= xxx
POSTCODE= xxx
DEPOSITED PLAN NO= 0
SECTION & HUNDRED NO= 0
PROPERTY PHONE NO=
Here's a small python snippet:
>>> f = open("test1.txt", "r")
>>> l = f.readlines()
>>> l = [line.split('=') for line in l]
>>> for line in l:
print line
['ADDRESS', '{Location Address}']
['SUBURB', '{Location Suburb}']
['STATE', 'xxx']
['POSTCODE', 'xxx']
['DEPOSITED PLAN NO', '0']
['SECTION & HUNDRED NO', '0']
['PROPERTY PHONE NO', '']
This would essentially give you a [Column, Value] tuple you could use to insert the data into your database (after escaping all strings, etc etc, SQL Injection warning).
This is assuming the email input and your DB will have the same column names, but if they didn't, it'd be fairly trivial to set up a column mapping using a dictionary. On the flip side, if the email and columns are in sync, you don't need to know the names of the columns to get the parsing down.
You could iterate through the pseudo-dictionary and print out each key-value pair in the right spot in your parameterized sql string.
Hope this helps!
Edit: While this is in Python, C#/VB.net should have the same/similar abilities.
Using f As StreamReader = File.OpenText("sample.txt")
Dim g As String = "undefined"
Do
Dim s As String = f.ReadLine
If s Is Nothing Then Exit Do
s = s.Replace(Chr(9), " ")
If s.StartsWith("[") And s.EndsWith("]") Then
g = s.Substring("[".Length, s.Length - "[]".Length)
Else
Dim ss() As String = s.Split(New Char() {"="c}, 2)
If ss.Length = 2 Then
Console.WriteLine("{0}.{1}={2}", g, Trim(ss(0)), Trim(ss(1)))
End If
End If
Loop
End Using