Class: InterMine::Lists::ListManager

Inherits:
Object
  • Object
show all
Defined in:
lib/intermine/lists.rb

Overview

Synopsis

An internal class for managing lists throughout the lifetime of a program. The main Service object delegates list functionality to this class.

# Creation
list = service.create_list("path/to/some/file.txt", "Gene", "my-favourite-genes")
# Retrieval
other_list = service.list("my-previously-saved-list")
# Combination
intersection = service.intersection_of([list, other_list])
# Deletion
service.delete_lists(list, other_list)

Description

This class contains logic for reading and updating the lists available to a given user at a webservice. This class in particular is responsible for parsing list responses, and performing the operations that combine lists into new result sets (intersection, union, symmetric difference, subtraction).

:include:contact_header.rdoc

Constant Summary collapse

DEFAULT_LIST_NAME =

The name given by default to all lists you do not explicitly name

l = service.create_list("genes.txt", "Gene")
puts l.name
=> "my_list_1"
"my_list"
DEFAULT_DESCRIPTION =

The description given by default to all new lists for which you do not provide a description explicitly. The purpose of this is to help you identify automatically created lists in you profile.

"Created with InterMine Ruby Webservice Client"

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(service) ⇒ ListManager

Construct a new ListManager.

You will never need to call this constructor yourself.



481
482
483
484
485
486
# File 'lib/intermine/lists.rb', line 481

def initialize(service)
    @service = service
    @lists = {}
    @temporary_lists = []
    do_at_exit(self)
end

Instance Attribute Details

#serviceObject (readonly)

The service this manager belongs to



471
472
473
# File 'lib/intermine/lists.rb', line 471

def service
  @service
end

#temporary_listsObject (readonly)

The temporary lists created in this session. These will be deleted at program exit.



475
476
477
# File 'lib/intermine/lists.rb', line 475

def temporary_lists
  @temporary_lists
end

Instance Method Details

#add_tags(list, *tags) ⇒ Object

Add tags to a list.

Returns the current tags



654
655
656
657
658
659
660
# File 'lib/intermine/lists.rb', line 654

def add_tags(list, *tags)
    uri = URI.parse(@service.root + Service::LIST_TAG_PATH)
    params = @service.params.merge("name" => list.name, "tags" => tags.join(";"))
    res = Net::HTTP.post_form(uri, params)
    check_response_for_error(res)
    return JSON.parse(res.body)["tags"]
end

#create_list(content, type = nil, tags = [], name = nil, description = nil) ⇒ Object

Create a new List with the given content.

Creates a new List and stores it on the appropriate webservice:

Arguments:

content

Can be a string with delimited identifiers, an Array of identifiers, a File object containing identifiers, or a name of an unopened readable file containing identifiers. It can also be another List (in which case the list is cloned) or a query that describes a result set.

type

Required when identifiers are being given (but not when the content is a PathQuery::Query or a List. This should be the kind of object to look for (such as “Gene”).

tags

An Array of tags to apply to the new list. If a list is supplied as the content, these tags will be added to the existing tags.

name

The name of the new list. One will be generated if none is provided. Lists created with generated names are considered temporary and will be deleted upon program exit.

description

An informative description of the list

# With Array of Ids
list = service.create_list(%{eve bib zen}) 

# From a file
list = service.create_list("path/to/some/file.txt", "Gene", [], "my-stored-genes")

# With a query
list = service.create_list(service.query("Gene").select(:id).where(:length => {"<" => 500}))


561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
# File 'lib/intermine/lists.rb', line 561

def create_list(content, type=nil, tags=[], name=nil, description=nil)
    name ||= get_unused_list_name
    description ||= DEFAULT_DESCRIPTION

    if content.is_a?(List) 
        tags += content.tags
        response = create_list_from_query(content.list_query, tags, name, description)
    elsif content.respond_to?(:list_upload_uri)
        response = create_list_from_query(content, tags, name, description)
    else 
        response = create_list_from_ids(content, type, tags, name, description)
    end

    return process_list_creation_response(response)
end

#delete_lists(*lists) ⇒ Object

Deletes the given lists from the webservice. The lists can be supplied as List objects, or as their names as Strings.

Raises errors if problems occur with the deletion of these lists, including if the lists do not exist.



583
584
585
586
587
588
589
590
591
592
593
594
# File 'lib/intermine/lists.rb', line 583

def delete_lists(*lists)
    lists.map {|x| x.is_a?(List) ? x.name : x.to_s}.uniq.each do |name|
        uri = URI.parse(@service.root + Service::LISTS_PATH)
        params = {"name" => name}
        req = Net::HTTP::Delete.new(uri.path + "?" + params_to_query_string(params))
        res = Net::HTTP.start(uri.host, uri.port) do |http|
            http.request(req)
        end
        check_response_for_error(res)
    end
    refresh_lists
end

#get_lists_with_tags(*tags) ⇒ Object

Gets all lists with the given tags. If more than one tag is supplied, then a list must have all given tags to be returned.

tagged = service.get_lists_with_tags("tagA", "tagB")


512
513
514
515
516
517
# File 'lib/intermine/lists.rb', line 512

def get_lists_with_tags(*tags)
    return lists.select do |l|
        union = l.tags | tags
        union.size == l.tags.size
    end
end

#intersection_of(lists = [], tags = [], name = nil, description = nil) ⇒ Object

Create a new list in the webservice from the intersection of two or more lists, and return a List object that represents it.

See ListManager#create_list for an explanation of tags, name and description



616
617
618
# File 'lib/intermine/lists.rb', line 616

def intersection_of(lists=[], tags=[], name=nil, description=nil)
    do_commutative_list_operation(Service::LIST_INTERSECTION_PATH, "Intersection", lists, tags, name, description)
end

#list(name) ⇒ Object

Get a list by name. Returns nil if the list does not exist.



502
503
504
505
# File 'lib/intermine/lists.rb', line 502

def list(name)
    refresh_lists
    return @lists[name]
end

#list_namesObject

Get the names of the lists currently available in the webservice



496
497
498
499
# File 'lib/intermine/lists.rb', line 496

def list_names
    refresh_lists
    return @lists.keys.sort
end

#listsObject

Get the lists currently available in the webservice.



490
491
492
493
# File 'lib/intermine/lists.rb', line 490

def lists
    refresh_lists
    return @lists.values
end

#params_to_query_string(p) ⇒ Object

only handles single value keys!



696
697
698
# File 'lib/intermine/lists.rb', line 696

def params_to_query_string(p)
    return @service.params.merge(p).map { |k,v| "#{k}=#{CGI::escape(v.to_s)}" }.join('&')
end

#process_list_creation_response(response) ⇒ Object

Common code to all list requests for interpreting the response from the webservice.



639
640
641
642
643
644
645
646
647
648
# File 'lib/intermine/lists.rb', line 639

def process_list_creation_response(response)
    check_response_for_error(response)
    new_list = JSON.parse(response.body)
    new_name = new_list["listName"]
    failed_matches = new_list["unmatchedIdentifiers"] || []
    refresh_lists
    ret = list(new_name)
    ret.unmatched_identifiers.replace(failed_matches)
    return ret
end

#refresh_listsObject

Update the stored record of lists. This method is called before all list retrieval methods.



521
522
523
524
525
526
527
528
# File 'lib/intermine/lists.rb', line 521

def refresh_lists
    lists = JSON.parse(@service.get_list_data)
    @lists = {}
    lists["lists"].each {|hash| 
        l = List.new(hash, self)
        @lists[l.name] = l
    }
end

#remove_tags(list, *tags) ⇒ Object

Remove tags from a list

Returns the current tags



666
667
668
669
670
671
672
673
674
675
676
677
678
679
# File 'lib/intermine/lists.rb', line 666

def remove_tags(list, *tags)
    uri = URI.parse(@service.root + Service::LIST_TAG_PATH)
    params = @service.params.merge(
        "name" => list.name, 
        "tags" => tags.join(";")
    )
    req_path = uri.path + "?" + params_to_query_string(params)
    req = Net::HTTP::Delete.new(req_path)
    res = Net::HTTP.start(uri.host, uri.port) do |http|
        http.request(req)
    end
    check_response_for_error(res)
    return JSON.parse(res.body)["tags"]
end

#subtract(references = [], delenda = [], tags = [], name = nil, description = nil) ⇒ Object

Create a new list in the webservice by subtracting all the elements in the ‘delenda’ lists from all the elements in the ‘reference’ lists, and return a List object that represents it.

See ListManager#create_list for an explanation of tags, name and description



625
626
627
628
629
630
631
632
633
634
635
# File 'lib/intermine/lists.rb', line 625

def subtract(references=[], delenda=[], tags=[], name=nil, description=nil)
    ref_names = make_list_names(references)
    del_names = make_list_names(delenda)
    name ||= get_unused_list_name
    description ||= "Subtraction of #{del_names[0 .. -2].join(", ")} and #{del_names.last} from #{ref_names[0 .. -2].join(", ")} and #{ref_names.last}"
    uri = URI.parse(@service.root + Service::LIST_SUBTRACTION_PATH)
    params = @service.params.merge("name" => name, "description" => description, "references" => ref_names.join(';'),
                                   "subtract" => del_names.join(';'), "tags" => tags.join(';'))
    res = Net::HTTP.post_form(uri, params)
    return process_list_creation_response(res)
end

#symmetric_difference_of(lists = [], tags = [], name = nil, description = nil) ⇒ Object

Create a new list in the webservice from the symmetric difference of two or more lists, and return a List object that represents it.

See ListManager#create_list for an explanation of tags, name and description



600
601
602
# File 'lib/intermine/lists.rb', line 600

def symmetric_difference_of(lists=[], tags=[], name=nil, description=nil)
    do_commutative_list_operation(Service::LIST_DIFFERENCE_PATH, "Symmetric difference", lists, tags, name, description)
end

#tags_for(list) ⇒ Object

Get the current tags for a list



682
683
684
685
686
687
688
689
690
691
692
693
# File 'lib/intermine/lists.rb', line 682

def tags_for(list)
    uri = URI.parse(@service.root + Service::LIST_TAG_PATH)
    params = @service.params.merge(
        "name" => list.name
    )
    req_path = uri.path + "?" + params_to_query_string(params)
    res = Net::HTTP.start(uri.host, uri.port) {|http|
          http.get(req_path)
    }
    check_response_for_error(res)
    return JSON.parse(res.body)["tags"]
end

#union_of(lists = [], tags = [], name = nil, description = nil) ⇒ Object

Create a new list in the webservice from the union of two or more lists, and return a List object that represents it.

See ListManager#create_list for an explanation of tags, name and description



608
609
610
# File 'lib/intermine/lists.rb', line 608

def union_of(lists=[], tags=[], name=nil, description=nil)
    do_commutative_list_operation(Service::LIST_UNION_PATH, "Union", lists, tags, name, description)
end