fixed scripts and replaced consts
This commit is contained in:
@@ -1,5 +1,8 @@
|
||||
# Production environment variables for KSPGUTI Schedule
|
||||
|
||||
# Site URL - used for canonical links and sitemap (optional, defaults to https://schedule.itlxrd.space)
|
||||
NEXT_PUBLIC_SITE_URL=https://schedule.itlxrd.space
|
||||
|
||||
# Proxy URL for schedule parsing (optional, defaults to https://lk.ks.psuti.ru)
|
||||
PROXY_URL=https://lk.ks.psuti.ru
|
||||
|
||||
|
||||
17
.example.env
17
.example.env
@@ -1,2 +1,15 @@
|
||||
PROXY_HOST=
|
||||
PARSING_FAILURE_NOTIFICATIONS_TELEGRAM_BOTAPI_TOKEN=
|
||||
# Development/Example environment variables for KSPGUTI Schedule
|
||||
|
||||
# Site URL - used for canonical links and sitemap (optional, defaults to https://schedule.itlxrd.space)
|
||||
NEXT_PUBLIC_SITE_URL=https://schedule.itlxrd.space
|
||||
|
||||
# Proxy URL for schedule parsing (optional, defaults to https://lk.ks.psuti.ru)
|
||||
PROXY_URL=https://lk.ks.psuti.ru
|
||||
|
||||
# Telegram Bot API token for parsing failure notifications (optional)
|
||||
# Get token from @BotFather on Telegram
|
||||
PARSING_FAILURE_NOTIFICATIONS_TELEGRAM_BOTAPI_TOKEN=
|
||||
|
||||
# Telegram Chat ID for receiving notifications (optional)
|
||||
# You can get your chat ID by messaging @userinfobot on Telegram
|
||||
PARSING_FAILURE_NOTIFICATIONS_TELEGRAM_CHAT_ID=
|
||||
@@ -3,4 +3,4 @@ Disallow: /
|
||||
Allow: /ps7
|
||||
Allow: /pks35k
|
||||
|
||||
Sitemap: https://kspsuti.ru/sitemap.xml
|
||||
Sitemap: https://schedule.itlxrd.space/sitemap.xml
|
||||
@@ -155,13 +155,34 @@ npm ci --legacy-peer-deps --production=false
|
||||
echo -e "${YELLOW}Building the application...${NC}"
|
||||
npm run build
|
||||
|
||||
# Check if service user exists, create if not
|
||||
echo -e "${YELLOW}Checking service user...${NC}"
|
||||
if ! id "$SERVICE_USER" &>/dev/null; then
|
||||
echo -e "${YELLOW}User $SERVICE_USER does not exist. Creating...${NC}"
|
||||
# Try to create user, fallback to current user if fails
|
||||
if useradd -r -s /bin/false -d "$INSTALL_DIR" "$SERVICE_USER" 2>/dev/null; then
|
||||
echo -e "${GREEN}User $SERVICE_USER created${NC}"
|
||||
else
|
||||
echo -e "${YELLOW}Could not create user $SERVICE_USER. Using current user instead.${NC}"
|
||||
SERVICE_USER=$(whoami)
|
||||
SERVICE_GROUP=$(id -gn)
|
||||
fi
|
||||
else
|
||||
echo -e "${GREEN}User $SERVICE_USER exists${NC}"
|
||||
fi
|
||||
|
||||
# Set ownership
|
||||
echo -e "${YELLOW}Setting ownership...${NC}"
|
||||
chown -R "$SERVICE_USER:$SERVICE_GROUP" "$INSTALL_DIR"
|
||||
|
||||
# Install systemd service
|
||||
echo -e "${YELLOW}Installing systemd service...${NC}"
|
||||
cp "$INSTALL_DIR/systemd/$SERVICE_NAME.service" "/etc/systemd/system/"
|
||||
# Create temporary service file with correct user/group
|
||||
cp "$INSTALL_DIR/systemd/$SERVICE_NAME.service" "/tmp/$SERVICE_NAME.service"
|
||||
# Update user/group in service file
|
||||
sed -i "s/^User=.*/User=$SERVICE_USER/g; s/^Group=.*/Group=$SERVICE_GROUP/g" "/tmp/$SERVICE_NAME.service"
|
||||
cp "/tmp/$SERVICE_NAME.service" "/etc/systemd/system/$SERVICE_NAME.service"
|
||||
rm -f "/tmp/$SERVICE_NAME.service"
|
||||
systemctl daemon-reload
|
||||
|
||||
# Enable service
|
||||
|
||||
@@ -4,10 +4,11 @@ import contentTypeParser from 'content-type'
|
||||
import { JSDOM } from 'jsdom'
|
||||
// import { content as mockContent } from './mock'
|
||||
import { reportParserError } from '@/app/logger'
|
||||
import { PROXY_URL } from '@/shared/constants/urls'
|
||||
|
||||
// ПС-7: 146
|
||||
export async function getSchedule(groupID: number, groupName: string): Promise<Day[]> {
|
||||
const page = await fetch(`${process.env.PROXY_URL ?? 'https://lk.ks.psuti.ru'}/?mn=2&obj=${groupID}`)
|
||||
const page = await fetch(`${PROXY_URL}/?mn=2&obj=${groupID}`)
|
||||
// const page = { text: async () => mockContent, status: 200, headers: { get: (s: string) => s && 'text/html' } }
|
||||
const content = await page.text()
|
||||
const contentType = page.headers.get('content-type')
|
||||
@@ -16,7 +17,7 @@ export async function getSchedule(groupID: number, groupName: string): Promise<D
|
||||
const root = new JSDOM(content).window.document
|
||||
return parsePage(root, groupName)
|
||||
} catch(e) {
|
||||
console.error('Error while parsing lk.ks.psuti.ru')
|
||||
console.error(`Error while parsing ${PROXY_URL}`)
|
||||
reportParserError(new Date().toISOString(), 'Не удалось сделать парсинг для группы', groupName)
|
||||
throw e
|
||||
}
|
||||
@@ -24,6 +25,6 @@ export async function getSchedule(groupID: number, groupName: string): Promise<D
|
||||
console.error(page.status, contentType)
|
||||
console.error(content.length > 500 ? content.slice(0, 500 - 3) + '...' : content)
|
||||
reportParserError(new Date().toISOString(), 'Не удалось получить страницу для группы', groupName)
|
||||
throw new Error('Error while fetching lk.ks.psuti.ru')
|
||||
throw new Error(`Error while fetching ${PROXY_URL}`)
|
||||
}
|
||||
}
|
||||
@@ -13,6 +13,7 @@ import Link from 'next/link'
|
||||
import Image from 'next/image'
|
||||
import { BsTelegram } from 'react-icons/bs'
|
||||
import { SlSocialVkontakte } from 'react-icons/sl'
|
||||
import { TELEGRAM_CONTACT_URL } from '@/shared/constants/urls'
|
||||
|
||||
export function AddGroupButton() {
|
||||
const [popupVisible, setPopupVisible] = React.useState(false)
|
||||
@@ -48,7 +49,7 @@ function Popup({ open, onClose }: {
|
||||
<DialogDescription>
|
||||
</DialogDescription>
|
||||
<DialogFooter className='!justify-start !flex-row mt-3 gap-3'>
|
||||
<Link href='https://t.me/ilyakm'>
|
||||
<Link href={TELEGRAM_CONTACT_URL}>
|
||||
<Button tabIndex={-1} className='gap-3'><BsTelegram /> Мой Telegram</Button>
|
||||
</Link>
|
||||
</DialogFooter>
|
||||
|
||||
@@ -6,6 +6,7 @@ import { NextSerialized, nextDeserialized, nextSerialized } from '@/app/utils/da
|
||||
import { NavBar } from '@/widgets/navbar'
|
||||
import { LastUpdateAt } from '@/entities/last-update-at'
|
||||
import { groups } from '@/shared/data/groups'
|
||||
import { SITE_URL } from '@/shared/constants/urls'
|
||||
import crypto from 'crypto'
|
||||
import React from 'react'
|
||||
import { getDayOfWeek } from '@/shared/utils'
|
||||
@@ -47,7 +48,7 @@ export default function HomePage(props: NextSerialized<PageProps>) {
|
||||
<>
|
||||
<Head>
|
||||
<title>{`Группа ${group.name} — Расписание занятий в Колледже Связи`}</title>
|
||||
<link rel="canonical" href={`https://kspsuti.ru/${group.id}`} />
|
||||
<link rel="canonical" href={`${SITE_URL}/${group.id}`} />
|
||||
<meta name="description" content={`Расписание занятий группы ${group.name} на неделю в Колледже Связи ПГУТИ. Расписание пар, материалы для подготовки и изменения в расписании.`} />
|
||||
<meta property="og:title" content={`Группа ${group.name} — Расписание занятий в Колледже Связи`} />
|
||||
<meta property="og:description" content={`Расписание занятий группы ${group.name} на неделю в Колледже Связи ПГУТИ. Расписание пар, материалы для подготовки и изменения в расписании.`} />
|
||||
|
||||
@@ -1,13 +1,12 @@
|
||||
import { ISitemapField, getServerSideSitemapLegacy } from 'next-sitemap'
|
||||
import { GetServerSideProps } from 'next'
|
||||
import { groups } from '@/shared/data/groups'
|
||||
import { SITEMAP_SITE_URL } from '@/shared/constants/urls'
|
||||
|
||||
export const getServerSideProps: GetServerSideProps = async (ctx) => {
|
||||
const siteURL = 'https://kspsuti.ru'
|
||||
|
||||
const fields = Object.keys(groups).map<ISitemapField>(group => (
|
||||
{
|
||||
loc: `${siteURL}/${group}`,
|
||||
loc: `${SITEMAP_SITE_URL}/${group}`,
|
||||
changefreq: 'weekly',
|
||||
priority: 0.8
|
||||
}
|
||||
|
||||
19
src/shared/constants/urls.ts
Normal file
19
src/shared/constants/urls.ts
Normal file
@@ -0,0 +1,19 @@
|
||||
/**
|
||||
* URL constants used throughout the application
|
||||
*/
|
||||
|
||||
// Site URLs
|
||||
export const SITE_URL = process.env.NEXT_PUBLIC_SITE_URL || 'https://schedule.itlxrd.space'
|
||||
export const SITEMAP_SITE_URL = process.env.NEXT_PUBLIC_SITE_URL || 'https://schedule.itlxrd.space'
|
||||
|
||||
// External service URLs
|
||||
export const PROXY_URL = process.env.PROXY_URL || 'https://lk.ks.psuti.ru'
|
||||
export const KS_PSUTI_IMAGES_BASE_URL = 'https://ks.psuti.ru/images'
|
||||
|
||||
// Social media and external links
|
||||
export const GITHUB_REPO_URL = 'https://github.com/kilyabin/kspguti-schedule'
|
||||
export const TELEGRAM_CONTACT_URL = 'https://t.me/ilyakm'
|
||||
|
||||
// Teacher photos base URL
|
||||
export const TEACHER_PHOTOS_BASE_URL = `${KS_PSUTI_IMAGES_BASE_URL}/stories`
|
||||
|
||||
@@ -9,6 +9,7 @@ import { FaGithub } from 'react-icons/fa'
|
||||
import cx from 'classnames'
|
||||
import { NavContext, NavContextProvider } from '@/shared/context/nav-context'
|
||||
import { groups } from '@/shared/data/groups'
|
||||
import { GITHUB_REPO_URL } from '@/shared/constants/urls'
|
||||
|
||||
export function NavBar({ cacheAvailableFor }: {
|
||||
cacheAvailableFor: string[]
|
||||
@@ -51,7 +52,7 @@ export function NavBar({ cacheAvailableFor }: {
|
||||
<AddGroupButton />
|
||||
</ul>
|
||||
<div className='flex gap-1 min-[500px]:gap-2'>
|
||||
<Link href='https://github.com/kilyabin/kspguti-schedule' target='_blank' rel='nofollower noreferrer'>
|
||||
<Link href={GITHUB_REPO_URL} target='_blank' rel='nofollower noreferrer'>
|
||||
<Button variant='outline' size='icon' tabIndex={-1}>
|
||||
<FaGithub />
|
||||
</Button>
|
||||
|
||||
Reference in New Issue
Block a user