KiCad PCB EDA Suite
PROJECT_ARCHIVER Class Reference

#include <project_archiver.h>

Public Member Functions

 PROJECT_ARCHIVER ()
 
 ~PROJECT_ARCHIVER ()=default
 
bool Archive (const wxString &aSrcDir, const wxString &aDestFile, REPORTER &aReporter, bool aVerbose=true, bool aIncludeExtraFiles=false)
 Creates an archive of the project. More...
 
bool Unarchive (const wxString &aSrcFile, const wxString &aDestDir, REPORTER &aReporter)
 Extracts an archive of the current project over existing files Warning: this will overwrite files in the project directory. More...
 

Detailed Description

Definition at line 31 of file project_archiver.h.

Constructor & Destructor Documentation

◆ PROJECT_ARCHIVER()

PROJECT_ARCHIVER::PROJECT_ARCHIVER ( )

Definition at line 37 of file project_archiver.cpp.

38 {
39 }

◆ ~PROJECT_ARCHIVER()

PROJECT_ARCHIVER::~PROJECT_ARCHIVER ( )
default

Member Function Documentation

◆ Archive()

bool PROJECT_ARCHIVER::Archive ( const wxString &  aSrcDir,
const wxString &  aDestFile,
REPORTER aReporter,
bool  aVerbose = true,
bool  aIncludeExtraFiles = false 
)

Creates an archive of the project.

Parameters
aSrcFileis the full path to the project to be archived
aDestFileis the full path to the zip file to be created
aReporteris used to report status
aVerbosecontrols the verbosity of reported status messages
aIncludeExtraFilesif true will archive legacy and output files
Returns
true if the archive was created successfully

Definition at line 154 of file project_archiver.cpp.

156 {
157  // List of file extensions that are always archived
158  static const wxChar* extensionList[] = {
159  wxT( "*.kicad_pro" ),
160  wxT( "*.kicad_prl" ),
161  wxT( "*.kicad_sch" ),
162  wxT( "*.kicad_sym" ),
163  wxT( "*.kicad_pcb" ),
164  wxT( "*.kicad_mod" ),
165  wxT( "*.kicad_dru" ),
166  wxT( "*.kicad_wks" ),
167  wxT( "fp-lib-table" ),
168  wxT( "sym-lib-table" )
169  };
170 
171  // List of additional file extensions that are only archived when aIncludeExtraFiles is true
172  static const wxChar* extraExtensionList[] = {
173  wxT( "*.pro" ),
174  wxT( "*.sch" ), // Legacy schematic files
175  wxT( "*.lib" ), wxT( "*.dcm" ), // Legacy schematic library files
176  wxT( "*.cmp" ),
177  wxT( "*.brd" ),
178  wxT( "*.mod" ),
179  wxT( "*.stp" ), wxT( "*.step" ), // 3d files
180  wxT( "*.wrl" ),
181  wxT( "*.gb?" ), wxT( "*.gbrjob" ), // Gerber files
182  wxT( "*.gko" ), wxT( "*.gm1" ),
183  wxT( "*.gm2" ), wxT( "*.g?" ),
184  wxT( "*.gp1" ), wxT( "*.gp2" ),
185  wxT( "*.gpb" ), wxT( "*.gpt" ),
186  wxT( "*.gt?" ),
187  wxT( "*.pos" ), wxT( "*.drl" ), wxT( "*.nc" ), wxT( "*.xnc" ), // Fab files
188  wxT( "*.d356" ), wxT( "*.rpt" ),
189  wxT( "*.net" ), wxT( "*.py" ),
190  wxT( "*.pdf" ), wxT( "*.txt" )
191  };
192 
193  bool success = true;
194  wxString msg;
195  wxString oldCwd = wxGetCwd();
196 
197  wxSetWorkingDirectory( aSrcDir );
198 
199  wxFFileOutputStream ostream( aDestFile );
200 
201  if( !ostream.IsOk() ) // issue to create the file. Perhaps not writable dir
202  {
203  msg.Printf( _( "Unable to create archive file \"%s\"\n" ), aDestFile );
204  aReporter.Report( msg, RPT_SEVERITY_ERROR );
205  return false;
206  }
207 
208  wxZipOutputStream zipstream( ostream, -1, wxConvUTF8 );
209 
210  // Build list of filenames to put in zip archive
211  wxString currFilename;
212 
213  wxArrayString files;
214 
215  for( unsigned ii = 0; ii < arrayDim( extensionList ); ii++ )
216  wxDir::GetAllFiles( aSrcDir, &files, extensionList[ii] );
217 
218  if( aIncludeExtraFiles )
219  {
220  for( unsigned ii = 0; ii < arrayDim( extraExtensionList ); ii++ )
221  wxDir::GetAllFiles( aSrcDir, &files, extraExtensionList[ii] );
222  }
223 
224  files.Sort();
225 
226  unsigned long uncompressedBytes = 0;
227 
228  for( unsigned ii = 0; ii < files.GetCount(); ii++ )
229  {
230  wxFileSystem fsfile;
231 
232  wxFileName curr_fn( files[ii] );
233  curr_fn.MakeRelativeTo( aSrcDir );
234  currFilename = curr_fn.GetFullPath();
235 
236  // Read input file and add it to the zip file:
237  wxFSFile* infile = fsfile.OpenFile( wxFileSystem::FileNameToURL( curr_fn ) );
238 
239  if( infile )
240  {
241  zipstream.PutNextEntry( currFilename, infile->GetModificationTime() );
242  infile->GetStream()->Read( zipstream );
243  zipstream.CloseEntry();
244 
245  uncompressedBytes += infile->GetStream()->GetSize();
246 
247  if( aVerbose )
248  {
249  msg.Printf( _( "Archive file \"%s\"\n" ), currFilename );
250  aReporter.Report( msg, RPT_SEVERITY_INFO );
251  }
252 
253  delete infile;
254  }
255  else
256  {
257  if( aVerbose )
258  {
259  msg.Printf( _( "Archive file \"%s\": Failed!\n" ), currFilename );
260  aReporter.Report( msg, RPT_SEVERITY_ERROR );
261  }
262 
263  success = false;
264  }
265  }
266 
267  auto reportSize =
268  []( unsigned long aSize ) -> wxString
269  {
270  constexpr float KB = 1024.0;
271  constexpr float MB = KB * 1024.0;
272 
273  if( aSize >= MB )
274  return wxString::Format( wxT( "%0.2f MB" ), aSize / MB );
275  else if( aSize >= KB )
276  return wxString::Format( wxT( "%0.2f KB" ), aSize / KB );
277  else
278  return wxString::Format( wxT( "%lu bytes" ), aSize );
279  };
280 
281  size_t zipBytesCnt = ostream.GetSize();
282 
283  if( zipstream.Close() )
284  {
285  msg.Printf( _( "Zip archive \"%s\" created (%s uncompressed, %s compressed)\n" ), aDestFile,
286  reportSize( uncompressedBytes ), reportSize( zipBytesCnt ) );
287  aReporter.Report( msg, RPT_SEVERITY_INFO );
288  }
289  else
290  {
291  msg.Printf( wxT( "Unable to create archive \"%s\"\n" ), aDestFile );
292  aReporter.Report( msg, RPT_SEVERITY_ERROR );
293  success = false;
294  }
295 
296  wxSetWorkingDirectory( oldCwd );
297  return success;
298 }
static const std::vector< std::string > extensionList
virtual REPORTER & Report(const wxString &aText, SEVERITY aSeverity=RPT_SEVERITY_UNDEFINED)=0
Report a string with a given severity.
constexpr std::size_t arrayDim(T const (&)[N]) noexcept
Returns # of elements in an array.
Definition: arraydim.h:31
void Format(OUTPUTFORMATTER *out, int aNestLevel, int aCtl, const CPTREE &aTree)
Output a PTREE into s-expression format via an OUTPUTFORMATTER derivative.
Definition: ptree.cpp:200
#define _(s)
Definition: 3d_actions.cpp:33

References _, arrayDim(), extensionList, Format(), REPORTER::Report(), RPT_SEVERITY_ERROR, and RPT_SEVERITY_INFO.

Referenced by SETTINGS_MANAGER::BackupProject(), and KICAD_MANAGER_FRAME::OnArchiveFiles().

◆ Unarchive()

bool PROJECT_ARCHIVER::Unarchive ( const wxString &  aSrcFile,
const wxString &  aDestDir,
REPORTER aReporter 
)

Extracts an archive of the current project over existing files Warning: this will overwrite files in the project directory.

Use with care. The caller is responsible for doing any reloading of state after taking this action.

Parameters
aSrcFileis the full path to the archive to extract
aDestDiris the target directory to unarchive to
aReporteris used to report status
Returns
true if the archive was created successfully

Definition at line 83 of file project_archiver.cpp.

85 {
86  wxFFileInputStream stream( aSrcFile );
87 
88  if( !stream.IsOk() )
89  {
90  aReporter.Report( _( "Could not open archive file\n" ), RPT_SEVERITY_ERROR );
91  return false;
92  }
93 
94  const wxArchiveClassFactory* archiveClassFactory =
95  wxArchiveClassFactory::Find( aSrcFile, wxSTREAM_FILEEXT );
96 
97  if( !archiveClassFactory )
98  {
99  aReporter.Report( _( "Invalid archive file format\n" ), RPT_SEVERITY_ERROR );
100  return false;
101  }
102 
103  wxScopedPtr<wxArchiveInputStream> archiveStream( archiveClassFactory->NewStream( stream ) );
104 
105  wxString fileStatus;
106 
107  for( wxArchiveEntry* entry = archiveStream->GetNextEntry(); entry;
108  entry = archiveStream->GetNextEntry() )
109  {
110  fileStatus.Printf( _( "Extracting file \"%s\"\n" ), entry->GetName() );
111  aReporter.Report( fileStatus, RPT_SEVERITY_INFO );
112 
113  wxString fullname = aDestDir + entry->GetName();
114 
115  // Ensure the target directory exists and created it if not
116  wxString t_path = wxPathOnly( fullname );
117 
118  if( !wxDirExists( t_path ) )
119  {
120  // To create t_path, we need to create all subdirs from unzipDir
121  // to t_path.
122  wxFileName pathToCreate;
123  pathToCreate.AssignDir( t_path );
124  pathToCreate.MakeRelativeTo( aDestDir );
125 
126  // Create the list of subdirs candidates
127  wxArrayString subDirs;
128  subDirs = pathToCreate.GetDirs();
129  pathToCreate.AssignDir( aDestDir );
130 
131  for( size_t ii = 0; ii < subDirs.Count(); ii++ )
132  {
133  pathToCreate.AppendDir( subDirs[ii] );
134  wxString currPath = pathToCreate.GetPath();
135 
136  if( !wxDirExists( currPath ) )
137  wxMkdir( currPath );
138  }
139  }
140 
141  wxTempFileOutputStream outputFileStream( fullname );
142 
143  if( CopyStreamData( *archiveStream, outputFileStream, entry->GetSize() ) )
144  outputFileStream.Commit();
145  else
146  aReporter.Report( _( "Error extracting file!\n" ), RPT_SEVERITY_ERROR );
147  }
148 
149  aReporter.Report( wxT( "Extracted project\n" ), RPT_SEVERITY_INFO );
150  return true;
151 }
virtual REPORTER & Report(const wxString &aText, SEVERITY aSeverity=RPT_SEVERITY_UNDEFINED)=0
Report a string with a given severity.
static bool CopyStreamData(wxInputStream &inputStream, wxOutputStream &outputStream, wxFileOffset size)
#define _(s)
Definition: 3d_actions.cpp:33

References _, CopyStreamData(), REPORTER::Report(), RPT_SEVERITY_ERROR, and RPT_SEVERITY_INFO.

Referenced by KICAD_MANAGER_FRAME::OnUnarchiveFiles().


The documentation for this class was generated from the following files: