Class: SportDb::Pathspec

Inherits:
Object
  • Object
show all
Defined in:
lib/fbtok/pathspec.rb

Constant Summary collapse

SEASON_RE =
%r{ (?:
        (?<season>\d{4}-\d{2})
      | (?<season>\d{4})
  )
}x
MATCH_RE =

note: if pattern includes directory add here

  (otherwise move to more "generic" datafile) - why? why not?
update - note include/allow dot (.) too
  BUT NOT as first character!!! (e.g. exclude .confg.txt !!!)
            e.g. 2024-25/at.1.txt
                     change to at_1 or uefa_cl or such - why? why not?

note - support case-insensitive flag  (e.g. 2025-26/namur/2_Prov_A.txt)
%r{
    ## "classic" variant i)  with season folder
    ##     e.g.  /1930/cup.txt
    (?:
      (?: ^|/ )    # beginning (^) or beginning of path (/)

       #{SEASON_RE}
          (?:  --[a-z0-9_-]+
          )?
         /

        ### note - allow optional directories
        (?:
            [a-z0-9][a-z0-9_-]*
              /
        )*

       [a-z0-9][a-z0-9._-]* \.txt   ## e.g /1-premierleague.txt
         $
    )

      |
    ## "compact" variant ii) with season in filename
    ##         e.g. 1930.txt or 2024_br.txt etc.
    (?:
       (?: ^|/ )      # beginning (^) or beginning of path (/)
         #{SEASON_RE}
         (?:   _   ## allow more than one underscore - why? why not?
            [a-z0-9][a-z0-9._-]*
          )?
            \.txt
            $
    )
}xi

Class Method Summary collapse

Class Method Details

._find(path, seasons: nil) ⇒ Object

Raises:

  • (Errno::ENOENT)


74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
# File 'lib/fbtok/pathspec.rb', line 74

def self._find( path, seasons: nil )
    ##
    ## note -  only if seasons filter is turn on
    ##                     MATCH_RE gets used!!!
    ##            otherwise generic **/*.txt
    ##
    ## note -   the ignore/exlude filter always gets used/applied for now


    ## check - rename dir
    ##          use root_dir or work_dir or cd or such - why? why not?

    ## note: normalize path - use File.expand_path ??
    ##    change all backslash to slash for now
    ## path = path.gsub( "\\", '/' )
    fullpath =  File.expand_path( path )

    ####
    ## note - make sure path exists; raise error if not
    raise Errno::ENOENT, "No such directory - #{path})"  unless Dir.exist?( fullpath )


    if seasons && seasons.size > 0
       ## norm seasons (string, integer => Season obj)
       seasons =  seasons.map {|season| Season(season) }
    end


    ## check all txt files
    ## note: incl. files starting with dot (.)) as candidates
    ##     (normally excluded with just *)
    ##  was:  Dir.glob( "#{path}/**/{*,.*}.txt" )

    candidates = Dir.glob( "#{fullpath}/**/*.txt" )
    ## pp candidates


    datafiles = []
    candidates.each do |candidate|

         ## (i) check for (optional) seasons filter
         if seasons && seasons.size > 0
            if m=MATCH_RE.match( candidate )
               next   unless seasons.include?( Season.parse( m[:season] ))
            else
              next    ## note - no season found in filename; skip too
            end
         end


         ## (ii) check for (default/built-in) ignore/excludes
          basename = File.basename( candidate, File.extname( candidate ))
          dirname  = File.dirname( candidate )

          ### exclude basenames with:
          ##   - squad
          ##   - .v2 or .v2603
          ##
          ##    - worldcup/more/1930_squads.txt   =>   squads
          ##    - 2014--brazil/cup.v2.txt
          ##    - 2014--brazil/cup.v260318_164934.txt

          next   if /squad/i.match?( basename )
          next   if /\.v[0-9][0-9_]*/i.match?( basename )

          #####
          ### exclude dirs  with:
          ##    - squad or wiki
          next   if /squad|wiki/i.match?( dirname )


          datafiles << candidate
    end

    ## pp datafiles
    datafiles
end

.build(args, filepack: nil) ⇒ Object



183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
# File 'lib/fbtok/pathspec.rb', line 183

def self.build( args, filepack: nil )
  recs = []

  ## check fo no args case  (and filepack present with default)
  if args.empty?
    if filepack && filepack.has_key?('default')
               recs << { 'path'      => '<default>',
                         'datafiles' => filepack['default'] }
    end
  else

    ## note - collect all "loose/standalone" files (NOT directories)
    ##             in single default pathspec node
    more = []


    args.each do |arg|
      if filepack && filepack.has_key?( arg.downcase )
           recs << { 'path'      => "<#{arg.downcase}>",
                     'datafiles' => filepack[arg.downcase] }
      ## check if directory
      elsif Dir.exist?( arg )
          recs << { 'path'       => arg,
                    'datafiles'  => _find( arg ) }
      elsif File.file?( arg )  ## assume it's a file
        ## make sure path exists; raise error if not
        ##   (auto-)expand path to normalize - yes why? why not?
          more << File.expand_path( arg )
      else
        raise Errno::ENOENT, "No such file or directory - #{arg}"
      end
    end

    if more.size > 0
      recs << { 'path'      => '<input>',
                'datafiles' =>  more }
    end
  end

  recs
end

.debug=(value) ⇒ Object



6
# File 'lib/fbtok/pathspec.rb', line 6

def self.debug=(value) @@debug = value; end

.debug?Boolean

note: default is FALSE

Returns:

  • (Boolean)


7
# File 'lib/fbtok/pathspec.rb', line 7

def self.debug?()      @@debug ||= false; end

.read(src) ⇒ Object

rename/change to read_csv - why? why not?



157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
# File 'lib/fbtok/pathspec.rb', line 157

def self.read( src )
    ## note: normalize scr - use File.expand_path ??
    ##    change all backslash to slash for now
    ## scr = scr.gsub( "\\", '/' )
    fullsrc =  File.expand_path( scr )

    recs = read_csv( fullsrc )
    pp recs     if debug?

    ##  note - make pathspecs relative to passed in file arg!!!
    basedir = File.dirname( fullsrc )

    recs.each do |rec|
        path = rec['path']
        fullpath = File.expand_path( path, basedir )
        datafiles =   _find( fullpath )

        ## add (new) datafiles column (from expanded pathspec)
        rec['datafiles'] = datafiles
    end

    recs
end