class ContactsTxt

Attributes

to_s[R]

Public Class Methods

new(src=nil, fields: %w(role organisation mobile sms email dob tags address notes note mobile2 ), username: nil, password: nil, debug: false) click to toggle source
# File lib/contacts_txt.rb, line 13
def initialize(src=nil, fields: %w(role organisation mobile 
               sms email dob tags address notes note mobile2 ), 
               username: nil, password: nil, debug: false)
  
  @debug = debug
  @fields  = %w(fullname firstname lastname tel) | fields

  txt, type = if src then
    RXFHelper.read(src, username: username, password: password)
  else
    ['', :unknown]
  end
  
  case type
  when :file
    @path, @filename =  File.dirname(src), File.basename(src)
  when :url
    @path, @filename = '.', File.basename(src)
  when :dfs
    @path, @filename =  File.dirname(src), File.basename(src)
  when :unknown
    @path, @filename = '.', 'contacts.txt'
  end
  
  @dx = txt.lines.length > 1 ? import_to_dx(txt) : new_dx()

end

Public Instance Methods

all() click to toggle source
# File lib/contacts_txt.rb, line 41
def all()
  @dx.all
end
dx() click to toggle source
# File lib/contacts_txt.rb, line 45
def dx()
  @dx
end
email_list() click to toggle source

returns a Dynarex object

# File lib/contacts_txt.rb, line 115
def email_list()
  @dx.filter {|x| x.email.length > 0}
end
find_by_id(id) click to toggle source
# File lib/contacts_txt.rb, line 49
def find_by_id(id)
  
  @dx.find_by_id id
  
end
find_by_mobile(raw_number, countrycode='44') click to toggle source
# File lib/contacts_txt.rb, line 55
def find_by_mobile(raw_number, countrycode='44')

  number = Regexp.new raw_number.sub(/^(?:0|#{countrycode})/,'').gsub(/[ -]*/,'')
  
  @dx.all.find {|x| x.mobile.gsub(/[ -]*/,'') =~ number }    

end
find_by_name(s) click to toggle source
# File lib/contacts_txt.rb, line 63
def find_by_name(s)

  # Appending a hashtag to the name can help with finding the specific record
  # e.g. 'Peter#plumber' or 'Peter #plumber'
  
  raw_name, tag = s.split('#',2).map(&:strip)
  
  name = Regexp.new "\b#{raw_name}\b|#{raw_name}",  Regexp::IGNORECASE
  puts 'name: ' + name.inspect if @debug
  
  a = @dx.all.select do |x| 
    x.fullname =~ name or x.firstname =~ name or x.lastname =~ name
  end
  
  if tag then
    a.find {|x| x.tags.split.map(&:downcase).include? tag.downcase } 
  else
    a
  end

end
find_by_sms(raw_number, countrycode='44') click to toggle source
# File lib/contacts_txt.rb, line 85
def find_by_sms(raw_number, countrycode='44')

  number = Regexp.new raw_number\
      .sub(/^(?:0|#{countrycode})/,'').gsub(/[ -]*/,'')
  
  @dx.all.find {|x| x.sms.gsub(/[ -]*/,'') =~ number \
                or x.mobile.gsub(/[ -]*/,'') =~ number }    

end
find_by_telno(raw_number) click to toggle source

find using the tel, mobile, or mobile2 fields

# File lib/contacts_txt.rb, line 97
def find_by_telno(raw_number)

  number = Regexp.new raw_number.gsub(/[ -]*/,'')
  
  @dx.all.find do |x|
          
    numbers = %i(tel mobile mobile2).map do |y|
      x.method(y).call.gsub(/[ -]*/,'') if x.respond_to? y
    end
    
    puts 'numbers: ' + numbers.inspect if @debug
    numbers.grep(number).any?
  end

end
list_names() click to toggle source
# File lib/contacts_txt.rb, line 119
def list_names()
  
  @dx.all.inject([]) do |r, x|
    x.fullname.length >= 1 ? r << x.fullname : r
  end

end
mobile_list() click to toggle source
# File lib/contacts_txt.rb, line 127
def mobile_list()
  @dx.filter {|x| x.mobile.length > 0}
end
multi_tel_index() click to toggle source
# File lib/contacts_txt.rb, line 131
def multi_tel_index()

  a = @dx.all.map do |x|

    tel = %i(tel mobile mobile2).detect do |name|
      !x.method(name).call.empty?
    end
    next unless tel
    "%s %s" % [x.fullname, x.method(tel).call]
  end.compact 


  # group by first name
  r = a.group_by {|x| x[0]}

  a2 = a.clone

  # group by last name
  r2 = a.group_by {|x| x.split(/ /,2).last[0]}
  c = r2.merge(r)

  c.each do |k, v|

    puts "k: %s v: %s" % [k, v]
    v.concat(r2[k]) if r2[k]  
    
  end

  h = c.sort.each {|k,v| v.uniq!}.to_h

  out = []

  h.each do |k,v|

    out << ' ' + (' ' * 30) + k

    v.each do |x|

      name, phone = x.split(/(?=\d)/,2)
      out << "\n" + (name.length >= 29 ? name[0..26] + '...' : name)
      tel = (' ' + ' ' * (26 - phone.length)) + 't: ' + phone
      out <<  tel + "\n"
      out << ('-' * 30) 

    end  

  end

  puts out.join("\n")

end
save(filename=@filename) click to toggle source
# File lib/contacts_txt.rb, line 183
def save(filename=@filename)
  
  s = dx_to_s(@dx)
  FileX.write File.join(@path, filename), s
  @dx.save File.join(@path, filename.sub(/\.txt$/,'.xml'))
      
end
to_dx() click to toggle source
# File lib/contacts_txt.rb, line 191
def to_dx()
  @dx
end

Private Instance Methods

dx_to_s(dx) click to toggle source
# File lib/contacts_txt.rb, line 201
def dx_to_s(dx)
  
  rows = dx.all.map do |row|
    
    h = row.to_h

    fullname = h.delete :fullname
    h.delete :firstname
    h.delete :lastname
    a = h.to_a.reject! {|k,v| v.empty?}

    ([fullname] + a.map {|x| x.join(': ') }).join("\n")
  end
  
  "<?contacts fields='%s'?>\n\n%s" % [@fields, rows.join("\n\n")]
  
end
import_to_dx(raw_s) click to toggle source
# File lib/contacts_txt.rb, line 219
def import_to_dx(raw_s)

  s = if raw_s =~ /<?contacts / then

    raw_contacts = raw_s.clone
    s2 = raw_contacts.slice!(/<\?contacts [^>]+\?>/)

    attributes = %w(fields delimiter id).inject({}) do |r, keyword|
      found = s2[/(?<=#{keyword}=['"])[^'"]+/]
      found ? r.merge(keyword.to_sym => found) : r
    end
    
    h = {
      fields: @fields.join(', '), 
    }.merge attributes          

    @fields = h[:fields].split(/ *, */)      

    if h[:root] then
      "\n\n" + h[:root] + "\n" + 
        raw_contacts.strip.lines.map {|line| '  ' + line}.join
    else
      raw_contacts
    end
    
  else
    
    raw_s.lstrip.lines[2..-1].join.strip

  end

  new_dx().import  "--+\n" + s.split(/\s+(?=^[\w\s\(\)]+$)/)\
    .map {|x| 'fullname: ' + x }.join("\n")    
  
end
new_dx() click to toggle source
# File lib/contacts_txt.rb, line 255
def new_dx()
  
  Dynarex.new "contacts/contact(#{@fields.join ', '})"
  
end