Saturday, June 25, 2016

ASA notes - add recognition of UAS sku before pw2017 launch




  1. investigate uas sku empty product request
    1. no db yet
    2. no uas codes in the wild before
    3. need to notify user when act code is entered into reg grid
    4. strategy
      1. user enters uas code iinto 2017_000
      2. show mbox
      3. initiate call to updates


Friday, June 24, 2016

cannoli-notifications-test.rb


#!/usr/bin/env ruby

warning_lvls = {"Info"=>3, "Warning"=>2, "Critical"=>1}

# this is just BS to simulate an array of rows in the database
rows = [
"Server1, C, 60, Info",
"Server1, C, 70, Warning",
"Server1, C, 90, Critical",
"Server1, D, 90, Critical",
"Server2, E, 80, Critical",
"Server3, F, 70, Warning",
"Server3, F, 85, Critical",
"Server4, F, 63, Info",
"Server4, F, 74, Warning",
]

seen = {}

# init the seen hash with empty arrays for values
rows.each do |row|
  cols = row.split(/,\s+/)
  server = cols[0]
  drive_letter = cols[1]
  key = "#{server}-#{drive_letter}"
  seen[key] = []
end

# add dicts for the appropriate key of the seen hash
rows.each do |row|
  cols = row.split(/,\s+/)
  server = cols[0]
  drive_letter = cols[1]
  percent_full = cols[2]
  warning_lvl_word = cols[3]
  warning_lvl_int = warning_lvls[warning_lvl_word]
  key = "#{server}-#{drive_letter}"

  dict = { server_drive:key, 
    percent_full:percent_full, 
    warning_lvl_int:warning_lvl_int, 
    warning_lvl_word:warning_lvl_word }

  seen[key] << dict
end

# print out only the top priority item for each server-drive combo
seen.each_pair do |key, val|
  puts "key=#{key}"
  puts "val=#{val}"
  # sort an array of hashes by one of the fields of the hash
  sorted = val.sort_by! { |dict| dict[:warning_lvl_int] }
  puts "sorted=#{sorted}"
  top_priority = sorted.first
  puts "top_priority=#{top_priority}"
  msg = "#{top_priority[:warning_lvl_word]}: #{top_priority[:server_drive]} #{top_priority[:percent_full]}% full"
  puts "#{msg}\n\n"
end




# output:
# key=Server1-C
# val=[{:server_drive=>"Server1-C", :percent_full=>"60", :warning_lvl_int=>3, :warning_lvl_word=>"Info"}, {:server_drive=>"Server1-C", :percent_full=>"70", :warning_lvl_int=>2, :warning_lvl_word=>"Warning"}, {:server_drive=>"Server1-C", :percent_full=>"90", :warning_lvl_int=>1, :warning_lvl_word=>"Critical"}]
# sorted=[{:server_drive=>"Server1-C", :percent_full=>"90", :warning_lvl_int=>1, :warning_lvl_word=>"Critical"}, {:server_drive=>"Server1-C", :percent_full=>"70", :warning_lvl_int=>2, :warning_lvl_word=>"Warning"}, {:server_drive=>"Server1-C", :percent_full=>"60", :warning_lvl_int=>3, :warning_lvl_word=>"Info"}]
# top_priority={:server_drive=>"Server1-C", :percent_full=>"90", :warning_lvl_int=>1, :warning_lvl_word=>"Critical"}
# Critical: Server1-C 90% full

# key=Server1-D
# val=[{:server_drive=>"Server1-D", :percent_full=>"90", :warning_lvl_int=>1, :warning_lvl_word=>"Critical"}]
# sorted=[{:server_drive=>"Server1-D", :percent_full=>"90", :warning_lvl_int=>1, :warning_lvl_word=>"Critical"}]
# top_priority={:server_drive=>"Server1-D", :percent_full=>"90", :warning_lvl_int=>1, :warning_lvl_word=>"Critical"}
# Critical: Server1-D 90% full

# key=Server2-E
# val=[{:server_drive=>"Server2-E", :percent_full=>"80", :warning_lvl_int=>1, :warning_lvl_word=>"Critical"}]
# sorted=[{:server_drive=>"Server2-E", :percent_full=>"80", :warning_lvl_int=>1, :warning_lvl_word=>"Critical"}]
# top_priority={:server_drive=>"Server2-E", :percent_full=>"80", :warning_lvl_int=>1, :warning_lvl_word=>"Critical"}
# Critical: Server2-E 80% full

# key=Server3-F
# val=[{:server_drive=>"Server3-F", :percent_full=>"70", :warning_lvl_int=>2, :warning_lvl_word=>"Warning"}, {:server_drive=>"Server3-F", :percent_full=>"85", :warning_lvl_int=>1, :warning_lvl_word=>"Critical"}]
# sorted=[{:server_drive=>"Server3-F", :percent_full=>"85", :warning_lvl_int=>1, :warning_lvl_word=>"Critical"}, {:server_drive=>"Server3-F", :percent_full=>"70", :warning_lvl_int=>2, :warning_lvl_word=>"Warning"}]
# top_priority={:server_drive=>"Server3-F", :percent_full=>"85", :warning_lvl_int=>1, :warning_lvl_word=>"Critical"}
# Critical: Server3-F 85% full

# key=Server4-F
# val=[{:server_drive=>"Server4-F", :percent_full=>"63", :warning_lvl_int=>3, :warning_lvl_word=>"Info"}, {:server_drive=>"Server4-F", :percent_full=>"74", :warning_lvl_int=>2, :warning_lvl_word=>"Warning"}]
# sorted=[{:server_drive=>"Server4-F", :percent_full=>"74", :warning_lvl_int=>2, :warning_lvl_word=>"Warning"}, {:server_drive=>"Server4-F", :percent_full=>"63", :warning_lvl_int=>3, :warning_lvl_word=>"Info"}]
# top_priority={:server_drive=>"Server4-F", :percent_full=>"74", :warning_lvl_int=>2, :warning_lvl_word=>"Warning"}
# Warning: Server4-F 74% full












Monday, June 20, 2016

ASA support - error downloading prepware installer using windows 10 Edge browser



root cause: use of a SHA-1 cert for signing.

http://www.irisbg.com/support/?topic=download-with-ie-or-edge-signature-is-corrupt-or-invalid


From January 2016, you may have been given a warning that reads “Signature is corrupt or invalid” when downloading IrisBG software.
Microsoft has from January 1st changed its policy and will no longer automatically trust software the is signed with SHA-1 code signing certificates. We are in the process of switching over to SHA-256 code signing, but in the meantime you will be given a warning that the software signature is corrupt or invalid if you download the software using Internet Explorer or MS Edge.
A workaround is to download the software using another browser.
We will update this post when we have fixed the issue and fresh downloads are available. Thank you for your patience.

Sunday, June 19, 2016

ASA task - transform tpp xml






/Users/smr/current_projects/tpp-xml-transform/


new for 2016-06: S3-based preview workflow

/Users/smr/current_projects/tpp-xml-transform/
/Users/smr/current_projects/tpp-xml-transform/xml-to-html-preview/00-transform-and-upload.command

  1. uses the xml source found in: /Users/smr/current_projects/tpp-xml-transform/xml-source/
  2. inline css
  3. uploads html to http://media.prepware.com.s3.amazonaws.com/tpp-xml-preview




Friday, June 17, 2016

script - copy tpp images from html help folder



#!/usr/bin/env ruby

require 'find'
require "fileutils"

dest_path = "/Users/smr/Desktop/tpp-images/"

ARGV.each do |look_here_path|
  Find.find(look_here_path) do |path|
    if path =~ /\.png|jpg|jpeg/i
      puts "copying #{path}"
      FileUtils.cp path, dest_path
    end
  end
end

Thursday, June 16, 2016

ASA task - create new falcon db


see Prepware Updaters 02-2016 checklists google doc

checklist - create new falcon db (if necessary)

/Users/smr/current_projects/prepware-tools/create-falcon-db/

modify testmaps xls as needed
generate tab-delim txt
e.g. testmaps_2015_rev_b.txt
run 00-create-falcon.command
creates falcon db
adds topics table, referencing tab_delim/*



Wednesday, June 15, 2016

ASA task - add new skus to the act codes app



##################################################
# add new skus to the act codes app
##################################################


# add skus in code
##################################################
registrar

/Users/smr/current_projects/asa-act-codes/actcodes/app/controllers/activation_codes_controller.rb
  def validate_act_code


# add new products to db
##################################################

copy old block as sql
tweak with sublime


old:
INSERT INTO `products` (`id`, `name`, `sku`, `created_at`, `updated_at`)
VALUES
  (33, 'Airframe', 'ASA-TW-AMA-16', '2013-06-12 20:44:15', '2013-06-12 20:44:15'),
  (34, 'General', 'ASA-TW-AMG-16', '2013-06-12 20:44:15', '2013-06-12 20:44:15'),
  (35, 'Powerplant', 'ASA-TW-AMP-16', '2013-06-12 20:44:15', '2013-06-12 20:44:15'),
  (36, 'Aircraft Maintenance Technician', 'ASA-TW-AMT-16', '2013-06-12 20:44:15', '2013-06-12 20:44:15'),
  (37, 'Commercial Pilot', 'ASA-TW-C-16', '2013-06-12 20:44:15', '2013-06-12 20:44:15'),
  (38, 'Certified Flight Instructor', 'ASA-TW-CFI-16', '2013-06-12 20:44:15', '2013-06-12 20:44:15'),
  (39, 'Inspection Authorization', 'ASA-TW-IA-16', '2013-06-12 20:44:15', '2013-06-12 20:44:15'),
  (40, 'Instrument Rating', 'ASA-TW-I-16', '2013-06-12 20:44:15', '2013-06-12 20:44:15'),
  (41, 'Military Competency', 'ASA-TW-MIL-16', '2013-06-12 20:44:15', '2013-06-12 20:44:15'),
  (42, 'Private Pilot', 'ASA-TW-PVT-16', '2013-06-12 20:44:15', '2013-06-12 20:44:15'),
  (43, 'Bundle P-I', 'ASA-TW-PI-16', '2013-06-12 20:44:15', '2013-06-12 20:44:15'),
  (44, 'Bundle P-I-C-CFI', 'ASA-TW-PIC-16', '2013-06-12 20:44:15', '2013-06-12 20:44:15'),
  (45, 'Bundle P-I-C-ATP', 'ASA-TW-PICA-16', '2013-06-12 20:44:15', '2013-06-12 20:44:15'),
  (46, 'ATP and Flight Engineer', 'ASA-TW-ATP-FE-16', '2013-06-12 20:44:15', '2013-06-12 20:44:15');

new:
INSERT INTO `products` (`id`, `name`, `sku`, `created_at`, `updated_at`)
VALUES
  (0, 'Airframe', 'ASA-TW-AMA-17', '2016-06-15 06:55:50', '2016-06-15 06:55:59'),
  (0, 'General', 'ASA-TW-AMG-17', '2016-06-15 06:55:50', '2016-06-15 06:55:59'),
  (0, 'Powerplant', 'ASA-TW-AMP-17', '2016-06-15 06:55:50', '2016-06-15 06:55:59'),
  (0, 'Aircraft Maintenance Technician', 'ASA-TW-AMT-17', '2016-06-15 06:55:50', '2016-06-15 06:55:59'),
  (0, 'Commercial Pilot', 'ASA-TW-C-17', '2016-06-15 06:55:50', '2016-06-15 06:55:59'),
  (0, 'Certified Flight Instructor', 'ASA-TW-CFI-17', '2016-06-15 06:55:50', '2016-06-15 06:55:59'),
  (0, 'Inspection Authorization', 'ASA-TW-IA-17', '2016-06-15 06:55:50', '2016-06-15 06:55:59'),
  (0, 'Instrument Rating', 'ASA-TW-I-17', '2016-06-15 06:55:50', '2016-06-15 06:55:59'),
  (0, 'Military Competency', 'ASA-TW-MIL-17', '2016-06-15 06:55:50', '2016-06-15 06:55:59'),
  (0, 'Private Pilot', 'ASA-TW-PVT-17', '2016-06-15 06:55:50', '2016-06-15 06:55:59'),
  (0, 'Bundle P-I', 'ASA-TW-PI-17', '2016-06-15 06:55:50', '2016-06-15 06:55:59'),
  (0, 'Bundle P-I-C-CFI', 'ASA-TW-PIC-17', '2016-06-15 06:55:50', '2016-06-15 06:55:59'),
  (0, 'Bundle P-I-C-ATP', 'ASA-TW-PICA-17', '2016-06-15 06:55:50', '2016-06-15 06:55:59'),
  (0, 'ATP and Flight Engineer', 'ASA-TW-ATP-FE-17', '2016-06-15 06:55:50', '2016-06-15 06:55:59');

Tuesday, June 14, 2016

ruby sandbox



#docs at
#http://ruby-doc.org/
#http://my.safaribooksonline.com/9780596516178

#a comment
puts "hello world"
print "hello world using print\n"  #print doesn't add a newline

#==============================================================================
#                                                                      integers
#==============================================================================
my_int = 111
puts my_int
puts my_int.class  #integers are objects (returns Fixnum)
puts "my_int=#{my_int}"

s="my string"


#==============================================================================
#                                                                       if else
#==============================================================================
#if else
if my_int == 111
    puts "my_int=111"
elsif my_int == 222
    puts "my_int=222"
else
    puts "my_int=#{my_int}"
end

#short syntax
puts "short if syntax" if true

#==============================================================================
#                                                                        unless
#==============================================================================
x = 1
y = nil
z = 2
unless x == 2
  puts "x is not 2"
end

#==============================================================================
#                                                                          case
#==============================================================================
case
when x == 0
  puts "x is 0"
when x == 1
  puts "x is 1"
when x == 2
  puts "x is 2"
else
  puts "x is not 0, 1, or 2"
end

case x 
when 0
  puts "x is 0"
when 1
  puts "x is 1"
when 2
  puts "x is 2"
else
  puts "x is not 0, 1, or 2"
end

#==============================================================================
#                                                                       ternary
#==============================================================================
puts x == 1 ? "one" : "not one"

#logical
x = y || z
x ||= y  #unless x, x = y

#==============================================================================
#                                                                     do, break
#==============================================================================
#break - terminates the loop
#next - jump to next iteration
#redo - redo this iteration
#retry - start the eholeloop over
x=0
puts "do"
loop do
  x += 2
  break if x >= 10
  puts x
end

#==============================================================================
#                                                               do, break, next
#==============================================================================
x = 0
puts "do, break, next"
loop do
  x += 2
  break if x >= 10
  next if x == 6  #skip this one
  puts x
end

#==============================================================================
#                                                                    N.times do
#==============================================================================
5.times do
  puts "hello"
end

#==============================================================================
#                                                                         while
#==============================================================================
#evaluates at the top of the loop
x = 0
puts "while"
while x < 10
  x += 2
  puts x
end

#==============================================================================
#                                                               iterate with do
#==============================================================================
#access to data in the current iteration with |varname|
#break, next, redo, retry can all be used
puts "iterator"
1.upto(5) do |num|
  puts "Hello " + num.to_s
  puts "num=#{num}"
end

#curly brace syntax:
# 1.upto(5) {
#     |i| puts "hello #" + i.to_s
# }

#==============================================================================
#                                                         iterate with for each
#==============================================================================
fruits = ['banana', 'apple', 'pear']
fruits.each do |fruit|
  puts fruit.capitalize
end

#curly brace syntax:
fruits.each { |fruit|
  puts fruit.upcase
}


#==============================================================================
#                                                           iterate with for in
#==============================================================================
for fruit in fruits
  puts fruit.capitalize
end

#==============================================================================
#                                                       curly brace loop syntax
#==============================================================================
puts "curly brace loop syntax"
5.times {
    puts "hello"
}

1.upto(5) {
    |i| puts "hello #" + i.to_s
}

#==============================================================================
#                                                           scope inside blocks
#==============================================================================
#differs between ruby 1.8.7 and 1.9
i=3
1.upto(5) {
    |i| puts "hello #" + i.to_s  #i goes from 1 to 5
}
#puts i  #with ruby 1.8.7, outputs 5

#==============================================================================
#                                                                   find/detect
#==============================================================================
#look at a set, and grab the *first* one
#returns an object or nil
found = (1..10).find {|i| i == 5 }
puts "found=#{found}"

found = ['dog', 'cat', 'mouse', 'mouse', 'frog'].find {|i| i == 'mouse' }
puts "found=#{found}"
#detect is a synonym for find
detected = ['dog', 'cat', 'mouse', 'mouse', 'frog'].detect {|i| i == 'mouse' }
puts "found=#{found}"

#==============================================================================
#                                                               find_all/select
#==============================================================================
#finds all matches
#returns an array
divisible_by_3 = (1..10).find_all {|i| i % 3 == 0 }
puts divisible_by_3.inspect

#select is a synonym for find_all
divisible_by_3 = (1..10).select {|i| i % 3 == 0 }
puts divisible_by_3.inspect

#==============================================================================
#                                                                       any/all
#==============================================================================
#any? returns a boolean (true if the set contains a match)
found = ['dog', 'cat', 'mouse', 'mouse', 'frog'].any? {|i| i == 'mouse' }
puts found

#all? returns a boolean (true if all elements match)
all_gt_5 = (6..10).all? {|i| i > 5}
puts "all_gt_5=#{all_gt_5}"

#==============================================================================
#                                                                     delete_if
#==============================================================================
#returns an array of items that remain after the deletion
#after_delete = (1..10).delete_if {|i| i % 3 == 0 }  #error, can't call delete_if on a range
after_delete = [*1..10].delete_if {|i| i % 2 == 0 }  #delete even numbers
puts after_delete.inspect



# 
# #a few string methods
# uc_s = s.upcase
# puts "uc_s=#{uc_s}"
# #chaining
# altered = uc_s.downcase.reverse
# puts "altered=#{altered}"


#==============================================================================
#                                                                       sandbox
#==============================================================================
range = (1..10)
array = *range
puts range.inspect
puts array.inspect

array.each do |i|
  puts i
end

5.times do
    puts "hello"
end


adjust grs student record screen for small viewport sizes


evaluate getViewport fn: https://gist.github.com/oorabona/f1a062ce11936c32b51f


/Users/smr/current_projects/pws2016/app/assets/javascripts/viewport.coffee

getViewport = ->
    e = window
    a = "inner"
    unless "innerWidth" of window
      a = "client"
      e = document.documentElement or document.body
    width: e[a + "Width"]
    height: e[a + "Height"]

# https://gist.github.com/oorabona/f1a062ce11936c32b51f
# If you'd like to create top-level variables for other scripts to use, attach
# them as properties on window, or on the exports object in CommonJS.
# window.foo = "Lorem ipsum"
window.getViewport = getViewport


usage:
jQuery ->
  if $('div.ground-school').length
    # tweak layout for small devices
    if window.getViewport().width <= 480
      console.log("narrow")
      $("div.container").removeClass('container')
      $("div.content-wrapper-bordered").removeClass('content-wrapper-bordered')




notes
  1. ASA
    1. grs student record doesn't work for small phones, e.g. iphone5
      1. strategy
        1. for xs, do not render lesson-thumbnails
        2. on page load
          1. detect viewport?
          2. hide/show
          3. remove container classes on page load?


Friday, June 10, 2016

render markdown with a ruby script


#!/usr/bin/env ruby
require "redcarpet"
# https://github.com/vmg/redcarpet
# http://daringfireball.net/projects/markdown/syntax

# Initializes a Markdown parser
renderer = Redcarpet::Render::HTML.new()
markdown = Redcarpet::Markdown.new(renderer, extensions = {})

html = markdown.render("This is *bongos*, indeed.")
puts "html=#{html}"


Monday, June 6, 2016

date needs to be set correctly when installing el capitan from boot disk, fix-os-x-install-errors-cant-be-verified-error-occurred-preparing-mac/



http://osxdaily.com/2015/01/19/fix-os-x-install-errors-cant-be-verified-error-occurred-preparing-mac/


How to make a bootable OS X 10.11 El Capitan installer drive


http://www.macworld.com/article/2981585/operating-systems/how-to-make-a-bootable-os-x-10-11-el-capitan-installer-drive.html




Keep the installer safe

Like all recent versions of OS X, El Capitan is distributed through the Mac App Store: You download an installer app (called Install OS X El Capitan.app) to your Applications folder. In this respect, the OS X installer is just like any other app you buy from the Mac App Store. However, unlike any other app, if you run the OS X installer from that default location, the app deletes itself after it's done installing OS X.
If you plan to use the OS X installer on other Macs, or—in this case—to create a bootable installer drive, be sure to copy the installer to another drive, or at least move it out of the Applications folder, before you use it to install the OS on your Mac. If you don't, you'll have to redownload the installer from the Mac App Store before you can use the instructions below.

Making the installer drive

  1. Connect to your Mac a properly formatted 8GB (or larger) drive, and rename the drive Untitled. (The Terminal commands I provide here assume that the drive is named Untitled. If the drive isn’t named Untitled, the procedure won’t work.)
  2. Make sure the El Capitan installer (or at least a copy of it), called Install OS X El Capitan.app, is in its default location in your main Applications folder (/Applications).
  3. Select the text of the following Terminal command and copy it.
    sudo /Applications/Install\ OS\ X\ El\ Capitan.app/Contents/Resources/createinstallmedia --volume /Volumes/Untitled --applicationpath /Applications/Install\ OS\ X\ El\ Capitan.app --nointeraction
  4. Launch Terminal (in /Applications/Utilities).
  5. Warning: This step will erase the destination drive or partition, so make sure that it doesn’t contain any valuable data. Paste the copied command into Terminal and press Return.
  6. Type your admin-level account password when prompted, and then press Return.
  7. You may see the message “To continue we need to erase the disk at /Volumes/Untitled. If you wish to continue type (Y) then press return:” If so, type the letter Y and then press Return. If you don't see this message, you're already set.

Last login: Mon Jun  6 13:47:18 on ttys005
You have mail.
[smr@macpro ~]$ sudo /Applications/Install\ OS\ X\ El\ Capitan.app/Contents/Resources/createinstallmedia --volume /Volumes/Untitled --applicationpath /Applications/Install\ OS\ X\ El\ Capitan.app --nointeraction
Password:
Erasing Disk: 0%... 10%... 20%... 30%...100%...
Copying installer files to disk...
Copy complete.
Making disk bootable...
Copying boot files...
Copy complete.

Done.

The Terminal window displays createinstallmedia’s progress as a textual representation of a progress bar: Erasing Disk: 0%... 10 percent...20 percent...and so on. You also see a list of the program’s tasks as they occur: Copying installer files to disk... Copy complete. Making disk bootable... Copying boot files... Copy complete. The procedure can take as little as a couple minutes, or as long as 20 to 30 minutes, depending on how fast your Mac can copy data to the destination drive. Once you see Copy Complete. Done., as shown in the screenshot above, the process has finished.
Createinstallmedia will have renamed your drive from Untitled to Install OS X El Capitan. You can rename the drive (in the Finder) if you like—renaming it won’t prevent it from working properly.

Booting from the installer drive

You can boot any El Capitan-compatible Mac from your new installer drive. First, connect the drive to your Mac. Then, restart your Mac (or, if it's currently shut down, start it up) while holding down the Option key. When OS X’s Startup Manager appears, select the installer drive and then click the arrow below it to proceed with startup. (Alternatively, if your Mac is already booted into OS X, you may be able to choose the installer drive in the Startup Disk pane of System Preferences, and then click restart. However, sometimes OS X installer drives don't appear in the Startup Disk window.)
Once booted from your installer drive, you can perform any of the tasks available from the OS X installer’s special recovery and restore features. In fact, you'll see the same OS X Utilities screen you get when you boot into OS X Recovery—but unlike with recovery mode, your bootable installer includes the entire installer.

Check Download Progress on the Mac App Store



http://osxdaily.com/2011/07/27/check-download-progress-mac-app-store/


set complete flag for grs requirements


check:

User.find_by(email:'j.berger343434@gmail.com').grs_courses.first.stages.first.lessons.each{|les| les.requirements.each{|req| puts req.completed  } }


set:
User.find_by(email:'j.berger343434@gmail.com').grs_courses.first.stages.first.lessons.each{|les| les.requirements.each{|req| req.update_attribute(:completed, true)  } }


Thursday, June 2, 2016

ruby script to find images in a file tree



#!/usr/bin/env ruby

require 'find'

ARGV.each do |look_here_path|
  # hits = []
  Find.find(look_here_path) do |path|
    # hits << path if path =~ /\.png/
    puts "path=#{path}" if path =~ /\.png|jpg|jpeg/i
  end
end