コード例 #1
0
ファイル: fe_xml.cpp プロジェクト: omegaman1/attract
void FeMessXMLParser::end_element( const char *element )
{
	if ( strcmp( element, "software" ) == 0 )
	{
		if ( m_keep_rom )
		{
			set_info_values( *m_itr );
		}
		else
		{
			// otherwise try matching based on description
			for ( m_itr=m_ctx.romlist.begin(); m_itr!=m_ctx.romlist.end(); ++m_itr )
			{
				if ( m_description.compare(
							(*m_itr).get_info( FeRomInfo::Romname ) ) == 0 )
				{
					set_info_values( *m_itr );
				}
				else if ( (*m_itr).get_info( FeRomInfo::AltRomname ).empty() )
				{
					// Try using a "fuzzy" match (ignores brackets).
					//
					const std::string &temp = (*m_itr).get_info( FeRomInfo::BuildScratchPad );
					if ( temp.compare( m_fuzzydesc ) == 0 )
					{
						set_info_values( *m_itr );
					}
				}
			}
		}
		clear_parse_state();
	}
	else if ( m_element_open )
	{
		if ( strcmp( element, "description" ) == 0 )
		{
			m_description = m_current_data;
			m_fuzzydesc = get_fuzzy( m_current_data );
		}
		else if ( strcmp( element, "year" ) == 0 )
			m_year = m_current_data;
		else if ( strcmp( element, "publisher" ) == 0 )
			m_man = m_current_data;

		m_current_data.clear();
		m_element_open=false;
	}
}
コード例 #2
0
ファイル: fe_xml.cpp プロジェクト: omegaman1/attract
void FeGameDBParser::end_element( const char *element )
{
	if ( strcmp( element, "Similar" ) == 0 )
	{
		m_ignore=false;
		return;
	}
	if ( m_ignore )
		return;

	if ( m_element_open )
	{
		if ( strcmp( element, "GameTitle" ) == 0 )
			m_work.set_info( FeRomInfo::Title, m_current_data );
		else if ( strcmp( element, "title" ) == 0 )
		{
			if ( m_work.get_info( FeRomInfo::AltTitle ).empty() )
				m_work.set_info( FeRomInfo::AltTitle, m_current_data );
		}
		else if ( strcmp( element, "ReleaseDate" ) == 0 )
		{
			size_t cut = m_current_data.find_last_of( "/" );

			if ( cut != std::string::npos )
				m_work.set_info( FeRomInfo::Year, m_current_data.substr( cut+1 ) );
			else
				m_work.set_info( FeRomInfo::Year, m_current_data );
		}
		else if ( strcmp( element, "genre" ) == 0 )
		{
			std::string cat = m_work.get_info( FeRomInfo::Category );
			if ( cat.size() == 0 )
				cat = m_current_data;
			else
			{
				cat += " / ";
				cat += m_current_data;
			}
			m_work.set_info( FeRomInfo::Category, cat );
		}
		else if ( strcmp( element, "Players" ) == 0 )
			m_work.set_info( FeRomInfo::Players, m_current_data );
		else if ( strcmp( element, "Publisher" ) == 0 )
			m_work.set_info( FeRomInfo::Manufacturer, m_current_data );
		else if ( strcmp( element, "Platform" ) == 0 )
			m_work_platform = m_current_data;

		else if ( m_art )
		{
			if ( strcmp( element, "baseImgUrl" ) == 0 )
				m_art->base = m_current_data;
			else if ( strcmp( element, "banner" ) == 0 )
				m_work_art.marquee = m_current_data;
			else if ( strcmp( element, "clearlogo" ) == 0 )
				m_work_art.wheel = m_current_data;
			else if ( strcmp( element, "original" ) == 0 )
			{
				if ( m_fanart )
				{
					m_work_art.fanart.push_back( m_current_data );
					m_fanart = false;
				}
				else
				{
					if ( m_work_art.snap.empty() )
						m_work_art.snap = m_current_data;

					m_screenshot=false;
				}
			}
			else if ( strcmp( element, "boxart" ) == 0 )
				m_work_art.flyer = m_current_data;
		}

		m_element_open=false;
		m_current_data.clear();
	}

	if ( strcmp( element, "Game" ) == 0 )
	{
		std::string title_str = get_fuzzy( m_rom.get_info( FeRomInfo::Title ) );
		std::string work_title = get_fuzzy( m_work.get_info(FeRomInfo::Title ) );

		bool match_plat=false;
		for ( std::vector<std::string>::iterator itr=m_system_list.begin(); itr!=m_system_list.end(); ++itr )
		{
			if ( m_work_platform.compare( *itr ) == 0 )
			{
				match_plat=true;
				break;
			}
		}

		if ( work_title.compare( title_str ) == 0 )
		{
			if ( match_plat )
			{
				m_work.set_info( FeRomInfo::Emulator, m_rom.get_info( FeRomInfo::Emulator ) );
				m_work.set_info( FeRomInfo::Romname, m_rom.get_info( FeRomInfo::Romname ) );
				m_rom = m_work;

				if ( m_art )
				{
					m_art->snap = m_work_art.snap;
					m_art->marquee = m_work_art.marquee;
					m_art->flyer = m_work_art.flyer;
					m_art->fanart = m_work_art.fanart;

					if ( !m_work_art.wheel.empty() )
						m_art->wheel = m_work_art.wheel;
				}
			}
			else if ( m_art && !m_work_art.wheel.empty() && m_art->wheel.empty() )
				m_art->wheel = m_work_art.wheel;
		}
		else
		{
			std::string work_alt = get_fuzzy( m_work.get_info(FeRomInfo::AltTitle ) );
			bool match_alt = ( work_alt.compare( title_str ) == 0 );

			if ( match_alt && !m_work_art.wheel.empty() && m_art->wheel.empty() )
				m_art->wheel = m_work_art.wheel;

			if ( match_plat && match_alt )
			{
				if ( !m_work_art.flyer.empty() && m_art->flyer.empty() )
					m_art->flyer = m_work_art.flyer;

				if ( !m_work_art.marquee.empty() && m_art->marquee.empty() )
					m_art->marquee = m_work_art.marquee;

				if ( !m_work_art.snap.empty() && m_art->snap.empty() )
					m_art->snap = m_work_art.snap;
			}
		}
	}
}
コード例 #3
0
ファイル: fe_xml.cpp プロジェクト: omegaman1/attract
bool FeMessXMLParser::parse( const std::string &prog,
		const std::vector < std::string > &system_names )
{
	// First get our machine -listxml settings
	//
	std::string system_name;
	FeRomInfoListType::iterator itr;

	for ( std::vector<std::string>::const_iterator its=system_names.begin(); its!=system_names.end(); ++its )
	{
		FeRomInfoListType temp_list;
		temp_list.push_back( FeRomInfo( *its ) );

		FeEmulatorInfo ignored;
		FeImporterContext temp( ignored, temp_list );
		FeMameXMLParser listxml( temp );

		if (( listxml.parse( prog ) )
				&& ( !temp_list.empty() ))
		{
			const FeRomInfo &ri = temp_list.front();
			for ( itr=m_ctx.romlist.begin(); itr!=m_ctx.romlist.end(); ++itr )
			{
				(*itr).set_info( FeRomInfo::Players, ri.get_info( FeRomInfo::Players ));
				(*itr).set_info( FeRomInfo::Rotation, ri.get_info( FeRomInfo::Rotation ));
				(*itr).set_info( FeRomInfo::Control, ri.get_info( FeRomInfo::Control ));
				(*itr).set_info( FeRomInfo::Status, ri.get_info( FeRomInfo::Status ));
				(*itr).set_info( FeRomInfo::DisplayCount, ri.get_info( FeRomInfo::DisplayCount ));
				(*itr).set_info( FeRomInfo::DisplayType, ri.get_info( FeRomInfo::DisplayType ));

				// A bit of a hack here: the Category field gets repurposed for this stage of a MESS
				// import...We temporarily store a "fuzzy" match romname
				//
				(*itr).set_info( FeRomInfo::BuildScratchPad,
							get_fuzzy( (*itr).get_info( FeRomInfo::Romname ) ) );
			}
			system_name=(*its);
			break;
		}
	}

	if ( system_name.empty() )
	{
		std::cerr << " * Error: No system identifier found that is recognized by MESS -listxml" << std::endl;
		return false;
	}

	std::cout << " - Obtaining -listsoftware info [" << system_name << "]" << std::endl;

	// Now get the individual game -listsoftware settings
	//
	int retval=parse_internal( prog, system_name + " -listsoftware" );

	if ( !retval )
	{
		std::cout << " * Error: No XML output found, command: " << prog << " "
					<< system_name + " -listsoftware" << std::endl;
	}

	// We're done with our "fuzzy" matching, so clear where we were storing them
	//
	for ( itr=m_ctx.romlist.begin(); itr!=m_ctx.romlist.end(); ++itr )
		(*itr).set_info( FeRomInfo::BuildScratchPad, "" );

	return retval;
}
コード例 #4
0
ファイル: scraper_net.cpp プロジェクト: Cucurbitace/attract
bool FeSettings::thegamesdb_scraper( FeImporterContext &c )
{
#ifndef NO_NET
	const char *HOSTNAME = "http://thegamesdb.net";
	const char *PLATFORM_LIST_REQ = "api/GetPlatformsList.php";
	const char *PLAT_REQ = "api/GetPlatform.php?id=$1";
	const char *GAME_REQ = "api/GetGame.php?name=$1";
	const char *FLYER = "flyer/";
	const char *WHEEL = "wheel/";
	const char *MARQUEE = "marquee/";
	const char *SNAP = "snap/";
	const char *FANART = "fanart/";

	//
	// Get a list of valid platforms
	//
	FeNetQueue q;
	q.add_buffer_task( HOSTNAME, PLATFORM_LIST_REQ, 0 );
	sf::Http::Response::Status status;
	std::string err_req;

	q.do_next_task( status, err_req );

	if ( status != sf::Http::Response::Ok )
	{
		get_resource( "Error getting platform list from thegamesdb.net.  Code: $1",
			as_str( status ), c.user_message );

		std::cerr << " ! " << c.user_message << " (" << err_req << ")" << std::endl;
		return true;
	}

	int temp;
	std::string body;
	q.pop_completed_task( temp, body );

	FeGameDBPlatformListParser gdbplp;
	gdbplp.parse( body );

	std::vector<std::string> system_list;
	std::vector<int> system_ids;

	const std::vector<std::string> &sl_temp = c.emulator.get_systems();
	for ( std::vector<std::string>::const_iterator itr = sl_temp.begin();
			itr != sl_temp.end(); ++itr )
	{
		std::string comp_fuzz = get_fuzzy( *itr );

		for ( size_t i=0; i<gdbplp.m_names.size(); i++ )
		{
			ASSERT( gdbplp.m_names.size() == gdbplp.m_ids.size() );

			std::string &n = gdbplp.m_names[i];
			int id = ( i < gdbplp.m_ids.size() ) ? i : 0;

			if ( comp_fuzz.compare( get_fuzzy( n ) ) == 0 )
			{
				system_list.push_back( n );
				system_ids.push_back( id );
				break;
			}
			else
			{
				size_t pos = n.find_first_of( "(" );

				if (( pos != std::string::npos ) &&
					(( comp_fuzz.compare( get_fuzzy( n.substr(0,pos-1))) == 0 )
					|| ( comp_fuzz.compare(get_fuzzy( n.substr(pos+1,n.size()-pos-1 ))) == 0 )))
				{
					system_list.push_back( n );
					system_ids.push_back( id );
					break;
				}
			}
		}
	}

	if ( system_list.size() < 1 )
	{
		// Correct if we can based on the configured info source,
		// otherwise we error out
		switch( c.emulator.get_info_source() )
		{
		case FeEmulatorInfo::Listxml:
			system_list.push_back( "Arcade" ); break;
		case FeEmulatorInfo::Steam:
			system_list.push_back( "PC" ); break;
		default:
			get_resource( "Error: None of the configured system identifier(s) are recognized by thegamesdb.net.",
								c.user_message );

			std::cerr << " ! " << c.user_message << std::endl;
			return true;
		}
	}

	std::string emu_name = c.emulator.get_info( FeEmulatorInfo::Name );
	std::string base_path = get_config_dir() + FE_SCRAPER_SUBDIR;
	base_path += emu_name + "/";

	if ( c.scrape_art )
	{
		//
		// Get emulator-specific images
		//
		for ( std::vector<int>::iterator iti=system_ids.begin();
				iti != system_ids.end(); ++iti )
		{
			std::string plat_string = PLAT_REQ;
			perform_substitution( plat_string, "$1", as_str( *iti ) );

			q.add_buffer_task( HOSTNAME, plat_string, 0 );
			q.do_next_task( status, err_req );
			if ( status != sf::Http::Response::Ok )
			{
				std::cout << " * Unable to get platform information. Status code: "
					<< status << " (" << err_req << ")" << std::endl;
				continue;
			}

			body.clear();
			q.pop_completed_task( temp, body );

			FeGameDBArt my_art;
			FeGameDBPlatformParser gdbpp( my_art );
			gdbpp.parse( body );

			std::string hostn = HOSTNAME;
			std::string base_req = "banners/";
			get_url_components( my_art.base,
				hostn, base_req );

			std::string path = base_path + FLYER;
			if ( m_scrape_flyers && ( !my_art.flyer.empty() )
				&& ( !art_exists( path, emu_name ) ))
			{
				confirm_directory( base_path, FLYER );
				q.add_file_task( hostn, base_req + my_art.flyer,
					path + emu_name );
			}

			path = base_path + WHEEL;
			if ( m_scrape_wheels && ( !my_art.wheel.empty() )
				&& ( !art_exists( path, emu_name ) ))
			{
				confirm_directory( base_path, WHEEL );
				q.add_file_task( hostn, base_req + my_art.wheel,
					path + emu_name );
			}

			path = base_path + MARQUEE;
			if ( m_scrape_marquees && ( !my_art.marquee.empty() )
				&& ( !art_exists( path, emu_name ) ))
			{
				confirm_directory( base_path, MARQUEE );
				q.add_file_task( hostn, base_req + my_art.marquee,
					path + emu_name );
			}

			if ( m_scrape_fanart && !my_art.fanart.empty() )
			{
				std::string path_base = base_path + FANART + emu_name + "/";
				confirm_directory( base_path, "" );
				confirm_directory( base_path + FANART, emu_name );

				for ( std::vector<std::string>::iterator itr = my_art.fanart.begin();
							itr != my_art.fanart.end(); ++itr )
				{
					size_t start_pos = (*itr).find_last_of( "/\\" );
					size_t end_pos = (*itr).find_last_of( '.' );

					if (( start_pos != std::string::npos )
						&& ( !file_exists( path_base + (*itr).substr( start_pos+1 ) ) ))
					{
						if (( end_pos != std::string::npos ) && ( end_pos > start_pos ))
						{
							q.add_file_task( hostn,
								base_req + (*itr),
								path_base + (*itr).substr( start_pos+1,
											end_pos-start_pos-1 ) );
						}
					}
				}
			}
		}
	}

	bool prefer_alt_filename = c.emulator.is_mess();

	//
	// Build a map for looking up parents
	//
	ParentMapType parent_map;
	build_parent_map( parent_map, c.romlist, prefer_alt_filename );

	//
	// Build a worklist of the roms where we need to lookup
	//
	std::vector<FeRomInfo *> worklist;
	worklist.reserve( c.romlist.size() );
	for ( FeRomInfoListType::iterator itr=c.romlist.begin(); itr!=c.romlist.end(); ++itr )
	{
		(*itr).set_info( FeRomInfo::Emulator, emu_name );

		// Don't scrape for a clone if its parent has the same name
		//
		if ( has_same_name_as_parent( *itr, parent_map ) )
			continue;

		if ( !c.scrape_art || m_scrape_fanart
				|| ( m_scrape_flyers && (!has_artwork( *itr, "flyer" ) ) )
				|| ( m_scrape_wheels && (!has_artwork( *itr, "wheel" ) ) )
				|| ( m_scrape_snaps && (!has_image_artwork( *itr, "snap" ) ) )
				|| ( m_scrape_marquees && (!has_artwork( *itr, "marquee" ) ) ) )
			worklist.push_back( &(*itr) );
	}

	const int NUM_ARTS=5; // the number of scrape-able artwork types
	int done_count( 0 );

	//
	// Set up our initial queue of network tasks
	//
	for ( unsigned int i=0; i<worklist.size(); i++ )
	{
		std::string req_string = GAME_REQ;

		std::string game = url_escape(
				name_with_brackets_stripped( worklist[i]->get_info( FeRomInfo::Title ) ) );

		perform_substitution( req_string, "$1", game );

		//
		// If we don't need to scrape a wheel artwork, then add the specific platform to our request
		// If we are scraping a wheel, we want to be able to grab them where the game name (but
		// not the system) matches, so we don't limit ourselves by system...
		//
		if (( system_list.size() == 1 )
			&& ( !c.scrape_art || !m_scrape_wheels || has_artwork( *(worklist[i]), "wheel" ) ))
		{
			req_string += "&platform=";
			req_string += url_escape( system_list.front() );
		}

		q.add_buffer_task( HOSTNAME, req_string, i );
	}

	//
	// Create worker threads to process the queue, adding new tasks to download
	// artwork files where appropriate
	//
	FeNetWorker worker1( q ), worker2( q ), worker3( q ), worker4( q );
	std::string aux;

	//
	// Process the output queue from our worker threads
	//
	while ( !( q.input_done() && q.output_done() ) )
	{
		int id;
		std::string result;

		if ( q.pop_completed_task( id, result ) )
		{
			if ( id < 0 )
			{
				if (( id == FeNetTask::FileTask ) || ( id == FeNetTask::SpecialFileTask ))
				{
					std::cout << " + Downloaded: " << result << std::endl;
					c.download_count++;

					// find second last forward slash in filename
					// we assume that there will always be at least two
					size_t pos = result.find_last_of( "\\/" );
					if ( pos != std::string::npos )
					{
						pos = result.find_last_of( "\\/", pos-1 );
						if ( pos != std::string::npos )
							aux = result.substr( pos );
					}
				}

				if ( id == FeNetTask::FileTask ) // we don't increment if id = FeNetTask::SpecialFileTask
					done_count++;
			}
			else
			{
				FeGameDBArt my_art;
				FeGameDBParser gdbp( system_list, *(worklist[id]), ( c.scrape_art ? &my_art : NULL ) );
				gdbp.parse( result );

				if ( c.scrape_art && !my_art.base.empty() )
				{
					std::string hostn = HOSTNAME;
					std::string base_req = "banners/";
					get_url_components( my_art.base,
						hostn, base_req );

					const FeRomInfo &rom = *(worklist[id]);

					if ( m_scrape_flyers && ( !my_art.flyer.empty() ) && (!has_artwork( rom, "flyer" )) )
					{
						std::string fname = base_path + FLYER;

						const std::string &altname = rom.get_info( FeRomInfo::AltRomname );
						if ( prefer_alt_filename && !altname.empty() )
							fname += rom.get_info( FeRomInfo::AltRomname );
						else
							fname += rom.get_info( FeRomInfo::Romname );

						confirm_directory( base_path, FLYER );
						q.add_file_task( hostn, base_req + my_art.flyer, fname );
					}
					else
						done_count++;

					if ( m_scrape_wheels && ( !my_art.wheel.empty() ) && (!has_artwork( rom, "wheel" )) )
					{
						std::string fname = base_path + WHEEL;

						const std::string &altname = rom.get_info( FeRomInfo::AltRomname );
						if ( prefer_alt_filename && !altname.empty() )
							fname += rom.get_info( FeRomInfo::AltRomname );
						else
							fname += rom.get_info( FeRomInfo::Romname );

						confirm_directory( base_path, WHEEL );
						q.add_file_task( hostn, base_req + my_art.wheel, fname );
					}
					else
						done_count++;

					if ( m_scrape_marquees && (!my_art.marquee.empty() ) && (!has_artwork( rom, "marquee" )) )
					{
						std::string fname = base_path + MARQUEE;

						const std::string &altname = rom.get_info( FeRomInfo::AltRomname );
						if ( prefer_alt_filename && !altname.empty() )
							fname += rom.get_info( FeRomInfo::AltRomname );
						else
							fname += rom.get_info( FeRomInfo::Romname );

						confirm_directory( base_path, MARQUEE );
						q.add_file_task( hostn, base_req + my_art.marquee, fname );
					}
					else
						done_count++;

					if ( m_scrape_snaps && (!my_art.snap.empty() ) && (!has_image_artwork( rom, "snap" )) )
					{
						std::string fname = base_path + SNAP;

						const std::string &altname = rom.get_info( FeRomInfo::AltRomname );
						if ( prefer_alt_filename && !altname.empty() )
							fname += rom.get_info( FeRomInfo::AltRomname );
						else
							fname += rom.get_info( FeRomInfo::Romname );

						confirm_directory( base_path, SNAP );
						q.add_file_task( hostn, base_req + my_art.snap, fname );
					}
					else
						done_count++;

					if ( m_scrape_fanart && !my_art.fanart.empty() )
					{
						std::string fname_base = base_path + FANART;

						confirm_directory( base_path, "" );

						const std::string &altname = rom.get_info( FeRomInfo::AltRomname );
						if ( prefer_alt_filename && !altname.empty() )
						{
							fname_base += rom.get_info( FeRomInfo::AltRomname );
							confirm_directory( base_path + FANART,
								rom.get_info( FeRomInfo::AltRomname ) );
						}
						else
						{
							fname_base += rom.get_info( FeRomInfo::Romname );
							confirm_directory( base_path + FANART,
								rom.get_info( FeRomInfo::Romname ) );
						}

						fname_base += "/";

						bool done_first=false; // we only count the first fanart against our percentage completed...

						for ( std::vector<std::string>::iterator itr = my_art.fanart.begin();
								itr != my_art.fanart.end(); ++itr )
						{
							size_t start_pos = (*itr).find_last_of( "/\\" );
							size_t end_pos = (*itr).find_last_of( '.' );

							if (( start_pos != std::string::npos )
								&& ( !file_exists( fname_base + (*itr).substr( start_pos+1 ) ) ))
							{
								if (( end_pos != std::string::npos ) && ( end_pos > start_pos ))
								{
									q.add_file_task( hostn,
												base_req + (*itr),
												fname_base + (*itr).substr( start_pos+1, end_pos-start_pos-1 ),
												done_first );
									done_first=true;
								}
							}
						}
					}
					else
						done_count++;
				}
				else
				{
					aux = (worklist[id])->get_info( FeRomInfo::Title );
					done_count+=NUM_ARTS;
				}
			}

			if (( c.uiupdate ) && !worklist.empty() )
			{
				int p = c.progress_past + done_count * c.progress_range / ( NUM_ARTS * worklist.size() );
				if ( c.uiupdate( c.uiupdatedata, p, aux ) == false )
					return false;
			}
		}
		else if ( q.output_done() )
		{
			sf::Http::Response::Status status;
			std::string err_req;
			q.do_next_task( status, err_req );
			if ( status != sf::Http::Response::Ok )
			{
				std::cout << " * Error processing request. Status code: "
					<< status << " (" << err_req << ")" << std::endl;
			}
		}
		else
			sf::sleep( sf::milliseconds( 10 ) );
	}
#endif
	return true;
}