Categorygithub.com/bitterpilot/emailToCalendar
repository
0.0.0-20200908140638-4ea97bf11207
Repository: https://github.com/bitterpilot/emailtocalendar.git
Documentation: pkg.go.dev

# Packages

No description provided by the author
No description provided by the author
No description provided by the author

# README

Gmail to gCal

Go Report Card
Take a email of shifts from riteq and put them into google calendar

Sample

Your schedule for 24 Dec 2018 through to 6 Jan 2019 is shown below

DayDateStart WorkEnd WorkTotal HoursBreaksPayOrg Level
Mon24 Dec12:4518:1505:3000:3005:00AAAA\Dry Operations\Snr CSO
Thu27 Dec13:4520:0006:1500:3005:45AAAA\Dry Operations\Snr CSO
Fri28 Dec13:4520:0006:1500:3005:45AAAA\Dry Operations\Snr CSO
Sat29 Dec06:0012:1506:1500:0006:15AAAA\Dry Operations\Dry Ops Officer
Sun30 Dec13:0018:1505:1500:0005:15AAAA\Dry Operations\Snr CSO
Thu03 Jan13:1521:1508:0000:0008:00AAAA\Dry Operations\Dry Ops Officer
Fri04 Jan07:3014:0006:3000:3006:00AAAA\Dry Operations\Snr CSO

Road map

v0.7

Functions to batch requests for gmail and calendar

v0.6

Recognize a email that changes previously published shifts. This will probably use the dates in the first line of the email so it will also need to recognizing the difference between republish and an email for the same dates but different location.

v0.5

Restructure code to a clean code architecture
alt text

.  
├── cmd
│   ├── cli  // full cli version of the app(expects user interaction) calls app.Run()
│   └── FAAS // functions as a service version(expects events (i.e. mail received, timed event) to trigger
│            // function)
├── pkg  
│   ├── email // gets emails
│   │   │     // expects: User && (MsgID || ThdID || Watch Response)
│   │   │     // returns: err && (email body || MsgID || ThdID || time received)
│   │   │     // methods:
│   │   │           // NewService calls a provider specific function to open a new authentication session.
│   │   │           // Although tempting to have the authentication tokens combine permissions for email
│   │   │           // and calendar, the email NewService is distinct from the calendar one to avoid the
│   │   │           // two packages from being tightly coupled.
│   │   │           // It also has the benefit of avoiding complexity if the user wants to map between providers.
│   │   │           type ServiceHandler struct {
│   │   │               user string
│   │   │               providerService interface
│   │   │               logger *log.logger
│   │   │               db *sql.db
│   │   │           }
│   │   │           NewService(user, provider) (svc, err) {
│   │   │               switch {
│   │   │                  case provider: provider methods
│   │   │                  default: errors.New("must have provider")
│   │   │               }
│   │   │           }
│   │   │
│   │   │           type provider interface {
│   │   │               (*NewService) Push(bool) (pushRsp, err){if true{watch} if false{stop}}
│   │   │               (*NewService) HandlePush(pushRsp) (historyID, err)
│   │   │               (*NewService) ListRecentEmails(historyID)
│   │   │               (*NewService) ListAllEmails()
│   │   │               (*NewService) GetEmail(MsgID) *email
│   │   │               (*NewService) GetEmails(ThdID || []MsgID) *[]email
│   │   │           }
│   │   ├──  email.go  // implements newService() and provider interface
│   │   └──  providers
│   │        ├──  google.go     // implements the functions listed in provider interface for Gmail
│   │        └──  microsoft.go // implements the functions listed in provider interface for Microsoft
│   │
│   ├── calendar // gets, removes and publishes events
│   │   │        // expects: User && (Event || eventIds)
│   │   │        // returns: Err && (eventIDs || Events)
│   │   │        // methods:
│   │   │           // NewService calls a provider specific function to open a new authentication session.
│   │   │           // Although tempting to have the authentication tokens combine permissions for calendar
│   │   │           // and email, the calendar NewService is distinct from the email one to avoid the
│   │   │           // two packages from being tightly coupled.
│   │   │           // It also has the benefit of avoiding complexity if the user wants to map between providers.
│   │   │           type ServiceHandler struct {
│   │   │               user string
│   │   │               providerService interface
│   │   │               logger *log.logger
│   │   │           }
│   │   │           NewService(user, provider) (svc, err)
│   │   │
│   │   │           (*NewService) GetEvents(startDate, endDate) ([]event, err)
│   │   │           // maybe these bulk actions can take []event or ...event and if event < 1 call the multiple
│   │   │           // operation method.
│   │   │           (*NewService) RemoveEvent(eventID) err
│   │   │           (*NewService) RemoveEvents([]eventIDs) err
│   │   │           (*NewService) PublishEvent(event) err
│   │   │           (*NewService) PublishEvents([]event) err
│   │   │           (*NewService) ChangeEvent([]event) err
│   │   ├──  calendar.go  // implements newService() and provider interface
│   │   └──  providers
│   │        ├──  google.go    // implements the functions listed in provider interface for Google
│   │        └──  microsoft.go // implements the functions listed in provider interface for Microsoft
│   │
│   └── app // builds events from email body and checks for existing events
│       │       // expects: User && (shift || email)
│       │       // returns: Err && (event)
│       │       // methods:
│       │           type email struct {
│       │               IntId    int    // Internal Storage ID
│       │               ExtID    string // ID from the service provider
│       │               ExtThdID string // ID linking emails together from the service provider
│       │               Body     string // base64 encoded
│       │           }
│       │           type shift struct {
│       │               IntId      int    // Internal Storage ID
│       │               ExtEventID string // ID from the service provider
│       │               ExtMsgID   string // ID linking emails together from the service provider
│       │               Comment    string // base64 encoded
│       │               URL        string // direct link to source email
│       │
│       │           }
│       │           type handler struct {
│       │               logger *log.logger
│       │               db     *sql.db
│       │           }
│       │           NewHandler(logger, db) handler
│       │           RunCli() // function handles all the code to run the cli version expects parameters handed
│       │                    // at runtime
│       │           (*handler) ProcessEmail(MsgID) (*email)
│       │           (*handler) dateRange(body)
│       │           (*handler) checkEncoding(body)
│       │           (*handler) processTable(body) [][]string
│       │           (*handler) tagReader
│       │           (*handler) convertTableLineToShift([]string) shift
│       │           (*handler) convertShiftToEvent(shift) event
│       │           (*handler) compareEvent(event, event) (bool, diff)
│       │           (*handler) convertDates(string) time
│       │           (*handler)
│       ├── store
│       │   └── db
│       ├── app.go   // designed in a way that it will be easy to break up into individual files such as email.go
│       └── run.go   // contains method that are called from main.go
│
├── vendor
│   └── ...
├── README.md
├── .gitignore
├── dockerfile
├── go.mod
├── continuous integration
└── ...

v0.4

check for failures Notify of failures

v0.3

use map[]? values into sqlite send each event to gCalendar enter successful to sqlite

v0.2

check first line if the year dates are the same or different take the date from the date column and the year from the first line to create a full date place all values into a map[]?

v0.1

decode email