Backend: Code clean-up

Signed-off-by: Michael Mayer <michael@liquidbytes.net>
This commit is contained in:
Michael Mayer 2020-05-03 18:00:50 +02:00
parent c474ec5dd2
commit 2032b40f2b
33 changed files with 145 additions and 134 deletions

4
go.mod
View file

@ -27,7 +27,6 @@ require (
github.com/gosimple/slug v1.9.0
github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de4 // indirect
github.com/grpc-ecosystem/grpc-gateway v1.5.1 // indirect
github.com/guregu/null v3.4.0+incompatible // indirect
github.com/jinzhu/gorm v1.9.5
github.com/kardianos/osext v0.0.0-20190222173326-2bc1f35cddc0 // indirect
github.com/karrick/godirwalk v1.15.6
@ -59,7 +58,6 @@ require (
github.com/sirupsen/logrus v1.5.0
github.com/soheilhy/cmux v0.1.4 // indirect
github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72 // indirect
github.com/stretchr/objx v0.2.0 // indirect
github.com/stretchr/testify v1.5.1
github.com/studio-b12/gowebdav v0.0.0-20200303150724-9380631c29a1
github.com/tensorflow/tensorflow v1.15.2
@ -79,7 +77,7 @@ require (
golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5
golang.org/x/sys v0.0.0-20200501052902-10377860bb8e // indirect
golang.org/x/time v0.0.0-20200416051211-89c76fbcd5d1 // indirect
golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d
golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d // indirect
gopkg.in/stretchr/testify.v1 v1.2.2 // indirect
gopkg.in/ugjka/go-tz.v2 v2.0.9
gopkg.in/yaml.v2 v2.2.8

40
go.sum
View file

@ -15,8 +15,6 @@ github.com/apache/thrift v0.0.0-20161221203622-b2a4d4ae21c7 h1:Fv9bK1Q+ly/ROk4aJ
github.com/apache/thrift v0.0.0-20161221203622-b2a4d4ae21c7/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ=
github.com/apache/thrift v0.12.0 h1:pODnxUFNcjP9UTLZGTdeh+j16A8lJbRvD3rOtrk/7bs=
github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ=
github.com/araddon/dateparse v0.0.0-20190622164848-0fb0a474d195 h1:c4mLfegoDw6OhSJXTd2jUEQgZUQuJWtocudb97Qn9EM=
github.com/araddon/dateparse v0.0.0-20190622164848-0fb0a474d195/go.mod h1:SLqhdZcd+dF3TEVL2RMoob5bBP5R1P1qkox+HtCBgGI=
github.com/araddon/dateparse v0.0.0-20200409225146-d820a6159ab1 h1:TEBmxO80TM04L8IuMWk77SGL1HomBmKTdzdJLLWznxI=
github.com/araddon/dateparse v0.0.0-20200409225146-d820a6159ab1/go.mod h1:SLqhdZcd+dF3TEVL2RMoob5bBP5R1P1qkox+HtCBgGI=
github.com/beorn7/perks v0.0.0-20160229213445-3ac7bf7a47d1/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
@ -138,12 +136,6 @@ github.com/golang/protobuf v1.3.3 h1:gyjaxf+svBWX08ZjK86iN9geUJF0H6gp2IRKX6Nf6/I
github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
github.com/golang/protobuf v1.3.5 h1:F768QJ1E9tib+q5Sc8MkdJi1RxLTbRcTf8LJV56aRls=
github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk=
github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=
github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=
github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs=
github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w=
github.com/golang/protobuf v1.4.0 h1:oOuy+ugB+P/kBdUnG5QaMXSIyJ1q38wWSojYCb3z5VQ=
github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db h1:woRePGFeVFfLKN/pOkfl+p/TAqKOfFu+7KPlMVpok/w=
github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
github.com/golang/snappy v0.0.1 h1:Qgr9rKW7uDUkrbSmQeiDsGa8SjGyCOGtuasMWwvp2P4=
@ -153,10 +145,6 @@ github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c h1:964Od4U6p2jUkFxvCy
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
github.com/google/go-cmp v0.2.0 h1:+dTQ8DZQJz0Mb/HjFlkptS1FeQ4cWSnN941F8aEG4SQ=
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/google/go-cmp v0.3.1 h1:Xye71clBPdm5HgqGwUkwhbynsUJZhDbS20FvLhQ2izg=
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
github.com/google/open-location-code/go v0.0.0-20191230190541-a6eb95b4d2f9 h1:6ILzS4n0F17S38XvOB1BcyzB+0BtVzU77EyuMtkMffo=
@ -182,8 +170,6 @@ github.com/grpc-ecosystem/go-grpc-prometheus v0.0.0-20160910222444-6b7015e65d36/
github.com/grpc-ecosystem/grpc-gateway v1.4.1/go.mod h1:RSKVYQBd5MCa4OVpNdGskqpgL2+G+NZTnrVHpWWfpdw=
github.com/grpc-ecosystem/grpc-gateway v1.5.1 h1:3scN4iuXkNOyP98jF55Lv8a9j1o/IwvnDIZ0LHJK1nk=
github.com/grpc-ecosystem/grpc-gateway v1.5.1/go.mod h1:RSKVYQBd5MCa4OVpNdGskqpgL2+G+NZTnrVHpWWfpdw=
github.com/guregu/null v3.4.0+incompatible h1:a4mw37gBO7ypcBlTJeZGuMpSxxFTV9qFfFKgWxQSGaM=
github.com/guregu/null v3.4.0+incompatible/go.mod h1:ePGpQaN9cw0tj45IR5E5ehMvsFlLlQZAkkOXZurJ3NM=
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI=
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
@ -327,8 +313,6 @@ github.com/satori/go.uuid v1.2.0 h1:0uYX9dsZ2yD7q2RtLRtPSdGDWzjeM3TbMJP9utgA0ww=
github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0=
github.com/sevlyar/go-daemon v0.1.5 h1:Zy/6jLbM8CfqJ4x4RPr7MJlSKt90f00kNM1D401C+Qk=
github.com/sevlyar/go-daemon v0.1.5/go.mod h1:6dJpPatBT9eUwM5VCw9Bt6CdX9Tk6UWvhW3MebLDRKE=
github.com/shopspring/decimal v0.0.0-20191130220710-360f2bc03045 h1:8CnFGhoe92Izugjok8nZEGYCNovJwdRFYwrEiLtG6ZQ=
github.com/shopspring/decimal v0.0.0-20191130220710-360f2bc03045/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o=
github.com/shopspring/decimal v1.2.0 h1:abSATXmQEYyShuxI4/vyW3tV1MrKAJzCZ/0zLUXYbsQ=
github.com/shopspring/decimal v1.2.0/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o=
github.com/shurcooL/sanitized_anchor_name v1.0.0 h1:PdmoCO6wvbs+7yrJyMORt4/BmY5IYyJwS/kOiWx8mHo=
@ -346,8 +330,6 @@ github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasO
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.1.1 h1:2vfRuCMp5sSVIDSqO8oNnWJq7mPa6KVP3iPIwFBuy8A=
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.2.0 h1:Hbg2NidpLE8veEBkEZTL3CvlkUIVzuU9jDplZO54c48=
github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE=
github.com/stretchr/testify v1.2.2 h1:bSDNvY7ZPG5RlJ8otE/7V6gMiyenm9RtJ7IUVIAoJ1w=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q=
@ -389,8 +371,6 @@ github.com/ugorji/go v1.1.7 h1:/68gy2h+1mWMrwZFeD1kQialdSzAb432dtpeJ42ovdo=
github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw=
github.com/ugorji/go/codec v1.1.7 h1:2SvQaVZ1ouYrrKKwoSk2pzd4A9evlKJb9oTL+OaLUSs=
github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY=
github.com/ulule/deepcopier v0.0.0-20200117111125-792cfb847af8 h1:iCslye9fWwp1ExDu06BcKM8/gjDRAlX9DBL+T8CjuWU=
github.com/ulule/deepcopier v0.0.0-20200117111125-792cfb847af8/go.mod h1:wUZg40sMUnY+1FU5F9rZwwCruLb8h1bHF8HzI09kgok=
github.com/ulule/deepcopier v0.0.0-20200430083143-45decc6639b6 h1:TtyC78WMafNW8QFfv3TeP3yWNDG+uxNkk9vOrnDu6JA=
github.com/ulule/deepcopier v0.0.0-20200430083143-45decc6639b6/go.mod h1:h8272+G2omSmi30fBXiZDMkmHuOgonplfKIKjQWzlfs=
github.com/unrolled/render v0.0.0-20171102162132-65450fb6b2d3/go.mod h1:tu82oB5W2ykJRVioYsB+IQKcft7ryBr7w12qMBUPyXg=
@ -416,15 +396,11 @@ golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnf
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20190325154230-a5d413f7728c/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20200323165209-0ec3e9974c59 h1:3zb4D3T4G8jdExgVU/95+vQXfpEPiMdCaZgmGVxjNHM=
golang.org/x/crypto v0.0.0-20200323165209-0ec3e9974c59/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20200429183012-4b2356b1ed79 h1:IaQbIIB2X/Mp/DKctl6ROxz1KyMlKp4uyvL6+kQ7C88=
golang.org/x/crypto v0.0.0-20200429183012-4b2356b1ed79/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/image v0.0.0-20191009234506-e7c1f5e7dbb8 h1:hVwzHzIUGRjiF7EcUjqNxk3NCfkPxbDKRdnNE1Rpg0U=
golang.org/x/image v0.0.0-20191009234506-e7c1f5e7dbb8/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
golang.org/x/image v0.0.0-20200119044424-58c23975cae1 h1:5h3ngYt7+vXCDZCup/HkCQgW5XwmSvR/nA2JmJ0RErg=
golang.org/x/image v0.0.0-20200119044424-58c23975cae1/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
golang.org/x/image v0.0.0-20200430140353-33d19683fad8 h1:6WW6V3x1P/jokJBpRQYUJnMHRP6isStQwCozxnU7XQw=
golang.org/x/image v0.0.0-20200430140353-33d19683fad8/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
@ -446,8 +422,6 @@ golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553 h1:efeOvDhwQ29Dj3SdAV/MJf8ou
golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200320220750-118fecf932d8/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200421231249-e086a090c8fd h1:QPwSajcTUrFriMF1nJ3XzgoqakqQEsnZf9LdXdi2nkI=
golang.org/x/net v0.0.0-20200421231249-e086a090c8fd/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5 h1:WQ8q63x+f/zpC8Ac1s9wLElVoHhm32p6tudrU72n1QA=
golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
@ -470,8 +444,6 @@ golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20200116001909-b77594299b42 h1:vEOn+mP2zCOVzKckCZy6YsCtDblrpj/w7B9nxGNELpg=
golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200331124033-c3d80250170d h1:nc5K6ox/4lTFbMVSL9WRR81ixkcwXThoiF6yf+R9scA=
golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200501052902-10377860bb8e h1:hq86ru83GdWTlfQFZGO4nZJTU4Bs2wfHl8oFHRaXsfc=
golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg=
@ -482,8 +454,6 @@ golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c h1:fqgJT0MGcGpPgpWU7VRdRjuArfcOvC4AoJmILihzhDg=
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20191024005414-555d28b269f0 h1:/5xXl8Y5W96D+TtHSlonuFqGHIWVuyCkGJLwGh9JJFs=
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20200416051211-89c76fbcd5d1 h1:NusfzzA6yGQ+ua51ck7E3omNUX/JuqbFSaRGqU8CcLI=
golang.org/x/time v0.0.0-20200416051211-89c76fbcd5d1/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
@ -495,8 +465,6 @@ golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3
golang.org/x/tools v0.0.0-20190312170243-e65039ee4138 h1:H3uGjxCR/6Ds0Mjgyp7LMK81+LvmbvWWEnJhzk1Pi9E=
golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20200401192744-099440627f01 h1:ysQJ/fU6laLOZJseIeOqXl6Mo+lw5z6b7QHnmUKjW+k=
golang.org/x/tools v0.0.0-20200401192744-099440627f01/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d h1:lzLdP95xJmMpwQ6LUHwrc5V7js93hTiY7gkznu0BgmY=
golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
@ -516,12 +484,6 @@ google.golang.org/grpc v1.17.0 h1:TRJYBgMclJvGYn2rIMjj+h9KtMt5r1Ij7ODVRIZkwhk=
google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs=
google.golang.org/grpc v1.19.0 h1:cfg4PD8YEdSFnm7qLV4++93WcmhH2nIUhMjhdCvl3j8=
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE=
google.golang.org/protobuf v1.21.0 h1:qdOKuR/EIArgaWNjetjgTzgVTAZ+S/WXVrq9HW9zimw=
google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo=
gopkg.in/alecthomas/gometalinter.v2 v2.0.12/go.mod h1:NDRytsqEZyolNuAgTzJkZMkSQM7FIKyzVzGhjB/qfYo=
gopkg.in/alecthomas/kingpin.v2 v2.2.6 h1:jMFz6MfLP0/4fUyZle81rXUoxOBFi19VUFKVDOQfozc=
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
@ -537,8 +499,6 @@ gopkg.in/stretchr/testify.v1 v1.2.2 h1:yhQC6Uy5CqibAIlk1wlusa/MJ3iAN49/BsR/dCCKz
gopkg.in/stretchr/testify.v1 v1.2.2/go.mod h1:QI5V/q6UbPmuhtm10CaFZxED9NreB8PnFYN9JcR6TxU=
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
gopkg.in/ugjka/go-tz.v2 v2.0.8 h1:EmQ1tY6aa9upe1EDqyPdyHgM9STimr2fw7+b/CuMQ94=
gopkg.in/ugjka/go-tz.v2 v2.0.8/go.mod h1:l93M5EnjrSTTaABtGKIqNcl+z08IYbVDS7v1VA8+PgU=
gopkg.in/ugjka/go-tz.v2 v2.0.9 h1:2ECB40UPBRJ6G53XE6zf7LMsiI038orvYfJKx/eir3g=
gopkg.in/ugjka/go-tz.v2 v2.0.9/go.mod h1:1iX2y1/xUdZjNIyGW/dLRRinbWrntuHYc9oIkGWFvz4=
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=

View file

@ -96,7 +96,7 @@ func CreateAlbum(router *gin.RouterGroup, conf *config.Config) {
if res := conf.Db().Create(m); res.Error != nil {
log.Error(res.Error.Error())
c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"error": fmt.Sprintf("\"%s\" already exists", m.AlbumName)})
c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"error": fmt.Sprintf("%s already exists", txt.Quote(m.AlbumName))})
return
}
@ -180,7 +180,7 @@ func DeleteAlbum(router *gin.RouterGroup, conf *config.Config) {
conf.Db().Delete(&m)
event.Publish("config.updated", event.Data(conf.ClientConfig()))
event.Success(fmt.Sprintf("album \"%s\" deleted", m.AlbumName))
event.Success(fmt.Sprintf("album %s deleted", txt.Quote(m.AlbumName)))
c.JSON(http.StatusOK, m)
})
@ -396,16 +396,15 @@ func DownloadAlbum(router *gin.RouterGroup, conf *config.Config) {
c.AbortWithStatusJSON(http.StatusInternalServerError, gin.H{"error": txt.UcFirst("failed to create zip file")})
return
}
log.Infof("album: added \"%s\" as \"%s\"", f.FileName, fileAlias)
log.Infof("album: added %s as %s", txt.Quote(f.FileName), txt.Quote(fileAlias))
} else {
log.Warnf("album: \"%s\" is missing", f.FileName)
log.Warnf("album: %s is missing", txt.Quote(f.FileName))
f.FileMissing = true
conf.Db().Save(&f)
}
}
log.Infof("album: archive \"%s\" created in %s", zipBaseName, time.Since(start))
log.Infof("album: archive %s created in %s", txt.Quote(zipBaseName), time.Since(start))
zipWriter.Close()
newZipFile.Close()
@ -420,7 +419,7 @@ func DownloadAlbum(router *gin.RouterGroup, conf *config.Config) {
c.File(zipFileName)
if err := os.Remove(zipFileName); err != nil {
log.Errorf("album: could not remove \"%s\" %s", zipFileName, err.Error())
log.Errorf("album: could not remove %s (%s)", txt.Quote(zipFileName), err.Error())
}
})
}

View file

@ -56,10 +56,10 @@ func StartImport(router *gin.RouterGroup, conf *config.Config) {
var opt photoprism.ImportOptions
if f.Move {
event.Info(fmt.Sprintf("moving files from \"%s\"", filepath.Base(path)))
event.Info(fmt.Sprintf("moving files from %s", txt.Quote(filepath.Base(path))))
opt = photoprism.ImportOptionsMove(path)
} else {
event.Info(fmt.Sprintf("copying files from \"%s\"", filepath.Base(path)))
event.Info(fmt.Sprintf("copying files from %s", txt.Quote(filepath.Base(path))))
opt = photoprism.ImportOptionsCopy(path)
}
@ -67,9 +67,9 @@ func StartImport(router *gin.RouterGroup, conf *config.Config) {
if subPath != "" && path != conf.ImportPath() && fs.IsEmpty(path) {
if err := os.Remove(path); err != nil {
log.Errorf("import: could not deleted empty directory \"%s\": %s", path, err)
log.Errorf("import: could not deleted empty directory %s: %s", txt.Quote(path), err)
} else {
log.Infof("import: deleted empty directory \"%s\"", path)
log.Infof("import: deleted empty directory %s", txt.Quote(path))
}
}

View file

@ -34,7 +34,7 @@ func StartIndexing(router *gin.RouterGroup, conf *config.Config) {
path := conf.OriginalsPath()
event.Info(fmt.Sprintf("indexing photos in \"%s\"", filepath.Base(path)))
event.Info(fmt.Sprintf("indexing photos in %s", txt.Quote(filepath.Base(path))))
cancel := func(err error) {
log.Error(err.Error())

View file

@ -175,7 +175,7 @@ func LabelThumbnail(router *gin.RouterGroup, conf *config.Config) {
thumbType, ok := thumb.Types[typeName]
if !ok {
log.Errorf("label: invalid thumb type \"%s\"", typeName)
log.Errorf("label: invalid thumb type %s", txt.Quote(typeName))
c.Data(http.StatusOK, "image/svg+xml", labelIconSvg)
return
}

View file

@ -10,6 +10,7 @@ import (
"github.com/photoprism/photoprism/internal/query"
"github.com/photoprism/photoprism/internal/thumb"
"github.com/photoprism/photoprism/pkg/fs"
"github.com/photoprism/photoprism/pkg/txt"
)
// GET /api/v1/thumbnails/:hash/:type
@ -25,7 +26,7 @@ func GetThumbnail(router *gin.RouterGroup, conf *config.Config) {
thumbType, ok := thumb.Types[typeName]
if !ok {
log.Errorf("photo: invalid thumb type \"%s\"", typeName)
log.Errorf("photo: invalid thumb type %s", txt.Quote(typeName))
c.Data(http.StatusBadRequest, "image/svg+xml", photoIconSvg)
return
}

View file

@ -55,7 +55,7 @@ func Upload(router *gin.RouterGroup, conf *config.Config) {
for _, file := range files {
filename := path.Join(p, filepath.Base(file.Filename))
log.Debugf("upload: saving file \"%s\"", file.Filename)
log.Debugf("upload: saving file %s", txt.Quote(file.Filename))
if err := c.SaveUploadedFile(file, filename); err != nil {
c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"error": txt.UcFirst(err.Error())})
@ -82,7 +82,7 @@ func Upload(router *gin.RouterGroup, conf *config.Config) {
continue
}
log.Infof("nsfw: \"%s\" might be offensive", filename)
log.Infof("nsfw: %s might be offensive", txt.Quote(filename))
containsNSFW = true
}
@ -90,7 +90,7 @@ func Upload(router *gin.RouterGroup, conf *config.Config) {
if containsNSFW {
for _, filename := range uploads {
if err := os.Remove(filename); err != nil {
log.Errorf("nsfw: could not delete \"%s\"", filename)
log.Errorf("nsfw: could not delete %s", txt.Quote(filename))
}
}

View file

@ -90,9 +90,9 @@ func CreateZip(router *gin.RouterGroup, conf *config.Config) {
c.AbortWithStatusJSON(http.StatusInternalServerError, gin.H{"error": txt.UcFirst("failed to create zip file")})
return
}
log.Infof("zip: added \"%s\" as \"%s\"", f.FileName, fileAlias)
log.Infof("zip: added %s as %s", txt.Quote(f.FileName), txt.Quote(fileAlias))
} else {
log.Warnf("zip: \"%s\" is missing", f.FileName)
log.Warnf("zip: %s is missing", txt.Quote(f.FileName))
f.FileMissing = true
conf.Db().Save(&f)
}
@ -100,7 +100,7 @@ func CreateZip(router *gin.RouterGroup, conf *config.Config) {
elapsed := int(time.Since(start).Seconds())
log.Infof("zip: archive \"%s\" created in %s", zipBaseName, time.Since(start))
log.Infof("zip: archive %s created in %s", txt.Quote(zipBaseName), time.Since(start))
c.JSON(http.StatusOK, gin.H{"message": fmt.Sprintf("zip created in %d s", elapsed), "filename": zipBaseName})
})
@ -124,7 +124,7 @@ func DownloadZip(router *gin.RouterGroup, conf *config.Config) {
c.File(zipFileName)
if err := os.Remove(zipFileName); err != nil {
log.Errorf("zip: could not remove \"%s\" %s", zipFileName, err.Error())
log.Errorf("zip: could not remove %s (%s)", txt.Quote(zipFileName), err.Error())
}
})
}

View file

@ -12,6 +12,7 @@ import (
"unicode"
"github.com/photoprism/photoprism/pkg/fs"
"github.com/photoprism/photoprism/pkg/txt"
"gopkg.in/yaml.v2"
)
@ -33,7 +34,7 @@ func main() {
fileName := "rules.yml"
if !fs.FileExists(fileName) {
log.Panicf("tensorflow: label rules file not found in \"%s\"", filepath.Base(fileName))
log.Panicf("tensorflow: label rules file not found in %s", txt.Quote(filepath.Base(fileName)))
}
yamlConfig, err := ioutil.ReadFile(fileName)

View file

@ -14,6 +14,7 @@ import (
"strings"
"github.com/disintegration/imaging"
"github.com/photoprism/photoprism/pkg/txt"
tf "github.com/tensorflow/tensorflow/tensorflow/go"
)
@ -142,7 +143,7 @@ func (t *TensorFlow) loadModel() error {
modelPath := path.Join(t.modelsPath, t.modelName)
log.Infof("tensorflow: loading image classification model from \"%s\"", filepath.Base(modelPath))
log.Infof("tensorflow: loading image classification model from %s", txt.Quote(filepath.Base(modelPath)))
// Load model
model, err := tf.LoadSavedModel(modelPath, t.modelTags, nil)

View file

@ -5,14 +5,15 @@ import (
"github.com/photoprism/photoprism/internal/config"
"github.com/photoprism/photoprism/internal/service"
"github.com/photoprism/photoprism/pkg/txt"
"github.com/urfave/cli"
)
// ResampleCommand is used to register the thumbs cli command
var ResampleCommand = cli.Command{
Name: "resample",
Name: "resample",
Aliases: []string{"thumbs"},
Usage: "Pre-renders thumbnails (significantly reduces memory and cpu usage)",
Usage: "Pre-renders thumbnails (significantly reduces memory and cpu usage)",
Flags: []cli.Flag{
cli.BoolFlag{
Name: "force, f",
@ -33,7 +34,7 @@ func resampleAction(ctx *cli.Context) error {
return err
}
log.Infof("creating thumbnails in \"%s\"", conf.ThumbnailsPath())
log.Infof("creating thumbnails in %s", txt.Quote(conf.ThumbnailsPath()))
rs := service.Resample()

View file

@ -14,6 +14,7 @@ import (
"github.com/photoprism/photoprism/internal/service"
"github.com/photoprism/photoprism/internal/workers"
"github.com/photoprism/photoprism/pkg/fs"
"github.com/photoprism/photoprism/pkg/txt"
"github.com/sevlyar/go-daemon"
"github.com/urfave/cli"
)
@ -104,7 +105,7 @@ func startAction(ctx *cli.Context) error {
if child != nil {
if !fs.Overwrite(conf.PIDFilename(), []byte(strconv.Itoa(child.Pid))) {
log.Fatalf("failed writing process id to \"%s\"", conf.PIDFilename())
log.Fatalf("failed writing process id to %s", txt.Quote(conf.PIDFilename()))
}
log.Infof("daemon started with process id %v\n", child.Pid)

View file

@ -4,6 +4,7 @@ import (
"syscall"
"github.com/photoprism/photoprism/internal/config"
"github.com/photoprism/photoprism/pkg/txt"
"github.com/sevlyar/go-daemon"
"github.com/urfave/cli"
)
@ -20,7 +21,7 @@ var StopCommand = cli.Command{
func stopAction(ctx *cli.Context) error {
conf := config.NewConfig(ctx)
log.Infof("looking for pid in \"%s\"", conf.PIDFilename())
log.Infof("looking for pid in %s", txt.Quote(conf.PIDFilename()))
dcxt := new(daemon.Context)
dcxt.PidFileName = conf.PIDFilename()

View file

@ -7,6 +7,7 @@ import (
"path/filepath"
"github.com/photoprism/photoprism/pkg/fs"
"github.com/photoprism/photoprism/pkg/txt"
)
func findExecutable(configBin, defaultBin string) (result string) {
@ -31,9 +32,9 @@ func findExecutable(configBin, defaultBin string) (result string) {
func (c *Config) CreateDirectories() error {
createError := func(path string, err error) (result error) {
if fs.FileExists(path) {
result = fmt.Errorf("\"%s\" is a file, not a directory: please check your configuration", path)
result = fmt.Errorf("%s is a file, not a directory: please check your configuration", txt.Quote(path))
} else {
result = fmt.Errorf("can't create \"%s\": please check configuration and permissions", path)
result = fmt.Errorf("can't create %s: please check configuration and permissions", txt.Quote(path))
}
log.Debug(err)

View file

@ -6,6 +6,7 @@ import (
"os"
"github.com/photoprism/photoprism/pkg/fs"
"github.com/photoprism/photoprism/pkg/txt"
"gopkg.in/yaml.v2"
)
@ -88,7 +89,7 @@ func (s *Settings) Propagate() {
// Load uses a yaml config file to initiate the configuration entity.
func (s *Settings) Load(fileName string) error {
if !fs.FileExists(fileName) {
return fmt.Errorf("settings file not found: \"%s\"", fileName)
return fmt.Errorf("settings file not found: %s", txt.Quote(fileName))
}
yamlConfig, err := ioutil.ReadFile(fileName)

View file

@ -332,7 +332,7 @@ func (m *Photo) UpdateTitle(labels classify.Labels) error {
loc := m.Location
if title := labels.Title(loc.Name()); title != "" { // TODO: User defined title format
log.Infof("photo: using label \"%s\" to create photo title", title)
log.Infof("photo: using label %s to create photo title", txt.Quote(title))
if loc.NoCity() || loc.LongCity() || loc.CityContains(title) {
m.SetTitle(fmt.Sprintf("%s / %s / %s", txt.Title(title), loc.CountryName(), m.TakenAt.Format("2006")), SrcAuto)
} else {
@ -364,9 +364,9 @@ func (m *Photo) UpdateTitle(labels classify.Labels) error {
m.SetTitle("Unknown", SrcAuto)
}
log.Infof("photo: changed photo title to \"%s\"", m.PhotoTitle)
log.Infof("photo: changed photo title to %s", txt.Quote(m.PhotoTitle))
} else {
log.Infof("photo: new title is \"%s\"", m.PhotoTitle)
log.Infof("photo: new title is %s", txt.Quote(m.PhotoTitle))
}
return nil

View file

@ -5,6 +5,7 @@ import (
"github.com/jinzhu/gorm"
"github.com/photoprism/photoprism/internal/maps"
"github.com/photoprism/photoprism/pkg/txt"
)
// Place used to associate photos to places
@ -49,7 +50,7 @@ func FindPlaceByLabel(id string, label string) *Place {
place := &Place{}
if err := Db().First(place, "id = ? OR loc_label = ?", id, label).Error; err != nil {
log.Debugf("place: %s for id %s or label \"%s\"", err.Error(), id, label)
log.Debugf("place: %s for id %s or label %s", err.Error(), id, txt.Quote(label))
return nil
}
@ -68,7 +69,7 @@ func (m *Place) Find() error {
// FirstOrCreate checks if the place already exists in the database
func (m *Place) FirstOrCreate() *Place {
if err := Db().FirstOrCreate(m, "id = ? OR loc_label = ?", m.ID, m.LocLabel).Error; err != nil {
log.Debugf("place: %s for token %s or label \"%s\"", err.Error(), m.ID, m.LocLabel)
log.Debugf("place: %s for token %s or label %s", err.Error(), m.ID, txt.Quote(m.LocLabel))
}
return m

View file

@ -10,6 +10,7 @@ import (
"sync"
"github.com/photoprism/photoprism/pkg/fs"
"github.com/photoprism/photoprism/pkg/txt"
tf "github.com/tensorflow/tensorflow/tensorflow/go"
"github.com/tensorflow/tensorflow/tensorflow/go/op"
)
@ -31,7 +32,7 @@ func New(modelPath string) *Detector {
// File returns matching labels for a jpeg media file.
func (t *Detector) File(filename string) (result Labels, err error) {
if fs.MimeType(filename) != "image/jpeg" {
return result, fmt.Errorf("nsfw: \"%s\" is not a jpeg file", filename)
return result, fmt.Errorf("nsfw: %s is not a jpeg file", txt.Quote(filepath.Base(filename)))
}
imageBuffer, err := ioutil.ReadFile(filename)
@ -121,7 +122,7 @@ func (t *Detector) loadModel() error {
return nil
}
log.Infof("tensorflow: loading image classification model from \"%s\"", filepath.Base(t.modelPath))
log.Infof("tensorflow: loading image classification model from %s", txt.Quote(filepath.Base(t.modelPath)))
// Load model
model, err := tf.LoadSavedModel(t.modelPath, t.modelTags, nil)

View file

@ -14,6 +14,7 @@ import (
"github.com/photoprism/photoprism/internal/event"
"github.com/photoprism/photoprism/internal/mutex"
"github.com/photoprism/photoprism/pkg/fs"
"github.com/photoprism/photoprism/pkg/txt"
)
// Import represents an importer that can copy/move MediaFiles to the originals directory.
@ -167,9 +168,9 @@ func (imp *Import) Start(opt ImportOptions) {
for _, directory := range directories {
if fs.IsEmpty(directory) {
if err := os.Remove(directory); err != nil {
log.Errorf("import: could not deleted empty directory %s (%s)", directory, err)
log.Errorf("import: could not deleted empty directory %s (%s)", fs.RelativeName(directory, importPath), err)
} else {
log.Infof("import: deleted empty directory %s", directory)
log.Infof("import: deleted empty directory %s", fs.RelativeName(directory, importPath))
}
}
}
@ -183,7 +184,7 @@ func (imp *Import) Start(opt ImportOptions) {
}
if err := os.Remove(file); err != nil {
log.Errorf("import: could not remove \"%s\" (%s)", file, err.Error())
log.Errorf("import: could not remove %s (%s)", txt.Quote(fs.RelativeName(file, importPath)), err.Error())
}
}
}
@ -207,7 +208,7 @@ func (imp *Import) DestinationFilename(mainFile *MediaFile, mediaFile *MediaFile
if !mediaFile.IsSidecar() {
if f, err := entity.FirstFileByHash(mediaFile.Hash()); err == nil {
existingFilename := imp.conf.OriginalsPath() + string(os.PathSeparator) + f.FileName
return existingFilename, fmt.Errorf("\"%s\" is identical to \"%s\" (%s)", mediaFile.FileName(), f.FileName, mediaFile.Hash())
return existingFilename, fmt.Errorf("%s is identical to %s (sha1 %s)", txt.Quote(mediaFile.FileName()), txt.Quote(f.FileName), mediaFile.Hash())
}
}

View file

@ -7,6 +7,7 @@ import (
"github.com/photoprism/photoprism/internal/event"
"github.com/photoprism/photoprism/pkg/fs"
"github.com/photoprism/photoprism/pkg/txt"
)
type ImportJob struct {
@ -48,25 +49,25 @@ func ImportWorker(jobs <-chan ImportJob) {
if related.Main.HasSameName(f) {
destinationMainFilename = destinationFilename
log.Infof("import: moving main %s file \"%s\" to \"%s\"", f.FileType(), relativeFilename, fs.RelativeName(destinationFilename, imp.originalsPath()))
log.Infof("import: moving main %s file %s to %s", f.FileType(), txt.Quote(relativeFilename), txt.Quote(fs.RelativeName(destinationFilename, imp.originalsPath())))
} else {
log.Infof("import: moving related %s file \"%s\" to \"%s\"", f.FileType(), relativeFilename, fs.RelativeName(destinationFilename, imp.originalsPath()))
log.Infof("import: moving related %s file %s to %s", f.FileType(), txt.Quote(relativeFilename), txt.Quote(fs.RelativeName(destinationFilename, imp.originalsPath())))
}
if opt.Move {
if err := f.Move(destinationFilename); err != nil {
log.Errorf("import: could not move file to %s (%s)", fs.RelativeName(destinationMainFilename, imp.originalsPath()), err.Error())
log.Errorf("import: could not move file to %s (%s)", txt.Quote(fs.RelativeName(destinationMainFilename, imp.originalsPath())), err.Error())
}
} else {
if err := f.Copy(destinationFilename); err != nil {
log.Errorf("import: could not copy file to %s (%s)", fs.RelativeName(destinationMainFilename, imp.originalsPath()), err.Error())
log.Errorf("import: could not copy file to %s (%s)", txt.Quote(fs.RelativeName(destinationMainFilename, imp.originalsPath())), err.Error())
}
}
} else if opt.RemoveExistingFiles {
if err := f.Remove(); err != nil {
log.Errorf("import: could not delete %s (%s)",fs.RelativeName(f.FileName(), importPath), err.Error())
log.Errorf("import: could not delete %s (%s)", txt.Quote(fs.RelativeName(f.FileName(), importPath)), err.Error())
} else {
log.Infof("import: deleted %s (already exists)", relativeFilename)
log.Infof("import: deleted %s (already exists)", txt.Quote(relativeFilename))
}
}
}
@ -75,7 +76,7 @@ func ImportWorker(jobs <-chan ImportJob) {
importedMainFile, err := NewMediaFile(destinationMainFilename)
if err != nil {
log.Errorf("import: could not index \"%s\" (%s)", fs.RelativeName(destinationMainFilename, imp.originalsPath()), err.Error())
log.Errorf("import: could not index %s (%s)", txt.Quote(fs.RelativeName(destinationMainFilename, imp.originalsPath())), err.Error())
continue
}
@ -97,7 +98,7 @@ func ImportWorker(jobs <-chan ImportJob) {
related, err := importedMainFile.RelatedFiles(imp.conf.Settings().Library.GroupRelated)
if err != nil {
log.Errorf("import: could not index \"%s\" (%s)", fs.RelativeName(destinationMainFilename, imp.originalsPath()), err.Error())
log.Errorf("import: could not index %s (%s)", txt.Quote(fs.RelativeName(destinationMainFilename, imp.originalsPath())), err.Error())
continue
}
@ -107,7 +108,7 @@ func ImportWorker(jobs <-chan ImportJob) {
if related.Main != nil {
res := ind.MediaFile(related.Main, indexOpt, originalName)
log.Infof("import: %s main %s file \"%s\"", res, related.Main.FileType(), related.Main.RelativeName(ind.originalsPath()))
log.Infof("import: %s main %s file %s", res, related.Main.FileType(), txt.Quote(related.Main.RelativeName(ind.originalsPath())))
done[related.Main.FileName()] = true
} else {
log.Warnf("import: no main file for %s (conversion to jpeg failed?)", fs.RelativeName(destinationMainFilename, imp.originalsPath()))
@ -125,7 +126,7 @@ func ImportWorker(jobs <-chan ImportJob) {
res := ind.MediaFile(f, indexOpt, "")
done[f.FileName()] = true
log.Infof("import: %s related %s file \"%s\"", res, f.FileType(), f.RelativeName(ind.originalsPath()))
log.Infof("import: %s related %s file %s", res, f.FileType(), txt.Quote(f.RelativeName(ind.originalsPath())))
}
}
}

View file

@ -3,6 +3,7 @@ package photoprism
import (
"github.com/jinzhu/gorm"
"github.com/photoprism/photoprism/internal/entity"
"github.com/photoprism/photoprism/pkg/txt"
)
func (ind *Index) estimateLocation(photo *entity.Photo) {
@ -13,7 +14,7 @@ func (ind *Index) estimateLocation(photo *entity.Photo) {
photo.Place = recentPhoto.Place
photo.PhotoCountry = photo.Place.LocCountry
photo.LocationSrc = entity.SrcAuto
log.Debugf("index: approximate location is \"%s\"", recentPhoto.Place.Label())
log.Debugf("index: approximate location is %s", txt.Quote(recentPhoto.Place.Label()))
}
}
}

View file

@ -184,7 +184,7 @@ func (ind *Index) MediaFile(m *MediaFile, o IndexOptions, originalName string) (
}
if len(metaData.UniqueID) > 15 {
log.Debugf("index: file uuid \"%s\"", metaData.UniqueID)
log.Debugf("index: file uuid %s", txt.Quote(metaData.UniqueID))
file.FileUUID = metaData.UniqueID
}

View file

@ -1,6 +1,9 @@
package photoprism
import "github.com/photoprism/photoprism/pkg/fs"
import (
"github.com/photoprism/photoprism/pkg/fs"
"github.com/photoprism/photoprism/pkg/txt"
)
type IndexJob struct {
FileName string
@ -20,9 +23,9 @@ func IndexWorker(jobs <-chan IndexJob) {
res := ind.MediaFile(related.Main, opt, "")
done[related.Main.FileName()] = true
log.Infof("index: %s main %s file \"%s\"", res, related.Main.FileType(), related.Main.RelativeName(ind.originalsPath()))
log.Infof("index: %s main %s file %s", res, related.Main.FileType(), txt.Quote(related.Main.RelativeName(ind.originalsPath())))
} else {
log.Warnf("index: no main file for %s (conversion to jpeg failed?)", fs.RelativeName(job.FileName, ind.originalsPath()))
log.Warnf("index: no main file for %s (conversion failed?)", txt.Quote(fs.RelativeName(job.FileName, ind.originalsPath())))
}
for _, f := range related.Files {
@ -33,7 +36,7 @@ func IndexWorker(jobs <-chan IndexJob) {
res := ind.MediaFile(f, opt, "")
done[f.FileName()] = true
log.Infof("index: %s related %s file \"%s\"", res, f.FileType(), f.RelativeName(ind.originalsPath()))
log.Infof("index: %s related %s file %s", res, f.FileType(), txt.Quote(f.RelativeName(ind.originalsPath())))
}
}
}

View file

@ -19,6 +19,7 @@ import (
"github.com/photoprism/photoprism/internal/thumb"
"github.com/photoprism/photoprism/pkg/capture"
"github.com/photoprism/photoprism/pkg/fs"
"github.com/photoprism/photoprism/pkg/txt"
)
// MediaFile represents a single photo, video or sidecar file.
@ -725,7 +726,7 @@ func (m *MediaFile) ResampleDefault(thumbPath string, force bool) (err error) {
}
if fileName, err := thumb.Filename(hash, thumbPath, thumbType.Width, thumbType.Height, thumbType.Options...); err != nil {
log.Errorf("mediafile: could not create \"%s\" (%s)", name, err)
log.Errorf("mediafile: could not create %s (%s)", txt.Quote(name), err)
return err
} else {
@ -737,7 +738,7 @@ func (m *MediaFile) ResampleDefault(thumbPath string, force bool) (err error) {
img, err := imaging.Open(m.FileName(), imaging.AutoOrientation(true))
if err != nil {
log.Errorf("mediafile: can't open \"%s\" (%s)", m.FileName(), err.Error())
log.Errorf("mediafile: can't open %s (%s)", txt.Quote(m.FileName()), err.Error())
return err
}
@ -756,7 +757,7 @@ func (m *MediaFile) ResampleDefault(thumbPath string, force bool) (err error) {
}
if err != nil {
log.Errorf("mediafile: could not create \"%s\" (%s)", name, err)
log.Errorf("mediafile: could not create %s (%s)", txt.Quote(name), err)
return err
}

View file

@ -70,21 +70,21 @@ func TestThumb_Filename(t *testing.T) {
t.FailNow()
}
assert.Equal(t, "thumbs: file hash is empty or too short (\"999\")", err.Error())
assert.Equal(t, "resample: file hash is empty or too short (999)", err.Error())
})
t.Run("invalid width", func(t *testing.T) {
_, err := thumb.Filename("99988", thumbsPath, -4, 150, thumb.ResampleFit, thumb.ResampleNearestNeighbor)
if err == nil {
t.FailNow()
}
assert.Equal(t, "thumbs: width exceeds limit (-4)", err.Error())
assert.Equal(t, "resample: width exceeds limit (-4)", err.Error())
})
t.Run("invalid height", func(t *testing.T) {
_, err := thumb.Filename("99988", thumbsPath, 200, -1, thumb.ResampleFit, thumb.ResampleNearestNeighbor)
if err == nil {
t.FailNow()
}
assert.Equal(t, "thumbs: height exceeds limit (-1)", err.Error())
assert.Equal(t, "resample: height exceeds limit (-1)", err.Error())
})
t.Run("empty thumbpath", func(t *testing.T) {
path := ""
@ -92,7 +92,7 @@ func TestThumb_Filename(t *testing.T) {
if err == nil {
t.FailNow()
}
assert.Equal(t, "thumbs: path is empty", err.Error())
assert.Equal(t, "resample: path is empty", err.Error())
})
}
@ -130,7 +130,7 @@ func TestThumb_FromFile(t *testing.T) {
t.Fatal("err should NOT be nil")
}
assert.Equal(t, "thumbs: file hash is empty or too short (\"123\")", err.Error())
assert.Equal(t, "resample: file hash is empty or too short (123)", err.Error())
})
t.Run("filename too short", func(t *testing.T) {
fileModel := &entity.File{
@ -142,7 +142,7 @@ func TestThumb_FromFile(t *testing.T) {
if err == nil {
t.FailNow()
}
assert.Equal(t, "thumbs: image filename is empty or too short (\"xxx\")", err.Error())
assert.Equal(t, "resample: image filename is empty or too short (xxx)", err.Error())
})
}
@ -209,7 +209,7 @@ func TestThumb_Create(t *testing.T) {
thumbnail := *res
assert.Equal(t, "thumbs: width has an invalid value (-1)", err.Error())
assert.Equal(t, "resample: width has an invalid value (-1)", err.Error())
bounds := thumbnail.Bounds()
assert.NotEqual(t, 150, bounds.Dx())
})
@ -235,7 +235,7 @@ func TestThumb_Create(t *testing.T) {
thumbnail := *res
assert.Equal(t, "thumbs: height has an invalid value (-1)", err.Error())
assert.Equal(t, "resample: height has an invalid value (-1)", err.Error())
bounds := thumbnail.Bounds()
assert.NotEqual(t, 150, bounds.Dx())
})

View file

@ -9,6 +9,7 @@ import (
"github.com/photoprism/photoprism/internal/entity"
"github.com/photoprism/photoprism/internal/form"
"github.com/photoprism/photoprism/pkg/capture"
"github.com/photoprism/photoprism/pkg/txt"
)
// LabelResult contains found labels
@ -132,7 +133,7 @@ func (q *Query) Labels(f form.LabelSearch) (results []LabelResult, err error) {
likeString := "%" + strings.ToLower(f.Query) + "%"
if result := q.db.First(&label, "label_slug = ? OR custom_slug = ?", slugString, slugString); result.Error != nil {
log.Infof("search: label \"%s\" not found", f.Query)
log.Infof("search: label %s not found", txt.Quote(f.Query))
s = s.Where("LOWER(labels.label_name) LIKE ?", likeString)
} else {
@ -144,7 +145,7 @@ func (q *Query) Labels(f form.LabelSearch) (results []LabelResult, err error) {
labelIds = append(labelIds, category.LabelID)
}
log.Infof("search: label \"%s\" includes %d categories", label.LabelName, len(labelIds))
log.Infof("search: label %s includes %d categories", txt.Quote(label.LabelName), len(labelIds))
s = s.Where("labels.id IN (?)", labelIds)
}

View file

@ -188,8 +188,8 @@ func (q *Query) Photos(f form.PhotoSearch) (results PhotoResults, count int, err
if f.Label != "" {
slugString := strings.ToLower(f.Label)
if result := q.db.First(&label, "label_slug =? OR custom_slug = ?", slugString, slugString); result.Error != nil {
log.Errorf("search: label \"%s\" not found", f.Label)
return results, 0, fmt.Errorf("label \"%s\" not found", f.Label)
log.Errorf("search: label %s not found", txt.Quote(f.Label))
return results, 0, fmt.Errorf("label %s not found", txt.Quote(f.Label))
} else {
labelIds = append(labelIds, label.ID)
@ -224,7 +224,7 @@ func (q *Query) Photos(f form.PhotoSearch) (results PhotoResults, count int, err
Joins("LEFT JOIN keywords ON photos_keywords.keyword_id = keywords.id")
if result := q.db.First(&label, "label_slug = ? OR custom_slug = ?", slugString, slugString); result.Error != nil {
log.Infof("search: label \"%s\" not found, using fuzzy search", f.Query)
log.Infof("search: label %s not found, using fuzzy search", txt.Quote(f.Query))
s = s.Where("keywords.keyword LIKE ?", likeString)
} else {
@ -236,7 +236,7 @@ func (q *Query) Photos(f form.PhotoSearch) (results PhotoResults, count int, err
labelIds = append(labelIds, category.LabelID)
}
log.Infof("search: label \"%s\" includes %d categories", label.LabelName, len(labelIds))
log.Infof("search: label %s includes %d categories", txt.Quote(label.LabelName), len(labelIds))
s = s.Where("photos_labels.label_id IN (?) OR keywords.keyword LIKE ?", labelIds, likeString)
}

View file

@ -114,6 +114,7 @@ func TestSearch_Photos(t *testing.T) {
if err != nil {
// TODO: Add database fixtures to avoid failing queries
t.Logf("query failed: %s", err.Error())
// t.Fatal(err)
}
t.Logf("results: %+v", photos)
@ -126,9 +127,12 @@ func TestSearch_Photos(t *testing.T) {
photos, _, err := search.Photos(f)
assert.Equal(t, err.Error(), "label \"xxx\" not found")
assert.Error(t, err)
assert.Empty(t, photos)
t.Logf("results: %+v", photos)
if err != nil {
assert.Equal(t, err.Error(), "label xxx not found")
}
})
t.Run("form.location true", func(t *testing.T) {
var f form.PhotoSearch

View file

@ -10,6 +10,7 @@ import (
"path/filepath"
"github.com/photoprism/photoprism/pkg/fs"
"github.com/photoprism/photoprism/pkg/txt"
"github.com/disintegration/imaging"
)
@ -75,19 +76,19 @@ func Postfix(width, height int, opts ...ResampleOption) (result string) {
func Filename(hash string, thumbPath string, width, height int, opts ...ResampleOption) (filename string, err error) {
if width < 0 || width > MaxRenderSize {
return "", fmt.Errorf("thumbs: width exceeds limit (%d)", width)
return "", fmt.Errorf("resample: width exceeds limit (%d)", width)
}
if height < 0 || height > MaxRenderSize {
return "", fmt.Errorf("thumbs: height exceeds limit (%d)", height)
return "", fmt.Errorf("resample: height exceeds limit (%d)", height)
}
if len(hash) < 4 {
return "", fmt.Errorf("thumbs: file hash is empty or too short (\"%s\")", hash)
return "", fmt.Errorf("resample: file hash is empty or too short (%s)", txt.Quote(hash))
}
if len(thumbPath) == 0 {
return "", errors.New("thumbs: path is empty")
return "", errors.New("resample: path is empty")
}
postfix := Postfix(width, height, opts...)
@ -104,17 +105,17 @@ func Filename(hash string, thumbPath string, width, height int, opts ...Resample
func FromFile(imageFilename string, hash string, thumbPath string, width, height int, opts ...ResampleOption) (fileName string, err error) {
if len(hash) < 4 {
return "", fmt.Errorf("thumbs: file hash is empty or too short (\"%s\")", hash)
return "", fmt.Errorf("resample: file hash is empty or too short (%s)", txt.Quote(hash))
}
if len(imageFilename) < 4 {
return "", fmt.Errorf("thumbs: image filename is empty or too short (\"%s\")", imageFilename)
return "", fmt.Errorf("resample: image filename is empty or too short (%s)", txt.Quote(imageFilename))
}
fileName, err = Filename(hash, thumbPath, width, height, opts...)
if err != nil {
log.Errorf("thumbs: can't determine filename (%s)", err)
log.Errorf("resample: can't determine filename (%s)", err)
return "", err
}
@ -125,7 +126,7 @@ func FromFile(imageFilename string, hash string, thumbPath string, width, height
img, err := imaging.Open(imageFilename, imaging.AutoOrientation(true))
if err != nil {
log.Errorf("thumbs: can't open \"%s\" (%s)", imageFilename, err.Error())
log.Errorf("resample: can't open %s (%s)", txt.Quote(imageFilename), err.Error())
return "", err
}
@ -138,11 +139,11 @@ func FromFile(imageFilename string, hash string, thumbPath string, width, height
func Create(img *image.Image, fileName string, width, height int, opts ...ResampleOption) (result *image.Image, err error) {
if width < 0 || width > MaxRenderSize {
return img, fmt.Errorf("thumbs: width has an invalid value (%d)", width)
return img, fmt.Errorf("resample: width has an invalid value (%d)", width)
}
if height < 0 || height > MaxRenderSize {
return img, fmt.Errorf("thumbs: height has an invalid value (%d)", height)
return img, fmt.Errorf("resample: height has an invalid value (%d)", height)
}
result = Resample(img, width, height, opts...)
@ -160,7 +161,7 @@ func Create(img *image.Image, fileName string, width, height int, opts ...Resamp
err = imaging.Save(*result, fileName, saveOption)
if err != nil {
log.Errorf("thumbs: failed to save %s", fileName)
log.Errorf("resample: failed to save %s", fileName)
return result, err
}

View file

@ -39,10 +39,10 @@ func TestNewFileInfos(t *testing.T) {
}
expected := map[string]FileInfo{
"test.jpg": {Abs: "/test.jpg", Size: 10990, Dir: false},
"test.jpg": {Abs: "/test.jpg", Size: 10990, Dir: false},
"CATYELLOW.jpg": {Abs: "/CATYELLOW.jpg", Size: 70790, Dir: false},
"directory": {Abs: "/directory", Size: 4096, Dir: true},
"linked": {Abs: "/linked", Size: 4096, Dir: true},
"directory": {Abs: "/directory", Size: 4096, Dir: true},
"linked": {Abs: "/linked", Size: 4096, Dir: true},
}
for _, file := range result {

15
pkg/txt/quote.go Normal file
View file

@ -0,0 +1,15 @@
package txt
import (
"fmt"
"strings"
)
// Quote adds quotation marks to a string if needed.
func Quote(text string) string {
if strings.ContainsAny(text, " \n'\"") {
return fmt.Sprintf("“%s”", text)
}
return text
}

16
pkg/txt/quote_test.go Normal file
View file

@ -0,0 +1,16 @@
package txt
import (
"testing"
"github.com/stretchr/testify/assert"
)
func TestQuote(t *testing.T) {
t.Run("The quick brown fox.", func(t *testing.T) {
assert.Equal(t, "“The quick brown fox.”", Quote("The quick brown fox."))
})
t.Run("filename.txt", func(t *testing.T) {
assert.Equal(t, "filename.txt", Quote("filename.txt"))
})
}