rwdaddresses 1.01 → 1.02
Sign up to get free protection for your applications and to get access to all the features.
- data/Readme.txt +5 -0
- data/code/01rwdcore/01rwdcore.rb +15 -13
- data/code/01rwdcore/openhelpwindow.rb +26 -26
- data/code/01rwdcore/returntomain.rb +8 -8
- data/code/01rwdcore/rwdtinkerversion.rb +12 -13
- data/code/01rwdcore/rwdwindowreturn.rb +3 -5
- data/code/01rwdcore/test_cases.rb +115 -0
- data/code/01rwdcore/test_harness.rb +12 -0
- data/code/01rwdcore/uploadreturns.rb +60 -59
- data/code/superant.com.rwdaddresses/attachtmpcontactphoto.rb +23 -23
- data/code/superant.com.rwdaddresses/clearscreendisplay.rb +14 -15
- data/code/superant.com.rwdaddresses/createnewnamerecord.rb +19 -18
- data/code/superant.com.rwdaddresses/deletecontactrecord.rb +22 -21
- data/code/superant.com.rwdaddresses/deleterwdaddressesupdatefiles.rb +15 -16
- data/code/superant.com.rwdaddresses/downloadrwdaddressfiles.rb +34 -32
- data/code/superant.com.rwdaddresses/listnamerecord.rb +14 -14
- data/code/superant.com.rwdaddresses/listvcardrecord.rb +15 -0
- data/code/superant.com.rwdaddresses/loadconfigurationrecord.rb +45 -44
- data/code/superant.com.rwdaddresses/loadconfigurationvariables.rb +14 -13
- data/code/superant.com.rwdaddresses/loadnamerecord.rb +29 -29
- data/code/superant.com.rwdaddresses/openhelpwindowrwdaddresses.rb +25 -25
- data/code/superant.com.rwdaddresses/renamecontact.rb +14 -15
- data/code/superant.com.rwdaddresses/returntomain.rb +8 -8
- data/code/superant.com.rwdaddresses/runaddresseswindow.rb +8 -8
- data/code/superant.com.rwdaddresses/runrwdaddressesmenu1.rb +31 -31
- data/code/superant.com.rwdaddresses/runrwdaddresssyncbackwindow.rb +8 -8
- data/code/superant.com.rwdaddresses/rwdaddressesbackwindow.rb +8 -8
- data/code/superant.com.rwdaddresses/rwdaddresseshelpabout.rb +10 -11
- data/code/superant.com.rwdaddresses/saveconfigurationrecord.rb +20 -20
- data/code/superant.com.rwdaddresses/savevcardrecord.rb +76 -0
- data/code/superant.com.rwdaddresses/syncrwdaddress.rb +24 -26
- data/code/superant.com.rwdaddresses/uploadrwdaddressfiles.rb +28 -28
- data/code/superant.com.rwdaddresses/viewaddressconfiguration.rb +21 -21
- data/code/superant.com.rwdaddresses/viewnamedata.rb +27 -26
- data/code/superant.com.rwdaddresses/viewphoto.rb +4 -4
- data/code/superant.com.rwdaddresses/viewrwdaddressesconfiguration.rb +23 -21
- data/code/superant.com.rwdaddresses/viewtmpcontactphoto.rb +6 -6
- data/code/superant.com.rwdaddresses/viewvcarddata.rb +22 -0
- data/code/superant.com.rwdtinkerbackwindow/controlclient.rb +89 -92
- data/code/superant.com.rwdtinkerbackwindow/diagnostictab.rb +15 -20
- data/code/superant.com.rwdtinkerbackwindow/installapplet.rb +19 -18
- data/code/superant.com.rwdtinkerbackwindow/installgemapplet.rb +20 -19
- data/code/superant.com.rwdtinkerbackwindow/installremotegem.rb +19 -18
- data/code/superant.com.rwdtinkerbackwindow/listgemdirs.rb +7 -7
- data/code/superant.com.rwdtinkerbackwindow/listgemzips.rb +48 -49
- data/code/superant.com.rwdtinkerbackwindow/listinstalledfiles.rb +8 -7
- data/code/superant.com.rwdtinkerbackwindow/listzips.rb +22 -26
- data/code/superant.com.rwdtinkerbackwindow/loadconfigurationrecord.rb +32 -31
- data/code/superant.com.rwdtinkerbackwindow/loadconfigurationvariables.rb +14 -13
- data/code/superant.com.rwdtinkerbackwindow/network.rb +82 -82
- data/code/superant.com.rwdtinkerbackwindow/openappletname.rb +18 -17
- data/code/superant.com.rwdtinkerbackwindow/openhelpwindowtinkerwin2.rb +37 -37
- data/code/superant.com.rwdtinkerbackwindow/remotegemlist.rb +20 -20
- data/code/superant.com.rwdtinkerbackwindow/removeapplet.rb +33 -32
- data/code/superant.com.rwdtinkerbackwindow/runrwdtinkerbackwindow.rb +8 -9
- data/code/superant.com.rwdtinkerbackwindow/rwdtinkerwin2version.rb +10 -11
- data/code/superant.com.rwdtinkerbackwindow/saveconfigurationrecord.rb +19 -18
- data/code/superant.com.rwdtinkerbackwindow/viewappletcontents.rb +21 -20
- data/code/superant.com.rwdtinkerbackwindow/viewgemappletcontents.rb +23 -20
- data/configuration/language.dist +1 -1
- data/configuration/rwdaddresses.dist +2 -2
- data/configuration/rwdtinker.dist +2 -2
- data/configuration/tinkerwin2variables.dist +1 -1
- data/extras/vpim/date.rb +198 -0
- data/extras/vpim/dirinfo.rb +229 -0
- data/extras/vpim/enumerator.rb +29 -0
- data/extras/vpim/field.rb +497 -0
- data/extras/vpim/maker/vcard.rb +312 -0
- data/extras/vpim/rfc2425.rb +244 -0
- data/extras/vpim/rrule.rb +482 -0
- data/extras/vpim/time.rb +42 -0
- data/extras/vpim/vcard.rb +151 -0
- data/extras/vpim/vpim.rb +94 -0
- data/gui/frontwindow0/superant.com.rwdaddresses/16editrecord.rwd +5 -0
- data/gui/frontwindow0/superant.com.rwdaddresses/17viewvcardrecord.rwd +32 -0
- data/gui/helpaboutinstalled/superant.com.tinkerhelpabout/3copyright.rwd +1 -1
- data/gui/tinkerbackwindows/superant.com.rwdaddressessyncbackwindow/70rwddiagnostics.rwd +1 -11
- data/init.rb +231 -228
- data/names/Angelina Jolie.vcf +8 -0
- data/rwd_files/HowTo_Addresses.txt +5 -0
- data/rwd_files/HowTo_Tinker.txt +14 -0
- data/rwdconfig.dist +6 -2
- data/tests/makedist.rb +36 -7
- metadata +23 -21
- data/extras/cmdline_parse +0 -47
- data/extras/config_file +0 -69
- data/extras/errorMsg +0 -19
- data/extras/makePlaylist +0 -34
- data/extras/mp3controld +0 -289
- data/extras/playlist +0 -186
- data/extras/plugins/Network +0 -237
- data/extras/showHelp +0 -18
- data/gui/frontwindowselections/superant.com.rwdaddressesselectiontab/rwdaddressessyncselectiontab.rwd +0 -12
- data/gui/helpaboutinstalled/superant.com.rwdwin2helpabout/1appname.rwd +0 -4
- data/gui/helpaboutinstalled/superant.com.rwdwin2helpabout/3copyright.rwd +0 -3
- data/gui/helpaboutinstalled/superant.com.rwdwin2helpabout/5version.rwd +0 -10
- data/installed/rwdaddressesdata2.inf +0 -8
- data/rwd_files/tinker.png +0 -0
@@ -1,24 +1,24 @@
|
|
1
1
|
# This tinker method is to retrieve the list of rwdzip applets available to install from the remote repository
|
2
|
-
|
3
2
|
def superantcomremotegemlist
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
3
|
+
gemcommandoption = "search --remote "
|
4
|
+
gemfilename = "rwdzip"
|
5
|
+
commandtext = "gem search --remote rwdzip"
|
6
|
+
commandtemp = $xpcommand + commandtext
|
7
|
+
begin # exception trapped block
|
8
|
+
|
9
|
+
tempremotegemappletsresult = `#{commandtemp} 2>&1`
|
10
|
+
@superantcomremotegemappletsfullresult = tempremotegemappletsresult
|
11
|
+
fileList = tempremotegemappletsresult.split(/\n/).delete_if { |x| ! (x =~ /\Arwdzip/) }
|
12
|
+
|
13
|
+
@superantcomremotegemappletsresult = fileList.rwd_method("superantcomremotegemappletdirsname")
|
14
|
+
rescue SystemCallError, StandardError
|
15
|
+
@superantcomremotegemappletsresult = "system call error: " + $!
|
16
|
+
end # exception rescue
|
18
17
|
end
|
19
|
-
|
18
|
+
|
20
19
|
def superantcomremotegemappletdirsname(inffile)
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
end
|
20
|
+
applet = inffile
|
21
|
+
@superantcominstallremoteappletinput = applet
|
22
|
+
|
23
|
+
end
|
24
|
+
|
@@ -1,32 +1,33 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
1
|
+
# method to remove a tinker applet
|
2
|
+
def removeapplet
|
3
|
+
require 'fileutils'
|
4
|
+
nametext = "%s" % [@a_removeapplet]
|
5
|
+
|
6
|
+
begin # exception trapped block
|
7
|
+
fileName = "installed/" + nametext + ".inf"
|
8
|
+
count = 0
|
9
|
+
fd = File.open(fileName,"r")
|
10
|
+
|
11
|
+
|
12
|
+
fd.each { |oneline|
|
13
|
+
if count == 1
|
14
|
+
if File.exist?(oneline.chop)
|
15
|
+
FileUtils.rm_rf( oneline.chop)
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
19
|
+
count = 1
|
20
|
+
}
|
21
|
+
fd.close
|
22
|
+
|
23
|
+
FileUtils.rm_rf( fileName)
|
24
|
+
|
25
|
+
|
26
|
+
@removeapplettext = "applet files removed! - restart rwd to finish uninstalling"
|
27
|
+
|
28
|
+
rescue
|
29
|
+
@removeapplettext = "\n" + "error"
|
30
|
+
|
31
|
+
end # exception rescue
|
32
|
+
|
33
|
+
end
|
@@ -1,12 +1,11 @@
|
|
1
1
|
# Application RwdTinker orginally (c) 2004 Steven Gibson under GPL.
|
2
2
|
# This application is a framework for writing programs from RubyWebDialogs
|
3
|
-
# http://www.
|
4
|
-
|
5
|
-
|
6
|
-
|
3
|
+
# For information see http://www.rubyforge.net/projects/rwdapplications
|
4
|
+
|
5
|
+
# call the rwdtinker helpwindow
|
6
|
+
|
7
|
+
def runrwdtinkerbackwindow
|
8
|
+
@rwd_window = "tinkerbackwindow"
|
9
|
+
@rwd_tab = "rwdzipslister"
|
10
|
+
end
|
7
11
|
|
8
|
-
def runrwdtinkerbackwindow
|
9
|
-
@rwd_window = "tinkerbackwindow"
|
10
|
-
@rwd_tab = "rwdzipslister"
|
11
|
-
end
|
12
|
-
|
@@ -1,14 +1,13 @@
|
|
1
1
|
# Application RwdTinker orginally (c) 2004 Steven Gibson under GPL.
|
2
2
|
# This application is a framework for writing programs from RubyWebDialogs
|
3
|
-
# http://www.
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
3
|
+
# For information see http://www.rubyforge.net/projects/rwdapplications
|
4
|
+
|
5
|
+
# return the version constant defined in the config file
|
6
|
+
def runrwdtinkerwin2version
|
7
|
+
@rwd_window = "applicationversion"
|
8
|
+
@versionappnamedisplay = "RwdTinkerWin2"
|
9
|
+
@versioncopyrightdisplay = "(c) 2004 Steven Gibson "
|
10
|
+
@versionnumberdisplay = "Version " + RwdTinkerWin2Version
|
11
|
+
|
12
|
+
end
|
12
13
|
|
13
|
-
end
|
14
|
-
|
@@ -1,18 +1,19 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
1
|
+
# this method saves the configuration record
|
2
|
+
def saveconfigurationrecord
|
3
|
+
require 'fileutils'
|
4
|
+
if @a_configurationfilename
|
5
|
+
newname = "%s" % [@a_configurationfilename] # grab the filename to create
|
6
|
+
newdata =@a_configline1.to_s + "\n" + @a_configline2.to_s + "\n" + @a_configline3.to_s + "\n" + @a_configline4.to_s + "\n" + @a_configline5.to_s + "\n" + @a_configline6.to_s + "\n" + @a_configline7.to_s + "\n" + @a_configline8.to_s + "\n"
|
7
|
+
|
8
|
+
begin # exception trapped block
|
9
|
+
fileName = File.join( ConfigurationDir, newname )
|
10
|
+
fd = File.open(fileName,"w")
|
11
|
+
fd.print(newdata) # save the record info to the file
|
12
|
+
fd.close
|
13
|
+
@newconfigurationresult=newdata # show the record info in the browser
|
14
|
+
rescue SystemCallError, StandardError
|
15
|
+
$stderr.print "system call error: " + $!
|
16
|
+
end # exception rescue
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
@@ -1,21 +1,22 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
begin # exception trapped block
|
7
|
-
fullname = nametext + ".zip"
|
8
|
-
fileName = File.join($zipslocation,fullname)
|
9
|
-
tempfilecontents = " "
|
10
|
-
zf = Zip::ZipFile.new(fileName)
|
11
|
-
zf.sort.each {
|
12
|
-
|entry|
|
13
|
-
tempfilecontents = tempfilecontents + entry.to_s + "\n"
|
14
|
-
}
|
15
|
-
@appletcontentstext = tempfilecontents
|
16
|
-
|
17
|
-
rescue
|
18
|
-
@installapplettext = "unzip error - error opening applet"
|
19
|
-
end # exception rescue
|
1
|
+
#view contents of a tinker applet
|
2
|
+
def viewappletcontents
|
3
|
+
require 'fileutils'
|
4
|
+
require 'extras/zip/zip'
|
5
|
+
nametext = "%s" % [@a_installapplet]
|
20
6
|
|
21
|
-
|
7
|
+
begin # exception trapped block
|
8
|
+
fullname = nametext + ".zip"
|
9
|
+
fileName = File.join($zipslocation,fullname)
|
10
|
+
tempfilecontents = " "
|
11
|
+
zf = Zip::ZipFile.new(fileName)
|
12
|
+
zf.sort.each {
|
13
|
+
|entry|
|
14
|
+
tempfilecontents = tempfilecontents + entry.to_s + "\n"
|
15
|
+
}
|
16
|
+
@appletcontentstext = tempfilecontents
|
17
|
+
|
18
|
+
rescue
|
19
|
+
@installapplettext = "unzip error - error opening applet"
|
20
|
+
end # exception rescue
|
21
|
+
|
22
|
+
end
|
@@ -1,21 +1,24 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
1
|
+
#view gem info
|
2
|
+
def viewgemappletcontents
|
3
|
+
require 'fileutils'
|
4
|
+
require 'extras/zip/zip'
|
5
|
+
nametext = "%s" % [@a_installapplet]
|
6
|
+
|
7
|
+
begin # exception trapped block
|
8
|
+
fullname = nametext + ".zip"
|
9
|
+
|
10
|
+
tempfilecontents = " "
|
11
|
+
zf = Zip::ZipFile.new(fullname)
|
12
|
+
zf.sort.each {
|
13
|
+
|entry|
|
14
|
+
tempfilecontents = tempfilecontents + entry.to_s + "\n"
|
15
|
+
}
|
16
|
+
@appletcontentstext = tempfilecontents
|
17
|
+
|
18
|
+
rescue
|
19
|
+
@installapplettext = "unzip error - error opening applet"
|
20
|
+
end # exception rescue
|
21
|
+
|
22
|
+
end
|
23
|
+
|
20
24
|
|
21
|
-
end
|
data/configuration/language.dist
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
##VERSION:1.
|
1
|
+
##VERSION:1.02
|
2
2
|
#rwdaddresses contact book
|
3
3
|
$photodelay = 1
|
4
4
|
##NAME:$addressfiles_directory:0
|
@@ -16,4 +16,4 @@ $rwdaddresses_ftpdirectory = "/incoming/rwdnames/"
|
|
16
16
|
##NAME:$rwdaddresses_updatedirectory:0
|
17
17
|
$rwdaddresses_updatedirectory = "updates"
|
18
18
|
|
19
|
-
RwdAddressesVersion = "1.
|
19
|
+
RwdAddressesVersion = "1.02"
|
@@ -1,4 +1,4 @@
|
|
1
|
-
##VERSION:1.
|
1
|
+
##VERSION:1.62
|
2
2
|
ConfigurationDir = "configuration" # for use in program - init.rb has this value without using this constant
|
3
3
|
CodeName = "rwdtinker"
|
4
4
|
CodeNameFile = CodeName + ".rb"
|
@@ -12,4 +12,4 @@ LangDir = "lang"
|
|
12
12
|
$rwdcontrolports =["13713","13714","13715","13716","13717","13718"]
|
13
13
|
$port = 7705
|
14
14
|
|
15
|
-
RwdTinkerVersion = "1.
|
15
|
+
RwdTinkerVersion = "1.62"
|
data/extras/vpim/date.rb
ADDED
@@ -0,0 +1,198 @@
|
|
1
|
+
=begin
|
2
|
+
$Id: date.rb,v 1.8 2004/11/17 05:06:27 sam Exp $
|
3
|
+
|
4
|
+
Copyright (C) 2005 Sam Roberts
|
5
|
+
|
6
|
+
This library is free software; you can redistribute it and/or modify it
|
7
|
+
under the same terms as the ruby language itself, see the file COPYING for
|
8
|
+
details.
|
9
|
+
=end
|
10
|
+
|
11
|
+
require 'date'
|
12
|
+
|
13
|
+
# Extensions to the standard library Date.
|
14
|
+
class Date
|
15
|
+
|
16
|
+
TIME_START = Date.new(1970, 1, 1)
|
17
|
+
SECS_PER_DAY = 24 * 60 * 60
|
18
|
+
|
19
|
+
# Converts this object to a Time object, or throws an ArgumentError if
|
20
|
+
# conversion is not possible because it is before the start of epoch.
|
21
|
+
def to_time
|
22
|
+
raise ArgumentError, 'date is before the start of system time' if self < TIME_START
|
23
|
+
days = self - TIME_START
|
24
|
+
|
25
|
+
Time.at((days * SECS_PER_DAY).to_i)
|
26
|
+
end
|
27
|
+
|
28
|
+
# If wday responds to to_str, convert it to the wday number by searching for
|
29
|
+
# a wday that matches, using as many characters as are in wday to do the
|
30
|
+
# comparison. wday must be 2 or more characters long in order to be a unique
|
31
|
+
# match, other than that, "mo", "Mon", and "MonDay" are all valid strings
|
32
|
+
# for wday 1.
|
33
|
+
#
|
34
|
+
# This method can be called on a valid wday, and it will return it. Perhaps
|
35
|
+
# it should be called by default inside the Date#new*() methods so that
|
36
|
+
# non-integer wday arguments can be used? Perhaps a similar method should
|
37
|
+
# exist for months? But with months, we all know January is 1, who can
|
38
|
+
# remember where Date chooses to start its wday count!
|
39
|
+
#
|
40
|
+
# Examples:
|
41
|
+
# Date.bywday(2004, 2, Date.str2wday('TU')) => the first Tuesday in
|
42
|
+
# February
|
43
|
+
# Date.bywday(2004, 2, Date.str2wday(2)) => the same day, but notice
|
44
|
+
# that a valid wday integer can be passed right through.
|
45
|
+
#
|
46
|
+
def Date.str2wday(wdaystr)
|
47
|
+
return wdaystr unless wdaystr.respond_to? :to_str
|
48
|
+
|
49
|
+
str = wdaystr.to_str.upcase
|
50
|
+
if str.length < 2
|
51
|
+
raise ArgumentError, 'wday #{wday} is not long enough to be a unique weekday name'
|
52
|
+
end
|
53
|
+
|
54
|
+
wday = Date::DAYNAMES.map { |n| n.slice(0, str.length).upcase }.index(str)
|
55
|
+
|
56
|
+
return wday if wday
|
57
|
+
|
58
|
+
raise ArgumentError, 'wday #{wdaystr} was not a recognizable weekday name'
|
59
|
+
end
|
60
|
+
|
61
|
+
|
62
|
+
# Create a new Date object for the date specified by year +year+, month
|
63
|
+
# +mon+, and day-of-the-week +wday+.
|
64
|
+
#
|
65
|
+
# The nth, +n+, occurrence of +wday+ within the period will be generated
|
66
|
+
# (+n+ defaults to 1). If +n+ is positive, the nth occurence from the
|
67
|
+
# beginning of the period will be returned, if negative, the nth occurrence
|
68
|
+
# from the end of the period will be returned.
|
69
|
+
#
|
70
|
+
# The period is a year, unless +month+ is non-nil, in which case it is just
|
71
|
+
# that month.
|
72
|
+
#
|
73
|
+
# Examples:
|
74
|
+
# - Date.bywday(2004, nil, 1, 9) => the ninth Sunday of 2004
|
75
|
+
# - Date.bywday(2004, nil, 1) => the first Sunday of 2004
|
76
|
+
# - Date.bywday(2004, nil, 1, -2) => the second last Sunday of 2004
|
77
|
+
# - Date.bywday(2004, 12, 1) => the first sunday in the 12th month of 2004
|
78
|
+
# - Date.bywday(2004, 2, 2, -1) => last Tuesday in the 2nd month in 2004
|
79
|
+
# - Date.bywday(2004, -2, 3, -2) => second last Wednesday in the second last month of 2004
|
80
|
+
#
|
81
|
+
# Compare this to Date.new, which allows a Date to be created by
|
82
|
+
# day-of-the-month, mday, to Date.new2, which allows a Date to be created by
|
83
|
+
# day-of-the-year, yday, and to Date.neww, which allows a Date to be created
|
84
|
+
# by day-of-the-week, but within a specific week.
|
85
|
+
def Date.bywday(year, mon, wday, n = 1, sg=Date::ITALY)
|
86
|
+
# Normalize mon to 1-12.
|
87
|
+
if mon
|
88
|
+
if mon > 12 || mon == 0 || mon < -12
|
89
|
+
raise ArgumentError, "mon #{mon} must be 1-12 or negative 1-12"
|
90
|
+
end
|
91
|
+
if mon < 0
|
92
|
+
mon = 13 + mon
|
93
|
+
end
|
94
|
+
end
|
95
|
+
if wday < 0 || wday > 6
|
96
|
+
raise ArgumentError, 'wday must be in range 0-6, or a weekday name'
|
97
|
+
end
|
98
|
+
|
99
|
+
# Determine direction of indexing.
|
100
|
+
inc = n <=> 0
|
101
|
+
if inc == 0
|
102
|
+
raise ArgumentError, 'n must be greater or less than zero'
|
103
|
+
end
|
104
|
+
|
105
|
+
# if !mon, n is index into year, but direction of search is determined by
|
106
|
+
# sign of n
|
107
|
+
d = Date.new(year, mon ? mon : inc, inc, sg)
|
108
|
+
|
109
|
+
while d.wday != wday
|
110
|
+
d += inc
|
111
|
+
end
|
112
|
+
|
113
|
+
# Now we have found the first/last day with the correct wday, search
|
114
|
+
# for nth occurrence, by jumping by n.abs-1 weeks forward or backward.
|
115
|
+
d += 7 * (n.abs - 1) * inc
|
116
|
+
|
117
|
+
if d.year != year
|
118
|
+
raise ArgumentError, 'n is out of bounds of year'
|
119
|
+
end
|
120
|
+
if mon && d.mon != mon
|
121
|
+
raise ArgumentError, 'n is out of bounds of month'
|
122
|
+
end
|
123
|
+
d
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
# DateGen generates arrays of dates matching simple criteria.
|
128
|
+
class DateGen
|
129
|
+
# Generate an array of dates on +wday+ (the day-of-week,
|
130
|
+
# 0-6, where 0 is Sunday).
|
131
|
+
#
|
132
|
+
# If +n+ is specified, only the nth occurrence of +wday+ within the period
|
133
|
+
# will be generated. If +n+ is positive, the nth occurence from the
|
134
|
+
# beginning of the period will be returned, if negative, the nth occurrence
|
135
|
+
# from the end of the period will be returned.
|
136
|
+
#
|
137
|
+
# The period is a year, unless +month+ is non-nil, in which case it is just
|
138
|
+
# that month.
|
139
|
+
#
|
140
|
+
# Examples:
|
141
|
+
# - DateGen.bywday(2004, nil, 1, 9) => the ninth Sunday in 2004
|
142
|
+
# - DateGen.bywday(2004, nil, 1) => all Sundays in 2004
|
143
|
+
# - DateGen.bywday(2004, nil, 1, -2) => second last Sunday in 2004
|
144
|
+
# - DateGen.bywday(2004, 12, 1) => all sundays in December 2004
|
145
|
+
# - DateGen.bywday(2004, 2, 2, -1) => last Tuesday in February in 2004
|
146
|
+
# - DateGen.bywday(2004, -2, 3, -2) => second last Wednesday in November of 2004
|
147
|
+
#
|
148
|
+
# Compare to Date.bywday(), which allows a single Date to be created with
|
149
|
+
# similar criteria.
|
150
|
+
def DateGen.bywday(year, month, wday, n = nil)
|
151
|
+
seed = Date.bywday(year, month, wday, n ? n : 1)
|
152
|
+
|
153
|
+
dates = [ seed ]
|
154
|
+
|
155
|
+
return dates if n
|
156
|
+
|
157
|
+
succ = seed.clone
|
158
|
+
|
159
|
+
# Collect all matches until we're out of the year (or month, if specified)
|
160
|
+
loop do
|
161
|
+
succ += 7
|
162
|
+
|
163
|
+
break if succ.year != year
|
164
|
+
break if month && succ.month != seed.month
|
165
|
+
|
166
|
+
dates.push succ
|
167
|
+
end
|
168
|
+
dates.sort!
|
169
|
+
dates
|
170
|
+
end
|
171
|
+
|
172
|
+
# Generate an array of dates on +mday+ (the day-of-month, 1-31). For months
|
173
|
+
# in which the +mday+ is not present, no date will be generated.
|
174
|
+
#
|
175
|
+
# The period is a year, unless +month+ is non-nil, in which case it is just
|
176
|
+
# that month.
|
177
|
+
#
|
178
|
+
# Compare to Date.new(), which allows a single Date to be created with
|
179
|
+
# similar criteria.
|
180
|
+
def DateGen.bymonthday(year, month, mday)
|
181
|
+
months = month ? [ month ] : 1..12
|
182
|
+
dates = [ ]
|
183
|
+
|
184
|
+
months.each do |m|
|
185
|
+
begin
|
186
|
+
dates << Date.new(year, m, mday)
|
187
|
+
rescue ArgumentError
|
188
|
+
# Don't generate dates for invalid combinations (Feb 29, when it's not
|
189
|
+
# a leap year, for example).
|
190
|
+
#
|
191
|
+
# TODO - should we raise when month is out of range, or mday can never
|
192
|
+
# be in range (32)?
|
193
|
+
end
|
194
|
+
end
|
195
|
+
dates
|
196
|
+
end
|
197
|
+
end
|
198
|
+
|