friends 0.18 → 0.19
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +11 -0
- data/README.md +39 -22
- data/bin/friends +44 -17
- data/lib/friends/activity.rb +8 -1
- data/lib/friends/introvert.rb +79 -35
- data/lib/friends/location.rb +7 -0
- data/lib/friends/version.rb +1 -1
- data/test/introvert_spec.rb +16 -13
- metadata +1 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4ba2ca1e570ce12bae59bd92e45eed450b15859d
|
4
|
+
data.tar.gz: f29a32cae219ae83c7cbc925d1493894d76409cb
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 264af4e8b7d6956401c9a7e6babecb6a8e8b6dc154de383394aef7890c2262685ea90c24c1d525d03802ecb1a028ffbc445cd4306fa91c5badbf044389667d1e
|
7
|
+
data.tar.gz: 674aa75753fc7aedc6f50bbb54956ecd91f6df2d8930d886f5f018e08d9c89b0db2e4f5aa74c014b45b35c6d429809d6fbdb7982598b52b66b0636f377136d3a
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,16 @@
|
|
1
1
|
# Change Log
|
2
2
|
|
3
|
+
## [v0.19](https://github.com/JacobEvelyn/friends/tree/v0.19) (2016-05-02)
|
4
|
+
[Full Changelog](https://github.com/JacobEvelyn/friends/compare/v0.18...v0.19)
|
5
|
+
|
6
|
+
**Implemented enhancements:**
|
7
|
+
|
8
|
+
- Add command to list favorite locations [\#108](https://github.com/JacobEvelyn/friends/issues/108)
|
9
|
+
|
10
|
+
**Merged pull requests:**
|
11
|
+
|
12
|
+
- Add `list favorite locations` command [\#115](https://github.com/JacobEvelyn/friends/pull/115) ([JacobEvelyn](https://github.com/JacobEvelyn))
|
13
|
+
|
3
14
|
## [v0.18](https://github.com/JacobEvelyn/friends/tree/v0.18) (2016-05-02)
|
4
15
|
[Full Changelog](https://github.com/JacobEvelyn/friends/compare/v0.17...v0.18)
|
5
16
|
|
data/README.md
CHANGED
@@ -14,7 +14,7 @@ Extrovert-approved.
|
|
14
14
|
- [Global flags](#global-flags)
|
15
15
|
- [Syncing across multiple machines](#syncing-across-multiple-machines)
|
16
16
|
- [Command reference](#command-reference)
|
17
|
-
-
|
17
|
+
- `add`
|
18
18
|
- [`add activity`](#add-activity)
|
19
19
|
- [`add friend`](#add-friend)
|
20
20
|
- [`add location`](#add-location)
|
@@ -22,13 +22,15 @@ Extrovert-approved.
|
|
22
22
|
- [`clean`](#clean)
|
23
23
|
- [`graph`](#graph)
|
24
24
|
- [`help`](#help)
|
25
|
-
-
|
25
|
+
- `list`
|
26
26
|
- [`list activities`](#list-activities)
|
27
|
-
-
|
27
|
+
- `list favorite`
|
28
|
+
- [`list favorite friends`](#list-favorite-friends)
|
29
|
+
- [`list favorite locations`](#list-favorite-locations)
|
28
30
|
- [`list friends`](#list-friends)
|
29
31
|
- [`list locations`](#list-locations)
|
30
32
|
- [`remove nickname`](#remove-nickname)
|
31
|
-
-
|
33
|
+
- `rename`
|
32
34
|
- [`rename friend`](#rename-friend)
|
33
35
|
- [`rename location`](#rename-location)
|
34
36
|
- [`set location`](#set)
|
@@ -177,9 +179,7 @@ alias friends="friends --filename '~/Dropbox/friends.md'"
|
|
177
179
|
|
178
180
|
*Note that the command-line output is colored, which this README cannot show.
|
179
181
|
|
180
|
-
#### `add`
|
181
|
-
|
182
|
-
##### `add activity`
|
182
|
+
#### `add activity`
|
183
183
|
|
184
184
|
```bash
|
185
185
|
$ friends add activity "Got lunch with Grace and George."
|
@@ -240,21 +240,21 @@ $ friends add activity "2015-11-01: Grace and I went to \Marie's Diner. \George
|
|
240
240
|
Activity added: "2015-11-01: Grace Hopper and I went to Marie's Diner. George had to cancel at the last minute."
|
241
241
|
```
|
242
242
|
|
243
|
-
|
243
|
+
#### `add friend`
|
244
244
|
|
245
245
|
```bash
|
246
246
|
$ friends add friend "Grace Hopper"
|
247
247
|
Friend added: "Grace Hopper"
|
248
248
|
```
|
249
249
|
|
250
|
-
|
250
|
+
#### `add location`
|
251
251
|
|
252
252
|
```
|
253
253
|
$ friends add location Atlantis
|
254
254
|
Location added: "Atlantis"
|
255
255
|
```
|
256
256
|
|
257
|
-
|
257
|
+
#### `add nickname`
|
258
258
|
|
259
259
|
```bash
|
260
260
|
$ friends add nickname "Grace Hopper" "The Admiral"
|
@@ -344,9 +344,7 @@ $ friends help list
|
|
344
344
|
$ friends help list activities
|
345
345
|
```
|
346
346
|
|
347
|
-
#### `list`
|
348
|
-
|
349
|
-
##### `list activities`
|
347
|
+
#### `list activities`
|
350
348
|
|
351
349
|
Lists recent activities:
|
352
350
|
|
@@ -380,12 +378,12 @@ $ friends list activities --in "New York"
|
|
380
378
|
2014-12-31: Celebrated the new year with Marie Curie in New York City.
|
381
379
|
```
|
382
380
|
|
383
|
-
|
381
|
+
#### `list favorite friends`
|
384
382
|
|
385
383
|
Lists your "favorite" friends (by total number of activities):
|
386
384
|
|
387
385
|
```bash
|
388
|
-
$ friends list
|
386
|
+
$ friends list favorite friends
|
389
387
|
Your favorite friends:
|
390
388
|
1. George Washington Carver (2 activities)
|
391
389
|
2. Grace Hopper (1)
|
@@ -395,13 +393,34 @@ Your favorite friends:
|
|
395
393
|
You can specify a number of favorites to show:
|
396
394
|
|
397
395
|
```bash
|
398
|
-
$ friends list
|
396
|
+
$ friends list favorite friends --limit 2
|
399
397
|
Your favorite friends:
|
400
398
|
1. George Washington Carver (2 activities)
|
401
399
|
2. Grace Hopper (1)
|
402
400
|
```
|
403
401
|
|
404
|
-
|
402
|
+
#### `list favorite locations`
|
403
|
+
|
404
|
+
Lists your "favorite" locations (by total number of activities):
|
405
|
+
|
406
|
+
```bash
|
407
|
+
$ friends list favorite locations
|
408
|
+
Your favorite locations:
|
409
|
+
1. Atlantis (2 activities)
|
410
|
+
2. Paris (1)
|
411
|
+
3. London (1)
|
412
|
+
```
|
413
|
+
|
414
|
+
You can specify a number of favorites to show:
|
415
|
+
|
416
|
+
```bash
|
417
|
+
$ friends list favorite locations --limit 2
|
418
|
+
Your favorite locations:
|
419
|
+
1. Atlantis (2 activities)
|
420
|
+
2. Paris (1)
|
421
|
+
```
|
422
|
+
|
423
|
+
#### `list friends`
|
405
424
|
|
406
425
|
Lists all of your friends:
|
407
426
|
|
@@ -419,7 +438,7 @@ $ friends list friends --in Paris
|
|
419
438
|
Marie Curie
|
420
439
|
```
|
421
440
|
|
422
|
-
|
441
|
+
#### `list locations`
|
423
442
|
|
424
443
|
Lists all of the locations you've added:
|
425
444
|
|
@@ -439,16 +458,14 @@ $ friends remove nickname "Grace Hopper" "The Admiral"
|
|
439
458
|
Nickname removed: "Grace Hopper (a.k.a. Amazing Grace)"
|
440
459
|
```
|
441
460
|
|
442
|
-
#### `rename`
|
443
|
-
|
444
|
-
##### `rename friend`
|
461
|
+
#### `rename friend`
|
445
462
|
|
446
463
|
```bash
|
447
464
|
$ friends rename friend "Grace Hopper" "Grace Brewster Murray Hopper"
|
448
465
|
Name changed: "Grace Brewster Murray Hopper (a.k.a. Amazing Grace)"
|
449
466
|
```
|
450
467
|
|
451
|
-
|
468
|
+
#### `rename location`
|
452
469
|
|
453
470
|
```bash
|
454
471
|
$ friends rename location Paris "Paris, France"
|
data/bin/friends
CHANGED
@@ -79,25 +79,52 @@ command :list do |list|
|
|
79
79
|
end
|
80
80
|
end
|
81
81
|
|
82
|
-
list.desc "List favorite friends"
|
83
|
-
list.command :
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
82
|
+
list.desc "List favorite friends and locations"
|
83
|
+
list.command :favorite do |list_favorite|
|
84
|
+
list_favorite.desc "List favorite friends"
|
85
|
+
list_favorite.command :friends do |list_favorite_friends|
|
86
|
+
list_favorite_friends.flag [:limit],
|
87
|
+
arg_name: "NUMBER",
|
88
|
+
default_value: 10,
|
89
|
+
desc: "The number of friends to return"
|
90
|
+
|
91
|
+
list_favorite_friends.action do |_, options|
|
92
|
+
limit = options[:limit].to_i
|
93
|
+
favorites = @introvert.list_favorite_friends(limit: limit)
|
94
|
+
|
95
|
+
if limit == 1
|
96
|
+
puts "Your best friend is #{favorites.first}"
|
97
|
+
else
|
98
|
+
puts "Your favorite friends:"
|
92
99
|
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
100
|
+
num_str_size = favorites.size.to_s.size + 1
|
101
|
+
favorites.each.with_index(1) do |name, rank|
|
102
|
+
puts "#{"#{rank}.".ljust(num_str_size)} #{name}"
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
list_favorite.desc "List favorite locations"
|
109
|
+
list_favorite.command :locations do |list_favorite_locations|
|
110
|
+
list_favorite_locations.flag [:limit],
|
111
|
+
arg_name: "NUMBER",
|
112
|
+
default_value: 10,
|
113
|
+
desc: "The number of locations to return"
|
114
|
+
|
115
|
+
list_favorite_locations.action do |_, options|
|
116
|
+
limit = options[:limit].to_i
|
117
|
+
favorites = @introvert.list_favorite_locations(limit: limit)
|
118
|
+
|
119
|
+
if limit == 1
|
120
|
+
puts "Your favorite location is #{favorites.first}"
|
121
|
+
else
|
122
|
+
puts "Your favorite locations:"
|
97
123
|
|
98
|
-
|
99
|
-
|
100
|
-
|
124
|
+
num_str_size = favorites.size.to_s.size + 1
|
125
|
+
favorites.each.with_index(1) do |name, rank|
|
126
|
+
puts "#{"#{rank}.".ljust(num_str_size)} #{name}"
|
127
|
+
end
|
101
128
|
end
|
102
129
|
end
|
103
130
|
end
|
data/lib/friends/activity.rb
CHANGED
@@ -127,6 +127,13 @@ module Friends
|
|
127
127
|
end
|
128
128
|
memoize :friend_names
|
129
129
|
|
130
|
+
# Find the names of all locations in this description.
|
131
|
+
# @return [Array] list of all location names in the description
|
132
|
+
def location_names
|
133
|
+
@description.scan(/(?<=_)\w[^_]*(?=_)/).uniq
|
134
|
+
end
|
135
|
+
memoize :location_names
|
136
|
+
|
130
137
|
private
|
131
138
|
|
132
139
|
# Modify the description to turn inputted location names (e.g. "Atlantis")
|
@@ -184,7 +191,7 @@ module Friends
|
|
184
191
|
end
|
185
192
|
|
186
193
|
# Now, we compute the likelihood of each friend in the possible-match set.
|
187
|
-
introvert.
|
194
|
+
introvert.set_friend_n_activities!
|
188
195
|
introvert.set_likelihood_score!(
|
189
196
|
matches: matched_friends,
|
190
197
|
possible_matches: possible_matched_friends
|
data/lib/friends/introvert.rb
CHANGED
@@ -192,29 +192,19 @@ module Friends
|
|
192
192
|
end
|
193
193
|
|
194
194
|
# List your favorite friends.
|
195
|
-
# @param limit [Integer] the number of favorite friends to return
|
196
|
-
# for no limit
|
195
|
+
# @param limit [Integer] the number of favorite friends to return
|
197
196
|
# @return [Array] a list of the favorite friends' names and activity
|
198
197
|
# counts
|
199
|
-
def
|
200
|
-
|
201
|
-
|
202
|
-
end
|
203
|
-
|
204
|
-
set_n_activities! # Set n_activities for all friends.
|
205
|
-
|
206
|
-
# Sort the results, with the most favorite friend first.
|
207
|
-
results = @friends.sort_by { |friend| -friend.n_activities }
|
208
|
-
|
209
|
-
# If we need to, trim the list.
|
210
|
-
results = results.take(limit) unless limit.nil?
|
198
|
+
def list_favorite_friends(limit:)
|
199
|
+
list_favorite_things(:friend, limit: limit)
|
200
|
+
end
|
211
201
|
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
202
|
+
# List your favorite friends.
|
203
|
+
# @param limit [Integer] the number of favorite locations to return
|
204
|
+
# @return [Array] a list of the favorite locations' names and activity
|
205
|
+
# counts
|
206
|
+
def list_favorite_locations(limit:)
|
207
|
+
list_favorite_things(:location, limit: limit)
|
218
208
|
end
|
219
209
|
|
220
210
|
# List all activity details.
|
@@ -306,7 +296,7 @@ module Friends
|
|
306
296
|
# for unfiltered
|
307
297
|
# @return [Hash{String => Array<String>}]
|
308
298
|
def suggest(location_name:)
|
309
|
-
|
299
|
+
set_friend_n_activities! # Set n_activities for all friends.
|
310
300
|
|
311
301
|
# Filter our friends by location if necessary.
|
312
302
|
fs = @friends
|
@@ -338,20 +328,8 @@ module Friends
|
|
338
328
|
###################################################################
|
339
329
|
|
340
330
|
# Sets the n_activities field on each friend.
|
341
|
-
def
|
342
|
-
|
343
|
-
freq_table = Hash.new { |h, k| h[k] = 0 }
|
344
|
-
@activities.each do |activity|
|
345
|
-
activity.friend_names.each do |friend_name|
|
346
|
-
freq_table[friend_name] += 1
|
347
|
-
end
|
348
|
-
end
|
349
|
-
|
350
|
-
# Remove names that are not in the friends list.
|
351
|
-
freq_table.each do |name, count|
|
352
|
-
friend = friend_with_exact_name(name)
|
353
|
-
friend.n_activities = count if friend # Do nothing if name not valid.
|
354
|
-
end
|
331
|
+
def set_friend_n_activities!
|
332
|
+
set_n_activities!(:friend)
|
355
333
|
end
|
356
334
|
|
357
335
|
# Get a regex friend map.
|
@@ -445,6 +423,59 @@ module Friends
|
|
445
423
|
|
446
424
|
private
|
447
425
|
|
426
|
+
# @param type [Symbol] one of: [:friend, :location]
|
427
|
+
# @param limit [Integer] the number of favorite things to return
|
428
|
+
# @return [Array] a list of the favorite things' names and activity counts
|
429
|
+
def list_favorite_things(type, limit:)
|
430
|
+
unless [:friend, :location].include? type
|
431
|
+
raise FriendsError, "Type must be either :friend or :location"
|
432
|
+
end
|
433
|
+
|
434
|
+
if limit < 1
|
435
|
+
raise FriendsError, "Favorites limit must be positive"
|
436
|
+
end
|
437
|
+
|
438
|
+
send("set_n_activities!", type) # Set n_activities for all things.
|
439
|
+
|
440
|
+
# Sort the results, with the most favorite thing first.
|
441
|
+
results = instance_variable_get("@#{type}s").sort_by do |thing|
|
442
|
+
-thing.n_activities
|
443
|
+
end.take(limit) # Trim the list.
|
444
|
+
|
445
|
+
max_str_size = results.map(&:name).map(&:size).max
|
446
|
+
results.map.with_index(0) do |thing, index|
|
447
|
+
name = thing.name.ljust(max_str_size)
|
448
|
+
n = thing.n_activities
|
449
|
+
if index == 0
|
450
|
+
label = n == 1 ? " activity" : " activities"
|
451
|
+
end
|
452
|
+
parenthetical = "(#{n}#{label})"
|
453
|
+
"#{name} #{parenthetical}"
|
454
|
+
end
|
455
|
+
end
|
456
|
+
|
457
|
+
# Sets the n_activities field on each thing.
|
458
|
+
# @param type [Symbol] one of: [:friend, :location]
|
459
|
+
def set_n_activities!(type)
|
460
|
+
unless [:friend, :location].include? type
|
461
|
+
raise FriendsError, "Type must be either :friend or :location"
|
462
|
+
end
|
463
|
+
|
464
|
+
# Construct a hash of location name to frequency of appearance.
|
465
|
+
freq_table = Hash.new { |h, k| h[k] = 0 }
|
466
|
+
@activities.each do |activity|
|
467
|
+
activity.send("#{type}_names").each do |thing_name|
|
468
|
+
freq_table[thing_name] += 1
|
469
|
+
end
|
470
|
+
end
|
471
|
+
|
472
|
+
# Remove names that are not in the locations list.
|
473
|
+
freq_table.each do |name, count|
|
474
|
+
thing = send("#{type}_with_exact_name", name)
|
475
|
+
thing.n_activities = count if thing # Do nothing if name isn't valid.
|
476
|
+
end
|
477
|
+
end
|
478
|
+
|
448
479
|
# Process the friends.md file and store its contents in internal data
|
449
480
|
# structures.
|
450
481
|
def read_file
|
@@ -541,6 +572,19 @@ module Friends
|
|
541
572
|
end
|
542
573
|
end
|
543
574
|
|
575
|
+
# @param name [String] the name of the location to search for
|
576
|
+
# @return [Location] the location whose name exactly matches the argument
|
577
|
+
# @raise [FriendsError] if more than one location has the given name
|
578
|
+
def location_with_exact_name(name)
|
579
|
+
results = @locations.select { |location| location.name == name }
|
580
|
+
|
581
|
+
case results.size
|
582
|
+
when 0 then nil
|
583
|
+
when 1 then results.first
|
584
|
+
else raise FriendsError, "More than one location named #{name}"
|
585
|
+
end
|
586
|
+
end
|
587
|
+
|
544
588
|
# @param text [String] the name (or substring) of the location to search for
|
545
589
|
# @return [Location] the location that matches
|
546
590
|
# @raise [FriendsError] if 0 or 2+ location match the given text
|
data/lib/friends/location.rb
CHANGED
@@ -39,6 +39,13 @@ module Friends
|
|
39
39
|
Friends::RegexBuilder.regex(@name)
|
40
40
|
end
|
41
41
|
|
42
|
+
# The number of activities this location is in. This is for internal use
|
43
|
+
# only and is set by the Introvert as needed.
|
44
|
+
attr_writer :n_activities
|
45
|
+
def n_activities
|
46
|
+
@n_activities || 0
|
47
|
+
end
|
48
|
+
|
42
49
|
private
|
43
50
|
|
44
51
|
# Default sorting for an array of locations is alphabetical.
|
data/lib/friends/version.rb
CHANGED
data/test/introvert_spec.rb
CHANGED
@@ -562,31 +562,34 @@ describe Friends::Introvert do
|
|
562
562
|
end
|
563
563
|
end
|
564
564
|
|
565
|
-
describe "#
|
566
|
-
subject { introvert.
|
565
|
+
describe "#list_favorite_friends" do
|
566
|
+
subject { introvert.list_favorite_friends(limit: limit) }
|
567
567
|
|
568
|
-
describe "when
|
569
|
-
let(:limit) {
|
568
|
+
describe "when there are more friends than favorites requested" do
|
569
|
+
let(:limit) { 1 }
|
570
570
|
|
571
|
-
it "returns
|
571
|
+
it "returns the number of favorites requested" do
|
572
572
|
stub_friends(friends) do
|
573
573
|
stub_activities(activities) do
|
574
|
-
subject.must_equal [
|
575
|
-
"Betsy Ross (2 activities)",
|
576
|
-
"George Washington Carver (1)"
|
577
|
-
]
|
574
|
+
subject.must_equal ["Betsy Ross (2 activities)"]
|
578
575
|
end
|
579
576
|
end
|
580
577
|
end
|
581
578
|
end
|
579
|
+
end
|
582
580
|
|
583
|
-
|
581
|
+
describe "#list_favorite_locations" do
|
582
|
+
subject { introvert.list_favorite_locations(limit: limit) }
|
583
|
+
|
584
|
+
describe "when there are more locations than favorites requested" do
|
584
585
|
let(:limit) { 1 }
|
585
586
|
|
586
587
|
it "returns the number of favorites requested" do
|
587
|
-
|
588
|
-
stub_activities(
|
589
|
-
|
588
|
+
stub_locations(locations) do
|
589
|
+
stub_activities(
|
590
|
+
[Friends::Activity.new(str: "Swimming in _Atlantis_.")]
|
591
|
+
) do
|
592
|
+
subject.must_equal ["Atlantis (1 activity)"]
|
590
593
|
end
|
591
594
|
end
|
592
595
|
end
|