Пример #1
0
// 更新该项目的喜欢数
// objid:被喜欢对象id;num: 喜欢数(负数表示取消喜欢)
func (self ProjectLike) UpdateLike(objid, num int) {
	// 更新喜欢数(TODO:暂时每次都更新表)
	err := model.NewOpenProject().Where("id=?", objid).Increment("likenum", num)
	if err != nil {
		logger.Errorln("更新项目喜欢数失败:", err)
	}
}
Пример #2
0
// 开源项目总数
func ProjectsTotal() (total int) {
	total, err := model.NewOpenProject().Count()
	if err != nil {
		logger.Errorln("project service ProjectsTotal error:", err)
	}
	return
}
Пример #3
0
func UpdateProjectStatus(id, status int, username string) error {
	if status < model.StatusNew || status > model.StatusOffline {
		return errors.New("status is illegal")
	}

	logger.Infoln("UpdateProjectStatus by username:"******"status=?", status).Where("id=?", id).Update()
}
Пример #4
0
// 更新该项目的评论信息
// cid:评论id;objid:被评论对象id;uid:评论者;cmttime:评论时间
func (self ProjectComment) UpdateComment(cid, objid, uid int, cmttime string) {
	id := strconv.Itoa(objid)

	// 更新评论数(TODO:暂时每次都更新表)
	err := model.NewOpenProject().Where("id="+id).Increment("cmtnum", 1)
	if err != nil {
		logger.Errorln("更新项目评论数失败:", err)
	}
}
Пример #5
0
// 获得某个用户最近发布的开源项目
func FindUserRecentProjects(username string) []*model.OpenProject {
	projectList, err := model.NewOpenProject().Where("username=?", username).Limit("0,5").Order("ctime DESC").FindAll()
	if err != nil {
		logger.Errorln("project service FindUserRecentProjects error:", err)
		return nil
	}

	return projectList
}
Пример #6
0
// 通过objid获得 project 的所有者
func getProjectOwner(id int) int {
	project := model.NewOpenProject()
	err := project.Where("id=" + strconv.Itoa(id)).Find()
	if err != nil {
		logger.Errorln("project service getProjectOwner Error:", err)
		return 0
	}

	user := FindUserByUsername(project.Username)
	return user.Uid
}
Пример #7
0
// 获取多个项目详细信息
func FindProjectsByIds(ids []int) []*model.OpenProject {
	if len(ids) == 0 {
		return nil
	}
	inIds := util.Join(ids, ",")
	projects, err := model.NewOpenProject().Where("id in(" + inIds + ")").FindAll()
	if err != nil {
		logger.Errorln("project service FindProjectsByIds error:", err)
		return nil
	}
	return projects
}
Пример #8
0
func ProjectUriExists(uri string) bool {
	project := model.NewOpenProject()
	err := project.Where("uri=?", uri).Find("id")
	if err != nil {
		return false
	}

	if project.Id > 0 {
		return true
	}

	return false
}
Пример #9
0
// flush 将浏览数刷入数据库中
func (this *view) flush() {
	this.locker.Lock()
	defer this.locker.Unlock()

	objid := strconv.Itoa(this.objid)
	switch this.objtype {
	case model.TYPE_TOPIC:
		model.NewTopicEx().Where("tid="+objid).Increment("view", this.num)
	case model.TYPE_ARTICLE:
		model.NewArticle().Where("id="+objid).Increment("viewnum", this.num)
	case model.TYPE_RESOURCE:
		model.NewResourceEx().Where("id="+objid).Increment("viewnum", this.num)
	case model.TYPE_PROJECT:
		model.NewOpenProject().Where("id="+objid).Increment("viewnum", this.num)
	}

	this.num = 0
}
Пример #10
0
// 新建项目
// uri: /project/new{json:(|.json)}
func NewProjectHandler(rw http.ResponseWriter, req *http.Request) {
	vars := mux.Vars(req)
	name := req.PostFormValue("name")
	// 请求新建项目页面
	if name == "" || req.Method != "POST" || vars["json"] == "" {
		project := model.NewOpenProject()
		req.Form.Set(filter.CONTENT_TPL_KEY, "/template/projects/new.html")
		filter.SetData(req, map[string]interface{}{"project": project, "activeProjects": "active"})
		return
	}

	user, _ := filter.CurrentUser(req)
	err := service.PublishProject(user, req.PostForm)
	if err != nil {
		fmt.Fprint(rw, `{"ok": 0, "error":"内部服务错误!"}`)
		return
	}
	fmt.Fprint(rw, `{"ok": 1, "data":""}`)
}
Пример #11
0
// 获取开源项目列表(分页)
func FindProjects(lastId, limit string) []*model.OpenProject {
	project := model.NewOpenProject()

	query := "status IN(?,?)"
	args := []interface{}{model.StatusNew, model.StatusOnline}
	if lastId != "0" {
		query += " AND id<?"
		args = append(args, lastId)
	}

	projectList, err := project.Where(query, args...).Order("id DESC").Limit(limit).
		FindAll()
	if err != nil {
		logger.Errorln("project service FindProjects Error:", err)
		return nil
	}

	return projectList
}
Пример #12
0
// 获取单个项目
func FindProject(uniq string) *model.OpenProject {
	field := "id"
	_, err := strconv.Atoi(uniq)
	if err != nil {
		field = "uri"
	}

	project := model.NewOpenProject()
	err = project.Where(field+"=? AND status IN(?,?)", uniq, model.StatusNew, model.StatusOnline).Find()

	if err != nil {
		logger.Errorln("project service FindProject error:", err)
		return nil
	}

	if project.Id == 0 {
		return nil
	}

	return project
}
Пример #13
0
// 获取开源项目列表(分页,后台用)
func FindProjectByPage(conds map[string]string, curPage, limit int) ([]*model.OpenProject, int) {
	conditions := make([]string, 0, len(conds))
	for k, v := range conds {
		conditions = append(conditions, k+"="+v)
	}

	project := model.NewOpenProject()

	limitStr := strconv.Itoa((curPage-1)*limit) + "," + strconv.Itoa(limit)
	projectList, err := project.Where(strings.Join(conditions, " AND ")).Order("id DESC").Limit(limitStr).
		FindAll()
	if err != nil {
		logger.Errorln("project service FindProjectByPage Error:", err)
		return nil, 0
	}

	total, err := project.Count()
	if err != nil {
		logger.Errorln("project service FindProjectByPage COUNT Error:", err)
		return nil, 0
	}

	return projectList, total
}
Пример #14
0
func GenSitemap() {
	sitemapFiles := []string{}

	// 首页
	home := map[string]string{
		"loc":      "http://" + config.Config["domain"],
		"lastmode": time.Now().Format(time.RFC3339),
	}

	var (
		little = 1
		step   = 4999
		large  = little + step
	)

	// 文章
	article := model.NewArticle()
	for {
		sitemapFile := "sitemap_article_" + strconv.Itoa(large) + ".xml"

		articles, err := article.Where("id BETWEEN ? AND ? AND status!=?", little, large, model.StatusOffline).FindAll("id", "mtime")
		little = large + 1
		large = little + step

		if err != nil {
			continue
		}

		if len(articles) == 0 {
			break
		}

		data := map[string]interface{}{
			"home":     home,
			"articles": articles,
		}

		if err = output(sitemapFile, data); err == nil {
			sitemapFiles = append(sitemapFiles, sitemapFile)
		}
	}

	little = 1
	large = little + step

	// 主题(帖子)
	topic := model.NewTopic()
	for {
		sitemapFile := "sitemap_topic_" + strconv.Itoa(large) + ".xml"

		topics, err := topic.Where("tid BETWEEN ? AND ? AND flag IN(?,?)", little, large, 0, 1).FindAll("tid", "mtime")
		little, large = large+1, little+step

		if err != nil {
			continue
		}

		if len(topics) == 0 {
			break
		}

		data := map[string]interface{}{
			"home":   home,
			"topics": topics,
		}

		if err = output(sitemapFile, data); err == nil {
			sitemapFiles = append(sitemapFiles, sitemapFile)
		}
	}

	little = 1
	large = little + step

	// 资源
	resource := model.NewResource()
	for {
		sitemapFile := "sitemap_resource_" + strconv.Itoa(large) + ".xml"

		resources, err := resource.Where("id BETWEEN ? AND ?", little, large).FindAll("id", "mtime")
		little, large = large+1, little+step

		if err != nil {
			continue
		}

		if len(resources) == 0 {
			break
		}

		data := map[string]interface{}{
			"home":      home,
			"resources": resources,
		}

		if err = output(sitemapFile, data); err == nil {
			sitemapFiles = append(sitemapFiles, sitemapFile)
		}
	}

	little = 1
	large = little + step

	// 项目
	project := model.NewOpenProject()
	for {
		sitemapFile := "sitemap_project_" + strconv.Itoa(large) + ".xml"

		projects, err := project.Where("id BETWEEN ? AND ? AND status=?", little, large, model.StatusOnline).FindAll("id", "uri", "mtime")
		little, large = large+1, little+step

		if err != nil {
			continue
		}

		if len(projects) == 0 {
			break
		}

		data := map[string]interface{}{
			"home":     home,
			"projects": projects,
		}

		if err = output(sitemapFile, data); err == nil {
			sitemapFiles = append(sitemapFiles, sitemapFile)
		}
	}

	little = 1
	large = little + step

	// wiki
	wiki := model.NewWiki()
	for {
		sitemapFile := "sitemap_wiki_" + strconv.Itoa(large) + ".xml"

		wikis, err := wiki.Where("id BETWEEN ? AND ?", little, large).FindAll("id", "uri", "mtime")
		little, large = large+1, little+step

		if err != nil {
			continue
		}

		if len(wikis) == 0 {
			break
		}

		data := map[string]interface{}{
			"home":  home,
			"wikis": wikis,
		}

		if err = output(sitemapFile, data); err == nil {
			sitemapFiles = append(sitemapFiles, sitemapFile)
		}
	}

	file, err := os.Create(sitemapPath + "sitemapindex.xml")
	if err != nil {
		logger.Errorln("gen sitemap index file error:", err)
		return
	}
	defer file.Close()

	err = sitemapIndexTpl.Execute(file, map[string]interface{}{
		"home":         home,
		"sitemapFiles": sitemapFiles,
	})
	if err != nil {
		logger.Errorln("execute sitemap index template error:", err)
	}
}
Пример #15
0
func PublishProject(user map[string]interface{}, form url.Values) (err error) {
	id := form.Get("id")
	isModify := id != ""

	if !isModify && ProjectUriExists(form.Get("uri")) {
		err = errors.New("uri存在")
		return
	}

	username := user["username"].(string)

	project := model.NewOpenProject()

	if isModify {
		err = project.Where("id=?", id).Find()
		if err != nil {
			logger.Errorln("Publish Project find error:", err)
			return
		}
		isAdmin := false
		if _, ok := user["isadmin"]; ok {
			isAdmin = user["isadmin"].(bool)
		}
		if project.Username != username && !isAdmin {
			err = NotModifyAuthorityErr
			return
		}

		util.ConvertAssign(project, form)
	} else {
		util.ConvertAssign(project, form)

		project.Username = username
		project.Ctime = util.TimeNow()
	}

	project.Uri = strings.ToLower(project.Uri)

	github := "github.com"
	pos := strings.Index(project.Src, github)
	if pos != -1 {
		project.Repo = project.Src[pos+len(github)+1:]
	}

	if !isModify {
		_, err = project.Insert()
	} else {
		err = project.Persist(project)
	}

	if err != nil {
		logger.Errorln("Publish Project error:", err)
	}

	// 发布項目,活跃度+10
	if uid, ok := user["uid"].(int); ok {
		weight := 10
		if isModify {
			weight = 2
		}
		go IncUserWeight("uid="+strconv.Itoa(uid), weight)
	}

	return
}
Пример #16
0
// ParseOneProject 处理单个 project
func ParseOneProject(projectUrl string) error {
	if !strings.HasPrefix(projectUrl, "http") {
		projectUrl = OsChinaDomain + projectUrl
	}

	var (
		doc *goquery.Document
		err error
	)

	// 加上 ?fromerr=xfwefs,否则页面有 js 重定向
	if doc, err = goquery.NewDocument(projectUrl + "?fromerr=xfwefs"); err != nil {
		return errors.New("goquery fetch " + projectUrl + " error:" + err.Error())
	}

	// 标题
	category := strings.TrimSpace(doc.Find(".Project .name").Text())
	name := strings.TrimSpace(doc.Find(".Project .name u").Text())
	if category == "" && name == "" {
		return errors.New("projectUrl:" + projectUrl + " category and name are empty")
	}

	tmpIndex := strings.LastIndex(category, name)
	if tmpIndex != -1 {
		category = category[:tmpIndex]
	}

	// uri
	uri := projectUrl[strings.LastIndex(projectUrl, "/")+1:]

	project := model.NewOpenProject()

	err = project.Where("uri=?", uri).Find("id")
	// 已经存在
	if project.Id != 0 {
		return errors.New("url" + projectUrl + "has exists!")
	}

	logoSelection := doc.Find(".Project .PN img")
	if logoSelection.AttrOr("title", "") != "" {
		project.Logo = logoSelection.AttrOr("src", "")

		if !strings.HasPrefix(project.Logo, "http") {
			project.Logo = OsChinaDomain + project.Logo
		}

		project.Logo, err = UploadUrlFile(project.Logo, ProjectLogoPrefix)
		if err != nil {
			logger.Errorln("project logo upload error:", err)
		}
	}

	// 获取项目相关链接
	doc.Find("#Body .urls li").Each(func(i int, liSelection *goquery.Selection) {
		aSelection := liSelection.Find("a")
		uri := util.FetchRealUrl(OsChinaDomain + aSelection.AttrOr("href", ""))
		switch aSelection.Text() {
		case "软件首页":
			project.Home = uri
		case "软件文档":
			project.Doc = uri
		case "软件下载":
			project.Download = uri
		}
	})

	ctime := util.TimeNow()

	doc.Find("#Body .attrs li").Each(func(i int, liSelection *goquery.Selection) {
		aSelection := liSelection.Find("a")
		txt := aSelection.Text()
		if i == 0 {
			project.Licence = txt
			if txt == "未知" {
				project.Licence = "其他"
			}
		} else if i == 1 {
			project.Lang = txt
		} else if i == 2 {
			project.Os = txt
		} else if i == 3 {
			dtime, err := time.ParseInLocation("2006年01月02日", aSelection.Last().Text(), time.Local)
			if err != nil {
				logger.Errorln("parse ctime error:", err)
			} else {
				ctime = dtime.Local().Format("2006-01-02 15:04:05")
			}
		}
	})

	project.Name = name
	project.Category = category
	project.Uri = uri
	project.Repo = strings.TrimSpace(doc.Find("#Body .github-widget").AttrOr("data-repo", ""))
	project.Src = "https://github.com/" + project.Repo

	pos := strings.Index(project.Repo, "/")
	if pos > -1 {
		project.Author = project.Repo[:pos]
	} else {
		project.Author = "网友"
	}

	if project.Doc == "" {
		// TODO:暂时认为一定是 Go 语言
		project.Doc = "https://godoc.org/" + project.Src[8:]
	}

	desc := ""
	doc.Find("#Body .detail").Find("p").NextAll().Each(func(i int, domSelection *goquery.Selection) {
		doc.FindSelection(domSelection).WrapHtml(`<div id="tmp` + strconv.Itoa(i) + `"></div>`)
		domHtml, _ := doc.Find("#tmp" + strconv.Itoa(i)).Html()
		if domSelection.Is("pre") {
			desc += domHtml + "\n\n"
		} else {
			desc += html2md.Convert(domHtml) + "\n\n"
		}
	})

	project.Desc = strings.TrimSpace(desc)
	project.Username = PresetUsernames[rand.Intn(4)]
	project.Status = model.ProjectStatusOnline
	project.Ctime = ctime

	_, err = project.Insert()
	if err != nil {
		return errors.New("insert into open project error:" + err.Error())
	}

	return nil
}