Skip to content

Commit

Permalink
Basic docs
Browse files Browse the repository at this point in the history
  • Loading branch information
Marekkon5 committed Sep 7, 2023
1 parent da63231 commit af16785
Show file tree
Hide file tree
Showing 12 changed files with 420 additions and 99 deletions.
81 changes: 79 additions & 2 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions crates/onetagger-cli/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ convert_case = "0.6"
clap = { version = "4.1", features = ["derive"] }

onetagger-tagger = { path = "../onetagger-tagger" }
onetagger-python = { path = "../onetagger-python" }
onetagger-shared = { path = "../onetagger-shared" }
onetagger-autotag = { path = "../onetagger-autotag" }
onetagger-renamer = { path = "../onetagger-renamer" }
Expand Down
27 changes: 20 additions & 7 deletions crates/onetagger-cli/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,7 @@ use onetagger_tagger::{TaggerConfig, AudioFileInfo, SupportedTag};


fn main() {
// Python subprocess
if std::env::args().any(|a| a == "--python-subprocess") {
onetagger_autotag::python_process();
std::process::exit(0);
}

onetagger_python::python_hook();
let cli = Cli::parse();

// Default configs
Expand All @@ -35,6 +30,12 @@ fn main() {
println!("{config}");
return;
}
// Generate docs
if cli.python_docs {
onetagger_shared::setup();
println!("{}", onetagger_python::generate_docs().expect("Failed to generate docs").to_string_lossy());
return;
}

if cli.action.is_none() {
println!("No action. Use onetagger-cli --help to get print help.");
Expand Down Expand Up @@ -121,7 +122,9 @@ fn main() {

renamer.rename(&config).expect("Failed renaming!");
},

Actions::Python { platform } => {
onetagger_python::python_interpreter(platform).expect("Failed");
}
}
}

Expand All @@ -140,6 +143,10 @@ struct Cli {
/// Prints the default Audio Features config and exits
#[clap(long)]
audiofeatures_config: bool,

/// Generate python module documentation and exit
#[clap(long)]
python_docs: bool,
}

#[derive(Subcommand, Debug, Clone)]
Expand Down Expand Up @@ -314,6 +321,12 @@ enum Actions {
/// Keep original subfolders
#[clap(long)]
keep_subfolders: bool,
},
/// Start interactive Python interpreter for platform
Python {
/// Context of which platform
#[clap(long, short)]
platform: String,
}
}

Expand Down
1 change: 1 addition & 0 deletions crates/onetagger-python/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ edition = "2021"
dunce = "1.0"
chrono = "0.4"
anyhow = "1.0"
tempdir = "0.3"
rmp-serde = "1.1"
serde_json = "1.0"

Expand Down
25 changes: 25 additions & 0 deletions crates/onetagger-python/src/docs.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import pdoc
import requests
from bs4 import BeautifulSoup

def generate_docs(module, output):
html = pdoc.html(module)
soup = BeautifulSoup(html, features='lxml')

# Make CSS offline
for e in soup.select('link'):
if e.has_attr('href'):
r = requests.get(e.attrs['href'])
new = soup.new_tag('style')
new.string = r.text
e.replace_with(new)
# Make JS offline
for e in soup.select('script'):
if e.has_attr('src'):
r = requests.get(e.attrs['src'])
new = soup.new_tag('script')
new.string = r.text
e.replace_with(new)

with open(output, 'w') as f:
f.write(soup.prettify())
60 changes: 55 additions & 5 deletions crates/onetagger-python/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ use std::process::{Command, Stdio};
use anyhow::Error;
use onetagger_shared::Settings;
use onetagger_tagger::{PlatformInfo, AutotaggerSourceBuilder, TaggerConfig, AutotaggerSource, AudioFileInfo, Track, TrackMatch};
use pyembed::MainPythonInterpreter;
use serde::{Serialize, Deserialize};
use subprocess::{SubprocessWrap, PythonResponse, PythonRequest};

Expand All @@ -16,6 +17,7 @@ mod subprocess;

/// Re-Export python process
pub use subprocess::python_process;
use tempdir::TempDir;

/// Python Standard Library ZIP
const PYTHON_STDLIB: &[u8] = include_bytes!("../pyembedded/stdlib.zip");
Expand Down Expand Up @@ -50,10 +52,6 @@ pub fn setup() -> Result<(), Error> {
Ok(())
}

/// Get standard library path
fn stdlib_path() -> Result<PathBuf, Error> {
Ok(dunce::canonicalize(Settings::get_folder()?.join("python_stdlib.zip"))?)
}

/// Platform info for Python
#[derive(Debug, Clone, Serialize, Deserialize)]
Expand Down Expand Up @@ -88,6 +86,59 @@ fn spawn_python_child() -> Result<SubprocessWrap, Error> {
Ok(wrap)
}

/// Generate python module docs
pub fn generate_docs() -> Result<PathBuf, Error> {
let temp = TempDir::new("1tdocs")?;

// Pip
debug!("Pip install");
let mut wrap = spawn_python_child()?;
wrap.send(&PythonRequest::PipInstall {
path: temp.path().to_owned(),
requirements: vec!["pdoc3".into(), "requests".into(), "beautifulsoup4".into(), "lxml".into()]
})?;
wrap.recv()?;
drop(wrap);

// Generate
debug!("Generate docs");
let mut wrap = spawn_python_child()?;
let path = Settings::get_folder()?.join("onetagger-python.html");
wrap.send(&PythonRequest::GenerateDocs { python_path: temp.path().to_owned(), output: path.to_owned() })?;
wrap.recv()?;
Ok(path)
}

/// Get python interpreter for platform
/// WARNING: Exits the process, can be only called once
pub fn python_interpreter(platform: &str) -> Result<(), Error> {
module::setup();
let folder = Settings::get_folder()?;
let mut config = module::pyoxidizer_config(folder.join("platforms").join(platform).join(".python"))?;
config.interpreter_config.module_search_paths.as_mut().unwrap().push(folder.join("pip.pyz"));
let interpreter = MainPythonInterpreter::new(config)?;
// Enable modern shell
interpreter.with_gil(|py| { py.import("readline").ok(); });
std::process::exit(interpreter.run());
}

/// Check the args, if it has python (non-1T related ones, start Python)
pub fn python_hook() {
// 1T Python subprocess
let args = std::env::args().collect::<Vec<_>>();
if args.iter().any(|a| a == "--python-subprocess") {
python_process();
std::process::exit(0);
}

// Python subprocess spawned
if std::env::var("_1T_PY_HOME").is_ok() {
let mut config = module::pyoxidizer_config(std::env::var("_1T_PY_HOME").unwrap()).unwrap();
config.argv = Some(args.into_iter().map(|v| v.into()).collect());
std::process::exit(MainPythonInterpreter::new(config).unwrap().py_runmain());
}
}

pub struct PythonPlatformBuilder {
pub info: PythonPlatformInfo,
path: PathBuf
Expand All @@ -104,7 +155,6 @@ impl AutotaggerSourceBuilder for PythonPlatformBuilder {
let mut wrap = spawn_python_child()?;
wrap.send(&PythonRequest::PipInstall {
path: self.path.join(".python"),
pip_path: Settings::get_folder()?.join("pip.pyz"),
requirements: self.info.requirements.clone()
})?;
wrap.recv()?;
Expand Down
Loading

0 comments on commit af16785

Please sign in to comment.