diff options
Diffstat (limited to 'pcbnew/github/github_getliblist.cpp')
-rw-r--r-- | pcbnew/github/github_getliblist.cpp | 242 |
1 files changed, 242 insertions, 0 deletions
diff --git a/pcbnew/github/github_getliblist.cpp b/pcbnew/github/github_getliblist.cpp new file mode 100644 index 0000000..15c321a --- /dev/null +++ b/pcbnew/github/github_getliblist.cpp @@ -0,0 +1,242 @@ +/* + * This program source code file is part of KiCad, a free EDA CAD application. + * + * Copyright (C) 2015 Jean-Pierre Charras jp.charras at wanadoo.fr + * Copyright (C) 2013 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com> + * Copyright (C) 2015 KiCad Developers, see CHANGELOG.TXT for contributors. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, you may find one here: + * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html + * or you may search the http://www.gnu.org website for the version 2 license, + * or you may write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + + +/* + * While creating a wizard to edit the fp lib tables, and mainly the web viewer + * which can read the list of pretty library on a github repos, I was told there is + * this URL to retrieve info from any particular repo: + * + * https://api.github.com/orgs/KiCad/repos + * or + * https://api.github.com/users/KiCad/repos + * + * This gets just information on the repo in JSON format. + * + * JP Charras. + */ + +#include <kicad_curl/kicad_curl_easy.h> // Include before any wx file +#include <wx/uri.h> + +#include <github_getliblist.h> +#include <macros.h> +#include <common.h> +#include <html_link_parser.h> + + +GITHUB_GETLIBLIST::GITHUB_GETLIBLIST( const wxString& aRepoURL ) +{ + m_repoURL = aRepoURL; + m_libs_ext = wxT( ".pretty" ); + strcpy( m_option_string, "application/json" ); +} + + +bool GITHUB_GETLIBLIST::Get3DshapesLibsList( wxArrayString* aList, + bool (*aFilter)( const wxString& aData ) ) +{ + std::string fullURLCommand; + + strcpy( m_option_string, "text/html" ); + + wxString repoURL = m_repoURL; + + wxString errorMsg; + + fullURLCommand = repoURL.utf8_str(); + bool success = remoteGetJSON( fullURLCommand, &errorMsg ); + + if( !success ) + { + wxMessageBox( errorMsg ); + return false; + } + + if( aFilter && aList ) + { + //Convert m_image (std::string) to a wxString for HTML_LINK_PARSER + wxString buffer( GetBuffer() ); + + HTML_LINK_PARSER html_parser( buffer, *aList ); + html_parser.ParseLinks( aFilter ); + } + + return true; +} + + +bool GITHUB_GETLIBLIST::GetFootprintLibraryList( wxArrayString& aList ) +{ + std::string fullURLCommand; + int page = 1; + int itemCountMax = 99; // Do not use a valu > 100, it does not work + + strcpy( m_option_string, "application/json" ); + + // Github max items returned is 100 per page + + if( !repoURL2listURL( m_repoURL, &fullURLCommand, itemCountMax, page ) ) + { + wxString msg = wxString::Format( _( "malformed URL:\n'%s'" ), GetChars( m_repoURL ) ); + wxMessageBox( msg ); + return false; + } + + // The URL lib names are relative to the server name. + // so add the server name to them. + wxURI repo( m_repoURL ); + wxString urlPrefix = repo.GetScheme() + wxT( "://" ) + repo.GetServer() + wxT( "/" ); + + wxString errorMsg; + const char sep = ','; // Separator fields, in json returned file + wxString tmp; + int items_count_per_page = 0; + std::string& json_image = GetBuffer(); + + while( 1 ) + { + bool success = remoteGetJSON( fullURLCommand, &errorMsg ); + + if( !success ) + { + wxMessageBox( errorMsg ); + return false; + } + + + for( unsigned ii = 0; ii < json_image.size(); ii++ ) + { + if( json_image[ii] == sep || ii == json_image.size() - 1 ) + { + if( tmp.StartsWith( wxT( "\"full_name\"" ) ) ) + { + #define QUOTE '\"' + // Remove useless quotes: + if( tmp[tmp.Length() - 1] == QUOTE ) + tmp.RemoveLast(); + + if( tmp.EndsWith( m_libs_ext ) ) + { + aList.Add( tmp.AfterLast( ':' ) ); + int idx = aList.GetCount() - 1; + + if( aList[idx][0] == QUOTE ) + aList[idx].Remove( 0, 1 ); + + aList[idx].Prepend( urlPrefix ); + } + + items_count_per_page++; + } + + tmp.Clear(); + } + else + tmp << json_image[ii]; + } + + if( items_count_per_page >= itemCountMax ) + { + page++; + repoURL2listURL( m_repoURL, &fullURLCommand, itemCountMax, page ); + items_count_per_page = 0; + ClearBuffer(); + } + else + break; + } + + aList.Sort(); + return true; +} + + +bool GITHUB_GETLIBLIST::repoURL2listURL( const wxString& aRepoURL, + std::string* aFullURLCommand, + int aItemCountMax, int aPage ) +{ + // aListURL is e.g. "https://api.github.com/orgs/KiCad/repos" + // or "https://api.github.com/users/KiCad/repos" + // aRepoURL is e.g. "https://github.com/KiCad" + // Github has a default pagination set to 30 items. + // but allows up to 100 items max if we add the "?per_page=100" option + + wxURI repo( aRepoURL ); + + if( repo.HasServer() && repo.HasPath() ) + { + // goal: "https://api.github.com/users/KiCad" + // or "https://api.github.com/orgs/KiCad" + // "https://api.github.com/users/..." works both for orgs and users + // if we just retrieve the .pretty list + wxString target_url( wxT( "https://api.github.com/users" ) ); + target_url += repo.GetPath(); + target_url += wxT( "/repos" ); + + // Github has a default pagination set to 30 items. + // but allows up to 100 items max. Use this limit + target_url += wxString::Format( "?per_page=%d&page=%d", aItemCountMax, aPage ); + + *aFullURLCommand = target_url.utf8_str(); + return true; + } + + return false; +} + + +bool GITHUB_GETLIBLIST::remoteGetJSON( const std::string& aFullURLCommand, wxString* aMsgError ) +{ + KICAD_CURL_EASY kcurl; + + wxLogDebug( wxT( "Attempting to download: " ) + aFullURLCommand ); + + kcurl.SetURL( aFullURLCommand ); + kcurl.SetUserAgent( "http://kicad-pcb.org" ); + kcurl.SetHeader( "Accept", m_option_string ); + kcurl.SetFollowRedirects( true ); + + try + { + kcurl.Perform(); + m_image = kcurl.GetBuffer(); + return true; + } + catch( const IO_ERROR& ioe ) + { + if( aMsgError ) + { + UTF8 fmt( _( "Error fetching JSON data from URL '%s'.\nReason: '%s'" ) ); + + std::string msg = StrPrintf( fmt.c_str(), + aFullURLCommand.c_str(), + TO_UTF8( ioe.errorText ) ); + + *aMsgError = FROM_UTF8( msg.c_str() ); + } + return false; + } +} |