Restructure project

This commit is contained in:
James Booth
2016-11-13 17:01:39 +00:00
parent 5eea0240ad
commit cdb6cd93b5
20 changed files with 0 additions and 27 deletions

16
development/ChatStart.rb Normal file
View File

@@ -0,0 +1,16 @@
module ChatStart
@@starts = {
"prof1@panesar" => [ "\"Prof 2\"", "prof3@panesar" ],
"prof2@panesar" => [ "prof1@panesar" ]
}
def self.prof_on_connect(account_name, fulljid)
if @@starts[account_name]
@@starts[account_name].each { | contact |
Prof::send_line("/msg " + contact)
}
Prof::send_line("/win 1")
end
end
end

View File

@@ -0,0 +1,51 @@
import prof
from chatterbotapi import ChatterBotFactory, ChatterBotType
factory = ChatterBotFactory()
bot = factory.create(ChatterBotType.CLEVERBOT)
# bot = factory.create(ChatterBotType.JABBERWACKY)
# bot = factory.create(ChatterBotType.PANDORABOTS, 'b0dafd24ee35a477')
bot_session = {}
bot_state = False
def prof_post_chat_message_display(barejid, resource, message):
if bot_state:
if barejid not in bot_session:
bot_session[barejid] = bot.create_session()
response = bot_session[barejid].think(message)
prof.send_line("/msg " + barejid + " " + response)
def _cmd_chatterbot(state):
global bot_state
if state == "enable":
prof.cons_show("ChatterBot Activated")
bot_state = True
elif state == "disable":
prof.cons_show("ChatterBot Stopped")
bot_state = False
else:
if bot_state:
prof.cons_show("ChatterBot is running - current sessions:")
prof.cons_show(str(bot_session))
else:
prof.cons_show("ChatterBot is stopped - /chatterbot enable to activate.")
def prof_init(version, status, account_name, fulljid):
synopsis = [
"/chatterbot",
"/chatterbot enable|disable"
]
description = "ChatterBot, running with no args will show the current chatterbot status"
args = [
[ "enable", "Enable chatterbot" ],
[ "disable", "Disable chatterbot" ]
]
examples = []
prof.register_command("/chatterbot", 0, 1, synopsis, description, args, examples, _cmd_chatterbot)
prof.completer_add("/chatterbot", [ "enable", "disable" ])

View File

@@ -0,0 +1,190 @@
import re
import sys
import hashlib
if sys.version_info >= (3, 0):
from urllib.request import build_opener, HTTPCookieProcessor, urlopen
from urllib.parse import urlencode
import http.cookiejar as cookielib
else:
from urllib import urlencode, urlopen
from urllib2 import build_opener, HTTPCookieProcessor
import cookielib
import uuid
import xml.dom.minidom
"""
chatterbotapi
Copyright (C) 2011 pierredavidbelanger@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
"""
#################################################
# API
#################################################
class ChatterBotType:
CLEVERBOT = 1
JABBERWACKY = 2
PANDORABOTS = 3
class ChatterBotFactory:
def create(self, type, arg = None):
if type == ChatterBotType.CLEVERBOT:
return _Cleverbot('http://www.cleverbot.com', 'http://www.cleverbot.com/webservicemin', 35)
elif type == ChatterBotType.JABBERWACKY:
return _Cleverbot('http://jabberwacky.com', 'http://jabberwacky.com/webservicemin', 29)
elif type == ChatterBotType.PANDORABOTS:
if arg == None:
raise Exception('PANDORABOTS needs a botid arg')
return _Pandorabots(arg)
return None
class ChatterBot:
def create_session(self):
return None
class ChatterBotSession:
def think_thought(self, thought):
return thought
def think(self, text):
thought = ChatterBotThought()
thought.text = text
return self.think_thought(thought).text
class ChatterBotThought:
pass
#################################################
# Cleverbot impl
#################################################
class _Cleverbot(ChatterBot):
def __init__(self, baseUrl, serviceUrl, endIndex):
self.baseUrl = baseUrl
self.serviceUrl = serviceUrl
self.endIndex = endIndex
def create_session(self):
return _CleverbotSession(self)
class _CleverbotSession(ChatterBotSession):
def __init__(self, bot):
self.bot = bot
self.vars = {}
self.vars['start'] = 'y'
self.vars['icognoid'] = 'wsf'
self.vars['fno'] = '0'
self.vars['sub'] = 'Say'
self.vars['islearning'] = '1'
self.vars['cleanslate'] = 'false'
self.cookieJar = cookielib.CookieJar()
self.opener = build_opener(HTTPCookieProcessor(self.cookieJar))
self.opener.open(self.bot.baseUrl)
def think_thought(self, thought):
self.vars['stimulus'] = thought.text
data = urlencode(self.vars)
data_to_digest = data[9:self.bot.endIndex]
data_digest = hashlib.md5(data_to_digest.encode('utf-8')).hexdigest()
data = data + '&icognocheck=' + data_digest
url_response = self.opener.open(self.bot.serviceUrl, data.encode('utf-8'))
response = str(url_response.read())
response_values = re.split(r'\\r|\r', response)
#self.vars['??'] = _utils_string_at_index(response_values, 0)
self.vars['sessionid'] = _utils_string_at_index(response_values, 1)
self.vars['logurl'] = _utils_string_at_index(response_values, 2)
self.vars['vText8'] = _utils_string_at_index(response_values, 3)
self.vars['vText7'] = _utils_string_at_index(response_values, 4)
self.vars['vText6'] = _utils_string_at_index(response_values, 5)
self.vars['vText5'] = _utils_string_at_index(response_values, 6)
self.vars['vText4'] = _utils_string_at_index(response_values, 7)
self.vars['vText3'] = _utils_string_at_index(response_values, 8)
self.vars['vText2'] = _utils_string_at_index(response_values, 9)
self.vars['prevref'] = _utils_string_at_index(response_values, 10)
#self.vars['??'] = _utils_string_at_index(response_values, 11)
self.vars['emotionalhistory'] = _utils_string_at_index(response_values, 12)
self.vars['ttsLocMP3'] = _utils_string_at_index(response_values, 13)
self.vars['ttsLocTXT'] = _utils_string_at_index(response_values, 14)
self.vars['ttsLocTXT3'] = _utils_string_at_index(response_values, 15)
self.vars['ttsText'] = _utils_string_at_index(response_values, 16)
self.vars['lineRef'] = _utils_string_at_index(response_values, 17)
self.vars['lineURL'] = _utils_string_at_index(response_values, 18)
self.vars['linePOST'] = _utils_string_at_index(response_values, 19)
self.vars['lineChoices'] = _utils_string_at_index(response_values, 20)
self.vars['lineChoicesAbbrev'] = _utils_string_at_index(response_values, 21)
self.vars['typingData'] = _utils_string_at_index(response_values, 22)
self.vars['divert'] = _utils_string_at_index(response_values, 23)
response_thought = ChatterBotThought()
response_thought.text = _utils_string_at_index(response_values, 16)
return response_thought
#################################################
# Pandorabots impl
#################################################
class _Pandorabots(ChatterBot):
def __init__(self, botid):
self.botid = botid
def create_session(self):
return _PandorabotsSession(self)
class _PandorabotsSession(ChatterBotSession):
def __init__(self, bot):
self.vars = {}
self.vars['botid'] = bot.botid
self.vars['custid'] = uuid.uuid1()
def think_thought(self, thought):
self.vars['input'] = thought.text
data = urlencode(self.vars)
url_response = urlopen('http://www.pandorabots.com/pandora/talk-xml', data)
response = url_response.read()
response_dom = xml.dom.minidom.parseString(response)
response_thought = ChatterBotThought()
that_elements = response_dom.getElementsByTagName('that')
if that_elements is None or len(that_elements) == 0 or that_elements[0] is None:
return ''
that_elements_child_nodes = that_elements[0].childNodes
if that_elements_child_nodes is None or len(that_elements_child_nodes) == 0 or that_elements_child_nodes[0] is None:
return ''
that_elements_child_nodes_data = that_elements_child_nodes[0].data
if that_elements_child_nodes_data is None:
return ''
response_thought.text = that_elements_child_nodes_data.strip()
return response_thought
#################################################
# Utils
#################################################
def _utils_string_at_index(strings, index):
if len(strings) > index:
return strings[index]
else:
return ''

531
development/jenkins.py Normal file
View File

@@ -0,0 +1,531 @@
"""
Manage jenkins jobs
Prerequisites:
The jenkinsapi module is required https://pypi.python.org/pypi/jenkinsapi
To install the module using pip:
sudo pip install jenkinsapi
The plugin polls the jenkins server at 'jenkins_url' every 'jenkins_poll_interval' seconds.
The results are checked by profanity every 'prof_cb_interval'.
New failures are reported in the jenkins window, and a desktop notification is sent.
The 'prof_remind_interval' specifies the time between reminder notifications of broken builds
"""
import prof
import os
import threading
import time
import webbrowser
import urllib2
import base64
import jenkinsapi
from jenkinsapi.jenkins import Jenkins
# Settings
jenkins_url = "http://localhost:8080"
username = None
password = None
jenkins_poll_interval = 5
prof_cb_interval = 5
prof_remind_interval = 10
enable_notify = True
enable_remind = True
# Global state
last_state = {}
STATE_SUCCESS = "SUCCESS"
STATE_UNSTABLE = "UNSTABLE"
STATE_FAILURE = "FAILURE"
STATE_QUEUED = "QUEUED"
STATE_RUNNING = "RUNNING"
STATE_NOBUILDS = "NOBUILDS"
STATE_UNKNOWN = "UNKNOWN"
win_tag = "Jenkins"
poll_fail = False
poll_fail_message = None
job_list = None
changes_list = None
def _help():
prof.win_show(win_tag, "Commands:")
prof.win_show(win_tag, " /jenkins help - Show this help")
prof.win_show(win_tag, " /jenkins jobs - List all jobs")
prof.win_show(win_tag, " /jenkins failing - List all failing jobs")
prof.win_show(win_tag, " /jenkins passing - List all passing jobs")
prof.win_show(win_tag, " /jenkins unstable - List all unstable jobs")
prof.win_show(win_tag, " /jenkins build [job] - Trigger build for job")
prof.win_show(win_tag, " /jenkins open [job] - Open job in browser")
prof.win_show(win_tag, " /jenkins log [job] - Show the latest build log")
prof.win_show(win_tag, " /jenkins remind on|off - Enable/disable reminder notifications")
prof.win_show(win_tag, " /jenkins notify on|off - Enable/disable build notifications")
prof.win_show(win_tag, " /jenkins settings - Show current settings")
def _settings():
prof.win_show(win_tag, "Jenkins settings:")
prof.win_show(win_tag, " Jenkins URL : " + jenkins_url)
prof.win_show(win_tag, " Jenkins poll interval : " + str(jenkins_poll_interval) + " seconds")
prof.win_show(win_tag, " Profanity update interval : " + str(prof_cb_interval) + " seconds")
prof.win_show(win_tag, " Reminder interval : " + str(prof_remind_interval) + " seconds")
prof.win_show(win_tag, " Notifications enabled : " + str(enable_notify))
prof.win_show(win_tag, " Reminders enabled : " + str(enable_remind))
def _safe_remove(jobname, state):
if jobname in last_state[state]:
last_state[state].remove(jobname)
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 _open_job_url(url):
savout = os.dup(1)
saverr = os.dup(2)
os.close(1)
os.close(2)
os.open(os.devnull, os.O_RDWR)
try:
webbrowser.open(url, new=2)
finally:
os.dup2(savout, 1)
os.dup2(saverr, 2)
class JobList():
def __init__(self):
self.jobs = []
def add_job(self, name, build_number, state):
self.jobs.append((name, build_number, state))
def get_jobs(self, in_state=None):
if not in_state:
return self.jobs
else:
result = []
for name, build_number, state in self.jobs:
if state == in_state:
result.append((name, build_number, state))
return result
def get_job(self, jobname):
for name, build_number, state in self.jobs:
if name == jobname:
return name, build_number
return None
def contains_job(self, jobname):
for name, build_number, state in self.jobs:
if name == jobname:
return True
return False
def num_in_state(self, given_state):
count = 0
for name, build_number, state in self.jobs:
if state == given_state:
count = count + 1
return count
class JobUpdates():
def __init__(self):
self.states = {}
self.states[STATE_FAILURE] = []
self.states[STATE_SUCCESS] = []
self.states[STATE_UNSTABLE] = []
self.states[STATE_QUEUED] = []
self.states[STATE_RUNNING] = []
def add_update(self, state, name, build_number=None):
if build_number:
self.states[state].append((name, build_number))
else:
self.states[state].append(name)
def get_in_state(self, state):
return self.states[state]
def _process_build(name, build, new_job_list, new_changes_list):
if build.get_status() == STATE_FAILURE:
new_job_list.add_job(name, build.get_number(), STATE_FAILURE)
changed = _set_state(name, STATE_FAILURE)
if changed:
new_changes_list.add_update(STATE_FAILURE, name, build.get_number())
elif build.get_status() == STATE_SUCCESS:
new_job_list.add_job(name, build.get_number(), STATE_SUCCESS)
changed = _set_state(name, STATE_SUCCESS)
if changed:
new_changes_list.add_update(STATE_SUCCESS, name, build.get_number())
elif build.get_status() == STATE_UNSTABLE:
new_job_list.add_job(name, build.get_number(), STATE_UNSTABLE)
changed = _set_state(name, STATE_UNSTABLE)
if changed:
new_changes_list.add_update(STATE_UNSTABLE, name, build.get_number())
def _process_queued_or_running(name, job, new_job_list, new_changes_list):
if job.is_queued():
new_job_list.add_job(name, None, STATE_QUEUED)
changed = _set_state(name, STATE_QUEUED)
if changed:
new_changes_list.add_update(STATE_QUEUED, name)
elif job.is_running():
new_job_list.add_job(name, None, STATE_RUNNING)
changed = _set_state(name, STATE_RUNNING)
if changed:
new_changes_list.add_update(STATE_RUNNING, name)
def _jenkins_poll():
global poll_fail
global poll_fail_message
global job_list
global changes_list
job_ac = []
while True:
time.sleep(jenkins_poll_interval)
try:
j = Jenkins(jenkins_url, username, password)
except Exception, e:
poll_fail = True
poll_fail_message = str(e)
else:
poll_fail = False
poll_fail_message = None
new_job_list = JobList()
new_changes_list = JobUpdates()
for name, job in j.get_jobs():
if not job.is_queued_or_running():
build = job.get_last_build_or_none()
if build:
_process_build(name, build, new_job_list, new_changes_list)
else:
new_job_list.add_job(name, None, STATE_NOBUILDS)
else:
_process_queued_or_running(name, job, new_job_list, new_changes_list)
if not job_list:
job_ac.append(name)
if not job_list:
prof.completer_add("/jenkins build", job_ac)
prof.completer_add("/jenkins open", job_ac)
prof.completer_add("/jenkins log", job_ac)
job_list = new_job_list
changes_list = new_changes_list
def _prof_callback():
global changes_list
if poll_fail:
if not prof.win_exists(win_tag):
prof.win_create(win_tag, _handle_input)
prof.win_show(win_tag, "Could not connect to jenkins, see the logs.")
if poll_fail_message:
prof.log_warning("Jenkins poll failed: " + str(poll_fail_message))
else:
prof.log_warning("Jenkins poll failed")
elif changes_list:
for name in changes_list.get_in_state(STATE_QUEUED):
if not prof.win_exists(win_tag):
prof.win_create(win_tag, _handle_input)
prof.win_show_themed(win_tag, None, None, "cyan", name + " " + STATE_QUEUED)
for name in changes_list.get_in_state(STATE_RUNNING):
if not prof.win_exists(win_tag):
prof.win_create(win_tag, _handle_input)
prof.win_show_themed(win_tag, None, None, "cyan", name + " " + STATE_RUNNING)
for name, build_number in changes_list.get_in_state(STATE_SUCCESS):
if not prof.win_exists(win_tag):
prof.win_create(win_tag, _handle_input)
prof.win_show_themed(win_tag, None, None, "green", name + " #" + str(build_number) + " " + STATE_SUCCESS)
if enable_notify:
prof.notify(name + " " + STATE_SUCCESS, 5000, "Jenkins")
for name, build_number in changes_list.get_in_state(STATE_UNSTABLE):
if not prof.win_exists(win_tag):
prof.win_create(win_tag, _handle_input)
prof.win_show_themed(win_tag, None, None, "yellow", name + " #" + str(build_number) + " " + STATE_UNSTABLE)
if enable_notify:
prof.notify(name + " " + STATE_UNSTABLE, 5000, "Jenkins")
for name, build_number in changes_list.get_in_state(STATE_FAILURE):
if not prof.win_exists(win_tag):
prof.win_create(win_tag, _handle_input)
prof.win_show_themed(win_tag, None, None, "red", name + " #" + str(build_number) + " " + STATE_FAILURE)
if enable_notify:
prof.notify(name + " " + STATE_FAILURE, 5000, "Jenkins")
changes_list = None
def _handle_input(win, line):
pass
def _list_jobs(jobs):
for name, build_number, state in jobs:
if state == STATE_SUCCESS:
prof.win_show_themed(win_tag, None, None, "green", " " + name + " #" + str(build_number) + " " + STATE_SUCCESS)
elif state == STATE_UNSTABLE:
prof.win_show_themed(win_tag, None, None, "yellow", " " + name + " #" + str(build_number) + " " + STATE_UNSTABLE)
elif state == STATE_FAILURE:
prof.win_show_themed(win_tag, None, None, "red", " " + name + " #" + str(build_number) + " " + STATE_FAILURE)
elif state == STATE_NOBUILDS:
prof.win_show(win_tag, " " + name + ", no builds")
else:
prof.win_show_themed(win_tag, None, None, "cyan", " " + name + " " + state)
def _build_job(job):
try:
request = urllib2.Request(jenkins_url + "/job/" + job + "/build");
if username:
basicauth = base64.encodestring("%s:%s" %(username, password)).replace("\n", "")
request.add_header("Authorization", "Basic %s" %basicauth);
request.add_data("")
urllib2.urlopen(request)
except Exception, e:
prof.win_show(win_tag, "Failed to build " + job + ", see the logs.")
prof.log_warning("Failed to build " + job + ": " + str(e))
else:
prof.win_show(win_tag, "Build request sent for " + job)
def _job_log(job):
name = job[0]
build_no = job[1]
if build_no:
try:
response = urllib2.urlopen(jenkins_url + "/job/" + name + "/" + str(build_no) + "/consoleText")
except Exception, e:
prof.win_show(win_tag, "Unable to fetch log for " + name + "#" + str(build_no) + ", see the logs.")
prof.log_warning("Unable to fetch log for " + name + "#" + str(build_no) + ": " + str(e))
else:
log_str = "Log for " + name + " #" + str(build_no) + ":\n" + response.read()
prof.win_show(win_tag, log_str)
else:
prof.win_show(win_tag, "No build found for " + name)
def _cmd_jenkins(cmd=None, arg=None):
global enable_remind
global enable_notify
if not prof.win_exists(win_tag):
prof.win_create(win_tag, _handle_input)
prof.win_focus(win_tag)
if cmd == "jobs":
if job_list and job_list.get_jobs():
prof.win_show(win_tag, "Jobs:")
_list_jobs(job_list.get_jobs())
else:
prof.win_show(win_tag, "No job data yet.")
elif cmd == "failing":
if job_list:
jobs_in_state = job_list.get_jobs(STATE_FAILURE)
if jobs_in_state:
prof.win_show(win_tag, "Failing jobs:")
_list_jobs(jobs_in_state)
else:
prof.win_show(win_tag, "No failing jobs.")
else:
prof.win_show(win_tag, "No job data yet.")
elif cmd == "passing":
if job_list:
jobs_in_state = job_list.get_jobs(STATE_SUCCESS)
if jobs_in_state:
prof.win_show(win_tag, "Passing jobs:")
_list_jobs(jobs_in_state)
else:
prof.win_show(win_tag, "No passing jobs.")
else:
prof.win_show(win_tag, "No job data yet.")
elif cmd == "unstable":
if job_list:
jobs_in_state = job_list.get_jobs(STATE_UNSTABLE)
if jobs_in_state:
prof.win_show(win_tag, "Unstable jobs:")
_list_jobs(jobs_in_state)
else:
prof.win_show(win_tag, "No unstable jobs.")
else:
prof.win_show(win_tag, "No job data yet.")
elif cmd == "build":
if not arg:
prof.win_show(win_tag, "You must supply a job argument.")
elif job_list and job_list.contains_job(arg):
_build_job(arg)
else:
prof.win_show(win_tag, "No such job: " + arg)
elif cmd == "open":
if not arg:
prof.win_show(win_tag, "You must supply a job argument.")
elif job_list and job_list.contains_job(arg):
_open_job_url(jenkins_url + "/job/" + arg)
else:
prof.win_show(win_tag, "No such job: " + arg)
elif cmd == "remind":
if not arg:
prof.win_show(win_tag, "You must specify either 'on' or 'off'.")
elif arg == "on":
enable_remind = True
prof.win_show(win_tag, "Reminder notifications enabled.")
elif arg == "off":
enable_remind = False
prof.win_show(win_tag, "Reminder notifications disabled.")
else:
prof.win_show(win_tag, "You must specify either 'on' or 'off'.")
elif cmd == "notify":
if not arg:
prof.win_show(win_tag, "You must specify either 'on' or 'off'.")
elif arg == "on":
enable_notify = True
prof.win_show(win_tag, "Build notifications enabled.")
elif arg == "off":
enable_notify = False
prof.win_show(win_tag, "Build notifications disabled.")
else:
prof.win_show(win_tag, "You must specify either 'on' or 'off'.")
elif cmd == "settings":
_settings()
elif cmd == "help":
_help()
elif cmd == "log":
if not arg:
prof.win_show(win_tag, "You must specify a job.")
else:
job = job_list.get_job(arg)
if job:
_job_log(job)
else:
prof.win_show(win_tag, "No job found: " + arg)
else:
prof.win_show(win_tag, "Unknown command.")
def _remind():
if enable_remind and job_list:
notify_string = ""
failing = job_list.num_in_state(STATE_FAILURE)
unstable = job_list.num_in_state(STATE_UNSTABLE)
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 prof_init(version, status, account_name, fulljid):
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] = []
jenkins_t = threading.Thread(target=_jenkins_poll)
jenkins_t.daemon = True;
jenkins_t.start()
prof.register_timed(_prof_callback, prof_cb_interval)
prof.register_timed(_remind, prof_remind_interval)
prof.completer_add(
"/jenkins", [
"help",
"jobs",
"failing",
"passing",
"unstable",
"build",
"open",
"log",
"remind",
"notify",
"settings"
]
);
prof.completer_add(
"/jenkins remind", [
"on",
"off"
]
);
prof.completer_add(
"/jenkins notify", [
"on",
"off"
]
);
synopsis = [
"/jenkins jobs|failing|passing|unstable",
"/jenkins build <job>",
"/jenkins open <job>",
"/jenkins log <job>",
"/jenkins remind on|off",
"/jenkins notify on|off",
"/jenkins settings"
]
description = "Monitor, run and view Jenkins jobs."
args = [
[ "jobs", "List all jobs" ],
[ "failing", "List all failing jobs" ],
[ "passing", "List all passing jobs" ],
[ "unstable", "List all unstable jobs" ],
[ "build <job>", "Trigger build for job" ],
[ "open <job>", "Open job in browser" ],
[ "log <job>", "Show the latest build log for job" ],
[ "remind on|off", "Enable/disable reminder notifications" ],
[ "notify on|off", "Enable/disable build notifications" ],
[ "settings", "Show current settings" ]
]
examples = [
"/kenkins failing",
"/kenkins build stabber-build",
"/kenkins remind off"
]
prof.register_command("/jenkins", 0, 2, synopsis, description, args, examples, _cmd_jenkins)
def prof_on_start():
prof.win_create(win_tag, _handle_input)
prof.win_show(win_tag, "Jenkins plugin started.")