Best K6 code snippet using html.LocalName
pluginmanager.go
Source:pluginmanager.go
...58 pm.stateLock.Lock()59 pm.initialPluginLoadInProgress = true60 mStates, _ := pm.ReadAllInstalledPluginsFromDisk()61 for _, mState := range mStates {62 pm.state[mState.LocalName] = mState63 }64 pm.initialPluginLoadInProgress = false65 pm.updateDcsLuaIndex()6667 pm.stateLock.Unlock()6869 jsonAPI.RegisterType("install_plugin", InstallPluginRequest{})70 jsonAPI.RegisterApiCall("install_plugin", pm.HandleInstallPluginRequest)7172 jsonAPI.RegisterType("remove_plugin", RemovePluginListRequest{})73 jsonAPI.RegisterApiCall("remove_plugin", pm.HandleRemovePluginRequest)7475 jsonAPI.RegisterType("monitor_plugin_list", MonitorPluginListRequest{})76 jsonAPI.RegisterType("plugin_list", PluginList(nil))77 jsonAPI.RegisterApiCall("monitor_plugin_list", pm.HandleMonitorPluginListRequest)7879 jsonAPI.RegisterType("check_for_plugin_updates", CheckForPluginUpdatesRequest{})80 jsonAPI.RegisterApiCall("check_for_plugin_updates", pm.HandleCheckForPluginUpdatesRequest)8182 jsonAPI.RegisterType("apply_plugin_updates", ApplyPluginUpdatesRequest{})83 jsonAPI.RegisterApiCall("apply_plugin_updates", pm.HandleApplyPluginUpdateRequest)8485 pm.registerPluginCatalogApi()8687 return pm, nil88}8990// PluginState describes the current state of a module definition that has been installed91// or is in the process of being installed, updated or removed.92type PluginState struct {93 LocalName string `json:"localName"` // Name of the on-disk folder94 RemoteURL string `json:"remoteURL"` // remote URL (origin)95 CheckedOutCommitHash string `json:"checkedOutCommitHash"` // the commit hash that is currently checked out (HEAD)96 CheckedOutTags []string `json:"checkedOutTags"` // The tags that point to the current HEAD97 CheckedOutBranch string `json:"checkedOutBranch"` // the checked out branch. Empty if in detached head state.98 CanApplyUpdates bool `json:"canApplyUpdates"` // true if HEAD is a branch and the remote branch differs99 Tags []string `json:"tags"` // available tags that can be checked out100 Branches []string `json:"branches"` // available remote branches that can be checked out101 IsManagedManually bool `json:"isManagedManually"` // if true, this repository will not be touched by the plugin manager102 ProgressMessage string `json:"progressMessage"`103 ProgressState string `json:"progressState"` // "", "working", "error", "success"104 IsLoaded bool `json:"isLoaded"` // true if the plugin was loaded correctly105 LoadError string `json:"loadError"` // if IsLoaded is false, this contains the error description106 ModuleDefinitionName string `json:"moduleDefinitionName"`107}108109type MonitorPluginListRequest struct {110}111type PluginList []PluginState112113func (pm *pluginManager) HandleMonitorPluginListRequest(req *MonitorPluginListRequest, responseCh chan<- interface{}, followupCh <-chan interface{}) {114 subscription := make(chan []PluginState)115 go func() {116 defer close(responseCh)117 for newState := range subscription {118 select {119 case responseCh <- PluginList(newState):120 case _, ok := <-followupCh:121 if !ok {122 pm.stateLock.Lock()123 defer pm.stateLock.Unlock()124 delete(pm.stateSubscriptions, subscription)125 return126 }127 }128129 }130 }()131132 pm.stateLock.Lock()133 pm.stateSubscriptions[subscription] = true134 stateCopy := make([]PluginState, 0, len(pm.state))135 names := make([]string, 0, len(pm.state))136 for name := range pm.state {137 names = append(names, name)138 }139 sort.Strings(names)140 for _, name := range names {141 stateCopy = append(stateCopy, *pm.state[name])142 }143 pm.stateLock.Unlock()144 subscription <- stateCopy145146 <-followupCh // wait for connection to be closed147148}149150type RemovePluginListRequest struct {151 LocalName string152}153154func (pm *pluginManager) HandleRemovePluginRequest(req *RemovePluginListRequest, responseCh chan<- interface{}, followupCh <-chan interface{}) {155 defer close(responseCh)156 pm.stateLock.Lock()157 mState, ok := pm.state[req.LocalName]158 if !ok || mState.IsManagedManually {159 pm.stateLock.Unlock()160 responseCh <- jsonapi.ErrorResult{161 Message: "plugin is not installed or is manually managed: " + req.LocalName,162 }163 return164 }165166 if mState.ProgressState == "working" {167 pm.stateLock.Unlock()168 responseCh <- jsonapi.ErrorResult{169 Message: "module definition " + req.LocalName + " is locked by another operation.",170 }171 return172 }173174 mState.ProgressState = "working"175 mState.ProgressMessage = "removing..."176 pm.unloadPlugin(mState)177 pm.notifyStateObservers()178 pm.stateLock.Unlock()179180 err := os.RemoveAll(filepath.Join(pm.CheckoutPath, req.LocalName))181182 pm.stateLock.Lock()183 delete(pm.state, req.LocalName)184 pm.updateDcsLuaIndex()185 pm.notifyStateObservers()186 pm.stateLock.Unlock()187188 if err == nil {189 responseCh <- jsonapi.SuccessResult{}190 } else {191 responseCh <- jsonapi.ErrorResult{192 Message: err.Error(),193 }194 }195}196197type InstallPluginRequest struct {198 RemoteURL string `json:"remoteURL"`199}200201func localNameFromRemoteURL(url *url.URL) string {202 localName := path.Base(url.Path)203 if strings.Trim(localName, ". /\\") == "" {204 return url.String()205 }206 if localName == ".git" {207 localName = path.Base(url.Path)208 }209 localName = strings.TrimSuffix(localName, ".git")210 return localName211}212213func (pm *pluginManager) HandleInstallPluginRequest(req *InstallPluginRequest, responseCh chan<- interface{}, followupCh <-chan interface{}) {214 pm.stateLock.Lock()215216 // check if plugin is already installed217 for _, state := range pm.state {218 if strings.ToLower(state.RemoteURL) == strings.ToLower(req.RemoteURL) {219 pm.stateLock.Unlock()220 responseCh <- jsonapi.ErrorResult{221 Message: "plugin is already installed.",222 }223 close(responseCh)224 return225 }226 }227228 // determine local URL from module name229 url, err := url.Parse(req.RemoteURL)230 if err == nil && !(url.Scheme == "http" || url.Scheme == "https" || url.Scheme == "file") {231 err = errors.New("URL must start with https:// or http:// or file://")232 }233 if err != nil {234 pm.stateLock.Unlock()235 responseCh <- jsonapi.ErrorResult{236 Message: "invalid remote URL: " + req.RemoteURL + ": " + err.Error(),237 }238 close(responseCh)239 return240 }241242 localName := localNameFromRemoteURL(url)243244 // make sure that localName is unique by appending a number if necessary245 suffix := ""246 suffixCnt := 0247 for _, ok := pm.state[localName+suffix]; ok; {248 suffixCnt++249 suffix = strconv.Itoa(suffixCnt)250 }251 localName += suffix252253 pm.state[localName] = &PluginState{254 LocalName: localName,255 ProgressState: "working",256 ProgressMessage: "installing...",257 CheckedOutTags: make([]string, 0),258 Tags: make([]string, 0),259 Branches: make([]string, 0),260 }261 pm.notifyStateObservers()262 pm.stateLock.Unlock()263264 responseCh <- jsonapi.SuccessResult{265 Message: "installing.",266 }267 close(responseCh)268269 err = pm.InstallModuleDefinition(localName, req.RemoteURL)270271 pm.stateLock.Lock()272 defer pm.stateLock.Unlock()273 if err != nil {274 pm.state[localName].ProgressState = "error"275 pm.state[localName].ProgressMessage = err.Error()276 pm.notifyStateObservers()277 }278279 pm.state[localName].ProgressState = "success"280 pm.state[localName].ProgressMessage = "installed."281 pm.notifyStateObservers()282}283284func (pm *pluginManager) ReadSinglePluginStateFromDisk(localName string) (*PluginState, error) {285 repo, err := git.PlainOpen(filepath.Join(pm.CheckoutPath, localName))286 if err != nil {287 return nil, err288 }289 state := &PluginState{290 LocalName: localName,291 CheckedOutTags: make([]string, 0),292 Tags: make([]string, 0),293 Branches: make([]string, 0),294 }295296 // determine remoteURL297 origin, err := repo.Remote(PluginManagerRemoteName)298 if err != nil {299 state.IsManagedManually = true300 } else {301 if len(origin.Config().URLs) == 1 {302 state.RemoteURL = origin.Config().URLs[0]303 }304 }305306 // determine current HEAD state307 head, err := repo.Head()308 if err != nil {309 return nil, err310 }311 if head.Name().IsBranch() {312 state.CheckedOutBranch = head.Name().Short()313 // check remote tracking branch314 if !state.IsManagedManually {315 ref, err := repo.Reference(plumbing.NewRemoteReferenceName(PluginManagerRemoteName, head.Name().Short()), true)316 if err != nil {317 fmt.Printf("error resolving ref: %v\n", err)318 }319 if err == nil {320 if ref.Hash() != head.Hash() {321 state.CanApplyUpdates = true322 }323 }324 }325 } else {326 state.CheckedOutBranch = ""327 }328 state.CheckedOutCommitHash = head.Hash().String()329330 // list tags331 tags, err := repo.Tags()332 if err != nil {333 return nil, err334 }335 tags.ForEach(func(tag *plumbing.Reference) error {336 //fmt.Printf("tag: %v %v %v\n", tag.Target(), tag.Name(), tag.Hash())337 state.Tags = append(state.Tags, tag.Name().Short())338 if tag.Hash() == head.Hash() {339 state.CheckedOutTags = append(state.CheckedOutTags, tag.Name().Short())340 }341 return nil342 })343344 // list branches345 refIter, err := repo.Branches()346 if err != nil {347 return nil, err348 }349 refIter.ForEach(func(branch *plumbing.Reference) error {350 state.Branches = append(state.Branches, branch.Name().Short())351 return nil352 })353354 // determine remote branches355 refs, err := repo.References()356 refs.ForEach(func(ref *plumbing.Reference) error {357 if ref.Name().IsRemote() {358 state.Branches = append(state.Branches, ref.Name().Short())359 }360 return nil361 })362363 type pluginManifest struct {364 ManifestVersion int `json:"manifestVersion"`365 ModuleDefinitionName string `json:"moduleDefinitionName"`366 }367368 // check for manifest369 manifestFilename := filepath.Join(pm.CheckoutPath, localName, "dcs-bios-plugin-manifest.json")370 stat, err := os.Stat(manifestFilename)371 if err == nil && !stat.IsDir() {372 file, err := os.Open(manifestFilename)373 if err == nil {374 defer file.Close()375 dec := json.NewDecoder(file)376 var manifest pluginManifest377 err = dec.Decode(&manifest)378 if err == nil {379 if manifest.ManifestVersion == 1 {380 if manifest.ModuleDefinitionName != "" {381 state.ModuleDefinitionName = manifest.ModuleDefinitionName382 }383 } else {384 state.LoadError = "invalid manifest version"385 }386 }387 }388389 }390391 return state, nil392}393394func (pm *pluginManager) loadPlugin(state *PluginState) {395 if state.ModuleDefinitionName != "" {396 jsonPath := filepath.Join(pm.CheckoutPath, state.LocalName, state.ModuleDefinitionName+".json")397 pm.controlReferenceStore.LoadFile(jsonPath)398 pm.updateDcsLuaIndex()399 }400}401402func (pm *pluginManager) unloadPlugin(state *PluginState) {403 if state.ModuleDefinitionName != "" {404 pm.controlReferenceStore.UnloadModuleDefinition(state.ModuleDefinitionName)405 }406 pm.updateDcsLuaIndex()407 return408}409410// ReadAllInstalledPluginsFromDisk returns a list of currently installed411// module definitions.412func (pm *pluginManager) ReadAllInstalledPluginsFromDisk() ([]*PluginState, error) {413 files, err := ioutil.ReadDir(pm.CheckoutPath)414 if err != nil {415 return nil, err416 }417418 pluginStateList := make([]*PluginState, 0)419 for _, f := range files {420 if !f.IsDir() {421 continue422 }423 state, err := pm.ReadSinglePluginStateFromDisk(f.Name())424 if err != nil {425 return nil, err426 }427 pluginStateList = append(pluginStateList, state)428 pm.loadPlugin(state)429 }430 return pluginStateList, nil431}432433type CheckForPluginUpdatesRequest struct{}434435func (pm *pluginManager) HandleCheckForPluginUpdatesRequest(req *CheckForPluginUpdatesRequest, responseCh chan<- interface{}, followupCh <-chan interface{}) {436 defer close(responseCh)437438 pluginNamesToCheck := make([]string, 0)439 pm.stateLock.Lock()440 for localName, state := range pm.state {441 if state.IsManagedManually { // handle manually managed repositories442 pm.unloadPlugin(state)443 // manual repos: just re-read current state444 newState, err := pm.ReadSinglePluginStateFromDisk(state.LocalName)445 if err != nil {446 state.ProgressState = "error"447 state.ProgressMessage = "failed to read from disk: " + err.Error()448 } else {449 pm.state[state.LocalName] = newState450 pm.loadPlugin(newState)451 }452 continue453 }454455 if state.ProgressState == "working" {456 continue // skip plugins that are already being worked on457 }458 pluginNamesToCheck = append(pluginNamesToCheck, localName)459 state.ProgressState = "working"460 state.ProgressMessage = "wait for update check"461 }462 pm.notifyStateObservers()463 pm.stateLock.Unlock()464465 fetchJobChannel := make(chan string)466 const numConcurrentFetches = 2467 wg := sync.WaitGroup{}468 wg.Add(numConcurrentFetches)469 for i := 0; i < numConcurrentFetches; i++ {470 go func() {471 for localName := range fetchJobChannel {472 pm.stateLock.Lock()473 state := pm.state[localName]474 state.ProgressMessage = "checking for updates"475 pm.notifyStateObservers()476 pm.stateLock.Unlock()477478 err := pm.CheckForUpdates(localName)479 if err == git.NoErrAlreadyUpToDate {480 err = nil481 }482483 pm.stateLock.Lock()484 var newState *PluginState485 if err == nil {486 newState, err = pm.ReadSinglePluginStateFromDisk(localName)487 }488489 if err != nil {490 pm.state[localName].ProgressState = "error"491 pm.state[localName].ProgressMessage = err.Error()492 } else {493 pm.state[localName] = newState494 pm.state[localName].ProgressState = "success"495 }496 pm.notifyStateObservers()497 pm.stateLock.Unlock()498499 }500 }()501502 responseCh <- jsonapi.SuccessResult{503 Message: "started update checks",504 }505 }506507 go func() {508 for _, name := range pluginNamesToCheck {509 fetchJobChannel <- name510 }511 close(fetchJobChannel)512 }()513 wg.Wait()514515}516517func (pm *pluginManager) CheckForUpdates(localName string) error {518 repo, err := git.PlainOpen(filepath.Join(pm.CheckoutPath, localName))519 if err != nil {520 return err521 }522 err = repo.Fetch(&git.FetchOptions{523 RemoteName: PluginManagerRemoteName,524 Tags: git.AllTags,525 })526 if err != nil {527 return err528 }529530 return nil531}532533func (pm *pluginManager) startWorkOnPlugin(localName string, progressMessage string) (state *PluginState, ok bool) {534 pm.stateLock.Lock()535 defer pm.stateLock.Unlock()536 state, ok = pm.state[localName]537 if !ok {538 return nil, false539 }540 if state.ProgressState == "working" {541 return nil, false542 }543 state.ProgressState = "working"544 state.ProgressMessage = progressMessage545 return state, true546}547548func (pm *pluginManager) finishWorkOnPlugin(localName string, progressState, progressMessage string) {549 pm.stateLock.Lock()550 defer pm.stateLock.Unlock()551 state, ok := pm.state[localName]552 if !ok {553 return554 }555 state.ProgressState = progressState556 state.ProgressMessage = progressMessage557 pm.notifyStateObservers()558}559560type ApplyPluginUpdatesRequest struct {561 LocalName string `json:"localName"`562}563564func (pm *pluginManager) HandleApplyPluginUpdateRequest(req *ApplyPluginUpdatesRequest, responseCh chan<- interface{}, followupCh <-chan interface{}) {565 defer close(responseCh)566567 currentState, ok := pm.startWorkOnPlugin(req.LocalName, "applying updates...")568 if !ok {569 responseCh <- jsonapi.ErrorResult{570 Message: "Plugin does not exist or is already in use.",571 }572 return573 }574575 pm.unloadPlugin(currentState)576 err := pm.ApplyUpdates(currentState.LocalName)577578 if err != nil {579 pm.finishWorkOnPlugin(req.LocalName, "error", err.Error())580 responseCh <- jsonapi.ErrorResult{581 Message: err.Error(),582 }583 }584 newState, err := pm.ReadSinglePluginStateFromDisk(req.LocalName)585586 if err != nil {587 pm.finishWorkOnPlugin(req.LocalName, "error", "error re-reading plugin contents:"+err.Error())588 } else {589 pm.stateLock.Lock()590 pm.state[req.LocalName] = newState591 pm.loadPlugin(newState)592 pm.stateLock.Unlock()593594 pm.finishWorkOnPlugin(req.LocalName, "success", "updates applied")595 }596 responseCh <- jsonapi.SuccessResult{}597}598599func (pm *pluginManager) ApplyUpdates(localName string) error {600 repo, err := git.PlainOpen(filepath.Join(pm.CheckoutPath, localName))601 if err != nil {602 return err603 }604605 // determine current HEAD state606 head, err := repo.Head()607 if err != nil {608 return err609 }610 if !head.Name().IsBranch() {611 return errors.New(fmt.Sprintf("Module definition %s is not on a branch.", localName))612 }613 // check remote tracking branch614 ref, err := repo.Reference(plumbing.NewRemoteReferenceName(PluginManagerRemoteName, head.Name().Short()), true)615 if err != nil {616 return errors.New(fmt.Sprintf("error resolving ref: %v\n", err))617 }618 if ref.Hash() == head.Hash() {619 return errors.New(fmt.Sprintf("Module definition %s is already up-to-date.", localName))620 }621 wt, err := repo.Worktree()622 if err != nil {623 return err624 }625626 err = wt.Reset(&git.ResetOptions{627 Commit: ref.Hash(),628 Mode: git.HardReset,629 })630631 if err != nil {632 return err633 }634 return nil635}636637// notifyStateObservers sends a copy of the current state638// to each observer. The caller of this function has to hold the639// stateLock.640func (pm *pluginManager) notifyStateObservers() {641 pluginStateList := make([]PluginState, 0, len(pm.state))642 names := make([]string, 0, len(pm.state))643 for name := range pm.state {644 names = append(names, name)645 }646 sort.Strings(names)647 for _, name := range names {648 pluginStateList = append(pluginStateList, *pm.state[name])649 }650 for sub, _ := range pm.stateSubscriptions {651 select {652 case sub <- pluginStateList:653 case <-time.After(200 * time.Millisecond):654 fmt.Printf("PluginManager: notifyStateObservers(): failed to send state to subscriber\n")655 }656657 }658}659660// InstallModuleDefinition installs a module definition.661func (pm *pluginManager) InstallModuleDefinition(localName string, repoURL string) error {662 clonePath := filepath.Join(pm.CheckoutPath, localName)663 _, err := os.Stat(clonePath)664 if err == nil {665 return errors.New("module definition already installed, folder exists: " + clonePath)666 }667 _, err = git.PlainClone(clonePath, false, &git.CloneOptions{668 URL: repoURL,669 SingleBranch: false,670 RemoteName: PluginManagerRemoteName,671 })672 if err != nil {673 return err674 }675676 pluginState, err := pm.ReadSinglePluginStateFromDisk(localName)677 if err != nil {678 return errors.New("InstallModuleDefinition(): failed to read state after clone: " + err.Error())679 }680681 pm.stateLock.Lock()682 pm.state[localName] = pluginState683 pm.loadPlugin(pluginState)684 pm.notifyStateObservers()685 pm.stateLock.Unlock()686687 return nil688}689690type DcsLuaIndexEntry struct {691 PluginDir string `json:"pluginDir"`692 LuaFile string `json:"luaFile"`693}694695// updateDcsLuaIndex writes a list of all installed plugins696// to CheckoutPath\dcs-lua-index.json697// the caller has to hold the stateLock.698func (pm *pluginManager) updateDcsLuaIndex() {699 if pm.initialPluginLoadInProgress {700 return701 }702703 indexFilename := filepath.Join(pm.CheckoutPath, "dcs-lua-index.json")704 index := make([]DcsLuaIndexEntry, 0)705706 for _, pluginState := range pm.state {707 if pluginState.ModuleDefinitionName != "" {708 index = append(index, DcsLuaIndexEntry{709 PluginDir: filepath.Join(pm.CheckoutPath, pluginState.LocalName) + string(os.PathSeparator),710 LuaFile: filepath.Join(pm.CheckoutPath, pluginState.LocalName, pluginState.ModuleDefinitionName+".lua"),711 })712 }713 }714715 file, _ := os.Create(indexFilename)716 enc := json.NewEncoder(file)717 enc.SetEscapeHTML(false)718 enc.SetIndent("", " ")719 enc.Encode(index)720 file.Close()721722}
...
smtp.go
Source:smtp.go
1package smtp2import (3 "context"4 "crypto/rand"5 "crypto/tls"6 "encoding/hex"7 "fmt"8 "net"9 gosmtp "net/smtp"10 "net/url"11 "strconv"12 "time"13 "github.com/getfider/fider/app/models/cmd"14 "github.com/getfider/fider/app/models/dto"15 "github.com/getfider/fider/app/pkg/bus"16 "github.com/getfider/fider/app/pkg/env"17 "github.com/getfider/fider/app/pkg/errors"18 "github.com/getfider/fider/app/pkg/log"19 "github.com/getfider/fider/app/pkg/web"20 "github.com/getfider/fider/app/services/email"21)22func init() {23 bus.Register(Service{})24}25type Service struct{}26func (s Service) Name() string {27 return "SMTP"28}29func (s Service) Category() string {30 return "email"31}32func (s Service) Enabled() bool {33 return env.Config.Email.Mailgun.APIKey == ""34}35func (s Service) Init() {36 bus.AddListener(sendMail)37}38func sendMail(ctx context.Context, c *cmd.SendMail) {39 if c.Props == nil {40 c.Props = dto.Props{}41 }42 for _, to := range c.To {43 if to.Address == "" {44 return45 }46 u, err := url.Parse(web.BaseURL(ctx))47 localname := "localhost"48 if err == nil {49 localname = u.Hostname()50 }51 if !email.CanSendTo(to.Address) {52 log.Warnf(ctx, "Skipping email to '@{Name} <@{Address}>'.", dto.Props{53 "Name": to.Name,54 "Address": to.Address,55 })56 return57 }58 log.Debugf(ctx, "Sending email to @{Address} with template @{TemplateName} and params @{Props}.", dto.Props{59 "Address": to.Address,60 "TemplateName": c.TemplateName,61 "Props": to.Props,62 })63 message := email.RenderMessage(c.TemplateName, c.Props.Merge(to.Props))64 b := builder{}65 b.Set("From", dto.NewRecipient(c.From, email.NoReply, dto.Props{}).String())66 b.Set("Reply-To", email.NoReply)67 b.Set("To", to.String())68 b.Set("Subject", message.Subject)69 b.Set("MIME-version", "1.0")70 b.Set("Content-Type", "text/html; charset=\"UTF-8\"")71 b.Set("Date", time.Now().Format(time.RFC1123Z))72 b.Set("Message-ID", generateMessageID(localname))73 b.Body(message.Body)74 smtpConfig := env.Config.Email.SMTP75 servername := fmt.Sprintf("%s:%s", smtpConfig.Host, smtpConfig.Port)76 auth := authenticate(smtpConfig.Username, smtpConfig.Password, smtpConfig.Host)77 err = Send(localname, servername, auth, email.NoReply, []string{to.Address}, b.Bytes())78 if err != nil {79 panic(errors.Wrap(err, "failed to send email with template %s", c.TemplateName))80 }81 log.Debug(ctx, "Email sent.")82 }83}84var Send = func(localName, serverAddress string, a gosmtp.Auth, from string, to []string, msg []byte) error {85 host, _, _ := net.SplitHostPort(serverAddress)86 c, err := gosmtp.Dial(serverAddress)87 if err != nil {88 return err89 }90 defer c.Close()91 if err = c.Hello(localName); err != nil {92 return err93 }94 if ok, _ := c.Extension("STARTTLS"); ok {95 config := &tls.Config{ServerName: host}96 if err = c.StartTLS(config); err != nil {97 return err98 }99 }100 if a != nil {101 if ok, _ := c.Extension("AUTH"); !ok {102 return errors.New("smtp: server doesn't support AUTH")103 }104 if err = c.Auth(a); err != nil {105 return err106 }107 }108 if err = c.Mail(from); err != nil {109 return err110 }111 for _, addr := range to {112 if err = c.Rcpt(addr); err != nil {113 return err114 }115 }116 w, err := c.Data()117 if err != nil {118 return err119 }120 _, err = w.Write(msg)121 if err != nil {122 return err123 }124 err = w.Close()125 if err != nil {126 return err127 }128 return c.Quit()129}130func generateMessageID(localName string) string {131 timestamp := strconv.FormatInt(time.Now().UTC().UnixNano(), 10)132 buf := make([]byte, 16)133 _, err := rand.Read(buf)134 if err != nil {135 panic(err)136 }137 randStr := hex.EncodeToString(buf)138 messageID := fmt.Sprintf("<%s.%s@%s>", randStr, timestamp, localName)139 return messageID140}141func authenticate(username string, password string, host string) gosmtp.Auth {142 if username == "" && password == "" {143 return nil144 }145 return AgnosticAuth("", username, password, host)146}147type builder struct {148 content string149}150func (b *builder) Set(key, value string) {151 b.content += fmt.Sprintf("%s: %s\r\n", key, value)152}153func (b *builder) Body(body string) {154 b.content += "\r\n" + body155}156func (b *builder) Bytes() []byte {157 return []byte(b.content)158}...
main.go
Source:main.go
1package main2import (3 "fmt"4 "html/template"5 "os"6 "os/exec"7 "sync"8 "time"9 "github.com/coreos/go-systemd/journal"10 "github.com/fsnotify/fsnotify"11)12func main() {13 paths := os.Args[1:]14 if len(paths) == 0 {15 fmt.Fprintln(os.Stderr, "expecting path(s) to scan")16 os.Exit(2)17 }18 if err := run(paths); err != nil {19 fmt.Fprintln(os.Stderr, "failed to start up: ", err)20 os.Exit(1)21 }22}23const (24 // ScanDelay is how long we wait for file access to be quiescent before25 // initiating a scan.26 ScanDelay = 2 * time.Second27)28// timers map filenames to callbacks that actually perform a scan. The idea is29// to wait for 2s of quiescence before initiating the scan, in case the file is30// in the process of being modified.31var timers struct {32 lock sync.Mutex33 t map[string]*time.Timer34}35// run is the primary runtime function36func run(paths []string) error {37 timers.t = make(map[string]*time.Timer)38 var err error39 if successTpl, err = template.New("success").Parse(successTplT); err != nil {40 return err41 }42 if errorTpl, err = template.New("error").Parse(errorTplT); err != nil {43 return err44 }45 watcher, err := fsnotify.NewWatcher()46 if err != nil {47 return err48 }49 for _, path := range paths {50 if err = watcher.Add(path); err != nil {51 return err52 }53 }54 go func() {55 if err := <-watcher.Errors; err != nil {56 fmt.Fprintln(os.Stderr, "fsnotify error: ", err)57 os.Exit(1)58 }59 }()60 for ev := range watcher.Events {61 localName := ev.Name // don't close over the loop var62 timers.lock.Lock()63 if tmr, already := timers.t[localName]; already {64 // cancel existing timer65 tmr.Stop()66 }67 // start new timer waiting for file access to be quiescent68 timers.t[localName] = time.AfterFunc(ScanDelay, func() {69 scan(localName)70 timers.lock.Lock()71 delete(timers.t, localName)72 timers.lock.Unlock()73 })74 timers.lock.Unlock()75 }76 return nil77}78// scan a file and report the result via dialog.79func scan(name string) {80 jvars := map[string]string{81 "CLAMSCAN_FNAME": name,82 }83 // fsnotify will trigger on removed files, symlinks, directories etc.84 // so filter out those cases85 st, err := os.Lstat(name)86 switch {87 case os.IsNotExist(err):88 journal.Send(fmt.Sprintf("not executing clamscan on %q "+89 "as it was removed", name), journal.PriDebug, jvars)90 return91 case !st.Mode().IsRegular():92 journal.Send(fmt.Sprintf("not executing clamscan on %q "+93 "as it is mode %v", name, st.Mode()),94 journal.PriDebug, jvars)95 return96 }97 jvars["CLAMSCAN_FILESIZE"] = fmt.Sprintf("%d", st.Size())98 journal.Send(fmt.Sprintf("executing clamscan on %q "+99 "(%d bytes)", name, st.Size()),100 journal.PriDebug, jvars)101 clam := exec.Command("clamdscan", name)102 clamOP, err := clam.CombinedOutput()103 status := "success"104 priority := journal.PriNotice105 if err != nil {106 status = err.Error()107 priority = journal.PriAlert108 }109 jvars["CLAMSCAN_STATUS"] = status110 jvars["CLAMSCAN_OUTPUT"] = string(clamOP)111 journal.Send(fmt.Sprintf("clamscan executed on %q with status: %s",112 name, status), priority, jvars)113 dialog(clamOP, err)114}...
LocalName
Using AI Code Generation
1import (2func main() {3 doc, err := html.Parse(os.Stdin)4 if err != nil {5 fmt.Fprintf(os.Stderr, "findlinks1: %v6 os.Exit(1)7 }8 for _, link := range visit(nil, doc) {9 fmt.Println(link)10 }11}12func visit(links []string, n *html.Node) []string {13 if n.Type == html.ElementNode {14 links = append(links, n.Data)15 }16 for c := n.FirstChild; c != nil; c = c.NextSibling {17 links = visit(links, c)18 }19}20import (21func main() {22 doc, err := html.Parse(os.Stdin)23 if err != nil {24 fmt.Fprintf(os.Stderr, "findlinks1: %v25 os.Exit(1)26 }27 for _, link := range visit(nil, doc) {28 fmt.Println(link)29 }30}31func visit(links []string, n *html.Node) []string {32 if n.Type == html.ElementNode && n.Data == "a" {33 for _, a := range n.Attr {34 if a.Key == "href" {35 links = append(links, a.Val)36 }37 }38 }39 for c := n.FirstChild; c != nil; c = c.NextSibling {40 links = visit(links, c)41 }42}43import (
LocalName
Using AI Code Generation
1import (2func main() {3 doc, err := html.Parse(os.Stdin)4 if err != nil {5 fmt.Fprintf(os.Stderr, "findlinks1: %v6 os.Exit(1)7 }8 for _, link := range visit(nil, doc) {9 fmt.Println(link)10 }11}12func visit(links []string, n *html.Node) []string {13 if n.Type == html.ElementNode {14 links = append(links, n.Data)15 }16 for c := n.FirstChild; c != nil; c = c.NextSibling {17 links = visit(links, c)18 }19}
LocalName
Using AI Code Generation
1import (2func main() {3 doc, err := html.Parse(os.Stdin)4 if err != nil {5 fmt.Fprintf(os.Stderr, "findlinks1: %v6 os.Exit(1)7 }8 for _, link := range visit(nil, doc) {9 fmt.Println(link)10 }11}12func visit(links []string, n *html.Node) []string {13 if n.Type == html.ElementNode {14 links = append(links, n.Data)15 }16 for c := n.FirstChild; c != nil; c = c.NextSibling {17 links = visit(links, c)18 }19}
LocalName
Using AI Code Generation
1import (2func main() {3 doc, err := html.Parse(strings.NewReader("<html>"))4 if err != nil {5 fmt.Println(err)6 }7 fmt.Println(doc.Data)8}9import (10func main() {11 doc, err := html.Parse(strings.NewReader("<html id='id'>"))12 if err != nil {13 fmt.Println(err)14 }15 fmt.Println(doc.Attr[0].Key, doc.Attr[0].Val)16}17import (18func main() {19 doc, err := html.Parse(strings.NewReader("<html><body><p>hello</p></body></html>"))20 if err != nil {21 fmt.Println(err)22 }23 fmt.Println(node.Data)24}25import (26func main() {27 doc, err := html.Parse(strings.NewReader("<html><body><p>hello</p></body></html>"))28 if err != nil {29 fmt.Println(err)30 }31 fmt.Println(node.Data)32}33import (34func main() {35 doc, err := html.Parse(strings.NewReader("<html><body><p>hello</p></body></html>"))36 if err != nil {37 fmt.Println(err)38 }39 fmt.Println(node.Data)40}41import (
LocalName
Using AI Code Generation
1import (2func main() {3 doc, err := html.Parse(strings.NewReader("<html><head><title>My Title</title></head><body><h1>My Title</h1></body></html>"))4 if err != nil {5 fmt.Println(err)6 }7 fmt.Println(doc.FirstChild.FirstChild.Data)8}9Recommended Posts: HTML | DOM - getElementsByTagName()10HTML | DOM - getAttribute()11HTML | DOM - getAttributeNode()12HTML | DOM - getAttributeNodeNS()13HTML | DOM - getAttributeNS()14HTML | DOM - getElementsByClassName()15HTML | DOM - getElementsByTagNameNS()16HTML | DOM - getElementsByTagName()17HTML | DOM - hasAttribute()18HTML | DOM - hasAttributeNS()19HTML | DOM - hasAttributes()20HTML | DOM - hasChildNodes()21HTML | DOM - insertBefore()22HTML | DOM - isDefaultNamespace()23HTML | DOM - isEqualNode()24HTML | DOM - isSameNode()25HTML | DOM - isSupported()26HTML | DOM - normalize()27HTML | DOM - removeAttribute()28HTML | DOM - removeAttributeNode()29HTML | DOM - removeAttributeNS()30HTML | DOM - removeChild()31HTML | DOM - replaceChild()32HTML | DOM - setAttribute()33HTML | DOM - setAttributeNode()34HTML | DOM - setAttributeNodeNS()35HTML | DOM - setAttributeNS()36HTML | DOM - setNodeValue()37HTML | DOM - setPrefix()38HTML | DOM - setUserData()39HTML | DOM - setXmlVersion()40HTML | DOM - splitText()41HTML | DOM - supports()42HTML | DOM - swapNode()43HTML | DOM - toLowerCase()44HTML | DOM - toUpperCase()45HTML | DOM - toString()46HTML | DOM - toXmlString()47HTML | DOM - transformNode()48HTML | DOM - transformNodeToObject()49HTML | DOM - uniqueID()50HTML | DOM - unselectable()51HTML | DOM - updateSettings()52HTML | DOM - validate()53HTML | DOM - xml()54HTML | DOM - xmlEncoding()55HTML | DOM - xmlStandalone()56HTML | DOM - xmlVersion()57HTML | DOM - doctype()58HTML | DOM - documentElement()59HTML | DOM - documentMode()60HTML | DOM - documentURI()61HTML | DOM - documentURIObject()
LocalName
Using AI Code Generation
1import (2func main() {3 doc, err := html.Parse(strings.NewReader("<html><head><title>My Title</title></head></html>"))4 if err != nil {5 fmt.Println(err)6 }7 fmt.Println(doc.FirstChild.Data)8}
LocalName
Using AI Code Generation
1import (2func main() {3 if f, err = os.Open("test.html"); err != nil {4 fmt.Println(err)5 }6 defer f.Close()7 doc, err := html.Parse(f)8 if err != nil {9 fmt.Println(err)10 }11 var f1 func(*html.Node)12 f1 = func(n *html.Node) {13 if n.Type == html.ElementNode {14 fmt.Println(n.Data)15 }16 for c := n.FirstChild; c != nil; c = c.NextSibling {17 f1(c)18 }19 }20 f1(doc)21}
Learn to execute automation testing from scratch with LambdaTest Learning Hub. Right from setting up the prerequisites to run your first automation test, to following best practices and diving deeper into advanced test scenarios. LambdaTest Learning Hubs compile a list of step-by-step guides to help you be proficient with different test automation frameworks i.e. Selenium, Cypress, TestNG etc.
You could also refer to video tutorials over LambdaTest YouTube channel to get step by step demonstration from industry experts.
Get 100 minutes of automation test minutes FREE!!