1use crate::Pyo3Docker;
2use chrono::{DateTime, Utc};
3use docker_api::opts::LogsOpts;
4use docker_api::task::TaskListOpts;
5use docker_api::{Task, Tasks};
6use futures_util::stream::StreamExt;
7use pyo3::exceptions;
8use pyo3::prelude::*;
9use pyo3::types::PyDateTime;
10use pythonize::pythonize;
11
12#[pymodule]
13pub fn task(_py: Python<'_>, m: &Bound<'_, PyModule>) -> PyResult<()> {
14 m.add_class::<Pyo3Tasks>()?;
15 m.add_class::<Pyo3Task>()?;
16 Ok(())
17}
18
19#[derive(Debug)]
24#[pyclass(name = "Tasks")]
25pub struct Pyo3Tasks {
26 tasks: Tasks,
27}
28
29#[derive(Debug)]
34#[pyclass(name = "Task")]
35pub struct Pyo3Task {
36 task: Task,
37}
38
39#[pymethods]
40impl Pyo3Tasks {
41 #[new]
42 pub fn new(docker: Pyo3Docker) -> Self {
43 Pyo3Tasks {
44 tasks: Tasks::new(docker.0),
45 }
46 }
47
48 pub fn get(&self, id: &str) -> Pyo3Task {
56 Pyo3Task {
57 task: self.tasks.get(id),
58 }
59 }
60
61 pub fn list(&self) -> PyResult<Py<PyAny>> {
69 let rv = __tasks_list(&self.tasks, &Default::default());
70
71 match rv {
72 Ok(rv) => Ok(pythonize_this!(rv)),
73 Err(rv) => Err(py_sys_exception!(rv)),
74 }
75 }
76}
77
78#[tokio::main]
79async fn __tasks_list(
80 tasks: &Tasks,
81 opts: &TaskListOpts,
82) -> Result<Vec<docker_api::models::Task>, docker_api::Error> {
83 tasks.list(opts).await
84}
85
86#[pymethods]
87impl Pyo3Task {
88 #[new]
89 pub fn new(docker: Pyo3Docker, id: &str) -> Self {
90 Pyo3Task {
91 task: Task::new(docker.0, id),
92 }
93 }
94
95 pub fn id(&self) -> String {
100 self.task.id().to_string()
101 }
102
103 pub fn inspect(&self) -> PyResult<Py<PyAny>> {
111 let rv = __task_inspect(&self.task);
112
113 match rv {
114 Ok(rv) => Ok(pythonize_this!(rv)),
115 Err(rv) => Err(py_sys_exception!(rv)),
116 }
117 }
118
119 #[pyo3(signature = (stdout=None, stderr=None, timestamps=None, n_lines=None, all=None, since=None))]
132 pub fn logs(
133 &self,
134 stdout: Option<bool>,
135 stderr: Option<bool>,
136 timestamps: Option<bool>,
137 n_lines: Option<usize>,
138 all: Option<bool>,
139 since: Option<&Bound<'_, PyDateTime>>,
140 ) -> String {
141 let mut log_opts = LogsOpts::builder();
142
143 bo_setter!(stdout, log_opts);
144 bo_setter!(stderr, log_opts);
145 bo_setter!(timestamps, log_opts);
146 bo_setter!(n_lines, log_opts);
147
148 if all.is_some() && all.unwrap() {
149 log_opts = log_opts.all();
150 }
151
152 if since.is_some() {
153 let rs_since: DateTime<Utc> = since.unwrap().extract().unwrap();
154 log_opts = log_opts.since(&rs_since);
155 }
156
157 __task_logs(&self.task, &log_opts.build())
158 }
159}
160
161#[tokio::main]
162async fn __task_inspect(task: &Task) -> Result<docker_api::models::Task, docker_api::Error> {
163 task.inspect().await
164}
165
166#[tokio::main]
167async fn __task_logs(task: &Task, log_opts: &LogsOpts) -> String {
168 let log_stream = task.logs(log_opts);
169
170 let log = log_stream
171 .map(|chunk| match chunk {
172 Ok(chunk) => chunk.to_vec(),
173 Err(e) => {
174 eprintln!("Error: {e}");
175 vec![]
176 }
177 })
178 .collect::<Vec<_>>()
179 .await
180 .into_iter()
181 .flatten()
182 .collect::<Vec<_>>();
183
184 format!("{}", String::from_utf8_lossy(&log))
185}