Module: Syctask
- Defined in:
- lib/syctask/task.rb,
lib/syctask/times.rb,
lib/syctask/meeting.rb,
lib/syctask/scanner.rb,
lib/syctask/version.rb,
lib/syctask/schedule.rb,
lib/syctask/settings.rb,
lib/syctask/evaluator.rb,
lib/syctask/statistics.rb,
lib/syctask/environment.rb,
lib/syctask/task_planner.rb,
lib/syctask/task_service.rb,
lib/syctask/task_tracker.rb,
lib/syctask/task_scheduler.rb
Overview
require_relative ‘../sycutil/console_timer.rb’
Defined Under Namespace
Classes: Evaluator, Meeting, Scanner, Schedule, Settings, Statistics, Task, TaskPlanner, TaskScheduler, TaskService, TaskTracker, Times, Track
Constant Summary collapse
- VERSION =
Holds the version number of syctask
'0.4.2'
- SYC_DIR =
System directory of syctask
File.join(ENV['HOME'], '.syc/syctask')
- ID =
ID file where the last issued ID is saved
SYC_DIR + "/id"
- IDS =
File that contains all issued IDs
SYC_DIR + "/ids"
- TAGS =
File with tags
SYC_DIR + "/tags"
- DEFAULT_TASKS =
File with the general purpose tasks
SYC_DIR + "/default_tasks"
- DEFAULT_TASKS_DIR =
File that holds the default task directory
SYC_DIR + "/default_tasks_dir"
- TASKS_LOG =
Log file that logs all activities of syctask like creation of tasks
SYC_DIR + "/tasks.log"
- TRACKED_TASK =
File that holds the tracked task
SYC_DIR + "/tracked_tasks"
- RIDX_LOG =
If files are re-indexed during re-indexing these tasks are save here
SYC_DIR + "/reindex.log"
- WORK_DIR =
Set eather user defined work directory or default
work_dir.nil? ? File.join(ENV['HOME'], '.tasks') : work_dir
- PROMPT_STRING =
String that is prompted during planning
'(a)dd, (c)omplete, (s)kip, (q)uit: '
- INSPECT_STRING =
String that is prompted during inspect
'(e)dit, (d)one, de(l)ete, (p)lan, da(t)e, (c)omplete, '+ '(s)kip, (b)ack, (q)uit: '
- PRIORITIZE_STRING =
String that is prompted during prioritization
'Task 1 has (h)igher or (l)ower priority, or (q)uit: '
Instance Method Summary collapse
-
#check_environment ⇒ Object
Checks whether all files are available that are needed for syctask’s operation.
-
#collect_by_id(tasks) ⇒ Object
Extracts tasks that have no unique id.
-
#get_files(included, excluded = [], pattern) ⇒ Object
Retrieves all files that meet the pattern in and below the given directory.
-
#get_task_dirs(dir) ⇒ Object
Retrieve all directories that contain tasks.
-
#get_task_dirs_and_count(dir) ⇒ Object
Retrieves all directories that contain tasks and the count of contained tasks in and below the provided directory.
-
#initialize_id(tasks) ⇒ Object
Determines the greatest task ID out of the provided tasks and saves it to the ID file.
-
#initialize_or_recover_system ⇒ Object
Asks the user whether this is a fresh install because of missing system files.
-
#log_meetings(type, busy_time, meetings) ⇒ Object
Logs meeting times.
-
#log_reindexing(old_id, new_id, file) ⇒ Object
Logs if a task is re-indexed.
-
#log_task(type, task) ⇒ Object
Logs a task regarding create, update, done, delete.
-
#log_work_time(type, work_time) ⇒ Object
Logs the work time.
-
#move_planned_tasks_files(dirs, excluded) ⇒ Object
Moves the planned tasks file to the system directory if not there.
-
#move_task_log_file(dirs, excluded) ⇒ Object
Moves the tasks.log file to the system directory if not there.
-
#move_time_schedule_files(dirs, excluded) ⇒ Object
Moves the schedule file to the system directory if not there.
-
#next_id ⇒ Object
Retrieve the next unassigned task id.
-
#planned_tasks_files(dirs, excluded = []) ⇒ Object
Retrieves all planned task files in and below the given directory.
-
#reindex_task(file) ⇒ Object
Re-indexes the tasks’ IDs and renames the task files to match the new ID.
-
#reindex_tasks(dirs, excluded) ⇒ Object
Re-indexing of tasks is done when tasks are available but SYC_DIR or ID file is missing.
-
#save_id(id) ⇒ Object
Save the id to the ID file.
-
#save_ids(id, file) ⇒ Object
Saves the ids to ids file.
-
#task_files(dirs, excluded = []) ⇒ Object
Retrieves all task files in and below the provided dir.
-
#tasks_log_files(dirs, excluded = []) ⇒ Object
Retrieves als tasks.log files in and below the given directory.
-
#time_schedule_files(dirs, excluded = []) ⇒ Object
Retrieves all schedule files in and below the given directory.
-
#update_planned_tasks(dirs, excluded, new_ids) ⇒ Object
Replaces the old ids with the new ids in the planned tasks files.
-
#update_tasks_log(dirs, excluded = [], new_ids) ⇒ Object
Updates the tasks.log file if tasks are re-indexed with the task’s new ids.
-
#update_tracked_task(dirs, excluded) ⇒ Object
Updates tracked_tasks file if task has been re-indexed with new ID.
-
#viable? ⇒ Boolean
Checks if system files are available that are needed for running syc-task.
Instance Method Details
#check_environment ⇒ Object
Checks whether all files are available that are needed for syctask’s operation
91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 |
# File 'lib/syctask/environment.rb', line 91 def check_environment FileUtils.mkdir_p WORK_DIR unless File.exists? WORK_DIR unless viable? recover, whitelisted_dirs, blacklisted_dirs = initialize_or_recover_system case recover when 0 FileUtils.mkdir_p SYC_DIR unless File.exists? SYC_DIR File.write(ID, "0") when 1 # Backup ARGV content args = [] ARGV.each {|arg| args << arg} unless ARGV.empty? ARGV.clear reindex_tasks(whitelisted_dirs, blacklisted_dirs) puts "Successfully recovered syc-task" puts "-> A log file of re-indexed tasks can be found at\n"+ "#{RIDX_LOG}" if File.exists? RIDX_LOG print "Press any key to continue " gets # Restore ARGV content args.each {|arg| ARGV << arg} unless args.empty? when 2 puts "o.k. - don't do nothing" exit -1 end end end |
#collect_by_id(tasks) ⇒ Object
Extracts tasks that have no unique id
364 365 366 367 368 369 370 371 |
# File 'lib/syctask/environment.rb', line 364 def collect_by_id(tasks) extract = {} tasks.each do |task| id = task.scan(/(?<=\/)\d+(?=\.task$)/)[0] extract[id].nil? ? extract[id] = [task] : extract[id] << task end extract end |
#get_files(included, excluded = [], pattern) ⇒ Object
Retrieves all files that meet the pattern in and below the given directory
397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 |
# File 'lib/syctask/environment.rb', line 397 def get_files(included, excluded=[], pattern) files = [] Find.find(*included) do |path| if FileTest.directory?(path) if excluded.include?(path) Find.prune else next end else files << File.(path) if File.basename(path) =~ pattern end end files end |
#get_task_dirs(dir) ⇒ Object
Retrieve all directories that contain tasks
414 415 416 417 418 419 420 421 422 |
# File 'lib/syctask/environment.rb', line 414 def get_task_dirs(dir) original_dir = File.(".") Dir.chdir(dir) dirs = Dir.glob("**/*.task", File::FNM_DOTMATCH).map do |f| File.dirname(File.(f)) end Dir.chdir(original_dir) dirs.uniq end |
#get_task_dirs_and_count(dir) ⇒ Object
Retrieves all directories that contain tasks and the count of contained tasks in and below the provided directory
426 427 428 429 430 431 432 433 434 435 436 |
# File 'lib/syctask/environment.rb', line 426 def get_task_dirs_and_count(dir) original_dir = File.(".") Dir.chdir(dir) dirs_and_count = Hash.new(0) Dir.glob("**/*.task", File::FNM_DOTMATCH).each do |f| dirname = File.dirname(File.(f)) dirs_and_count[dirname] += 1 end Dir.chdir(original_dir) dirs_and_count end |
#initialize_id(tasks) ⇒ Object
Determines the greatest task ID out of the provided tasks and saves it to the ID file
269 270 271 272 273 |
# File 'lib/syctask/environment.rb', line 269 def initialize_id(tasks) pattern = %r{(?<=\/)\d+(?=\.task)} tasks.sort_by! {|t| t.scan(pattern)[0].to_i} save_id(tasks[tasks.size-1].scan(pattern)[0].to_i) end |
#initialize_or_recover_system ⇒ Object
Asks the user whether this is a fresh install because of missing system files. If it is not a fresh install then this might be because of an upgrade to a version > 0.0.7 or the user accidentally has deleted the system files. If it is a fresh install the system files are created. Otherwise the user can select to search for task files and recover the system.
intialize_or_recover_system #=> recover, whitelisted_dirs, blacklisted_dirs recover = 0 just creates the system files as it is fresh install recover = 1 recover task files recover = 2 abort, don’t recover task files whitelisted_dirs = array of directories where to search for task files blacklisted_dirs = array of directories where not to search for task files
137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 |
# File 'lib/syctask/environment.rb', line 137 def initialize_or_recover_system whitelisted_dirs = [] blacklisted_dirs = [] puts "This seems to be a fresh install because there are no system files "+ "available." puts "* If this is a fresh install just hit 'y'. " puts "* Otherwise hit 'n' to go to the recovery step." print "Is this a fresh install (y/n)? " answer = gets.chomp if answer.downcase == "y" [0, nil, nil] else puts puts "If you have upgraded from version 0.0.7 or below than this is "+ "due to a changed\nfile structure. For changes in version "+ "greater 0.0.7 see" puts "--> https://rubygems.org/gems/syc-task" puts "Or you have accidentially deleted system files. In both cases "+ "re-indexing\nwill recover syc-task." print "Do you want to recover syc-task (y/n)? " answer = gets.chomp if answer.downcase == "y" puts puts "If you know where your task files are located then you can "+ "specify the\ndirectories. Search starts in your home directory." print "Do you want to specify the directories (y/n)? " answer = gets.chomp if answer.downcase == "y" puts "Please enter directories, e.g. ~/.my-tasks ~/work-tasks" whitelisted_dirs = gets.chomp.split(/\s+/) .map { |f| File.(f) } else puts "You don't want to select task directories. It is adviced to "+ "exclude mounted \ndirectories as this might take very long to "+ "search all directories for task files. Also if it is no " + "stable connection\n the recovery process might be aborted" print "Do you want to exclude directories (y/n)? " if answer.downcase == "y" puts "Please enter directories, e.g. ~/mount ~/.no-tasks" blacklisted_dirs = gets.chomp.split(/\s+/) .map { |f| File.(f) } else whitelisted_dir = [ENV['HOME']] puts "Searching directories and all sub-directories starting in\n"+ "#{ENV['HOME']}" end end [1, whitelisted_dirs, blacklisted_dirs] else [2, nil, nil] end end end |
#log_meetings(type, busy_time, meetings) ⇒ Object
Logs meeting times
74 75 76 77 78 79 80 81 82 83 84 85 86 87 |
# File 'lib/syctask/environment.rb', line 74 def log_meetings(type, busy_time, meetings) today = Time.now logs = File.read(TASKS_LOG) time_pat = "#{today.strftime("%Y-%m-%d")} \\d{2}:\\d{2}:\\d{2} [+-]\\d{4}" pattern = %r{#{type};-2;;.*?;#{time_pat};#{time_pat}\n} logs.gsub!(pattern, "") busy_time.each_with_index do |busy,i| begins = Time.local(today.year,today.mon,today.day,busy[0],busy[1],0) ends = Time.local(today.year,today.mon,today.day,busy[2],busy[3],0) meeting = meetings[i] ? meetings[i] : "Meeting #{i}" logs << "#{type};-2;;#{meeting};#{begins};#{ends}\n" end File.write(TASKS_LOG, logs) end |
#log_reindexing(old_id, new_id, file) ⇒ Object
Logs if a task is re-indexed
296 297 298 299 300 301 |
# File 'lib/syctask/environment.rb', line 296 def log_reindexing(old_id, new_id, file) entry = "#{old_id},#{new_id},#{file}" return if File.exists? RIDX_LOG and not File.read(RIDX_LOG). scan(entry).empty? File.open(RIDX_LOG, 'a') {|f| f.puts entry} end |
#log_task(type, task) ⇒ Object
Logs a task regarding create, update, done, delete
34 35 36 37 38 39 40 41 42 43 |
# File 'lib/syctask/environment.rb', line 34 def log_task(type, task) File.open(TASKS_LOG, 'a') do |file| log_entry = "#{type.to_s};" log_entry += "#{task.id};#{task.dir};" log_entry += "#{task.title.gsub(';', '\'semicolon\'')};" log_entry += "#{Time.now};" log_entry += "#{Time.now}" file.puts log_entry end end |
#log_work_time(type, work_time) ⇒ Object
Logs the work time
46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 |
# File 'lib/syctask/environment.rb', line 46 def log_work_time(type, work_time) today = Time.now begins = Time.local(today.year, today.mon, today.day, work_time[0], work_time[1], 0) ends = Time.local(today.year, today.mon, today.day, work_time[2], work_time[3], 0) entry = "#{type};-1;;work;#{begins};#{ends}\n" logs = File.read(TASKS_LOG) return if logs.scan(entry)[0] time_pat = "#{today.strftime("%Y-%m-%d")} \\d{2}:\\d{2}:\\d{2} [+-]\\d{4}" pattern = %r{#{type};-1;;work;#{time_pat};#{time_pat}\n} log = logs.scan(pattern)[0] if log and logs.sub!(log, entry) File.write(TASKS_LOG, logs) else File.open(TASKS_LOG, 'a') {|f| f.puts entry} end end |
#move_planned_tasks_files(dirs, excluded) ⇒ Object
Moves the planned tasks file to the system directory if not there. Should only be if upgrading from version 0.0.7 and below
454 455 456 457 458 459 460 461 462 463 |
# File 'lib/syctask/environment.rb', line 454 def move_planned_tasks_files(dirs, excluded) if @planned_tasks_files.nil? @planned_tasks_files = planned_tasks_files(dirs, excluded) end @planned_tasks_files.each do |file| to_file = "#{SYC_DIR}/#{File.basename(file)}" next if file == to_file FileUtils.mv file, to_file end end |
#move_task_log_file(dirs, excluded) ⇒ Object
Moves the tasks.log file to the system directory if not there. Should only be if upgrading from version 0.0.7 and below
440 441 442 443 444 445 446 447 448 449 450 |
# File 'lib/syctask/environment.rb', line 440 def move_task_log_file(dirs, excluded) if @tasks_log_files.nil? @tasks_log_files = tasks_log_files(dirs, excluded) end @tasks_log_files.each do |f| next if f == TASKS_LOG tasks_log = File.read(f) File.open(TASKS_LOG, 'a') {|t| t.puts tasks_log} FileUtils.mv(f, "#{f}_#{Time.now.strftime("%y%m%d")}") end end |
#move_time_schedule_files(dirs, excluded) ⇒ Object
Moves the schedule file to the system directory if not there. Should only be if upgrading from version 0.0.7 and below
467 468 469 470 471 472 473 474 475 476 |
# File 'lib/syctask/environment.rb', line 467 def move_time_schedule_files(dirs, excluded) if @time_schedule_files.nil? @time_schedule_files = time_schedule_files(dirs, excluded) end @time_schedule_files.each do |file| to_file = "#{SYC_DIR}/#{File.basename(file)}" next if file == to_file FileUtils.mv file, to_file end end |
#next_id ⇒ Object
Retrieve the next unassigned task id
289 290 291 292 293 |
# File 'lib/syctask/environment.rb', line 289 def next_id id = File.read(ID).to_i + 1 save_id(id) id end |
#planned_tasks_files(dirs, excluded = []) ⇒ Object
Retrieves all planned task files in and below the given directory
380 381 382 383 |
# File 'lib/syctask/environment.rb', line 380 def planned_tasks_files(dirs, excluded=[]) pattern = %r{\d{4}-\d{2}-\d{2}_planned_tasks} get_files(dirs, excluded, pattern) end |
#reindex_task(file) ⇒ Object
Re-indexes the tasks’ IDs and renames the task files to match the new ID. The orginal file is deleted. Returns old_id, new_id, tmp_file_name and new_file_name. The task is save with the tmp_file_name in case the new ID and hence the new_file_name exists already from a not yet re-indexed task. After all tasks are re-indexed the tmp_file_names have to be renamed to the new_file_names. The renaming is in the responsibility of the calling method.
249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 |
# File 'lib/syctask/environment.rb', line 249 def reindex_task(file) print "." task = File.read(file) old_id = task.scan(/(?<=^id: )\d+$/)[0] new_id = next_id.to_s task.gsub!(/(?<=^id: )\d+$/, new_id) dirname = File.dirname(file) new_file = "#{dirname}/#{new_id}.task" tmp_file = "#{new_file}_" File.write(tmp_file, task) File.delete(file) {old_id: old_id, new_id: new_id, tmp_file: tmp_file, new_file: new_file, dirname: dirname} end |
#reindex_tasks(dirs, excluded) ⇒ Object
Re-indexing of tasks is done when tasks are available but SYC_DIR or ID file is missing. The ID file contains the last issued task ID. The ID file is referenced for obtaining the next ID for a new task. Re-indexing is done as follows:
-
Retrieve all tasks in and below the given directory root
-
Determine the highest ID number and add it to the ID file
-
Determine all tasks that don’t have a unique ID
-
Re-index all tasks not having a unique ID and rename the file names accordingly
-
Adjust the IDs in the planned_tasks, tasks.log and tracked_tasks files
-
Copy all system files planned_tasks, time_schedule, tasks.log, id to the SYC_DIR directory if not already in the SYC_DIR directory. This should only be if upgrading from version 0.0.7 and below.
205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 |
# File 'lib/syctask/environment.rb', line 205 def reindex_tasks(dirs, excluded) #root) FileUtils.mkdir_p SYC_DIR unless File.exists? SYC_DIR new_id = {} to_be_renamed = {} puts "-> Collect task files..." task_files = task_files(dirs, excluded) puts "-> Restore ID counter..." initialize_id(task_files) print "-> Start re-indexing now..." collect_by_id(task_files).each do |id, files| next if files.size < 2 files.each_with_index do |file,i| next if i == 0 # need to re-index only second and following tasks result = reindex_task(file) # associate old id to new id and dir name if new_id[result[:old_id]].nil? new_id[result[:old_id]] = {result[:dirname] => result[:new_id]} else new_id[result[:old_id]][result[:dirname]] = result[:new_id] end # assign tmp_file to new_file for later renaming to_be_renamed[result[:tmp_file]] = result[:new_file] # document the re-indexing of tasks log_reindexing(result[:old_id], result[:new_id], result[:new_file]) end end to_be_renamed.each {|old_name,new_name| File.rename(old_name, new_name)} puts puts "-> Update task log file" update_tasks_log(dirs, excluded, new_id) puts "-> Update planned tasks files" update_planned_tasks(dirs, excluded, new_id) puts "-> Move schedule files..." move_time_schedule_files(dirs, excluded) puts "-> Update tracked task file..." update_tracked_task(dirs, excluded) end |
#save_id(id) ⇒ Object
Save the id to the ID file. Returns the id when save was successful
283 284 285 286 |
# File 'lib/syctask/environment.rb', line 283 def save_id(id) File.write(ID,id) id end |
#save_ids(id, file) ⇒ Object
Saves the ids to ids file
276 277 278 279 280 |
# File 'lib/syctask/environment.rb', line 276 def save_ids(id, file) entry = "#{id},#{file}" return if File.exists? IDS and not File.read(IDS).scan(entry).empty? File.open(IDS, 'a') {|f| f.puts entry} end |
#task_files(dirs, excluded = []) ⇒ Object
Retrieves all task files in and below the provided dir. Returns an array of task files
375 376 377 |
# File 'lib/syctask/environment.rb', line 375 def task_files(dirs, excluded=[]) get_files(dirs, excluded, /\d+\.task$/) end |
#tasks_log_files(dirs, excluded = []) ⇒ Object
Retrieves als tasks.log files in and below the given directory
392 393 394 |
# File 'lib/syctask/environment.rb', line 392 def tasks_log_files(dirs, excluded=[]) get_files(dirs, excluded, /tasks\.log/) end |
#time_schedule_files(dirs, excluded = []) ⇒ Object
Retrieves all schedule files in and below the given directory
386 387 388 389 |
# File 'lib/syctask/environment.rb', line 386 def time_schedule_files(dirs, excluded=[]) pattern = %r{\d{4}-\d{2}-\d{2}_time_schedule} get_files(dirs, excluded, pattern) end |
#update_planned_tasks(dirs, excluded, new_ids) ⇒ Object
Replaces the old ids with the new ids in the planned tasks files. A planned tasks file has the form ‘2013-03-03_planned_tasks’ and lives until syctask’s version 0.0.7 in ~/.tasks directory. From version 0.1.0 on the planned tasks files live in the ~/.syc/syctask directory. So the calling method has the responsibility to copy or move the planned tasks files after they have been updated to the new planned tasks directory.
333 334 335 336 337 338 339 340 341 342 343 344 |
# File 'lib/syctask/environment.rb', line 333 def update_planned_tasks(dirs, excluded, new_ids) planned_tasks_files(dirs, excluded).each do |file| tasks = File.readlines(file) tasks.each_with_index do |task,i| task_dir, old_id = task.chomp.split(',') next unless new_ids[old_id] next unless new_ids[old_id][task_dir] tasks[i] = "#{task_dir},#{new_ids[old_id][task_dir]}" end File.write("#{SYC_DIR}/#{File.basename(file)}", tasks.join("\n")) end end |
#update_tasks_log(dirs, excluded = [], new_ids) ⇒ Object
Updates the tasks.log file if tasks are re-indexed with the task’s new ids
304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 |
# File 'lib/syctask/environment.rb', line 304 def update_tasks_log(dirs, excluded=[], new_ids) tasks_log_files(dirs, excluded).each do |file| logs = File.readlines(file) logs.each_with_index do |log,i| type = log.scan(/^.*?(?=;)/)[0] logs[i] = log.sub!("-",";") if log.scan(/(?<=^#{type};)\d+-/)[0] old_id = log.scan(/(?<=^#{type};)\d+(?=;)/)[0] next unless new_ids[old_id] task_dir = log.scan(/(?<=^#{type};#{old_id};).*?(?=;)/)[0] next unless new_ids[old_id][task_dir] logs[i] = log.sub("#{old_id};#{task_dir}", "#{new_ids[old_id][task_dir]};#{task_dir}") end if file == TASKS_LOG File.write(TASKS_LOG, logs.join) else #TODO only append a line if it is not already available in TASKS_LOG File.open(TASKS_LOG, 'a') {|f| f.puts logs.join} FileUtils.rm file end end end |
#update_tracked_task(dirs, excluded) ⇒ Object
Updates tracked_tasks file if task has been re-indexed with new ID
347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 |
# File 'lib/syctask/environment.rb', line 347 def update_tracked_task(dirs, excluded) @tracked = get_files(dirs, excluded, /tracked_tasks/) if @tracked.nil? return if @tracked.empty? task = File.read(@tracked[0]) if File.exists? RIDX_LOG old_id = task.scan(/(?<=id: )\d+$/) old_dir = task.scan(/(?<=dir: ).*$/) return if old_id.empty? or old_dir.empty? pattern = %r{(?<=#{old_id[0]},)\d+(?=,#{old_dir[0]}\/\d+\.task)} new_id = File.read(RIDX_LOG).scan(pattern) task.gsub!("id: #{old_id}", "id: #{new_id}") end File.write(TRACKED_TASK, task) FileUtils.rm @tracked[0] unless TRACKED_TASK == @tracked[0] end |