✨ Download Count for Packages
This commit is contained in:
parent
6c1ca1e8c0
commit
13b0b6095e
4 changed files with 64 additions and 3 deletions
9
migrations/0001_pkg_meta.sql
Normal file
9
migrations/0001_pkg_meta.sql
Normal file
|
@ -0,0 +1,9 @@
|
|||
CREATE TABLE IF NOT EXISTS package_meta (
|
||||
repo TEXT NOT NULL,
|
||||
name TEXT NOT NULL,
|
||||
arch TEXT NOT NULL,
|
||||
version TEXT NOT NULL,
|
||||
rel INTEGER NOT NULL,
|
||||
download_count INTEGER NOT NULL DEFAULT 1,
|
||||
PRIMARY KEY (repo, name, arch, version, rel)
|
||||
);
|
|
@ -4,6 +4,8 @@ use std::{
|
|||
path::{Path, PathBuf},
|
||||
};
|
||||
|
||||
use based::get_pg;
|
||||
use sqlx::FromRow;
|
||||
use tar::Archive;
|
||||
|
||||
use super::{Repository, arch::Architecture};
|
||||
|
@ -17,14 +19,14 @@ pub struct Package {
|
|||
pub arch: Architecture,
|
||||
/// Name of the package
|
||||
pub name: String,
|
||||
pub rel: u64,
|
||||
pub rel: i32,
|
||||
/// Version of the package
|
||||
pub version: Option<String>,
|
||||
}
|
||||
|
||||
impl Package {
|
||||
/// Create a new package
|
||||
pub fn new(repo: &str, arch: Architecture, pkg_name: &str, version: &str, rel: u64) -> Self {
|
||||
pub fn new(repo: &str, arch: Architecture, pkg_name: &str, version: &str, rel: i32) -> Self {
|
||||
let pkg = Package {
|
||||
repo: repo.to_string(),
|
||||
arch,
|
||||
|
@ -37,7 +39,7 @@ impl Package {
|
|||
pkg
|
||||
}
|
||||
|
||||
pub fn version(ver: &str) -> (String, u64) {
|
||||
pub fn version(ver: &str) -> (String, i32) {
|
||||
let mut splitted = ver.split('-').collect::<Vec<_>>();
|
||||
let rel = splitted.pop().unwrap();
|
||||
let ver = splitted.join("-");
|
||||
|
@ -402,3 +404,42 @@ pub fn list_tar_file(tar: &PathBuf) -> Option<Vec<String>> {
|
|||
|
||||
Some(paths)
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, FromRow)]
|
||||
pub struct PackageMeta {
|
||||
pub repo: String,
|
||||
pub name: String,
|
||||
pub arch: String,
|
||||
pub version: String,
|
||||
pub rel: String,
|
||||
pub download_count: i32,
|
||||
}
|
||||
|
||||
pub trait PackageMetaInfo {
|
||||
fn download_amount(&self) -> impl std::future::Future<Output = i32>;
|
||||
fn increase_download_count(&self) -> impl std::future::Future<Output = ()>;
|
||||
}
|
||||
|
||||
impl PackageMetaInfo for Package {
|
||||
async fn download_amount(&self) -> i32 {
|
||||
let res: Option<(i32,)> = sqlx::query_as("SELECT download_count FROM package_meta WHERE repo = $1 AND name = $2 AND version = $3 AND arch = $4 AND rel = $5")
|
||||
.bind(&self.repo)
|
||||
.bind(&self.name)
|
||||
.bind(self.version.as_ref().unwrap())
|
||||
.bind(&self.arch.to_string())
|
||||
.bind(&self.rel)
|
||||
.fetch_optional(get_pg!()).await.unwrap();
|
||||
|
||||
res.map(|x| x.0).unwrap_or(0)
|
||||
}
|
||||
|
||||
async fn increase_download_count(&self) {
|
||||
sqlx::query("INSERT INTO package_meta (repo, name, arch, version, rel) VALUES ($1, $2, $3, $4, $5) ON CONFLICT (repo, name, arch, version, rel) DO UPDATE SET download_count = package_meta.download_count + 1")
|
||||
.bind(&self.repo)
|
||||
.bind(&self.name)
|
||||
.bind(&self.arch.to_string())
|
||||
.bind(&self.version.as_ref().map(|x| x.to_string()).unwrap_or_default())
|
||||
.bind(&self.rel)
|
||||
.execute(get_pg!()).await.unwrap();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@ use based::ui::components::Shell;
|
|||
use based::ui::{prelude::*, render_page};
|
||||
use maud::{PreEscaped, Render, html};
|
||||
use pacco::pkg::mirror::MirrorRepository;
|
||||
use pacco::pkg::package::PackageMetaInfo;
|
||||
use rocket::http::{ContentType, Status};
|
||||
use rocket::{State, get};
|
||||
|
||||
|
@ -98,6 +99,7 @@ pub async fn pkg_route(
|
|||
.unwrap();
|
||||
|
||||
if pkg_name.ends_with("pkg.tar.zst") {
|
||||
pkg.increase_download_count().await;
|
||||
return respond_with(
|
||||
Status::Ok,
|
||||
ContentType::new("application", "tar"),
|
||||
|
|
|
@ -4,6 +4,7 @@ use based::ui::primitives::space::SpaceBetweenWidget;
|
|||
use based::ui::primitives::text::{Code, TextWidget};
|
||||
use based::ui::{UIWidget, prelude::*};
|
||||
use maud::{PreEscaped, Render, html};
|
||||
use pacco::pkg::package::PackageMetaInfo;
|
||||
use rocket::{State, get};
|
||||
|
||||
use pacco::pkg::{Package, Repository, arch::Architecture, find_package_by_name};
|
||||
|
@ -30,6 +31,8 @@ pub async fn pkg_ui(
|
|||
pkg.rel = rel;
|
||||
}
|
||||
|
||||
let dl_count = pkg.download_amount().await;
|
||||
|
||||
let versions = pkg.versions();
|
||||
let arch = pkg.arch();
|
||||
let install_script = pkg.install_script();
|
||||
|
@ -118,6 +121,9 @@ pub async fn pkg_ui(
|
|||
take_out(&mut pkginfo, |x| { x.0 == "size" }).1,
|
||||
|x: (String, String)| build_info(x.0, x.1)
|
||||
)
|
||||
.push(
|
||||
build_info("download_amount".to_string(), dl_count.to_string())
|
||||
)
|
||||
.push_for_each(&pkginfo, |(key, val)| build_info(key.clone(), val.clone()))
|
||||
).y(ScreenValue::_2)).all(ScreenValue::_4)).all(ScreenValue::_2)).size(Size::Large)))))
|
||||
)).push(
|
||||
|
@ -413,6 +419,9 @@ pub async fn repo_ui(
|
|||
|
||||
pub fn build_info(key: String, value: String) -> PreEscaped<String> {
|
||||
match key.as_str() {
|
||||
"download_amount" => {
|
||||
return key_value("Downloads".to_string(), value);
|
||||
}
|
||||
"pkgname" => {}
|
||||
"xdata" => {}
|
||||
"arch" => {}
|
||||
|
|
Loading…
Add table
Reference in a new issue