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.


492
493
494
495
496
497
498
499
500
501
502
# File 'lib/intermine/lists.rb', line 492

def initialize(service)
    @service = service
    @lists = {}
    @temporary_lists = []
    @uri = URI.parse(@service.root)
    @http = Net::HTTP.new(@uri.host, @uri.port)
    if @uri.scheme == 'https'
        @http.use_ssl = true
    end
    do_at_exit(self)
end

Instance Attribute Details

#serviceObject (readonly)

The service this manager belongs to


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

def service
  @service
end

#temporary_listsObject (readonly)

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


486
487
488
# File 'lib/intermine/lists.rb', line 486

def temporary_lists
  @temporary_lists
end

Instance Method Details

#add_tags(list, *tags) ⇒ Object

Add tags to a list.

Returns the current tags


672
673
674
675
676
677
678
679
680
# File 'lib/intermine/lists.rb', line 672

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 = @http.start() do |http|
        Net::HTTP.post_form(uri, params)
    end
    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}))

577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
# File 'lib/intermine/lists.rb', line 577

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.


599
600
601
602
603
604
605
606
607
608
609
610
# File 'lib/intermine/lists.rb', line 599

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 = @http.start 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")

528
529
530
531
532
533
# File 'lib/intermine/lists.rb', line 528

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


632
633
634
# File 'lib/intermine/lists.rb', line 632

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.


518
519
520
521
# File 'lib/intermine/lists.rb', line 518

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

#list_namesObject

Get the names of the lists currently available in the webservice


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

def list_names
    refresh_lists
    return @lists.keys.sort
end

#listsObject

Get the lists currently available in the webservice.


506
507
508
509
# File 'lib/intermine/lists.rb', line 506

def lists
    refresh_lists
    return @lists.values
end

#params_to_query_string(p) ⇒ Object

only handles single value keys!


716
717
718
# File 'lib/intermine/lists.rb', line 716

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.


657
658
659
660
661
662
663
664
665
666
# File 'lib/intermine/lists.rb', line 657

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.


537
538
539
540
541
542
543
544
# File 'lib/intermine/lists.rb', line 537

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


686
687
688
689
690
691
692
693
694
695
696
697
698
699
# File 'lib/intermine/lists.rb', line 686

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 = @http.start() 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


641
642
643
644
645
646
647
648
649
650
651
652
653
# File 'lib/intermine/lists.rb', line 641

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 = @http.start() do |http|
        Net::HTTP.post_form(uri, params)
    end
    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


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

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


702
703
704
705
706
707
708
709
710
711
712
713
# File 'lib/intermine/lists.rb', line 702

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 = @http.start() do |http|
        http.get(req_path)
    end
    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


624
625
626
# File 'lib/intermine/lists.rb', line 624

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