nhkore 0.3.3 → 0.3.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +22 -1
- data/README.md +35 -11
- data/Rakefile +25 -0
- data/lib/nhkore/cli/news_cmd.rb +2 -1
- data/lib/nhkore/cli/search_cmd.rb +2 -2
- data/lib/nhkore/cli/sift_cmd.rb +6 -111
- data/lib/nhkore/datetime_parser.rb +342 -0
- data/lib/nhkore/lib.rb +1 -0
- data/lib/nhkore/util.rb +0 -17
- data/lib/nhkore/version.rb +1 -1
- data/nhkore.gemspec +1 -1
- metadata +6 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1db415fe5fa2d6f112fae3ef163b79ddaa88d639de565c4cb35b40fa14fb5a66
|
4
|
+
data.tar.gz: c535ba1f719db2c64ba6713c21c6365f51e31361efd6046064cdf700219f30ab
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: af517bada681dc850e60f1c0e275ba35d2177dc413b076612a091217fd653bba82be725c0247c52bb1e342489fe99c731ac7f5efc0b681d54cdcbb02cdb5360b
|
7
|
+
data.tar.gz: 579569f8c5201f3fe8b460281d585ac8b10c50c881d18ca6d6ff342fab0c178f0ad6e532df42200db117b0f8e85dbbace87846c85fcdd5c0c4eac1501f4b24e7
|
data/CHANGELOG.md
CHANGED
@@ -2,7 +2,28 @@
|
|
2
2
|
|
3
3
|
Format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
|
4
4
|
|
5
|
-
## [[Unreleased]](https://github.com/esotericpig/nhkore/compare/v0.3.
|
5
|
+
## [[Unreleased]](https://github.com/esotericpig/nhkore/compare/v0.3.4...master)
|
6
|
+
|
7
|
+
## [v0.3.4] - 2020-04-25
|
8
|
+
|
9
|
+
### Added
|
10
|
+
- DatetimeParser
|
11
|
+
- Extracted from SiftCmd into its own class
|
12
|
+
- Fixed some minor logic bugs from the old code
|
13
|
+
- Added new feature where 1 range can be empty:
|
14
|
+
- `sift ez -d '...2019'` (from = 1924)
|
15
|
+
- `sift ez -d '2019...'` (to = current year)
|
16
|
+
- `sift ez -d '...'` (still an error)
|
17
|
+
- Added `update_core` rake task for dev
|
18
|
+
- Makes pushing a new release much easier
|
19
|
+
- See *Hacking.Releasing* section in *README*
|
20
|
+
|
21
|
+
### Fixed
|
22
|
+
- SiftCmd `parse_sift_datetime()` for `-d/--datetime` option
|
23
|
+
- Didn't work exactly right (as written in *README*) for some special inputs:
|
24
|
+
- `-d '2019...3'`
|
25
|
+
- `-d '3-3'`
|
26
|
+
- `-d '3'`
|
6
27
|
|
7
28
|
## [v0.3.3] - 2020-04-23
|
8
29
|
|
data/README.md
CHANGED
@@ -26,6 +26,8 @@ This is similar to a [core word/vocabulary list](https://www.fluentin3months.com
|
|
26
26
|
- [News Command](#news-command-)
|
27
27
|
- [Using the Library](#using-the-library-)
|
28
28
|
- [Hacking](#hacking-)
|
29
|
+
- [Updating](#updating-)
|
30
|
+
- [Releasing](#releasing-)
|
29
31
|
- [License](#license-)
|
30
32
|
|
31
33
|
## For Non-Power Users [^](#contents)
|
@@ -525,7 +527,7 @@ doc = ss.html_doc()
|
|
525
527
|
doc.css('a').each() do |anchor|
|
526
528
|
link = anchor['href']
|
527
529
|
|
528
|
-
next if ss.ignore_link?(link)
|
530
|
+
next if ss.ignore_link?(link,cleaned: false)
|
529
531
|
|
530
532
|
if link.include?('https://www3.nhk')
|
531
533
|
puts link
|
@@ -564,6 +566,7 @@ end
|
|
564
566
|
|
565
567
|
```Ruby
|
566
568
|
require 'nhkore/article_scraper'
|
569
|
+
require 'time'
|
567
570
|
|
568
571
|
as = NHKore::ArticleScraper.new(
|
569
572
|
'https://www3.nhk.or.jp/news/easy/k10011862381000/k10011862381000.html',
|
@@ -687,6 +690,7 @@ end
|
|
687
690
|
`Sifter` will sift & sort the `News` data into a single file. The data is sorted by frequency in descending order (i.e., most frequent words first).
|
688
691
|
|
689
692
|
```Ruby
|
693
|
+
require 'nhkore/datetime_parser'
|
690
694
|
require 'nhkore/news'
|
691
695
|
require 'nhkore/sifter'
|
692
696
|
require 'time'
|
@@ -698,7 +702,8 @@ sifter = NHKore::Sifter.new(news)
|
|
698
702
|
sifter.caption = 'Sakura Fields Forever!'
|
699
703
|
|
700
704
|
# Filter the data.
|
701
|
-
|
705
|
+
sifter.filter_by_datetime(NHKore::DatetimeParser.parse_range('2019-12-4...7'))
|
706
|
+
sifter.filter_by_datetime([Time.new(2019,12,4),Time.new(2019,12,7)])
|
702
707
|
sifter.filter_by_datetime(
|
703
708
|
from: Time.new(2019,12,4),to: Time.new(2019,12,7)
|
704
709
|
)
|
@@ -727,13 +732,14 @@ if !File.exist?(file)
|
|
727
732
|
end
|
728
733
|
```
|
729
734
|
|
730
|
-
### Util &
|
735
|
+
### Util, UserAgents, & DatetimeParser
|
731
736
|
|
732
737
|
These provide a variety of useful methods/constants.
|
733
738
|
|
734
739
|
Here are some of the most useful ones:
|
735
740
|
|
736
741
|
```Ruby
|
742
|
+
require 'nhkore/datetime_parser'
|
737
743
|
require 'nhkore/user_agents'
|
738
744
|
require 'nhkore/util'
|
739
745
|
|
@@ -759,14 +765,16 @@ puts
|
|
759
765
|
puts '========'
|
760
766
|
puts '[ Time ]'
|
761
767
|
puts '========'
|
762
|
-
puts "JST now: #{Util.jst_now}"
|
768
|
+
puts "JST now: #{Util.jst_now()}"
|
763
769
|
# Drops in JST_OFFSET, does not change hour/min.
|
764
770
|
puts "JST time: #{Util.jst_time(Time.now)}"
|
765
771
|
puts "JST year: #{Util::JST_YEAR}"
|
766
772
|
puts "1999 sane? #{Util.sane_year?(1999)}" # true
|
767
773
|
puts "1776 sane? #{Util.sane_year?(1776)}" # false
|
768
|
-
puts "Guess 5: #{
|
769
|
-
puts "Guess 99: #{
|
774
|
+
puts "Guess 5: #{DatetimeParser.guess_year(5)}" # 2005
|
775
|
+
puts "Guess 99: #{DatetimeParser.guess_year(99)}" # 1999
|
776
|
+
# => [2020-12-01 00:00:00 +0900, 2020-12-31 23:59:59 +0900]
|
777
|
+
puts "Parse: #{DatetimeParser.parse_range('2020-12')}"
|
770
778
|
puts
|
771
779
|
puts "JST timezone offset: #{Util::JST_OFFSET}"
|
772
780
|
puts "JST timezone offset hour: #{Util::JST_OFFSET_HOUR}"
|
@@ -792,9 +800,9 @@ def fmt_jpn()
|
|
792
800
|
end
|
793
801
|
|
794
802
|
puts " #{fmt_jpn{|x| x}}"
|
795
|
-
puts "Hiragana? #{fmt_jpn{|x|
|
796
|
-
puts "Kana? #{fmt_jpn{|x|
|
797
|
-
puts "Kanji? #{fmt_jpn{|x|
|
803
|
+
puts "Hiragana? #{fmt_jpn{|x| Util.hiragana?(x)}}"
|
804
|
+
puts "Kana? #{fmt_jpn{|x| Util.kana?(x)}}"
|
805
|
+
puts "Kanji? #{fmt_jpn{|x| Util.kanji?(x)}}"
|
798
806
|
puts "Reduce: #{Util.reduce_jpn_space("' '")}"
|
799
807
|
puts
|
800
808
|
|
@@ -842,9 +850,25 @@ You can make some changes/fixes to the code and then install your local version:
|
|
842
850
|
|
843
851
|
`$ bundle exec rake install:local`
|
844
852
|
|
845
|
-
###
|
853
|
+
### Updating [^](#contents)
|
854
|
+
|
855
|
+
This will update *core/* for you:
|
856
|
+
|
857
|
+
`$ bundle exec rake update_core`
|
858
|
+
|
859
|
+
### Releasing [^](#contents)
|
846
860
|
|
847
|
-
|
861
|
+
1. Update *CHANGELOG.md*, *version.rb*, & *Gemfile.lock*
|
862
|
+
- *Raketary*: `$ raketary bump -v`
|
863
|
+
- Run: `$ bundle update`
|
864
|
+
2. Run: `$ bundle exec rake update_core`
|
865
|
+
3. Run: `$ bundle exec rake clobber pkg_core`
|
866
|
+
4. Create a new release & tag
|
867
|
+
- Add `pkg/nhkore-core.zip`
|
868
|
+
5. Run: `$ git pull`
|
869
|
+
6. Upload GitHub package
|
870
|
+
- *Raketary*: `$ raketary github_pkg`
|
871
|
+
7. Run: `$ bundle exec rake release`
|
848
872
|
|
849
873
|
## License [^](#contents)
|
850
874
|
|
data/Rakefile
CHANGED
@@ -63,6 +63,31 @@ Rake::TestTask.new() do |task|
|
|
63
63
|
task.warning = true
|
64
64
|
end
|
65
65
|
|
66
|
+
# If you need to run a part after the 1st part,
|
67
|
+
# just type 'n' to not overwrite the file and then 'y' for continue.
|
68
|
+
desc "Update '#{File.join(NHKore::Util::CORE_DIR,'')}' files for release"
|
69
|
+
task :update_core do |task|
|
70
|
+
require 'highline'
|
71
|
+
|
72
|
+
CONTINUE_MSG = "\nContinue (y/n)? "
|
73
|
+
|
74
|
+
cmd = ['ruby','-w','./lib/nhkore.rb','-t','300','-m','10']
|
75
|
+
hl = HighLine.new()
|
76
|
+
|
77
|
+
next unless sh(*cmd,'se','ez','bing')
|
78
|
+
next unless hl.agree(CONTINUE_MSG)
|
79
|
+
puts
|
80
|
+
|
81
|
+
next unless sh(*cmd,'news','-s','100','ez')
|
82
|
+
next unless hl.agree(CONTINUE_MSG)
|
83
|
+
puts
|
84
|
+
|
85
|
+
next unless sh(*cmd,'sift','-e','csv' ,'ez')
|
86
|
+
next unless sh(*cmd,'sift','-e','html','ez')
|
87
|
+
next unless sh(*cmd,'sift','-e','json','ez')
|
88
|
+
next unless sh(*cmd,'sift','-e','yml' ,'ez')
|
89
|
+
end
|
90
|
+
|
66
91
|
YARD::Rake::YardocTask.new() do |task|
|
67
92
|
task.files = [File.join('lib','**','*.rb')]
|
68
93
|
|
data/lib/nhkore/cli/news_cmd.rb
CHANGED
@@ -23,6 +23,7 @@
|
|
23
23
|
|
24
24
|
require 'time'
|
25
25
|
|
26
|
+
require 'nhkore/datetime_parser'
|
26
27
|
require 'nhkore/error'
|
27
28
|
require 'nhkore/missingno'
|
28
29
|
require 'nhkore/news'
|
@@ -57,7 +58,7 @@ module CLI
|
|
57
58
|
date time to use as a fallback in cases when an article doesn't have one;
|
58
59
|
format: YYYY-mm-dd H:M; example: 2020-03-30 15:30
|
59
60
|
EOD
|
60
|
-
value = Time.strptime(value,'%Y-%m-%d %H:%M',&
|
61
|
+
value = Time.strptime(value,'%Y-%m-%d %H:%M',&DatetimeParser.method(:guess_year))
|
61
62
|
value = Util.jst_time(value)
|
62
63
|
value
|
63
64
|
end
|
@@ -83,7 +83,7 @@ module CLI
|
|
83
83
|
key = key.to_s()
|
84
84
|
|
85
85
|
if key.include?('show')
|
86
|
-
raise CLIError
|
86
|
+
raise CLIError,"must specify a sub command for option[#{key}]"
|
87
87
|
end
|
88
88
|
end
|
89
89
|
|
@@ -283,7 +283,7 @@ module CLI
|
|
283
283
|
puts "> Easy: #{BingScraper.build_url(SearchScraper::YASASHII_SITE,count: count)}"
|
284
284
|
puts "> Regular: #{BingScraper.build_url(SearchScraper::FUTSUU_SITE,count: count)}"
|
285
285
|
else
|
286
|
-
raise CLIError
|
286
|
+
raise CLIError,'must specify a sub command for option[show-urls]'
|
287
287
|
end
|
288
288
|
|
289
289
|
return true
|
data/lib/nhkore/cli/sift_cmd.rb
CHANGED
@@ -24,6 +24,7 @@
|
|
24
24
|
require 'date'
|
25
25
|
require 'time'
|
26
26
|
|
27
|
+
require 'nhkore/datetime_parser'
|
27
28
|
require 'nhkore/news'
|
28
29
|
require 'nhkore/sifter'
|
29
30
|
require 'nhkore/util'
|
@@ -41,26 +42,6 @@ module CLI
|
|
41
42
|
DEFAULT_SIFT_YASASHII_FILE = "#{Sifter::DEFAULT_YASASHII_FILE}{search.criteria}{file.ext}"
|
42
43
|
SIFT_EXTS = [:csv,:htm,:html,:json,:yaml,:yml]
|
43
44
|
|
44
|
-
# Order matters.
|
45
|
-
SIFT_DATETIME_FMTS = [
|
46
|
-
'%Y-%m-%d %H:%M',
|
47
|
-
'%Y-%m-%d %H',
|
48
|
-
'%Y-%m-%d',
|
49
|
-
'%m-%d %H:%M',
|
50
|
-
'%Y-%m %H:%M',
|
51
|
-
'%m-%d %H',
|
52
|
-
'%Y-%m %H',
|
53
|
-
'%m-%d',
|
54
|
-
'%Y-%m',
|
55
|
-
'%d %H:%M',
|
56
|
-
'%y %H:%M',
|
57
|
-
'%d %H',
|
58
|
-
'%Y %H',
|
59
|
-
'%H:%M',
|
60
|
-
'%d',
|
61
|
-
'%Y'
|
62
|
-
]
|
63
|
-
|
64
45
|
attr_accessor :sift_datetime_text
|
65
46
|
attr_accessor :sift_search_criteria
|
66
47
|
|
@@ -90,7 +71,11 @@ module CLI
|
|
90
71
|
'9' (9th of Current Year & Month)
|
91
72
|
EOD
|
92
73
|
app.sift_datetime_text = value # Save the original value for the file name
|
93
|
-
|
74
|
+
|
75
|
+
value = DatetimeParser.parse_range(value)
|
76
|
+
|
77
|
+
app.check_empty_opt(:datetime,value) if value.nil?()
|
78
|
+
|
94
79
|
value
|
95
80
|
end
|
96
81
|
option :e,:ext,<<-EOD,argument: :required,default: DEFAULT_SIFT_EXT,transform: -> (value) do
|
@@ -211,96 +196,6 @@ module CLI
|
|
211
196
|
return filename
|
212
197
|
end
|
213
198
|
|
214
|
-
# TODO: This should probably be moved into its own class, into Util, or into Sifter?
|
215
|
-
def parse_sift_datetime(value)
|
216
|
-
value = Util.reduce_space(value).strip() # Don't use unspace_web_str(), want spaces for formats
|
217
|
-
value = value.split('...',2)
|
218
|
-
|
219
|
-
check_empty_opt(:datetime,nil) if value.empty?() # For ''
|
220
|
-
|
221
|
-
# Make a "to" and a "from" date time range.
|
222
|
-
value << value[0].dup() if value.length == 1
|
223
|
-
|
224
|
-
to_day = nil
|
225
|
-
to_hour = 23
|
226
|
-
to_minute = 59
|
227
|
-
to_month = 12
|
228
|
-
to_year = Util::MAX_SANE_YEAR
|
229
|
-
|
230
|
-
value.each_with_index() do |v,i|
|
231
|
-
v = check_empty_opt(:datetime,v) # For '...', '12-25...', or '...12-25'
|
232
|
-
|
233
|
-
has_day = false
|
234
|
-
has_hour = false
|
235
|
-
has_minute = false
|
236
|
-
has_month = false
|
237
|
-
has_year = false
|
238
|
-
|
239
|
-
SIFT_DATETIME_FMTS.each_with_index() do |fmt,i|
|
240
|
-
begin
|
241
|
-
# If don't do this, "%d" values will be parsed using "%d %H".
|
242
|
-
# It seems as though strptime() ignores space.
|
243
|
-
raise ArgumentError if !v.include?(' ') && fmt.include?(' ')
|
244
|
-
|
245
|
-
# If don't do this, "%y" values will be parsed using "%d".
|
246
|
-
raise ArgumentError if fmt == '%d' && v.length > 2
|
247
|
-
|
248
|
-
v = Time.strptime(v,fmt,&Util.method(:guess_year))
|
249
|
-
|
250
|
-
has_day = fmt.include?('%d')
|
251
|
-
has_hour = fmt.include?('%H')
|
252
|
-
has_minute = fmt.include?('%M')
|
253
|
-
has_month = fmt.include?('%m')
|
254
|
-
has_year = fmt.include?('%Y')
|
255
|
-
|
256
|
-
break # No problem; this format worked
|
257
|
-
rescue ArgumentError
|
258
|
-
# Out of formats.
|
259
|
-
raise if i >= (SIFT_DATETIME_FMTS.length - 1)
|
260
|
-
end
|
261
|
-
end
|
262
|
-
|
263
|
-
# "From" date time.
|
264
|
-
if i == 0
|
265
|
-
# Set these so that "2012-7-4...7-9" will use the appropriate year
|
266
|
-
# of "2012" for "7-9".
|
267
|
-
to_day = v.day if has_day
|
268
|
-
to_hour = v.hour if has_hour
|
269
|
-
to_minute = v.min if has_minute
|
270
|
-
to_month = v.month if has_month
|
271
|
-
to_year = v.year if has_year
|
272
|
-
|
273
|
-
v = Time.new(
|
274
|
-
has_year ? v.year : Util::MIN_SANE_YEAR,
|
275
|
-
has_month ? v.month : 1,
|
276
|
-
has_day ? v.day : 1,
|
277
|
-
has_hour ? v.hour : 0,
|
278
|
-
has_minute ? v.min : 0
|
279
|
-
)
|
280
|
-
# "To" date time.
|
281
|
-
else
|
282
|
-
to_hour = v.hour if has_hour
|
283
|
-
to_minute = v.min if has_minute
|
284
|
-
to_month = v.month if has_month
|
285
|
-
to_year = v.year if has_year
|
286
|
-
|
287
|
-
if has_day
|
288
|
-
to_day = v.day
|
289
|
-
# Nothing passed from the "from" date time?
|
290
|
-
elsif to_day.nil?()
|
291
|
-
# Last day of month.
|
292
|
-
to_day = Date.new(to_year,to_month,-1).day
|
293
|
-
end
|
294
|
-
|
295
|
-
v = Time.new(to_year,to_month,to_day,to_hour,to_minute)
|
296
|
-
end
|
297
|
-
|
298
|
-
value[i] = v
|
299
|
-
end
|
300
|
-
|
301
|
-
return value
|
302
|
-
end
|
303
|
-
|
304
199
|
def run_sift_cmd(type)
|
305
200
|
news_name = nil
|
306
201
|
|
@@ -0,0 +1,342 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# encoding: UTF-8
|
3
|
+
# frozen_string_literal: true
|
4
|
+
|
5
|
+
#--
|
6
|
+
# This file is part of NHKore.
|
7
|
+
# Copyright (c) 2020 Jonathan Bradley Whited (@esotericpig)
|
8
|
+
#
|
9
|
+
# NHKore is free software: you can redistribute it and/or modify
|
10
|
+
# it under the terms of the GNU Lesser General Public License as published by
|
11
|
+
# the Free Software Foundation, either version 3 of the License, or
|
12
|
+
# (at your option) any later version.
|
13
|
+
#
|
14
|
+
# NHKore is distributed in the hope that it will be useful,
|
15
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
16
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
17
|
+
# GNU Lesser General Public License for more details.
|
18
|
+
#
|
19
|
+
# You should have received a copy of the GNU Lesser General Public License
|
20
|
+
# along with NHKore. If not, see <https://www.gnu.org/licenses/>.
|
21
|
+
#++
|
22
|
+
|
23
|
+
|
24
|
+
require 'attr_bool'
|
25
|
+
require 'date'
|
26
|
+
require 'time'
|
27
|
+
|
28
|
+
require 'nhkore/util'
|
29
|
+
|
30
|
+
|
31
|
+
module NHKore
|
32
|
+
###
|
33
|
+
# @author Jonathan Bradley Whited (@esotericpig)
|
34
|
+
# @since 0.3.4
|
35
|
+
###
|
36
|
+
class DatetimeParser
|
37
|
+
# Order matters!
|
38
|
+
FMTS = [
|
39
|
+
'%Y-%m-%d %H:%M',
|
40
|
+
'%Y-%m-%d %H',
|
41
|
+
'%Y-%m-%d',
|
42
|
+
'%m-%d %H:%M',
|
43
|
+
'%Y-%m %H:%M',
|
44
|
+
'%m-%d %H',
|
45
|
+
'%Y-%m %H',
|
46
|
+
'%m-%d',
|
47
|
+
'%Y-%m',
|
48
|
+
'%d %H:%M',
|
49
|
+
'%y %H:%M',
|
50
|
+
'%d %H',
|
51
|
+
'%Y %H',
|
52
|
+
'%H:%M',
|
53
|
+
'%d',
|
54
|
+
'%Y',
|
55
|
+
]
|
56
|
+
|
57
|
+
def self.guess_year(year)
|
58
|
+
if year < 1000
|
59
|
+
century = Util::JST_YEAR / 100 * 100 # 2120 -> 2100
|
60
|
+
millennium = Util::JST_YEAR / 1000 * 1000 # 2120 -> 2000
|
61
|
+
|
62
|
+
# If year <= 23 (2022 -> 23)...
|
63
|
+
if year <= ((Util::JST_YEAR % 100) + 1)
|
64
|
+
# Assume this century.
|
65
|
+
year = century + year
|
66
|
+
elsif year >= 100
|
67
|
+
# If (2000 + 150) <= 2201 (if current year is 2200)...
|
68
|
+
if (millennium + year) <= (Util::JST_YEAR + 1)
|
69
|
+
# Assume this millennium.
|
70
|
+
# So if the current year is 2200, and year is 150,
|
71
|
+
# then it will be 2000 + 150 = 2150.
|
72
|
+
year = millennium + year
|
73
|
+
else
|
74
|
+
# Assume previous millennium (2000 -> 1000),
|
75
|
+
# so year 999 will become 1999.
|
76
|
+
millennium -= 1000 if millennium >= 1000
|
77
|
+
year = millennium + year
|
78
|
+
end
|
79
|
+
else
|
80
|
+
# Assume previous century (2000 -> 1900).
|
81
|
+
century -= 100 if century >= 100
|
82
|
+
year = century + year
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
return year
|
87
|
+
end
|
88
|
+
|
89
|
+
def self.parse_range(value)
|
90
|
+
# Do not use unspace_web_str(), want spaces for formats.
|
91
|
+
value = Util.strip_web_str(Util.reduce_space(value))
|
92
|
+
values = value.split('...',2)
|
93
|
+
|
94
|
+
return nil if values.empty?() # For '' or '...'
|
95
|
+
|
96
|
+
# For '2020...' or '...2020'.
|
97
|
+
if value.include?('...')
|
98
|
+
# values.length is always 2 because of 2 in split() above.
|
99
|
+
|
100
|
+
# For '2020...'.
|
101
|
+
if Util.empty_web_str?(values[1])
|
102
|
+
values[1] = :infinity
|
103
|
+
# For '...2020'.
|
104
|
+
elsif Util.empty_web_str?(values[0])
|
105
|
+
values[0] = :infinity
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
datetimes = [
|
110
|
+
DatetimeParser.new(), # "From" date time
|
111
|
+
DatetimeParser.new(), # "To" date time
|
112
|
+
]
|
113
|
+
|
114
|
+
values.each_with_index() do |v,i|
|
115
|
+
dt = datetimes[i]
|
116
|
+
|
117
|
+
# Minimum/Maximum date time for '2020...' or '...2020'.
|
118
|
+
if v == :infinity
|
119
|
+
# "From" date time.
|
120
|
+
if i == 0
|
121
|
+
dt.min!()
|
122
|
+
# "To" date time.
|
123
|
+
else
|
124
|
+
dt.max!()
|
125
|
+
end
|
126
|
+
else
|
127
|
+
v = Util.strip_web_str(v)
|
128
|
+
|
129
|
+
FMTS.each_with_index() do |fmt,i|
|
130
|
+
begin
|
131
|
+
# If don't do this, "%d" values will be parsed using "%d %H".
|
132
|
+
# It seems as though strptime() ignores space.
|
133
|
+
raise ArgumentError if fmt.include?(' ') && !v.include?(' ')
|
134
|
+
|
135
|
+
# If don't do this, "%y..." values will be parsed using "%d...".
|
136
|
+
raise ArgumentError if fmt.start_with?('%d') && v.split(' ')[0].length > 2
|
137
|
+
|
138
|
+
dt.parse!(v,fmt)
|
139
|
+
|
140
|
+
break # No problem; this format worked
|
141
|
+
rescue ArgumentError
|
142
|
+
# Out of formats.
|
143
|
+
raise if i >= (FMTS.length - 1)
|
144
|
+
end
|
145
|
+
end
|
146
|
+
end
|
147
|
+
end
|
148
|
+
|
149
|
+
from = datetimes[0]
|
150
|
+
to = datetimes[1]
|
151
|
+
|
152
|
+
from.autofill!(:from,to)
|
153
|
+
to.autofill!(:to,from)
|
154
|
+
|
155
|
+
return [from.jst_time(),to.jst_time()]
|
156
|
+
end
|
157
|
+
|
158
|
+
attr_accessor :day
|
159
|
+
attr_accessor :hour
|
160
|
+
attr_accessor :min
|
161
|
+
attr_accessor :month
|
162
|
+
attr_accessor :sec
|
163
|
+
attr_accessor :year
|
164
|
+
|
165
|
+
attr_accessor? :has_day
|
166
|
+
attr_accessor? :has_hour
|
167
|
+
attr_accessor? :has_min
|
168
|
+
attr_accessor? :has_month
|
169
|
+
attr_accessor? :has_sec
|
170
|
+
attr_accessor? :has_year
|
171
|
+
|
172
|
+
attr_reader? :min_or_max
|
173
|
+
|
174
|
+
def initialize(year=nil,month=nil,day=nil,hour=nil,min=nil,sec=nil)
|
175
|
+
super()
|
176
|
+
|
177
|
+
set!(year,month,day,hour,min,sec)
|
178
|
+
|
179
|
+
self.has = false
|
180
|
+
@min_or_max = false
|
181
|
+
end
|
182
|
+
|
183
|
+
def autofill!(type,other)
|
184
|
+
case type
|
185
|
+
when :from
|
186
|
+
is_from = true
|
187
|
+
when :to
|
188
|
+
is_from = false
|
189
|
+
else
|
190
|
+
raise ArgumentError,"invalid type[#{type}]"
|
191
|
+
end
|
192
|
+
|
193
|
+
return self if @min_or_max
|
194
|
+
|
195
|
+
has_small = false
|
196
|
+
jst_now = Util.jst_now()
|
197
|
+
|
198
|
+
# Must be from smallest to biggest.
|
199
|
+
|
200
|
+
if @has_sec || other.has_sec?()
|
201
|
+
@sec = other.sec unless @has_sec
|
202
|
+
has_small = true
|
203
|
+
else
|
204
|
+
if has_small
|
205
|
+
@sec = jst_now.sec
|
206
|
+
else
|
207
|
+
@sec = is_from ? 0 : 59
|
208
|
+
end
|
209
|
+
end
|
210
|
+
|
211
|
+
if @has_min || other.has_min?()
|
212
|
+
@min = other.min unless @has_min
|
213
|
+
has_small = true
|
214
|
+
else
|
215
|
+
if has_small
|
216
|
+
@min = jst_now.min
|
217
|
+
else
|
218
|
+
@min = is_from ? 0 : 59
|
219
|
+
end
|
220
|
+
end
|
221
|
+
|
222
|
+
if @has_hour || other.has_hour?()
|
223
|
+
@hour = other.hour unless @has_hour
|
224
|
+
has_small = true
|
225
|
+
else
|
226
|
+
if has_small
|
227
|
+
@hour = jst_now.hour
|
228
|
+
else
|
229
|
+
@hour = is_from ? 0 : 23
|
230
|
+
end
|
231
|
+
end
|
232
|
+
|
233
|
+
if @has_day || other.has_day?()
|
234
|
+
@day = other.day unless @has_day
|
235
|
+
has_small = true
|
236
|
+
else
|
237
|
+
if has_small
|
238
|
+
@day = jst_now.day
|
239
|
+
else
|
240
|
+
@day = is_from ? 1 : :last_day
|
241
|
+
end
|
242
|
+
end
|
243
|
+
|
244
|
+
if @has_month || other.has_month?()
|
245
|
+
@month = other.month unless @has_month
|
246
|
+
has_small = true
|
247
|
+
else
|
248
|
+
if has_small
|
249
|
+
@month = jst_now.month
|
250
|
+
else
|
251
|
+
@month = is_from ? 1 : 12
|
252
|
+
end
|
253
|
+
end
|
254
|
+
|
255
|
+
if @has_year || other.has_year?()
|
256
|
+
@year = other.year unless @has_year
|
257
|
+
has_small = true
|
258
|
+
else
|
259
|
+
if has_small
|
260
|
+
@year = jst_now.year
|
261
|
+
else
|
262
|
+
@year = is_from ? Util::MIN_SANE_YEAR : jst_now.year
|
263
|
+
end
|
264
|
+
end
|
265
|
+
|
266
|
+
# Must be after setting @year & @month.
|
267
|
+
if @day == :last_day
|
268
|
+
@day = Date.new(@year,@month,-1).day
|
269
|
+
end
|
270
|
+
|
271
|
+
return self
|
272
|
+
end
|
273
|
+
|
274
|
+
def max!()
|
275
|
+
@min_or_max = true
|
276
|
+
|
277
|
+
# Ex: 2020-12-31 23:59:59
|
278
|
+
return set!(Util::JST_YEAR,12,31,23,59,59)
|
279
|
+
end
|
280
|
+
|
281
|
+
def min!()
|
282
|
+
@min_or_max = true
|
283
|
+
|
284
|
+
# Ex: 1924-01-01 00:00:00
|
285
|
+
return set!(Util::MIN_SANE_YEAR,1,1,0,0,0)
|
286
|
+
end
|
287
|
+
|
288
|
+
def parse!(value,fmt)
|
289
|
+
value = Time.strptime(value,fmt,&self.class.method(:guess_year))
|
290
|
+
|
291
|
+
@has_day = fmt.include?('%d')
|
292
|
+
@has_hour = fmt.include?('%H')
|
293
|
+
@has_min = fmt.include?('%M')
|
294
|
+
@has_month = fmt.include?('%m')
|
295
|
+
@has_sec = fmt.include?('%S')
|
296
|
+
@has_year = fmt.include?('%Y')
|
297
|
+
|
298
|
+
@day = value.day if @has_day
|
299
|
+
@hour = value.hour if @has_hour
|
300
|
+
@min = value.min if @has_min
|
301
|
+
@month = value.month if @has_month
|
302
|
+
@sec = value.sec if @has_sec
|
303
|
+
@year = value.year if @has_year
|
304
|
+
|
305
|
+
return self
|
306
|
+
end
|
307
|
+
|
308
|
+
def set!(year=nil,month=nil,day=nil,hour=nil,min=nil,sec=nil)
|
309
|
+
@year = year
|
310
|
+
@month = month
|
311
|
+
@day = day
|
312
|
+
@hour = hour
|
313
|
+
@min = min
|
314
|
+
@sec = sec
|
315
|
+
|
316
|
+
return self
|
317
|
+
end
|
318
|
+
|
319
|
+
def has=(value)
|
320
|
+
@has_day = value
|
321
|
+
@has_hour = value
|
322
|
+
@has_min = value
|
323
|
+
@has_month = value
|
324
|
+
@has_sec = value
|
325
|
+
@has_year = value
|
326
|
+
|
327
|
+
return self
|
328
|
+
end
|
329
|
+
|
330
|
+
def jst_time()
|
331
|
+
return Util.jst_time(time())
|
332
|
+
end
|
333
|
+
|
334
|
+
def time()
|
335
|
+
return Time.new(@year,@month,@day,@hour,@min,@sec)
|
336
|
+
end
|
337
|
+
|
338
|
+
def to_s()
|
339
|
+
return "#{@year}-#{@month}-#{@day} #{@hour}:#{@min}:#{@sec}"
|
340
|
+
end
|
341
|
+
end
|
342
|
+
end
|
data/lib/nhkore/lib.rb
CHANGED
data/lib/nhkore/util.rb
CHANGED
@@ -108,23 +108,6 @@ module NHKore
|
|
108
108
|
return !str.match?(/[\/\\]/)
|
109
109
|
end
|
110
110
|
|
111
|
-
def self.guess_year(year)
|
112
|
-
if year < 100
|
113
|
-
# 2021 -> 2000.
|
114
|
-
millennium = JST_YEAR / 100 * 100
|
115
|
-
|
116
|
-
# If year <= (2021 -> 21), assume this century.
|
117
|
-
if year <= (JST_YEAR % 100)
|
118
|
-
year = millennium + year
|
119
|
-
else
|
120
|
-
# Assume previous century (2000 -> 1900).
|
121
|
-
year = (millennium - 100) + year
|
122
|
-
end
|
123
|
-
end
|
124
|
-
|
125
|
-
return year
|
126
|
-
end
|
127
|
-
|
128
111
|
def self.hiragana?(str)
|
129
112
|
return HIRAGANA_REGEX =~ str
|
130
113
|
end
|
data/lib/nhkore/version.rb
CHANGED
data/nhkore.gemspec
CHANGED
@@ -67,7 +67,7 @@ Gem::Specification.new() do |spec|
|
|
67
67
|
spec.add_runtime_dependency 'http-cookie' ,'~> 1.0' # For parsing/setting cookies (BingScraper/Scraper)
|
68
68
|
spec.add_runtime_dependency 'japanese_deinflector' ,'~> 0.0' # For unconjugating Japanese words (plain/dictionary form)
|
69
69
|
spec.add_runtime_dependency 'nokogiri' ,'~> 1.10' # For scraping/hacking
|
70
|
-
spec.add_runtime_dependency 'psychgus' ,'~> 1.
|
70
|
+
spec.add_runtime_dependency 'psychgus' ,'~> 1.3' # For styling Psych YAML
|
71
71
|
spec.add_runtime_dependency 'public_suffix' ,'~> 4.0' # For parsing URL domain names
|
72
72
|
spec.add_runtime_dependency 'rainbow' ,'~> 3.0' # For CLI color output
|
73
73
|
spec.add_runtime_dependency 'rubyzip' ,'~> 2.3' # For extracting Zip files (GetCmd)
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: nhkore
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.3.
|
4
|
+
version: 0.3.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jonathan Bradley Whited (@esotericpig)
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-04-
|
11
|
+
date: 2020-04-25 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: attr_bool
|
@@ -128,14 +128,14 @@ dependencies:
|
|
128
128
|
requirements:
|
129
129
|
- - "~>"
|
130
130
|
- !ruby/object:Gem::Version
|
131
|
-
version: '1.
|
131
|
+
version: '1.3'
|
132
132
|
type: :runtime
|
133
133
|
prerelease: false
|
134
134
|
version_requirements: !ruby/object:Gem::Requirement
|
135
135
|
requirements:
|
136
136
|
- - "~>"
|
137
137
|
- !ruby/object:Gem::Version
|
138
|
-
version: '1.
|
138
|
+
version: '1.3'
|
139
139
|
- !ruby/object:Gem::Dependency
|
140
140
|
name: public_suffix
|
141
141
|
requirement: !ruby/object:Gem::Requirement
|
@@ -357,6 +357,7 @@ files:
|
|
357
357
|
- lib/nhkore/cli/news_cmd.rb
|
358
358
|
- lib/nhkore/cli/search_cmd.rb
|
359
359
|
- lib/nhkore/cli/sift_cmd.rb
|
360
|
+
- lib/nhkore/datetime_parser.rb
|
360
361
|
- lib/nhkore/defn.rb
|
361
362
|
- lib/nhkore/dict.rb
|
362
363
|
- lib/nhkore/dict_scraper.rb
|
@@ -389,7 +390,7 @@ metadata:
|
|
389
390
|
changelog_uri: https://github.com/esotericpig/nhkore/blob/master/CHANGELOG.md
|
390
391
|
homepage_uri: https://github.com/esotericpig/nhkore
|
391
392
|
source_code_uri: https://github.com/esotericpig/nhkore
|
392
|
-
post_install_message: " \n NHKore v0.3.
|
393
|
+
post_install_message: " \n NHKore v0.3.4\n \n You can now use [nhkore] on the
|
393
394
|
command line.\n \n Homepage: https://github.com/esotericpig/nhkore\n \n Code:
|
394
395
|
\ https://github.com/esotericpig/nhkore\n Changelog: https://github.com/esotericpig/nhkore/blob/master/CHANGELOG.md\n
|
395
396
|
\ Bugs: https://github.com/esotericpig/nhkore/issues\n \n"
|