Add otrs support
This commit is contained in:
parent
5a7d41300c
commit
8dabbb8c20
Binary file not shown.
|
@ -1,7 +1,7 @@
|
|||
{ config, lib, pkgs , ... }:
|
||||
with lib;
|
||||
let
|
||||
inherit (config.m-0.private) me gitlab github;
|
||||
inherit (config.m-0.private) me gitlab github otrs;
|
||||
in {
|
||||
options.m-0.bugwarrior.enable = mkEnableOption "Sync tasks from issuetrackers";
|
||||
config = mkIf config.m-0.bugwarrior.enable {
|
||||
|
@ -43,8 +43,13 @@ config = mkIf config.m-0.bugwarrior.enable {
|
|||
};
|
||||
Service = {
|
||||
Type = "oneshot";
|
||||
Environment="PATH=${pkgs.taskwarrior}/bin:${pkgs.eventd}/bin:${pkgs.gnugrep}/bin";
|
||||
ExecStart="${pkgs.bugwarrior}/bin/bugwarrior-pull";
|
||||
Environment=''PATH=${pkgs.taskwarrior}/bin:${pkgs.eventd}/bin OTRS_USER=${me.user} OTRS_PASSWORD=${otrs.password} OTRS_QUEUES="${otrs.queues}" OTRS_OWNERS="${otrs.owners}" OTRS_HOST=${otrs.host}'';
|
||||
ExecStart= let
|
||||
update = pkgs.writeShellScriptBin "update" ''
|
||||
${pkgs.bugwarrior}/bin/bugwarrior-pull
|
||||
${pkgs.rust_scripts}/bin/sync_otrs
|
||||
true
|
||||
''; in "${update}/bin/update";
|
||||
};
|
||||
};
|
||||
timers.bugwarrior = {
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
{ config, lib, pkgs , ... }:
|
||||
with lib;
|
||||
let
|
||||
inherit (config.m-0.private) me gitlab;
|
||||
inherit (config.m-0.private) me;
|
||||
in {
|
||||
options.m-0.update_tasks.enable = mkEnableOption "Update Tasks";
|
||||
config = mkIf config.m-0.update_tasks.enable {
|
||||
|
|
1031
home-manager/packages/rust-scripts/Cargo.lock
generated
1031
home-manager/packages/rust-scripts/Cargo.lock
generated
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
@ -1,7 +1,6 @@
|
|||
[package]
|
||||
name = "rust-scripts"
|
||||
version = "0.1.0"
|
||||
authors = ["Malte Brandy <malte.brandy@maralorn.de>"]
|
||||
|
||||
[dependencies]
|
||||
dialog = { git = "https://git.darmstadt.ccc.de/maralorn/dialog-rs.git" }
|
||||
|
@ -16,3 +15,6 @@ serde_yaml = "0.7"
|
|||
maildir = "0.1.1"
|
||||
mailparse = "0.5.1"
|
||||
regex = "0.2"
|
||||
serde_json = "1.0"
|
||||
reqwest = "0.8"
|
||||
config = "0.9.0"
|
||||
|
|
5
home-manager/packages/rust-scripts/shell.nix
Normal file
5
home-manager/packages/rust-scripts/shell.nix
Normal file
|
@ -0,0 +1,5 @@
|
|||
with import <unstable> {};
|
||||
stdenv.mkDerivation {
|
||||
name = "habitask";
|
||||
buildInputs = [ pkgs.openssl pkgs.pkgconfig ];
|
||||
}
|
15
home-manager/packages/rust-scripts/src/bin/sync_otrs.rs
Normal file
15
home-manager/packages/rust-scripts/src/bin/sync_otrs.rs
Normal file
|
@ -0,0 +1,15 @@
|
|||
extern crate rust_scripts;
|
||||
extern crate task_hookrs;
|
||||
|
||||
use rust_scripts::error::Result;
|
||||
use rust_scripts::otrs::sync_otrs;
|
||||
use task_hookrs::cache::TaskCache;
|
||||
use task_hookrs::status::TaskStatus;
|
||||
|
||||
fn main() -> Result<()> {
|
||||
let mut cache = TaskCache::new(vec![TaskStatus::Deleted]);
|
||||
cache.load()?;
|
||||
sync_otrs(&mut cache)?;
|
||||
cache.write()?;
|
||||
Ok(())
|
||||
}
|
|
@ -874,6 +874,14 @@ Do you want to change the state? (Esc to cancel)",
|
|||
.arg("-e")
|
||||
.arg(read_command)
|
||||
.output()?;
|
||||
} else if task.gen_name() == Some(&"cda-otrs".to_owned()) {
|
||||
let ticket_number = task.gen_id().chain_err(|| "Missing Ticketnumber")?;
|
||||
let url = format!(
|
||||
"https://tickets.darmstadt.ccc.de/otrs/index.pl?Action=AgentTicketZoom;TicketID={}",
|
||||
ticket_number
|
||||
);
|
||||
str2cmd("firefox --new-window").arg(url).output()?;
|
||||
bail!(EK::WorkingOnTask(print_task(task)));
|
||||
} else {
|
||||
bail!(EK::WorkingOnTask(print_task(task)));
|
||||
}
|
||||
|
|
|
@ -12,6 +12,8 @@ extern crate serde_yaml;
|
|||
extern crate maildir;
|
||||
extern crate mailparse;
|
||||
extern crate regex;
|
||||
extern crate reqwest;
|
||||
extern crate config;
|
||||
|
||||
pub mod hotkeys;
|
||||
pub mod generate;
|
||||
|
@ -21,14 +23,12 @@ pub mod kassandra;
|
|||
pub mod tasktree;
|
||||
pub mod well_known;
|
||||
pub mod mail;
|
||||
pub mod otrs;
|
||||
#[allow(renamed_and_removed_lints)]
|
||||
|
||||
pub mod error {
|
||||
use task_hookrs::error as terror;
|
||||
use dialog::errors as derror;
|
||||
use serde_yaml;
|
||||
use maildir;
|
||||
use mailparse;
|
||||
error_chain! {
|
||||
links {
|
||||
TaskError(terror::Error, terror::ErrorKind);
|
||||
|
@ -36,10 +36,12 @@ pub mod error {
|
|||
}
|
||||
foreign_links {
|
||||
Io(::std::io::Error);
|
||||
Yaml(serde_yaml::Error);
|
||||
Yaml(::serde_yaml::Error);
|
||||
PathError(::std::env::JoinPathsError);
|
||||
MailDir(maildir::MailEntryError);
|
||||
MailParse(mailparse::MailParseError);
|
||||
MailDir(::maildir::MailEntryError);
|
||||
MailParse(::mailparse::MailParseError);
|
||||
Config(::config::ConfigError);
|
||||
HttpError(::reqwest::Error);
|
||||
}
|
||||
errors {
|
||||
WorkingOnTask(t: String) {
|
||||
|
|
173
home-manager/packages/rust-scripts/src/otrs.rs
Normal file
173
home-manager/packages/rust-scripts/src/otrs.rs
Normal file
|
@ -0,0 +1,173 @@
|
|||
use task_hookrs::task::TaskBuilder;
|
||||
use task_hookrs::cache::TaskCache;
|
||||
|
||||
use error::{Result, ResultExt};
|
||||
use generate::{GeneratedTask, TaskGenerator};
|
||||
use reqwest::Client;
|
||||
use config::{Config, Environment};
|
||||
|
||||
#[derive(Debug, Deserialize)]
|
||||
struct Ticket {
|
||||
#[serde(rename = "TicketID")]
|
||||
number: u32,
|
||||
#[serde(rename = "Title")]
|
||||
title: String,
|
||||
#[serde(rename = "CustomerUserID")]
|
||||
customer: String,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Deserialize)]
|
||||
struct Settings {
|
||||
user: String,
|
||||
password: String,
|
||||
queues: String,
|
||||
owners: String,
|
||||
host: String,
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize)]
|
||||
struct QueueRequest {
|
||||
#[serde(rename = "UserLogin")]
|
||||
user: String,
|
||||
#[serde(rename = "Password")]
|
||||
password: String,
|
||||
#[serde(rename = "Queues")]
|
||||
queues: Vec<String>,
|
||||
#[serde(rename = "States")]
|
||||
states: Vec<String>,
|
||||
#[serde(rename = "OwnerIDs")]
|
||||
owners: Vec<u32>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize)]
|
||||
struct QueueResponse {
|
||||
#[serde(rename = "TicketID")]
|
||||
tickets: Vec<String>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize)]
|
||||
struct Credentials {
|
||||
#[serde(rename = "UserLogin")]
|
||||
user: String,
|
||||
#[serde(rename = "Password")]
|
||||
password: String,
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize)]
|
||||
struct TicketResponse {
|
||||
#[serde(rename = "Ticket")]
|
||||
ticket: Vec<Ticket>,
|
||||
}
|
||||
|
||||
impl From<Settings> for Credentials {
|
||||
fn from(settings: Settings) -> Self {
|
||||
Credentials {
|
||||
user: settings.user,
|
||||
password: settings.password,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Settings> for QueueRequest {
|
||||
fn from(settings: Settings) -> Self {
|
||||
QueueRequest {
|
||||
user: settings.user,
|
||||
password: settings.password,
|
||||
queues: settings
|
||||
.queues
|
||||
.split(", ")
|
||||
.into_iter()
|
||||
.map(|s| s.to_string())
|
||||
.collect(),
|
||||
states: vec!["open".to_owned(), "new".to_owned()],
|
||||
owners: settings
|
||||
.owners
|
||||
.split(", ")
|
||||
.into_iter()
|
||||
.map(|id| id.parse().unwrap())
|
||||
.collect(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Settings {
|
||||
fn get() -> Result<Self> {
|
||||
let mut settings = Config::new();
|
||||
settings.merge(Environment::with_prefix("otrs"))?;
|
||||
let settings = settings.try_into()?;
|
||||
Ok(settings)
|
||||
}
|
||||
}
|
||||
|
||||
struct OTRSSync {
|
||||
client: Client,
|
||||
settings: Settings,
|
||||
}
|
||||
|
||||
impl OTRSSync {
|
||||
fn new() -> Result<Self> {
|
||||
Ok(OTRSSync {
|
||||
client: Client::new(),
|
||||
settings: Settings::get()?,
|
||||
})
|
||||
}
|
||||
|
||||
fn get_ids(&self) -> Result<Vec<String>> {
|
||||
let mut builder = self.client.post(&self.queue_url());
|
||||
let request_body = QueueRequest::from(self.settings.clone());
|
||||
builder.json(&request_body);
|
||||
let mut response = builder.send()?;
|
||||
let response = response.json::<QueueResponse>()?;
|
||||
Ok(response.tickets)
|
||||
}
|
||||
|
||||
fn get_ticket(&self, id: String) -> Result<Ticket> {
|
||||
let mut builder = self.client.post(&self.ticket_url(id));
|
||||
let request_body = Credentials::from(self.settings.clone());
|
||||
builder.json(&request_body);
|
||||
let mut response = builder.send()?;
|
||||
let response = response.json::<TicketResponse>()?;
|
||||
Ok(response.ticket.into_iter().next().chain_err(
|
||||
|| "No Tickets",
|
||||
)?)
|
||||
}
|
||||
|
||||
fn queue_url(&self) -> String {
|
||||
self.base_url() + "TicketSearch"
|
||||
}
|
||||
|
||||
fn base_url(&self) -> String {
|
||||
format!(
|
||||
"https://{}/otrs/nph-genericinterface.pl/Webservice/GenericConnector/",
|
||||
&self.settings.host
|
||||
)
|
||||
}
|
||||
|
||||
fn ticket_url(&self, id: String) -> String {
|
||||
self.base_url() + "TicketGet/" + &id
|
||||
}
|
||||
|
||||
fn get_tickets(&self) -> Result<Vec<Ticket>> {
|
||||
self.get_ids()?
|
||||
.into_iter()
|
||||
.map(|id| self.get_ticket(id))
|
||||
.collect()
|
||||
}
|
||||
}
|
||||
|
||||
pub fn sync_otrs(cache: &mut TaskCache) -> Result<()> {
|
||||
let sync = OTRSSync::new()?;
|
||||
let tickets = sync.get_tickets()?;
|
||||
let tasks = tickets.into_iter().map(|ticket| {
|
||||
let mut t = TaskBuilder::default()
|
||||
.description(format!("CDA: {}: {}", ticket.customer, ticket.title))
|
||||
.build()
|
||||
.expect("TaskBuilding failed inspite of set description");
|
||||
t.set_gen_name(Some("cda-otrs"));
|
||||
t.set_gen_id(Some(ticket.number.to_string()));
|
||||
t
|
||||
});
|
||||
cache.generate(tasks)?;
|
||||
cache.write()?;
|
||||
Ok(())
|
||||
}
|
|
@ -5,7 +5,7 @@ in {
|
|||
# channel = 18.03
|
||||
|
||||
imports = [
|
||||
<home-manager/nixos>
|
||||
/home/maralorn/git/home-manager/nixos
|
||||
../common
|
||||
./modules/laptop.nix
|
||||
./modules/server
|
||||
|
|
Loading…
Reference in a new issue