gridcli 0.0.5 → 0.0.6
Sign up to get free protection for your applications and to get access to all the features.
- data/README.rdoc +39 -3
- data/gridcli.gemspec +1 -0
- data/lib/gridcli/commands/base.rb +21 -0
- data/lib/gridcli/commands/dislike.rb +2 -1
- data/lib/gridcli/commands/friends.rb +1 -1
- data/lib/gridcli/commands/help.rb +1 -1
- data/lib/gridcli/commands/like.rb +2 -1
- data/lib/gridcli/commands/list.rb +2 -1
- data/lib/gridcli/commands/message.rb +19 -8
- data/lib/gridcli/commands/plugin.rb +28 -0
- data/lib/gridcli/commands/pprint.rb +3 -5
- data/lib/gridcli/commands/profile.rb +13 -1
- data/lib/gridcli/commands/search.rb +2 -1
- data/lib/gridcli/commands/signup.rb +2 -0
- data/lib/gridcli/commands/status.rb +3 -2
- data/lib/gridcli/commands/subgrid.rb +30 -0
- data/lib/gridcli/commands/update.rb +7 -5
- data/lib/gridcli/config.rb +2 -18
- data/lib/gridcli/hooks.rb +15 -0
- data/lib/gridcli/plugins.rb +39 -0
- data/lib/gridcli/pprinter.rb +117 -30
- data/lib/gridcli/resources/post.rb +26 -4
- data/lib/gridcli/resources/user.rb +4 -0
- data/lib/gridcli/stats.rb +13 -0
- data/lib/gridcli/storage/base.rb +2 -2
- data/lib/gridcli/storage/files.rb +6 -4
- data/lib/gridcli/subgrids.rb +35 -0
- data/lib/gridcli/version.rb +1 -1
- data/lib/gridcli/ymlhash.rb +28 -0
- data/lib/gridcli.rb +32 -12
- metadata +33 -11
- data/TODO +0 -13
data/README.rdoc
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
= gridcli -- A command line interface to The Grid
|
2
2
|
|
3
|
-
The Grid is a command line social network that is
|
3
|
+
The Grid is a command line social network that is fast, modular, and simple.
|
4
4
|
|
5
5
|
To install:
|
6
6
|
gem install gridcli
|
@@ -14,7 +14,9 @@ To show your profile:
|
|
14
14
|
grid profile
|
15
15
|
|
16
16
|
To update your profile:
|
17
|
-
grid profile [--github-username <username>] [--name <name>]
|
17
|
+
grid profile [--github-username <username>] [--name <name>] [--avatar <avatar text file>]
|
18
|
+
|
19
|
+
If you want a profile pic, use a program like jp2a to convert a jpeg image to ascii format first.
|
18
20
|
|
19
21
|
To show someone else's profile:
|
20
22
|
grid profile <username>
|
@@ -28,7 +30,7 @@ To list your friends:
|
|
28
30
|
|
29
31
|
== Messaging
|
30
32
|
To send a message to a list of users:
|
31
|
-
grid message <username>[,<username>,...] [<subject>] <body>
|
33
|
+
grid message <username>[,<username>,...] [-s <subject>] [-b <body>] [-f <body file>]
|
32
34
|
|
33
35
|
To send a status update, like, or dislike to your friends:
|
34
36
|
grid status <status message>
|
@@ -49,6 +51,9 @@ The <when> parameter is free form text and can be a range ("x to y"). For insta
|
|
49
51
|
grid search message "chronic" "two weeks ago to today"
|
50
52
|
grid search all "the grid" "1 month ago to last week"
|
51
53
|
|
54
|
+
You can see your messages in your ~/.grid directory. For instance, if you want to search all likes using grep:
|
55
|
+
grep -RiI ~/.grid/like "grid"
|
56
|
+
|
52
57
|
== Listing Posts
|
53
58
|
You can list any type (or all types) of posts.
|
54
59
|
grid list <like|dislike|message|status|all> [<when>]
|
@@ -65,6 +70,37 @@ To block another user:
|
|
65
70
|
|
66
71
|
This will "unfriend" them and they will no longer see your posts.
|
67
72
|
|
73
|
+
== Subgrids
|
74
|
+
Subgrids are groups that you manage and are defined in a local config file.
|
75
|
+
|
76
|
+
To create a subgrid, use:
|
77
|
+
grid subgrid @mygroup bob,john,snakeplisskin
|
78
|
+
|
79
|
+
To see what subgrids exist:
|
80
|
+
grid subgrid
|
81
|
+
|
82
|
+
To see what users are in a particular subgrid:
|
83
|
+
grid subgrid @mygroup
|
84
|
+
|
85
|
+
You can then use the group as though it were a user. For instance, to send a message to @mygroup:
|
86
|
+
grid message @mygroup -s "hey guys" -b "Let's go make a rum ham."
|
87
|
+
|
88
|
+
If you prefer to simply edit the config file, you can do so (the file is located at ~/.grid/subgrids).
|
89
|
+
|
90
|
+
== Plugins
|
91
|
+
Plugins are easy to create and can register hooks. To install/uninstall a plugin, use:
|
92
|
+
grid plugin install <name>
|
93
|
+
grid plugin uninstall <name>
|
94
|
+
|
95
|
+
To see a list of installed plugins:
|
96
|
+
grid plugin
|
68
97
|
|
98
|
+
An example plugin is the echo plugin:
|
99
|
+
grid plugin install echo
|
69
100
|
|
101
|
+
This command will install the gem "grid-plugin-echo" and load it each time the gridcli gem is loaded. It uses the available hooks:
|
102
|
+
* before_post_creation(post_hash)
|
103
|
+
* before_signup(username)
|
104
|
+
* before_update
|
70
105
|
|
106
|
+
and prints out a message whenever a user signs up, a post is created, or the update command is called. You can see the code for the echo module at https://github.com/bmuller/grid-plugin-echo.
|
data/gridcli.gemspec
CHANGED
@@ -15,6 +15,7 @@ Gem::Specification.new do |s|
|
|
15
15
|
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
16
16
|
s.require_paths = ["lib"]
|
17
17
|
s.add_dependency("activeresource", ">= 3.0.10")
|
18
|
+
s.add_dependency("activesupport", ">= 3.0.10")
|
18
19
|
s.add_dependency("chronic", ">= 0.6.4")
|
19
20
|
s.add_dependency("json", ">= 1.6.1")
|
20
21
|
s.add_dependency("colorize", ">= 0.5.8")
|
@@ -7,6 +7,7 @@ module GridCLI
|
|
7
7
|
|
8
8
|
def initialize(cmd, desc, default_opts = nil)
|
9
9
|
@config = GridCLI.config
|
10
|
+
@stats = GridCLI.stats
|
10
11
|
@cmd = cmd
|
11
12
|
@desc = desc
|
12
13
|
@opts = default_opts || {}
|
@@ -19,6 +20,21 @@ module GridCLI
|
|
19
20
|
@optp.on(*args) { |u| yield u }
|
20
21
|
end
|
21
22
|
|
23
|
+
def add_format_option
|
24
|
+
msg = "Specify output format (json, cmdcolor, cmd, textline)"
|
25
|
+
add_option("-o format", "--output-format format", msg) { |o|
|
26
|
+
@opts[:output_format] = o
|
27
|
+
}
|
28
|
+
end
|
29
|
+
|
30
|
+
def output_format
|
31
|
+
@opts[:output_format] || "cmdcolor"
|
32
|
+
end
|
33
|
+
|
34
|
+
def pprint(json)
|
35
|
+
puts PrettyPrinter.new(json, output_format)
|
36
|
+
end
|
37
|
+
|
22
38
|
def usage(cmd_opts=nil)
|
23
39
|
cmd_opts ||= ""
|
24
40
|
@optp.banner = "Usage: grid #{@cmd} #{cmd_opts} [options]"
|
@@ -26,6 +42,11 @@ module GridCLI
|
|
26
42
|
exit
|
27
43
|
end
|
28
44
|
|
45
|
+
def error(msg)
|
46
|
+
puts msg
|
47
|
+
exit 1
|
48
|
+
end
|
49
|
+
|
29
50
|
def parse_dates(datestring)
|
30
51
|
dates = [nil, nil]
|
31
52
|
return dates if datestring.nil? or datestring.strip == ""
|
@@ -2,6 +2,7 @@ module GridCLI
|
|
2
2
|
class DislikeCommand < BaseCommand
|
3
3
|
def initialize
|
4
4
|
super "dislike", "Dislike something."
|
5
|
+
add_format_option
|
5
6
|
end
|
6
7
|
|
7
8
|
def usage
|
@@ -21,7 +22,7 @@ module GridCLI
|
|
21
22
|
return
|
22
23
|
end
|
23
24
|
|
24
|
-
|
25
|
+
pprint post.to_post_json
|
25
26
|
end
|
26
27
|
end
|
27
28
|
|
@@ -17,7 +17,7 @@ module GridCLI
|
|
17
17
|
log "Getting all friends of '#{username}'"
|
18
18
|
friends = Friendship.find(:all, :params => { :id => username })
|
19
19
|
friends.each { |f|
|
20
|
-
|
20
|
+
pprint f.user.to_json
|
21
21
|
}
|
22
22
|
puts "You have no friends :(" if friends.length == 0
|
23
23
|
rescue ActiveResource::ForbiddenAccess
|
@@ -2,6 +2,7 @@ module GridCLI
|
|
2
2
|
class LikeCommand < BaseCommand
|
3
3
|
def initialize
|
4
4
|
super "like", "Like something."
|
5
|
+
add_format_option
|
5
6
|
end
|
6
7
|
|
7
8
|
def usage
|
@@ -21,7 +22,7 @@ module GridCLI
|
|
21
22
|
return
|
22
23
|
end
|
23
24
|
|
24
|
-
|
25
|
+
pprint post.to_post_json
|
25
26
|
end
|
26
27
|
end
|
27
28
|
|
@@ -2,6 +2,7 @@ module GridCLI
|
|
2
2
|
class ListCommand < BaseCommand
|
3
3
|
def initialize
|
4
4
|
super "list", "List posts of a particular kind or all posts"
|
5
|
+
add_format_option
|
5
6
|
end
|
6
7
|
|
7
8
|
def usage
|
@@ -16,7 +17,7 @@ module GridCLI
|
|
16
17
|
parse_opts args
|
17
18
|
|
18
19
|
log "Showing #{type} posts in range #{dates.first || 'first'} - #{dates.last || 'last'}"
|
19
|
-
GridCLI.storage.list(type, dates[0], dates[1])
|
20
|
+
GridCLI.storage.list(type, dates[0], dates[1], output_format)
|
20
21
|
end
|
21
22
|
end
|
22
23
|
|
@@ -1,24 +1,35 @@
|
|
1
|
+
require 'active_support/core_ext'
|
2
|
+
|
1
3
|
module GridCLI
|
2
4
|
class MessageCommand < BaseCommand
|
3
5
|
def initialize
|
4
6
|
super "message", "Send a message to a friend or group of friends."
|
7
|
+
add_option("-s subject", "--subject subject", "Subject for message") { |s| @opts[:subject] = s }
|
8
|
+
add_option("-f file", "--file file", "File to use for message body") { |f| @opts[:file] = f }
|
9
|
+
add_option("-b body", "--body body", "Message body") { |b| @opts[:body] = b }
|
10
|
+
add_format_option
|
5
11
|
end
|
6
12
|
|
7
13
|
def usage
|
8
|
-
super "<username>[,<username>,...]
|
14
|
+
super "<username>[,<username>,...]"
|
9
15
|
end
|
10
16
|
|
11
17
|
def run(args)
|
12
18
|
usage if args.length < 2
|
13
19
|
recipients = args.shift
|
14
|
-
if args.length > 1 and not args[1].start_with?('-')
|
15
|
-
subject = args.shift
|
16
|
-
else
|
17
|
-
subject = args.first.slice(0,30) + "..."
|
18
|
-
end
|
19
|
-
body = args.shift
|
20
20
|
parse_opts args
|
21
21
|
|
22
|
+
body = nil
|
23
|
+
if not @opts[:file].nil?
|
24
|
+
error("File '#{@opts[:file]}' does not exist.") unless File.exists? @opts[:file]
|
25
|
+
body = File.read(@opts[:file])
|
26
|
+
elsif not @opts[:body].nil?
|
27
|
+
body = @opts[:body]
|
28
|
+
end
|
29
|
+
|
30
|
+
error("Body cannot be blank. Use one of -f or -b") if body.nil?
|
31
|
+
subject = @opts[:subject].nil? ? body.truncate(30) : @opts[:subject]
|
32
|
+
|
22
33
|
begin
|
23
34
|
log "Trying to send a message '#{subject}' to '#{recipients}'"
|
24
35
|
post = Post::Message.create :subject => subject, :body => body, :recipients => recipients, :posttype => 'message'
|
@@ -27,7 +38,7 @@ module GridCLI
|
|
27
38
|
return
|
28
39
|
end
|
29
40
|
|
30
|
-
|
41
|
+
pprint post.to_post_json
|
31
42
|
end
|
32
43
|
end
|
33
44
|
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module GridCLI
|
2
|
+
class PluginCommand < BaseCommand
|
3
|
+
def initialize
|
4
|
+
super "plugin", "Install / uninstall plugins"
|
5
|
+
end
|
6
|
+
|
7
|
+
def usage
|
8
|
+
super "[<install|uninstall> <name>]"
|
9
|
+
end
|
10
|
+
|
11
|
+
def run(args)
|
12
|
+
if args.length == 0
|
13
|
+
puts "The following plugins are installed: "
|
14
|
+
puts GridCLI.plugins['enabled'].join(', ')
|
15
|
+
elsif args.length == 2 and args.first == "install"
|
16
|
+
log "Attempting to install gem grid-plugin-#{args[1]}"
|
17
|
+
GridCLI.plugins.install args[1]
|
18
|
+
elsif args.length == 2 and args.first == "uninstall"
|
19
|
+
log "Attempting to uninstall gem grid-plugin-#{args[1]}"
|
20
|
+
GridCLI.plugins.uninstall args[1]
|
21
|
+
else
|
22
|
+
usage
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
Runner.register "plugin", PluginCommand
|
28
|
+
end
|
@@ -2,16 +2,14 @@ module GridCLI
|
|
2
2
|
class PPrintCommand < BaseCommand
|
3
3
|
def initialize
|
4
4
|
super "pprint", "A program that will pretty print posts/users"
|
5
|
+
add_format_option
|
5
6
|
end
|
6
7
|
|
7
8
|
def run(args)
|
8
|
-
|
9
|
+
parse_opts args
|
9
10
|
|
10
11
|
ARGV.clear
|
11
|
-
ARGF.each { |line|
|
12
|
-
puts PrettyPrinter.new(line)
|
13
|
-
puts
|
14
|
-
}
|
12
|
+
ARGF.each { |line| pprint(line) }
|
15
13
|
end
|
16
14
|
end
|
17
15
|
|
@@ -10,6 +10,11 @@ module GridCLI
|
|
10
10
|
@opts[:name] = u
|
11
11
|
@opts[:update] = true
|
12
12
|
}
|
13
|
+
add_option("--avatar file", "Set your avatar (a text file)") { |u|
|
14
|
+
@opts[:avatar] = u
|
15
|
+
@opts[:update] = true
|
16
|
+
}
|
17
|
+
add_format_option
|
13
18
|
end
|
14
19
|
|
15
20
|
def usage
|
@@ -34,11 +39,18 @@ module GridCLI
|
|
34
39
|
# if we're supposed to update, do so
|
35
40
|
if @opts[:update]
|
36
41
|
[:github_username, :name].each { |n| user.send("#{n.to_s}=", @opts[n]) }
|
42
|
+
unless @opts[:avatar].nil?
|
43
|
+
if File.exists?(@opts[:avatar])
|
44
|
+
user.avatar = File.read(@opts[:avatar])
|
45
|
+
else
|
46
|
+
error("File #{@opts[:avatar]} does not exist")
|
47
|
+
end
|
48
|
+
end
|
37
49
|
user.id = username
|
38
50
|
user.save
|
39
51
|
end
|
40
52
|
|
41
|
-
|
53
|
+
pprint user.to_json
|
42
54
|
end
|
43
55
|
end
|
44
56
|
|
@@ -2,6 +2,7 @@ module GridCLI
|
|
2
2
|
class SearchCommand < BaseCommand
|
3
3
|
def initialize
|
4
4
|
super "search", "Search posts"
|
5
|
+
add_format_option
|
5
6
|
end
|
6
7
|
|
7
8
|
def usage
|
@@ -18,7 +19,7 @@ module GridCLI
|
|
18
19
|
parse_opts args
|
19
20
|
|
20
21
|
log "Showing #{type} posts in range #{dates.first || 'first'} - #{dates.last || 'last'}"
|
21
|
-
GridCLI.storage.search(type, query, dates[0], dates[1])
|
22
|
+
GridCLI.storage.search(type, query, dates[0], dates[1], output_format)
|
22
23
|
end
|
23
24
|
end
|
24
25
|
|
@@ -2,6 +2,7 @@ module GridCLI
|
|
2
2
|
class StatusCommand < BaseCommand
|
3
3
|
def initialize
|
4
4
|
super "status", "Send a status update to all friends."
|
5
|
+
add_format_option
|
5
6
|
end
|
6
7
|
|
7
8
|
def usage
|
@@ -20,8 +21,8 @@ module GridCLI
|
|
20
21
|
puts "There was an error sending your status. Please make sure it's not empty."
|
21
22
|
return
|
22
23
|
end
|
23
|
-
|
24
|
-
|
24
|
+
|
25
|
+
pprint post.to_post_json
|
25
26
|
end
|
26
27
|
end
|
27
28
|
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module GridCLI
|
2
|
+
class SubgridCommand < BaseCommand
|
3
|
+
def initialize
|
4
|
+
super "subgrid", "Create / read / update subgrids (groups)"
|
5
|
+
end
|
6
|
+
|
7
|
+
def usage
|
8
|
+
super "[<groupname> [<comma separated list of users>]]"
|
9
|
+
end
|
10
|
+
|
11
|
+
def run(args)
|
12
|
+
subgrids = SubGrids.new
|
13
|
+
|
14
|
+
groups = (args.length == 0) ? subgrids.groups : [args.shift]
|
15
|
+
|
16
|
+
# if setting users...
|
17
|
+
if args.length > 0
|
18
|
+
subgrids.set_group(groups.first, args.first.split(","))
|
19
|
+
end
|
20
|
+
|
21
|
+
groups.each { |gname|
|
22
|
+
error("Group not found: #{gname}") unless subgrids.groups.include? gname
|
23
|
+
puts "#{gname} has users: #{subgrids.get_group(gname).join(', ')}"
|
24
|
+
}
|
25
|
+
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
Runner.register "subgrid", SubgridCommand
|
30
|
+
end
|
@@ -2,11 +2,14 @@ module GridCLI
|
|
2
2
|
class UpdateCommand < BaseCommand
|
3
3
|
def initialize
|
4
4
|
super "update", "Download all messages"
|
5
|
+
add_format_option
|
5
6
|
end
|
6
7
|
|
7
8
|
def run(args)
|
8
9
|
parse_opts args
|
9
|
-
last_sha = @
|
10
|
+
last_sha = @stats['last_sha']
|
11
|
+
|
12
|
+
GridCLI.hooker.invoke :before_update
|
10
13
|
|
11
14
|
begin
|
12
15
|
if last_sha.nil?
|
@@ -32,11 +35,10 @@ module GridCLI
|
|
32
35
|
posts.each { |p|
|
33
36
|
type = p.known_attributes.first
|
34
37
|
json = p.send(type).to_json(:root => type)
|
35
|
-
|
36
|
-
puts
|
38
|
+
pprint json
|
37
39
|
}
|
38
|
-
@
|
39
|
-
@
|
40
|
+
@stats['last_sha'] = GridCLI.storage.append(posts)
|
41
|
+
@stats.save
|
40
42
|
|
41
43
|
# run again if we got back 300 posts
|
42
44
|
run(args) if posts.length == 300
|
data/lib/gridcli/config.rb
CHANGED
@@ -1,19 +1,7 @@
|
|
1
|
-
require 'yaml'
|
2
|
-
|
3
1
|
module GridCLI
|
4
|
-
class Config <
|
2
|
+
class Config < YMLHash
|
5
3
|
def initialize
|
6
|
-
|
7
|
-
@griddir = File.expand_path(File.join("~", ".grid"))
|
8
|
-
Dir.mkdir(@griddir) if not File.exists?(@griddir)
|
9
|
-
|
10
|
-
# This is a hash, so initialize it, set w/ default config options, then set
|
11
|
-
# with any config options in the ~/.grid/config file
|
12
|
-
@conffile = File.join(@griddir, "config")
|
13
|
-
super
|
14
|
-
update default_config
|
15
|
-
# if conf file exists, update this obj w/ it's values. Otherwise, create file
|
16
|
-
File.exists?(@conffile) ? update(YAML.load_file(@conffile)) : save
|
4
|
+
super "config"
|
17
5
|
end
|
18
6
|
|
19
7
|
|
@@ -23,9 +11,5 @@ module GridCLI
|
|
23
11
|
'token' => rand(36**31).to_s(36)
|
24
12
|
}
|
25
13
|
end
|
26
|
-
|
27
|
-
def save
|
28
|
-
File.open(@conffile, 'w') { |f| YAML.dump(self, f) }
|
29
|
-
end
|
30
14
|
end
|
31
15
|
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module GridCLI
|
2
|
+
class Hooker
|
3
|
+
def initialize
|
4
|
+
@hooks = {}
|
5
|
+
end
|
6
|
+
|
7
|
+
def register(name, &method)
|
8
|
+
@hooks[name] = @hooks.fetch(name, []) + [method]
|
9
|
+
end
|
10
|
+
|
11
|
+
def invoke(name, arg=nil)
|
12
|
+
@hooks.fetch(name, []).inject(arg) { |params,proc| proc.call(params) }
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
require 'rubygems/gem_runner'
|
2
|
+
|
3
|
+
module GridCLI
|
4
|
+
class Plugins < YMLHash
|
5
|
+
def initialize
|
6
|
+
super "plugins"
|
7
|
+
end
|
8
|
+
|
9
|
+
def default_config
|
10
|
+
{
|
11
|
+
'enabled' => [],
|
12
|
+
'disabled' => []
|
13
|
+
}
|
14
|
+
end
|
15
|
+
|
16
|
+
def install(name)
|
17
|
+
name = "grid-plugin-#{name}" unless name.start_with?("grid-plugin-")
|
18
|
+
unless fetch('enabled', []).include? name
|
19
|
+
self['enabled'] << name
|
20
|
+
save
|
21
|
+
end
|
22
|
+
Gem::GemRunner.new.run ["install", name, "--no-rdoc", "--no-ri"]
|
23
|
+
end
|
24
|
+
|
25
|
+
def uninstall(name)
|
26
|
+
name = "grid-plugin-#{name}" unless name.start_with?("grid-plugin-")
|
27
|
+
return unless fetch('enabled', []).include? name
|
28
|
+
self['enabled'].delete(name)
|
29
|
+
save
|
30
|
+
Gem::GemRunner.new.run ["uninstall", name]
|
31
|
+
end
|
32
|
+
|
33
|
+
def include!
|
34
|
+
fetch('enabled', []).each { |m|
|
35
|
+
require m
|
36
|
+
}
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
data/lib/gridcli/pprinter.rb
CHANGED
@@ -2,47 +2,134 @@ require 'json'
|
|
2
2
|
require 'colorize'
|
3
3
|
|
4
4
|
module GridCLI
|
5
|
-
class
|
6
|
-
def
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
5
|
+
class PPTextLineFormat
|
6
|
+
def self.all(parsed)
|
7
|
+
parsed.map { |k,v| "#{k}: #{v}" }.join("; ")
|
8
|
+
end
|
9
|
+
|
10
|
+
def self.like(original, parsed)
|
11
|
+
self.all(parsed)
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.dislike(original, parsed)
|
15
|
+
self.all(parsed)
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.status(original, parsed)
|
19
|
+
self.all(parsed)
|
20
|
+
end
|
21
|
+
|
22
|
+
def self.message(original, parsed)
|
23
|
+
self.all(parsed)
|
24
|
+
end
|
25
|
+
|
26
|
+
def self.user(original, parsed)
|
27
|
+
self.all(parsed)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
class PPCmdFormat
|
32
|
+
def self.like(original, parsed)
|
33
|
+
"on #{@created_at} #{@contents['from_username']} liked #{@contents['body']}\n\n"
|
34
|
+
end
|
35
|
+
|
36
|
+
def self.dislike(original, parsed)
|
37
|
+
"on #{@created_at} #{@contents['from_username']} disliked #{@contents['body']}\n\n"
|
38
|
+
end
|
39
|
+
|
40
|
+
def self.status(original, parsed)
|
41
|
+
"on #{@created_at} #{@contents['from_username']} was #{@contents['body']}\n\n"
|
42
|
+
end
|
43
|
+
|
44
|
+
def self.message(original, parsed)
|
45
|
+
s = "Message from: #{parsed['from_username']}\n"
|
46
|
+
s+= "Subject: #{parsed['subject']}\n"
|
47
|
+
s+= "Date: #{parsed['created_at']}\n"
|
48
|
+
s+= "To: #{parsed['recipients']}\n"
|
49
|
+
s+= "#{parsed['body']}\n\n"
|
50
|
+
end
|
51
|
+
|
52
|
+
def self.user(original, parsed)
|
53
|
+
s = "#{parsed['username']}\n"
|
54
|
+
s+= "created: #{parsed['created_at']}\n"
|
55
|
+
(parsed.keys - ['created_at', 'username', 'avatar']).each { |key|
|
56
|
+
next if parsed[key].nil?
|
57
|
+
s += "#{key}: #{parsed[key]}\n"
|
58
|
+
}
|
59
|
+
s+= parsed['avatar'] unless parsed['avatar'].nil?
|
60
|
+
s += "\n"
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
class PPCmdColorFormat < PPCmdFormat
|
65
|
+
def self.like(original, parsed)
|
66
|
+
super(original, parsed).green
|
67
|
+
end
|
68
|
+
|
69
|
+
def self.dislike(original, parsed)
|
70
|
+
super(original, parsed).red
|
22
71
|
end
|
23
72
|
|
24
|
-
def
|
25
|
-
|
73
|
+
def self.status(original, parsed)
|
74
|
+
super(original, parsed).cyan
|
26
75
|
end
|
27
76
|
|
28
|
-
def
|
29
|
-
"
|
77
|
+
def self.message(original, parsed)
|
78
|
+
s = "Message from: ".cyan + parsed['from_username'] + "\n"
|
79
|
+
s+= "Subject: ".cyan + parsed['subject'] + "\n"
|
80
|
+
s+= "Date: ".cyan + parsed['created_at'] + "\n"
|
81
|
+
s+= "To: ".cyan + parsed['recipients'] + "\n"
|
82
|
+
s+= "#{parsed['body']}\n\n"
|
30
83
|
end
|
31
84
|
|
32
|
-
def
|
33
|
-
"
|
85
|
+
def self.user(original, parsed)
|
86
|
+
s = "username: ".magenta + "#{parsed['username']}\n".yellow
|
87
|
+
s+= "created: ".magenta + "#{parsed['created_at']}\n"
|
88
|
+
(parsed.keys - ['created_at', 'username', 'avatar']).each { |key|
|
89
|
+
next if parsed[key].nil?
|
90
|
+
s += "#{key}: ".magenta + "#{parsed[key]}\n"
|
91
|
+
}
|
92
|
+
s+= parsed['avatar'] unless parsed['avatar'].nil?
|
93
|
+
s += "\n"
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
|
98
|
+
class PrettyPrinter
|
99
|
+
# format can be one of :cmdcolor, :cmd, :textline, :json
|
100
|
+
def initialize(string, format=nil)
|
101
|
+
@format = format.nil? ? :cmdcolor : format.intern
|
102
|
+
@original = string
|
103
|
+
begin
|
104
|
+
j = JSON.parse(string)
|
105
|
+
@type = j.keys.first
|
106
|
+
@contents = j[@type]
|
107
|
+
@contents['created_at'] = Time.parse(@contents['created_at']).localtime.to_s
|
108
|
+
rescue JSON::ParserError
|
109
|
+
@type = nil
|
110
|
+
@format = nil
|
111
|
+
@contents = {}
|
112
|
+
end
|
34
113
|
end
|
35
114
|
|
36
|
-
def
|
37
|
-
|
38
|
-
s+= "Subject: ".cyan + @contents['subject'] + "\n"
|
39
|
-
s+= "Date: ".cyan + @created_at + "\n"
|
40
|
-
s+= "To: ".cyan + @contents['recipients'] + "\n"
|
41
|
-
s+= @contents['body']
|
115
|
+
def formatters
|
116
|
+
{ :cmdcolor => PPCmdColorFormat, :cmd => PPCmdFormat, :textline => PPTextLineFormat }
|
42
117
|
end
|
43
118
|
|
44
119
|
def to_s
|
45
|
-
@
|
120
|
+
formatter = formatters.fetch(@format, nil)
|
121
|
+
# if the format is unknown or :json return original
|
122
|
+
return @original if formatter.nil?
|
123
|
+
|
124
|
+
case @type
|
125
|
+
when "message" then formatter.message(@original, @contents)
|
126
|
+
when "like" then formatter.like(@original, @contents)
|
127
|
+
when "dislike" then formatter.dislike(@original, @contents)
|
128
|
+
when "status" then formatter.status(@original, @contents)
|
129
|
+
when "friend_request" then formatter.message(@original, @contents)
|
130
|
+
when "user" then formatter.user(@original, @contents)
|
131
|
+
else @original #unknown type
|
132
|
+
end
|
46
133
|
end
|
47
134
|
end
|
48
135
|
end
|
@@ -1,15 +1,37 @@
|
|
1
1
|
module GridCLI
|
2
2
|
module Post
|
3
|
-
|
3
|
+
|
4
|
+
class PostBase < BaseResource
|
5
|
+
# before we create, resolve names from subgrid and call hooks
|
6
|
+
def self.create(attributes)
|
7
|
+
subgrids = SubGrids.new
|
8
|
+
users = attributes[:recipients].split(",")
|
9
|
+
attributes[:recipients] = subgrids.resolve(users).join(",")
|
10
|
+
attributes = GridCLI.hooker.invoke :before_post_creation, attributes
|
11
|
+
super attributes
|
12
|
+
end
|
13
|
+
|
14
|
+
# if we just call post.to_json, the root attribute will be "post"
|
15
|
+
# for prettyprint, the root attribute needs to be one of: like,dislike,status,message
|
16
|
+
def to_post_json
|
17
|
+
type = self.class.name.split("::").last.downcase
|
18
|
+
to_json(:root => type)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
class Message < PostBase
|
4
23
|
self.element_name = "post"
|
5
24
|
end
|
6
|
-
|
25
|
+
|
26
|
+
class Like < PostBase
|
7
27
|
self.element_name = "post"
|
8
28
|
end
|
9
|
-
|
29
|
+
|
30
|
+
class Dislike < PostBase
|
10
31
|
self.element_name = "post"
|
11
32
|
end
|
12
|
-
|
33
|
+
|
34
|
+
class Status < PostBase
|
13
35
|
self.element_name = "post"
|
14
36
|
end
|
15
37
|
end
|
data/lib/gridcli/storage/base.rb
CHANGED
@@ -8,11 +8,11 @@ module GridCLI
|
|
8
8
|
raise "Not implemented"
|
9
9
|
end
|
10
10
|
|
11
|
-
def search(type, query, state_date, end_date)
|
11
|
+
def search(type, query, state_date, end_date, output_format)
|
12
12
|
raise "Not implemented"
|
13
13
|
end
|
14
14
|
|
15
|
-
def list(type, start_date, end_date)
|
15
|
+
def list(type, start_date, end_date, output_format)
|
16
16
|
raise "Not implemented"
|
17
17
|
end
|
18
18
|
end
|
@@ -83,15 +83,17 @@ module GridCLI
|
|
83
83
|
}
|
84
84
|
end
|
85
85
|
|
86
|
-
def search(type, query, start_date, end_date)
|
86
|
+
def search(type, query, start_date, end_date, output_format)
|
87
|
+
options = output_format.nil? ? "" : "-o #{output_format}"
|
87
88
|
files(type, start_date, end_date) { |path|
|
88
|
-
system "grep -R \"#{query}\" #{path} | #{$0} pprint"
|
89
|
+
system "grep -R \"#{query}\" #{path} | #{$0} pprint #{options}"
|
89
90
|
}
|
90
91
|
end
|
91
92
|
|
92
|
-
def list(type, start_date, end_date)
|
93
|
+
def list(type, start_date, end_date, output_format)
|
94
|
+
options = output_format.nil? ? "" : "-o #{output_format}"
|
93
95
|
files(type, start_date, end_date) { |path|
|
94
|
-
system "cat #{path} | #{$0} pprint"
|
96
|
+
system "cat #{path} | #{$0} pprint #{options}"
|
95
97
|
}
|
96
98
|
end
|
97
99
|
|
@@ -0,0 +1,35 @@
|
|
1
|
+
module GridCLI
|
2
|
+
class SubGrids < YMLHash
|
3
|
+
def initialize
|
4
|
+
super "subgrids"
|
5
|
+
end
|
6
|
+
|
7
|
+
def get_group(group, stack=nil)
|
8
|
+
stack ||= []
|
9
|
+
if stack.include? group
|
10
|
+
puts "Recursive subgrid definition detected."
|
11
|
+
exit 1
|
12
|
+
end
|
13
|
+
stack << group
|
14
|
+
|
15
|
+
fetch(group, "").split(" ").map { |user|
|
16
|
+
user.start_with?('@') ? get_group(user, stack) : user
|
17
|
+
}.flatten
|
18
|
+
end
|
19
|
+
|
20
|
+
def groups
|
21
|
+
keys
|
22
|
+
end
|
23
|
+
|
24
|
+
def set_group(name, members)
|
25
|
+
self[name] = members.join(" ")
|
26
|
+
save
|
27
|
+
end
|
28
|
+
|
29
|
+
def resolve(userlist)
|
30
|
+
userlist.map { |user|
|
31
|
+
user.start_with?('@') ? get_group(user) : user
|
32
|
+
}
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
data/lib/gridcli/version.rb
CHANGED
@@ -0,0 +1,28 @@
|
|
1
|
+
require 'yaml'
|
2
|
+
|
3
|
+
module GridCLI
|
4
|
+
class YMLHash < Hash
|
5
|
+
def initialize(fname)
|
6
|
+
# Initialize the grid dir
|
7
|
+
@griddir = File.expand_path(File.join("~", ".grid"))
|
8
|
+
Dir.mkdir(@griddir) if not File.exists?(@griddir)
|
9
|
+
|
10
|
+
# This is a hash, so initialize it, set w/ default config options, then set
|
11
|
+
# with any config options in the ~/.grid/#{fname} file
|
12
|
+
@conffile = File.join(@griddir, fname)
|
13
|
+
super
|
14
|
+
update default_config
|
15
|
+
# if conf file exists, update this obj w/ it's values. Otherwise, create file
|
16
|
+
File.exists?(@conffile) ? update(YAML.load_file(@conffile)) : save
|
17
|
+
end
|
18
|
+
|
19
|
+
|
20
|
+
def default_config
|
21
|
+
{}
|
22
|
+
end
|
23
|
+
|
24
|
+
def save
|
25
|
+
File.open(@conffile, 'w') { |f| YAML.dump(self, f) }
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
data/lib/gridcli.rb
CHANGED
@@ -3,7 +3,12 @@ require 'active_resource'
|
|
3
3
|
require 'gridcli/storage/base'
|
4
4
|
require 'gridcli/storage/files'
|
5
5
|
|
6
|
+
require 'gridcli/ymlhash'
|
6
7
|
require 'gridcli/config'
|
8
|
+
require 'gridcli/subgrids'
|
9
|
+
require 'gridcli/stats'
|
10
|
+
require 'gridcli/hooks'
|
11
|
+
require 'gridcli/plugins'
|
7
12
|
|
8
13
|
module GridCLI
|
9
14
|
def self.config
|
@@ -13,31 +18,46 @@ module GridCLI
|
|
13
18
|
def self.storage
|
14
19
|
@storage ||= FileStorage.new
|
15
20
|
end
|
21
|
+
|
22
|
+
def self.stats
|
23
|
+
@stats ||= Stats.new
|
24
|
+
end
|
25
|
+
|
26
|
+
def self.hooker
|
27
|
+
@hooker ||= Hooker.new
|
28
|
+
end
|
29
|
+
|
30
|
+
def self.plugins
|
31
|
+
@plugins ||= Plugins.new
|
32
|
+
end
|
16
33
|
end
|
17
34
|
|
18
|
-
require 'gridcli/version'
|
19
|
-
require 'gridcli/runner'
|
20
35
|
require 'gridcli/pprinter'
|
36
|
+
require 'gridcli/runner'
|
37
|
+
require 'gridcli/version'
|
21
38
|
|
22
39
|
require 'gridcli/commands/base'
|
23
|
-
require 'gridcli/commands/pprint'
|
24
|
-
require 'gridcli/commands/signup'
|
25
|
-
require 'gridcli/commands/help'
|
26
|
-
require 'gridcli/commands/profile'
|
27
40
|
require 'gridcli/commands/befriend'
|
28
41
|
require 'gridcli/commands/block'
|
42
|
+
require 'gridcli/commands/dislike'
|
29
43
|
require 'gridcli/commands/friends'
|
44
|
+
require 'gridcli/commands/help'
|
45
|
+
require 'gridcli/commands/like'
|
46
|
+
require 'gridcli/commands/list'
|
30
47
|
require 'gridcli/commands/message'
|
48
|
+
require 'gridcli/commands/plugin'
|
49
|
+
require 'gridcli/commands/pprint'
|
50
|
+
require 'gridcli/commands/profile'
|
51
|
+
require 'gridcli/commands/search'
|
52
|
+
require 'gridcli/commands/signup'
|
31
53
|
require 'gridcli/commands/status'
|
32
|
-
require 'gridcli/commands/
|
33
|
-
require 'gridcli/commands/dislike'
|
54
|
+
require 'gridcli/commands/subgrid'
|
34
55
|
require 'gridcli/commands/update'
|
35
|
-
require 'gridcli/commands/search'
|
36
|
-
require 'gridcli/commands/list'
|
37
56
|
|
38
57
|
require 'gridcli/resources/base'
|
39
|
-
require 'gridcli/resources/
|
58
|
+
require 'gridcli/resources/blockage'
|
40
59
|
require 'gridcli/resources/friendship'
|
41
60
|
require 'gridcli/resources/post'
|
42
|
-
require 'gridcli/resources/
|
61
|
+
require 'gridcli/resources/user'
|
43
62
|
|
63
|
+
GridCLI.plugins.include!
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: gridcli
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 19
|
5
5
|
prerelease: false
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 0
|
9
|
-
-
|
10
|
-
version: 0.0.
|
9
|
+
- 6
|
10
|
+
version: 0.0.6
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Brian Muller
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2011-10-
|
18
|
+
date: 2011-10-08 00:00:00 -04:00
|
19
19
|
default_executable:
|
20
20
|
dependencies:
|
21
21
|
- !ruby/object:Gem::Dependency
|
@@ -35,9 +35,25 @@ dependencies:
|
|
35
35
|
type: :runtime
|
36
36
|
version_requirements: *id001
|
37
37
|
- !ruby/object:Gem::Dependency
|
38
|
-
name:
|
38
|
+
name: activesupport
|
39
39
|
prerelease: false
|
40
40
|
requirement: &id002 !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ">="
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
hash: 19
|
46
|
+
segments:
|
47
|
+
- 3
|
48
|
+
- 0
|
49
|
+
- 10
|
50
|
+
version: 3.0.10
|
51
|
+
type: :runtime
|
52
|
+
version_requirements: *id002
|
53
|
+
- !ruby/object:Gem::Dependency
|
54
|
+
name: chronic
|
55
|
+
prerelease: false
|
56
|
+
requirement: &id003 !ruby/object:Gem::Requirement
|
41
57
|
none: false
|
42
58
|
requirements:
|
43
59
|
- - ">="
|
@@ -49,11 +65,11 @@ dependencies:
|
|
49
65
|
- 4
|
50
66
|
version: 0.6.4
|
51
67
|
type: :runtime
|
52
|
-
version_requirements: *
|
68
|
+
version_requirements: *id003
|
53
69
|
- !ruby/object:Gem::Dependency
|
54
70
|
name: json
|
55
71
|
prerelease: false
|
56
|
-
requirement: &
|
72
|
+
requirement: &id004 !ruby/object:Gem::Requirement
|
57
73
|
none: false
|
58
74
|
requirements:
|
59
75
|
- - ">="
|
@@ -65,11 +81,11 @@ dependencies:
|
|
65
81
|
- 1
|
66
82
|
version: 1.6.1
|
67
83
|
type: :runtime
|
68
|
-
version_requirements: *
|
84
|
+
version_requirements: *id004
|
69
85
|
- !ruby/object:Gem::Dependency
|
70
86
|
name: colorize
|
71
87
|
prerelease: false
|
72
|
-
requirement: &
|
88
|
+
requirement: &id005 !ruby/object:Gem::Requirement
|
73
89
|
none: false
|
74
90
|
requirements:
|
75
91
|
- - ">="
|
@@ -81,7 +97,7 @@ dependencies:
|
|
81
97
|
- 8
|
82
98
|
version: 0.5.8
|
83
99
|
type: :runtime
|
84
|
-
version_requirements: *
|
100
|
+
version_requirements: *id005
|
85
101
|
description: "A command line interface to The Grid: Social Networking, Web 0.2"
|
86
102
|
email:
|
87
103
|
- bamuller@gmail.com
|
@@ -98,7 +114,6 @@ files:
|
|
98
114
|
- Gemfile
|
99
115
|
- README.rdoc
|
100
116
|
- Rakefile
|
101
|
-
- TODO
|
102
117
|
- bin/grid
|
103
118
|
- gridcli.gemspec
|
104
119
|
- lib/gridcli.rb
|
@@ -111,13 +126,17 @@ files:
|
|
111
126
|
- lib/gridcli/commands/like.rb
|
112
127
|
- lib/gridcli/commands/list.rb
|
113
128
|
- lib/gridcli/commands/message.rb
|
129
|
+
- lib/gridcli/commands/plugin.rb
|
114
130
|
- lib/gridcli/commands/pprint.rb
|
115
131
|
- lib/gridcli/commands/profile.rb
|
116
132
|
- lib/gridcli/commands/search.rb
|
117
133
|
- lib/gridcli/commands/signup.rb
|
118
134
|
- lib/gridcli/commands/status.rb
|
135
|
+
- lib/gridcli/commands/subgrid.rb
|
119
136
|
- lib/gridcli/commands/update.rb
|
120
137
|
- lib/gridcli/config.rb
|
138
|
+
- lib/gridcli/hooks.rb
|
139
|
+
- lib/gridcli/plugins.rb
|
121
140
|
- lib/gridcli/pprinter.rb
|
122
141
|
- lib/gridcli/resources/base.rb
|
123
142
|
- lib/gridcli/resources/blockage.rb
|
@@ -125,9 +144,12 @@ files:
|
|
125
144
|
- lib/gridcli/resources/post.rb
|
126
145
|
- lib/gridcli/resources/user.rb
|
127
146
|
- lib/gridcli/runner.rb
|
147
|
+
- lib/gridcli/stats.rb
|
128
148
|
- lib/gridcli/storage/base.rb
|
129
149
|
- lib/gridcli/storage/files.rb
|
150
|
+
- lib/gridcli/subgrids.rb
|
130
151
|
- lib/gridcli/version.rb
|
152
|
+
- lib/gridcli/ymlhash.rb
|
131
153
|
has_rdoc: true
|
132
154
|
homepage: http://gridcli.com
|
133
155
|
licenses: []
|
data/TODO
DELETED
@@ -1,13 +0,0 @@
|
|
1
|
-
grid list friends --of-friends
|
2
|
-
|
3
|
-
pretty print for profiles
|
4
|
-
|
5
|
-
ascii profiles
|
6
|
-
|
7
|
-
circles (or grids?) - with lists stored locally. Format:
|
8
|
-
|
9
|
-
play: [ sally, mary, suzie ]
|
10
|
-
work: [ bob, john ]
|
11
|
-
everyone: [ @work, @play ]
|
12
|
-
|
13
|
-
or something like that..
|