/reg/
@ -33,6 +33,7 @@ reply_limit = 1000
|
||||
locked = false
|
||||
user_ids = false
|
||||
flags = false
|
||||
flags_reg = false
|
||||
thread_captcha = "off"
|
||||
reply_captcha = "off"
|
||||
board_theme = "yotsuba.css"
|
||||
|
@ -64,6 +64,7 @@ pub struct BoardCfg {
|
||||
pub locked: bool,
|
||||
pub user_ids: bool,
|
||||
pub flags: bool,
|
||||
pub flags_reg: bool,
|
||||
pub thread_captcha: String,
|
||||
pub reply_captcha: String,
|
||||
pub board_theme: String,
|
||||
|
@ -20,7 +20,7 @@ impl Banner {
|
||||
|
||||
pub async fn read(ctx: &Ctx, id: i32) -> Result<Option<Self>, NekrochanError> {
|
||||
let banners: Vec<String> = ctx.cache().zrangebyscore("banners", id, id).await?;
|
||||
let json = banners.get(0);
|
||||
let json = banners.first();
|
||||
|
||||
let banner = match json {
|
||||
Some(json) => Some(serde_json::from_str(json)?),
|
||||
|
@ -37,6 +37,7 @@ impl Board {
|
||||
files JSONB NOT NULL,
|
||||
password VARCHAR(64) DEFAULT NULL,
|
||||
country VARCHAR(2) NOT NULL,
|
||||
region VARCHAR(64) NOT NULL,
|
||||
ip INET NOT NULL,
|
||||
bumps INT NOT NULL DEFAULT 0,
|
||||
replies INT NOT NULL DEFAULT 0,
|
||||
|
@ -60,6 +60,7 @@ pub struct Post {
|
||||
pub files: Json<Vec<File>>,
|
||||
pub password: String,
|
||||
pub country: String,
|
||||
pub region: Option<String>,
|
||||
pub ip: IpAddr,
|
||||
pub bumps: i32,
|
||||
pub replies: i32,
|
||||
|
@ -27,13 +27,14 @@ impl Post {
|
||||
files: Vec<File>,
|
||||
password: String,
|
||||
country: String,
|
||||
region: Option<String>,
|
||||
ip: IpAddr,
|
||||
bump: bool,
|
||||
) -> Result<Self, NekrochanError> {
|
||||
let post: Post = query_as(&format!(
|
||||
r#"INSERT INTO posts_{}
|
||||
(thread, name, tripcode, capcode, email, content, content_nomarkup, files, password, country, ip)
|
||||
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11)
|
||||
(thread, name, tripcode, capcode, email, content, content_nomarkup, files, password, country, region, ip)
|
||||
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12)
|
||||
RETURNING *"#, board.id)
|
||||
)
|
||||
.bind(thread)
|
||||
@ -46,6 +47,7 @@ impl Post {
|
||||
.bind(Json(files))
|
||||
.bind(password)
|
||||
.bind(country)
|
||||
.bind(region)
|
||||
.bind(ip)
|
||||
.fetch_one(ctx.db())
|
||||
.await?;
|
||||
|
@ -26,7 +26,7 @@ pub async fn appeal_ban(
|
||||
QsForm(form): QsForm<AppealBanForm>,
|
||||
) -> Result<HttpResponse, NekrochanError> {
|
||||
let tcx = TemplateCtx::new(&ctx, &req).await?;
|
||||
let (ip, _) = ip_from_req(&req)?;
|
||||
let (ip, _, _) = ip_from_req(&req)?;
|
||||
|
||||
let ban = Ban::read_by_id(&ctx, form.id)
|
||||
.await?
|
||||
|
@ -49,7 +49,7 @@ pub async fn create_post(
|
||||
None => PermissionWrapper::new(0, false),
|
||||
};
|
||||
|
||||
let (ip, country) = ip_from_req(&req)?;
|
||||
let (ip, country, region) = ip_from_req(&req)?;
|
||||
|
||||
let board = form.board.0;
|
||||
let board = Board::read(&ctx, board.clone())
|
||||
@ -238,6 +238,7 @@ pub async fn create_post(
|
||||
files,
|
||||
password,
|
||||
country,
|
||||
region,
|
||||
ip,
|
||||
bump,
|
||||
)
|
||||
|
@ -29,7 +29,7 @@ pub async fn report_posts(
|
||||
QsForm(form): QsForm<ReportPostsForm>,
|
||||
) -> Result<HttpResponse, NekrochanError> {
|
||||
let tcx = TemplateCtx::new(&ctx, &req).await?;
|
||||
let (reporter_ip, reporter_country) = ip_from_req(&req)?;
|
||||
let (reporter_ip, reporter_country, _) = ip_from_req(&req)?;
|
||||
let bans = Ban::read_by_ip(&ctx, reporter_ip).await?;
|
||||
|
||||
if let Some(ban) = bans.get(&None) {
|
||||
|
@ -34,7 +34,7 @@ pub async fn user_post_actions(
|
||||
QsForm(form): QsForm<UserPostActionsForm>,
|
||||
) -> Result<HttpResponse, NekrochanError> {
|
||||
let tcx = TemplateCtx::new(&ctx, &req).await?;
|
||||
let (ip, _) = ip_from_req(&req)?;
|
||||
let (ip, _, _) = ip_from_req(&req)?;
|
||||
let bans = Ban::read_by_ip(&ctx, ip).await?;
|
||||
|
||||
if let Some(ban) = bans.get(&None) {
|
||||
|
@ -18,6 +18,7 @@ pub struct UpdateBoardConfigForm {
|
||||
locked: Option<String>,
|
||||
user_ids: Option<String>,
|
||||
flags: Option<String>,
|
||||
flags_reg: Option<String>,
|
||||
thread_captcha: String,
|
||||
reply_captcha: String,
|
||||
board_theme: String,
|
||||
@ -58,6 +59,7 @@ pub async fn update_board_config(
|
||||
let locked = form.locked.is_some();
|
||||
let user_ids = form.user_ids.is_some();
|
||||
let flags = form.flags.is_some();
|
||||
let flags_reg = form.flags_reg.is_some();
|
||||
let thread_captcha = form.thread_captcha;
|
||||
let reply_captcha = form.reply_captcha;
|
||||
let board_theme = form.board_theme;
|
||||
@ -81,6 +83,7 @@ pub async fn update_board_config(
|
||||
locked,
|
||||
user_ids,
|
||||
flags,
|
||||
flags_reg,
|
||||
thread_captcha,
|
||||
reply_captcha,
|
||||
board_theme,
|
||||
|
@ -34,7 +34,7 @@ impl TemplateCtx {
|
||||
None => PermissionWrapper::new(0, false),
|
||||
};
|
||||
|
||||
let (ip, _) = ip_from_req(req)?;
|
||||
let (ip, _, _) = ip_from_req(req)?;
|
||||
let yous = ctx.cache().zrange(format!("by_ip:{ip}"), 0, -1).await?;
|
||||
|
||||
let account = account.map(|account| account.username);
|
||||
@ -99,7 +99,7 @@ pub async fn account_from_auth_opt(
|
||||
Ok(account)
|
||||
}
|
||||
|
||||
pub fn ip_from_req(req: &HttpRequest) -> Result<(IpAddr, String), NekrochanError> {
|
||||
pub fn ip_from_req(req: &HttpRequest) -> Result<(IpAddr, String, Option<String>), NekrochanError> {
|
||||
let ip = req
|
||||
.connection_info()
|
||||
.realip_remote_addr()
|
||||
@ -107,10 +107,27 @@ pub fn ip_from_req(req: &HttpRequest) -> Result<(IpAddr, String), NekrochanError
|
||||
ip.parse().unwrap_or(IpAddr::V4(Ipv4Addr::UNSPECIFIED))
|
||||
});
|
||||
|
||||
let country = req.headers().get("X-Country-Code").map_or_else(
|
||||
|| "xx".into(),
|
||||
|hdr| hdr.to_str().unwrap_or("xx").to_ascii_lowercase(),
|
||||
);
|
||||
let country = req
|
||||
.headers()
|
||||
.get("X-Country-Code")
|
||||
.and_then(|hdr| hdr.to_str().ok())
|
||||
.unwrap_or("xx")
|
||||
.to_ascii_lowercase();
|
||||
|
||||
Ok((ip, country))
|
||||
let region = req
|
||||
.headers()
|
||||
.get("X-Region-Code")
|
||||
.and_then(|hdr| hdr.to_str().ok())
|
||||
.unwrap_or("xx")
|
||||
.to_ascii_lowercase();
|
||||
|
||||
let region = if country == "cz" {
|
||||
Some(region)
|
||||
} else if country == "ru" && region == "kgd" {
|
||||
Some("kralovec".into())
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
Ok((ip, country, region))
|
||||
}
|
||||
|
binární
static/flags/reg/10.png
Normální soubor
Za Šířka: | Výška: | Velikost: 1.0 KiB |
binární
static/flags/reg/20.png
Normální soubor
Za Šířka: | Výška: | Velikost: 1.0 KiB |
binární
static/flags/reg/31.png
Normální soubor
Za Šířka: | Výška: | Velikost: 1.0 KiB |
binární
static/flags/reg/32.png
Normální soubor
Za Šířka: | Výška: | Velikost: 1.0 KiB |
binární
static/flags/reg/41.png
Normální soubor
Za Šířka: | Výška: | Velikost: 1.0 KiB |
binární
static/flags/reg/42.png
Normální soubor
Za Šířka: | Výška: | Velikost: 1.0 KiB |
binární
static/flags/reg/51.png
Normální soubor
Za Šířka: | Výška: | Velikost: 1.0 KiB |
binární
static/flags/reg/52.png
Normální soubor
Za Šířka: | Výška: | Velikost: 1.0 KiB |
binární
static/flags/reg/53.png
Normální soubor
Za Šířka: | Výška: | Velikost: 1.0 KiB |
binární
static/flags/reg/63.png
Normální soubor
Za Šířka: | Výška: | Velikost: 1.0 KiB |
binární
static/flags/reg/64.png
Normální soubor
Za Šířka: | Výška: | Velikost: 1.0 KiB |
binární
static/flags/reg/71.png
Normální soubor
Za Šířka: | Výška: | Velikost: 1.0 KiB |
binární
static/flags/reg/72.png
Normální soubor
Za Šířka: | Výška: | Velikost: 1.0 KiB |
binární
static/flags/reg/80.png
Normální soubor
Za Šířka: | Výška: | Velikost: 1.0 KiB |
binární
static/flags/reg/kralovec.png
Normální soubor
Za Šířka: | Výška: | Velikost: 1.0 KiB |
binární
static/flags/reg/xx.png
Spustitelný soubor
Za Šířka: | Výška: | Velikost: 447 B |
@ -23,6 +23,11 @@
|
||||
{% if board.config.0.flags %}
|
||||
<img title="Země: {{ post.country }}" class="icon" src="/static/flags/{{ post.country }}.png"> 
|
||||
{% endif %}
|
||||
{% if board.config.0.flags_reg %}
|
||||
{% if let Some(region) = post.region %}
|
||||
<img title="Region: {{ region }}" class="icon" src="/static/flags/reg/{{ region }}.png"> 
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
<time datetime="{{ post.created }}">{{ post.created|czech_datetime }}</time> 
|
||||
{% if board.config.0.user_ids %}
|
||||
<span class="user-id" style="background-color: #{{ post.user_id }};">{{ post.user_id }}</span> 
|
||||
|
@ -69,6 +69,15 @@
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td class="label">Vlajky Regionů</td>
|
||||
<td>
|
||||
<div class="input-wrapper">
|
||||
<input name="flags_reg" type="checkbox" {% if board.config.0.flags_reg %}checked=""{% endif %}>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td class="label">CAPTCHA (vlákno)</td>
|
||||
<td>
|
||||
|