sync every hour the latest version of packages with aur
display current version and if outdated in ui display correct time in output log
This commit is contained in:
		@@ -27,9 +27,9 @@ FROM archlinux
 | 
				
			|||||||
# Copy the built binary from the previous stage
 | 
					# Copy the built binary from the previous stage
 | 
				
			||||||
COPY --from=builder /app/target/release/untitled /usr/local/bin/untitled
 | 
					COPY --from=builder /app/target/release/untitled /usr/local/bin/untitled
 | 
				
			||||||
 | 
					
 | 
				
			||||||
RUN echo " \
 | 
					RUN echo $'\
 | 
				
			||||||
[extra]\
 | 
					[extra]\
 | 
				
			||||||
Include = /etc/pacman.d/mirrorlist" >> /etc/pacman.conf
 | 
					Include = /etc/pacman.d/mirrorlist' >> /etc/pacman.conf
 | 
				
			||||||
 | 
					
 | 
				
			||||||
RUN pacman -Syyu --noconfirm
 | 
					RUN pacman -Syyu --noconfirm
 | 
				
			||||||
RUN pacman-key --init && pacman-key --populate
 | 
					RUN pacman-key --init && pacman-key --populate
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1188,8 +1188,8 @@ fi
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
if (( ! INFAKEROOT )); then
 | 
					if (( ! INFAKEROOT )); then
 | 
				
			||||||
	if (( EUID == 0 )); then
 | 
						if (( EUID == 0 )); then
 | 
				
			||||||
		error "$(gettext "Running %s as root is not allowed as it can cause permanent,\n\
 | 
							: #error "$(gettext "Running %s as root is not allowed as it can cause permanent,\n\
 | 
				
			||||||
catastrophic damage to your system.")" "makepkg"
 | 
					#catastrophic damage to your system.")" "makepkg"
 | 
				
			||||||
		#exit $E_ROOT
 | 
							#exit $E_ROOT
 | 
				
			||||||
	fi
 | 
						fi
 | 
				
			||||||
else
 | 
					else
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -9,9 +9,9 @@ use rocket::serde::{Deserialize, Serialize};
 | 
				
			|||||||
use rocket::{get, State};
 | 
					use rocket::{get, State};
 | 
				
			||||||
use rocket_okapi::okapi::schemars;
 | 
					use rocket_okapi::okapi::schemars;
 | 
				
			||||||
use rocket_okapi::{openapi, JsonSchema};
 | 
					use rocket_okapi::{openapi, JsonSchema};
 | 
				
			||||||
use sea_orm::PaginatorTrait;
 | 
					 | 
				
			||||||
use sea_orm::{ColumnTrait, QueryFilter};
 | 
					use sea_orm::{ColumnTrait, QueryFilter};
 | 
				
			||||||
use sea_orm::{DatabaseConnection, EntityTrait, FromQueryResult, QuerySelect, RelationTrait};
 | 
					use sea_orm::{DatabaseConnection, EntityTrait, FromQueryResult, QuerySelect, RelationTrait};
 | 
				
			||||||
 | 
					use sea_orm::{Order, PaginatorTrait, QueryOrder};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#[derive(Serialize, JsonSchema)]
 | 
					#[derive(Serialize, JsonSchema)]
 | 
				
			||||||
#[serde(crate = "rocket::serde")]
 | 
					#[serde(crate = "rocket::serde")]
 | 
				
			||||||
@@ -43,8 +43,11 @@ pub async fn search(query: &str) -> Result<Json<Vec<ApiPackage>>, String> {
 | 
				
			|||||||
pub struct ListPackageModel {
 | 
					pub struct ListPackageModel {
 | 
				
			||||||
    id: i32,
 | 
					    id: i32,
 | 
				
			||||||
    name: String,
 | 
					    name: String,
 | 
				
			||||||
    count: i32,
 | 
					 | 
				
			||||||
    status: i32,
 | 
					    status: i32,
 | 
				
			||||||
 | 
					    outofdate: bool,
 | 
				
			||||||
 | 
					    latest_version: String,
 | 
				
			||||||
 | 
					    latest_version_id: i32,
 | 
				
			||||||
 | 
					    latest_aur_version: String,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#[openapi(tag = "test")]
 | 
					#[openapi(tag = "test")]
 | 
				
			||||||
@@ -55,13 +58,15 @@ pub async fn package_list(
 | 
				
			|||||||
    let db = db as &DatabaseConnection;
 | 
					    let db = db as &DatabaseConnection;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    let all: Vec<ListPackageModel> = Packages::find()
 | 
					    let all: Vec<ListPackageModel> = Packages::find()
 | 
				
			||||||
        .join_rev(JoinType::InnerJoin, versions::Relation::Packages.def())
 | 
					        .join_rev(JoinType::InnerJoin, versions::Relation::LatestPackage.def())
 | 
				
			||||||
        .select_only()
 | 
					        .select_only()
 | 
				
			||||||
        .column_as(versions::Column::Id.count(), "count")
 | 
					 | 
				
			||||||
        .column(packages::Column::Name)
 | 
					        .column(packages::Column::Name)
 | 
				
			||||||
        .column(packages::Column::Id)
 | 
					        .column(packages::Column::Id)
 | 
				
			||||||
        .column(packages::Column::Status)
 | 
					        .column(packages::Column::Status)
 | 
				
			||||||
        .group_by(packages::Column::Name)
 | 
					        .column_as(packages::Column::OutOfDate, "outofdate")
 | 
				
			||||||
 | 
					        .column_as(packages::Column::LatestAurVersion, "latest_aur_version")
 | 
				
			||||||
 | 
					        .column_as(versions::Column::Version, "latest_version")
 | 
				
			||||||
 | 
					        .column_as(packages::Column::LatestVersionId, "latest_version_id")
 | 
				
			||||||
        .into_model::<ListPackageModel>()
 | 
					        .into_model::<ListPackageModel>()
 | 
				
			||||||
        .all(db)
 | 
					        .all(db)
 | 
				
			||||||
        .await
 | 
					        .await
 | 
				
			||||||
@@ -146,6 +151,8 @@ pub struct ListBuildsModel {
 | 
				
			|||||||
    pkg_name: String,
 | 
					    pkg_name: String,
 | 
				
			||||||
    version: String,
 | 
					    version: String,
 | 
				
			||||||
    status: i32,
 | 
					    status: i32,
 | 
				
			||||||
 | 
					    start_time: Option<u32>,
 | 
				
			||||||
 | 
					    end_time: Option<u32>,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#[openapi(tag = "test")]
 | 
					#[openapi(tag = "test")]
 | 
				
			||||||
@@ -165,6 +172,9 @@ pub async fn list_builds(
 | 
				
			|||||||
        .column(builds::Column::Status)
 | 
					        .column(builds::Column::Status)
 | 
				
			||||||
        .column_as(packages::Column::Name, "pkg_name")
 | 
					        .column_as(packages::Column::Name, "pkg_name")
 | 
				
			||||||
        .column(versions::Column::Version)
 | 
					        .column(versions::Column::Version)
 | 
				
			||||||
 | 
					        .column(builds::Column::EndTime)
 | 
				
			||||||
 | 
					        .column(builds::Column::StartTime)
 | 
				
			||||||
 | 
					        .order_by(builds::Column::StartTime, Order::Desc)
 | 
				
			||||||
        .limit(limit);
 | 
					        .limit(limit);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    let build = match pkgid {
 | 
					    let build = match pkgid {
 | 
				
			||||||
@@ -197,6 +207,8 @@ pub async fn get_build(
 | 
				
			|||||||
        .column(builds::Column::Status)
 | 
					        .column(builds::Column::Status)
 | 
				
			||||||
        .column_as(packages::Column::Name, "pkg_name")
 | 
					        .column_as(packages::Column::Name, "pkg_name")
 | 
				
			||||||
        .column(versions::Column::Version)
 | 
					        .column(versions::Column::Version)
 | 
				
			||||||
 | 
					        .column(builds::Column::EndTime)
 | 
				
			||||||
 | 
					        .column(builds::Column::StartTime)
 | 
				
			||||||
        .into_model::<ListBuildsModel>()
 | 
					        .into_model::<ListBuildsModel>()
 | 
				
			||||||
        .one(db)
 | 
					        .one(db)
 | 
				
			||||||
        .await
 | 
					        .await
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -5,6 +5,7 @@ use crate::repo::repo::add_pkg;
 | 
				
			|||||||
use anyhow::anyhow;
 | 
					use anyhow::anyhow;
 | 
				
			||||||
use sea_orm::{ActiveModelTrait, DatabaseConnection, EntityTrait, Set};
 | 
					use sea_orm::{ActiveModelTrait, DatabaseConnection, EntityTrait, Set};
 | 
				
			||||||
use std::ops::Add;
 | 
					use std::ops::Add;
 | 
				
			||||||
 | 
					use std::time::{SystemTime, UNIX_EPOCH};
 | 
				
			||||||
use tokio::sync::broadcast;
 | 
					use tokio::sync::broadcast;
 | 
				
			||||||
use tokio::sync::broadcast::error::RecvError;
 | 
					use tokio::sync::broadcast::error::RecvError;
 | 
				
			||||||
use tokio::sync::broadcast::Sender;
 | 
					use tokio::sync::broadcast::Sender;
 | 
				
			||||||
@@ -16,12 +17,17 @@ pub async fn init(db: DatabaseConnection, tx: Sender<Action>) {
 | 
				
			|||||||
                // add a package to parallel build
 | 
					                // add a package to parallel build
 | 
				
			||||||
                Action::Build(name, version, url, mut version_model) => {
 | 
					                Action::Build(name, version, url, mut version_model) => {
 | 
				
			||||||
                    let db = db.clone();
 | 
					                    let db = db.clone();
 | 
				
			||||||
 | 
					 | 
				
			||||||
                    let build = builds::ActiveModel {
 | 
					                    let build = builds::ActiveModel {
 | 
				
			||||||
                        pkg_id: version_model.package_id.clone(),
 | 
					                        pkg_id: version_model.package_id.clone(),
 | 
				
			||||||
                        version_id: version_model.id.clone(),
 | 
					                        version_id: version_model.id.clone(),
 | 
				
			||||||
                        ouput: Set(None),
 | 
					                        ouput: Set(None),
 | 
				
			||||||
                        status: Set(Some(0)),
 | 
					                        status: Set(Some(0)),
 | 
				
			||||||
 | 
					                        start_time: Set(Some(
 | 
				
			||||||
 | 
					                            SystemTime::now()
 | 
				
			||||||
 | 
					                                .duration_since(UNIX_EPOCH)
 | 
				
			||||||
 | 
					                                .unwrap()
 | 
				
			||||||
 | 
					                                .as_secs() as u32,
 | 
				
			||||||
 | 
					                        )),
 | 
				
			||||||
                        ..Default::default()
 | 
					                        ..Default::default()
 | 
				
			||||||
                    };
 | 
					                    };
 | 
				
			||||||
                    let mut new_build = build.save(&db).await.unwrap();
 | 
					                    let mut new_build = build.save(&db).await.unwrap();
 | 
				
			||||||
@@ -62,6 +68,8 @@ pub async fn init(db: DatabaseConnection, tx: Sender<Action>) {
 | 
				
			|||||||
                                let _ = set_pkg_status(
 | 
					                                let _ = set_pkg_status(
 | 
				
			||||||
                                    &db,
 | 
					                                    &db,
 | 
				
			||||||
                                    version_model.package_id.clone().unwrap(),
 | 
					                                    version_model.package_id.clone().unwrap(),
 | 
				
			||||||
 | 
					                                    version_model.id.clone().unwrap(),
 | 
				
			||||||
 | 
					                                    Some(false),
 | 
				
			||||||
                                    1,
 | 
					                                    1,
 | 
				
			||||||
                                )
 | 
					                                )
 | 
				
			||||||
                                .await;
 | 
					                                .await;
 | 
				
			||||||
@@ -70,18 +78,32 @@ pub async fn init(db: DatabaseConnection, tx: Sender<Action>) {
 | 
				
			|||||||
                                let _ = version_model.update(&db).await;
 | 
					                                let _ = version_model.update(&db).await;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                                new_build.status = Set(Some(1));
 | 
					                                new_build.status = Set(Some(1));
 | 
				
			||||||
 | 
					                                new_build.end_time = Set(Some(
 | 
				
			||||||
 | 
					                                    SystemTime::now()
 | 
				
			||||||
 | 
					                                        .duration_since(UNIX_EPOCH)
 | 
				
			||||||
 | 
					                                        .unwrap()
 | 
				
			||||||
 | 
					                                        .as_secs() as u32,
 | 
				
			||||||
 | 
					                                ));
 | 
				
			||||||
                                let _ = new_build.update(&db).await;
 | 
					                                let _ = new_build.update(&db).await;
 | 
				
			||||||
                            }
 | 
					                            }
 | 
				
			||||||
                            Err(e) => {
 | 
					                            Err(e) => {
 | 
				
			||||||
                                let _ = set_pkg_status(
 | 
					                                let _ = set_pkg_status(
 | 
				
			||||||
                                    &db,
 | 
					                                    &db,
 | 
				
			||||||
                                    version_model.package_id.clone().unwrap(),
 | 
					                                    version_model.package_id.clone().unwrap(),
 | 
				
			||||||
 | 
					                                    version_model.id.clone().unwrap(),
 | 
				
			||||||
 | 
					                                    None,
 | 
				
			||||||
                                    2,
 | 
					                                    2,
 | 
				
			||||||
                                )
 | 
					                                )
 | 
				
			||||||
                                .await;
 | 
					                                .await;
 | 
				
			||||||
                                let _ = version_model.update(&db).await;
 | 
					                                let _ = version_model.update(&db).await;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                                new_build.status = Set(Some(2));
 | 
					                                new_build.status = Set(Some(2));
 | 
				
			||||||
 | 
					                                new_build.end_time = Set(Some(
 | 
				
			||||||
 | 
					                                    SystemTime::now()
 | 
				
			||||||
 | 
					                                        .duration_since(UNIX_EPOCH)
 | 
				
			||||||
 | 
					                                        .unwrap()
 | 
				
			||||||
 | 
					                                        .as_secs() as u32,
 | 
				
			||||||
 | 
					                                ));
 | 
				
			||||||
                                let _ = new_build.update(&db).await;
 | 
					                                let _ = new_build.update(&db).await;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                                println!("Error: {e}")
 | 
					                                println!("Error: {e}")
 | 
				
			||||||
@@ -98,6 +120,8 @@ pub async fn init(db: DatabaseConnection, tx: Sender<Action>) {
 | 
				
			|||||||
async fn set_pkg_status(
 | 
					async fn set_pkg_status(
 | 
				
			||||||
    db: &DatabaseConnection,
 | 
					    db: &DatabaseConnection,
 | 
				
			||||||
    package_id: i32,
 | 
					    package_id: i32,
 | 
				
			||||||
 | 
					    version_id: i32,
 | 
				
			||||||
 | 
					    outofdate: Option<bool>,
 | 
				
			||||||
    status: i32,
 | 
					    status: i32,
 | 
				
			||||||
) -> anyhow::Result<()> {
 | 
					) -> anyhow::Result<()> {
 | 
				
			||||||
    let mut pkg: packages::ActiveModel = Packages::find_by_id(package_id)
 | 
					    let mut pkg: packages::ActiveModel = Packages::find_by_id(package_id)
 | 
				
			||||||
@@ -107,6 +131,10 @@ async fn set_pkg_status(
 | 
				
			|||||||
        .into();
 | 
					        .into();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    pkg.status = Set(status);
 | 
					    pkg.status = Set(status);
 | 
				
			||||||
 | 
					    pkg.latest_version_id = Set(Some(version_id));
 | 
				
			||||||
 | 
					    if outofdate.is_some() {
 | 
				
			||||||
 | 
					        pkg.out_of_date = Set(outofdate.unwrap() as i32)
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
    pkg.update(db).await?;
 | 
					    pkg.update(db).await?;
 | 
				
			||||||
    Ok(())
 | 
					    Ok(())
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -14,6 +14,8 @@ pub struct Model {
 | 
				
			|||||||
    pub version_id: i32,
 | 
					    pub version_id: i32,
 | 
				
			||||||
    pub ouput: Option<String>,
 | 
					    pub ouput: Option<String>,
 | 
				
			||||||
    pub status: Option<i32>,
 | 
					    pub status: Option<i32>,
 | 
				
			||||||
 | 
					    pub start_time: Option<u32>,
 | 
				
			||||||
 | 
					    pub end_time: Option<u32>,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
 | 
					#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -19,7 +19,9 @@ create table builds
 | 
				
			|||||||
	pkg_id integer not null,
 | 
						pkg_id integer not null,
 | 
				
			||||||
	version_id integer not null,
 | 
						version_id integer not null,
 | 
				
			||||||
	ouput TEXT,
 | 
						ouput TEXT,
 | 
				
			||||||
	status integer
 | 
						status integer,
 | 
				
			||||||
 | 
						start_time INTEGER,
 | 
				
			||||||
 | 
						end_time integer
 | 
				
			||||||
);
 | 
					);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
create table packages
 | 
					create table packages
 | 
				
			||||||
@@ -27,7 +29,12 @@ create table packages
 | 
				
			|||||||
	id integer not null
 | 
						id integer not null
 | 
				
			||||||
		primary key autoincrement,
 | 
							primary key autoincrement,
 | 
				
			||||||
	name text not null,
 | 
						name text not null,
 | 
				
			||||||
	status integer default 0 not null
 | 
						status integer default 0 not null,
 | 
				
			||||||
 | 
						out_of_date INTEGER default 0 not null,
 | 
				
			||||||
 | 
						latest_version_id integer
 | 
				
			||||||
 | 
							constraint packages_versions_id_fk
 | 
				
			||||||
 | 
								references versions,
 | 
				
			||||||
 | 
						latest_aur_version TEXT
 | 
				
			||||||
);
 | 
					);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
create table status
 | 
					create table status
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -12,6 +12,9 @@ pub struct Model {
 | 
				
			|||||||
    pub id: i32,
 | 
					    pub id: i32,
 | 
				
			||||||
    pub name: String,
 | 
					    pub name: String,
 | 
				
			||||||
    pub status: i32,
 | 
					    pub status: i32,
 | 
				
			||||||
 | 
					    pub out_of_date: i32,
 | 
				
			||||||
 | 
					    pub latest_version_id: Option<i32>,
 | 
				
			||||||
 | 
					    pub latest_aur_version: Option<String>,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
impl ActiveModelBehavior for ActiveModel {}
 | 
					impl ActiveModelBehavior for ActiveModel {}
 | 
				
			||||||
@@ -22,6 +25,8 @@ pub enum Relation {
 | 
				
			|||||||
    Versions,
 | 
					    Versions,
 | 
				
			||||||
    #[sea_orm(has_many = "super::builds::Entity")]
 | 
					    #[sea_orm(has_many = "super::builds::Entity")]
 | 
				
			||||||
    Builds,
 | 
					    Builds,
 | 
				
			||||||
 | 
					    #[sea_orm(has_one = "super::versions::Entity")]
 | 
				
			||||||
 | 
					    LatestVersion,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
impl Related<super::versions::Entity> for Entity {
 | 
					impl Related<super::versions::Entity> for Entity {
 | 
				
			||||||
@@ -30,8 +35,14 @@ impl Related<super::versions::Entity> for Entity {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// impl Related<super::versions::Entity> for Entity {
 | 
				
			||||||
 | 
					//     fn to() -> RelationDef {
 | 
				
			||||||
 | 
					//         Relation::LatestVersion.def()
 | 
				
			||||||
 | 
					//     }
 | 
				
			||||||
 | 
					// }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
impl Related<super::builds::Entity> for crate::db::versions::Entity {
 | 
					impl Related<super::builds::Entity> for crate::db::versions::Entity {
 | 
				
			||||||
    fn to() -> RelationDef {
 | 
					    fn to() -> RelationDef {
 | 
				
			||||||
        crate::db::versions::Relation::Builds.def()
 | 
					        Relation::Builds.def()
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -23,6 +23,12 @@ pub enum Relation {
 | 
				
			|||||||
        to = "super::packages::Column::Id"
 | 
					        to = "super::packages::Column::Id"
 | 
				
			||||||
    )]
 | 
					    )]
 | 
				
			||||||
    Packages,
 | 
					    Packages,
 | 
				
			||||||
 | 
					    #[sea_orm(
 | 
				
			||||||
 | 
					        belongs_to = "super::packages::Entity",
 | 
				
			||||||
 | 
					        from = "Column::Id",
 | 
				
			||||||
 | 
					        to = "super::packages::Column::LatestVersionId"
 | 
				
			||||||
 | 
					    )]
 | 
				
			||||||
 | 
					    LatestPackage,
 | 
				
			||||||
    #[sea_orm(has_many = "super::builds::Entity")]
 | 
					    #[sea_orm(has_many = "super::builds::Entity")]
 | 
				
			||||||
    Builds,
 | 
					    Builds,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -4,6 +4,7 @@ mod builder;
 | 
				
			|||||||
mod db;
 | 
					mod db;
 | 
				
			||||||
mod pkgbuild;
 | 
					mod pkgbuild;
 | 
				
			||||||
mod repo;
 | 
					mod repo;
 | 
				
			||||||
 | 
					mod scheduler;
 | 
				
			||||||
mod utils;
 | 
					mod utils;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use crate::api::backend;
 | 
					use crate::api::backend;
 | 
				
			||||||
@@ -11,6 +12,7 @@ use crate::api::backend;
 | 
				
			|||||||
use crate::api::embed::CustomHandler;
 | 
					use crate::api::embed::CustomHandler;
 | 
				
			||||||
use crate::builder::types::Action;
 | 
					use crate::builder::types::Action;
 | 
				
			||||||
use crate::db::migration::Migrator;
 | 
					use crate::db::migration::Migrator;
 | 
				
			||||||
 | 
					use crate::scheduler::aur_version_update::start_aur_version_checking;
 | 
				
			||||||
use rocket::config::Config;
 | 
					use rocket::config::Config;
 | 
				
			||||||
use rocket::fs::FileServer;
 | 
					use rocket::fs::FileServer;
 | 
				
			||||||
use rocket::futures::future::join_all;
 | 
					use rocket::futures::future::join_all;
 | 
				
			||||||
@@ -48,6 +50,8 @@ fn main() {
 | 
				
			|||||||
            builder::builder::init(db2, tx2).await;
 | 
					            builder::builder::init(db2, tx2).await;
 | 
				
			||||||
        });
 | 
					        });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        start_aur_version_checking(db.clone());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        let backend_handle = tokio::spawn(async {
 | 
					        let backend_handle = tokio::spawn(async {
 | 
				
			||||||
            let mut config = Config::default();
 | 
					            let mut config = Config::default();
 | 
				
			||||||
            config.address = "0.0.0.0".parse().unwrap();
 | 
					            config.address = "0.0.0.0".parse().unwrap();
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										55
									
								
								backend/src/scheduler/aur_version_update.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										55
									
								
								backend/src/scheduler/aur_version_update.rs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,55 @@
 | 
				
			|||||||
 | 
					use crate::db::packages;
 | 
				
			||||||
 | 
					use crate::db::prelude::Packages;
 | 
				
			||||||
 | 
					use anyhow::anyhow;
 | 
				
			||||||
 | 
					use aur_rs::{Package, Request};
 | 
				
			||||||
 | 
					use sea_orm::ActiveValue::Set;
 | 
				
			||||||
 | 
					use sea_orm::{ActiveModelTrait, DatabaseConnection, EntityTrait};
 | 
				
			||||||
 | 
					use std::time::Duration;
 | 
				
			||||||
 | 
					use tokio::time::sleep;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					pub fn start_aur_version_checking(db: DatabaseConnection) {
 | 
				
			||||||
 | 
					    tokio::spawn(async move {
 | 
				
			||||||
 | 
					        sleep(Duration::from_secs(10)).await;
 | 
				
			||||||
 | 
					        loop {
 | 
				
			||||||
 | 
					            println!("performing aur version checks");
 | 
				
			||||||
 | 
					            match aur_check_versions(db.clone()).await {
 | 
				
			||||||
 | 
					                Ok(_) => {}
 | 
				
			||||||
 | 
					                Err(e) => {
 | 
				
			||||||
 | 
					                    println!("Failed to perform aur version check: {e}")
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            sleep(Duration::from_secs(3600)).await;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					async fn aur_check_versions(db: DatabaseConnection) -> anyhow::Result<()> {
 | 
				
			||||||
 | 
					    let packages = Packages::find().all(&db).await?;
 | 
				
			||||||
 | 
					    let names: Vec<&str> = packages.iter().map(|x| x.name.as_str()).collect();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    let request = Request::default();
 | 
				
			||||||
 | 
					    let response = request.search_multi_info_by_names(names.as_slice()).await;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    let results: Vec<Package> = response
 | 
				
			||||||
 | 
					        .map_err(|_| anyhow!("couldn't download version update"))?
 | 
				
			||||||
 | 
					        .results;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if results.len() != packages.len() {
 | 
				
			||||||
 | 
					        println!("Package nr in repo and aur api response has different size");
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    for package in packages {
 | 
				
			||||||
 | 
					        match results.iter().find(|x1| x1.name == package.name) {
 | 
				
			||||||
 | 
					            None => {
 | 
				
			||||||
 | 
					                println!("Couldn't find {} in AUR response", package.name)
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            Some(result) => {
 | 
				
			||||||
 | 
					                let mut package: packages::ActiveModel = package.into();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                package.latest_aur_version = Set(Some(result.version.clone()));
 | 
				
			||||||
 | 
					                let _ = package.update(&db).await;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    Ok(())
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										1
									
								
								backend/src/scheduler/mod.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								backend/src/scheduler/mod.rs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1 @@
 | 
				
			|||||||
 | 
					pub mod aur_version_update;
 | 
				
			||||||
@@ -58,7 +58,10 @@ class _YourPackagesState extends State<YourPackages> {
 | 
				
			|||||||
                          label: Text("Package Name"),
 | 
					                          label: Text("Package Name"),
 | 
				
			||||||
                        ),
 | 
					                        ),
 | 
				
			||||||
                        DataColumn(
 | 
					                        DataColumn(
 | 
				
			||||||
                          label: Text("Number of versions"),
 | 
					                          label: Text("Version"),
 | 
				
			||||||
 | 
					                        ),
 | 
				
			||||||
 | 
					                        DataColumn(
 | 
				
			||||||
 | 
					                          label: Text("Up-To-Date"),
 | 
				
			||||||
                        ),
 | 
					                        ),
 | 
				
			||||||
                        DataColumn(
 | 
					                        DataColumn(
 | 
				
			||||||
                          label: Text("Status"),
 | 
					                          label: Text("Status"),
 | 
				
			||||||
@@ -85,14 +88,25 @@ class _YourPackagesState extends State<YourPackages> {
 | 
				
			|||||||
      cells: [
 | 
					      cells: [
 | 
				
			||||||
        DataCell(Text(package.id.toString())),
 | 
					        DataCell(Text(package.id.toString())),
 | 
				
			||||||
        DataCell(Text(package.name)),
 | 
					        DataCell(Text(package.name)),
 | 
				
			||||||
        DataCell(Text(package.count.toString())),
 | 
					        DataCell(Text(package.latest_version.toString())),
 | 
				
			||||||
 | 
					        DataCell(IconButton(
 | 
				
			||||||
 | 
					          icon: Icon(
 | 
				
			||||||
 | 
					            package.outofdate ? Icons.update : Icons.verified,
 | 
				
			||||||
 | 
					            color: package.outofdate ? Color(0xFF6B43A4) : Color(0xFF0A6900),
 | 
				
			||||||
 | 
					          ),
 | 
				
			||||||
 | 
					          onPressed: package.outofdate
 | 
				
			||||||
 | 
					              ? () {
 | 
				
			||||||
 | 
					                  // todo open build info with logs
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					              : null,
 | 
				
			||||||
 | 
					        )),
 | 
				
			||||||
        DataCell(IconButton(
 | 
					        DataCell(IconButton(
 | 
				
			||||||
          icon: Icon(
 | 
					          icon: Icon(
 | 
				
			||||||
            switchSuccessIcon(package.status),
 | 
					            switchSuccessIcon(package.status),
 | 
				
			||||||
            color: switchSuccessColor(package.status),
 | 
					            color: switchSuccessColor(package.status),
 | 
				
			||||||
          ),
 | 
					          ),
 | 
				
			||||||
          onPressed: () {
 | 
					          onPressed: () {
 | 
				
			||||||
            // todo open build info with logs
 | 
					            //context.push("/build/${package.latest_version_id}");
 | 
				
			||||||
          },
 | 
					          },
 | 
				
			||||||
        )),
 | 
					        )),
 | 
				
			||||||
        DataCell(
 | 
					        DataCell(
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -3,17 +3,22 @@ class Build {
 | 
				
			|||||||
  final String pkg_name;
 | 
					  final String pkg_name;
 | 
				
			||||||
  final String version;
 | 
					  final String version;
 | 
				
			||||||
  final int status;
 | 
					  final int status;
 | 
				
			||||||
 | 
					  final int? start_time, end_time;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  Build(
 | 
					  Build(
 | 
				
			||||||
      {required this.id,
 | 
					      {required this.id,
 | 
				
			||||||
      required this.pkg_name,
 | 
					      required this.pkg_name,
 | 
				
			||||||
      required this.version,
 | 
					      required this.version,
 | 
				
			||||||
 | 
					      required this.start_time,
 | 
				
			||||||
 | 
					      required this.end_time,
 | 
				
			||||||
      required this.status});
 | 
					      required this.status});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  factory Build.fromJson(Map<String, dynamic> json) {
 | 
					  factory Build.fromJson(Map<String, dynamic> json) {
 | 
				
			||||||
    return Build(
 | 
					    return Build(
 | 
				
			||||||
      id: json["id"] as int,
 | 
					      id: json["id"] as int,
 | 
				
			||||||
      status: json["status"] as int,
 | 
					      status: json["status"] as int,
 | 
				
			||||||
 | 
					      start_time: json["start_time"] as int?,
 | 
				
			||||||
 | 
					      end_time: json["end_time"] as int?,
 | 
				
			||||||
      pkg_name: json["pkg_name"] as String,
 | 
					      pkg_name: json["pkg_name"] as String,
 | 
				
			||||||
      version: json["version"] as String,
 | 
					      version: json["version"] as String,
 | 
				
			||||||
    );
 | 
					    );
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,21 +1,28 @@
 | 
				
			|||||||
class Package {
 | 
					class Package {
 | 
				
			||||||
  final int id;
 | 
					  final int id, latest_version_id;
 | 
				
			||||||
  final String name;
 | 
					  final String name;
 | 
				
			||||||
  final int count;
 | 
					  final bool outofdate;
 | 
				
			||||||
  final int status;
 | 
					  final int status;
 | 
				
			||||||
 | 
					  final String latest_version, latest_aur_version;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  Package(
 | 
					  Package(
 | 
				
			||||||
      {required this.id,
 | 
					      {required this.id,
 | 
				
			||||||
 | 
					      required this.latest_version_id,
 | 
				
			||||||
      required this.name,
 | 
					      required this.name,
 | 
				
			||||||
      required this.count,
 | 
					      required this.status,
 | 
				
			||||||
      required this.status});
 | 
					      required this.latest_version,
 | 
				
			||||||
 | 
					      required this.latest_aur_version,
 | 
				
			||||||
 | 
					      required this.outofdate});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  factory Package.fromJson(Map<String, dynamic> json) {
 | 
					  factory Package.fromJson(Map<String, dynamic> json) {
 | 
				
			||||||
    return Package(
 | 
					    return Package(
 | 
				
			||||||
      id: json["id"] as int,
 | 
					      id: json["id"] as int,
 | 
				
			||||||
      count: json["count"] as int,
 | 
					      outofdate: json["outofdate"] as bool,
 | 
				
			||||||
      status: json["status"] as int,
 | 
					      status: json["status"] as int,
 | 
				
			||||||
      name: json["name"] as String,
 | 
					      name: json["name"] as String,
 | 
				
			||||||
 | 
					      latest_version: json["latest_version"] as String,
 | 
				
			||||||
 | 
					      latest_version_id: json["latest_version_id"] as int,
 | 
				
			||||||
 | 
					      latest_aur_version: json["latest_aur_version"] as String,
 | 
				
			||||||
    );
 | 
					    );
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,14 +1,11 @@
 | 
				
			|||||||
import 'dart:async';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import 'package:aurcache/api/builds.dart';
 | 
					 | 
				
			||||||
import 'package:aurcache/components/build_output.dart';
 | 
					import 'package:aurcache/components/build_output.dart';
 | 
				
			||||||
import 'package:aurcache/models/build.dart';
 | 
					import 'package:aurcache/models/build.dart';
 | 
				
			||||||
import 'package:aurcache/components/api/APIBuilder.dart';
 | 
					import 'package:aurcache/components/api/APIBuilder.dart';
 | 
				
			||||||
import 'package:aurcache/providers/build_provider.dart';
 | 
					import 'package:aurcache/providers/build_provider.dart';
 | 
				
			||||||
 | 
					import 'package:aurcache/utils/time_formatter.dart';
 | 
				
			||||||
import 'package:flutter/material.dart';
 | 
					import 'package:flutter/material.dart';
 | 
				
			||||||
import 'package:go_router/go_router.dart';
 | 
					import 'package:go_router/go_router.dart';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import '../api/API.dart';
 | 
					 | 
				
			||||||
import '../components/dashboard/your_packages.dart';
 | 
					import '../components/dashboard/your_packages.dart';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class BuildScreen extends StatefulWidget {
 | 
					class BuildScreen extends StatefulWidget {
 | 
				
			||||||
@@ -29,6 +26,9 @@ class _BuildScreenState extends State<BuildScreen> {
 | 
				
			|||||||
          interval: const Duration(seconds: 10),
 | 
					          interval: const Duration(seconds: 10),
 | 
				
			||||||
          onLoad: () => const Text("no data"),
 | 
					          onLoad: () => const Text("no data"),
 | 
				
			||||||
          onData: (buildData) {
 | 
					          onData: (buildData) {
 | 
				
			||||||
 | 
					            final start_time = DateTime.fromMillisecondsSinceEpoch(
 | 
				
			||||||
 | 
					                (buildData.start_time ?? 0) * 1000);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            return Column(
 | 
					            return Column(
 | 
				
			||||||
              crossAxisAlignment: CrossAxisAlignment.start,
 | 
					              crossAxisAlignment: CrossAxisAlignment.start,
 | 
				
			||||||
              mainAxisAlignment: MainAxisAlignment.start,
 | 
					              mainAxisAlignment: MainAxisAlignment.start,
 | 
				
			||||||
@@ -58,7 +58,7 @@ class _BuildScreenState extends State<BuildScreen> {
 | 
				
			|||||||
                    const SizedBox(
 | 
					                    const SizedBox(
 | 
				
			||||||
                      width: 10,
 | 
					                      width: 10,
 | 
				
			||||||
                    ),
 | 
					                    ),
 | 
				
			||||||
                    const Text("triggered 2 months ago")
 | 
					                    Text("triggered ${start_time.readableDuration()}")
 | 
				
			||||||
                  ],
 | 
					                  ],
 | 
				
			||||||
                ),
 | 
					                ),
 | 
				
			||||||
                const SizedBox(
 | 
					                const SizedBox(
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -23,6 +23,7 @@ class _DashboardScreenState extends State<DashboardScreen> {
 | 
				
			|||||||
  @override
 | 
					  @override
 | 
				
			||||||
  Widget build(BuildContext context) {
 | 
					  Widget build(BuildContext context) {
 | 
				
			||||||
    return APIBuilder<StatsProvider, Stats, Object>(
 | 
					    return APIBuilder<StatsProvider, Stats, Object>(
 | 
				
			||||||
 | 
					      interval: const Duration(seconds: 10),
 | 
				
			||||||
      onData: (stats) {
 | 
					      onData: (stats) {
 | 
				
			||||||
        return SafeArea(
 | 
					        return SafeArea(
 | 
				
			||||||
          child: SingleChildScrollView(
 | 
					          child: SingleChildScrollView(
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										20
									
								
								frontend/lib/utils/time_formatter.dart
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								frontend/lib/utils/time_formatter.dart
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,20 @@
 | 
				
			|||||||
 | 
					extension TimeFormatter on DateTime {
 | 
				
			||||||
 | 
					  String readableDuration() {
 | 
				
			||||||
 | 
					    final now = DateTime.now();
 | 
				
			||||||
 | 
					    final duration = now.difference(this);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (duration.inSeconds < 60) {
 | 
				
			||||||
 | 
					      return '${duration.inSeconds} seconds ago';
 | 
				
			||||||
 | 
					    } else if (duration.inMinutes < 60) {
 | 
				
			||||||
 | 
					      return '${duration.inMinutes} minutes ago';
 | 
				
			||||||
 | 
					    } else if (duration.inHours < 24) {
 | 
				
			||||||
 | 
					      return '${duration.inHours} hours ago';
 | 
				
			||||||
 | 
					    } else if (duration.inDays < 30) {
 | 
				
			||||||
 | 
					      return '${duration.inDays} days ago';
 | 
				
			||||||
 | 
					    } else if ((duration.inDays / 30) < 12) {
 | 
				
			||||||
 | 
					      return '${duration.inDays ~/ 30} months ago';
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					      return '${duration.inDays ~/ 365} years ago';
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
		Reference in New Issue
	
	Block a user