Class TaskImportsController
In: app/controllers/task_imports_controller.rb
Parent: ApplicationController
File:task_imports_controller.rb
(C):Hipposoft 2008, 2009
Purpose:Import task definition data from external sources.

          30-Mar-2008 (ADH): Created.

Methods

create   update  

Public Instance methods

Take the file data from the ‘new’ view form and ‘create’ an "import session"; that is, parse the file and generate an intermediate representation of the tasks therein. Render an ‘edit’ view where the user can ‘edit’ the "import session", by changing titles etc. of the task list obtained from the file.

[Source]

    # File app/controllers/task_imports_controller.rb, line 28
28:   def create
29: 
30:     # Set up a new TaskImport session object and read the XML file details
31: 
32:     xmlfile = params[ :import ][ :xmlfile ] || ''
33:     @import = TaskImport.new
34:     @import.project_id = @current_user.control_panel.project_id
35: 
36:     if ( xmlfile == '' ) # Empty string = nothing chosen, else a file object
37: 
38:       flash[ :error ] = "Please choose a file before using the 'Analyse' button."
39: 
40:     else
41: 
42:       # The user selected a file to upload, so process it
43: 
44:       begin
45: 
46:         # We assume XML files always begin with "<" in the first byte and
47:         # if that's missing then it's GZip compressed. That's true in the
48:         # limited case of project files.
49: 
50:         byte = xmlfile.getc()
51:         xmlfile.rewind()
52: 
53:         xmlfile       = Zlib::GzipReader.new( xmlfile ) if ( byte != '<'[ 0 ] )
54:         xmldoc        = REXML::Document.new( xmlfile.read() )
55:         task_data     = TaskImport.get_tasks_from_xml( xmldoc )
56: 
57:         tasks         = task_data[ :tasks         ]
58:         parent_uids   = task_data[ :parent_uids   ]
59:         parent_titles = task_data[ :parent_titles ]
60: 
61:         if ( tasks.nil? or tasks.empty? )
62:           flash[ :error  ] = 'No usable tasks were found in that file'
63: 
64:         else
65:           @import.tasks         = tasks
66:           @import.parent_uids   = parent_uids
67:           @import.parent_titles = parent_titles
68:           @import.collapse      = @import.max_level
69: 
70:           @import.generate_filtered_task_list()
71: 
72:           flash[ :notice ] = 'Tasks read successfully. Please choose items to import.'
73:           render( { :action => :edit } )
74:           flash.delete( :notice ) and return # If not deleted, flash message persists for one fetch too many
75: 
76:         end
77: 
78:       rescue => error
79: 
80:         # REXML errors can be huge, including a full backtrace. It can cause
81:         # session cookie overflow and we don't want the user to see it. Cut
82:         # the message off at the first newline.
83: 
84:         lines = error.message.split("\n")
85:         flash[ :error ] = "Failed to read file: #{ lines[ 0 ] }"
86:         flash.delete( :notice ) # In case it got set above, but the render call then failed
87: 
88:       end
89:     end
90: 
91:     render( { :action => :new } )
92:     flash.delete( :error ) # If not deleted, flash message persists for one fetch too many
93:   end

Once the user has updated anything they need to update in the import session ‘edit’-like view (see also ‘create’ above), process the form submission and import any real Tasks into the database if so requested or re-process the input file if necessary.

[Source]

     # File app/controllers/task_imports_controller.rb, line 100
100:   def update
101: 
102:     @import = TaskImport.new( params[ :import ] )
103: 
104:     # Should this list now be collapsed, or should it be imported?
105: 
106:     unless ( params[ :do_collapse ].nil? )
107:       @import.generate_filtered_task_list()
108:       render( { :action => :edit } ) and return
109:     end
110: 
111:     # Import tasks from the filtered list submitted with the form, which holds
112:     # a combination of user-editable and hidden preset values.
113: 
114:     to_import = @import.filtered_tasks.reject { | task | task.import != '1' }
115: 
116:     if ( to_import.empty? )
117: 
118:       flash[ :error ] = 'No tasks were selected for import. Please select at least one task and try again.'
119: 
120:     else
121: 
122:       # Right, good to go! Do the import.
123: 
124:       project_id = @import.project_id
125:       project    = nil
126: 
127:       begin
128:         Task.transaction do
129:           project = Project.find( project_id )
130: 
131:           to_import.each do | source_task |
132:             destination_task          = Task.new
133:             destination_task.title    = source_task.title
134:             destination_task.code     = source_task.code
135:             destination_task.duration = source_task.duration
136:             destination_task.billable = source_task.billable
137:             destination_task.project  = project
138:             destination_task.save!
139:           end
140: 
141:           flash[ :notice ] = "#{ to_import.length } #{ to_import.length == 1 ? 'task' : 'tasks' } imported successfully."
142:           redirect_to( home_path() ) and return
143:         end
144: 
145:       rescue => error
146:         flash[ :error ] = "Unable to import tasks: #{ error }"
147: 
148:       end
149: 
150:     end
151: 
152:     render( { :action => :edit } )
153:     flash.delete( :error )
154:   end

[Validate]