growl-atom 0.0.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/bin/growl-atom ADDED
@@ -0,0 +1,92 @@
1
+ #!/usr/bin/ruby
2
+
3
+ # == Synopsis
4
+ #
5
+ # Makes growl notifications from new Atom entries.
6
+ #
7
+ # == Usage
8
+ #
9
+ # growl-atom [COMMAND]
10
+ #
11
+ # help:
12
+ # Show this help page
13
+ #
14
+ # check:
15
+ # Check the current feeds defined in the current user's config file, found at
16
+ # ~/.growl-atom/config This command is run from the LaunchAgent setup by the install command
17
+ #
18
+ # install:
19
+ # Install this for the current user, installs an OS X LaunchAgent (daemon process) for
20
+ # the current user and creates an empty config file in ~/.growl-atom/config
21
+ #
22
+ # uninstall:
23
+ # Uninstall the LaunchAgent for the current user, also delete all config and cache
24
+ # files under ~/.growl-atom/
25
+ #
26
+ # clear-caches:
27
+ # Clear all cache files for the current user. Cache files stop notifications being repeated.
28
+ # Atom entry IDs are stored in them once a notification has been shown. They can be found in
29
+ # ~/.growl-atom/caches/
30
+ #
31
+
32
+ $:.push(File.dirname(__FILE__) + "/../lib")
33
+ require 'rubygems'
34
+ require 'growl-atom'
35
+ require 'rdoc/usage'
36
+
37
+ user_dir = File.expand_path('~')
38
+ gem_dir = GrowlAtom.gem_dir
39
+ launch_agent = "growl.atom"
40
+ launch_agent_plist = launch_agent + ".plist"
41
+ launch_agents_dir = user_dir + "/Library/LaunchAgents/"
42
+
43
+ case ARGV[0]
44
+ when 'check'
45
+
46
+ GrowlAtom.check(File.join(user_dir, '.growl-atom'))
47
+ exit
48
+
49
+ when 'install'
50
+
51
+ # Create user config dir
52
+ system 'mkdir -p ' + File.join(user_dir, '.growl-atom/caches')
53
+ system "cp -i #{File.join(gem_dir, 'config')} #{File.join(user_dir, '.growl-atom/config')}"
54
+ system "cp -ri #{File.join(gem_dir, 'icons')} #{File.join(user_dir, '.growl-atom/icons')}"
55
+
56
+ # Create Launch Agent dir
57
+ if (!File.directory?(launch_agents_dir))
58
+ system "mkdir #{launch_agents_dir}"
59
+ end
60
+
61
+ # Install and start launch agent
62
+ system "sed -e 's/@USER.HOME@/#{user_dir.gsub(/\//, '\/')}/g' #{File.join(gem_dir, launch_agent_plist)} > #{launch_agents_dir + launch_agent_plist}"
63
+ system "launchctl load #{launch_agents_dir + launch_agent_plist}"
64
+ system "launchctl start #{launch_agent}"
65
+ exit
66
+
67
+ when 'uninstall'
68
+
69
+ puts("Are you sure you want to uninstall? This will delete your config file. (y/n)")
70
+ input=STDIN.gets
71
+
72
+ if (input.chomp.downcase != 'y' )
73
+ puts "Uninstall aborted"
74
+ exit
75
+ end
76
+
77
+ # Remove Launch Agent
78
+ system "launchctl unload #{launch_agents_dir + launch_agent_plist}"
79
+ system "rm #{launch_agents_dir + launch_agent_plist}"
80
+ system 'rm -rdf ' + File.join(user_dir, '.growl-atom')
81
+ exit
82
+
83
+ when 'clear-caches'
84
+
85
+ system 'rm -rdf ' + File.join(user_dir, '.growl-atom/caches/*')
86
+ exit
87
+
88
+ else
89
+
90
+ RDoc::usage
91
+ exit
92
+ end
data/config ADDED
@@ -0,0 +1,41 @@
1
+ ---
2
+
3
+ # Example config for growl-atom, note this is a YAML file, see http://yaml.org/
4
+
5
+ # Available options:
6
+ #
7
+ # global:
8
+ # proxy_host: your.proxy
9
+ # proxy_port: 80
10
+ # proxy_user: username
11
+ # proxy_pass: password
12
+ #
13
+ # feeds:
14
+ # name: Growl Application Name
15
+ # url: http://your.feed.com
16
+ # auth_user: http_user
17
+ # auth_pass: http_pass
18
+ # cert: /path/to/your/client/cert.pem
19
+ # title: Name of Atom entry node to be used as notification title, default is title
20
+ # message: Name of Atom entry node to be used as notification message, default is summary
21
+ # image: /path/to/notification/icon.png
22
+ # sticky: true default is false
23
+ #
24
+
25
+ # Global configs
26
+ #
27
+ # These config options can be overwritten on a per feed basis
28
+
29
+ global:
30
+
31
+
32
+ feeds:
33
+ - name: Gmail
34
+ url: https://mail.google.com/mail/feed/atom/
35
+ auth_user: your_gmail_username
36
+ auth_pass: your_gmail_password
37
+ image: ~/.growl-atom/icons/gmail.png
38
+ title: author/email
39
+ message: title
40
+ sticky: false
41
+
data/growl.atom.plist ADDED
@@ -0,0 +1,22 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3
+ <plist version="1.0">
4
+ <dict>
5
+ <key>Label</key>
6
+ <string>growl.atom</string>
7
+ <key>ProgramArguments</key>
8
+ <array>
9
+ <string>growl-atom</string>
10
+ <string>check</string>
11
+ </array>
12
+ <key>StartInterval</key>
13
+ <integer>90</integer>
14
+ <key>EnvironmentVariables</key>
15
+ <dict>
16
+ <key>PATH</key>
17
+ <string>/usr/bin:/usr/local/bin:/bin</string>
18
+ <key>HOME</key>
19
+ <string>@USER.HOME@</string>
20
+ </dict>
21
+ </dict>
22
+ </plist>
data/icons/gmail.png ADDED
Binary file
data/lib/growl-atom.rb ADDED
@@ -0,0 +1,117 @@
1
+ require 'rubygems'
2
+ gem 'growl', '=1.0.3'
3
+ require 'growl'
4
+ require 'yaml'
5
+ require 'digest/md5'
6
+ require 'uri'
7
+ require 'net/http'
8
+ require 'net/https'
9
+ require 'rexml/document'
10
+
11
+ module GrowlAtom
12
+
13
+ VERSION = "0.0.4"
14
+
15
+ class Error < StandardError; end
16
+
17
+ # The Installation directory of this gem package
18
+ def GrowlAtom.gem_dir
19
+ File.expand_path(File.join(File.dirname(__FILE__), '..'))
20
+ end
21
+
22
+ # Check all URLs in this config file
23
+ def GrowlAtom.check(config_dir)
24
+
25
+ default_options = {
26
+ :name => 'growl-atom',
27
+ :title => 'title',
28
+ :message => 'summary',
29
+ :sticky => false
30
+ }
31
+
32
+ config = YAML.load_file(File.join(config_dir, 'config'))
33
+ cache_dir = File.join(config_dir, 'caches')
34
+
35
+ config['feeds'].each {|feed|
36
+ options = feed
37
+ options = default_options.merge(config['global']).merge(feed) if config['global']
38
+ self.parse_feed(self.get_feed(options), options, cache_dir)
39
+ }
40
+
41
+ end
42
+
43
+ # Download feed respecting any http proxy, auth type stuff set in options
44
+ def GrowlAtom.get_feed(options)
45
+
46
+ raise Error, "No url set for feed" unless options['url'] != nil
47
+
48
+ uri = URI.parse(options['url'])
49
+
50
+ http = Net::HTTP::Proxy(options['proxy_host'], options['proxy_port'],
51
+ options['proxy_user'], options['proxy_pass']).new(uri.host, uri.port)
52
+
53
+ req = Net::HTTP::Get.new(uri.path)
54
+
55
+ if (uri.scheme == 'https')
56
+ http.use_ssl = true
57
+ http.verify_mode = OpenSSL::SSL::VERIFY_NONE
58
+ end
59
+
60
+ if (options['auth_user'] && options['auth_pass'])
61
+ req.basic_auth options['auth_user'], options['auth_pass']
62
+ end
63
+
64
+ if (options['cert'])
65
+ File.open(File.expand_path(options['cert'])) do |cert_file|
66
+ key_data = cert_file.read
67
+ http.cert = OpenSSL::X509::Certificate.new(key_data)
68
+ http.key = OpenSSL::PKey::RSA.new(key_data, nil)
69
+ end
70
+ end
71
+
72
+ response = http.request(req)
73
+
74
+ if (!response.kind_of?(Net::HTTPClientError) && !response.kind_of?(Net::HTTPServerError))
75
+ return response.body
76
+ end
77
+
78
+ raise Error, "#{response.code} Error in HTTP Response for #{options['url']}"
79
+
80
+ end
81
+
82
+ # Parse feed xml
83
+ def GrowlAtom.parse_feed(feed_xml, options, cache_dir)
84
+
85
+ cache_file = File.join(cache_dir, Digest::MD5.hexdigest(options['url']))
86
+ system("touch #{cache_file}")
87
+
88
+ include REXML
89
+
90
+ doc = Document.new feed_xml
91
+ doc.elements.each('//entry') {|entry|
92
+
93
+ id = entry.elements['id'].text
94
+
95
+ if (!system("grep #{id} #{cache_file} > /dev/null"))
96
+
97
+ growl_options = {}
98
+
99
+ growl_options['name'] = options['name']
100
+ growl_options['sticky'] = options['sticky']
101
+ growl_options['title'] = entry.elements[options['title']].text
102
+ growl_options['message'] = entry.elements[options['message']].text
103
+
104
+ growl_options['image'] = File.expand_path(options['image']) unless(options['image'] == nil)
105
+
106
+ Growl.notify(growl_options['message'], growl_options)
107
+
108
+ system("echo #{id} >> #{cache_file}")
109
+ system("tail -n 500 #{cache_file} > #{cache_file}.tmp")
110
+ system("mv #{cache_file}.tmp #{cache_file}")
111
+
112
+ end
113
+
114
+ }
115
+ end
116
+
117
+ end
metadata ADDED
@@ -0,0 +1,67 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: growl-atom
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.5
5
+ platform: ruby
6
+ authors:
7
+ - Matt Haynes
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2009-10-18 00:00:00 +01:00
13
+ default_executable:
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: growl
17
+ type: :runtime
18
+ version_requirement:
19
+ version_requirements: !ruby/object:Gem::Requirement
20
+ requirements:
21
+ - - "="
22
+ - !ruby/object:Gem::Version
23
+ version: 1.0.3
24
+ version:
25
+ description:
26
+ email: matt@matthaynes.net
27
+ executables:
28
+ - growl-atom
29
+ extensions: []
30
+
31
+ extra_rdoc_files: []
32
+
33
+ files:
34
+ - config
35
+ - growl.atom.plist
36
+ - lib/growl-atom.rb
37
+ - icons/gmail.png
38
+ has_rdoc: true
39
+ homepage: http://github.com/matth/growl-atom/tree/master
40
+ licenses: []
41
+
42
+ post_install_message:
43
+ rdoc_options: []
44
+
45
+ require_paths:
46
+ - lib
47
+ required_ruby_version: !ruby/object:Gem::Requirement
48
+ requirements:
49
+ - - ">="
50
+ - !ruby/object:Gem::Version
51
+ version: "0"
52
+ version:
53
+ required_rubygems_version: !ruby/object:Gem::Requirement
54
+ requirements:
55
+ - - ">="
56
+ - !ruby/object:Gem::Version
57
+ version: "0"
58
+ version:
59
+ requirements: []
60
+
61
+ rubyforge_project:
62
+ rubygems_version: 1.3.5
63
+ signing_key:
64
+ specification_version: 3
65
+ summary: Creates growl notifications for Atom entries
66
+ test_files: []
67
+