Change metadata
This commit is contained in:
45
.vscode/launch.json
vendored
Normal file
45
.vscode/launch.json
vendored
Normal file
@@ -0,0 +1,45 @@
|
||||
{
|
||||
// Verwendet IntelliSense zum Ermitteln möglicher Attribute.
|
||||
// Zeigen Sie auf vorhandene Attribute, um die zugehörigen Beschreibungen anzuzeigen.
|
||||
// Weitere Informationen finden Sie unter https://go.microsoft.com/fwlink/?linkid=830387
|
||||
"version": "0.2.0",
|
||||
"configurations": [
|
||||
{
|
||||
"type": "lldb",
|
||||
"request": "launch",
|
||||
"name": "Debug executable 'no-man-sky'",
|
||||
"cargo": {
|
||||
"args": [
|
||||
"build",
|
||||
"--bin=no-man-sky",
|
||||
"--package=no-man-sky"
|
||||
],
|
||||
"filter": {
|
||||
"name": "no-man-sky",
|
||||
"kind": "bin"
|
||||
}
|
||||
},
|
||||
"args": [],
|
||||
"cwd": "${workspaceFolder}"
|
||||
},
|
||||
{
|
||||
"type": "lldb",
|
||||
"request": "launch",
|
||||
"name": "Debug unit tests in executable 'no-man-sky'",
|
||||
"cargo": {
|
||||
"args": [
|
||||
"test",
|
||||
"--no-run",
|
||||
"--bin=no-man-sky",
|
||||
"--package=no-man-sky"
|
||||
],
|
||||
"filter": {
|
||||
"name": "no-man-sky",
|
||||
"kind": "bin"
|
||||
}
|
||||
},
|
||||
"args": [],
|
||||
"cwd": "${workspaceFolder}"
|
||||
}
|
||||
]
|
||||
}
|
||||
16
Cargo.toml
Normal file
16
Cargo.toml
Normal file
@@ -0,0 +1,16 @@
|
||||
[package]
|
||||
name = "no-man-sky"
|
||||
version = "0.1.0"
|
||||
edition = "2024"
|
||||
publish = ["merlin"]
|
||||
description = "Utility functions to read environment with fallback and values from a file"
|
||||
license = "MIT"
|
||||
repository = "ssh://git@gitea.merlinserver.de:2222/Stefan/merlin_env_helper.git"
|
||||
|
||||
[dependencies]
|
||||
ego-tree = "0.10.0"
|
||||
env_logger = "0.11.8"
|
||||
log = "0.4.27"
|
||||
merlin_env_helper = { version = "0.2.0", registry = "merlin" }
|
||||
reqwest = {version="0.12.15", features=["blocking"]}
|
||||
scraper = "0.23.1"
|
||||
76
snipped.html
Normal file
76
snipped.html
Normal file
@@ -0,0 +1,76 @@
|
||||
<span
|
||||
class="resource-substanzmithoherenergie"
|
||||
style="border: 1px solid #d3d3d3"
|
||||
>
|
||||
<span class="mw-valign-text-bottom" typeof="mw:File">
|
||||
<a href="/de/wiki/Diwasserstoff" title="Diwasserstoff">
|
||||
<img
|
||||
class="mw-file-element lazyload"
|
||||
data-image-key="SUBSTANCE.LAUNCHSUB.1.png"
|
||||
data-image-name="SUBSTANCE.LAUNCHSUB.1.png"
|
||||
data-relevant="1"
|
||||
data-src="https://static.wikia.nocookie.net/nomanssky_gamepedia/images/0/03/SUBSTANCE.LAUNCHSUB.1.png/revision/latest/scale-to-width-down/18?cb=20180725071716"
|
||||
decoding="async"
|
||||
height="18"
|
||||
loading="lazy"
|
||||
src="data:image/gif;base64,R0lGODlhAQABAIABAAAAAP///yH5BAEAAAEALAAAAAABAAEAQAICTAEAOw%3D%3D"
|
||||
width="18"
|
||||
/>
|
||||
</a>
|
||||
</span>
|
||||
</span>
|
||||
<a href="/de/wiki/Diwasserstoff" title="Diwasserstoff">
|
||||
<span class="itemlink ajaxttlink">Diwasserstoff</span>
|
||||
</a>
|
||||
x1 +
|
||||
<span
|
||||
class="resource-konzentrierterflüssigtreibstoff"
|
||||
style="border: 1px solid #d3d3d3"
|
||||
>
|
||||
<span class="mw-valign-text-bottom" typeof="mw:File">
|
||||
<a href="/de/wiki/Sauerstoff" title="Sauerstoff">
|
||||
<img
|
||||
class="mw-file-element lazyload"
|
||||
data-image-key="SUBSTANCE.AIR.1.png"
|
||||
data-image-name="SUBSTANCE.AIR.1.png"
|
||||
data-relevant="1"
|
||||
data-src="https://static.wikia.nocookie.net/nomanssky_gamepedia/images/e/ec/SUBSTANCE.AIR.1.png/revision/latest/scale-to-width-down/18?cb=20221007220715"
|
||||
decoding="async"
|
||||
height="18"
|
||||
loading="lazy"
|
||||
src="data:image/gif;base64,R0lGODlhAQABAIABAAAAAP///yH5BAEAAAEALAAAAAABAAEAQAICTAEAOw%3D%3D"
|
||||
width="18"
|
||||
/>
|
||||
</a>
|
||||
</span>
|
||||
</span>
|
||||
<a href="/de/wiki/Sauerstoff" title="Sauerstoff">
|
||||
<span class="itemlink ajaxttlink">Sauerstoff</span>
|
||||
</a>
|
||||
x1 →
|
||||
<span
|
||||
class="resource-aquatischesmineral-extrakt"
|
||||
style="border: 1px solid #d3d3d3"
|
||||
>
|
||||
<span class="mw-valign-text-bottom" typeof="mw:File">
|
||||
<a href="/de/wiki/Salz" title="Salz">
|
||||
<img
|
||||
class="mw-file-element lazyload"
|
||||
data-image-key="SUBSTANCE.WATER.1.png"
|
||||
data-image-name="SUBSTANCE.WATER.1.png"
|
||||
data-relevant="1"
|
||||
data-src="https://static.wikia.nocookie.net/nomanssky_gamepedia/images/9/9f/SUBSTANCE.WATER.1.png/revision/latest/scale-to-width-down/18?cb=20180726042119"
|
||||
decoding="async"
|
||||
height="18"
|
||||
loading="lazy"
|
||||
src="data:image/gif;base64,R0lGODlhAQABAIABAAAAAP///yH5BAEAAAEALAAAAAABAAEAQAICTAEAOw%3D%3D"
|
||||
width="18"
|
||||
/>
|
||||
</a>
|
||||
</span>
|
||||
</span>
|
||||
<strong class="mw-selflink selflink">
|
||||
<span class="itemlink ajaxttlink">Salz</span>
|
||||
</strong>
|
||||
x1
|
||||
<small>( <i>"Schnelle Formation/Verdunstung"</i>, 0,08 sek./Stück)</small>
|
||||
155
src/main.rs
Normal file
155
src/main.rs
Normal file
@@ -0,0 +1,155 @@
|
||||
use std::{fs::File, io::{Read}};
|
||||
|
||||
use scraper::{ElementRef, Node};
|
||||
use ego_tree::NodeRef;
|
||||
|
||||
fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
env_logger::init();
|
||||
let html = read("test.html")?;
|
||||
parse(&html)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
||||
fn _download_file(url: &str, _path: &str) -> Result<String, Box<dyn std::error::Error>> {
|
||||
// Some simple CLI args requirements...
|
||||
|
||||
eprintln!("Fetching {url:?}...");
|
||||
|
||||
// reqwest::blocking::get() is a convenience function.
|
||||
//
|
||||
// In most cases, you should create/build a reqwest::Client and reuse
|
||||
// it for all requests.
|
||||
let res = reqwest::blocking::get(url)?;
|
||||
|
||||
|
||||
let body = res.text()?;
|
||||
Ok(body)
|
||||
}
|
||||
|
||||
fn read(path: &str) -> Result<String, std::io::Error> {
|
||||
let mut file = File::open(path)?;
|
||||
let mut contents = String::new();
|
||||
file.read_to_string(&mut contents)?;
|
||||
Ok(contents)
|
||||
}
|
||||
|
||||
fn parse(html: &str) -> Result<bool, Box<dyn std::error::Error>> {
|
||||
// Parse the HTML content
|
||||
let document = scraper::Html::parse_document(html);
|
||||
let selector_quelle = scraper::Selector::parse("#Quelle").unwrap();
|
||||
let selector_verwendung = scraper::Selector::parse("#Verwendung").unwrap();
|
||||
let selector_li = scraper::Selector::parse("li").unwrap();
|
||||
|
||||
let elt_quelle= document.select(&selector_quelle).next();
|
||||
|
||||
if elt_quelle.is_none() {
|
||||
eprintln!("No element found with the selector '#Quelle'");
|
||||
return Ok(false);
|
||||
}
|
||||
|
||||
let elt_quelle = elt_quelle.unwrap();
|
||||
|
||||
let mut elt_quelle = elt_quelle.parent().unwrap();
|
||||
|
||||
let mut c = 0;
|
||||
let mut elt_ul = None;
|
||||
|
||||
while elt_quelle. next_sibling().is_some() {
|
||||
|
||||
elt_quelle = elt_quelle.next_sibling().unwrap();
|
||||
|
||||
if !elt_quelle.value().is_element(){
|
||||
continue;
|
||||
}
|
||||
|
||||
let elt = elt_quelle.value().as_element().unwrap();
|
||||
if elt.name() == "ul" {
|
||||
c += 1;
|
||||
|
||||
if c > 1 {
|
||||
elt_ul = Some(elt_quelle);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if elt.name() == "h2" {
|
||||
eprintln!("Found 'h2' element, stopping search for 'ul'");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if elt_ul.is_none() {
|
||||
eprintln!("No second 'ul' element found after '#Quelle'");
|
||||
return Ok(false);
|
||||
}
|
||||
let elt_ul = ElementRef::wrap(elt_ul.unwrap()).unwrap();
|
||||
let li = elt_ul.select(&selector_li);
|
||||
|
||||
for item in li
|
||||
{
|
||||
parse_li_to_resource(item);
|
||||
}
|
||||
|
||||
let elt_verwendung= document.select(&selector_verwendung).next();
|
||||
|
||||
if elt_verwendung.is_none() {
|
||||
eprintln!("No element found with the selector '#Verwendung'");
|
||||
return Ok(false);
|
||||
}
|
||||
|
||||
let elt_verwendung = elt_verwendung.unwrap();
|
||||
|
||||
Ok(true)
|
||||
}
|
||||
|
||||
fn parse_li_to_resource(item: ElementRef<'_>) {
|
||||
if !item.has_children() {
|
||||
println!("Item has no children, skipping.");
|
||||
return;
|
||||
}
|
||||
|
||||
let mut resource_items = Vec::new();
|
||||
|
||||
let first_child = item.first_child().unwrap();
|
||||
|
||||
resource_items.push(first_child);
|
||||
|
||||
let iter = first_child.next_siblings();
|
||||
|
||||
for next in iter {
|
||||
if next.value().is_text() {
|
||||
resource_items.push(next);
|
||||
}
|
||||
else if next.value().is_element() {
|
||||
if next.value().as_element().unwrap().name() == "span" {
|
||||
parse_resource (resource_items);
|
||||
resource_items = Vec::new();
|
||||
}
|
||||
|
||||
resource_items.push(next);
|
||||
}
|
||||
}
|
||||
|
||||
println!("======================");
|
||||
}
|
||||
|
||||
fn parse_resource(resource_items: Vec<NodeRef<'_, Node>>) {
|
||||
if resource_items.is_empty() {
|
||||
println!("No resource items to parse.");
|
||||
return;
|
||||
}
|
||||
|
||||
println!("Parsing resource items...");
|
||||
|
||||
for item in resource_items {
|
||||
if item.value().is_text() {
|
||||
println!("Text: {}", item.value().as_text().unwrap().text.trim_ascii());
|
||||
continue;
|
||||
}
|
||||
println!("Resource: {:?}", item.value());
|
||||
}
|
||||
|
||||
println!("------------------");
|
||||
|
||||
}
|
||||
8
src/test.html
Normal file
8
src/test.html
Normal file
@@ -0,0 +1,8 @@
|
||||
<html>
|
||||
<body>
|
||||
<img
|
||||
src="data:image/gif;base64,R0lGODlhAQABAIABAAAAAP///yH5BAEAAAEALAAAAAABAAEAQAICTAEAOw%3D%3D"
|
||||
width="18"
|
||||
/>
|
||||
</body>
|
||||
</html>
|
||||
2
src/types/mod.rs
Normal file
2
src/types/mod.rs
Normal file
@@ -0,0 +1,2 @@
|
||||
pub mod types;
|
||||
pub use types::*;
|
||||
0
src/types/types.rs
Normal file
0
src/types/types.rs
Normal file
3
src/util/cmd.rs
Normal file
3
src/util/cmd.rs
Normal file
@@ -0,0 +1,3 @@
|
||||
pub fn parse_command_line_args() -> Vec<String> {
|
||||
std::env::args().skip(1).collect()
|
||||
}
|
||||
2
src/util/mod.rs
Normal file
2
src/util/mod.rs
Normal file
@@ -0,0 +1,2 @@
|
||||
pub mod cmd;
|
||||
pub use cmd::*;
|
||||
Reference in New Issue
Block a user