1// Copyright (C) 2013-2015 Sören Tempel2//3// This program is free software: you can redistribute it and/or modify4// it under the terms of the GNU General Public License as published by5// the Free Software Foundation, either version 3 of the License, or6// (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 of10// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the11// GNU General Public License for more details.12//13// You should have received a copy of the GNU General Public License14// along with this program. If not, see <http://www.gnu.org/licenses/>.1516package util1718import (19 "errors"20 "html"21 "os"22 "os/signal"23 "os/user"24 "path/filepath"25 "strings"26 "unicode"27)2829// Lock creates a lockfile at the given path and creates a signal30// 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 return35 }3637 // Setup unlock handler38 ch := make(chan os.Signal, 1)39 go func() {40 <-ch // Block until signal is received41 os.Remove(path)42 os.Exit(2)43 }()44 signal.Notify(ch, os.Interrupt, os.Kill)4546 return47}4849// Escape escapes the given data to make sure it is safe to use it as a50// filename. It also replaces spaces and other seperation characters51// with the '-' character. It returns an error if the escaped string is52// empty.53func Escape(name string) (escaped string, err error) {54 mfunc := func(r rune) rune {55 switch {56 case unicode.IsLetter(r):57 return r58 case unicode.IsNumber(r):59 return r60 case unicode.IsSpace(r):61 return '-'62 case unicode.IsPunct(r):63 return '-'64 }6566 return -167 }6869 escaped = strings.Map(mfunc, html.UnescapeString(name))70 for strings.Contains(escaped, "--") {71 escaped = strings.Replace(escaped, "--", "-", -1)72 }7374 escaped = strings.TrimPrefix(escaped, "-")75 escaped = strings.TrimSuffix(escaped, "-")7677 if len(escaped) <= 0 {78 err = errors.New("couldn't escape title")79 }8081 return82}8384// EnvDefault returns the value of the given environment variable85// key if it is not empty. If it is empty it returns the fallback86// 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 dir91 }9293 var home string94 user, err := user.Current()95 if err == nil {96 home = user.HomeDir97 } 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}