1// Copyright (C) 2013-2015 Sören Tempel 2// 3// This program is free software: you can redistribute it and/or modify 4// it under the terms of the GNU General Public License as published by 5// the Free Software Foundation, either version 3 of the License, or 6// (at your option) any later version. 7// 8// This program is distributed in the hope that it will be useful, 9// but WITHOUT ANY WARRANTY; without even the implied warranty of 10// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11// GNU General Public License for more details. 12// 13// You should have received a copy of the GNU General Public License 14// along with this program. If not, see <http://www.gnu.org/licenses/>. 15 16package util 17 18import ( 19 "errors" 20 "html" 21 "os" 22 "os/signal" 23 "os/user" 24 "path/filepath" 25 "strings" 26 "unicode" 27) 28 29// Lock creates a lockfile at the given path and creates a signal 30// handler which removes the lockfile on interrupt or kill. 31func Lock(path string) (err error) { 32 _, err = os.OpenFile(path, os.O_CREATE|os.O_EXCL|os.O_RDWR, 0444) 33 if err != nil { 34 return 35 } 36 37 // Setup unlock handler 38 ch := make(chan os.Signal, 1) 39 go func() { 40 <-ch // Block until signal is received 41 os.Remove(path) 42 os.Exit(2) 43 }() 44 signal.Notify(ch, os.Interrupt, os.Kill) 45 46 return 47} 48 49// Escape escapes the given data to make sure it is safe to use it as a 50// filename. It also replaces spaces and other seperation characters 51// with the '-' character. It returns an error if the escaped string is 52// empty. 53func Escape(name string) (escaped string, err error) { 54 mfunc := func(r rune) rune { 55 switch { 56 case unicode.IsLetter(r): 57 return r 58 case unicode.IsNumber(r): 59 return r 60 case unicode.IsSpace(r): 61 return '-' 62 case unicode.IsPunct(r): 63 return '-' 64 } 65 66 return -1 67 } 68 69 escaped = strings.Map(mfunc, html.UnescapeString(name)) 70 for strings.Contains(escaped, "--") { 71 escaped = strings.Replace(escaped, "--", "-", -1) 72 } 73 74 escaped = strings.TrimPrefix(escaped, "-") 75 escaped = strings.TrimSuffix(escaped, "-") 76 77 if len(escaped) <= 0 { 78 err = errors.New("couldn't escape title") 79 } 80 81 return 82} 83 84// EnvDefault returns the value of the given environment variable 85// key if it is not empty. If it is empty it returns the fallback 86// as an absolute path joined with the users home. 87func EnvDefault(key, fallback string) string { 88 dir := os.Getenv(key) 89 if len(dir) > 0 { 90 return dir 91 } 92 93 var home string 94 user, err := user.Current() 95 if err == nil { 96 home = user.HomeDir 97 } else { 98 home = os.Getenv("HOME") 99 }100101 return filepath.Join(home, fallback)102}103104// Username returns the username of the current user. It tries to105// determine the username using os/user first and if that doesn't106// work it returns the value of the USER environment variable.107func Username() string {108 var name string109 user, err := user.Current()110 if err == nil {111 name = user.Username112 } else {113 name = os.Getenv("USER")114 }115116 return name117}