Implemented ICal update
This commit is contained in:
		
							parent
							
								
									e3c64211e0
								
							
						
					
					
						commit
						26d0cd400a
					
				| @ -10,6 +10,7 @@ import ( | |||||||
| 	"log" | 	"log" | ||||||
| 	"net/http" | 	"net/http" | ||||||
| 	"net/url" | 	"net/url" | ||||||
|  | 	"regexp" | ||||||
| 	"strings" | 	"strings" | ||||||
| 	"text/template" | 	"text/template" | ||||||
| 	"time" | 	"time" | ||||||
| @ -73,6 +74,31 @@ func (i ICal) getTimeField(f string) time.Time { | |||||||
| 	return time.Time{} | 	return time.Time{} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | var fieldMatch = regexp.MustCompile(`^(\w+)[;:]`) | ||||||
|  | 
 | ||||||
|  | // Update the ical structure with a new start/end time (and the | ||||||
|  | // timestamp of the last modification). | ||||||
|  | func (ical *ICal) Update(newStart, newEnd time.Time) { | ||||||
|  | 	for i, line := range ical.eventData { | ||||||
|  | 		match := fieldMatch.FindStringSubmatch(line) | ||||||
|  | 		if match == nil { | ||||||
|  | 			continue | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		// For last modification | ||||||
|  | 		now := time.Now().UTC() | ||||||
|  | 
 | ||||||
|  | 		switch match[1] { | ||||||
|  | 		case "DTSTART": | ||||||
|  | 			ical.eventData[i] = "DTSTART:" + newStart.UTC().Format(ICAL_TIME) + "Z" | ||||||
|  | 		case "DTEND": | ||||||
|  | 			ical.eventData[i] = "DTEND:" + newEnd.UTC().Format(ICAL_TIME) + "Z" | ||||||
|  | 		case "DTSTAMP", "LAST-MODIFIED": | ||||||
|  | 			ical.eventData[i] = match[1] + ":" + now.Format(ICAL_TIME) + "Z" | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
| // Retrieve the start time of the event. | // Retrieve the start time of the event. | ||||||
| func (i ICal) Start() time.Time { | func (i ICal) Start() time.Time { | ||||||
| 	return i.getTimeField("DTSTART") | 	return i.getTimeField("DTSTART") | ||||||
|  | |||||||
| @ -73,6 +73,68 @@ func TestParseICal(t *testing.T) { | |||||||
| 	}) | 	}) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | func TestICal_Update(t *testing.T) { | ||||||
|  | 	newStart := time.Date(2019, 10, 05, 10, 25, 0, 0, time.UTC) | ||||||
|  | 	newEnd := time.Date(2019, 10, 05, 10, 55, 30, 0, time.UTC) | ||||||
|  | 
 | ||||||
|  | 	t.Run("Values updated", func(t *testing.T) { | ||||||
|  | 		ical, _ := ParseICal(strings.NewReader(icsSimple)) | ||||||
|  | 		ical.Update(newStart, newEnd) | ||||||
|  | 
 | ||||||
|  | 		if ical.Start() != newStart { | ||||||
|  | 			t.Error("Start not updated correctly") | ||||||
|  | 		} | ||||||
|  | 		if ical.End() != newEnd { | ||||||
|  | 			t.Error("End not updated correctly") | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		if ical.getTimeField("DTSTAMP").Sub(time.Now()) > 5*time.Second { | ||||||
|  | 			t.Error("Timestamp doesn't seem to be updated") | ||||||
|  | 		} | ||||||
|  | 	}) | ||||||
|  | 	t.Run("Other values untouched", func(t *testing.T) { | ||||||
|  | 		// Use a ICal structure with dummy/unknown fields but also without | ||||||
|  | 		// DTSTAMP or LAST-MODIFIED, so we can do a string comparison against | ||||||
|  | 		// known values. | ||||||
|  | 		ical, _ := ParseICal(strings.NewReader(`BEGIN:VCALENDAR | ||||||
|  | PRODID:-//some//thing//EN | ||||||
|  | VERSION:2.0 | ||||||
|  | UNKNOWN:FIELD | ||||||
|  | SOME;MORE:STUFF | ||||||
|  | BEGIN:VEVENT | ||||||
|  | UID:WHATEVERID | ||||||
|  | SUMMARY:Summary | ||||||
|  | CLASS:PUBLIC | ||||||
|  | DTSTART:20180308T113000Z | ||||||
|  | DTEND:20180308T130000Z | ||||||
|  | CREATED:20180401T182238Z | ||||||
|  | END:VEVENT | ||||||
|  | EVEN;MORE:STUFF | ||||||
|  | END:VCALENDAR`)) | ||||||
|  | 
 | ||||||
|  | 		ical.Update(newStart, newEnd) | ||||||
|  | 
 | ||||||
|  | 		if ical.String() != `BEGIN:VCALENDAR | ||||||
|  | PRODID:-//some//thing//EN | ||||||
|  | VERSION:2.0 | ||||||
|  | UNKNOWN:FIELD | ||||||
|  | SOME;MORE:STUFF | ||||||
|  | BEGIN:VEVENT | ||||||
|  | UID:WHATEVERID | ||||||
|  | SUMMARY:Summary | ||||||
|  | CLASS:PUBLIC | ||||||
|  | DTSTART:20191005T102500Z | ||||||
|  | DTEND:20191005T105530Z | ||||||
|  | CREATED:20180401T182238Z | ||||||
|  | END:VEVENT | ||||||
|  | EVEN;MORE:STUFF | ||||||
|  | END:VCALENDAR` { | ||||||
|  | 
 | ||||||
|  | 			t.Error("The resulting ICS seems wrong.") | ||||||
|  | 		} | ||||||
|  | 	}) | ||||||
|  | } | ||||||
|  | 
 | ||||||
| const icsWithTZ = `BEGIN:VCALENDAR | const icsWithTZ = `BEGIN:VCALENDAR | ||||||
| PRODID:-//Ximian//NONSGML Evolution Calendar//EN | PRODID:-//Ximian//NONSGML Evolution Calendar//EN | ||||||
| VERSION:2.0 | VERSION:2.0 | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user