ifetch-tools-0.15.26d/0000755000175000017500000000000013155645503013156 5ustar useruserifetch-tools-0.15.26d/ifetch0000755000175000017500000007116313155645454014363 0ustar useruser#!/usr/bin/ruby #################################################################################### # ifetch-tools is a set of tools in ruby that can collect images from ip based cameras, # monitor collection process, and provide an interface to view collected history. # Copyright (C) 2005-2017 Richard Nelson # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 # of the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. ############################################################################################## # Set the current version information. ############################################################################################## VER = "0.15.26d" ############################################################################################## # The below should daemonize this code. ############################################################################################## #exit if fork # Parent exits, child continues. #Process.setsid # Become session leader. #exit if fork # Zap session leader. See [1]. #Dir.chdir "/" # Release old working directory. ##File.umask 0000 # Ensure sensible umask. Adjust as needed. #File.umask 0177 # Ensure sensible umask. Adjust as needed. #STDIN.reopen "/dev/null" # Free file descriptors and #STDOUT.reopen "/dev/null", "a" # point them somewhere sensible. #STDERR.reopen STDOUT # STDOUT/ERR should better go to a logfile. ############################################################################################## # Set some options to ensure memory management. ############################################################################################## RMAGICK_ENABLE_MANAGED_MEMORY = true GC.enable ############################################################################################## # Do the require and include stuff we need for our operations. ############################################################################################## require 'English' require 'drb' require 'fileutils' require 'logger' require 'uri' require 'net/http' require 'net/http/digest_auth' require 'time' #require "rubygems" #gem "rmagick", "= 2.15.3" require "rmagick" ############################################################################################## # Initialize the global array for the image access info with all nil values. ############################################################################################## $image_array = Array.new ############################################################################################## # Initialize the global variables to assist RMagick in memory help. ############################################################################################## $image_temp = nil $mdpp = nil ############################################################################################## # Initialize various variables that we intend to pull in with nil values. ############################################################################################## data_location=nil day_image_sleep=nil image_addr=nil image_addr_port=nil image_auth_type=nil image_count=nil image_count_on_motion=nil image_pwd=nil image_sleep=nil image_uid=nil image_url=nil image_watermark=nil log_files=nil log_size=nil marshal_dump_enable=nil marshal_dump_sentry=1 motion_enable=nil motion_mdpp=nil motion_sleep=nil sentry_gc_count=0 ############################################################################################## # Define a class for our DRB communications. ############################################################################################## class DataExchangeServer def xchange_array $image_array end end ############################################################################################## # Define the way we pull in an image from a camera. # # This def will pull the image from the cam now and return the response. ############################################################################################## def pullimage(address,port,url,uid,pwd,auth_type) Timeout.timeout(10) do # Here we determine if we need to handle as basic auth or digest if auth_type == 'digest' then uri = URI.parse('http://'+address.to_s+':'+port.to_s+''+url.to_s) uri.user = uid uri.password = pwd Net::HTTP.start(address, port) do |http| req_img = Net::HTTP::Get.new uri.request_uri digest_auth = Net::HTTP::DigestAuth.new response = http.request(req_img) # response is a 401 response with a WWW-Authenticate header auth = digest_auth.auth_header uri, response['www-authenticate'], 'GET' # create a new request with the Authorization header req_img = Net::HTTP::Get.new uri.request_uri req_img.add_field 'Authorization', auth # re-issue request with Authorization response = http.request req_img # Now send response back return response.body end else Net::HTTP.start(address, port) do |http| req_img = Net::HTTP::Get.new(url) #req_img.basic_auth 'username', 'password' req_img.basic_auth uid, pwd response = http.request(req_img) #puts "Code = #{response.code}" #puts "Message = #{response.message}" #response.each {|key, val| printf "%14s = %40.40s\n", key, val } ## Nelson working f.write(response.body) #Magick::Image.from_blob(response.body)[0]; return response.body end end end end ############################################################################################## # The two def below are modified from gpl code at: # http://spodzone.org.uk/packages/hawking-HNC230G-motion-detect.txt # Copyright Tim Haynes 2006- # Distributable under the terms of the Gnu Public Licence (GPL) - see # . ############################################################################################## ############################################################################################## # Define process(image) # massage an image to be suitable for comparison # here we compute the luminosity channel since rmagick's builtin doesn't work # and scale it down to half/quarter-size to remove tiny transient errors. ############################################################################################## #def process(image) # #image.colorize(0.25, 0.6, 0.15, 1, Magick::Pixel::from_color("grey")).modulate(1.25,0.01,1).scale(0.5) # #image_temp=Magick::Image.from_blob(image)[0] # #image_temp.colorize(0.25, 0.6, 0.15, 1, Magick::Pixel::from_color("grey")).modulate(1.25,0.01,1).scale(0.5) # #image_temp.modulate(1.25,0.01,1).scale(0.5) # #image_temp.modulate.scale(0.25) # Magick::Image.from_blob(image)[0] #end def difference(a,b) #a.write("a.jpeg") #b.write("b.jpeg") # see "mean difference per pixel" in the RMagick docs a=Magick::Image.from_blob(a)[0] b=Magick::Image.from_blob(b)[0] $mdpp = a.difference(b)[1] a.destroy! b.destroy! return $mdpp end ############################################################################################## # timeStamp images with RMagick. ############################################################################################## def timeStamp(image,textInfo) #GC.start mark = Magick::Image.new(300, 30) do self.background_color = 'black' end gc = Magick::Draw.new gc.annotate(mark, 0, 0, 0, 0, textInfo) do self.gravity = Magick::CenterGravity self.pointsize = 32 self.font_family = "Times" self.fill = "white" self.stroke = "none" end #image_temp.write("/tmp/annotatewatermark.jpg") # Now return the image #image.to_blob # Convert to from_blob image = Magick::Image.from_blob(image)[0] # Watermark and to_blob $image_temp = image.watermark(mark, 0.15, 0, Magick::NorthWestGravity).to_blob # Try to cleanup things mark.destroy! image.destroy! gc = nil GC.start return $image_temp end ############################################################### # Eval in the ifetch-tools.conf file with error trap on this operation. begin eval(File.open("/etc/ifetch-tools/ifetch-tools.conf") {|fh| fh.read}) rescue puts "Error encountered reading the ifetch-tools.conf file of: "+$!.to_s # Stop after the error feedback. exit end ############################################################### # Eval in the conf file for the camera with error trap on this operation. begin eval(File.open(ARGV[0]) {|fh| fh.read}) rescue puts "Encountered reading the camera.conf file of: "+$!.to_s # Stop after the error feedback. exit end ############################################################### # Set the prefix to be the name of the conf file. Also the prefix is now expected to be a numeric value for port operations on drb exchange. prefix=File.basename(ARGV[0], ".conf") ############################################################### # Set on varialbe names for file operations. log_name = "/var/log/ifetch-tools/#{prefix}.txt" mdpp_log_name = "/var/log/ifetch-tools/#{prefix}.mdpp.txt" pid_name = "/var/run/ifetch-tools/#{prefix}.pid" ################################################################ # Set the singleton so we can be the only one with this config. lock_file = File::open("/var/lock/ifetch-tools/#{prefix}.lock", 'w') if lock_file.flock(File::LOCK_EX|File::LOCK_NB) == 0 then # Do stuff on singleton if clean singleton established. ############################################################### # Just drop our PID out for multi camera monitoring and operations. File.open(pid_name,'w') do |f| f.write(Process.pid) end ############################################################### # Setup for logging general output. log = Logger.new(log_name, 5, log_size*1024) log.info("RMagick memory management status: "+Magick::MANAGED_MEMORY.to_s) ############################################################### # Setup for logging mdpp output. mdpp_log = Logger.new(mdpp_log_name, 1, 5*1024) ############################################################### # Lets trap here to ensure we can close clean with the signal of INT # Funny on the rescue where this shows up. Please see the rescue where we # are watching the HTTP:: stuff that I seem to have to make a clause for # exit. trap("INT"){ puts "Caught INT so attempting to exit!" log.warn("Caught INT so attempting to exit!") exit } ############################################################### # First thing and let the log file know we are alive. log.info("ifetch version - #{VER} starting.") ############################################################### ## 20070203 Nelson - After a bit of consideration and talking with a user on history ## operations I need a way to offer greater history than what I had designed for so ## the trick we shall try is to use the mod of the image count and splice out the images ## to sub folders. This may take some time and to do so we will glob in still. ############################################################### # 20090122 Nelson - tesing for /var/lib/ifetch-tools which is the default location that # data is to be stored in. Just create it if it does not exists. if File.exist?("/var/lib/ifetch-tools") then log.info("/var/lib/ifetch-tools directory exists.") else log.info("No /var/lib/ifetch-tools data directory found so creating one.") Dir.mkdir("/var/lib/ifetch-tools") # This is a simple step on directory structures to override File.umaks setting. File.chmod(0700, "/var/lib/ifetch-tools") end ############################################################### # 20080224 Nelson - modified for dynamic symlink via variable data_location that can now # be included in the camera conf file. # # Below is the code to generate the folder structure for history work. # If the MODPRIME is changed in the ifetch.conf file then the history will need to be smoked! log.info("Testing for directory structure for camera #{prefix}!") # Fist check for the camera directory. if File.exist?("/var/lib/ifetch-tools/#{prefix}") then log.info("Camera #{prefix} parent directory exists.") # This is a simple step on directory structures to override File.umaks setting. File.chmod(0700, "/var/lib/ifetch-tools/#{prefix}") else log.info("Camera #{prefix} NO htdocs folder starting data directory generation.") if data_location!=nil then log.info("Camera #{prefix} data directory is being generated for symlink operations at #{data_location}.") if File.exist?(data_location+"/#{prefix}") then log.info("Camera #{prefix} symlink parent directory exists.") log.info("Camera #{prefix} only creating symlink.") File.symlink(data_location+"/#{prefix}", "/var/lib/ifetch-tools/#{prefix}") else log.info("Camera #{prefix} NO symlink parent directory exists.") log.info("Camera #{prefix} creating parent and symlink.") Dir.mkdir(data_location+"/#{prefix}") log.info("Camera #{prefix} data directory is being symlinked from #{data_location}/#{prefix} to /var/lib/ifetch-tools/#{prefix}.") File.symlink(data_location+"/#{prefix}", "/var/lib/ifetch-tools/#{prefix}") end # This is a simple step on directory structures to override File.umaks setting. File.chmod(0700, data_location+"/#{prefix}") else log.info("Camera #{prefix} data directory is being generated and NOT symlinked.") Dir.mkdir("/var/lib/ifetch-tools/#{prefix}") # This is a simple step on directory structures to override File.umaks setting. File.chmod(0700, "/var/lib/ifetch-tools/#{prefix}") end end # Now handle the mod directory. 0.upto(MODPRIME-1) do |count| if File.exist?("/var/lib/ifetch-tools/#{prefix}/#{count}") then log.info("Camera #{prefix} mod #{count} directory exists.") else log.info("Camera #{prefix} mod #{count} directory is being generated.") Dir.mkdir("/var/lib/ifetch-tools/#{prefix}/#{count}") end # This is a simple step on directory structures to override File.umaks setting. File.chmod(0700, "/var/lib/ifetch-tools/#{prefix}/#{count}") end ############################################################### # We will use info here because we will sniff for all ok later with entry on the log # and a simple sentry on success after trouble. log.info("Please wait for history to initialize before attempting to access the history!") ############################################################### # This is the area where we collect the timestamps are on any history. # 20170205 Feature add to attempt to improve indexing on large storages utilizing Marshaling. # Set a temp file name for the tstamp path. temp_mdump_path = ["/var/lib/ifetch-tools",prefix,prefix+".marshal"].join('/') # Load the contents of last Marshal dump first in to the global array. if File.exist?(temp_mdump_path) then log.info("Camera .marshal file found. Attempting to load...") # If we are here then we have found a .marshal file for the camera. # First let us load the image_array dump. $image_array = Marshal.load File.read(temp_mdump_path) log.info("Camera .marshal file loaded!") # Second let us pull in all the .tstamp files for the images that we need to pull in # to make our image_array up to day. log.info("Attempting to load camera .tstamp files...") temp_tstamp_files = Dir["/var/lib/ifetch-tools/#{prefix}/*.tstamp"] 0.upto(temp_tstamp_files.length - 1) do |count| temp_fn = File.basename(temp_tstamp_files[count], ".tstamp").split(/_/)[1].to_i begin $image_array[temp_fn] = Marshal.load File.read(temp_tstamp_files[count]) rescue Exception log.warn("Encountered an error during .tstamp import of: "+$!.to_s) end end log.info("Loading of camera .tstamp files complete!") else # If we are here then we must brute force time stamps for all files. log.info("No .marshal file found to switching to brute force dating of history!") # Get a listing of all the images in the history history_files = Dir["/var/lib/ifetch-tools/#{prefix}/*/*.jpg"] # Unremark the below lines for diagnostic #puts history_files #puts history_files.length 0.upto(history_files.length - 1) do |count| # Here we step through the files and pop off the file name/number and put it in the image_array in # the correct position. temp_fn = File.basename(history_files[count], ".jpg").split(/_/)[1].to_i $image_array[temp_fn] = Time.parse(File.mtime(history_files[count]).to_s).strftime("%Y-%m-%d %H:%M:%S")+","+[prefix,temp_fn.divmod(MODPRIME)[1].to_s,File.basename(history_files[count])].join('/') #Unremark for below for diag on the actual number being split out. #puts File.basename(history_files[count], ".jpg").split(/_/)[1] end end ############################################################### # Here we adjust the array if need be to be the size requested by the configs. if image_count >= $image_array.length then log.info("Starting history generation with history count normal!") # Make sure no entries are nil 0.upto($image_array.length - 1) do |count| if $image_array[count] == nil then $image_array[count] = "19000101 00:00:01,images/missed.jpg" end end else #puts "History is more than desired count." log.info("Starting history generation with history count over set collection!") 0.upto(image_count - 1) do |count| # This is the same as the above logic for images missing from the array. if $image_array[count] == nil then $image_array[count] = "19000101 00:00:01,images/missed.jpg" end end log.info("Dumping history count over set collection from disk!") image_count.upto($image_array.length - 1) do |count| #puts "Deleting "+$image_array[count].split(/,/)[1]+"!" if File.exist?(temp_mdump_path) then File.delete("/var/lib/ifetch-tools/"+$image_array[count].split(/,/)[1]) else # FIXME test the below logging. log.warn("File /var/lib/ifetch-tools/"+$image_array[count].split(/,/)[1]+" was not found to delete.") end end # Drop the elements out of the array now. $image_array = $image_array.take image_count end # 20070108 Nelson: We need to bump the image count to the next correct number. # Set the counter up for starting at correct location. count = $image_array.index($image_array.max) if count == nil count = 0 end history_count = $image_array.length log.info("History generation complete with #{history_count} images in the history and start image of #{count+1}. Collection count set at #{image_count}. History access is now online.") # Here we clear out things we want to like unused array space and others. #history_files = nil temp_mdump_path = nil temp_tstamp_files = nil ############################################################### # Put in service 20061011 test code. # Setup the communication model with DRB for the servlet to talk to us. #DRb::DRbServer.default_load_limit LOADLIMIT #DRb.start_service("druby://:7777", SentenceWrapper.new, {:load_limit => 90214400}) #DRb.start_service('druby://localhost:9000', aServerObject) drb_port = "druby://localhost:"+(BASEPORT+prefix.to_i).to_s aServerObject = DataExchangeServer.new DRb.start_service(drb_port, aServerObject, {:load_limit => LOADLIMIT}) #puts "Hello!" #DRb.thread.join # Don't exit just yet! # Set a sentry to a value of 0 to skip clean operation logging. This is the # default behavior. sentry_check = 0 ############################################################### # Here is where we add a couple of things for the motion detection operations. # Set a sentry for skip checking that will count down until images without test are done. motion_sentry = 0 # We need a reference image to test with and we will not write it so we do not need to time stamp it. if motion_enable == 0 then begin log.info("Motion detection enabled. Pulling first image!") image1=pullimage(image_addr,image_addr_port,image_url,image_uid,image_pwd,image_auth_type) rescue Exception log.warn("Encountered an error during image1 initial pull of: "+$!.to_s) end end ############################################################### # Now start the loop that monitors via image_count. until count>image_count # Test here to ensure once we get to image_count just start over. if count < image_count-1 # puts "I am adding 1 to count check!" count=count+1 else #puts "I am here at count check!" #puts count count=0 end begin # Keep the GC in order sentry_gc_count=sentry_gc_count+1 if sentry_gc_count%100 == 0 # For sanity run the GC in an effort to keep RMagick memory in check. GC.start sentry_gc_count = 0 end # Get the current image image2=pullimage(image_addr,image_addr_port,image_url,image_uid,image_pwd,image_auth_type) # Adding pullTime to timeStamp images. pullTime = Time.now.strftime("%Y-%m-%d %H:%M:%S") image_name_DRB_exchange = [prefix,count.divmod(MODPRIME)[1].to_s,prefix+"_"+count.to_s+".jpg"].join('/') image_name = ["/var/lib/ifetch-tools",image_name_DRB_exchange].join('/') ################################################################################ # Now we test to see if we are doing motion detection and if so then we need two # images and we will now compare for difference unless asked to skip # Just to be safe run the Garbage Collection if motion_enable == 0 then #puts "Starting sentry_motion test.\n" if motion_sentry < 1 then # Here we are asked to listen for testing again. #puts "Before" #mdpp = difference(process(image2),process(image1)) mdpp = difference(image2,image1) #puts "Images tested resulted with mdpp of #{mdpp}" # Log out all mdpp tests to log file. mdpp_log.info("Images tested resulted with mdpp of #{mdpp}") if mdpp.is_a?(Numeric) then if mdpp > motion_mdpp then #puts "Motion detected!" log.info("Motion detected: mdpp=#{mdpp} and motion_mdpp=#{motion_mdpp}!") motion_sentry = image_count_on_motion end else log.info("The mdpp call did not return a number: mdpp=#{mdpp}!") end else # Here we are taking the number of images without testing. # Drop one of the count of untested images. motion_sentry = motion_sentry-1 end #puts "Ending sentry_motion test.\n" end # Write image2 to image1, since image1 is what we write and image2 is latest. #puts "Swap images" image1 = image2 ############################################################### # Here we test to determine if motion is detected or if motion # is off. If either case write file to disk. if motion_sentry > 0 || motion_enable == 1 then # Add to the image_array for DRB exchange $image_array[count] = pullTime+","+image_name_DRB_exchange #puts $image_array.max #puts $image_array.index($image_array.max) #log.info("The $image_array.max="+$image_array.max.to_s+" and the $image_array.index($image_array.max)="+$image_array.index($image_array.max).to_s+"!") # Here is where we watermark the image if enabled. if image_watermark == 0 then #image1=timeStamp(process(image1),pullTime) image1=timeStamp(image1,pullTime) end ############################################################### # Now put image in a file. Also let us do a quick error trap here. #puts count #puts "#{image_name} - Image Name" #puts $image_array[count] begin File.open(image_name,'w') do |f| f.write(image1) end rescue Exception log.warn("Encountered an error during image file output of: "+$!.to_s) end ############################################################### # To improve large data stores we want to marshal dump every 1000 images. # Do marshal_dump operations if true and it is the last image recorded on montion detection. if count.divmod(1000)[1] == 0 then marshal_dump_sentry = 0 end if marshal_dump_enable == 0 then if marshal_dump_sentry == 0 then ############################################################### # To improve large data stores we want to marshal dump image_array every 1000 images. begin # First marshal dump the image array. image_array_name_mdump = ["/var/lib/ifetch-tools",prefix,prefix+".marshal"].join('/') image_array_dump = Marshal.dump($image_array) File.open(image_array_name_mdump, 'w') {|f| f.write(image_array_dump) } # Second clean up the tstamp dumps. Dir.glob("/var/lib/ifetch-tools/#{prefix}/*.tstamp").each { |f| File.delete(f) } rescue Exception log.warn("Encountered an error during marshal dump of: "+$!.to_s) end # Reset the sentry for the next time. marshal_dump_sentry = 1 else ############################################################### # Now only dump single images one per file for 1000 begin image_name_dump = ["/var/lib/ifetch-tools",prefix,prefix+"_"+count.to_s+".tstamp"].join('/') image_dump = Marshal.dump($image_array[count]) File.open(image_name_dump, 'w') {|f| f.write(image_dump) } rescue Exception log.warn("Encountered an error during marshal dump of: "+$!.to_s) end end end else # Here drop the count back and just keep writing out the same image number # until we detect sufficient mdpp. # I suppose count could equal 0. if count >= 0 then count=count-1 end end ############################################################### # Now throttle the program back if need be. # First test to see if which sleep we need to use. # Use the motion burst as first option if triggered. if motion_sentry > 0 then #puts "Performing motion_sleep of #{motion_sleep}." sleep motion_sleep else # Set the daily sleep modification specified in each camera conf. sleep_test_data = day_image_sleep[Time.now.strftime("%w").to_i].split(",") if Time.now.strftime("%H:%M") >= sleep_test_data[0] && Time.now.strftime("%H:%M") <= sleep_test_data[1] # If we are here we are in a modified time in the day for sleep change #puts true sleep sleep_test_data[2].to_f else #puts false sleep image_sleep end end ############################################################### # If we encounter an issue that raised the rescue Exception and set the sentry_check = 1 # then we are just listenting here if we get to this point to let the log file know that # we are ok again. This is used to determine the health of a running script to a camera for # for problems. I am sure there are better ways but this seems KISS. if sentry_check != 0 log.info("Sentry clear hit and appears to be operating again ok! ifetch version - #{VER}!") sentry_check = 0 end ############################################################### # Rescue out for all errors. rescue Exception ############################################################### # First things is notify there is an error. #puts "Encountered an error: "+$!.to_s #log.warn("Encountered an error from the Net::HTTP work of: "+$!.to_s) log.warn("Encountered an error in collection operations of: "+$!.to_s) # Sleep a bit when error is raised for this process. sleep ERRORSLEEP ############################################################### # Try to setup catching a clean interrupt. This seems to be odd that I have to # do this. It is for the trap("INT") form comman line testing. if ""+$!.to_s == 'exit' log.warn('Exiting now!') # Try to be nice and close the lock file. lock_file.close exit end ############################################################### # If we encounter an issue lets set a sentry to let the program know that # we are still alive and well. Setting the sentry to 1 will force an information # output to logging that we are back to ok status. sentry_check = 1 # Write image2 to image1, since image1 is what we write and image2 is latest. # We swap here in case we get a bad image as image1 and this should flush out. image1 = image2 # If we encounter a bad image we need to dump the bad pull and pull again. log.warn("Backing image count sequence down by 1 in an attempt to pull image again after rescue!") if count < image_count-1 && count > 0 count=count-1 else count=0 end end end ############################################################### # Try to close the lock file and the Logger. lock_file.close log.close mdpp_log.close DRb.stop_service() # Stop the DRb on the ifetch session else ############################################################### # If we get here we already have a running ifetch.rb puts "According to lock file the program for the conf file is already running!" end ifetch-tools-0.15.26d/templates/0000755000175000017500000000000013156057654015161 5ustar useruserifetch-tools-0.15.26d/templates/CameraHistoryBasic0000644000175000017500000000064713062773624020625 0ustar useruser%{ Camera #{cameraName} History Interface




#{myTempRespond}
} ifetch-tools-0.15.26d/templates/Archive0000644000175000017500000000156513155642437016472 0ustar useruser# Call to get uptime info for template. _UPTIME = %x[uptime] # Call to get current date for template. _DATE =%x[date +%Y-%m-%d] # Main page. %{ Camera Archive View Interface
#{_DATE} #{_UPTIME}
(Archive) Live Monitor
#{myTempRespond}
version: #{VER} } ifetch-tools-0.15.26d/templates/Live0000644000175000017500000000156413155642013015775 0ustar useruser# Call to get uptime info for template. _UPTIME = %x[uptime] # Call to get current date for template. _DATE =%x[date +%Y-%m-%d] # Main page. %{ Camera Live View Interface
#{_DATE} #{_UPTIME}
Archive (Live) Monitor
#{myTempRespond}
version: #{VER} } ifetch-tools-0.15.26d/templates/LiveSingle0000644000175000017500000000220013156114715017127 0ustar useruser# Call to get uptime info for template. _UPTIME = %x[uptime] # Call to get current date for template. _DATE =%x[date +%Y-%m-%d] # Main page. %{ Camera Single Live View
#{_DATE} #{_UPTIME}
Cam #{cameraName} #{image_alt}
Archive Live Monitor
#{myTempRespond}
version: #{VER} } ifetch-tools-0.15.26d/templates/CameraStartStop0000644000175000017500000000077313062773624020165 0ustar useruser%{ Camera #{cameraName} Action Info

#{myTempRespond}

You will be redirected in just a moment or you may click this link.

} ifetch-tools-0.15.26d/templates/Monitor0000644000175000017500000000330613062773624016533 0ustar useruser# Call to get uptime info for template. _UPTIME = %x[uptime] # Call to get current date for template. _DATE =%x[date +%Y-%m-%d] # Main page. %{ Camera Monitor Interface

Monitor View
Operation & Action Legend
- Start collection
- Stop collection
- View log
- Start all cameras
- Collection offline
- Collection working
- Collection in alarm mode
- View mdpp
#{_DATE} #{_UPTIME}
#{myTempRespond}
Camera PID - (Memory) VIRT RES SHR Actions Status Logs mdpp Information

ifetch-tools version: #{VER}

} ifetch-tools-0.15.26d/templates/StartAllCameras0000644000175000017500000000100213062773624020115 0ustar useruser%{ Start All Cameras

The servlet is attempting to start all cameras. You will be redirected in just a moment or you may click this link.

} ifetch-tools-0.15.26d/templates/Camera0000644000175000017500000000067513062773624016302 0ustar useruser%{ Camera #{cameraName} Interface } ifetch-tools-0.15.26d/templates/CameraHistoryPlayback0000644000175000017500000001403013121112325021276 0ustar useruser%{ Camera #{cameraName} History Interface

Date Error




Home | Archive | Live | Monitor | HTML Export | Video Export

ifetch-tools version: #{VER}

} ifetch-tools-0.15.26d/templates/ShowImage0000644000175000017500000000140713062773624016767 0ustar useruser%{ Camera #{cameraName} Interface

#{theDate}

#{pageToBuild}

Home | Archive | Live | Monitor | HTML Archive | Video Export

ifetch-tools version: #{VER}

} ifetch-tools-0.15.26d/templates/CameraHistory0000644000175000017500000000561513155644455017665 0ustar useruser%{ Camera #{cameraName} History Interface
#{myNavigation}




#{myTempRespond}
} ifetch-tools-0.15.26d/README.txt0000644000175000017500000000340213047224236014647 0ustar useruser#################################################################################### # ifetch-tools is a set of tools that can collect images from ip based cameras, # monitor collection process, and provide an interface to view collected history. # Copyright (C) 2005-2017 Richard Nelson # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 # of the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #################################################################################### # Notes for README.txt #################################################################################### # - As of ifetch-tools-0.15.0 you need to install via the .deb and start and stop # from /etc/init.d/ifetch-tools # - ifetch-tools will not start until you edit the /etc/ifetch-tools/ifetch-tools.conf # - Please read the available options in the /etc/ifetch-tools/ifetch-tools.conf file. To access a camera history once configured try something like the following URL: http://localhost:2000/camera?cameraName=camera# where exampleCamera would be the ending dir name in the htdocs directory. To check the status of your cameras try something like the following URL: http://localhost:2000/monitor ifetch-tools-0.15.26d/wwwifetch0000755000175000017500000012004613155645503015116 0ustar useruser#!/usr/bin/ruby ##################################################################################### # ifetch-tools is a set of tools that can collect images from ip based cameras, # monitor collection process, and provide an interface to view collected history. # Copyright (C) 2005-2017 Richard Nelson # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 # of the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. ############################################################################################## # Set some variables. ############################################################################################## # Version number VER = "0.15.26d" ############################################################################################## # Set some options to ensure memory management. ############################################################################################## GC.enable ############################################################################################## # Do the require and include stuff we need for our operations. ############################################################################################## require 'webrick' require 'drb' require 'rmagick' require 'net/http' require 'net/http/digest_auth' #require 'logger' # Unremark the below two lines if you want to try with high-performance. #require 'rubygems' #require 'webrick/highperformanceserver' include WEBrick ############################################################################################## # Define the way we pull in an image from a camera. # # This def will pull the image from the cam now and return the response. ############################################################################################## def pullimage(address,port,url,uid,pwd,auth_type) Timeout.timeout(10) do # Here we determine if we need to handle as basic auth or digest if auth_type == 'digest' then uri = URI.parse('http://'+address.to_s+':'+port.to_s+''+url.to_s) uri.user = uid uri.password = pwd Net::HTTP.start(address, port) do |http| req_img = Net::HTTP::Get.new uri.request_uri digest_auth = Net::HTTP::DigestAuth.new response = http.request(req_img) # response is a 401 response with a WWW-Authenticate header auth = digest_auth.auth_header uri, response['www-authenticate'], 'GET' # create a new request with the Authorization header req_img = Net::HTTP::Get.new uri.request_uri req_img.add_field 'Authorization', auth # re-issue request with Authorization response = http.request req_img # Now send response back return response.body end else Net::HTTP.start(address, port) do |http| req_img = Net::HTTP::Get.new(url) #req_img.basic_auth 'username', 'password' req_img.basic_auth uid, pwd response = http.request(req_img) #puts "Code = #{response.code}" #puts "Message = #{response.message}" #response.each {|key, val| printf "%14s = %40.40s\n", key, val } ## Nelson working f.write(response.body) #Magick::Image.from_blob(response.body)[0]; return response.body end end end end ############################################################################################## # Suck in the config settings from the ifetch-tools.conf file. ############################################################################################## begin eval(File.open("/etc/ifetch-tools/ifetch-tools.conf") {|fh| fh.read}) rescue puts "Error encountered reading the conf file of: "+$!.to_s # Stop after the error feedback. exit end ############################################################################################## # Class definitions below. ############################################################################################## ############################################################################################## # Camera generates two frames and calls CameraHistory on the left frame of the system. ############################################################################################## class Camera < HTTPServlet::AbstractServlet def do_GET(req, res) HTTPAuth.basic_auth(req, res, 'Camera History Realm') {|user, pass| # this block returns true if # authentication token is valid user == HISTORYUSER && pass == HISTORYPASS } res['Content-Type'] = "text/html" # Tell the browser how we are talking raise HTTPServerError, 'Error: cameraName parameter not passed correctly.' if req.query['cameraName'] == nil || /[0-9]+/.match(req.query['cameraName']) == nil cameraName = /[0-9]+/.match(req.query['cameraName']).to_s res.body = eval(File.open("/usr/share/ifetch-tools/templates/Camera") {|fh| fh.read}) end end ############################################################################################## # CameraHistory generates the left frame of the system and setup some stuff to do the magic # on the camera history. ############################################################################################## class CameraHistory < HTTPServlet::AbstractServlet def do_GET(req, res) HTTPAuth.basic_auth(req, res, 'Camera History Realm') {|user, pass| # this block returns true if # authentication token is valid user == HISTORYUSER && pass == HISTORYPASS } res['Content-Type'] = "text/html" # Tell the browser how we are talking # cameraName we are to work with. raise HTTPServerError, 'Error: cameraName parameter not passed correctly.' if req.query['cameraName'] == nil || /[0-9]+/.match(req.query['cameraName']) == nil cameraName = /[0-9]+/.match(req.query['cameraName']).to_s # index is a page reference to where we are in the view. raise HTTPServerError, 'Error: index parameter not passed correctly.' if req.query['index'] == nil || /[0-9]+/.match(req.query['index']) == nil index = /[0-9]+/.match(req.query['index']).to_s # Crop out all the bad stuff. # navigation is to determine whether we populate the viewing pane of first view. raise HTTPServerError, 'Error: navigation parameter not passed correctly.' if req.query['navigation'] == nil || /[0-9]+/.match(req.query['navigation']) == nil navigation = /[0-1]/.match(req.query['navigation']).to_s # Crop out all the bad stuff. # basicView is for the Basic Archive View. raise HTTPServerError, 'Error: basicView parameter not passed correctly.' if req.query['basicView'] == nil || /[0-3]/.match(req.query['basicView']) == nil basicView = /[0-3]/.match(req.query['basicView']).to_s # Initialize some vars. myJumpNavigation = "" # Jump navigation string. myNavigation = "" # General navigation string. myTempRespond = "" # Set a local var to null. # 20090201 Nelson - I am now starting this on startup and only do the new object here. # Here is the performance boost for exchange of data between the collection daemon and the web interface #DRb.start_service(nil,nil,{:load_limit => LOADLIMIT}) drb_port = "druby://localhost:"+(BASEPORT+cameraName.to_i).to_s #obj = DRbObject.new(nil, 'druby://localhost:9000') obj = DRbObject.new(nil, drb_port) # Define our array to handle the DRb exchange. imgSorted = Array.new # Now use obj, imgSorted is not as descriptive but remember that we expect the sequence to be pre sorted so in fact name is ok. imgSorted = obj.xchange_array # 20090201 Nelson - I am now stoping this on trap of close here. #DRb.stop_service() # Stop the DRb on the webrick session imgSortedLength = imgSorted.length totalPages = imgSortedLength / IMAGESPERPAGE # Get the total number of pages. #puts imgSortedLength # This is just a logic flow here for the first page while the system is populating. # Note, that the way we display images will cause drift in respect to amount of images and the time at the interface. #if totalPages != 0 #totalPagesCounter = totalPages - 1 #end # Ok here we are getting a number to reference so we do not have time drift. tmpIndex = index.to_i # Set a sentry for start over on count back to 0 # We do not have to worry about backward count since that is addressed in the "< Previous | Next >" navigation on down. indexSentry = -1 # Generate the response of images per page and guard against no images yet. if imgSortedLength > 0 if tmpIndex+IMAGESPERPAGE >= imgSortedLength lastImgOnPage = imgSortedLength - 1 indexSentry = tmpIndex+IMAGESPERPAGE - imgSortedLength - 1 else lastImgOnPage = tmpIndex+IMAGESPERPAGE - 1 end else lastImgOnPage = 0 totalPages = -1 end # This just keeps us from populating the navigation frame on the initial login to history and if no history collected yet. if navigation.to_i == 1 && imgSortedLength > 0 # Ok now actually populate the page with the lastImgOnPage # Keep track of image file names when building frame for video export imgFileList = Array.new # Keep track of image file names for javascript playback imgPlaybackList = Array.new index.to_i.upto(lastImgOnPage) do |imgIndex| #imgTime, imgFile = imgSorted[5].to_s.split(/,/) imgTime, imgFile = imgSorted[imgIndex].split(/,/) #puts imgFile # Ok here we are getting a number to reference so we do not have time drift based on our new navigation. #imgTime, imgFile = imgSorted[imgIndex].to_s.split(/,/) myTempRespond = myTempRespond+'
'+imgTime+'

' # Push the image on the array javascript playback imgPlaybackList.push("/data/#{imgFile}?timehash=#{imgTime}") # Push the image on the array where we are keeping image file names if File.exist?("/var/lib/ifetch-tools/#{imgFile}") && File.size("/var/lib/ifetch-tools/#{imgFile}")>0 then imgFileList.push("/var/lib/ifetch-tools/#{imgFile}") end end # 20081007 Nelson - removing this block to leave last page possibly short. ### Now finish starting back at 0 on the page that ran over the end of the array if imgSortedLength >= IMAGESPERPAGE 0.to_i.upto(indexSentry) do |imgIndex| #imgTime, imgFile = imgSorted[5].to_s.split(/,/) imgTime, imgFile = imgSorted[imgIndex].split(/,/) #puts imgFile # Ok here we are getting a number to reference so we do not have time drift based on our new navigation. #imgTime, imgFile = imgSorted[imgIndex].to_s.split(/,/) myTempRespond = myTempRespond+'
'+imgTime+'

' # Push the image on the array javascript playback imgPlaybackList.push("/data/#{imgFile}?timehash=#{imgTime}") # Push the image on the array where we are keeping image file names if File.exist?("/var/lib/ifetch-tools/#{imgFile}") && File.size("/var/lib/ifetch-tools/#{imgFile}")>0 then imgFileList.push("/var/lib/ifetch-tools/#{imgFile}") end end end end # Ok here we do the Jump List as an array for just a bit. #myJumpNavigation = myJumpNavigation+'\n" # Build the navi 0.upto(totalPages) do |count| pageIndex = count*IMAGESPERPAGE # Bug 11618 squash - The below is since we index with 0 and not 1 we have to watch for even page count division in to our total images and adjust if need be. if pageIndex >= lastImgOnPage pageIndex = pageIndex-1 end # Split out our info from the array element. imgTime, imgFile = imgSorted[pageIndex].split(/,/) #puts imgFile # tmpIndex will hold the index position of the page we are on. tmpIndex = File.basename(imgFile, ".jpg").split(/_/)[1].to_i # This is the elements in the jumping list. This could be sorted but for now I am leaving since I sort of like how if shows the scroll of image count in an abstract way. myJumpHash[imgTime] = '\n" end # Now that we have built it lets prep it to display it like we want (sorted in this case). #myJumpNavigation = myJumpHash.sort.each {|key, value| puts "The key value is #{key} and the hash is #{value}" } myJumpHash.sort.reverse.each {|key, value| myJumpNavigation = "#{myJumpNavigation}#{value}" } #puts myJumpNavigation # Ok here is where we handle the < Previous | Next >" navigation. # Here is the code for a sinle page of images only or if this is the first time the user hits the hitsory. if index.to_i-IMAGESPERPAGE < 0 && index.to_i+IMAGESPERPAGE > imgSortedLength-1 || navigation.to_i == 0 myNavigation = %{
Please select a time.
} else # If we are here then there is more than one page of images. # Here is the move back page code if index.to_i-IMAGESPERPAGE >= 0 myNavigation = %{
< Previous } else myNavigation = %{
< Previous } end # Here is the move forward between page code if index.to_i+IMAGESPERPAGE <= imgSortedLength-1 myNavigation = %{#{myNavigation}| Next >
} else myNavigation = %{#{myNavigation}| Next >
} end end if basicView.to_i == 1 # If we are here we are asking to build a page with images only. myTempRespond.gsub!(/(]*)width=\d+ height=\d+/i, '\\1') myTempRespond.gsub!(/(
/i,"A>

") # Now generate the page with the correct substitution. res.body = eval(File.open("/usr/share/ifetch-tools/templates/CameraHistoryBasic") {|fh| fh.read}) elsif basicView.to_i == 2 # If we are here we need to call rmagick with to make a vidoe of the frame of images starting with the selected image. # Setup to make video from images tempResponse = Magick::ImageList.new(*imgFileList) do self.delay = $video_export_delay end # Write out temp video to a random directory in /tmp, set mime_type for default launch, # then destroy said temp area upon return for security. Dir.mktmpdir(nil, "/tmp") {|dir| # use the directory... tempResponse.write("#{dir}/tmpVideo."+$video_export_type) mtype = WEBrick::HTTPUtils::mime_type("#{dir}/tmpVideo."+$video_export_type, WEBrick::HTTPUtils::DefaultMimeTypes) res['Content-Type'] = mtype res['Content-Disposition'] = "inline; filename=\"video."+$video_export_type puts mtype res.body = File.open("#{dir}/tmpVideo."+$video_export_type,"rb") {|io| io.read} } elsif basicView.to_i == 3 # If we are here then we need to setup for javascript playback # Now generate the page with the correct substitution. # Unify history playback here while dropping ShowImage method # tmpIndex will hold the index position of the page we are on. res.body = eval(File.open("/usr/share/ifetch-tools/templates/CameraHistoryPlayback") {|fh| fh.read}) else GC.start # Now generate the page with the correct substitution. res.body = eval(File.open("/usr/share/ifetch-tools/templates/CameraHistory") {|fh| fh.read}) end end end ############################################################################################## # Start and Stop the collection process for a given camera. ############################################################################################## class CameraStartStop < HTTPServlet::AbstractServlet def do_GET(req, res) HTTPAuth.basic_auth(req, res, 'Camera Monitor Realm') {|user, pass| # this block returns true if # authentication token is valid user == MONITORUSER && pass == MONITORPASS } res['Content-Type'] = "text/html" # Tell the browser how we are talking raise HTTPServerError, 'Error: cameraName parameter not passed correctly.' if req.query['cameraName'] == nil || /[0-9]+/.match(req.query['cameraName']) == nil cameraName = /[0-9]+/.match(req.query['cameraName']).to_s # Now test for the status of the cameras lock file. If running we stop and if not we start. myTempRespond = "" lock_file = File::open("/var/lock/ifetch-tools/"+cameraName.to_s+".lock", 'w') if lock_file.flock(File::LOCK_EX|File::LOCK_NB) == 0 then # Camera not running action here # Really important here to close the file or you will get confused! lock_file.close system_call = "/usr/bin/ifetch /etc/ifetch-tools/cameras/"+cameraName.to_s+".conf&" pid = fork { Process.setsid (0...2).each do |i| begin #closing stdin, stdout and stderr 0,1,2 IO.for_fd(i).close rescue Errno::EBADF end end pid2 = fork { exec(system_call) } Process.detach(pid2) exit! } Process.detach(pid) myTempRespond = "The servlet is attempting to start camera #{cameraName.to_s}" else # Camera running action here # Set the camera_pid to hold the pid of the running camera process. camera_pid = File.read("/var/run/ifetch-tools/"+cameraName.to_s+".pid").chomp system_call = "kill -s 9 #{camera_pid} &" Process.detach( fork { system(system_call) } ) myTempRespond = "The servlet is attempting to stop camera #{cameraName.to_s} " end res.body = eval(File.open("/usr/share/ifetch-tools/templates/CameraStartStop") {|fh| fh.read}) end end ############################################################################################## # CArchive is dynamic to create an archive view of each camera that is listed from the # conf dir at the time of the servlet creation. The tool will use the listing of files with # the .conf extension. ############################################################################################## class CArchive < HTTPServlet::AbstractServlet def do_GET(req, res) HTTPAuth.basic_auth(req, res, 'Camera History Realm') {|user, pass| # this block returns true if # authentication token is valid user == HISTORYUSER && pass == HISTORYPASS } res['Content-Type'] = "text/html" # Tell the browser how we are talking myTempRespond = "" image_addr = "127.0.0.1" image_addr_port = "80" image_alt = "no_image_alt" image_uid = "no_image_uid" image_url = "no_image_url" image_pwd = "no_image_pwd" # 20160408 Rework the live and archive dynamic view to utilize the global ifetch-tools.conf file. Dir["/etc/ifetch-tools/cameras/*.conf"].sort.each do |cam_tmp| ############################################################### # First suck in the config settings from the ifetch-tools.conf file. begin eval(File.open("/etc/ifetch-tools/ifetch-tools.conf") {|fh| fh.read}) rescue puts "Error encountered reading the conf file of: "+$!.to_s # Stop after the error feedback. break end ############################################################### # Now let the camera.conf file overload the settings they want. begin eval(File.open(cam_tmp) {|fh| fh.read}) rescue res.body = eval(puts "Encountered reading the camera.conf file of: "+$!.to_s) # Stop after the error feedback. break end # Add the inline image and link to the page. myTempRespond = myTempRespond+''+image_alt+'' end GC.start res.body = eval(File.open("/usr/share/ifetch-tools/templates/Archive") {|fh| fh.read}) end end ############################################################################################## # CLive is dynamic to create a live view of each camera that is listed from the # conf dir at the time of the servlet creation. The tool will use the listing of files with # the .conf extension. ############################################################################################## class CLive < HTTPServlet::AbstractServlet def do_GET(req, res) HTTPAuth.basic_auth(req, res, 'Camera History Realm') {|user, pass| # this block returns true if # authentication token is valid user == HISTORYUSER && pass == HISTORYPASS } res['Content-Type'] = "text/html" # Tell the browser how we are talking myTempRespond = "" image_addr = "127.0.0.1" image_addr_port = "80" image_alt = "no_image_alt" image_uid = "no_image_uid" image_url = "no_image_url" image_pwd = "no_image_pwd" # 20160408 Rework the live and archive dynamic view to utilize the global ifetch-tools.conf file. Dir["/etc/ifetch-tools/cameras/*.conf"].sort.each do |cam_tmp| ############################################################### # First suck in the config settings from the ifetch-tools.conf file. begin eval(File.open("/etc/ifetch-tools/ifetch-tools.conf") {|fh| fh.read}) rescue puts "Error encountered reading the conf file of: "+$!.to_s # Stop after the error feedback. break end ############################################################### # Now let the camera.conf file overload the settings they want. begin eval(File.open(cam_tmp) {|fh| fh.read}) rescue res.body = eval(puts "Encountered reading the camera.conf file of: "+$!.to_s) # Stop after the error feedback. break end # Add the inline image and link to the page. myTempRespond = myTempRespond+''+image_alt+'' end GC.start res.body = eval(File.open("/usr/share/ifetch-tools/templates/Live") {|fh| fh.read}) end end ############################################################################################## # CLiveSingle creates a live view of a single camera. ############################################################################################## class CLiveSingle < HTTPServlet::AbstractServlet def do_GET(req, res) HTTPAuth.basic_auth(req, res, 'Camera History Realm') {|user, pass| # this block returns true if # authentication token is valid user == HISTORYUSER && pass == HISTORYPASS } res['Content-Type'] = "text/html" # Tell the browser how we are talking raise HTTPServerError, 'Error: cameraName parameter not passed correctly.' if req.query['cameraName'] == nil || /[0-9]+/.match(req.query['cameraName']) == nil cameraName = /[0-9]+/.match(req.query['cameraName']).to_s myTempRespond = "" image_addr = "127.0.0.1" image_addr_port = "80" image_alt = "no_image_alt" image_sleep = "1" image_uid = "no_image_uid" image_url = "no_image_url" image_pwd = "no_image_pwd" # 20160408 Rework the live and archive dynamic view to utilize the global ifetch-tools.conf file. ############################################################### # First suck in the config settings from the ifetch-tools.conf file. begin eval(File.open("/etc/ifetch-tools/ifetch-tools.conf") {|fh| fh.read}) rescue puts "Error encountered reading the conf file of: "+$!.to_s # Stop after the error feedback. #break end ############################################################### # Now let the camera.conf file overload the settings they want. begin eval(File.open("/etc/ifetch-tools/cameras/"+cameraName+".conf") {|fh| fh.read}) rescue res.body = eval(puts "Encountered reading the camera.conf file of: "+$!.to_s) # Stop after the error feedback. #break end # Put the camera image in the template return myTempRespond = ''+image_alt+'' GC.start res.body = eval(File.open("/usr/share/ifetch-tools/templates/LiveSingle") {|fh| fh.read}) end end ############################################################################################## # Monitor will be used as the basis to check the status of each camera that is listed from the # conf dir at the time of the servlet creation. The tool will use the listing of files with # the .conf extension. ############################################################################################## class CMonitor < HTTPServlet::AbstractServlet def do_GET(req, res) HTTPAuth.basic_auth(req, res, 'Camera Monitor Realm') {|user, pass| # this block returns true if # authentication token is valid user == MONITORUSER && pass == MONITORPASS } res['Content-Type'] = "text/html" # Tell the browser how we are talking myTempRespond = "" # 20061207 not as clean as I would like it but this seems to do the trick camera_array = Array.new cam_count = 0 Dir["/etc/ifetch-tools/cameras/*.conf"].each do |cam_tmp| camera_array[cam_count] = File.basename(cam_tmp, ".conf").to_i cam_count = cam_count+1 end camera_array.sort.each do |camera_num| # Now test for the status of the cameras lock file. lock_file = File::open("/var/lock/ifetch-tools/"+camera_num.to_s+".lock", 'w') # Table col 1 camera number, 2 - pid / mem, 3 - actions, 4 - status, 5 - log file, 6 - mdpp, 7 - information if lock_file.flock(File::LOCK_EX|File::LOCK_NB) == 0 then myTempRespond = myTempRespond+'

'+camera_num.to_s+'
- / -
Camera ifetch is not running. ' # Really important here to close the file or you will get confused! lock_file.close else # Set the camera_pid to hold the pid of the running camera process. camera_pid = File.read("/var/run/ifetch-tools/"+camera_num.to_s+".pid").chomp # Put the camera pid and camera number in the table myTempRespond = myTempRespond+'
'+camera_num.to_s+'
'+camera_pid+' - '+%x[pmap -x #{camera_pid} | tail -1][10,40].strip+'
' # Set the logFileName logFileName = "/var/log/ifetch-tools/"+camera_num.to_s+".txt" # Remarked out the backtick with tail for a pure ruby try. Not for sure about performance but want to try. # logFileLastLine = `/usr/bin/tail -n 1 #{logFileName}`.split(/,/) # Put the notes of what the log file says in monitor. tempForLastLine=[] File.open(logFileName, "r") { |f| while f.gets tempForLastLine.push $_ tempForLastLine.shift if $. > 1 end } #tempForLastLine.each{|e| print e} logFileLastLine = tempForLastLine[0].split(/,/) # Below is for diagnostics #myTempRespond = myTempRespond+logFileLastLine[0]+logFileName if logFileLastLine[0] == "I" then myTempRespond = myTempRespond+'
'+logFileLastLine[1]+" " else myTempRespond = myTempRespond+'
'+logFileLastLine[1]+" " end end end GC.start res.body = eval(File.open("/usr/share/ifetch-tools/templates/Monitor") {|fh| fh.read}) end end ############################################################################################## # CSnapshot pulls a live snapshot of a given camera. ############################################################################################## class CSnapshot < HTTPServlet::AbstractServlet def do_GET(req, res) HTTPAuth.basic_auth(req, res, 'Camera History Realm') {|user, pass| # this block returns true if # authentication token is valid user == HISTORYUSER && pass == HISTORYPASS } res['Content-Type'] = "image/jpeg" # Tell the browser how we are talking raise HTTPServerError, 'Error: cameraName parameter not passed correctly.' if req.query['cameraName'] == nil || /[0-9]+/.match(req.query['cameraName']) == nil cameraName = /[0-9]+/.match(req.query['cameraName']).to_s myTempRespond = "" image_addr = "127.0.0.1" image_addr_port = "80" image_alt = "no_image_alt" image_auth_type="basic" image_uid = "no_image_uid" image_url = "no_image_url" image_pwd = "no_image_pwd" # 20160408 Rework the live and archive dynamic view to utilize the global ifetch-tools.conf file. ############################################################### # First suck in the config settings from the ifetch-tools.conf file. begin eval(File.open("/etc/ifetch-tools/ifetch-tools.conf") {|fh| fh.read}) rescue puts "Error encountered reading the conf file of: "+$!.to_s # Stop after the error feedback. #break end ############################################################### # Now let the camera.conf file overload the settings they want. begin eval(File.open("/etc/ifetch-tools/cameras/"+cameraName+".conf") {|fh| fh.read}) rescue res.body = eval(puts "Encountered reading the camera.conf file of: "+$!.to_s) # Stop after the error feedback. #break end # return the current camera snapshot image. res.body = pullimage(image_addr,image_addr_port,image_url,image_uid,image_pwd,image_auth_type) end end ############################################################################################## # Display an image and a time stamp. of the system. ############################################################################################## class ShowImage < HTTPServlet::AbstractServlet def do_GET(req, res) HTTPAuth.basic_auth(req, res, 'Camera History Realm') {|user, pass| # this block returns true if # authentication token is valid user == HISTORYUSER && pass == HISTORYPASS } res['Content-Type'] = "text/html" # Tell the browser how we are talking raise HTTPServerError, 'Error: cameraName parameter not passed correctly.' if req.query['cameraName'] == nil || /[0-9]+/.match(req.query['cameraName']) == nil cameraName = /[0-9]+/.match(req.query['cameraName']).to_s imgFile = /([\/A-Za-z0-9_]+)+(.jpg|.png)/.match(req.query['imageName'])[0] # Crop out all the bad stuff. if imgFile == "images/ifetch.png" || imgFile == "images/missed.jpg" tmpIndex = 0 theDate = "Welcome to camera number #{cameraName} history." pageToBuild = %{} pageToBuildBasic = %{/data/#{imgFile}} pageToBuildVideo = %{/data/#{imgFile}} elsif imgFile != nil # tmpIndex will hold the index position of the page we are on. tmpIndex = File.basename(imgFile, ".jpg").split(/_/)[1].to_i theDate = File.mtime("/var/lib/ifetch-tools/#{imgFile}") pageToBuild = %{} pageToBuildBasic = %{/camerahistory?cameraName=#{cameraName}&index=#{tmpIndex}&navigation=1&basicView=1} pageToBuildVideo = %{/camerahistory?cameraName=#{cameraName}&index=#{tmpIndex}&navigation=1&basicView=2} else pageToBuild = %{Error in image passing to ShowImage could be a security issue.} end res.body = eval(File.open("/usr/share/ifetch-tools/templates/ShowImage") {|fh| fh.read}) end end ############################################################################################## # Attempt to start all cameras. ############################################################################################## class StartAllCameras < HTTPServlet::AbstractServlet def do_GET(req, res) HTTPAuth.basic_auth(req, res, 'Camera Monitor Realm') {|user, pass| # this block returns true if # authentication token is valid user == MONITORUSER && pass == MONITORPASS } res.body = eval(File.open("/usr/share/ifetch-tools/templates/StartAllCameras") {|fh| fh.read}) start_all_cameras end end ############################################################################################## # The below def should attempt to start every camera conf it can find. ############################################################################################## def start_all_cameras Dir["/etc/ifetch-tools/cameras/*.conf"].each do |cam_tmp| cameraName = File.basename(cam_tmp, ".conf").to_i pid = fork { Process.setsid (0...2).each do |i| begin #closing stdin, stdout and stderr 0,1,2 IO.for_fd(i).close rescue Errno::EBADF end end system_call = "/usr/bin/ifetch /etc/ifetch-tools/cameras/"+cameraName.to_s+".conf&" pid2 = fork { exec(system_call) } Process.detach(pid2) exit! } Process.detach(pid) end end ############################################################################################## # The below def should attempt to stop every camera pid it can find upon a shutdown request. ############################################################################################## def stop_all_cameras Dir["/var/lock/ifetch-tools/*.pid"].each do |cam_tmp| cameraName = File.basename(cam_tmp, ".pid").to_i # Camera running action here # Set the camera_pid to hold the pid of the running camera process. camera_pid = File.read("/var/run/ifetch-tools/"+cameraName.to_s+".pid").chomp system_call = "kill -s 9 #{camera_pid} &" Process.detach( fork { system(system_call) } ) puts "Shutdown signal received, attempting stop on"+cameraName.to_s+".pid" end end ############################################################################################## # The below should daemonize this code. # 20090124 Nelson - Remarking out since I want init.d to catch the pid correct. ############################################################################################## #exit if fork # Parent exits, child continues. #Process.setsid # Become session leader. #exit if fork # Zap session leader. See [1]. #Dir.chdir "/" # Release old working directory. ##File.umask 0000 # Ensure sensible umask. Adjust as needed. #STDIN.reopen "/dev/null" # Free file descriptors and #STDOUT.reopen "/dev/null", "a" # point them somewhere sensible. #STDERR.reopen STDOUT # STDOUT/ERR should better go to a logfile. ############################################################################################## # Enable the logging operations we want below. ############################################################################################## # Set up the log information server_log = WEBrick::Log::new("/var/log/ifetch-tools/wwwifetch-server.txt", WEBrick::Log::DEBUG) access_log = WEBrick::BasicLog::new("/var/log/ifetch-tools/wwwifetch-access.txt") referer_log = WEBrick::BasicLog::new("/var/log/ifetch-tools/wwwifetch-referer.txt") agent_log = WEBrick::BasicLog::new("/var/log/ifetch-tools/wwwifetch-agent.txt") custom_log = WEBrick::BasicLog::new("/var/log/ifetch-tools/wwwifetch-custom.txt") ############################################################################################## # Setup for layered approach for authentication. ############################################################################################## authenticate_history = Proc.new do |req, res| HTTPAuth.basic_auth(req, res, 'History Level Authentication Required') do |user, pass| #user == 'foo' && password == 'bar' user == HISTORYUSER && pass == HISTORYPASS end end ############################################################################################## # Start the DRb service for use later. ############################################################################################## DRb.start_service(nil,nil,{:load_limit => LOADLIMIT}) ############################################################################################## # Create the instance of the web server. ############################################################################################## s = WEBrick::HTTPServer.new( :Port => 2000, #:DocumentRoot => "/usr/share/ifetch-tools/htdocs", :DocumentRoot => "/dev/null", :Logger => server_log, :AccessLog => [ [ access_log, WEBrick::AccessLog::COMMON_LOG_FORMAT ], [ referer_log, WEBrick::AccessLog::REFERER_LOG_FORMAT ], [ agent_log, WEBrick::AccessLog::AGENT_LOG_FORMAT ], [ custom_log, "%a %U %T" ] # peeraddr, Request-URI, process time ] ) ############################################################################################## # Create some mount points for servlet navigation ############################################################################################## # Monitor Operations s.mount("/archive", CArchive) s.mount("/snapshot", CSnapshot) s.mount("/live", CLive) s.mount("/livesingle", CLiveSingle) s.mount("/monitor", CMonitor) s.mount("/camerastartstop", CameraStartStop) s.mount("/startallcameras", StartAllCameras) # History Operations s.mount("/camera", Camera) s.mount("/camerahistory", CameraHistory) s.mount("/showimage", ShowImage) # Below creates symlink to default area if no custom /var/lib/ifetch-tools/htdocs folder or symlink is found. if File.exist?("/var/lib/ifetch-tools/htdocs") then puts "Symlink or folder exists for /var/lib/ifetch-tools/htdocs." else puts "No symlink or folder exists for /var/lib/ifetch-tools/htdocs." puts "Attempting to create symlink to /usr/share/ifetch-tools/htdocs." File.symlink("/usr/share/ifetch-tools/htdocs", "/var/lib/ifetch-tools/htdocs") end s.mount('/', HTTPServlet::FileHandler, "/var/lib/ifetch-tools/htdocs/", :FancyIndexing => true, :HandlerCallback => authenticate_history # Hook up the authentication proc. ) # The below is for .deb operations and good locations. s.mount('/log/', WEBrick::HTTPServlet::FileHandler, '/var/log/ifetch-tools/') s.mount('/data/', WEBrick::HTTPServlet::FileHandler, '/var/lib/ifetch-tools/') # Added the below in an attempt to refer default images. s.mount('/data/images/', WEBrick::HTTPServlet::FileHandler, '/usr/share/ifetch-tools/htdocs/') # Catch the INT sig to shutdown trap("INT"){ puts "Shutdown signal received, stop all cameras." stop_all_cameras # Stop all running camera collection processes DRb.stop_service() # Stop the DRb on the webrick session s.shutdown } ############################################################################################## # Start the cameras ############################################################################################## start_all_cameras ############################################################################################## # Launch webrick ############################################################################################## s.start ifetch-tools-0.15.26d/htdocs/0000755000175000017500000000000013156060003014425 5ustar useruserifetch-tools-0.15.26d/htdocs/grey.jpg0000644000175000017500000000063612475075610016117 0ustar useruserJFIFLHExifMM*C  !"$"$C"$A!1aq!A ?9-)IoVX4|ZUQks>UZ$@pCQc{+x\~^TUZjtӀW}xV|JpQN`Kkph?ifetch-tools-0.15.26d/htdocs/start.jpg0000644000175000017500000000116312475075610016302 0ustar useruserJFIFKHExifMM*CC"  !  !"1 ?ptzJ)LUkr/SْQkqfvm˺/=i͵IN.bR3jhHf#a Q$aY!߆Eh򼯛j`lf UHmXGf 0Z,ʹ"&<_;ys̻7}uOռv+"$ W+%~rk&F(iNLH02100100CC"! "'  ?舉VBT}#ҖugR5cP.֞[Ĺnv4*ڷ4)by54@wqn2D; zVv8XoSV:.KŚ7hg:hB!Q',CS 'Ugy[w:ʧմ#M@ٿSM"0K $S8`80 ?޲T t l)5$ i; 1y@^0:P.tbPT">4iDyKi.]`BE%I ;6to &u¯ky\]Zz};X6H2`BAnve,_j=_QZlR*?ifetch-tools-0.15.26d/htdocs/restart.jpg0000644000175000017500000000124712475075610016634 0ustar useruserJFIFLHExifMM*CC"   # ?`r=1:z:̟Mvb`I؊zPn>؀m%!SĽnň!R6v]@-cYB®~戱6q\ꏟ)Ң(QW{v* H<|~>j!E=ˢ.{++y3.[lyx[l cXv7B/=u]OXy8 Vّ\M5)m`V,jF|EL/M@\/=鵹̵kuBԲ4qIlak5_ P+th\ͧ !bEt+O}H$kb'ifetch-tools-0.15.26d/htdocs/log.jpg0000644000175000017500000000077012475075610015731 0ustar useruserJFIFLHExifMM*C  !"$"$C"#!"1Br1Qa! ?`U&!GɢXa:cA#ҧfljxXu1GVHƒkJ1(^[⡓'Z% ߭~4|=>Mk ifetch-tools HOME



Archive | Live | Monitor
####################################################################################
# ifetch-tools is a set of tools that can collect images from ip based cameras,
# monitor collection process, and provide an interface to view collected history.
# Copyright (C) 2005-2017 Richard Nelson
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
####################################################################################

This page is custom coded at each location that ifetch-tools is installed.

If you need $$ support or consulting on ifetch-tools you are welcome to email the author at unixabg@gmail.com , which may elect to provide support and consulting for a fee. On a paid solicitation please include a subject line of **pay-support-ifetch-tools** to ensure that your email will not be filtered.

Updated on 20170911 by RJ Ent of FYEOX

ifetch-tools-0.15.26d/htdocs/ifetch.png0000644000175000017500000005051512475075610016420 0ustar useruserPNG  IHDRZ=sRGBbKGD pHYs  tIME 2DJtEXtCommentCreated with GIMPW IDATxipy( A .Hv`#۲eI=4vcvݝqرG^ynuubI A}_uW~@d "qT7+)v)*c~u?Օߴ1cBι1֬)M^Tnܸ_m{EKQL?;deYW&BP.+~: fyC`, W\o'fff&''0 B;,;!B4Bgsss+*Eф:@c4 v0;˗իWp8l_5 d2w粮cXQWUU)Fi.77ISS|>߶ {GG:::ٹ~GuB7F !wђ?Xw+++4 tx9PVa 郼!BhBR?n;B;McdEX~1ƈFCCfJiMӠ=zرcF-33\2kch===tww~Ѳ,eXRmۦB=dggӧO={Vv{[!6הRUH)mJ^ً:!DWUd]]݁ZU4BIw4M!&ضd2y_>|g>3g"*(RJ5߽QJQPP@h~~>[YY)X[[ (to0N !~#33svlXw 9De޶޲,L&1==wKaJ|BUVV6UVV_`K*8m[XB<ٍ{.ѣ78v9|3 n1kѺRJկ7 >66fі{-m=|8q~>|t{fDRcǎ#G= ٧?_u\<eW^aB>ON>TWWׯömX3.+J$X/{F5Eqy<ӡP?y׏2܊C ιvrD"˻<44!:uhjjB~9dz}s dz6(,B"=ʚ{BضN|_Eoo/f>??O ccc6%0KL%riPJ_R唪B</FvvJ~~QRR8v횸~:,+~)y_֭[uyDs%E+++YYYeRr++..VgE(w%ηV6ǁi0MX ϟ'(++SO8A7sN ygg'YYYʖ߭1ڲ 7o"R~Z\\Lsssz`ll `?0JKKIII <Zzjp!o֭[WߩT /vfܶs7oBگBDBB QU4x]ѣr̒-VWQm=4ea``Ͳ2"۸uI}?J]~_֭[8w\[YY&J^VVFEI'kB :ׯ_wfgg!`,]@vc~:ZZZ  ܏>>>1LLL H 77X]]r C~ ׯ_OÇ VZZ>h 4166fMOOz^X97Ӣ2<n]P8{,$Ec xߏL`uu<p]j;طv[n}_~WՊ CQQ3664Bԝp\x;o=BPPP1# n II|˲:8ccc|ԝ23??˲>UYYv7A++hkkǎ5#9t!={nj(jxC//  ͅ Z΍7 2226L&/ ! ېYo=VqSι;8mەڪ>.Ӏwvvvӛom"V{d(ʷށZ wx/5W^IEϟ?_w }z%%%X__SSS$ȑ#paqdjqM%XsǶm0 H'8[4rTU},[p\zV, ݘa~0uЏAus~"UD.^Eo7Zkmt!Ǫ*?~7o$dX]]ɧ%˶mg||ܲmVUUBطoN8oiiÇ555.%^_җ z tbo k2k*=vMpV uo"D.#{N$K"7NC++;Oi ~w}wW9rwx0>>.8LN¼xN$fѪszLĄ=>>X]]d-b1WCCCi}}=MIߩ:h<(> Ԃl}TU`.!yc2PBP~Dr/_F(BQQCgz~D<' BuBx^^33381KI8狎=c˕_SSӧOk%%%TQ=9iQ!sb^dǐx|MUXJVN$ct2XP2Yn@W\aBu244D"\Zs Dqqqw4f0RXX|ȑ7kjj_yRkt^aOϜ@H(xrd"P2ctjJvǏ@x{*//1@7o$|rrr%;;{ezzom9?KПD`0zˬUnJ=2p,߂0aN"^ԭ@X6e$Ɛ \4P TS`NÜ^߉P.@NNdrx<> !߹6]jjj̈l=C,X˰oz\uTW7{e1$oLnXfzyDWA}nPMM,Hֆ7|nouuuu8v9qDԔX^^\J?MיYݨ!5^niZ9 jx]]8@c C}i3;Ff}JП^mPSÇ>|XZ{{;:;;qGw\!-ǝqÄ5 @-ٰ^7׵j  3 ~jkkÙ3gVr|?*}U4(v[kkk}555l2ikSK|:H p²8M* dw]zzkeYpVff&4Ms&A*!D^w~j;:@)m̻!. Lv,46~&# 8QۆÚ]deʮL[Uzb6d=H v7PY}}=}g- q`,Z9Fr cbzE܇@=OޘZ!{ppJ$\.-S^mdi%Yq@(0-y8eØE>7&`E pp#>8h σ3>Z.… |۶1<Z9Th\0ZI7n^ʲ2A @ n,m9wAmmLh8ܺu+_Qi%OtEQNVVVձ(S؉p}HL¿7%*d7(q;ϟǛoD"/| b1 ɨ%cɓY ei_oQ @y1/A+Fr6#Gք6m|'XX,Hos}x\曲Nt0<qiCNPj_j!zQXH$+SrxԩS M8mc{)**Baa!}\xot;JA:gaҚ׽1 :<կk_b/ r۶kuIwߕOџyIсGxw7SJ.HP r; nXxzyípŚ/\X,=:_M }(eYbp.^1BPQQ ,fa\0*،vo y-O} ׮]CFFrssO~ԧ>܃x<ћ7o (E1pEQl0qbxΝ;w}gΜA󯽌, Eâ<+իWV Ol6ʿK]NU-OGv헗l5 IDATv9s#vvvnO͑tds !4BBH%OvC)eǎcGogZwOi8z$i6MV ',.p O{?Â{JF$Se] ;Ң?qEQ1$Ot۶? \B8;&u-[AT얳!.q_X%GQ 폶mG{{{!{:/Boo/9wu.QT#!vV{l%˲> GQ JNNs.;^͋SJۅW$MӴ~}ι{(B(@,AMӴoܸQ'gXn$O}ОS%LӔn`$+++U$O􌌌K__+@qO"`r~.Ahyy9H$}ڻSK/뵵5kMotB"b)@ wZJ.^vP*+i"c}%Ke80zaYL&H6O*!$sjaa!YYU޲m?񏝟gGGGWssnnN}ȝZZZZܲ,z>@,͇iRjnXEe_}_i.LN\bQ~~>-(( ~rMӄimmH$dvB,AWZ D]XX(/c1Gi,BII ___ׯ]av")[I߬]XX !yyyJAAJd2qķX,vݲ+Ң\21H$;scMQ>abX]]Eoo(JвBKo;<Ҽ:"]{I&Bb||QU{iF\ܱiymb13++bcc㡮.[Feu6@#x|-YGZnIⅅ₂ZXXH Qp8<\QQ7;;wm'@!LӼ{H%φltwwZ>`paaaRBGҫi؏?!^y[gg:6$u6xclnuu5{qqPQevv_ ޟ{)DUUҜunnxvvq /JП J-B,,,,(7n r3g 0%EB|KǑ/JП!7-bavv6{aa!_x<466]Vk"J)rrrz```=uªܾ*.q4ͯ8_CP2R]]tENBQi'N"Ң?[RUP(.G)y+^{5x^8C όښ<#Av BNO744?{VRRBSj{{eYcA9 3󗋊m3gθ꘮wL]8bvv`zzz$B%ҀYRR~ mu]Glp V}vv,//7,,,;3 ~oC"`_;!1ܜw1r|[FSJOBdPN Rruu+ nOE![֑e+}vR__O],O >)rJU՗*Oty8ڋSNl 挱N5662UU!F>Zr `xHХ5FԔqEEEl{t4O՚UUMMM\/))!~T:yfff&_UU, --QUUr^4iwhC}}=gǑ=$SR ksZT@1&!"uti̗zi`eKH;(TA^滛SeYٳg)]}l=8NX":d1 iK,))OEQd2)[d:v=ehTZt PkktsޚJR;c ~JEaXL6tVVVɓ'0Lwg)4hTU%DB6O_eѮ+2'tB)1sRI6.4-9w֐s&9,m'&&&se }߹ ??8HQ-%]w s$۶a!ò,iѥEtefz pq~7lz( ҂,;8SN5v]zU&HNn \VA #no\0J&8DU5XOqp9x<6P ࡣ $7o\[J`BpNLsddĒ?gxiGE4W?##'TtTU݄Ll(edy aa]f"rPN>,=mnIC.DZ?J Ѩ?2{5rM/(*QJ6݂;p|/c7vrrx?E"oG&'~?c 0\?6ȷZ?/ !JEQضϚǢpYEir3AU?mYf ~1:51ꚚXm'4U4m8gTYi~˲`òۉ0RT\1t} Eq B4S=`m uk.(;'O?c}_szqI&w?Zǭ+ AaQ93X2* UU=X䛮^сW^SMӶ 544h>߯\gLy(.nn+p3 3$JӢ F\b( C/,vbE[~@@u\9Խ !6I/yyyv΢r-T\}PPTR!ijWL4UU m?|57 ¢ϗA< nq\ -趝LDkk-vϱj)n>W!(( Y~C 3"UUS5wNF*4T\F Ce^Ƕ3eY`LQb1ղtv?X^^/km`Ybiy}S4**GALx4M dgggǢLLB|mgUECaQ/9Sײ≄?]FaYד?q\| 84eIJ)EcbX/յ}A7Y͂a۶#m y*e˿ }!F C9z-!kGkk -7ۓH$0<<躾gp>e:::O~:\.Dz5Dd"4]Iv9B0H~a/"˦}kzj͏LM-B (EQW86(IV]5R\rfg&Jpn۶f&TӴ,7LD$傢(i"Lb}}sss)+*}vcnSSsU鱘++Ƀ;n1EAaep{Y ! x=W^yExVVq#՘PH"^א,.*8eB)%ı93 +N8J˫K)4]G]PX6-10(y&n޼@ Yy7i{9PpΑL&ݍ~ ayyXYYA,m PTT7x8z(<|>ߞVI/Fiyn<5Us9D]Ḵm(EѶaiJm tݟ3322m92r8_/G#՘qW] *Sp81QN6 T\]wm ΩPBF K4<FGGQ[[oсo~F,{4ѱѹ^g>gb޾9UTjWoǶ1911pe %6Q9.]GOOWD"s!L~ na2TCdSwtGm/SJ2ĵy$ޟ@oJMomcJB=ٶHП!M,$Ͱp.|>x~Psr˂X8Et"ɝm) r S X> ]qjmm sa}}_/b||x,A+@<L٩0[\\__;|y{K[s GQI5o6SSc0 L < H0,?2\d{@bE1;7 ?\' i,HT+gHo>%, nWfx3qupykTy-r#Ƶkdƅ%I\v ?v~D"DʚHEԲLxE h Z ZmH021O(*)GUXC%ϐ&1- k q vF|^8 n8tڿ1MՑL`ffp[з>.in,'vx!`'V `ˏ¢rl.&rY6~e"E^0P**v2c J*,R͕JП$-{r!2MM.]]38Ξ=Z,V 1?7 .tuuKSo]u`0|:=6++ (**B xh{:ilp4 C[Ҍw> (#9_fFi,#f lj ik!(% *yyyԟ1[1||[tZp1ckID ^U?.a Di PTR9owDDװd"۷o#77YYY[RjDڒ:tpa4=9?MӐBTUUm&x;Χw!i()Ѻ&'{m s30wI!HXY[úebL"`$e JKn;NM#Y8666+AߟR(mu ee_.[! lL%-2eXV Z9zE5}3cθ]@@@`q~i"H`jj `nv]i4MC]]aYlۆNO p!|sٳgQXX̀ܽ[{{;z-öm5Ǒc`Ap!KwEEʖS 1uZ BJʡGv}!8)NCae+=X\\Cض&|>\K'|+X[[VWWFa6ǁmucCaa!~w%%%D جgn{Mm҉1CֶrWϧA\J4xgc@ nC30@ƒ(.ocvzQθ\.۷;ejJQqrmĶ;j:|c9iw±mpȪݨ*2elˈp<8 Dž۷oܹsp\رcGu[ZaOOD099 `oc<}{؎qc21$"F*+jXݭ}ZlU#J&3{<=_s?<:&Zb|(R9w9{Rf( VRIDATS?EQ( 4Mxڥ###xgQV,˕]N]9i$QjԢ4MfTuR)teTIdW*Udj Ʀ&ژeȲ lzxn}ܒ2ɒw~?pEa&ָ[GS SG2+\3J5n(eYZ7CԦnUUIZmfK/,"xȲI]seqI !"r) T%ʊSTjNvfUEY(:wI]|҇҇(2 5iq};OݛEYVnK4x,jlgjRjBr /^Q|>7 eYx`Ae}(ou$O&\.˗/КzEQw4v7!麞P@nBw\ut:yPNc':.NS[ɚbin.^msu=L&nw??*9|)zaf5'!8t:K|0׬T Xn;B+N$ pF˰,Kjll6(7}󡡡rѣGxnK3>~hffɃַUU,?Tntuuaqqz[ QHaLMM:t'Nnݵ>t(5 X:36r^!&ci{"].Y,Pm-F߱:;;y&,G2٬Xȁs8]pp1M4WaQ ˢ0<ąwWJfsScP,ncjjSyd2luuUX0t4JxZc6U?GсW^y=_?8??gX7U;|>J慠^^N=^OLG٩ȤSSiUu~m`R f/K{} >Zּ +QRWm6[X,*ʿU*])*Iiy0Jү⋙C`}wjWo5iwuzr h;w`غmttccc&9s'u;WUr}MQ*B#mxDܹt{cEETRl6cnǾ-} (5[3אL&]޽}hni!KKr2whcnGLp9˲|0i&c!]/q.\0w* >.ov:J!0  tJ)fxl6q5O#v,bct^4;9џvoZ#KfH-3gx~n"$ R&k!N#vI$RzMyRkn-0y(eUUeZ[[<,]]]r4ݸi{@ ikk#ߩSމ$p8r%#IᡡiB!4͍_74 ^=}"# ŋR #k_S/>@eBoo/ B!:u _S\bt^}F$8΍}>i4 ^?x(T*_s=r_N | ڹݞ188xwޙ{ %B499ӧOo';|>!p8vg?L#<}a``. eJ}㗿\4}-X4t`P BwTjw0逸'm.FeDh#GڿRT*LLL'N^T*n %DՂagMӌR E!@JZ9UUy54 s^KAsrP:w;w\)_({snV#pޯ(OWե#G׷mnzzzz577g1 B|j&2fff.NMMP(M)-7ArSS=MӴ+1^Be={{zzynnNTU5PUաi3zގ;u}maa!S;"*@nwwwwkR b*~ao8փM(cqw\XX8uע(J}vvڻwo4sR)\|"Ѕm'TBf}}}iJ&|>oz<+Lʵ֫~ /.|NtX\\r+#~aZT*W_                                    Gd?SIENDB`ifetch-tools-0.15.26d/htdocs/stop.jpg0000644000175000017500000000124712475075610016135 0ustar useruserJFIFHHExifMM*CC"   ?.WGB2'*tW5{sއĖ:*B"fZlԁT;agl,OK>lQxz>.qsA~q9lp͌+fPyHȠmO=MimhvI0.^zlZjh)YEeeLn୚+ #mieJ\f%;jD琰drQos!'t Y;GCN=@s_<2}TI\/j>}IB?BJH.Z?nJH`UNypu\-5:[h~^MzU!; Ԭ駏m+-k\EWifetch-tools-0.15.26d/htdocs/missed.jpg0000644000175000017500000003264012475075610016435 0ustar useruserJFIFHHCreated with GIMPC  !"$"$C" V !1"AQ#2aq BR$3%47CvUWbr58Ggs#!1"AQq ?t((((Yj7ln^Mylw%J؁k)JBAQ5VzZYtL}!6Ҕ 8ZRT HۂI^:W4!&c@XJ NRZ'^zolxy0-cNu} :VqNTLeA* :JZ#jxr2y sXj8ݫY+IΏ^Ӯ &KlpVJ+_4ďDFm5&{vLVTw:iBxP$ ޡjX+/F,!J H ’q|OU.T AYqK>˅4iP*AV4>i&QwuFR!I*^Ԕ@ܲ8 řO g nu&"(JB ImDD !)FJqAd_σt,ʉ%ۨPV 5RRRRRRR9\oԷxם4ĜOKHr;ʂTLoY3Jyp!Hʔ$S:񨶴D7ey:O4Dt/n|ĀBmMΩ%K*YjK(Huⵡ;=>> LTvZw8dzF7(Kaj$N!ZuԚTަ繑pbJ($^-Ys 7%c;+c*ǜܕR7͸OY-.6ȍA 8n<3R QiFv@lyUB\b%nmCRNBB gb~^ , A߭5\l !^%r@Jp # } /OxV Pux?VO]'" ]08vihg*<+8 stlOvݰ ܬgOΣaOg558o^mOۛq>JQh&sX狀tz{f=luͩ p_ԍ:\A(VczD筐~-ќe ?i<k3KZi4nUkWYS)I;|p01 u$eƔBb^(Sm(No'H»>#"UKtRcDnJ8- P>7Ztg48Fj1¶rSQi+%8*ܢ ZA+e~TGPiJ L,:Jp lG_^HjCE]tVi( b"M_I_Å$#҃Բo)ֽE;?n{b>rJJӵ{x w F_N<~[w 9;FӹiBK[t@ӢI.,r X^Y܀5{S kpmؒlMuAFI >I'ߩT7Ç뮘}3ԧf.^]yN˄gw*}E'v7 k@flt7ԈI*I =f3U_[N:ͺ6DOTH @uzu}M706d:AI$nYH:kzz suԇF%qhAvd(pF[[V5/ ^x]_%6=9neDa![ZJۀVHJ@4J:&m7Q] uƇg|sGwyخ֍u`m2KyeU$G^$j/r{\4.(.-xY *A' ̝A]/!^yZ>ŋLۭ1CmŎG{}^rq^|՞ 剷h^ !@|'cw_Ή%&@7 lh$Fv=]1Ѻr#"!@3gސ>ڊ~CBï;t8wo]vY֞!=Lt~k}t-5b6*I<1y ǰ5o/BMn~)z8{5>:kyOzo_Iz7qHP[I!]n[.ZN-8Ru+>Vo6axp]2%~ʳ޲M}xuɑ`t$)jwHO]51;p8M{q?\?*vDo+R56o}x8C#^p >.EWr\T7H~"JqA#k14{ˀ2Ҥ3 d~}XX-3i/r6*q VO8R~[3H}2sP9/o>dFUΕ(s@> ulֵtM]q/j j8ސq-m>ꂫ(EJ$O&/Vņ?>s R;J>I?uaϤkmH#ZS-|>& ..Ӓq2v}! IPCV1ք ^X];aqd$$G²>tc \#9S[ԟ1R$2?* :V<Pt3._{Ko:R ۜZ V4IRI>#:fJ:7L!ۖ%$=v:@PXP܏5dG.%A;RӻvG Pmʕұ] _,p/v"3rIq!HVIOzER <+ڧTrH~::,id8(+C J[Tܓ3YjV3ϹDv'J %$W>\N%R产} uj9RԣʔI$&Ьʺ_>mڒTiZPZHP)y\ mZ7HZ*2#)x+*QeJ'޽Rj0sNܮzZ§ JP%jNUEl#%AȎV\إvH H \s(: 䈒~&"{]< %n{T#]tJPHMHK7Ft\8WMcFTr*rV ?J@*W}4LN=Lvw_)m`gpey8''֑Z3^?*osg{vv{px KA'{M&kmN?! ʹkb910$cjAF Ϸ5$%)zLiXzxi߹P=G88o'<<3k{fqE+G#)K}N_ |,6 j" RnqfZtt7K{me{'= 7f˽%&4(+qv̓Q3RatQ¾;.bӑ\1|TkR^Z2wS:^u]Ԣs~}jPS10igX`J A8cL͡tH_>ڴ5MvmZ[$rm8I@H)Y08\Qhx*\IcPk}GpLmH);S{Z4\6h)s#YP{ׄxI=*u:r!_@[\)*I JxpU#3*Mտa/Ac7y4r- g48Qǀ|9ᾞk)m(._$G2֐Zچd=5mSUcZP>CVwkǗ?wYsJRJRJRPJE]EԺr 9w AqHi!%D 3*ogˍS lWT\Vq>9;!?H 7qg&jo$,  u@{ y27m5o߯?KKZ?\?^KC^JwYi +)$zq qEA\ʠ~\u^LG:pִH`!e=XՎa$ PMYuF_9ܕ'[Q =NfcYm^izW%єl'#* z֜n$g-q9I~Cޤ_nƠh[{V{XYݺI yyh~jqPq_9rRC,2Z$ OUoYAJ{e9J#&jxC?nyi b<mS\\ HnDY iչ+Ikq q mhJҡ8##SaԷM0\7XJ0Hc4+s\)JP)JPk7srBb?;?1 .T޺맦IzKYJpA !J86~\mK!uSirr9o8_*R ׎\+乌yLD [|ƃd}c.'ӞZߤLw%Yfj"3.mvy<kz{fvMQ':^) 6gnF+N+ϷnTWv%^[)  >uk \#7*+1a@p@?:)J)J >¢μ]-LʼɊA3 ֯qGR*)ss ۬B[P!jRJF=h=ډX@mBR`}kXT5@z贐v*CzP V:eVS:KtvS &&'r FߺAV-gOtjEs;7d~ 4jkA@P9RWJtcϽxJ+i-XH$ Oʻ ?u;&\o',%Q1 AIO"t/J%<8VQʖTI$I5tF{6=o{q%ɇw)uN'_hgKgLyHqɽ~rS6P04K;)JB~6qnqJAItwtV&lgtfeDҙ} m(aHRO I 6ļkOF(YɠٕpEs^6q.1X RR(J67]!iBL⛞Q'n2I Rʁ씐y'O":G&iV>znAg$- n Glڡ82q8+[9ZO%DyEA J†1቎埔ϥݭ)i|UwO#gLRiLh7_P(q)Qu*9 zO#rn:1G)Sj JApMs&%x;*p},DҝyBR2MkQԭRRQD c?(~H.];$*gHtvBH3UqIV/IZv.b# /r'st+Am.5jR8 !ޮp?[ڠX- Ii`>: )@H8N5V)v?NiFڟCD-̟a~uV`V;m$>i8^ƚR,GIq"x.%Hf,H͗yՄ!2TI5+ĆRa[>8Q ?{]H<)!N$;w%}9m͈Tʂ‚6C$ )H<^^Ե-v^%-] KnHRI>}KM,8)$jMdu)mI I )jMϧkRRNW𧍙=@vL^=}'Euw]ki^{ʱe\XmRJKi( $ aA`ԞVn.R’/7(% (z]e>%r”RFHBSpY,XsK[>%Zޔ'* @4.Ҷ9ǜj&!$V3}PoZQ@Q7!@IHVG2JRJR.%-L6n^RXc)RT?$Fkqw\ }@Fr,>cN$iH#)$d~U~4߉}ET%8*i V_/]W{}4T+_cn8-}LyױRR аJ) )#pR#חknTgR%m݉Y!CjRvRABǬ:s]Ẋ-r.B[N¤')'FA#u,6d6BH-N 6 m$8WVh{Z'VRp3Y[lwfѶ Bqr#%,e*QJBʁvw{cPl[ 8#$3^vzr4xz}Ge9jKLUL=㭅);ATkmQ?B_gFӒE.ŖUUā/O44v<ߗNqUpu?pꝐ֢}_{g툟oݦcӬTI$y$שT(vj? $ט҄$j8J@'WIYZm{tQ\ xA6 ?>=Oے-#|p0D5 qo{Q[Vġ>ZHn{x醡N,l9=-6~3i*qvwTaݐN=6I9w\68ݵӫtwSY[n|)@A'q٨U֑J_ݝ;j`AC Fsڼ{a^Ͳ&- 2@W$uRFsyӵ@}'ˍ36T%m)I@JTQKg5 Ef&g:X~[μY(rBTܥ8PۅML^Pz⍖=1%LSIBӁjq\i)!dӟǤ]fu՜Jp'r8ZJPRv݌ԙJP)JP)JP*ghSNδ[:6ˡ()$nJ%*^fPi|IP'H:3euL͔8p)'AEJ~zv]RJ\+h 6焺28 %Da*E:߯SkKSRd9Fh-[W"0%nSؗ OI 0=[ۭ͑p専VR=9zɤ(LԺj`O֡' ~Y PZrBCvΛ-lQR(\)qTH3LFGQKrJNCh^%*oѧ>>Ӧ-.%sWG*agkd|;_uUfqP/CJ.g}Սr|ҒZ7EFT $h0ه am!)B@ ͇duƗ ahu!IPj{Lyl%ϴj*B1޾ #Ty53:AB4xc6V\JՔ$c t;t;ͥ Mi ؒ ²SH 4NPqZIJ^OPW>ڠioč:EjdVB;^TU_[jN=+raZ$3TO:tjǑ.lsǷz !,oҖm<Qj哧V8܌bPo!c;pj꾠5Sk.Qm.<}cʾfO F-< DGa Cm)ijRH`cA8#+7:\یՠ|T?\GpIYOw+⭫y}9RRjw"'sK a+IP?U]NS4.T+1Ԕ\ur`(j3[%`-9ڣ(?=2ѷM-NYLN%)JAR!G+i,6h{~ DG yd*$[nC)ZT8RH 8 ~iPA*b}u[<.nD <S"%ㅳS~U-Ќ@sW~>%KG1;`+i>gF[O@}C0yi! 8e Ƃ&Z6Ʀ2 ҨVL̅哑RF+^f6 5f㡔?>Z#$$)dAҫnK#+oKEe6щ%xRGP9H}t?Sƿ~Ҭzma'%N bD(-/nka霟/"CIZU2SZ;·(H5UuCn/\ndHt{) WRDz:#c9[*vnҚFj,D|-HRTkoҽmW[ֻݲ|سK9ACr8Pdwiҽ15V՝Kz|N߈:sݹۻbnV3'WS6xt<WJs !*솋cNKRx#֌NB4Vވ^NR qI$07ۭ6ˑ:l4y֐NA n#331{UGmenGJvvvq"z h7 )եW!#$%tjㄤOXO?g]zo~6Gi=3 10?%zFw8 ʲF0& Ib:;Չgڵ.ZB`-i ByJ  PdګĿZu 3c;޷DͶ;Q߸!P9)G ''1eu]^snsʘuͩ I@'k'.×!Zsv.l)F־Ha'3$<֘`m'9bϨF0% *g]).lΔǟHۜS]2KJ 'S7#Lm8\lw -/pXBM *R>>;'G^Wifetch-tools-0.15.26d/ifetch-tools-html-page/0000755000175000017500000000000013155645553017437 5ustar useruserifetch-tools-0.15.26d/ifetch-tools-html-page/grey.jpg0000644000175000017500000000063612475104127021103 0ustar useruserJFIFLHExifMM*C  !"$"$C"$A!1aq!A ?9-)IoVX4|ZUQks>UZ$@pCQc{+x\~^TUZjtӀW}xV|JpQN`Kkph?ifetch-tools-0.15.26d/ifetch-tools-html-page/index.html0000644000175000017500000001241613155645553021440 0ustar useruser ifetch tools
ifetch-tools - A set of tools that can collect images from ip based cameras, monitor collection process, and provide an interface to view collected history. The current release has two components:

1.) ifetch.rb - A console tool written in ruby to collect images from ip based cameras with a conf file per camera.

2.) wwwifetch.rb - A ruby servlet to view collected history from a camera and monitor the collection status of each camera. The following feedback is provided on each cameras collection status:

- all well
- collection in alarm mode
- collection is offline

Cameras donated/tested for the project will be graded in to three categories as follows: Excellent, Average, Other.
Manufacturer
Rating
Model
Comments
Amcrest
Average IP3M-954E Works out of the box for configuration. Camera exterior is well constructed and should last a long time.
* Had trouble getting good frame rate on image pull which is what ifetch-tools utilizes.
Apexis
Excellent APM-J011-WS Works out of the box. Camera web interface can now be utilized with Linux+Firefox so upgrading rating to Excellent.
Axis
Excellent 2100, 210, 206, 207, 221 Easy to work with out of the box, excellent frame rates, and tech support is very good.
D-Link
Excellent D-Link DCS-930L Easy to work with out of the box and inexpensive.
Hawking
Average HNC320W Works out of the box, inexpensive and sturdy. I only have a HNC320W wireless unit to test.
IGuard
Other IP-250E Low fps on jpeg pull. About 1 frame every 2 or 3 seconds.
IP Camera
Average 510 Works out of the box, inexpensive and sturdy.
Plustek
Average IPcam P1000 Works out of the box, web interface, dome model, and tech support is very good. Camera expects to have IE for web browser and general access.
Panasonic
Excellent BL-C210A Works out of the box, inexpensive and sturdy.
Trendnet
Average *TV-IP201(P), TV-IP301, **TV-IP320PI, TV-IP512(P) Works out of the box, inexpensive and sturdy. Takes cctv lenses.
* On the TV-IP201(P) can get duplicate frames on short padded jpeg pulls.
** On the TV-IP320PI it requires addon software that appears to be IE only for username and passwor configuration. All other settings I cared about I could set from a generic browser.
Toshiba
Average IK-WR01A Orite IC301 Works out of the box, tested for a user.
TP-Link
Other NC220 Works, but, depends on M$ for some feature and password is bas64 encoded for snapshot pull.
Wanscam
Excellent IP Camera Works out of the box, inexpensive and sturdy.

If you do not like the above opinions please email me for information to send a unit you want me to test.

Current release - 0.15.26d

ifetch-tools information being tracked in Debian:

BTS (Bug Tracking System)
PDO (packages.debian.org)
PTS (Package Tracking System)
VCS (Version Control System)

Also see FYEOX.COM for other ifetch-tools related information.

Last updated on 20170317

ifetch-tools-0.15.26d/ifetch-tools-html-page/ifetch.png0000644000175000017500000005051512475104127021404 0ustar useruserPNG  IHDRZ=sRGBbKGD pHYs  tIME 2DJtEXtCommentCreated with GIMPW IDATxipy( A .Hv`#۲eI=4vcvݝqرG^ynuubI A}_uW~@d "qT7+)v)*c~u?Օߴ1cBι1֬)M^Tnܸ_m{EKQL?;deYW&BP.+~: fyC`, W\o'fff&''0 B;,;!B4Bgsss+*Eф:@c4 v0;˗իWp8l_5 d2w粮cXQWUU)Fi.77ISS|>߶ {GG:::ٹ~GuB7F !wђ?Xw+++4 tx9PVa 郼!BhBR?n;B;McdEX~1ƈFCCfJiMӠ=zرcF-33\2kch===tww~Ѳ,eXRmۦB=dggӧO={Vv{[!6הRUH)mJ^ً:!DWUd]]݁ZU4BIw4M!&ضd2y_>|g>3g"*(RJ5߽QJQPP@h~~>[YY)X[[ (to0N !~#33svlXw 9De޶޲,L&1==wKaJ|BUVV6UVV_`K*8m[XB<ٍ{.ѣ78v9|3 n1kѺRJկ7 >66fі{-m=|8q~>|t{fDRcǎ#G= ٧?_u\<eW^aB>ON>TWWׯömX3.+J$X/{F5Eqy<ӡP?y׏2܊C ιvrD"˻<44!:uhjjB~9dz}s dz6(,B"=ʚ{BضN|_Eoo/f>??O ccc6%0KL%riPJ_R唪B</FvvJ~~QRR8v횸~:,+~)y_֭[uyDs%E+++YYYeRr++..VgE(w%ηV6ǁi0MX ϟ'(++SO8A7sN ygg'YYYʖ߭1ڲ 7o"R~Z\\Lsssz`ll `?0JKKIII <Zzjp!o֭[WߩT /vfܶs7oBگBDBB QU4x]ѣr̒-VWQm=4ea``Ͳ2"۸uI}?J]~_֭[8w\[YY&J^VVFEI'kB :ׯ_wfgg!`,]@vc~:ZZZ  ܏>>>1LLL H 77X]]r C~ ׯ_OÇ VZZ>h 4166fMOOz^X97Ӣ2<n]P8{,$Ec xߏL`uu<p]j;طv[n}_~WՊ CQQ3664Bԝp\x;o=BPPP1# n II|˲:8ccc|ԝ23??˲>UYYv7A++hkkǎ5#9t!={nj(jxC//  ͅ Z΍7 2226L&/ ! ېYo=VqSι;8mەڪ>.Ӏwvvvӛom"V{d(ʷށZ wx/5W^IEϟ?_w }z%%%X__SSS$ȑ#paqdjqM%XsǶm0 H'8[4rTU},[p\zV, ݘa~0uЏAus~"UD.^Eo7Zkmt!Ǫ*?~7o$dX]]ɧ%˶mg||ܲmVUUBطoN8oiiÇ555.%^_җ z tbo k2k*=vMpV uo"D.#{N$K"7NC++;Oi ~w}wW9rwx0>>.8LN¼xN$fѪszLĄ=>>X]]d-b1WCCCi}}=MIߩ:h<(> Ԃl}TU`.!yc2PBP~Dr/_F(BQQCgz~D<' BuBx^^33381KI8狎=c˕_SSӧOk%%%TQ=9iQ!sb^dǐx|MUXJVN$ct2XP2Yn@W\aBu244D"\Zs Dqqqw4f0RXX|ȑ7kjj_yRkt^aOϜ@H(xrd"P2ctjJvǏ@x{*//1@7o$|rrr%;;{ezzom9?KПD`0zˬUnJ=2p,߂0aN"^ԭ@X6e$Ɛ \4P TS`NÜ^߉P.@NNdrx<> !߹6]jjj̈l=C,X˰oz\uTW7{e1$oLnXfzyDWA}nPMM,Hֆ7|nouuuu8v9qDԔX^^\J?MיYݨ!5^niZ9 jx]]8@c C}i3;Ff}JП^mPSÇ>|XZ{{;:;;qGw\!-ǝqÄ5 @-ٰ^7׵j  3 ~jkkÙ3gVr|?*}U4(v[kkk}555l2ikSK|:H p²8M* dw]zzkeYpVff&4Ms&A*!D^w~j;:@)m̻!. Lv,46~&# 8QۆÚ]deʮL[Uzb6d=H v7PY}}=}g- q`,Z9Fr cbzE܇@=OޘZ!{ppJ$\.-S^mdi%Yq@(0-y8eØE>7&`E pp#>8h σ3>Z.… |۶1<Z9Th\0ZI7n^ʲ2A @ n,m9wAmmLh8ܺu+_Qi%OtEQNVVVձ(S؉p}HL¿7%*d7(q;ϟǛoD"/| b1 ɨ%cɓY ei_oQ @y1/A+Fr6#Gք6m|'XX,Hos}x\曲Nt0<qiCNPj_j!zQXH$+SrxԩS M8mc{)**Baa!}\xot;JA:gaҚ׽1 :<կk_b/ r۶kuIwߕOџyIсGxw7SJ.HP r; nXxzyípŚ/\X,=:_M }(eYbp.^1BPQQ ,fa\0*،vo y-O} ׮]CFFrssO~ԧ>܃x<ћ7o (E1pEQl0qbxΝ;w}gΜA󯽌, Eâ<+իWV Ol6ʿK]NU-OGv헗l5 IDATv9s#vvvnO͑tds !4BBH%OvC)eǎcGogZwOi8z$i6MV ',.p O{?Â{JF$Se] ;Ң?qEQ1$Ot۶? \B8;&u-[AT얳!.q_X%GQ 폶mG{{{!{:/Boo/9wu.QT#!vV{l%˲> GQ JNNs.;^͋SJۅW$MӴ~}ι{(B(@,AMӴoܸQ'gXn$O}ОS%LӔn`$+++U$O􌌌K__+@qO"`r~.Ahyy9H$}ڻSK/뵵5kMotB"b)@ wZJ.^vP*+i"c}%Ke80zaYL&H6O*!$sjaa!YYU޲m?񏝟gGGGWssnnN}ȝZZZZܲ,z>@,͇iRjnXEe_}_i.LN\bQ~~>-(( ~rMӄimmH$dvB,AWZ D]XX(/c1Gi,BII ___ׯ]av")[I߬]XX !yyyJAAJd2qķX,vݲ+Ң\21H$;scMQ>abX]]Eoo(JвBKo;<Ҽ:"]{I&Bb||QU{iF\ܱiymb13++bcc㡮.[Feu6@#x|-YGZnIⅅ₂ZXXH Qp8<\QQ7;;wm'@!LӼ{H%φltwwZ>`paaaRBGҫi؏?!^y[gg:6$u6xclnuu5{qqPQevv_ ޟ{)DUUҜunnxvvq /JП J-B,,,,(7n r3g 0%EB|KǑ/JП!7-bavv6{aa!_x<466]Vk"J)rrrz```=uªܾ*.q4ͯ8_CP2R]]tENBQi'N"Ң?[RUP(.G)y+^{5x^8C όښ<#Av BNO744?{VRRBSj{{eYcA9 3󗋊m3gθ꘮wL]8bvv`zzz$B%ҀYRR~ mu]Glp V}vv,//7,,,;3 ~oC"`_;!1ܜw1r|[FSJOBdPN Rruu+ nOE![֑e+}vR__O],O >)rJU՗*Oty8ڋSNl 挱N5662UU!F>Zr `xHХ5FԔqEEEl{t4O՚UUMMM\/))!~T:yfff&_UU, --QUUr^4iwhC}}=gǑ=$SR ksZT@1&!"uti̗zi`eKH;(TA^滛SeYٳg)]}l=8NX":d1 iK,))OEQd2)[d:v=ehTZt PkktsޚJR;c ~JEaXL6tVVVɓ'0Lwg)4hTU%DB6O_eѮ+2'tB)1sRI6.4-9w֐s&9,m'&&&se }߹ ??8HQ-%]w s$۶a!ò,iѥEtefz pq~7lz( ҂,;8SN5v]zU&HNn \VA #no\0J&8DU5XOqp9x<6P ࡣ $7o\[J`BpNLsddĒ?gxiGE4W?##'TtTU݄Ll(edy aa]f"rPN>,=mnIC.DZ?J Ѩ?2{5rM/(*QJ6݂;p|/c7vrrx?E"oG&'~?c 0\?6ȷZ?/ !JEQضϚǢpYEir3AU?mYf ~1:51ꚚXm'4U4m8gTYi~˲`òۉ0RT\1t} Eq B4S=`m uk.(;'O?c}_szqI&w?Zǭ+ AaQ93X2* UU=X䛮^сW^SMӶ 544h>߯\gLy(.nn+p3 3$JӢ F\b( C/,vbE[~@@u\9Խ !6I/yyyv΢r-T\}PPTR!ijWL4UU m?|57 ¢ϗA< nq\ -趝LDkk-vϱj)n>W!(( Y~C 3"UUS5wNF*4T\F Ce^Ƕ3eY`LQb1ղtv?X^^/km`Ybiy}S4**GALx4M dgggǢLLB|mgUECaQ/9Sײ≄?]FaYד?q\| 84eIJ)EcbX/յ}A7Y͂a۶#m y*e˿ }!F C9z-!kGkk -7ۓH$0<<躾gp>e:::O~:\.Dz5Dd"4]Iv9B0H~a/"˦}kzj͏LM-B (EQW86(IV]5R\rfg&Jpn۶f&TӴ,7LD$傢(i"Lb}}sss)+*}vcnSSsU鱘++Ƀ;n1EAaep{Y ! x=W^yExVVq#՘PH"^א,.*8eB)%ı93 +N8J˫K)4]G]PX6-10(y&n޼@ Yy7i{9PpΑL&ݍ~ ayyXYYA,m PTT7x8z(<|>ߞVI/Fiyn<5Us9D]Ḵm(EѶaiJm tݟ3322m92r8_/G#՘qW] *Sp81QN6 T\]wm ΩPBF K4<FGGQ[[oсo~F,{4ѱѹ^g>gb޾9UTjWoǶ1911pe %6Q9.]GOOWD"s!L~ na2TCdSwtGm/SJ2ĵy$ޟ@oJMomcJB=ٶHП!M,$Ͱp.|>x~Psr˂X8Et"ɝm) r S X> ]qjmm sa}}_/b||x,A+@<L٩0[\\__;|y{K[s GQI5o6SSc0 L < H0,?2\d{@bE1;7 ?\' i,HT+gHo>%, nWfx3qupykTy-r#Ƶkdƅ%I\v ?v~D"DʚHEԲLxE h Z ZmH021O(*)GUXC%ϐ&1- k q vF|^8 n8tڿ1MՑL`ffp[з>.in,'vx!`'V `ˏ¢rl.&rY6~e"E^0P**v2c J*,R͕JП$-{r!2MM.]]38Ξ=Z,V 1?7 .tuuKSo]u`0|:=6++ (**B xh{:ilp4 C[Ҍw> (#9_fFi,#f lj ik!(% *yyyԟ1[1||[tZp1ckID ^U?.a Di PTR9owDDװd"۷o#77YYY[RjDڒ:tpa4=9?MӐBTUUm&x;Χw!i()Ѻ&'{m s30wI!HXY[úebL"`$e JKn;NM#Y8666+AߟR(mu ee_.[! lL%-2eXV Z9zE5}3cθ]@@@`q~i"H`jj `nv]i4MC]]aYlۆNO p!|sٳgQXX̀ܽ[{{;z-öm5Ǒc`Ap!KwEEʖS 1uZ BJʡGv}!8)NCae+=X\\Cض&|>\K'|+X[[VWWFa6ǁmucCaa!~w%%%D جgn{Mm҉1CֶrWϧA\J4xgc@ nC30@ƒ(.ocvzQθ\.۷;ejJQqrmĶ;j:|c9iw±mpȪݨ*2elˈp<8 Dž۷oܹsp\رcGu[ZaOOD099 `oc<}{؎qc21$"F*+jXݭ}ZlU#J&3{<=_s?<:&Zb|(R9w9{Rf( VRIDATS?EQ( 4Mxڥ###xgQV,˕]N]9i$QjԢ4MfTuR)teTIdW*Udj Ʀ&ژeȲ lzxn}ܒ2ɒw~?pEa&ָ[GS SG2+\3J5n(eYZ7CԦnUUIZmfK/,"xȲI]seqI !"r) T%ʊSTjNvfUEY(:wI]|҇҇(2 5iq};OݛEYVnK4x,jlgjRjBr /^Q|>7 eYx`Ae}(ou$O&\.˗/КzEQw4v7!麞P@nBw\ut:yPNc':.NS[ɚbin.^msu=L&nw??*9|)zaf5'!8t:K|0׬T Xn;B+N$ pF˰,Kjll6(7}󡡡rѣGxnK3>~hffɃַUU,?Tntuuaqqz[ QHaLMM:t'Nnݵ>t(5 X:36r^!&ci{"].Y,Pm-F߱:;;y&,G2٬Xȁs8]pp1M4WaQ ˢ0<ąwWJfsScP,ncjjSyd2luuUX0t4JxZc6U?GсW^y=_?8??gX7U;|>J慠^^N=^OLG٩ȤSSiUu~m`R f/K{} >Zּ +QRWm6[X,*ʿU*])*Iiy0Jү⋙C`}wjWo5iwuzr h;w`غmttccc&9s'u;WUr}MQ*B#mxDܹt{cEETRl6cnǾ-} (5[3אL&]޽}hni!KKr2whcnGLp9˲|0i&c!]/q.\0w* >.ov:J!0  tJ)fxl6q5O#v,bct^4;9џvoZ#KfH-3gx~n"$ R&k!N#vI$RzMyRkn-0y(eUUeZ[[<,]]]r4ݸi{@ ikk#ߩSމ$p8r%#IᡡiB!4͍_74 ^=}"# ŋR #k_S/>@eBoo/ B!:u _S\bt^}F$8΍}>i4 ^?x(T*_s=r_N | ڹݞ188xwޙ{ %B499ӧOo';|>!p8vg?L#<}a``. eJ}㗿\4}-X4t`P BwTjw0逸'm.FeDh#GڿRT*LLL'N^T*n %DՂagMӌR E!@JZ9UUy54 s^KAsrP:w;w\)_({snV#pޯ(OWե#G׷mnzzzz577g1 B|j&2fff.NMMP(M)-7ArSS=MӴ+1^Be={{zzynnNTU5PUաi3zގ;u}maa!S;"*@nwwwwkR b*~ao8փM(cqw\XX8uע(J}vvڻwo4sR)\|"Ѕm'TBf}}}iJ&|>oz<+Lʵ֫~ /.|NtX\\r+#~aZT*W_                                    Gd?SIENDB`ifetch-tools-0.15.26d/ifetch-tools-html-page/green.jpg0000644000175000017500000000070412475104127021231 0ustar useruserJFIFLHExifMM*C  !"$"$C"$!1a!A ?[ynFrpd1-$s;VnUSUZ :l |dcUy?n[ehZ̅ *ǹ&Z5ĈC$c'ZfnDuifetch-tools-0.15.26d/ifetch-tools-html-page/red.jpg0000644000175000017500000000067712475104127020714 0ustar useruserJFIFLHExifMM*C  !"$"$C""!"a1Q ! ?2 "*kK)>ǟHۜS]2KJ 'S7#Lm8\lw -/pXBM *R>>;'G^Wifetch-tools-0.15.26d/examples/0000755000175000017500000000000013105210660014757 5ustar useruserifetch-tools-0.15.26d/examples/ifetch-tools.conf0000644000175000017500000003707113062773624020256 0ustar useruser##################################################################################### # ifetch-tools is a set of tools that can collect images from ip based cameras, # monitor collection process, and provide an interface to view collected history. # Copyright (C) 2005-2017 Richard Nelson # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 # of the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. ################################################################################## ################# DO NOT RUN ifetch-tools BY DEFAULT ############################# ################################################################################## ## For security the below exit line prevents the start of ifetch and wwwifetch. ## Please set the HISTORYUSER, HISTORYPASS, MONITORUSER, and MONITORPASS to what ## you want,then remark out the lines below when you are ready to start using the ## program. ## puts "Attention: ifetch-tools is disabled in /etc/ifetch-tools/ifetch-tools.conf!" exit ## ################################################################################## ################# DO NOT RUN ifetch-tools BY DEFAULT ############################# ################################################################################## ################################################################################## ###################### BEGIN CONSTANT VARIABLE CONFIG ############################ ################################################################################## # Variables in the CONSTANT VARIABLE section are constants used throughout. ####################################################### ## security settings ####################################################### # user name and password for the camera history operations. HISTORYUSER="history" HISTORYPASS="history" # user name and password for the camera monitor operations. MONITORUSER="monitor" MONITORPASS="monitor" ####################################################### ## Web Page Settings ####################################################### ######################### # This sets the home page to navigate to if you do not want to drop one in # in the ifetch-tools/htdocs/index.html . You should put in a fully qualified # link, something like the below # HOMELINK="http://somepage.somewhere/page.html" HOMELINK="/" ####################################################### ## camera history navigation ####################################################### # set the size of the image on the navigation pane. HISTORYIMAGEWIDTH="240" HISTORYIMAGEHEIGHT="180" ####################################################### ## system settings ####################################################### ######################### # Set the base port to add to camera names. BASEPORT=60000 ######################### # Set the sleep when a collection process hits an error. ERRORSLEEP=5 ######################### # Set some variables for the wwwifetch.rb file. # Images to show per page. IMAGESPERPAGE=150 ######################### # This is the max exchange load limit between ifetch.rb and wwwifetch.rb. 50mb = 52428800 LOADLIMIT = 52428800 ###### CAUTION - CAUTION - CAUTION - CAUTION - CAUTION - CAUTION - CAUTION - ###### # Set this variable for history tune. This number has to be prime and I would advise you read # the code in ifetch.rb for how this works. For my development area I will be setting MODPRIME # to 101. This setting is dangerous! This number must be prime and you need to read the code to # understand that it is for directory storage structure. If you change this number after launching # once, you will need to smoke your history. I hope that you understand what I am trying to tell # you in this section. Please, please do not tamper with unless you understand! # # Here are some other prime numbers to adjust to your storage needs. # # 151 157 163 167 173 179 181 191 193 197 199 211 223 227 229 233 239 241 251 # 257 263 269 271 277 281 283 293 307 311 313 317 331 337 347 349 353 359 367 # 373 379 383 389 397 401 409 419 421 431 433 439 443 449 457 461 463 467 479 # 487 491 499 503 509 521 523 541 547 557 563 569 571 577 587 593 599 601 607 # 613 617 619 631 641 643 647 653 659 661 673 677 683 691 701 709 719 727 733 # 739 743 751 757 761 769 773 787 797 809 811 821 823 827 829 839 853 857 859 # 863 877 881 883 887 907 911 919 929 937 941 947 953 967 971 977 983 991 997 # MODPRIME = 101 # ###### END CAUTION - END CAUTION - END CAUTION - END CAUTION - END CAUTION - ###### ################################################################################## ######################## END CONSTANT VARIABLE CONFIG ############################ ################################################################################## ################################################################################## ################### BEGIN NON-CONSTANT VARIABLE CONFIG ########################### ################################################################################## ## Variables in the NON-CONSTANT VARIABLE section are dynamic and can be overriden ## in the various conf files. They are placed here to be used as system defaults ## that again can be overriden in various conf files. So if you are familar with ## these variables, please tune them as you wish. If you are not familar with these ## variables, PLEASE READ THE CODE AND UNDERSTAND WHAT THEY DO before you change ## any of them. ##################################################################################### ## Set the location for data_location ##################################################################################### ## The data_location variable is if your storage is somewhere else other than ## ifetch-tools/htdocs . Do not include a trailing / and do not include the camera ## number. Example line is below: ## ## data_location="/path/to/camera/storage" ##################################################################################### ## Set the options for day_image_sleep ##################################################################################### ## The below is for a feature add allowing for a subset of the entire day to have a ## a different sleep padding on a given time range. So on each day of the week you ## can have a time range where image collection padding is different than what is ## specified with image_sleep. ## ## O is Sun, 1 is Mon, 2 is Tue, 3 is Wed, 4 is Thu, 5 Fri, 6 is Sat ## On a given day "00:00,00:00,1" implies "startTime,stopTime,sleepDuration" ## See the example line is below: ## day_image_sleep={ 0 => "00:00,00:00,1", 1 => "00:00,00:00,1", 2 => "00:00,00:00,1", 3 => "00:00,00:00,1", 4 => "00:00,00:00,1", 5 => "00:00,00:00,1", 6 => "00:00,00:00,1"} #################################################################################### ## Set the options for image_uid, image_pwd, and image_auth_type ##################################################################################### ## The image_uid is the user name and the image_pwd is the password to use if ## using security on the remote camera. The image_auth_type is for basic (the default) ## or digest. image_alt is for dynamic page creation with img src alt tag. image_uid='' image_pwd='' image_auth_type='basic' image_alt='no_image_alt' #################################################################################### ## Set the option for image_addr and image_addr_port ##################################################################################### ## The image_addr is the IP address of the remote camera and the image_addr_port is ## the port the camera is listening on. ## Example line is below: ## image_addr='127.0.0.1' image_addr_port=80 ##################################################################################### ## Set the option for image_count ##################################################################################### ## The image_count is the number of images to store history. image_count=200 ##################################################################################### ## Set the option for image_count_on_motion ##################################################################################### ## The image_count_on_motion is the number of images to store once motion is detected ## without another motion test on images. image_count_on_motion=20 ##################################################################################### ## Set the option for log_files ##################################################################################### ## The log_files is the number of log files to keep in rotation. log_files=10 ##################################################################################### ## Set the option for image_sleep ##################################################################################### ## The image sleep is the padding between image downloads. Each download is a complete ## http transaction with an open, download, and close operation. Tuning will depend on ## each individual setup. For partial second sleep use something like 0.5 image_sleep=1 ##################################################################################### ## Set the option for log_size ##################################################################################### ## The log_size is the size in kb for a rotation. log_size=1000 ##################################################################################### ## Set the option for image_url ##################################################################################### ## This is the url to get the current image of the camera. ############################## ## Amcrest MODEL: IP3M-954E ## http://user:password@xxx.xxx.xxx.xxx/cgi-bin/snapshot.cgi ## ## image_url='/cgi-bin/snapshot.cgi' ## ############################## ## Apexis MODEL: APM-J011-WS ## http://user:password@xxx.xxx.xxx.xxx/snapshot.cgi ## ## image_url='/snapshot.cgi' ## ############################## ## Axis cameras are the default setting. ## image_url='/jpg/image.jpg' ## ############################## ## D-Link DCS-930L ## image_url='/image.jpg' ## ############################## ## Hawking HNC320W wireless ## image_url='/IMAGE.JPG' ## ############################## ## IGuard IP-250E ## According to firmware upgrade 2.55.cv7 ## ## http://xxx.xxx.xxx.xxx/pda.cgi?user=admin&password=1234&page=image&cam=1 ## ## And the following is configured as below ## xxx.xxx.xxx.xxx - the IP address of the camera ## admin - the login account name ## 1234 - the login password ## 1 - the camera number ## ## So the image_url would look something like: ## image_url='/pda.cgi?user=admin&password=1234&page=image&cam=1' ## ############################## ## IPCamera 510 ## ## image_url='/image.jpg' ## ############################## ## IPcam P1000 from Plustek ## ## http://xxx.xxx.xxx.xxx/snapshot.jpg?account=admin&password=1234` ## ## And the following is configured as below ## xxx.xxx.xxx.xxx - the IP address of the camera ## admin - the login account name for the admin username ## 1234 - the login password for the admin username ## ## So the image_url would look something like: ## image_url='/snapshot.jpg?account=admin&password=1234' ## ############################## ## Panasonic BL-C210A ## ## http://xxx.xxx.xxx.xxx/SnapshotJPEG?Resolution=640x480&Quality=Clarity ## ## And the following is configured as below ## xxx.xxx.xxx.xxx - the IP address of the camera ## Resolution - 320x240 640x480 ## Quality - Motion Standard Clarity ## ### So the image_url would look something like: ## image_url='/SnapshotJPEG?Resolution=640x480&Quality=Clarity' ## ############################# ## TPLink NC220 ## image_url='/stream/snapshot.jpg' ## ## Snapshot pulls appear to have port hard coded at 8080 so include the below ## in your config: ## ## image_addr_port=8080 ## ## And security for the pull at time of writing requires that you pass the ## base64 encoded password you configured in the web interface. ## ############################## ## Trendnet TV-IP201 use the below: ## image_url='/goform/capture' ## ############################## ## Trendnet TV-IP301 use the below: ## image_url='/goform/video' ## ############################## ## TV-IP320PI ## image_url='/streaming/channels/1/picture' ## image_auth_type='digest' ## ############################## ## Trendnet TV-IP512P use the below: ## image_url='/image/jpeg.cgi' ## ############################## ## Toshiba IK-WR01A Orite IC301 use the below: ## image_url='/Jpeg/CamImg.jpg' ## ############################## ## Wanscam IP Camera: ## image_url='/snapshot.cgi' ##################################################################################### ## Set the option for image_watermark ##################################################################################### ## The image_watermark when true writes the collection time on the image. ## The value is either 0 for True or 1 for False. ## The default is 1. image_watermark=1 ##################################################################################### ## Set the option for marshal_dump_enable ##################################################################################### ## The marshal dump option is an attempt to help the indexing of time stamps after a ## shutdown,reboot, or a service restart. ## The marshal_dump_enable is either 0 for True or 1 for False. ## The default is 1. marshal_dump_enable=1 ##################################################################################### ## Set the option for motion_enable ##################################################################################### ## The motion_enable is either 0 for True or 1 for False. ## The default is 1. motion_enable=1 ##################################################################################### ## Set the option for motion_mdpp ##################################################################################### ## The motion_mdpp is used to adjust the threshold of motion detection. motion_mdpp=0.002 ##################################################################################### ## Set the option for motion_sleep ##################################################################################### ## The motion_sleep is if you want to shorten the sleep when motion is detected. motion_sleep=0.5 ##################################################################################### ## Set the option for $video_export_type ##################################################################################### ## The $video_export_type sets the video export type. It is set only from ## this file for wwwifetch. The default is mp4. $video_export_type='mp4' ##################################################################################### ## Set the option for $video_export_delay ##################################################################################### ## The $video_export_delay sets the video delay between frames. It is set only from ## this file for wwwifetch. The default is 50. $video_export_delay=50 ################################################################################## ##################### END NON-CONSTANT VARIABLE CONFIG ########################### ################################################################################## ifetch-tools-0.15.26d/examples/cameras/0000755000175000017500000000000013062773624016412 5ustar useruserifetch-tools-0.15.26d/examples/cameras/camera_number.conf0000644000175000017500000002412413062773624022064 0ustar useruser##################################################################################### # ifetch-tools is a set of tools that can collect images from ip based cameras, # monitor collection process, and provide an interface to view collected history. # Copyright (C) 2005-2017 Richard Nelson # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 # of the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #################################################################################### #################################################################################### # General notes on the config file are as follows. # - Each camera needs a config file for operations. # - Default settings are stored in the /etc/ifetch-tools/ifetch-tools.conf file now. # - This file is used to override the default options in ifetch-tools.conf. #################################################################################### # Set the location for data_location #################################################################################### # The data_location variable is if your storage is somewhere else other than # ifetch-tools/htdocs . Do not include a trailing / and do not include the camera # number. Example line is below: # # data_location="/path/to/camera/storage" #################################################################################### # Set the options for day_image_sleep #################################################################################### # The below is for a feature add allowing for a subset of the entire day to have a # a different sleep padding on a given time range. So on each day of the week you # can have a time range where image collection padding is different than what is # specified with image_sleep. # # O is Sun, 1 is Mon, 2 is Tue, 3 is Wed, 4 is Thu, 5 Fri, 6 is Sat # On a given day "00:00,00:00,1" implies "startTime,stopTime,sleepDuration" # See the example line is below: # # day_image_sleep={ 0 => "00:00,00:00,1", 1 => "00:00,00:00,1", 2 => "00:00,00:00,1", 3 => "00:00,00:00,1", 4 => "00:00,00:00,1", 5 => "00:00,00:00,1", 6 => "00:00,00:00,1"} #################################################################################### ## Set the options for image_uid, image_pwd, image_auth_type, and image_alt ##################################################################################### ## The image_uid is the user name and the image_pwd is the password to use if ## using security on the remote camera. The image_auth_type is for basic (the default) ## or digest. image_alt is for dynamic page creation with img src alt tag. # Example lines are below: # # image_uid='' # image_pwd='' # image_auth_type='basic # image_alt='no_image_alt' #################################################################################### # Set the option for image_addr #################################################################################### # The image_addr is the IP address of the remote camera and the image_addr_port is # the port the camera is listening on. # Example line is below: # # image_addr='127.0.0.1' # image_addr_port=80 #################################################################################### # Set the option for image_count #################################################################################### # The image_count is the number of images to store history. # Example line is below: # # image_count=1 #################################################################################### # Set the option for image_count_on_motion #################################################################################### # The image_count_on_motion is the number of images to store once motion is detected # without another motion test on images. # image_count_on_motion=20 #################################################################################### # Set the option for image_sleep #################################################################################### # The image sleep is the padding between image downloads. Each download is a complete # http transaction with an open, download, and close operation. Tuning will depend on # each individual setup. # If you use a float use the example of 0.5 and the example # line is below: # # image_sleep=0 #################################################################################### # Set the option for image_url #################################################################################### # This is the url to get the current image of the camera. # ############################# # Amcrest MODEL: IP3M-954E # http://user:password@xxx.xxx.xxx.xxx/cgi-bin/snapshot.cgi # # image_url='/cgi-bin/snapshot.cgi' # ############################# # Apexis MODEL: APM-J011-WS # http://user:password@xxx.xxx.xxx.xxx/snapshot.cgi # # image_url='/snapshot.cgi' # ############################# # Axis cameras use the below: # image_url='/jpg/image.jpg' # ############################# # D-Link DCS-930L # image_url='/image.jpg' # ############################# # Hawking HNC320W wireless # image_url='/IMAGE.JPG' # ############################# # IGuard IP-250E # According to firmware upgrade 2.55.cv7 # # http://xxx.xxx.xxx.xxx/pda.cgi?user=admin&password=1234&page=image&cam=1 # # And the following is configured as below # xxx.xxx.xxx.xxx - the IP address of the camera # admin - the login account name # 1234 - the login password # 1 - the camera number # # So the image_url would look something like: # image_url='/pda.cgi?user=admin&password=1234&page=image&cam=1' # ############################# # IPCamera 510 # # image_url='/image.jpg' # ############################# # IPcam P1000 from Plustek # # http://xxx.xxx.xxx.xxx/snapshot.jpg?account=admin&password=1234` # # And the following is configured as below # xxx.xxx.xxx.xxx - the IP address of the camera # admin - the login account name for the admin username # 1234 - the login password for the admin username # # So the image_url would look something like: # image_url='/snapshot.jpg?account=admin&password=1234' # ############################# # Panasonic BL-C210A # # http://xxx.xxx.xxx.xxx/SnapshotJPEG?Resolution=640x480&Quality=Clarity # # And the following is configured as below # xxx.xxx.xxx.xxx - the IP address of the camera # Resolution - 320x240 640x480 # Quality - Motion Standard Clarity # ## So the image_url would look something like: # image_url='/SnapshotJPEG?Resolution=640x480&Quality=Clarity' # ############################# # TPLink NC220 # image_url='/stream/snapshot.jpg' # # Snapshot pulls appear to have port hard coded at 8080 so include the below # in your config: # # image_addr_port=8080 # # And security for the pull at time of writing requires that you pass the # base64 encoded password you configured in the web interface. # ############################# # Trendnet TV-IP201 use the below: # image_url='/goform/capture' # ############################# # Trendnet TV-IP301 use the below: # image_url='/goform/video' # ############################# # TV-IP320PI # image_url='/streaming/channels/1/picture' # image_auth_type='digest' # ############################# # Trendnet TV-IP512P use the below: # image_url='/image/jpeg.cgi' # ############################# # Toshiba IK-WR01A Orite IC301 use the below: # image_url='/Jpeg/CamImg.jpg' # ############################# # Wanscam IP Camera: # image_url='/snapshot.cgi' #################################################################################### # Set the option for image_watermark #################################################################################### # The image_watermark when true writes the collection time on the image. # The value is either 0 for True or 1 for False. # The default is 1. # image_watermark=1 #################################################################################### # Set the option for log_files #################################################################################### # The log_files is the number of log files to keep in rotation. # Example line is below: # # log_files=5 #################################################################################### # Set the option for log_size #################################################################################### # The log_size is the size in kb for a rotation. # Example line is below: # # log_size=100 ##################################################################################### # Set the option for marshal_dump_enable ##################################################################################### # The marshal dump option is an attempt to help the indexing of time stamps after a # shutdown,reboot, or a service restart. # The marshal_dump_enable is either 0 for True or 1 for False. # The default is 1. # marshal_dump_enable=1 #################################################################################### # Set the option for motion_enable #################################################################################### # The motion_enable is either 0 for True or 1 for False. # The default is 1. # motion_enable=1 ##################################################################################### ## Set the option for motion_mdpp ##################################################################################### ## The motion_mdpp is used to adjust the threshold of motion detection. # motion_mdpp=0.002 #################################################################################### # Set the option for motion_sleep #################################################################################### # The motion_sleep is if you want to shorten the sleep when motion is detected. # motion_sleep=0.5 ifetch-tools-0.15.26d/changelog0000644000175000017500000003760313047224236015035 0ustar useruser#################################################################################### # ifetch-tools is a set of tools that can collect images from ip based cameras, # monitor collection process, and provide an interface to view collected history. # Copyright (C) 2005-2017 Richard Nelson # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 # of the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #################################################################################### # Changlog for milestone operations #################################################################################### # See debian/changelog 20141103 * Updating to standards version 3.9.6. * Address postinst uses /usr/share/doc content, (Closes: #767859). * Adding Dutch translation of debconf messages from Frans Spiesschaert (Closes: #767294). * Update Homepage in debian/control. * Update web page to remove rubyforge.org links. 20140204 * Update version references to 0.15.24c. * Address lintain issue of maintainer-script-should-not-use-adduser-system-without-home . * Drop depends of librmagick-ruby and now use ruby-rmagick (Closes: #731946). * Drop depends of ffmpeg and now use libav-tools (Closes: #728615). * Initial update on ifetch and wwwifetch for ruby1.9.x. * Dropping ruby1.8 support for current ruby. * Update init script with set -e at the top. * Update init script with call to /lib/lsb/init-functions. * Update debian/control to Build-Depends >=9. * Update debian/control to Standards-Version 3.9.5. * Update edit date on ifetch-tools.rubyforge.org home page. * Add Wanscam IP Camera to ifetch-tools.rubyforge.org home page. * Add D-Link DCS-930L to ifetch-tools.rubyforge.org home page. * Minor html correction on format of ifetch-tools.rubyforge.org home page. * Adding image_url for D-Link DCS-930L Camera. * Adding image_url for Wanscam IP Camera. * Correcting Panasonic BL-C210A entry. * Upload to unstable. 20120819 * Release 0.15.24b see below. * Correcting when image count should be decremented. 20120713 * Release 0.15.24a see below. * Add video_export_delay variable for tuning video delay speed. * Added image_watermark variable so timestamp is optional on images. * Change from info to warn on log messages when backing image count down after rescue. * Correct begin count number when no history and motion enabled. * Only set DRB exchange data and write image when we need to. * Add nicelevel on start-stop-daemon and set to 10. 20120705 * Release 0.15.24 see below. * Watermark image with date on write. * Added feature to export images to a video download. * Added depends of ffmepg for video download feature. 20120414 * Release 0.15.23b see below. * Updated Copyright years. 20110606 * Release 0.15.23a see below. * Fix missing > on navigation default. * Close option tag on navigation. 20110415 * Release 0.15.23 see below. * Add timeout for execution on pullimage call. * Cleanup on mdpp inclusion for monitor page. * Initial add of logging for mdpp tests. * Initial add of mdpplog.jpg image. * Initial add of mdpp log access from monitor page. 20110401 * Release 0.15.22f see below. * Remove modulate call on difference prep due to high cpu utilization. 20110327 * Release 0.15.22e see below. * Added date and uptime info to Monitor template. * Made version references consistent in templates. * Added prerm to ensure stop of running process on package removal. 20101231 * Release 0.15.22d no change to core just translation bugs. 20101104 * Release 0.15.22c no change to core just translation bugs. 20101005 * Release 0.15.22b no change to core just translation bugs. 20101001 * Release 0.15.22a no change to core just translation bugs. 20100929 * Release 0.15.22 20100902 * Release 0.15.21 * Adding French debconf translation from Christian Perrier (Closes: #594848). * Adding Swedish debconf translation from Martin Bagge (Closes: #594080). * Adding Russian debconf translation from Yuri Kozlov (Closes: #593494). * Adding Portuguese debconf translation from Américo Monteiro (Closes: #593649). 20100729 Nelson * Release 0.15.20 * Changing debconf question to be ran each time. 20100727 Nelson * Release 0.15.19 * Adding debconf question for purge by Daniel Baumann . * Add purge of data, logs, and settings as configured from debconf question. * Set Default-Stop to 0 1 6 in .init. 20100712 Nelson * Move to common version number to match debian version. * Correct lintian errors. * Release ifetch-tools-0.15.17 * Move directory creation from .dirs to .postinst. * Release ifetch-tools-0.15.18 20100525 Nelson * Bumped version of wwwifetch to 0.8.8 * Added ability for custom htdocs folder. 20100218 Nelson * Bumped version of ifetch to 0.14.8 * Attempt to avoid nil split errors in Drb exchanges. 20100105 Nelson * Attempt to prevent cached pages on templates. 20100103 Nelson * Bumped version of wwwifetch to 0.8.7 -- Error testing on passed params. * Bumped versions in man pages and web page. * Updated Copyright years. 20091211 Nelson * Bumped version of wwwifetch to 0.8.6 -- Corrected spelling on variable name. -- Bumped versions in man pages and web page. 20091207 Nelson * Bumped version of wwwifetch to 0.8.5 -- Add basicView on images for various purposes. -- gsub code assistance from Mark Meves on irc. 20091204 Nelson * Bumped version of ifetch to 0.14.7 -- Remarked out some diag puts. 20091117 Nelson * Bumped version of wwwifetch to 0.8.4 -- More strict image pass to ShowImage 20091115 Nelson * Bumped version of ifetch to 0.14.6 * Fixed nil entries when image count is reduced and image missing. * Bumped version of wwwifetch to 0.8.3 20091113 Nelson - Comments from debian/changelog * Bumped version of ifetch to 0.14.5 * Modified ifetch.png on missed images to a missed.jpg image. * Started actually keeping change log and will still include ifetch-tools/changelog. 20090925 Nelson - Fix bug on image jump when motion enabled and bad image pull on sequence of images after motion detection. - Building ifetch-tools-0.15.6 -- ifetch 0.14.4 -- wwwifetch 0.8.2 20090420 Nelson - Bug I introduced when cleaning whitespace I believe. So just updating file with no version changes. - Building ifetch-tools-0.15.5a -- ifetch 0.14.3 -- wwwifetch 0.8.2 20090417 Nelson - Cleanup of ifetch on trap errors with bad images. - Whitespace cleanup started on all files. - Building ifetch-tools-0.15.5 -- ifetch 0.14.3 -- wwwifetch 0.8.2 20090205 Nelson - Moving to ifetch-tools-0.15.4 for new .deb operations -- ifetch 0.14.2 -- wwwifetch 0.8.2 - Trap for config files and when to die better. 20090203 Nelson - Moving to ifetch-tools-0.15.3 for new .deb operations -- ifetch 0.14.1 -- wwwifetch 0.8.1 - Added fix for log-rotate - Added other minor format issues. 20090201 Nelson - Added some performance improvements with making better use of DRb - Moving to ifetch-tools-0.15.1 -- ifetch 0.14.1 -- wwwifetch 0.8.1 20090130 Nelson - Added info for IP Camera 510 and some general camera info for the project web page. 20090130 Nelson - Moving to ifetch-tools-0.15.0 -- ifetch 0.14.0 -- wwwifetch 0.8.0 - Added info for IPCam P1000 from Plustek in examples/cameras/camera_number.conf 20090126 Nelson - Added to default not to run ifetch or wwwifetch until line remarked out in /etc/ifetch-tools/ifetch-tools.conf 20090125 Nelson - Cleaning out notes onf conf files since all operations now in this file. - All references to PATHTOROOT now removed. 20090124 Nelson - More cleanup for debian setup. 20090122 Nelson - Removing ifetch-startup and ifetch-shutdown examples since moving to /etc/init.d/ifetch-tools - Removing lock folder since now will be using /var/lock/ifetch-tools 20090121 Nelson - Changes to get code in the form that will be ready for .deb building - Rename ifetch.rb to ifetch - Rename wwwifetch.rb to wwwifetch - chmod 755 ifetch and wwwifetch - Expect upon .deb install that ifetch and wwwifetch will be in /usr/bin - Expect static htdocs data to be in /usr/share/ifetch-tools/htdocs - Rename template folder to templates - Expect static templates data to be in /usr/share/ifetch-tools/templates - Expect user data to be created dynamic in /var/lib/ifetch-tools and test for it - Expect config files to be in /etc/ifetch-tools/ifetch-tools.conf - Modified README.txt to reflect the move to using a .deb for installing. 20081213 Nelson - Minor change on ifetch.rb to attempt to close Logging handle upon exit. - Update ifetch image. - Release ifetch-tools-0.14.2 -- ifetch.rb 0.12.1 -- wwwifetch.rb 0.7.0 20081105 Nelson - Changed log extension from .log to .txt - Minor bug fixes and typo corrections. - Minor presentation modifications. - Minor feature adds. - Release ifetch-tools-0.14.0 -- ifetch.rb 0.12.0 -- wwwifetch.rb 0.7.0 20081101 Nelson - Minor tuning on the mdpp testing for performance - Release ifetch-tools-0.12.4 -- ifetch.rb 0.11.5 -- wwwifetch.rb 0.6.9 20081007 Nelson - Minor tuning on images on first page - Release ifetch-tools-0.12.3 -- ifetch.rb 0.11.4 -- wwwifetch.rb 0.6.9 - Minor security adjustments - Minor last page display removal - Release ifetch-tools-0.12.2 -- ifetch.rb 0.11.4 -- wwwifetch.rb 0.6.8 20080920 Nelson - Fixed bug on ifetch.rb and bumped to 0.11.4 - Releasing ifetch-tools-0.12.1 -- ifetch.rb 0.11.4 -- wwwifetch.rb 0.6.6 20080806 Nelson - Added support for motion detection on camera recording with a motion_sleep for a burst of images. - You will need to have librmagick-ruby installed for the the application to start since I require it. - Releasing ifetch-tools-0.12.0 -- ifetch.rb 0.11.3 -- wwwifetch.rb 0.6.6 -- You will need to merge in existing configs with new variables at least in the global ifetch.conf file. 20080701 Nelson - Added support for image_addr_port for cameras or users who want to use a non stanard port. - Releasing ifetch-tools-0.11.5 -- ifetch.rb 0.10.17 -- wwwifetch.rb 0.6.5 20080319 Nelson - Fixed bug in data_location code for global usage if desired. - Releasing ifetch-tools-0.11.4 -- ifetch.rb 0.10.16 -- wwwifetch.rb 0.6.5 20080225 Nelson - Added data_location variable for global usage if desired. - Releasing ifetch-tools-0.11.3 -- ifetch.rb 0.10.15 -- wwwifetch.rb 0.6.5 20080127 Nelson - Minor comments modification in ./conf/example.conf.example - Corrected a bug in day_image_sleep operations in ifetch.rb - Modified the ifetch.png image to relect changes on the logo for fyeox.com - Releasing ifetch-tools-0.11.2 -- ifetch.rb 0.10.14 -- wwwifetch.rb 0.6.5 20080120 Nelson - Modified ./template/Monitor for correct image display when garbage added after. 20080106 Nelson - Setup logging capture for wwwifetch.rb in ./htdocs/log - Added a sample wwwifetch-logrotate.conf for log rotation of wwwifetch.rb logs - Centralized system defaults for camera confs and ifetch.rb in ifetch.conf - Modified remarks in ./conf/example.conf.example - Releasing ifetch-tools-0.11.1 -- ifetch.rb 0.10.13 -- wwwifetch.rb 0.6.5 20071129 Nelson - Formating cleanup on ifetch.conf.example and conf/example.conf.example - Releasing 0.10.2 - ifetch.rb 0.10.11 - wwwifetch.rb 0.6.3 20071128 Nelson - Modified templates - Modified ifetch.conf.example for new variable - Minor code cleanup on wwwifetch.rb 0.6.3 20071125 Nelson - Released ifetch-tools-0.10.1 - Minor typo bugs corrected. - ifetch.rb 0.10.11 - wwwifetch.rb 0.6.2 20071103 Nelson - Released ifetch-tools-0.10.0-pre-1 - ifetch.rb 0.10.11 - wwwifetch.rb 0.6.1 20071101 Nelson - Released ifetch-tools-0.10.0-pre-1 - ifetch.rb 0.10.11 - wwwifetch.rb 0.6.0 20071006 Nelson - Released ifetch-tools-0.9.19 - ifetch.rb 0.10.10 - wwwifetch.rb 0.5.19 20071005 Nelson - Released ifetch-tools-0.9.18 - ifetch.rb 0.10.10 - wwwifetch.rb 0.5.18 20071002 Nelson - Released ifetch-tools-0.9.16 - ifetch.rb 0.10.10 - wwwifetch.rb 0.5.16 20071001 Nelson - Released ifetch-tools-0.9.15 - ifetch.rb 0.10.9 - wwwifetch.rb 0.5.16 20070927 Nelson - Released ifetch-tools-0.9.14 - ifetch.rb 0.10.7 - wwwifetch.rb 0.5.15 20070710 Nelson - Released ifetch-tools-0.9.13 - ifetch.rb 0.10.6 - wwwifetch.rb 0.5.12 20070627 Nelson - Released ifetch-tools-0.9.12 - ifetch.rb 0.10.4 - wwwifetch.rb 0.5.9 20070618 Nelson - Released ifetch-tools-0.9.11 - ifetch.rb 0.10.4 - wwwifetch.rb 0.5.6 20070615 Nelson - Released ifetch-tools-0.9.10 - ifetch.rb 0.10.4 - wwwifetch.rb 0.5.5 20070615 Nelson - Released ifetch-tools-0.9.9 - ifetch.rb 0.10.4 - wwwifetch.rb 0.5.2 20070610 Nelson - Released ifetch-tools-0.9.8 - ifetch.rb 0.10.3 - wwwifetch.rb 0.5.1 20070325 Nelson - Released ifetch-tools-0.9.7 - wwwifetch.rb 0.5.1 20070316 Nelson - Released ifetch-tools-0.9.6 - ifetch.rb 0.10.1 20070203 Nelson - Released ifetch-tools-0.9.5 - ifetch.rb 0.10.0 - wwwifetch.rb 0.5.0 20061207 Nelson - Fixed bug 6970 in wwwifetch.rb - Fixed bug 6961 in ifetch.conf.example - Released ifetch-tools-0.9.3 - ifetch.rb 0.9.5 - wwwifetch.rb 0.4.4 20061024 Nelson - Initial work on authentication for security. - Cleanup on address history other minor cleanup. - Released ifetch-tools-0.9.2 - ifetch.rb 0.9.4 - wwwifetch.rb 0.4.1 20061019 Nelson - Initial work to echange data between iftech and wwwifetch processes for performance. - Expecting to have camera.conf files to be a int >= 0. - Released ifetch-tools-0.9.0 - ifetch.rb 0.9.0 - wwwifetch.rb 0.4.0 20060705 Nelson - Small cleanup in remarks in wwwifetch.rb. - Sort cameras based on prefix in wwwifetch.rb. - Removed image_prefix var in all areas and standardized on prefix of the cameras .conf as the prefix for all files. - ifetch.rb 0.8.6 - wwwifetch.rb 0.3.2 20060318 Nelson - Small cleanup on information in all files and cleanup for putting at web site. - Included web site in source information with dir of ifetch-tools.rubyforge.org - Bump release verstion to ifetch-tools-0.8.3 and included web page release by iso date: - ifetch.rb 0.8.5 - wwwifetch.rb 0.3.1 - ifetch-tools.rubyforge.org 20060318 20060312 Nelson - Small cleanup on default index.html to include that the code is GPL 20060311 Nelson - Getting docs ready for ue with http://rubyforge.org/projects/ifetch-tools - Bumped file versions on ifetch-tools-0.8.2 tool set to: - ifetch.rb 0.8.5 - wwwifetch.rb 0.3.1 20060219 Nelson - Completed initial work on web monitor of camera status. - Bumped file versions on ifetch-tools-0.8.1 tool set to: - ifetch.rb 0.8.4 - wwwifetch.rb 0.3.0 - I am sure there are bugs but in general I think the code is ready to ship out for beta. - I elected to use a backtick operation on part of the new monitoring operation and I would put this on a todo as a clean up in prue ruby. But it was just to clean and easy to make the backtick call for what I needed. This call expects that the system is running Linux. 20060201 Nelson - Change variable of version to VER in ifetch.rb - Start work on ifetch-tools-0.8.1 tool set. 20060120 Nelson - Removed images folder and elected to use htdocs as default parent dir for camera image folders on default tarball. i.e. each camera will have a folder under htdocs - wwwifetch.rb phase 2 appears to be at a stable point. - Starting to use a ifetch-tools release stamp of 0.8.0 with file versions are as follows: - ifetch.rb 0.8.3 - wwwifetch.rb 0.2.1 20060105 Nelson - Started this file since we are getting close to first production release. - Cleaned up the images some on the servlet operations. - Verified the GPL to all files.