Merge pull request #32 from tmshv/fix/drop-person-entity

Drop person entity
This commit is contained in:
tmshv authored and GitHub committed 2020-02-25 04:51:44 +03:00
commit 3d59757c28
18 files changed
+34 -503

No files matched your search

@@ -1,60 +0,0 @@
import Teacher from '../core/Teacher'
import { encodePerson } from '../factory/person'
import { Request, Response } from 'express'
import { prioritySort } from '../lib/sort'
export async function getItem(req: Request, res: Response) {
const id = req.params.slug
const data = await Teacher.findById(id)
if (data) {
res.json(encodePerson(data))
} else {
res.status(404)
res.json({
error: `Resource ${id} not found`
})
}
}
export async function getAll(req: Request, res: Response) {
const order = [
'mg-timasheva',
'va-sarzhin',
'od-gogoleva',
'my-valkova',
'nv-andreeva',
'vv-voronova',
]
const teachersSorted = prioritySort.bind(null, [...order], t => t.id)
const teachers = await Teacher.find({ hidden: false })
const data = teachersSorted(teachers).map(encodePerson)
if (data) {
res.json({
items: data,
})
} else {
res.status(404)
res.json({
error: `Not found`
})
}
}
export async function getUrls(req: Request, res: Response) {
const data = await Teacher.find({})
if (data) {
const items = data.map(x => `/teacher/${x.id}`)
res.json({
items
})
} else {
res.status(404)
res.json({
error: `Not found`
})
}
}
-2
View File
@@ -20,7 +20,6 @@ export default class Config {
public file: any
public server: any
public articlesPerPage: any
public collectiveOrder: any
public articleCardDefaultPreview: any
public collectiveImage: any
public redirect: any
@@ -30,7 +29,6 @@ export default class Config {
this.file = file
this.server = data.server
this.articlesPerPage = data.articlesPerPage || 5
this.collectiveOrder = data.collectiveOrder || []
this.articleCardDefaultPreview = data.articleCardDefaultPreview
this.collectiveImage = data.collectiveImage
-87
View File
@@ -1,87 +0,0 @@
import Data from './Data'
import Image from './Image'
import { find, findOne } from '../lib/store'
const store = () => Data.getStore('Teacher')
export default class Teacher {
static async find(query, options = {}): Promise<Teacher[]> {
const items = await find(store(), query, options as any)
return Promise.all(items.map(processProfile))
}
static async findById(id) {
const data = await findOne(store(), { id })
if (!data) return null
return processProfile(data)
}
public id: any
public post: any
public file: any
public edu: any
public picture: any
public preview: any
public diploma: any
public position: any
public name: any
public status: any
public hash: any
public url: any
constructor(data) {
this.id = data.id
this.post = data.post
this.file = data.file
this.edu = data.edu
this.picture = data.picture
this.preview = data.preview
this.diploma = data.diploma
this.position = data.position
this.name = data.name
this.status = data.status
this.hash = data.hash
this.url = `/teacher/${this.id}`
}
/**
*
* "First Middle Last" -> "F. M. Last"
*
* @returns {string}
*/
shortName() {
const f = i => i.replace(/^(.).+/, '$1')
const [first, middle, last] = this.splitName()
return `${f(first)}. ${f(middle)}. ${last}`
}
/**
*
* "First Middle Last" -> ["First", "Middle", "Last"]
*
* @returns {Array|{index: number, input: string}}
*/
splitName() {
const name = this.name
const m = /(.+)\s(.+)\s(.+)/.exec(name)
return m.slice(1)
}
}
const processProfile = async profile => {
const imageId = profile.picture
const previewId = profile.preview
const picture = await Image.findById(imageId)
const preview = await Image.findById(previewId)
return new Teacher({
...profile,
picture,
preview,
})
}
-19
View File
@@ -1,19 +0,0 @@
import {c} from '../core/db';
const PAGES = 'pages';
export async function getPageUrls() {
return await c(PAGES)
.find({}, {url: 1})
.toArray();
}
/**
* Find a person by it's id
*
* @param {string} url
* @returns {Promise|*}
*/
export async function getPage(url) {
return await c(PAGES).findOne({url: url});
}
-1
View File
@@ -30,7 +30,6 @@ function init(db: Db) {
Data.setStore('Article', db.collection('articles'))
Data.setStore('Album', db.collection('albums'))
Data.setStore('Image', db.collection('images'))
Data.setStore('Teacher', db.collection('collective'))
Data.setStore('Document', db.collection('documents'))
Data.setStore('Settings', db.collection('settings'))
-13
View File
@@ -1,13 +0,0 @@
import ImageArtifactType from '../core/ImageArtifactType'
import { encodeImage } from './image'
const profilePicture = profile => profile.picture.getPicture(ImageArtifactType.BIG)
export function encodePerson(person) {
return {
...person,
shortName: person.shortName(),
name: person.splitName(),
picture: profilePicture(person),
preview: encodeImage(person.picture),
}
}
-15
View File
@@ -1,17 +1,3 @@
function prioritySort(priority, key, list) {
priority = priority.reverse()
let weight = i => {
const p = key(i)
const index = priority.indexOf(p)
return index > -1
? index + 1
: 0
}
return sort(list, weight)
}
function sort(list, fn, reverse = false) {
return list
.map(i => [fn(i), i])
@@ -32,6 +18,5 @@ function sortBy(fn, reverse = false) {
}
}
exports.prioritySort = prioritySort
exports.sortBy = sortBy
exports.sort = sort
-5
View File
@@ -1,7 +1,6 @@
import { config } from 'dotenv'
import express from 'express'
import { connect } from './db'
import * as person from './controllers/person'
import * as article from './controllers/article'
import * as album from './controllers/album'
import * as schedule from './controllers/schedule'
@@ -25,10 +24,6 @@ async function main() {
}
const app = express()
app.get('/persons', person.getAll)
app.get('/persons/urls', person.getUrls)
app.get('/persons/:slug', person.getItem)
app.get('/articles', article.getAll)
app.get('/articles/urls', article.getUrls)
app.get('/articles/:slug', article.getItem)
@@ -1,18 +0,0 @@
const { collection } = require('../db')
// import { collection } from '../core/db'
export async function getCollective(query = {}) {
return await collection('collective')
.find(query)
.toArray();
}
/**
* Find a person by it's id
*
* @param id
* @returns {Promise|*}
*/
export async function getPerson(id) {
return await collection('collective').findOne({ id: id });
}
+1 -2
View File
@@ -1,5 +1,4 @@
import { createMap } from '../utils/common'
import { getCollective } from './collective'
import {
scheduleDate,
getPeriod as schedulePeriod,
@@ -96,7 +95,7 @@ function migrate10to20(schedule) {
async function migrate20to30(schedule) {
const days = ['mon', 'tue', 'wed', 'thu', 'fri', 'sat']//, 'sun']
const persons = await getCollective()
const persons = []
const person = createMap(i => i.id, persons)
const week = week => days
-12
View File
@@ -41,15 +41,6 @@ database_uri = value('database_uri') # env('MONGO_URI')
skip_unchanged = value('skip_unchanged')
person_uri = {
'Н.В.Андреева': 'nv-andreeva',
'И.Н.Втюрина': 'in-vturina',
'О.Д.Гоголева': 'od-gogoleva',
'В.А.Саржин': 'va-sarzhin',
'Р.К.Тимашев': 'rk-timashev',
'А.С.Тимашева': 'as-timasheva',
}
image_processing_enabled = value('image_processing')
album_html_img_class = 'hudozka-product'
@@ -104,7 +95,6 @@ collection_images = 'images'
collection_documents = 'documents'
collection_schedules = 'schedules'
collection_articles = 'articles'
collection_collective = 'collective'
collection_albums = 'albums'
collection_pages = 'pages'
@@ -113,7 +103,6 @@ hash_salt_pages = '4'
hash_salt_albums = '1'
hash_salt_documents = '4'
hash_salt_images = '5'
hash_salt_person = '4'
provider_name = value('provider')['name'] # env('SYNC_PROVIDER', 'fs')
provider_root = value('provider')['root'] # env('SYNC_PROVIDER', 'fs')
@@ -124,7 +113,6 @@ dir_settings = './Settings'
dir_documents = './Documents'
dir_schedules = './Schedules'
dir_articles = './Articles'
dir_persons = './Collective'
dir_albums = './Gallery'
dir_pages = './Pages'
dir_images = './Images'
-9
View File
@@ -11,7 +11,6 @@ from sync.models.Image import Image
from sync.models.Album import Album
from sync.models.Article import Article
from sync.models.Page import Page
from sync.models.Person import Person
from sync.models.Schedule import Schedule
from sync.models.Settings import Settings
@@ -58,13 +57,6 @@ async def run(run_interval=0):
)
sync_pages.set_options(True, True, True)
sync_persons = Sync(
provider=io(settings.provider_root),
model=Person,
)
sync_persons.set_options(True, True, True)
sync_persons.validate_urls = False
sync_articles = Sync(
provider=io(settings.provider_root),
model=Article,
@@ -105,7 +97,6 @@ async def run(run_interval=0):
await asyncio.wait([
run_sync(sync_documents),
run_sync(sync_pages),
run_sync(sync_persons),
run_sync(sync_articles),
run_sync(sync_schedules),
run_sync(sync_albums),
-130
View File
@@ -1,130 +0,0 @@
import logging
import os
import settings
from db import collection
from sync import create_post
from sync.data import Provider
from sync.models import Model
from sync.models.Image import Image
from utils.fn import swap_ext
from utils.hash import hash_str
from utils.io import read_yaml_md, parse_yaml_front_matter
from utils.text.transform import url_encode_text
logger = logging.getLogger(settings.name + '.Person')
store = collection(settings.collection_collective)
class Person(Model):
@staticmethod
async def find(query):
return store.find(query)
@staticmethod
async def delete(query):
return store.find_one_and_delete(query)
@staticmethod
async def scan(provider):
scan_dir = settings.dir_persons
documents = provider.type_filter(scan_dir, '.md')
documents = [Person.read(provider, i) for i in documents]
return documents
@staticmethod
def read(provider, path):
params = get_manifest(provider, path)
return Person(
provider,
path,
params=params,
)
def __init__(self, provider, file, params=None):
self.__hash_salt = settings.hash_salt_person
self.__hash_keys = ['id', 'url']
self.__id_template: str = '{category}-{file}'
self.__url_template: str = settings.document_url_template
self.__url_preview_template: str = settings.document_url_preview_template
self.picture = None
self.preview = None
self.post = None
self.images = None
self.documents = None
super().__init__(provider, store, file, params)
def init(self):
pass
self.__set_id()
self.__set_hash()
async def build(self, **kwargs):
sizes = kwargs['sizes']
image_path = self._get_relpath(self.get_param('picture'))
self.picture = await Image.new(self.provider, image_path, sizes)
markdown_post = self.get_param('content')
post, images, documents = await create_post(self.provider, self.get_param('folder'), markdown_post, sizes)
self.post = post
self.images = images
self.documents = documents
if self.has_param('preview'):
preview = self.get_param('preview')
preview = self._get_relpath(preview)
self.preview = await Image.new(self.provider, preview, sizes)
def bake(self):
return {
**self.params,
'post': self.post,
'images': [x.ref for x in self.images],
'documents': [x.ref for x in self.documents],
'id': self.id,
'hash': self.hash,
'file': self.file,
'picture': self.picture.ref,
'preview': self.preview.ref if self.preview else None,
}
def __set_id(self):
if 'id' in self.params:
self.id = self.params['id']
else:
self.id = url_encode_text(self.params['name'])
def __set_hash(self):
files = [self.file]
files.append(self._get_relpath(self.get_param('picture')))
if self.has_param('preview'):
files.append(self._get_relpath(self.get_param('preview')))
hashes = [self.provider.hash(x) for x in files]
self.hash = hash_str(
self.__hash_salt + ''.join(hashes)
)
def __str__(self):
return f'<Person file={self.file} id={self.id}>'
def get_manifest(provider: Provider, path: str) -> dict:
data = provider.read(path).read().decode('utf-8')
manifest = parse_yaml_front_matter(data)
return {
**manifest,
'picture': manifest['picture'] if 'picture' in manifest else os.path.basename(swap_ext('.jpg')(path)),
'preview': manifest['preview'] if 'preview' in manifest else os.path.basename(swap_ext('.jpg')(path)),
'folder': os.path.dirname(path),
'hidden': manifest['hidden'] if 'hidden' in manifest else False,
}
-13
View File
@@ -1,6 +1,5 @@
import settings
from db import collection
from sync.core.person import SyncPerson
from utils.text.transform import interpolate_swift
@@ -15,14 +14,6 @@ def resolve_value(param, store):
return store(i)
def resolve_teacher(i):
sync = SyncPerson(
collection(settings.collection_collective),
None,
''
)
return resolve_value(i, lambda teacher_id: sync.read({'id': teacher_id}))
def create_product(doc):
# author, image, title, awards, teacher, date
@@ -33,8 +24,4 @@ def create_product(doc):
product = {**doc}
# unpop_image(product)
# product['teacher'] = resolve_teacher(doc['teacher'])
# if (product['teacher']):
# unpop_teacher(product)
return product
+33 -13
View File
@@ -1,16 +1,32 @@
import Head from 'next/head'
import { get } from 'lodash'
import { App } from 'src/components/App'
import { Meta } from 'src/components/Meta'
import { CollectiveImage } from 'src/components/CollectiveImage'
import { meta } from 'src/lib/meta'
import { IMeta, Person } from 'src/types'
import { createApiUrl, requestGet, IResponseItems } from 'src/next-lib'
import { IMeta, IPage, ImageDefinition } from 'src/types'
import { createApiUrl, requestGet } from 'src/next-lib'
import { NextPage, NextPageContext } from 'next'
import { CardGrid } from 'src/components/CardGrid'
import { Card } from 'src/components/Card'
import { Block } from 'src/components/Block'
const persons = [
'/teacher/mg-timasheva',
'/teacher/va-sarzhin',
'/teacher/od-gogoleva',
'/teacher/nv-andreeva',
'/teacher/vv-voronova',
'/teacher/ea-burovtseva',
'/teacher/sa-latipova',
'/teacher/iv-khramov',
'/teacher/ma-khramova',
// АС Тимашева
// ЕЮ Тарасова
// ИН Втюрина
// МЮ Валькова
// РК Тимашев
]
type CardData = {
title: string
caption?: string
@@ -83,25 +99,29 @@ const Page: NextPage<Props> = props => {
}
export const unstable_getStaticProps = async (ctx: NextPageContext) => {
const res = await requestGet<IResponseItems<Person>>(createApiUrl('/api/persons'), null)
const title = 'Преподаватели Шлиссельбургской ДХШ'
const imageFile = 'Images/HudozkaCollective2017.jpg'
const resImage = await requestGet(createApiUrl(`/api/image?file=${imageFile}`), null)
const image = get(resImage, 'artifacts.large', null)
const data: CardData[] = (res?.items || [])
const resImage = await requestGet<ImageDefinition>(createApiUrl(`/api/image?file=${imageFile}`), null)
const image = resImage?.artifacts.large
const pages = await Promise.all(persons
.map(page => requestGet<IPage>(createApiUrl(`/api/page?page=${page}`), null))
)
const data: CardData[] = pages
.filter(Boolean)
.map(x => {
const title = `${x.name[0]} ${x.name[1]} ${x.name[2]}`
const image = x.preview.artifacts.large
return {
title,
caption: x.position,
title: x.title,
caption: x.description,
href: x.url,
imageSrc: x.picture.src,
imageSrc: image.src,
imageAlt: title,
imageSrcSet: '',
imageSrcSet: image.set.join(' ')
}
})
return {
props: {
data,
-90
View File
@@ -1,90 +0,0 @@
import Head from 'next/head'
import { App } from 'src/components/App'
import { Article } from 'src/components/Article'
import { Meta } from 'src/components/Meta'
import { MetaBuilder } from 'src/lib/meta'
import { createApiUrl, requestGet, IResponseItems } from 'src/next-lib'
import { NextPage } from 'next'
import { IMeta, Person } from 'src/types'
import { Html } from 'src/components/Html'
interface IProps {
title: string
meta: IMeta
person: any
}
const Index: NextPage<IProps> = props => {
if (!props?.person?.post) {
console.log('kek error', props)
return null
}
return (
<App
showAuthor={true}
>
<Head>
<title>{props.title}</title>
<Meta meta={props.meta} />
</Head>
{!props.person.post ? null : (
<Article
title={''}
tags={[]}
date={null}
shareable={true}
>
<Html
html={props.person.post}
/>
</Article>
)}
</App>
)
}
export const unstable_getStaticProps = async (ctx: any) => {
const id = ctx.params.person
if (!id) {
throw new Error('sry')
}
const person = await requestGet<Person>(createApiUrl(`/api/persons/${id}`), null)
if (!person?.post) {
throw new Error(`post kek ${id}`)
}
const title = person.name.join(' ')
const meta = (new MetaBuilder())
.setImage(person.preview)
.setTitle(title)
.setDescription(person.position)
.build()
return {
props: {
person,
title,
meta,
}
}
}
export const unstable_getStaticPaths = async () => {
const urls = await requestGet<IResponseItems<string>>(createApiUrl(`/api/persons/urls`), null)
return {
paths: urls.items
.map(x => x.replace('/teacher/', ''))
.map(person => ({
params: {
person,
},
})),
}
}
export default Index
-10
View File
@@ -41,15 +41,6 @@ async function getAlbumsUrls() {
}))
}
async function getTeacherUrls() {
const res = await api.get('/api/persons/urls')
return res.data.items.map(url => ({
changefreq: 'monthly',
url,
}))
}
async function getArticleUrls() {
const res = await api.get('/api/articles/urls')
@@ -64,7 +55,6 @@ async function getArticleUrls() {
getMenuUrls(),
getPageUrls(),
getAlbumsUrls(),
getTeacherUrls(),
getArticleUrls(),
])
urls = urls.reduce((urls, i) => urls.concat(i))
-4
View File
@@ -35,10 +35,6 @@ export default {
name: 'Школа',
href: '/',
},
{
name: 'Расписание',
href: '/schedule',
},
{
name: 'Поступление',
href: '/join',