From ea7cb09ffc418c1506ce93e5a77587114d1b8792 Mon Sep 17 00:00:00 2001 From: James Booth Date: Sun, 8 Jun 2014 18:38:57 +0100 Subject: [PATCH] Updated jenkins plugin, added say.py --- jenkins.py | 291 +++++++++++++++++++++++++++++++++++------------------ say.py | 14 +++ 2 files changed, 206 insertions(+), 99 deletions(-) create mode 100644 say.py diff --git a/jenkins.py b/jenkins.py index 944db57..1510940 100644 --- a/jenkins.py +++ b/jenkins.py @@ -30,18 +30,23 @@ import jenkinsapi from jenkinsapi.jenkins import Jenkins win_tag = "Jenkins" -poll_interval = 5 +poll_interval = 10 remind_interval = 60 * 15 +enable_remind = True jenkins_url = "http://localhost:8080" username = None password = None -failing = [] -passing = [] +last_state = {} +STATE_SUCCESS = "SUCCESS" +STATE_UNSTABLE = "UNSTABLE" +STATE_FAILURE = "FAILURE" +STATE_QUEUED = "QUEUED" +STATE_RUNNING = "RUNNING" +STATE_NOBUILDS = "NOBUILDS" +STATE_UNKNOWN = "UNKNOWN" def _show_help(): - global win_tag - prof.win_show(win_tag, "Commands:") prof.win_show(win_tag, " /jenkins help - Show this help") prof.win_show(win_tag, " /jenkins list - List all jobs") @@ -62,37 +67,70 @@ def _open_job_url(url): os.dup2(savout, 1) os.dup2(saverr, 2) -def _list_jobs(j): - global win_tag +def _safe_remove(jobname, state): + if jobname in last_state[state]: + last_state[state].remove(jobname) - if len(j.keys()) == 0: - prof.win_show(win_tag, "No jobs available") +def _set_state(jobname, state): + if not jobname in last_state[state]: + _safe_remove(jobname, STATE_SUCCESS) + _safe_remove(jobname, STATE_UNSTABLE) + _safe_remove(jobname, STATE_FAILURE) + _safe_remove(jobname, STATE_QUEUED) + _safe_remove(jobname, STATE_RUNNING) + _safe_remove(jobname, STATE_NOBUILDS) + _safe_remove(jobname, STATE_UNKNOWN) + last_state[state].append(jobname) + return True + else: + return False + +def _list_jobs(): + try: + j = Jenkins(jenkins_url, username, password) + except Exception, e: + prof.log_warning("Could not connect to jenkins: " + str(e)) + prof.win_show(win_tag, "Could not connect to Jenkins.") prof.win_show(win_tag, "") else: - prof.win_show(win_tag, "Jobs:") - for name, job in j.get_jobs(): - if job.is_queued(): - prof.win_show_cyan(win_tag, " " + name + ", QUEUED") - elif job.is_running(): - prof.win_show_cyan(win_tag, " " + name + ", RUNNING") - else: - build = job.get_last_build_or_none() - if build: - if build.get_status() == "FAILURE": - prof.win_show_red(win_tag, " " + name + " #" + str(build.get_number()) + ", " + build.get_status()) - elif build.get_status() == "SUCCESS": - prof.win_show_green(win_tag, " " + name + " #" + str(build.get_number()) + ", " + build.get_status()) - else: - prof.win_show_cyan(win_tag, " " + name + " #" + str(build.get_number()) + ", " + build.get_status()) + if len(j.keys()) == 0: + prof.win_show(win_tag, "No jobs available") + prof.win_show(win_tag, "") + else: + prof.win_show(win_tag, "Jobs:") + for name, job in j.get_jobs(): + if job.is_queued(): + _set_state(name, STATE_QUEUED) + prof.win_show_cyan(win_tag, " " + name + ", QUEUED") + elif job.is_running(): + _set_state(name, STATE_RUNNING) + prof.win_show_cyan(win_tag, " " + name + ", RUNNING") else: - prof.win_show(win_tag, " " + name + ", no builds") - prof.win_show(win_tag, "") + build = job.get_last_build_or_none() + if build: + if build.get_status() == "FAILURE": + _set_state(name, STATE_FAILURE) + prof.win_show_red(win_tag, " " + name + " #" + str(build.get_number()) + ", " + build.get_status()) + elif build.get_status() == "SUCCESS": + _set_state(name, STATE_SUCCESS) + prof.win_show_green(win_tag, " " + name + " #" + str(build.get_number()) + ", " + build.get_status()) + elif build.get_status() == "UNSTABLE": + _set_state(name, STATE_UNSTABLE) + prof.win_show_yellow(win_tag, " " + name + " #" + str(build.get_number()) + ", " + build.get_status()) + else: + _set_state(name, STATE_UNKNOWN) + prof.win_show_cyan(win_tag, " " + name + " #" + str(build.get_number()) + ", " + build.get_status()) + else: + _set_state(name, STATE_NOBUILDS) + prof.win_show(win_tag, " " + name + ", no builds") + prof.win_show(win_tag, "") -def _show_job(j, jobname=None): - global win_tag - - if not jobname: - prof.win_show(win_tag, "Usage: show [job]") +def _show_job(jobname): + try: + j = Jenkins(jenkins_url, username, password) + except Exception, e: + prof.log_warning("Could not connect to jenkins: " + str(e)) + prof.win_show(win_tag, "Could not connect to Jenkins.") prof.win_show(win_tag, "") else: if j.has_job(jobname): @@ -104,20 +142,29 @@ def _show_job(j, jobname=None): prof.win_show(win_tag, " Description : " + desc) if job.is_queued(): + _set_state(jobname, STATE_QUEUED) prof.win_show_cyan(win_tag, " Status : Queued") elif job.is_running(): + _set_state(jobname, STATE_RUNNING) prof.win_show_cyan(win_tag, " Status : Running") else: build = job.get_last_build_or_none() if build: prof.win_show(win_tag, " Last build : #" + str(build.get_number())) if build.get_status() == "FAILURE": + _set_state(jobname, STATE_FAILURE) prof.win_show_red(win_tag, " Status : " + build.get_status()) elif build.get_status() == "SUCCESS": + _set_state(jobname, STATE_SUCCESS) prof.win_show_green(win_tag, " Status : " + build.get_status()) + elif build.get_status() == "UNSTABLE": + _set_state(jobname, STATE_UNSTABLE) + prof.win_show_yellow(win_tag, " Status : " + build.get_status()) else: + _set_state(jobname, STATE_UNKNOWN) prof.win_show_cyan(win_tag, " Status : " + build.get_status()) else: + _set_state(jobname, STATE_NOBUILDS) prof.win_show(win_tag, " Last build : No builds") prof.win_show(win_tag, " Trigger : " + job.get_build_triggerurl()) @@ -126,11 +173,12 @@ def _show_job(j, jobname=None): prof.win_show(win_tag, "No such job " + jobname) prof.win_show(win_tag, "") -def _build_job(j, jobname): - global win_tag - - if not jobname: - prof.win_show(win_tag, "Usage: build [job]") +def _build_job(jobname): + try: + j = Jenkins(jenkins_url, username, password) + except Exception, e: + prof.log_warning("Could not connect to jenkins: " + str(e)) + prof.win_show(win_tag, "Could not connect to Jenkins.") prof.win_show(win_tag, "") else: if j.has_job(jobname): @@ -138,78 +186,100 @@ def _build_job(j, jobname): try: job.invoke(invoke_pre_check_delay=1) except Exception, e: - prof.win_show(win_tag, "Failed to trigger build: " + str(e)) + prof.log_warning("Failed to trigger build: " + str(e)) + prof.win_show(win_tag, "Failed to trigger build.") prof.win_show(win_tag, "") else: prof.win_show(win_tag, "No such job " + jobname) prof.win_show(win_tag, "") -def _open_job(j, jobname): - global win_tag - - if not jobname: - prof.win_show(win_tag, "Usage: open [job]") +def _open_job(jobname): + try: + j = Jenkins(jenkins_url, username, password) + except Exception, e: + prof.log_warning("Could not connect to jenkins: " + str(e)) + prof.win_show(win_tag, "Could not connect to Jenkins.") prof.win_show(win_tag, "") else: - if j.has_job(jobname): - _open_job_url(jenkins_url + "/job/" + jobname) - else: - prof.win_show(win_tag, "No such job " + jobname) + if not jobname: + prof.win_show(win_tag, "Usage: open [job]") prof.win_show(win_tag, "") + else: + if j.has_job(jobname): + _open_job_url(jenkins_url + "/job/" + jobname) + else: + prof.win_show(win_tag, "No such job " + jobname) + prof.win_show(win_tag, "") def _process_job(name, job): - global failing - global passing - global win_tag - if not job.is_queued_or_running(): build = job.get_last_build_or_none() if build: if build.get_status() == "FAILURE": - if not name in failing: - prof.win_show_red(win_tag, name + " #" + str(build.get_number()) + " BROKEN") + changed = _set_state(name, STATE_FAILURE) + if changed: + prof.win_show_red(win_tag, name + " #" + str(build.get_number()) + " FAILURE") prof.win_show(win_tag, "") - prof.notify(name + " BROKEN", 5000, "Jenkins") - failing.append(name) - if name in passing: - passing.remove(name) - else: - if name in failing: - prof.win_show_green(win_tag, name + " #" + str(build.get_number()) + " FIXED") + prof.notify(name + " FAILURE", 5000, "Jenkins") + elif build.get_status() == "SUCCESS": + changed = _set_state(name, STATE_SUCCESS) + if changed: + prof.win_show_green(win_tag, name + " #" + str(build.get_number()) + " SUCCESS") prof.win_show(win_tag, "") - prof.notify(name + " FIXED", 5000, "Jenkins") - failing.remove(name) - if not name in passing: - passing.append(name) + prof.notify(name + " SUCCESS", 5000, "Jenkins") + elif build.get_status() == "UNSTABLE": + changed = _set_state(name, STATE_UNSTABLE) + if changed: + prof.win_show_yellow(win_tag, name + " #" + str(build.get_number()) + " UNSTABLE") + prof.win_show(win_tag, "") + prof.notify(name + " UNSTABLE", 5000, "Jenkins") + else: + if job.is_queued(): + changed = _set_state(name, STATE_QUEUED) + if changed: + prof.win_show_cyan(win_tag, name + " QUEUED") + prof.win_show(win_tag, "") + elif job.is_running(): + changed = _set_state(name, STATE_RUNNING) + if changed: + prof.win_show_cyan(win_tag, name + " RUNNING") + prof.win_show(win_tag, "") def _remind(): - global failing + if enable_remind: + notify_string = "" + failing = len(last_state[STATE_FAILURE]) + unstable = len(last_state[STATE_UNSTABLE]) - if len(failing) == 1: - prof.notify("1 broken build", 5000, "Jenkins") - if len(failing) > 1: - prof.notify(str(len(failing)) + " broken builds", 5000, "Jenkins") + if failing == 1: + notify_string = notify_string + "1 failing build" + if failing > 1: + notify_string = notify_string + str(failing) + " failing builds" + + if failing > 0 and unstable > 0: + notify_string = notify_string + "\n" + + if unstable == 1: + notify_string = notify_string + "1 unstable build" + if unstable > 1: + notify_string = notify_string + str(unstable) + " unstable builds" + + if not notify_string == "": + prof.notify(notify_string, 5000, "Jenkins") def _poll_jobs(): - global jenkins_url - global username - global password - global win_tag - try: j = Jenkins(jenkins_url, username, password) - except Exception: - prof.win_show(win_tag, "Jenkins down") + except Exception, e: + prof.log_warning("Could not connect to jenkins: " + str(e)) + prof.win_show(win_tag, "Could not connect to Jenkins.") prof.win_show(win_tag, "") else: for name, job in j.get_jobs(): _process_job(name, job) -def _cmd_jenkins(cmd=None, jobname=None): - global jenkins_url - global username - global password - global win_tag +def _cmd_jenkins(cmd=None, arg=None): + global enable_remind if not prof.win_exists(win_tag): prof.win_create(win_tag, _handle_input) @@ -221,47 +291,70 @@ def _cmd_jenkins(cmd=None, jobname=None): else: try: j = Jenkins(jenkins_url, username, password) - except Exception: - prof.win_show(win_tag, "Jenkins down") + except Exception, e: + prof.log_warning("Could not connect to jenkins: " + str(e)) + prof.win_show(win_tag, "Could not connect to Jenkins.") prof.win_show(win_tag, "") else: if cmd == "help": _show_help() elif cmd == "list": - _list_jobs(j) + _list_jobs() elif cmd == "show": - _show_job(j, jobname) + if not arg: + prof.win_show(win_tag, "Usage: show [job]") + prof.win_show(win_tag, "") + else: + _show_job(arg) elif cmd == "build": - _build_job(j, jobname) + if not arg: + prof.win_show(win_tag, "Usage: build [job]") + prof.win_show(win_tag, "") + else: + _build_job(arg) elif cmd == "open": - _open_job(j, jobname) + if not arg: + prof.win_show(win_tag, "Usage: open [job]") + prof.win_show(win_tag, "") + else: + _open_job(arg) + elif cmd == "remind": + if not arg: + prof.win_show(win_tag, "Usage: remind on|off") + else: + if arg == "on": + enable_remind = True + prof.win_show(win_tag, "Reminders enabled.") + elif arg == "off": + enable_remind = False + prof.win_show(win_tag, "Reminders disabled.") + else: + prof.win_show(win_tag, "Usage: remind on|off") + prof.win_show(win_tag, "") else: - prof.win_show(win_tag, "Usage: list|show|build|open [job].") + prof.win_show(win_tag, "Usage: list|show|build|open|remind") prof.win_show(win_tag, "") def prof_init(version, status): - global poll_interval - global win_tag + last_state[STATE_SUCCESS] = [] + last_state[STATE_UNSTABLE] = [] + last_state[STATE_FAILURE] = [] + last_state[STATE_QUEUED] = [] + last_state[STATE_RUNNING] = [] + last_state[STATE_NOBUILDS] = [] + last_state[STATE_UNKNOWN] = [] if poll_interval > 0: prof.register_timed(_poll_jobs, poll_interval) if remind_interval > 0: prof.register_timed(_remind, remind_interval) - prof.register_command("/jenkins", 0, 2, "/jenkins list|show|build|open [job]", "Do jenkins stuff.", "Do jenkins stuff.", + prof.register_command("/jenkins", 0, 2, "/jenkins list|show|build|open|remind", "Do jenkins stuff.", "Do jenkins stuff.", _cmd_jenkins) def _handle_input(win, line): _show_help() def prof_on_start(): - global win_tag - prof.win_create(win_tag, _handle_input) _show_help() - - try: - j = Jenkins(jenkins_url, username, password) - except Exception: - prof.win_show(win_tag, "Jenkins down") - else: - _list_jobs(j) + _list_jobs() diff --git a/say.py b/say.py new file mode 100644 index 0000000..628a2f6 --- /dev/null +++ b/say.py @@ -0,0 +1,14 @@ +import prof +import os + +def prof_on_message_received(jid, message): + os.system("say \"" + jid + " says " + message + "\" 2>/dev/null") + return message + +def prof_on_room_message_received(room, nick, message): + os.system("say \"" + nick + " says " + message + " in " + room + "\" 2>/dev/null") + return message + +def prof_on_private_message_received(room, nick, message): + os.system("say \"" + nick + " says " + message + "\" 2>/dev/null") + return message