// 输出Hash func OutHash(master chan string) { for { select { case infohash := <-master: if models.DbConfig.ShowMsg { fmt.Println("Get InfoHash: ", infohash) } // 定义一个SC_Hash var schash models.SC_Hash // 设置SC_Hash schash.Hot = 1 schash.IsPut = false schash.InfoHash = strings.ToUpper(strings.TrimSpace(infohash)) // 检测infohash是否存在 has := models.Has(models.DbHash, bson.M{"infohash": schash.InfoHash}) // 保存hash数据 err := schash.Save() if err == nil && has == false { // 自增统计数据 models.SaveLog(time.Now().Format("20060102"), "dhtnums") } // 修改种子热度 models.SetHot(schash.InfoHash) } } }
// 磁力链转种子 func (this *IndexController) Torrent() { if this.Ctx.Request.Method == "POST" { // 获取磁力链接 magnet := this.GetString("magnetLink") // 将磁力链接转换为大写格式 magnet = strings.ToUpper(magnet) // 定义一个正则 re, _ := regexp.Compile(`MAGNET:\?XT=URN:BTIH:([^&]+)`) // 匹配磁力链接 match := re.FindAllString(magnet, -1) // 获取infohash magnet = strings.Replace(match[0], "MAGNET:?XT=URN:BTIH:", "", -1) // 去除空格并转换为大写 magnet = strings.ToUpper(strings.TrimSpace(magnet)) if match[0] == "" { // 如果匹配不到磁力链接 if len(magnet) != 40 { // 跳转404 this.Abort("404") } } // 检测infohash是否已经存在 if !models.Has(models.DbHash, bson.M{"infohash": magnet}) { // 定义一个SC_Hash var schash models.SC_Hash // 设置SC_Hash schash.Hot = 1 schash.IsPut = true schash.InfoHash = magnet // 保存hash数据 err := schash.Save() if err == nil { // 自增统计数据 models.SaveLog(time.Now().Format("20060102"), "dhtnums") } } // 检测infohash是否已入库过 if !models.Has(models.DbInfo, bson.M{"infohash": magnet}) { // 下载并入库种子 ret, err := common.PullTorrent(magnet) if err != nil || ret != 0 { this.Abort("404") } } // 跳转到种子信息页 this.Redirect("/"+magnet, 302) } this.TplNames = "torrent.html" }
// 搜索页 func (this *IndexController) Search() { // 获取搜索关键字 key := this.Ctx.Input.Param(":k") // 获取排序方式 sort := this.Ctx.Input.Param(":sort") // 设置排序方式 this.Data["Sort"] = sort if sort == "" { this.Data["Sort"] = "puttime" sort = "-hot" } sort = "-" + sort // 设置搜索词 this.Data["Key"] = key // 定义两个SC_Info列表 var infos, newlist, hots []models.SC_Info // 获取热门种子列表 models.GetDataByQuery(models.DbInfo, 0, 5, "-hot", nil, &hots) // 设置热门列表 this.Data["HotList"] = hots // 获取最新入库 models.GetDataByQuery(models.DbInfo, 0, 10, "-puttime", nil, &newlist) // 设置最新入库 this.Data["NewList"] = newlist // 设置查询条件 query := bson.M{"$or": []bson.M{bson.M{"caption": bson.M{"$regex": bson.RegEx{key, "i"}}}, bson.M{"keys": bson.M{"$regex": bson.RegEx{key, "i"}}}}} // 获取种子数量 count := models.Count(models.DbInfo, query) // 设置数量 this.Data["Nums"] = count // 获取分页数据 page := pagination.NewPaginator(this.Ctx.Request, 15, count) // 设置分页数据 this.Data["paginator"] = page // 获取种子列表 models.GetDataByQuery(models.DbInfo, page.Offset(), 15, sort, query, &infos) // 设置种子列表 this.Data["Lists"] = infos // 定义三个SC_Search列表 var randomlist, lastsearch, relevantsearch []models.SC_Search // 设置查询条件 query = bson.M{"$or": []bson.M{bson.M{"caption": bson.M{"$regex": bson.RegEx{key, "i"}}}}} // 获取相关搜索 models.GetDataByQuery(models.DbSearch, 0, 10, "-searchtime", query, &relevantsearch) // 设置相关搜索 this.Data["RelevantList"] = relevantsearch // 获取热门搜索 models.GetDataByQuery(models.DbSearch, 0, 10, "-views", nil, &randomlist) // 设置热门搜索 this.Data["RandomList"] = randomlist // 获取最近搜索 models.GetDataByQuery(models.DbSearch, 0, 10, "-searchtime", nil, &lastsearch) // 设置最后搜索 this.Data["LastSearch"] = lastsearch // 定义一个SC_Search var scsearch models.SC_Search // 设置关键字 scsearch.Caption = key // 设置查询次数 scsearch.Views = 1 // 设置查询到的数据总量 scsearch.Count = count // 保存数据 scsearch.Save() // 自增查询次数 models.SaveLog(time.Now().Format("20060102"), "searchnums") // 输出模板 this.TplNames = "list.html" }
// 显示页 func (this *IndexController) View() { // 获取InfoHash infohash := this.Ctx.Input.Param(":infohash") // 将infohash转换为大写 infohash = strings.ToUpper(infohash) // 定义一个SC_Info var scinfo models.SC_Info // 获取种子信息 models.GetOneByQuery(models.DbInfo, bson.M{"infohash": infohash}, &scinfo) if scinfo.InfoHash == "" { // 如果infohash为空或小于40则报错 this.Abort("404") } // 设置种子标题 this.Data["Caption"] = scinfo.Caption // 定义两个SC_Info列表 var hots []models.SC_Info // 获取热门种子列表 models.GetDataByQuery(models.DbInfo, 0, 5, "-hot", nil, &hots) // 设置热门列表 this.Data["HotList"] = hots // 自增下载次数 models.SetAdd(models.DbInfo, bson.M{"infohash": infohash}, "views", true) // 设置创建时间 this.Data["CreateTime"] = scinfo.CreateTime // 设置入库时间 this.Data["PutTime"] = scinfo.PutTime // 设置文件大小 this.Data["Length"] = scinfo.Length // 设置关键词 this.Data["Keys"] = scinfo.Keys // 设置种子热度 this.Data["Hot"] = scinfo.Hot // 设置文件数量 this.Data["FileCount"] = scinfo.FileCount // 设置InfoHash this.Data["InfoHash"] = scinfo.InfoHash // 设置文件列表 this.Data["FileList"] = scinfo.FileList // 设置下载链接 this.Data["Down"] = fmt.Sprintf("http://btcache.me/torrent/%s", scinfo.InfoHash) // 二维码文件是否存在 if _, err := os.Stat("/static/qrcode/" + scinfo.InfoHash[0:1] + "/" + scinfo.InfoHash[1:2] + "/" + scinfo.InfoHash[2:3] + "/" + scinfo.InfoHash[3:4] + "/" + scinfo.InfoHash[4:5] + "/" + scinfo.InfoHash[5:6] + "/" + scinfo.InfoHash[6:7] + "/" + scinfo.InfoHash + ".png"); err != nil { // 存在则设置二维码图片 this.Data["Qrcode"] = "/static/qrcode/" + scinfo.InfoHash[0:1] + "/" + scinfo.InfoHash[1:2] + "/" + scinfo.InfoHash[2:3] + "/" + scinfo.InfoHash[3:4] + "/" + scinfo.InfoHash[4:5] + "/" + scinfo.InfoHash[5:6] + "/" + scinfo.InfoHash[6:7] + "/" + scinfo.InfoHash + ".png" } // 自增查看次数 models.SaveLog(time.Now().Format("20060102"), "viewnums") // 输出模板 this.TplNames = "view.html" }
// 种子转磁力链 func (this *IndexController) Magnet() { if this.Ctx.Request.Method == "POST" { // 获取上传文件 f, h, err := this.GetFile("torrentFile") if err != nil { // 跳转404 this.Abort("404") } // 保证正确关闭 defer f.Close() // 获取最后一个.出现的位置 index := strings.LastIndex(h.Filename, ".") // 获取文件后缀 ext := strings.ToUpper(h.Filename[index+1:]) // 若不是种子文件后缀则报错 if ext != "TORRENT" { // 跳转404 this.Abort("404") } // 读取种子信息 meta, err := common.ReadTorrent(f) if err != nil || len(meta.InfoHash) != 40 { // 跳转404 this.Abort("404") } // 获取种子UTF-8格式名称 caption := meta.Info.Name8 if caption == "" { // 获取失败则获取默认名称 caption = meta.Info.Name } // 种子入库 err = common.PutTorrent(meta) if err == nil { // 检测infohash是否已经存在 if models.Has(models.DbHash, bson.M{"infohash": strings.ToUpper(strings.TrimSpace(meta.InfoHash))}) { // 设置当前infohash已经入库 models.SetPut(strings.ToUpper(strings.TrimSpace(meta.InfoHash))) } else { // 定义一个SC_Hash var schash models.SC_Hash // 设置SC_Hash schash.Hot = 1 schash.IsPut = true schash.InfoHash = strings.ToUpper(strings.TrimSpace(meta.InfoHash)) // 保存hash数据 err = schash.Save() if err == nil { // 自增统计数据 models.SaveLog(time.Now().Format("20060102"), "dhtnums") } } this.Redirect("/"+strings.ToUpper(strings.TrimSpace(meta.InfoHash)), 302) } } this.TplNames = "magnet.html" }
// 种子入库 func PutTorrent(metaTorrent MetaInfo) error { // 定义一个SC_Info var scinfo models.SC_Info // 如果有utf-8格式名称 if metaTorrent.Info.Name8 != "" { // 直接使用utf-8格式的 scinfo.Caption = strings.TrimSpace(metaTorrent.Info.Name8) } else { // 否则使用非utf-8格式 scinfo.Caption = strings.TrimSpace(metaTorrent.Info.Name) } // 设置infohash, 并转换为大写格式 scinfo.InfoHash = strings.ToUpper(metaTorrent.InfoHash) // 如果没有获取到creationdate信息 if metaTorrent.CreationDate == 0 { // 将creationdate设置为当前时间 scinfo.CreateTime = time.Now() } else { // 否则为获取到的时间 scinfo.CreateTime = time.Unix(metaTorrent.CreationDate, 0) } // 定义一个File var file File // 定义一个File列表保存路径信息 var spath []File // 判断文件列表是否大于0 if len(metaTorrent.Info.Files) > 0 { // 循环处理文件列表 for _, FileDict := range metaTorrent.Info.Files { // 加上文件长度 scinfo.Length += FileDict.Length // 文件数量+1 scinfo.FileCount += 1 // 设置文件长度 file.Length = FileDict.Length // 清空文件路径 file.Path = "" if FileDict.Path8 != nil { // 如果存在utf8编码则使用utf8编码 for _, path := range FileDict.Path8 { file.Path += strings.TrimSpace(path) + "/" } } else { // 否则使用默认 for _, path := range FileDict.Path { file.Path += strings.TrimSpace(path) + "/" } } // 获取最后一个/的位置 index := strings.LastIndex(file.Path, "/") if index <= len(file.Path) && index != -1 { // 将最后一个/去掉 file.Path = file.Path[0:index] } // 将文件信息加入列表 scinfo.Files = append(scinfo.Files, file) // 加入路径信息 spath = append(spath, file) } } else { // 设置文件长度 scinfo.Length = metaTorrent.Info.Length // 设置文件数量 scinfo.FileCount = 1 // 设置文件路径 file.Path = scinfo.Caption // 设置文件长度 file.Length = scinfo.Length // 将文件本身加入列表 scinfo.Files = append(scinfo.Files, file) // 加入路径信息 spath = append(spath, file) } // 对路径数组循环 for _, f := range spath { // 分割路径 p := strings.Split(f.Path, "/") // 创建树结构 treeDir(p, f.Length) } // 设置树结构 scinfo.FileList = append(scinfo.FileList, root) // 清空 root.Dirs = nil root.Files = nil // 设置文件热度为1 scinfo.Hot = 1 // 如果都没有问题 if scinfo.Caption != "" && scinfo.FileCount > 0 && scinfo.InfoHash != "" { // 定义一个正则 re, _ := regexp.Compile("\\pP|\\pS") // 去除种子名称中的所有符号 caption := re.ReplaceAllString(scinfo.Caption, " ") // 检测是否存在 if !models.Has(models.DbInfo, bson.M{"infohash": scinfo.InfoHash}) { // 设置种子分词 scinfo.Keys = Sego(caption) // 设置种子发布时间 scinfo.PutTime = time.Now() // 保存种子信息 err := scinfo.Save() if err == nil { // 设置当前hash已经入库 models.SetPut(scinfo.InfoHash) // 自增统计数据 models.SaveLog(time.Now().Format("20060102"), "putnums") // 定义一个Qrcode对象 qr := &Qrcode{ Version: 0, Level: ECLevelM, ModuleSize: 7, QuietZoneWidth: 0, } // 生成二维码 img, _ := qr.Encode("magnet:?xt=urn:btih:" + scinfo.InfoHash) // 截取infohash作为目录 dir := "./static/qrcode/" + scinfo.InfoHash[0:1] + "/" + scinfo.InfoHash[1:2] + "/" + scinfo.InfoHash[2:3] + "/" + scinfo.InfoHash[3:4] + "/" + scinfo.InfoHash[4:5] + "/" + scinfo.InfoHash[5:6] + "/" + scinfo.InfoHash[6:7] // 创建目录 os.MkdirAll(dir, 0777) // 创建二维码图片文件 f, _ := os.Create(fmt.Sprintf("%s/%s.png", dir, scinfo.InfoHash)) // 保证正确关闭 defer f.Close() // 将二维码写入文件 png.Encode(f, img) } return err } else { // 如果没有设置为入库 if !models.IsPut(scinfo.InfoHash) { // 设置为入库 return models.SetPut(scinfo.InfoHash) } } } return nil }