├── .gitignore ├── README.md ├── jenx.xcodeproj └── project.pbxproj ├── jenx ├── Growl Registration Ticket.growlRegDict ├── Jenx.rb ├── JenxConnection.rb ├── JenxConnectionManager.rb ├── JenxConstants.rb ├── JenxLocalize.rb ├── JenxNotificationCenter.rb ├── JenxPreferences.rb ├── JenxStartup.rb ├── PreferencesController.rb ├── PreferencesGeneralViewController.rb ├── en.lproj │ ├── InfoPlist.strings │ ├── Jenx.xib │ ├── Localizable.strings │ └── PreferencesGeneralView.xib ├── fr.lproj │ ├── Jenx.xib │ ├── Localizable.strings │ └── PreferencesGeneralView.xib ├── images │ ├── app.tiff │ ├── build_failure.tiff │ ├── build_initiated.tiff │ ├── build_success.tiff │ ├── connecting.tiff │ ├── jenx.icns │ ├── jenx_failure.tiff │ ├── jenx_issues.tiff │ ├── jenx_success.tiff │ ├── projects.png │ └── refresh.png ├── jenx-Info.plist ├── jenx-Prefix.pch ├── main.m └── rb_main.rb └── tests ├── JenxConnectionTest.rb ├── JenxTestCase.rb └── run_suite.rb /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | *.swp 3 | *~.nib 4 | build/ 5 | *.pbxuser 6 | *.perspective 7 | *.perspectivev3 8 | *.mode1v3 9 | *.mode2v3 10 | *.xcworkspace/ 11 | xcuserdata -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # [Jenx](http://urbancoding.github.com/jenx/) # 2 | 3 | **Note: Due to Apple’s abandonment of the Objective-C Garbage Collector (libauto) which MacRuby 4 | relied heavily on and hence Jenx relied on, Jenx no longer works on recent versions of OS X and 5 | future development of Jenx is on an indefinite hiatus.** 6 | 7 | A [Jenkins](http://jenkins-ci.org/) build server monitor for Mac OS X, powered by [MacRuby](http://macruby.com/). 8 | This app sits in your status bar and reports the status of all your Jenkins builds. 9 | Click on a job, and it opens it up in your browser. It even supports [Growl](http://growl.info/)! 10 | 11 | Screenshot 12 | ------------ 13 | 14 | ![Screenshot](http://f.cl.ly/items/0n1N0n2E1m1l2y0G0y1C/Screen%20shot%202011-12-09%20at%208.45.32%20AM.png) 15 | 16 | Requirements 17 | ------------ 18 | 19 | * Mac OS X 10.6 (Snow Leopard) or higher 20 | * [MacRuby](http://macruby.com/) 1.0 (nightly build, 2011-04-14 or newer) 21 | 22 | Updates, Changelog & Feedback 23 | ------------ 24 | 25 | * The beta release can be downloaded here [Jenx](http://urbancoding.github.com/jenx/) 26 | 27 | Contact 28 | ------------ 29 | 30 | * Email: jenx@urbancoding.net 31 | * Hop into the IRC channel: [#jenx](irc://irc.freenode.net/#jenx) 32 | * Watch for updates or ask questions on Twitter: [@jenx_monitor](https://twitter.com/#!/jenx_monitor) 33 | 34 | Contributors 35 | ------------ 36 | 37 | Roman Dmytrenko (erka) 38 | 39 | * brought ssl and basic auth to Jenx 40 | 41 | 42 | Contributing 43 | ------------ 44 | 45 | **Everyone** is encouraged to help improve this project. 46 | 47 | Here are some ways *you* can contribute: 48 | 49 | * by reporting bugs 50 | * by suggesting new features 51 | * by writing or editing documentation 52 | * by writing specifications 53 | * by writing code (**no patch is too small**: fix typos, add comments, clean up inconsistent whitespace) 54 | * by refactoring code 55 | * by reviewing patches 56 | 57 | -------------------------------------------------------------------------------- /jenx.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 04E861051423BE62006DA573 /* PreferencesGeneralView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 04E861071423BE62006DA573 /* PreferencesGeneralView.xib */; }; 11 | 04E861181423DE92006DA573 /* JenxLocalize.rb in Resources */ = {isa = PBXBuildFile; fileRef = 04E861171423DE92006DA573 /* JenxLocalize.rb */; }; 12 | 04E8611C1423E2E8006DA573 /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = 04E8611E1423E2E8006DA573 /* Localizable.strings */; }; 13 | 962C55B9146766DD007994E9 /* MacRuby.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 962C55B8146766DD007994E9 /* MacRuby.framework */; }; 14 | 9642B2A013CF4F9200B50334 /* Growl.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = 96801661138A3BB800050ED2 /* Growl.framework */; }; 15 | 96512B6D13CBD75A0028D5A8 /* JenxNotificationCenter.rb in Resources */ = {isa = PBXBuildFile; fileRef = 96512B6C13CBD75A0028D5A8 /* JenxNotificationCenter.rb */; }; 16 | 96512B7113CBE2610028D5A8 /* jenx_failure.tiff in Resources */ = {isa = PBXBuildFile; fileRef = 96512B6F13CBE2610028D5A8 /* jenx_failure.tiff */; }; 17 | 96512B7213CBE2610028D5A8 /* jenx_success.tiff in Resources */ = {isa = PBXBuildFile; fileRef = 96512B7013CBE2610028D5A8 /* jenx_success.tiff */; }; 18 | 9654D82013CAD9AD00FC2602 /* jenx.icns in Resources */ = {isa = PBXBuildFile; fileRef = 9654D81F13CAD9AD00FC2602 /* jenx.icns */; }; 19 | 96801662138A3BB800050ED2 /* Growl.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 96801661138A3BB800050ED2 /* Growl.framework */; settings = {ATTRIBUTES = (Required, ); }; }; 20 | 9680166F138A3CDA00050ED2 /* Growl Registration Ticket.growlRegDict in Resources */ = {isa = PBXBuildFile; fileRef = 9680166E138A3CDA00050ED2 /* Growl Registration Ticket.growlRegDict */; }; 21 | 96801689138B26F500050ED2 /* JenxConnectionManager.rb in Resources */ = {isa = PBXBuildFile; fileRef = 96801688138B26F500050ED2 /* JenxConnectionManager.rb */; }; 22 | 9680168C138B6A2800050ED2 /* JenxConnection.rb in Resources */ = {isa = PBXBuildFile; fileRef = 9680168B138B6A2800050ED2 /* JenxConnection.rb */; }; 23 | 96803B6C1384B19300D5DD90 /* refresh.png in Resources */ = {isa = PBXBuildFile; fileRef = 96803B6B1384B19300D5DD90 /* refresh.png */; }; 24 | 96803B6E1384B79F00D5DD90 /* projects.png in Resources */ = {isa = PBXBuildFile; fileRef = 96803B6D1384B79F00D5DD90 /* projects.png */; }; 25 | 96803B8B1384CA3B00D5DD90 /* build_initiated.tiff in Resources */ = {isa = PBXBuildFile; fileRef = 96803B8A1384CA3B00D5DD90 /* build_initiated.tiff */; }; 26 | 96803B8E1384CB4000D5DD90 /* app.tiff in Resources */ = {isa = PBXBuildFile; fileRef = 96803B8C1384CB4000D5DD90 /* app.tiff */; }; 27 | 96803B8F1384CB4000D5DD90 /* build_failure.tiff in Resources */ = {isa = PBXBuildFile; fileRef = 96803B8D1384CB4000D5DD90 /* build_failure.tiff */; }; 28 | 9683417013CE969E003667B5 /* jenx_issues.tiff in Resources */ = {isa = PBXBuildFile; fileRef = 9683416F13CE969E003667B5 /* jenx_issues.tiff */; }; 29 | 96B6FD0413860F95009C1021 /* PreferencesGeneralViewController.rb in Resources */ = {isa = PBXBuildFile; fileRef = 96B6FD0313860F95009C1021 /* PreferencesGeneralViewController.rb */; }; 30 | 96B6FD0613861B97009C1021 /* PreferencesController.rb in Resources */ = {isa = PBXBuildFile; fileRef = 96B6FD0513861B97009C1021 /* PreferencesController.rb */; }; 31 | 96B6FD0813862428009C1021 /* JenxConstants.rb in Resources */ = {isa = PBXBuildFile; fileRef = 96B6FD0713862428009C1021 /* JenxConstants.rb */; }; 32 | 96CCF18413838DD50010CC22 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 96CCF18313838DD50010CC22 /* Cocoa.framework */; }; 33 | 96CCF18D13838DD50010CC22 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 96CCF18B13838DD50010CC22 /* InfoPlist.strings */; }; 34 | 96CCF19013838DD50010CC22 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 96CCF18F13838DD50010CC22 /* main.m */; }; 35 | 96CCF19413838DD50010CC22 /* Jenx.xib in Resources */ = {isa = PBXBuildFile; fileRef = 96CCF19213838DD50010CC22 /* Jenx.xib */; }; 36 | 96CCF19713838DD50010CC22 /* rb_main.rb in Resources */ = {isa = PBXBuildFile; fileRef = 96CCF19613838DD50010CC22 /* rb_main.rb */; }; 37 | 96CCF19913838DD50010CC22 /* Jenx.rb in Resources */ = {isa = PBXBuildFile; fileRef = 96CCF19813838DD50010CC22 /* Jenx.rb */; }; 38 | 96EB2829138A04DF00D02D6B /* connecting.tiff in Resources */ = {isa = PBXBuildFile; fileRef = 96EB2828138A04DF00D02D6B /* connecting.tiff */; }; 39 | 96EF2B9E1384E2E8002A755A /* build_success.tiff in Resources */ = {isa = PBXBuildFile; fileRef = 96EF2B9D1384E2E8002A755A /* build_success.tiff */; }; 40 | 96F678DD13CE753D003BFD59 /* JenxStartup.rb in Resources */ = {isa = PBXBuildFile; fileRef = 96F678DC13CE753D003BFD59 /* JenxStartup.rb */; }; 41 | 96FB0083138642C4001EB442 /* JenxPreferences.rb in Resources */ = {isa = PBXBuildFile; fileRef = 96FB0082138642C4001EB442 /* JenxPreferences.rb */; }; 42 | /* End PBXBuildFile section */ 43 | 44 | /* Begin PBXCopyFilesBuildPhase section */ 45 | 9642B29F13CF4F3C00B50334 /* CopyFiles */ = { 46 | isa = PBXCopyFilesBuildPhase; 47 | buildActionMask = 2147483647; 48 | dstPath = ""; 49 | dstSubfolderSpec = 10; 50 | files = ( 51 | 9642B2A013CF4F9200B50334 /* Growl.framework in CopyFiles */, 52 | ); 53 | runOnlyForDeploymentPostprocessing = 0; 54 | }; 55 | /* End PBXCopyFilesBuildPhase section */ 56 | 57 | /* Begin PBXFileReference section */ 58 | 04E861041423BDF1006DA573 /* fr */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = fr; path = fr.lproj/Jenx.xib; sourceTree = ""; }; 59 | 04E861061423BE62006DA573 /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = en.lproj/PreferencesGeneralView.xib; sourceTree = ""; }; 60 | 04E861081423C128006DA573 /* fr */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = fr; path = fr.lproj/PreferencesGeneralView.xib; sourceTree = ""; }; 61 | 04E861171423DE92006DA573 /* JenxLocalize.rb */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.ruby; path = JenxLocalize.rb; sourceTree = ""; }; 62 | 04E8611D1423E2E8006DA573 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/Localizable.strings; sourceTree = ""; }; 63 | 04E8611F1423FD2D006DA573 /* fr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fr; path = fr.lproj/Localizable.strings; sourceTree = ""; }; 64 | 962C55B8146766DD007994E9 /* MacRuby.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = MacRuby.framework; path = Library/Frameworks/MacRuby.framework; sourceTree = SDKROOT; }; 65 | 96512B6C13CBD75A0028D5A8 /* JenxNotificationCenter.rb */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.ruby; path = JenxNotificationCenter.rb; sourceTree = ""; }; 66 | 96512B6F13CBE2610028D5A8 /* jenx_failure.tiff */ = {isa = PBXFileReference; lastKnownFileType = image.tiff; name = jenx_failure.tiff; path = images/jenx_failure.tiff; sourceTree = ""; }; 67 | 96512B7013CBE2610028D5A8 /* jenx_success.tiff */ = {isa = PBXFileReference; lastKnownFileType = image.tiff; name = jenx_success.tiff; path = images/jenx_success.tiff; sourceTree = ""; }; 68 | 9654D81F13CAD9AD00FC2602 /* jenx.icns */ = {isa = PBXFileReference; lastKnownFileType = image.icns; name = jenx.icns; path = images/jenx.icns; sourceTree = ""; }; 69 | 96801661138A3BB800050ED2 /* Growl.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Growl.framework; path = Library/Frameworks/Growl.framework; sourceTree = SDKROOT; }; 70 | 9680166E138A3CDA00050ED2 /* Growl Registration Ticket.growlRegDict */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = "Growl Registration Ticket.growlRegDict"; sourceTree = ""; }; 71 | 96801688138B26F500050ED2 /* JenxConnectionManager.rb */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.ruby; path = JenxConnectionManager.rb; sourceTree = ""; }; 72 | 9680168B138B6A2800050ED2 /* JenxConnection.rb */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.ruby; path = JenxConnection.rb; sourceTree = ""; }; 73 | 96803B6B1384B19300D5DD90 /* refresh.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = refresh.png; path = images/refresh.png; sourceTree = ""; }; 74 | 96803B6D1384B79F00D5DD90 /* projects.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = projects.png; path = images/projects.png; sourceTree = ""; }; 75 | 96803B8A1384CA3B00D5DD90 /* build_initiated.tiff */ = {isa = PBXFileReference; lastKnownFileType = image.tiff; name = build_initiated.tiff; path = images/build_initiated.tiff; sourceTree = ""; }; 76 | 96803B8C1384CB4000D5DD90 /* app.tiff */ = {isa = PBXFileReference; lastKnownFileType = image.tiff; name = app.tiff; path = images/app.tiff; sourceTree = ""; }; 77 | 96803B8D1384CB4000D5DD90 /* build_failure.tiff */ = {isa = PBXFileReference; lastKnownFileType = image.tiff; name = build_failure.tiff; path = images/build_failure.tiff; sourceTree = ""; }; 78 | 9683416F13CE969E003667B5 /* jenx_issues.tiff */ = {isa = PBXFileReference; lastKnownFileType = image.tiff; name = jenx_issues.tiff; path = images/jenx_issues.tiff; sourceTree = ""; }; 79 | 96B6FD0313860F95009C1021 /* PreferencesGeneralViewController.rb */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.ruby; path = PreferencesGeneralViewController.rb; sourceTree = ""; }; 80 | 96B6FD0513861B97009C1021 /* PreferencesController.rb */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.ruby; path = PreferencesController.rb; sourceTree = ""; }; 81 | 96B6FD0713862428009C1021 /* JenxConstants.rb */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.ruby; path = JenxConstants.rb; sourceTree = ""; }; 82 | 96CCF17F13838DD50010CC22 /* jenx.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = jenx.app; sourceTree = BUILT_PRODUCTS_DIR; }; 83 | 96CCF18313838DD50010CC22 /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = System/Library/Frameworks/Cocoa.framework; sourceTree = SDKROOT; }; 84 | 96CCF18A13838DD50010CC22 /* jenx-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "jenx-Info.plist"; sourceTree = ""; }; 85 | 96CCF18C13838DD50010CC22 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = ""; }; 86 | 96CCF18E13838DD50010CC22 /* jenx-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "jenx-Prefix.pch"; sourceTree = ""; }; 87 | 96CCF18F13838DD50010CC22 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 88 | 96CCF19313838DD50010CC22 /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = en.lproj/Jenx.xib; sourceTree = ""; }; 89 | 96CCF19613838DD50010CC22 /* rb_main.rb */ = {isa = PBXFileReference; lastKnownFileType = text.script.ruby; path = rb_main.rb; sourceTree = ""; }; 90 | 96CCF19813838DD50010CC22 /* Jenx.rb */ = {isa = PBXFileReference; lastKnownFileType = text.script.ruby; path = Jenx.rb; sourceTree = ""; }; 91 | 96EB2828138A04DF00D02D6B /* connecting.tiff */ = {isa = PBXFileReference; lastKnownFileType = image.tiff; name = connecting.tiff; path = images/connecting.tiff; sourceTree = ""; }; 92 | 96EF2B9D1384E2E8002A755A /* build_success.tiff */ = {isa = PBXFileReference; lastKnownFileType = image.tiff; name = build_success.tiff; path = images/build_success.tiff; sourceTree = ""; }; 93 | 96F678DC13CE753D003BFD59 /* JenxStartup.rb */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.ruby; path = JenxStartup.rb; sourceTree = ""; }; 94 | 96FB0082138642C4001EB442 /* JenxPreferences.rb */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.ruby; path = JenxPreferences.rb; sourceTree = ""; }; 95 | /* End PBXFileReference section */ 96 | 97 | /* Begin PBXFrameworksBuildPhase section */ 98 | 96CCF17C13838DD50010CC22 /* Frameworks */ = { 99 | isa = PBXFrameworksBuildPhase; 100 | buildActionMask = 2147483647; 101 | files = ( 102 | 962C55B9146766DD007994E9 /* MacRuby.framework in Frameworks */, 103 | 96801662138A3BB800050ED2 /* Growl.framework in Frameworks */, 104 | 96CCF18413838DD50010CC22 /* Cocoa.framework in Frameworks */, 105 | ); 106 | runOnlyForDeploymentPostprocessing = 0; 107 | }; 108 | /* End PBXFrameworksBuildPhase section */ 109 | 110 | /* Begin PBXGroup section */ 111 | 96803B891384CA0600D5DD90 /* Icons */ = { 112 | isa = PBXGroup; 113 | children = ( 114 | 9683416F13CE969E003667B5 /* jenx_issues.tiff */, 115 | 96512B6F13CBE2610028D5A8 /* jenx_failure.tiff */, 116 | 96512B7013CBE2610028D5A8 /* jenx_success.tiff */, 117 | 9654D81F13CAD9AD00FC2602 /* jenx.icns */, 118 | 96EB2828138A04DF00D02D6B /* connecting.tiff */, 119 | 96803B8C1384CB4000D5DD90 /* app.tiff */, 120 | 96EF2B9D1384E2E8002A755A /* build_success.tiff */, 121 | 96803B8D1384CB4000D5DD90 /* build_failure.tiff */, 122 | 96803B8A1384CA3B00D5DD90 /* build_initiated.tiff */, 123 | 96803B6D1384B79F00D5DD90 /* projects.png */, 124 | 96803B6B1384B19300D5DD90 /* refresh.png */, 125 | ); 126 | name = Icons; 127 | sourceTree = ""; 128 | }; 129 | 96B6FD09138626E2009C1021 /* Controllers */ = { 130 | isa = PBXGroup; 131 | children = ( 132 | 96B6FD0513861B97009C1021 /* PreferencesController.rb */, 133 | 96B6FD0313860F95009C1021 /* PreferencesGeneralViewController.rb */, 134 | ); 135 | name = Controllers; 136 | sourceTree = ""; 137 | }; 138 | 96B6FD0A138626F3009C1021 /* Assets */ = { 139 | isa = PBXGroup; 140 | children = ( 141 | 9680166E138A3CDA00050ED2 /* Growl Registration Ticket.growlRegDict */, 142 | 96803B891384CA0600D5DD90 /* Icons */, 143 | ); 144 | name = Assets; 145 | sourceTree = ""; 146 | }; 147 | 96CCF17413838DD50010CC22 = { 148 | isa = PBXGroup; 149 | children = ( 150 | 96CCF18813838DD50010CC22 /* jenx */, 151 | 96CCF18213838DD50010CC22 /* Frameworks */, 152 | 96CCF18013838DD50010CC22 /* Products */, 153 | ); 154 | sourceTree = ""; 155 | }; 156 | 96CCF18013838DD50010CC22 /* Products */ = { 157 | isa = PBXGroup; 158 | children = ( 159 | 96CCF17F13838DD50010CC22 /* jenx.app */, 160 | ); 161 | name = Products; 162 | sourceTree = ""; 163 | }; 164 | 96CCF18213838DD50010CC22 /* Frameworks */ = { 165 | isa = PBXGroup; 166 | children = ( 167 | 96CCF18313838DD50010CC22 /* Cocoa.framework */, 168 | 96801661138A3BB800050ED2 /* Growl.framework */, 169 | 962C55B8146766DD007994E9 /* MacRuby.framework */, 170 | ); 171 | name = Frameworks; 172 | sourceTree = ""; 173 | }; 174 | 96CCF18813838DD50010CC22 /* jenx */ = { 175 | isa = PBXGroup; 176 | children = ( 177 | 96CCF19813838DD50010CC22 /* Jenx.rb */, 178 | 96B6FD0A138626F3009C1021 /* Assets */, 179 | 96B6FD09138626E2009C1021 /* Controllers */, 180 | 96FB008013864264001EB442 /* Classes */, 181 | 96CCF19113838DD50010CC22 /* Views */, 182 | 96CCF19513838DD50010CC22 /* Other Sources */, 183 | 96CCF18913838DD50010CC22 /* Supporting Files */, 184 | ); 185 | path = jenx; 186 | sourceTree = ""; 187 | }; 188 | 96CCF18913838DD50010CC22 /* Supporting Files */ = { 189 | isa = PBXGroup; 190 | children = ( 191 | 96CCF18A13838DD50010CC22 /* jenx-Info.plist */, 192 | 96CCF18B13838DD50010CC22 /* InfoPlist.strings */, 193 | 96CCF18E13838DD50010CC22 /* jenx-Prefix.pch */, 194 | 96CCF18F13838DD50010CC22 /* main.m */, 195 | 04E8611E1423E2E8006DA573 /* Localizable.strings */, 196 | ); 197 | name = "Supporting Files"; 198 | sourceTree = ""; 199 | }; 200 | 96CCF19113838DD50010CC22 /* Views */ = { 201 | isa = PBXGroup; 202 | children = ( 203 | 96CCF19213838DD50010CC22 /* Jenx.xib */, 204 | 04E861071423BE62006DA573 /* PreferencesGeneralView.xib */, 205 | ); 206 | name = Views; 207 | sourceTree = ""; 208 | }; 209 | 96CCF19513838DD50010CC22 /* Other Sources */ = { 210 | isa = PBXGroup; 211 | children = ( 212 | 96CCF19613838DD50010CC22 /* rb_main.rb */, 213 | ); 214 | name = "Other Sources"; 215 | sourceTree = ""; 216 | }; 217 | 96FB008013864264001EB442 /* Classes */ = { 218 | isa = PBXGroup; 219 | children = ( 220 | 04E861171423DE92006DA573 /* JenxLocalize.rb */, 221 | 96B6FD0713862428009C1021 /* JenxConstants.rb */, 222 | 96FB0082138642C4001EB442 /* JenxPreferences.rb */, 223 | 9680168B138B6A2800050ED2 /* JenxConnection.rb */, 224 | 96801688138B26F500050ED2 /* JenxConnectionManager.rb */, 225 | 96512B6C13CBD75A0028D5A8 /* JenxNotificationCenter.rb */, 226 | 96F678DC13CE753D003BFD59 /* JenxStartup.rb */, 227 | ); 228 | name = Classes; 229 | sourceTree = ""; 230 | }; 231 | /* End PBXGroup section */ 232 | 233 | /* Begin PBXLegacyTarget section */ 234 | 96CCF18713838DD50010CC22 /* Deployment */ = { 235 | isa = PBXLegacyTarget; 236 | buildArgumentsString = "--compile --embed"; 237 | buildConfigurationList = 96CCF19F13838DD50010CC22 /* Build configuration list for PBXLegacyTarget "Deployment" */; 238 | buildPhases = ( 239 | ); 240 | buildToolPath = /Library/Frameworks/MacRuby.framework/Versions/Current/usr/bin/macruby_deploy; 241 | buildWorkingDirectory = ""; 242 | dependencies = ( 243 | ); 244 | name = Deployment; 245 | passBuildSettingsInEnvironment = 1; 246 | productName = Deployment; 247 | }; 248 | /* End PBXLegacyTarget section */ 249 | 250 | /* Begin PBXNativeTarget section */ 251 | 96CCF17E13838DD50010CC22 /* jenx */ = { 252 | isa = PBXNativeTarget; 253 | buildConfigurationList = 96CCF19C13838DD50010CC22 /* Build configuration list for PBXNativeTarget "jenx" */; 254 | buildPhases = ( 255 | 96CCF17B13838DD50010CC22 /* Sources */, 256 | 96CCF17C13838DD50010CC22 /* Frameworks */, 257 | 96CCF17D13838DD50010CC22 /* Resources */, 258 | 9642B29F13CF4F3C00B50334 /* CopyFiles */, 259 | ); 260 | buildRules = ( 261 | ); 262 | dependencies = ( 263 | ); 264 | name = jenx; 265 | productName = jenx; 266 | productReference = 96CCF17F13838DD50010CC22 /* jenx.app */; 267 | productType = "com.apple.product-type.application"; 268 | }; 269 | /* End PBXNativeTarget section */ 270 | 271 | /* Begin PBXProject section */ 272 | 96CCF17613838DD50010CC22 /* Project object */ = { 273 | isa = PBXProject; 274 | attributes = { 275 | LastUpgradeCheck = 0420; 276 | ORGANIZATIONNAME = "Urban Coding"; 277 | }; 278 | buildConfigurationList = 96CCF17913838DD50010CC22 /* Build configuration list for PBXProject "Jenx" */; 279 | compatibilityVersion = "Xcode 3.2"; 280 | developmentRegion = English; 281 | hasScannedForEncodings = 0; 282 | knownRegions = ( 283 | en, 284 | fr, 285 | ); 286 | mainGroup = 96CCF17413838DD50010CC22; 287 | productRefGroup = 96CCF18013838DD50010CC22 /* Products */; 288 | projectDirPath = ""; 289 | projectRoot = ""; 290 | targets = ( 291 | 96CCF17E13838DD50010CC22 /* jenx */, 292 | 96CCF18713838DD50010CC22 /* Deployment */, 293 | ); 294 | }; 295 | /* End PBXProject section */ 296 | 297 | /* Begin PBXResourcesBuildPhase section */ 298 | 96CCF17D13838DD50010CC22 /* Resources */ = { 299 | isa = PBXResourcesBuildPhase; 300 | buildActionMask = 2147483647; 301 | files = ( 302 | 96CCF18D13838DD50010CC22 /* InfoPlist.strings in Resources */, 303 | 96CCF19413838DD50010CC22 /* Jenx.xib in Resources */, 304 | 96CCF19713838DD50010CC22 /* rb_main.rb in Resources */, 305 | 96CCF19913838DD50010CC22 /* Jenx.rb in Resources */, 306 | 96803B6C1384B19300D5DD90 /* refresh.png in Resources */, 307 | 96803B6E1384B79F00D5DD90 /* projects.png in Resources */, 308 | 96803B8B1384CA3B00D5DD90 /* build_initiated.tiff in Resources */, 309 | 96803B8E1384CB4000D5DD90 /* app.tiff in Resources */, 310 | 96803B8F1384CB4000D5DD90 /* build_failure.tiff in Resources */, 311 | 96EF2B9E1384E2E8002A755A /* build_success.tiff in Resources */, 312 | 04E861051423BE62006DA573 /* PreferencesGeneralView.xib in Resources */, 313 | 96B6FD0413860F95009C1021 /* PreferencesGeneralViewController.rb in Resources */, 314 | 96B6FD0613861B97009C1021 /* PreferencesController.rb in Resources */, 315 | 96B6FD0813862428009C1021 /* JenxConstants.rb in Resources */, 316 | 96FB0083138642C4001EB442 /* JenxPreferences.rb in Resources */, 317 | 96EB2829138A04DF00D02D6B /* connecting.tiff in Resources */, 318 | 9680166F138A3CDA00050ED2 /* Growl Registration Ticket.growlRegDict in Resources */, 319 | 96801689138B26F500050ED2 /* JenxConnectionManager.rb in Resources */, 320 | 9680168C138B6A2800050ED2 /* JenxConnection.rb in Resources */, 321 | 9654D82013CAD9AD00FC2602 /* jenx.icns in Resources */, 322 | 96512B6D13CBD75A0028D5A8 /* JenxNotificationCenter.rb in Resources */, 323 | 96512B7113CBE2610028D5A8 /* jenx_failure.tiff in Resources */, 324 | 96512B7213CBE2610028D5A8 /* jenx_success.tiff in Resources */, 325 | 96F678DD13CE753D003BFD59 /* JenxStartup.rb in Resources */, 326 | 9683417013CE969E003667B5 /* jenx_issues.tiff in Resources */, 327 | 04E861181423DE92006DA573 /* JenxLocalize.rb in Resources */, 328 | 04E8611C1423E2E8006DA573 /* Localizable.strings in Resources */, 329 | ); 330 | runOnlyForDeploymentPostprocessing = 0; 331 | }; 332 | /* End PBXResourcesBuildPhase section */ 333 | 334 | /* Begin PBXSourcesBuildPhase section */ 335 | 96CCF17B13838DD50010CC22 /* Sources */ = { 336 | isa = PBXSourcesBuildPhase; 337 | buildActionMask = 2147483647; 338 | files = ( 339 | 96CCF19013838DD50010CC22 /* main.m in Sources */, 340 | ); 341 | runOnlyForDeploymentPostprocessing = 0; 342 | }; 343 | /* End PBXSourcesBuildPhase section */ 344 | 345 | /* Begin PBXVariantGroup section */ 346 | 04E861071423BE62006DA573 /* PreferencesGeneralView.xib */ = { 347 | isa = PBXVariantGroup; 348 | children = ( 349 | 04E861061423BE62006DA573 /* en */, 350 | 04E861081423C128006DA573 /* fr */, 351 | ); 352 | name = PreferencesGeneralView.xib; 353 | sourceTree = ""; 354 | }; 355 | 04E8611E1423E2E8006DA573 /* Localizable.strings */ = { 356 | isa = PBXVariantGroup; 357 | children = ( 358 | 04E8611D1423E2E8006DA573 /* en */, 359 | 04E8611F1423FD2D006DA573 /* fr */, 360 | ); 361 | name = Localizable.strings; 362 | sourceTree = ""; 363 | }; 364 | 96CCF18B13838DD50010CC22 /* InfoPlist.strings */ = { 365 | isa = PBXVariantGroup; 366 | children = ( 367 | 96CCF18C13838DD50010CC22 /* en */, 368 | ); 369 | name = InfoPlist.strings; 370 | sourceTree = ""; 371 | }; 372 | 96CCF19213838DD50010CC22 /* Jenx.xib */ = { 373 | isa = PBXVariantGroup; 374 | children = ( 375 | 96CCF19313838DD50010CC22 /* en */, 376 | 04E861041423BDF1006DA573 /* fr */, 377 | ); 378 | name = Jenx.xib; 379 | sourceTree = ""; 380 | }; 381 | /* End PBXVariantGroup section */ 382 | 383 | /* Begin XCBuildConfiguration section */ 384 | 96CCF19A13838DD50010CC22 /* Debug */ = { 385 | isa = XCBuildConfiguration; 386 | buildSettings = { 387 | ARCHS = "$(ARCHS_STANDARD_32_64_BIT)"; 388 | GCC_C_LANGUAGE_STANDARD = gnu99; 389 | GCC_OPTIMIZATION_LEVEL = 0; 390 | GCC_PREPROCESSOR_DEFINITIONS = DEBUG; 391 | GCC_SYMBOLS_PRIVATE_EXTERN = NO; 392 | GCC_VERSION = com.apple.compilers.llvm.clang.1_0; 393 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 394 | GCC_WARN_ABOUT_RETURN_TYPE = YES; 395 | GCC_WARN_UNUSED_VARIABLE = YES; 396 | MACOSX_DEPLOYMENT_TARGET = 10.6; 397 | ONLY_ACTIVE_ARCH = YES; 398 | SDKROOT = macosx; 399 | VALID_ARCHS = x86_64; 400 | }; 401 | name = Debug; 402 | }; 403 | 96CCF19B13838DD50010CC22 /* Release */ = { 404 | isa = XCBuildConfiguration; 405 | buildSettings = { 406 | ARCHS = "$(ARCHS_STANDARD_32_64_BIT)"; 407 | GCC_C_LANGUAGE_STANDARD = gnu99; 408 | GCC_VERSION = com.apple.compilers.llvm.clang.1_0; 409 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 410 | GCC_WARN_ABOUT_RETURN_TYPE = YES; 411 | GCC_WARN_UNUSED_VARIABLE = YES; 412 | MACOSX_DEPLOYMENT_TARGET = 10.6; 413 | SDKROOT = macosx; 414 | VALID_ARCHS = x86_64; 415 | }; 416 | name = Release; 417 | }; 418 | 96CCF19D13838DD50010CC22 /* Debug */ = { 419 | isa = XCBuildConfiguration; 420 | buildSettings = { 421 | ALWAYS_SEARCH_USER_PATHS = NO; 422 | ARCHS = "$(NATIVE_ARCH_ACTUAL)"; 423 | COPY_PHASE_STRIP = NO; 424 | GCC_DYNAMIC_NO_PIC = NO; 425 | GCC_ENABLE_OBJC_EXCEPTIONS = YES; 426 | GCC_ENABLE_OBJC_GC = required; 427 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 428 | GCC_PREFIX_HEADER = "jenx/jenx-Prefix.pch"; 429 | INFOPLIST_FILE = "jenx/jenx-Info.plist"; 430 | PRODUCT_NAME = jenx; 431 | VALID_ARCHS = x86_64; 432 | WRAPPER_EXTENSION = app; 433 | }; 434 | name = Debug; 435 | }; 436 | 96CCF19E13838DD50010CC22 /* Release */ = { 437 | isa = XCBuildConfiguration; 438 | buildSettings = { 439 | ALWAYS_SEARCH_USER_PATHS = NO; 440 | ARCHS = "$(NATIVE_ARCH_ACTUAL)"; 441 | COPY_PHASE_STRIP = YES; 442 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 443 | GCC_ENABLE_OBJC_EXCEPTIONS = YES; 444 | GCC_ENABLE_OBJC_GC = required; 445 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 446 | GCC_PREFIX_HEADER = "jenx/jenx-Prefix.pch"; 447 | INFOPLIST_FILE = "jenx/jenx-Info.plist"; 448 | PRODUCT_NAME = jenx; 449 | VALID_ARCHS = x86_64; 450 | WRAPPER_EXTENSION = app; 451 | }; 452 | name = Release; 453 | }; 454 | 96CCF1A013838DD50010CC22 /* Debug */ = { 455 | isa = XCBuildConfiguration; 456 | buildSettings = { 457 | }; 458 | name = Debug; 459 | }; 460 | 96CCF1A113838DD50010CC22 /* Release */ = { 461 | isa = XCBuildConfiguration; 462 | buildSettings = { 463 | }; 464 | name = Release; 465 | }; 466 | /* End XCBuildConfiguration section */ 467 | 468 | /* Begin XCConfigurationList section */ 469 | 96CCF17913838DD50010CC22 /* Build configuration list for PBXProject "Jenx" */ = { 470 | isa = XCConfigurationList; 471 | buildConfigurations = ( 472 | 96CCF19A13838DD50010CC22 /* Debug */, 473 | 96CCF19B13838DD50010CC22 /* Release */, 474 | ); 475 | defaultConfigurationIsVisible = 0; 476 | defaultConfigurationName = Release; 477 | }; 478 | 96CCF19C13838DD50010CC22 /* Build configuration list for PBXNativeTarget "jenx" */ = { 479 | isa = XCConfigurationList; 480 | buildConfigurations = ( 481 | 96CCF19D13838DD50010CC22 /* Debug */, 482 | 96CCF19E13838DD50010CC22 /* Release */, 483 | ); 484 | defaultConfigurationIsVisible = 0; 485 | defaultConfigurationName = Release; 486 | }; 487 | 96CCF19F13838DD50010CC22 /* Build configuration list for PBXLegacyTarget "Deployment" */ = { 488 | isa = XCConfigurationList; 489 | buildConfigurations = ( 490 | 96CCF1A013838DD50010CC22 /* Debug */, 491 | 96CCF1A113838DD50010CC22 /* Release */, 492 | ); 493 | defaultConfigurationIsVisible = 0; 494 | defaultConfigurationName = Release; 495 | }; 496 | /* End XCConfigurationList section */ 497 | }; 498 | rootObject = 96CCF17613838DD50010CC22 /* Project object */; 499 | } 500 | -------------------------------------------------------------------------------- /jenx/Growl Registration Ticket.growlRegDict: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | TicketVersion 6 | 1 7 | AllNotifications 8 | 9 | Connection Failure 10 | Build Failure 11 | Build Success 12 | Build Issues 13 | 14 | DefaultNotifications 15 | 16 | Connection Failure 17 | Build Failure 18 | Build Success 19 | Build Issues 20 | 21 | 22 | -------------------------------------------------------------------------------- /jenx/Jenx.rb: -------------------------------------------------------------------------------- 1 | # 2 | # Jenx.rb 3 | # jenx 4 | # 5 | # Created by Trent Kocurek on 5/18/11. 6 | # Copyright 2011 Urban Coding. Released under the MIT license. 7 | # 8 | 9 | class Jenx 10 | attr_accessor :menu 11 | attr_accessor :menu_jenx_status 12 | attr_accessor :menu_default_project 13 | attr_accessor :menu_default_project_status 14 | attr_accessor :menu_default_project_update_time 15 | 16 | def awakeFromNib 17 | JenxPreferences::setup_defaults 18 | initialize_menu_ui_items 19 | register_observers 20 | 21 | @old_default_build_status = '' 22 | @new_default_build_status = '' 23 | @old_sub_build_statuses = {} 24 | @new_sub_build_statuses = {} 25 | 26 | #Uncomment the following line to clear NSUserDefaults on each run. 27 | #Testing purposes only. 28 | #clear_nsdefaults 29 | end 30 | 31 | def applicationDidFinishLaunching(notification) 32 | @initial_load = true 33 | @editing_preferences = false 34 | 35 | init_jenx 36 | end 37 | 38 | def init_jenx(sender=nil) 39 | @prefs = JenxPreferences.sharedInstance 40 | @project_menu_count = @prefs.num_menu_projects 41 | @growl_center = JenxNotificationCenter.new(@prefs) 42 | 43 | if @prefs.are_invalid? 44 | NSLog("showing preferences because invalid") 45 | show_preferences_window(nil) 46 | else 47 | ensure_connection 48 | end 49 | end 50 | 51 | def ensure_connection(sender=nil) 52 | NSLog("ensuring connection...") 53 | if @refresh_timer.nil? || !@refresh_timer.isValid 54 | create_timer 55 | end 56 | JenxConnection.new(@prefs.build_server_url, @prefs.username, @prefs.password).is_connected? do |is_connected| 57 | is_connected ? fetch_current_build_status : handle_broken_connection(ERROR_SERVER_CANNOT_BE_CONTACTED) 58 | end 59 | end 60 | 61 | def fetch_current_build_status 62 | @old_default_build_status = @new_default_build_status 63 | JenxConnection.new(@prefs.build_server_url, @prefs.username, @prefs.password).all_projects do |all_projects| 64 | @all_projects = all_projects 65 | if @all_projects then 66 | NSLog("fetching current build status for #{@prefs.num_menu_projects} projects...") 67 | 68 | default_project_status_color = '' 69 | @all_projects['jobs'].find {|p| default_project_status_color = p['color'] if p['name'].downcase.eql?(@prefs.default_project.downcase)} 70 | @new_default_build_status = get_current_status_for(default_project_status_color) 71 | 72 | jenx_status_item = @jenx_item.menu.itemAtIndex(0) 73 | jenx_status_item.setTitle(CONNECTED) 74 | 75 | @menu_default_project.setTitle(localize_format("Project: %@", "#{@prefs.default_project}")) 76 | @menu_default_project_status.setTitle(localize_format("Status: %@", "#{@new_default_build_status}")) 77 | date = Time.now.strftime(localize("%I:%M:%S %p", "%I:%M:%S %p")) 78 | @menu_default_project_update_time.setTitle(localize_format("Last Update: %@", date)) 79 | 80 | @jenx_item.setImage(get_current_status_icon_for(default_project_status_color, nil)) 81 | 82 | load_projects 83 | end 84 | end 85 | rescue Exception => e 86 | NSLog("error fetching build status: #{e.message}...") 87 | end 88 | 89 | def load_projects 90 | @old_sub_build_statuses = @new_sub_build_statuses 91 | if @initial_load 92 | NSLog("initial load of project menu items with #{@project_menu_count} projects...") 93 | @all_projects['jobs'].each_with_index do |project, index| 94 | if index < @project_menu_count 95 | @jenx_item.menu.insertItem(project_menu_item(project, index), atIndex:index + JENX_STARTING_PROJECT_MENU_INDEX) 96 | end 97 | end 98 | 99 | growl_initial_status 100 | 101 | @jenx_item.menu.insertItem(view_all_menu_item(@project_menu_count), atIndex:@project_menu_count + JENX_STARTING_PROJECT_MENU_INDEX) 102 | 103 | @initial_load = false 104 | else 105 | NSLog("refreshing project menu items...") 106 | 107 | @all_projects['jobs'].each_with_index do |project, index| 108 | if index < @project_menu_count 109 | project_menu_item = @jenx_item.menu.itemAtIndex(index + JENX_STARTING_PROJECT_MENU_INDEX) 110 | project_menu_item.setImage(get_current_status_icon_for(project['color'], project_menu_item.image.name)) 111 | end 112 | end 113 | end 114 | 115 | growl_update_status 116 | end 117 | 118 | def handle_broken_connection(error_type) 119 | # Comment out invalidate to fix issue GH-8 120 | # @refresh_timer.invalidate 121 | NSLog("#{CONNECTION_ERROR_TITLE}: #{error_type}") 122 | @jenx_item.setImage(@build_failure_icon) 123 | 124 | jenx_status_item = @jenx_item.menu.itemAtIndex(0) 125 | 126 | jenx_status_item.setTitle(CANNOT_CONNECT) 127 | jenx_status_item.setToolTip(CANNOT_CONNECT) 128 | @growl_center.notify(CONNECTION_ERROR_TITLE, CONNECTION_ERROR_MESSAGE, nil, CONNECTION_FAILURE) 129 | 130 | clear_projects_from_menu 131 | end 132 | 133 | def clear_projects_from_menu 134 | NSLog("clearing #{@project_menu_count} items from the menu if they exist...") 135 | 136 | begin 137 | for i in 1..@project_menu_count + 1 138 | @jenx_item.menu.removeItem(@jenx_item.menu.itemWithTag(i)) if @jenx_item.menu.itemWithTag(i) 139 | end 140 | rescue Exception => e 141 | NSLog(e.message) 142 | end 143 | 144 | NSLog("finished clearing") 145 | end 146 | 147 | def create_timer 148 | time = @prefs.refresh_time == 0 ? 5 : @prefs.refresh_time 149 | 150 | NSLog("create timer with refresh time of: #{time.to_s} seconds...") 151 | 152 | @refresh_timer = NSTimer.scheduledTimerWithTimeInterval(time, target:self, selector:"init_jenx:", userInfo:nil, repeats:true) 153 | end 154 | 155 | def update_for_preferences(sender) 156 | NSLog("preferences saved, recreating timer...") 157 | @editing_preferences = false 158 | @initial_load = true 159 | 160 | init_jenx 161 | end 162 | 163 | def open_web_interface_for(sender) 164 | project_url = NSURL.alloc.initWithString(sender.toolTip) 165 | workspace = NSWorkspace.sharedWorkspace 166 | workspace.openURL(project_url) 167 | end 168 | 169 | def show_preferences_window(sender) 170 | @editing_preferences = true 171 | 172 | clear_projects_from_menu 173 | NSApplication.sharedApplication.activateIgnoringOtherApps(true) 174 | PreferencesController.sharedController.showWindow(sender) 175 | end 176 | 177 | def initialize_menu_ui_items 178 | @app_icon = NSImage.imageNamed('app.tiff') 179 | @connecting_icon = NSImage.imageNamed('connecting.tiff') 180 | 181 | @build_success_icon = NSImage.imageNamed('build_success.tiff') 182 | @build_failure_icon = NSImage.imageNamed('build_failure.tiff') 183 | @build_initiated_icon = NSImage.imageNamed('build_initiated.tiff') 184 | 185 | @jenx_success = NSImage.imageNamed('jenx_success.tiff') 186 | @jenx_failure = NSImage.imageNamed('jenx_failure.tiff') 187 | @jenx_issues = NSImage.imageNamed('jenx_issues.tiff') 188 | 189 | @status_bar = NSStatusBar.systemStatusBar 190 | @jenx_item = @status_bar.statusItemWithLength(NSVariableStatusItemLength) 191 | @jenx_item.setHighlightMode(true) 192 | @jenx_item.setMenu(@menu) 193 | @jenx_item.setImage(@connecting_icon) 194 | 195 | jenx_status_item = @jenx_item.menu.itemAtIndex(0) 196 | jenx_status_item.setTitle(CONNECTED) 197 | 198 | @menu_default_project.setTitle(localize("Project: ...")) 199 | @menu_default_project_status.setTitle(localize("Status: ...")) 200 | @menu_default_project_update_time.setTitle(localize("Last Update: ...")) 201 | end 202 | 203 | def register_observers 204 | notification_center = NSNotificationCenter.defaultCenter 205 | 206 | notification_center.addObserver( 207 | self, 208 | selector:"update_for_preferences:", 209 | name:NOTIFICATION_PREFERENCES_UPDATED, 210 | object:nil 211 | ) 212 | end 213 | 214 | def get_job_url_for(project) 215 | "#{@prefs.build_server_url}/job/#{project}" 216 | end 217 | 218 | def get_current_status_icon_for(color, current_image) 219 | case color.to_sym 220 | when :red 221 | @build_failure_icon 222 | when :blue_anime 223 | @build_initiated_icon 224 | else 225 | @app_icon 226 | end 227 | end 228 | 229 | def get_current_status_for(color) 230 | if @prefs.default_project.empty? 231 | "No default project set" 232 | end 233 | 234 | case color.to_sym 235 | when "" 236 | localize("Could not retrieve status") 237 | when :red 238 | localize("Broken") 239 | when :blue_anime 240 | localize("Building") 241 | else 242 | localize("Stable") 243 | end 244 | end 245 | 246 | def growl_initial_status 247 | passing_count = @new_sub_build_statuses.count - @new_sub_build_statuses.delete_if {|k,v| v != "red"}.count 248 | notify_message = "#{passing_count} of #{@project_menu_count} other projects are passing." 249 | case @new_default_build_status 250 | when "Stable" 251 | @growl_center.notify("#{@prefs.default_project} is passing!", notify_message, @jenx_success, BUILD_SUCCESS) 252 | when "Broken" 253 | @growl_center.notify("#{@prefs.default_project} is failing!", notify_message, @jenx_failure, BUILD_FAILURE) 254 | else 255 | @growl_center.notify("#{@prefs.default_project} is busy..", notify_message, @jenx_issues, BUILD_ISSUES) 256 | end 257 | end 258 | 259 | def growl_update_status 260 | if @new_sub_build_statuses.delete_if {|k, v| @old_sub_build_statuses[k] == v}.count > 0 || @old_default_build_status != @new_default_build_status 261 | passing_count = @new_sub_build_statuses.count - @new_sub_build_statuses.delete_if {|k,v| v != "red"}.count 262 | notify_message = "#{passing_count} of #{@project_menu_count} other projects are passing." 263 | case @default_project_current_status 264 | when "Stable" 265 | @growl_center.notify("#{@prefs.default_project} is passing!", notify_message, @jenx_success, BUILD_SUCCESS) 266 | when "Broken" 267 | @growl_center.notify("#{@prefs.default_project} is failing!", notify_message, @jenx_failure, BUILD_FAILURE) 268 | else 269 | @growl_center.notify("#{@prefs.default_project} is busy..", notify_message, @jenx_issues, BUILD_ISSUES) 270 | end 271 | end 272 | end 273 | 274 | def project_menu_item(project, index) 275 | @new_sub_build_statuses[project['name']] = project['color'] 276 | 277 | project_menu_item = NSMenuItem.alloc.init 278 | project_menu_item.setTitle(" #{project['name']}") 279 | project_menu_item.setToolTip(get_job_url_for(project['name'])) 280 | project_menu_item.setEnabled(true) 281 | project_menu_item.setIndentationLevel(1) 282 | project_menu_item.setImage(get_current_status_icon_for(project['color'], nil)) 283 | project_menu_item.setAction("open_web_interface_for:") 284 | project_menu_item.setTag(index + 1) 285 | end 286 | 287 | def view_all_menu_item(project_menu_count) 288 | view_all_menu_item = NSMenuItem.alloc.init 289 | view_all_menu_item.setTitle(localize("View all projects..")) 290 | view_all_menu_item.setToolTip(@prefs.build_server_url) 291 | view_all_menu_item.setIndentationLevel(1) 292 | view_all_menu_item.setAction("open_web_interface_for:") 293 | view_all_menu_item.setTag(project_menu_count + 1) 294 | end 295 | 296 | #testing purposes only 297 | def clear_nsdefaults 298 | NSUserDefaults.standardUserDefaults.removeObjectForKey(PREFERENCES_TOTAL_NUM_PROJECTS) 299 | NSUserDefaults.standardUserDefaults.removeObjectForKey(PREFERENCES_BUILD_SERVER_URL) 300 | NSUserDefaults.standardUserDefaults.removeObjectForKey(PREFERENCES_BUILD_SERVER_USERNAME) 301 | NSUserDefaults.standardUserDefaults.removeObjectForKey(PREFERENCES_BUILD_SERVER_PASSWORD) 302 | NSUserDefaults.standardUserDefaults.removeObjectForKey(PREFERENCES_DEFAULT_PROJECT) 303 | NSUserDefaults.standardUserDefaults.removeObjectForKey(PREFERENCES_REFRESH_TIME_INTERVAL) 304 | NSUserDefaults.standardUserDefaults.removeObjectForKey(PREFERENCES_MAX_PROJECTS_TO_SHOW) 305 | end 306 | end 307 | -------------------------------------------------------------------------------- /jenx/JenxConnection.rb: -------------------------------------------------------------------------------- 1 | # 2 | # JenxConnection.rb 3 | # jenx 4 | # 5 | # Created by Trent Kocurek on 5/23/11. 6 | # Copyright 2011 Urban Coding. Released under the MIT license. 7 | # 8 | 9 | class JenxConnection 10 | def initialize(url, username = nil, password = nil) 11 | @url = url 12 | @username = username 13 | @password = password 14 | self 15 | end 16 | 17 | def auth(req) 18 | req.basic_auth @username, @password unless @username.nil? or @username.empty? 19 | end 20 | 21 | def initSSL(http, scheme) 22 | if scheme == "https" then 23 | http.use_ssl = true 24 | http.verify_mode = OpenSSL::SSL::VERIFY_NONE 25 | end 26 | end 27 | 28 | def all_projects(&block) 29 | uri = URI.parse(@url) 30 | 31 | if !uri.respond_to?(:request_uri) then 32 | NSLog("Failed to load list of projects from @url = \"#{@url}\"") 33 | return {'jobs' => []} 34 | end 35 | 36 | connection_result = JenxConnectionManager.new do 37 | all_projects = nil 38 | http = Net::HTTP.new(uri.host, uri.port) 39 | initSSL(http, uri.scheme) 40 | req = Net::HTTP::Get.new(uri.request_uri + JENX_API_URI) 41 | auth(req) 42 | response = http.request(req) 43 | if response.code_type == Net::HTTPOK then 44 | result = response.body 45 | all_projects = JSON.parse(result) 46 | end 47 | Dispatch::Queue.main.async do 48 | block.call(all_projects) 49 | end 50 | end 51 | ## This blocks: connection_result.value 52 | end 53 | 54 | def is_connected?(&block) 55 | connection_result = JenxConnectionManager.new do 56 | uri = URI.parse(@url) 57 | http = Net::HTTP.new(uri.host, uri.port) 58 | initSSL(http, uri.scheme) 59 | req = Net::HTTP::Head.new(uri.request_uri + JENX_API_URI) 60 | auth(req) 61 | response = http.request(req) 62 | Dispatch::Queue.main.async do 63 | block.call(response.code_type == Net::HTTPOK) 64 | end 65 | end 66 | ## This blocks: connection_result.value 67 | end 68 | end 69 | -------------------------------------------------------------------------------- /jenx/JenxConnectionManager.rb: -------------------------------------------------------------------------------- 1 | # 2 | # JenxConnectionManager.rb 3 | # jenx 4 | # 5 | # Created by Trent Kocurek on 5/23/11. 6 | # Copyright 2011 Urban Coding. Released under the MIT license. 7 | # 8 | 9 | class JenxConnectionManager 10 | def initialize(&block) 11 | @queue ||= Dispatch::Queue.new("com.urbancoding.jenx") 12 | @group = Dispatch::Group.new 13 | 14 | @queue.async(@group) { @value = block.call } 15 | end 16 | 17 | def value 18 | @group.wait(5) 19 | @value 20 | end 21 | end -------------------------------------------------------------------------------- /jenx/JenxConstants.rb: -------------------------------------------------------------------------------- 1 | # 2 | # JenxConstants.rb 3 | # jenx 4 | # 5 | # Created by Trent Kocurek on 5/19/11. 6 | # Copyright 2011 Urban Coding. Released under the MIT license. 7 | # 8 | 9 | #global 10 | JENX_API_URI = "/api/json" 11 | JENX_STARTING_PROJECT_MENU_INDEX = 9 12 | JENX_REFRESH_TIME_INTERVAL = 10.0 #seconds 13 | 14 | #preferences 15 | PREFERENCES_TOTAL_NUM_PROJECTS = "total_num_projects" 16 | PREFERENCES_BUILD_SERVER_URL = "build_server_url" 17 | PREFERENCES_BUILD_SERVER_USERNAME = "build_server_username" 18 | PREFERENCES_BUILD_SERVER_PASSWORD = "build_server_password" 19 | PREFERENCES_DEFAULT_PROJECT = "default_project" 20 | PREFERENCES_MAX_PROJECTS_TO_SHOW = "max_project_to_show" 21 | PREFERENCES_REFRESH_TIME_INTERVAL = "refresh_time_interval" 22 | PREFERENCES_ENABLE_GROWL = "enable_growl" 23 | PREFERENCES_ENABLE_AUTO_LAUNCH = "enable_auto_launch" 24 | 25 | PREFERENCES_SELECTION = "preferences_selection" 26 | PREFERENCES_TOOLBAR_ITEM_GENERAL = "preferences_toolbar_item_general" 27 | 28 | #notifications 29 | NOTIFICATION_PREFERENCES_UPDATED = "preferences_updated" 30 | 31 | #errors 32 | ERROR_NO_INTERNET_CONNECTION = "no_internet_connection" 33 | ERROR_SERVER_CANNOT_BE_CONTACTED = "server cannot be contacted" 34 | CONNECTION_ERROR_TITLE = localize("Connection Error", "Connection Error") 35 | CONNECTION_ERROR_MESSAGE = localize("Cannot connect to build server.", "Cannot connect to build server.") 36 | CANNOT_CONNECT = localize("Jenx Status: Not Connected", "Jenx Status: Not Connected") 37 | CONNECTED = localize("Jenx Status: Connected","Jenx Status: Connected") 38 | 39 | #growl notification types 40 | CONNECTION_FAILURE = localize("Connection Failure", "Connection Failure") 41 | BUILD_FAILURE = localize("Build Failure", "Build Failure") 42 | BUILD_SUCCESS = localize("Build Success", "Build Success") 43 | BUILD_ISSUES = localize("Build has Issues","Build has Issues") -------------------------------------------------------------------------------- /jenx/JenxLocalize.rb: -------------------------------------------------------------------------------- 1 | # 2 | # JenxUtils.rb 3 | # jenx 4 | # 5 | # Created by Johan BLEUZEN on 16/09/11. 6 | # Copyright 2011 Urban Coding. All rights reserved. 7 | # 8 | 9 | def localize(key, default_value = "") 10 | NSBundle.mainBundle.localizedStringForKey(key, value: default_value, table: nil) 11 | end 12 | 13 | #varargs don't work yet 14 | def localize_format(key, placeholder_value) 15 | format_str = localize(key, nil) 16 | puts format_str 17 | NSString.stringWithFormat(format_str, placeholder_value) 18 | end 19 | -------------------------------------------------------------------------------- /jenx/JenxNotificationCenter.rb: -------------------------------------------------------------------------------- 1 | # 2 | # JenxNotificationCenter.rb 3 | # jenx 4 | # 5 | # Created by Trent Kocurek on 7/11/11. 6 | # Copyright 2011 Urban Coding. Released under the MIT license. 7 | # 8 | 9 | class JenxNotificationCenter 10 | def initialize(preferences) 11 | GrowlApplicationBridge.setGrowlDelegate(self) 12 | @preferences = preferences 13 | end 14 | 15 | def applicationNameForGrowl 16 | "Jenx" 17 | end 18 | 19 | def growlNotificationWasClicked(clickContext) 20 | end 21 | 22 | def growlNotificationTimedOut(clickContext) 23 | end 24 | 25 | def notify(title, message, image, notification_name) 26 | image_data = image.nil? ? "" : image.TIFFRepresentation 27 | if @preferences.enable_growl? 28 | NSLog("Sending growl notification - Title: " + title + ", Message: " + message + ", Notification Name: " + notification_name) 29 | 30 | GrowlApplicationBridge 31 | .notifyWithTitle( 32 | title, 33 | description: message, 34 | notificationName: notification_name, 35 | iconData: image_data, 36 | priority: 0, 37 | isSticky: false, 38 | clickContext: title 39 | ) 40 | end 41 | end 42 | end -------------------------------------------------------------------------------- /jenx/JenxPreferences.rb: -------------------------------------------------------------------------------- 1 | # 2 | # JenxPreferences.rb 3 | # jenx 4 | # 5 | # Created by Trent Kocurek on 5/20/11. 6 | # Copyright 2011 Urban Coding. Released under the MIT license. 7 | # 8 | 9 | class JenxPreferences 10 | attr_accessor :projects 11 | 12 | def self.sharedInstance 13 | self.alloc.init 14 | end 15 | 16 | def init 17 | super 18 | self 19 | end 20 | 21 | def total_num_projects 22 | NSUserDefaults.standardUserDefaults.integerForKey(PREFERENCES_TOTAL_NUM_PROJECTS) 23 | end 24 | 25 | def total_num_projects=(val) 26 | NSUserDefaults.standardUserDefaults.setInteger(val, forKey:PREFERENCES_TOTAL_NUM_PROJECTS) 27 | NSUserDefaults.standardUserDefaults.synchronize 28 | end 29 | 30 | def build_server_url 31 | NSUserDefaults.standardUserDefaults.stringForKey(PREFERENCES_BUILD_SERVER_URL) 32 | end 33 | 34 | def build_server_url=(val) 35 | NSUserDefaults.standardUserDefaults.setObject(val, forKey:PREFERENCES_BUILD_SERVER_URL) 36 | NSUserDefaults.standardUserDefaults.synchronize 37 | end 38 | 39 | def default_project 40 | NSUserDefaults.standardUserDefaults.stringForKey(PREFERENCES_DEFAULT_PROJECT) 41 | end 42 | 43 | def default_project=(val) 44 | NSUserDefaults.standardUserDefaults.setObject(val, forKey:PREFERENCES_DEFAULT_PROJECT) 45 | NSUserDefaults.standardUserDefaults.synchronize 46 | end 47 | 48 | def refresh_time 49 | NSUserDefaults.standardUserDefaults.integerForKey(PREFERENCES_REFRESH_TIME_INTERVAL) 50 | end 51 | 52 | def refresh_time=(val) 53 | NSUserDefaults.standardUserDefaults.setInteger(val, forKey:PREFERENCES_REFRESH_TIME_INTERVAL) 54 | NSUserDefaults.standardUserDefaults.synchronize 55 | end 56 | 57 | def num_menu_projects 58 | NSUserDefaults.standardUserDefaults.integerForKey(PREFERENCES_MAX_PROJECTS_TO_SHOW) 59 | end 60 | 61 | def num_menu_projects=(val) 62 | NSUserDefaults.standardUserDefaults.setInteger(val, forKey:PREFERENCES_MAX_PROJECTS_TO_SHOW) 63 | NSUserDefaults.standardUserDefaults.synchronize 64 | end 65 | 66 | def enable_growl? 67 | NSUserDefaults.standardUserDefaults.boolForKey(PREFERENCES_ENABLE_GROWL) 68 | end 69 | 70 | def enable_growl=(val) 71 | NSUserDefaults.standardUserDefaults.setObject(val, forKey:PREFERENCES_ENABLE_GROWL) 72 | NSUserDefaults.standardUserDefaults.synchronize 73 | end 74 | 75 | def launch_at_login? 76 | JenxStartup.alloc.init.is_set? 77 | end 78 | 79 | def launch_at_login=(val) 80 | JenxStartup.alloc.init.set(val) 81 | end 82 | 83 | def username 84 | NSUserDefaults.standardUserDefaults.stringForKey(PREFERENCES_BUILD_SERVER_USERNAME) 85 | end 86 | 87 | def username=(val) 88 | NSUserDefaults.standardUserDefaults.setObject(val, forKey:PREFERENCES_BUILD_SERVER_USERNAME) 89 | NSUserDefaults.standardUserDefaults.synchronize 90 | end 91 | 92 | def password 93 | NSUserDefaults.standardUserDefaults.stringForKey(PREFERENCES_BUILD_SERVER_PASSWORD) 94 | end 95 | 96 | def password=(val) 97 | NSUserDefaults.standardUserDefaults.setObject(val, forKey:PREFERENCES_BUILD_SERVER_PASSWORD) 98 | NSUserDefaults.standardUserDefaults.synchronize 99 | end 100 | 101 | def are_invalid? 102 | build_server_url.nil? || default_project.nil? || refresh_time.nil? || num_menu_projects.nil? 103 | end 104 | 105 | class << self 106 | def setup_defaults 107 | NSUserDefaults.standardUserDefaults.registerDefaults( 108 | NSDictionary.dictionaryWithObjectsAndKeys( 109 | PREFERENCES_TOOLBAR_ITEM_GENERAL, PREFERENCES_SELECTION, 110 | nil)) 111 | end 112 | end 113 | end -------------------------------------------------------------------------------- /jenx/JenxStartup.rb: -------------------------------------------------------------------------------- 1 | # 2 | # JenxStartup.rb 3 | # jenx 4 | # 5 | # Created by Trent Kocurek on 7/13/11. 6 | # Copyright 2011 Urban Coding. Released under the MIT license. 7 | # 8 | 9 | class JenxStartup 10 | def is_set? 11 | copy_value = CFPreferencesCopyValue("AutoLaunchedApplicationDictionary", "loginwindow", KCFPreferencesCurrentUser, KCFPreferencesAnyHost) 12 | 13 | return false unless copy_value 14 | 15 | copy_value.any? { |application| path == application["Path"] } 16 | end 17 | 18 | def set(auto_launch) 19 | if auto_launch != is_set? 20 | copy_value = CFPreferencesCopyValue("AutoLaunchedApplicationDictionary", "loginwindow", KCFPreferencesCurrentUser, KCFPreferencesAnyHost) 21 | 22 | if copy_value 23 | copy_value = copy_value.mutableCopy 24 | else 25 | copy_value = NSMutableArray.alloc.init 26 | end 27 | 28 | if auto_launch 29 | copy_value.addObject(NSDictionary.dictionaryWithObject(path, forKey:"Path")) 30 | else 31 | to_remove = nil 32 | 33 | copy_value.each do |application| 34 | to_remove = application and break if application.valueForKey("Path") == path 35 | end 36 | 37 | copy_value.removeObject(to_remove) if to_remove 38 | end 39 | 40 | CFPreferencesSetValue("AutoLaunchedApplicationDictionary", copy_value, "loginwindow", KCFPreferencesCurrentUser, KCFPreferencesAnyHost) 41 | 42 | CFPreferencesSynchronize("loginwindow", KCFPreferencesCurrentUser, KCFPreferencesAnyHost) 43 | end 44 | end 45 | 46 | def path 47 | @path ||= NSBundle.mainBundle.bundlePath 48 | end 49 | end -------------------------------------------------------------------------------- /jenx/PreferencesController.rb: -------------------------------------------------------------------------------- 1 | # 2 | # PreferencesController.rb 3 | # jenx 4 | # 5 | # Created by Trent Kocurek on 5/19/11. 6 | # Copyright 2011 Urban Coding. Released under the MIT license. 7 | # 8 | 9 | class PreferencesController < NSWindowController 10 | attr_accessor :general_pane 11 | 12 | def self.sharedController 13 | unless @shared_instance 14 | @shared_instance = self.alloc.init 15 | general = PreferencesGeneralViewController.alloc.initWithNibName("PreferencesGeneralView", bundle:nil) 16 | @shared_instance.modules = [general] 17 | end 18 | @shared_instance 19 | end 20 | 21 | def init 22 | if super 23 | preferences_window = NSWindow.alloc.initWithContentRect( 24 | NSMakeRect(0, 0, 550, 260), 25 | styleMask:NSTitledWindowMask | NSClosableWindowMask, 26 | backing:NSBackingStoreBuffered, 27 | defer:true 28 | ) 29 | preferences_window.setShowsToolbarButton(false) 30 | self.window = preferences_window 31 | 32 | setup_toolbar 33 | end 34 | 35 | self 36 | end 37 | 38 | def toolbar(toolbar, itemForItemIdentifier:itemIdentifier, willBeInsertedIntoToolbar:flag) 39 | mod = module_for_identifier(itemIdentifier) 40 | item = NSToolbarItem.alloc.initWithItemIdentifier(itemIdentifier) 41 | 42 | if mod 43 | item.label = mod.title 44 | item.image = mod.image 45 | item.target = self; 46 | item.action = "select_module:" 47 | end 48 | 49 | item 50 | end 51 | 52 | def toolbarAllowedItemIdentifiers(toolbar) 53 | @modules.map { |mod| mod.identifier } 54 | end 55 | 56 | def toolbarDefaultItemIdentifiers(toolbar) 57 | nil 58 | end 59 | 60 | def toolbarSelectableItemIdentifiers(toolbar) 61 | toolbarAllowedItemIdentifiers(toolbar) 62 | end 63 | 64 | def showWindow(sender) 65 | self.window.center 66 | super 67 | end 68 | 69 | def select_module(sender) 70 | mod = module_for_identifier(sender.itemIdentifier) 71 | switch_to_module(mod) if mod 72 | end 73 | 74 | def modules=(new_modules) 75 | @modules = new_modules 76 | toolbar = self.window.toolbar 77 | return unless toolbar && toolbar.items.count == 0 78 | 79 | @modules.each do |mod| 80 | toolbar.insertItemWithItemIdentifier(mod.identifier, atIndex:toolbar.items.count) 81 | end 82 | 83 | saved_identifier = NSUserDefaults.standardUserDefaults.stringForKey(PREFERENCES_SELECTION) 84 | default_module = module_for_identifier(saved_identifier) || @modules.first 85 | switch_to_module(default_module) 86 | end 87 | 88 | private 89 | def setup_toolbar 90 | toolbar = NSToolbar.alloc.initWithIdentifier("preferences_toolbar") 91 | toolbar.delegate = self 92 | toolbar.setAllowsUserCustomization(false) 93 | self.window.setToolbar(toolbar) 94 | end 95 | 96 | def switch_to_module(mod) 97 | @current_module.view.removeFromSuperview if @current_module 98 | 99 | new_view = mod.view 100 | 101 | window_frame = self.window.frameRectForContentRect(new_view.frame) 102 | window_frame.origin = self.window.frame.origin; 103 | window_frame.origin.y -= window_frame.size.height - self.window.frame.size.height 104 | self.window.setFrame(window_frame, display:true, animate:true) 105 | 106 | self.window.toolbar.setSelectedItemIdentifier(mod.identifier) 107 | self.window.title = mod.title 108 | 109 | @current_module = mod 110 | self.window.contentView.addSubview(@current_module.view) 111 | self.window.setInitialFirstResponder(@current_module.view) 112 | 113 | NSUserDefaults.standardUserDefaults.setObject(mod.identifier, forKey:PREFERENCES_SELECTION) 114 | end 115 | 116 | def module_for_identifier(identifier) 117 | @modules.find { |mod| mod.identifier == identifier } 118 | end 119 | end -------------------------------------------------------------------------------- /jenx/PreferencesGeneralViewController.rb: -------------------------------------------------------------------------------- 1 | # 2 | # PreferencesViewController.rb 3 | # jenx 4 | # 5 | # Created by Trent Kocurek on 5/19/11. 6 | # Copyright 2011 Urban Coding. Released under the MIT license. 7 | # 8 | 9 | class PreferencesGeneralViewController < NSViewController 10 | attr_accessor :server_url 11 | attr_accessor :username 12 | attr_accessor :password 13 | attr_accessor :project_list 14 | attr_accessor :connection_spinner 15 | attr_accessor :connection_label 16 | attr_accessor :default_project 17 | attr_accessor :refresh_time 18 | attr_accessor :num_menu_projects 19 | attr_accessor :enable_growl 20 | attr_accessor :launch_at_login 21 | 22 | def title 23 | localize("Settings", "Settings") 24 | end 25 | 26 | def image 27 | NSImage.imageNamed("NSPreferencesGeneral") 28 | end 29 | 30 | def identifier 31 | PREFERENCES_TOOLBAR_ITEM_GENERAL 32 | end 33 | 34 | def loadView 35 | super 36 | begin 37 | @prefs = JenxPreferences.sharedInstance 38 | 39 | @server_url.stringValue = (@prefs.build_server_url.nil? || @prefs.build_server_url.eql?('')) ? '' : @prefs.build_server_url 40 | @refresh_time.intValue = (@prefs.refresh_time.nil? || @prefs.refresh_time.eql?('')) ? 0 : @prefs.refresh_time 41 | @num_menu_projects.intValue = (@prefs.num_menu_projects.nil? || @prefs.num_menu_projects.eql?('')) ? 0 : @prefs.num_menu_projects 42 | @enable_growl.state = @prefs.enable_growl? ? NSOnState : NSOffState 43 | @launch_at_login.state = @prefs.launch_at_login? ? NSOnState : NSOffState 44 | @username.stringValue = (@prefs.username.nil?) ? '' : @prefs.username 45 | @password.stringValue = (@prefs.password.nil?) ? '' : @prefs.password 46 | load_projects 47 | rescue Exception => e 48 | NSLog(e.message) 49 | end 50 | end 51 | 52 | def load_projects(sender=nil) 53 | @project_list.removeAllItems 54 | begin 55 | url = @server_url.stringValue[-1,1].eql?('/') ? @server_url.stringValue : @server_url.stringValue + '/' 56 | JenxConnection.new(url, @username.stringValue, @password.stringValue).all_projects do |all_projects| 57 | @all_projects = all_projects 58 | @all_projects['jobs'].each do |project| 59 | @project_list.addItemWithObjectValue(project['name']) 60 | end 61 | 62 | if !@prefs.default_project 63 | @project_list.selectItemWithObjectValue(0) 64 | else 65 | @project_list.selectItemWithObjectValue(@prefs.default_project) 66 | end 67 | end 68 | rescue URI::InvalidURIError => uri_error 69 | NSLog(uri_error.inspect) 70 | rescue Exception => error 71 | NSLog(error.inspect) 72 | end 73 | end 74 | 75 | def save_preferences(sender) 76 | @prefs.total_num_projects = @all_projects.count 77 | @prefs.build_server_url = @server_url.stringValue[-1,1].eql?('/') ? @server_url.stringValue : @server_url.stringValue + '/' 78 | @prefs.username = @username.stringValue 79 | @prefs.password = @password.stringValue 80 | @prefs.default_project = @project_list.objectValueOfSelectedItem 81 | @prefs.refresh_time = @refresh_time.intValue 82 | @prefs.num_menu_projects = (@num_menu_projects.intValue > @project_list.numberOfItems) ? @project_list.numberOfItems : @num_menu_projects.intValue 83 | @prefs.enable_growl = (@enable_growl.state == NSOnState) 84 | @prefs.launch_at_login = (@launch_at_login.state == NSOnState) 85 | 86 | NSNotificationCenter.defaultCenter.postNotificationName(NOTIFICATION_PREFERENCES_UPDATED, object:self) 87 | 88 | self.view.window.close 89 | end 90 | end -------------------------------------------------------------------------------- /jenx/en.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Localized versions of Info.plist keys */ 2 | 3 | -------------------------------------------------------------------------------- /jenx/en.lproj/Localizable.strings: -------------------------------------------------------------------------------- 1 | /* 2 | Localizable.strings 3 | jenx 4 | 5 | Created by Johan BLEUZEN on 16/09/11. 6 | Copyright 2011 Urban Coding. All rights reserved. 7 | */ 8 | 9 | "Settings" = "Settings"; 10 | 11 | "Connection Error" = "Connection Error"; 12 | "Cannot connect to build server." = "Cannot connect to build server."; 13 | "Jenx Status: Not Connected" = "Jenx Status: Not Connected"; 14 | "Jenx Status: Connected" = "Jenx Status: Connected"; 15 | 16 | "Connection Failure" = "Connection Failure"; 17 | "Build has Issues" = "Build has Issues"; 18 | "Build Failure" = "Build Failure"; 19 | "Build Success" = "Build Success"; 20 | 21 | "Project: ..." = "Project: ..."; 22 | "Status: ..." = "Status: ..."; 23 | "Last Update: ..." = "Last Update: ..."; 24 | 25 | "Project: %@" = "Project: %@"; 26 | "Status: %@" = "Status: %@"; 27 | "%I:%M:%S %p" = "%I:%M:%S %p"; /* This is for date formating */ 28 | "Last Update: %@" = "Last Update: %@"; 29 | 30 | "View all projects.." = "View all projects.."; 31 | 32 | "Could not retrieve status" = "Could not retrieve status"; 33 | "Broken" = "Broken"; 34 | "Stable" = "Stable"; 35 | "Building" = "Building"; -------------------------------------------------------------------------------- /jenx/en.lproj/PreferencesGeneralView.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 1060 5 | 10K540 6 | 851 7 | 1038.36 8 | 461.00 9 | 10 | com.apple.InterfaceBuilder.CocoaPlugin 11 | 851 12 | 13 | 14 | YES 15 | 16 | 17 | 18 | YES 19 | com.apple.InterfaceBuilder.CocoaPlugin 20 | 21 | 22 | YES 23 | 24 | YES 25 | 26 | 27 | YES 28 | 29 | 30 | 31 | YES 32 | 33 | PreferencesGeneralViewController 34 | 35 | 36 | FirstResponder 37 | 38 | 39 | NSApplication 40 | 41 | 42 | 43 | 268 44 | 45 | YES 46 | 47 | 48 | 268 49 | {{133, 252}, {183, 22}} 50 | 51 | 2 52 | YES 53 | 54 | -1804468671 55 | 272630784 56 | 57 | 58 | LucidaGrande 59 | 13 60 | 1044 61 | 62 | 63 | YES 64 | 65 | 6 66 | System 67 | textBackgroundColor 68 | 69 | 3 70 | MQA 71 | 72 | 73 | 74 | 6 75 | System 76 | textColor 77 | 78 | 3 79 | MAA 80 | 81 | 82 | 83 | 84 | 85 | 86 | 268 87 | {{133, 220}, {183, 22}} 88 | 89 | 2 90 | YES 91 | 92 | 343014976 93 | 272630784 94 | 95 | 96 | 97 | YES 98 | 99 | 100 | 101 | YES 102 | NSAllRomanInputSourcesLocaleIdentifier 103 | 104 | 105 | 106 | 107 | 108 | 268 109 | {{263, 149}, {56, 17}} 110 | 111 | 112 | 2 113 | YES 114 | 115 | 68288064 116 | 272630784 117 | seconds 118 | 119 | 120 | 121 | 6 122 | System 123 | controlColor 124 | 125 | 3 126 | MC42NjY2NjY2NjY3AA 127 | 128 | 129 | 130 | 6 131 | System 132 | controlTextColor 133 | 134 | 135 | 136 | 137 | 138 | 139 | 268 140 | {{218, 146}, {40, 22}} 141 | 142 | 143 | 2 144 | YES 145 | 146 | -1804468671 147 | 138413056 148 | 0 149 | 150 | 151 | YES 152 | 1 153 | 154 | 155 | 156 | 157 | 158 | 159 | 268 160 | {{20, 282}, {409, 13}} 161 | 162 | 163 | 2 164 | YES 165 | 166 | 67239424 167 | 138412032 168 | Enter the root url or your Jenkins build server. Include protocol and port. 169 | 170 | LucidaGrande 171 | 10 172 | 16 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 268 182 | {{174, 56}, {111, 18}} 183 | 184 | 185 | 2 186 | YES 187 | 188 | -2080244224 189 | 0 190 | Open at Login 191 | 192 | 193 | 1211912703 194 | 2 195 | 196 | NSImage 197 | NSSwitch 198 | 199 | 200 | NSSwitch 201 | 202 | 203 | 204 | 200 205 | 25 206 | 207 | 208 | 209 | 210 | 268 211 | {{324, 18}, {99, 25}} 212 | 213 | 2 214 | YES 215 | 216 | -2080244224 217 | 134217728 218 | Save 219 | 220 | 221 | -2038152961 222 | 163 223 | 224 | 225 | 400 226 | 75 227 | 228 | 229 | 230 | 231 | 268 232 | {{135, 85}, {188, 18}} 233 | 234 | 235 | 2 236 | YES 237 | 238 | -2080244224 239 | 0 240 | Enable Growl Notifications 241 | 242 | 243 | 1211912703 244 | 2 245 | 246 | 247 | 248 | 249 | 200 250 | 25 251 | 252 | 253 | 254 | 255 | 268 256 | {{29, 122}, {321, 17}} 257 | 258 | 259 | 2 260 | YES 261 | 262 | 68288064 263 | 272630784 264 | Maximum number of projects shown in the menu: 265 | 266 | 267 | 268 | 269 | 270 | 271 | 272 | 273 | 268 274 | {{355, 119}, {57, 22}} 275 | 276 | 277 | 2 278 | YES 279 | 280 | -1804468671 281 | 138413056 282 | 283 | 284 | 285 | YES 286 | 287 | YES 288 | allowsFloats 289 | formatterBehavior 290 | locale 291 | negativeInfinitySymbol 292 | nilSymbol 293 | numberStyle 294 | positiveInfinitySymbol 295 | 296 | 297 | YES 298 | 299 | 300 | 301 | 302 | 303 | -∞ 304 | 305 | 306 | +∞ 307 | 308 | 309 | #,##0.### 310 | #,##0.### 311 | 312 | 313 | 314 | 315 | 316 | 317 | 318 | NaN 319 | 320 | YES 321 | 322 | 323 | YES 324 | 325 | 326 | 327 | 328 | 0 329 | 0 330 | YES 331 | NO 332 | 1 333 | AAAAAAAAAAAAAAAAAAAAAA 334 | 335 | 336 | 337 | 3 338 | YES 339 | YES 340 | YES 341 | 342 | . 343 | , 344 | YES 345 | NO 346 | YES 347 | 348 | 5 349 | 350 | YES 351 | 1 352 | 353 | 354 | 355 | 356 | 357 | 358 | 268 359 | {{125, 149}, {88, 17}} 360 | 361 | 362 | 2 363 | YES 364 | 365 | 68288064 366 | 272630784 367 | Refresh Rate: 368 | 369 | 370 | 371 | 372 | 373 | 374 | 375 | 376 | 12 377 | {{12, 173}, {419, 5}} 378 | 379 | 380 | 2 381 | {0, 0} 382 | 383 | 67239424 384 | 0 385 | Box 386 | 387 | 388 | 389 | 3 390 | MCAwLjgwMDAwMDAxMTkAA 391 | 392 | 393 | 3 394 | 2 395 | 0 396 | NO 397 | 398 | 399 | 400 | 268 401 | {{133, 188}, {293, 26}} 402 | 403 | 404 | 2 405 | YES 406 | 407 | 74579521 408 | 272634880 409 | 410 | 411 | 412 | YES 413 | 414 | 415 | 5 416 | YES 417 | 418 | 419 | 420 | 274 421 | {15, 0} 422 | 423 | 424 | YES 425 | 426 | YES 427 | 428 | 12 429 | 10 430 | 1000 431 | 432 | 75628032 433 | 0 434 | 435 | 436 | LucidaGrande 437 | 12 438 | 16 439 | 440 | 441 | 3 442 | MC4zMzMzMzI5ODU2AA 443 | 444 | 445 | 446 | 447 | 338820672 448 | 268436480 449 | 450 | 451 | YES 452 | 453 | 6 454 | System 455 | controlBackgroundColor 456 | 457 | 458 | 459 | 460 | 3 461 | YES 462 | 463 | 464 | 465 | 3 466 | 2 467 | 468 | 469 | 6 470 | System 471 | gridColor 472 | 473 | 3 474 | MC41AA 475 | 476 | 477 | 19 478 | tableViewAction: 479 | -767524864 480 | 481 | 482 | 483 | 1 484 | 15 485 | 0 486 | YES 487 | 0 488 | 489 | 490 | 491 | 492 | 493 | 268 494 | {{26, 194}, {102, 17}} 495 | 496 | 497 | 2 498 | YES 499 | 500 | 68288064 501 | 272630784 502 | Default Project: 503 | 504 | 505 | 506 | 507 | 508 | 509 | 510 | 511 | 268 512 | {{324, 300}, {99, 25}} 513 | 514 | 515 | 2 516 | YES 517 | 518 | -2080244224 519 | 134217728 520 | Load Projects 521 | 522 | 523 | -2038152961 524 | 163 525 | 526 | 527 | 400 528 | 75 529 | 530 | 531 | 532 | 533 | 268 534 | {{17, 225}, {111, 17}} 535 | 536 | 2 537 | YES 538 | 539 | 68288064 540 | 71304192 541 | Password: 542 | 543 | 544 | 545 | 546 | 547 | 548 | 549 | 550 | 268 551 | {{17, 257}, {111, 17}} 552 | 553 | 2 554 | YES 555 | 556 | 68288064 557 | 71304192 558 | Username: 559 | 560 | 561 | 562 | 563 | 564 | 565 | 566 | 567 | 268 568 | {{133, 302}, {183, 22}} 569 | 570 | 571 | 2 572 | YES 573 | 574 | -1804468671 575 | 272630784 576 | 577 | 578 | 579 | YES 580 | 581 | 582 | 583 | 584 | 585 | 586 | 268 587 | {{17, 308}, {111, 17}} 588 | 589 | 590 | 2 591 | YES 592 | 593 | 68288064 594 | 71304192 595 | Build Server URL: 596 | 597 | 598 | 599 | 600 | 601 | 602 | 603 | {443, 345} 604 | 605 | 606 | 2 607 | NSView 608 | 609 | 610 | YES 611 | 612 | 613 | 614 | 615 | YES 616 | 617 | 618 | project_list 619 | 620 | 621 | 622 | 22 623 | 624 | 625 | 626 | view 627 | 628 | 629 | 630 | 25 631 | 632 | 633 | 634 | default_project 635 | 636 | 637 | 638 | 43 639 | 640 | 641 | 642 | num_menu_projects 643 | 644 | 645 | 646 | 44 647 | 648 | 649 | 650 | server_url 651 | 652 | 653 | 654 | 45 655 | 656 | 657 | 658 | load_projects: 659 | 660 | 661 | 662 | 52 663 | 664 | 665 | 666 | save_preferences: 667 | 668 | 669 | 670 | 62 671 | 672 | 673 | 674 | launch_at_login 675 | 676 | 677 | 678 | 65 679 | 680 | 681 | 682 | refresh_time 683 | 684 | 685 | 686 | 89 687 | 688 | 689 | 690 | username 691 | 692 | 693 | 694 | 114 695 | 696 | 697 | 698 | password 699 | 700 | 701 | 702 | 115 703 | 704 | 705 | 706 | enable_growl 707 | 708 | 709 | 710 | 118 711 | 712 | 713 | 714 | nextKeyView 715 | 716 | 717 | 718 | 119 719 | 720 | 721 | 722 | nextKeyView 723 | 724 | 725 | 726 | 120 727 | 728 | 729 | 730 | nextKeyView 731 | 732 | 733 | 734 | 121 735 | 736 | 737 | 738 | nextKeyView 739 | 740 | 741 | 742 | 124 743 | 744 | 745 | 746 | nextKeyView 747 | 748 | 749 | 750 | 125 751 | 752 | 753 | 754 | nextKeyView 755 | 756 | 757 | 758 | 126 759 | 760 | 761 | 762 | nextKeyView 763 | 764 | 765 | 766 | 127 767 | 768 | 769 | 770 | nextKeyView 771 | 772 | 773 | 774 | 130 775 | 776 | 777 | 778 | nextKeyView 779 | 780 | 781 | 782 | 131 783 | 784 | 785 | 786 | 787 | YES 788 | 789 | 0 790 | 791 | 792 | 793 | 794 | 795 | -2 796 | 797 | 798 | File's Owner 799 | 800 | 801 | -1 802 | 803 | 804 | First Responder 805 | 806 | 807 | -3 808 | 809 | 810 | Application 811 | 812 | 813 | 3 814 | 815 | 816 | YES 817 | 818 | 819 | 820 | 821 | 822 | 823 | 824 | 825 | 826 | 827 | 828 | 829 | 830 | 831 | 832 | 833 | 834 | 835 | 836 | 837 | 838 | Jenx General Settings 839 | 840 | 841 | 4 842 | 843 | 844 | YES 845 | 846 | 847 | 848 | 849 | 850 | 5 851 | 852 | 853 | 854 | 855 | 6 856 | 857 | 858 | YES 859 | 860 | 861 | 862 | Build Server URL 863 | 864 | 865 | 7 866 | 867 | 868 | 869 | 870 | 8 871 | 872 | 873 | YES 874 | 875 | 876 | 877 | 878 | 879 | 9 880 | 881 | 882 | 883 | 884 | 10 885 | 886 | 887 | YES 888 | 889 | 890 | 891 | 892 | 893 | 11 894 | 895 | 896 | 897 | 898 | 12 899 | 900 | 901 | YES 902 | 903 | 904 | 905 | 906 | 907 | 13 908 | 909 | 910 | 911 | 912 | 18 913 | 914 | 915 | 916 | 917 | 26 918 | 919 | 920 | YES 921 | 922 | 923 | 924 | 925 | 926 | 27 927 | 928 | 929 | 930 | 931 | 35 932 | 933 | 934 | YES 935 | 936 | 937 | 938 | 939 | 940 | 36 941 | 942 | 943 | YES 944 | 945 | 946 | 947 | 948 | 949 | 37 950 | 951 | 952 | 953 | 954 | 38 955 | 956 | 957 | YES 958 | 959 | 960 | 961 | 962 | 963 | 39 964 | 965 | 966 | 967 | 968 | 57 969 | 970 | 971 | YES 972 | 973 | 974 | 975 | 976 | 977 | 58 978 | 979 | 980 | 981 | 982 | 60 983 | 984 | 985 | YES 986 | 987 | 988 | 989 | 990 | 991 | 61 992 | 993 | 994 | 995 | 996 | 63 997 | 998 | 999 | YES 1000 | 1001 | 1002 | 1003 | Open At Login 1004 | 1005 | 1006 | 64 1007 | 1008 | 1009 | 1010 | 1011 | 76 1012 | 1013 | 1014 | YES 1015 | 1016 | 1017 | 1018 | Information Label 1019 | 1020 | 1021 | 77 1022 | 1023 | 1024 | 1025 | 1026 | 85 1027 | 1028 | 1029 | YES 1030 | 1031 | 1032 | 1033 | 1034 | 1035 | 86 1036 | 1037 | 1038 | 1039 | 1040 | 87 1041 | 1042 | 1043 | YES 1044 | 1045 | 1046 | 1047 | 1048 | 1049 | 88 1050 | 1051 | 1052 | 1053 | 1054 | 92 1055 | 1056 | 1057 | YES 1058 | 1059 | 1060 | 1061 | 1062 | 1063 | 95 1064 | 1065 | 1066 | 1067 | 1068 | 96 1069 | 1070 | 1071 | YES 1072 | 1073 | 1074 | 1075 | 1076 | 1077 | 99 1078 | 1079 | 1080 | 1081 | 1082 | 100 1083 | 1084 | 1085 | 1086 | 1087 | 103 1088 | 1089 | 1090 | YES 1091 | 1092 | 1093 | 1094 | Build server password 1095 | 1096 | 1097 | 104 1098 | 1099 | 1100 | 1101 | 1102 | 105 1103 | 1104 | 1105 | YES 1106 | 1107 | 1108 | 1109 | Build server username 1110 | 1111 | 1112 | 106 1113 | 1114 | 1115 | 1116 | 1117 | 1118 | 1119 | YES 1120 | 1121 | YES 1122 | -1.IBPluginDependency 1123 | -2.IBPluginDependency 1124 | -3.IBPluginDependency 1125 | 10.IBPluginDependency 1126 | 10.IBViewBoundsToFrameTransform 1127 | 103.IBAttributePlaceholdersKey 1128 | 103.IBPluginDependency 1129 | 103.IBViewBoundsToFrameTransform 1130 | 104.IBPluginDependency 1131 | 105.IBAttributePlaceholdersKey 1132 | 105.IBPluginDependency 1133 | 105.IBViewBoundsToFrameTransform 1134 | 106.IBPluginDependency 1135 | 11.IBPluginDependency 1136 | 12.IBPluginDependency 1137 | 12.IBViewBoundsToFrameTransform 1138 | 13.IBPluginDependency 1139 | 18.IBPluginDependency 1140 | 18.IBViewBoundsToFrameTransform 1141 | 26.IBPluginDependency 1142 | 26.IBViewBoundsToFrameTransform 1143 | 27.IBPluginDependency 1144 | 3.IBEditorWindowLastContentRect 1145 | 3.IBPluginDependency 1146 | 3.IBViewBoundsToFrameTransform 1147 | 35.IBPluginDependency 1148 | 35.IBViewBoundsToFrameTransform 1149 | 36.IBPluginDependency 1150 | 37.IBNumberFormatterBehaviorMetadataKey 1151 | 37.IBNumberFormatterLocalizesFormatMetadataKey 1152 | 37.IBPluginDependency 1153 | 38.IBPluginDependency 1154 | 38.IBViewBoundsToFrameTransform 1155 | 39.IBPluginDependency 1156 | 4.IBPluginDependency 1157 | 4.IBViewBoundsToFrameTransform 1158 | 5.IBPluginDependency 1159 | 57.IBPluginDependency 1160 | 57.IBViewBoundsToFrameTransform 1161 | 58.IBPluginDependency 1162 | 6.IBPluginDependency 1163 | 6.IBViewBoundsToFrameTransform 1164 | 60.IBPluginDependency 1165 | 60.IBViewBoundsToFrameTransform 1166 | 61.IBPluginDependency 1167 | 63.IBPluginDependency 1168 | 63.IBViewBoundsToFrameTransform 1169 | 64.IBPluginDependency 1170 | 7.IBPluginDependency 1171 | 76.IBPluginDependency 1172 | 76.IBViewBoundsToFrameTransform 1173 | 77.IBPluginDependency 1174 | 8.IBPluginDependency 1175 | 8.IBViewBoundsToFrameTransform 1176 | 85.IBPluginDependency 1177 | 85.IBViewBoundsToFrameTransform 1178 | 86.IBPluginDependency 1179 | 87.IBPluginDependency 1180 | 87.IBViewBoundsToFrameTransform 1181 | 88.IBPluginDependency 1182 | 9.IBPluginDependency 1183 | 92.IBPluginDependency 1184 | 92.IBViewBoundsToFrameTransform 1185 | 95.IBPluginDependency 1186 | 96.IBPluginDependency 1187 | 96.IBViewBoundsToFrameTransform 1188 | 99.IBPluginDependency 1189 | 1190 | 1191 | YES 1192 | com.apple.InterfaceBuilder.CocoaPlugin 1193 | com.apple.InterfaceBuilder.CocoaPlugin 1194 | com.apple.InterfaceBuilder.CocoaPlugin 1195 | com.apple.InterfaceBuilder.CocoaPlugin 1196 | 1197 | P4AAAL+AAABB0AAAw66AAA 1198 | 1199 | 1200 | AccessibilityDescription 1201 | 1202 | AccessibilityDescription 1203 | 1204 | Build server password 1205 | 1206 | 1207 | com.apple.InterfaceBuilder.CocoaPlugin 1208 | 1209 | P4AAAL+AAABDBQAAw3AAAA 1210 | 1211 | com.apple.InterfaceBuilder.CocoaPlugin 1212 | 1213 | AccessibilityDescription 1214 | 1215 | AccessibilityDescription 1216 | 1217 | Build server username 1218 | 1219 | 1220 | com.apple.InterfaceBuilder.CocoaPlugin 1221 | 1222 | P4AAAL+AAABDBQAAw4gAAA 1223 | 1224 | com.apple.InterfaceBuilder.CocoaPlugin 1225 | com.apple.InterfaceBuilder.CocoaPlugin 1226 | com.apple.InterfaceBuilder.CocoaPlugin 1227 | 1228 | P4AAAL+AAABDBQAAw1QAAA 1229 | 1230 | com.apple.InterfaceBuilder.CocoaPlugin 1231 | com.apple.InterfaceBuilder.CocoaPlugin 1232 | 1233 | AUFAAABDkwAAA 1234 | 1235 | com.apple.InterfaceBuilder.CocoaPlugin 1236 | 1237 | P4AAAL+AAABC+gAAw46AAA 1238 | 1239 | com.apple.InterfaceBuilder.CocoaPlugin 1240 | {{1, 488}, {443, 345}} 1241 | com.apple.InterfaceBuilder.CocoaPlugin 1242 | 1243 | com.apple.InterfaceBuilder.CocoaPlugin 1244 | 1245 | P4AAAL+AAABDsYAAwwsAAA 1246 | 1247 | com.apple.InterfaceBuilder.CocoaPlugin 1248 | 1249 | 1250 | com.apple.InterfaceBuilder.CocoaPlugin 1251 | com.apple.InterfaceBuilder.CocoaPlugin 1252 | 1253 | P4AAAL+AAABB6AAAwwkAAA 1254 | 1255 | com.apple.InterfaceBuilder.CocoaPlugin 1256 | com.apple.InterfaceBuilder.CocoaPlugin 1257 | 1258 | P4AAAL+AAABBiAAAw7uAAA 1259 | 1260 | com.apple.InterfaceBuilder.CocoaPlugin 1261 | com.apple.InterfaceBuilder.CocoaPlugin 1262 | 1263 | P4AAAL+AAABDBwAAwsoAAA 1264 | 1265 | com.apple.InterfaceBuilder.CocoaPlugin 1266 | com.apple.InterfaceBuilder.CocoaPlugin 1267 | 1268 | P4AAAL+AAABDBQAAw6EAAA 1269 | 1270 | com.apple.InterfaceBuilder.CocoaPlugin 1271 | 1272 | P4AAAL+AAABDogAAwiQAAA 1273 | 1274 | com.apple.InterfaceBuilder.CocoaPlugin 1275 | com.apple.InterfaceBuilder.CocoaPlugin 1276 | 1277 | P4AAAL+AAABDLgAAw0EAAA 1278 | 1279 | com.apple.InterfaceBuilder.CocoaPlugin 1280 | com.apple.InterfaceBuilder.CocoaPlugin 1281 | com.apple.InterfaceBuilder.CocoaPlugin 1282 | 1283 | P4AAAL+AAABBoAAAw5KAAA 1284 | 1285 | com.apple.InterfaceBuilder.CocoaPlugin 1286 | com.apple.InterfaceBuilder.CocoaPlugin 1287 | 1288 | P4AAAL+AAABDogAAw6GAAA 1289 | 1290 | com.apple.InterfaceBuilder.CocoaPlugin 1291 | 1292 | P4AAAL+AAABDWgAAw4+AAA 1293 | 1294 | com.apple.InterfaceBuilder.CocoaPlugin 1295 | com.apple.InterfaceBuilder.CocoaPlugin 1296 | 1297 | P4AAAL+AAABDg4AAw46AAA 1298 | 1299 | com.apple.InterfaceBuilder.CocoaPlugin 1300 | com.apple.InterfaceBuilder.CocoaPlugin 1301 | com.apple.InterfaceBuilder.CocoaPlugin 1302 | 1303 | P4AAAL+AAABBiAAAw6IAAA 1304 | 1305 | com.apple.InterfaceBuilder.CocoaPlugin 1306 | com.apple.InterfaceBuilder.CocoaPlugin 1307 | 1308 | P4AAAL+AAABBiAAAw5IAAA 1309 | 1310 | com.apple.InterfaceBuilder.CocoaPlugin 1311 | 1312 | 1313 | 1314 | YES 1315 | 1316 | 1317 | YES 1318 | 1319 | 1320 | 1321 | 1322 | YES 1323 | 1324 | 1325 | YES 1326 | 1327 | 1328 | 1329 | 131 1330 | 1331 | 1332 | 1333 | YES 1334 | 1335 | PreferencesGeneralViewController 1336 | NSViewController 1337 | 1338 | save_preferences: 1339 | id 1340 | 1341 | 1342 | save_preferences: 1343 | 1344 | save_preferences: 1345 | id 1346 | 1347 | 1348 | 1349 | YES 1350 | 1351 | YES 1352 | connection_label 1353 | connection_spinner 1354 | default_project 1355 | enable_growl 1356 | launch_at_login 1357 | num_menu_projects 1358 | password 1359 | project_list 1360 | refresh_time 1361 | server_url 1362 | username 1363 | 1364 | 1365 | YES 1366 | id 1367 | id 1368 | id 1369 | id 1370 | id 1371 | id 1372 | id 1373 | id 1374 | id 1375 | id 1376 | id 1377 | 1378 | 1379 | 1380 | YES 1381 | 1382 | YES 1383 | connection_label 1384 | connection_spinner 1385 | default_project 1386 | enable_growl 1387 | launch_at_login 1388 | num_menu_projects 1389 | password 1390 | project_list 1391 | refresh_time 1392 | server_url 1393 | username 1394 | 1395 | 1396 | YES 1397 | 1398 | connection_label 1399 | id 1400 | 1401 | 1402 | connection_spinner 1403 | id 1404 | 1405 | 1406 | default_project 1407 | id 1408 | 1409 | 1410 | enable_growl 1411 | id 1412 | 1413 | 1414 | launch_at_login 1415 | id 1416 | 1417 | 1418 | num_menu_projects 1419 | id 1420 | 1421 | 1422 | password 1423 | id 1424 | 1425 | 1426 | project_list 1427 | id 1428 | 1429 | 1430 | refresh_time 1431 | id 1432 | 1433 | 1434 | server_url 1435 | id 1436 | 1437 | 1438 | username 1439 | id 1440 | 1441 | 1442 | 1443 | 1444 | IBProjectSource 1445 | jenx/PreferencesGeneralViewController.rb 1446 | 1447 | 1448 | 1449 | PreferencesGeneralViewController 1450 | NSViewController 1451 | 1452 | myOutlet1 1453 | id 1454 | 1455 | 1456 | myOutlet1 1457 | 1458 | myOutlet1 1459 | id 1460 | 1461 | 1462 | 1463 | IBUserSource 1464 | 1465 | 1466 | 1467 | 1468 | 1469 | YES 1470 | 1471 | NSObject 1472 | 1473 | IBFrameworkSource 1474 | Growl.framework/Headers/GrowlApplicationBridge.h 1475 | 1476 | 1477 | 1478 | 1479 | 0 1480 | IBCocoaFramework 1481 | 1482 | com.apple.InterfaceBuilder.CocoaPlugin.macosx 1483 | 1484 | 1485 | 1486 | com.apple.InterfaceBuilder.CocoaPlugin.InterfaceBuilder3 1487 | 1488 | 1489 | YES 1490 | 1491 | 3 1492 | 1493 | NSSwitch 1494 | {15, 15} 1495 | 1496 | 1497 | 1498 | -------------------------------------------------------------------------------- /jenx/fr.lproj/Jenx.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 1060 5 | 11B26 6 | 1617 7 | 1138 8 | 566.00 9 | 10 | com.apple.InterfaceBuilder.CocoaPlugin 11 | 1617 12 | 13 | 14 | YES 15 | NSMenu 16 | NSMenuItem 17 | NSCustomObject 18 | 19 | 20 | YES 21 | com.apple.InterfaceBuilder.CocoaPlugin 22 | 23 | 24 | YES 25 | 26 | YES 27 | 28 | 29 | 30 | 31 | YES 32 | 33 | NSApplication 34 | 35 | 36 | FirstResponder 37 | 38 | 39 | NSApplication 40 | 41 | 42 | 43 | 44 | YES 45 | 46 | 47 | 48 | 49 | 131072 50 | 2147483647 51 | 52 | NSImage 53 | NSMenuCheckmark 54 | 55 | 56 | NSImage 57 | NSMenuMixedState 58 | 59 | 60 | 61 | 62 | YES 63 | YES 64 | 65 | 66 | 2147483647 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 2147483647 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 2147483647 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 2147483647 91 | 92 | 93 | 94 | 95 | 96 | YES 97 | YES 98 | 99 | 100 | 2147483647 101 | 102 | 103 | 104 | 105 | 106 | Rafraîchir les status 107 | 108 | 2147483647 109 | 110 | NSImage 111 | refresh 112 | 113 | 114 | 115 | 116 | 117 | 118 | YES 119 | YES 120 | 121 | 122 | 2147483647 123 | 124 | 125 | 126 | 127 | 128 | Projets 129 | 130 | 2147483647 131 | 132 | NSImage 133 | projects 134 | 135 | 136 | 137 | 138 | 139 | 140 | YES 141 | YES 142 | 143 | 144 | 2147483647 145 | 146 | 147 | 148 | 149 | 150 | Préférences... 151 | 152 | 2147483647 153 | 154 | 155 | 156 | 157 | 158 | Quitter Jenx 159 | 160 | 2147483647 161 | 162 | 163 | 164 | 165 | 166 | 167 | Jenx 168 | 169 | 170 | NSFontManager 171 | 172 | 173 | 174 | 175 | YES 176 | 177 | 178 | delegate 179 | 180 | 181 | 182 | 495 183 | 184 | 185 | 186 | menu 187 | 188 | 189 | 190 | 538 191 | 192 | 193 | 194 | terminate: 195 | 196 | 197 | 198 | 574 199 | 200 | 201 | 202 | show_preferences_window: 203 | 204 | 205 | 206 | 580 207 | 208 | 209 | 210 | ensure_connection: 211 | 212 | 213 | 214 | 590 215 | 216 | 217 | 218 | menu_default_project 219 | 220 | 221 | 222 | 595 223 | 224 | 225 | 226 | menu_default_project_status 227 | 228 | 229 | 230 | 596 231 | 232 | 233 | 234 | menu_default_project_update_time 235 | 236 | 237 | 238 | 597 239 | 240 | 241 | 242 | 243 | YES 244 | 245 | 0 246 | 247 | 248 | 249 | 250 | 251 | -2 252 | 253 | 254 | File's Owner 255 | 256 | 257 | -1 258 | 259 | 260 | First Responder 261 | 262 | 263 | -3 264 | 265 | 266 | Application 267 | 268 | 269 | 420 270 | 271 | 272 | 273 | 274 | 494 275 | 276 | 277 | 278 | 279 | 533 280 | 281 | 282 | YES 283 | 284 | 285 | 286 | 287 | 288 | 289 | 290 | 291 | 292 | 293 | 294 | 295 | 296 | 297 | 298 | 299 | 535 300 | 301 | 302 | Refresh Status 303 | 304 | 305 | 540 306 | 307 | 308 | 309 | 310 | 541 311 | 312 | 313 | 314 | 315 | 542 316 | 317 | 318 | Default Project 319 | 320 | 321 | 544 322 | 323 | 324 | Projects 325 | 326 | 327 | 571 328 | 329 | 330 | Quit Jenx 331 | 332 | 333 | 572 334 | 335 | 336 | 337 | 338 | 578 339 | 340 | 341 | Preferences... 342 | 343 | 344 | 592 345 | 346 | 347 | Default Project Update Time 348 | 349 | 350 | 594 351 | 352 | 353 | Default Project Status 354 | 355 | 356 | 598 357 | 358 | 359 | Jenx Status 360 | 361 | 362 | 599 363 | 364 | 365 | 366 | 367 | 368 | 369 | YES 370 | 371 | YES 372 | -1.IBPluginDependency 373 | -2.IBPluginDependency 374 | -3.IBPluginDependency 375 | 420.IBPluginDependency 376 | 494.IBPluginDependency 377 | 533.IBPluginDependency 378 | 535.IBPluginDependency 379 | 540.IBPluginDependency 380 | 541.IBPluginDependency 381 | 542.IBPluginDependency 382 | 544.IBPluginDependency 383 | 571.IBPluginDependency 384 | 572.IBPluginDependency 385 | 578.IBPluginDependency 386 | 592.IBPluginDependency 387 | 594.IBPluginDependency 388 | 598.IBPluginDependency 389 | 599.IBPluginDependency 390 | 391 | 392 | YES 393 | com.apple.InterfaceBuilder.CocoaPlugin 394 | com.apple.InterfaceBuilder.CocoaPlugin 395 | com.apple.InterfaceBuilder.CocoaPlugin 396 | com.apple.InterfaceBuilder.CocoaPlugin 397 | com.apple.InterfaceBuilder.CocoaPlugin 398 | com.apple.InterfaceBuilder.CocoaPlugin 399 | com.apple.InterfaceBuilder.CocoaPlugin 400 | com.apple.InterfaceBuilder.CocoaPlugin 401 | com.apple.InterfaceBuilder.CocoaPlugin 402 | com.apple.InterfaceBuilder.CocoaPlugin 403 | com.apple.InterfaceBuilder.CocoaPlugin 404 | com.apple.InterfaceBuilder.CocoaPlugin 405 | com.apple.InterfaceBuilder.CocoaPlugin 406 | com.apple.InterfaceBuilder.CocoaPlugin 407 | com.apple.InterfaceBuilder.CocoaPlugin 408 | com.apple.InterfaceBuilder.CocoaPlugin 409 | com.apple.InterfaceBuilder.CocoaPlugin 410 | com.apple.InterfaceBuilder.CocoaPlugin 411 | 412 | 413 | 414 | YES 415 | 416 | 417 | 418 | 419 | 420 | YES 421 | 422 | 423 | 424 | 425 | 599 426 | 427 | 428 | 0 429 | IBCocoaFramework 430 | 431 | com.apple.InterfaceBuilder.CocoaPlugin.macosx 432 | 433 | 434 | 435 | com.apple.InterfaceBuilder.CocoaPlugin.InterfaceBuilder3 436 | 437 | 438 | YES 439 | 3 440 | 441 | YES 442 | 443 | YES 444 | NSMenuCheckmark 445 | NSMenuMixedState 446 | projects 447 | refresh 448 | 449 | 450 | YES 451 | {9, 8} 452 | {7, 2} 453 | {14, 13} 454 | {14, 16} 455 | 456 | 457 | 458 | 459 | -------------------------------------------------------------------------------- /jenx/fr.lproj/Localizable.strings: -------------------------------------------------------------------------------- 1 | /* 2 | Localizable.strings 3 | jenx 4 | 5 | Created by Johan BLEUZEN on 16/09/11. 6 | Copyright 2011 Urban Coding. All rights reserved. 7 | */ 8 | 9 | "Settings" = "Préférences"; 10 | 11 | "Connection Error" = "Erreur de connection"; 12 | "Cannot connect to build server." = "Impossible de se connecter à Jenkins."; 13 | "Jenx Status: Not Connected" = "Status de Jenx: Non Connecté"; 14 | "Jenx Status: Connected" = "Status de Jenx: Connecté"; 15 | 16 | "Connection Failure" = "Connection Failure"; 17 | "Build has Issues" = "Build has Issues"; 18 | "Build Failure" = "Build Failure"; 19 | "Build Success" = "Build Success"; 20 | 21 | "Project: ..." = "Projet: ..."; 22 | "Status: ..." = "Status: ..."; 23 | "Last Update: ..." = "Dernière mise à jour : ..."; 24 | 25 | "Project: %@" = "Projet: %@"; 26 | "Status: %@" = "Status: %@"; 27 | "%I:%M:%S %p" = "%H:%M:%S"; /* This is for date formating */ 28 | "Last Update: %@" = "Dernière mise à jour: %@"; 29 | 30 | "View all projects.." = "Voir tous les projets.."; 31 | 32 | "Could not retrieve status" = "Impossible de récupérer le status"; 33 | "Broken" = "Cassé"; 34 | "Stable" = "Stable"; 35 | "Building" = "Build en cours"; -------------------------------------------------------------------------------- /jenx/fr.lproj/PreferencesGeneralView.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 1060 5 | 11B26 6 | 1617 7 | 1138 8 | 566.00 9 | 10 | com.apple.InterfaceBuilder.CocoaPlugin 11 | 1617 12 | 13 | 14 | YES 15 | NSComboBoxCell 16 | NSNumberFormatter 17 | NSButton 18 | NSButtonCell 19 | NSTextFieldCell 20 | NSSecureTextFieldCell 21 | NSBox 22 | NSComboBox 23 | NSCustomObject 24 | NSCustomView 25 | NSUserDefaultsController 26 | NSSecureTextField 27 | NSTextField 28 | 29 | 30 | YES 31 | com.apple.InterfaceBuilder.CocoaPlugin 32 | 33 | 34 | YES 35 | 36 | YES 37 | 38 | 39 | 40 | 41 | YES 42 | 43 | PreferencesGeneralViewController 44 | 45 | 46 | FirstResponder 47 | 48 | 49 | NSApplication 50 | 51 | 52 | 53 | 268 54 | 55 | YES 56 | 57 | 58 | 268 59 | {{133, 252}, {183, 22}} 60 | 61 | 62 | 63 | 2 64 | YES 65 | 66 | -1804468671 67 | 272630784 68 | 69 | 70 | LucidaGrande 71 | 13 72 | 1044 73 | 74 | 75 | YES 76 | 77 | 6 78 | System 79 | textBackgroundColor 80 | 81 | 3 82 | MQA 83 | 84 | 85 | 86 | 6 87 | System 88 | textColor 89 | 90 | 3 91 | MAA 92 | 93 | 94 | 95 | 96 | 97 | 98 | 268 99 | {{133, 220}, {183, 22}} 100 | 101 | 102 | 103 | 2 104 | YES 105 | 106 | 343014976 107 | 272630784 108 | 109 | 110 | 111 | YES 112 | 113 | 114 | 115 | YES 116 | NSAllRomanInputSourcesLocaleIdentifier 117 | 118 | 119 | 120 | 121 | 122 | 268 123 | {{289, 149}, {63, 17}} 124 | 125 | 126 | 127 | 2 128 | YES 129 | 130 | 68288064 131 | 272630784 132 | secondes 133 | 134 | 135 | 136 | 6 137 | System 138 | controlColor 139 | 140 | 3 141 | MC42NjY2NjY2NjY3AA 142 | 143 | 144 | 145 | 6 146 | System 147 | controlTextColor 148 | 149 | 150 | 151 | 152 | 153 | 154 | 268 155 | {{244, 146}, {40, 22}} 156 | 157 | 158 | 159 | 2 160 | YES 161 | 162 | -1804468671 163 | 138413056 164 | 0 165 | 166 | 167 | YES 168 | 1 169 | 170 | 171 | 172 | 173 | 174 | 175 | 268 176 | {{35, 269}, {409, 26}} 177 | 178 | 179 | 180 | 2 181 | YES 182 | 183 | 67239424 184 | 138412032 185 | Entrer l'url complète de votre serveur Jenkins (avec le protocole et le port) 186 | 187 | LucidaGrande 188 | 10 189 | 16 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 268 199 | {{147, 56}, {155, 18}} 200 | 201 | 202 | 203 | 2 204 | YES 205 | 206 | -2080244224 207 | 0 208 | Lancer au démarrage 209 | 210 | 211 | 1211912703 212 | 2 213 | 214 | NSImage 215 | NSSwitch 216 | 217 | 218 | NSSwitch 219 | 220 | 221 | 222 | 200 223 | 25 224 | 225 | 226 | 227 | 228 | 268 229 | {{360, 18}, {99, 25}} 230 | 231 | 232 | 2 233 | YES 234 | 235 | -2080244224 236 | 134217728 237 | Sauver 238 | 239 | 240 | -2038152961 241 | 163 242 | 243 | 244 | 400 245 | 75 246 | 247 | 248 | 249 | 250 | 268 251 | {{119, 85}, {211, 18}} 252 | 253 | 254 | 255 | 2 256 | YES 257 | 258 | -2080244224 259 | 0 260 | Activer les notifications Growl 261 | 262 | 263 | 1211912703 264 | 2 265 | 266 | 267 | 268 | 269 | 200 270 | 25 271 | 272 | 273 | 274 | 275 | 268 276 | {{24, 122}, {336, 17}} 277 | 278 | 279 | 280 | 2 281 | YES 282 | 283 | 68288064 284 | 272630784 285 | Nombre maximum de projets dans la barre de menu 286 | 287 | 288 | 289 | 290 | 291 | 292 | 293 | 294 | 268 295 | {{365, 119}, {57, 22}} 296 | 297 | 298 | 299 | 2 300 | YES 301 | 302 | -1804468671 303 | 138413056 304 | 305 | 306 | 307 | YES 308 | 309 | YES 310 | allowsFloats 311 | formatterBehavior 312 | locale 313 | negativeInfinitySymbol 314 | nilSymbol 315 | numberStyle 316 | positiveInfinitySymbol 317 | 318 | 319 | YES 320 | 321 | 322 | 323 | 324 | 325 | -∞ 326 | 327 | 328 | +∞ 329 | 330 | 331 | #,##0.### 332 | #,##0.### 333 | 334 | 335 | 336 | 337 | 338 | 339 | 340 | NaN 341 | 342 | YES 343 | 344 | 345 | 346 | 347 | 348 | 0 349 | 0 350 | YES 351 | NO 352 | 1 353 | AAAAAAAAAAAAAAAAAAAAAA 354 | 355 | 356 | 357 | 3 358 | YES 359 | YES 360 | YES 361 | 362 | . 363 | , 364 | YES 365 | NO 366 | YES 367 | 368 | 5 369 | 370 | YES 371 | 1 372 | 373 | 374 | 375 | 376 | 377 | 378 | 268 379 | {{97, 149}, {142, 17}} 380 | 381 | 382 | 383 | 2 384 | YES 385 | 386 | 68288064 387 | 272630784 388 | Taux de rafraissiment 389 | 390 | 391 | 392 | 393 | 394 | 395 | 396 | 397 | 12 398 | {{12, 173}, {447, 5}} 399 | 400 | 401 | 402 | 2 403 | {0, 0} 404 | 405 | 67239424 406 | 0 407 | Box 408 | 409 | 410 | 411 | 3 412 | MCAwLjgwMDAwMDAxMTkAA 413 | 414 | 415 | 3 416 | 2 417 | 0 418 | NO 419 | 420 | 421 | 422 | 268 423 | {{133, 188}, {329, 26}} 424 | 425 | 426 | 427 | 2 428 | YES 429 | 430 | 74579521 431 | 272634880 432 | 433 | 434 | 435 | YES 436 | 437 | 438 | 5 439 | YES 440 | 441 | 442 | 443 | 274 444 | {13, 0} 445 | 446 | 447 | YES 448 | 449 | YES 450 | 451 | 10 452 | 10 453 | 1000 454 | 455 | 75628032 456 | 0 457 | 458 | 459 | LucidaGrande 460 | 12 461 | 16 462 | 463 | 464 | 3 465 | MC4zMzMzMzI5ODU2AA 466 | 467 | 468 | 469 | 470 | 338820672 471 | 268436480 472 | 473 | 474 | YES 475 | 476 | 6 477 | System 478 | controlBackgroundColor 479 | 480 | 481 | 482 | 483 | 3 484 | YES 485 | 486 | 487 | 488 | 3 489 | 2 490 | 491 | 492 | 6 493 | System 494 | gridColor 495 | 496 | 3 497 | MC41AA 498 | 499 | 500 | 19 501 | tableViewAction: 502 | -765427712 503 | 504 | 505 | 506 | 1 507 | 15 508 | 0 509 | YES 510 | 0 511 | 1 512 | 513 | 514 | 515 | 516 | 517 | 268 518 | {{14, 194}, {114, 17}} 519 | 520 | 521 | 522 | 2 523 | YES 524 | 525 | 68288064 526 | 272630784 527 | Projet par défaut: 528 | 529 | 530 | 531 | 532 | 533 | 534 | 535 | 536 | 268 537 | {{324, 300}, {135, 25}} 538 | 539 | 540 | 541 | 2 542 | YES 543 | 544 | -2080244224 545 | 134217728 546 | Charger les projets 547 | 548 | 549 | -2038152961 550 | 163 551 | 552 | 553 | 400 554 | 75 555 | 556 | 557 | 558 | 559 | 268 560 | {{17, 225}, {111, 17}} 561 | 562 | 563 | 564 | 2 565 | YES 566 | 567 | 68288064 568 | 71304192 569 | Mot de passe: 570 | 571 | 572 | 573 | 574 | 575 | 576 | 577 | 578 | 268 579 | {{17, 257}, {111, 17}} 580 | 581 | 582 | 583 | 2 584 | YES 585 | 586 | 68288064 587 | 71304192 588 | Utilisateur: 589 | 590 | 591 | 592 | 593 | 594 | 595 | 596 | 597 | 268 598 | {{133, 302}, {183, 22}} 599 | 600 | 601 | 602 | 2 603 | YES 604 | 605 | -1804468671 606 | 272630784 607 | 608 | 609 | 610 | YES 611 | 612 | 613 | 614 | 615 | 616 | 617 | 268 618 | {{50, 308}, {78, 17}} 619 | 620 | 621 | 622 | 2 623 | YES 624 | 625 | 68288064 626 | 71304192 627 | URL Jenkins 628 | 629 | 630 | 631 | 632 | 633 | 634 | 635 | {479, 345} 636 | 637 | 638 | 639 | 2 640 | NSView 641 | 642 | 643 | YES 644 | 645 | 646 | 647 | 648 | YES 649 | 650 | 651 | project_list 652 | 653 | 654 | 655 | 22 656 | 657 | 658 | 659 | view 660 | 661 | 662 | 663 | 25 664 | 665 | 666 | 667 | default_project 668 | 669 | 670 | 671 | 43 672 | 673 | 674 | 675 | num_menu_projects 676 | 677 | 678 | 679 | 44 680 | 681 | 682 | 683 | server_url 684 | 685 | 686 | 687 | 45 688 | 689 | 690 | 691 | load_projects: 692 | 693 | 694 | 695 | 52 696 | 697 | 698 | 699 | save_preferences: 700 | 701 | 702 | 703 | 62 704 | 705 | 706 | 707 | launch_at_login 708 | 709 | 710 | 711 | 65 712 | 713 | 714 | 715 | refresh_time 716 | 717 | 718 | 719 | 89 720 | 721 | 722 | 723 | username 724 | 725 | 726 | 727 | 114 728 | 729 | 730 | 731 | password 732 | 733 | 734 | 735 | 115 736 | 737 | 738 | 739 | enable_growl 740 | 741 | 742 | 743 | 118 744 | 745 | 746 | 747 | nextKeyView 748 | 749 | 750 | 751 | 119 752 | 753 | 754 | 755 | nextKeyView 756 | 757 | 758 | 759 | 120 760 | 761 | 762 | 763 | nextKeyView 764 | 765 | 766 | 767 | 121 768 | 769 | 770 | 771 | nextKeyView 772 | 773 | 774 | 775 | 124 776 | 777 | 778 | 779 | nextKeyView 780 | 781 | 782 | 783 | 125 784 | 785 | 786 | 787 | nextKeyView 788 | 789 | 790 | 791 | 126 792 | 793 | 794 | 795 | nextKeyView 796 | 797 | 798 | 799 | 127 800 | 801 | 802 | 803 | nextKeyView 804 | 805 | 806 | 807 | 130 808 | 809 | 810 | 811 | nextKeyView 812 | 813 | 814 | 815 | 131 816 | 817 | 818 | 819 | 820 | YES 821 | 822 | 0 823 | 824 | 825 | 826 | 827 | 828 | -2 829 | 830 | 831 | File's Owner 832 | 833 | 834 | -1 835 | 836 | 837 | First Responder 838 | 839 | 840 | -3 841 | 842 | 843 | Application 844 | 845 | 846 | 3 847 | 848 | 849 | YES 850 | 851 | 852 | 853 | 854 | 855 | 856 | 857 | 858 | 859 | 860 | 861 | 862 | 863 | 864 | 865 | 866 | 867 | 868 | 869 | 870 | 871 | Jenx General Settings 872 | 873 | 874 | 4 875 | 876 | 877 | YES 878 | 879 | 880 | 881 | 882 | 883 | 5 884 | 885 | 886 | 887 | 888 | 6 889 | 890 | 891 | YES 892 | 893 | 894 | 895 | Build Server URL 896 | 897 | 898 | 7 899 | 900 | 901 | 902 | 903 | 8 904 | 905 | 906 | YES 907 | 908 | 909 | 910 | 911 | 912 | 9 913 | 914 | 915 | 916 | 917 | 10 918 | 919 | 920 | YES 921 | 922 | 923 | 924 | 925 | 926 | 11 927 | 928 | 929 | 930 | 931 | 12 932 | 933 | 934 | YES 935 | 936 | 937 | 938 | 939 | 940 | 13 941 | 942 | 943 | 944 | 945 | 18 946 | 947 | 948 | 949 | 950 | 26 951 | 952 | 953 | YES 954 | 955 | 956 | 957 | 958 | 959 | 27 960 | 961 | 962 | 963 | 964 | 35 965 | 966 | 967 | YES 968 | 969 | 970 | 971 | 972 | 973 | 36 974 | 975 | 976 | YES 977 | 978 | 979 | 980 | 981 | 982 | 37 983 | 984 | 985 | 986 | 987 | 38 988 | 989 | 990 | YES 991 | 992 | 993 | 994 | 995 | 996 | 39 997 | 998 | 999 | 1000 | 1001 | 57 1002 | 1003 | 1004 | YES 1005 | 1006 | 1007 | 1008 | 1009 | 1010 | 58 1011 | 1012 | 1013 | 1014 | 1015 | 60 1016 | 1017 | 1018 | YES 1019 | 1020 | 1021 | 1022 | 1023 | 1024 | 61 1025 | 1026 | 1027 | 1028 | 1029 | 63 1030 | 1031 | 1032 | YES 1033 | 1034 | 1035 | 1036 | Open At Login 1037 | 1038 | 1039 | 64 1040 | 1041 | 1042 | 1043 | 1044 | 76 1045 | 1046 | 1047 | YES 1048 | 1049 | 1050 | 1051 | Information Label 1052 | 1053 | 1054 | 77 1055 | 1056 | 1057 | 1058 | 1059 | 85 1060 | 1061 | 1062 | YES 1063 | 1064 | 1065 | 1066 | 1067 | 1068 | 86 1069 | 1070 | 1071 | 1072 | 1073 | 87 1074 | 1075 | 1076 | YES 1077 | 1078 | 1079 | 1080 | 1081 | 1082 | 88 1083 | 1084 | 1085 | 1086 | 1087 | 92 1088 | 1089 | 1090 | YES 1091 | 1092 | 1093 | 1094 | 1095 | 1096 | 95 1097 | 1098 | 1099 | 1100 | 1101 | 96 1102 | 1103 | 1104 | YES 1105 | 1106 | 1107 | 1108 | 1109 | 1110 | 99 1111 | 1112 | 1113 | 1114 | 1115 | 100 1116 | 1117 | 1118 | 1119 | 1120 | 103 1121 | 1122 | 1123 | YES 1124 | 1125 | 1126 | 1127 | Build server password 1128 | 1129 | 1130 | 104 1131 | 1132 | 1133 | 1134 | 1135 | 105 1136 | 1137 | 1138 | YES 1139 | 1140 | 1141 | 1142 | Build server username 1143 | 1144 | 1145 | 106 1146 | 1147 | 1148 | 1149 | 1150 | 1151 | 1152 | YES 1153 | 1154 | YES 1155 | -1.IBPluginDependency 1156 | -2.IBPluginDependency 1157 | -3.IBPluginDependency 1158 | 10.IBPluginDependency 1159 | 100.IBPluginDependency 1160 | 103.IBAttributePlaceholdersKey 1161 | 103.IBPluginDependency 1162 | 104.IBPluginDependency 1163 | 105.IBAttributePlaceholdersKey 1164 | 105.IBPluginDependency 1165 | 106.IBPluginDependency 1166 | 11.IBPluginDependency 1167 | 12.IBPluginDependency 1168 | 13.IBPluginDependency 1169 | 18.IBPluginDependency 1170 | 26.IBPluginDependency 1171 | 27.IBPluginDependency 1172 | 3.IBPluginDependency 1173 | 35.IBPluginDependency 1174 | 36.IBPluginDependency 1175 | 37.IBNumberFormatterBehaviorMetadataKey 1176 | 37.IBNumberFormatterLocalizesFormatMetadataKey 1177 | 37.IBPluginDependency 1178 | 38.IBPluginDependency 1179 | 39.IBPluginDependency 1180 | 4.IBPluginDependency 1181 | 5.IBPluginDependency 1182 | 57.IBPluginDependency 1183 | 58.IBPluginDependency 1184 | 6.IBPluginDependency 1185 | 60.IBPluginDependency 1186 | 61.IBPluginDependency 1187 | 63.IBPluginDependency 1188 | 64.IBPluginDependency 1189 | 7.IBPluginDependency 1190 | 76.IBPluginDependency 1191 | 77.IBPluginDependency 1192 | 8.IBPluginDependency 1193 | 85.IBPluginDependency 1194 | 86.IBPluginDependency 1195 | 87.IBPluginDependency 1196 | 88.IBPluginDependency 1197 | 9.IBPluginDependency 1198 | 92.IBPluginDependency 1199 | 95.IBPluginDependency 1200 | 96.IBPluginDependency 1201 | 99.IBPluginDependency 1202 | 1203 | 1204 | YES 1205 | com.apple.InterfaceBuilder.CocoaPlugin 1206 | com.apple.InterfaceBuilder.CocoaPlugin 1207 | com.apple.InterfaceBuilder.CocoaPlugin 1208 | com.apple.InterfaceBuilder.CocoaPlugin 1209 | com.apple.InterfaceBuilder.CocoaPlugin 1210 | 1211 | AccessibilityDescription 1212 | 1213 | AccessibilityDescription 1214 | 1215 | Build server password 1216 | 1217 | 1218 | com.apple.InterfaceBuilder.CocoaPlugin 1219 | com.apple.InterfaceBuilder.CocoaPlugin 1220 | 1221 | AccessibilityDescription 1222 | 1223 | AccessibilityDescription 1224 | 1225 | Build server username 1226 | 1227 | 1228 | com.apple.InterfaceBuilder.CocoaPlugin 1229 | com.apple.InterfaceBuilder.CocoaPlugin 1230 | com.apple.InterfaceBuilder.CocoaPlugin 1231 | com.apple.InterfaceBuilder.CocoaPlugin 1232 | com.apple.InterfaceBuilder.CocoaPlugin 1233 | com.apple.InterfaceBuilder.CocoaPlugin 1234 | com.apple.InterfaceBuilder.CocoaPlugin 1235 | com.apple.InterfaceBuilder.CocoaPlugin 1236 | com.apple.InterfaceBuilder.CocoaPlugin 1237 | com.apple.InterfaceBuilder.CocoaPlugin 1238 | com.apple.InterfaceBuilder.CocoaPlugin 1239 | 1240 | 1241 | com.apple.InterfaceBuilder.CocoaPlugin 1242 | com.apple.InterfaceBuilder.CocoaPlugin 1243 | com.apple.InterfaceBuilder.CocoaPlugin 1244 | com.apple.InterfaceBuilder.CocoaPlugin 1245 | com.apple.InterfaceBuilder.CocoaPlugin 1246 | com.apple.InterfaceBuilder.CocoaPlugin 1247 | com.apple.InterfaceBuilder.CocoaPlugin 1248 | com.apple.InterfaceBuilder.CocoaPlugin 1249 | com.apple.InterfaceBuilder.CocoaPlugin 1250 | com.apple.InterfaceBuilder.CocoaPlugin 1251 | com.apple.InterfaceBuilder.CocoaPlugin 1252 | com.apple.InterfaceBuilder.CocoaPlugin 1253 | com.apple.InterfaceBuilder.CocoaPlugin 1254 | com.apple.InterfaceBuilder.CocoaPlugin 1255 | com.apple.InterfaceBuilder.CocoaPlugin 1256 | com.apple.InterfaceBuilder.CocoaPlugin 1257 | com.apple.InterfaceBuilder.CocoaPlugin 1258 | com.apple.InterfaceBuilder.CocoaPlugin 1259 | com.apple.InterfaceBuilder.CocoaPlugin 1260 | com.apple.InterfaceBuilder.CocoaPlugin 1261 | com.apple.InterfaceBuilder.CocoaPlugin 1262 | com.apple.InterfaceBuilder.CocoaPlugin 1263 | com.apple.InterfaceBuilder.CocoaPlugin 1264 | com.apple.InterfaceBuilder.CocoaPlugin 1265 | com.apple.InterfaceBuilder.CocoaPlugin 1266 | 1267 | 1268 | 1269 | YES 1270 | 1271 | 1272 | 1273 | 1274 | 1275 | YES 1276 | 1277 | 1278 | 1279 | 1280 | 131 1281 | 1282 | 1283 | 0 1284 | IBCocoaFramework 1285 | 1286 | com.apple.InterfaceBuilder.CocoaPlugin.macosx 1287 | 1288 | 1289 | 1290 | com.apple.InterfaceBuilder.CocoaPlugin.InterfaceBuilder3 1291 | 1292 | 1293 | YES 1294 | 3 1295 | 1296 | NSSwitch 1297 | {15, 15} 1298 | 1299 | 1300 | 1301 | -------------------------------------------------------------------------------- /jenx/images/app.tiff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/urbancoding/jenx/65e9969ae3330a428df3fc7e83f74271b3619284/jenx/images/app.tiff -------------------------------------------------------------------------------- /jenx/images/build_failure.tiff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/urbancoding/jenx/65e9969ae3330a428df3fc7e83f74271b3619284/jenx/images/build_failure.tiff -------------------------------------------------------------------------------- /jenx/images/build_initiated.tiff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/urbancoding/jenx/65e9969ae3330a428df3fc7e83f74271b3619284/jenx/images/build_initiated.tiff -------------------------------------------------------------------------------- /jenx/images/build_success.tiff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/urbancoding/jenx/65e9969ae3330a428df3fc7e83f74271b3619284/jenx/images/build_success.tiff -------------------------------------------------------------------------------- /jenx/images/connecting.tiff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/urbancoding/jenx/65e9969ae3330a428df3fc7e83f74271b3619284/jenx/images/connecting.tiff -------------------------------------------------------------------------------- /jenx/images/jenx.icns: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/urbancoding/jenx/65e9969ae3330a428df3fc7e83f74271b3619284/jenx/images/jenx.icns -------------------------------------------------------------------------------- /jenx/images/jenx_failure.tiff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/urbancoding/jenx/65e9969ae3330a428df3fc7e83f74271b3619284/jenx/images/jenx_failure.tiff -------------------------------------------------------------------------------- /jenx/images/jenx_issues.tiff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/urbancoding/jenx/65e9969ae3330a428df3fc7e83f74271b3619284/jenx/images/jenx_issues.tiff -------------------------------------------------------------------------------- /jenx/images/jenx_success.tiff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/urbancoding/jenx/65e9969ae3330a428df3fc7e83f74271b3619284/jenx/images/jenx_success.tiff -------------------------------------------------------------------------------- /jenx/images/projects.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/urbancoding/jenx/65e9969ae3330a428df3fc7e83f74271b3619284/jenx/images/projects.png -------------------------------------------------------------------------------- /jenx/images/refresh.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/urbancoding/jenx/65e9969ae3330a428df3fc7e83f74271b3619284/jenx/images/refresh.png -------------------------------------------------------------------------------- /jenx/jenx-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleDocumentTypes 8 | 9 | CFBundleExecutable 10 | Jenx 11 | CFBundleIconFile 12 | jenx 13 | CFBundleIdentifier 14 | com.urbancoding.${PRODUCT_NAME:rfc1034identifier} 15 | CFBundleInfoDictionaryVersion 16 | 6.0 17 | CFBundleName 18 | ${PRODUCT_NAME} 19 | CFBundlePackageType 20 | APPL 21 | CFBundleShortVersionString 22 | 0.2 23 | CFBundleSignature 24 | ???? 25 | CFBundleURLTypes 26 | 27 | CFBundleVersion 28 | 1 29 | LSApplicationCategoryType 30 | public.app-category.developer-tools 31 | LSMinimumSystemVersion 32 | ${MACOSX_DEPLOYMENT_TARGET} 33 | LSUIElement 34 | 35 | NSMainNibFile 36 | Jenx 37 | NSPrincipalClass 38 | NSApplication 39 | NSServices 40 | 41 | UTExportedTypeDeclarations 42 | 43 | UTImportedTypeDeclarations 44 | 45 | 46 | 47 | -------------------------------------------------------------------------------- /jenx/jenx-Prefix.pch: -------------------------------------------------------------------------------- 1 | // 2 | // Prefix header for all source files of the 'jenx' target in the 'jenx' project 3 | // 4 | 5 | #ifdef __OBJC__ 6 | #import 7 | #endif 8 | -------------------------------------------------------------------------------- /jenx/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // jenx 4 | // 5 | // Created by Trent Kocurek on 5/18/11. 6 | // Copyright 2011 Urban Coding. Released under the MIT license. 7 | // 8 | 9 | #import 10 | 11 | #import 12 | 13 | int main(int argc, char *argv[]) 14 | { 15 | return macruby_main("rb_main.rb", argc, argv); 16 | } 17 | -------------------------------------------------------------------------------- /jenx/rb_main.rb: -------------------------------------------------------------------------------- 1 | # 2 | # rb_main.rb 3 | # jenx 4 | # 5 | # Created by Trent Kocurek on 5/18/11. 6 | # Copyright (c) 2011 Urban Coding. Released under the MIT license. 7 | # 8 | 9 | # Loading the Cocoa framework. If you need to load more frameworks, you can 10 | # do that here too. 11 | framework 'Cocoa' 12 | framework 'Growl' 13 | 14 | require 'rubygems' 15 | require 'json' 16 | require 'timeout' 17 | require 'net/https' 18 | require 'open-uri' 19 | 20 | # Localize must be loaded in first position 21 | require 'JenxLocalize' 22 | 23 | # Loading all the Ruby project files. 24 | main = File.basename(__FILE__, File.extname(__FILE__)) 25 | dir_path = NSBundle.mainBundle.resourcePath.fileSystemRepresentation 26 | Dir.glob(File.join(dir_path, '*.{rb,rbo}')).map { |x| File.basename(x, File.extname(x)) }.uniq.each do |path| 27 | # JenxLocalize is already, so we skip it 28 | if path == 'JenxLocalize' 29 | next 30 | end 31 | if path != main 32 | require(path) 33 | end 34 | end 35 | 36 | # Starting the Cocoa main loop. 37 | NSApplicationMain(0, nil) 38 | -------------------------------------------------------------------------------- /tests/JenxConnectionTest.rb: -------------------------------------------------------------------------------- 1 | # 2 | # JenxConnectionTest.rb 3 | # jenx 4 | # 5 | # Created by Roman Dmytrenko. 6 | # Copyright 2011 Urban Coding. Released under the MIT license. 7 | # 8 | 9 | class JenxConnectionTest < JenxTestCase 10 | 11 | def test_should_auth_if_username_provided 12 | connection = JenxConnection.new('http://fake.jenkins', 'user', 'password') 13 | req = Net::HTTP::Head.new(JENX_API_URI) 14 | connection.auth(req) 15 | headers = req.to_hash 16 | assert_equal headers['authorization'], ['Basic dXNlcjpwYXNzd29yZA=='] 17 | end 18 | 19 | def test_should_not_auth_if_username_is_nil 20 | connection = JenxConnection.new('http://fake.jenkins') 21 | req = Net::HTTP::Head.new(JENX_API_URI) 22 | connection.auth(req) 23 | headers = req.to_hash 24 | assert_nil headers['authorization'] 25 | end 26 | 27 | def test_should_not_auth_if_username_is_empty_string 28 | connection = JenxConnection.new('http://fake.jenkins', '', '') 29 | req = Net::HTTP::Head.new(JENX_API_URI) 30 | connection.auth(req) 31 | headers = req.to_hash 32 | assert_nil headers['authorization'] 33 | end 34 | 35 | def test_should_use_ssl_if_url_is_secure 36 | connection = JenxConnection.new('https://fake.jenkins') 37 | uri = URI.parse('https://fake.jenkins') 38 | http = Net::HTTP.new(uri.host, uri.port) 39 | connection.initSSL(http, uri.scheme) 40 | assert http.use_ssl? 41 | end 42 | 43 | def test_should_connect_successfully 44 | url = 'http://user:pass@fake.jenkins/api/json'; 45 | FakeWeb.register_uri(:head, url, :status => ["200", "OK"]) 46 | connection = JenxConnection.new('http://fake.jenkins', 'user', 'pass') 47 | assert connection.is_connected? 48 | end 49 | 50 | def test_should_fail_if_user_and_password_is_wrong 51 | url = 'http://user:pass@fake.jenkins/api/json'; 52 | FakeWeb.register_uri(:head, url, :status => ["403", "Forbidden"]) 53 | connection = JenxConnection.new('http://fake.jenkins', 'user', 'pass') 54 | assert !connection.is_connected? 55 | end 56 | 57 | def test_should_fail_if_can_not_connect 58 | url = 'http://fake.jenkins/api/json'; 59 | FakeWeb.register_uri(:head, url, :status => ["500", "Internal Error"]) 60 | connection = JenxConnection.new('http://fake.jenkins') 61 | assert !connection.is_connected? 62 | end 63 | end -------------------------------------------------------------------------------- /tests/JenxTestCase.rb: -------------------------------------------------------------------------------- 1 | # 2 | # JenxTestCase.rb 3 | # jenx 4 | # 5 | # Created by Roman Dmytrenko. 6 | # Copyright 2011 Urban Coding. Released under the MIT license. 7 | # 8 | class JenxTestCase < Test::Unit::TestCase 9 | 10 | def teardown 11 | FakeWeb.clean_registry 12 | end 13 | end -------------------------------------------------------------------------------- /tests/run_suite.rb: -------------------------------------------------------------------------------- 1 | #sudo macgem install fakeweb 2 | 3 | framework 'Cocoa' 4 | framework 'Growl' 5 | 6 | require 'rubygems' 7 | require 'json' 8 | require 'timeout' 9 | require 'net/https' 10 | require 'open-uri' 11 | require 'test/unit' 12 | require 'fakeweb' 13 | 14 | FakeWeb.allow_net_connect = false 15 | 16 | # Loading all the Ruby project files. 17 | dir_path = File.expand_path('../../jenx/', __FILE__) 18 | ['JenxLocalize', 'JenxConstants', 'JenxConnection', 'JenxConnectionManager'].each do |class_name| 19 | require "#{dir_path}/#{class_name}.rb" 20 | end 21 | 22 | require File.expand_path('../JenxTestCase.rb', __FILE__) 23 | Dir.glob(File.expand_path('../**/*Test.rb', __FILE__)).each do |test| 24 | require test 25 | end 26 | --------------------------------------------------------------------------------