elements within under the package_div
required_xref_elements = package_div.select('p.optional a.xref')
# Extract and join the titles of all found xref elements with a comma
titles = [xref.get("title").replace(" ","-") for xref in required_xref_elements if xref.get("title")]
if titles:
return titles
else:
print(f"extract_package_optional_pks: nothing found")
return []
else:
print(f"extract_package_optional_pks: nothing found")
return []
def extract_package_installed_content():
global soup
# Find all div.seg within div.sect1 > div.content > div.seglistitem
seglistitems = None
if is_module:
seglistitems = soup.select('div.content div.seglistitem')
else:
seglistitems = soup.select('div.sect1 > div.content div.seglistitem')
content_dict = {}
for seglistitem in seglistitems:
segs = seglistitem.find_all("div", class_="seg")
for seg in segs:
segtitle = seg.find("strong", class_="segtitle")
segbody = seg.find("span", class_="segbody")
if segtitle and segbody:
segtitle_text = segtitle.get_text().strip().lower().replace(" ", "_").replace(":","")
segbody_text = ' '.join(segbody.get_text().split()) # Remove multiple spaces and newlines
content_dict[segtitle_text] = segbody_text.replace(" and "," ")
return content_dict
def extract_package_commands(class_names):
global soup
# Find the div element with class "installation"
#command_div = soup.find(class_=class_names)
command_div = soup.select(class_names + " >*")
if command_div:
contents = []
# Iterate through the elements within div.installation
for element in command_div:
if element.name == "h2":
d_content = "\n\n\n#### " + ''.join(line.strip() for line in element.get_text().splitlines()).replace('\n', '') + "\n"
contents.append(d_content)
elif element.name == "h3":
d_content = "\n\n### " + ''.join(line.strip() for line in element.get_text().splitlines()).replace('\n', '')
contents.append(d_content)
elif element.name == "h4":
d_content = "\n\n## " + ''.join(line.strip() for line in element.get_text().splitlines()).replace('\n', '')
contents.append(d_content)
elif element.name == "p":
# If it's a
element, add its text content with "# " prefix
p_content = ' '.join(line.strip() for line in element.get_text().splitlines()).replace('\n', ' ')
p_content = "\n\n# " + p_content.strip() + "\n"
contents.append(p_content)
elif element.name == "pre":
kbd_command = element.find("kbd", class_="command")
if kbd_command:
# If it's a
element, add its text content
contents.append(kbd_command.get_text().strip())
elif element.name == "div":
element_classes = element.get("class", [])
if isinstance(element, Tag) and "admon" in element.get("class", []):
element_classes.remove("admon")
contents.append("\n#### " + ''.join([element.upper() for element in element_classes]) + " ####")
for element_admon in element:
if element_admon.name == "p":
lines = []
# Iterate through the contents of the p element
for item in element_admon.contents:
if isinstance(item, str):
# If it's a text node (not a child element), strip leading and trailing whitespace
line = re.sub(r'\s+', ' ', item.strip())
if line:
lines.append(line)
elif item.name: # If it's a child element (has a name)
# Add the content of the child element without leading/trailing whitespace
child_text = item.get_text().strip()
child_text = re.sub(r'\s+', ' ', child_text)
if child_text:
lines.append(child_text)
# Join the lines into a single string, replacing line breaks with spaces
content_str = ' '.join(lines)
contents.append("## " + content_str.replace(" , ", ", "))
contents.append("")
if contents:
joined_contents = '\n'.join(contents)
return joined_contents
else:
print(f"extract_package_commands({class_names}): nothing found")
return ""
else:
print(f"extract_package_commands({class_names}): nothing found")
return ""
def extract_classnames_between_package_and_installation():
global soup
# Find the div element with class "sect1"
sect1_div = soup.find("div", class_="sect1")
if sect1_div:
installation_div = sect1_div.find("div", class_="package")
configuration_div = sect1_div.find("div", class_="installation")
if installation_div and configuration_div:
# Find all siblings of div.installation that are on the same level
elements_between = []
for sibling in installation_div.next_siblings:
if sibling == configuration_div:
break
if sibling.name:
elements_between.append(sibling["class"])
if elements_between:
classnames = [classname for element_classes in elements_between for classname in element_classes]
return classnames
def format_array_to_bash_array(input_array):
formatted_elements = " ".join([f"'{element}'" for element in input_array])
return f'({formatted_elements})'
if __name__ == "__main__":
install_groups = []
# get url from arguments
parser = argparse.ArgumentParser(description="Fetch data from a URL")
parser.add_argument("url", help="URL of the webpage to fetch")
args = parser.parse_args()
url = args.url
# Check if pkg is a module
parsed_url = urlsplit(url)
fragment = parsed_url.fragment
# Remove URL encoding from the fragment
if fragment:
is_module = unquote(fragment)
install_groups.append(os.path.basename(parsed_url.path.strip('/')).replace(".html", ""))
#url = "https://www.linuxfromscratch.org/blfs/view/12.0/x/qt5.html"
#url = "https://www.linuxfromscratch.org/blfs/view/12.0/xsoft/libreoffice.html"
#url = "https://www.linuxfromscratch.org/blfs/view/12.0/postlfs/mitkrb.html"
# Fetch the webpage and parse it
fetch_webpage(url)
print(f'\n\n–––––––––––––––––––––––––––––––––––––\n')
print(f'Getting content\n')
if extract_name_version is None:
extract_name_version = extractPackageNameFull()
# Get the extract_name
if extract_name is None:
extract_name, extracted_version = extractPackageNameVersion(extract_name_version)
extract_name = extractPackageName()
# Convert extract_name to lowercase
extract_name_lower = extract_name.lower()
# Define the filename
filename = f"install_{extract_name_version}"
pkg_link = extract_package_link()
pkg_name = basename = os.path.basename(pkg_link)
installed_content = extract_package_installed_content()
# Extract the keys from the dictionary
installed_content_formatted_keys = [f'"{key.rstrip(":")}"' for key in installed_content.keys()]
# Create the first string
installed_content_a = f"installed_content=({' '.join(installed_content_formatted_keys)})"
# Create the second string by joining the values of the dictionary
installed_content_b = '\n'.join([f'{key}="{value}"' for key, value in installed_content.items()])
installation_command = extract_package_commands("div.installation")
installation_configuration = extract_package_commands("div.configuration >div.sect3")
classnames_between_package_and_installation = extract_classnames_between_package_and_installation()
# Open the file for writing
with open(filename, "w") as script_file:
# Write the script content to the file
script_file.write(f'#!/bin/bash\n\n')
script_file.write(f'############################################\n### {extract_name_version}\n\n')
script_file.write(f'url="{url}"\n')
script_file.write(f'name="{extract_name}"\n')
script_file.write(f'name_version="{extract_name_version}"\n')
script_file.write(f'link="{pkg_link}"\n')
script_file.write(f'pkg="{pkg_name}"\n')
script_file.write(f'pkg_dir="" # this is getting set within the script\n')
script_file.write(f'md5_sum="{extract_package_md5()}"\n')
script_file.write(f'additional_links={format_array_to_bash_array(extract_additional_downloads())}\n')
script_file.write(f'info="{extract_package_info()}"\n')
script_file.write(f'required={format_array_to_bash_array(extract_package_required_pks())}\n')
script_file.write(f'recommended={format_array_to_bash_array(extract_package_recommended_pks())}\n')
script_file.write(f'optional={format_array_to_bash_array(extract_package_optional_pks())}\n')
script_file.write(f'{installed_content_a}\n')
script_file.write(f'{installed_content_b}\n')
if is_module:
script_file.write(f'install_groups={format_array_to_bash_array(install_groups)}\n')
script_file.write(f'\n\n')
script_file.write(f'install_pkg() {{\n')
if classnames_between_package_and_installation:
script_file.write(f'#### BEFORE INSTALLATION ####\n\n')
for b_package in classnames_between_package_and_installation:
bc_package = "div." + b_package
script_file.write(f'{extract_package_commands(bc_package)}\n')
script_file.write(f'#### BEFORE INSTALLATION DONE ####\n\n')
script_file.write(f'#### INSTALLATION ####\n\n')
script_file.write(f'# Get tar/zip\n')
script_file.write(f'[ -f "$pkg" ] || wget -4 $link\n\n')
script_file.write(f'# Check md5sum\n')
script_file.write(f'if ! grep -wq "$md5_sum" <<< $(md5sum $pkg); then\n\techo "ERROR: md5sum check failed" && exit\nfi\n\n')
script_file.write(f'# Get additional links\n')
# LAST WORKED HERE:
script_file.write('for li in "${additional_links[@]}"; do wget -4 "$li"; done\n\n')
if not re.search(fr"^tar .* {re.escape(pkg_name)} .*", installation_command):
script_file.write(f'# Unpack tar/zip and get pkg_dir variable\n')
script_file.write(f'rm -rf tmp && mkdir tmp && cd tmp\n')
if pkg_name.endswith(".zip"):
script_file.write(f'unzip ../$pkg &&\nif [ "$(ls | wc -w)" = "1" ]; then\n\tpkg_dir="$(ls)"; [ -d ../$pkg_dir ] && rm -rf ../$pkg_dir; cd .. && mv tmp/* . && rm -r tmp\nelse\n\tcd ..\n\t[ -d $name_version ] && rm -rf $name_version\n\tmv tmp $name_version\n\tpkg_dir=$name_version\nfi\n')
elif pkg_name.endswith((".tar", ".tgz", ".tar.gz", ".tar.bz2", ".tar.xz")):
script_file.write(f'tar -xvf ../$pkg && if [ "$(ls | wc -w)" = "1" ]; then\n\tpkg_dir="$(ls)";\nelse\n\techo "ERROR: unpacked tar leaves unknown directory: \\"$(ls)\\"" && exit;\nfi &&\ncd ..\n[ -d $pkg_dir ] && rm -rf $pkg_dir\nmv tmp/* . && rm -r tmp\n')
script_file.write(f'cd $pkg_dir\n')
script_file.write(f'{installation_command}\n')
script_file.write(f'\n#### INSTALLATION DONE ####\n\n')
script_file.write(f'}}\n\n')
if installation_configuration:
script_file.write(f'\nconfigure_pkg() {{\n')
script_file.write(f'\n#### CONFIGURATION ####\n\n')
script_file.write('echo "## Configuration"\n\n')
script_file.write(f'{installation_configuration}\n')
script_file.write(f'\n#### CONFIGURATION DONE ####\n\n')
script_file.write(f'}}\n\n')
script_file.write(f'if [[ "$1" == "install" ]]; then install_pkg; else echo -e "you may want to run\\n$0 install"; fi\n')
if installation_configuration:
script_file.write(f'if [[ "$1" == "install" ]]; then configure_pkg; fi')
# script_file.write(f'cd ..; llist_package $(whoami) > pkg.lst 2>&1 & disown')
print(f'\n\n–––––––––––––––––––––––––––––––––––––')
print(f'\nSuccessfully created {filename}')
# Check the syntax of the script without executing it
try:
subprocess.run(["bash", "-n", filename], check=True)
print(f'\n–––––––––––––––––––––––––––––––––––––')
print("\nBash script syntax is valid.")
except subprocess.CalledProcessError as e:
print(f'\n–––––––––––––––––––––––––––––––––––––')
print("\n!!! Error in Bash script syntax !!!")
if e.stderr is not None:
print(e.stderr)
print(f'\n–––––––––––––––––––––––––––––––––––––')
print(f'\nFile path: {filename}')