Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improved dictionary lookup #8

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
68 changes: 32 additions & 36 deletions retaliation.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,46 +13,46 @@
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
#

############################################################################
#
#
# RETALIATION - A Jenkins "Extreme Feedback" Contraption
#
# Lava Lamps are for pussies! Retaliate to a broken build with a barrage
# Lava Lamps are for pussies! Retaliate to a broken build with a barrage
# of foam missiles.
#
# Steps to use:
#
# 1. Mount your Dream Cheeky Thunder USB missile launcher in a central and
# 1. Mount your Dream Cheeky Thunder USB missile launcher in a central and
# fixed location.
#
# 2. Copy this script onto the system connected to your missile lanucher.
#
# 3. Modify your `COMMAND_SETS` in the `retaliation.py` script to define
# your targeting commands for each one of your build-braking coders
# (their user ID as listed in Jenkins). A command set is an array of
# move and fire commands. It is recommend to start each command set
# with a "zero" command. This parks the launcher in a known position
# (bottom-left). You can then use "up" and "right" followed by a
# 3. Modify your `COMMAND_SETS` in the `retaliation.py` script to define
# your targeting commands for each one of your build-braking coders
# (their user ID as listed in Jenkins). A command set is an array of
# move and fire commands. It is recommend to start each command set
# with a "zero" command. This parks the launcher in a known position
# (bottom-left). You can then use "up" and "right" followed by a
# time (in milliseconds) to position your fire.
#
# You can test a set by calling retaliation.py with the target name.
# e.g.:
#
# You can test a set by calling retaliation.py with the target name.
# e.g.:
#
# retaliation.py "[developer's user name]"
#
# Trial and error is the best approch. Consider doing this secretly
# Trial and error is the best approch. Consider doing this secretly
# after hours for best results!
#
# 4. Setup the Jenkins "notification" plugin. Define a UDP endpoint
# 4. Setup the Jenkins "notification" plugin. Define a UDP endpoint
# on port 22222 pointing to the system hosting this script.
# Tip: Make sure your firewall is not blocking UDP on this port.
#
# 5. Start listening for failed build events by running the command:
# retaliation.py stalk
# (Consider setting this up as a boot/startup script. On Windows
# start with pythonw.exe to keep it running hidden in the
# (Consider setting this up as a boot/startup script. On Windows
# start with pythonw.exe to keep it running hidden in the
# background.)
#
# 6. Wait for DEFCON 1 - Let the war games begin!
Expand All @@ -61,7 +61,7 @@
# Requirements:
# * A Dream Cheeky Thunder USB Missile Launcher
# * Python 2.6+
# * Python PyUSB Support and its dependencies
# * Python PyUSB Support and its dependencies
# http://sourceforge.net/apps/trac/pyusb/
# (on Mac use brew to "brew install libusb")
# * Should work on Windows, Mac and Linux
Expand All @@ -86,12 +86,12 @@
########################## CONFIG #########################

#
# Define a dictionary of "command sets" that map usernames to a sequence
# of commands to target the user (e.g their desk/workstation). It's
# Define a dictionary of "command sets" that map usernames to a sequence
# of commands to target the user (e.g their desk/workstation). It's
# suggested that each set start and end with a "zero" command so it's
# always parked in a known reference location. The timing on move commands
# is milli-seconds. The number after "fire" denotes the number of rockets
# to shoot.
# to shoot. Usernames should be lower case.
#
COMMAND_SETS = {
"will" : (
Expand All @@ -104,7 +104,7 @@
("zero", 0), # Park after use for next time
),
"tom" : (
("zero", 0),
("zero", 0),
("right", 4400),
("up", 200),
("fire", 4),
Expand All @@ -123,13 +123,13 @@
}

#
# The UDP port to listen to Jenkins events on (events are generated/supplied
# The UDP port to listen to Jenkins events on (events are generated/supplied
# by Jenkins "notification" plugin)
#
JENKINS_NOTIFICATION_UDP_PORT = 22222

#
# The URL of your Jenkins server - used to callback to determine who broke
# The URL of your Jenkins server - used to callback to determine who broke
# the build.
#
JENKINS_SERVER = "http://192.168.1.100:23456"
Expand Down Expand Up @@ -179,7 +179,7 @@ def usage():

def setup_usb():
# Tested only with the Cheeky Dream Thunder
global DEVICE
global DEVICE
DEVICE = usb.core.find(idVendor=0x2123, idProduct=0x1010)

if DEVICE is None:
Expand All @@ -190,7 +190,7 @@ def setup_usb():
try:
DEVICE.detach_kernel_driver(0)
except Exception, e:
pass # already unregistered
pass # already unregistered

DEVICE.set_configuration()

Expand Down Expand Up @@ -249,13 +249,9 @@ def jenkins_target_user(user):
match = False
# Not efficient but our user list is probably less than 1k.
# Do a case insenstive search for convenience.
for key in COMMAND_SETS:
if key.lower() == user.lower():
# We have a command set that targets our user so got for it!
run_command_set(COMMAND_SETS[key])
match = True
break
if not match:
if COMMAND_SETS.get(user.lower()) is not None:
run_command_set(COMMAND_SETS[user.lower()])
else:
print "WARNING: No target command set defined for user %s" % user


Expand All @@ -273,7 +269,7 @@ def read_url(url):
def jenkins_get_responsible_user(job_name):
# Call back to Jenkins and determin who broke the build. (Hacky)
# We do this by crudly parsing the changes on the last failed build

changes_url = JENKINS_SERVER + "/job/" + job_name + "/lastFailedBuild/changes"
changedata = read_url(changes_url)

Expand All @@ -287,7 +283,7 @@ def jenkins_get_responsible_user(job_name):

def jenkins_wait_for_event():

# Data in the format:
# Data in the format:
# {"name":"Project", "url":"JobUrl", "build":{"number":1, "phase":"STARTED", "status":"FAILURE" }}

sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
Expand All @@ -309,7 +305,7 @@ def jenkins_wait_for_event():
jenkins_target_user(target)
except:
pass


def main(args):

Expand Down