コード例 #1
0
ファイル: package.go プロジェクト: harryyeh/switch
func Download(ctx *middleware.Context) {
	importPath := archive.GetRootPath(ctx.Query("pkgname"))
	rev := ctx.Query("revision")
	r, err := models.CheckPkg(importPath, rev)
	if err != nil {
		ctx.JSON(422, map[string]interface{}{
			"error": err.Error(),
		})
		return
	}

	if err = models.IncreasePackageDownloadCount(importPath); err != nil {
		ctx.JSON(500, map[string]interface{}{
			"error": err.Error(),
		})
		return
	} else if err = models.AddDownloader(ctx.RemoteAddr()); err != nil {
		ctx.JSON(500, map[string]interface{}{
			"error": err.Error(),
		})
		return
	}

	ext := archive.GetExtension(importPath)
	serveName := path.Base(importPath) + "-" + base.ShortSha(r.Revision) + ext
	switch r.Storage {
	case models.LOCAL:
		ctx.ServeFile(path.Join(setting.ArchivePath, importPath, r.Revision+ext), serveName)
	case models.QINIU:
		ctx.Redirect("http://" + setting.BucketUrl + "/" + importPath + "-" + r.Revision + ext)
	}
}
コード例 #2
0
ファイル: package.go プロジェクト: harryyeh/switch
// KeyName returns QiNiu key name.
func (r *Revision) KeyName() (string, error) {
	if r.Storage == LOCAL {
		return "", ErrRevisionIsLocal
	}
	if err := r.GetPackage(); err != nil {
		return "", err
	}
	return r.Pkg.ImportPath + "-" + r.Revision + archive.GetExtension(r.Pkg.ImportPath), nil
}
コード例 #3
0
ファイル: block.go プロジェクト: harryyeh/switch
// BlockPackage blocks given package.
func BlockPackage(importPath, note string) (keys []string, err error) {
	pkg, err := GetPakcageByPath(importPath)
	if err != nil {
		return nil, err
	}

	has, err := x.Where("import_path=?", pkg.ImportPath).Get(new(Block))
	if err != nil {
		return nil, err
	} else if has {
		return nil, nil
	}

	sess := x.NewSession()
	defer sess.Close()
	if err = sess.Begin(); err != nil {
		return nil, err
	}

	keys = make([]string, 0, 10)

	revs, err := pkg.GetRevisions()
	if err != nil {
		return nil, fmt.Errorf("error getting revisions(%s): %v", pkg.ImportPath, err)
	}

	ext := archive.GetExtension(pkg.ImportPath)
	for _, rev := range revs {
		switch rev.Storage {
		case QINIU:
			keys = append(keys, pkg.ImportPath+"-"+rev.Revision+ext)
		}
		if _, err = sess.Id(rev.Id).Delete(new(Revision)); err != nil {
			sess.Rollback()
			return nil, err
		}
	}
	os.RemoveAll(path.Join(setting.ArchivePath, pkg.ImportPath))

	if _, err = sess.Id(pkg.Id).Delete(new(Package)); err != nil {
		sess.Rollback()
		return nil, err
	}

	b := &Block{
		ImportPath: pkg.ImportPath,
		Note:       note,
	}
	if _, err = sess.Insert(b); err != nil {
		sess.Rollback()
		return nil, err
	}

	return keys, sess.Commit()
}
コード例 #4
0
ファイル: block.go プロジェクト: harryyeh/switch
// RunBlockRule applies given block rule to all packages.
func RunBlockRule(id int64) (count int64, keys []string, err error) {
	r, err := GetBlockRuleById(id)
	if err != nil {
		return 0, nil, err
	}
	exp, err := regexp.Compile(r.Rule)
	if err != nil {
		return 0, nil, err
	}

	keys = make([]string, 0, 10)

	err = x.Iterate(new(Package), func(idx int, bean interface{}) error {
		pkg := bean.(*Package)

		if !exp.MatchString(pkg.ImportPath) {
			return nil
		}

		revs, err := pkg.GetRevisions()
		if err != nil {
			return fmt.Errorf("error getting revisions(%s): %v", pkg.ImportPath, err)
		}

		// Delete package archives.
		ext := archive.GetExtension(pkg.ImportPath)
		for _, rev := range revs {
			switch rev.Storage {
			case QINIU:
				keys = append(keys, pkg.ImportPath+"-"+rev.Revision+ext)
			}

			if _, err = x.Id(rev.Id).Delete(new(Revision)); err != nil {
				return fmt.Errorf("error deleting revision(%s-%s): %v", pkg.ImportPath, rev.Revision, err)
			}
		}
		os.RemoveAll(path.Join(setting.ArchivePath, pkg.ImportPath))

		if setting.ProdMode {
			if _, err = x.Id(pkg.Id).Delete(new(Package)); err != nil {
				return fmt.Errorf("error deleting package(%s): %v", pkg.ImportPath, err)
			}
		}

		log.Info("[%d] Package blocked: %s", r.Id, pkg.ImportPath)

		count++
		return nil
	})

	return count, keys, err
}
コード例 #5
0
ファイル: package.go プロジェクト: harryyeh/switch
func BlockPackage(ctx *middleware.Context) {
	id := ctx.QueryInt64("id")
	pkg, err := models.GetPakcageById(id)
	if err != nil {
		if err == models.ErrPackageNotExist {
			ctx.JSON(404, map[string]string{
				"error": err.Error(),
			})
		} else {
			ctx.JSON(500, map[string]string{
				"error": fmt.Sprintf("fail to get package by ID(%d): %v", id, err),
			})
		}
		return
	}

	revs, err := pkg.GetRevisions()
	if err != nil {
		ctx.JSON(500, map[string]string{
			"error": fmt.Sprintf("fail to get package revisions by ID(%d): %v", id, err),
		})
		return
	}

	// Delete package archives.
	ext := archive.GetExtension(pkg.ImportPath)
	for _, rev := range revs {
		switch rev.Storage {
		case models.QINIU:
			key := pkg.ImportPath + "-" + rev.Revision + ext
			if err = qiniu.DeleteArchive(key); err != nil {
				ctx.JSON(500, map[string]string{
					"error": fmt.Sprintf("fail to delete archive(%s): %v", key, err),
				})
				return
			}
		}
	}
	os.RemoveAll(path.Join(setting.ArchivePath, pkg.ImportPath))

	if err = models.BlockPackage(pkg, revs, ctx.Query("note")); err != nil {
		ctx.JSON(500, map[string]string{
			"error": fmt.Sprintf("fail to block package by ID(%d): %v", id, err),
		})
		return
	}

	ctx.JSON(200, map[string]interface{}{
		"ok": true,
	})
}
コード例 #6
0
ファイル: download.go プロジェクト: harryyeh/switch
func Download(ctx *middleware.Context) {
	ctx.Data["Title"] = ctx.Tr("download")
	ctx.Data["PageIsDownload"] = true
	importPath := archive.GetRootPath(ctx.Query("pkgname"))

	if ctx.Req.Method == "POST" {
		rev := ctx.Query("revision")
		r, err := models.CheckPkg(importPath, rev)
		if err != nil {
			ctx.Data["pkgname"] = importPath
			ctx.Data["revision"] = rev

			errMsg := err.Error()
			if err == archive.ErrNotMatchAnyService {
				ctx.Data["Err_PkgName"] = true
				errMsg = ctx.Tr("download.err_not_match_service")
			} else if _, ok := err.(*models.BlockError); ok {
				errMsg = ctx.Tr("download.err_package_blocked", err.Error())
			}
			ctx.RenderWithErr(errMsg, "download", nil)
			return
		}

		if err = models.IncreasePackageDownloadCount(importPath); err != nil {
			ctx.Handle(500, "IncreasePackageDownloadCount", err)
			return
		} else if err = models.AddDownloader(ctx.RemoteAddr()); err != nil {
			ctx.Handle(500, "AddDownloader", err)
			return
		}

		ext := archive.GetExtension(importPath)
		serveName := path.Base(importPath) + "-" + base.ShortSha(r.Revision) + ext
		switch r.Storage {
		case models.LOCAL:
			ctx.ServeFile(path.Join(setting.ArchivePath, importPath, r.Revision+ext), serveName)
		case models.QINIU:
			ctx.Redirect("http://" + setting.BucketUrl + "/" + importPath + "-" + r.Revision + ext)
		}
		return
	}

	ctx.Data["pkgname"] = importPath
	ctx.HTML(200, "download")
}
コード例 #7
0
ファイル: package.go プロジェクト: harryyeh/switch
func cleanExpireRevesions() {
	if err := x.Where("updated<?", time.Now().Add(_EXPIRE_DURATION)).
		Iterate(new(Revision), func(idx int, bean interface{}) (err error) {
			rev := bean.(*Revision)
			if err = rev.GetPackage(); err != nil {
				return err
			}

			if _, err = x.Id(rev.Id).Delete(new(Revision)); err != nil {
				return err
			}

			ext := archive.GetExtension(rev.Pkg.ImportPath)
			fpath := path.Join(setting.ArchivePath, rev.Pkg.ImportPath, rev.Revision+ext)

			switch rev.Storage {
			case LOCAL:
				os.Remove(fpath)
				log.Info("Revision deleted: %s", fpath)
				return nil
			case QINIU:
				key, err := rev.KeyName()
				if err != nil {
					return err
				}
				if setting.ProdMode {
					if err = qiniu.DeleteArchive(key); err != nil {
						return err
					}
				}
				log.Info("Revision deleted: %s", key)
				return nil
			default:
				return nil
			}

			return nil
		}); err != nil {
		log.Error(3, "Fail to clean expire revisions: %v", err)
	}
}
コード例 #8
0
ファイル: models.go プロジェクト: harryyeh/switch
// uploadArchives checks and uploads local archives to QiNiu.
func uploadArchives() {
	revs, err := GetLocalRevisions()
	if err != nil {
		log.Error(4, "Fail to get local revisions: %v", err)
		return
	}

	// Upload.
	for _, rev := range revs {
		pkg, err := GetPakcageById(rev.PkgId)
		if err != nil {
			log.Error(4, "Fail to get package by ID(%d): %v", rev.PkgId, err)
			continue
		}

		ext := archive.GetExtension(pkg.ImportPath)
		key := pkg.ImportPath + "-" + rev.Revision + ext
		localPath := path.Join(pkg.ImportPath, rev.Revision)
		fpath := path.Join(setting.ArchivePath, localPath+ext)

		// Move.
		// rsCli := rs.New(nil)
		// log.Info(key)
		// err = rsCli.Move(nil, setting.BucketName, pkg.ImportPath+"-"+rev.Revision, setting.BucketName, key)
		// if err != nil {
		// 	log.Error(4, rev.Revision)
		// }
		// continue

		if !com.IsFile(fpath) {
			log.Debug("Delete: %v", fpath)
			DeleteRevisionById(rev.Id)
			continue
		}

		// Check archive size.
		f, err := os.Open(fpath)
		if err != nil {
			log.Error(4, "Fail to open file(%s): %v", fpath, err)
			continue
		}
		fi, err := f.Stat()
		if err != nil {
			log.Error(4, "Fail to get file info(%s): %v", fpath, err)
			continue
		}
		// Greater then MAX_UPLOAD_SIZE.
		if fi.Size() > setting.MaxUploadSize<<20 {
			log.Debug("Ignore large archive: %v", fpath)
			continue
		}

		log.Debug("Uploading: %s", localPath)
		if err = qiniu.UploadArchive(key, fpath); err != nil {
			log.Error(4, "Fail to upload file(%s): %v", fpath, err)
			continue
		}
		rev.Storage = QINIU
		if err := UpdateRevision(rev); err != nil {
			log.Error(4, "Fail to upadte revision(%d): %v", rev.Id, err)
			continue
		}
		os.Remove(fpath)
		log.Info("Uploaded: %s", localPath)
	}
}
コード例 #9
0
ファイル: package.go プロジェクト: harryyeh/switch
func ListLargeRevisions(ctx *middleware.Context) {
	revs, err := models.GetLocalRevisions()
	if err != nil {
		ctx.JSON(500, map[string]string{
			"error": fmt.Sprintf("fail to get local revisions: %v", err),
		})
		return
	}

	largeRevs := make([]*ApiRevesion, 0, len(revs)/2)
	for _, rev := range revs {
		pkg, err := models.GetPakcageById(rev.PkgId)
		if err != nil {
			ctx.JSON(500, map[string]string{
				"error": fmt.Sprintf("fail to get package by ID(%d): %v", rev.PkgId, err),
			})
			return
		}

		ext := archive.GetExtension(pkg.ImportPath)
		localPath := path.Join(pkg.ImportPath, rev.Revision)
		fpath := path.Join(setting.ArchivePath, localPath+ext)

		if !com.IsFile(fpath) {
			continue
		}

		// Check archive size.
		f, err := os.Open(fpath)
		if err != nil {
			ctx.JSON(500, map[string]string{
				"error": fmt.Sprintf("fail to open file(%s): %v", fpath, err),
			})
			return
		}
		fi, err := f.Stat()
		if err != nil {
			ctx.JSON(500, map[string]string{
				"error": fmt.Sprintf("fail to get file info(%s): %v", fpath, err),
			})
			return
		}
		// Greater then MAX_UPLOAD_SIZE.
		if fi.Size() > setting.MaxUploadSize<<20 {
			largeRevs = append(largeRevs, &ApiRevesion{
				Id: rev.Id,
				Package: &ApiPackage{
					Id:         pkg.Id,
					ImportPath: pkg.ImportPath,
					Created:    pkg.Created,
				},
				Revision: rev.Revision,
				Size:     fi.Size(),
				Updated:  rev.Updated,
			})
			continue
		}
	}

	ctx.JSON(200, map[string]interface{}{
		"revisions": &largeRevs,
	})
}