/* * [ImportManufacturer.java] * * Summary: Base class to import motherboard data from various manufacturer websites. * * Copyright: (c) 2011-2017 Roedy Green, Canadian Mind Products, http://mindprod.com * * Licence: This software may be copied and used freely for any purpose but military. * http://mindprod.com/contact/nonmil.html * * Requires: JDK 1.7+ * * Created with: JetBrains IntelliJ IDEA IDE http://www.jetbrains.com/idea/ * * Version History: * 1.0 2011-02-21 initial version */ package com.mindprod.mother; import com.mindprod.common17.BigDate; import com.mindprod.common17.ST; import com.mindprod.fastcat.FastCat; import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.SQLException; import java.text.DecimalFormat; import java.util.regex.Matcher; import java.util.regex.Pattern; import static java.lang.System.*; /** * Base class to import motherboard data from various manufacturer websites. * * @author Roedy Green, Canadian Mind Products * @version 1.0 2011-02-21 initial version * @since 2011-02-21 */ class ImportManufacturer { private static final boolean DEBUGGING = false; /** * which database */ private static final String DATA_BASE_NAME = "mother"; /** * class name of the JDBC driver * You must install the postgresql-9.0-801.jdbc4.jar containing the driver in the ext dir. * Download it separately from http://jdbc.postgresql.org */ private static final String DRIVER_CLASS_NAME = "org.postgresql.Driver"; /** * access PASSWORD */ private static final String PASSWORD = System.getenv( "pgpw" ); /** * login name of user */ private static final String USERNAME = "postgres"; /** * one decimal place */ private static final DecimalFormat DF1 = new DecimalFormat( "##0.0" ); /** * The connection. Handle to the database */ static Connection conn; /** * 3-letter currency code CAD USD ... */ static String currency; /** * count of incomplete motherboards */ static int incomplete = 0; /** * when info about this mb was last updated */ static BigDate lastUpdated; /** * who made the motherboard */ static Manufacturer manufacturer; /** * number that lets us directly find the motherboard on the manufacturers website */ static String manufacturerPartNo; /** * max gigs of RAM */ static int maxGig; /** * model of the motherboard */ static String model; /** * price in local currency excluding taxes */ static double price; /** * ram speed */ static int ramSpeedMHz; /** * current revision of the motherboard */ static String revision; /** * who sells this mb */ static Seller seller; /* seller's part no, e.g. for Amazon the ASIN */ static String sellerPartNo; /** * type of socket the CPU takes */ static SocketType socket; /** * power MB consumes in watts, exclusive of CPU and RAM. */ static int watts; /** * how many channels of sound. l/r count separately mic, line in line out do not count. */ private static int audioChannels; /** * form factor */ private static FormFactor formFactor; /** * height of motherboard in cm */ private static double heightInCm; /** * how many parallel IDE ports for floppies and old-style hard disks and CDs */ private static int ide; /** * memory type DDR2 DDR3 */ private static MemoryType memoryType; /** * how many 3Gb/s SATA2 ports */ private static int sata2; /** * how many 6Gb/s SATA3 ports */ private static int sata3; private static PreparedStatement updater; /** * total USB-2 ports */ private static int usb2; /** * count of USB-2 ports on accessible inside the case, needing headers. */ private static int usb2Internal; /** * count of USB-2 ports on the rear panel */ private static int usb2Rear; /** * total USB-3 ports */ private static int usb3; /** * count of USB-3 ports on accessible inside the case, needing headers. */ private static int usb3Internal; /** * count of USB-3 ports on the rear panel */ private static int usb3Rear; /** * manufacturer of onboard video */ private static Video video; /** * width of motherboard in cm */ private static double widthInCm; /** * clear mb specs */ static void clearMBSpecs() { audioChannels = 0; formFactor = FormFactor.UNKNOWN; widthInCm = 0; heightInCm = 0; ide = 0; memoryType = MemoryType.UNKNOWN; maxGig = 0; ramSpeedMHz = 0; sata2 = 0; sata3 = 0; socket = SocketType.UNKNOWN; usb2 = 0; usb2Internal = 0; usb2Rear = 0; usb3 = 0; usb3Internal = 0; usb3Rear = 0; video = Video.UNKNOWN; watts = 0; } /** * close database connection */ static void closeDatabase() throws SQLException { conn.close(); } /** * connect to the database */ static Connection connect() throws SQLException { try { Class.forName( DRIVER_CLASS_NAME ); // just load class. Don't retain handle to driver. } catch ( Exception e ) { err.println( "can't load SQL Server driver: " + e.getMessage() ); } return DriverManager.getConnection( "jdbc:postgresql:" + DATA_BASE_NAME, USERNAME, PASSWORD ); } /** * dump out values of field we just extracted */ static void dumpExtracts() { final FastCat sb = new FastCat( 45 ); sb.append( manufacturer ); sb.append( ", " ); sb.append( model ); sb.append( ", " ); sb.append( manufacturerPartNo ); sb.append( ", " ); sb.append( audioChannels ); sb.append( " audio channels, " ); sb.append( formFactor ); sb.append( ", " ); sb.append( DF1.format( widthInCm ) ); sb.append( " x " ); sb.append( DF1.format( heightInCm ) ); sb.append( ", " ); sb.append( memoryType ); sb.append( ", " ); sb.append( maxGig ); sb.append( "GB, " ); sb.append( ramSpeedMHz ); sb.append( "MHz, " ); sb.append( socket ); sb.append( ", " ); sb.append( ide ); sb.append( " ide, sata[" ); sb.append( sata2 ); sb.append( "," ); sb.append( sata3 ); sb.append( "], usb[" ); sb.append( usb2 ); sb.append( "," ); sb.append( usb2Rear ); sb.append( "," ); sb.append( usb2Internal ); sb.append( "/" ); sb.append( usb3 ); sb.append( "," ); sb.append( usb3Rear ); sb.append( "," ); sb.append( usb3Internal ); sb.append( "], " ); sb.append( video ); sb.append( ", " ); sb.append( watts ); sb.append( " watts" ); if ( audioChannels == 0 || maxGig == 0 || ramSpeedMHz == 0 || usb2 + usb3 == 0 || ide + sata2 + sata3 == 0 || formFactor == FormFactor.UNKNOWN || memoryType == MemoryType.UNKNOWN || socket == SocketType.UNKNOWN || video == Video.UNKNOWN ) { incomplete++; sb.append( ", I N C O M P L E T E" ); } out.println( sb.toString() ); } /** * extract audioChannels from motherboard page * * @param mbData motherboard page data from website. */ static void extractAudioChannels( String mbData, Pattern[] audioChannelsFinders ) { for ( Pattern p : audioChannelsFinders ) { final Matcher m = p.matcher( mbData ); while ( m.find() ) { final String audio = m.group( 1 ); if ( audio.equals( "10" ) || audio.equals( "8+2" ) || audio.equals( "7.1+2" ) ) { audioChannels = 10; return; } else if ( audio.equals( "8" ) || audio.equals( "7.1" ) || audio.equals( "7+1" ) ) { audioChannels = 8; return; } else if ( audio.equals( "6" ) || audio.equals( "5.1" ) ) { audioChannels = 6; return; } else if ( audio.equals( "4" ) ) { audioChannels = 4; return; } else if ( audio.equals( "2" ) ) { audioChannels = 2; return; } } } } /** * extract information about the form factor * * @param mbData motherboard page data from website. */ static void extractFormFactor( String mbData, Pattern formFactorFinder, double scale ) { final Matcher m = formFactorFinder.matcher( mbData ); if ( m.find() ) { try { formFactor = FormFactor.valueOfAlias( ST.chopTrailingString( m.group( 1 ).toUpperCase(), "FORM FACTOR" ).trim() ); widthInCm = Double.parseDouble( m.group( 2 ) ) * scale; heightInCm = Double.parseDouble( m.group( 3 ) ) * scale; } catch ( NumberFormatException e ) { err.println( "malformed widthInCm [" + m.group( 2 ) + "] and heightInCm [" + m.group( 3 ) + "] for " + model ); } } } /** * extract IDE from motherboard page * * @param mbData motherboard page data from ECS website. */ static void extractIde( String mbData, Pattern[] ideFinders ) { for ( Pattern p : ideFinders ) { final Matcher m = p.matcher( mbData ); while ( m.find() ) { final int count = Integer.parseInt( m.group( 1 ) ); if ( count > ide ) { ide = count; } } } } /** * extract maxGig from motherboard page * * @param mbData motherboard page data from ECS website. */ static void extractMaxGig( String mbData, Pattern MaxGigFinder ) { final Matcher m = MaxGigFinder.matcher( mbData ); if ( m.find() ) { maxGig = Integer.parseInt( ST.chopTrailingString( m.group( 1 ), ".0" ) ); } } /** * extract memory type from motherboard page * * @param mbData motherboard page data from website. */ static void extractMemoryType( String mbData, Pattern memoryTypeFinder ) { final Matcher m = memoryTypeFinder.matcher( mbData ); if ( m.find() ) { memoryType = MemoryType.valueOfAlias( m.group( 1 ).trim() ); } } /** * extract maxGig from motherboard page * * @param rawMDSpecs motherboard page data from website. */ static void extractRamSpeedMHz( String rawMDSpecs, Pattern ramSpeedMHzFinder, Pattern ramSpeedMhzSplitter ) { final Matcher m = ramSpeedMHzFinder.matcher( rawMDSpecs ); int bestSpeed = 0; while ( m.find() ) { final String allSpeeds = m.group( 1 ); if ( DEBUGGING ) { out.println( "allspeeds: " + allSpeeds ); } final String[] speeds = ramSpeedMhzSplitter.split( allSpeeds ); for ( String candidate : speeds ) { candidate = candidate.trim(); if ( candidate.length() == 0 ) { continue; } if ( DEBUGGING ) { out.println( candidate ); } if ( candidate.indexOf( 'N' ) >= 0 || candidate.indexOf( 'O' ) >= 0 || candidate.indexOf( 'X' ) >= 0 ) { continue; } try { int speed = Integer.parseInt( candidate ); if ( speed > bestSpeed ) { bestSpeed = speed; } } catch ( NumberFormatException e ) { err.println( "--" + candidate ); // ignore / (OC) or other junk. } } } ramSpeedMHz = bestSpeed; } /** * extract SATA2 from motherboard page * * @param mbData motherboard page data from ECS website. */ static void extractSata2( String mbData, Pattern[] sata2Finders ) { for ( Pattern p : sata2Finders ) { final Matcher m = p.matcher( mbData ); while ( m.find() ) { final int count = Integer.parseInt( m.group( 1 ) ); if ( count > sata2 ) { sata2 = count; } } } } /** * extract SATA3 from motherboard page * * @param mbData motherboard page data from website. */ static void extractSata3( String mbData, Pattern[] sata3Finders ) { for ( Pattern p : sata3Finders ) { final Matcher m = p.matcher( mbData ); while ( m.find() ) { final int count = Integer.parseInt( m.group( 1 ) ); if ( count > sata3 ) { sata3 = count; } } } } /** * extract maxGig from motherboard page * * @param mbData motherboard page data from ECS website. */ static void extractSocket( String mbData, Pattern[] socketFinders ) { for ( Pattern p : socketFinders ) { final Matcher m = p.matcher( mbData ); while ( m.find() ) { try { socket = SocketType.valueOfAlias( m.group( 1 ) ); return; } catch ( IllegalArgumentException e ) { err.println( e.getMessage() ); // keep going } } } } /** * extract USB from motherboard page * * @param mbData motherboard page data from Gigabyte website. */ static void extractUSB( String mbData, Pattern[] Usb2TotalFinder, Pattern[] Usb2RearFinder, Pattern[] Usb2InternalFinder, Pattern[] Usb3TotalFinder, Pattern[] Usb3RearFinder, Pattern[] Usb3InternalFinder ) { Matcher m; for ( Pattern p : Usb2TotalFinder ) { m = p.matcher( mbData ); if ( m.find() ) { usb2 = Integer.parseInt( m.group( 1 ) ); break; } } for ( Pattern p : Usb2RearFinder ) { m = p.matcher( mbData ); if ( m.find() ) { usb2Rear = Integer.parseInt( m.group( 1 ) ); break; } } for ( Pattern p : Usb2InternalFinder ) { m = p.matcher( mbData ); if ( m.find() ) { usb2Internal = Integer.parseInt( m.group( 1 ) ); break; } } for ( Pattern p : Usb3TotalFinder ) { m = p.matcher( mbData ); if ( m.find() ) { usb3 = Integer.parseInt( m.group( 1 ) ); break; } } for ( Pattern p : Usb3RearFinder ) { m = p.matcher( mbData ); if ( m.find() ) { usb3Rear = Integer.parseInt( m.group( 1 ) ); break; } } for ( Pattern p : Usb3InternalFinder ) { m = p.matcher( mbData ); if ( m.find() ) { usb3Internal = Integer.parseInt( m.group( 1 ) ); break; } } if ( usb2 == 0 ) { usb2 = usb2Rear + usb2Internal; } if ( usb3 == 0 ) { usb3 = usb3Rear + usb3Internal; } if ( usb2Rear == 0 && usb2Internal == 0 ) { usb2Internal = usb2; } if ( usb3Rear == 0 && usb3Internal == 0 ) { usb3Internal = usb3; } if ( usb3 != usb3Rear + usb3Internal ) { err.println( usb3 + " total usb3 ports != " + usb3Rear + " usb3rear + " + usb3Internal + " usb3Internal " + "for " + model ); } if ( usb2 != usb2Rear + usb2Internal ) { if ( usb2 - usb3 == usb2Rear + usb2Internal ) { usb2 -= usb3; } else { err.println( usb2 + " total usb2 ports != " + usb2Rear + " usb2rear + " + usb2Internal + " " + "usb2Internal for " + model ); } } } /** * extract information about integrated video * * @param mbData motherboard page data from website. */ static void extractVideo( String mbData, Pattern[] videoFinders ) { for ( Pattern p : videoFinders ) { final Matcher m = p.matcher( mbData ); while ( m.find() ) { try { video = Video.valueOfAlias( m.group( 1 ) ); } catch ( IllegalArgumentException e ) { err.println( "unknown Video for " + model + " " + m.group( 1 ) ); } } } } /** * extract wattage from motherboard page * * @param mbData motherboard page data from website. */ static void extractWatts( String mbData, Pattern wattsFinder ) { final Matcher m = wattsFinder.matcher( mbData ); if ( m.find() ) { watts = Integer.parseInt( m.group( 1 ) ); } } /** * initialise the database to update fields */ static void initDatabase() throws SQLException { conn = connect(); updater = conn.prepareStatement( "UPDATE mboards " + "SET audioChannels=?, formFactor=?, widthInCm=?, heightInCm=?, ide=?, " + "memoryType=?, maxGig=?, ramSpeedMHz=?, sata2=?, sata3=?, socket=?, " + "usb2=?, usb2Rear=?, usb2Internal=?, usb3=?, usb3Rear=?, usb3Internal=?, " + "video=?, watts=?, lastUpdated=? " + "WHERE manufacturer=? AND model=?;" ); } /** * convert PC1600 to 100 Mhz * * @param pcNumber pc number e.g. 1600 * * @return MHz */ static int pcToMHz( int pcNumber ) { switch ( pcNumber ) { case 1600: return 100; case 2100: return 133; case 2700: return 166; case 3200: return 200; default: return ( pcNumber + 8 ) / 16; } } /** * record what we extracted in the database. * * @throws SQLException */ static void updateMBFields() throws SQLException { // record our findings in SQL updater.setInt( 1, audioChannels ); updater.setInt( 2, formFactor.ordinal() ); updater.setDouble( 3, widthInCm ); updater.setDouble( 4, heightInCm ); updater.setInt( 5, ide ); updater.setInt( 6, memoryType.ordinal() ); updater.setInt( 7, maxGig ); updater.setInt( 8, ramSpeedMHz ); updater.setInt( 9, sata2 ); updater.setInt( 10, sata3 ); updater.setInt( 11, socket.ordinal() ); updater.setInt( 12, usb2 ); updater.setInt( 13, usb2Rear ); updater.setInt( 14, usb2Internal ); updater.setInt( 15, usb3 ); updater.setInt( 16, usb3Rear ); updater.setInt( 17, usb3Internal ); updater.setInt( 18, video.ordinal() ); updater.setInt( 19, watts ); updater.setInt( 20, lastUpdated.ordinal() ); updater.setInt( 21, manufacturer.ordinal() ); updater.setString( 22, model ); updater.executeUpdate(); } /** * extract information about integrated video * * @param mbData motherboard page data from website. * @param videoValidator Pattern to see if there is any sort of video mentioned */ static void validateVideo( String mbData, Pattern videoValidator ) { if ( video == Video.UNKNOWN ) { final Matcher m = videoValidator.matcher( mbData ); if ( m.find() ) { err.println( "missed video for " + model ); } else { video = Video.NONE; } } } }