# R Script to create Grimmest # collection of functions to operate on extracted Grim Dawn records ## ######### ######### ######### # # S( whatever ) returns string : wrap as.character() # S = function( x ) { as.character( x ); } # # endsWIth( stringToSearch, endSearchText ) return boolean : test if string # ends in some text # endsWith = function( s, end.s ) { length( grep( sprintf( "%s$", end.s ), s ) ) > 0; } # # forceSuffix( path, suffix ) return path.suffix : if path already has suffix, # no change, otherwise append suffix to path # forceSuffix = function( path, suffix ) { suffix = gsub( "^[.]", "", suffix ); regexp = sprintf( "[.]%s$", suffix ); sprintf( "%s.%s", gsub( regexp, "", path ), suffix ); } ## ######### ######### ######### # # loadTags( path ) return list of tag=value pairs : uses getPathsOfType and # splitTags to recurively read all text files under path into one list obj # getPathsOfType = function( path, suffix ) { rv = c(); if( file.exists( path ) ) { rv = path; } else if( dir.exists( path ) ) { rv = list.files( path, sprintf( "[.]%s$", suffix ), recursive = TRUE ); rv = sprintf( "%s/%s", path, rv ); } return( rv ); } splitTags = function( line ) { strsplit( line, "=" )[[ 1 ]]; } loadTags = function( path ) { paths = c(); if( length( path ) == 1 ) { paths = getPathsOfType( path, "*.txt" ); } else { for( p in path ) { paths = c( paths, getPathsOfType( p, "*.txt" ) ); } } lines = c(); for( tag.file in paths ) { lines = c( lines, readLines( tag.file, warn=FALSE ) ); } lines = lines[ sapply( lines, nchar ) > 0 ]; lines = lines[ grepl( ".*[=].*", lines ) ]; toks = sapply( lines, splitTags ); rv = lapply( toks, function( x ) { x[ 2 ]; } ); names( rv ) = lapply( toks, function( x ) { x[ 1 ]; } ); return( rv ); } ## ######### ######### ######### # # obj.save() and obj.load() are generics that get use as in examples tags. and # dbrs. save/load. The default path is only fine as long as you do not make # more than one of these, otherwise, use these function and provide unique # path arguments. Otherwise, just use saveRDS amd readRDS, the really do not # need to be wrapped. # obj.save = function( obj, default.path, path = NULL ) { if( is.null( path ) ) { path = default.path; } saveRDS( obj, file=path ); } obj.load = function( default.path, path = NULL ) { if( is.null( path ) ) { path = default.path; } readRDS( path ); } tags.save = function( x, ... ) { obj.save( x, default.path="tags.rds", ... ); } tags.load = function( x, ... ) { obj.load( default.path="tags.rds", ... ); } dbrs.save = function( x, ... ) { obj.save( x, default.path="dbrs.rds", ... ); } dbrs.load = function( x, ... ) { obj.load( default.path="dbrs.rds", ... ); } ## ######### ######### ######### # listRecords() is your entry to getting all the recordNames (paths) # a lot of the rest here should be documented a tad in run.R # listRecords = function( path = "database", recursive = TRUE ) { rv = list.files( path, recursive = recursive ); names( rv ) = rv; return( rv ); } findByRecordName = function( records, name, ignore.case = TRUE ) { records[ grep( name, records, ignore.case = ignore.case ) ]; } splitFields = function( line ) { strsplit( line, "," )[[ 1 ]]; } pasteFields = function( record ) { nFields = length( record ); rv = vector( mode="character", length( nFields ) ); for( i in 1:nFields ) { rv[ i ] = sprintf( "%s", paste( names( record )[ i ], record[ i ], sep="," ) ); } return( rv ); } safeField = function( dbr, field.name ) { if( field.name %in% names( dbr ) ) { dbr[[ field.name ]]; } else { "nada"; } } # # readRecord(s) # readRecord = function( recordName, dir.prefix = "database" ) { rv = list(); path = recordName; if( !is.null( dir.prefix ) ) { path = sprintf( "%s/%s", dir.prefix, recordName ); } if( !file.exists( path ) ) { message( "readRecord: failed on ", recordName, " path = ", path ); rv[[ "error" ]] = "FileNotFound"; } lines = readLines( path ); toks = lapply( lines, splitFields ); if( ( nToks = length( toks ) ) < 0 ) { stop( recordName, " was empty?" ); } rv = lapply( toks, function( x ) { x[ 2:(length(x)) ]; } ); names( rv ) = lapply( toks, function( x ) { x[ 1 ]; } ); return( rv ); } readRecordS = function( records, ... ) { lapply( records, readRecord, ... ); } readRecords = readRecordS; # # writeRecord(s) # writeRecord = function( record, out.prefix = NULL ) { text = pasteFields( record ); if( !is.null( out.prefix ) ) { writeLines( text, out.prefix ); invisible( text ); } else { return( text ); } } writeRecordS = function( records, out.prefix ) { sapply( names( records ), function( recordName, out.dir = out.prefix ) { out.path = sprintf( "%s/%s", out.dir, recordName ); dir.name = dirname( out.path ); if( !dir.exists( dir.name ) ) { dir.create( dir.name, recursive = TRUE ); } writeRecord( records[[ recordName ]], sprintf( "%s/%s", out.dir, recordName ) ); } ); invisible(); } writeRecords = writeRecordS; addField = function( record, fieldName, fieldValue ) { record[[ fieldName ]] = fieldValue; return( record ); } changeField = addField; showFieldValues = function( dbr.set, field.name ) { unlist( lapply( dbr.set, function( x ) { x[ field.name ] } ) ); } showUniqueFieldValues = function( dbr.set, field.name ) { unique( sort( showFieldValues( dbr.set, field.name ) ) ); } subsetDBRsBy = function( dbr.set, field.name, field.value ) { dbr.set[ showFieldValues( dbr.set, field.name ) == field.value ]; } subsetDBRsByTemplate = function( dbr.set, template.name, template.prefix="database/templates" ) { template.name = tolower( template.name ); template.name = forceSuffix( tolower( template.name ), "tpl" ); if( !is.null( template.prefix ) ) { template.name = sprintf( "%s/%s", template.prefix, template.name ); } subsetDBRsBy( dbr.set, "templateName", template.name ); } whoAmIX = function( dbr ) { name.fields = grep( "^name", names( dbr ) ); named.recs = dbr[ name.fields ]; named.dbrs = readRecordS( S( named.recs ) ); tags = tags[ unlist( lapply( named.dbrs, function(x){x$description} ) ) ]; names( tags ) = sprintf( "%s.%s", names( named.recs ), "tagDescription" ); dbr = c( dbr, tags ); return( dbr ); } whoAmI= function( dbr.set ) { lapply( dbr.set, whoAmIX ); } fieldHas = function( record, fieldName, fieldValue ) { if( fieldName %in% names( record ) ) { if( record[[ fieldName ]] == fieldValue ) { return( TRUE ); } } return( FALSE ); } hasField = function( record, fieldName ) { fieldName %in% names( record ); } recordClassTest = function( records, className ) { unlist( lapply( records, fieldHas, "Class", className ) ); } # not really sure what all works down here # needs to get more organized, but for the curious, # you might find something of interest. dbrMerge = function( a, b ) { # a and b are fld.lists and a will take priority # when any fields are shared by a and b rv = b; for( field.name in names( a ) ) { rv[[ field.name ]] = a[[ field.name ]]; } return( rv ); } modMerge = function( a, b ) { # a and b are dbr.lists and a will take priority # when any records shared by a and b are merged a.records = names( a ); b.records = names( b ); shared.records = a.records[ a.records %in% b.records ]; m = list(); for( sh.rec in shared.records ) { m[[ sh.rec ]] = dbrMerge( a[[ sh.rec ]], b[[ sh.rec ]] ); } rv = c( m, a[ !( a.records %in% b.records ) ] ); rv = c( rv, b[ !( b.records %in% a.records ) ] ); return( rv ); } modMod = function( dbrs, mod.tab ) { for( roi in rownames( mod.tab ) ) { rec = dbrs[[ roi ]]; rec[[ mod.tab[ roi, "fieldName" ] ]] = mod.tab[ roi, "fieldValue" ]; dbrs[[ roi ]] = rec; } return( dbrs ); } findDBRValue = function( dbr.list, value.text ) { for( rec.name in names( dbr.list ) ) { for( field.name in names( dbr.list[[ rec.name ]] ) ) { if( length( grep( value.text, dbr.list[[rec.name]][[field.name]], ignore.case=TRUE ) ) > 0 ) { message( "Found ", value.text, " in ", rec.name, " at ", field.name ); } } } } getAllReferencesX = function( dbr ) { S( dbr[ grepl( "[.]dbr$", dbr ) ] ); } getAllReferences = function( dbr.list ) { unlist( lapply( dbr.list, getAllReferencesX ) ); }