caveat_patch_kids 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +17 -0
- data/Gemfile +6 -0
- data/LICENSE.txt +22 -0
- data/README.md +72 -0
- data/Rakefile +1 -0
- data/bin/caveat-patch-kids +4 -0
- data/caveat_patch_kids.gemspec +22 -0
- data/lib/caveat_patch_kids.rb +57 -0
- data/lib/caveat_patch_kids/version.rb +3 -0
- data/scripts/caveat_patch_kids.js +1 -0
- data/scripts/caveat_patch_kids/bundles/all.js +6 -0
- data/scripts/caveat_patch_kids/bundles/unsupported.js +12 -0
- data/scripts/caveat_patch_kids/display_avatars.js +106 -0
- data/scripts/caveat_patch_kids/display_githubs.js +73 -0
- data/scripts/caveat_patch_kids/embiggen_message_history.js +1 -0
- data/scripts/caveat_patch_kids/stylize_diffs.js +52 -0
- data/scripts/caveat_patch_kids/stylize_nagios.js +45 -0
- data/scripts/caveat_patch_kids/unsupported/display_emoji.js +53 -0
- data/scripts/caveat_patch_kids/unsupported/display_html.js +42 -0
- data/scripts/caveat_patch_kids/unsupported/display_musics.js +57 -0
- data/scripts/caveat_patch_kids/unsupported/display_newrelic_charts.js +44 -0
- data/scripts/caveat_patch_kids/unsupported/display_stars.js +29 -0
- data/scripts/caveat_patch_kids/unsupported/focus_scroll_hax.js +9 -0
- data/scripts/caveat_patch_kids/unsupported/stylize_builds.js +60 -0
- data/scripts/caveat_patch_kids/unsupported/stylize_commits_and_deploys.js +36 -0
- data/scripts/caveat_patch_kids/unsupported/stylize_pivotal_tracker.js +70 -0
- data/vendor/assets/md5.js +176 -0
- metadata +123 -0
data/.gitignore
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2013 Josh Nichols
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,72 @@
|
|
1
|
+
# CaveatPatchKids
|
2
|
+
|
3
|
+
CaveatPatchKids is a tool for generating caveatPatchor.js files and for easily sharing snippets for use in caveatPatchor.js
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
Install in the usual way:
|
8
|
+
|
9
|
+
$ gem install caveat_patch_kids
|
10
|
+
|
11
|
+
## Usage
|
12
|
+
|
13
|
+
To start, plant a cavet patch:
|
14
|
+
|
15
|
+
$ caveat-patch-kids plant
|
16
|
+
create /Users/yourface/.caveat_patch_kids/caveatPatchor.js
|
17
|
+
|
18
|
+
This creates a basic caveatPatchor.js you can customize. Either drop you code at the bottom, or require scripts provided by CaveatPatchKids (see below).
|
19
|
+
|
20
|
+
When you are happy with the results, bloom it:
|
21
|
+
|
22
|
+
$ caveat-patch-kids bloom
|
23
|
+
bloom /Users/yourface/Library/Application Support/Propane/unsupported/caveatPatchor.js
|
24
|
+
|
25
|
+
Now you can quit Propane, and launch it again. Hopefully nothing breaks...
|
26
|
+
|
27
|
+
If something does break, and you really need to get back into Propane, you can till:
|
28
|
+
|
29
|
+
$ caveat-patch-kids till
|
30
|
+
remove /Users/technicalpickles/Library/Application Support/Propane/unsupported/caveatPatchor.js
|
31
|
+
|
32
|
+
### Scripts
|
33
|
+
|
34
|
+
These scripts are provided by CaveatPatchKids. Include them by updating ~/.caveat_patch_kids/caveatPatchor.js like:
|
35
|
+
|
36
|
+
//= require caveat_patch_kids/the_scripts
|
37
|
+
|
38
|
+
* caveat_patch_kids/display_avatars: display gravatars next to user's
|
39
|
+
* caveat_patch_kids/embiggen_message_history: increase message history
|
40
|
+
* caveat_patch_kids/stylize_diffs: colorize diffs with red/green
|
41
|
+
* caveat_patch_kids/stylize_diffs: colorize nagios alerts
|
42
|
+
|
43
|
+
The original caveatPatchor.js had a lot of mysterious and odd things. Those weren't included by default, but could be of use to someone, somewhere, or maybe just need some cleanup and documentation. See `scripts/caveat_patch_kids/unsupported` for the good.
|
44
|
+
|
45
|
+
### Bundles
|
46
|
+
|
47
|
+
For convience, a full bundles with several scripts are included. Require them like any other script:
|
48
|
+
|
49
|
+
* caveat_patch_kids/bundles/all: all scripts (that aren't unsupported)
|
50
|
+
* caveat_patch_kids/bundles/unsupported: all scripts, even ones unsupported. you probably shouldn't do this unless you are a crazy person
|
51
|
+
|
52
|
+
## Thanks
|
53
|
+
|
54
|
+
* [@protocool](https://github.com/protocool) for releasing Propane with caveatPatchor.js support
|
55
|
+
* [@wfarr](https://github.com/wfarr) for convincing someone to share their caveatPatchor.js
|
56
|
+
* [@sstephenson](https://github.com/sstephenson) for sprockets
|
57
|
+
* [@weppos](https://github.com/weppos) for [blogging about using sprockets outside of the context of a webapp](http://www.simonecarletti.com/blog/2011/09/using-sprockets-without-a-railsrack-project/)
|
58
|
+
* Maybe you? If you wrote a script here, and it's uncredited, please let me know
|
59
|
+
|
60
|
+
## TODO
|
61
|
+
|
62
|
+
* make it easy for other people to release their own scripts as gems, and be able to load them
|
63
|
+
* include screenshots of scripts in action
|
64
|
+
* review unsupported stuff more closely
|
65
|
+
|
66
|
+
## Contributing
|
67
|
+
|
68
|
+
1. Fork it
|
69
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
70
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
71
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
72
|
+
5. Create new Pull Request
|
data/Rakefile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
@@ -0,0 +1,22 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'caveat_patch_kids/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |gem|
|
7
|
+
gem.name = "caveat_patch_kids"
|
8
|
+
gem.version = CaveatPatchKids::VERSION
|
9
|
+
gem.authors = ["Josh Nichols"]
|
10
|
+
gem.email = ["josh@technicalpickles.com"]
|
11
|
+
gem.description = %q{Manage caveatPatchor.js files for Propane}
|
12
|
+
gem.summary = %q{CaveatPatchKids is a tool for generating, sharing, and maintaing caveatPatchor.js files for use with Propane, powered by sprockets and other fun stuff}
|
13
|
+
gem.homepage = ""
|
14
|
+
|
15
|
+
gem.files = `git ls-files`.split($/)
|
16
|
+
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
17
|
+
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
18
|
+
gem.require_paths = ["lib"]
|
19
|
+
gem.add_dependency 'sprockets', '>= 0'
|
20
|
+
gem.add_dependency 'thor', '>= 0'
|
21
|
+
gem.add_dependency 'coffee-script', '>= 0'
|
22
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
require "caveat_patch_kids/version"
|
2
|
+
|
3
|
+
require 'sprockets'
|
4
|
+
require 'pathname'
|
5
|
+
require 'logger'
|
6
|
+
require 'fileutils'
|
7
|
+
|
8
|
+
require 'thor'
|
9
|
+
|
10
|
+
module CaveatPatchKids
|
11
|
+
|
12
|
+
class App < Thor
|
13
|
+
include Thor::Actions
|
14
|
+
desc "plant", "Plant a basic ~/.caveat_patch_kids"
|
15
|
+
def plant
|
16
|
+
create_file "~/.caveat_patch_kids/caveatPatchor.js", <<END
|
17
|
+
//= require caveat_patch_kids
|
18
|
+
//
|
19
|
+
//= require caveat_patch_kids/display_avatars
|
20
|
+
//= require caveat_patch_kids/stylize_diffs
|
21
|
+
//
|
22
|
+
//= require_self
|
23
|
+
END
|
24
|
+
end
|
25
|
+
|
26
|
+
desc "bloom", "bloom a caveatPatchor.js using your planted ~/.caveat_patch_kids"
|
27
|
+
def bloom
|
28
|
+
root_dir = Pathname.new(__FILE__).basename + '..'
|
29
|
+
sprockets = Sprockets::Environment.new(root_dir)
|
30
|
+
|
31
|
+
vendor_assets_dir = root_dir + 'vendor/assets'
|
32
|
+
scripts_dir = root_dir + 'scripts'
|
33
|
+
home_dir = Pathname.new("~/.caveat_patch_kids")
|
34
|
+
unsupported_dir = Pathname.new("~/Library/Application Support/Propane/unsupported/").expand_path
|
35
|
+
|
36
|
+
sprockets.append_path vendor_assets_dir.to_s
|
37
|
+
sprockets.append_path scripts_dir.to_s
|
38
|
+
sprockets.append_path home_dir.expand_path.to_s
|
39
|
+
|
40
|
+
caveat_patchor = sprockets.find_asset('caveatPatchor.js')
|
41
|
+
|
42
|
+
prefix, basename = caveat_patchor.pathname.to_s.split('/')[-2..-1]
|
43
|
+
|
44
|
+
FileUtils.mkdir_p(unsupported_dir.to_s)
|
45
|
+
|
46
|
+
say_status "bloom", "#{unsupported_dir}/#{basename}"
|
47
|
+
caveat_patchor.write_to "#{unsupported_dir}/#{basename}"
|
48
|
+
end
|
49
|
+
|
50
|
+
desc "till", "till planted ~/.caveat_patch_kids"
|
51
|
+
def till
|
52
|
+
caveat_patchor = Pathname.new("~/Library/Application Support/Propane/unsupported/caveatPatchor.js").expand_path
|
53
|
+
|
54
|
+
remove_file caveat_patchor.to_s
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
//= require md5
|
@@ -0,0 +1,12 @@
|
|
1
|
+
//= require caveat_patch_kids/bundles/all
|
2
|
+
//
|
3
|
+
//= require caveat_patch_kids/unsupported/display_emoji
|
4
|
+
//= require caveat_patch_kids/unsupported/display_githubs
|
5
|
+
//= require caveat_patch_kids/unsupported/display_html
|
6
|
+
//= require caveat_patch_kids/unsupported/display_musics
|
7
|
+
//= require caveat_patch_kids/unsupported/display_newrelic_charts
|
8
|
+
//= require caveat_patch_kids/unsupported/display_stars
|
9
|
+
//= require caveat_patch_kids/unsupported/focus_scroll_hax
|
10
|
+
//= require caveat_patch_kids/unsupported/stylize_builds
|
11
|
+
//= require caveat_patch_kids/unsupported/stylize_commits_and_deploys
|
12
|
+
//= require caveat_patch_kids/unsupported/stylize_pivotal_tracker
|
@@ -0,0 +1,106 @@
|
|
1
|
+
var USER_ACTIONS = ['enter','leave','kick','conference_created','lock','unlock'];
|
2
|
+
|
3
|
+
Object.extend(Campfire.Message.prototype, {
|
4
|
+
authorID: function() {
|
5
|
+
if (Element.hasClassName(this.element, 'you'))
|
6
|
+
return this.chat.userID;
|
7
|
+
|
8
|
+
var idtext = (this.element.className.match(/\s*user_(\d+)\s*/) || [])[1];
|
9
|
+
return parseInt(idtext) || 0;
|
10
|
+
},
|
11
|
+
|
12
|
+
addAvatar: function() {
|
13
|
+
var
|
14
|
+
author = this.authorElement(),
|
15
|
+
body = this.bodyCell,
|
16
|
+
email,
|
17
|
+
avatar, name, imgSize = 32, img;
|
18
|
+
|
19
|
+
email = author.getAttribute('data-email')
|
20
|
+
if (email) {
|
21
|
+
var hash = calcMD5(email.trim().toLowerCase())
|
22
|
+
avatar = "http://gravatar.com/avatar/"+hash
|
23
|
+
} else {
|
24
|
+
// avatar = author.getAttribute('data-avatar') || 'http://asset1.37img.com/global/missing/avatar.png?r=3';
|
25
|
+
avatar = 'http://globase.heroku.com/redirect/gh.gravatars.' + this.authorID() + '?default=http://github.com/images/gravatars/gravatar-140.png';
|
26
|
+
}
|
27
|
+
name = '<strong class="authorName" style="color:#333;">'+author.textContent+'</strong>'
|
28
|
+
|
29
|
+
if (USER_ACTIONS.include(this.kind)) {
|
30
|
+
imgSize = 16
|
31
|
+
if ('conference_created' != this.kind)
|
32
|
+
body = body.select('div:first')[0]
|
33
|
+
name += ' '
|
34
|
+
} else if (this.actsLikeTextMessage()) {
|
35
|
+
name += '<br>'
|
36
|
+
} else {
|
37
|
+
return;
|
38
|
+
}
|
39
|
+
|
40
|
+
img = '<img alt="'+this.author()+'" width="'+imgSize+'" height="'+imgSize+'" align="absmiddle" style="opacity: 1.0; margin: 0px; border-radius:3px" src="'+avatar+'">'
|
41
|
+
|
42
|
+
if (USER_ACTIONS.include(this.kind)) {
|
43
|
+
name = img + ' ' + name;
|
44
|
+
img = ''
|
45
|
+
}
|
46
|
+
|
47
|
+
if (author.visible()) {
|
48
|
+
author.hide();
|
49
|
+
|
50
|
+
if (body.select('strong.authorName').length === 0) {
|
51
|
+
body.insert({top: name});
|
52
|
+
if (img)
|
53
|
+
author.insert({after: img});
|
54
|
+
}
|
55
|
+
}
|
56
|
+
}
|
57
|
+
});
|
58
|
+
|
59
|
+
/* if you can wrap rather than rewrite, use swizzle like this: */
|
60
|
+
swizzle(Campfire.Message, {
|
61
|
+
setAuthorVisibilityInRelationTo: function($super, message) {
|
62
|
+
$super(message);
|
63
|
+
this.addAvatar();
|
64
|
+
},
|
65
|
+
authorElement: function($super) {
|
66
|
+
if (USER_ACTIONS.include(this.kind)) {
|
67
|
+
return $super().select('span.author')[0]
|
68
|
+
} else {
|
69
|
+
return $super()
|
70
|
+
}
|
71
|
+
}
|
72
|
+
});
|
73
|
+
|
74
|
+
|
75
|
+
/* defining a new responder is probably the best way to insulate your hacks from Campfire and Propane */
|
76
|
+
Campfire.AvatarMangler = Class.create({
|
77
|
+
initialize: function(chat) {
|
78
|
+
this.chat = chat;
|
79
|
+
|
80
|
+
var messages = this.chat.transcript.messages;
|
81
|
+
for (var i = 0; i < messages.length; i++) {
|
82
|
+
var message = messages[i];
|
83
|
+
message.addAvatar();
|
84
|
+
}
|
85
|
+
|
86
|
+
this.chat.layoutmanager.layout();
|
87
|
+
this.chat.windowmanager.scrollToBottom();
|
88
|
+
},
|
89
|
+
|
90
|
+
onMessagesInserted: function(messages) {
|
91
|
+
var scrolledToBottom = this.chat.windowmanager.isScrolledToBottom();
|
92
|
+
|
93
|
+
for (var i = 0; i < messages.length; i++) {
|
94
|
+
var message = messages[i];
|
95
|
+
message.addAvatar();
|
96
|
+
}
|
97
|
+
|
98
|
+
if (scrolledToBottom) {
|
99
|
+
this.chat.windowmanager.scrollToBottom();
|
100
|
+
}
|
101
|
+
}
|
102
|
+
});
|
103
|
+
|
104
|
+
/* Here is how to install your responder into the running chat */
|
105
|
+
Campfire.Responders.push("AvatarMangler");
|
106
|
+
window.chat.installPropaneResponder("AvatarMangler", "avatarmangler");
|
@@ -0,0 +1,73 @@
|
|
1
|
+
Campfire.GitHubExpander = Class.create({
|
2
|
+
initialize: function(chat) {
|
3
|
+
this.chat = chat;
|
4
|
+
var messages = this.chat.transcript.messages;
|
5
|
+
for (var i = 0; i < messages.length; i++) {
|
6
|
+
this.detectGitHubURL(messages[i]);
|
7
|
+
}
|
8
|
+
this.chat.windowmanager.scrollToBottom();
|
9
|
+
},
|
10
|
+
|
11
|
+
detectGitHubURL: function(message) {
|
12
|
+
if (!message.pending() && message.kind === 'text') {
|
13
|
+
var iframe = null, elem, height = 150;
|
14
|
+
|
15
|
+
var gists = message.bodyElement().select('a[href*="gist.github.com"]');
|
16
|
+
if (gists.length == 1) {
|
17
|
+
elem = gists[0];
|
18
|
+
var href = elem.getAttribute('href');
|
19
|
+
var match = href.match(/^https?:\/\/gist.github.com\/([A-Fa-f0-9]+)/);
|
20
|
+
if (match) {
|
21
|
+
iframe = 'https://gist.github.com/'+match[1]+'.pibb';
|
22
|
+
}
|
23
|
+
}
|
24
|
+
|
25
|
+
var blobs = message.bodyElement().select('a[href*="#L"]');
|
26
|
+
if (blobs.length == 1) {
|
27
|
+
elem = blobs[0];
|
28
|
+
var href = elem.getAttribute('href');
|
29
|
+
iframe = href;
|
30
|
+
}
|
31
|
+
|
32
|
+
var blobs = message.bodyElement().select('a[href*="/blob/"]');
|
33
|
+
if (!iframe && blobs.length == 1) {
|
34
|
+
elem = blobs[0];
|
35
|
+
var href = elem.getAttribute('href');
|
36
|
+
if (href.indexOf('#') > -1)
|
37
|
+
iframe = href;
|
38
|
+
else
|
39
|
+
iframe = href + '#L1';
|
40
|
+
}
|
41
|
+
|
42
|
+
// var commits = message.bodyElement().select('a[href*=/commit/]')
|
43
|
+
// if (!iframe && commits.length == 1 && message.author() != 'Mister Robot' && message.author() != 'Git') {
|
44
|
+
// elem = commits[0];
|
45
|
+
// var href = elem.getAttribute('href');
|
46
|
+
// if (href.indexOf('#') > -1)
|
47
|
+
// iframe = href;
|
48
|
+
// else
|
49
|
+
// iframe = href + '#diff-stat';
|
50
|
+
// }
|
51
|
+
|
52
|
+
if (!iframe || IFRAME_HATERS.include(this.chat.username)) return;
|
53
|
+
message.bodyElement().insert({bottom:"<iframe style='border:0; margin-top: 5px' height='"+height+"' width='98%' src='"+iframe+"'></iframe>"});
|
54
|
+
}
|
55
|
+
},
|
56
|
+
|
57
|
+
onMessagesInsertedBeforeDisplay: function(messages) {
|
58
|
+
var scrolledToBottom = this.chat.windowmanager.isScrolledToBottom();
|
59
|
+
for (var i = 0; i < messages.length; i++) {
|
60
|
+
this.detectGitHubURL(messages[i]);
|
61
|
+
}
|
62
|
+
if (scrolledToBottom) {
|
63
|
+
this.chat.windowmanager.scrollToBottom();
|
64
|
+
}
|
65
|
+
},
|
66
|
+
|
67
|
+
onMessageAccepted: function(message, messageID) {
|
68
|
+
this.detectGitHubURL(message);
|
69
|
+
}
|
70
|
+
});
|
71
|
+
|
72
|
+
Campfire.Responders.push("GitHubExpander");
|
73
|
+
window.chat.installPropaneResponder("GitHubExpander", "githubexpander");
|
@@ -0,0 +1 @@
|
|
1
|
+
window.chat.messageHistory = 1600;
|
@@ -0,0 +1,52 @@
|
|
1
|
+
Campfire.DiffExpander = Class.create({
|
2
|
+
initialize: function(chat) {
|
3
|
+
this.chat = chat;
|
4
|
+
var messages = this.chat.transcript.messages;
|
5
|
+
for (var i = 0; i < messages.length; i++) {
|
6
|
+
this.detectDiff(messages[i]);
|
7
|
+
}
|
8
|
+
this.chat.windowmanager.scrollToBottom();
|
9
|
+
},
|
10
|
+
|
11
|
+
detectDiff: function(message) {
|
12
|
+
if (message.kind === 'paste') {
|
13
|
+
var code = message.bodyCell.select('pre code')
|
14
|
+
if (code.length) {
|
15
|
+
var diff = code[0].innerText
|
16
|
+
if (diff.match(/^\+\+\+/m)) {
|
17
|
+
var lines = diff.split("\n").map(function(line){
|
18
|
+
if (line.match(/^(diff|index)/)) {
|
19
|
+
return "<b>"+line.escapeHTML()+"</b>"
|
20
|
+
} else if (match = line.match(/^(@@.+?@@)(.*)$/)) {
|
21
|
+
return "<b>"+match[1]+"</b> " + match[2].escapeHTML()
|
22
|
+
} else if (line.match(/^\+/)) {
|
23
|
+
return "<font style='color:green'>"+line.escapeHTML()+"</font>"
|
24
|
+
} else if (line.match(/^\-/)) {
|
25
|
+
return "<font style='color:red'>"+line.escapeHTML()+"</font>"
|
26
|
+
} else {
|
27
|
+
return line.escapeHTML()
|
28
|
+
}
|
29
|
+
})
|
30
|
+
code[0].innerHTML = lines.join("\n")
|
31
|
+
}
|
32
|
+
}
|
33
|
+
}
|
34
|
+
},
|
35
|
+
|
36
|
+
onMessagesInsertedBeforeDisplay: function(messages) {
|
37
|
+
var scrolledToBottom = this.chat.windowmanager.isScrolledToBottom();
|
38
|
+
for (var i = 0; i < messages.length; i++) {
|
39
|
+
this.detectDiff(messages[i]);
|
40
|
+
}
|
41
|
+
if (scrolledToBottom) {
|
42
|
+
this.chat.windowmanager.scrollToBottom();
|
43
|
+
}
|
44
|
+
},
|
45
|
+
|
46
|
+
onMessageAccepted: function(message, messageID) {
|
47
|
+
this.detectDiff(message);
|
48
|
+
}
|
49
|
+
});
|
50
|
+
|
51
|
+
Campfire.Responders.push("DiffExpander");
|
52
|
+
window.chat.installPropaneResponder("DiffExpander", "diffexpander");
|
@@ -0,0 +1,45 @@
|
|
1
|
+
Campfire.NagiosExpander = Class.create({
|
2
|
+
initialize: function(chat) {
|
3
|
+
this.chat = chat;
|
4
|
+
var messages = this.chat.transcript.messages;
|
5
|
+
for (var i = 0; i < messages.length; i++) {
|
6
|
+
this.detectNagios(messages[i]);
|
7
|
+
}
|
8
|
+
},
|
9
|
+
|
10
|
+
detectNagios: function(message) {
|
11
|
+
if (!message.pending() && message.kind === 'text') {
|
12
|
+
var body = message.bodyElement()
|
13
|
+
var author = message.author();
|
14
|
+
var email = message.authorElement().getAttribute('data-email');
|
15
|
+
if (body.innerText.match(/^Nagios : /) || (email && email.match(/nagios/i))) {
|
16
|
+
if (body.innerText.match(/PROBLEM/)) {
|
17
|
+
message.bodyCell.setStyle({
|
18
|
+
color: "#ef2929"
|
19
|
+
})
|
20
|
+
} else if (body.innerText.match(/WARNING/)) {
|
21
|
+
message.bodyCell.setStyle({
|
22
|
+
color: "#fce94f"
|
23
|
+
})
|
24
|
+
} else if (body.innerText.match(/RECOVERY/)) {
|
25
|
+
message.bodyCell.setStyle({
|
26
|
+
color: "#4e9a06"
|
27
|
+
})
|
28
|
+
}
|
29
|
+
}
|
30
|
+
}
|
31
|
+
},
|
32
|
+
|
33
|
+
onMessagesInsertedBeforeDisplay: function(messages) {
|
34
|
+
for (var i = 0; i < messages.length; i++) {
|
35
|
+
this.detectNagios(messages[i]);
|
36
|
+
}
|
37
|
+
},
|
38
|
+
|
39
|
+
onMessageAccepted: function(message, messageID) {
|
40
|
+
this.detectNagios(message);
|
41
|
+
}
|
42
|
+
});
|
43
|
+
|
44
|
+
Campfire.Responders.push("NagiosExpander");
|
45
|
+
window.chat.installPropaneResponder("NagiosExpander", "nagiosexpander");
|
@@ -0,0 +1,53 @@
|
|
1
|
+
Autolink['Emoji']['bear'] = '1f40b'
|
2
|
+
CAMPFIRE_EMOJI = new Hash(Autolink.Emoji).inject({}, function(hash,v){ hash[v[1]]=v[0]; return hash })
|
3
|
+
// from GitHub::HTML::EmojiFilter::EmojiPattern
|
4
|
+
GITHUB_EMOJI = /:(sparkles|key|scissors|octocat|warning|heart|clap|airplane|leaves|new|broken_heart|ok|couple|fire|iphone|sunny|rainbow|email|book|mag|koala|mega|apple|dog|princess|rose|calling|tophat|beer|art|v|cat|ski|thumbsup|punch|dolphin|cloud|zap|bear|fist|horse|lock|smoking|moneybag|computer|cake|taxi|cool|feet|tm|kiss|train|bulb|thumbsdown|sunflower|nail_care|bike|hammer|gift|lipstick|fish|zzz|lips|bus|star|cop|pencil|bomb|vs|memo|\-1|\+1|runner|wheelchair):/g
|
5
|
+
|
6
|
+
Campfire.EmojiExpander = Class.create({
|
7
|
+
initialize: function(chat) {
|
8
|
+
this.chat = chat;
|
9
|
+
var messages = this.chat.transcript.messages;
|
10
|
+
for (var i = 0; i < messages.length; i++) {
|
11
|
+
this.detectEmoji(messages[i]);
|
12
|
+
}
|
13
|
+
this.chat.windowmanager.scrollToBottom();
|
14
|
+
},
|
15
|
+
|
16
|
+
detectEmoji: function(message) {
|
17
|
+
if (message.kind == 'text') {
|
18
|
+
var body = message.bodyElement()
|
19
|
+
var emoji = body.select('span.emoji');
|
20
|
+
emoji.each(function(e){
|
21
|
+
var code = e.className.match(/emoji([\da-f]+)/)[1]
|
22
|
+
e.replace(':' + CAMPFIRE_EMOJI[code] + ':')
|
23
|
+
})
|
24
|
+
var html = body.innerHTML
|
25
|
+
var match = html.match(GITHUB_EMOJI)
|
26
|
+
if (match) {
|
27
|
+
body.innerHTML = html.replace(GITHUB_EMOJI, function(all, e){
|
28
|
+
var size = 28
|
29
|
+
if (e == 'octocat') size = 40
|
30
|
+
if (message.author() == 'Mister Robot') size = 18
|
31
|
+
return "<img title=':"+e+":' alt=':"+e+":' src='http://d3nwyuy0nl342s.cloudfront.net/images/icons/emoji/v2/"+e+".png' height='"+size+"' width='"+size+"' align='absmiddle'/>"
|
32
|
+
})
|
33
|
+
}
|
34
|
+
}
|
35
|
+
},
|
36
|
+
|
37
|
+
onMessagesInsertedBeforeDisplay: function(messages) {
|
38
|
+
var scrolledToBottom = this.chat.windowmanager.isScrolledToBottom();
|
39
|
+
for (var i = 0; i < messages.length; i++) {
|
40
|
+
this.detectEmoji(messages[i]);
|
41
|
+
}
|
42
|
+
if (scrolledToBottom) {
|
43
|
+
this.chat.windowmanager.scrollToBottom();
|
44
|
+
}
|
45
|
+
},
|
46
|
+
|
47
|
+
onMessageAccepted: function(message, messageID) {
|
48
|
+
this.detectEmoji(message);
|
49
|
+
}
|
50
|
+
});
|
51
|
+
|
52
|
+
Campfire.Responders.push("EmojiExpander");
|
53
|
+
window.chat.installPropaneResponder("EmojiExpander", "emojiexpander");
|
@@ -0,0 +1,42 @@
|
|
1
|
+
Campfire.HTMLExpander = Class.create({
|
2
|
+
initialize: function(chat) {
|
3
|
+
this.chat = chat;
|
4
|
+
// var messages = this.chat.transcript.messages;
|
5
|
+
// for (var i = 0; i < messages.length; i++) {
|
6
|
+
// this.detectHTML(messages[i]);
|
7
|
+
// }
|
8
|
+
// this.chat.windowmanager.scrollToBottom();
|
9
|
+
},
|
10
|
+
|
11
|
+
detectHTML: function(message) {
|
12
|
+
if (!message.pending() && ['text','paste'].include(message.kind)) {
|
13
|
+
var body = message.bodyElement()
|
14
|
+
var match = body.innerText.match(/^HTML!\s+(.+)$/m);
|
15
|
+
|
16
|
+
// Some people can't handle this much fun
|
17
|
+
var halt = SOUND_HATERS.include(this.chat.username) && body.innerText.match(/<audio/)
|
18
|
+
|
19
|
+
if (!halt && match && !body.innerText.match(/<\s*script/)) {
|
20
|
+
body.update(match[1])
|
21
|
+
}
|
22
|
+
}
|
23
|
+
},
|
24
|
+
|
25
|
+
onMessagesInsertedBeforeDisplay: function(messages) {
|
26
|
+
var scrolledToBottom = this.chat.windowmanager.isScrolledToBottom();
|
27
|
+
for (var i = 0; i < messages.length; i++) {
|
28
|
+
this.detectHTML(messages[i]);
|
29
|
+
}
|
30
|
+
if (scrolledToBottom) {
|
31
|
+
this.chat.windowmanager.scrollToBottom();
|
32
|
+
}
|
33
|
+
},
|
34
|
+
|
35
|
+
onMessageAccepted: function(message, messageID) {
|
36
|
+
this.detectHTML(message);
|
37
|
+
}
|
38
|
+
});
|
39
|
+
|
40
|
+
Campfire.Responders.push("HTMLExpander");
|
41
|
+
window.chat.installPropaneResponder("HTMLExpander", "htmlexpander");
|
42
|
+
|
@@ -0,0 +1,57 @@
|
|
1
|
+
Campfire.MusicExpander = Class.create({
|
2
|
+
initialize: function(chat) {
|
3
|
+
this.chat = chat;
|
4
|
+
var messages = this.chat.transcript.messages;
|
5
|
+
for (var i = 0; i < messages.length; i++) {
|
6
|
+
this.detectMusic(messages[i]);
|
7
|
+
}
|
8
|
+
this.chat.windowmanager.scrollToBottom();
|
9
|
+
},
|
10
|
+
|
11
|
+
detectMusic: function(message) {
|
12
|
+
if (message.actsLikeTextMessage()) {
|
13
|
+
var body = message.bodyElement()
|
14
|
+
var html = body.innerHTML
|
15
|
+
|
16
|
+
var match = html.match(/(Now playing|is listening to|Queued up) "(.*)" by (.*), from(?: the album)? "(.*)"/i)
|
17
|
+
if (match) {
|
18
|
+
var text = match[1]
|
19
|
+
var song = match[2], artist = match[3], album = match[4]
|
20
|
+
var url = "http://www.amazon.com/s/ref=nb_sb_noss?url=search-alias%3Ddigital-music&x=8&y=16&field-keywords="
|
21
|
+
var linkify = function(text, query){
|
22
|
+
if (!query) query = text
|
23
|
+
return new Element('a', {target:'_blank',href:url+encodeURI(query)}).update(text).outerHTML;
|
24
|
+
}
|
25
|
+
|
26
|
+
html = text + ' "'
|
27
|
+
if (song)
|
28
|
+
html += linkify(song, song+" "+artist+" "+album)
|
29
|
+
html += '" by '
|
30
|
+
if (artist)
|
31
|
+
html += linkify(artist)
|
32
|
+
html += ', from the album "'
|
33
|
+
if (album)
|
34
|
+
html += linkify(album, artist+" "+album)
|
35
|
+
html += '"'
|
36
|
+
body.innerHTML = html
|
37
|
+
}
|
38
|
+
}
|
39
|
+
},
|
40
|
+
|
41
|
+
onMessagesInsertedBeforeDisplay: function(messages) {
|
42
|
+
var scrolledToBottom = this.chat.windowmanager.isScrolledToBottom();
|
43
|
+
for (var i = 0; i < messages.length; i++) {
|
44
|
+
this.detectMusic(messages[i]);
|
45
|
+
}
|
46
|
+
if (scrolledToBottom) {
|
47
|
+
this.chat.windowmanager.scrollToBottom();
|
48
|
+
}
|
49
|
+
},
|
50
|
+
|
51
|
+
onMessageAccepted: function(message, messageID) {
|
52
|
+
this.detectMusic(message);
|
53
|
+
}
|
54
|
+
});
|
55
|
+
|
56
|
+
Campfire.Responders.push("MusicExpander");
|
57
|
+
window.chat.installPropaneResponder("MusicExpander", "musicexpander");
|
@@ -0,0 +1,44 @@
|
|
1
|
+
Campfire.NewRelicChartExpander = Class.create({
|
2
|
+
initialize: function(chat) {
|
3
|
+
this.chat = chat;
|
4
|
+
var messages = this.chat.transcript.messages;
|
5
|
+
for (var i = 0; i < messages.length; i++) {
|
6
|
+
this.detectNewRelicChartURL(messages[i]);
|
7
|
+
}
|
8
|
+
this.chat.windowmanager.scrollToBottom();
|
9
|
+
},
|
10
|
+
|
11
|
+
detectNewRelicChartURL: function(message) {
|
12
|
+
if (!message.pending() && message.kind === 'text') {
|
13
|
+
var iframe = null, elem, height = 200;
|
14
|
+
|
15
|
+
var charts = message.bodyElement().select('a[href*="rpm.newrelic.com/public/charts"]');
|
16
|
+
|
17
|
+
if (charts.length == 1) {
|
18
|
+
elem = charts[0];
|
19
|
+
var href = elem.getAttribute('href');
|
20
|
+
iframe = href;
|
21
|
+
}
|
22
|
+
|
23
|
+
if (!iframe || IFRAME_HATERS.include(this.chat.username)) return;
|
24
|
+
message.bodyCell.insert({bottom:"<iframe style='border:0; margin-top: 5px' height='"+height+"' width='98%' src='"+iframe+"'></iframe>"});
|
25
|
+
}
|
26
|
+
},
|
27
|
+
|
28
|
+
onMessagesInsertedBeforeDisplay: function(messages) {
|
29
|
+
var scrolledToBottom = this.chat.windowmanager.isScrolledToBottom();
|
30
|
+
for (var i = 0; i < messages.length; i++) {
|
31
|
+
this.detectNewRelicChartURL(messages[i]);
|
32
|
+
}
|
33
|
+
if (scrolledToBottom) {
|
34
|
+
this.chat.windowmanager.scrollToBottom();
|
35
|
+
}
|
36
|
+
},
|
37
|
+
|
38
|
+
onMessageAccepted: function(message, messageID) {
|
39
|
+
this.detectNewRelicChartURL(message);
|
40
|
+
}
|
41
|
+
});
|
42
|
+
|
43
|
+
Campfire.Responders.push("NewRelicChartExpander");
|
44
|
+
window.chat.installPropaneResponder("NewRelicChartExpander", "newrelicchartexpander");
|
@@ -0,0 +1,29 @@
|
|
1
|
+
swizzle(Campfire.StarManager, {
|
2
|
+
toggle: function($super, element) {
|
3
|
+
$super(element);
|
4
|
+
|
5
|
+
var star = $(element).up('span.star'),
|
6
|
+
message = this.chat.findMessage(element)
|
7
|
+
if (star.hasClassName('starred')) {
|
8
|
+
trackStar(message);
|
9
|
+
}
|
10
|
+
}
|
11
|
+
});
|
12
|
+
|
13
|
+
// 5490ef76-50fa-11e0-8fed-2495f6688d41
|
14
|
+
// bb628a4e-5199-11e0-949d-2e03dd584bf3 is a test cluster
|
15
|
+
function trackStar(message) {
|
16
|
+
var id = message.id()
|
17
|
+
, url = "http://allofthestars.com/clusters/.../campfire" +
|
18
|
+
"?message=" + encodeURIComponent(message.bodyElement().innerText) +
|
19
|
+
"&message_id=" + encodeURIComponent(id.toString()) +
|
20
|
+
"&url=" + encodeURIComponent(starPermalink(id)) +
|
21
|
+
"&author=" + encodeURIComponent(message.author()) +
|
22
|
+
"&room=" + encodeURIComponent($('room_name').innerText)
|
23
|
+
window.propane.requestJSON(id, url)
|
24
|
+
}
|
25
|
+
|
26
|
+
function starPermalink(id) {
|
27
|
+
return location.href.toString().replace(/#.*/, '') +
|
28
|
+
"transcript/message/" + id + "#message_" + id
|
29
|
+
}
|
@@ -0,0 +1,9 @@
|
|
1
|
+
/* focus/scroll hax */
|
2
|
+
// var $focused = true;
|
3
|
+
// window.onfocus = function(){ alert(1); $focused = true }
|
4
|
+
// window.onblur = function(){ $focused = false }
|
5
|
+
// swizzle(Campfire.WindowManager, {
|
6
|
+
// isScrolledToBottom: function($super) {
|
7
|
+
// return $focused ? $super() : false;
|
8
|
+
// }
|
9
|
+
// });
|
@@ -0,0 +1,60 @@
|
|
1
|
+
Campfire.BuildExpander = Class.create({
|
2
|
+
initialize: function(chat) {
|
3
|
+
this.chat = chat;
|
4
|
+
var messages = this.chat.transcript.messages;
|
5
|
+
for (var i = 0; i < messages.length; i++) {
|
6
|
+
this.detectBuild(messages[i]);
|
7
|
+
}
|
8
|
+
},
|
9
|
+
|
10
|
+
detectBuild: function(message) {
|
11
|
+
if (!message.pending() && message.kind === 'text') {
|
12
|
+
var body = message.bodyElement()
|
13
|
+
if (body.innerText.match(/^Build #(\d+) \([0-9a-zA-Z]+\) of (github-)?([-_0-9a-zA-Z]+)/)) {
|
14
|
+
var failed_p = body.innerText.match(/failed/);
|
15
|
+
var success_p = body.innerText.match(/success/);
|
16
|
+
var color = failed_p ? '#ff0000' : '#00941f';
|
17
|
+
if (failed_p || success_p)
|
18
|
+
message.bodyCell.setStyle({
|
19
|
+
color: color,
|
20
|
+
fontWeight: 'bold'
|
21
|
+
})
|
22
|
+
|
23
|
+
var sha = body.innerText.match(/\(([0-9a-z]+)\)/i)[1]
|
24
|
+
var build;
|
25
|
+
if (body.outerHTML.match(/^github-(?!services)/)) {
|
26
|
+
build = body.outerHTML.replace(/#(\d+) \(([0-9a-zA-Z]+)\) of (?:github-)?([-_0-9a-zA-Z]+)/, '<a target="_blank" href="http://ci2.rs.github.com:8080/job/github-$3/$1/console">#$1</a> ($2) of github-$3')
|
27
|
+
} else {
|
28
|
+
build = body.outerHTML.replace(/#(\d+) \(([0-9a-zA-Z]+)\) of ([-_0-9a-zA-Z]+)/, '<a target="_blank" href="https://janky.rs.github.com/$1/output">#$1</a> ($2) of $3')
|
29
|
+
}
|
30
|
+
var btime = build.match(/\d+s/)
|
31
|
+
body.replace(build)
|
32
|
+
build = build.replace(/^.*?<a/,'<a').replace(/<\/a>.*/, '</a>')
|
33
|
+
|
34
|
+
var msgIndex = this.chat.transcript.messages.indexOf(message);
|
35
|
+
if (msgIndex > -1) {
|
36
|
+
for (var i=msgIndex; i > 0 && i > msgIndex - 5; i--) {
|
37
|
+
var otherMsg = this.chat.transcript.messages[i]
|
38
|
+
if (otherMsg.element.innerHTML.match("/commit/" + sha)) {
|
39
|
+
build = build.replace(/<\/a>.*$/, '</a>').replace('Build ','');
|
40
|
+
if (btime) build += "] [" + btime;
|
41
|
+
otherMsg.bodyElement().insert({bottom: " ["+build+"]"})
|
42
|
+
otherMsg.bodyCell.setStyle({color:color,fontWeight:'bold'})
|
43
|
+
message.element.remove()
|
44
|
+
break
|
45
|
+
}
|
46
|
+
}
|
47
|
+
}
|
48
|
+
}
|
49
|
+
}
|
50
|
+
},
|
51
|
+
|
52
|
+
onMessagesInsertedBeforeDisplay: function(messages) {
|
53
|
+
for (var i = 0; i < messages.length; i++) {
|
54
|
+
this.detectBuild(messages[i]);
|
55
|
+
}
|
56
|
+
}
|
57
|
+
});
|
58
|
+
|
59
|
+
Campfire.Responders.push("BuildExpander");
|
60
|
+
window.chat.installPropaneResponder("BuildExpander", "buildexpander");
|
@@ -0,0 +1,36 @@
|
|
1
|
+
Campfire.CommitExpander = Class.create({
|
2
|
+
initialize: function(chat) {
|
3
|
+
this.chat = chat;
|
4
|
+
var messages = this.chat.transcript.messages;
|
5
|
+
for (var i = 0; i < messages.length; i++) {
|
6
|
+
this.detectCommit(messages[i]);
|
7
|
+
}
|
8
|
+
},
|
9
|
+
|
10
|
+
detectCommit: function(message) {
|
11
|
+
if (!message.pending() && message.kind === 'text') {
|
12
|
+
var body = message.bodyElement()
|
13
|
+
if (body.innerText.match(/^\[[\w-\.]+(\/|\])/) || body.innerText.match(/(is deploying|deployment of)/)) {
|
14
|
+
message.bodyCell.setStyle({
|
15
|
+
color: '#888888'
|
16
|
+
})
|
17
|
+
}
|
18
|
+
else if (body.innerText.match(/^\w+'s deploy of (.*) failed$/)) {
|
19
|
+
message.bodyCell.setStyle({
|
20
|
+
color: '#ff0000',
|
21
|
+
fontWeight: 'bold'
|
22
|
+
})
|
23
|
+
}
|
24
|
+
}
|
25
|
+
},
|
26
|
+
|
27
|
+
onMessagesInsertedBeforeDisplay: function(messages) {
|
28
|
+
for (var i = 0; i < messages.length; i++) {
|
29
|
+
this.detectCommit(messages[i]);
|
30
|
+
}
|
31
|
+
}
|
32
|
+
});
|
33
|
+
|
34
|
+
Campfire.Responders.push("CommitExpander");
|
35
|
+
window.chat.installPropaneResponder("CommitExpander", "commitexpander");
|
36
|
+
|
@@ -0,0 +1,70 @@
|
|
1
|
+
Campfire.PivotalTrackerExpander = Class.create({
|
2
|
+
initialize: function(chat) {
|
3
|
+
this.chat = chat;
|
4
|
+
var messages = this.chat.transcript.messages;
|
5
|
+
for (var i = 0; i < messages.length; i++) {
|
6
|
+
this.detectPivotalTracker(messages[i]);
|
7
|
+
}
|
8
|
+
},
|
9
|
+
|
10
|
+
detectPivotalTracker: function(message) {
|
11
|
+
if (!message.pending() && message.kind === 'text') {
|
12
|
+
var body = message.bodyElement()
|
13
|
+
if (body.innerText.match(/(in|to) project/i)) {
|
14
|
+
if (body.innerText.match(/pivotaltracker.com/i)) {
|
15
|
+
|
16
|
+
if (colorizePivotalTracker) {
|
17
|
+
if (body.innerText.match(/added/g)) {
|
18
|
+
message.bodyCell.setStyle({
|
19
|
+
color: pivotalTrackerAddedColor
|
20
|
+
})
|
21
|
+
} else if (body.innerText.match(/started/g)) {
|
22
|
+
message.bodyCell.setStyle({
|
23
|
+
color: pivotalTrackerStartedColor
|
24
|
+
})
|
25
|
+
} else if (body.innerText.match(/finished/g)) {
|
26
|
+
message.bodyCell.setStyle({
|
27
|
+
color: pivotalTrackerFinishedColor
|
28
|
+
})
|
29
|
+
} else if (body.innerText.match(/delivered/g)) {
|
30
|
+
message.bodyCell.setStyle({
|
31
|
+
color: pivotalTrackerDeliveredColor
|
32
|
+
})
|
33
|
+
} else if (body.innerText.match(/accepted/g)) {
|
34
|
+
message.bodyCell.setStyle({
|
35
|
+
color: pivotalTrackerAcceptedColor
|
36
|
+
})
|
37
|
+
} else if (body.innerText.match(/rejected/g)) {
|
38
|
+
message.bodyCell.setStyle({
|
39
|
+
color: pivotalTrackerRejectedColor
|
40
|
+
})
|
41
|
+
}
|
42
|
+
}
|
43
|
+
|
44
|
+
if (shortenPivotalName) {
|
45
|
+
matches = body.innerText.match(/^((?:[A-Z]{1}[a-z]* ?){2,3}) (?:added|started|finished|delivered|accepted|rejected)/)
|
46
|
+
body.innerHTML = body.innerHTML.replace(/^((?:[A-Z]{1}[a-z]* ?){2,3})/, "<strong>" + matches[1].replace(/[^A-Z]/g, '') + "</strong> ")
|
47
|
+
}
|
48
|
+
|
49
|
+
if (linkifyPivotalStories) {
|
50
|
+
matches = body.innerText.match(/"(.*)" \((.*)\)/)
|
51
|
+
body.innerHTML = body.innerHTML.replace(/(".*" \(.*\))/, "\"<a href='" + matches[2] + "' target='_blank'>" + matches[1] + "</a>\"");
|
52
|
+
}
|
53
|
+
}
|
54
|
+
}
|
55
|
+
}
|
56
|
+
},
|
57
|
+
|
58
|
+
onMessagesInsertedBeforeDisplay: function(messages) {
|
59
|
+
for (var i = 0; i < messages.length; i++) {
|
60
|
+
this.detectPivotalTracker(messages[i]);
|
61
|
+
}
|
62
|
+
},
|
63
|
+
|
64
|
+
onMessageAccepted: function(message, messageID) {
|
65
|
+
this.detectPivotalTracker(message);
|
66
|
+
}
|
67
|
+
});
|
68
|
+
|
69
|
+
Campfire.Responders.push("PivotalTrackerExpander");
|
70
|
+
window.chat.installPropaneResponder("PivotalTrackerExpander", "pivotaltrackerexpander");
|
@@ -0,0 +1,176 @@
|
|
1
|
+
/* MD5 LIB */
|
2
|
+
/*
|
3
|
+
* A JavaScript implementation of the RSA Data Security, Inc. MD5 Message
|
4
|
+
* Digest Algorithm, as defined in RFC 1321.
|
5
|
+
* Copyright (C) Paul Johnston 1999 - 2000.
|
6
|
+
* Updated by Greg Holt 2000 - 2001.
|
7
|
+
* See http://pajhome.org.uk/site/legal.html for details.
|
8
|
+
*/
|
9
|
+
|
10
|
+
/*
|
11
|
+
* Convert a 32-bit number to a hex string with ls-byte first
|
12
|
+
*/
|
13
|
+
var hex_chr = "0123456789abcdef";
|
14
|
+
function rhex(num)
|
15
|
+
{
|
16
|
+
str = "";
|
17
|
+
for(j = 0; j <= 3; j++)
|
18
|
+
str += hex_chr.charAt((num >> (j * 8 + 4)) & 0x0F) +
|
19
|
+
hex_chr.charAt((num >> (j * 8)) & 0x0F);
|
20
|
+
return str;
|
21
|
+
}
|
22
|
+
|
23
|
+
/*
|
24
|
+
* Convert a string to a sequence of 16-word blocks, stored as an array.
|
25
|
+
* Append padding bits and the length, as described in the MD5 standard.
|
26
|
+
*/
|
27
|
+
function str2blks_MD5(str)
|
28
|
+
{
|
29
|
+
nblk = ((str.length + 8) >> 6) + 1;
|
30
|
+
blks = new Array(nblk * 16);
|
31
|
+
for(i = 0; i < nblk * 16; i++) blks[i] = 0;
|
32
|
+
for(i = 0; i < str.length; i++)
|
33
|
+
blks[i >> 2] |= str.charCodeAt(i) << ((i % 4) * 8);
|
34
|
+
blks[i >> 2] |= 0x80 << ((i % 4) * 8);
|
35
|
+
blks[nblk * 16 - 2] = str.length * 8;
|
36
|
+
return blks;
|
37
|
+
}
|
38
|
+
|
39
|
+
/*
|
40
|
+
* Add integers, wrapping at 2^32. This uses 16-bit operations internally
|
41
|
+
* to work around bugs in some JS interpreters.
|
42
|
+
*/
|
43
|
+
function add(x, y)
|
44
|
+
{
|
45
|
+
var lsw = (x & 0xFFFF) + (y & 0xFFFF);
|
46
|
+
var msw = (x >> 16) + (y >> 16) + (lsw >> 16);
|
47
|
+
return (msw << 16) | (lsw & 0xFFFF);
|
48
|
+
}
|
49
|
+
|
50
|
+
/*
|
51
|
+
* Bitwise rotate a 32-bit number to the left
|
52
|
+
*/
|
53
|
+
function rol(num, cnt)
|
54
|
+
{
|
55
|
+
return (num << cnt) | (num >>> (32 - cnt));
|
56
|
+
}
|
57
|
+
|
58
|
+
/*
|
59
|
+
* These functions implement the basic operation for each round of the
|
60
|
+
* algorithm.
|
61
|
+
*/
|
62
|
+
function cmn(q, a, b, x, s, t)
|
63
|
+
{
|
64
|
+
return add(rol(add(add(a, q), add(x, t)), s), b);
|
65
|
+
}
|
66
|
+
function ff(a, b, c, d, x, s, t)
|
67
|
+
{
|
68
|
+
return cmn((b & c) | ((~b) & d), a, b, x, s, t);
|
69
|
+
}
|
70
|
+
function gg(a, b, c, d, x, s, t)
|
71
|
+
{
|
72
|
+
return cmn((b & d) | (c & (~d)), a, b, x, s, t);
|
73
|
+
}
|
74
|
+
function hh(a, b, c, d, x, s, t)
|
75
|
+
{
|
76
|
+
return cmn(b ^ c ^ d, a, b, x, s, t);
|
77
|
+
}
|
78
|
+
function ii(a, b, c, d, x, s, t)
|
79
|
+
{
|
80
|
+
return cmn(c ^ (b | (~d)), a, b, x, s, t);
|
81
|
+
}
|
82
|
+
|
83
|
+
/*
|
84
|
+
* Take a string and return the hex representation of its MD5.
|
85
|
+
*/
|
86
|
+
function calcMD5(str)
|
87
|
+
{
|
88
|
+
x = str2blks_MD5(str);
|
89
|
+
a = 1732584193;
|
90
|
+
b = -271733879;
|
91
|
+
c = -1732584194;
|
92
|
+
d = 271733878;
|
93
|
+
|
94
|
+
for(i = 0; i < x.length; i += 16)
|
95
|
+
{
|
96
|
+
olda = a;
|
97
|
+
oldb = b;
|
98
|
+
oldc = c;
|
99
|
+
oldd = d;
|
100
|
+
|
101
|
+
a = ff(a, b, c, d, x[i+ 0], 7 , -680876936);
|
102
|
+
d = ff(d, a, b, c, x[i+ 1], 12, -389564586);
|
103
|
+
c = ff(c, d, a, b, x[i+ 2], 17, 606105819);
|
104
|
+
b = ff(b, c, d, a, x[i+ 3], 22, -1044525330);
|
105
|
+
a = ff(a, b, c, d, x[i+ 4], 7 , -176418897);
|
106
|
+
d = ff(d, a, b, c, x[i+ 5], 12, 1200080426);
|
107
|
+
c = ff(c, d, a, b, x[i+ 6], 17, -1473231341);
|
108
|
+
b = ff(b, c, d, a, x[i+ 7], 22, -45705983);
|
109
|
+
a = ff(a, b, c, d, x[i+ 8], 7 , 1770035416);
|
110
|
+
d = ff(d, a, b, c, x[i+ 9], 12, -1958414417);
|
111
|
+
c = ff(c, d, a, b, x[i+10], 17, -42063);
|
112
|
+
b = ff(b, c, d, a, x[i+11], 22, -1990404162);
|
113
|
+
a = ff(a, b, c, d, x[i+12], 7 , 1804603682);
|
114
|
+
d = ff(d, a, b, c, x[i+13], 12, -40341101);
|
115
|
+
c = ff(c, d, a, b, x[i+14], 17, -1502002290);
|
116
|
+
b = ff(b, c, d, a, x[i+15], 22, 1236535329);
|
117
|
+
|
118
|
+
a = gg(a, b, c, d, x[i+ 1], 5 , -165796510);
|
119
|
+
d = gg(d, a, b, c, x[i+ 6], 9 , -1069501632);
|
120
|
+
c = gg(c, d, a, b, x[i+11], 14, 643717713);
|
121
|
+
b = gg(b, c, d, a, x[i+ 0], 20, -373897302);
|
122
|
+
a = gg(a, b, c, d, x[i+ 5], 5 , -701558691);
|
123
|
+
d = gg(d, a, b, c, x[i+10], 9 , 38016083);
|
124
|
+
c = gg(c, d, a, b, x[i+15], 14, -660478335);
|
125
|
+
b = gg(b, c, d, a, x[i+ 4], 20, -405537848);
|
126
|
+
a = gg(a, b, c, d, x[i+ 9], 5 , 568446438);
|
127
|
+
d = gg(d, a, b, c, x[i+14], 9 , -1019803690);
|
128
|
+
c = gg(c, d, a, b, x[i+ 3], 14, -187363961);
|
129
|
+
b = gg(b, c, d, a, x[i+ 8], 20, 1163531501);
|
130
|
+
a = gg(a, b, c, d, x[i+13], 5 , -1444681467);
|
131
|
+
d = gg(d, a, b, c, x[i+ 2], 9 , -51403784);
|
132
|
+
c = gg(c, d, a, b, x[i+ 7], 14, 1735328473);
|
133
|
+
b = gg(b, c, d, a, x[i+12], 20, -1926607734);
|
134
|
+
|
135
|
+
a = hh(a, b, c, d, x[i+ 5], 4 , -378558);
|
136
|
+
d = hh(d, a, b, c, x[i+ 8], 11, -2022574463);
|
137
|
+
c = hh(c, d, a, b, x[i+11], 16, 1839030562);
|
138
|
+
b = hh(b, c, d, a, x[i+14], 23, -35309556);
|
139
|
+
a = hh(a, b, c, d, x[i+ 1], 4 , -1530992060);
|
140
|
+
d = hh(d, a, b, c, x[i+ 4], 11, 1272893353);
|
141
|
+
c = hh(c, d, a, b, x[i+ 7], 16, -155497632);
|
142
|
+
b = hh(b, c, d, a, x[i+10], 23, -1094730640);
|
143
|
+
a = hh(a, b, c, d, x[i+13], 4 , 681279174);
|
144
|
+
d = hh(d, a, b, c, x[i+ 0], 11, -358537222);
|
145
|
+
c = hh(c, d, a, b, x[i+ 3], 16, -722521979);
|
146
|
+
b = hh(b, c, d, a, x[i+ 6], 23, 76029189);
|
147
|
+
a = hh(a, b, c, d, x[i+ 9], 4 , -640364487);
|
148
|
+
d = hh(d, a, b, c, x[i+12], 11, -421815835);
|
149
|
+
c = hh(c, d, a, b, x[i+15], 16, 530742520);
|
150
|
+
b = hh(b, c, d, a, x[i+ 2], 23, -995338651);
|
151
|
+
|
152
|
+
a = ii(a, b, c, d, x[i+ 0], 6 , -198630844);
|
153
|
+
d = ii(d, a, b, c, x[i+ 7], 10, 1126891415);
|
154
|
+
c = ii(c, d, a, b, x[i+14], 15, -1416354905);
|
155
|
+
b = ii(b, c, d, a, x[i+ 5], 21, -57434055);
|
156
|
+
a = ii(a, b, c, d, x[i+12], 6 , 1700485571);
|
157
|
+
d = ii(d, a, b, c, x[i+ 3], 10, -1894986606);
|
158
|
+
c = ii(c, d, a, b, x[i+10], 15, -1051523);
|
159
|
+
b = ii(b, c, d, a, x[i+ 1], 21, -2054922799);
|
160
|
+
a = ii(a, b, c, d, x[i+ 8], 6 , 1873313359);
|
161
|
+
d = ii(d, a, b, c, x[i+15], 10, -30611744);
|
162
|
+
c = ii(c, d, a, b, x[i+ 6], 15, -1560198380);
|
163
|
+
b = ii(b, c, d, a, x[i+13], 21, 1309151649);
|
164
|
+
a = ii(a, b, c, d, x[i+ 4], 6 , -145523070);
|
165
|
+
d = ii(d, a, b, c, x[i+11], 10, -1120210379);
|
166
|
+
c = ii(c, d, a, b, x[i+ 2], 15, 718787259);
|
167
|
+
b = ii(b, c, d, a, x[i+ 9], 21, -343485551);
|
168
|
+
|
169
|
+
a = add(a, olda);
|
170
|
+
b = add(b, oldb);
|
171
|
+
c = add(c, oldc);
|
172
|
+
d = add(d, oldd);
|
173
|
+
}
|
174
|
+
return rhex(a) + rhex(b) + rhex(c) + rhex(d);
|
175
|
+
}
|
176
|
+
/* END MD5 LIB */
|
metadata
ADDED
@@ -0,0 +1,123 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: caveat_patch_kids
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Josh Nichols
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2013-01-15 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: sprockets
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '0'
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ! '>='
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '0'
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
name: thor
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
34
|
+
requirements:
|
35
|
+
- - ! '>='
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: '0'
|
38
|
+
type: :runtime
|
39
|
+
prerelease: false
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ! '>='
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: '0'
|
46
|
+
- !ruby/object:Gem::Dependency
|
47
|
+
name: coffee-script
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
49
|
+
none: false
|
50
|
+
requirements:
|
51
|
+
- - ! '>='
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: '0'
|
54
|
+
type: :runtime
|
55
|
+
prerelease: false
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
58
|
+
requirements:
|
59
|
+
- - ! '>='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
description: Manage caveatPatchor.js files for Propane
|
63
|
+
email:
|
64
|
+
- josh@technicalpickles.com
|
65
|
+
executables:
|
66
|
+
- caveat-patch-kids
|
67
|
+
extensions: []
|
68
|
+
extra_rdoc_files: []
|
69
|
+
files:
|
70
|
+
- .gitignore
|
71
|
+
- Gemfile
|
72
|
+
- LICENSE.txt
|
73
|
+
- README.md
|
74
|
+
- Rakefile
|
75
|
+
- bin/caveat-patch-kids
|
76
|
+
- caveat_patch_kids.gemspec
|
77
|
+
- lib/caveat_patch_kids.rb
|
78
|
+
- lib/caveat_patch_kids/version.rb
|
79
|
+
- scripts/caveat_patch_kids.js
|
80
|
+
- scripts/caveat_patch_kids/bundles/all.js
|
81
|
+
- scripts/caveat_patch_kids/bundles/unsupported.js
|
82
|
+
- scripts/caveat_patch_kids/display_avatars.js
|
83
|
+
- scripts/caveat_patch_kids/display_githubs.js
|
84
|
+
- scripts/caveat_patch_kids/embiggen_message_history.js
|
85
|
+
- scripts/caveat_patch_kids/stylize_diffs.js
|
86
|
+
- scripts/caveat_patch_kids/stylize_nagios.js
|
87
|
+
- scripts/caveat_patch_kids/unsupported/display_emoji.js
|
88
|
+
- scripts/caveat_patch_kids/unsupported/display_html.js
|
89
|
+
- scripts/caveat_patch_kids/unsupported/display_musics.js
|
90
|
+
- scripts/caveat_patch_kids/unsupported/display_newrelic_charts.js
|
91
|
+
- scripts/caveat_patch_kids/unsupported/display_stars.js
|
92
|
+
- scripts/caveat_patch_kids/unsupported/focus_scroll_hax.js
|
93
|
+
- scripts/caveat_patch_kids/unsupported/stylize_builds.js
|
94
|
+
- scripts/caveat_patch_kids/unsupported/stylize_commits_and_deploys.js
|
95
|
+
- scripts/caveat_patch_kids/unsupported/stylize_pivotal_tracker.js
|
96
|
+
- vendor/assets/md5.js
|
97
|
+
homepage: ''
|
98
|
+
licenses: []
|
99
|
+
post_install_message:
|
100
|
+
rdoc_options: []
|
101
|
+
require_paths:
|
102
|
+
- lib
|
103
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
104
|
+
none: false
|
105
|
+
requirements:
|
106
|
+
- - ! '>='
|
107
|
+
- !ruby/object:Gem::Version
|
108
|
+
version: '0'
|
109
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
110
|
+
none: false
|
111
|
+
requirements:
|
112
|
+
- - ! '>='
|
113
|
+
- !ruby/object:Gem::Version
|
114
|
+
version: '0'
|
115
|
+
requirements: []
|
116
|
+
rubyforge_project:
|
117
|
+
rubygems_version: 1.8.23
|
118
|
+
signing_key:
|
119
|
+
specification_version: 3
|
120
|
+
summary: CaveatPatchKids is a tool for generating, sharing, and maintaing caveatPatchor.js
|
121
|
+
files for use with Propane, powered by sprockets and other fun stuff
|
122
|
+
test_files: []
|
123
|
+
has_rdoc:
|