2015-01-15 20:01:53 +00:00
|
|
|
/*
|
|
|
|
* 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.
|
|
|
|
*
|
|
|
|
* I used avhttp, already used in the pcbnew Github plugin to download
|
|
|
|
* the json file.
|
|
|
|
*
|
|
|
|
* JP Charras.
|
|
|
|
*/
|
|
|
|
|
2016-01-10 21:44:37 +00:00
|
|
|
#include <kicad_curl/kicad_curl_easy.h> // Include before any wx file
|
2015-01-15 20:01:53 +00:00
|
|
|
#include <wx/uri.h>
|
|
|
|
|
|
|
|
#include <github_getliblist.h>
|
|
|
|
#include <macros.h>
|
|
|
|
#include <common.h>
|
2015-08-20 07:14:44 +00:00
|
|
|
#include <html_link_parser.h>
|
2015-01-15 20:01:53 +00:00
|
|
|
|
|
|
|
|
|
|
|
GITHUB_GETLIBLIST::GITHUB_GETLIBLIST( const wxString& aRepoURL )
|
|
|
|
{
|
|
|
|
m_repoURL = aRepoURL;
|
2015-08-20 07:14:44 +00:00
|
|
|
m_libs_ext = wxT( ".pretty" );
|
|
|
|
strcpy( m_option_string, "application/json" );
|
2015-01-15 20:01:53 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2015-08-20 07:14:44 +00:00
|
|
|
bool GITHUB_GETLIBLIST::Get3DshapesLibsList( wxArrayString* aList,
|
|
|
|
bool (*aFilter)( const wxString& aData ) )
|
|
|
|
{
|
|
|
|
std::string fullURLCommand;
|
2016-01-10 21:44:37 +00:00
|
|
|
|
2015-08-20 07:14:44 +00:00
|
|
|
strcpy( m_option_string, "text/html" );
|
|
|
|
|
|
|
|
wxString errorMsg;
|
|
|
|
|
2017-07-14 11:34:42 +00:00
|
|
|
wxString repoURL = m_repoURL;
|
2015-08-20 07:14:44 +00:00
|
|
|
fullURLCommand = repoURL.utf8_str();
|
2015-12-21 20:30:33 +00:00
|
|
|
bool success = remoteGetJSON( fullURLCommand, &errorMsg );
|
2015-08-20 07:14:44 +00:00
|
|
|
|
|
|
|
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 )
|
2015-01-15 20:01:53 +00:00
|
|
|
{
|
|
|
|
std::string fullURLCommand;
|
|
|
|
int page = 1;
|
2017-07-14 11:34:42 +00:00
|
|
|
int itemCountMax = 99; // Do not use a value >= 100, it does not work
|
2016-01-10 21:44:37 +00:00
|
|
|
|
2015-08-20 07:14:44 +00:00
|
|
|
strcpy( m_option_string, "application/json" );
|
2015-01-15 20:01:53 +00:00
|
|
|
|
|
|
|
// Github max items returned is 100 per page
|
|
|
|
|
|
|
|
if( !repoURL2listURL( m_repoURL, &fullURLCommand, itemCountMax, page ) )
|
|
|
|
{
|
2017-12-15 11:37:46 +00:00
|
|
|
wxString msg = wxString::Format( _( "malformed URL:\n\"%s\"" ), GetChars( m_repoURL ) );
|
2015-01-15 20:01:53 +00:00
|
|
|
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 );
|
2015-08-20 07:14:44 +00:00
|
|
|
wxString urlPrefix = repo.GetScheme() + wxT( "://" ) + repo.GetServer() + wxT( "/" );
|
2015-01-15 20:01:53 +00:00
|
|
|
|
|
|
|
wxString errorMsg;
|
|
|
|
const char sep = ','; // Separator fields, in json returned file
|
|
|
|
wxString tmp;
|
|
|
|
int items_count_per_page = 0;
|
2015-08-20 07:14:44 +00:00
|
|
|
std::string& json_image = GetBuffer();
|
2015-01-15 20:01:53 +00:00
|
|
|
|
|
|
|
while( 1 )
|
|
|
|
{
|
2015-12-21 20:30:33 +00:00
|
|
|
bool success = remoteGetJSON( fullURLCommand, &errorMsg );
|
2015-01-15 20:01:53 +00:00
|
|
|
|
|
|
|
if( !success )
|
|
|
|
{
|
|
|
|
wxMessageBox( errorMsg );
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2015-08-20 07:14:44 +00:00
|
|
|
|
|
|
|
for( unsigned ii = 0; ii < json_image.size(); ii++ )
|
2015-01-15 20:01:53 +00:00
|
|
|
{
|
2015-08-20 07:14:44 +00:00
|
|
|
if( json_image[ii] == sep || ii == json_image.size() - 1 )
|
2015-01-15 20:01:53 +00:00
|
|
|
{
|
|
|
|
if( tmp.StartsWith( wxT( "\"full_name\"" ) ) )
|
|
|
|
{
|
|
|
|
#define QUOTE '\"'
|
|
|
|
// Remove useless quotes:
|
|
|
|
if( tmp[tmp.Length() - 1] == QUOTE )
|
|
|
|
tmp.RemoveLast();
|
|
|
|
|
2015-08-20 07:14:44 +00:00
|
|
|
if( tmp.EndsWith( m_libs_ext ) )
|
2015-01-15 20:01:53 +00:00
|
|
|
{
|
|
|
|
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
|
2015-08-20 07:14:44 +00:00
|
|
|
tmp << json_image[ii];
|
2015-01-15 20:01:53 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if( items_count_per_page >= itemCountMax )
|
|
|
|
{
|
|
|
|
page++;
|
|
|
|
repoURL2listURL( m_repoURL, &fullURLCommand, itemCountMax, page );
|
|
|
|
items_count_per_page = 0;
|
2015-08-20 07:14:44 +00:00
|
|
|
ClearBuffer();
|
2015-01-15 20:01:53 +00:00
|
|
|
}
|
|
|
|
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() )
|
|
|
|
{
|
2016-07-20 08:24:24 +00:00
|
|
|
// 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" ) );
|
2015-01-15 20:01:53 +00:00
|
|
|
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;
|
|
|
|
}
|
2015-12-21 20:30:33 +00:00
|
|
|
|
|
|
|
|
|
|
|
bool GITHUB_GETLIBLIST::remoteGetJSON( const std::string& aFullURLCommand, wxString* aMsgError )
|
|
|
|
{
|
|
|
|
KICAD_CURL_EASY kcurl;
|
2015-12-22 14:19:00 +00:00
|
|
|
|
2015-12-21 20:30:33 +00:00
|
|
|
wxLogDebug( wxT( "Attempting to download: " ) + aFullURLCommand );
|
|
|
|
|
2016-01-10 21:44:37 +00:00
|
|
|
kcurl.SetURL( aFullURLCommand );
|
|
|
|
kcurl.SetUserAgent( "http://kicad-pcb.org" );
|
|
|
|
kcurl.SetHeader( "Accept", m_option_string );
|
|
|
|
kcurl.SetFollowRedirects( true );
|
2015-12-21 20:30:33 +00:00
|
|
|
|
|
|
|
try
|
|
|
|
{
|
|
|
|
kcurl.Perform();
|
2016-01-10 21:44:37 +00:00
|
|
|
m_image = kcurl.GetBuffer();
|
2015-12-21 20:30:33 +00:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
catch( const IO_ERROR& ioe )
|
|
|
|
{
|
|
|
|
if( aMsgError )
|
|
|
|
{
|
2017-12-15 11:37:46 +00:00
|
|
|
UTF8 fmt( _( "Error fetching JSON data from URL \"%s\".\nReason: \"%s\"" ) );
|
2016-01-10 21:44:37 +00:00
|
|
|
|
|
|
|
std::string msg = StrPrintf( fmt.c_str(),
|
2015-12-21 20:30:33 +00:00
|
|
|
aFullURLCommand.c_str(),
|
2016-09-14 22:36:45 +00:00
|
|
|
TO_UTF8( ioe.What() ) );
|
2015-12-21 20:30:33 +00:00
|
|
|
|
|
|
|
*aMsgError = FROM_UTF8( msg.c_str() );
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
2016-01-10 21:44:37 +00:00
|
|
|
}
|