class Wmap::SiteTracker
Main class to automatically track the site inventory
Attributes
Public Class Methods
Set default instance variables
# File lib/wmap/site_tracker.rb, line 21 def initialize (params = {}) # Initialize the instance variables @data_dir=params.fetch(:data_dir, File.dirname(__FILE__)+'/../../data/') Dir.mkdir(@data_dir) unless Dir.exist?(@data_dir) @sites_file=params.fetch(:sites_file, @data_dir+'sites') @verbose=params.fetch(:verbose, false) @max_parallel=params.fetch(:max_parallel, 30) File.write(@sites_file, "") unless File.exist?(@sites_file) # Hash table to hold the site store load_site_stores_from_file(@sites_file) end
Public Instance Methods
Setter to add site entry to the cache one at a time
# File lib/wmap/site_tracker.rb, line 118 def add(site) puts "Add entry to the site store: #{site}" # Preliminary sanity check site=site.strip.downcase unless site.nil? if site_known?(site) puts "Site already exists. Skip it: #{site}" return nil end site=normalize_url(site) if is_url?(site) site=url_2_site(site) if is_url?(site) puts "Site in standard format: #{site}" if @verbose raise "Exception on method #{__method__}: invalid site format of #{site}. Expected format is: http://your_website_name/" unless is_site?(site) trusted=false host=url_2_host(site) ip=host_2_ip(host) # Additional logic to refresh deactivated site, 02/12/2014 deact=Wmap::SiteTracker::DeactivatedSite.instance deact.sites_file=@data_dir + "/" + "deactivated_sites" File.write(deact.sites_file, "") unless File.exist?(deact.sites_file) deact.load_site_stores_from_file # only trust either the domain or IP we know if is_ip?(host) trusted=Wmap::CidrTracker.new(:data_dir=>@data_dir).ip_trusted?(ip) else root=get_domain_root(host) if root.nil? raise "Invalid web site format. Please check your record again." else domain_tracker=Wmap::DomainTracker.instance domain_tracker.domains_file=@data_dir + "/" + "domains" File.write(domain_tracker.domains_file, "") unless File.exist?(domain_tracker.domains_file) domain_tracker.load_domains_from_file(domain_tracker.domains_file) trusted=domain_tracker.domain_known?(root) domain_tracker=nil end end # add record only if trusted host_tracker = Wmap::HostTracker.instance host_tracker.data_dir= @data_dir host_tracker.hosts_file = host_tracker.data_dir + "/" + "hosts" host_tracker.load_known_hosts_from_file(host_tracker.hosts_file) if trusted # Add logic to check site status before adding it checker=Wmap::UrlChecker.new(:data_dir=>@data_dir).check(site) raise "Site is currently down. Skip #{site}" if checker.nil? raise "Site is time-out. Skip #{site}" if checker["code"] == 10000 # Skip the http site if it's un-responsive; for the https we'll keep it because we're interested in analysing the SSL layer later if is_https?(site) # do nothing else raise "Site is currently down. Skip #{site}" if checker['code']==10000 end raise "Exception on add method - Fail to resolve the host-name: Host - #{host}, IP - #{ip}. Skip #{site}" unless is_ip?(ip) # Update the local host table when necessary if is_ip?(host) # Case #1: Trusted site contains IP if host_tracker.ip_known?(host) # Try local reverse DNS lookup first puts "Local hosts table lookup for IP: #{ip}" if @verbose host=host_tracker.local_ip_2_host(host) puts "Host found from the local hosts table for #{ip}: #{host}" if @verbose site.sub!(/\d+\.\d+\.\d+\.\d+/,host) else # Try reverse DNS lookup over Internet as secondary precaution puts "Reverse DNS lookup for IP: #{ip}" if @verbose host1=ip_2_host(host) puts "host1: #{host1}" if @verbose if is_fqdn?(host1) if host_tracker.domain_known?(host1) # replace IP with host-name only if domain root is known puts "Host found from the Internet reverse DNS lookup for #{ip}: #{host1}" if @verbose host=host1 site.sub!(/\d+\.\d+\.\d+\.\d+/,host) end end end # Adding site for Case #1 raise "Site already exist! Skip #{site}" if @known_sites.key?(site) puts "Adding site: #{site}" if @verbose @known_sites[site]=Hash.new @known_sites[site]=checker if deact.site_known?(site) deact.delete(site) deact.save! end puts "Site entry loaded: #{checker}" if is_fqdn?(host) # Add logic to update the hosts table for case #1 variance # - case that reverse DNS lookup successful puts "Update local hosts table for host: #{host}" if host_tracker.host_known?(host) old_ip=host_tracker.local_host_2_ip(host) if old_ip != ip host_tracker.refresh(host) else puts "Host resolve to the same IP #{ip} - no need to update the local host table." if @verbose end else host_tracker.add(host) end end else # Case #2: Trusted site contains valid FQDN puts "Ading site: #{site}" if @verbose @known_sites[site]=Hash.new @known_sites[site]=checker if deact.site_known?(site) deact.delete(site) deact.save! end puts "Site entry loaded: #{checker}" # Add logic to update the hosts table for case #2 puts "Update local hosts table for host: #{host}" if host_tracker.host_known?(host) old_ip=host_tracker.local_host_2_ip(host) if old_ip != ip host_tracker.refresh(host) else # Skip - no need to update the local hosts table end else host_tracker.add(host) end end deact=nil host_tracker=nil return checker else puts "Problem found: untrusted Internet domain or IP. Skip #{site}" deact=nil host_tracker.save! host_tracker=nil return nil end rescue => ee puts "Exception on method #{__method__}: #{ee}" checker=nil deact=nil host_tracker=nil return nil end
Setter to add site entry to the cache in batch (from a list)
# File lib/wmap/site_tracker.rb, line 274 def bulk_add(list,num=@max_parallel) puts "Add entries to the local site store from list:\n #{list}" results=Hash.new list = list - [nil,""] if list.size > 0 puts "Start parallel adding on the sites:\n #{list}" Parallel.map(list, :in_processes => num) { |target| add(target) }.each do |process| if process.nil? next elsif process.empty? next #do nothing else results[process['url']]=Hash.new results[process['url']]=process end end @known_sites.merge!(results) else puts "Error: no entry is added. Please check your list and try again." end puts "Done adding site entries." if results.size>0 puts "New entries added: #{results}" else puts "No new entry added. " end return results rescue => ee puts "Exception on method #{__method__}: #{ee}" if @verbose end
Setter to delete site entry to the cache in batch (from a list)
# File lib/wmap/site_tracker.rb, line 349 def bulk_delete(list) puts "Delete entries to the local site store from list:\n #{list}" if @verbose sites=list changes=Array.new if sites.size > 0 sites.map do |x| x=url_2_site(x) site=delete(x) changes.push(site) unless site.nil? end puts "Done deleting sites from the list:\n #{list}" return changes else puts "Error: no entry is loaded. Please check your list and try again." end rescue => ee puts "Exception on method #{__method__}: #{ee}" if @verbose end
'Refresh sites in the site store in batch (from a list)
# File lib/wmap/site_tracker.rb, line 415 def bulk_refresh(list,num=@max_parallel) puts "Refresh entries in the site store from list:\n #{list}" if @verbose results=Hash.new if list.size > 0 puts "Start parallel refreshing on the sites:\n #{list}" Parallel.map(list, :in_processes => num) { |target| refresh(target) }.each do |process| if process.nil? next elsif process.empty? #do nothing else results[process['url']]=Hash.new results[process['url']]=process end end # Clean up old entries, by Y.L. 03/30/2015 list.map {|x| @known_sites.delete(x)} # Add back fresh entries @known_sites.merge!(results) puts "Done refresh sites." else puts "Error: no entry is loaded. Please check your list and try again." end return results rescue => ee puts "Exception on method #{__method__}: #{ee}" if @verbose end
Count numbers of entries in the site store table
# File lib/wmap/site_tracker.rb, line 92 def count puts "Counting number of entries in the site store table ..." return @known_sites.size rescue => ee puts "Exception on method #{__method__}: #{ee}" end
Setter to remove entry from the site store one at a time
# File lib/wmap/site_tracker.rb, line 309 def delete(site) puts "Remove entry from the site store: #{site} " if @verbose # Additional logic to deactivate the site properly, by moving it to the DeactivatedSite list, 02/07/2014 deact=Wmap::SiteTracker::DeactivatedSite.instance deact.sites_file=@data_dir + 'deactivated_sites' File.write(deact.sites_file, "") unless File.exist?(deact.sites_file) site=site.strip.downcase site=url_2_site(site) if @known_sites.key?(site) site_info=@known_sites[site] deact.add(site,site_info) deact.save! deact=nil del=@known_sites.delete(site) puts "Entry cleared: #{site}" return del else puts "Entry not fund. Skip #{site}" deact=nil return nil end rescue => ee puts "Exception on method #{__method__}: #{ee}" if @verbose deact=nil end
Setter to add site entry to the cache table in batch (from a file)
# File lib/wmap/site_tracker.rb, line 261 def file_add(file) puts "Add entries to the local site store from file: #{file}" raise "File non-exist. Please check your file path and name again: #{file}" unless File.exist?(file) changes=Hash.new sites=file_2_list(file) changes=bulk_add(sites) unless sites.nil? or sites.empty? puts "Done loading file #{file}. " return changes rescue => ee puts "Exception on method #{__method__}: #{ee}" end
Setter to delete site entry to the cache in batch (from a file)
# File lib/wmap/site_tracker.rb, line 337 def file_delete(file) puts "Delete entries to the local site store from file: #{file}" if @verbose raise "File non-exist. Please check your file path and name again: #{file}" unless File.exist?(file) sites=file_2_list(file) changes=Array.new changes=bulk_delete(sites) unless sites.nil? or sites.empty? rescue => ee puts "Exception on method file_delete: #{ee} for file: #{file}" if @verbose end
'Refresh sites in the site store in batch (from a file)
# File lib/wmap/site_tracker.rb, line 389 def file_refresh(file) puts "Refresh entries in the site store from file: #{file}" if @verbose changes=Hash.new sites=file_2_list(file) changes=bulk_refresh(sites) unless sites.nil? or sites.empty? return changes rescue => ee puts "Exception on method #{__method__}: #{ee} for file: #{file}" if @verbose end
Retrieve external hosted sites into a list
# File lib/wmap/site_tracker.rb, line 517 def get_ext_sites puts "getter to retrieve all the external hosted sites. " if @verbose sites=Array.new @known_sites.keys.map do |key| if @known_sites[key]['status']=="ext_hosted" sites.push(key) end end sites.sort! return sites rescue Exception => ee puts "Exception on method #{__method__}: #{ee}" if @verbose return nil end
Retrieve a list of internal hosted site URLs
# File lib/wmap/site_tracker.rb, line 534 def get_int_sites puts "getter to retrieve all the internal hosted sites." if @verbose sites=Array.new @known_sites.keys.map do |key| if @known_sites[key]['status']=="int_hosted" sites.push(key) end end sites.sort! return sites rescue Exception => ee puts "Exception on method #{__method__}: #{ee}" if @verbose return nil end
Retrieve a list of sites that contain an IP in the site URL
# File lib/wmap/site_tracker.rb, line 551 def get_ip_sites puts "Getter to retrieve sites contain an IP instead of a host-name ." if @verbose sites=Array.new @known_sites.keys.map do |key| host=url_2_host(key) if is_ip?(host) sites.push(key) end end sites.sort! return sites rescue Exception => ee puts "Exception on method #{__method__}: #{ee}" if @verbose return nil end
Retrieve the unique sites from the local site store in the primary host format
# File lib/wmap/site_tracker.rb, line 821 def get_prim_uniq_sites puts "Retrieve and prime unique sites in the site store. " if @verbose host_tracker=Wmap::HostTracker.instance host_tracker.data_dir=@data_dir primary_host_tracker=Wmap::HostTracker::PrimaryHost.instance primary_host_tracker.data_dir=@data_dir primary_host_tracker.hosts_file = primary_host_tracker.data_dir + "/" + "prime_hosts" primary_host_tracker.known_hosts=primary_host_tracker.load_known_hosts_from_file(@hosts_file) # Step 1. Retrieve the unique site list first sites=get_uniq_sites prim_uniq_sites=Array.new # Step 2. Iterate on the unique site list, spit out the site in the primary host format one at a time sites.map do |site| puts "Work on priming unique site: #{site}" if @verbose host=url_2_host(site) # case#1, for the IP only site, do nothing (presuming 'refresh_ip_sites' or 'refresh_all' method already take care of the potential discrepancy here). if is_ip?(host) prim_uniq_sites.push(site) next end ip=@known_sites[site]['ip'] # case#2, for site with an unique IP, do nothing puts "Local hosts table entry count for #{ip}: #{host_tracker.alias[ip]}" if @verbose if host_tracker.alias[ip] == 1 prim_uniq_sites.push(site) next end # case#3, case of multiple IPs for A DNS record, where the site IP may have 0 alias count, do nothing if host_tracker.alias[ip] == nil prim_uniq_sites.push(site) next end # case#4, for the site has a duplicate IP with others, we try to determine which one is the primary site # raise "Error: inconsistency detected on record: #{site}. Please run the following shell command to refresh it first: \n\srefresh #{site}" if tracker1.alias[ip].nil? if ( primary_host_tracker.known_hosts.key?(ip) and (host_tracker.alias[ip] > 1) ) new_host=primary_host_tracker.prime(host) puts "Host: #{host}, New host:#{new_host}" if @verbose unless host==new_host new_site=site.sub(host,new_host) raise "Site not found in the site tracking data repository: #{new_site}. You may need to add it into the site store first. Execute the following shell command before trying again: \n\twadd #{new_site}\n" unless @known_sites.key?(new_site) new_ip=@known_sites[new_site]['ip'] if new_ip==ip # consistency check site=new_site else # TBD - case of multiple IPs for A DNS record #raise "Inconsistency found on prime host entrance: #{new_ip}, #{ip}; #{new_site}, #{site}. Please refresh your entries by running the following shell command: \n\s refresh #{new_site}" end end end prim_uniq_sites.push(site) end primary_host_tracker=nil host_tracker=nil return prim_uniq_sites #rescue => ee # puts "Exception on method #{__method__}: #{ee}" end
Retrieve redirection URL if available
# File lib/wmap/site_tracker.rb, line 649 def get_redirection_url (site) puts "getter to retrieve the redirection URL from the site store." if @verbose site=site.strip.downcase if @known_sites.key?(site) return @known_sites[site]['redirection'] else puts "Unknown site: #{site}" if @verbose return nil end rescue Exception => ee puts "Exception on method #{__method__}: #{ee}" if @verbose return nil end
Retrieve a list of redirection URLs from the site store
# File lib/wmap/site_tracker.rb, line 633 def get_redirection_urls puts "getter to retrieve all the redirection URLs from the site store." if @verbose urls=Array.new @known_sites.keys.map do |key| unless @known_sites[key]['redirection'].nil? urls.push(@known_sites[key]['redirection']) end end urls.sort! return urls rescue Exception => ee puts "Exception on method #{__method__}: #{ee}" if @verbose return nil end
Retrieve a list of sites that contain an IP in the site URL
# File lib/wmap/site_tracker.rb, line 618 def get_ssl_sites puts "getter to retrieve https sites from the site store." if @verbose sites=Array.new @known_sites.keys.map do |key| key =~ /https/i sites.push(key) end sites.sort! return sites rescue Exception => ee puts "Exception on method #{__method__}: #{ee}" if @verbose return nil end
Retrieve a list of unique sites within the known site store
# File lib/wmap/site_tracker.rb, line 568 def get_uniq_sites puts "Getter to retrieve unique sites containing unique IP:PORT key identifier." if @verbose= #primary_host_tracker=Wmap::HostTracker::PrimaryHost.instance sites=Hash.new #uniqueness=Hash.new host_tracker=Wmap::HostTracker.instance host_tracker.data_dir=@data_dir host_tracker.hosts_file=host_tracker.data_dir + '/' + 'hosts' host_tracker.load_known_hosts_from_file @known_sites.keys.map do |key| port=url_2_port(key).to_s host=url_2_host(key) md5=@known_sites[key]['md5'] code=@known_sites[key]['code'] ip=host_tracker.local_host_2_ip(host) ip=host_2_ip(host) if ip.nil? # filtering out 'un-reachable' sites next if (code == 10000 or code == 20000) # filtering out 'empty' sites next if (md5.nil? or md5.empty?) next if ip.nil? # url_new=key #if primary_host_tracker.ip_known?(ip) # p_host=primary_host_tracker.known_hosts[ip] # url_new=key.sub(host,p_host) #end id=ip+":"+port # filtering out duplicates by 'IP:PORT' key pair unless sites.key?(id) #if @known_sites.key?(key) # sites[id]=url_new #else # Further filtering out redundant site by checking MD5 finger-print #unless uniqueness.key?(md5) sites[id]=key # uniqueness[md5]=true #end #end end end #primary_host_tracker=nil host_tracker=nil return sites.values rescue Exception => ee puts "Exception on method #{__method__}: #{ee}" if @verbose return nil end
determine site is trusted based on the known domains
# File lib/wmap/site_tracker.rb, line 100 def is_trusted?(site) trusted=false host=url_2_host(site) root=get_domain_root(host) domain_tracker=Wmap::DomainTracker.instance domain_tracker.data_dir=@data_dir domain_tracker.domains_file=@data_dir + "/" + "domains" File.write(domain_tracker.domains_file, "") unless File.exist?(domain_tracker.domains_file) domain_tracker.load_domains_from_file(domain_tracker.domains_file) trusted=domain_tracker.domain_known?(root) domain_tracker=nil return trusted rescue => ee puts "Exception on method #{__method__}: #{ee}" return trusted end
Setter to load the known hosts into an instance variable
# File lib/wmap/site_tracker.rb, line 34 def load_site_stores_from_file (file=@sites_file) puts "Loading the site store data repository from file: #{file} " if @verbose @known_sites=Hash.new File.write(file, "") unless File.exist?(file) f=File.open(file, 'r') f.each do |line| line=line.chomp.strip next if line.nil? next if line.empty? next if line =~ /^\s*#/ entry=line.split(%r{\t+|\,}) site=entry[0].downcase ip=entry[1] port=entry[2] status=entry[3] server=entry[4] res=entry[5].to_i fp=entry[6] loc=entry[7] timestamp=entry[8] puts "Loading entry: #{site} - #{ip} - #{status}" if @verbose @known_sites[site]= Hash.new unless @known_sites.key?(site) @known_sites[site]['ip']=ip @known_sites[site]['port']=port @known_sites[site]['status']=status @known_sites[site]['server']=server @known_sites[site]['code']=res @known_sites[site]['md5']=fp @known_sites[site]['redirection']=loc @known_sites[site]['timestamp']=timestamp end f.close puts "Successfully loading file: #{file}" if @verbose return @known_sites rescue => ee puts "Exception on method #{__method__} for file #{file}: #{ee}" end
Print summary report of all sites URL in the site store
# File lib/wmap/site_tracker.rb, line 739 def print_all_sites puts "\nSummary Report of the site store:"<EMAIL_ADDRESS>sites.each do |site| puts site end puts "End of the summary" rescue => ee puts "Exception on method #{__method__} " end
Print summary report of external hosted sites URL in the
# File lib/wmap/site_tracker.rb, line 881 def print_ext_sites puts "\nSummary Report of the External Hosted Site" sites=get_ext_sites sites.each do |site| puts site end return nil end
Print summary report of internal hosted site URLs
# File lib/wmap/site_tracker.rb, line 892 def print_int_sites puts "\nSummary Report of the Internal Hosted Site" sites=get_int_sites sites.each do |site| puts site end return nil end
Print summary report on all sites that contain an IP in the site URL
# File lib/wmap/site_tracker.rb, line 709 def print_ip_sites puts "Print sites contain an IP instead of a host-name." sites=get_ip_sites sites.map { |x| puts x } puts "End of report. " rescue => ee puts "Exception on method #{__method__} " end
Retrieve and print specific information of a site in the site store
# File lib/wmap/site_tracker.rb, line 719 def print_site(site) puts "Site Information Report for: #{site}" if @verbose site=site.strip unless site.nil? raise "Unknown site: #{site}" unless @known_sites.key?(site) ip=@known_sites[site]['ip'] port=@known_sites[site]['port'] status=@known_sites[site]['status'] server=@known_sites[site]['server'] fp=@known_sites[site]['md5'] loc=@known_sites[site]['redirection'] res=@known_sites[site]['code'] timestamp=@known_sites[site]['timestamp'] puts "#{site},#{ip},#{port},#{status},#{server},#{res},#{fp},#{loc},#{timestamp}" rescue => ee puts "Exception on method #{__method__} for #{site}: #{ee}" end
Print summary report of internal hosted site URLs
# File lib/wmap/site_tracker.rb, line 903 def print_ssl_sites puts "\nSummary Report of the HTTPS Sites from the Site Store" sites=get_ssl_sites sites.each do |site| puts site end return nil end
Print summary report of unique sites in the site store
# File lib/wmap/site_tracker.rb, line 913 def print_uniq_sites puts "Summary Report for the Unique sites:" puts "Website,Primary IP,Port,Hosting Status,Server,Response Code,Site MD5 Finger-print,Site Redirection,Timestamp" sites=get_uniq_sites sites.each do |site| print_site(site) end end
Setter to refresh the entry in the site store one at a time
# File lib/wmap/site_tracker.rb, line 370 def refresh(site) puts "Refresh the local site store for site: #{site} " raise "Invalid site: #{site}" if site.nil? or site.empty? site=site.strip.downcase if @known_sites.key?(site) delete(site) site_info=add(site) puts "Done refresh entry: #{site}" return site_info else puts "Error entry non exist: #{site}" end return nil rescue => ee puts "Exception on method #{__method__}: #{ee}" if @verbose return nil end
Refresh all site entries in the stores in one shot
# File lib/wmap/site_tracker.rb, line 448 def refresh_all puts "Refresh all the entries within the local site store ... " changes=Hash.new<EMAIL_ADDRESS>@known_sites.merge!(changes) puts "Done refresh all entries." return changes rescue => ee puts "Exception on method #{__method__}: #{ee}" if @verbose end
Refresh all site entries in the stores that contains an IP instead of a hostname
# File lib/wmap/site_tracker.rb, line 460 def refresh_ip_sites puts "Refresh all entries that contain an IP address instead of a FQDN ... " sites=get_ip_sites live_sites=sites.delete_if { |x| @known_sites[x]['code'] == 10000 or @known_sites[x]['code'] == 20000 } changes=Hash.new changes=bulk_refresh(live_sites) @known_sites.merge!(changes) puts "Done refresh IP sites." return changes rescue => ee puts "Exception on method #{__method__}: #{ee}" if @verbose end
'Refresh unique sites in the site store only
# File lib/wmap/site_tracker.rb, line 400 def refresh_uniq_sites puts "Refresh unique site entries in the site store. " if @verbose changes=Hash.new sites=get_uniq_sites if sites.size > 0 changes=bulk_refresh(sites) else puts "Error: no entry is refreshed. Please check your site store and try again." end return changes rescue => ee puts "Exception on method #{__method__}: #{ee}" if @verbose end
Perform local host table reverse lookup for the IP sites, in hope that the hostname could now be resolved since the site was discovered
# File lib/wmap/site_tracker.rb, line 664 def resolve_ip_sites puts "Resolve sites that contain an IP address. Update the site cache table once a hostname is found in the local host table." if @verbose updates=Array.new sites=get_ip_sites host_tracker=Wmap::HostTracker.instance host_tracker.data_dir=@data_dir host_tracker.hosts_file = host_tracker.data_dir + "/" + "hosts" host_tracker.load_known_hosts_from_file sites.map do |site| puts "Work on resolve the IP site: #{site}" if @verbose ip=url_2_host(site) hostname=host_tracker.local_ip_2_host(ip) if hostname.nil? puts "Can't resolve #{ip} from the local host store. Skip #{site}" if @verbose else puts "Host-name found for IP #{ip}: #{hostname}" if @verbose updates.push(site) refresh(site) end end updates.sort! puts "The following sites are now refreshed: #{updates}" if @verbose host_tracker=nil return updates rescue Exception => ee puts "Exception on method #{__method__}: #{ee}" if @verbose end
Save the current site store hash table into a file
# File lib/wmap/site_tracker.rb, line 73 def save_sites_to_file!(file_sites=@sites_file) puts "Saving the current site store table from memory to file: #{file_sites}" timestamp=Time.now f=File.open(file_sites, 'w') f.write "# Local site store created by class #{self.class} method #{__method__} at: #{timestamp}\n" f.write "# Website,Primary IP,Port,Hosting Status,Server,Response Code,MD5 Finger-print,Redirection,Timestamp\n" @known_sites.keys.sort.map do |key| if is_trusted?(key) f.write "#{key},#{@known_sites[key]['ip']},#{@known_sites[key]['port']},#{@known_sites[key]['status']},#{@known_sites[key]['server']},#{@known_sites[key]['code']},#{@known_sites[key]['md5']},#{@known_sites[key]['redirection']},#{@known_sites[key]['timestamp']}\n" end end f.close puts "site store table is successfully saved: #{file_sites}" rescue => ee puts "Exception on method #{__method__}: #{ee}" end
Retrieve and save unique sites information for the quarterly scan into a plain local file
# File lib/wmap/site_tracker.rb, line 752 def save_uniq_sites(file) puts "Save unique sites information into a flat file: #{file}\nThis may take a long while as it go through a lengthy self correction check process, please be patient ..." prime_sites=get_prim_uniq_sites puts "Primary Sites: #{prime_sites}" if @verbose f=File.open(file,"w") f.write "Unique Sites Information Report\n" f.write "Site, IP, Port, Server, Hosting, Response Code, MD5, Redirect, Timestamps\n" prime_sites.map do |key| next if key.nil? site=key.strip raise "Unknown site: #{site}. You may need to add it into the site store first. Execute the following shell command before trying again: \n\wadd #{site}\n" unless @known_sites.key?(site) ip=@known_sites[site]['ip'] port=@known_sites[site]['port'] status=@known_sites[site]['status'] server=@known_sites[site]['server'] fp=@known_sites[site]['md5'] loc=@known_sites[site]['redirection'] res=@known_sites[site]['code'] timestamp=@known_sites[site]['timestamp'] f.write "#{site},#{ip},#{port},#{server},#{status},#{res},#{fp},#{loc},#{timestamp}\n" end f.close puts "Done!" return true # success rescue => ee puts "Exception on method #{__method__}: #{ee}" return false # fail end
Retrieve and save unique sites information for the quarterly scan into a XML file
# File lib/wmap/site_tracker.rb, line 783 def save_uniq_sites_xml(file) puts "Save unique sites information into XML file: #{file}\nThis may take a long while as it go through lengthy self correctness check, please be patient ..." prime_sites=get_prim_uniq_sites builder = Nokogiri::XML::Builder.new do |xml| xml.root { xml.websites { prime_sites.each do |key| next if key.nil? site=key.strip raise "Unknown site: #{site}. You may need to add it into the site store first. Execute the following shell command before trying again: \n\twmap #{site}\n" unless @known_sites.key?(site) xml.site { xml.name site xml.ip_ @known_sites[site]['ip'] xml.port_ @known_sites[site]['port'] xml.status_ @known_sites[site]['status'] xml.server_ @known_sites[site]['server'] xml.fingerprint_ @known_sites[site]['md5'] xml.redirection_ @known_sites[site]['redirection'] xml.responsecode_ @known_sites[site]['code'] xml.timestamp_ @known_sites[site]['timestamp'] } end } } end puts builder.to_xml if @verbose f=File.new(file,'w') f.write(builder.to_xml) f.close puts "Done!" return true rescue => ee puts "Exception on method #{__method__}: #{ee}" return false end
Search potential matching sites from the site store by using simple regular expression. Note that any upper-case char in the search string will be automatically converted into lower case
# File lib/wmap/site_tracker.rb, line 693 def search (pattern) puts "Search site store based on the regular expression: #{pattern}" if @verbose pattern=pattern.strip.downcase results=Array.new @known_sites.keys.map do |key| if key =~ /#{pattern}/i results.push(key) end end return results rescue Exception => ee puts "Exception on method search: #{ee}" if @verbose return nil end
Quick check of the stored information of a site within the store
# File lib/wmap/site_tracker.rb, line 505 def site_check(site) raise "Web site store not loaded properly! " if @known_sites.nil? site=site.strip.downcase unless site.nil? site=url_2_site(site) return @known_sites[site] unless site.nil? rescue => ee puts "Exception on method #{__method__}: #{ee}" return nil end
Quick validation check on an IP is already part of the site store
# File lib/wmap/site_tracker.rb, line 486 def site_ip_known?(ip) ip=ip.chomp.strip known=false if is_ip?(ip) @known_sites.keys.map do |site| if @known_sites[site]['ip']==ip return true end end end myDis=nil return known rescue => ee puts "Exception on method #{__method__}: #{ee}" return false end
Quick validation if a site is already covered under the site store
# File lib/wmap/site_tracker.rb, line 474 def site_known?(site) raise "Web site store not loaded properly! " if @known_sites.nil? site=site.strip.downcase unless site.nil? site=url_2_site(site) return @known_sites.key?(site) unless site.nil? rescue => ee puts "Error checking web site #{site} against the site store: #{ee}" return false end


Nginx Phases
Rearrange the lines properly
Drag and drop or click source and destination
Verify
Congratulations!


First, download a copy of jsnbt-strap-angular from https://github.com/akonoupakis/jsnbt-strap-angular.
This is a quick bootstrap to strart you up. Put the files in a folder of your choice, and lets have a look at a few of them.
The file should have filled the grunt dependencies that will be needed.
Also, the "main" attribute that points to the module's index file!
This is the hosting configuration file. This should be kept out of source control systems and should not be overriden during deployment.
This is used by the gulp task runner to bundle the site to the deployment target folder (/www) in order to be started by the node web server.
The jsnbt gulp process is fairly complicated, so it has been embedded in the jsnbt core code and will be covered in next chapters.
In your gulpfile, you should point the gulp function to jsnbt/gulpfile.js.
This is the entry point of your site to the cms engine. We will go through the module index file in next chapters.
This is the configuration file of your site.
Specify here the bower dependencies that your site will need.
The "deploy" section of this config file, guides the system to copy the downloaded files to a target location (we will see later, that this target location is the lib folder within our app).
Runs the application in node.
Point to the app folder and:
Run npm install to install all dependencies.
Run npm install jsnbt --save to install jsnbt.
Run gulp dev or gulp prod to structure-up the app (this also downloads any bower components needed).
Run node server-app.js to run the app.
You can hit the /admin section to create your first sa user and access the administration panel.


Vue is Awesome!
Oh no 😢
Title
Paragraf 1
Paragraf 2
Now you see me: {{ random }}
Now you don't
A
B
C
Not A/B/C


Environmental group in Singapore pushes for sustainable palm oil use
- Advertisement -
Following the forest fires in Indonesia that caused a haze in neighbouring countries, one environmental group in Singapore has proposed a way to reduce such deforestation incidents caused by the farming and production of palm oil.
The People’s Movement to Stop Haze (PM Haze) is a charity that aims to get local business to use only sustainable and ethically-produced palm oil, Reuters reported.
Several restaurants have reportedly committed to the cause.
Palm oil is the most dynamic and widely used edible oil in the world. It is used in cooking, food processing, as well as cleaning and industrial products.
- Advertisement -
Farming palm oil is linked to slash-and-burn practices which lead to deforestations.
Read: Palm oil at the centre of the ‘killer’ haze: Report
The PM Haze initiative took inspiration from Chester city in Britain, the world’s first sustainable palm city.
“Switching cooking oil [to sustainable palm oil], you can do at a snap of your fingers. It’s easy. The challenge comes from palm oil derivatives that are in other edible and non-edible oils. It’s hard to find, and operationally that’s a big challenge for companies,” said Benjamin Tay, executive director of PM Haze in a report by Eco-Business.
The charity will begin to focus on restaurants and cooking oil first before they reach out to other businesses. They are getting technical support from palm oil company Wilmar as well.
“Singapore is at the epicenter of the global trade in palm oil and a hub for some of the biggest banks funding its expansion into tropical rainforests frontiers of Indonesia,” said Gemma Tillack, policy director at Rainforest Action Network.
“It is a country that has a huge role to play in tackling the haze crisis,” she added. -/TISG
- Advertisement -


| Package | Description |
|---|---|
| com.ibm.team.build.common.model | |
| com.ibm.team.interop.client | |
| com.ibm.team.interop.common | |
| com.ibm.team.interop.common.service | |
| com.ibm.team.process.common | |
| com.ibm.team.repository.client |
Provides the main client-side-only APIs for the Repository component.
|
| com.ibm.team.repository.common |
Provides APIs for the Repository component that are common to both the
client-side and the server-side.
|
| com.ibm.team.scm.client | |
| com.ibm.team.scm.common | |
| com.ibm.team.scm.common.dto | |
| com.ibm.team.workitem.client | |
| com.ibm.team.workitem.common | |
| com.ibm.team.workitem.common.model | |
| com.ibm.team.workitem.common.query |
| Modifier and Type | Interface and Description |
|---|---|
interface |
IBuildCategoryHandle
A grouping of build results
|
interface |
IBuildDefinition
The build definition is a primary identifier for a set of builds.
|
interface |
IBuildDefinitionHandle
Handle for a build definition.
|
interface |
IBuildEngine
A definition for a build engine.
|
interface |
IBuildEngineHandle
Definition for a build engine available on the network.
|
interface |
IBuildRequest
Represents a request to perform an action on a build result or build
definition.
|
interface |
IBuildRequestHandle
Represents a request to perform an action on a build result or build definition.
|
interface |
IBuildResult
The result of a build.
|
interface |
IBuildResultHandle
The result of a build.
|
| Modifier and Type | Method and Description |
|---|---|
void |
IInteropManager.synchronizeIncoming(IExternalProxyHandle proxyHandle,
IExternalStateHandle xstateHandle,
IAuditableHandle syncedItemStateHandle,
ISyncRuleHandle syncRuleHandle,
org.eclipse.core.runtime.IProgressMonitor monitor)
Schedule synchronization of a Jazz item with the state of an external
object.
|
IExternalProxy |
IInteropManager.synchronizeIncomingAndWait(IExternalProxyHandle proxyHandle,
IExternalStateHandle xstateHandle,
IAuditableHandle syncedItemStateHandle,
ISyncRuleHandle syncRuleHandle,
org.eclipse.core.runtime.IProgressMonitor monitor)
Schedule synchronization of a Jazz item with the state of an external
object, and wait for the request to complete.
|
| Modifier and Type | Interface and Description |
|---|---|
interface |
IExternalProxy
Class to represent a proxy for an external object that is being replicated
in the Jazz repository, and possibly synchronized with a Jazz item.
|
interface |
IExternalProxyHandle
Represents a handle to an Item proxy.
|
interface |
IExternalState
Class to represent the replicated state associated with a proxy for
an external object.
|
interface |
IExternalStateHandle
A handle for an IExternalState item.
|
interface |
ISyncRule
A synchronization rule defines how external object properties and Jazz item
properties are transformed into each other.
|
interface |
ISyncRuleHandle
Handle for an ISyncRule item.
|
| Modifier and Type | Method and Description |
|---|---|
void |
IInteropService.synchronizeIncoming(IExternalProxyHandle proxyHandle,
IExternalStateHandle xstateHandle,
IAuditableHandle syncedItemStateHandle,
ISyncRuleHandle syncRuleHandle)
Schedule synchronization of a Jazz item with the state of an external
object.
|
IExternalProxy |
IInteropService.synchronizeIncomingAndWait(IExternalProxyHandle proxyHandle,
IExternalStateHandle xstateHandle,
IAuditableHandle syncedItemStateHandle,
ISyncRuleHandle syncRuleHandle)
Schedule synchronization of a Jazz item with the state of an external
object, and wait for the request to complete.
|
| Modifier and Type | Interface and Description |
|---|---|
interface |
IAccessGroup
An access group represents a group of items that are used as a context to provide read access
to one or more items.
|
interface |
IAccessGroupHandle
Handle to an
IAccessGroup . |
interface |
IDevelopmentLine
A project area development line.
|
interface |
IDevelopmentLineHandle
Handle to an
IDevelopmentLine . |
interface |
IIteration
An iteration in a project area.
|
interface |
IIterationHandle
Handle to an
IIteration . |
interface |
IIterationType
A type of iteration.
|
interface |
IIterationTypeHandle
Handle to an
IIterationType . |
interface |
IProcessArea
Common interface for project and team areas.
|
interface |
IProcessAreaHandle
Handle to an
IProcessArea . |
interface |
IProcessAttachment
A process attachment allows content to be associated with a process container
at a path which is specified relative to the container.
|
interface |
IProcessAttachmentHandle |
interface |
IProcessContainer
A mix-in interface for process items that contain process data.
|
interface |
IProcessContainerHandle |
interface |
IProcessDefinition
A process definition consists of
the process id
the definition of the process details
the schema of the settings the process supports
the list of process domains belonging to this process
As the set of item types and platform operations is extensible, the
activities and resources governed by a process are extensible.
|
interface |
IProcessDefinitionHandle |
interface |
IProcessItem
Supertype for all auditable items introduced by the team process support.
|
interface |
IProcessItemHandle |
interface |
IProjectArea
A project area is owned by a project team and contains or references all
artifacts and all relationships between these artifacts that constitute the
resources of a development project.
|
interface |
IProjectAreaHandle |
interface |
IProjectLink
A project link.
|
interface |
IProjectLinkHandle
Handle to an
IProjectLink . |
interface |
IReadAccessList
A list of contributors who have read access to a project area.
|
interface |
IReadAccessListHandle |
interface |
ITeamArea
A team area defines the resort of a team inside a project area.
|
interface |
ITeamAreaHandle |
| Modifier and Type | Method and Description |
|---|---|
java.util.List |
IItemManager.fetchAllStateHandles(IAuditableHandle itemHandle,
org.eclipse.core.runtime.IProgressMonitor monitor)
Retrieves the full history of the given auditable item.
|
IAuditable |
IItemManager.fetchCompleteState(IAuditableHandle itemHandle,
org.eclipse.core.runtime.IProgressMonitor monitor)
Retrieves the specified state of the item with the specified item type
and item id and state id; the resulting item is complete (has all its
properties).
|
IAuditable |
IItemManager.fetchPartialState(IAuditableHandle itemHandle,
java.util.Collection requiredProperties,
org.eclipse.core.runtime.IProgressMonitor monitor)
Retrieves the specified state of the item with the specified item type
and item id and state id; the resulting item may be partial, but will
have at least the given list of properties.
|
| Modifier and Type | Interface and Description |
|---|---|
interface |
IAuditable
Represents an auditable item.
|
interface |
IAuditableBaseline
An auditable baseline is a collection of specific states of a group of
auditable items.
|
interface |
IAuditableBaselineHandle
Represents a handle to an auditable baseline item; see
IAuditableBaseline . |
interface |
IContributor
Represents a contributor known to the repository.
|
interface |
IContributorDetails
Represents a contributor extension known to the repository.
|
interface |
IContributorDetailsHandle
Represents a handle to a contributor extension item.
|
interface |
IContributorGroup |
interface |
IContributorGroupHandle |
interface |
IContributorHandle
Represents a handle to a contributor item.
|
interface |
IContributorRecord
Represents a contributor known to the repository.
|
interface |
IContributorRecordHandle
Represents a handle to a contributor record item.
|
interface |
IRepositoryRoot
Represents the root of the repository.
|
interface |
IRepositoryRootHandle
Represents a handle to a repository root item.
|
| Modifier and Type | Method and Description |
|---|---|
IAuditableHandle |
IBaselineMemberComparison.getAfterState()
Get the state of the item present in the prior baseline.
|
IAuditableHandle |
IBaselineMemberComparison.getItem()
Get the item being compared.
|
IAuditableHandle |
IAuditable.getMergePredecessorState()
Returns the secondary merge predecessor state of this auditable item
state.
|
IAuditableHandle |
IAuditable.getPredecessorState()
Returns the primary predecessor state of this auditable item state.
|
IAuditableHandle |
IBaselineMemberComparison.getPriorState()
Get the state of the item present in the prior baseline.
|
IAuditableHandle |
IChangeEvent.getProcessArea()
Returns a reference to the process area that this ChangeEvent is associated
to.
|
| Modifier and Type | Method and Description |
|---|---|
void |
IChangeEvent.setProcessArea(IAuditableHandle processArea)
Sets the process area to be associated to this event.
|
| Modifier and Type | Method and Description |
|---|---|
IAuditableHandle |
IFlowNodeConnection.getOwner()
Returns a handle to the auditable item that owns the flow node.
|
| Modifier and Type | Method and Description |
|---|---|
java.util.List<IAuditableHandle> |
IWorkspaceManager.findOwnersForComponents(java.util.List<? extends IComponentHandle> components,
org.eclipse.core.runtime.IProgressMonitor progressMonitor)
Finds and retrieves owners for specified components in the repository.
|
| Modifier and Type | Method and Description |
|---|---|
IWorkspaceConnection |
IWorkspaceManager.copyWorkspace(IAuditableHandle scopeHandle,
IWorkspaceConnection peerWorkspaceConnection,
java.lang.String workspaceName,
java.lang.String description,
org.eclipse.core.runtime.IProgressMonitor progressMonitor)
Creates the workspace by cloning another workspace.
|
IComponent |
IWorkspaceManager.createComponent(java.lang.String componentName,
IAuditableHandle ownerHandle,
org.eclipse.core.runtime.IProgressMonitor progressMonitor)
Creates a new component in the repository, with the given name and owner.
|
com.ibm.team.scm.common.IQueryItem |
IWorkspaceManager.createQueryItem(java.lang.String queryName,
java.lang.String queryDescription,
IAuditableHandle ownerHandle,
IReadScope readScope,
com.ibm.team.scm.common.dto.IItemSearchCriteria searchCriteria,
org.eclipse.core.runtime.IProgressMonitor progressMonitor)
Creates a new SCM QueryItem in the repository.
|
java.util.Set |
IWorkspaceManager.findAllWorkspaceNames(IAuditableHandle scopeHandle,
org.eclipse.core.runtime.IProgressMonitor progressMonitor)
Finds the names for workspaces available in the repository.
|
java.util.List |
IWorkspaceManager.findAllWorkspaces(IAuditableHandle scopeHandle,
java.lang.String namePattern,
org.eclipse.core.runtime.IProgressMonitor progressMonitor)
|
java.util.List |
IWorkspaceManager.findComponents(java.lang.String namePattern,
IAuditableHandle owner,
boolean exact,
org.eclipse.core.runtime.IProgressMonitor progressMonitor)
|
java.util.List |
IWorkspaceManager.findWorkspaceAcceptRelationships(IWorkspaceHandle workspaceHandle,
IAuditableHandle ownerFilter,
org.eclipse.core.runtime.IProgressMonitor progressMonitor)
|
java.util.List |
IWorkspaceManager.findWorkspaceDeliverRelationships(IWorkspaceHandle workspaceHandle,
IAuditableHandle ownerFilter,
org.eclipse.core.runtime.IProgressMonitor progressMonitor)
|
void |
IWorkspaceManager.setComponentOwner(IComponentHandle component,
IAuditableHandle newOwnerHandle,
org.eclipse.core.runtime.IProgressMonitor progressMonitor)
Sets the owner of a component in the repository.
|
void |
IWorkspaceManager.setComponentOwnerAndVisibility(IComponentHandle comp,
IAuditableHandle newOwner,
IReadScope newScope,
org.eclipse.core.runtime.IProgressMonitor progress)
Set the owner and visibility of the given component.
|
void |
IFlowNodeConnection.setOwner(IAuditableHandle owner,
org.eclipse.core.runtime.IProgressMonitor monitor)
Sets the flow node's owner.
|
void |
IWorkspaceConnection.setOwnerAndVisibility(IAuditableHandle newOwner,
IReadScope newScope,
org.eclipse.core.runtime.IProgressMonitor mon)
Set the owner and visibility for this workspace.
|
com.ibm.team.scm.common.IQueryItem |
IWorkspaceManager.updateQueryItem(com.ibm.team.scm.common.IQueryItem queryItem,
java.lang.String queryName,
java.lang.String queryDescription,
IAuditableHandle ownerHandle,
IReadScope readScope,
com.ibm.team.scm.common.dto.IItemSearchCriteria searchCriteria,
org.eclipse.core.runtime.IProgressMonitor progressMonitor)
Updates an existing SCM QueryItem.
|
| Modifier and Type | Interface and Description |
|---|---|
interface |
IBaseline
A Baseline represents an immutable Configuration of a set of Versionables
(i.e. it records the StateId of a subset of the Versionables in a
Repository), and the history of ChangeSets which led up to the Configuration.
|
interface |
IBaselineHandle
Represents a handle to a baseline item.
|
interface |
IChangeSet
Represents a change set.
|
interface |
IChangeSetHandle
Represents a handle to a change set item.
|
interface |
IComponent
Represents a component known to the repository.
|
interface |
IComponentHandle
Represents a handle to a component item.
|
| Modifier and Type | Method and Description |
|---|---|
IAuditableHandle |
IWorkspace.getOwner()
Returns a handle to the auditable item that owns the
IWorkspace . |
IAuditableHandle |
IWorkspace.getProcessAreaScope() |
| Modifier and Type | Method and Description |
|---|---|
IAuditableHandle |
IPublicScope.getOwner()
Return the owner of the associated item.
|
IAuditableHandle |
IProcessAreaScope.getProcessArea()
Gets the owner of the item - which is also the read scope of the item.
|
IAuditableHandle |
IContributorDeferringScope.getScope()
Get the scope of the item - this is not the owner, but the process area
that decide's read permissions.
|
IAuditableHandle |
ITeamAreaPrivateScope.getTeamArea()
Return the team area that decides the user's permissions.
|
| Modifier and Type | Method and Description |
|---|---|
java.util.List<IAuditableHandle> |
IComponentSearchCriteria.getFilterByOwnerOptional() |
java.util.List<IAuditableHandle> |
IWorkspaceSearchCriteria.getFilterByOwnerOptional() |
| Modifier and Type | Method and Description |
|---|---|
void |
IContributorDeferringScope.setScope(IAuditableHandle createItemHandle)
Set the
IProjectAreaHandle that the contributor is deferring
read access control. |
| Modifier and Type | Method and Description |
|---|---|
<T extends IAuditable> |
IAuditableClient.fetchCurrentAuditable(IAuditableHandle handle,
ItemProfile<T> profile,
org.eclipse.core.runtime.IProgressMonitor monitor) |
<T extends IAuditable> |
IAuditableClient.findCachedAuditable(IAuditableHandle handle,
ItemProfile<T> profile) |
IAuditable |
IDependentItems.get(IAuditableHandle handle) |
IAuditable |
IDependentItems.remove(IAuditableHandle handle) |
| Modifier and Type | Method and Description |
|---|---|
<T extends IAuditable> |
IAuditableClient.fetchCurrentAuditables(java.util.List<? extends IAuditableHandle> handles,
ItemProfile<T> profile,
org.eclipse.core.runtime.IProgressMonitor monitor) |
<T extends IAuditable> |
IAuditableClient.findCachedAuditables(java.util.List<? extends IAuditableHandle> handles,
ItemProfile<T> profile) |
| Modifier and Type | Method and Description |
|---|---|
IAuditableHandle |
IAuditableCommon.createAuditableHandle(IItemType itemType,
UUID itemUuid,
UUID stateUuid) |
| Modifier and Type | Method and Description |
|---|---|
<T extends IAuditable> |
IAuditableCommon.findCachedAuditable(IAuditableHandle handle,
ItemProfile<T> profile) |
ISaveParameter |
ISaveOperationParameter.findSaveParameter(IAuditableHandle handle) |
<T extends IAuditable> |
IAuditableCommon.resolveAuditable(IAuditableHandle handle,
ItemProfile<T> profile,
org.eclipse.core.runtime.IProgressMonitor monitor) |
| Modifier and Type | Method and Description |
|---|---|
java.util.List<IQueryDescriptor> |
IQueryCommon.findQuickPlannerSharedQueries(IProjectAreaHandle projectAreaHandle,
java.util.List<? extends IAuditableHandle> sharingTargets,
java.lang.String queryType,
ItemProfile<IQueryDescriptor> profile,
org.eclipse.core.runtime.IProgressMonitor monitor)
Deprecated.
- Quick planner apis are deprecated and are not supposed to be used.
|
java.util.List<IQueryDescriptor> |
IQueryCommon.findSharedQueries(IProjectAreaHandle projectAreaHandle,
java.util.List<? extends IAuditableHandle> sharingTargets,
java.lang.String queryType,
ItemProfile<IQueryDescriptor> profile,
org.eclipse.core.runtime.IProgressMonitor monitor) |
<T extends IAuditable> |
IAuditableCommon.resolveAuditables(java.util.List<? extends IAuditableHandle> handles,
ItemProfile<T> profile,
org.eclipse.core.runtime.IProgressMonitor monitor) |
<T extends IAuditable> |
IAuditableCommon.resolveAuditables2(java.util.List<? extends IAuditableHandle> handles,
ItemProfile<T> profile,
int flags,
org.eclipse.core.runtime.IProgressMonitor monitor)
Fetches the latest states of requested auditables using the provided profile
|
<T extends IAuditable> |
IAuditableCommon.resolveAuditablesPermissionAware(java.util.List<? extends IAuditableHandle> handles,
ItemProfile<T> profile,
org.eclipse.core.runtime.IProgressMonitor monitor) |
| Modifier and Type | Interface and Description |
|---|---|
interface |
IAttachment |
interface |
IAttachmentHandle
An attachment handle is used for referencing an attachmen by item id
or a particular state of an attachment by item and state ids.
|
interface |
IAttribute
An attribute of a work item.
|
interface |
IAttributeHandle
An attribute handle is used for referencing an attribute by item id
or a particular state of an attribute by item and state ids.
|
interface |
ICategory
A category of work items.
|
interface |
ICategoryHandle
A category handle is used for referencing a category by item id
or a particular state of a category by item and state ids.
|
interface |
IDeliverable
A deliverable represents a release like a milestone or final release.
|
interface |
IDeliverableHandle
A deliverable handle is used for referencing a deliverable by item id
or a particular state of a deliverable by item and state ids.
|
interface |
ITimeSheetEntry |
interface |
ITimeSheetEntryHandle |
interface |
IWorkItem
A work item represents a piece of work in a certain state (like new, in progress, done).
|
interface |
IWorkItemHandle
A work item handle is used for referencing a work item by item id
or a particular state of a work item by item and state ids.
|
| Modifier and Type | Method and Description |
|---|---|
java.util.List<IAuditableHandle> |
PendingItemChangesException.getItemHandles() |
| Constructor and Description |
|---|
PendingItemChangesException(java.lang.Object origin,
java.util.List<IAuditableHandle> itemHandles) |
| Modifier and Type | Interface and Description |
|---|---|
interface |
IQueryDescriptor |
interface |
IQueryDescriptorHandle |
| Modifier and Type | Method and Description |
|---|---|
IAuditableHandle |
IAssociation.getTarget() |
| Modifier and Type | Method and Description |
|---|---|
boolean |
IAssociations.containsTarget(IAuditableHandle target) |
IAssociation |
IAssociations.createAssociation(IAuditableHandle handle) |


FEATURES
Convenient
Pick up and delivery at your doorstep
Quality Assurance
Quality dry cleaning, steam pressing and folding
Timely return
Delivered within 2 days
Range
All types of fabrics and materials, from bedsheets to suits, accepted
PRICES
Dry cleaning
|
Rs. 15/- per garment |
|
Rs. 20/- per garment |
Steam pressing
|
Rs. 6/- per garment |
|
Rs. 10/- per garment |
About
Laundry Service is an affordable and convenient way to manage your laundry from the comfort of your home. The owner, Mr. Kanojia, has been running this business since the past 17 years and thus understands the importance of customer loyalty and reasonable prices. They offer their services primarily in Kharghar, commonly in sectors 20 to 25.
Operating hours
7 am to 10 pm
Calling hours
7 am to 11 pm
Office
Shri Vidyadaan CHS Ltd, Sector 21, Kharghar, Navi Mumbai, Maharashtra 410210


I love talking with founders about their startup plans. If you have questions, and want an honest, no-strings-attached chat with a developer who understands business, I have some time coming up next week. Fill out the form below, and we can pencil in a time to talk to see if there’s a fit.


When I was a kid, I was a Boy Scout. I made it pretty far too, but then I became a teenager, decided it was “lame,” and quit. As a Boy Scout, I learned how to tie knots, camp outdoors, be a good citizen, play with knives, and got to have cool sleepovers. One of the most important things you learn as a Boy Scout is their motto to always “be prepared,” and as I’ve grown up and traveled the world, I’ve found this to also be a travel truism.
You never know what might happen on the road. Stepping out your door into the unknown is what makes travel so exciting. Each day brings endless possibility, but that possibility is for both good and bad. You may end up enjoying a day sightseeing in Paris — or getting robbed in Berlin. You may spend an amazing day on the beaches of Thailand — or suffer food poisoning in Costa Rica.
But if you’re prepared, you’ll be able to face whatever happens to you on the road:
1] Take Multipurpose Gear. Packing multiuse gear ensures you can easily adjust to changing conditions and helps reduce the amount of clothing you need to take. I like pants that zip off into shorts, walking shoes that look nice enough for an evening out, and using my swim trunks as a pair of shorts. It saves room, and I’m prepared for any dress situation.
2] Carry a Small First Aid Kit. While we live in 2012, not 1912, and you can find modern medicine anywhere in the world, I always carry a small first aid kit with me with a few essential items to be safe. I take Tylenol, stomach illness medicine, eyedrops, Band-Aids, scissors, hydrocortisone cream, antibacterial ointment, and a small supply of doctor-approved antibiotics. I’m usually able to find a pharmacy when I need one, but in case of an emergency, it’s good to have these items handy.
3] Pack a Small Flashlight.You’d be surprised how many travelers don’t carry one, but a flashlight will prove to be invaluable when you suddenly decide to go caving in Panama, when your hike lasts longer than expected and nightfall sets in, or when the electricity goes out unexpectedly, which is not uncommon in a lot of places. I carry a small, waterproof pen flashlight when I travel.
4] Bring an Umbrella. Many travelers don’t pack an umbrella because it adds weight to their bag, and they figure they can just buy one if they ever need it. However, while it does add a small amount of weight, I’ve found myself thankful for taking it more times than I can count. You never know when you might be exiting an airport or walking down the street and find yourself in a sudden storm. While others run for cover, I simply take out my umbrella and continue to my destination.
5] Learn Basic Phrases. Locals don’t expect you to be an expert in their language, but knowing how to say “hello,” “goodbye,” and “thank you” go a long way in endearing yourself to locals. After all, wouldn’t you be annoyed if someone came to your home and expected you to know their language? Knowing a few key phrases will not only make interactions easier, it will also help you when you bargain for goods, order food, get lost, or need help. I download the latest language app for my iPhone when I travel, but for those not using a smartphone, Lonely Planet guidebooks makes excellent pocket language guides for just about every language spoken, and Benny Lewis wrote this excellent guide on learning languages.
6] Study Nonverbal Communication.Most people interact using both verbal and nonverbal communication, so paying attention to facial expressions can help you appropriately read a situation, even if you don’t understand the verbal part. When you don’t know the language or might take words out of context, keep calm and take a moment to read the feelings of the person. This has helped me defuse tense situations with taxi drivers, vendors, and hotel owners. Understanding nonverbal communication doesn’t happen overnight. It takes practice, but these websites offer good guides on how to understand nonverbal cues.
7] Keep Emergency Cash with You.While there is almost always an ATM around these days, you never know when emergency cash might come in handy. You could end up in an airport (like I recently did) and find that none of your ATM cards work and you are stuck without any money. I recommend having a stash of $200 USD for emergency situations. I don’t carry this money around but leave it in my hotel room safe in case something happens. It will be useful if you get robbed or lose your wallet.
8] Have Backup Cards.I always keep one backup credit card and bank card with me in case of emergencies. You never know when one bank might decide to lock your account for suspicious activity without telling you (yes, that has also happened to me) or when you might get robbed. I recently had my bank account information stolen while I was traveling in Europe. My bank had to deactivate my card, and if I hadn’t had a second one with me, I wouldn’t have had access to any money.
9] Carry Cash.With the advent of the chip credit card, many countries don’t take the American-style credit card anymore (cards with just a magnetic strip). While you should be able to use a credit card pretty much everywhere, you never know when you might not. One of my cards was rejected in Denmark because it lacked a chip, and I had to run to a bank to get money. We get used to using credit cards, but it’s always good to have a little cash.
10] Make Extra Copies.Keeping copies of your documents can come in handy during an emergency, especially if you lose your originals. If you get robbed or lose your passport, having copies ready for officials can make filing police reports and obtaining new documents much easier. When I lost my passport, my backup copies helped with my police report and served as my proof of identity at the American embassy. Copy your passport, your health/travel insurance paperwork, and your credit cards.


General Electric, Financial Management Program (FMP)
Northeastern University, Finance & Investments; Accounting