Pour tout problème contactez-nous par mail : support@froggit.fr | La FAQ :grey_question: | Rejoignez-nous sur le Chat :speech_balloon:

Skip to content
Snippets Groups Projects
static_view.rs 5.63 KiB
Newer Older
  • Learn to ignore specific revisions
  • Pierre Jarriges's avatar
    Pierre Jarriges committed
    use crate::{app_state::AppState, model::Article};
    use chrono::{Datelike, FixedOffset, TimeZone, Utc};
    use sitemap::{
        reader::{SiteMapEntity, SiteMapReader},
        structs::UrlEntry,
        writer::SiteMapWriter,
    };
    use std::{
        fs::{create_dir, create_dir_all, remove_dir_all, remove_file, rename, File},
        io::Write,
        path::PathBuf,
    };
    
    Pierre Jarriges's avatar
    Pierre Jarriges committed
    enum UpdateSitemapMode {
        CreateUrl,
        DeleteUrl,
    }
    
    pub fn create_static_view(app_state: &AppState, article: &Article) -> Result<(), String> {
        let view_path = app_state
            .env
            .public_dir
            .join(&article.category)
            .join("view");
    
    
        if !view_path.exists() {
            if let Err(e) = create_dir(&view_path) {
                return Err(format!("Couldn't create directory {:?}: {}", view_path, e));
            }
        }
    
    
    Pierre Jarriges's avatar
    Pierre Jarriges committed
        let d_path = article.metadata.static_resource_path.as_ref().unwrap();
    
    
        if let Err(e) = create_dir_all(&d_path) {
            return Err(format!("Error creating directory {:?} : {}", d_path, e));
        }
    
    
    Pierre Jarriges's avatar
    Pierre Jarriges committed
        let art_img_def = String::new();
    
        let mut art_image_uri = article
            .images
            .iter()
            .next()
            .unwrap_or(&art_img_def)
            .to_owned();
    
        if !art_image_uri.is_empty() {
            art_image_uri = format!("/assets/images/{}", art_image_uri);
        }
    
        let html = format!(
            "
    <html lang='{}'>
    <head>
        <meta charset='UTF-8'>
        <meta http-equiv='X-UA-Compatible' content='IE=edge'>
        <meta name='viewport' content='width=device-width, initial-scale=1.0'>
        <meta name='author' content='Kuadrado Software' />
        <meta name='image' content='{}'/>
        <meta name='description' content='{}'>
        <link rel='icon' type='image/svg+xml' href='/favicon.svg' />
        <title>{}</title>
        <link href='/style/style.css' rel='stylesheet' />
    </head>
    <body>
        <div>{}<div>
    </body>
    <script type='text/javascript' src='/games/view.js'></script>
    </html>
                ",
            article.locale, art_image_uri, article.metadata.description, article.title, article.body,
        );
    
    
        let f_path = d_path.join("index.html");
    
    Pierre Jarriges's avatar
    Pierre Jarriges committed
    
    
        match File::create(&f_path) {
            Ok(mut f) => {
                if let Err(e) = f.write_all(html.as_bytes()) {
                    return Err(format!("Error writing to {:?} : {}", f_path, e));
                }
    
    Pierre Jarriges's avatar
    Pierre Jarriges committed
    
                if let Err(e) = update_sitemap(
                    app_state,
                    &article.metadata.view_uri,
                    UpdateSitemapMode::CreateUrl,
                ) {
                    return Err(e);
                };
    
    
                Ok(())
            }
            Err(e) => Err(format!("Error creating {:?} : {}", f_path, e)),
        }
    }
    
    Pierre Jarriges's avatar
    Pierre Jarriges committed
    pub fn delete_static_view(
        app_state: &AppState,
        path: &Option<PathBuf>,
        uri: &Option<String>,
    ) -> Result<(), String> {
    
        if let Some(path) = path {
            if path.exists() {
                let parent = path.parent().unwrap();
    
    
    Pierre Jarriges's avatar
    Pierre Jarriges committed
                if let Err(e) = remove_dir_all(parent) {
    
    Pierre Jarriges's avatar
    Pierre Jarriges committed
                        "Error deleting static view at {:?} : {}",
    
    Pierre Jarriges's avatar
    Pierre Jarriges committed
        if let Err(e) = update_sitemap(app_state, uri, UpdateSitemapMode::DeleteUrl) {
            return Err(e);
        };
    
        Ok(())
    }
    
    fn update_sitemap(
        app_state: &AppState,
        uri: &Option<String>,
        mode: UpdateSitemapMode,
    ) -> Result<(), String> {
        if uri.is_none() {
            return Ok(());
        }
    
        let sitemap_name = match std::env::var("CONTEXT") {
            Ok(value) => {
                if value.eq("testing") {
                    String::from("test_sitemap.xml")
                } else {
                    String::from("sitemap.xml")
                }
            }
            Err(_) => String::from("sitemap.xml"),
        };
    
        let standard_dir_pth = app_state.env.public_dir.join("standard");
        let uri = uri.as_ref().unwrap().to_owned();
    
        let sitemap =
            File::open(standard_dir_pth.join(&sitemap_name)).expect("Couldn't open file sitemap.xml");
    
        let mut urls = Vec::new();
    
        for entity in SiteMapReader::new(sitemap) {
            if let SiteMapEntity::Url(url_entry) = entity {
                urls.push(url_entry.loc.get_url().unwrap().to_string());
            }
        }
    
        let updated_sitemap = File::create(standard_dir_pth.join("tmp_sitemap.xml"))
            .expect("Couldn't create temporary sitemap");
    
        let writer = SiteMapWriter::new(updated_sitemap);
        let mut url_writer = writer
            .start_urlset()
            .expect("Unable to write sitemap urlset");
    
        match mode {
            UpdateSitemapMode::CreateUrl => {
                urls.push(uri);
            }
            UpdateSitemapMode::DeleteUrl => {
                let mut updated_urls = Vec::new();
                for u in urls {
                    if !u.eq(&uri) {
                        updated_urls.push(u);
                    }
                }
                urls = updated_urls;
            }
        }
    
        let now = Utc::today().naive_utc();
    
        for u in urls {
            url_writer
                .url(
                    UrlEntry::builder()
                        .loc(u)
                        .lastmod(
                            FixedOffset::west(0)
                                .ymd(now.year(), now.month(), now.day())
                                .and_hms(0, 0, 0),
                        )
                        .build()
                        .unwrap(),
                )
                .expect("Unable to write url");
        }
    
        url_writer
            .end()
            .expect("Unable to write sitemap closing tags");
    
        if let Err(e) = remove_file(standard_dir_pth.join(&sitemap_name)) {
            return Err(format!("Error updating sitemap.xml {}", e));
        };
    
        if let Err(e) = rename(
            standard_dir_pth.join("tmp_sitemap.xml"),
            standard_dir_pth.join(&sitemap_name),
        ) {
            return Err(format!("Error updating sitemap.xml {}", e));
        };