@ -0,0 +1,129 @@ |
|||||||
|
package bootstrap |
||||||
|
|
||||||
|
import ( |
||||||
|
"bufio" |
||||||
|
"encoding/json" |
||||||
|
"github.com/astaxie/beego/cache" |
||||||
|
"io/ioutil" |
||||||
|
"os" |
||||||
|
"time" |
||||||
|
) |
||||||
|
|
||||||
|
type AuxpiConfig struct { |
||||||
|
|
||||||
|
}
|
||||||
|
type SiteConfig struct { |
||||||
|
//站点名称
|
||||||
|
SiteName string `json:"site_name"` |
||||||
|
//底部信息
|
||||||
|
SiteFooter string `json:"site_footer"` |
||||||
|
//网站链接
|
||||||
|
SiteUrl string `json:"site_url"` |
||||||
|
//最大上传的图片个数
|
||||||
|
SiteUploadMaxNumber int `json:"site_upload_max_number"` |
||||||
|
//最大图片规格 MB
|
||||||
|
SiteUpLoadMaxSize int `json:"site_up_load_max_size"` |
||||||
|
//图床储存的一些配置
|
||||||
|
SiteUploadWay UploadConfig `json:"site_upload_way"` |
||||||
|
} |
||||||
|
|
||||||
|
type UploadConfig struct { |
||||||
|
//是否开启本地上传
|
||||||
|
LocalStore bool `json:"local_store"` |
||||||
|
//是否开启微博图床
|
||||||
|
OpenSinaPicStore bool `json:"open_sina_pic_store"` |
||||||
|
//Sina Account
|
||||||
|
SinaAccount Account `json:"sina_account"` |
||||||
|
//
|
||||||
|
} |
||||||
|
type Account struct { |
||||||
|
//用户名
|
||||||
|
UserName string `json:"user_name"` |
||||||
|
//密码
|
||||||
|
PassWord string `json:"pass_word"` |
||||||
|
//新浪 Cookie 更新的频率,默认为3600s ,单位 s
|
||||||
|
ResetSinaCookieTime int `json:"reset_sina_cookie_time"` |
||||||
|
//新浪图床默认使用的尺寸大小 square,thumb150,orj360,orj480,mw690,mw1024,mw2048,small,bmiddle,large 、默认为large
|
||||||
|
DefultPicSize string `json:"defult_pic_size"` |
||||||
|
} |
||||||
|
|
||||||
|
var cCache, _ = cache.NewCache("memory", `{"interval":3600}`) |
||||||
|
|
||||||
|
type JsonStruct struct { |
||||||
|
} |
||||||
|
|
||||||
|
func NewJsonStruct() *JsonStruct { |
||||||
|
return &JsonStruct{} |
||||||
|
} |
||||||
|
|
||||||
|
func (jst *JsonStruct) Load(filename string, v interface{}) { |
||||||
|
data, err := ioutil.ReadFile(filename) |
||||||
|
if err != nil { |
||||||
|
panic(err) |
||||||
|
return |
||||||
|
} |
||||||
|
err = json.Unmarshal(data, v) |
||||||
|
if err != nil { |
||||||
|
return |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
//返回 Config 里面的 数据
|
||||||
|
func Config() *SiteConfig { |
||||||
|
//尝试从缓存中检索
|
||||||
|
cacheConfig := cCache.Get("SiteConfig") |
||||||
|
if cacheConfig != nil { |
||||||
|
config, _ := cacheConfig.(*SiteConfig) |
||||||
|
return config |
||||||
|
} |
||||||
|
reader := &JsonStruct{} |
||||||
|
config := &SiteConfig{} |
||||||
|
configDir := GetPath() + "/conf/siteConfig.json" |
||||||
|
reader.Load(configDir, config) |
||||||
|
//缓存到内存
|
||||||
|
cCache.Put("SiteConfig", config, time.Second*3600) |
||||||
|
return config |
||||||
|
} |
||||||
|
//func (this *AuxpiConfig)GetConfig(key string) {
|
||||||
|
// config :=Config()
|
||||||
|
//}
|
||||||
|
|
||||||
|
//初始化的时候检测是否进行安装,生成对应的 lock 文件,生成配置的 json
|
||||||
|
|
||||||
|
func init() { |
||||||
|
baseDir := GetPath() + "/conf/" |
||||||
|
lockDir := baseDir + "install.lock" |
||||||
|
_, err := os.Stat(lockDir) |
||||||
|
if err == nil { |
||||||
|
return |
||||||
|
} |
||||||
|
if os.IsNotExist(err) { |
||||||
|
var f *os.File |
||||||
|
siteconfig := SiteConfig{} |
||||||
|
siteconfig.SiteName = "BusterApi 图床" |
||||||
|
siteconfig.SiteUrl = "/" |
||||||
|
siteconfig.SiteFooter = "你好世界" |
||||||
|
siteconfig.SiteUpLoadMaxSize = 5 |
||||||
|
siteconfig.SiteUploadMaxNumber = 10 |
||||||
|
siteconfig.SiteUploadWay.OpenSinaPicStore = false |
||||||
|
siteconfig.SiteUploadWay.LocalStore = false |
||||||
|
siteconfig.SiteUploadWay.SinaAccount.UserName = "" |
||||||
|
siteconfig.SiteUploadWay.SinaAccount.PassWord = "" |
||||||
|
siteconfig.SiteUploadWay.SinaAccount.ResetSinaCookieTime = 3600 |
||||||
|
siteconfig.SiteUploadWay.SinaAccount.DefultPicSize = "large" |
||||||
|
configJson, err := siteconfig.MarshalJSON() |
||||||
|
if err != nil { |
||||||
|
panic(err) |
||||||
|
} |
||||||
|
//创建lock文件
|
||||||
|
f, err = os.Create(lockDir) |
||||||
|
//创建 config 文件并且写入内容
|
||||||
|
configDir := baseDir + "siteConfig.json" |
||||||
|
f, err = os.Create(configDir) |
||||||
|
w := bufio.NewWriter(f) |
||||||
|
_, err = w.WriteString(string(configJson)) |
||||||
|
w.Flush() |
||||||
|
f.Close() |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,411 @@ |
|||||||
|
// Code generated by easyjson for marshaling/unmarshaling. DO NOT EDIT.
|
||||||
|
|
||||||
|
package bootstrap |
||||||
|
|
||||||
|
import ( |
||||||
|
json "encoding/json" |
||||||
|
easyjson "github.com/mailru/easyjson" |
||||||
|
jlexer "github.com/mailru/easyjson/jlexer" |
||||||
|
jwriter "github.com/mailru/easyjson/jwriter" |
||||||
|
) |
||||||
|
|
||||||
|
// suppress unused package warning
|
||||||
|
var ( |
||||||
|
_ *json.RawMessage |
||||||
|
_ *jlexer.Lexer |
||||||
|
_ *jwriter.Writer |
||||||
|
_ easyjson.Marshaler |
||||||
|
) |
||||||
|
|
||||||
|
func easyjsonDc4bdceDecodeAuxpiBootstrap(in *jlexer.Lexer, out *UploadConfig) { |
||||||
|
isTopLevel := in.IsStart() |
||||||
|
if in.IsNull() { |
||||||
|
if isTopLevel { |
||||||
|
in.Consumed() |
||||||
|
} |
||||||
|
in.Skip() |
||||||
|
return |
||||||
|
} |
||||||
|
in.Delim('{') |
||||||
|
for !in.IsDelim('}') { |
||||||
|
key := in.UnsafeString() |
||||||
|
in.WantColon() |
||||||
|
if in.IsNull() { |
||||||
|
in.Skip() |
||||||
|
in.WantComma() |
||||||
|
continue |
||||||
|
} |
||||||
|
switch key { |
||||||
|
case "local_store": |
||||||
|
out.LocalStore = bool(in.Bool()) |
||||||
|
case "open_sina_pic_store": |
||||||
|
out.OpenSinaPicStore = bool(in.Bool()) |
||||||
|
case "sina_account": |
||||||
|
(out.SinaAccount).UnmarshalEasyJSON(in) |
||||||
|
default: |
||||||
|
in.SkipRecursive() |
||||||
|
} |
||||||
|
in.WantComma() |
||||||
|
} |
||||||
|
in.Delim('}') |
||||||
|
if isTopLevel { |
||||||
|
in.Consumed() |
||||||
|
} |
||||||
|
} |
||||||
|
func easyjsonDc4bdceEncodeAuxpiBootstrap(out *jwriter.Writer, in UploadConfig) { |
||||||
|
out.RawByte('{') |
||||||
|
first := true |
||||||
|
_ = first |
||||||
|
{ |
||||||
|
const prefix string = ",\"local_store\":" |
||||||
|
if first { |
||||||
|
first = false |
||||||
|
out.RawString(prefix[1:]) |
||||||
|
} else { |
||||||
|
out.RawString(prefix) |
||||||
|
} |
||||||
|
out.Bool(bool(in.LocalStore)) |
||||||
|
} |
||||||
|
{ |
||||||
|
const prefix string = ",\"open_sina_pic_store\":" |
||||||
|
if first { |
||||||
|
first = false |
||||||
|
out.RawString(prefix[1:]) |
||||||
|
} else { |
||||||
|
out.RawString(prefix) |
||||||
|
} |
||||||
|
out.Bool(bool(in.OpenSinaPicStore)) |
||||||
|
} |
||||||
|
{ |
||||||
|
const prefix string = ",\"sina_account\":" |
||||||
|
if first { |
||||||
|
first = false |
||||||
|
out.RawString(prefix[1:]) |
||||||
|
} else { |
||||||
|
out.RawString(prefix) |
||||||
|
} |
||||||
|
(in.SinaAccount).MarshalEasyJSON(out) |
||||||
|
} |
||||||
|
out.RawByte('}') |
||||||
|
} |
||||||
|
|
||||||
|
// MarshalJSON supports json.Marshaler interface
|
||||||
|
func (v UploadConfig) MarshalJSON() ([]byte, error) { |
||||||
|
w := jwriter.Writer{} |
||||||
|
easyjsonDc4bdceEncodeAuxpiBootstrap(&w, v) |
||||||
|
return w.Buffer.BuildBytes(), w.Error |
||||||
|
} |
||||||
|
|
||||||
|
// MarshalEasyJSON supports easyjson.Marshaler interface
|
||||||
|
func (v UploadConfig) MarshalEasyJSON(w *jwriter.Writer) { |
||||||
|
easyjsonDc4bdceEncodeAuxpiBootstrap(w, v) |
||||||
|
} |
||||||
|
|
||||||
|
// UnmarshalJSON supports json.Unmarshaler interface
|
||||||
|
func (v *UploadConfig) UnmarshalJSON(data []byte) error { |
||||||
|
r := jlexer.Lexer{Data: data} |
||||||
|
easyjsonDc4bdceDecodeAuxpiBootstrap(&r, v) |
||||||
|
return r.Error() |
||||||
|
} |
||||||
|
|
||||||
|
// UnmarshalEasyJSON supports easyjson.Unmarshaler interface
|
||||||
|
func (v *UploadConfig) UnmarshalEasyJSON(l *jlexer.Lexer) { |
||||||
|
easyjsonDc4bdceDecodeAuxpiBootstrap(l, v) |
||||||
|
} |
||||||
|
func easyjsonDc4bdceDecodeAuxpiBootstrap1(in *jlexer.Lexer, out *SiteConfig) { |
||||||
|
isTopLevel := in.IsStart() |
||||||
|
if in.IsNull() { |
||||||
|
if isTopLevel { |
||||||
|
in.Consumed() |
||||||
|
} |
||||||
|
in.Skip() |
||||||
|
return |
||||||
|
} |
||||||
|
in.Delim('{') |
||||||
|
for !in.IsDelim('}') { |
||||||
|
key := in.UnsafeString() |
||||||
|
in.WantColon() |
||||||
|
if in.IsNull() { |
||||||
|
in.Skip() |
||||||
|
in.WantComma() |
||||||
|
continue |
||||||
|
} |
||||||
|
switch key { |
||||||
|
case "site_name": |
||||||
|
out.SiteName = string(in.String()) |
||||||
|
case "site_footer": |
||||||
|
out.SiteFooter = string(in.String()) |
||||||
|
case "site_url": |
||||||
|
out.SiteUrl = string(in.String()) |
||||||
|
case "site_upload_max_number": |
||||||
|
out.SiteUploadMaxNumber = int(in.Int()) |
||||||
|
case "site_up_load_max_size": |
||||||
|
out.SiteUpLoadMaxSize = int(in.Int()) |
||||||
|
case "site_upload_way": |
||||||
|
(out.SiteUploadWay).UnmarshalEasyJSON(in) |
||||||
|
default: |
||||||
|
in.SkipRecursive() |
||||||
|
} |
||||||
|
in.WantComma() |
||||||
|
} |
||||||
|
in.Delim('}') |
||||||
|
if isTopLevel { |
||||||
|
in.Consumed() |
||||||
|
} |
||||||
|
} |
||||||
|
func easyjsonDc4bdceEncodeAuxpiBootstrap1(out *jwriter.Writer, in SiteConfig) { |
||||||
|
out.RawByte('{') |
||||||
|
first := true |
||||||
|
_ = first |
||||||
|
{ |
||||||
|
const prefix string = ",\"site_name\":" |
||||||
|
if first { |
||||||
|
first = false |
||||||
|
out.RawString(prefix[1:]) |
||||||
|
} else { |
||||||
|
out.RawString(prefix) |
||||||
|
} |
||||||
|
out.String(string(in.SiteName)) |
||||||
|
} |
||||||
|
{ |
||||||
|
const prefix string = ",\"site_footer\":" |
||||||
|
if first { |
||||||
|
first = false |
||||||
|
out.RawString(prefix[1:]) |
||||||
|
} else { |
||||||
|
out.RawString(prefix) |
||||||
|
} |
||||||
|
out.String(string(in.SiteFooter)) |
||||||
|
} |
||||||
|
{ |
||||||
|
const prefix string = ",\"site_url\":" |
||||||
|
if first { |
||||||
|
first = false |
||||||
|
out.RawString(prefix[1:]) |
||||||
|
} else { |
||||||
|
out.RawString(prefix) |
||||||
|
} |
||||||
|
out.String(string(in.SiteUrl)) |
||||||
|
} |
||||||
|
{ |
||||||
|
const prefix string = ",\"site_upload_max_number\":" |
||||||
|
if first { |
||||||
|
first = false |
||||||
|
out.RawString(prefix[1:]) |
||||||
|
} else { |
||||||
|
out.RawString(prefix) |
||||||
|
} |
||||||
|
out.Int(int(in.SiteUploadMaxNumber)) |
||||||
|
} |
||||||
|
{ |
||||||
|
const prefix string = ",\"site_up_load_max_size\":" |
||||||
|
if first { |
||||||
|
first = false |
||||||
|
out.RawString(prefix[1:]) |
||||||
|
} else { |
||||||
|
out.RawString(prefix) |
||||||
|
} |
||||||
|
out.Int(int(in.SiteUpLoadMaxSize)) |
||||||
|
} |
||||||
|
{ |
||||||
|
const prefix string = ",\"site_upload_way\":" |
||||||
|
if first { |
||||||
|
first = false |
||||||
|
out.RawString(prefix[1:]) |
||||||
|
} else { |
||||||
|
out.RawString(prefix) |
||||||
|
} |
||||||
|
(in.SiteUploadWay).MarshalEasyJSON(out) |
||||||
|
} |
||||||
|
out.RawByte('}') |
||||||
|
} |
||||||
|
|
||||||
|
// MarshalJSON supports json.Marshaler interface
|
||||||
|
func (v SiteConfig) MarshalJSON() ([]byte, error) { |
||||||
|
w := jwriter.Writer{} |
||||||
|
easyjsonDc4bdceEncodeAuxpiBootstrap1(&w, v) |
||||||
|
return w.Buffer.BuildBytes(), w.Error |
||||||
|
} |
||||||
|
|
||||||
|
// MarshalEasyJSON supports easyjson.Marshaler interface
|
||||||
|
func (v SiteConfig) MarshalEasyJSON(w *jwriter.Writer) { |
||||||
|
easyjsonDc4bdceEncodeAuxpiBootstrap1(w, v) |
||||||
|
} |
||||||
|
|
||||||
|
// UnmarshalJSON supports json.Unmarshaler interface
|
||||||
|
func (v *SiteConfig) UnmarshalJSON(data []byte) error { |
||||||
|
r := jlexer.Lexer{Data: data} |
||||||
|
easyjsonDc4bdceDecodeAuxpiBootstrap1(&r, v) |
||||||
|
return r.Error() |
||||||
|
} |
||||||
|
|
||||||
|
// UnmarshalEasyJSON supports easyjson.Unmarshaler interface
|
||||||
|
func (v *SiteConfig) UnmarshalEasyJSON(l *jlexer.Lexer) { |
||||||
|
easyjsonDc4bdceDecodeAuxpiBootstrap1(l, v) |
||||||
|
} |
||||||
|
func easyjsonDc4bdceDecodeAuxpiBootstrap2(in *jlexer.Lexer, out *JsonStruct) { |
||||||
|
isTopLevel := in.IsStart() |
||||||
|
if in.IsNull() { |
||||||
|
if isTopLevel { |
||||||
|
in.Consumed() |
||||||
|
} |
||||||
|
in.Skip() |
||||||
|
return |
||||||
|
} |
||||||
|
in.Delim('{') |
||||||
|
for !in.IsDelim('}') { |
||||||
|
key := in.UnsafeString() |
||||||
|
in.WantColon() |
||||||
|
if in.IsNull() { |
||||||
|
in.Skip() |
||||||
|
in.WantComma() |
||||||
|
continue |
||||||
|
} |
||||||
|
switch key { |
||||||
|
default: |
||||||
|
in.SkipRecursive() |
||||||
|
} |
||||||
|
in.WantComma() |
||||||
|
} |
||||||
|
in.Delim('}') |
||||||
|
if isTopLevel { |
||||||
|
in.Consumed() |
||||||
|
} |
||||||
|
} |
||||||
|
func easyjsonDc4bdceEncodeAuxpiBootstrap2(out *jwriter.Writer, in JsonStruct) { |
||||||
|
out.RawByte('{') |
||||||
|
first := true |
||||||
|
_ = first |
||||||
|
out.RawByte('}') |
||||||
|
} |
||||||
|
|
||||||
|
// MarshalJSON supports json.Marshaler interface
|
||||||
|
func (v JsonStruct) MarshalJSON() ([]byte, error) { |
||||||
|
w := jwriter.Writer{} |
||||||
|
easyjsonDc4bdceEncodeAuxpiBootstrap2(&w, v) |
||||||
|
return w.Buffer.BuildBytes(), w.Error |
||||||
|
} |
||||||
|
|
||||||
|
// MarshalEasyJSON supports easyjson.Marshaler interface
|
||||||
|
func (v JsonStruct) MarshalEasyJSON(w *jwriter.Writer) { |
||||||
|
easyjsonDc4bdceEncodeAuxpiBootstrap2(w, v) |
||||||
|
} |
||||||
|
|
||||||
|
// UnmarshalJSON supports json.Unmarshaler interface
|
||||||
|
func (v *JsonStruct) UnmarshalJSON(data []byte) error { |
||||||
|
r := jlexer.Lexer{Data: data} |
||||||
|
easyjsonDc4bdceDecodeAuxpiBootstrap2(&r, v) |
||||||
|
return r.Error() |
||||||
|
} |
||||||
|
|
||||||
|
// UnmarshalEasyJSON supports easyjson.Unmarshaler interface
|
||||||
|
func (v *JsonStruct) UnmarshalEasyJSON(l *jlexer.Lexer) { |
||||||
|
easyjsonDc4bdceDecodeAuxpiBootstrap2(l, v) |
||||||
|
} |
||||||
|
func easyjsonDc4bdceDecodeAuxpiBootstrap3(in *jlexer.Lexer, out *Account) { |
||||||
|
isTopLevel := in.IsStart() |
||||||
|
if in.IsNull() { |
||||||
|
if isTopLevel { |
||||||
|
in.Consumed() |
||||||
|
} |
||||||
|
in.Skip() |
||||||
|
return |
||||||
|
} |
||||||
|
in.Delim('{') |
||||||
|
for !in.IsDelim('}') { |
||||||
|
key := in.UnsafeString() |
||||||
|
in.WantColon() |
||||||
|
if in.IsNull() { |
||||||
|
in.Skip() |
||||||
|
in.WantComma() |
||||||
|
continue |
||||||
|
} |
||||||
|
switch key { |
||||||
|
case "user_name": |
||||||
|
out.UserName = string(in.String()) |
||||||
|
case "pass_word": |
||||||
|
out.PassWord = string(in.String()) |
||||||
|
case "reset_sina_cookie_time": |
||||||
|
out.ResetSinaCookieTime = int(in.Int()) |
||||||
|
case "defult_pic_size": |
||||||
|
out.DefultPicSize = string(in.String()) |
||||||
|
default: |
||||||
|
in.SkipRecursive() |
||||||
|
} |
||||||
|
in.WantComma() |
||||||
|
} |
||||||
|
in.Delim('}') |
||||||
|
if isTopLevel { |
||||||
|
in.Consumed() |
||||||
|
} |
||||||
|
} |
||||||
|
func easyjsonDc4bdceEncodeAuxpiBootstrap3(out *jwriter.Writer, in Account) { |
||||||
|
out.RawByte('{') |
||||||
|
first := true |
||||||
|
_ = first |
||||||
|
{ |
||||||
|
const prefix string = ",\"user_name\":" |
||||||
|
if first { |
||||||
|
first = false |
||||||
|
out.RawString(prefix[1:]) |
||||||
|
} else { |
||||||
|
out.RawString(prefix) |
||||||
|
} |
||||||
|
out.String(string(in.UserName)) |
||||||
|
} |
||||||
|
{ |
||||||
|
const prefix string = ",\"pass_word\":" |
||||||
|
if first { |
||||||
|
first = false |
||||||
|
out.RawString(prefix[1:]) |
||||||
|
} else { |
||||||
|
out.RawString(prefix) |
||||||
|
} |
||||||
|
out.String(string(in.PassWord)) |
||||||
|
} |
||||||
|
{ |
||||||
|
const prefix string = ",\"reset_sina_cookie_time\":" |
||||||
|
if first { |
||||||
|
first = false |
||||||
|
out.RawString(prefix[1:]) |
||||||
|
} else { |
||||||
|
out.RawString(prefix) |
||||||
|
} |
||||||
|
out.Int(int(in.ResetSinaCookieTime)) |
||||||
|
} |
||||||
|
{ |
||||||
|
const prefix string = ",\"defult_pic_size\":" |
||||||
|
if first { |
||||||
|
first = false |
||||||
|
out.RawString(prefix[1:]) |
||||||
|
} else { |
||||||
|
out.RawString(prefix) |
||||||
|
} |
||||||
|
out.String(string(in.DefultPicSize)) |
||||||
|
} |
||||||
|
out.RawByte('}') |
||||||
|
} |
||||||
|
|
||||||
|
// MarshalJSON supports json.Marshaler interface
|
||||||
|
func (v Account) MarshalJSON() ([]byte, error) { |
||||||
|
w := jwriter.Writer{} |
||||||
|
easyjsonDc4bdceEncodeAuxpiBootstrap3(&w, v) |
||||||
|
return w.Buffer.BuildBytes(), w.Error |
||||||
|
} |
||||||
|
|
||||||
|
// MarshalEasyJSON supports easyjson.Marshaler interface
|
||||||
|
func (v Account) MarshalEasyJSON(w *jwriter.Writer) { |
||||||
|
easyjsonDc4bdceEncodeAuxpiBootstrap3(w, v) |
||||||
|
} |
||||||
|
|
||||||
|
// UnmarshalJSON supports json.Unmarshaler interface
|
||||||
|
func (v *Account) UnmarshalJSON(data []byte) error { |
||||||
|
r := jlexer.Lexer{Data: data} |
||||||
|
easyjsonDc4bdceDecodeAuxpiBootstrap3(&r, v) |
||||||
|
return r.Error() |
||||||
|
} |
||||||
|
|
||||||
|
// UnmarshalEasyJSON supports easyjson.Unmarshaler interface
|
||||||
|
func (v *Account) UnmarshalEasyJSON(l *jlexer.Lexer) { |
||||||
|
easyjsonDc4bdceDecodeAuxpiBootstrap3(l, v) |
||||||
|
} |
@ -0,0 +1,32 @@ |
|||||||
|
package bootstrap |
||||||
|
|
||||||
|
import ( |
||||||
|
"encoding/base64" |
||||||
|
"log" |
||||||
|
"os" |
||||||
|
"path/filepath" |
||||||
|
"strings" |
||||||
|
) |
||||||
|
|
||||||
|
func GetPath() string { |
||||||
|
dir, err := filepath.Abs(filepath.Dir(os.Args[0])) //返回绝对路径 filepath.Dir(os.Args[0])去除最后一个元素的路径
|
||||||
|
if err != nil { |
||||||
|
log.Fatal(err) |
||||||
|
} |
||||||
|
return strings.Replace(dir, "\\", "/", -1) //将\替换成/
|
||||||
|
} |
||||||
|
|
||||||
|
func Decode(enc *base64.Encoding, str string) string { |
||||||
|
data, err := enc.DecodeString(str) |
||||||
|
|
||||||
|
if err != nil { |
||||||
|
panic(err) |
||||||
|
} |
||||||
|
return string(data) |
||||||
|
} |
||||||
|
|
||||||
|
func Encode(enc *base64.Encoding, str string) string { |
||||||
|
bData := []byte(str) |
||||||
|
data := enc.EncodeToString(bData) |
||||||
|
return string(data) |
||||||
|
} |
@ -0,0 +1,6 @@ |
|||||||
|
appname = auxpi |
||||||
|
httpport = 2333 |
||||||
|
runmode = dev |
||||||
|
enablexsrf = true |
||||||
|
xsrfkey = HIDoas923n;'0shd3jlc903jsp[a332 |
||||||
|
xsrfexpire = 3600 |
@ -0,0 +1,125 @@ |
|||||||
|
package api |
||||||
|
|
||||||
|
import ( |
||||||
|
"auxpi/bootstrap" |
||||||
|
"auxpi/server" |
||||||
|
"github.com/astaxie/beego" |
||||||
|
"log" |
||||||
|
"strings" |
||||||
|
) |
||||||
|
|
||||||
|
//easyjson:json
|
||||||
|
type ApiUpLoadController struct { |
||||||
|
beego.Controller |
||||||
|
server.Sina |
||||||
|
server.SouGou |
||||||
|
} |
||||||
|
|
||||||
|
//easyjson:json
|
||||||
|
type ResultJson struct { |
||||||
|
Code int `json:"code"` |
||||||
|
Msg string `json:"msg"` |
||||||
|
Data fileData `json:"data"` |
||||||
|
} |
||||||
|
|
||||||
|
//easyjson:json
|
||||||
|
type fileData struct { |
||||||
|
Name string `json:"name"` |
||||||
|
Url string `json:"url"` |
||||||
|
} |
||||||
|
|
||||||
|
//easyjson:json
|
||||||
|
type ErrorJson struct { |
||||||
|
Code int `json:"code"` |
||||||
|
Msg string `json:"msg"` |
||||||
|
} |
||||||
|
|
||||||
|
//需要关闭 xsrf
|
||||||
|
func (this *ApiUpLoadController) Prepare() { |
||||||
|
this.EnableXSRF = false |
||||||
|
} |
||||||
|
|
||||||
|
var picType = []string{"png", "jpg", "jpeg", "gif", "bmp"} |
||||||
|
var siteConfig = bootstrap.Config() |
||||||
|
|
||||||
|
func (c *ApiUpLoadController) URLMapping() { |
||||||
|
c.Mapping("UpLoad", c.AuthUpLoadHandle) |
||||||
|
} |
||||||
|
|
||||||
|
// @router /api/v1/upload/ [post]
|
||||||
|
func (this *ApiUpLoadController) AuthUpLoadHandle() { |
||||||
|
//获取上传类型
|
||||||
|
apiSelect := this.GetString("apiSelect") |
||||||
|
f, h, err := this.GetFile("image") |
||||||
|
defer f.Close() |
||||||
|
if err != nil { |
||||||
|
log.Fatal("File Upload Err", err) |
||||||
|
} |
||||||
|
imgMime := h.Header.Get("Content-Type") |
||||||
|
//验证
|
||||||
|
validate := this.validate(imgMime, h.Filename) |
||||||
|
if validate { |
||||||
|
//读取文件
|
||||||
|
size := h.Size |
||||||
|
fileContent := make([]byte, size) |
||||||
|
f.Read(fileContent) |
||||||
|
url := "" |
||||||
|
if siteConfig.SiteUploadWay.OpenSinaPicStore == false { |
||||||
|
url = this.UpLoadToSouGou(fileContent) |
||||||
|
} else { |
||||||
|
switch apiSelect { |
||||||
|
case "SouGou": |
||||||
|
url = this.UpLoadToSouGou(fileContent) |
||||||
|
case "Sina": |
||||||
|
url = this.UpLoadToSina(fileContent, imgMime) |
||||||
|
default: |
||||||
|
url = "" |
||||||
|
} |
||||||
|
} |
||||||
|
//url := this.UpLoadToSina(fileContent,imgMime)
|
||||||
|
//如果有返回值
|
||||||
|
if strings.HasPrefix(url, "http") { |
||||||
|
//配置 json
|
||||||
|
result := &ResultJson{} |
||||||
|
result.Code = 200 |
||||||
|
result.Msg = "上传成功" |
||||||
|
result.Data.Url = url |
||||||
|
result.Data.Name = h.Filename |
||||||
|
beego.Alert(result) |
||||||
|
this.Data["json"] = result |
||||||
|
this.ServeJSON() |
||||||
|
return |
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
|
//返回失败 json
|
||||||
|
result := &ErrorJson{} |
||||||
|
result.Code = 500 |
||||||
|
result.Msg = "上传失败" |
||||||
|
this.Data["json"] = result |
||||||
|
this.ServeJSON() |
||||||
|
return |
||||||
|
} |
||||||
|
|
||||||
|
//验证文件后缀&文件MIME
|
||||||
|
func (this *ApiUpLoadController) validate(contentType string, fileName string) bool { |
||||||
|
//首先检测文件的后缀
|
||||||
|
isSuffix := false |
||||||
|
for _, pType := range picType { |
||||||
|
if strings.HasSuffix(fileName, pType) { |
||||||
|
isSuffix = true |
||||||
|
break |
||||||
|
} |
||||||
|
} |
||||||
|
//然后检测 MIME 类型
|
||||||
|
//beego.Alert(contentType)
|
||||||
|
if strings.HasPrefix(contentType, "image") && isSuffix { |
||||||
|
for _, pType := range picType { |
||||||
|
if strings.HasSuffix(contentType, pType) { |
||||||
|
return true |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
|
return false |
||||||
|
} |
@ -0,0 +1,115 @@ |
|||||||
|
package page |
||||||
|
|
||||||
|
import ( |
||||||
|
"auxpi/bootstrap" |
||||||
|
"github.com/astaxie/beego" |
||||||
|
) |
||||||
|
|
||||||
|
type PagesController struct { |
||||||
|
beego.Controller |
||||||
|
} |
||||||
|
|
||||||
|
//获取 config 的配置
|
||||||
|
var siteConfig = bootstrap.Config() |
||||||
|
|
||||||
|
func (c *PagesController) URLMapping() { |
||||||
|
c.Mapping("Show", c.IndexShow) |
||||||
|
c.Mapping("AboutShow", c.AboutShow) |
||||||
|
c.Mapping("SinaShow", c.SinaShow) |
||||||
|
c.Mapping("TestShow", c.TestShow) |
||||||
|
} |
||||||
|
|
||||||
|
// @router / [get]
|
||||||
|
func (this *PagesController) IndexShow() { |
||||||
|
this.Data["siteName"] = siteConfig.SiteName |
||||||
|
this.Data["siteUrl"] = siteConfig.SiteUrl |
||||||
|
this.Data["siteFooterText"] = siteConfig.SiteFooter |
||||||
|
this.Data["apiUrl"] = "/api/v1/auth/upload" |
||||||
|
this.Data["maxNumber"] = siteConfig.SiteUploadMaxNumber |
||||||
|
//单位为Mb 5mb ==> 5*1024 kb
|
||||||
|
this.Data["maxPicSize"] = siteConfig.SiteUpLoadMaxSize << 10 |
||||||
|
this.Data["apiSelect"] = "SouGou" |
||||||
|
this.Data["iconStyle"] ="sougou" |
||||||
|
this.Data["iconColor"] ="orange" |
||||||
|
this.Data["xsrf_token"] = this.XSRFToken() |
||||||
|
this.LayoutSections = make(map[string]string) |
||||||
|
this.LayoutSections["Scripts"] = "upload/uploadScript.tpl" |
||||||
|
this.LayoutSections["Header"] = "layouts/header.tpl" |
||||||
|
this.LayoutSections["Footer"] = "layouts/footer.tpl" |
||||||
|
this.LayoutSections["Left"] = "layouts/left.tpl" |
||||||
|
this.Layout = "layouts/app.tpl" |
||||||
|
this.TplName = "upload/box.tpl" |
||||||
|
} |
||||||
|
|
||||||
|
// @router /Sina [get]
|
||||||
|
func (this *PagesController) SinaShow() { |
||||||
|
this.Data["siteName"] = siteConfig.SiteName |
||||||
|
this.Data["siteUrl"] = siteConfig.SiteUrl |
||||||
|
this.Data["siteFooterText"] = siteConfig.SiteFooter |
||||||
|
this.Data["apiUrl"] = "/api/v1/auth/upload" |
||||||
|
this.Data["maxNumber"] = siteConfig.SiteUploadMaxNumber |
||||||
|
//单位为Mb 5mb ==> 5*1024 kb
|
||||||
|
this.Data["maxPicSize"] = siteConfig.SiteUpLoadMaxSize << 10 |
||||||
|
this.Data["xsrf_token"] = this.XSRFToken() |
||||||
|
this.LayoutSections = make(map[string]string) |
||||||
|
this.Data["apiSelect"] = "Sina" |
||||||
|
this.Data["iconStyle"] ="xinlang" |
||||||
|
this.Data["iconColor"] ="red" |
||||||
|
this.LayoutSections["Scripts"] = "upload/uploadScript.tpl" |
||||||
|
this.LayoutSections["Header"] = "layouts/header.tpl" |
||||||
|
this.LayoutSections["Footer"] = "layouts/footer.tpl" |
||||||
|
this.LayoutSections["Left"] = "layouts/left.tpl" |
||||||
|
this.Layout = "layouts/app.tpl" |
||||||
|
//检测是否开启新浪图床
|
||||||
|
if siteConfig.SiteUploadWay.OpenSinaPicStore { |
||||||
|
this.TplName = "upload/box.tpl" |
||||||
|
return |
||||||
|
} |
||||||
|
this.TplName = "upload/ban.tpl" |
||||||
|
} |
||||||
|
|
||||||
|
// @router /about/ [get]
|
||||||
|
func (this *PagesController) AboutShow() { |
||||||
|
this.Data["siteName"] = siteConfig.SiteName |
||||||
|
this.Data["siteUrl"] = siteConfig.SiteUrl |
||||||
|
this.Data["siteFooterText"] = siteConfig.SiteFooter |
||||||
|
this.LayoutSections = make(map[string]string) |
||||||
|
this.LayoutSections["Scripts"] = "upload/uploadScript.tpl" |
||||||
|
this.LayoutSections["Header"] = "layouts/header.tpl" |
||||||
|
this.LayoutSections["Footer"] = "layouts/footer.tpl" |
||||||
|
this.LayoutSections["Left"] = "layouts/left.tpl" |
||||||
|
this.Data["title"] = "关于 Buster API 图床" |
||||||
|
this.Layout = "layouts/app.tpl" |
||||||
|
this.TplName = "about/about-me.tpl" |
||||||
|
} |
||||||
|
|
||||||
|
// @router /app [get]
|
||||||
|
func (this *PagesController) InstallShow() { |
||||||
|
this.Data["siteName"] = siteConfig.SiteName |
||||||
|
this.Data["siteUrl"] = siteConfig.SiteUrl |
||||||
|
this.Data["siteFooterText"] = siteConfig.SiteFooter |
||||||
|
this.TplName = "about-me.tpl" |
||||||
|
} |
||||||
|
|
||||||
|
// @router /test [get]
|
||||||
|
func (this *PagesController) TestShow() { |
||||||
|
this.Data["siteName"] = siteConfig.SiteName |
||||||
|
this.Data["siteUrl"] = siteConfig.SiteUrl |
||||||
|
this.Data["siteFooterText"] = siteConfig.SiteFooter |
||||||
|
this.Data["apiUrl"] = "/api/v1/auth/upload" |
||||||
|
this.Data["maxNumber"] = siteConfig.SiteUploadMaxNumber |
||||||
|
//单位为Mb 5mb ==> 5*1024 kb
|
||||||
|
this.Data["maxPicSize"] = siteConfig.SiteUpLoadMaxSize << 10 |
||||||
|
this.Data["xsrf_token"] = this.XSRFToken() |
||||||
|
this.LayoutSections = make(map[string]string) |
||||||
|
this.Data["apiSelect"] = "Sina" |
||||||
|
this.Data["iconStyle"] ="xinlang" |
||||||
|
this.Data["iconColor"] ="red" |
||||||
|
//this.LayoutSections["Scripts"] = "upload/uploadScript.tpl"
|
||||||
|
this.LayoutSections["Header"] = "layouts/header.tpl" |
||||||
|
this.LayoutSections["Footer"] = "layouts/footer.tpl" |
||||||
|
this.LayoutSections["Left"] = "layouts/left.tpl" |
||||||
|
this.Layout = "layouts/app.tpl" |
||||||
|
this.TplName = "upload/ban.tpl" |
||||||
|
|
||||||
|
} |
@ -0,0 +1,123 @@ |
|||||||
|
package controllers |
||||||
|
|
||||||
|
import ( |
||||||
|
"auxpi/server" |
||||||
|
"encoding/base64" |
||||||
|
"github.com/astaxie/beego" |
||||||
|
"log" |
||||||
|
"strings" |
||||||
|
) |
||||||
|
|
||||||
|
//easyjson:json
|
||||||
|
type UpLoadController struct { |
||||||
|
beego.Controller |
||||||
|
server.Sina |
||||||
|
server.SouGou |
||||||
|
} |
||||||
|
|
||||||
|
//easyjson:json
|
||||||
|
type ResultJson struct { |
||||||
|
Code int `json:"code"` |
||||||
|
Msg string `json:"msg"` |
||||||
|
Data fileData `json:"data"` |
||||||
|
} |
||||||
|
|
||||||
|
//easyjson:json
|
||||||
|
type fileData struct { |
||||||
|
Name string `json:"name"` |
||||||
|
Url string `json:"url"` |
||||||
|
} |
||||||
|
|
||||||
|
//easyjson:json
|
||||||
|
type ErrorJson struct { |
||||||
|
Code int `json:"code"` |
||||||
|
Msg string `json:"msg"` |
||||||
|
} |
||||||
|
|
||||||
|
var picType = []string{"png", "jpg", "jpeg", "gif", "bmp"} |
||||||
|
|
||||||
|
func (c *UpLoadController) URLMapping() { |
||||||
|
c.Mapping("UpLoad", c.AuthUpLoadHandle) |
||||||
|
} |
||||||
|
|
||||||
|
// @router /api/v1/auth/upload/ [post]
|
||||||
|
func (this *UpLoadController) AuthUpLoadHandle() { |
||||||
|
//获取上传类型
|
||||||
|
apiSelect := this.GetString("apiSelect") |
||||||
|
f, h, err := this.GetFile("image") |
||||||
|
defer f.Close() |
||||||
|
if err != nil { |
||||||
|
log.Fatal("File Upload Err", err) |
||||||
|
} |
||||||
|
imgMime := h.Header.Get("Content-Type") |
||||||
|
//验证
|
||||||
|
validate := this.validate(imgMime, h.Filename) |
||||||
|
if validate { |
||||||
|
//读取文件
|
||||||
|
size := h.Size |
||||||
|
fileContent := make([]byte, size) |
||||||
|
f.Read(fileContent) |
||||||
|
url := "" |
||||||
|
switch apiSelect { |
||||||
|
case "SouGou": |
||||||
|
url = this.UpLoadToSouGou(fileContent) |
||||||
|
case "Sina": |
||||||
|
url = this.UpLoadToSina(fileContent, imgMime) |
||||||
|
default: |
||||||
|
url = "" |
||||||
|
} |
||||||
|
//如果有返回值
|
||||||
|
if strings.HasPrefix(url, "http") { |
||||||
|
//配置 json
|
||||||
|
result := &ResultJson{} |
||||||
|
result.Code = 200 |
||||||
|
result.Msg = "上传成功" |
||||||
|
result.Data.Url = url |
||||||
|
result.Data.Name = h.Filename |
||||||
|
//beego.Alert(result)
|
||||||
|
this.Data["json"] = result |
||||||
|
this.ServeJSON() |
||||||
|
return |
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
|
//返回失败 json
|
||||||
|
result := &ErrorJson{} |
||||||
|
result.Code = 500 |
||||||
|
result.Msg = "上传失败" |
||||||
|
this.Data["json"] = result |
||||||
|
this.ServeJSON() |
||||||
|
return |
||||||
|
} |
||||||
|
|
||||||
|
//验证文件后缀&文件MIME
|
||||||
|
func (this *UpLoadController) validate(contentType string, fileName string) bool { |
||||||
|
//首先检测文件的后缀
|
||||||
|
isSuffix := false |
||||||
|
for _, pType := range picType { |
||||||
|
if strings.HasSuffix(fileName, pType) { |
||||||
|
isSuffix = true |
||||||
|
break |
||||||
|
} |
||||||
|
} |
||||||
|
//然后检测 MIME 类型
|
||||||
|
//beego.Alert(contentType)
|
||||||
|
if strings.HasPrefix(contentType, "image") && isSuffix { |
||||||
|
for _, pType := range picType { |
||||||
|
if strings.HasSuffix(contentType, pType) { |
||||||
|
return true |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
|
return false |
||||||
|
} |
||||||
|
|
||||||
|
//tools---
|
||||||
|
func Decode(enc *base64.Encoding, str string) string { |
||||||
|
data, err := enc.DecodeString(str) |
||||||
|
if err != nil { |
||||||
|
panic(err) |
||||||
|
} |
||||||
|
return string(data) |
||||||
|
} |
@ -0,0 +1,11 @@ |
|||||||
|
package main |
||||||
|
|
||||||
|
import ( |
||||||
|
_ "auxpi/routers" |
||||||
|
"github.com/astaxie/beego" |
||||||
|
) |
||||||
|
|
||||||
|
func main() { |
||||||
|
beego.Run() |
||||||
|
} |
||||||
|
|
@ -0,0 +1,24 @@ |
|||||||
|
package models |
||||||
|
|
||||||
|
type SiteDefault struct { |
||||||
|
Url string |
||||||
|
Api string |
||||||
|
} |
||||||
|
|
||||||
|
type SiteConfig struct { |
||||||
|
Name string |
||||||
|
//最大上传的图片个数
|
||||||
|
UploadMaxNumber string |
||||||
|
//最大图片规格 MB
|
||||||
|
UpLoadMaxSize int |
||||||
|
//图床储存的一些配置
|
||||||
|
UploadWay UploadConfig |
||||||
|
} |
||||||
|
|
||||||
|
type UploadConfig struct { |
||||||
|
//是否开启本地上传
|
||||||
|
LocalStore bool |
||||||
|
//选择上传的图床 Sina | SouGou | All
|
||||||
|
StorePic string |
||||||
|
//
|
||||||
|
} |
@ -0,0 +1,55 @@ |
|||||||
|
package routers |
||||||
|
|
||||||
|
import ( |
||||||
|
"github.com/astaxie/beego" |
||||||
|
"github.com/astaxie/beego/context/param" |
||||||
|
) |
||||||
|
|
||||||
|
func init() { |
||||||
|
|
||||||
|
beego.GlobalControllerRouter["auxpi/controllers:PagesController"] = append(beego.GlobalControllerRouter["auxpi/controllers:PagesController"], |
||||||
|
beego.ControllerComments{ |
||||||
|
Method: "IndexShow", |
||||||
|
Router: `/`, |
||||||
|
AllowHTTPMethods: []string{"get"}, |
||||||
|
MethodParams: param.Make(), |
||||||
|
Filters: nil, |
||||||
|
Params: nil}) |
||||||
|
|
||||||
|
beego.GlobalControllerRouter["auxpi/controllers:PagesController"] = append(beego.GlobalControllerRouter["auxpi/controllers:PagesController"], |
||||||
|
beego.ControllerComments{ |
||||||
|
Method: "SinaShow", |
||||||
|
Router: `/Sina`, |
||||||
|
AllowHTTPMethods: []string{"get"}, |
||||||
|
MethodParams: param.Make(), |
||||||
|
Filters: nil, |
||||||
|
Params: nil}) |
||||||
|
|
||||||
|
beego.GlobalControllerRouter["auxpi/controllers:PagesController"] = append(beego.GlobalControllerRouter["auxpi/controllers:PagesController"], |
||||||
|
beego.ControllerComments{ |
||||||
|
Method: "AboutShow", |
||||||
|
Router: `/about/`, |
||||||
|
AllowHTTPMethods: []string{"get"}, |
||||||
|
MethodParams: param.Make(), |
||||||
|
Filters: nil, |
||||||
|
Params: nil}) |
||||||
|
|
||||||
|
beego.GlobalControllerRouter["auxpi/controllers:PagesController"] = append(beego.GlobalControllerRouter["auxpi/controllers:PagesController"], |
||||||
|
beego.ControllerComments{ |
||||||
|
Method: "InstallShow", |
||||||
|
Router: `/app`, |
||||||
|
AllowHTTPMethods: []string{"get"}, |
||||||
|
MethodParams: param.Make(), |
||||||
|
Filters: nil, |
||||||
|
Params: nil}) |
||||||
|
|
||||||
|
beego.GlobalControllerRouter["auxpi/controllers:PagesController"] = append(beego.GlobalControllerRouter["auxpi/controllers:PagesController"], |
||||||
|
beego.ControllerComments{ |
||||||
|
Method: "TestShow", |
||||||
|
Router: `/test`, |
||||||
|
AllowHTTPMethods: []string{"get"}, |
||||||
|
MethodParams: param.Make(), |
||||||
|
Filters: nil, |
||||||
|
Params: nil}) |
||||||
|
|
||||||
|
} |
@ -0,0 +1,19 @@ |
|||||||
|
package routers |
||||||
|
|
||||||
|
import ( |
||||||
|
"github.com/astaxie/beego" |
||||||
|
"github.com/astaxie/beego/context/param" |
||||||
|
) |
||||||
|
|
||||||
|
func init() { |
||||||
|
|
||||||
|
beego.GlobalControllerRouter["auxpi/controllers/api:ApiUpLoadController"] = append(beego.GlobalControllerRouter["auxpi/controllers/api:ApiUpLoadController"], |
||||||
|
beego.ControllerComments{ |
||||||
|
Method: "AuthUpLoadHandle", |
||||||
|
Router: `/api/v1/upload/`, |
||||||
|
AllowHTTPMethods: []string{"post"}, |
||||||
|
MethodParams: param.Make(), |
||||||
|
Filters: nil, |
||||||
|
Params: nil}) |
||||||
|
|
||||||
|
} |
@ -0,0 +1,19 @@ |
|||||||
|
package routers |
||||||
|
|
||||||
|
import ( |
||||||
|
"github.com/astaxie/beego" |
||||||
|
"github.com/astaxie/beego/context/param" |
||||||
|
) |
||||||
|
|
||||||
|
func init() { |
||||||
|
|
||||||
|
beego.GlobalControllerRouter["auxpi/controllers/upload:UpLoadController"] = append(beego.GlobalControllerRouter["auxpi/controllers/upload:UpLoadController"], |
||||||
|
beego.ControllerComments{ |
||||||
|
Method: "AuthUpLoadHandle", |
||||||
|
Router: `/api/v1/auth/upload/`, |
||||||
|
AllowHTTPMethods: []string{"post"}, |
||||||
|
MethodParams: param.Make(), |
||||||
|
Filters: nil, |
||||||
|
Params: nil}) |
||||||
|
|
||||||
|
} |
@ -0,0 +1,55 @@ |
|||||||
|
package routers |
||||||
|
|
||||||
|
import ( |
||||||
|
"github.com/astaxie/beego" |
||||||
|
"github.com/astaxie/beego/context/param" |
||||||
|
) |
||||||
|
|
||||||
|
func init() { |
||||||
|
|
||||||
|
beego.GlobalControllerRouter["auxpi/controllers:PagesController"] = append(beego.GlobalControllerRouter["auxpi/controllers:PagesController"], |
||||||
|
beego.ControllerComments{ |
||||||
|
Method: "IndexShow", |
||||||
|
Router: `/`, |
||||||
|
AllowHTTPMethods: []string{"get"}, |
||||||
|
MethodParams: param.Make(), |
||||||
|
Filters: nil, |
||||||
|
Params: nil}) |
||||||
|
|
||||||
|
beego.GlobalControllerRouter["auxpi/controllers:PagesController"] = append(beego.GlobalControllerRouter["auxpi/controllers:PagesController"], |
||||||
|
beego.ControllerComments{ |
||||||
|
Method: "SinaShow", |
||||||
|
Router: `/Sina`, |
||||||
|
AllowHTTPMethods: []string{"get"}, |
||||||
|
MethodParams: param.Make(), |
||||||
|
Filters: nil, |
||||||
|
Params: nil}) |
||||||
|
|
||||||
|
beego.GlobalControllerRouter["auxpi/controllers:PagesController"] = append(beego.GlobalControllerRouter["auxpi/controllers:PagesController"], |
||||||
|
beego.ControllerComments{ |
||||||
|
Method: "AboutShow", |
||||||
|
Router: `/about/`, |
||||||
|
AllowHTTPMethods: []string{"get"}, |
||||||
|
MethodParams: param.Make(), |
||||||
|
Filters: nil, |
||||||
|
Params: nil}) |
||||||
|
|
||||||
|
beego.GlobalControllerRouter["auxpi/controllers:PagesController"] = append(beego.GlobalControllerRouter["auxpi/controllers:PagesController"], |
||||||
|
beego.ControllerComments{ |
||||||
|
Method: "InstallShow", |
||||||
|
Router: `/app`, |
||||||
|
AllowHTTPMethods: []string{"get"}, |
||||||
|
MethodParams: param.Make(), |
||||||
|
Filters: nil, |
||||||
|
Params: nil}) |
||||||
|
|
||||||
|
beego.GlobalControllerRouter["auxpi/controllers:PagesController"] = append(beego.GlobalControllerRouter["auxpi/controllers:PagesController"], |
||||||
|
beego.ControllerComments{ |
||||||
|
Method: "TestShow", |
||||||
|
Router: `/test`, |
||||||
|
AllowHTTPMethods: []string{"get"}, |
||||||
|
MethodParams: param.Make(), |
||||||
|
Filters: nil, |
||||||
|
Params: nil}) |
||||||
|
|
||||||
|
} |
@ -0,0 +1,19 @@ |
|||||||
|
package routers |
||||||
|
|
||||||
|
import ( |
||||||
|
"github.com/astaxie/beego" |
||||||
|
"github.com/astaxie/beego/context/param" |
||||||
|
) |
||||||
|
|
||||||
|
func init() { |
||||||
|
|
||||||
|
beego.GlobalControllerRouter["auxpi/controllers/api:ApiUpLoadController"] = append(beego.GlobalControllerRouter["auxpi/controllers/api:ApiUpLoadController"], |
||||||
|
beego.ControllerComments{ |
||||||
|
Method: "AuthUpLoadHandle", |
||||||
|
Router: `/api/v1/upload/`, |
||||||
|
AllowHTTPMethods: []string{"post"}, |
||||||
|
MethodParams: param.Make(), |
||||||
|
Filters: nil, |
||||||
|
Params: nil}) |
||||||
|
|
||||||
|
} |
@ -0,0 +1,19 @@ |
|||||||
|
package routers |
||||||
|
|
||||||
|
import ( |
||||||
|
"github.com/astaxie/beego" |
||||||
|
"github.com/astaxie/beego/context/param" |
||||||
|
) |
||||||
|
|
||||||
|
func init() { |
||||||
|
|
||||||
|
beego.GlobalControllerRouter["auxpi/controllers/upload:UpLoadController"] = append(beego.GlobalControllerRouter["auxpi/controllers/upload:UpLoadController"], |
||||||
|
beego.ControllerComments{ |
||||||
|
Method: "AuthUpLoadHandle", |
||||||
|
Router: `/api/v1/auth/upload/`, |
||||||
|
AllowHTTPMethods: []string{"post"}, |
||||||
|
MethodParams: param.Make(), |
||||||
|
Filters: nil, |
||||||
|
Params: nil}) |
||||||
|
|
||||||
|
} |
@ -0,0 +1,16 @@ |
|||||||
|
package routers |
||||||
|
|
||||||
|
import ( |
||||||
|
"auxpi/controllers" |
||||||
|
"auxpi/controllers/api" |
||||||
|
"auxpi/controllers/upload" |
||||||
|
"github.com/astaxie/beego" |
||||||
|
) |
||||||
|
|
||||||
|
func init() { |
||||||
|
//注册控制器内的路由
|
||||||
|
beego.Include(&controllers.UpLoadController{}) |
||||||
|
beego.Include(&page.PagesController{}) |
||||||
|
beego.Include(&api.ApiUpLoadController{}) |
||||||
|
} |
||||||
|
|
@ -0,0 +1,164 @@ |
|||||||
|
package server |
||||||
|
|
||||||
|
import ( |
||||||
|
"auxpi/bootstrap" |
||||||
|
"encoding/base64" |
||||||
|
"fmt" |
||||||
|
"github.com/astaxie/beego" |
||||||
|
"github.com/astaxie/beego/cache" |
||||||
|
"hash/crc32" |
||||||
|
"io/ioutil" |
||||||
|
"net/http" |
||||||
|
"net/url" |
||||||
|
"regexp" |
||||||
|
"strings" |
||||||
|
"time" |
||||||
|
) |
||||||
|
|
||||||
|
type Sina struct { |
||||||
|
} |
||||||
|
|
||||||
|
//easyjson:json
|
||||||
|
type SinaMsg struct { |
||||||
|
Code string `json:"code"` |
||||||
|
Data SinaData `json:"data"` |
||||||
|
} |
||||||
|
|
||||||
|
//easyjson:json
|
||||||
|
type SinaData struct { |
||||||
|
Count int `json:"count"` |
||||||
|
Data string `json:"data"` |
||||||
|
Pics SinaPics `json:"pics"` |
||||||
|
} |
||||||
|
|
||||||
|
//easyjson:json
|
||||||
|
type SinaPics struct { |
||||||
|
Pic_1 picInfo `json:"pic_1"` |
||||||
|
} |
||||||
|
|
||||||
|
//easyjson:json
|
||||||
|
type picInfo struct { |
||||||
|
Width int `json:"width"` |
||||||
|
Size int `json:"size"` |
||||||
|
Ret int `json:"ret"` |
||||||
|
Height int `json:"height"` |
||||||
|
Name string `json:"name"` |
||||||
|
Pid string `json:"pid"` |
||||||
|
} |
||||||
|
|
||||||
|
var picType = []string{"png", "jpg", "jpeg", "gif", "bmp"} |
||||||
|
var memoryCache, _ = cache.NewCache("memory", `{"interval":3600}`) |
||||||
|
//获取 config 的配置
|
||||||
|
var siteConfig = bootstrap.Config() |
||||||
|
|
||||||
|
func (this *Sina) Login(name string, pass string) interface{} { |
||||||
|
url := "https://login.sina.com.cn/sso/login.php?client=ssologin.js(v1.4.15)&_=1403138799543" |
||||||
|
userInfo := make(map[string]string) |
||||||
|
userInfo["UserName"] = bootstrap.Encode(base64.StdEncoding, name) |
||||||
|
userInfo["PassWord"] = pass |
||||||
|
cookie := this.getCookies(url, userInfo) |
||||||
|
return cookie |
||||||
|
} |
||||||
|
|
||||||
|
//返回综合 []*httpCookie
|
||||||
|
func (this *Sina) getCookies(durl string, data map[string]string) (interface{}) { |
||||||
|
//尝试从缓存里面获取 Cookie
|
||||||
|
if memoryCache.Get("SinaCookies") != nil { |
||||||
|
//beego.Alert("cached")
|
||||||
|
return memoryCache.Get("SinaCookies") |
||||||
|
} |
||||||
|
postData := make(url.Values) |
||||||
|
postData["entry"] = []string{"sso"} |
||||||
|
postData["gateway"] = []string{"1"} |
||||||
|
postData["from"] = []string{"null"} |
||||||
|
postData["savestate"] = []string{"30"} |
||||||
|
postData["uAddicket"] = []string{"0"} |
||||||
|
postData["pagerefer"] = []string{""} |
||||||
|
postData["vsnf"] = []string{"1"} |
||||||
|
postData["su"] = []string{data["UserName"]} //UserName
|
||||||
|
postData["service"] = []string{"sso"} |
||||||
|
postData["sp"] = []string{data["PassWord"]} //PassWord
|
||||||
|
postData["sr"] = []string{"1920*1080"} |
||||||
|
postData["encoding"] = []string{"UTF-8"} |
||||||
|
postData["cdult"] = []string{"3"} |
||||||
|
postData["domain"] = []string{"sina.com.cn"} |
||||||
|
postData["prelt"] = []string{"0"} |
||||||
|
postData["returntype"] = []string{"TEXT"} |
||||||
|
client := &http.Client{} |
||||||
|
request, err := http.NewRequest("POST", durl, strings.NewReader(postData.Encode())) |
||||||
|
if err != nil { |
||||||
|
fmt.Println(err) |
||||||
|
} |
||||||
|
request.Header.Set("Content-Type", "application/x-www-form-urlencoded") |
||||||
|
resp, err := client.Do(request) |
||||||
|
defer resp.Body.Close() |
||||||
|
cookie := resp.Cookies() |
||||||
|
//缓存 Cookie 缓存一个小时
|
||||||
|
memoryCache.Put("SinaCookies", cookie, time.Second*3600) |
||||||
|
return cookie |
||||||
|
} |
||||||
|
|
||||||
|
//上传图片
|
||||||
|
func (this *Sina) UpLoadToSina(img []byte, imgType string) string { |
||||||
|
if siteConfig.SiteUploadWay.OpenSinaPicStore == false { |
||||||
|
return "" |
||||||
|
} |
||||||
|
durl := "http://picupload.service.weibo.com/interface/pic_upload.php" + |
||||||
|
"?mime=image%2Fjpeg&data=base64&url=0&markpos=1&logo=&nick=0&marks=1&app=miniblog" |
||||||
|
imgStr := base64.StdEncoding.EncodeToString(img) |
||||||
|
//构造 http 请求
|
||||||
|
postData := make(url.Values) |
||||||
|
postData["b64_data"] = []string{imgStr} |
||||||
|
client := &http.Client{} |
||||||
|
request, err := http.NewRequest("POST", durl, strings.NewReader(postData.Encode())) |
||||||
|
if err != nil { |
||||||
|
fmt.Println(err) |
||||||
|
} |
||||||
|
request.Header.Set("Content-Type", "application/x-www-form-urlencoded") |
||||||
|
//设置 cookie
|
||||||
|
uncooikes := this.Login(siteConfig.SiteUploadWay.SinaAccount.UserName, siteConfig.SiteUploadWay.SinaAccount.PassWord) |
||||||
|
//需要进行断言转换
|
||||||
|
cookies, ok := uncooikes.([]*http.Cookie) |
||||||
|
if !ok { |
||||||
|
panic(ok) |
||||||
|
} |
||||||
|
for _, value := range cookies { |
||||||
|
request.AddCookie(value) |
||||||
|
} |
||||||
|
resp, err := client.Do(request) |
||||||
|
defer resp.Body.Close() |
||||||
|
body, err := ioutil.ReadAll(resp.Body) |
||||||
|
return this.getSinaUrl(body, imgType) |
||||||
|
} |
||||||
|
|
||||||
|
func (this *Sina) getSinaUrl(body []byte, imgType string) string { |
||||||
|
str := string(body) |
||||||
|
//正则获取
|
||||||
|
pat := "({.*)" |
||||||
|
check := "[a-zA-Z0-9]{32}" |
||||||
|
res := regexp.MustCompile(pat) |
||||||
|
rule := regexp.MustCompile(check) |
||||||
|
jsons := res.FindAllStringSubmatch(str, -1) |
||||||
|
//beego.Alert(rule, jsons)
|
||||||
|
msg := SinaMsg{} |
||||||
|
//解析 json 到 struct
|
||||||
|
msg.UnmarshalJSON([]byte(jsons[0][1])) |
||||||
|
//验证 pid 的合法性
|
||||||
|
pid := msg.Data.Pics.Pic_1.Pid |
||||||
|
if rule.MatchString(pid) { |
||||||
|
sinaNumber := fmt.Sprint((crc32.ChecksumIEEE([]byte(pid)) & 3) + 1) |
||||||
|
//从配置文件中获取
|
||||||
|
size := siteConfig.SiteUploadWay.SinaAccount.DefultPicSize |
||||||
|
n := len(imgType) |
||||||
|
rs := []rune(imgType) |
||||||
|
suffix := string(rs[6:n]) |
||||||
|
if suffix != "gif" { |
||||||
|
suffix = "jpg" |
||||||
|
} |
||||||
|
sinaUrl := "https://ws" + sinaNumber + ".sinaimg.cn/" + size + "/" + pid + "." + suffix |
||||||
|
//转成 rune 直接截取即可 "image/png"
|
||||||
|
beego.Alert(sinaUrl) |
||||||
|
return sinaUrl |
||||||
|
} |
||||||
|
return "" |
||||||
|
} |
@ -0,0 +1,458 @@ |
|||||||
|
// Code generated by easyjson for marshaling/unmarshaling. DO NOT EDIT.
|
||||||
|
|
||||||
|
package server |
||||||
|
|
||||||
|
import ( |
||||||
|
json "encoding/json" |
||||||
|
easyjson "github.com/mailru/easyjson" |
||||||
|
jlexer "github.com/mailru/easyjson/jlexer" |
||||||
|
jwriter "github.com/mailru/easyjson/jwriter" |
||||||
|
) |
||||||
|
|
||||||
|
// suppress unused package warning
|
||||||
|
var ( |
||||||
|
_ *json.RawMessage |
||||||
|
_ *jlexer.Lexer |
||||||
|
_ *jwriter.Writer |
||||||
|
_ easyjson.Marshaler |
||||||
|
) |
||||||
|
|
||||||
|
func easyjsonB7954fafDecodeAuxpiServer(in *jlexer.Lexer, out *picInfo) { |
||||||
|
isTopLevel := in.IsStart() |
||||||
|
if in.IsNull() { |
||||||
|
if isTopLevel { |
||||||
|
in.Consumed() |
||||||
|
} |
||||||
|
in.Skip() |
||||||
|
return |
||||||
|
} |
||||||
|
in.Delim('{') |
||||||
|
for !in.IsDelim('}') { |
||||||
|
key := in.UnsafeString() |
||||||
|
in.WantColon() |
||||||
|
if in.IsNull() { |
||||||
|
in.Skip() |
||||||
|
in.WantComma() |
||||||
|
continue |
||||||
|
} |
||||||
|
switch key { |
||||||
|
case "width": |
||||||
|
out.Width = int(in.Int()) |
||||||
|
case "size": |
||||||
|
out.Size = int(in.Int()) |
||||||
|
case "ret": |
||||||
|
out.Ret = int(in.Int()) |
||||||
|
case "height": |
||||||
|
out.Height = int(in.Int()) |
||||||
|
case "name": |
||||||
|
out.Name = string(in.String()) |
||||||
|
case "pid": |
||||||
|
out.Pid = string(in.String()) |
||||||
|
default: |
||||||
|
in.SkipRecursive() |
||||||
|
} |
||||||
|
in.WantComma() |
||||||
|
} |
||||||
|
in.Delim('}') |
||||||
|
if isTopLevel { |
||||||
|
in.Consumed() |
||||||
|
} |
||||||
|
} |
||||||
|
func easyjsonB7954fafEncodeAuxpiServer(out *jwriter.Writer, in picInfo) { |
||||||
|
out.RawByte('{') |
||||||
|
first := true |
||||||
|
_ = first |
||||||
|
{ |
||||||
|
const prefix string = ",\"width\":" |
||||||
|
if first { |
||||||
|
first = false |
||||||
|
out.RawString(prefix[1:]) |
||||||
|
} else { |
||||||
|
out.RawString(prefix) |
||||||
|
} |
||||||
|
out.Int(int(in.Width)) |
||||||
|
} |
||||||
|
{ |
||||||
|
const prefix string = ",\"size\":" |
||||||
|
if first { |
||||||
|
first = false |
||||||
|
out.RawString(prefix[1:]) |
||||||
|
} else { |
||||||
|
out.RawString(prefix) |
||||||
|
} |
||||||
|
out.Int(int(in.Size)) |
||||||
|
} |
||||||
|
{ |
||||||
|
const prefix string = ",\"ret\":" |
||||||
|
if first { |
||||||
|
first = false |
||||||
|
out.RawString(prefix[1:]) |
||||||
|
} else { |
||||||
|
out.RawString(prefix) |
||||||
|
} |
||||||
|
out.Int(int(in.Ret)) |
||||||
|
} |
||||||
|
{ |
||||||
|
const prefix string = ",\"height\":" |
||||||
|
if first { |
||||||
|
first = false |
||||||
|
out.RawString(prefix[1:]) |
||||||
|
} else { |
||||||
|
out.RawString(prefix) |
||||||
|
} |
||||||
|
out.Int(int(in.Height)) |
||||||
|
} |
||||||
|
{ |
||||||
|
const prefix string = ",\"name\":" |
||||||
|
if first { |
||||||
|
first = false |
||||||
|
out.RawString(prefix[1:]) |
||||||
|
} else { |
||||||
|
out.RawString(prefix) |
||||||
|
} |
||||||
|
out.String(string(in.Name)) |
||||||
|
} |
||||||
|
{ |
||||||
|
const prefix string = ",\"pid\":" |
||||||
|
if first { |
||||||
|
first = false |
||||||
|
out.RawString(prefix[1:]) |
||||||
|
} else { |
||||||
|
out.RawString(prefix) |
||||||
|
} |
||||||
|
out.String(string(in.Pid)) |
||||||
|
} |
||||||
|
out.RawByte('}') |
||||||
|
} |
||||||
|
|
||||||
|
// MarshalJSON supports json.Marshaler interface
|
||||||
|
func (v picInfo) MarshalJSON() ([]byte, error) { |
||||||
|
w := jwriter.Writer{} |
||||||
|
easyjsonB7954fafEncodeAuxpiServer(&w, v) |
||||||
|
return w.Buffer.BuildBytes(), w.Error |
||||||
|
} |
||||||
|
|
||||||
|
// MarshalEasyJSON supports easyjson.Marshaler interface
|
||||||
|
func (v picInfo) MarshalEasyJSON(w *jwriter.Writer) { |
||||||
|
easyjsonB7954fafEncodeAuxpiServer(w, v) |
||||||
|
} |
||||||
|
|
||||||
|
// UnmarshalJSON supports json.Unmarshaler interface
|
||||||
|
func (v *picInfo) UnmarshalJSON(data []byte) error { |
||||||
|
r := jlexer.Lexer{Data: data} |
||||||
|
easyjsonB7954fafDecodeAuxpiServer(&r, v) |
||||||
|
return r.Error() |
||||||
|
} |
||||||
|
|
||||||
|
// UnmarshalEasyJSON supports easyjson.Unmarshaler interface
|
||||||
|
func (v *picInfo) UnmarshalEasyJSON(l *jlexer.Lexer) { |
||||||
|
easyjsonB7954fafDecodeAuxpiServer(l, v) |
||||||
|
} |
||||||
|
func easyjsonB7954fafDecodeAuxpiServer1(in *jlexer.Lexer, out *SinaPics) { |
||||||
|
isTopLevel := in.IsStart() |
||||||
|
if in.IsNull() { |
||||||
|
if isTopLevel { |
||||||
|
in.Consumed() |
||||||
|
} |
||||||
|
in.Skip() |
||||||
|
return |
||||||
|
} |
||||||
|
in.Delim('{') |
||||||
|
for !in.IsDelim('}') { |
||||||
|
key := in.UnsafeString() |
||||||
|
in.WantColon() |
||||||
|
if in.IsNull() { |
||||||
|
in.Skip() |
||||||
|
in.WantComma() |
||||||
|
continue |
||||||
|
} |
||||||
|
switch key { |
||||||
|
case "pic_1": |
||||||
|
(out.Pic_1).UnmarshalEasyJSON(in) |
||||||
|
default: |
||||||
|
in.SkipRecursive() |
||||||
|
} |
||||||
|
in.WantComma() |
||||||
|
} |
||||||
|
in.Delim('}') |
||||||
|
if isTopLevel { |
||||||
|
in.Consumed() |
||||||
|
} |
||||||
|
} |
||||||
|
func easyjsonB7954fafEncodeAuxpiServer1(out *jwriter.Writer, in SinaPics) { |
||||||
|
out.RawByte('{') |
||||||
|
first := true |
||||||
|
_ = first |
||||||
|
{ |
||||||
|
const prefix string = ",\"pic_1\":" |
||||||
|
if first { |
||||||
|
first = false |
||||||
|
out.RawString(prefix[1:]) |
||||||
|
} else { |
||||||
|
out.RawString(prefix) |
||||||
|
} |
||||||
|
(in.Pic_1).MarshalEasyJSON(out) |
||||||
|
} |
||||||
|
out.RawByte('}') |
||||||
|
} |
||||||
|
|
||||||
|
// MarshalJSON supports json.Marshaler interface
|
||||||
|
func (v SinaPics) MarshalJSON() ([]byte, error) { |
||||||
|
w := jwriter.Writer{} |
||||||
|
easyjsonB7954fafEncodeAuxpiServer1(&w, v) |
||||||
|
return w.Buffer.BuildBytes(), w.Error |
||||||
|
} |
||||||
|
|
||||||
|
// MarshalEasyJSON supports easyjson.Marshaler interface
|
||||||
|
func (v SinaPics) MarshalEasyJSON(w *jwriter.Writer) { |
||||||
|
easyjsonB7954fafEncodeAuxpiServer1(w, v) |
||||||
|
} |
||||||
|
|
||||||
|
// UnmarshalJSON supports json.Unmarshaler interface
|
||||||
|
func (v *SinaPics) UnmarshalJSON(data []byte) error { |
||||||
|
r := jlexer.Lexer{Data: data} |
||||||
|
easyjsonB7954fafDecodeAuxpiServer1(&r, v) |
||||||
|
return r.Error() |
||||||
|
} |
||||||
|
|
||||||
|
// UnmarshalEasyJSON supports easyjson.Unmarshaler interface
|
||||||
|
func (v *SinaPics) UnmarshalEasyJSON(l *jlexer.Lexer) { |
||||||
|
easyjsonB7954fafDecodeAuxpiServer1(l, v) |
||||||
|
} |
||||||
|
func easyjsonB7954fafDecodeAuxpiServer2(in *jlexer.Lexer, out *SinaMsg) { |
||||||
|
isTopLevel := in.IsStart() |
||||||
|
if in.IsNull() { |
||||||
|
if isTopLevel { |
||||||
|
in.Consumed() |
||||||
|
} |
||||||
|
in.Skip() |
||||||
|
return |
||||||
|
} |
||||||
|
in.Delim('{') |
||||||
|
for !in.IsDelim('}') { |
||||||
|
key := in.UnsafeString() |
||||||
|
in.WantColon() |
||||||
|
if in.IsNull() { |
||||||
|
in.Skip() |
||||||
|
in.WantComma() |
||||||
|
continue |
||||||
|
} |
||||||
|
switch key { |
||||||
|
case "code": |
||||||
|
out.Code = string(in.String()) |
||||||
|
case "data": |
||||||
|
(out.Data).UnmarshalEasyJSON(in) |
||||||
|
default: |
||||||
|
in.SkipRecursive() |
||||||
|
} |
||||||
|
in.WantComma() |
||||||
|
} |
||||||
|
in.Delim('}') |
||||||
|
if isTopLevel { |
||||||
|
in.Consumed() |
||||||
|
} |
||||||
|
} |
||||||
|
func easyjsonB7954fafEncodeAuxpiServer2(out *jwriter.Writer, in SinaMsg) { |
||||||
|
out.RawByte('{') |
||||||
|
first := true |
||||||
|
_ = first |
||||||
|
{ |
||||||
|
const prefix string = ",\"code\":" |
||||||
|
if first { |
||||||
|
first = false |
||||||
|
out.RawString(prefix[1:]) |
||||||
|
} else { |
||||||
|
out.RawString(prefix) |
||||||
|
} |
||||||
|
out.String(string(in.Code)) |
||||||
|
} |
||||||
|
{ |
||||||
|
const prefix string = ",\"data\":" |
||||||
|
if first { |
||||||
|
first = false |
||||||
|
out.RawString(prefix[1:]) |
||||||
|
} else { |
||||||
|
out.RawString(prefix) |
||||||
|
} |
||||||
|
(in.Data).MarshalEasyJSON(out) |
||||||
|
} |
||||||
|
out.RawByte('}') |
||||||
|
} |
||||||
|
|
||||||
|
// MarshalJSON supports json.Marshaler interface
|
||||||
|
func (v SinaMsg) MarshalJSON() ([]byte, error) { |
||||||
|
w := jwriter.Writer{} |
||||||
|
easyjsonB7954fafEncodeAuxpiServer2(&w, v) |
||||||
|
return w.Buffer.BuildBytes(), w.Error |
||||||
|
} |
||||||
|
|
||||||
|
// MarshalEasyJSON supports easyjson.Marshaler interface
|
||||||
|
func (v SinaMsg) MarshalEasyJSON(w *jwriter.Writer) { |
||||||
|
easyjsonB7954fafEncodeAuxpiServer2(w, v) |
||||||
|
} |
||||||
|
|
||||||
|
// UnmarshalJSON supports json.Unmarshaler interface
|
||||||
|
func (v *SinaMsg) UnmarshalJSON(data []byte) error { |
||||||
|
r := jlexer.Lexer{Data: data} |
||||||
|
easyjsonB7954fafDecodeAuxpiServer2(&r, v) |
||||||
|
return r.Error() |
||||||
|
} |
||||||
|
|
||||||
|
// UnmarshalEasyJSON supports easyjson.Unmarshaler interface
|
||||||
|
func (v *SinaMsg) UnmarshalEasyJSON(l *jlexer.Lexer) { |
||||||
|
easyjsonB7954fafDecodeAuxpiServer2(l, v) |
||||||
|
} |
||||||
|
func easyjsonB7954fafDecodeAuxpiServer3(in *jlexer.Lexer, out *SinaData) { |
||||||
|
isTopLevel := in.IsStart() |
||||||
|
if in.IsNull() { |
||||||
|
if isTopLevel { |
||||||
|
in.Consumed() |
||||||
|
} |
||||||
|
in.Skip() |
||||||
|
return |
||||||
|
} |
||||||
|
in.Delim('{') |
||||||
|
for !in.IsDelim('}') { |
||||||
|
key := in.UnsafeString() |
||||||
|
in.WantColon() |
||||||
|
if in.IsNull() { |
||||||
|
in.Skip() |
||||||
|
in.WantComma() |
||||||
|
continue |
||||||
|
} |
||||||
|
switch key { |
||||||
|
case "count": |
||||||
|
out.Count = int(in.Int()) |
||||||
|
case "data": |
||||||
|
out.Data = string(in.String()) |
||||||
|
case "pics": |
||||||
|
(out.Pics).UnmarshalEasyJSON(in) |
||||||
|
default: |
||||||
|
in.SkipRecursive() |
||||||
|
} |
||||||
|
in.WantComma() |
||||||
|
} |
||||||
|
in.Delim('}') |
||||||
|
if isTopLevel { |
||||||
|
in.Consumed() |
||||||
|
} |
||||||
|
} |
||||||
|
func easyjsonB7954fafEncodeAuxpiServer3(out *jwriter.Writer, in SinaData) { |
||||||
|
out.RawByte('{') |
||||||
|
first := true |
||||||
|
_ = first |
||||||
|
{ |
||||||
|
const prefix string = ",\"count\":" |
||||||
|
if first { |
||||||
|
first = false |
||||||
|
out.RawString(prefix[1:]) |
||||||
|
} else { |
||||||
|
out.RawString(prefix) |
||||||
|
} |
||||||
|
out.Int(int(in.Count)) |
||||||
|
} |
||||||
|
{ |
||||||
|
const prefix string = ",\"data\":" |
||||||
|
if first { |
||||||
|
first = false |
||||||
|
out.RawString(prefix[1:]) |
||||||
|
} else { |
||||||
|
out.RawString(prefix) |
||||||
|
} |
||||||
|
out.String(string(in.Data)) |
||||||
|
} |
||||||
|
{ |
||||||
|
const prefix string = ",\"pics\":" |
||||||
|
if first { |
||||||
|
first = false |
||||||
|
out.RawString(prefix[1:]) |
||||||
|
} else { |
||||||
|
out.RawString(prefix) |
||||||
|
} |
||||||
|
(in.Pics).MarshalEasyJSON(out) |
||||||
|
} |
||||||
|
out.RawByte('}') |
||||||
|
} |
||||||
|
|
||||||
|
// MarshalJSON supports json.Marshaler interface
|
||||||
|
func (v SinaData) MarshalJSON() ([]byte, error) { |
||||||
|
w := jwriter.Writer{} |
||||||
|
easyjsonB7954fafEncodeAuxpiServer3(&w, v) |
||||||
|
return w.Buffer.BuildBytes(), w.Error |
||||||
|
} |
||||||
|
|
||||||
|
// MarshalEasyJSON supports easyjson.Marshaler interface
|
||||||
|
func (v SinaData) MarshalEasyJSON(w *jwriter.Writer) { |
||||||
|
easyjsonB7954fafEncodeAuxpiServer3(w, v) |
||||||
|
} |
||||||
|
|
||||||
|
// UnmarshalJSON supports json.Unmarshaler interface
|
||||||
|
func (v *SinaData) UnmarshalJSON(data []byte) error { |
||||||
|
r := jlexer.Lexer{Data: data} |
||||||
|
easyjsonB7954fafDecodeAuxpiServer3(&r, v) |
||||||
|
return r.Error() |
||||||
|
} |
||||||
|
|
||||||
|
// UnmarshalEasyJSON supports easyjson.Unmarshaler interface
|
||||||
|
func (v *SinaData) UnmarshalEasyJSON(l *jlexer.Lexer) { |
||||||
|
easyjsonB7954fafDecodeAuxpiServer3(l, v) |
||||||
|
} |
||||||
|
func easyjsonB7954fafDecodeAuxpiServer4(in *jlexer.Lexer, out *Sina) { |
||||||
|
isTopLevel := in.IsStart() |
||||||
|
if in.IsNull() { |
||||||
|
if isTopLevel { |
||||||
|
in.Consumed() |
||||||
|
} |
||||||
|
in.Skip() |
||||||
|
return |
||||||
|
} |
||||||
|
in.Delim('{') |
||||||
|
for !in.IsDelim('}') { |
||||||
|
key := in.UnsafeString() |
||||||
|
in.WantColon() |
||||||
|
if in.IsNull() { |
||||||
|
in.Skip() |
||||||
|
in.WantComma() |
||||||
|
continue |
||||||
|
} |
||||||
|
switch key { |
||||||
|
default: |
||||||
|
in.SkipRecursive() |
||||||
|
} |
||||||
|
in.WantComma() |
||||||
|
} |
||||||
|
in.Delim('}') |
||||||
|
if isTopLevel { |
||||||
|
in.Consumed() |
||||||
|
} |
||||||
|
} |
||||||
|
func easyjsonB7954fafEncodeAuxpiServer4(out *jwriter.Writer, in Sina) { |
||||||
|
out.RawByte('{') |
||||||
|
first := true |
||||||
|
_ = first |
||||||
|
out.RawByte('}') |
||||||
|
} |
||||||
|
|
||||||
|
// MarshalJSON supports json.Marshaler interface
|
||||||
|
func (v Sina) MarshalJSON() ([]byte, error) { |
||||||
|
w := jwriter.Writer{} |
||||||
|
easyjsonB7954fafEncodeAuxpiServer4(&w, v) |
||||||
|
return w.Buffer.BuildBytes(), w.Error |
||||||
|
} |
||||||
|
|
||||||
|
// MarshalEasyJSON supports easyjson.Marshaler interface
|
||||||
|
func (v Sina) MarshalEasyJSON(w *jwriter.Writer) { |
||||||
|
easyjsonB7954fafEncodeAuxpiServer4(w, v) |
||||||
|
} |
||||||
|
|
||||||
|
// UnmarshalJSON supports json.Unmarshaler interface
|
||||||
|
func (v *Sina) UnmarshalJSON(data []byte) error { |
||||||
|
r := jlexer.Lexer{Data: data} |
||||||
|
easyjsonB7954fafDecodeAuxpiServer4(&r, v) |
||||||
|
return r.Error() |
||||||
|
} |
||||||
|
|
||||||
|
// UnmarshalEasyJSON supports easyjson.Unmarshaler interface
|
||||||
|
func (v *Sina) UnmarshalEasyJSON(l *jlexer.Lexer) { |
||||||
|
easyjsonB7954fafDecodeAuxpiServer4(l, v) |
||||||
|
} |
@ -0,0 +1,37 @@ |
|||||||
|
package server |
||||||
|
|
||||||
|
import ( |
||||||
|
"auxpi/bootstrap" |
||||||
|
"bytes" |
||||||
|
"encoding/base64" |
||||||
|
"io/ioutil" |
||||||
|
"net/http" |
||||||
|
"strings" |
||||||
|
) |
||||||
|
|
||||||
|
type SouGou struct { |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
func (this *SouGou) UpLoadToSouGou(img []byte) string { |
||||||
|
preStr := "LS0tLS0tV2ViS2l0Rm9ybUJvdW5kYXJ5R0xmR0IwSGdVTnRwVFQxaw0KQ29udGVudC1EaXNwb3NpdGlvbjogZm9ybS1kYXRhOyBuYW1lPSJwaWNfcGF0aCI7IGZpbGVuYW1lPSIxMS5wbmciDQpDb250ZW50LVR5cGU6IGltYWdlL3BuZw0KDQo=" |
||||||
|
sufStr := "DQotLS0tLS1XZWJLaXRGb3JtQm91bmRhcnlHTGZHQjBIZ1VOdHBUVDFrLS0NCg==" |
||||||
|
preStr = bootstrap.Decode(base64.StdEncoding, preStr) |
||||||
|
sufStr = bootstrap.Decode(base64.StdEncoding, sufStr) |
||||||
|
imgStr := bootstrap.Decode(base64.StdEncoding, base64.StdEncoding.EncodeToString(img)) |
||||||
|
data := []byte(preStr + string(img) + sufStr) |
||||||
|
url := "http://pic.sogou.com/pic/upload_pic.jsp" |
||||||
|
client := &http.Client{} |
||||||
|
req, _ := http.NewRequest("POST", url, bytes.NewBuffer(data)) |
||||||
|
req.Header.Set("Content-Type", " multipart/form-data; boundary=----WebKitFormBoundaryGLfGB0HgUNtpTT1k") |
||||||
|
req.Header.Add("Content-Length", string(strings.Count(imgStr, ""))) |
||||||
|
resp, err := client.Do(req) |
||||||
|
if err != nil { |
||||||
|
panic(err) |
||||||
|
} |
||||||
|
defer resp.Body.Close() |
||||||
|
body, _ := ioutil.ReadAll(resp.Body) |
||||||
|
respUrl :=string(body) |
||||||
|
respUrl = strings.Replace(respUrl,"http","https",-1) |
||||||
|
return respUrl |
||||||
|
} |
@ -0,0 +1,511 @@ |
|||||||
|
*, |
||||||
|
*:before, |
||||||
|
*:after { |
||||||
|
box-sizing: border-box; |
||||||
|
} |
||||||
|
a { |
||||||
|
color: #03A9F4; |
||||||
|
} |
||||||
|
a, |
||||||
|
a:hover, |
||||||
|
a:active, |
||||||
|
a:focus { |
||||||
|
text-decoration: none; |
||||||
|
} |
||||||
|
a:focus { |
||||||
|
outline-style: none; |
||||||
|
} |
||||||
|
audio, |
||||||
|
body, |
||||||
|
caption, |
||||||
|
div, |
||||||
|
footer, |
||||||
|
form, |
||||||
|
h1, |
||||||
|
h2, |
||||||
|
h3, |
||||||
|
h4, |
||||||
|
h5, |
||||||
|
h6, |
||||||
|
header, |
||||||
|
html, |
||||||
|
iframe, |
||||||
|
label, |
||||||
|
legend, |
||||||
|
li, |
||||||
|
main, |
||||||
|
mark, |
||||||
|
menu, |
||||||
|
nav, |
||||||
|
ol, |
||||||
|
p, |
||||||
|
section, |
||||||
|
span, |
||||||
|
summary, |
||||||
|
table, |
||||||
|
textarea, |
||||||
|
time, |
||||||
|
ul, |
||||||
|
video { |
||||||
|
padding: 0; |
||||||
|
margin: 0; |
||||||
|
border: 0; |
||||||
|
outline: 0 none; |
||||||
|
} |
||||||
|
html { |
||||||
|
position: relative; |
||||||
|
min-height: 100%; |
||||||
|
} |
||||||
|
html, |
||||||
|
body { |
||||||
|
width: 100%; |
||||||
|
margin: 0; |
||||||
|
padding: 0; |
||||||
|
} |
||||||
|
body { |
||||||
|
margin-bottom: 60px; |
||||||
|
overflow-x: hidden; |
||||||
|
} |
||||||
|
.mdui-drawer-body-left footer { |
||||||
|
width: calc(100% - 240px); |
||||||
|
} |
||||||
|
main { |
||||||
|
position: relative; |
||||||
|
top: 0; |
||||||
|
left: 0; |
||||||
|
right: 0; |
||||||
|
margin: 1.7rem 0; |
||||||
|
} |
||||||
|
main .login-container, |
||||||
|
main .register-container { |
||||||
|
margin-top: 4rem; |
||||||
|
margin-bottom: 4rem; |
||||||
|
} |
||||||
|
main .not-logged-in { |
||||||
|
margin: 10rem 0; |
||||||
|
text-align: center; |
||||||
|
} |
||||||
|
main .not-logged-in h2 { |
||||||
|
margin-bottom: 2rem; |
||||||
|
} |
||||||
|
main .upload-container .title { |
||||||
|
margin: 1rem 0; |
||||||
|
} |
||||||
|
main .upload-container .title h1 { |
||||||
|
font-weight: 300; |
||||||
|
font-size: 3rem; |
||||||
|
text-shadow: -5px 5px 0 rgba(0, 0, 0, 0.1); |
||||||
|
} |
||||||
|
main .upload-container .title p { |
||||||
|
margin-top: 1rem; |
||||||
|
font-size: 1.3rem; |
||||||
|
color: #999; |
||||||
|
} |
||||||
|
main .upload-container .success-info { |
||||||
|
margin-top: 1rem; |
||||||
|
width: 0; |
||||||
|
} |
||||||
|
main .upload-container .success-info .mdui-tab a { |
||||||
|
text-transform: inherit; |
||||||
|
} |
||||||
|
main .upload-container .success-info ul { |
||||||
|
list-style: none; |
||||||
|
} |
||||||
|
main .upload-container .success-info ul li { |
||||||
|
position: relative; |
||||||
|
margin-top: 0.5rem; |
||||||
|
padding: 1rem; |
||||||
|
border: 1px solid #dadada; |
||||||
|
background-color: #f7f7f7; |
||||||
|
font-size: 14px; |
||||||
|
color: #555; |
||||||
|
white-space: pre-wrap; |
||||||
|
word-break: break-all; |
||||||
|
word-wrap: break-word; |
||||||
|
border-radius: 0; |
||||||
|
font-family: Menlo, Monaco, Consolas, "Courier New", monospace; |
||||||
|
} |
||||||
|
main .upload-container .success-info ul li i.icon-copy { |
||||||
|
display: none; |
||||||
|
} |
||||||
|
main .upload-container .success-info ul li:hover i.icon-copy { |
||||||
|
display: block; |
||||||
|
position: absolute; |
||||||
|
top: 4px; |
||||||
|
font-size: 25px; |
||||||
|
right: 10px; |
||||||
|
color: #00b0ff; |
||||||
|
cursor: pointer; |
||||||
|
} |
||||||
|
main .system-container .mdui-textfield-label { |
||||||
|
pointer-events: inherit; |
||||||
|
} |
||||||
|
main .images-container #info .mdui-dialog-content { |
||||||
|
word-break: break-all; |
||||||
|
word-wrap: break-word; |
||||||
|
} |
||||||
|
main .images-container #info .mdui-btn-group .mdui-btn { |
||||||
|
margin-left: 0; |
||||||
|
min-width: inherit; |
||||||
|
} |
||||||
|
main .images-container #info img.qrcode { |
||||||
|
text-align: center; |
||||||
|
} |
||||||
|
main .images-container #info .mdui-dialog-content { |
||||||
|
padding-bottom: 0; |
||||||
|
} |
||||||
|
main .images-container #info table { |
||||||
|
width: 100%; |
||||||
|
} |
||||||
|
main .images-container #info table tbody tr td[align="right"] { |
||||||
|
width: 50px; |
||||||
|
color: #998; |
||||||
|
} |
||||||
|
main .images-container .images-box .item { |
||||||
|
position: relative; |
||||||
|
padding: 2rem 0.4rem 0.4rem; |
||||||
|
text-align: center; |
||||||
|
width: 100%; |
||||||
|
height: auto; |
||||||
|
transition: all 0.1s; |
||||||
|
border: 1px solid transparent; |
||||||
|
margin-top: 1rem; |
||||||
|
} |
||||||
|
main .images-container .images-box .item i.iconfont { |
||||||
|
display: none; |
||||||
|
position: absolute; |
||||||
|
cursor: pointer; |
||||||
|
font-size: 19px; |
||||||
|
} |
||||||
|
main .images-container .images-box .item i.icon-choice { |
||||||
|
top: 5px; |
||||||
|
left: 5px; |
||||||
|
color: #cecece; |
||||||
|
} |
||||||
|
main .images-container .images-box .item i.icon-choice:hover { |
||||||
|
color: #999; |
||||||
|
} |
||||||
|
main .images-container .images-box .item i.icon-info { |
||||||
|
top: 5px; |
||||||
|
right: 5px; |
||||||
|
color: #129cff; |
||||||
|
} |
||||||
|
main .images-container .images-box .item:hover { |
||||||
|
background-color: #ebebeb; |
||||||
|
} |
||||||
|
main .images-container .images-box .item.choice { |
||||||
|
background: rgba(204, 232, 255, 0.5); |
||||||
|
border: 1px solid rgba(153, 209, 255, 0.57); |
||||||
|
} |
||||||
|
main .images-container .images-box .item.choice i.icon-choice { |
||||||
|
display: block; |
||||||
|
color: #3b8cff; |
||||||
|
} |
||||||
|
main .images-container .images-box .item:hover i.icon-choice, |
||||||
|
main .images-container .images-box .item.choice i.icon-choice, |
||||||
|
main .images-container .images-box .item:hover i.icon-info, |
||||||
|
main .images-container .images-box .item.choice i.icon-info { |
||||||
|
display: block; |
||||||
|
} |
||||||
|
main .images-container .images-box .item .info { |
||||||
|
cursor: pointer; |
||||||
|
height: 90px; |
||||||
|
overflow: hidden; |
||||||
|
display: block; |
||||||
|
text-align: center; |
||||||
|
vertical-align: middle; |
||||||
|
} |
||||||
|
main .images-container .images-box .item .info img { |
||||||
|
max-height: 100%; |
||||||
|
max-width: 100%; |
||||||
|
border-radius: 0; |
||||||
|
position: relative; |
||||||
|
top: 50%; |
||||||
|
transform: translateY(-50%); |
||||||
|
} |
||||||
|
main .images-container .images-box .item .info.image img { |
||||||
|
-webkit-box-shadow: 1px 1px 5px rgba(0, 0, 0, 0.2); |
||||||
|
-moz-box-shadow: 1px 1px 5px rgba(0, 0, 0, 0.2); |
||||||
|
box-shadow: 1px 1px 5px rgba(0, 0, 0, 0.2); |
||||||
|
} |
||||||
|
main .images-container .images-box .item p.name { |
||||||
|
color: #555; |
||||||
|
cursor: default; |
||||||
|
text-align: center; |
||||||
|
word-break: break-all; |
||||||
|
font-size: 12px; |
||||||
|
margin: 0.3rem auto; |
||||||
|
line-height: 1.5em; |
||||||
|
padding-bottom: 5px; |
||||||
|
overflow: hidden; |
||||||
|
display: -webkit-box; |
||||||
|
-webkit-box-orient: vertical; |
||||||
|
-webkit-line-clamp: 3; |
||||||
|
} |
||||||
|
main .update-container .item { |
||||||
|
margin-top: 1rem; |
||||||
|
} |
||||||
|
main .update-container .item h4 { |
||||||
|
font-size: 1.1rem; |
||||||
|
margin-bottom: 0.5rem; |
||||||
|
color: #555; |
||||||
|
} |
||||||
|
main .update-container .item h4 small { |
||||||
|
color: #777777; |
||||||
|
} |
||||||
|
main .update-container .item .info { |
||||||
|
margin-left: 0.8rem; |
||||||
|
} |
||||||
|
main .update-container .item .info p { |
||||||
|
color: #777; |
||||||
|
margin-bottom: 0.3em; |
||||||
|
} |
||||||
|
main .update-container p { |
||||||
|
color: #444; |
||||||
|
} |
||||||
|
main .mdui-textfield .captcha { |
||||||
|
position: absolute; |
||||||
|
top: 34px; |
||||||
|
right: 0; |
||||||
|
bottom: 0; |
||||||
|
width: 140px; |
||||||
|
cursor: pointer; |
||||||
|
} |
||||||
|
.file-input .file-preview { |
||||||
|
border-radius: 0; |
||||||
|
border: none; |
||||||
|
box-shadow: 0 0 15px 0 rgba(0, 0, 0, 0.13); |
||||||
|
} |
||||||
|
.file-input .file-preview .fileinput-remove { |
||||||
|
top: 6px; |
||||||
|
right: 6px; |
||||||
|
} |
||||||
|
.file-input .file-preview .file-preview-thumbnails .krajee-default.file-preview-frame { |
||||||
|
border: 0; |
||||||
|
box-shadow: 0 0 15px 0 rgba(0, 0, 0, 0.13); |
||||||
|
} |
||||||
|
.file-input .file-preview .kv-fileinput-error ul { |
||||||
|
list-style: none; |
||||||
|
} |
||||||
|
.file-input .file-caption-main .form-control { |
||||||
|
box-shadow: 0 2px 15px 0 rgba(0, 0, 0, 0.13); |
||||||
|
border: none; |
||||||
|
border-radius: 0; |
||||||
|
height: 40px; |
||||||
|
padding: 10px 18px; |
||||||
|
} |
||||||
|
.file-input .file-caption-main .form-control:focus { |
||||||
|
z-index: 0; |
||||||
|
} |
||||||
|
.file-input .file-caption-main .btn { |
||||||
|
padding: 10px 18px; |
||||||
|
border: 0; |
||||||
|
} |
||||||
|
.file-input .file-caption-main .btn:first-child { |
||||||
|
border-left: 1px solid #e2e2e2; |
||||||
|
} |
||||||
|
.file-input .file-caption-main .btn:last-child { |
||||||
|
margin-right: -1px; |
||||||
|
} |
||||||
|
.file-input .file-caption-main .btn-file { |
||||||
|
border-color: #2383eb; |
||||||
|
background-color: #2383eb; |
||||||
|
border-radius: 0; |
||||||
|
} |
||||||
|
.file-input .file-caption-main .input-group-append { |
||||||
|
box-shadow: 0 0 15px 0 rgba(0, 0, 0, 0.13); |
||||||
|
} |
||||||
|
.file-zoom-fullscreen.modal { |
||||||
|
z-index: 999999; |
||||||
|
} |
||||||
|
.mdui-tab-scrollable { |
||||||
|
padding-left: 0; |
||||||
|
} |
||||||
|
.panel { |
||||||
|
padding: 0; |
||||||
|
overflow: hidden; |
||||||
|
white-space: normal; |
||||||
|
word-break: break-all; |
||||||
|
box-shadow: 0 0 20px 0 rgba(0, 0, 0, 0.13); |
||||||
|
border-radius: 0.5rem; |
||||||
|
} |
||||||
|
.panel .panel-header { |
||||||
|
padding: 1rem; |
||||||
|
} |
||||||
|
.panel .panel-body { |
||||||
|
border-top: 1px solid #f1f1f1; |
||||||
|
border-bottom: 1px solid #f1f1f1; |
||||||
|
padding: 1rem; |
||||||
|
} |
||||||
|
.panel .panel-body-box { |
||||||
|
border-top: 1px solid #f1f1f1; |
||||||
|
padding: 1rem; |
||||||
|
border-bottom-left-radius: 0.5rem; |
||||||
|
border-bottom-right-radius: 0.5rem; |
||||||
|
} |
||||||
|
.panel .panel-footer { |
||||||
|
padding: 1rem; |
||||||
|
} |
||||||
|
.error-box { |
||||||
|
border: none; |
||||||
|
margin: 0; |
||||||
|
} |
||||||
|
.none { |
||||||
|
display: none; |
||||||
|
} |
||||||
|
#loading-container { |
||||||
|
position: fixed; |
||||||
|
top: 0; |
||||||
|
left: 0; |
||||||
|
right: 0; |
||||||
|
bottom: 0; |
||||||
|
display: none; |
||||||
|
} |
||||||
|
#loading-container .mask { |
||||||
|
position: absolute; |
||||||
|
width: 100%; |
||||||
|
z-index: 9999; |
||||||
|
} |
||||||
|
#loading-container .loading { |
||||||
|
position: absolute; |
||||||
|
top: 5rem; |
||||||
|
right: 1rem; |
||||||
|
z-index: 10000; |
||||||
|
} |
||||||
|
.panel-box { |
||||||
|
overflow: hidden; |
||||||
|
white-space: normal; |
||||||
|
word-break: break-all; |
||||||
|
box-shadow: 0 0 20px 0 rgba(0, 0, 0, 0.13); |
||||||
|
border-radius: 0.5rem; |
||||||
|
padding: 1rem; |
||||||
|
} |
||||||
|
#menu .quota-container { |
||||||
|
position: absolute; |
||||||
|
left: 50%; |
||||||
|
bottom: 2rem; |
||||||
|
text-align: left; |
||||||
|
transform: translateX(-50%); |
||||||
|
} |
||||||
|
#menu .quota-container progress { |
||||||
|
background-color: #f6f6f6; |
||||||
|
display: inline; |
||||||
|
height: 0.5rem; |
||||||
|
} |
||||||
|
#menu .quota-container progress::-webkit-progress-bar { |
||||||
|
background-color: #e0eaf0; |
||||||
|
} |
||||||
|
#menu .quota-container progress::-webkit-progress-value { |
||||||
|
background-color: #1abc9c; |
||||||
|
} |
||||||
|
#menu .quota-container progress::-moz-progress-bar { |
||||||
|
background-color: #e0eaf0; |
||||||
|
} |
||||||
|
#menu .quota-container progress::-moz-progress-value { |
||||||
|
background-color: #708d9b; |
||||||
|
} |
||||||
|
#search-form .search-input { |
||||||
|
display: inline-block; |
||||||
|
padding-bottom: 0.6rem; |
||||||
|
width: 140px; |
||||||
|
} |
||||||
|
footer { |
||||||
|
position: absolute; |
||||||
|
bottom: 0; |
||||||
|
width: 100%; |
||||||
|
height: 60px; |
||||||
|
line-height: 60px; |
||||||
|
color: #999; |
||||||
|
text-align: left; |
||||||
|
background-color: #f5f5f5; |
||||||
|
} |
||||||
|
.pagination { |
||||||
|
display: inline-block; |
||||||
|
padding-left: 0; |
||||||
|
margin: 20px 0; |
||||||
|
border-radius: 4px; |
||||||
|
} |
||||||
|
.pagination > li { |
||||||
|
display: inline; |
||||||
|
} |
||||||
|
.pagination > li > a, |
||||||
|
.pagination > li > span { |
||||||
|
position: relative; |
||||||
|
float: left; |
||||||
|
text-decoration: none; |
||||||
|
color: #00b5ad; |
||||||
|
background-color: #fff; |
||||||
|
border: 1px solid #ddd; |
||||||
|
margin-left: -1px; |
||||||
|
padding: 5px 10px; |
||||||
|
font-size: 12px; |
||||||
|
line-height: 1.5; |
||||||
|
} |
||||||
|
.pagination > li:first-child > a, |
||||||
|
.pagination > li:first-child > span { |
||||||
|
margin-left: 0; |
||||||
|
border-bottom-left-radius: 3px; |
||||||
|
border-top-left-radius: 3px; |
||||||
|
} |
||||||
|
.pagination > li:last-child > a, |
||||||
|
.pagination > li:last-child > span { |
||||||
|
border-bottom-right-radius: 3px; |
||||||
|
border-top-right-radius: 3px; |
||||||
|
} |
||||||
|
.pagination > li > a:hover, |
||||||
|
.pagination > li > a:focus, |
||||||
|
.pagination > li > span:hover, |
||||||
|
.pagination > li > span:focus { |
||||||
|
z-index: 2; |
||||||
|
color: #22ddde; |
||||||
|
background-color: #eeeeee; |
||||||
|
border-color: #ddd; |
||||||
|
} |
||||||
|
.pagination > .active > a, |
||||||
|
.pagination > .active > a:hover, |
||||||
|
.pagination > .active > a:focus, |
||||||
|
.pagination > .active > span, |
||||||
|
.pagination > .active > span:hover, |
||||||
|
.pagination > .active > span:focus { |
||||||
|
z-index: 3; |
||||||
|
color: #e4e4e4; |
||||||
|
background-color: transparent; |
||||||
|
border-color: #e4e4e4; |
||||||
|
cursor: default; |
||||||
|
} |
||||||
|
.pagination > .disabled > span, |
||||||
|
.pagination > .disabled > span:hover, |
||||||
|
.pagination > .disabled > span:focus, |
||||||
|
.pagination > .disabled > a, |
||||||
|
.pagination > .disabled > a:hover, |
||||||
|
.pagination > .disabled > a:focus { |
||||||
|
color: #777777; |
||||||
|
background-color: #fff; |
||||||
|
border-color: #ddd; |
||||||
|
cursor: not-allowed; |
||||||
|
} |
||||||
|
@media (max-width: 768px) { |
||||||
|
body { |
||||||
|
margin-bottom: 120px; |
||||||
|
} |
||||||
|
.krajee-default.file-preview-frame { |
||||||
|
width: 95%; |
||||||
|
} |
||||||
|
.krajee-default.file-preview-frame .kv-file-content { |
||||||
|
width: 100%; |
||||||
|
height: 100%; |
||||||
|
} |
||||||
|
#loading-container .loading { |
||||||
|
top: 4.5rem; |
||||||
|
} |
||||||
|
main .images-container #info img.qrcode { |
||||||
|
width: 150px; |
||||||
|
} |
||||||
|
footer { |
||||||
|
height: auto; |
||||||
|
width: 100% !important; |
||||||
|
line-height: 1.666; |
||||||
|
padding: 1rem 0; |
||||||
|
} |
||||||
|
} |
||||||
|
/*# sourceMappingURL=app.css.map */ |
@ -0,0 +1,578 @@ |
|||||||
|
*, *:before, *:after { |
||||||
|
box-sizing: border-box; |
||||||
|
} |
||||||
|
|
||||||
|
a { |
||||||
|
color: #03A9F4; |
||||||
|
} |
||||||
|
|
||||||
|
a, a:hover, a:active, a:focus { |
||||||
|
text-decoration: none; |
||||||
|
} |
||||||
|
|
||||||
|
a:focus { |
||||||
|
outline-style: none; |
||||||
|
} |
||||||
|
|
||||||
|
audio, body, caption, div, footer, form, h1, h2, h3, h4, h5, h6, header, html, iframe, label, legend, li, main, mark, menu, nav, ol, p, section, span, summary, table, textarea, time, ul, video { |
||||||
|
padding: 0; |
||||||
|
margin: 0; |
||||||
|
border: 0; |
||||||
|
outline: 0 none; |
||||||
|
} |
||||||
|
|
||||||
|
html { |
||||||
|
position: relative; |
||||||
|
min-height: 100%; |
||||||
|
} |
||||||
|
|
||||||
|
html, body { |
||||||
|
width: 100%; |
||||||
|
margin: 0; |
||||||
|
padding: 0; |
||||||
|
} |
||||||
|
|
||||||
|
body { |
||||||
|
margin-bottom: 60px; |
||||||
|
overflow-x: hidden; |
||||||
|
} |
||||||
|
|
||||||
|
.mdui-drawer-body-left { |
||||||
|
footer { |
||||||
|
width: calc(100% - 240px); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
main { |
||||||
|
position: relative; |
||||||
|
top: 0; |
||||||
|
left: 0; |
||||||
|
right: 0; |
||||||
|
margin: 1.7rem 0; |
||||||
|
.login-container, .register-container { |
||||||
|
margin-top: 4rem; |
||||||
|
margin-bottom: 4rem; |
||||||
|
} |
||||||
|
.not-logged-in { |
||||||
|
margin: 10rem 0; |
||||||
|
text-align: center; |
||||||
|
h2 { |
||||||
|
margin-bottom: 2rem; |
||||||
|
} |
||||||
|
} |
||||||
|
.upload-container { |
||||||
|
.title { |
||||||
|
margin: 1rem 0; |
||||||
|
h1 { |
||||||
|
font-weight: 300; |
||||||
|
font-size: 3rem; |
||||||
|
text-shadow: -5px 5px 0 rgba(0, 0, 0, .1); |
||||||
|
} |
||||||
|
p { |
||||||
|
margin-top: 1rem; |
||||||
|
font-size: 1.3rem; |
||||||
|
color: #999; |
||||||
|
} |
||||||
|
} |
||||||
|
.success-info { |
||||||
|
margin-top: 1rem; |
||||||
|
width: 0; |
||||||
|
.mdui-tab a { |
||||||
|
text-transform: inherit; |
||||||
|
} |
||||||
|
ul { |
||||||
|
list-style: none; |
||||||
|
li { |
||||||
|
position: relative; |
||||||
|
margin-top: 0.5rem; |
||||||
|
padding: 1rem; |
||||||
|
border: 1px solid #dadada; |
||||||
|
background-color: #f7f7f7; |
||||||
|
font-size: 14px; |
||||||
|
color: #555; |
||||||
|
white-space: pre-wrap; |
||||||
|
word-break: break-all; |
||||||
|
word-wrap: break-word; |
||||||
|
border-radius: 0; |
||||||
|
font-family: Menlo, Monaco, Consolas, "Courier New", monospace; |
||||||
|
i.icon-copy { |
||||||
|
display: none; |
||||||
|
} |
||||||
|
&:hover { |
||||||
|
i.icon-copy { |
||||||
|
display: block; |
||||||
|
position: absolute; |
||||||
|
top: 4px; |
||||||
|
font-size: 25px; |
||||||
|
right: 10px; |
||||||
|
color: #00b0ff; |
||||||
|
cursor: pointer; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
// 系统设置 |
||||||
|
.system-container { |
||||||
|
.mdui-textfield-label { |
||||||
|
pointer-events: inherit; |
||||||
|
} |
||||||
|
} |
||||||
|
// 我的图片 |
||||||
|
.images-container { |
||||||
|
#info { |
||||||
|
.mdui-dialog-content { |
||||||
|
word-break: break-all; |
||||||
|
word-wrap: break-word; |
||||||
|
} |
||||||
|
.mdui-btn-group { |
||||||
|
.mdui-btn { |
||||||
|
margin-left: 0; |
||||||
|
min-width: inherit; |
||||||
|
} |
||||||
|
} |
||||||
|
img.qrcode { |
||||||
|
text-align: center; |
||||||
|
} |
||||||
|
.mdui-dialog-content { |
||||||
|
padding-bottom: 0; |
||||||
|
} |
||||||
|
table { |
||||||
|
width: 100%; |
||||||
|
tbody { |
||||||
|
tr { |
||||||
|
td { |
||||||
|
&[align="right"] { |
||||||
|
width: 50px; |
||||||
|
color: #998; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
.screen-box { |
||||||
|
} |
||||||
|
.images-box { |
||||||
|
.item { |
||||||
|
position: relative; |
||||||
|
padding: 2rem .4rem .4rem; |
||||||
|
text-align: center; |
||||||
|
width: 100%; |
||||||
|
height: auto; |
||||||
|
transition: all .1s; |
||||||
|
border: 1px solid transparent; |
||||||
|
margin-top: 1rem; |
||||||
|
i.iconfont { |
||||||
|
display: none; |
||||||
|
position: absolute; |
||||||
|
cursor: pointer; |
||||||
|
font-size: 19px; |
||||||
|
} |
||||||
|
// 选择 |
||||||
|
i.icon-choice { |
||||||
|
top: 5px; |
||||||
|
left: 5px; |
||||||
|
color: #cecece; |
||||||
|
&:hover { |
||||||
|
color: #999; |
||||||
|
} |
||||||
|
} |
||||||
|
// 信息 |
||||||
|
i.icon-info { |
||||||
|
top: 5px; |
||||||
|
right: 5px; |
||||||
|
color: #129cff; |
||||||
|
} |
||||||
|
&:hover { |
||||||
|
background-color: #ebebeb; |
||||||
|
} |
||||||
|
&.choice { |
||||||
|
background: rgba(204, 232, 255, 0.5); |
||||||
|
border: 1px solid rgba(153, 209, 255, 0.57); |
||||||
|
i.icon-choice { |
||||||
|
display: block; |
||||||
|
color: #3b8cff; |
||||||
|
} |
||||||
|
} |
||||||
|
&:hover, &.choice { |
||||||
|
i.icon-choice, i.icon-info { |
||||||
|
display: block; |
||||||
|
} |
||||||
|
} |
||||||
|
.info { |
||||||
|
cursor: pointer; |
||||||
|
height: 90px; |
||||||
|
overflow: hidden; |
||||||
|
display: block; |
||||||
|
text-align: center; |
||||||
|
vertical-align: middle; |
||||||
|
img { |
||||||
|
max-height: 100%; |
||||||
|
max-width: 100%; |
||||||
|
border-radius: 0; |
||||||
|
position: relative; |
||||||
|
top: 50%; |
||||||
|
transform: translateY(-50%); |
||||||
|
} |
||||||
|
&.image { |
||||||
|
img { |
||||||
|
-webkit-box-shadow: 1px 1px 5px rgba(0, 0, 0, 0.2); |
||||||
|
-moz-box-shadow: 1px 1px 5px rgba(0, 0, 0, 0.2); |
||||||
|
box-shadow: 1px 1px 5px rgba(0, 0, 0, 0.2); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
p.name { |
||||||
|
color: #555; |
||||||
|
cursor: default; |
||||||
|
text-align: center; |
||||||
|
word-break: break-all; |
||||||
|
font-size: 12px; |
||||||
|
margin: .3rem auto; |
||||||
|
line-height: 1.5em; |
||||||
|
padding-bottom: 5px; |
||||||
|
overflow: hidden; |
||||||
|
display: -webkit-box; |
||||||
|
-webkit-box-orient: vertical; |
||||||
|
-webkit-line-clamp: 3; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
// 系统更新 |
||||||
|
.update-container { |
||||||
|
.item { |
||||||
|
margin-top: 1rem; |
||||||
|
h4 { |
||||||
|
font-size: 1.1rem; |
||||||
|
margin-bottom: .5rem; |
||||||
|
color: #555; |
||||||
|
small { |
||||||
|
color: #777777; |
||||||
|
} |
||||||
|
} |
||||||
|
.info { |
||||||
|
margin-left: .8rem; |
||||||
|
p { |
||||||
|
color: #777; |
||||||
|
margin-bottom: .3em; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
p { |
||||||
|
color: #444; |
||||||
|
} |
||||||
|
} |
||||||
|
.mdui-textfield { |
||||||
|
.captcha { |
||||||
|
position: absolute; |
||||||
|
top: 34px; |
||||||
|
right: 0; |
||||||
|
bottom: 0; |
||||||
|
width: 140px; |
||||||
|
cursor: pointer; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
// 重写fileinput插件样式 |
||||||
|
.file-input { |
||||||
|
@box-shadow: 0 0 15px 0 rgba(0, 0, 0, 0.13); |
||||||
|
@form-control-padding: 10px 18px; |
||||||
|
.file-preview { |
||||||
|
border-radius: 0; |
||||||
|
border: none; |
||||||
|
box-shadow: @box-shadow; |
||||||
|
.fileinput-remove { |
||||||
|
top: 6px; |
||||||
|
right: 6px; |
||||||
|
} |
||||||
|
.file-preview-thumbnails { |
||||||
|
.krajee-default.file-preview-frame { |
||||||
|
border: 0; |
||||||
|
box-shadow: @box-shadow; |
||||||
|
} |
||||||
|
} |
||||||
|
.kv-fileinput-error { |
||||||
|
ul { |
||||||
|
list-style: none; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
.file-caption-main { |
||||||
|
.form-control { |
||||||
|
box-shadow: 0 2px 15px 0 rgba(0, 0, 0, 0.13); |
||||||
|
border: none; |
||||||
|
border-radius: 0; |
||||||
|
height: 40px; |
||||||
|
padding: @form-control-padding; |
||||||
|
&:focus { |
||||||
|
z-index: 0; |
||||||
|
} |
||||||
|
} |
||||||
|
.btn { |
||||||
|
padding: @form-control-padding; |
||||||
|
border: 0; |
||||||
|
&:first-child { |
||||||
|
border-left: 1px solid #e2e2e2; |
||||||
|
} |
||||||
|
&:last-child { |
||||||
|
margin-right: -1px; |
||||||
|
} |
||||||
|
} |
||||||
|
.btn-file { |
||||||
|
border-color: #2383eb; |
||||||
|
background-color: #2383eb; |
||||||
|
border-radius: 0; |
||||||
|
} |
||||||
|
.input-group-append { |
||||||
|
box-shadow: @box-shadow; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
// 摸态框全屏 |
||||||
|
.file-zoom-fullscreen.modal { |
||||||
|
z-index: 999999; |
||||||
|
} |
||||||
|
|
||||||
|
// mdui |
||||||
|
.mdui-tab-scrollable { |
||||||
|
padding-left: 0; |
||||||
|
} |
||||||
|
|
||||||
|
.panel { |
||||||
|
@border-radius: .5rem; |
||||||
|
@padding: 1rem; |
||||||
|
@border-color: #f1f1f1; |
||||||
|
padding: 0; |
||||||
|
overflow: hidden; |
||||||
|
white-space: normal; |
||||||
|
word-break: break-all; |
||||||
|
box-shadow: 0 0 20px 0 rgba(0, 0, 0, 0.13); |
||||||
|
border-radius: @border-radius; |
||||||
|
.panel-header { |
||||||
|
padding: @padding; |
||||||
|
} |
||||||
|
.panel-body { |
||||||
|
border-top: 1px solid @border-color; |
||||||
|
border-bottom: 1px solid @border-color; |
||||||
|
padding: @padding; |
||||||
|
} |
||||||
|
.panel-body-box { |
||||||
|
border-top: 1px solid @border-color; |
||||||
|
padding: @padding; |
||||||
|
border-bottom-left-radius: @border-radius; |
||||||
|
border-bottom-right-radius: @border-radius; |
||||||
|
} |
||||||
|
.panel-footer { |
||||||
|
padding: @padding; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
.error-box { |
||||||
|
border: none; |
||||||
|
margin: 0; |
||||||
|
} |
||||||
|
|
||||||
|
.none { |
||||||
|
display: none; |
||||||
|
} |
||||||
|
|
||||||
|
#loading-container { |
||||||
|
position: fixed; |
||||||
|
top: 0; |
||||||
|
left: 0; |
||||||
|
right: 0; |
||||||
|
bottom: 0; |
||||||
|
display: none; |
||||||
|
.mask { |
||||||
|
position: absolute; |
||||||
|
width: 100%; |
||||||
|
z-index: 9999; |
||||||
|
} |
||||||
|
.loading { |
||||||
|
position: absolute; |
||||||
|
top: 5rem; |
||||||
|
right: 1rem; |
||||||
|
z-index: 10000; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
.panel-box { |
||||||
|
overflow: hidden; |
||||||
|
white-space: normal; |
||||||
|
word-break: break-all; |
||||||
|
box-shadow: 0 0 20px 0 rgba(0, 0, 0, 0.13); |
||||||
|
border-radius: .5rem; |
||||||
|
padding: 1rem; |
||||||
|
} |
||||||
|
|
||||||
|
#menu { |
||||||
|
.quota-container { |
||||||
|
position: absolute; |
||||||
|
left: 50%; |
||||||
|
bottom: 2rem; |
||||||
|
text-align: left; |
||||||
|
transform: translateX(-50%); |
||||||
|
progress { |
||||||
|
background-color: #f6f6f6; |
||||||
|
display: inline; |
||||||
|
height: .5rem; |
||||||
|
} |
||||||
|
progress::-webkit-progress-bar { |
||||||
|
background-color: #e0eaf0; |
||||||
|
} |
||||||
|
progress::-webkit-progress-value { |
||||||
|
background-color: #1abc9c; |
||||||
|
} |
||||||
|
progress::-moz-progress-bar { |
||||||
|
background-color: #e0eaf0; |
||||||
|
} |
||||||
|
progress::-moz-progress-value { |
||||||
|
background-color: #708d9b; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
#search-form { |
||||||
|
.search-input { |
||||||
|
display: inline-block; |
||||||
|
padding-bottom: .6rem; |
||||||
|
width: 140px; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
footer { |
||||||
|
position: absolute; |
||||||
|
bottom: 0; |
||||||
|
width: 100%; |
||||||
|
height: 60px; |
||||||
|
line-height: 60px; |
||||||
|
color: #999; |
||||||
|
text-align: left; |
||||||
|
background-color: #f5f5f5; |
||||||
|
} |
||||||
|
|
||||||
|
.pagination { |
||||||
|
display: inline-block; |
||||||
|
padding-left: 0; |
||||||
|
margin: 20px 0; |
||||||
|
border-radius: 4px; |
||||||
|
} |
||||||
|
|
||||||
|
.pagination > li { |
||||||
|
display: inline; |
||||||
|
} |
||||||
|
|
||||||
|
.pagination > li > a, |
||||||
|
.pagination > li > span { |
||||||
|
position: relative; |
||||||
|
float: left; |
||||||
|
text-decoration: none; |
||||||
|
color: #00b5ad; |
||||||
|
background-color: #fff; |
||||||
|
border: 1px solid #ddd; |
||||||
|
margin-left: -1px; |
||||||
|
padding: 5px 10px; |
||||||
|
font-size: 12px; |
||||||
|
line-height: 1.5; |
||||||
|
} |
||||||
|
|
||||||
|
.pagination > li:first-child > a, |
||||||
|
.pagination > li:first-child > span { |
||||||
|
margin-left: 0; |
||||||
|
border-bottom-left-radius: 3px; |
||||||
|
border-top-left-radius: 3px; |
||||||
|
} |
||||||
|
|
||||||
|
.pagination > li:last-child > a, |
||||||
|
.pagination > li:last-child > span { |
||||||
|
border-bottom-right-radius: 3px; |
||||||
|
border-top-right-radius: 3px; |
||||||
|
} |
||||||
|
|
||||||
|
.pagination > li > a:hover, |
||||||
|
.pagination > li > a:focus, |
||||||
|
.pagination > li > span:hover, |
||||||
|
.pagination > li > span:focus { |
||||||
|
z-index: 2; |
||||||
|
color: #22ddde; |
||||||
|
background-color: #eeeeee; |
||||||
|
border-color: #ddd; |
||||||
|
} |
||||||
|
|
||||||
|
.pagination > .active > a, |
||||||
|
.pagination > .active > a:hover, |
||||||
|
.pagination > .active > a:focus, |
||||||
|
.pagination > .active > span, |
||||||
|
.pagination > .active > span:hover, |
||||||
|
.pagination > .active > span:focus { |
||||||
|
z-index: 3; |
||||||
|
color: #e4e4e4; |
||||||
|
background-color: transparent; |
||||||
|
border-color: #e4e4e4; |
||||||
|
cursor: default; |
||||||
|
} |
||||||
|
|
||||||
|
.pagination > .disabled > span, |
||||||
|
.pagination > .disabled > span:hover, |
||||||
|
.pagination > .disabled > span:focus, |
||||||
|
.pagination > .disabled > a, |
||||||
|
.pagination > .disabled > a:hover, |
||||||
|
.pagination > .disabled > a:focus { |
||||||
|
color: #777777; |
||||||
|
background-color: #fff; |
||||||
|
border-color: #ddd; |
||||||
|
cursor: not-allowed; |
||||||
|
} |
||||||
|
|
||||||
|
@media (max-width: 1200px) { |
||||||
|
} |
||||||
|
|
||||||
|
@media (max-width: 992px) { |
||||||
|
} |
||||||
|
|
||||||
|
@media (max-width: 768px) { |
||||||
|
body { |
||||||
|
margin-bottom: 120px; |
||||||
|
} |
||||||
|
|
||||||
|
.krajee-default.file-preview-frame { |
||||||
|
width: 95%; |
||||||
|
.kv-file-content { |
||||||
|
width: 100%; |
||||||
|
height: 100%; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
#loading-container { |
||||||
|
.loading { |
||||||
|
top: 4.5rem; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
main { |
||||||
|
// 我的图片 |
||||||
|
.images-container { |
||||||
|
#info { |
||||||
|
img.qrcode { |
||||||
|
width: 150px; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
footer { |
||||||
|
height: auto; |
||||||
|
width: 100% !important; |
||||||
|
line-height: 1.666; |
||||||
|
padding: 1rem 0; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
@media (max-width: 576px) { |
||||||
|
|
||||||
|
} |
@ -0,0 +1,27 @@ |
|||||||
|
|
||||||
|
@font-face {font-family: "iconfont"; |
||||||
|
src: url('iconfont.eot?t=1540125096323'); /* IE9*/ |
||||||
|
src: url('iconfont.eot?t=1540125096323#iefix') format('embedded-opentype'), /* IE6-IE8 */ |
||||||
|
url('data:application/x-font-woff;charset=utf-8;base64,d09GRgABAAAAAAdMAAsAAAAACqgAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAABHU1VCAAABCAAAADMAAABCsP6z7U9TLzIAAAE8AAAARAAAAFY8dk3CY21hcAAAAYAAAABzAAAByIaQlDZnbHlmAAAB9AAAAzwAAAQggHL+42hlYWQAAAUwAAAALwAAADYTBGlNaGhlYQAABWAAAAAeAAAAJAfeA4pobXR4AAAFgAAAABEAAAAYGAMAAGxvY2EAAAWUAAAADgAAAA4D4gJKbWF4cAAABaQAAAAeAAAAIAEWAJJuYW1lAAAFxAAAAUUAAAJtPlT+fXBvc3QAAAcMAAAAQAAAAFGqHvHseJxjYGRgYOBikGPQYWB0cfMJYeBgYGGAAJAMY05meiJQDMoDyrGAaQ4gZoOIAgCKIwNPAHicY2BkYWScwMDKwMHUyXSGgYGhH0IzvmYwYuRgYGBiYGVmwAoC0lxTGByeMbw+z9zwv4EhhrmBoQEozAiSAwDtOQy4eJztkcsJgDAQRN+aKCJiG3qwErEeT/ZoF/FgEbqbVcEenPBCZsgHMkAJBGVUIsiKYFo0lZwHmpxHJvUtNQUxkbrU78OxnSd83SvR3c+wl0TvinoaqfjV5nm+XWm/6OR151gHqXesp31wrKtjcyguthIdygB4nE1SPYwbRRSeN7Mzs+v9sWe9a+Psnu/s9dpShJ3Ya+8qIBv7pBO5REJINHBpUNpLFAkaGpQzEpCCjpJISJTQ0SGh3KWCEiQKoKGAEgkhUKrzmLcHAaR5o++9+d58M58eYYRs/2QfMIcocoW8S0jaHdHpgk7aNPBoUiSzab8rdiDpiqDxPIRBY5LPIQsn+bSfDDyjCkJ6tNFssyYCpI2MwQiKBSsWdIpoMKKDEVtAMS0WPMNbm21oNmSbYpekP6T74zge799YXY3jq6v01WWt5V1zlHKuea3a0lXK/Z5J2xOUMxEEpsGZF13eC+NnDoaN+XKR9bhpSqOfFWHNl0AbjqyYTFQqFpOCGdW9Xn+gmpd7sRX43MCnMgq2a9bj8erGfimJyuP4m3mpOFctZ1EqLqjXUj96YWB7ZtU0L41Hz4a1bq9b44wZTEjTNOQy29lVVdf2g9DxQ5uHIX7Hi5pKttut54ZxVdp+6LTm8e6eYfuuqttodOn1F+wr9iIiSWqEwCwJ6ypR9Qlmexh0eHR0NPwSKvqJfqCfQIVat27pD0Hp3+inT2vwFlQu7jpjp2xFHNIlCd7lgURr0Wk0vQ6ifwX60xcgn+xCkTd2oQ1yDNvTjWFsTh9tON88+l1/a7jiIecp98TxueEhAM5WePQvTX+OJOAPkZFyfnyOhD53OSEU9c/ZO3RLdsgM1TvlkGSzjlQd/FSj2cFJySaoX6hpH7BQ4im+KREyvCAjh72x+VpaB/DR+/rXA2bDTUsw+rMAS4+oa7AHuBh3qf5JmuBAQreW/O7jl/TBZ79U6G1hwh0m6NvS0jcNF+hdwzHeZOC+bIm+i/YQIi48+gQ9MkmA/r5CXiPHhNTLGS6negjlUGe8zGT6H2Yd9DLBuJj2YjbNi0yhtxmWOiOYwwjKD2Clg3ZnGGrQTErbO12ct7IWlnQViNfrke9Hdfqe/sOuVm1wy/1/WOnH+SGsMJAIvXgJh/kWepFexz3ARkzh5B/G45Nl1IOlPsEdKVs8W6WwdFHA9+9RFfnUv+TffwooLZsP8xPPr7tlj17m1+nfvWtscteY0us5Ljhbr7G6OUsjCqUGqun7UUrIXwC3t0x4nGNgZGBgAGKTDaq/4/ltvjJwszCAwPVPk1Yg6P87WRiY3YFcDgYmkCgAT0ELywB4nGNgZGBgbvjfwBDDwswABCwMDIwMqIANAEdXAnIAAHicY2FgYGBBxswQGgABfQAcAAAAAAAAAAC2ANwBHAFuAhAAAHicY2BkYGBgY2gDYhBgAmIuIGRg+A/mMwAAFowBqQAAeJxlj01OwzAQhV/6B6QSqqhgh+QFYgEo/RGrblhUavdddN+mTpsqiSPHrdQDcB6OwAk4AtyAO/BIJ5s2lsffvHljTwDc4Acejt8t95E9XDI7cg0XuBeuU38QbpBfhJto41W4Rf1N2MczpsJtdGF5g9e4YvaEd2EPHXwI13CNT+E69S/hBvlbuIk7/Aq30PHqwj7mXle4jUcv9sdWL5xeqeVBxaHJIpM5v4KZXu+Sha3S6pxrW8QmU4OgX0lTnWlb3VPs10PnIhVZk6oJqzpJjMqt2erQBRvn8lGvF4kehCblWGP+tsYCjnEFhSUOjDFCGGSIyujoO1Vm9K+xQ8Jee1Y9zed0WxTU/3OFAQL0z1xTurLSeTpPgT1fG1J1dCtuy56UNJFezUkSskJe1rZUQuoBNmVXjhF6XNGJPyhnSP8ACVpuyAAAAHicY2BigAAuBuyAjZGJkZmRhZGVkY2RnYGjKDU9s7gktYglMy8tny05Iz8zOZU1Jz89M48lOb+gkoEBANqJC58=') format('woff'), |
||||||
|
url('iconfont.ttf?t=1540125096323') format('truetype'), /* chrome, firefox, opera, Safari, Android, iOS 4.2+*/ |
||||||
|
url('iconfont.svg?t=1540125096323#iconfont') format('svg'); /* iOS 4.1- */ |
||||||
|
} |
||||||
|
|
||||||
|
.iconfont { |
||||||
|
font-family:"iconfont" !important; |
||||||
|
font-size:16px; |
||||||
|
font-style:normal; |
||||||
|
-webkit-font-smoothing: antialiased; |
||||||
|
-moz-osx-font-smoothing: grayscale; |
||||||
|
} |
||||||
|
|
||||||
|
.icon-register:before { content: "\e60e"; } |
||||||
|
|
||||||
|
.icon-info:before { content: "\ebcf"; } |
||||||
|
|
||||||
|
.icon-choice:before { content: "\e627"; } |
||||||
|
|
||||||
|
.icon-login:before { content: "\e728"; } |
||||||
|
|
||||||
|
.icon-copy:before { content: "\e600"; } |
||||||
|
|
After Width: | Height: | Size: 11 KiB |
After Width: | Height: | Size: 455 KiB |
After Width: | Height: | Size: 475 KiB |
After Width: | Height: | Size: 12 KiB |
After Width: | Height: | Size: 10 KiB |
@ -0,0 +1,118 @@ |
|||||||
|
var app = { |
||||||
|
/** |
||||||
|
* ajax |
||||||
|
* @param url |
||||||
|
* @param data |
||||||
|
* @param success |
||||||
|
* @param error |
||||||
|
*/ |
||||||
|
ajax: function (url, data, success, error) { |
||||||
|
var loading = $('#loading-container'); |
||||||
|
$.ajax({ |
||||||
|
url: url, |
||||||
|
type: 'post', |
||||||
|
data: data, |
||||||
|
dataType: 'json', |
||||||
|
beforeSend: function () { |
||||||
|
loading.fadeIn(500); |
||||||
|
}, |
||||||
|
success: success, |
||||||
|
error: error, |
||||||
|
complete: function () { |
||||||
|
loading.fadeOut(100); |
||||||
|
} |
||||||
|
}); |
||||||
|
}, |
||||||
|
/** |
||||||
|
* 执行请求 |
||||||
|
* @param url 请求地址 |
||||||
|
* @param data 数据 |
||||||
|
* @param success 后端返回成功后执行的回调 |
||||||
|
* @param error 后端返回失败后执行的回调 |
||||||
|
* @returns {*|void} |
||||||
|
*/ |
||||||
|
request: function (url, data, success, error) { |
||||||
|
return app.ajax(url, data, function (response) { |
||||||
|
mdui.snackbar({ |
||||||
|
message: "<i class=\"mdui-icon material-icons\">" + (response.code ? '' : '') + ";</i> " + response.msg, |
||||||
|
position: 'right-top', |
||||||
|
timeout: response.code ? 1000 : 2000, |
||||||
|
onClose: function () { |
||||||
|
if (response.code) { |
||||||
|
success && success(); |
||||||
|
} else { |
||||||
|
error && error(); |
||||||
|
} |
||||||
|
} |
||||||
|
}); |
||||||
|
}); |
||||||
|
}, |
||||||
|
/** |
||||||
|
* Msg |
||||||
|
* @param bool |
||||||
|
* @param msg |
||||||
|
* @param callback |
||||||
|
*/ |
||||||
|
msg: function (bool, msg, callback) { |
||||||
|
mdui.snackbar({ |
||||||
|
message: "<i class=\"mdui-icon material-icons\">" + (bool ? '' : '') + ";</i> " + msg, |
||||||
|
position: 'right-top', |
||||||
|
timeout: bool ? 1000 : 2000, |
||||||
|
onClose: function () { |
||||||
|
if (bool) callback && callback(); |
||||||
|
} |
||||||
|
}); |
||||||
|
}, |
||||||
|
cookie: { |
||||||
|
/** |
||||||
|
* 设置cookie |
||||||
|
* @param key cookie名称 |
||||||
|
* @param val cookie值 |
||||||
|
* @param time 过期时间(天) |
||||||
|
* @param path cookie路径 |
||||||
|
*/ |
||||||
|
set: function (key, val, time, path) { |
||||||
|
var date = new Date(); |
||||||
|
var expiresDays = time; |
||||||
|
date.setTime(date.getTime() + expiresDays * 24 * 3600 * 1000); |
||||||
|
document.cookie = key + "=" + val + ";expires=" + date.toGMTString() + (path ? (";path=" + path) : ''); |
||||||
|
}, |
||||||
|
/** |
||||||
|
* 获取cookie |
||||||
|
* @param key cookie名称 |
||||||
|
* @returns {*} |
||||||
|
*/ |
||||||
|
get: function (key) { |
||||||
|
var getCookie = document.cookie.replace(/[ ]/g, ""); |
||||||
|
var arrCookie = getCookie.split(";"); |
||||||
|
var tips; |
||||||
|
for (var i = 0; i < arrCookie.length; i++) { |
||||||
|
var arr = arrCookie[i].split("="); |
||||||
|
if (key === arr[0]) { |
||||||
|
tips = arr[1]; |
||||||
|
break; |
||||||
|
} |
||||||
|
} |
||||||
|
return tips; |
||||||
|
}, |
||||||
|
/** |
||||||
|
* 删除cookie |
||||||
|
* @param key |
||||||
|
*/ |
||||||
|
delete: function (key) { |
||||||
|
var date = new Date(); |
||||||
|
date.setTime(date.getTime() - 10000); |
||||||
|
document.cookie = key + "=v; expires =" + date.toGMTString(); |
||||||
|
} |
||||||
|
}, |
||||||
|
/** |
||||||
|
* 字节换算 |
||||||
|
* @param bytes |
||||||
|
* @returns {string} |
||||||
|
*/ |
||||||
|
bytesToSize: function (bytes) { |
||||||
|
if (bytes === 0) return '0 B'; |
||||||
|
var k = 1024, sizes = ['B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'], i = Math.floor(Math.log(bytes) / Math.log(k)); |
||||||
|
return (bytes / Math.pow(k, i)).toFixed(2) + ' ' + sizes[i]; |
||||||
|
} |
||||||
|
}; |
@ -0,0 +1,25 @@ |
|||||||
|
|
||||||
|
@font-face {font-family: "iconfont"; |
||||||
|
src: url('iconfont.eot?t=1541323666371'); /* IE9*/ |
||||||
|
src: url('iconfont.eot?t=1541323666371#iefix') format('embedded-opentype'), /* IE6-IE8 */ |
||||||
|
url('data:application/x-font-woff;charset=utf-8;base64,d09GRgABAAAAAAdMAAsAAAAACiAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAABHU1VCAAABCAAAADMAAABCsP6z7U9TLzIAAAE8AAAARAAAAFY7j0tIY21hcAAAAYAAAABuAAABstYsnFZnbHlmAAAB8AAAA0kAAAO4ouPbfWhlYWQAAAU8AAAALwAAADYTP/0haGhlYQAABWwAAAAgAAAAJAf2A29obXR4AAAFjAAAAA4AAAAUFAAAAGxvY2EAAAWcAAAADAAAAAwBhgKGbWF4cAAABagAAAAfAAAAIAEWAIZuYW1lAAAFyAAAAUUAAAJtPlT+fXBvc3QAAAcQAAAAPAAAAE00I4RTeJxjYGRgYOBikGPQYWB0cfMJYeBgYGGAAJAMY05meiJQDMoDyrGAaQ4gZoOIAgCKIwNPAHicY2BkYWCcwMDKwMHUyXSGgYGhH0IzvmYwYuRgYGBiYGVmwAoC0lxTGByeSr4MY27438AQw9zA0AAUZgTJAQDlugxUeJztkcENgCAMRV8BjTEu4A4O4QCencKTJxeWhCmwpR4cwk9e0/9DaFKADojKoiSQE8F0aCotj4wtT6zqRwYC4Z7zlq+y1wrf/pXoPT/2alCvM6Tn19Tq+rpk23Osz5ujGyNfjv1C2R3iAwirGecAAHicTVLNbxtFFJ83Mzvrzdq7Xns9Yye2s/5axzIsij92W5c6aRDEEAk3h9RCpFKkVFAhUSIa1PZE2iBVRYZyQXxEQiBEwL1yag7lwLER4sAfYMSxUqUeqHthYZwTozfz3rz303vze/MQIPTvkALZRT2ELDsheGMJ/OAsMA+/AB4OfMEDP/Cg3QrcwM+D8BuiiwVXecpmKs+BLew8NP1Eu+XhooF/+ZJFMMVQ6RQy1NTKCbWxVNyYye/uBDyb6+X003c7MWclO2efev9qHSAS+erX9TsPfn9wZx2uHoaTNmACVLlEtWQ26poZU53dbKZqudSti4Plcz08l4zE45ot8Ory8uDivl0/exMwY6wF+o+XZRKZC8lFJK9vyZhsIR0J5CCkuKjqo4AjwRBYNu9CYLVcA6p5aPgtt8gwOg6fKAqYx8dgKkr4JHxWahZguqHYLEjZ+l/wWIKxCP/IlKCYgeem6mB2CioiRGXth+Rn4qM4KqIV9BJCYIAqe9cIZNkutD1ISocBJQ+q0iMjNqswt6pyGvhuVVquL/KQartliZKWFBXC+38rytOjjX5jUPJadHLdOe+Ve5XRmNLxSJ6L4YF6+Cpz4GGZLd7Gm8sqvPnB9UT4zQ0l45SHW1b/Y9Kmk/tHE1pInquf+qR/NPmn73aSukn//Gk0VpTxqLdfJenOTmr1N9KvwXyZ1JWoi7djL79F1srF3izpWUiV/MZUkCzKogXUQl20it5ANyRLt4urLlOZnBRXPWE4fTsvyytIUpKqz4UBRPoZF9yfwpjbkprbLGAedCEPrNLwg/ZJAps3fa7anLjMhMWTHjaDKVpw6WAyLHMs+i5+mlWYPd8Yqi6O0DNvX/mCvGhR8ejDjyDeqV8Kr+2NKB3t7d2j9N5310oMYoW12wsLS4dpJ5eec5w1La6RhBVR4HPdwPSuHjXN6AVTiWvPv27QWByAW7Gobt1qCpVQyhOxFK0NYcg4Wa3I/4rmnFpv3vtBG+zgT99TtctX3t0Ov6bvXNjYjdDNjcFNOJP+TCPNVNVpdQ7+wrxWIDizML/OsJGMESPxODZD9vMRMNOmvq3pcViZUSmmKcMSGNOI89rpV1g06iQhKr4/lOP9H+a9uFoAAAB4nGNgZGBgAGKvIonv8fw2Xxm4WRhA4AbLnUkI+n8PizhzCZDLwcAEEgUAIYIKNwB4nGNgZGBgbvjfwBDDwsDA8P8lizgDUAQFsAIAcccEbXicY2FgYGBBwwABBAAVAAAAAAAAAGwAqgEaAdx4nGNgZGBgYGWoYmBnAAEmIOYCQgaG/2A+AwAVXAGdAHicZY9NTsMwEIVf+gekEqqoYIfkBWIBKP0Rq25YVGr3XXTfpk6bKokjx63UA3AejsAJOALcgDvwSCebNpbH37x5Y08A3OAHHo7fLfeRPVwyO3INF7gXrlN/EG6QX4SbaONVuEX9TdjHM6bCbXRheYPXuGL2hHdhDx18CNdwjU/hOvUv4Qb5W7iJO/wKt9Dx6sI+5l5XuI1HL/bHVi+cXqnlQcWhySKTOb+CmV7vkoWt0uqca1vEJlODoF9JU51pW91T7NdD5yIVWZOqCas6SYzKrdnq0AUb5/JRrxeJHoQm5Vhj/rbGAo5xBYUlDowxQhhkiMro6DtVZvSvsUPCXntWPc3ndFsU1P9zhQEC9M9cU7qy0nk6T4E9XxtSdXQrbsuelDSRXs1JErJCXta2VELqATZlV44RelzRiT8oZ0j/AAlabsgAAAB4nGNgYoAALgbsgJWRiZGZkYWRlZGNgS09sySjNIk9vTQxr7LUmK04vzQ9v5S9IjMvJzEvnYEBAMJqCyc=') format('woff'), |
||||||
|
url('iconfont.ttf?t=1541323666371') format('truetype'), /* chrome, firefox, opera, Safari, Android, iOS 4.2+*/ |
||||||
|
url('iconfont.svg?t=1541323666371#iconfont') format('svg'); /* iOS 4.1- */ |
||||||
|
} |
||||||
|
|
||||||
|
.iconfont { |
||||||
|
font-family:"iconfont" !important; |
||||||
|
font-size:16px; |
||||||
|
font-style:normal; |
||||||
|
-webkit-font-smoothing: antialiased; |
||||||
|
-moz-osx-font-smoothing: grayscale; |
||||||
|
} |
||||||
|
|
||||||
|
.icon-github:before { content: "\e678"; } |
||||||
|
|
||||||
|
.icon-guanyu3:before { content: "\e64c"; } |
||||||
|
|
||||||
|
.icon-sougou:before { content: "\e956"; } |
||||||
|
|
||||||
|
.icon-xinlang:before { content: "\e519"; } |
||||||
|
|
After Width: | Height: | Size: 5.2 KiB |
After Width: | Height: | Size: 2.6 KiB |
After Width: | Height: | Size: 847 B |
@ -0,0 +1,100 @@ |
|||||||
|
/*! |
||||||
|
* FileInput Chinese Translations |
||||||
|
* |
||||||
|
* This file must be loaded after 'fileinput.js'. Patterns in braces '{}', or |
||||||
|
* any HTML markup tags in the messages must not be converted or translated. |
||||||
|
* |
||||||
|
* @see http://github.com/kartik-v/bootstrap-fileinput
|
||||||
|
* @author kangqf <kangqingfei@gmail.com> |
||||||
|
* |
||||||
|
* NOTE: this file must be saved in UTF-8 encoding. |
||||||
|
*/ |
||||||
|
(function ($) { |
||||||
|
"use strict"; |
||||||
|
|
||||||
|
$.fn.fileinputLocales['zh'] = { |
||||||
|
fileSingle: '文件', |
||||||
|
filePlural: '个文件', |
||||||
|
browseLabel: '选择 …', |
||||||
|
removeLabel: '移除', |
||||||
|
removeTitle: '清除选中文件', |
||||||
|
cancelLabel: '取消', |
||||||
|
cancelTitle: '取消进行中的上传', |
||||||
|
uploadLabel: '上传', |
||||||
|
uploadTitle: '上传选中文件', |
||||||
|
msgNo: '没有', |
||||||
|
msgNoFilesSelected: '未选择文件', |
||||||
|
msgCancelled: '取消', |
||||||
|
msgPlaceholder: '选择 {files}...', |
||||||
|
msgZoomModalHeading: '详细预览', |
||||||
|
msgFileRequired: '必须选择一个文件上传.', |
||||||
|
msgSizeTooSmall: '文件 "{name}" (<b>{size} KB</b>) 必须大于限定大小 <b>{minSize} KB</b>.', |
||||||
|
msgSizeTooLarge: '文件 "{name}" (<b>{size} KB</b>) 超过了允许大小 <b>{maxSize} KB</b>.', |
||||||
|
msgFilesTooLess: '你必须选择最少 <b>{n}</b> {files} 来上传. ', |
||||||
|
msgFilesTooMany: '选择的上传文件个数 <b>({n})</b> 超出最大文件的限制个数 <b>{m}</b>.', |
||||||
|
msgFileNotFound: '文件 "{name}" 未找到!', |
||||||
|
msgFileSecured: '安全限制,为了防止读取文件 "{name}".', |
||||||
|
msgFileNotReadable: '文件 "{name}" 不可读.', |
||||||
|
msgFilePreviewAborted: '取消 "{name}" 的预览.', |
||||||
|
msgFilePreviewError: '读取 "{name}" 时出现了一个错误.', |
||||||
|
msgInvalidFileName: '文件名 "{name}" 包含非法字符.', |
||||||
|
msgInvalidFileType: '不正确的类型 "{name}". 只支持 "{types}" 类型的文件.', |
||||||
|
msgInvalidFileExtension: '不正确的文件扩展名 "{name}". 只支持 "{extensions}" 的文件扩展名.', |
||||||
|
msgFileTypes: { |
||||||
|
'image': 'image', |
||||||
|
'html': 'HTML', |
||||||
|
'text': 'text', |
||||||
|
'video': 'video', |
||||||
|
'audio': 'audio', |
||||||
|
'flash': 'flash', |
||||||
|
'pdf': 'PDF', |
||||||
|
'object': 'object' |
||||||
|
}, |
||||||
|
msgUploadAborted: '该文件上传被中止', |
||||||
|
msgUploadThreshold: '处理中...', |
||||||
|
msgUploadBegin: '正在初始化...', |
||||||
|
msgUploadEnd: '完成', |
||||||
|
msgUploadEmpty: '无效的文件上传.', |
||||||
|
msgUploadError: '上传出错', |
||||||
|
msgValidationError: '验证错误', |
||||||
|
msgLoading: '加载第 {index} 文件 共 {files} …', |
||||||
|
msgProgress: '加载第 {index} 文件 共 {files} - {name} - {percent}% 完成.', |
||||||
|
msgSelected: '{n} {files} 选中', |
||||||
|
msgFoldersNotAllowed: '只支持拖拽文件! 跳过 {n} 拖拽的文件夹.', |
||||||
|
msgImageWidthSmall: '图像文件的"{name}"的宽度必须是至少{size}像素.', |
||||||
|
msgImageHeightSmall: '图像文件的"{name}"的高度必须至少为{size}像素.', |
||||||
|
msgImageWidthLarge: '图像文件"{name}"的宽度不能超过{size}像素.', |
||||||
|
msgImageHeightLarge: '图像文件"{name}"的高度不能超过{size}像素.', |
||||||
|
msgImageResizeError: '无法获取的图像尺寸调整。', |
||||||
|
msgImageResizeException: '调整图像大小时发生错误。<pre>{errors}</pre>', |
||||||
|
msgAjaxError: '{operation} 发生错误. 请重试!', |
||||||
|
msgAjaxProgressError: '{operation} 失败', |
||||||
|
ajaxOperations: { |
||||||
|
deleteThumb: '删除文件', |
||||||
|
uploadThumb: '上传文件', |
||||||
|
uploadBatch: '批量上传', |
||||||
|
uploadExtra: '表单数据上传' |
||||||
|
}, |
||||||
|
dropZoneTitle: '拖拽文件到这里 …<br>支持多文件同时上传', |
||||||
|
dropZoneClickTitle: '<br>(或点击{files}按钮选择文件)', |
||||||
|
fileActionSettings: { |
||||||
|
removeTitle: '删除文件', |
||||||
|
uploadTitle: '上传文件', |
||||||
|
uploadRetryTitle: '重试', |
||||||
|
zoomTitle: '查看详情', |
||||||
|
dragTitle: '移动 / 重置', |
||||||
|
indicatorNewTitle: '没有上传', |
||||||
|
indicatorSuccessTitle: '上传', |
||||||
|
indicatorErrorTitle: '上传错误', |
||||||
|
indicatorLoadingTitle: '上传 ...' |
||||||
|
}, |
||||||
|
previewZoomButtonTitles: { |
||||||
|
prev: '预览上一个文件', |
||||||
|
next: '预览下一个文件', |
||||||
|
toggleheader: '缩放', |
||||||
|
fullscreen: '全屏', |
||||||
|
borderless: '无边界模式', |
||||||
|
close: '关闭当前预览' |
||||||
|
} |
||||||
|
}; |
||||||
|
})(window.jQuery); |
After Width: | Height: | Size: 106 KiB |
@ -0,0 +1,228 @@ |
|||||||
|
/** |
||||||
|
* ContextJS Styles |
||||||
|
* For use WITHOUT Twitters Bootstrap CSS |
||||||
|
*/ |
||||||
|
|
||||||
|
.nav-header { |
||||||
|
display: block; |
||||||
|
padding: 3px 15px; |
||||||
|
font-size: 11px; |
||||||
|
font-weight: bold; |
||||||
|
line-height: 20px; |
||||||
|
color: #999; |
||||||
|
text-shadow: 0 1px 0 rgba(255, 255, 255, 0.5); |
||||||
|
text-transform: uppercase; |
||||||
|
} |
||||||
|
.dropdown-menu { |
||||||
|
position: absolute; |
||||||
|
top: 100%; |
||||||
|
left: 0; |
||||||
|
z-index: 1000; |
||||||
|
display: none; |
||||||
|
float: left; |
||||||
|
min-width: 160px; |
||||||
|
padding: 5px 0; |
||||||
|
margin: 2px 0 0; |
||||||
|
list-style: none; |
||||||
|
background-color: #ffffff; |
||||||
|
border: 1px solid #ccc; |
||||||
|
border: 1px solid rgba(0, 0, 0, 0.2); |
||||||
|
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; |
||||||
|
font-size: 14px; |
||||||
|
*border-right-width: 2px; |
||||||
|
*border-bottom-width: 2px; |
||||||
|
-webkit-border-radius: 6px; |
||||||
|
-moz-border-radius: 6px; |
||||||
|
border-radius: 6px; |
||||||
|
-webkit-box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2); |
||||||
|
-moz-box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2); |
||||||
|
box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2); |
||||||
|
-webkit-background-clip: padding-box; |
||||||
|
-moz-background-clip: padding; |
||||||
|
background-clip: padding-box; |
||||||
|
text-align:left; |
||||||
|
} |
||||||
|
.dropdown-menu.pull-right { |
||||||
|
right: 0; |
||||||
|
left: auto; |
||||||
|
} |
||||||
|
.dropdown-menu .divider { |
||||||
|
*width: 100%; |
||||||
|
height: 1px; |
||||||
|
margin: 9px 1px; |
||||||
|
*margin: -5px 0 5px; |
||||||
|
overflow: hidden; |
||||||
|
background-color: #e5e5e5; |
||||||
|
border-bottom: 1px solid #ffffff; |
||||||
|
} |
||||||
|
.dropdown-menu a { |
||||||
|
display: block; |
||||||
|
padding: 3px 20px; |
||||||
|
clear: both; |
||||||
|
font-weight: normal; |
||||||
|
line-height: 20px; |
||||||
|
color: #333333; |
||||||
|
white-space: nowrap; |
||||||
|
text-decoration: none; |
||||||
|
} |
||||||
|
.dropdown-menu li > a:hover, .dropdown-menu li > a:focus, .dropdown-submenu:hover > a { |
||||||
|
color: #ffffff; |
||||||
|
text-decoration: none; |
||||||
|
background-color: #0088cc; |
||||||
|
background-color: #0081c2; |
||||||
|
background-image: -moz-linear-gradient(top, #0088cc, #0077b3); |
||||||
|
background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#0088cc), to(#0077b3)); |
||||||
|
background-image: -webkit-linear-gradient(top, #0088cc, #0077b3); |
||||||
|
background-image: -o-linear-gradient(top, #0088cc, #0077b3); |
||||||
|
background-image: linear-gradient(to bottom, #0088cc, #0077b3); |
||||||
|
background-repeat: repeat-x; |
||||||
|
filter: progid: dximagetransform.microsoft.gradient(startColorstr='#ff0088cc', endColorstr='#ff0077b3', GradientType=0); |
||||||
|
} |
||||||
|
.dropdown-menu .active > a, .dropdown-menu .active > a:hover { |
||||||
|
color: #ffffff; |
||||||
|
text-decoration: none; |
||||||
|
background-color: #0088cc; |
||||||
|
background-color: #0081c2; |
||||||
|
background-image: linear-gradient(to bottom, #0088cc, #0077b3); |
||||||
|
background-image: -moz-linear-gradient(top, #0088cc, #0077b3); |
||||||
|
background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#0088cc), to(#0077b3)); |
||||||
|
background-image: -webkit-linear-gradient(top, #0088cc, #0077b3); |
||||||
|
background-image: -o-linear-gradient(top, #0088cc, #0077b3); |
||||||
|
background-repeat: repeat-x; |
||||||
|
outline: 0; |
||||||
|
filter: progid |
||||||
|
: dximagetransform.microsoft.gradient(startColorstr='#ff0088cc', endColorstr='#ff0077b3', GradientType=0); |
||||||
|
} |
||||||
|
.dropdown-menu .disabled > a, .dropdown-menu .disabled > a:hover { |
||||||
|
color: #999999; |
||||||
|
} |
||||||
|
.dropdown-menu .disabled > a:hover { |
||||||
|
text-decoration: none; |
||||||
|
cursor: default; |
||||||
|
background-color: transparent; |
||||||
|
} |
||||||
|
.open { |
||||||
|
*z-index: 1000; |
||||||
|
} |
||||||
|
.open > .dropdown-menu { |
||||||
|
display: block; |
||||||
|
} |
||||||
|
.pull-right > .dropdown-menu { |
||||||
|
right: 0; |
||||||
|
left: auto; |
||||||
|
} |
||||||
|
.dropup .caret, .navbar-fixed-bottom .dropdown .caret { |
||||||
|
border-top: 0; |
||||||
|
border-bottom: 4px solid #000000; |
||||||
|
content: "\2191"; |
||||||
|
} |
||||||
|
.dropup .dropdown-menu, .navbar-fixed-bottom .dropdown .dropdown-menu { |
||||||
|
top: auto; |
||||||
|
bottom: 100%; |
||||||
|
margin-bottom: 1px; |
||||||
|
} |
||||||
|
.dropdown-submenu { |
||||||
|
position: relative; |
||||||
|
} |
||||||
|
.dropdown-submenu > .dropdown-menu { |
||||||
|
top: 0; |
||||||
|
left: 100%; |
||||||
|
margin-top: -6px; |
||||||
|
margin-left: -1px; |
||||||
|
-webkit-border-radius: 0 6px 6px 6px; |
||||||
|
-moz-border-radius: 0 6px 6px 6px; |
||||||
|
border-radius: 0 6px 6px 6px; |
||||||
|
} |
||||||
|
.dropdown-submenu > .dropdown-menu.drop-left{ |
||||||
|
left:-100%; |
||||||
|
} |
||||||
|
.dropdown-submenu:hover .dropdown-menu { |
||||||
|
display: block; |
||||||
|
} |
||||||
|
.dropdown-submenu > a:after { |
||||||
|
display: block; |
||||||
|
float: right; |
||||||
|
width: 0; |
||||||
|
height: 0; |
||||||
|
margin-top: 5px; |
||||||
|
margin-right: -10px; |
||||||
|
border-color: transparent; |
||||||
|
border-left-color: #cccccc; |
||||||
|
border-style: solid; |
||||||
|
border-width: 5px 0 5px 5px; |
||||||
|
content: " "; |
||||||
|
} |
||||||
|
.dropdown-submenu:hover > a:after { |
||||||
|
border-left-color: #ffffff; |
||||||
|
} |
||||||
|
.dropdown .dropdown-menu .nav-header { |
||||||
|
padding-right: 20px; |
||||||
|
padding-left: 20px; |
||||||
|
} |
||||||
|
/** |
||||||
|
* Context Styles |
||||||
|
*/ |
||||||
|
|
||||||
|
.dropdown-context .nav-header { |
||||||
|
cursor: default; |
||||||
|
} |
||||||
|
.dropdown-context:before, .dropdown-context-up:before { |
||||||
|
position: absolute; |
||||||
|
top: -7px; |
||||||
|
left: 9px; |
||||||
|
display: inline-block; |
||||||
|
border-right: 7px solid transparent; |
||||||
|
border-bottom: 7px solid #ccc; |
||||||
|
border-left: 7px solid transparent; |
||||||
|
border-bottom-color: rgba(0, 0, 0, 0.2); |
||||||
|
content: ''; |
||||||
|
} |
||||||
|
.dropdown-context:after, .dropdown-context-up:after { |
||||||
|
position: absolute; |
||||||
|
top: -6px; |
||||||
|
left: 10px; |
||||||
|
display: inline-block; |
||||||
|
border-right: 6px solid transparent; |
||||||
|
border-bottom: 6px solid #ffffff; |
||||||
|
border-left: 6px solid transparent; |
||||||
|
content: ''; |
||||||
|
} |
||||||
|
.dropdown-context-up:before, .dropdown-context-up:after { |
||||||
|
top: auto; |
||||||
|
bottom: -7px; |
||||||
|
z-index: 9999; |
||||||
|
} |
||||||
|
.dropdown-context-up:before { |
||||||
|
border-right: 7px solid transparent; |
||||||
|
border-top: 7px solid #ccc; |
||||||
|
border-bottom: none; |
||||||
|
border-left: 7px solid transparent; |
||||||
|
} |
||||||
|
.dropdown-context-up:after { |
||||||
|
border-right: 6px solid transparent; |
||||||
|
border-top: 6px solid #ffffff; |
||||||
|
border-left: 6px solid transparent; |
||||||
|
border-bottom: none; |
||||||
|
} |
||||||
|
.dropdown-context-sub:before, .dropdown-context-sub:after { |
||||||
|
display: none; |
||||||
|
} |
||||||
|
.dropdown-context .dropdown-submenu:hover .dropdown-menu { |
||||||
|
display: none; |
||||||
|
} |
||||||
|
.dropdown-context .dropdown-submenu:hover > .dropdown-menu { |
||||||
|
display: block; |
||||||
|
} |
||||||
|
|
||||||
|
.compressed-context a{ |
||||||
|
padding-left: 14px; |
||||||
|
padding-top: 0; |
||||||
|
padding-bottom: 0; |
||||||
|
font-size: 13px; |
||||||
|
} |
||||||
|
.compressed-context .divider{ |
||||||
|
margin: 5px 1px; |
||||||
|
} |
||||||
|
.compressed-context .nav-header{ |
||||||
|
padding:1px 13px; |
||||||
|
} |
@ -0,0 +1,141 @@ |
|||||||
|
/* |
||||||
|
* Context.js |
||||||
|
* Copyright Jacob Kelley |
||||||
|
* MIT License |
||||||
|
*/ |
||||||
|
|
||||||
|
var context = context || (function () { |
||||||
|
|
||||||
|
var options = { |
||||||
|
fadeSpeed: 100, |
||||||
|
filter: function ($obj) { |
||||||
|
// Modify $obj, Do not return
|
||||||
|
}, |
||||||
|
above: 'auto', |
||||||
|
preventDoubleContext: true, |
||||||
|
compress: false |
||||||
|
}; |
||||||
|
|
||||||
|
function initialize(opts) { |
||||||
|
|
||||||
|
options = $.extend({}, options, opts); |
||||||
|
|
||||||
|
$(document).on('click', 'html', function () { |
||||||
|
$('.dropdown-context').fadeOut(options.fadeSpeed, function(){ |
||||||
|
$('.dropdown-context').css({display:''}).find('.drop-left').removeClass('drop-left'); |
||||||
|
}); |
||||||
|
}); |
||||||
|
if(options.preventDoubleContext){ |
||||||
|
$(document).on('contextmenu', '.dropdown-context', function (e) { |
||||||
|
e.preventDefault(); |
||||||
|
}); |
||||||
|
} |
||||||
|
$(document).on('mouseenter', '.dropdown-submenu', function(){ |
||||||
|
var $sub = $(this).find('.dropdown-context-sub:first'), |
||||||
|
subWidth = $sub.width(), |
||||||
|
subLeft = $sub.offset().left, |
||||||
|
collision = (subWidth+subLeft) > window.innerWidth; |
||||||
|
if(collision){ |
||||||
|
$sub.addClass('drop-left'); |
||||||
|
} |
||||||
|
}); |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
function updateOptions(opts){ |
||||||
|
options = $.extend({}, options, opts); |
||||||
|
} |
||||||
|
|
||||||
|
function buildMenu(data, id, subMenu) { |
||||||
|
var subClass = (subMenu) ? ' dropdown-context-sub' : '', |
||||||
|
compressed = options.compress ? ' compressed-context' : '', |
||||||
|
$menu = $('<ul class="dropdown-menu dropdown-context' + subClass + compressed+'" id="dropdown-' + id + '"></ul>'); |
||||||
|
var i = 0, linkTarget = ''; |
||||||
|
for(i; i<data.length; i++) { |
||||||
|
if (typeof data[i].divider !== 'undefined') { |
||||||
|
$menu.append('<li class="divider"></li>'); |
||||||
|
} else if (typeof data[i].header !== 'undefined') { |
||||||
|
$menu.append('<li class="nav-header">' + data[i].header + '</li>'); |
||||||
|
} else { |
||||||
|
if (typeof data[i].href == 'undefined') { |
||||||
|
data[i].href = '#'; |
||||||
|
} |
||||||
|
if (typeof data[i].target !== 'undefined') { |
||||||
|
linkTarget = ' target="'+data[i].target+'"'; |
||||||
|
} |
||||||
|
if (typeof data[i].subMenu !== 'undefined') { |
||||||
|
$sub = ('<li class="dropdown-submenu"><a tabindex="-1" href="' + data[i].href + '">' + data[i].text + '</a></li>'); |
||||||
|
} else { |
||||||
|
$sub = $('<li><a tabindex="-1" href="' + data[i].href + '"'+linkTarget+'>' + data[i].text + '</a></li>'); |
||||||
|
} |
||||||
|
if (typeof data[i].action !== 'undefined') { |
||||||
|
var actiond = new Date(), |
||||||
|
actionID = 'event-' + actiond.getTime() * Math.floor(Math.random()*100000), |
||||||
|
eventAction = data[i].action; |
||||||
|
$sub.find('a').attr('id', actionID); |
||||||
|
$('#' + actionID).addClass('context-event'); |
||||||
|
$(document).on('click', '#' + actionID, eventAction); |
||||||
|
} |
||||||
|
$menu.append($sub); |
||||||
|
if (typeof data[i].subMenu != 'undefined') { |
||||||
|
var subMenuData = buildMenu(data[i].subMenu, id, true); |
||||||
|
$menu.find('li:last').append(subMenuData); |
||||||
|
} |
||||||
|
} |
||||||
|
if (typeof options.filter == 'function') { |
||||||
|
options.filter($menu.find('li:last')); |
||||||
|
} |
||||||
|
} |
||||||
|
return $menu; |
||||||
|
} |
||||||
|
|
||||||
|
function addContext(selector, data) { |
||||||
|
|
||||||
|
var d = new Date(), |
||||||
|
id = d.getTime(), |
||||||
|
$menu = buildMenu(data, id); |
||||||
|
|
||||||
|
$('body').append($menu); |
||||||
|
|
||||||
|
|
||||||
|
$(document).on('contextmenu', selector, function (e) { |
||||||
|
e.preventDefault(); |
||||||
|
e.stopPropagation(); |
||||||
|
|
||||||
|
$('.dropdown-context:not(.dropdown-context-sub)').hide(); |
||||||
|
|
||||||
|
$dd = $('#dropdown-' + id); |
||||||
|
if (typeof options.above == 'boolean' && options.above) { |
||||||
|
$dd.addClass('dropdown-context-up').css({ |
||||||
|
top: e.pageY - 20 - $('#dropdown-' + id).height(), |
||||||
|
left: e.pageX - 13 |
||||||
|
}).fadeIn(options.fadeSpeed); |
||||||
|
} else if (typeof options.above == 'string' && options.above == 'auto') { |
||||||
|
$dd.removeClass('dropdown-context-up'); |
||||||
|
var autoH = $dd.height() + 12; |
||||||
|
if ((e.pageY + autoH) > $('html').height()) { |
||||||
|
$dd.addClass('dropdown-context-up').css({ |
||||||
|
top: e.pageY - 20 - autoH, |
||||||
|
left: e.pageX - 13 |
||||||
|
}).fadeIn(options.fadeSpeed); |
||||||
|
} else { |
||||||
|
$dd.css({ |
||||||
|
top: e.pageY + 10, |
||||||
|
left: e.pageX - 13 |
||||||
|
}).fadeIn(options.fadeSpeed); |
||||||
|
} |
||||||
|
} |
||||||
|
}); |
||||||
|
} |
||||||
|
|
||||||
|
function destroyContext(selector) { |
||||||
|
$(document).off('contextmenu', selector).off('click', '.context-event'); |
||||||
|
} |
||||||
|
|
||||||
|
return { |
||||||
|
init: initialize, |
||||||
|
settings: updateOptions, |
||||||
|
attach: addContext, |
||||||
|
destroy: destroyContext |
||||||
|
}; |
||||||
|
})(); |
@ -0,0 +1,455 @@ |
|||||||
|
/*! |
||||||
|
* Viewer.js v1.2.0 |
||||||
|
* https://fengyuanchen.github.io/viewerjs |
||||||
|
* |
||||||
|
* Copyright 2015-present Chen Fengyuan |
||||||
|
* Released under the MIT license |
||||||
|
* |
||||||
|
* Date: 2018-07-15T10:09:17.532Z |
||||||
|
*/ |
||||||
|
|
||||||
|
.viewer-zoom-in::before, |
||||||
|
.viewer-zoom-out::before, |
||||||
|
.viewer-one-to-one::before, |
||||||
|
.viewer-reset::before, |
||||||
|
.viewer-prev::before, |
||||||
|
.viewer-play::before, |
||||||
|
.viewer-next::before, |
||||||
|
.viewer-rotate-left::before, |
||||||
|
.viewer-rotate-right::before, |
||||||
|
.viewer-flip-horizontal::before, |
||||||
|
.viewer-flip-vertical::before, |
||||||
|
.viewer-fullscreen::before, |
||||||
|
.viewer-fullscreen-exit::before, |
||||||
|
.viewer-close::before { |
||||||
|
background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAARgAAAAUCAYAAABWOyJDAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAABx0RVh0U29mdHdhcmUAQWRvYmUgRmlyZXdvcmtzIENTNui8sowAAAQPSURBVHic7Zs/iFxVFMa/0U2UaJGksUgnIVhYxVhpjDbZCBmLdAYECxsRFBTUamcXUiSNncgKQbSxsxH8gzAP3FU2jY0kKKJNiiiIghFlccnP4p3nPCdv3p9778vsLOcHB2bfveeb7955c3jvvNkBIMdxnD64a94GHMfZu3iBcRynN7zAOI7TG15gHCeeNUkr8zaxG2lbYDYsdgMbktBsP03jdQwljSXdtBhLOmtjowC9Mg9L+knSlcD8TNKpSA9lBpK2JF2VdDSR5n5J64m0qli399hNFMUlpshQii5jbXTbHGviB0nLNeNDSd9VO4A2UdB2fp+x0eCnaXxWXGA2X0au/3HgN9P4LFCjIANOJdrLr0zzZ+BEpNYDwKbpnQMeAw4m8HjQtM6Z9qa917zPQwFr3M5KgA6J5rTJCdFZJj9/lyvGhsDvwFNVuV2MhhjrK6b9bFiE+j1r87eBl4HDwCF7/U/k+ofAX5b/EXBv5JoLMuILzf3Ap6Z3EzgdqHMCuF7hcQf4HDgeoHnccncqdK/TvSDWffFXI/exICY/xZyqc6XLWF1UFZna4gJ7q8BsRvgd2/xXpo6P+D9dfT7PpECtA3cnWPM0GXGFZh/wgWltA+cDNC7X+AP4GzjZQe+k5dRxuYPeiuXU7e1qwLpDz7dFjXKRaSwuMLvAlG8zZlG+YmiK1HoFqT7wP2z+4Q45TfEGcMt01xLoNZEBTwRqD4BLpnMLeC1A41UmVxsXgXeBayV/Wx20rpTyrpnWRft7p6O/FdqzGrDukPNtkaMoMo3FBdBSQMOnYBCReyf05s126fU9ytfX98+mY54Kxnp7S9K3kj6U9KYdG0h6UdLbkh7poFXMfUnSOyVvL0h6VtIXHbS6nOP+s/Zm9mvyXW1uuC9ohZ72E9uDmXWLJOB1GxsH+DxPftsB8B6wlGDN02TAkxG6+4D3TWsbeC5CS8CDFce+AW500LhhOW2020TRjK3b21HEmgti9m0RonxbdMZeVzV+/4tF3cBpP7E9mKHNL5q8h5g0eYsCMQz0epq8gQrwMXAgcs0FGXGFRcB9wCemF9PkbYqM/Bas7fxLwNeJPdTdpo4itQti8lPMqTpXuozVRVXPpbHI3KkNTB1NfkL81j2mvhDp91HgV9MKuRIqrykj3WPq4rHyL+axj8/qGPmTqi6F9YDlHOvJU6oYcTsh/TYSzWmTE6JT19CtLTJt32D6CmHe0eQn1O8z5AXgT4sx4Vcu0/EQecMydB8z0hUWkTd2t4CrwNEePqMBcAR4mrBbwyXLPWJa8zrXmmLEhNBmfpkuY2102xxrih+pb+ieAb6vGhuA97UcJ5KR8gZ77K+99xxeYBzH6Q3/Z0fHcXrDC4zjOL3hBcZxnN74F+zlvXFWXF9PAAAAAElFTkSuQmCC'); |
||||||
|
background-repeat: no-repeat; |
||||||
|
color: transparent; |
||||||
|
display: block; |
||||||
|
font-size: 0; |
||||||
|
height: 20px; |
||||||
|
line-height: 0; |
||||||
|
width: 20px; |
||||||
|
} |
||||||
|
|
||||||
|
.viewer-zoom-in::before { |
||||||
|
background-position: 0 0; |
||||||
|
content: 'Zoom In'; |
||||||
|
} |
||||||
|
|
||||||
|
.viewer-zoom-out::before { |
||||||
|
background-position: -20px 0; |
||||||
|
content: 'Zoom Out'; |
||||||
|
} |
||||||
|
|
||||||
|
.viewer-one-to-one::before { |
||||||
|
background-position: -40px 0; |
||||||
|
content: 'One to One'; |
||||||
|
} |
||||||
|
|
||||||
|
.viewer-reset::before { |
||||||
|
background-position: -60px 0; |
||||||
|
content: 'Reset'; |
||||||
|
} |
||||||
|
|
||||||
|
.viewer-prev::before { |
||||||
|
background-position: -80px 0; |
||||||
|
content: 'Previous'; |
||||||
|
} |
||||||
|
|
||||||
|
.viewer-play::before { |
||||||
|
background-position: -100px 0; |
||||||
|
content: 'Play'; |
||||||
|
} |
||||||
|
|
||||||
|
.viewer-next::before { |
||||||
|
background-position: -120px 0; |
||||||
|
content: 'Next'; |
||||||
|
} |
||||||
|
|
||||||
|
.viewer-rotate-left::before { |
||||||
|
background-position: -140px 0; |
||||||
|
content: 'Rotate Left'; |
||||||
|
} |
||||||
|
|
||||||
|
.viewer-rotate-right::before { |
||||||
|
background-position: -160px 0; |
||||||
|
content: 'Rotate Right'; |
||||||
|
} |
||||||
|
|
||||||
|
.viewer-flip-horizontal::before { |
||||||
|
background-position: -180px 0; |
||||||
|
content: 'Flip Horizontal'; |
||||||
|
} |
||||||
|
|
||||||
|
.viewer-flip-vertical::before { |
||||||
|
background-position: -200px 0; |
||||||
|
content: 'Flip Vertical'; |
||||||
|
} |
||||||
|
|
||||||
|
.viewer-fullscreen::before { |
||||||
|
background-position: -220px 0; |
||||||
|
content: 'Enter Full Screen'; |
||||||
|
} |
||||||
|
|
||||||
|
.viewer-fullscreen-exit::before { |
||||||
|
background-position: -240px 0; |
||||||
|
content: 'Exit Full Screen'; |
||||||
|
} |
||||||
|
|
||||||
|
.viewer-close::before { |
||||||
|
background-position: -260px 0; |
||||||
|
content: 'Close'; |
||||||
|
} |
||||||
|
|
||||||
|
.viewer-container { |
||||||
|
bottom: 0; |
||||||
|
direction: ltr; |
||||||
|
font-size: 0; |
||||||
|
left: 0; |
||||||
|
line-height: 0; |
||||||
|
overflow: hidden; |
||||||
|
position: absolute; |
||||||
|
right: 0; |
||||||
|
-webkit-tap-highlight-color: transparent; |
||||||
|
top: 0; |
||||||
|
-webkit-touch-callout: none; |
||||||
|
-ms-touch-action: none; |
||||||
|
touch-action: none; |
||||||
|
-webkit-user-select: none; |
||||||
|
-moz-user-select: none; |
||||||
|
-ms-user-select: none; |
||||||
|
user-select: none; |
||||||
|
} |
||||||
|
|
||||||
|
.viewer-container::-moz-selection, |
||||||
|
.viewer-container *::-moz-selection { |
||||||
|
background-color: transparent; |
||||||
|
} |
||||||
|
|
||||||
|
.viewer-container::selection, |
||||||
|
.viewer-container *::selection { |
||||||
|
background-color: transparent; |
||||||
|
} |
||||||
|
|
||||||
|
.viewer-container img { |
||||||
|
display: block; |
||||||
|
height: auto; |
||||||
|
max-height: none !important; |
||||||
|
max-width: none !important; |
||||||
|
min-height: 0 !important; |
||||||
|
min-width: 0 !important; |
||||||
|
width: 100%; |
||||||
|
} |
||||||
|
|
||||||
|
.viewer-canvas { |
||||||
|
bottom: 0; |
||||||
|
left: 0; |
||||||
|
overflow: hidden; |
||||||
|
position: absolute; |
||||||
|
right: 0; |
||||||
|
top: 0; |
||||||
|
} |
||||||
|
|
||||||
|
.viewer-canvas > img { |
||||||
|
height: auto; |
||||||
|
margin: 15px auto; |
||||||
|
max-width: 90% !important; |
||||||
|
width: auto; |
||||||
|
} |
||||||
|
|
||||||
|
.viewer-footer { |
||||||
|
bottom: 0; |
||||||
|
left: 0; |
||||||
|
overflow: hidden; |
||||||
|
position: absolute; |
||||||
|
right: 0; |
||||||
|
text-align: center; |
||||||
|
} |
||||||
|
|
||||||
|
.viewer-navbar { |
||||||
|
background-color: rgba(0, 0, 0, .5); |
||||||
|
overflow: hidden; |
||||||
|
} |
||||||
|
|
||||||
|
.viewer-list { |
||||||
|
-webkit-box-sizing: content-box; |
||||||
|
box-sizing: content-box; |
||||||
|
height: 50px; |
||||||
|
margin: 0; |
||||||
|
overflow: hidden; |
||||||
|
padding: 1px 0; |
||||||
|
} |
||||||
|
|
||||||
|
.viewer-list > li { |
||||||
|
color: transparent; |
||||||
|
cursor: pointer; |
||||||
|
float: left; |
||||||
|
font-size: 0; |
||||||
|
height: 50px; |
||||||
|
line-height: 0; |
||||||
|
opacity: .5; |
||||||
|
overflow: hidden; |
||||||
|
-webkit-transition: opacity .15s; |
||||||
|
transition: opacity .15s; |
||||||
|
width: 30px; |
||||||
|
} |
||||||
|
|
||||||
|
.viewer-list > li:hover { |
||||||
|
opacity: .75; |
||||||
|
} |
||||||
|
|
||||||
|
.viewer-list > li + li { |
||||||
|
margin-left: 1px; |
||||||
|
} |
||||||
|
|
||||||
|
.viewer-list > .viewer-loading { |
||||||
|
position: relative; |
||||||
|
} |
||||||
|
|
||||||
|
.viewer-list > .viewer-loading::after { |
||||||
|
border-width: 2px; |
||||||
|
height: 20px; |
||||||
|
margin-left: -10px; |
||||||
|
margin-top: -10px; |
||||||
|
width: 20px; |
||||||
|
} |
||||||
|
|
||||||
|
.viewer-list > .viewer-active, |
||||||
|
.viewer-list > .viewer-active:hover { |
||||||
|
opacity: 1; |
||||||
|
} |
||||||
|
|
||||||
|
.viewer-player { |
||||||
|
background-color: #000; |
||||||
|
bottom: 0; |
||||||
|
cursor: none; |
||||||
|
display: none; |
||||||
|
left: 0; |
||||||
|
position: absolute; |
||||||
|
right: 0; |
||||||
|
top: 0; |
||||||
|
} |
||||||
|
|
||||||
|
.viewer-player > img { |
||||||
|
left: 0; |
||||||
|
position: absolute; |
||||||
|
top: 0; |
||||||
|
} |
||||||
|
|
||||||
|
.viewer-toolbar > ul { |
||||||
|
display: inline-block; |
||||||
|
margin: 0 auto 5px; |
||||||
|
overflow: hidden; |
||||||
|
padding: 3px 0; |
||||||
|
} |
||||||
|
|
||||||
|
.viewer-toolbar > ul > li { |
||||||
|
background-color: rgba(0, 0, 0, .5); |
||||||
|
border-radius: 50%; |
||||||
|
cursor: pointer; |
||||||
|
float: left; |
||||||
|
height: 24px; |
||||||
|
overflow: hidden; |
||||||
|
-webkit-transition: background-color .15s; |
||||||
|
transition: background-color .15s; |
||||||
|
width: 24px; |
||||||
|
} |
||||||
|
|
||||||
|
.viewer-toolbar > ul > li:hover { |
||||||
|
background-color: rgba(0, 0, 0, .8); |
||||||
|
} |
||||||
|
|
||||||
|
.viewer-toolbar > ul > li::before { |
||||||
|
margin: 2px; |
||||||
|
} |
||||||
|
|
||||||
|
.viewer-toolbar > ul > li + li { |
||||||
|
margin-left: 1px; |
||||||
|
} |
||||||
|
|
||||||
|
.viewer-toolbar > ul > .viewer-small { |
||||||
|
height: 18px; |
||||||
|
margin-bottom: 3px; |
||||||
|
margin-top: 3px; |
||||||
|
width: 18px; |
||||||
|
} |
||||||
|
|
||||||
|
.viewer-toolbar > ul > .viewer-small::before { |
||||||
|
margin: -1px; |
||||||
|
} |
||||||
|
|
||||||
|
.viewer-toolbar > ul > .viewer-large { |
||||||
|
height: 30px; |
||||||
|
margin-bottom: -3px; |
||||||
|
margin-top: -3px; |
||||||
|
width: 30px; |
||||||
|
} |
||||||
|
|
||||||
|
.viewer-toolbar > ul > .viewer-large::before { |
||||||
|
margin: 5px; |
||||||
|
} |
||||||
|
|
||||||
|
.viewer-tooltip { |
||||||
|
background-color: rgba(0, 0, 0, 0.8); |
||||||
|
border-radius: 10px; |
||||||
|
color: #fff; |
||||||
|
display: none; |
||||||
|
font-size: 12px; |
||||||
|
height: 20px; |
||||||
|
left: 50%; |
||||||
|
line-height: 20px; |
||||||
|
margin-left: -25px; |
||||||
|
margin-top: -10px; |
||||||
|
position: absolute; |
||||||
|
text-align: center; |
||||||
|
top: 50%; |
||||||
|
width: 50px; |
||||||
|
} |
||||||
|
|
||||||
|
.viewer-title { |
||||||
|
color: #ccc; |
||||||
|
display: inline-block; |
||||||
|
font-size: 12px; |
||||||
|
line-height: 1; |
||||||
|
margin: 0 5% 5px; |
||||||
|
max-width: 90%; |
||||||
|
opacity: .8; |
||||||
|
overflow: hidden; |
||||||
|
text-overflow: ellipsis; |
||||||
|
-webkit-transition: opacity .15s; |
||||||
|
transition: opacity .15s; |
||||||
|
white-space: nowrap; |
||||||
|
} |
||||||
|
|
||||||
|
.viewer-title:hover { |
||||||
|
opacity: 1; |
||||||
|
} |
||||||
|
|
||||||
|
.viewer-button { |
||||||
|
background-color: rgba(0, 0, 0, .5); |
||||||
|
border-radius: 50%; |
||||||
|
cursor: pointer; |
||||||
|
height: 80px; |
||||||
|
overflow: hidden; |
||||||
|
position: absolute; |
||||||
|
right: -40px; |
||||||
|
top: -40px; |
||||||
|
-webkit-transition: background-color .15s; |
||||||
|
transition: background-color .15s; |
||||||
|
width: 80px; |
||||||
|
} |
||||||
|
|
||||||
|
.viewer-button:focus, |
||||||
|
.viewer-button:hover { |
||||||
|
background-color: rgba(0, 0, 0, .8); |
||||||
|
} |
||||||
|
|
||||||
|
.viewer-button::before { |
||||||
|
bottom: 15px; |
||||||
|
left: 15px; |
||||||
|
position: absolute; |
||||||
|
} |
||||||
|
|
||||||
|
.viewer-fixed { |
||||||
|
position: fixed; |
||||||
|
} |
||||||
|
|
||||||
|
.viewer-open { |
||||||
|
overflow: hidden; |
||||||
|
} |
||||||
|
|
||||||
|
.viewer-show { |
||||||
|
display: block; |
||||||
|
} |
||||||
|
|
||||||
|
.viewer-hide { |
||||||
|
display: none; |
||||||
|
} |
||||||
|
|
||||||
|
.viewer-backdrop { |
||||||
|
background-color: rgba(0, 0, 0, .5); |
||||||
|
} |
||||||
|
|
||||||
|
.viewer-invisible { |
||||||
|
visibility: hidden; |
||||||
|
} |
||||||
|
|
||||||
|
.viewer-move { |
||||||
|
cursor: move; |
||||||
|
cursor: -webkit-grab; |
||||||
|
cursor: grab; |
||||||
|
} |
||||||
|
|
||||||
|
.viewer-fade { |
||||||
|
opacity: 0; |
||||||
|
} |
||||||
|
|
||||||
|
.viewer-in { |
||||||
|
opacity: 1; |
||||||
|
} |
||||||
|
|
||||||
|
.viewer-transition { |
||||||
|
-webkit-transition: all .3s; |
||||||
|
transition: all .3s; |
||||||
|
} |
||||||
|
|
||||||
|
@-webkit-keyframes viewer-spinner { |
||||||
|
0% { |
||||||
|
-webkit-transform: rotate(0deg); |
||||||
|
transform: rotate(0deg); |
||||||
|
} |
||||||
|
|
||||||
|
100% { |
||||||
|
-webkit-transform: rotate(360deg); |
||||||
|
transform: rotate(360deg); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
@keyframes viewer-spinner { |
||||||
|
0% { |
||||||
|
-webkit-transform: rotate(0deg); |
||||||
|
transform: rotate(0deg); |
||||||
|
} |
||||||
|
|
||||||
|
100% { |
||||||
|
-webkit-transform: rotate(360deg); |
||||||
|
transform: rotate(360deg); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
.viewer-loading::after { |
||||||
|
-webkit-animation: viewer-spinner 1s linear infinite; |
||||||
|
animation: viewer-spinner 1s linear infinite; |
||||||
|
border: 4px solid rgba(255, 255, 255, .1); |
||||||
|
border-left-color: rgba(255, 255, 255, .5); |
||||||
|
border-radius: 50%; |
||||||
|
content: ''; |
||||||
|
display: inline-block; |
||||||
|
height: 40px; |
||||||
|
left: 50%; |
||||||
|
margin-left: -20px; |
||||||
|
margin-top: -20px; |
||||||
|
position: absolute; |
||||||
|
top: 50%; |
||||||
|
width: 40px; |
||||||
|
z-index: 1; |
||||||
|
} |
||||||
|
|
||||||
|
@media (max-width: 767px) { |
||||||
|
.viewer-hide-xs-down { |
||||||
|
display: none; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
@media (max-width: 991px) { |
||||||
|
.viewer-hide-sm-down { |
||||||
|
display: none; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
@media (max-width: 1199px) { |
||||||
|
.viewer-hide-md-down { |
||||||
|
display: none; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,75 @@ |
|||||||
|
/*! |
||||||
|
* jQuery Viewer v1.0.0 |
||||||
|
* https://github.com/fengyuanchen/jquery-viewer
|
||||||
|
* |
||||||
|
* Copyright (c) 2018 Chen Fengyuan |
||||||
|
* Released under the MIT license |
||||||
|
* |
||||||
|
* Date: 2018-04-01T05:58:29.617Z |
||||||
|
*/ |
||||||
|
|
||||||
|
(function (global, factory) { |
||||||
|
typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('jquery'), require('viewerjs')) : |
||||||
|
typeof define === 'function' && define.amd ? define(['jquery', 'viewerjs'], factory) : |
||||||
|
(factory(global.jQuery,global.Viewer)); |
||||||
|
}(this, (function ($,Viewer) { 'use strict'; |
||||||
|
|
||||||
|
$ = $ && $.hasOwnProperty('default') ? $['default'] : $; |
||||||
|
Viewer = Viewer && Viewer.hasOwnProperty('default') ? Viewer['default'] : Viewer; |
||||||
|
|
||||||
|
if ($.fn) { |
||||||
|
var AnotherViewer = $.fn.viewer; |
||||||
|
var NAMESPACE = 'viewer'; |
||||||
|
|
||||||
|
$.fn.viewer = function jQueryViewer(option) { |
||||||
|
for (var _len = arguments.length, args = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { |
||||||
|
args[_key - 1] = arguments[_key]; |
||||||
|
} |
||||||
|
|
||||||
|
var result = void 0; |
||||||
|
|
||||||
|
this.each(function (i, element) { |
||||||
|
var $element = $(element); |
||||||
|
var isDestroy = option === 'destroy'; |
||||||
|
var viewer = $element.data(NAMESPACE); |
||||||
|
|
||||||
|
if (!viewer) { |
||||||
|
if (isDestroy) { |
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
var options = $.extend({}, $element.data(), $.isPlainObject(option) && option); |
||||||
|
|
||||||
|
viewer = new Viewer(element, options); |
||||||
|
$element.data(NAMESPACE, viewer); |
||||||
|
} |
||||||
|
|
||||||
|
if (typeof option === 'string') { |
||||||
|
var fn = viewer[option]; |
||||||
|
|
||||||
|
if ($.isFunction(fn)) { |
||||||
|
result = fn.apply(viewer, args); |
||||||
|
|
||||||
|
if (result === viewer) { |
||||||
|
result = undefined; |
||||||
|
} |
||||||
|
|
||||||
|
if (isDestroy) { |
||||||
|
$element.removeData(NAMESPACE); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
}); |
||||||
|
|
||||||
|
return result !== undefined ? result : this; |
||||||
|
}; |
||||||
|
|
||||||
|
$.fn.viewer.Constructor = Viewer; |
||||||
|
$.fn.viewer.setDefaults = Viewer.setDefaults; |
||||||
|
$.fn.viewer.noConflict = function noConflict() { |
||||||
|
$.fn.viewer = AnotherViewer; |
||||||
|
return this; |
||||||
|
}; |
||||||
|
} |
||||||
|
|
||||||
|
}))); |
@ -0,0 +1,201 @@ |
|||||||
|
Apache License |
||||||
|
Version 2.0, January 2004 |
||||||
|
http://www.apache.org/licenses/ |
||||||
|
|
||||||
|
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION |
||||||
|
|
||||||
|
1. Definitions. |
||||||
|
|
||||||
|
"License" shall mean the terms and conditions for use, reproduction, |
||||||
|
and distribution as defined by Sections 1 through 9 of this document. |
||||||
|
|
||||||
|
"Licensor" shall mean the copyright owner or entity authorized by |
||||||
|
the copyright owner that is granting the License. |
||||||
|
|
||||||
|
"Legal Entity" shall mean the union of the acting entity and all |
||||||
|
other entities that control, are controlled by, or are under common |
||||||
|
control with that entity. For the purposes of this definition, |
||||||
|
"control" means (i) the power, direct or indirect, to cause the |
||||||
|
direction or management of such entity, whether by contract or |
||||||
|
otherwise, or (ii) ownership of fifty percent (50%) or more of the |
||||||
|
outstanding shares, or (iii) beneficial ownership of such entity. |
||||||
|
|
||||||
|
"You" (or "Your") shall mean an individual or Legal Entity |
||||||
|
exercising permissions granted by this License. |
||||||
|
|
||||||
|
"Source" form shall mean the preferred form for making modifications, |
||||||
|
including but not limited to software source code, documentation |
||||||
|
source, and configuration files. |
||||||
|
|
||||||
|
"Object" form shall mean any form resulting from mechanical |
||||||
|
transformation or translation of a Source form, including but |
||||||
|
not limited to compiled object code, generated documentation, |
||||||
|
and conversions to other media types. |
||||||
|
|
||||||
|
"Work" shall mean the work of authorship, whether in Source or |
||||||
|
Object form, made available under the License, as indicated by a |
||||||
|
copyright notice that is included in or attached to the work |
||||||
|
(an example is provided in the Appendix below). |
||||||
|
|
||||||
|
"Derivative Works" shall mean any work, whether in Source or Object |
||||||
|
form, that is based on (or derived from) the Work and for which the |
||||||
|
editorial revisions, annotations, elaborations, or other modifications |
||||||
|
represent, as a whole, an original work of authorship. For the purposes |
||||||
|
of this License, Derivative Works shall not include works that remain |
||||||
|
separable from, or merely link (or bind by name) to the interfaces of, |
||||||
|
the Work and Derivative Works thereof. |
||||||
|
|
||||||
|
"Contribution" shall mean any work of authorship, including |
||||||
|
the original version of the Work and any modifications or additions |
||||||
|
to that Work or Derivative Works thereof, that is intentionally |
||||||
|
submitted to Licensor for inclusion in the Work by the copyright owner |
||||||
|
or by an individual or Legal Entity authorized to submit on behalf of |
||||||
|
the copyright owner. For the purposes of this definition, "submitted" |
||||||
|
means any form of electronic, verbal, or written communication sent |
||||||
|
to the Licensor or its representatives, including but not limited to |
||||||
|
communication on electronic mailing lists, source code control systems, |
||||||
|
and issue tracking systems that are managed by, or on behalf of, the |
||||||
|
Licensor for the purpose of discussing and improving the Work, but |
||||||
|
excluding communication that is conspicuously marked or otherwise |
||||||
|
designated in writing by the copyright owner as "Not a Contribution." |
||||||
|
|
||||||
|
"Contributor" shall mean Licensor and any individual or Legal Entity |
||||||
|
on behalf of whom a Contribution has been received by Licensor and |
||||||
|
subsequently incorporated within the Work. |
||||||
|
|
||||||
|
2. Grant of Copyright License. Subject to the terms and conditions of |
||||||
|
this License, each Contributor hereby grants to You a perpetual, |
||||||
|
worldwide, non-exclusive, no-charge, royalty-free, irrevocable |
||||||
|
copyright license to reproduce, prepare Derivative Works of, |
||||||
|
publicly display, publicly perform, sublicense, and distribute the |
||||||
|
Work and such Derivative Works in Source or Object form. |
||||||
|
|
||||||
|
3. Grant of Patent License. Subject to the terms and conditions of |
||||||
|
this License, each Contributor hereby grants to You a perpetual, |
||||||
|
worldwide, non-exclusive, no-charge, royalty-free, irrevocable |
||||||
|
(except as stated in this section) patent license to make, have made, |
||||||
|
use, offer to sell, sell, import, and otherwise transfer the Work, |
||||||
|
where such license applies only to those patent claims licensable |
||||||
|
by such Contributor that are necessarily infringed by their |
||||||
|
Contribution(s) alone or by combination of their Contribution(s) |
||||||
|
with the Work to which such Contribution(s) was submitted. If You |
||||||
|
institute patent litigation against any entity (including a |
||||||
|
cross-claim or counterclaim in a lawsuit) alleging that the Work |
||||||
|
or a Contribution incorporated within the Work constitutes direct |
||||||
|
or contributory patent infringement, then any patent licenses |
||||||
|
granted to You under this License for that Work shall terminate |
||||||
|
as of the date such litigation is filed. |
||||||
|
|
||||||
|
4. Redistribution. You may reproduce and distribute copies of the |
||||||
|
Work or Derivative Works thereof in any medium, with or without |
||||||
|
modifications, and in Source or Object form, provided that You |
||||||
|
meet the following conditions: |
||||||
|
|
||||||
|
(a) You must give any other recipients of the Work or |
||||||
|
Derivative Works a copy of this License; and |
||||||
|
|
||||||
|
(b) You must cause any modified files to carry prominent notices |
||||||
|
stating that You changed the files; and |
||||||
|
|
||||||
|
(c) You must retain, in the Source form of any Derivative Works |
||||||
|
that You distribute, all copyright, patent, trademark, and |
||||||
|
attribution notices from the Source form of the Work, |
||||||
|
excluding those notices that do not pertain to any part of |
||||||
|
the Derivative Works; and |
||||||
|
|
||||||
|
(d) If the Work includes a "NOTICE" text file as part of its |
||||||
|
distribution, then any Derivative Works that You distribute must |
||||||
|
include a readable copy of the attribution notices contained |
||||||
|
within such NOTICE file, excluding those notices that do not |
||||||
|
pertain to any part of the Derivative Works, in at least one |
||||||
|
of the following places: within a NOTICE text file distributed |
||||||
|
as part of the Derivative Works; within the Source form or |
||||||
|
documentation, if provided along with the Derivative Works; or, |
||||||
|
within a display generated by the Derivative Works, if and |
||||||
|
wherever such third-party notices normally appear. The contents |
||||||
|
of the NOTICE file are for informational purposes only and |
||||||
|
do not modify the License. You may add Your own attribution |
||||||
|
notices within Derivative Works that You distribute, alongside |
||||||
|
or as an addendum to the NOTICE text from the Work, provided |
||||||
|
that such additional attribution notices cannot be construed |
||||||
|
as modifying the License. |
||||||
|
|
||||||
|
You may add Your own copyright statement to Your modifications and |
||||||
|
may provide additional or different license terms and conditions |
||||||
|
for use, reproduction, or distribution of Your modifications, or |
||||||
|
for any such Derivative Works as a whole, provided Your use, |
||||||
|
reproduction, and distribution of the Work otherwise complies with |
||||||
|
the conditions stated in this License. |
||||||
|
|
||||||
|
5. Submission of Contributions. Unless You explicitly state otherwise, |
||||||
|
any Contribution intentionally submitted for inclusion in the Work |
||||||
|
by You to the Licensor shall be under the terms and conditions of |
||||||
|
this License, without any additional terms or conditions. |
||||||
|
Notwithstanding the above, nothing herein shall supersede or modify |
||||||
|
the terms of any separate license agreement you may have executed |
||||||
|
with Licensor regarding such Contributions. |
||||||
|
|
||||||
|
6. Trademarks. This License does not grant permission to use the trade |
||||||
|
names, trademarks, service marks, or product names of the Licensor, |
||||||
|
except as required for reasonable and customary use in describing the |
||||||
|
origin of the Work and reproducing the content of the NOTICE file. |
||||||
|
|
||||||
|
7. Disclaimer of Warranty. Unless required by applicable law or |
||||||
|
agreed to in writing, Licensor provides the Work (and each |
||||||
|
Contributor provides its Contributions) on an "AS IS" BASIS, |
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or |
||||||
|
implied, including, without limitation, any warranties or conditions |
||||||
|
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A |
||||||
|
PARTICULAR PURPOSE. You are solely responsible for determining the |
||||||
|
appropriateness of using or redistributing the Work and assume any |
||||||
|
risks associated with Your exercise of permissions under this License. |
||||||
|
|
||||||
|
8. Limitation of Liability. In no event and under no legal theory, |
||||||
|
whether in tort (including negligence), contract, or otherwise, |
||||||
|
unless required by applicable law (such as deliberate and grossly |
||||||
|
negligent acts) or agreed to in writing, shall any Contributor be |
||||||
|
liable to You for damages, including any direct, indirect, special, |
||||||
|
incidental, or consequential damages of any character arising as a |
||||||
|
result of this License or out of the use or inability to use the |
||||||
|
Work (including but not limited to damages for loss of goodwill, |
||||||
|
work stoppage, computer failure or malfunction, or any and all |
||||||
|
other commercial damages or losses), even if such Contributor |
||||||
|
has been advised of the possibility of such damages. |
||||||
|
|
||||||
|
9. Accepting Warranty or Additional Liability. While redistributing |
||||||
|
the Work or Derivative Works thereof, You may choose to offer, |
||||||
|
and charge a fee for, acceptance of support, warranty, indemnity, |
||||||
|
or other liability obligations and/or rights consistent with this |
||||||
|
License. However, in accepting such obligations, You may act only |
||||||
|
on Your own behalf and on Your sole responsibility, not on behalf |
||||||
|
of any other Contributor, and only if You agree to indemnify, |
||||||
|
defend, and hold each Contributor harmless for any liability |
||||||
|
incurred by, or claims asserted against, such Contributor by reason |
||||||
|
of your accepting any such warranty or additional liability. |
||||||
|
|
||||||
|
END OF TERMS AND CONDITIONS |
||||||
|
|
||||||
|
APPENDIX: How to apply the Apache License to your work. |
||||||
|
|
||||||
|
To apply the Apache License to your work, attach the following |
||||||
|
boilerplate notice, with the fields enclosed by brackets "[]" |
||||||
|
replaced with your own identifying information. (Don't include |
||||||
|
the brackets!) The text should be enclosed in the appropriate |
||||||
|
comment syntax for the file format. We also recommend that a |
||||||
|
file or class name and description of purpose be included on the |
||||||
|
same "printed page" as the copyright notice for easier |
||||||
|
identification within third-party archives. |
||||||
|
|
||||||
|
Copyright [yyyy] [name of copyright owner] |
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License"); |
||||||
|
you may not use this file except in compliance with the License. |
||||||
|
You may obtain a copy of the License at |
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0 |
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software |
||||||
|
distributed under the License is distributed on an "AS IS" BASIS, |
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||||
|
See the License for the specific language governing permissions and |
||||||
|
limitations under the License. |
@ -0,0 +1,393 @@ |
|||||||
|
Attribution 4.0 International |
||||||
|
|
||||||
|
======================================================================= |
||||||
|
|
||||||
|
Creative Commons Corporation ("Creative Commons") is not a law firm and |
||||||
|
does not provide legal services or legal advice. Distribution of |
||||||
|
Creative Commons public licenses does not create a lawyer-client or |
||||||
|
other relationship. Creative Commons makes its licenses and related |
||||||
|
information available on an "as-is" basis. Creative Commons gives no |
||||||
|
warranties regarding its licenses, any material licensed under their |
||||||
|
terms and conditions, or any related information. Creative Commons |
||||||
|
disclaims all liability for damages resulting from their use to the |
||||||
|
fullest extent possible. |
||||||
|
|
||||||
|
Using Creative Commons Public Licenses |
||||||
|
|
||||||
|
Creative Commons public licenses provide a standard set of terms and |
||||||
|
conditions that creators and other rights holders may use to share |
||||||
|
original works of authorship and other material subject to copyright |
||||||
|
and certain other rights specified in the public license below. The |
||||||
|
following considerations are for informational purposes only, are not |
||||||
|
exhaustive, and do not form part of our licenses. |
||||||
|
|
||||||
|
Considerations for licensors: Our public licenses are |
||||||
|
intended for use by those authorized to give the public |
||||||
|
permission to use material in ways otherwise restricted by |
||||||
|
copyright and certain other rights. Our licenses are |
||||||
|
irrevocable. Licensors should read and understand the terms |
||||||
|
and conditions of the license they choose before applying it. |
||||||
|
Licensors should also secure all rights necessary before |
||||||
|
applying our licenses so that the public can reuse the |
||||||
|
material as expected. Licensors should clearly mark any |
||||||
|
material not subject to the license. This includes other CC- |
||||||
|
licensed material, or material used under an exception or |
||||||
|
limitation to copyright. More considerations for licensors: |
||||||
|
wiki.creativecommons.org/Considerations_for_licensors |
||||||
|
|
||||||
|
Considerations for the public: By using one of our public |
||||||
|
licenses, a licensor grants the public permission to use the |
||||||
|
licensed material under specified terms and conditions. If |
||||||
|
the licensor's permission is not necessary for any reason--for |
||||||
|
example, because of any applicable exception or limitation to |
||||||
|
copyright--then that use is not regulated by the license. Our |
||||||
|
licenses grant only permissions under copyright and certain |
||||||
|
other rights that a licensor has authority to grant. Use of |
||||||
|
the licensed material may still be restricted for other |
||||||
|
reasons, including because others have copyright or other |
||||||
|
rights in the material. A licensor may make special requests, |
||||||
|
such as asking that all changes be marked or described. |
||||||
|
Although not required by our licenses, you are encouraged to |
||||||
|
respect those requests where reasonable. More_considerations |
||||||
|
for the public: |
||||||
|
wiki.creativecommons.org/Considerations_for_licensees |
||||||
|
|
||||||
|
======================================================================= |
||||||
|
|
||||||
|
Creative Commons Attribution 4.0 International Public License |
||||||
|
|
||||||
|
By exercising the Licensed Rights (defined below), You accept and agree |
||||||
|
to be bound by the terms and conditions of this Creative Commons |
||||||
|
Attribution 4.0 International Public License ("Public License"). To the |
||||||
|
extent this Public License may be interpreted as a contract, You are |
||||||
|
granted the Licensed Rights in consideration of Your acceptance of |
||||||
|
these terms and conditions, and the Licensor grants You such rights in |
||||||
|
consideration of benefits the Licensor receives from making the |
||||||
|
Licensed Material available under these terms and conditions. |
||||||
|
|
||||||
|
|
||||||
|
Section 1 -- Definitions. |
||||||
|
|
||||||
|
a. Adapted Material means material subject to Copyright and Similar |
||||||
|
Rights that is derived from or based upon the Licensed Material |
||||||
|
and in which the Licensed Material is translated, altered, |
||||||
|
arranged, transformed, or otherwise modified in a manner requiring |
||||||
|
permission under the Copyright and Similar Rights held by the |
||||||
|
Licensor. For purposes of this Public License, where the Licensed |
||||||
|
Material is a musical work, performance, or sound recording, |
||||||
|
Adapted Material is always produced where the Licensed Material is |
||||||
|
synched in timed relation with a moving image. |
||||||
|
|
||||||
|
b. Adapter's License means the license You apply to Your Copyright |
||||||
|
and Similar Rights in Your contributions to Adapted Material in |
||||||
|
accordance with the terms and conditions of this Public License. |
||||||
|
|
||||||
|
c. Copyright and Similar Rights means copyright and/or similar rights |
||||||
|
closely related to copyright including, without limitation, |
||||||
|
performance, broadcast, sound recording, and Sui Generis Database |
||||||
|
Rights, without regard to how the rights are labeled or |
||||||
|
categorized. For purposes of this Public License, the rights |
||||||
|
specified in Section 2(b)(1)-(2) are not Copyright and Similar |
||||||
|
Rights. |
||||||
|
|
||||||
|
d. Effective Technological Measures means those measures that, in the |
||||||
|
absence of proper authority, may not be circumvented under laws |
||||||
|
fulfilling obligations under Article 11 of the WIPO Copyright |
||||||
|
Treaty adopted on December 20, 1996, and/or similar international |
||||||
|
agreements. |
||||||
|
|
||||||
|
e. Exceptions and Limitations means fair use, fair dealing, and/or |
||||||
|
any other exception or limitation to Copyright and Similar Rights |
||||||
|
that applies to Your use of the Licensed Material. |
||||||
|
|
||||||
|
f. Licensed Material means the artistic or literary work, database, |
||||||
|
or other material to which the Licensor applied this Public |
||||||
|
License. |
||||||
|
|
||||||
|
g. Licensed Rights means the rights granted to You subject to the |
||||||
|
terms and conditions of this Public License, which are limited to |
||||||
|
all Copyright and Similar Rights that apply to Your use of the |
||||||
|
Licensed Material and that the Licensor has authority to license. |
||||||
|
|
||||||
|
h. Licensor means the individual(s) or entity(ies) granting rights |
||||||
|
under this Public License. |
||||||
|
|
||||||
|
i. Share means to provide material to the public by any means or |
||||||
|
process that requires permission under the Licensed Rights, such |
||||||
|
as reproduction, public display, public performance, distribution, |
||||||
|
dissemination, communication, or importation, and to make material |
||||||
|
available to the public including in ways that members of the |
||||||
|
public may access the material from a place and at a time |
||||||
|
individually chosen by them. |
||||||
|
|
||||||
|
j. Sui Generis Database Rights means rights other than copyright |
||||||
|
resulting from Directive 96/9/EC of the European Parliament and of |
||||||
|
the Council of 11 March 1996 on the legal protection of databases, |
||||||
|
as amended and/or succeeded, as well as other essentially |
||||||
|
equivalent rights anywhere in the world. |
||||||
|
|
||||||
|
k. You means the individual or entity exercising the Licensed Rights |
||||||
|
under this Public License. Your has a corresponding meaning. |
||||||
|
|
||||||
|
|
||||||
|
Section 2 -- Scope. |
||||||
|
|
||||||
|
a. License grant. |
||||||
|
|
||||||
|
1. Subject to the terms and conditions of this Public License, |
||||||
|
the Licensor hereby grants You a worldwide, royalty-free, |
||||||
|
non-sublicensable, non-exclusive, irrevocable license to |
||||||
|
exercise the Licensed Rights in the Licensed Material to: |
||||||
|
|
||||||
|
a. reproduce and Share the Licensed Material, in whole or |
||||||
|
in part; and |
||||||
|
|
||||||
|
b. produce, reproduce, and Share Adapted Material. |
||||||
|
|
||||||
|
2. Exceptions and Limitations. For the avoidance of doubt, where |
||||||
|
Exceptions and Limitations apply to Your use, this Public |
||||||
|
License does not apply, and You do not need to comply with |
||||||
|
its terms and conditions. |
||||||
|
|
||||||
|
3. Term. The term of this Public License is specified in Section |
||||||
|
6(a). |
||||||
|
|
||||||
|
4. Media and formats; technical modifications allowed. The |
||||||
|
Licensor authorizes You to exercise the Licensed Rights in |
||||||
|
all media and formats whether now known or hereafter created, |
||||||
|
and to make technical modifications necessary to do so. The |
||||||
|
Licensor waives and/or agrees not to assert any right or |
||||||
|
authority to forbid You from making technical modifications |
||||||
|
necessary to exercise the Licensed Rights, including |
||||||
|
technical modifications necessary to circumvent Effective |
||||||
|
Technological Measures. For purposes of this Public License, |
||||||
|
simply making modifications authorized by this Section 2(a) |
||||||
|
(4) never produces Adapted Material. |
||||||
|
|
||||||
|
5. Downstream recipients. |
||||||
|
|
||||||
|
a. Offer from the Licensor -- Licensed Material. Every |
||||||
|
recipient of the Licensed Material automatically |
||||||
|
receives an offer from the Licensor to exercise the |
||||||
|
Licensed Rights under the terms and conditions of this |
||||||
|
Public License. |
||||||
|
|
||||||
|
b. No downstream restrictions. You may not offer or impose |
||||||
|
any additional or different terms or conditions on, or |
||||||
|
apply any Effective Technological Measures to, the |
||||||
|
Licensed Material if doing so restricts exercise of the |
||||||
|
Licensed Rights by any recipient of the Licensed |
||||||
|
Material. |
||||||
|
|
||||||
|
6. No endorsement. Nothing in this Public License constitutes or |
||||||
|
may be construed as permission to assert or imply that You |
||||||
|
are, or that Your use of the Licensed Material is, connected |
||||||
|
with, or sponsored, endorsed, or granted official status by, |
||||||
|
the Licensor or others designated to receive attribution as |
||||||
|
provided in Section 3(a)(1)(A)(i). |
||||||
|
|
||||||
|
b. Other rights. |
||||||
|
|
||||||
|
1. Moral rights, such as the right of integrity, are not |
||||||
|
licensed under this Public License, nor are publicity, |
||||||
|
privacy, and/or other similar personality rights; however, to |
||||||
|
the extent possible, the Licensor waives and/or agrees not to |
||||||
|
assert any such rights held by the Licensor to the limited |
||||||
|
extent necessary to allow You to exercise the Licensed |
||||||
|
Rights, but not otherwise. |
||||||
|
|
||||||
|
2. Patent and trademark rights are not licensed under this |
||||||
|
Public License. |
||||||
|
|
||||||
|
3. To the extent possible, the Licensor waives any right to |
||||||
|
collect royalties from You for the exercise of the Licensed |
||||||
|
Rights, whether directly or through a collecting society |
||||||
|
under any voluntary or waivable statutory or compulsory |
||||||
|
licensing scheme. In all other cases the Licensor expressly |
||||||
|
reserves any right to collect such royalties. |
||||||
|
|
||||||
|
|
||||||
|
Section 3 -- License Conditions. |
||||||
|
|
||||||
|
Your exercise of the Licensed Rights is expressly made subject to the |
||||||
|
following conditions. |
||||||
|
|
||||||
|
a. Attribution. |
||||||
|
|
||||||
|
1. If You Share the Licensed Material (including in modified |
||||||
|
form), You must: |
||||||
|
|
||||||
|
a. retain the following if it is supplied by the Licensor |
||||||
|
with the Licensed Material: |
||||||
|
|
||||||
|
i. identification of the creator(s) of the Licensed |
||||||
|
Material and any others designated to receive |
||||||
|
attribution, in any reasonable manner requested by |
||||||
|
the Licensor (including by pseudonym if |
||||||
|
designated); |
||||||
|
|
||||||
|
ii. a copyright notice; |
||||||
|
|
||||||
|
iii. a notice that refers to this Public License; |
||||||
|
|
||||||
|
iv. a notice that refers to the disclaimer of |
||||||
|
warranties; |
||||||
|
|
||||||
|
v. a URI or hyperlink to the Licensed Material to the |
||||||
|
extent reasonably practicable; |
||||||
|
|
||||||
|
b. indicate if You modified the Licensed Material and |
||||||
|
retain an indication of any previous modifications; and |
||||||
|
|
||||||
|
c. indicate the Licensed Material is licensed under this |
||||||
|
Public License, and include the text of, or the URI or |
||||||
|
hyperlink to, this Public License. |
||||||
|
|
||||||
|
2. You may satisfy the conditions in Section 3(a)(1) in any |
||||||
|
reasonable manner based on the medium, means, and context in |
||||||
|
which You Share the Licensed Material. For example, it may be |
||||||
|
reasonable to satisfy the conditions by providing a URI or |
||||||
|
hyperlink to a resource that includes the required |
||||||
|
information. |
||||||
|
|
||||||
|
3. If requested by the Licensor, You must remove any of the |
||||||
|
information required by Section 3(a)(1)(A) to the extent |
||||||
|
reasonably practicable. |
||||||
|
|
||||||
|
4. If You Share Adapted Material You produce, the Adapter's |
||||||
|
License You apply must not prevent recipients of the Adapted |
||||||
|
Material from complying with this Public License. |
||||||
|
|
||||||
|
|
||||||
|
Section 4 -- Sui Generis Database Rights. |
||||||
|
|
||||||
|
Where the Licensed Rights include Sui Generis Database Rights that |
||||||
|
apply to Your use of the Licensed Material: |
||||||
|
|
||||||
|
a. for the avoidance of doubt, Section 2(a)(1) grants You the right |
||||||
|
to extract, reuse, reproduce, and Share all or a substantial |
||||||
|
portion of the contents of the database; |
||||||
|
|
||||||
|
b. if You include all or a substantial portion of the database |
||||||
|
contents in a database in which You have Sui Generis Database |
||||||
|
Rights, then the database in which You have Sui Generis Database |
||||||
|
Rights (but not its individual contents) is Adapted Material; and |
||||||
|
|
||||||
|
c. You must comply with the conditions in Section 3(a) if You Share |
||||||
|
all or a substantial portion of the contents of the database. |
||||||
|
|
||||||
|
For the avoidance of doubt, this Section 4 supplements and does not |
||||||
|
replace Your obligations under this Public License where the Licensed |
||||||
|
Rights include other Copyright and Similar Rights. |
||||||
|
|
||||||
|
|
||||||
|
Section 5 -- Disclaimer of Warranties and Limitation of Liability. |
||||||
|
|
||||||
|
a. UNLESS OTHERWISE SEPARATELY UNDERTAKEN BY THE LICENSOR, TO THE |
||||||
|
EXTENT POSSIBLE, THE LICENSOR OFFERS THE LICENSED MATERIAL AS-IS |
||||||
|
AND AS-AVAILABLE, AND MAKES NO REPRESENTATIONS OR WARRANTIES OF |
||||||
|
ANY KIND CONCERNING THE LICENSED MATERIAL, WHETHER EXPRESS, |
||||||
|
IMPLIED, STATUTORY, OR OTHER. THIS INCLUDES, WITHOUT LIMITATION, |
||||||
|
WARRANTIES OF TITLE, MERCHANTABILITY, FITNESS FOR A PARTICULAR |
||||||
|
PURPOSE, NON-INFRINGEMENT, ABSENCE OF LATENT OR OTHER DEFECTS, |
||||||
|
ACCURACY, OR THE PRESENCE OR ABSENCE OF ERRORS, WHETHER OR NOT |
||||||
|
KNOWN OR DISCOVERABLE. WHERE DISCLAIMERS OF WARRANTIES ARE NOT |
||||||
|
ALLOWED IN FULL OR IN PART, THIS DISCLAIMER MAY NOT APPLY TO YOU. |
||||||
|
|
||||||
|
b. TO THE EXTENT POSSIBLE, IN NO EVENT WILL THE LICENSOR BE LIABLE |
||||||
|
TO YOU ON ANY LEGAL THEORY (INCLUDING, WITHOUT LIMITATION, |
||||||
|
NEGLIGENCE) OR OTHERWISE FOR ANY DIRECT, SPECIAL, INDIRECT, |
||||||
|
INCIDENTAL, CONSEQUENTIAL, PUNITIVE, EXEMPLARY, OR OTHER LOSSES, |
||||||
|
COSTS, EXPENSES, OR DAMAGES ARISING OUT OF THIS PUBLIC LICENSE OR |
||||||
|
USE OF THE LICENSED MATERIAL, EVEN IF THE LICENSOR HAS BEEN |
||||||
|
ADVISED OF THE POSSIBILITY OF SUCH LOSSES, COSTS, EXPENSES, OR |
||||||
|
DAMAGES. WHERE A LIMITATION OF LIABILITY IS NOT ALLOWED IN FULL OR |
||||||
|
IN PART, THIS LIMITATION MAY NOT APPLY TO YOU. |
||||||
|
|
||||||
|
c. The disclaimer of warranties and limitation of liability provided |
||||||
|
above shall be interpreted in a manner that, to the extent |
||||||
|
possible, most closely approximates an absolute disclaimer and |
||||||
|
waiver of all liability. |
||||||
|
|
||||||
|
|
||||||
|
Section 6 -- Term and Termination. |
||||||
|
|
||||||
|
a. This Public License applies for the term of the Copyright and |
||||||
|
Similar Rights licensed here. However, if You fail to comply with |
||||||
|
this Public License, then Your rights under this Public License |
||||||
|
terminate automatically. |
||||||
|
|
||||||
|
b. Where Your right to use the Licensed Material has terminated under |
||||||
|
Section 6(a), it reinstates: |
||||||
|
|
||||||
|
1. automatically as of the date the violation is cured, provided |
||||||
|
it is cured within 30 days of Your discovery of the |
||||||
|
violation; or |
||||||
|
|
||||||
|
2. upon express reinstatement by the Licensor. |
||||||
|
|
||||||
|
For the avoidance of doubt, this Section 6(b) does not affect any |
||||||
|
right the Licensor may have to seek remedies for Your violations |
||||||
|
of this Public License. |
||||||
|
|
||||||
|
c. For the avoidance of doubt, the Licensor may also offer the |
||||||
|
Licensed Material under separate terms or conditions or stop |
||||||
|
distributing the Licensed Material at any time; however, doing so |
||||||
|
will not terminate this Public License. |
||||||
|
|
||||||
|
d. Sections 1, 5, 6, 7, and 8 survive termination of this Public |
||||||
|
License. |
||||||
|
|
||||||
|
|
||||||
|
Section 7 -- Other Terms and Conditions. |
||||||
|
|
||||||
|
a. The Licensor shall not be bound by any additional or different |
||||||
|
terms or conditions communicated by You unless expressly agreed. |
||||||
|
|
||||||
|
b. Any arrangements, understandings, or agreements regarding the |
||||||
|
Licensed Material not stated herein are separate from and |
||||||
|
independent of the terms and conditions of this Public License. |
||||||
|
|
||||||
|
|
||||||
|
Section 8 -- Interpretation. |
||||||
|
|
||||||
|
a. For the avoidance of doubt, this Public License does not, and |
||||||
|
shall not be interpreted to, reduce, limit, restrict, or impose |
||||||
|
conditions on any use of the Licensed Material that could lawfully |
||||||
|
be made without permission under this Public License. |
||||||
|
|
||||||
|
b. To the extent possible, if any provision of this Public License is |
||||||
|
deemed unenforceable, it shall be automatically reformed to the |
||||||
|
minimum extent necessary to make it enforceable. If the provision |
||||||
|
cannot be reformed, it shall be severed from this Public License |
||||||
|
without affecting the enforceability of the remaining terms and |
||||||
|
conditions. |
||||||
|
|
||||||
|
c. No term or condition of this Public License will be waived and no |
||||||
|
failure to comply consented to unless expressly agreed to by the |
||||||
|
Licensor. |
||||||
|
|
||||||
|
d. Nothing in this Public License constitutes or may be interpreted |
||||||
|
as a limitation upon, or waiver of, any privileges and immunities |
||||||
|
that apply to the Licensor or You, including from the legal |
||||||
|
processes of any jurisdiction or authority. |
||||||
|
|
||||||
|
|
||||||
|
======================================================================= |
||||||
|
|
||||||
|
Creative Commons is not a party to its public licenses. |
||||||
|
Notwithstanding, Creative Commons may elect to apply one of its public |
||||||
|
licenses to material it publishes and in those instances will be |
||||||
|
considered the "Licensor." Except for the limited purpose of indicating |
||||||
|
that material is shared under a Creative Commons public license or as |
||||||
|
otherwise permitted by the Creative Commons policies published at |
||||||
|
creativecommons.org/policies, Creative Commons does not authorize the |
||||||
|
use of the trademark "Creative Commons" or any other trademark or logo |
||||||
|
of Creative Commons without its prior written consent including, |
||||||
|
without limitation, in connection with any unauthorized modifications |
||||||
|
to any of its public licenses or any other arrangements, |
||||||
|
understandings, or agreements concerning use of licensed material. For |
||||||
|
the avoidance of doubt, this paragraph does not form part of the public |
||||||
|
licenses. |
||||||
|
|
||||||
|
Creative Commons may be contacted at creativecommons.org. |
@ -0,0 +1,39 @@ |
|||||||
|
package test |
||||||
|
|
||||||
|
import ( |
||||||
|
"net/http" |
||||||
|
"net/http/httptest" |
||||||
|
"testing" |
||||||
|
"runtime" |
||||||
|
"path/filepath" |
||||||
|
_ "auxpi/routers" |
||||||
|
|
||||||
|
"github.com/astaxie/beego" |
||||||
|
. "github.com/smartystreets/goconvey/convey" |
||||||
|
) |
||||||
|
|
||||||
|
func init() { |
||||||
|
_, file, _, _ := runtime.Caller(1) |
||||||
|
apppath, _ := filepath.Abs(filepath.Dir(filepath.Join(file, ".." + string(filepath.Separator)))) |
||||||
|
beego.TestBeegoInit(apppath) |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
// TestBeego is a sample to run an endpoint test
|
||||||
|
func TestBeego(t *testing.T) { |
||||||
|
r, _ := http.NewRequest("GET", "/", nil) |
||||||
|
w := httptest.NewRecorder() |
||||||
|
beego.BeeApp.Handlers.ServeHTTP(w, r) |
||||||
|
|
||||||
|
beego.Trace("testing", "TestBeego", "Code[%d]\n%s", w.Code, w.Body.String()) |
||||||
|
|
||||||
|
Convey("Subject: Test Station Endpoint\n", t, func() { |
||||||
|
Convey("Status Code Should Be 200", func() { |
||||||
|
So(w.Code, ShouldEqual, 200) |
||||||
|
}) |
||||||
|
Convey("The Result Should Not Be Empty", func() { |
||||||
|
So(w.Body.Len(), ShouldBeGreaterThan, 0) |
||||||
|
}) |
||||||
|
}) |
||||||
|
} |
||||||
|
|
@ -0,0 +1,14 @@ |
|||||||
|
<div class="upload-container"> |
||||||
|
<div class="title"> |
||||||
|
<h1>{{.title}}</h1> |
||||||
|
<br> |
||||||
|
<p>在法律允许范围内可以随意使用本图床</p> |
||||||
|
<br> |
||||||
|
<h1>严禁上传及分享如下类型的图片:</h1> |
||||||
|
<ul> |
||||||
|
<li>含有色情、暴力、宣扬恐怖主义的图片</li> |
||||||
|
<li>侵犯版权、未经授权的图片</li> |
||||||
|
<li>其他违反中华人民共和国法律的图片</li> |
||||||
|
</ul> |
||||||
|
</div> |
||||||
|
</div> |
@ -0,0 +1,45 @@ |
|||||||
|
<!DOCTYPE html> |
||||||
|
<html lang="en"> |
||||||
|
<head> |
||||||
|
<meta charset="UTF-8"> |
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0,maximum-scale=1.0, user-scalable=no"/> |
||||||
|
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"/> |
||||||
|
<meta name="renderer" content="webkit"> |
||||||
|
<meta http-equiv="Cache-Control" content="no-siteapp"/> |
||||||
|
<meta name="keywords" content="{{.siteName}}"/> |
||||||
|
<meta name="description" content="{{.siteName}} sina Pictures & SouGou Pirtures & pictures upload"/> |
||||||
|
<title>{{ .siteName}}</title> |
||||||
|
|
||||||
|
<link href="/static/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet"> |
||||||
|
<link href="/static/bootstrap-fileinput/4.5.1/css/fileinput.min.css" rel="stylesheet"> |
||||||
|
|
||||||
|
<link rel="shortcut icon" href="/favicon.ico"> |
||||||
|
<link rel="stylesheet" href="/static/app/iconfont/iconfont.css"> |
||||||
|
<link rel="stylesheet" href="/static/app/newicon/iconfont.css"> |
||||||
|
<link rel="stylesheet" href="/static/mdui/0.4.1/css/mdui.min.css"> |
||||||
|
<link rel="stylesheet" href="/static/app/css/app.css"> |
||||||
|
<!--[if IE]> |
||||||
|
<script>window.location.href = '/compatibility.html';</script> |
||||||
|
<![endif]--> |
||||||
|
</head> |
||||||
|
<body class="mdui-theme-accent-indigo mdui-appbar-with-toolbar "> |
||||||
|
{{/*header*/}} |
||||||
|
{{ .Header}} |
||||||
|
{{/*left*/}} |
||||||
|
{{ .Left}} |
||||||
|
{{/*content*/}} |
||||||
|
<div class="mdui-container"> |
||||||
|
<main> |
||||||
|
{{.LayoutContent}} |
||||||
|
</main> |
||||||
|
</div> |
||||||
|
{{/*footer*/}} |
||||||
|
{{ .Footer}} |
||||||
|
|
||||||
|
</body> |
||||||
|
<script src="/static/jquery/3.3.1/jquery.min.js"></script> |
||||||
|
<script src="/static/mdui/0.4.1/js/mdui.min.js"></script> |
||||||
|
<script src="/static/app/js/app.js"></script> |
||||||
|
|
||||||
|
{{ .Scripts}} |
||||||
|
</html> |
@ -0,0 +1,17 @@ |
|||||||
|
<div class="mdui-fab-wrapper"> |
||||||
|
<button id="to-top" class="mdui-fab mdui-ripple mdui-fab-hide mdui-color-theme-accent"> |
||||||
|
<i class="mdui-icon material-icons"></i> |
||||||
|
</button> |
||||||
|
</div> |
||||||
|
<div id="loading-container"> |
||||||
|
<div class="mask"></div> |
||||||
|
<div class="loading"> |
||||||
|
<div class="mdui-spinner mdui-spinner-colorful"></div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
<footer> |
||||||
|
<div class="mdui-container"> |
||||||
|
Copyright © 2018 <a href="{{ .siteUrl}}">{{ .siteName}}</a>. All rights reserved. |
||||||
|
{{.siteFooterText}} |
||||||
|
</div> |
||||||
|
</footer> |
@ -0,0 +1,8 @@ |
|||||||
|
<div class="mdui-appbar mdui-appbar-fixed"> |
||||||
|
<div class="mdui-toolbar mdui-color-black"> |
||||||
|
<span mdui-drawer="{target: '#menu'}" class="mdui-btn mdui-btn-icon open-menu"><i |
||||||
|
class="mdui-icon material-icons"></i></span> |
||||||
|
<a href="/" class="mdui-typo-headline">{{ .siteName}}</a> |
||||||
|
<div class="mdui-toolbar-spacer"></div> |
||||||
|
</div> |
||||||
|
</div> |
@ -0,0 +1,20 @@ |
|||||||
|
<div id="menu" class="mdui-drawer mdui-drawer-close"> |
||||||
|
<div class="mdui-list" mdui-collapse="{accordion: true}"> |
||||||
|
<a class="mdui-list-item mdui-ripple" href="{{urlfor "PagesController.IndexShow"}}"> |
||||||
|
<i class="mdui-list-item-icon mdui-icon material-icons iconfont icon-sougou mdui-text-color-orange"></i> |
||||||
|
<div class="mdui-list-item-content">搜狗图床</div> |
||||||
|
</a> |
||||||
|
<a class="mdui-list-item mdui-ripple " href="{{urlfor "PagesController.SinaShow"}}"> |
||||||
|
<i class="mdui-list-item-icon mdui-icon material-icons iconfont icon-xinlang mdui-text-color-red"></i> |
||||||
|
<div class="mdui-list-item-content">新浪图床</div> |
||||||
|
</a> |
||||||
|
<a class="mdui-list-item mdui-ripple " href="{{urlfor "PagesController.AboutShow"}}"> |
||||||
|
<i class="mdui-list-item-icon mdui-icon material-icons iconfont icon-guanyu3 mdui-text-color-teal"></i> |
||||||
|
<div class="mdui-list-item-content">说明</div> |
||||||
|
</a> |
||||||
|
<a class="mdui-list-item mdui-ripple " href="{{urlfor "PagesController.AboutShow"}}"> |
||||||
|
<i class="mdui-list-item-icon mdui-icon material-icons iconfont icon-github mdui-text-color-black"></i> |
||||||
|
<div class="mdui-list-item-content">项目地址</div> |
||||||
|
</a> |
||||||
|
</div> |
||||||
|
</div> |
@ -0,0 +1,10 @@ |
|||||||
|
<div class="upload-container"> |
||||||
|
<div class="title"> |
||||||
|
<h1>Image Upload <i |
||||||
|
class="mdui-list-item-icon mdui-icon material-icons iconfont icon-{{.iconStyle}} mdui-text-color-{{ .iconColor}}"></i> |
||||||
|
</h1> |
||||||
|
</div> |
||||||
|
<form action="" method="post" enctype="multipart/form-data"> |
||||||
|
<p>管理员暂未开放此 API</p> |
||||||
|
</form> |
||||||
|
</div> |
@ -0,0 +1,35 @@ |
|||||||
|
<div class="upload-container"> |
||||||
|
<div class="title"> |
||||||
|
<h1>Image Upload <i |
||||||
|
class="mdui-list-item-icon mdui-icon material-icons iconfont icon-{{.iconStyle}} mdui-text-color-{{ .iconColor}}"></i> |
||||||
|
</h1> |
||||||
|
<p>最大可上传 5 MB的图片,单次同时可选择 10 张。</p> |
||||||
|
</div> |
||||||
|
<form action="" method="post" enctype="multipart/form-data"> |
||||||
|
<input id="image" style="display: none;" type="file" multiple name="image" accept="image/*"> |
||||||
|
</form> |
||||||
|
<div class="success-info"> |
||||||
|
<div class="mdui-tab mdui-tab-scrollable" mdui-tab> |
||||||
|
<a href="#code-url" class="mdui-ripple mdui-tab-active">URL</a> |
||||||
|
<a href="#code-html" class="mdui-ripple">HTML</a> |
||||||
|
<a href="#code-bbcode" class="mdui-ripple">BBCode</a> |
||||||
|
<a href="#code-markdown" class="mdui-ripple">Markdown</a> |
||||||
|
<a href="#code-markdown-with-link" class="mdui-ripple">Markdown with link</a> |
||||||
|
</div> |
||||||
|
<div id="code-url"> |
||||||
|
<ul></ul> |
||||||
|
</div> |
||||||
|
<div id="code-html"> |
||||||
|
<ul></ul> |
||||||
|
</div> |
||||||
|
<div id="code-bbcode"> |
||||||
|
<ul></ul> |
||||||
|
</div> |
||||||
|
<div id="code-markdown"> |
||||||
|
<ul></ul> |
||||||
|
</div> |
||||||
|
<div id="code-markdown-with-link"> |
||||||
|
<ul></ul> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</div> |
@ -0,0 +1,87 @@ |
|||||||
|
<script src="/static/clipboard.js/2.0.1/clipboard.min.js"></script> |
||||||
|
<script src="/static/bootstrap-fileinput/4.5.1/js/fileinput.min.js"></script> |
||||||
|
<script src="/static/bootstrap-fileinput/4.5.1/js/locales/zh.js"></script> |
||||||
|
<script src="/static/bootstrap/3.3.7/js/bootstrap.min.js"></script> |
||||||
|
<script> |
||||||
|
|
||||||
|
var clipboard = new ClipboardJS('.copy', { |
||||||
|
text: function (trigger) { |
||||||
|
return $(trigger).parent('li').text(); |
||||||
|
} |
||||||
|
}); |
||||||
|
|
||||||
|
clipboard.on('success', function (e) { |
||||||
|
app.msg(true, '复制成功'); |
||||||
|
}); |
||||||
|
|
||||||
|
clipboard.on('error', function (e) { |
||||||
|
app.msg(false, '复制失败'); |
||||||
|
}); |
||||||
|
|
||||||
|
$("#image").fileinput({ |
||||||
|
uploadUrl: "{{ .apiUrl}}", |
||||||
|
language: "zh", |
||||||
|
uploadAsync: true, |
||||||
|
overwriteInitial: false, |
||||||
|
//browseClass: "btn btn-file", |
||||||
|
maxFileSize: "{{.maxPicSize}}",// kb |
||||||
|
maxFileCount: "{{.maxNumber}}", |
||||||
|
showCaption: true, |
||||||
|
dropZoneEnabled: true, |
||||||
|
browseIcon: "<i class=\"glyphicon glyphicon-picture\"></i> ", |
||||||
|
allowedFileExtensions: JSON.parse('["jpg","jpeg","gif","png","ico"]'), |
||||||
|
uploadExtraData: { |
||||||
|
"_xsrf":{{.xsrf_token}}, |
||||||
|
"apiSelect": "{{ .apiSelect}}" |
||||||
|
} |
||||||
|
}).on("fileuploaded", function (event, data, previewId, index) { |
||||||
|
var form = data.form, files = data.files, extra = data.extra, response = data.response, reader = data.reader; |
||||||
|
if (200 === response.code) { |
||||||
|
$("#code-url ul").prepend("<li>" + response.data.url + "<i class=\"copy iconfont icon-copy\"></i></li>"); |
||||||
|
$("#code-html ul").prepend("<li><img src=\"" + response.data.url + "\" alt=\"" + response.data.name + "\" title=\"" + response.data.name + "\" /><i class=\"copy iconfont icon-copy\"></i></li>"); |
||||||
|
$("#code-bbcode ul").prepend("<li>[img]" + response.data.url + "[/img]<i class=\"copy iconfont icon-copy\"></i></li>"); |
||||||
|
$("#code-markdown ul").prepend("<li>![" + response.data.name + "](" + response.data.url + ")<i class=\"copy iconfont icon-copy\"></i></li>"); |
||||||
|
$("#code-markdown-with-link ul").prepend("<li>[![" + response.data.name + "](" + response.data.url + ")](" + response.data.url + ")<i class=\"copy iconfont icon-copy\"></i></li>"); |
||||||
|
$(".success-info").css("width", "inherit"); |
||||||
|
if (response.data.quota && response.data.use_quota) { |
||||||
|
$('.quota-container progress').attr('max', response.data.quota); |
||||||
|
$('.quota-container progress').val(response.data.use_quota); |
||||||
|
$('.quota-container span.quota').text(app.bytesToSize(response.data.quota)); |
||||||
|
$('.quota-container span.use-quota').text(app.bytesToSize(response.data.use_quota)); |
||||||
|
} |
||||||
|
} else if (500 === response.code) { |
||||||
|
mdui.alert(response.msg, '发生异常'); |
||||||
|
} else { |
||||||
|
mdui.alert(response.msg); |
||||||
|
} |
||||||
|
}); |
||||||
|
$('#image').css("display", "block"); |
||||||
|
</script> |
||||||
|
|
||||||
|
<script> |
||||||
|
$(function () { |
||||||
|
var toTop = $("#to-top"), toTopHide = function () { |
||||||
|
if ($(window).scrollTop() > 50) { |
||||||
|
toTop.removeClass('mdui-fab-hide'); |
||||||
|
} else { |
||||||
|
toTop.addClass('mdui-fab-hide'); |
||||||
|
} |
||||||
|
}; |
||||||
|
if ($(window).scrollTop() > 50) { |
||||||
|
toTopHide(); |
||||||
|
} |
||||||
|
$(window).scroll(function () { |
||||||
|
toTopHide(); |
||||||
|
}); |
||||||
|
|
||||||
|
toTop.click(function () { |
||||||
|
$('body,html').animate({scrollTop: 0}, 500); |
||||||
|
}); |
||||||
|
|
||||||
|
$('.open-menu').click(function () { |
||||||
|
if ($(window).width() > 1024) { |
||||||
|
app.cookie.set('menu', $('body').hasClass('mdui-drawer-body-left') ? 'open' : 'close', 10, '/'); |
||||||
|
} |
||||||
|
}); |
||||||
|
}); |
||||||
|
</script> |