Пример #1
0
func pkgindex(session *http.Session) {
	if _, ok := session.Stash["repo"]; !ok {
		session.RenderNotFound()
		return
	}

	repo := session.Stash["repo"].(string)

	for fname, _ := range indexes {
		if _, ok := indexes[fname][repo]; !ok && repo != "SmartPAN" {
			session.RenderNotFound()
			return
		}
	}

	if g, ok := session.Stash["gz"]; ok {
		if len(g.(string)) > 0 {
			// cheat and hijack gotchas gzip support
			session.Response.Headers.Set("Content-Type", "application/gzip")
			session.Response.Send()
			session.Response.Gzip()
			session.Response.Headers.Remove("Content-Encoding")
			log.Debug("Using gzip")
		}
	}

	session.Response.WriteText("File:         02packages.details.txt\n")
	session.Response.WriteText("Description:  Package names found in directory " + repo + "/authors/id\n")
	session.Response.WriteText("Columns:      package name, version, path\n")
	session.Response.WriteText("Written-By:   SmartPAN (from GoPAN)\n")
	session.Response.WriteText("Line-Count:   " + strconv.Itoa(summary.Packages) + "\n") // FIXME wrong count
	session.Response.WriteText("\n")

	if repo == "SmartPAN" {
		for _, pkg := range packages {
			writepkgindex(session, pkg)
		}
	} else {
		for _, pkg := range idxpackages[repo] {
			writepkgindex(session, pkg)
		}
	}
}
Пример #2
0
func download(session *http.Session) {
	if _, ok := session.Stash["repo"]; !ok {
		session.RenderNotFound()
		return
	}

	if _, ok := session.Stash["file"]; !ok {
		session.RenderNotFound()
		return
	}

	repo := session.Stash["repo"].(string)
	file := session.Stash["file"].(string)

	if repo == "SmartPAN" {
		if _, ok := filemap[file]; !ok {
			log.Debug("SmartPAN repo - file [%s] not found in any index", file)
			session.RenderNotFound()
			return
		}

		repo = filemap[file]
		log.Debug("SmartPAN repo - file [%s] found in [%s]", file, repo)
	}

	log.Debug("Repo [%s], file [%s]", repo, file)

	nfile := config.CacheDir + "/" + repo + "/" + file

	if _, err := os.Stat(nfile); err != nil {
		log.Debug("File not found on disk, considering readthrough")

		for fn, _ := range indexes {
			log.Debug("Trying file: %s", fn)
			if src, ok := indexes[fn][repo]; ok {
				log.Debug("Found matching repo")
				if strings.HasPrefix(src.URL, "http:") {
					log.Debug("Found HTTP URL, trying: %s", src.URL+"/"+file)

					res, err := nethttp.Get(src.URL + "/" + file)
					if err != nil {
						log.Debug("Error on readthrough: %s", err.Error())
						continue
					}
					defer res.Body.Close()
					b, err := ioutil.ReadAll(res.Body)
					if err != nil {
						log.Debug("Error reading body: %s", err.Error())
						continue
					}

					session.Response.Write(b)
					return
				}
			}
		}

		log.Debug("No readthrough available")
		session.RenderNotFound()
		return
	}

	f, err := os.Open(nfile)
	if err != nil {
		log.Error(err.Error())
		session.RenderNotFound()
		return
	}

	defer f.Close()

	b, err := ioutil.ReadAll(f)
	if err != nil {
		log.Error(err.Error())
		session.RenderNotFound()
		return
	}

	session.Response.Write(b)
}
Пример #3
0
func delete_file(session *http.Session) {
	session.Stash["Title"] = "Delete file"
	html, _ := session.RenderTemplate("delete.html")

	repo := session.Stash["repo"].(string)
	file := session.Stash["file"].(string)
	auth1 := session.Stash["auth1"].(string)
	auth2 := session.Stash["auth2"].(string)
	auth3 := session.Stash["auth3"].(string)

	fname := config.CacheDir + "/" + repo + "/" + auth1 + "/" + auth2 + "/" + auth3 + "/" + file

	if _, err := os.Stat(fname); err != nil {
		session.RenderNotFound()
		return
	}

	// Remove file from indexes
	for f, _ := range indexes {
		if _, ok := indexes[f][repo]; !ok {
			continue
		}
		if _, ok := indexes[f][repo].Authors[auth3]; !ok {
			continue
		}
		if _, ok := indexes[f][repo].Authors[auth3].Packages[file]; !ok {
			continue
		}
		log.Debug("Removing from index: %s", repo)

		pkg := indexes[f][repo].Authors[auth3].Packages[file]
		delete(indexes[f][repo].Authors[auth3].Packages, file)

		if len(indexes[f][repo].Authors[auth3].Packages) == 0 {
			log.Debug("Removing author")
			delete(indexes[f][repo].Authors, auth3)
		}

		if len(indexes[f][repo].Authors) == 0 {
			log.Debug("Removing index")
			delete(indexes[f], repo)
		}

		if auth, ok := mapped[repo][auth1][auth2][auth3]; ok {
			if len(auth.Packages) == 0 {
				log.Debug("Removing author from mapped index")
				delete(mapped[repo][auth1][auth2], auth3)
				delete(mapped[repo]["*"][auth2], auth3)
				delete(mapped[repo][auth1]["**"], auth3)
				delete(mapped[repo]["*"]["**"], auth3)
			}

			if len(mapped[repo][auth1][auth2]) == 0 {
				log.Debug("Removing auth1/auth2 from mapped index")
				delete(mapped[repo][auth1], auth2)
			}

			if len(mapped[repo]["*"][auth2]) == 0 {
				log.Debug("Removing author **/auth2 from mapped index")
				delete(mapped[repo][auth1], auth2)
			}
			if len(mapped[repo][auth1]["**"]) == 0 {
				log.Debug("Removing author auth1/** from mapped index")
				delete(mapped[repo][auth1], auth2)
			}
			if len(mapped[repo]["*"]["**"]) == 0 {
				log.Debug("Removing author */** from mapped index")
				delete(mapped[repo][auth1], auth2)
			}
			if len(mapped[repo]["*"]) == 0 {
				log.Debug("Removing author * from mapped index")
				delete(mapped[repo][auth1], auth2)
			}

			if len(mapped[repo][auth1]) == 1 {
				log.Debug("Removing author auth1 from mapped index")
				delete(mapped[repo], auth1)
			}

			if len(mapped[repo]) == 1 {
				log.Debug("Removing repo from mapped index")
				delete(mapped, repo)
			}
		}

		for _, prov := range pkg.Provides {
			parts := strings.Split(prov.Name, "::")
			// TODO remove from packages/idxpackages
			if ctx, ok := packages[parts[0]]; ok {
				parts = parts[1:]
				for len(parts) > 0 {
					if c, ok := ctx.Children[parts[0]]; ok {
						ctx = c
					} else {
						log.Debug("Package not found in packages: %s", parts)
						break
					}
					parts = parts[1:]
				}
				if len(parts) == 0 {
					for ctx != nil {
						for pi, p := range ctx.Packages {
							if p.Package == pkg {
								log.Debug("Removing package from packages: %s", ctx.FullName())
								ctx.Packages = append(ctx.Packages[:pi], ctx.Packages[pi+1:]...)
								break
							}
						}
						if len(ctx.Packages) == 0 {
							log.Debug("Removing PkgSpace from packages: %s", ctx.FullName())
							if ctx.Parent == nil {
								delete(packages, ctx.Namespace)
							} else {
								delete(ctx.Parent.Children, ctx.Namespace)
							}
						}

						ctx = ctx.Parent
					}
				}
			}
			parts = strings.Split(prov.Name, "::")
			if _, ok := idxpackages[repo]; ok {
				if ctx, ok := idxpackages[repo][parts[0]]; ok {
					parts = parts[1:]
					for len(parts) > 0 {
						if c, ok := ctx.Children[parts[0]]; ok {
							ctx = c
						} else {
							log.Debug("PkgSpace not found in idxpackages")
							break
						}
						parts = parts[1:]
					}
					if len(parts) == 0 {
						for ctx != nil {
							for pi, p := range ctx.Packages {
								if p.Package == pkg {
									log.Debug("Removing package from idxpackages")
									ctx.Packages = append(ctx.Packages[:pi], ctx.Packages[pi+1:]...)
									break
								}
							}
							if len(ctx.Packages) == 0 {
								log.Debug("Removing PkgSpace from idxpackages: %s", ctx.FullName())
								if ctx.Parent == nil {
									delete(idxpackages, ctx.Namespace)
								} else {
									delete(ctx.Parent.Children, ctx.Namespace)
								}
							}

							ctx = ctx.Parent
						}
					}
				}
			}
		}

		if _, ok := filemap[auth1+"/"+auth2+"/"+auth3+"/"+file]; ok {
			log.Debug("Removing file from filemap")
			// FIXME filemap should be map[string][]string, so we know if
			// the file exists in multiple indexes
			delete(filemap, auth1+"/"+auth2+"/"+auth3+"/"+file)
		}

		// write remove to index
		gopan.RemoveModule(config.CacheDir+"/"+config.Index, pkg.Author.Source, pkg.Author, pkg)
	}

	log.Debug("Removing file from gopancache: %s", fname)
	// TODO move file deletion to shared gopan package
	if err := os.Remove(fname); err != nil {
		log.Error("Error removing file: %s", err)
	}

	// TODO maybe clean up author tree (is this smartpans responsibility?)

	nsrc, nauth, npkg, nprov := gopan.CountIndex(indexes)
	// TODO should probably be in the index - needs to udpate when index changes
	summary = &Summary{nsrc, nauth, npkg, nprov}

	session.Stash["Page"] = "Browse"
	session.Stash["Content"] = template.HTML(html)
	session.Render("layout.html")
}
Пример #4
0
func getindex(session *http.Session) {
	idx := session.Stash["index"]

	switch idx {
	case "CPAN":
		go func() {
			config.CPANStatus = "Downloading"

			res, err := nethttp.Get("https://s3-eu-west-1.amazonaws.com/gopan/cpan_index.gz")
			if err != nil {
				log.Error("Error downloading index: %s", err.Error())
				session.RenderException(500, errors.New("Error downloading CPAN index: "+err.Error()))
				config.CPANStatus = "Failed"
				return
			}
			defer res.Body.Close()
			b, err := ioutil.ReadAll(res.Body)
			if err != nil {
				log.Error("Error reading index: %s", err.Error())
				session.RenderException(500, errors.New("Error reading CPAN index: "+err.Error()))
				config.CPANStatus = "Failed"
				return
			}
			fi, err := os.Create(config.CacheDir + "/" + config.CPANIndex)
			if err != nil {
				log.Error("Error creating output file: %s", err.Error())
				session.RenderException(500, errors.New("Error creating output file: "+err.Error()))
				config.CPANStatus = "Failed"
				return
			}
			defer fi.Close()
			fi.Write(b)

			config.CPANStatus = "Downloaded"
			config.HasCPANIndex = true
			config.CPANIndexDate = time.Now().String()

			config.CPANStatus = "Loading"
			load_index(config.CPANIndex, config.CacheDir+"/"+config.CPANIndex)

			config.CPANStatus = "Indexing"
			update_indexes()

			config.CPANStatus = "Loaded"
		}()

		session.Redirect(&url.URL{Path: "/settings"})
		return
	case "BackPAN":
		go func() {
			config.BackPANStatus = "Downloading"

			res, err := nethttp.Get("https://s3-eu-west-1.amazonaws.com/gopan/backpan_index.gz")
			if err != nil {
				log.Error("Error downloading index: %s", err.Error())
				session.RenderException(500, errors.New("Error downloading BackPAN index: "+err.Error()))
				config.BackPANStatus = "Failed"
				return
			}
			defer res.Body.Close()
			b, err := ioutil.ReadAll(res.Body)
			if err != nil {
				log.Error("Error reading index: %s", err.Error())
				session.RenderException(500, errors.New("Error reading BackPAN index: "+err.Error()))
				config.BackPANStatus = "Failed"
				return
			}
			fi, err := os.Create(config.CacheDir + "/" + config.BackPANIndex)
			if err != nil {
				log.Error("Error creating output file: %s", err.Error())
				session.RenderException(500, errors.New("Error creating output file: "+err.Error()))
				config.BackPANStatus = "Failed"
				return
			}
			defer fi.Close()
			fi.Write(b)

			config.BackPANStatus = "Downloaded"
			config.HasBackPANIndex = true
			config.BackPANIndexDate = time.Now().String()

			config.BackPANStatus = "Loading"
			load_index(config.BackPANIndex, config.CacheDir+"/"+config.BackPANIndex)

			config.BackPANStatus = "Indexing"
			update_indexes()

			config.BackPANStatus = "Loaded"
		}()

		session.Redirect(&url.URL{Path: "/settings"})
		return
	}

	session.RenderNotFound()
}
Пример #5
0
func browse(session *http.Session) {
	session.Stash["Title"] = "SmartPAN"

	path := ""
	repo := ""
	itype := ""
	fpath := ""
	if r, ok := session.Stash["repo"]; ok {
		repo = r.(string)
		fpath += repo + "/"

		found := false
		if repo == "SmartPAN" {
			found = true
		} else {
			for fname, _ := range indexes {
				if _, ok := indexes[fname][repo]; ok {
					found = true
					break
				}
			}
		}

		if !found {
			session.RenderNotFound()
			return
		}
	}
	if i, ok := session.Stash["type"]; ok {
		itype = i.(string)
		fpath += itype + "/"
	}
	if p, ok := session.Stash["path"]; ok {
		path = p.(string)
		fpath += path + "/"
	}

	fpath = strings.TrimSuffix(fpath, "/")
	session.Stash["path"] = fpath

	bits := strings.Split(path, "/")
	fbits := strings.Split(fpath, "/")
	dirs := make(map[string]map[string]string, 0)
	files := make(map[string]map[string]string, 0)

	log.Info("Path: %s, Bits: %d", path, len(bits))

	if repo == "" {
		dirs = toplevelRepo()
	} else if itype == "" {
		dirs, files = tlRepo1(repo)
	} else {
		switch itype {
		case "authors":
			if len(path) == 0 {
				dirs, files = tlRepo2(repo, itype)
			} else {
				switch len(bits) {
				case 1:
					log.Info("tlAuthor1")
					dirs = tlAuthor1(repo)
				case 2:
					log.Info("tlAuthor2: %s", bits[1])
					dirs = tlAuthor2(repo, bits[1])
				case 3:
					log.Info("tlAuthor3: %s, %s", bits[1], bits[2])
					dirs = tlAuthor3(repo, bits[1], bits[2])
				case 4:
					log.Info("tlModuleList: %s, %s", repo, bits[1], bits[2], bits[3])
					files = tlModuleList(repo, bits[1], bits[2], bits[3])
				default:
					log.Info("Invalid path - rendering not found")
					session.RenderNotFound()
				}
			}
		case "modules":
			if path == "" {
				dirs, files = tlRepo2(repo, itype)
			} else {
				if repo == "SmartPAN" {
					rbits := bits[1:]
					ctx := packages[bits[0]]
					log.Info("Starting with context: %s", ctx.Namespace)
					for len(rbits) > 0 {
						ctx = ctx.Children[rbits[0]]
						rbits = rbits[1:]
					}
					log.Info("Stashing package context: %s", ctx.Namespace)
					session.Stash["Package"] = ctx
					for ns, _ := range ctx.Children {
						files[ns] = map[string]string{
							"Name": ns,
							"Path": "/" + repo + "/modules/" + path + "/" + ns,
						}
					}
				} else {
					rbits := bits[1:]
					ctx := idxpackages[repo][bits[0]]
					log.Info("Starting with context: %s", ctx.Namespace)
					for len(rbits) > 0 {
						ctx = ctx.Children[rbits[0]]
						rbits = rbits[1:]
					}
					session.Stash["Package"] = ctx
					log.Info("Stashing package context: %s", ctx.Namespace)
					for ns, _ := range ctx.Children {
						files[ns] = map[string]string{
							"Name": ns,
							"Path": "/" + repo + "/modules/" + path + "/" + ns,
						}
					}
				}
			}
		default:
			session.RenderNotFound()
		}
	}

	session.Stash["Dirs"] = dirs
	session.Stash["Files"] = files

	pp := make([]map[string]string, 0)
	cp := ""
	for _, b := range fbits {
		cp = cp + "/" + b
		pp = append(pp, map[string]string{
			"Name": b,
			"Path": cp,
		})
	}

	if len(pp) > 0 && len(pp[0]["Name"]) > 0 {
		session.Stash["PathBits"] = pp
	}

	html, _ := session.RenderTemplate("browse.html")

	session.Stash["Page"] = "Browse"
	session.Stash["Content"] = template.HTML(html)
	session.Render("layout.html")
}