KiCad PCB EDA Suite
GITHUB_PLUGIN Class Reference

Class GITHUB_PLUGIN implements a portion of pcbnew's PLUGIN interface to provide read only access to a github repo consisting of pretty footprints, and optionally provides "Copy On Write" support of edited footprints. More...

#include <github_plugin.h>

Inheritance diagram for GITHUB_PLUGIN:
PCB_IO PLUGIN

Public Member Functions

const wxString PluginName () const override
 Function PluginName returns a brief hard coded name for this PLUGIN. More...
 
const wxString GetFileExtension () const override
 Function GetFileExtension returns the file extension for the PLUGIN. More...
 
wxArrayString FootprintEnumerate (const wxString &aLibraryPath, const PROPERTIES *aProperties=NULL) override
 Function FootprintEnumerate returns a list of footprint names contained within the library at aLibraryPath. More...
 
void PrefetchLib (const wxString &aLibraryPath, const PROPERTIES *aProperties=NULL) override
 Function PrefetchLib If possible, prefetches the specified library (e.g. More...
 
MODULEFootprintLoad (const wxString &aLibraryPath, const wxString &aFootprintName, const PROPERTIES *aProperties) override
 Function FootprintLoad loads a footprint having aFootprintName from the aLibraryPath containing a library format that this PLUGIN knows about. More...
 
void FootprintSave (const wxString &aLibraryPath, const MODULE *aFootprint, const PROPERTIES *aProperties=NULL) override
 Function FootprintSave will write aModule to an existing library located at aLibraryPath. More...
 
void FootprintDelete (const wxString &aLibraryPath, const wxString &aFootprintName, const PROPERTIES *aProperties=NULL) override
 Function FootprintDelete deletes aFootprintName from the library at aLibraryPath. More...
 
bool IsFootprintLibWritable (const wxString &aLibraryPath) override
 Function IsFootprintLibWritable returns true iff the library at aLibraryPath is writable. More...
 
void FootprintLibOptions (PROPERTIES *aListToAppendTo) const override
 Function FootprintLibOptions appends supported PLUGIN options to aListToAppenTo along with internationalized descriptions. More...
 
void FootprintLibCreate (const wxString &aLibraryPath, const PROPERTIES *aProperties) override
 Function FootprintLibCreate creates a new empty footprint library at aLibraryPath empty. More...
 
bool FootprintLibDelete (const wxString &aLibraryPath, const PROPERTIES *aProperties) override
 Function FootprintLibDelete deletes an existing footprint library and returns true, or if library does not exist returns false, or throws an exception if library exists but is read only or cannot be deleted for some other reason. More...
 
 GITHUB_PLUGIN ()
 
 ~GITHUB_PLUGIN ()
 
void Save (const wxString &aFileName, BOARD *aBoard, const PROPERTIES *aProperties=NULL) override
 Function Save will write aBoard to a storage file in a format that this PLUGIN implementation knows about, or it can be used to write a portion of aBoard to a special kind of export file. More...
 
BOARDLoad (const wxString &aFileName, BOARD *aAppendToMe, const PROPERTIES *aProperties=NULL) override
 Function Load loads information from some input file format that this PLUGIN implementation knows about, into either a new BOARD or an existing one. More...
 
void Format (BOARD_ITEM *aItem, int aNestLevel=0) const throw ( IO_ERROR )
 Function Format outputs aItem to aFormatter in s-expression format. More...
 
std::string GetStringOutput (bool doClear)
 
void SetOutputFormatter (OUTPUTFORMATTER *aFormatter)
 
BOARD_ITEMParse (const wxString &aClipboardSourceInput) throw ( FUTURE_FORMAT_ERROR, PARSE_ERROR, IO_ERROR )
 

Protected Member Functions

void init (const PROPERTIES *aProperties)
 
void cacheLib (const wxString &aLibraryPath, const PROPERTIES *aProperties)
 
void remoteGetZip (const wxString &aRepoURL) throw ( IO_ERROR )
 Function remoteGetZip fetches a zip file image from a github repo synchronously. More...
 
void cacheLib (const wxString &aLibraryPath, const wxString &aFootprintName=wxEmptyString)
 we only cache one footprint library, this determines which one. More...
 

Static Protected Member Functions

static bool repoURL_zipURL (const wxString &aRepoURL, std::string *aZipURL)
 Function repoURL_zipURL translates a repo URL to a zipfile URL name as commonly seen on github.com. More...
 

Protected Attributes

wxString m_lib_path
 from aLibraryPath, something like https://github.com/liftoff-sr/pretty_footprints More...
 
std::string m_zip_image
 byte image of the zip file in its entirety. More...
 
GH_CACHEm_gh_cache
 
wxString m_pretty_dir
 
wxString m_error
 for throwing exceptions More...
 
BOARDm_board
 which BOARD, no ownership here More...
 
const PROPERTIESm_props
 passed via Save() or Load(), no ownership, may be NULL. More...
 
FP_CACHEm_cache
 Footprint library cache. More...
 
LINE_READERm_reader
 no ownership here. More...
 
wxString m_filename
 for saves only, name is in m_reader for loads More...
 
int m_loading_format_version
 which SEXPR_BOARD_FILE_VERSION should be Load()ed? More...
 
STRING_FORMATTER m_sf
 
OUTPUTFORMATTERm_out
 output any Format()s to this, no ownership More...
 
int m_ctl
 
PCB_PARSERm_parser
 
NETINFO_MAPPINGm_mapping
 mapping for net codes, so only not empty net codes are stored with consecutive integers as net codes More...
 

Detailed Description

Class GITHUB_PLUGIN implements a portion of pcbnew's PLUGIN interface to provide read only access to a github repo consisting of pretty footprints, and optionally provides "Copy On Write" support of edited footprints.

It could have used version 3 of the github.com API documented here:

    http://developer.github.com/v3/
    https://help.github.com/articles/creating-an-access-token-for-command-line-use

but it does not, since a better technique was discovered. Cleverly this plugin simply reads in a zip file of the repo and unzips it from RAM as needed. Therefore this "Github" plugin is read only for accessing remote pretty libraries at https://github.com.

The fp-lib-table dialog is entered via menu choice "Preferences | Library Tables". For easy options editing in the current row, click on the "Edit Options" button. The "Library Path" in the fp-lib-table row for a Github library should be set to the full https:// URL.

For example:

     https://github.com/liftoff-sr/pretty_footprints

This is typically

     https://github.com/user_name/repo_name

The "Plugin Type" should be set to "Github".

This plugin also supports "Copy On Write", a.k.a. "COW". Thus a Github library may take an optional option called allow_pretty_writing_to_this_dir. This option is essentially the "Library Path" for a local "KiCad" (pretty) type library which is combined to make up the Github library found in the same fp-lib-table row. If the option is missing, then the Github library is read only as always. If the option is present for a Github library, then any writes to this hybrid library will go to the local *.pretty directory. Note that the github.com resident portion of this hybrid COW library is always read only, meaning you cannot delete anything or modify any footprint at github directly. The aggregate library type remains "Github" in your discussions, but it consists of a local R/W portion and a remote R/O portion.

Below is an fp-lib-table entry for the case without option allow_pretty_writing_to_this_dir:

NicknameLibrary PathPlugin TypeOptions

Description

githubhttps://github.com/liftoff-sr/pretty_footprintsGithub Liftoff's GH footprints

Below is an fp-lib-table entry with the COW option given. Note the use of the environment variable ${HOME}, as an example only. The github.pretty directory is based in ${HOME}/pretty/. Anytime you use option allow_pretty_writing_to_this_dir, you will create that directory manually and it must end in extension .pretty.

NicknameLibrary PathPlugin TypeOptions

Description

githubhttps://github.com/liftoff-sr/pretty_footprintsGithub allow_pretty_writing_to_this_dir=${HOME}/pretty/github.pretty Liftoff's GH footprints

Any footprint loads will always give precedence to the local footprints found in the pretty dir given by option allow_pretty_writing_to_this_dir. So once you have written to the COW library's local directory by doing a footprint save, no github updates will be seen when loading a footprint by the same name as one for which you've written locally.

Always keep a separate local *.pretty directory for each Github library, never combine them by referring to the same directory more than once. Also, do not also use the same COW (*.pretty) directory in a "KiCad" fp-lib-table entry. This would likely create a mess. The COW directory should be manually created in advance, and the directory name must end with ".pretty". The value of the option allow_pretty_writing_to_this_dir will be path substituted with any environment variable strings embedded, just like the "Library Path" is.

What's the point of COW? It is to turbo-charge the sharing of footprints. If you periodically email your COW pretty footprint modifications to the Github repo maintainer, you can help update the Github copy. Simply email the individual *.kicad_mod files you find in your COW directories. After you've received confirmation that your changes have been committed up at github.com, you can safely delete your COW file(s) and those from github.com will flow down. Your goal should be to keep the COW file set as small as possible by contributing frequently to the shared master copies at https://github.com.

Note that if you use the module editor to delete a footprint and it is present in the COW local dir, it will get deleted from there. However, it may not be deleted from the library as a whole if the footprint of the same name also exists in the github repo. In this case deleting the local copy will simply unmask the one at the github repo. Remember, it is masked out if there is a local COW copy, since the local copy always takes precedence. And remember you cannot modify the github copy except by emailing a COW modification to the repo maintainer.

If you happen to be the repo maintainer, then the obvious solution for you is to make your COW directory be your working copy directory. From there you can push to github. And you can receive *.kicad_mod files by email and put them into your local working copy directory also and do diffs, reverting or denying when appropriate, editing when appropriate before pushing or denying the change. Ultimately you would owe the sender either a note of acceptance or denial by email.

Author
Dick Hollenbeck
Date
Original date: 10-Sep-2013

Definition at line 162 of file github_plugin.h.

Constructor & Destructor Documentation

GITHUB_PLUGIN::GITHUB_PLUGIN ( )

Definition at line 109 of file github_plugin.cpp.

109  :
110  PCB_IO(),
111  m_gh_cache( 0 )
112 {
113 }
PCB_IO(int aControlFlags=CTL_FOR_BOARD)
GH_CACHE * m_gh_cache
GITHUB_PLUGIN::~GITHUB_PLUGIN ( )

Definition at line 116 of file github_plugin.cpp.

References m_gh_cache.

117 {
118  delete m_gh_cache;
119 }
GH_CACHE * m_gh_cache

Member Function Documentation

void PCB_IO::cacheLib ( const wxString &  aLibraryPath,
const wxString &  aFootprintName = wxEmptyString 
)
protectedinherited

we only cache one footprint library, this determines which one.

Definition at line 1809 of file kicad_plugin.cpp.

References PCB_IO::FP_CACHE, FP_CACHE::IsModified(), FP_CACHE::Load(), and PCB_IO::m_cache.

Referenced by PCB_IO::FootprintDelete(), PCB_IO::FootprintEnumerate(), PCB_IO::FootprintLoad(), PCB_IO::FootprintSave(), and PCB_IO::IsFootprintLibWritable().

1810 {
1811  if( !m_cache || m_cache->IsModified( aLibraryPath, aFootprintName ) )
1812  {
1813  // a spectacular episode in memory management:
1814  delete m_cache;
1815  m_cache = new FP_CACHE( this, aLibraryPath );
1816  m_cache->Load();
1817  }
1818 }
friend class FP_CACHE
FP_CACHE * m_cache
Footprint library cache.
bool IsModified(const wxString &aLibPath, const wxString &aFootprintName=wxEmptyString) const
Function IsModified check if the footprint cache has been modified relative to aLibPath and aFootprin...
void Load()
void GITHUB_PLUGIN::cacheLib ( const wxString &  aLibraryPath,
const PROPERTIES aProperties 
)
protected

Definition at line 373 of file github_plugin.cpp.

References LIB_TABLE::ExpandSubstitutions(), Format(), FROM_UTF8(), GetChars(), m_gh_cache, m_lib_path, m_pretty_dir, m_zip_image, PRETTY_DIR, remoteGetZip(), THROW_IO_ERROR, and PROPERTIES::Value().

Referenced by FootprintDelete(), FootprintEnumerate(), FootprintLibCreate(), FootprintLibDelete(), FootprintLoad(), and FootprintSave().

374 {
375  // This is edge triggered based on a change in 'aLibraryPath',
376  // usually it does nothing. When the edge fires, m_pretty_dir is set
377  // to either:
378  // 1) empty or
379  // 2) a verified and validated, writable, *.pretty directory.
380 
381  if( !m_gh_cache || m_lib_path != aLibraryPath )
382  {
383  delete m_gh_cache;
384  m_gh_cache = 0;
385  m_pretty_dir.clear();
386 
387  if( !m_lib_path.empty() )
388  {
389  // Library path wasn't empty before - it's been changed. Flush out the prefetch cache.
390  m_zip_image.clear();
391  }
392 
393  if( aProperties )
394  {
395  UTF8 pretty_dir;
396 
397  if( aProperties->Value( PRETTY_DIR, &pretty_dir ) )
398  {
399  wxString wx_pretty_dir = pretty_dir;
400 
401  wx_pretty_dir = LIB_TABLE::ExpandSubstitutions( wx_pretty_dir );
402 
403  wxFileName wx_pretty_fn = wx_pretty_dir;
404 
405  if( !wx_pretty_fn.IsOk() ||
406  !wx_pretty_fn.IsDirWritable() ||
407  wx_pretty_fn.GetExt() != "pretty"
408  )
409  {
410  wxString msg = wxString::Format(
411  _( "option '%s' for Github library '%s' must point to a writable directory ending with '.pretty'." ),
413  GetChars( aLibraryPath )
414  );
415 
416  THROW_IO_ERROR( msg );
417  }
418 
419  m_pretty_dir = wx_pretty_dir;
420  }
421  }
422 
423  // operator==( wxString, wxChar* ) does not exist, construct wxString once here.
424  const wxString kicad_mod( "kicad_mod" );
425 
426  //D(printf("%s: this:%p m_lib_path:'%s' aLibraryPath:'%s'\n", __func__, this, TO_UTF8( m_lib_path), TO_UTF8(aLibraryPath) );)
427  m_gh_cache = new GH_CACHE();
428 
429  // INIT_LOGGER( "/tmp", "test.log" );
430  remoteGetZip( aLibraryPath );
431  // UNINIT_LOGGER();
432 
433  m_lib_path = aLibraryPath;
434 
435  wxMemoryInputStream mis( &m_zip_image[0], m_zip_image.size() );
436 
437  // @todo: generalize this name encoding from a PROPERTY (option) later
438  wxZipInputStream zis( mis, wxConvUTF8 );
439 
440  wxZipEntry* entry;
441 
442  while( ( entry = zis.GetNextEntry() ) != NULL )
443  {
444  wxFileName fn( entry->GetName() ); // chop long name into parts
445 
446  if( fn.GetExt() == kicad_mod )
447  {
448  UTF8 fp_name = fn.GetName(); // omit extension & path
449 
450  m_gh_cache->insert( fp_name, entry );
451  }
452  else
453  delete entry;
454  }
455  }
456 }
Class UTF8 is an 8 bit std::string that is assuredly encoded in UTF8, and supplies special conversion...
Definition: utf8.h:53
static wxString FROM_UTF8(const char *cstring)
function FROM_UTF8 converts a UTF8 encoded C string to a wxString for all wxWidgets build modes...
Definition: macros.h:53
static const wxString ExpandSubstitutions(const wxString &aString)
Function ExpandSubstitutions.
bool Value(const char *aName, UTF8 *aFetchedValue=NULL) const
Function Value fetches a property by aName and returns true if that property was found, else false.
Definition: properties.cpp:24
std::string m_zip_image
byte image of the zip file in its entirety.
wxString m_lib_path
from aLibraryPath, something like https://github.com/liftoff-sr/pretty_footprints ...
#define THROW_IO_ERROR(x)
Definition: utf8.cpp:60
wxString m_pretty_dir
static const wxChar * GetChars(const wxString &s)
Function GetChars returns a wxChar* to the actual wxChar* data within a wxString, and is helpful for ...
Definition: macros.h:92
void Format(OUTPUTFORMATTER *out, int aNestLevel, int aCtl, CPTREE &aTree)
Function Format outputs a PTREE into s-expression format via an OUTPUTFORMATTER derivative.
Definition: ptree.cpp:205
void remoteGetZip(const wxString &aRepoURL)
Function remoteGetZip fetches a zip file image from a github repo synchronously.
GH_CACHE * m_gh_cache
Class GH_CACHE assists only within GITHUB_PLUGIN and holds a map of footprint name to wxZipEntry...
static const char * PRETTY_DIR
void GITHUB_PLUGIN::FootprintDelete ( const wxString &  aLibraryPath,
const wxString &  aFootprintName,
const PROPERTIES aProperties = NULL 
)
overridevirtual

Function FootprintDelete deletes aFootprintName from the library at aLibraryPath.

Parameters
aLibraryPathis a locator for the "library", usually a directory, file, or URL containing several footprints.
aFootprintNameis the name of a footprint to delete from the specified library.
aPropertiesis an associative array that can be used to tell the library delete function anything special, because it can take any number of additional named tuning arguments that the plugin is known to support. The caller continues to own this object (plugin may not delete it), and plugins should expect it to be optionally NULL.
Exceptions
IO_ERRORif there is a problem finding the footprint or the library, or deleting it.

Reimplemented from PLUGIN.

Definition at line 275 of file github_plugin.cpp.

References cacheLib(), PCB_IO::FootprintDelete(), PCB_IO::FootprintEnumerate(), Format(), GetChars(), IsFootprintLibWritable(), m_pretty_dir, PRETTY_DIR, StrPrintf(), THROW_IO_ERROR, and TO_UTF8.

277 {
278  // set m_pretty_dir to either empty or something in aProperties
279  cacheLib( aLibraryPath, aProperties );
280 
281  if( GITHUB_PLUGIN::IsFootprintLibWritable( aLibraryPath ) )
282  {
283  // Does the PCB_IO base class have this footprint?
284  // We cannot write to github.
285 
286  wxArrayString pretties = PCB_IO::FootprintEnumerate( m_pretty_dir, aProperties );
287 
288  if( pretties.Index( aFootprintName ) != wxNOT_FOUND )
289  {
290  PCB_IO::FootprintDelete( m_pretty_dir, aFootprintName, aProperties );
291  }
292  else
293  {
294  wxString msg = wxString::Format(
295  _( "Footprint\n'%s'\nis not in the writable portion of this Github library\n'%s'" ),
296  GetChars( aFootprintName ),
297  GetChars( aLibraryPath )
298  );
299 
300  THROW_IO_ERROR( msg );
301  }
302  }
303  else
304  {
305  // This typically will not happen if the caller first properly calls
306  // IsFootprintLibWritable() to determine if calling FootprintSave() is
307  // even legal, so I spend no time on internationalization here:
308 
309  string msg = StrPrintf( "Github library\n'%s'\nis only writable if you set option '%s' in Library Tables dialog.",
310  TO_UTF8( aLibraryPath ), PRETTY_DIR );
311 
312  THROW_IO_ERROR( msg );
313  }
314 }
int StrPrintf(std::string *result, const char *format,...)
Function StrPrintf is like sprintf() but the output is appended to a std::string instead of to a char...
Definition: richio.cpp:75
#define TO_UTF8(wxstring)
Macro TO_UTF8 converts a wxString to a UTF8 encoded C string for all wxWidgets build modes...
Definition: macros.h:47
void cacheLib(const wxString &aLibraryPath, const PROPERTIES *aProperties)
#define THROW_IO_ERROR(x)
Definition: utf8.cpp:60
wxString m_pretty_dir
void FootprintDelete(const wxString &aLibraryPath, const wxString &aFootprintName, const PROPERTIES *aProperties=NULL) override
Function FootprintDelete deletes aFootprintName from the library at aLibraryPath. ...
static const wxChar * GetChars(const wxString &s)
Function GetChars returns a wxChar* to the actual wxChar* data within a wxString, and is helpful for ...
Definition: macros.h:92
void Format(OUTPUTFORMATTER *out, int aNestLevel, int aCtl, CPTREE &aTree)
Function Format outputs a PTREE into s-expression format via an OUTPUTFORMATTER derivative.
Definition: ptree.cpp:205
wxArrayString FootprintEnumerate(const wxString &aLibraryPath, const PROPERTIES *aProperties=NULL) override
Function FootprintEnumerate returns a list of footprint names contained within the library at aLibrar...
bool IsFootprintLibWritable(const wxString &aLibraryPath) override
Function IsFootprintLibWritable returns true iff the library at aLibraryPath is writable.
static const char * PRETTY_DIR
wxArrayString GITHUB_PLUGIN::FootprintEnumerate ( const wxString &  aLibraryPath,
const PROPERTIES aProperties = NULL 
)
overridevirtual

Function FootprintEnumerate returns a list of footprint names contained within the library at aLibraryPath.

Parameters
aLibraryPathis a locator for the "library", usually a directory, file, or URL containing several footprints.
aPropertiesis an associative array that can be used to tell the plugin anything needed about how to perform with respect to aLibraryPath. The caller continues to own this object (plugin may not delete it), and plugins should expect it to be optionally NULL.
Returns
wxArrayString - is the array of available footprint names inside a library
Exceptions
IO_ERRORif the library cannot be found, or footprint cannot be loaded.

Reimplemented from PLUGIN.

Definition at line 134 of file github_plugin.cpp.

References cacheLib(), PCB_IO::FootprintEnumerate(), FROM_UTF8(), m_gh_cache, and m_pretty_dir.

136 {
137  //D(printf("%s: this:%p aLibraryPath:'%s'\n", __func__, this, TO_UTF8(aLibraryPath) );)
138  cacheLib( aLibraryPath, aProperties );
139 
140  typedef std::set<wxString> MYSET;
141 
142  MYSET unique;
143 
144  if( m_pretty_dir.size() )
145  {
146  wxArrayString locals = PCB_IO::FootprintEnumerate( m_pretty_dir );
147 
148  for( unsigned i=0; i<locals.GetCount(); ++i )
149  unique.insert( locals[i] );
150  }
151 
152  for( MODULE_ITER it = m_gh_cache->begin(); it!=m_gh_cache->end(); ++it )
153  {
154  unique.insert( FROM_UTF8( it->first.c_str() ) );
155  }
156 
157  wxArrayString ret;
158 
159  for( MYSET::const_iterator it = unique.begin(); it != unique.end(); ++it )
160  {
161  ret.Add( *it );
162  }
163 
164  return ret;
165 }
MODULE_MAP::iterator MODULE_ITER
static wxString FROM_UTF8(const char *cstring)
function FROM_UTF8 converts a UTF8 encoded C string to a wxString for all wxWidgets build modes...
Definition: macros.h:53
void cacheLib(const wxString &aLibraryPath, const PROPERTIES *aProperties)
wxString m_pretty_dir
wxArrayString FootprintEnumerate(const wxString &aLibraryPath, const PROPERTIES *aProperties=NULL) override
Function FootprintEnumerate returns a list of footprint names contained within the library at aLibrar...
GH_CACHE * m_gh_cache
void GITHUB_PLUGIN::FootprintLibCreate ( const wxString &  aLibraryPath,
const PROPERTIES aProperties 
)
overridevirtual

Function FootprintLibCreate creates a new empty footprint library at aLibraryPath empty.

It is an error to attempt to create an existing library or to attempt to create on a "read only" location.

Parameters
aLibraryPathis a locator for the "library", usually a directory, file, or URL containing several footprints.
aPropertiesis an associative array that can be used to tell the library create function anything special, because it can take any number of additional named tuning arguments that the plugin is known to support. The caller continues to own this object (plugin may not delete it), and plugins should expect it to be optionally NULL.
Exceptions
IO_ERRORif there is a problem finding the library, or creating it.

Reimplemented from PLUGIN.

Definition at line 317 of file github_plugin.cpp.

References cacheLib(), PCB_IO::FootprintLibCreate(), and m_pretty_dir.

318 {
319  // set m_pretty_dir to either empty or something in aProperties
320  cacheLib( aLibraryPath, aProperties );
321 
322  if( m_pretty_dir.size() )
323  {
325  }
326  else
327  {
328  // THROW_IO_ERROR() @todo
329  }
330 }
void FootprintLibCreate(const wxString &aLibraryPath, const PROPERTIES *aProperties=NULL) override
Function FootprintLibCreate creates a new empty footprint library at aLibraryPath empty...
void cacheLib(const wxString &aLibraryPath, const PROPERTIES *aProperties)
wxString m_pretty_dir
bool GITHUB_PLUGIN::FootprintLibDelete ( const wxString &  aLibraryPath,
const PROPERTIES aProperties 
)
overridevirtual

Function FootprintLibDelete deletes an existing footprint library and returns true, or if library does not exist returns false, or throws an exception if library exists but is read only or cannot be deleted for some other reason.

Parameters
aLibraryPathis a locator for the "library", usually a directory or file which will contain footprints.
aPropertiesis an associative array that can be used to tell the library delete implementation function anything special, because it can take any number of additional named tuning arguments that the plugin is known to support. The caller continues to own this object (plugin may not delete it), and plugins should expect it to be optionally NULL.
Returns
bool - true if library deleted, false if library did not exist.
Exceptions
IO_ERRORif there is a problem deleting an existing library.

Reimplemented from PLUGIN.

Definition at line 333 of file github_plugin.cpp.

References cacheLib(), PCB_IO::FootprintLibDelete(), and m_pretty_dir.

334 {
335  // set m_pretty_dir to either empty or something in aProperties
336  cacheLib( aLibraryPath, aProperties );
337 
338  if( m_pretty_dir.size() )
339  {
340  return PCB_IO::FootprintLibDelete( m_pretty_dir, aProperties );
341  }
342  else
343  {
344  // THROW_IO_ERROR() @todo
345  return false;
346  }
347 }
void cacheLib(const wxString &aLibraryPath, const PROPERTIES *aProperties)
wxString m_pretty_dir
bool FootprintLibDelete(const wxString &aLibraryPath, const PROPERTIES *aProperties=NULL) override
Function FootprintLibDelete deletes an existing footprint library and returns true, or if library does not exist returns false, or throws an exception if library exists but is read only or cannot be deleted for some other reason.
void GITHUB_PLUGIN::FootprintLibOptions ( PROPERTIES aListToAppendTo) const
overridevirtual

Function FootprintLibOptions appends supported PLUGIN options to aListToAppenTo along with internationalized descriptions.

Options are typically appended so that a derived PLUGIN can call its base class function by the same name first, thus inheriting options declared there. (Some base class options could pertain to all Footprint*() functions in all derived PLUGINs.) Note that since aListToAppendTo is a PROPERTIES object, all options will be unique and last guy wins.

Parameters
aListToAppendToholds a tuple of
option
This eventually is what shows up into the fp-lib-table "options" field, possibly combined with others.
internationalized description
The internationalized description is displayed in DIALOG_FP_PLUGIN_OPTIONS. It may be multi-line and be quite explanatory of the option.

In the future perhaps aListToAppendTo evolves to something capable of also holding a wxValidator for the cells in said dialog: http://forums.wxwidgets.org/viewtopic.php?t=23277&p=104180. This would require a 3 column list, and introducing wx GUI knowledge to PLUGIN, which has been avoided to date.

Reimplemented from PLUGIN.

Definition at line 350 of file github_plugin.cpp.

References PLUGIN::FootprintLibOptions(), and PRETTY_DIR.

351 {
352  // inherit options supported by all PLUGINs.
353  PLUGIN::FootprintLibOptions( aListToAppendTo );
354 
355  (*aListToAppendTo)[ PRETTY_DIR ] = UTF8( _(
356  "Set this property to a directory where footprints are to be written as pretty "
357  "footprints when saving to this library. Anything saved will take precedence over "
358  "footprints by the same name in the github repo. These saved footprints can then "
359  "be sent to the library maintainer as updates. "
360  "<p>The directory <b>must</b> have a <b>.pretty</b> file extension because the "
361  "format of the save is pretty.</p>"
362  ));
363 
364  /*
365  (*aListToAppendTo)["cache_github_zip_in_this_dir"] = UTF8( _(
366  "Set this property to a directory where the github *.zip file will be cached. "
367  "This should speed up subsequent visits to this library."
368  ));
369  */
370 }
Class UTF8 is an 8 bit std::string that is assuredly encoded in UTF8, and supplies special conversion...
Definition: utf8.h:53
virtual void FootprintLibOptions(PROPERTIES *aListToAppendTo) const
Function FootprintLibOptions appends supported PLUGIN options to aListToAppenTo along with internatio...
Definition: plugin.cpp:122
static const char * PRETTY_DIR
MODULE * GITHUB_PLUGIN::FootprintLoad ( const wxString &  aLibraryPath,
const wxString &  aFootprintName,
const PROPERTIES aProperties 
)
overridevirtual

Function FootprintLoad loads a footprint having aFootprintName from the aLibraryPath containing a library format that this PLUGIN knows about.

Parameters
aLibraryPathis a locator for the "library", usually a directory, file, or URL containing several footprints.
aFootprintNameis the name of the footprint to load.
aPropertiesis an associative array that can be used to tell the loader implementation to do something special, because it can take any number of additional named tuning arguments that the plugin is known to support. The caller continues to own this object (plugin may not delete it), and plugins should expect it to be optionally NULL.
Returns
MODULE* - if found caller owns it, else NULL if not found.
Exceptions
IO_ERRORif the library cannot be found or read. No exception is thrown in the case where aFootprintName cannot be found.

Reimplemented from PLUGIN.

Definition at line 180 of file github_plugin.cpp.

References cacheLib(), PCB_IO::FootprintLoad(), m_gh_cache, PCB_IO::m_parser, m_pretty_dir, m_zip_image, PCB_PARSER::Parse(), MODULE::SetFPID(), and PCB_PARSER::SetLineReader().

182 {
183  // D(printf("%s: this:%p aLibraryPath:'%s'\n", __func__, this, TO_UTF8(aLibraryPath) );)
184 
185  // clear or set to valid the variable m_pretty_dir
186  cacheLib( aLibraryPath, aProperties );
187 
188  if( m_pretty_dir.size() )
189  {
190  // API has FootprintLoad() *not* throwing an exception if footprint not found.
191  MODULE* local = PCB_IO::FootprintLoad( m_pretty_dir, aFootprintName, aProperties );
192 
193  if( local )
194  {
195  // It has worked, see <src>/scripts/test_kicad_plugin.py. So this was not firing:
196  // wxASSERT( aFootprintName == FROM_UTF8( local->GetFPID().GetLibItemName().c_str() ) );
197  // Moving it to higher API layer FP_LIB_TABLE::FootprintLoad().
198 
199  return local;
200  }
201  }
202 
203  UTF8 fp_name = aFootprintName;
204 
205  MODULE_CITER it = m_gh_cache->find( fp_name );
206 
207  if( it != m_gh_cache->end() ) // fp_name is present
208  {
209  //std::string::data() ensures that the referenced data block is contiguous.
210  wxMemoryInputStream mis( m_zip_image.data(), m_zip_image.size() );
211 
212  // This decoder should always be UTF8, since it was saved that way by git.
213  // That is, since pretty footprints are UTF8, and they were pushed to the
214  // github repo, they are still UTF8.
215  wxZipInputStream zis( mis, wxConvUTF8 );
216  wxZipEntry* entry = (wxZipEntry*) it->second; // remove "const"-ness
217 
218  if( zis.OpenEntry( *entry ) )
219  {
220  INPUTSTREAM_LINE_READER reader( &zis, aLibraryPath );
221 
222  // I am a PCB_IO derivative with my own PCB_PARSER
223  m_parser->SetLineReader( &reader ); // ownership not passed
224 
225  MODULE* ret = (MODULE*) m_parser->Parse();
226 
227  // In a github library, (as well as in a "KiCad" library) the name of
228  // the pretty file defines the footprint name. That filename trumps
229  // any name found in the pretty file; any name in the pretty file
230  // must be ignored here. Also, the library nickname is unknown in
231  // this context so clear it just in case.
232  ret->SetFPID( fp_name );
233 
234  return ret;
235  }
236  }
237 
238  return NULL; // this API function returns NULL for "not found", per spec.
239 }
Class UTF8 is an 8 bit std::string that is assuredly encoded in UTF8, and supplies special conversion...
Definition: utf8.h:53
Class INPUTSTREAM_LINE_READER is a LINE_READER that reads from a wxInputStream object.
Definition: richio.h:290
std::string m_zip_image
byte image of the zip file in its entirety.
MODULE * FootprintLoad(const wxString &aLibraryPath, const wxString &aFootprintName, const PROPERTIES *aProperties=NULL) override
Function FootprintLoad loads a footprint having aFootprintName from the aLibraryPath containing a lib...
void cacheLib(const wxString &aLibraryPath, const PROPERTIES *aProperties)
wxString m_pretty_dir
PCB_PARSER * m_parser
BOARD_ITEM * Parse()
Definition: pcb_parser.cpp:405
LINE_READER * SetLineReader(LINE_READER *aReader)
Function SetLineReader sets aLineReader into the parser, and returns the previous one...
Definition: pcb_parser.h:298
MODULE_MAP::const_iterator MODULE_CITER
GH_CACHE * m_gh_cache
void SetFPID(const LIB_ID &aFPID)
Definition: class_module.h:153
void GITHUB_PLUGIN::FootprintSave ( const wxString &  aLibraryPath,
const MODULE aFootprint,
const PROPERTIES aProperties = NULL 
)
overridevirtual

Function FootprintSave will write aModule to an existing library located at aLibraryPath.

If a footprint by the same name already exists, it is replaced.

Parameters
aLibraryPathis a locator for the "library", usually a directory, file, or URL containing several footprints.
aFootprintis what to store in the library. The caller continues to own the footprint after this call.
aPropertiesis an associative array that can be used to tell the saver how to save the footprint, because it can take any number of additional named tuning arguments that the plugin is known to support. The caller continues to own this object (plugin may not delete it), and plugins should expect it to be optionally NULL.
Exceptions
IO_ERRORif there is a problem saving.

Reimplemented from PLUGIN.

Definition at line 251 of file github_plugin.cpp.

References cacheLib(), PCB_IO::FootprintSave(), IsFootprintLibWritable(), m_pretty_dir, PRETTY_DIR, StrPrintf(), THROW_IO_ERROR, and TO_UTF8.

253 {
254  // set m_pretty_dir to either empty or something in aProperties
255  cacheLib( aLibraryPath, aProperties );
256 
257  if( GITHUB_PLUGIN::IsFootprintLibWritable( aLibraryPath ) )
258  {
259  PCB_IO::FootprintSave( m_pretty_dir, aFootprint, aProperties );
260  }
261  else
262  {
263  // This typically will not happen if the caller first properly calls
264  // IsFootprintLibWritable() to determine if calling FootprintSave() is
265  // even legal, so I spend no time on internationalization here:
266 
267  string msg = StrPrintf( "Github library\n'%s'\nis only writable if you set option '%s' in Library Tables dialog.",
268  TO_UTF8( aLibraryPath ), PRETTY_DIR );
269 
270  THROW_IO_ERROR( msg );
271  }
272 }
int StrPrintf(std::string *result, const char *format,...)
Function StrPrintf is like sprintf() but the output is appended to a std::string instead of to a char...
Definition: richio.cpp:75
#define TO_UTF8(wxstring)
Macro TO_UTF8 converts a wxString to a UTF8 encoded C string for all wxWidgets build modes...
Definition: macros.h:47
void FootprintSave(const wxString &aLibraryPath, const MODULE *aFootprint, const PROPERTIES *aProperties=NULL) override
Function FootprintSave will write aModule to an existing library located at aLibraryPath.
void cacheLib(const wxString &aLibraryPath, const PROPERTIES *aProperties)
#define THROW_IO_ERROR(x)
Definition: utf8.cpp:60
wxString m_pretty_dir
bool IsFootprintLibWritable(const wxString &aLibraryPath) override
Function IsFootprintLibWritable returns true iff the library at aLibraryPath is writable.
static const char * PRETTY_DIR
void PCB_IO::Format ( BOARD_ITEM aItem,
int  aNestLevel = 0 
) const
throw (IO_ERROR
)
inherited

Function Format outputs aItem to aFormatter in s-expression format.

Parameters
aItemA pointer the an BOARD_ITEM object to format.
aNestLevelThe indentation nest level.
Exceptions
IO_ERRORon write error.

Definition at line 442 of file kicad_plugin.cpp.

References PCB_DIMENSION_T, PCB_LINE_T, PCB_MODULE_EDGE_T, PCB_MODULE_T, PCB_MODULE_TEXT_T, PCB_PAD_T, PCB_T, PCB_TARGET_T, PCB_TEXT_T, PCB_TRACE_T, PCB_VIA_T, and PCB_ZONE_AREA_T.

Referenced by MODULE_EDITOR_TOOLS::CopyItems(), FOOTPRINT_EDIT_FRAME::Export_Module(), FOOTPRINT_EDIT_FRAME::retainLastFootprint(), PCB_IO::Save(), and FP_CACHE::Save().

444 {
445  LOCALE_IO toggle; // public API function, perform anything convenient for caller
446 
447  switch( aItem->Type() )
448  {
449  case PCB_T:
450  format( static_cast<BOARD*>( aItem ), aNestLevel );
451  break;
452 
453  case PCB_DIMENSION_T:
454  format( static_cast<DIMENSION*>( aItem ), aNestLevel );
455  break;
456 
457  case PCB_LINE_T:
458  format( static_cast<DRAWSEGMENT*>( aItem ), aNestLevel );
459  break;
460 
461  case PCB_MODULE_EDGE_T:
462  format( static_cast<EDGE_MODULE*>( aItem ), aNestLevel );
463  break;
464 
465  case PCB_TARGET_T:
466  format( static_cast<PCB_TARGET*>( aItem ), aNestLevel );
467  break;
468 
469  case PCB_MODULE_T:
470  format( static_cast<MODULE*>( aItem ), aNestLevel );
471  break;
472 
473  case PCB_PAD_T:
474  format( static_cast<D_PAD*>( aItem ), aNestLevel );
475  break;
476 
477  case PCB_TEXT_T:
478  format( static_cast<TEXTE_PCB*>( aItem ), aNestLevel );
479  break;
480 
481  case PCB_MODULE_TEXT_T:
482  format( static_cast<TEXTE_MODULE*>( aItem ), aNestLevel );
483  break;
484 
485  case PCB_TRACE_T:
486  case PCB_VIA_T:
487  format( static_cast<TRACK*>( aItem ), aNestLevel );
488  break;
489 
490  case PCB_ZONE_AREA_T:
491  format( static_cast<ZONE_CONTAINER*>( aItem ), aNestLevel );
492  break;
493 
494  default:
495  wxFAIL_MSG( wxT( "Cannot format item " ) + aItem->GetClass() );
496  }
497 }
KICAD_T Type() const
Function Type()
Definition: base_struct.h:198
Definition: typeinfo.h:97
Class LOCALE_IO is a class that can be instantiated within a scope in which you are expecting excepti...
Definition: common.h:166
class ZONE_CONTAINER, a zone area
Definition: typeinfo.h:114
class TEXTE_PCB, text on a layer
Definition: typeinfo.h:104
class D_PAD, a pad in a footprint
Definition: typeinfo.h:102
class EDGE_MODULE, a footprint edge
Definition: typeinfo.h:106
class TRACK, a track segment (segment on a copper layer)
Definition: typeinfo.h:107
class MODULE, a footprint
Definition: typeinfo.h:101
class DIMENSION, a dimension (graphic item)
Definition: typeinfo.h:112
class PCB_TARGET, a target (graphic item)
Definition: typeinfo.h:113
class TEXTE_MODULE, text in a footprint
Definition: typeinfo.h:105
virtual wxString GetClass() const =0
Function GetClass returns the class name.
void format(BOARD *aBoard, int aNestLevel=0) const
class VIA, a via (like a track segment on a copper layer)
Definition: typeinfo.h:108
class DRAWSEGMENT, a segment not on copper layers
Definition: typeinfo.h:103
const wxString GITHUB_PLUGIN::GetFileExtension ( ) const
overridevirtual

Function GetFileExtension returns the file extension for the PLUGIN.

Implements PLUGIN.

Definition at line 128 of file github_plugin.cpp.

129 {
130  return wxEmptyString;
131 }
std::string PCB_IO::GetStringOutput ( bool  doClear)
inlineinherited

Definition at line 149 of file pcbnew/kicad_plugin.h.

References STRING_FORMATTER::Clear(), STRING_FORMATTER::GetString(), and PCB_IO::m_sf.

Referenced by MODULE_EDITOR_TOOLS::CopyItems(), FOOTPRINT_EDIT_FRAME::Export_Module(), and FOOTPRINT_EDIT_FRAME::retainLastFootprint().

150  {
151  std::string ret = m_sf.GetString();
152  if( doClear )
153  m_sf.Clear();
154 
155  return ret;
156  }
const std::string & GetString()
Definition: richio.h:475
STRING_FORMATTER m_sf
void Clear()
Function Clear clears the buffer and empties the internal string.
Definition: richio.h:464
void GITHUB_PLUGIN::init ( const PROPERTIES aProperties)
protected
bool GITHUB_PLUGIN::IsFootprintLibWritable ( const wxString &  aLibraryPath)
overridevirtual

Function IsFootprintLibWritable returns true iff the library at aLibraryPath is writable.

(Often system libraries are read only because of where they are installed.)

Parameters
aLibraryPathis a locator for the "library", usually a directory, file, or URL containing several footprints.
Exceptions
IO_ERRORif no library at aLibraryPath exists.

Reimplemented from PLUGIN.

Definition at line 242 of file github_plugin.cpp.

References PCB_IO::IsFootprintLibWritable(), and m_pretty_dir.

Referenced by FootprintDelete(), and FootprintSave().

243 {
244  if( m_pretty_dir.size() )
246  else
247  return false;
248 }
bool IsFootprintLibWritable(const wxString &aLibraryPath) override
Function IsFootprintLibWritable returns true iff the library at aLibraryPath is writable.
wxString m_pretty_dir
BOARD * PCB_IO::Load ( const wxString &  aFileName,
BOARD aAppendToMe,
const PROPERTIES aProperties = NULL 
)
overridevirtualinherited

Function Load loads information from some input file format that this PLUGIN implementation knows about, into either a new BOARD or an existing one.

This may be used to load an entire new BOARD, or to augment an existing one if aAppendToMe is not NULL.

Parameters
aFileNameis the name of the file to use as input and may be foreign in nature or native in nature.
aAppendToMeis an existing BOARD to append to, but if NULL then this means "do not append, rather load anew".
aPropertiesis an associative array that can be used to tell the loader how to load the file, because it can take any number of additional named arguments that the plugin is known to support. These are tuning parameters for the import or load. The caller continues to own this object (plugin may not delete it), and plugins should expect it to be optionally NULL.
Returns
BOARD* - the successfully loaded board, or the same one as aAppendToMe if aAppendToMe was not NULL, and caller owns it.
Exceptions
IO_ERRORif there is a problem loading, and its contents should say what went wrong, using line number and character offsets of the input file if possible.

Reimplemented from PLUGIN.

Definition at line 1756 of file kicad_plugin.cpp.

References DSNLEXER::CurLine(), DSNLEXER::CurLineNumber(), DSNLEXER::CurOffset(), DSNLEXER::CurSource(), PCB_PARSER::GetRequiredVersion(), PCB_IO::init(), PCB_PARSER::IsTooRecent(), PCB_IO::m_parser, PCB_PARSER::Parse(), PCB_PARSER::SetBoard(), BOARD::SetFileName(), PCB_PARSER::SetLineReader(), and THROW_PARSE_ERROR.

1757 {
1758  FILE_LINE_READER reader( aFileName );
1759 
1760  init( aProperties );
1761 
1762  m_parser->SetLineReader( &reader );
1763  m_parser->SetBoard( aAppendToMe );
1764 
1765  BOARD* board;
1766 
1767  try
1768  {
1769  board = dynamic_cast<BOARD*>( m_parser->Parse() );
1770  }
1771  catch( const FUTURE_FORMAT_ERROR& )
1772  {
1773  // Don't wrap a FUTURE_FORMAT_ERROR in another
1774  throw;
1775  }
1776  catch( const PARSE_ERROR& parse_error )
1777  {
1778  if( m_parser->IsTooRecent() )
1779  throw FUTURE_FORMAT_ERROR( parse_error, m_parser->GetRequiredVersion() );
1780  else
1781  throw;
1782  }
1783 
1784  if( !board )
1785  {
1786  // The parser loaded something that was valid, but wasn't a board.
1787  THROW_PARSE_ERROR( _( "this file does not contain a PCB" ),
1790  }
1791 
1792  // Give the filename to the board if it's new
1793  if( !aAppendToMe )
1794  board->SetFileName( aFileName );
1795 
1796  return board;
1797 }
void init(const PROPERTIES *aProperties)
const wxString & CurSource()
Function CurFilename returns the current LINE_READER source.
Definition: dsnlexer.h:528
Class FILE_LINE_READER is a LINE_READER that reads from an open file.
Definition: richio.h:180
wxString GetRequiredVersion()
Return a string representing the version of kicad required to open this file.
Definition: pcb_parser.cpp:182
#define THROW_PARSE_ERROR(aProblem, aSource, aInputLine, aLineNumber, aByteIndex)
Definition: ki_exception.h:133
void SetBoard(BOARD *aBoard)
Definition: pcb_parser.h:305
int CurOffset()
Function CurOffset returns the byte offset within the current line, using a 1 based index...
Definition: dsnlexer.h:538
void SetFileName(const wxString &aFileName)
Definition: class_board.h:235
PCB_PARSER * m_parser
BOARD_ITEM * Parse()
Definition: pcb_parser.cpp:405
LINE_READER * SetLineReader(LINE_READER *aReader)
Function SetLineReader sets aLineReader into the parser, and returns the previous one...
Definition: pcb_parser.h:298
const char * CurLine()
Function CurLine returns the current line of text, from which the CurText() would return its token...
Definition: dsnlexer.h:517
bool IsTooRecent()
Return whether a version number, if any was parsed, was too recent.
Definition: pcb_parser.h:316
Struct PARSE_ERROR contains a filename or source description, a problem input line, a line number, a byte offset, and an error message which contains the the caller's report and his call site information: CPP source file, function, and line number.
Definition: ki_exception.h:94
Class BOARD holds information pertinent to a Pcbnew printed circuit board.
Definition: class_board.h:166
int CurLineNumber()
Function CurLineNumber returns the current line number within my LINE_READER.
Definition: dsnlexer.h:507
Struct FUTURE_FORMAT_ERROR variant of PARSE_ERROR indicating that a syntax or related error was likel...
Definition: ki_exception.h:143
BOARD_ITEM * PCB_IO::Parse ( const wxString &  aClipboardSourceInput)
throw ( FUTURE_FORMAT_ERROR,
PARSE_ERROR,
IO_ERROR
)
inherited

Definition at line 419 of file kicad_plugin.cpp.

References TO_UTF8.

Referenced by parse_module_kicad(), MODULE_EDITOR_TOOLS::PasteItems(), and FOOTPRINT_EDIT_FRAME::restoreLastFootprint().

421 {
422  std::string input = TO_UTF8( aClipboardSourceInput );
423 
424  STRING_LINE_READER reader( input, wxT( "clipboard" ) );
425 
426  m_parser->SetLineReader( &reader );
427 
428  try
429  {
430  return m_parser->Parse();
431  }
432  catch( const PARSE_ERROR& parse_error )
433  {
434  if( m_parser->IsTooRecent() )
435  throw FUTURE_FORMAT_ERROR( parse_error, m_parser->GetRequiredVersion() );
436  else
437  throw;
438  }
439 }
#define TO_UTF8(wxstring)
Macro TO_UTF8 converts a wxString to a UTF8 encoded C string for all wxWidgets build modes...
Definition: macros.h:47
wxString GetRequiredVersion()
Return a string representing the version of kicad required to open this file.
Definition: pcb_parser.cpp:182
PCB_PARSER * m_parser
BOARD_ITEM * Parse()
Definition: pcb_parser.cpp:405
LINE_READER * SetLineReader(LINE_READER *aReader)
Function SetLineReader sets aLineReader into the parser, and returns the previous one...
Definition: pcb_parser.h:298
bool IsTooRecent()
Return whether a version number, if any was parsed, was too recent.
Definition: pcb_parser.h:316
Struct PARSE_ERROR contains a filename or source description, a problem input line, a line number, a byte offset, and an error message which contains the the caller's report and his call site information: CPP source file, function, and line number.
Definition: ki_exception.h:94
Struct FUTURE_FORMAT_ERROR variant of PARSE_ERROR indicating that a syntax or related error was likel...
Definition: ki_exception.h:143
Class STRING_LINE_READER is a LINE_READER that reads from a multiline 8 bit wide std::string.
Definition: richio.h:254
const wxString GITHUB_PLUGIN::PluginName ( ) const
overridevirtual

Function PluginName returns a brief hard coded name for this PLUGIN.

Implements PLUGIN.

Definition at line 122 of file github_plugin.cpp.

123 {
124  return "Github";
125 }
void GITHUB_PLUGIN::PrefetchLib ( const wxString &  aLibraryPath,
const PROPERTIES aProperties = NULL 
)
overridevirtual

Function PrefetchLib If possible, prefetches the specified library (e.g.

performing downloads). Does not parse. Threadsafe.

This is a no-op for libraries that cannot be prefetched.

Plugins that cannot prefetch need not override this; a default no-op is provided.

Parameters
aLibraryPathis a locator for the "library", usually a directory, file, or URL containing several footprints.
aPropertiesis an associative array that can be used to tell the plugin anything needed about how to perform with respect to aLibraryPath. The caller continues to own this object (plugin may not delete it), and plugins should expect it to be optionally NULL.
Exceptions
IO_ERRORif there is an error prefetching the library.

Reimplemented from PLUGIN.

Definition at line 168 of file github_plugin.cpp.

References m_lib_path, m_zip_image, and remoteGetZip().

170 {
171  if( m_lib_path != aLibraryPath )
172  {
173  m_zip_image.clear();
174  }
175 
176  remoteGetZip( aLibraryPath );
177 }
std::string m_zip_image
byte image of the zip file in its entirety.
wxString m_lib_path
from aLibraryPath, something like https://github.com/liftoff-sr/pretty_footprints ...
void remoteGetZip(const wxString &aRepoURL)
Function remoteGetZip fetches a zip file image from a github repo synchronously.
void GITHUB_PLUGIN::remoteGetZip ( const wxString &  aRepoURL)
throw (IO_ERROR
)
protected

Function remoteGetZip fetches a zip file image from a github repo synchronously.

The byte image is received into the m_input_stream. If the image has already been stored, do nothing.

Definition at line 532 of file github_plugin.cpp.

References Format(), KICAD_CURL_EASY::GetBuffer(), GetChars(), KICAD_CURL_EASY::Perform(), KICAD_CURL_EASY::SetFollowRedirects(), KICAD_CURL_EASY::SetHeader(), KICAD_CURL_EASY::SetURL(), KICAD_CURL_EASY::SetUserAgent(), StrPrintf(), THROW_IO_ERROR, TO_UTF8, and IO_ERROR::What().

Referenced by cacheLib(), and PrefetchLib().

533 {
534  std::string zip_url;
535 
536  if( !m_zip_image.empty() )
537  return;
538 
539  if( !repoURL_zipURL( aRepoURL, &zip_url ) )
540  {
541  wxString msg = wxString::Format( _( "Unable to parse URL:\n'%s'" ), GetChars( aRepoURL ) );
542  THROW_IO_ERROR( msg );
543  }
544 
545  wxLogDebug( wxT( "Attempting to download: " ) + zip_url );
546 
547  KICAD_CURL_EASY kcurl; // this can THROW_IO_ERROR
548 
549  kcurl.SetURL( zip_url.c_str() );
550  kcurl.SetUserAgent( "http://kicad-pcb.org" );
551  kcurl.SetHeader( "Accept", "application/zip" );
552  kcurl.SetFollowRedirects( true );
553 
554  try
555  {
556  kcurl.Perform();
557  m_zip_image = kcurl.GetBuffer();
558  }
559  catch( const IO_ERROR& ioe )
560  {
561  // https "GET" has failed, report this to API caller.
562  // Note: kcurl.Perform() does not return an error if the file to download is not found
563  static const char errorcmd[] = "http GET command failed"; // Do not translate this message
564 
565  UTF8 fmt( _( "%s\nCannot get/download Zip archive: '%s'\nfor library path: '%s'.\nReason: '%s'" ) );
566 
567  std::string msg = StrPrintf( fmt.c_str(),
568  errorcmd,
569  zip_url.c_str(),
570  TO_UTF8( aRepoURL ),
571  TO_UTF8( ioe.What() )
572  );
573 
574  THROW_IO_ERROR( msg );
575  }
576 
577  // If the zip archive is not existing, the received data is "Not Found" or "404: Not Found",
578  // and no error is returned by kcurl.Perform().
579  if( ( m_zip_image.compare( 0, 9, "Not Found", 9 ) == 0 ) ||
580  ( m_zip_image.compare( 0, 14, "404: Not Found", 14 ) == 0 ) )
581  {
582  UTF8 fmt( _( "Cannot download library '%s'.\nThe library does not exist on the server" ) );
583  std::string msg = StrPrintf( fmt.c_str(), TO_UTF8( aRepoURL ) );
584 
585  THROW_IO_ERROR( msg );
586  }
587 }
Class UTF8 is an 8 bit std::string that is assuredly encoded in UTF8, and supplies special conversion...
Definition: utf8.h:53
bool SetUserAgent(const std::string &aAgent)
Function SetUserAgent sets the request user agent.
void Perform()
Function perform equivalent to curl_easy_perform.
bool SetFollowRedirects(bool aFollow)
Function SetFollowRedirects enables the following of HTTP(s) and other redirects, by default curl doe...
Class KICAD_CURL_EASY wrapper interface around the curl_easy API.
std::string m_zip_image
byte image of the zip file in its entirety.
int StrPrintf(std::string *result, const char *format,...)
Function StrPrintf is like sprintf() but the output is appended to a std::string instead of to a char...
Definition: richio.cpp:75
#define TO_UTF8(wxstring)
Macro TO_UTF8 converts a wxString to a UTF8 encoded C string for all wxWidgets build modes...
Definition: macros.h:47
const std::string & GetBuffer()
Function GetBuffer returns a const reference to the recevied data buffer.
#define THROW_IO_ERROR(x)
Definition: utf8.cpp:60
bool SetURL(const std::string &aURL)
Function SetURL sets the request URL.
virtual const wxString What() const
A composite of Problem() and Where()
Definition: exceptions.cpp:33
static const wxChar * GetChars(const wxString &s)
Function GetChars returns a wxChar* to the actual wxChar* data within a wxString, and is helpful for ...
Definition: macros.h:92
void Format(OUTPUTFORMATTER *out, int aNestLevel, int aCtl, CPTREE &aTree)
Function Format outputs a PTREE into s-expression format via an OUTPUTFORMATTER derivative.
Definition: ptree.cpp:205
static bool repoURL_zipURL(const wxString &aRepoURL, std::string *aZipURL)
Function repoURL_zipURL translates a repo URL to a zipfile URL name as commonly seen on github...
void SetHeader(const std::string &aName, const std::string &aValue)
Function SetHeader sets an arbitrary header for the HTTP(s) request.
Struct IO_ERROR is a class used to hold an error message and may be used when throwing exceptions con...
Definition: ki_exception.h:47
bool GITHUB_PLUGIN::repoURL_zipURL ( const wxString &  aRepoURL,
std::string *  aZipURL 
)
staticprotected

Function repoURL_zipURL translates a repo URL to a zipfile URL name as commonly seen on github.com.

Parameters
aRepoURLpoints to the base of the repo.
aZipURLis where to put the zip file URL.
Returns
bool - true if aRepoULR was parseable, else false

Definition at line 459 of file github_plugin.cpp.

460 {
461  // e.g. "https://github.com/liftoff-sr/pretty_footprints"
462  //D(printf("aRepoURL:%s\n", TO_UTF8( aRepoURL ) );)
463 
464  wxURI repo( aRepoURL );
465 
466  if( repo.HasServer() && repo.HasPath() )
467  {
468  // scheme might be "http" or if truly github.com then "https".
469  wxString zip_url;
470 
471  if( repo.GetServer() == "github.com" )
472  {
473  //codeload.github.com only supports https
474  zip_url = "https://";
475 #if 0 // A proper code path would be this one, but it is not the fastest.
476  zip_url += repo.GetServer();
477  zip_url += repo.GetPath(); // path comes with a leading '/'
478  zip_url += "/archive/master.zip";
479 #else
480  // Github issues a redirect for the "master.zip". i.e.
481  // "https://github.com/liftoff-sr/pretty_footprints/archive/master.zip"
482  // would be redirected to:
483  // "https://codeload.github.com/liftoff-sr/pretty_footprints/zip/master"
484 
485  // In order to bypass this redirect, saving time, we use the
486  // redirected URL on first attempt to save one HTTP GET hit.
487  zip_url += "codeload.github.com";
488  zip_url += repo.GetPath(); // path comes with a leading '/'
489  zip_url += "/zip/master";
490 #endif
491  }
492 
493  else
494  {
495  zip_url = repo.GetScheme();
496  zip_url += "://";
497 
498  // This is the generic code path for any server which can serve
499  // up zip files. The schemes tested include: http and https.
500 
501  // zip_url goal: "<scheme>://<server>[:<port>]/<path>"
502 
503  // Remember that <scheme>, <server>, <port> if present, and <path> all came
504  // from the lib_path in the fp-lib-table row.
505 
506  // This code path is used with the nginx proxy setup, but is useful
507  // beyond that.
508 
509  zip_url += repo.GetServer();
510 
511  if( repo.HasPort() )
512  {
513  zip_url += ':';
514  zip_url += repo.GetPort();
515  }
516 
517  zip_url += repo.GetPath(); // path comes with a leading '/'
518 
519  // Do not modify the path, we cannot anticipate the needs of all
520  // servers which are serving up zip files directly. URL modifications
521  // are more generally done in the server, rather than contaminating
522  // this code path with the needs of one particular inflexible server.
523  }
524 
525  *aZipURL = zip_url.utf8_str();
526  return true;
527  }
528  return false;
529 }
void PCB_IO::Save ( const wxString &  aFileName,
BOARD aBoard,
const PROPERTIES aProperties = NULL 
)
overridevirtualinherited

Function Save will write aBoard to a storage file in a format that this PLUGIN implementation knows about, or it can be used to write a portion of aBoard to a special kind of export file.

Parameters
aFileNameis the name of a file to save to on disk.
aBoardis the class BOARD in memory document tree from which to extract information when writing to aFileName. The caller continues to own the BOARD, and the plugin should refrain from modifying the BOARD if possible.
aPropertiesis an associative array that can be used to tell the saver how to save the file, because it can take any number of additional named tuning arguments that the plugin is known to support. The caller continues to own this object (plugin may not delete it), and plugins should expect it to be optionally NULL.
Exceptions
IO_ERRORif there is a problem saving or exporting.

Reimplemented from PLUGIN.

Definition at line 395 of file kicad_plugin.cpp.

References PCB_IO::Format(), GetBuildVersion(), PCB_IO::init(), PCB_IO::m_board, PCB_IO::m_mapping, PCB_IO::m_out, OUTPUTFORMATTER::Print(), OUTPUTFORMATTER::Quotew(), NETINFO_MAPPING::SetBoard(), and SEXPR_BOARD_FILE_VERSION.

396 {
397  LOCALE_IO toggle; // toggles on, then off, the C locale.
398 
399  init( aProperties );
400 
401  m_board = aBoard; // after init()
402 
403  // Prepare net mapping that assures that net codes saved in a file are consecutive integers
404  m_mapping->SetBoard( aBoard );
405 
406  FILE_OUTPUTFORMATTER formatter( aFileName );
407 
408  m_out = &formatter; // no ownership
409 
410  m_out->Print( 0, "(kicad_pcb (version %d) (host pcbnew %s)\n", SEXPR_BOARD_FILE_VERSION,
411  formatter.Quotew( GetBuildVersion() ).c_str() );
412 
413  Format( aBoard, 1 );
414 
415  m_out->Print( 0, ")\n" );
416 }
OUTPUTFORMATTER * m_out
output any Format()s to this, no ownership
Class LOCALE_IO is a class that can be instantiated within a scope in which you are expecting excepti...
Definition: common.h:166
void init(const PROPERTIES *aProperties)
#define SEXPR_BOARD_FILE_VERSION
Current s-expression file format version. 2 was the last legacy format version.
void SetBoard(const BOARD *aBoard)
Function SetBoard Sets a BOARD object that is used to prepare the net code map.
wxString GetBuildVersion()
Function GetBuildVersion Return the build version string.
void Format(BOARD_ITEM *aItem, int aNestLevel=0) const
Function Format outputs aItem to aFormatter in s-expression format.
NETINFO_MAPPING * m_mapping
mapping for net codes, so only not empty net codes are stored with consecutive integers as net codes ...
BOARD * m_board
which BOARD, no ownership here
Class FILE_OUTPUTFORMATTER may be used for text file output.
Definition: richio.h:492
int PRINTF_FUNC Print(int nestLevel, const char *fmt,...)
Function Print formats and writes text to the output stream.
Definition: richio.cpp:408
void PCB_IO::SetOutputFormatter ( OUTPUTFORMATTER aFormatter)
inlineinherited

Definition at line 158 of file pcbnew/kicad_plugin.h.

References PCB_IO::m_out.

Referenced by FP_CACHE::Save().

158 { m_out = aFormatter; }
OUTPUTFORMATTER * m_out
output any Format()s to this, no ownership

Member Data Documentation

BOARD* PCB_IO::m_board
protectedinherited

which BOARD, no ownership here

Definition at line 166 of file pcbnew/kicad_plugin.h.

Referenced by PCB_IO::init(), and PCB_IO::Save().

int PCB_IO::m_ctl
protectedinherited

Definition at line 179 of file pcbnew/kicad_plugin.h.

Referenced by PCB_IO::FootprintSave(), and PCB_IO::formatLayer().

wxString PCB_IO::m_error
protectedinherited

for throwing exceptions

Definition at line 165 of file pcbnew/kicad_plugin.h.

wxString PCB_IO::m_filename
protectedinherited

for saves only, name is in m_reader for loads

Definition at line 173 of file pcbnew/kicad_plugin.h.

GH_CACHE* GITHUB_PLUGIN::m_gh_cache
protected

Definition at line 228 of file github_plugin.h.

Referenced by cacheLib(), FootprintEnumerate(), FootprintLoad(), and ~GITHUB_PLUGIN().

wxString GITHUB_PLUGIN::m_lib_path
protected

from aLibraryPath, something like https://github.com/liftoff-sr/pretty_footprints

Definition at line 226 of file github_plugin.h.

Referenced by cacheLib(), and PrefetchLib().

int PCB_IO::m_loading_format_version
protectedinherited

which SEXPR_BOARD_FILE_VERSION should be Load()ed?

Definition at line 175 of file pcbnew/kicad_plugin.h.

Referenced by PCB_IO::init().

NETINFO_MAPPING* PCB_IO::m_mapping
protectedinherited

mapping for net codes, so only not empty net codes are stored with consecutive integers as net codes

Definition at line 181 of file pcbnew/kicad_plugin.h.

Referenced by PCB_IO::Save(), and PCB_IO::~PCB_IO().

OUTPUTFORMATTER* PCB_IO::m_out
protectedinherited

output any Format()s to this, no ownership

Definition at line 178 of file pcbnew/kicad_plugin.h.

Referenced by PCB_IO::formatLayer(), PCB_IO::PCB_IO(), PCB_IO::Save(), and PCB_IO::SetOutputFormatter().

PCB_PARSER* PCB_IO::m_parser
protectedinherited
wxString GITHUB_PLUGIN::m_pretty_dir
protected
const PROPERTIES* PCB_IO::m_props
protectedinherited

passed via Save() or Load(), no ownership, may be NULL.

Definition at line 169 of file pcbnew/kicad_plugin.h.

Referenced by PCB_IO::init().

LINE_READER* PCB_IO::m_reader
protectedinherited

no ownership here.

Definition at line 172 of file pcbnew/kicad_plugin.h.

Referenced by PCB_IO::init().

STRING_FORMATTER PCB_IO::m_sf
protectedinherited

Definition at line 177 of file pcbnew/kicad_plugin.h.

Referenced by PCB_IO::GetStringOutput(), and PCB_IO::PCB_IO().

std::string GITHUB_PLUGIN::m_zip_image
protected

byte image of the zip file in its entirety.

Definition at line 227 of file github_plugin.h.

Referenced by cacheLib(), FootprintLoad(), and PrefetchLib().


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