caveat_patch_kids 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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:
|