ref: 0c0404e806613648f9c292ff8bd86d8f652290b8
author: halfwit <michaelmisch1985@gmail.com>
date: Sat Mar 28 07:34:23 PDT 2020
move plugins
--- /dev/null
+++ b/appointments.go
@@ -1,0 +1,25 @@
+package plugins
+
+import (
+ "github.com/olmaxmedical/olmax_go/router"
+)
+
+// AddAppointment registers an appointment into the appointment book
+// TODO(halfwit) message/email client to fill out Symptoms form
+const AddAppointment router.PluginMask = 1 << 1
+
+func init() {
+ b := &router.Plugin{
+ Name: "Add Appointments",
+ Run: nil,
+ Validate: addAppt,
+ }
+ router.AddPlugin(b, AddAppointment)
+}
+
+func addAppt(s *router.Request) error {
+ // get &id=
+ // Auth user and requisite key
+ // TODO(halfwit) create unique key in patient/appointments
+ return nil
+}
--- /dev/null
+++ b/bookings.go
@@ -1,0 +1,22 @@
+package plugins
+
+import (
+ "github.com/olmaxmedical/olmax_go/router"
+)
+
+// ListBookings retreives a list of all upcoming bookings for a given doctor
+const ListBookings router.PluginMask = 1 << 2
+
+func init() {
+ b := &router.Plugin{
+ Name: "List Bookings",
+ Run: nil,
+ Validate: listBookings,
+ }
+ router.AddPlugin(b, ListBookings)
+}
+
+func listBookings(s *router.Request) error {
+
+ return nil
+}
--- /dev/null
+++ b/countries.go
@@ -1,0 +1,96 @@
+package plugins
+
+import (
+ "fmt"
+ "sort"
+ "strings"
+
+ "github.com/olmaxmedical/olmax_go/router"
+ "github.com/pariz/gountries"
+ "golang.org/x/text/message"
+)
+
+// Countries - Populate a localized spinner to select country
+const Countries router.PluginMask = 1 << 3
+
+// Country - Mapping token to internationalized country code
+type Country struct {
+ ID string
+ Name string
+}
+
+type countries struct {
+ list []gountries.Country
+}
+
+var cache *countries
+
+func init() {
+ var l []gountries.Country
+ c := gountries.New()
+ for _, c := range c.FindAllCountries() {
+ l = append(l, c)
+ }
+ cache = &countries{
+ list: l,
+ }
+ sort.Sort(cache)
+ b := &router.Plugin{
+ Name: "country",
+ Run: listCountries,
+ Validate: validateCountries,
+ }
+ router.AddPlugin(b, Countries)
+}
+
+// Len - For Sort implementation
+func (c *countries) Len() int {
+ return len(c.list)
+}
+
+// Less - For Sort implementation
+func (c *countries) Less(i, j int) bool {
+ switch strings.Compare(c.list[i].Name.Common, c.list[j].Name.Common) {
+ case -1:
+ return true
+ default:
+ return false
+ }
+}
+
+// Swap - For Sort implementation
+func (c *countries) Swap(i, j int) {
+ tmp := c.list[i]
+ c.list[i] = c.list[j]
+ c.list[j] = tmp
+}
+
+func listCountries(r *router.Request) map[string]interface{} {
+ p := r.Printer()
+ // TODO(halfwit): Use Request to get a localized country name
+ c := make(map[string]interface{})
+ c["label"] = p.Sprint("Select country/countries")
+ for _, item := range cache.list {
+ c[item.Name.Common] = item.Name.Common
+ }
+ return c
+}
+
+func validateCountries(r *router.Request) error {
+ s := r.Request()
+ for _, c := range s.PostFormValue("country") {
+ if msg := checkCountry(r.Printer(), c); msg != nil {
+ return msg
+ }
+ }
+ return nil
+}
+
+func checkCountry(p *message.Printer, country rune) error {
+ for _, item := range cache.list {
+ if item.Name.Common == string(country) {
+ return nil
+ }
+ }
+ return fmt.Errorf("%s", p.Sprint("No country entered/nil value entered"))
+}
--- /dev/null
+++ b/doctor.go
@@ -1,0 +1,55 @@
+package plugins
+
+import (
+ "github.com/olmaxmedical/olmax_go/router"
+)
+
+// ListDoctors - Bitmask to list doctors of in client country
+const ListDoctors router.PluginMask = 1 << 4
+
+type doctor struct {
+ Image string
+ AlmaMater string
+ Name string
+ Residency string
+ Current string
+ Country string
+ Specialty string
+ Rate string
+}
+
+func init() {
+ b := &router.Plugin{
+ Name: "doctors",
+ Run: ListDocs,
+ Validate: nil,
+ }
+ router.AddPlugin(b, ListDoctors)
+}
+
+// ListDocs - Query db and return list of doctors in country
+// These may need eventual localization for any bilingual doctors we have
+func ListDocs(r *router.Request) map[string]interface{} {
+ return map[string]interface{}{
+ "Mark Abuzamzam, MD": &doctor{
+ Image: "AbuzamzamMD.jpg",
+ AlmaMater: "University of Southern California School of Medicine",
+ Residency: "University of Southern California, San Diego. Internal Medicine Residency",
+ Name: "Mark Abuzamzam, MD",
+ Current: "Current Faculty at University of California Irvine Program Director",
+ Country: "United States of America",
+ Specialty: "Internal Medicine and Addictions Medicine",
+ Rate: "0.0013 BTC",
+ },
+ "Martha Woodfin, MD": &doctor{
+ Image: "WoodfinMD.jpg",
+ Name: "Martha Woodfin, MD",
+ AlmaMater: "University Seoul School of Medicine",
+ Residency: "University of Las Vegas Nevada, Pediatric Medicine Residency",
+ Current: "Current Staff at Mercy Hospital Jackson NC",
+ Country: "United States of America",
+ Specialty: "Internal Medicine",
+ Rate: "0.0011 BTC",
+ },
+ }
+}
--- /dev/null
+++ b/email.go
@@ -1,0 +1,83 @@
+package plugins
+
+import (
+ "errors"
+ "log"
+ "mime/multipart"
+
+ "github.com/olmaxmedical/olmax_go/email"
+ "github.com/olmaxmedical/olmax_go/router"
+)
+
+// EmailForm - Patient form to gmail
+const EmailForm router.PluginMask = 1 << 5
+
+// SendSignup - Send account creation validation email
+const SendSignup router.PluginMask = 1 << 6
+
+// SendReset - Send password reset email
+const SendReset router.PluginMask = 1 << 7
+
+func init() {
+ b := &router.Plugin{
+ Name: "emailform",
+ Run: nil,
+ Validate: emailForm,
+ }
+ router.AddPlugin(b, EmailForm)
+ c := &router.Plugin{
+ Name: "signupEmail",
+ Run: nil,
+ Validate: signupEmail,
+ }
+ router.AddPlugin(c, SendSignup)
+ d := &router.Plugin{
+ Name: "resetPassword",
+ Run: nil,
+ Validate: resetPassword,
+ }
+ router.AddPlugin(d, SendReset)
+}
+
+func signupEmail(s *router.Request) error {
+ r := s.Request()
+ first := r.PostFormValue("fname")
+ last := r.PostFormValue("lname")
+ address := r.PostFormValue("email")
+ pass := r.PostFormValue("pass")
+ email.SendSignup(first, last, address, pass, s.Printer())
+ return nil
+}
+
+func resetPassword(s *router.Request) error {
+ p := s.Printer()
+ r := s.Request()
+ email.SendReset(r.PostFormValue("email"), p)
+ return nil
+}
+
+func emailForm(s *router.Request) error {
+ p := s.Printer()
+ r := s.Request()
+ r.ParseMultipartForm(10 << 20) // parse up to 10MB
+ if r.PostFormValue("name") == "" || r.PostFormValue("email") == "" {
+ return errors.New(p.Sprint("Missing name or email in form. Please contact us at olmaxmedical@gmail.com"))
+ }
+ if b, ok := r.Form["sendto"]; !ok || b[0] == "" {
+ return errors.New(p.Sprint("Missing value for target email. Please contact us at olmaxmedical.gmail.com"))
+ }
+ attachments := make(map[string]multipart.File)
+ m := r.MultipartForm
+ for _, headers := range m.File {
+ for _, header := range headers {
+ file, err := header.Open()
+ if err != nil { //non fatal, log any oddities and continue
+ log.Println(err)
+ continue
+ }
+ attachments[header.Filename] = file
+ }
+ }
+ email.SendForm(r.Form, p, attachments)
+ return nil
+}
--- /dev/null
+++ b/errors.go
@@ -1,0 +1,28 @@
+package plugins
+
+import (
+ "github.com/olmaxmedical/olmax_go/router"
+)
+
+// FormErrors - A list of errors present on a POST request
+const FormErrors router.PluginMask = 1 << 8
+
+func init() {
+ b := &router.Plugin{
+ Name: "errors",
+ Run: GetFormErrors,
+ Validate: nil,
+ }
+ router.AddPlugin(b, FormErrors)
+}
+
+// GetFormErrors - return the client a list of any errors in the form
+func GetFormErrors(r *router.Request) map[string]interface{} {
+ s := r.Session()
+ if s == nil {
+ return nil
+ }
+ return map[string]interface{}{
+ "errors": s.Get("errors"),
+ }
+}
--- /dev/null
+++ b/messages.go
@@ -1,0 +1,29 @@
+package plugins
+
+import (
+ "github.com/olmaxmedical/olmax_go/router"
+)
+
+// Messages - list all messages by key for use in a message template
+const Messages router.PluginMask = 1 << 9
+
+func init() {
+ b := &router.Plugin{
+ Name: "messages",
+ Run: GetMessages,
+ Validate: nil,
+ }
+ router.AddPlugin(b, Messages)
+}
+
+// GetMessages - return a map of message structs
+func GetMessages(r *router.Request) map[string]interface{} {
+ s := r.Session()
+ if s == nil {
+ return nil
+ }
+ return map[string]interface{}{
+ // No, this won't actually do anything.
+ "messages": s.Get("messages"),
+ }
+}
--- /dev/null
+++ b/offers.go
@@ -1,0 +1,19 @@
+package plugins
+
+import "github.com/olmaxmedical/olmax_go/router"
+
+// MakeOffer - Request a time slot with doctor
+const MakeOffer router.PluginMask = 1 << 10
+
+func init() {
+ b := &router.Plugin{
+ Name: "offer",
+ Run: nil,
+ Validate: offer,
+ }
+ router.AddPlugin(b, MakeOffer)
+}
+
+func offer(s *router.Request) error {
+ return nil
+}
--- /dev/null
+++ b/password.go
@@ -1,0 +1,62 @@
+package plugins
+
+import (
+ "errors"
+
+ "github.com/olmaxmedical/olmax_go/db"
+ "github.com/olmaxmedical/olmax_go/router"
+)
+
+// ValidateLogin - Check user/pass combo exists
+const ValidateLogin router.PluginMask = 1 << 11
+
+// ResetPassword - Update database entry for password
+const ResetPassword router.PluginMask = 1 << 12
+
+func init() {
+ b := &router.Plugin{
+ Name: "login",
+ Run: nil,
+ Validate: login,
+ }
+ router.AddPlugin(b, ValidateLogin)
+ c := &router.Plugin{
+ Name: "setPassword",
+ Run: nil,
+ Validate: setPass,
+ }
+ router.AddPlugin(c, ResetPassword)
+}
+
+func login(s *router.Request) error {
+ r := s.Request()
+ us := s.Session()
+ p := s.Printer()
+ user := r.PostFormValue("email")
+ pass := r.PostFormValue("pass")
+ if db.ValidateLogin(user, pass) {
+ us.Set("username", user)
+ us.Set("login", "true")
+ us.Set("role", db.UserRole(user))
+ us.Set("token", db.NewToken())
+ return nil
+ }
+ return errors.New(p.Sprint("Invalid login"))
+}
+
+func setPass(s *router.Request) error {
+ r := s.Request()
+ p := s.Printer()
+
+ pass := r.PostFormValue("password")
+ repeat := r.PostFormValue("reenter")
+ if pass != repeat {
+ return errors.New(p.Sprint("Passwords do not match"))
+ }
+ token := r.PostFormValue("token")
+ if !db.FindTempEntry(token) {
+ return errors.New(p.Sprint("Session expired"))
+ }
+ db.UpdateUserPassword(token, pass)
+ return nil
+}
--- /dev/null
+++ b/search.go
@@ -1,0 +1,20 @@
+package plugins
+
+import "github.com/olmaxmedical/olmax_go/router"
+
+// Search - generic search for doctors in area
+const Search router.PluginMask = 1 << 13
+
+func init() {
+ b := &router.Plugin{
+ Name: "search",
+ Run: nil,
+ Validate: search,
+ }
+ router.AddPlugin(b, Search)
+}
+
+// Stuuuuubbb
+func search(r *router.Request) error {
+ return nil
+}
--- /dev/null
+++ b/services.go
@@ -1,0 +1,114 @@
+package plugins
+
+import (
+ "fmt"
+
+ "github.com/olmaxmedical/olmax_go/router"
+)
+
+// Services - Bitmask to list services in native language
+const Services router.PluginMask = 1 << 14
+
+func init() {
+ b := &router.Plugin{
+ Name: "specialties",
+ Run: ListServices,
+ Validate: ValidateServices,
+ }
+ router.AddPlugin(b, Services)
+}
+
+// ValidateServices - Ensure the specialties entered exist in our map
+func ValidateServices(r *router.Request) error {
+ s := r.Request()
+ var errs []string
+ for _, entry := range s.PostFormValue("specialty") {
+ switch string(entry) {
+ case "acutepain":
+ case "anasthesiology":
+ case "bariatric":
+ case "cardiology":
+ case "chiropractic":
+ case "chronic":
+ case "critcare":
+ case "dermatology":
+ case "emergency":
+ case "endocrinology":
+ case "otolaringology":
+ case "familymedicine":
+ case "gastro":
+ case "headneck":
+ case "hematology":
+ case "hepatology":
+ case "hyperbaric":
+ case "immunology":
+ case "diseases":
+ case "internal":
+ case "neonatal":
+ case "nephrology":
+ case "neurology":
+ case "neurosurgery":
+ case "obstetrics":
+ case "occupational":
+ case "opthamology":
+ case "orthopedics":
+ case "palliative":
+ case "pediatrics":
+ case "podiatry":
+ case "pulmonology":
+ case "radiology":
+ case "radiation":
+ case "transplants":
+ continue
+ default:
+ errs = append(errs, fmt.Sprintf("Unknown entry: %q\n", entry))
+ }
+ if len(errs) > 0 {
+ return fmt.Errorf("%s", errs)
+ }
+ }
+ return nil
+}
+
+// ListServices - return a list of native language representations of our medical fields
+func ListServices(r *router.Request) map[string]interface{} {
+ p := r.Printer()
+ return map[string]interface{}{
+ "label": p.Sprint("Select specialty/specialties"),
+ "acutepain": p.Sprint("Acute Pain Medicine"),
+ "anesthesiology": p.Sprint("Anesthesiology"),
+ "bariatric": p.Sprint("Bariatric Surgery"),
+ "cardiology": p.Sprint("Cardiology"),
+ "chiropractic": p.Sprint("Chiropractics"),
+ "chronic": p.Sprint("Chronic Pain"),
+ "critcare": p.Sprint("Critical Care"),
+ "dermatology": p.Sprint("Dermatology"),
+ "emergency": p.Sprint("Emergency Medicine"),
+ "endocrinology": p.Sprint("Endocrinology"),
+ "otolaringology": p.Sprint("Ear Nose and Throat"),
+ "familymedicine": p.Sprint("Family Medicine"),
+ "gastro": p.Sprint("Gastrointestinology"),
+ "headneck": p.Sprint("Head and Neck"),
+ "hematology": p.Sprint("Hematology and Oncology"),
+ "hepatology": p.Sprint("Hepatology"),
+ "hyperbaric": p.Sprint("Hyperbaric"),
+ "immunology": p.Sprint("Immunology"),
+ "diseases": p.Sprint("Infectious Diseases"),
+ "internal": p.Sprint("Internal Medicine"),
+ "neonatal": p.Sprint("Neonatology"),
+ "nephrology": p.Sprint("Nephrology"),
+ "neurology": p.Sprint("Neurology"),
+ "neurosurgery": p.Sprint("Neurosurgery"),
+ "obstetrics": p.Sprint("Obstetrics and Gynecology"),
+ "occupational": p.Sprint("Occupational Medicine"),
+ "opthamology": p.Sprint("Opthamology"),
+ "orthopedics": p.Sprint("Orthopedic Surgery"),
+ "palliative": p.Sprint("Palliative Care"),
+ "pediatrics": p.Sprint("Pediatrics"),
+ "podiatry": p.Sprint("Podiatry"),
+ "pulmonology": p.Sprint("Pulmonology"),
+ "radiology": p.Sprint("Radiology"),
+ "radiation": p.Sprint("Radiaton Oncology"),
+ "transplants": p.Sprint("Transplant Surgery"),
+ }
+}
--- /dev/null
+++ b/tokens.go
@@ -1,0 +1,29 @@
+package plugins
+
+import (
+ "github.com/olmaxmedical/olmax_go/db"
+ "github.com/olmaxmedical/olmax_go/router"
+)
+
+// FormToken - A database-persisted one time use token to relate forms to POST requests
+const FormToken router.PluginMask = 1 << 15
+
+func init() {
+ c := &router.Plugin{
+ Name: "formToken",
+ Run: newFormToken,
+ Validate: validateToken,
+ }
+ router.AddPlugin(c, FormToken)
+}
+
+func validateToken(r *router.Request) error {
+ return db.ValidateToken(r.Request(), r.Session())
+}
+
+// TODO(halfwit) - database
+func newFormToken(r *router.Request) map[string]interface{} {
+ return map[string]interface{}{
+ "token": db.NewToken(),
+ }
+}