directed-edge 0.1.2 → 0.1.3
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/VERSION +1 -1
- data/directed-edge.gemspec +3 -3
- data/lib/directed_edge.rb +65 -19
- data/test/test_directed_edge.rb +57 -0
- metadata +18 -9
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.1.
|
1
|
+
0.1.3
|
data/directed-edge.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{directed-edge}
|
8
|
-
s.version = "0.1.
|
8
|
+
s.version = "0.1.3"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Directed Edge"]
|
12
|
-
s.date = %q{2010-04-
|
12
|
+
s.date = %q{2010-04-09}
|
13
13
|
s.description = %q{Bindings for the Directed Edge webservices API}
|
14
14
|
s.email = %q{info@directededge.com}
|
15
15
|
s.extra_rdoc_files = [
|
@@ -30,7 +30,7 @@ Gem::Specification.new do |s|
|
|
30
30
|
s.homepage = %q{http://developer.directededge.com/}
|
31
31
|
s.rdoc_options = ["--charset=UTF-8"]
|
32
32
|
s.require_paths = ["lib"]
|
33
|
-
s.rubygems_version = %q{1.3.
|
33
|
+
s.rubygems_version = %q{1.3.6}
|
34
34
|
s.summary = %q{Bindings for the Directed Edge webservices API}
|
35
35
|
|
36
36
|
if s.respond_to? :specification_version then
|
data/lib/directed_edge.rb
CHANGED
@@ -330,10 +330,14 @@ module DirectedEdge
|
|
330
330
|
@id = id
|
331
331
|
@links = {}
|
332
332
|
@tags = Set.new
|
333
|
+
@preselected = []
|
334
|
+
@blacklisted = Set.new
|
333
335
|
@properties = {}
|
334
336
|
|
335
337
|
@links_to_remove = Set.new
|
336
338
|
@tags_to_remove = Set.new
|
339
|
+
@preselected_to_remove = Set.new
|
340
|
+
@blacklisted_to_remove = Set.new
|
337
341
|
@properties_to_remove = Set.new
|
338
342
|
|
339
343
|
@resource = @database.resource[URI.escape(@id)]
|
@@ -386,11 +390,17 @@ module DirectedEdge
|
|
386
390
|
|
387
391
|
put(complete_document, 'add')
|
388
392
|
|
389
|
-
if !@links_to_remove.empty? ||
|
393
|
+
if !@links_to_remove.empty? ||
|
394
|
+
!@tags_to_remove.empty? ||
|
395
|
+
!@preselected_to_remove.empty? ||
|
396
|
+
!@blacklisted_to_remove.empty? ||
|
397
|
+
!@properties_to_remove.empty?
|
390
398
|
put(removal_document, 'remove')
|
391
399
|
@links_to_remove.clear
|
392
400
|
@tags_to_remove.clear
|
393
401
|
@properties_to_remove.clear
|
402
|
+
@preselected_to_remove.clear
|
403
|
+
@blacklisted_to_remove.clear
|
394
404
|
end
|
395
405
|
end
|
396
406
|
self
|
@@ -404,10 +414,14 @@ module DirectedEdge
|
|
404
414
|
|
405
415
|
@links = hash_from_document(document, 'link', 'weight')
|
406
416
|
@tags = Set.new(list_from_document(document, 'tag'))
|
417
|
+
@preselected = list_from_document(document, 'preselected')
|
418
|
+
@blacklisted = Set.new(list_from_document(document, 'blacklisted'))
|
407
419
|
@properties = {}
|
408
420
|
|
409
421
|
@links_to_remove.clear
|
410
422
|
@tags_to_remove.clear
|
423
|
+
@preselected_to_remove.clear
|
424
|
+
@blacklisted_to_remove.clear
|
411
425
|
@properties_to_remove.clear
|
412
426
|
|
413
427
|
document.elements.each('//property') do |element|
|
@@ -430,6 +444,20 @@ module DirectedEdge
|
|
430
444
|
@tags
|
431
445
|
end
|
432
446
|
|
447
|
+
# Returns an ordered list of items that are preselected for this item.
|
448
|
+
|
449
|
+
def preselected
|
450
|
+
read
|
451
|
+
@preselected
|
452
|
+
end
|
453
|
+
|
454
|
+
# Returns a set of items that should not ever be recommended for this item.
|
455
|
+
|
456
|
+
def blacklisted
|
457
|
+
read
|
458
|
+
@blacklisted
|
459
|
+
end
|
460
|
+
|
433
461
|
# Returns a hash of all of this item's properties.
|
434
462
|
|
435
463
|
def properties
|
@@ -456,9 +484,7 @@ module DirectedEdge
|
|
456
484
|
# Remove the given property_name.
|
457
485
|
|
458
486
|
def clear_property(property_name)
|
459
|
-
|
460
|
-
@properties_to_remove.add(property_name)
|
461
|
-
end
|
487
|
+
@properties_to_remove.add(property_name) unless @cached
|
462
488
|
@properties.delete(property_name)
|
463
489
|
end
|
464
490
|
|
@@ -490,9 +516,7 @@ module DirectedEdge
|
|
490
516
|
# to detect 'broken' links that do not terminate at a valid item.
|
491
517
|
|
492
518
|
def link_to(other, weight=0)
|
493
|
-
if weight < 0 || weight > 10
|
494
|
-
raise RangeError
|
495
|
-
end
|
519
|
+
raise RangeError if (weight < 0 || weight > 10)
|
496
520
|
@links_to_remove.delete(other)
|
497
521
|
@links[other.to_s] = weight
|
498
522
|
end
|
@@ -502,9 +526,7 @@ module DirectedEdge
|
|
502
526
|
# The changes will not be reflected in the database until save is called.
|
503
527
|
|
504
528
|
def unlink_from(other)
|
505
|
-
|
506
|
-
@links_to_remove.add(other.to_s)
|
507
|
-
end
|
529
|
+
@links_to_remove.add(other.to_s) unless @cached
|
508
530
|
@links.delete(other.to_s)
|
509
531
|
end
|
510
532
|
|
@@ -530,12 +552,30 @@ module DirectedEdge
|
|
530
552
|
# The changes will not be reflected in the database until save is called.
|
531
553
|
|
532
554
|
def remove_tag(tag)
|
533
|
-
|
534
|
-
@tags_to_remove.add(tag)
|
535
|
-
end
|
555
|
+
@tags_to_remove.add(tag) unless @cached
|
536
556
|
@tags.delete(tag)
|
537
557
|
end
|
538
558
|
|
559
|
+
def add_preselected(item)
|
560
|
+
@preselected_to_remove.delete(item)
|
561
|
+
@preselected.push(item)
|
562
|
+
end
|
563
|
+
|
564
|
+
def remove_preselected(item)
|
565
|
+
@preselected_to_remove.add(item) unless @cached
|
566
|
+
@preselected.delete(item)
|
567
|
+
end
|
568
|
+
|
569
|
+
def add_blacklisted(item)
|
570
|
+
@blacklisted_to_remove.delete(item)
|
571
|
+
@blacklisted.add(item)
|
572
|
+
end
|
573
|
+
|
574
|
+
def remove_blacklisted(item)
|
575
|
+
@blacklisted_to_remove.add(item) unless @cached
|
576
|
+
@blacklisted.delete(item)
|
577
|
+
end
|
578
|
+
|
539
579
|
# Returns the list of items related to this one. Unlike "recommended" this
|
540
580
|
# may include items which are directly linked from this item. If any tags
|
541
581
|
# are specified, only items which have one or more of the specified tags
|
@@ -604,20 +644,24 @@ module DirectedEdge
|
|
604
644
|
document = read_document
|
605
645
|
@links.merge!(hash_from_document(document, 'link', 'weight'))
|
606
646
|
@tags.merge(list_from_document(document, 'tag'))
|
647
|
+
@preselected.concat(list_from_document(document, 'preselected'))
|
648
|
+
@blacklisted.merge(list_from_document(document, 'blacklisted'))
|
607
649
|
|
608
650
|
document.elements.each('//property') do |element|
|
609
651
|
name = element.attribute('name').value
|
610
|
-
|
611
|
-
@properties[name] = element.text
|
612
|
-
end
|
652
|
+
@properties[name] = element.text unless @properties.has_key?(name)
|
613
653
|
end
|
614
654
|
|
615
655
|
@links_to_remove.each { |link| @links.delete(link) }
|
616
656
|
@tags_to_remove.each { |tag| @tags.delete(tag) }
|
657
|
+
@preselected_to_remove.each { |p| @preselected.delete(p) }
|
658
|
+
@blacklisted_to_remove.each { |b| @blacklisted.delete(b) }
|
617
659
|
@properties_to_remove.each { |property| @properties.delete(property) }
|
618
660
|
|
619
661
|
@links_to_remove.clear
|
620
662
|
@tags_to_remove.clear
|
663
|
+
@preselected_to_remove.clear
|
664
|
+
@blacklisted_to_remove.clear
|
621
665
|
@properties_to_remove.clear
|
622
666
|
|
623
667
|
@cached = true
|
@@ -647,6 +691,8 @@ module DirectedEdge
|
|
647
691
|
item = setup_document(REXML::Document.new)
|
648
692
|
@links_to_remove.each { |link| item.add_element('link').add_text(link.to_s) }
|
649
693
|
@tags_to_remove.each { |tag| item.add_element('tag').add_text(tag.to_s) }
|
694
|
+
@preselected_to_remove.each { |p| item.add_element('preselected').add_text(p.to_s) }
|
695
|
+
@blacklisted_to_remove.each { |b| item.add_element('blacklisted').add_text(b.to_s) }
|
650
696
|
@properties_to_remove.each do |property|
|
651
697
|
item.add_element('property').add_attribute('name', property.to_s)
|
652
698
|
end
|
@@ -657,12 +703,12 @@ module DirectedEdge
|
|
657
703
|
item = setup_document(document)
|
658
704
|
@links.each do |link, weight|
|
659
705
|
element = item.add_element('link')
|
660
|
-
if weight != 0
|
661
|
-
element.add_attribute('weight', weight.to_s)
|
662
|
-
end
|
706
|
+
element.add_attribute('weight', weight.to_s) if weight != 0
|
663
707
|
element.add_text(link.to_s)
|
664
708
|
end
|
665
709
|
@tags.each { |tag| item.add_element('tag').add_text(tag.to_s) }
|
710
|
+
@preselected.each { |p| item.add_element('preselected').add_text(p.to_s) }
|
711
|
+
@blacklisted.each { |b| item.add_element('blacklisted').add_text(b.to_s) }
|
666
712
|
@properties.each do |key, value|
|
667
713
|
property = item.add_element('property')
|
668
714
|
property.add_attribute('name', key.to_s)
|
data/test/test_directed_edge.rb
CHANGED
@@ -231,6 +231,8 @@ class TestDirectedEdge < Test::Unit::TestCase
|
|
231
231
|
end
|
232
232
|
|
233
233
|
def test_load
|
234
|
+
return if ENV['NO_LOAD_TEST']
|
235
|
+
|
234
236
|
def run_load_test(prefix, count)
|
235
237
|
(1..count).concurrently do |i|
|
236
238
|
item = DirectedEdge::Item.new(@database, "test_item_#{prefix}_#{i}")
|
@@ -331,4 +333,59 @@ class TestDirectedEdge < Test::Unit::TestCase
|
|
331
333
|
recommended = customer.recommended(['product'], :include_properties => true)
|
332
334
|
assert_equal('bar', recommended['product21']['foo'])
|
333
335
|
end
|
336
|
+
|
337
|
+
def test_preselected
|
338
|
+
item = DirectedEdge::Item.new(@database, 'product1')
|
339
|
+
|
340
|
+
first = item.related[0]
|
341
|
+
|
342
|
+
item.add_preselected('product2')
|
343
|
+
item.add_preselected('product3')
|
344
|
+
item.save
|
345
|
+
item.reload
|
346
|
+
assert_equal(2, item.preselected.length)
|
347
|
+
assert_equal('product2', item.preselected[0])
|
348
|
+
assert_equal('product3', item.preselected[1])
|
349
|
+
|
350
|
+
related = item.related
|
351
|
+
assert_equal('product2', item.related[0])
|
352
|
+
assert_equal('product3', item.related[1])
|
353
|
+
|
354
|
+
item.remove_preselected('product2')
|
355
|
+
item.save
|
356
|
+
item.reload
|
357
|
+
assert_equal(1, item.preselected.length)
|
358
|
+
|
359
|
+
item.remove_preselected('product3')
|
360
|
+
item.save
|
361
|
+
assert_equal(first, item.related[0])
|
362
|
+
|
363
|
+
# Make sure that internal properties aren't overwriting normal properties
|
364
|
+
|
365
|
+
item['foo'] = 'bar'
|
366
|
+
item.save
|
367
|
+
item.add_preselected('product2')
|
368
|
+
item.save
|
369
|
+
item.reload
|
370
|
+
assert_equal(item['foo'], 'bar')
|
371
|
+
end
|
372
|
+
|
373
|
+
def test_blacklisted
|
374
|
+
customer = DirectedEdge::Item.new(@database, 'customer1')
|
375
|
+
first = customer.recommended.first
|
376
|
+
customer.add_blacklisted(first)
|
377
|
+
customer.save
|
378
|
+
assert_not_equal(customer.recommended.first, first)
|
379
|
+
|
380
|
+
assert(customer.blacklisted.include?(first))
|
381
|
+
customer.reload
|
382
|
+
assert(customer.blacklisted.include?(first))
|
383
|
+
|
384
|
+
customer.remove_blacklisted(first)
|
385
|
+
customer.save
|
386
|
+
assert(!customer.blacklisted.include?(first))
|
387
|
+
customer.reload
|
388
|
+
assert(!customer.blacklisted.include?(first))
|
389
|
+
assert_equal(customer.recommended.first, first)
|
390
|
+
end
|
334
391
|
end
|
metadata
CHANGED
@@ -1,7 +1,12 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: directed-edge
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
|
4
|
+
prerelease: false
|
5
|
+
segments:
|
6
|
+
- 0
|
7
|
+
- 1
|
8
|
+
- 3
|
9
|
+
version: 0.1.3
|
5
10
|
platform: ruby
|
6
11
|
authors:
|
7
12
|
- Directed Edge
|
@@ -9,19 +14,21 @@ autorequire:
|
|
9
14
|
bindir: bin
|
10
15
|
cert_chain: []
|
11
16
|
|
12
|
-
date: 2010-04-
|
17
|
+
date: 2010-04-09 00:00:00 +02:00
|
13
18
|
default_executable:
|
14
19
|
dependencies:
|
15
20
|
- !ruby/object:Gem::Dependency
|
16
21
|
name: rest-client
|
17
|
-
|
18
|
-
|
19
|
-
version_requirements: !ruby/object:Gem::Requirement
|
22
|
+
prerelease: false
|
23
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
20
24
|
requirements:
|
21
25
|
- - ">="
|
22
26
|
- !ruby/object:Gem::Version
|
27
|
+
segments:
|
28
|
+
- 0
|
23
29
|
version: "0"
|
24
|
-
|
30
|
+
type: :runtime
|
31
|
+
version_requirements: *id001
|
25
32
|
description: Bindings for the Directed Edge webservices API
|
26
33
|
email: info@directededge.com
|
27
34
|
executables: []
|
@@ -54,18 +61,20 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
54
61
|
requirements:
|
55
62
|
- - ">="
|
56
63
|
- !ruby/object:Gem::Version
|
64
|
+
segments:
|
65
|
+
- 0
|
57
66
|
version: "0"
|
58
|
-
version:
|
59
67
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
60
68
|
requirements:
|
61
69
|
- - ">="
|
62
70
|
- !ruby/object:Gem::Version
|
71
|
+
segments:
|
72
|
+
- 0
|
63
73
|
version: "0"
|
64
|
-
version:
|
65
74
|
requirements: []
|
66
75
|
|
67
76
|
rubyforge_project:
|
68
|
-
rubygems_version: 1.3.
|
77
|
+
rubygems_version: 1.3.6
|
69
78
|
signing_key:
|
70
79
|
specification_version: 3
|
71
80
|
summary: Bindings for the Directed Edge webservices API
|