friends 0.18 → 0.19
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.
- 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
|