lg 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,4 @@
1
+ *.gem
2
+ .bundle
3
+ Gemfile.lock
4
+ pkg/*
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in memories.gemspec
4
+ gemspec
@@ -0,0 +1,20 @@
1
+ # A sample Guardfile
2
+ # More info at https://github.com/guard/guard#readme
3
+
4
+ guard 'minitest' do
5
+
6
+ # with Minitest::Spec
7
+ watch(%r|^spec/(.*)_spec\.rb|)
8
+ watch(%r|^lib/(.*)([^/]+)\.rb|) { |m| "spec/#{m[1]}#{m[2]}_spec.rb" }
9
+ watch(%r|^spec/spec_helper\.rb|) { "spec" }
10
+
11
+ # Rails 3.2
12
+ # watch(%r|^app/controllers/(.*)\.rb|) { |m| "test/controllers/#{m[1]}_test.rb" }
13
+ # watch(%r|^app/helpers/(.*)\.rb|) { |m| "test/helpers/#{m[1]}_test.rb" }
14
+ # watch(%r|^app/models/(.*)\.rb|) { |m| "test/unit/#{m[1]}_test.rb" }
15
+
16
+ # Rails
17
+ # watch(%r|^app/controllers/(.*)\.rb|) { |m| "test/functional/#{m[1]}_test.rb" }
18
+ # watch(%r|^app/helpers/(.*)\.rb|) { |m| "test/helpers/#{m[1]}_test.rb" }
19
+ # watch(%r|^app/models/(.*)\.rb|) { |m| "test/unit/#{m[1]}_test.rb" }
20
+ end
@@ -0,0 +1,117 @@
1
+ # Logbook
2
+
3
+ Logbook allows you to record memories easily from your command line into
4
+ virtual book(s). Books are simply private Github Gists (backend is
5
+ replaceable).
6
+
7
+
8
+ It is heavily inspired from its pythonish friend, http://maebert.github.com/jrnl.
9
+
10
+ I built it because I love Ruby, it was easy enough, and I really loved
11
+ the idea of storing as Gists as opposed to plain files.
12
+
13
+
14
+
15
+ # Usage
16
+
17
+ For brevity's sake, the Logbook gem name and executable is `lg`.
18
+
19
+ $ gem install lg
20
+ $ lg
21
+
22
+
23
+ If you want private Gists attached to your user (you most probably
24
+ want that), make sure to set your Github credentials as environment
25
+ variables, example:
26
+
27
+ $ export GITHUB_USER=youruser
28
+ $ export GITHUB_PASSWORD=yourpw
29
+
30
+ Now we need to make a first `book` and start `add`ing into it.
31
+
32
+ ## Setting up a book
33
+
34
+ Create a new book with the `lg book` command. You can give it a
35
+ cover, in this case `The Wizzard of Oz`.
36
+
37
+ $ lg book The Wizzard of Oz
38
+
39
+
40
+ ## Adding lgries
41
+
42
+ Simply say 'lg add' and your memory in a short sentence.
43
+
44
+ $ lg add just wrote the logbook gem README
45
+
46
+ You might find it convenient to specify when a thing happend explicitly,
47
+ just make sure to specify a natural date such as `yesterday` separated
48
+ by a colon `:`. Translation done with the `chronic` gem.
49
+
50
+ $ lg add yesterday: wrote the logbook gem README
51
+
52
+
53
+ ## More
54
+
55
+ You can safely skip this if that's all what you're looking for.
56
+
57
+ ## Switching books
58
+
59
+ Switch between books, when you know what you want, you can explicitly
60
+ specify the ID.
61
+
62
+ $ lg book book-id
63
+
64
+ Or pick from a menu, leaving arguments blank:
65
+
66
+ $ lg book
67
+ 1 The Wizzard of Oz deadbeef0aef
68
+ ...
69
+ Pick one: 1
70
+
71
+
72
+ ## Listing lgries
73
+
74
+ Say `lg all` when you want to see everything you've recorded.
75
+
76
+
77
+
78
+
79
+ # Philosophy
80
+
81
+ Command line is awesome. Its fast, and you feel it when you're less
82
+ dependent on your mouse for your development work (e.g. VIM).
83
+
84
+ You should just Alt/Command-Tab, write a line and go back working.
85
+
86
+ You should be expected to remember at most one commands (pitfall of success) to do actual work. Seriously, [focus](http://ezliu.com/focus/).
87
+
88
+
89
+ ## There's no search like in jrnl
90
+
91
+ Feature slim. Use gist search for that. True, its limited, but as of now, I believe
92
+ Github are working on improving that.
93
+
94
+ In actuallity, `jrnl`'s search loads all of your entries to memory and
95
+ performs search on an in-memory structure.
96
+ If the need arises, it should be dead easy to
97
+ make *that* kind of search in `logbook`.
98
+
99
+ ## There's no delete/modify
100
+
101
+ Again, feature slim. If you were using a real logbook, you'd
102
+ just cross the bad entry. It will still be there.
103
+ If you must, you can always use the gist interface for that.
104
+
105
+ ## There's no analytics, let me reap added value from my work!
106
+
107
+ Actually, a gist entry is a Git repository.
108
+ The modeling on-top-of a
109
+ Gist was done intentionally. Clone your book and
110
+ treat it like a Git repo.
111
+
112
+ From there, you can script against git and/or run countless analysis tools on your repository.
113
+
114
+
115
+
116
+
117
+
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
data/bin/lg ADDED
@@ -0,0 +1,13 @@
1
+ #!/usr/bin/env ruby
2
+ require "logbook/cli"
3
+
4
+
5
+ # banner
6
+ # testing:
7
+ # cli 'all'
8
+ # pr:
9
+ # logo
10
+ #
11
+
12
+ Logbook::CLI.start
13
+
@@ -0,0 +1,116 @@
1
+ Certificate chain
2
+ 0 s:/O=*.github.com/OU=Domain Control Validated/CN=*.github.com
3
+ i:/C=US/ST=Arizona/L=Scottsdale/O=GoDaddy.com, Inc./OU=http://certificates.godaddy.com/repository/CN=Go Daddy Secure Certification Authority/serialNumber=07969287
4
+ -----BEGIN CERTIFICATE-----
5
+ MIIFVTCCBD2gAwIBAgIHBGX+dPs18DANBgkqhkiG9w0BAQUFADCByjELMAkGA1UE
6
+ BhMCVVMxEDAOBgNVBAgTB0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxGjAY
7
+ BgNVBAoTEUdvRGFkZHkuY29tLCBJbmMuMTMwMQYDVQQLEypodHRwOi8vY2VydGlm
8
+ aWNhdGVzLmdvZGFkZHkuY29tL3JlcG9zaXRvcnkxMDAuBgNVBAMTJ0dvIERhZGR5
9
+ IFNlY3VyZSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTERMA8GA1UEBRMIMDc5Njky
10
+ ODcwHhcNMDkxMjExMDUwMjM2WhcNMTQxMjExMDUwMjM2WjBRMRUwEwYDVQQKEwwq
11
+ LmdpdGh1Yi5jb20xITAfBgNVBAsTGERvbWFpbiBDb250cm9sIFZhbGlkYXRlZDEV
12
+ MBMGA1UEAxMMKi5naXRodWIuY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB
13
+ CgKCAQEA7dOJw11wcgnzM08acnTZtlqVULtoYZ/3+x8Z4doEMa8VfBp/+XOvHeVD
14
+ K1YJAEVpSujEW9/Cd1JRGVvRK9k5ZTagMhkcQXP7MrI9n5jsglsLN2Q5LLcQg3LN
15
+ 8OokS/rZlC7DhRU5qTr2iNr0J4mmlU+EojdOfCV4OsmDbQIXlXh9R6hVg+4TyBka
16
+ szzxX/47AuGF+xFmqwldn0xD8MckXilyKM7UdWhPJHIprjko/N+NT02Dc3QMbxGb
17
+ p91i3v/i6xfm/wy/wC0xO9ZZovLdh0pIe20zERRNNJ8yOPbIGZ3xtj3FRu9RC4rG
18
+ M+1IYcQdFxu9fLZn6TnPpVKACvTqzQIDAQABo4IBtjCCAbIwDwYDVR0TAQH/BAUw
19
+ AwEBADAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwDgYDVR0PAQH/BAQD
20
+ AgWgMDMGA1UdHwQsMCowKKAmoCSGImh0dHA6Ly9jcmwuZ29kYWRkeS5jb20vZ2Rz
21
+ MS0xMS5jcmwwUwYDVR0gBEwwSjBIBgtghkgBhv1tAQcXATA5MDcGCCsGAQUFBwIB
22
+ FitodHRwOi8vY2VydGlmaWNhdGVzLmdvZGFkZHkuY29tL3JlcG9zaXRvcnkvMIGA
23
+ BggrBgEFBQcBAQR0MHIwJAYIKwYBBQUHMAGGGGh0dHA6Ly9vY3NwLmdvZGFkZHku
24
+ Y29tLzBKBggrBgEFBQcwAoY+aHR0cDovL2NlcnRpZmljYXRlcy5nb2RhZGR5LmNv
25
+ bS9yZXBvc2l0b3J5L2dkX2ludGVybWVkaWF0ZS5jcnQwHwYDVR0jBBgwFoAU/axh
26
+ MpNsRdbi7oVfmrrndplozOcwIwYDVR0RBBwwGoIMKi5naXRodWIuY29tggpnaXRo
27
+ dWIuY29tMB0GA1UdDgQWBBSH0Y8ZbuSHb1OMd5EHUN+jv1VHIDANBgkqhkiG9w0B
28
+ AQUFAAOCAQEAwIe/Bbuk1/r38aqb5wlXjoW6tAmLpzLRkKorDOcDUJLtN6a9XqAk
29
+ cgMai7NCI1YV+A4IjEENj53mV2xWLpniqLDHI5y2NbQuL2deu1jQSSNz7xE/nZCk
30
+ WGt8OEtm6YI2bUsq5EXy078avRbigBko1bqtFuG0s5+nFrKCjhQVIk+GX7cwiyr4
31
+ XJ49FxETvePrxNYr7x7n/Jju59KXTw3juPET+bAwNlRXmScjrMylMNUMr3sFcyLz
32
+ DciaVnnextu6+L0w1+5KNVbMKndRwgg/cRldBL4AgmtouTC3mlDGGG3U6eV75cdH
33
+ D03DXDfrYYjxmWjTRdO2GdbYnt1ToEgxyA==
34
+ -----END CERTIFICATE-----
35
+ 1 s:/C=US/ST=Arizona/L=Scottsdale/O=GoDaddy.com, Inc./OU=http://certificates.godaddy.com/repository/CN=Go Daddy Secure Certification Authority/serialNumber=07969287
36
+ i:/C=US/O=The Go Daddy Group, Inc./OU=Go Daddy Class 2 Certification Authority
37
+ -----BEGIN CERTIFICATE-----
38
+ MIIE3jCCA8agAwIBAgICAwEwDQYJKoZIhvcNAQEFBQAwYzELMAkGA1UEBhMCVVMx
39
+ ITAfBgNVBAoTGFRoZSBHbyBEYWRkeSBHcm91cCwgSW5jLjExMC8GA1UECxMoR28g
40
+ RGFkZHkgQ2xhc3MgMiBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0wNjExMTYw
41
+ MTU0MzdaFw0yNjExMTYwMTU0MzdaMIHKMQswCQYDVQQGEwJVUzEQMA4GA1UECBMH
42
+ QXJpem9uYTETMBEGA1UEBxMKU2NvdHRzZGFsZTEaMBgGA1UEChMRR29EYWRkeS5j
43
+ b20sIEluYy4xMzAxBgNVBAsTKmh0dHA6Ly9jZXJ0aWZpY2F0ZXMuZ29kYWRkeS5j
44
+ b20vcmVwb3NpdG9yeTEwMC4GA1UEAxMnR28gRGFkZHkgU2VjdXJlIENlcnRpZmlj
45
+ YXRpb24gQXV0aG9yaXR5MREwDwYDVQQFEwgwNzk2OTI4NzCCASIwDQYJKoZIhvcN
46
+ AQEBBQADggEPADCCAQoCggEBAMQt1RWMnCZM7DI161+4WQFapmGBWTtwY6vj3D3H
47
+ KrjJM9N55DrtPDAjhI6zMBS2sofDPZVUBJ7fmd0LJR4h3mUpfjWoqVTr9vcyOdQm
48
+ VZWt7/v+WIbXnvQAjYwqDL1CBM6nPwT27oDyqu9SoWlm2r4arV3aLGbqGmu75RpR
49
+ SgAvSMeYddi5Kcju+GZtCpyz8/x4fKL4o/K1w/O5epHBp+YlLpyo7RJlbmr2EkRT
50
+ cDCVw5wrWCs9CHRK8r5RsL+H0EwnWGu1NcWdrxcx+AuP7q2BNgWJCJjPOq8lh8BJ
51
+ 6qf9Z/dFjpfMFDniNoW1fho3/Rb2cRGadDAW/hOUoz+EDU8CAwEAAaOCATIwggEu
52
+ MB0GA1UdDgQWBBT9rGEyk2xF1uLuhV+auud2mWjM5zAfBgNVHSMEGDAWgBTSxLDS
53
+ kdRMEXGzYcs9of7dqGrU4zASBgNVHRMBAf8ECDAGAQH/AgEAMDMGCCsGAQUFBwEB
54
+ BCcwJTAjBggrBgEFBQcwAYYXaHR0cDovL29jc3AuZ29kYWRkeS5jb20wRgYDVR0f
55
+ BD8wPTA7oDmgN4Y1aHR0cDovL2NlcnRpZmljYXRlcy5nb2RhZGR5LmNvbS9yZXBv
56
+ c2l0b3J5L2dkcm9vdC5jcmwwSwYDVR0gBEQwQjBABgRVHSAAMDgwNgYIKwYBBQUH
57
+ AgEWKmh0dHA6Ly9jZXJ0aWZpY2F0ZXMuZ29kYWRkeS5jb20vcmVwb3NpdG9yeTAO
58
+ BgNVHQ8BAf8EBAMCAQYwDQYJKoZIhvcNAQEFBQADggEBANKGwOy9+aG2Z+5mC6IG
59
+ OgRQjhVyrEp0lVPLN8tESe8HkGsz2ZbwlFalEzAFPIUyIXvJxwqoJKSQ3kbTJSMU
60
+ A2fCENZvD117esyfxVgqwcSeIaha86ykRvOe5GPLL5CkKSkB2XIsKd83ASe8T+5o
61
+ 0yGPwLPk9Qnt0hCqU7S+8MxZC9Y7lhyVJEnfzuz9p0iRFEUOOjZv2kWzRaJBydTX
62
+ RE4+uXR21aITVSzGh6O1mawGhId/dQb8vxRMDsxuxN89txJx9OjxUUAiKEngHUuH
63
+ qDTMBqLdElrRhjZkAzVvb3du6/KFUJheqwNTrZEjYx8WnM25sgVjOuH0aBsXBTWV
64
+ U+4=
65
+ -----END CERTIFICATE-----
66
+ 2 s:/C=US/O=The Go Daddy Group, Inc./OU=Go Daddy Class 2 Certification Authority
67
+ i:/L=ValiCert Validation Network/O=ValiCert, Inc./OU=ValiCert Class 2 Policy Validation Authority/CN=http://www.valicert.com//emailAddress=info@valicert.com
68
+ -----BEGIN CERTIFICATE-----
69
+ MIIE+zCCBGSgAwIBAgICAQ0wDQYJKoZIhvcNAQEFBQAwgbsxJDAiBgNVBAcTG1Zh
70
+ bGlDZXJ0IFZhbGlkYXRpb24gTmV0d29yazEXMBUGA1UEChMOVmFsaUNlcnQsIElu
71
+ Yy4xNTAzBgNVBAsTLFZhbGlDZXJ0IENsYXNzIDIgUG9saWN5IFZhbGlkYXRpb24g
72
+ QXV0aG9yaXR5MSEwHwYDVQQDExhodHRwOi8vd3d3LnZhbGljZXJ0LmNvbS8xIDAe
73
+ BgkqhkiG9w0BCQEWEWluZm9AdmFsaWNlcnQuY29tMB4XDTA0MDYyOTE3MDYyMFoX
74
+ DTI0MDYyOTE3MDYyMFowYzELMAkGA1UEBhMCVVMxITAfBgNVBAoTGFRoZSBHbyBE
75
+ YWRkeSBHcm91cCwgSW5jLjExMC8GA1UECxMoR28gRGFkZHkgQ2xhc3MgMiBDZXJ0
76
+ aWZpY2F0aW9uIEF1dGhvcml0eTCCASAwDQYJKoZIhvcNAQEBBQADggENADCCAQgC
77
+ ggEBAN6d1+pXGEmhW+vXX0iG6r7d/+TvZxz0ZWizV3GgXne77ZtJ6XCAPVYYYwhv
78
+ 2vLM0D9/AlQiVBDYsoHUwHU9S3/Hd8M+eKsaA7Ugay9qK7HFiH7Eux6wwdhFJ2+q
79
+ N1j3hybX2C32qRe3H3I2TqYXP2WYktsqbl2i/ojgC95/5Y0V4evLOtXiEqITLdiO
80
+ r18SPaAIBQi2XKVlOARFmR6jYGB0xUGlcmIbYsUfb18aQr4CUWWoriMYavx4A6lN
81
+ f4DD+qta/KFApMoZFv6yyO9ecw3ud72a9nmYvLEHZ6IVDd2gWMZEewo+YihfukEH
82
+ U1jPEX44dMX4/7VpkI+EdOqXG68CAQOjggHhMIIB3TAdBgNVHQ4EFgQU0sSw0pHU
83
+ TBFxs2HLPaH+3ahq1OMwgdIGA1UdIwSByjCBx6GBwaSBvjCBuzEkMCIGA1UEBxMb
84
+ VmFsaUNlcnQgVmFsaWRhdGlvbiBOZXR3b3JrMRcwFQYDVQQKEw5WYWxpQ2VydCwg
85
+ SW5jLjE1MDMGA1UECxMsVmFsaUNlcnQgQ2xhc3MgMiBQb2xpY3kgVmFsaWRhdGlv
86
+ biBBdXRob3JpdHkxITAfBgNVBAMTGGh0dHA6Ly93d3cudmFsaWNlcnQuY29tLzEg
87
+ MB4GCSqGSIb3DQEJARYRaW5mb0B2YWxpY2VydC5jb22CAQEwDwYDVR0TAQH/BAUw
88
+ AwEB/zAzBggrBgEFBQcBAQQnMCUwIwYIKwYBBQUHMAGGF2h0dHA6Ly9vY3NwLmdv
89
+ ZGFkZHkuY29tMEQGA1UdHwQ9MDswOaA3oDWGM2h0dHA6Ly9jZXJ0aWZpY2F0ZXMu
90
+ Z29kYWRkeS5jb20vcmVwb3NpdG9yeS9yb290LmNybDBLBgNVHSAERDBCMEAGBFUd
91
+ IAAwODA2BggrBgEFBQcCARYqaHR0cDovL2NlcnRpZmljYXRlcy5nb2RhZGR5LmNv
92
+ bS9yZXBvc2l0b3J5MA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQUFAAOBgQC1
93
+ QPmnHfbq/qQaQlpE9xXUhUaJwL6e4+PrxeNYiY+Sn1eocSxI0YGyeR+sBjUZsE4O
94
+ WBsUs5iB0QQeyAfJg594RAoYC5jcdnplDQ1tgMQLARzLrUc+cb53S8wGd9D0Vmsf
95
+ SxOaFIqII6hR8INMqzW/Rn453HWkrugp++85j09VZw==
96
+ -----END CERTIFICATE-----
97
+ 3 s:/L=ValiCert Validation Network/O=ValiCert, Inc./OU=ValiCert Class 2 Policy Validation Authority/CN=http://www.valicert.com//emailAddress=info@valicert.com
98
+ i:/L=ValiCert Validation Network/O=ValiCert, Inc./OU=ValiCert Class 2 Policy Validation Authority/CN=http://www.valicert.com//emailAddress=info@valicert.com
99
+ -----BEGIN CERTIFICATE-----
100
+ MIIC5zCCAlACAQEwDQYJKoZIhvcNAQEFBQAwgbsxJDAiBgNVBAcTG1ZhbGlDZXJ0
101
+ IFZhbGlkYXRpb24gTmV0d29yazEXMBUGA1UEChMOVmFsaUNlcnQsIEluYy4xNTAz
102
+ BgNVBAsTLFZhbGlDZXJ0IENsYXNzIDIgUG9saWN5IFZhbGlkYXRpb24gQXV0aG9y
103
+ aXR5MSEwHwYDVQQDExhodHRwOi8vd3d3LnZhbGljZXJ0LmNvbS8xIDAeBgkqhkiG
104
+ 9w0BCQEWEWluZm9AdmFsaWNlcnQuY29tMB4XDTk5MDYyNjAwMTk1NFoXDTE5MDYy
105
+ NjAwMTk1NFowgbsxJDAiBgNVBAcTG1ZhbGlDZXJ0IFZhbGlkYXRpb24gTmV0d29y
106
+ azEXMBUGA1UEChMOVmFsaUNlcnQsIEluYy4xNTAzBgNVBAsTLFZhbGlDZXJ0IENs
107
+ YXNzIDIgUG9saWN5IFZhbGlkYXRpb24gQXV0aG9yaXR5MSEwHwYDVQQDExhodHRw
108
+ Oi8vd3d3LnZhbGljZXJ0LmNvbS8xIDAeBgkqhkiG9w0BCQEWEWluZm9AdmFsaWNl
109
+ cnQuY29tMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDOOnHK5avIWZJV16vY
110
+ dA757tn2VUdZZUcOBVXc65g2PFxTXdMwzzjsvUGJ7SVCCSRrCl6zfN1SLUzm1NZ9
111
+ WlmpZdRJEy0kTRxQb7XBhVQ7/nHk01xC+YDgkRoKWzk2Z/M/VXwbP7RfZHM047QS
112
+ v4dk+NoS/zcnwbNDu+97bi5p9wIDAQABMA0GCSqGSIb3DQEBBQUAA4GBADt/UG9v
113
+ UJSZSWI4OB9L+KXIPqeCgfYrx+jFzug6EILLGACOTb2oWH+heQC1u+mNr0HZDzTu
114
+ IYEZoDJJKPTEjlbVUjP9UNV+mWwD5MlM/Mtsq2azSiGM5bUMMj4QssxsodyamEwC
115
+ W/POuZ6lcg5Ktz885hZo+L7tdEy8W9ViH0Pd
116
+ -----END CERTIFICATE-----
@@ -0,0 +1,255 @@
1
+ require 'gist_store/net_http_ext'
2
+ require 'open-uri'
3
+ require 'net/https'
4
+ require 'optparse'
5
+ require 'json'
6
+ require 'base64'
7
+
8
+
9
+
10
+ # You can use this class from other scripts with the greatest of
11
+ # ease.
12
+ #
13
+ # >> Gist.read(gist_id)
14
+ # Returns the body of gist_id as a string.
15
+ #
16
+ # >> Gist.write(content)
17
+ # Creates a gist from the string `content`. Returns the URL of the
18
+ # new gist.
19
+ #
20
+ # >> Gist.copy(string)
21
+ # Copies string to the clipboard.
22
+ #
23
+ # >> Gist.browse(url)
24
+ # Opens URL in your default browser.
25
+ module Gist
26
+ extend self
27
+
28
+ GIST_URL = 'https://api.github.com/gists/%s'
29
+ CREATE_URL = 'https://api.github.com/gists'
30
+
31
+ if ENV['HTTPS_PROXY']
32
+ PROXY = URI(ENV['HTTPS_PROXY'])
33
+ elsif ENV['HTTP_PROXY']
34
+ PROXY = URI(ENV['HTTP_PROXY'])
35
+ else
36
+ PROXY = nil
37
+ end
38
+ PROXY_HOST = PROXY ? PROXY.host : nil
39
+ PROXY_PORT = PROXY ? PROXY.port : nil
40
+
41
+
42
+ # Create a gist on gist.github.com
43
+ def write(files, private_gist = false, description = nil)
44
+ url = URI.parse(CREATE_URL)
45
+
46
+ if PROXY_HOST
47
+ proxy = Net::HTTP::Proxy(PROXY_HOST, PROXY_PORT)
48
+ http = proxy.new(url.host, url.port)
49
+ else
50
+ http = Net::HTTP.new(url.host, url.port)
51
+ end
52
+
53
+ http.use_ssl = true
54
+ http.verify_mode = OpenSSL::SSL::VERIFY_PEER
55
+ http.ca_file = ca_cert
56
+
57
+ req = Net::HTTP::Post.new(url.path)
58
+ req.body = JSON.generate(data(files, private_gist, description))
59
+
60
+ user, password = auth()
61
+ if user && password
62
+ req.basic_auth(user, password)
63
+ end
64
+
65
+ response = http.start{|h| h.request(req) }
66
+ case response
67
+ when Net::HTTPCreated
68
+ JSON.parse(response.body)['html_url']
69
+ else
70
+ raise "Creating gist failed: #{response.code} #{response.message}"
71
+ end
72
+ end
73
+
74
+ # Create a gist on gist.github.com
75
+ def update(id, files)
76
+ url = URI.parse(CREATE_URL)
77
+
78
+ if PROXY_HOST
79
+ proxy = Net::HTTP::Proxy(PROXY_HOST, PROXY_PORT)
80
+ http = proxy.new(url.host, url.port)
81
+ else
82
+ http = Net::HTTP.new(url.host, url.port)
83
+ end
84
+
85
+ http.use_ssl = true
86
+ http.verify_mode = OpenSSL::SSL::VERIFY_PEER
87
+ http.ca_file = ca_cert
88
+
89
+ req = Net::HTTP::Patch.new(GIST_URL % id)
90
+ req.body = JSON.generate(data(files, nil, nil))
91
+
92
+ user, password = auth()
93
+ if user && password
94
+ req.basic_auth(user, password)
95
+ end
96
+
97
+ response = http.start{|h| h.request(req) }
98
+ case response
99
+ when Net::HTTPOK
100
+ JSON.parse(response.body)['html_url']
101
+ else
102
+ raise "Updating gist failed: #{response.code} #{response.message}"
103
+ end
104
+ end
105
+
106
+
107
+
108
+ # Create a gist on gist.github.com
109
+ def delete(id)
110
+ url = URI.parse(CREATE_URL)
111
+
112
+ if PROXY_HOST
113
+ proxy = Net::HTTP::Proxy(PROXY_HOST, PROXY_PORT)
114
+ http = proxy.new(url.host, url.port)
115
+ else
116
+ http = Net::HTTP.new(url.host, url.port)
117
+ end
118
+
119
+ http.use_ssl = true
120
+ http.verify_mode = OpenSSL::SSL::VERIFY_PEER
121
+ http.ca_file = ca_cert
122
+
123
+ req = Net::HTTP::Delete.new(GIST_URL % id)
124
+
125
+ user, password = auth()
126
+ if user && password
127
+ req.basic_auth(user, password)
128
+ end
129
+
130
+ response = http.start{|h| h.request(req) }
131
+ case response
132
+ when Net::HTTPNoContent
133
+ true
134
+ else
135
+ raise "Creating gist failed: #{response.code} #{response.message}"
136
+ end
137
+ end
138
+
139
+ # Given a gist id, returns its content.
140
+ def read(gist_id)
141
+ data = read_raw(gist_id)
142
+ data["files"].map{|name, content| content['content'] }.join("\n\n")
143
+ end
144
+
145
+ def read_raw(gist_id)
146
+ data = JSON.parse(open(GIST_URL % gist_id).read)
147
+ end
148
+
149
+
150
+ private
151
+ # Give an array of file information and private boolean, returns
152
+ # an appropriate payload for POSTing to gist.github.com
153
+ def data(files, private_gist, description)
154
+ i = 0
155
+ file_data = {}
156
+ files.each do |file|
157
+ i = i + 1
158
+ filename = file[:filename] ? file[:filename] : "gistfile#{i}"
159
+ file_data[filename] = {:content => file[:input]}
160
+ end
161
+
162
+ data = {"files" => file_data}
163
+ data.merge!({ 'description' => description }) unless description.nil?
164
+ data.merge!({ 'public' => !private_gist }) unless private_gist.nil?
165
+ data
166
+ end
167
+
168
+ # Returns a basic auth string of the user's GitHub credentials if set.
169
+ # http://github.com/guides/local-github-config
170
+ #
171
+ # Returns an Array of Strings if auth is found: [user, password]
172
+ # Returns nil if no auth is found.
173
+ def auth
174
+ user = config("github.user")
175
+ password = config("github.password")
176
+
177
+ token = config("github.token")
178
+ if password.to_s.empty? && !token.to_s.empty?
179
+ raise "Please set GITHUB_PASSWORD or github.password instead of using a token."
180
+ end
181
+
182
+ if user.to_s.empty? || password.to_s.empty?
183
+ nil
184
+ else
185
+ [ user, password ]
186
+ end
187
+ end
188
+
189
+ # Returns default values based on settings in your gitconfig. See
190
+ # git-config(1) for more information.
191
+ #
192
+ # Settings applicable to gist.rb are:
193
+ #
194
+ # gist.private - boolean
195
+ # gist.extension - string
196
+ def defaults
197
+ extension = config("gist.extension")
198
+
199
+ return {
200
+ "private" => config("gist.private"),
201
+ "browse" => config("gist.browse"),
202
+ "extension" => extension
203
+ }
204
+ end
205
+
206
+ # Reads a config value using:
207
+ # => Environment: GITHUB_PASSWORD, GITHUB_USER
208
+ # like vim gist plugin
209
+ # => git-config(1)
210
+ #
211
+ # return something useful or nil
212
+ def config(key)
213
+ env_key = ENV[key.upcase.gsub(/\./, '_')]
214
+ return env_key if env_key and not env_key.strip.empty?
215
+
216
+ str_to_bool `git config --global #{key}`.strip
217
+ end
218
+
219
+ # Parses a value that might appear in a .gitconfig file into
220
+ # something useful in a Ruby script.
221
+ def str_to_bool(str)
222
+ if str.size > 0 and str[0].chr == '!'
223
+ command = str[1, str.length]
224
+ value = `#{command}`
225
+ else
226
+ value = str
227
+ end
228
+
229
+ case value.downcase.strip
230
+ when "false", "0", "nil", "", "no", "off"
231
+ nil
232
+ when "true", "1", "yes", "on"
233
+ true
234
+ else
235
+ value
236
+ end
237
+ end
238
+
239
+ def ca_cert
240
+ cert_file = [
241
+ File.expand_path("../cacert.pem", __FILE__),
242
+ "/tmp/gist_cacert.pem"
243
+ ].find{|l| File.exist?(l) }
244
+
245
+ if cert_file
246
+ cert_file
247
+ else
248
+ File.open("/tmp/gist_cacert.pem", "w") do |f|
249
+ f.write(DATA.read.split("__CACERT__").last)
250
+ end
251
+ "/tmp/gist_cacert.pem"
252
+ end
253
+ end
254
+
255
+ end