mirror of
https://github.com/kremalicious/blog.git
synced 2024-11-22 09:56:51 +01:00
lib reorg
This commit is contained in:
parent
a65b7ff201
commit
cd1e3dd0b3
@ -1,6 +1,6 @@
|
||||
import { defineConfig } from 'astro/config'
|
||||
import remarkLeadParagraph from '../src/lib/remark-lead-paragraph'
|
||||
import remarkToc from '../src/lib/remark-toc'
|
||||
import { remarkLeadParagraph } from '../src/lib/remark-lead-paragraph/remark-lead-paragraph'
|
||||
import { remarkToc } from '../src/lib/remark-toc/remark-toc'
|
||||
import react from '@astrojs/react'
|
||||
import sitemap from '@astrojs/sitemap'
|
||||
import expressiveCode from 'astro-expressive-code'
|
||||
|
@ -2,7 +2,7 @@ import fs from 'node:fs/promises'
|
||||
import { existsSync, mkdirSync, readFileSync } from 'node:fs'
|
||||
import path from 'node:path'
|
||||
import { fileURLToPath } from 'node:url'
|
||||
import slugify from '../../src/lib/slugify.js'
|
||||
import { slugify } from '../../src/lib/slugify'
|
||||
import type { Ora } from 'ora'
|
||||
|
||||
const __dirname = path.dirname(fileURLToPath(import.meta.url))
|
||||
|
@ -1,7 +1,7 @@
|
||||
import fs from 'node:fs/promises'
|
||||
import { existsSync, mkdirSync, readFileSync } from 'node:fs'
|
||||
import slugify from '../../src/lib/slugify.js'
|
||||
import { readOutExif } from '../../src/lib/exif/index.js'
|
||||
import { slugify } from '../../src/lib/slugify'
|
||||
import { readOutExif } from '@lib/exif'
|
||||
import path from 'node:path'
|
||||
import { fileURLToPath } from 'node:url'
|
||||
import type { Ora } from 'ora'
|
||||
|
@ -1,5 +1,5 @@
|
||||
---
|
||||
import type { Exif } from '@lib/exif/types'
|
||||
import type { Exif } from '@lib/exif'
|
||||
import {
|
||||
Camera,
|
||||
Crosshair,
|
||||
|
@ -1,6 +1,6 @@
|
||||
---
|
||||
import type { CollectionEntry } from 'astro:content'
|
||||
import slugify from '@lib/slugify'
|
||||
import { slugify } from '@lib/slugify'
|
||||
import config from '@config/blog.config'
|
||||
import Tag from '@components/Tag.astro'
|
||||
import styles from './Meta.module.css'
|
||||
|
@ -1,6 +1,7 @@
|
||||
export { getAllPosts } from './getAllPosts'
|
||||
export { getAllTags } from './getAllTags'
|
||||
export { getPostsByTag } from './getPostsByTag'
|
||||
export { loadAndFormatCollection } from './loadAndFormatCollection'
|
||||
export { sortPosts } from './sortPosts'
|
||||
export { getAllPostsForSearch } from './getAllPostsForSearch'
|
||||
export * from './getAllPosts'
|
||||
export * from './getAllTags'
|
||||
export * from './getPostsByTag'
|
||||
export * from './getSlug'
|
||||
export * from './loadAndFormatCollection'
|
||||
export * from './sortPosts'
|
||||
export * from './getAllPostsForSearch'
|
||||
|
78
src/lib/exif/format.test.ts
Normal file
78
src/lib/exif/format.test.ts
Normal file
@ -0,0 +1,78 @@
|
||||
import { it, describe, expect } from 'vitest'
|
||||
import { formatGps, formatExposure, formatExif } from './format'
|
||||
import type { FastExif } from '.'
|
||||
|
||||
describe('Exif formatting functions', () => {
|
||||
describe('formatGps', () => {
|
||||
it('should format GPS data correctly', () => {
|
||||
const input: FastExif['gps'] = {
|
||||
GPSLatitudeRef: 'N',
|
||||
GPSLatitude: [52, 30, 0],
|
||||
GPSLongitudeRef: 'E',
|
||||
GPSLongitude: [13, 23, 0]
|
||||
}
|
||||
const result = formatGps(input)
|
||||
expect(result).toEqual({
|
||||
latitude: 52.5,
|
||||
longitude: 13.383333333333333
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('formatExposure', () => {
|
||||
it('should format exposure correctly for positive numbers', () => {
|
||||
const input = 0.25
|
||||
const result = formatExposure(input)
|
||||
expect(result).toBe('+ 0.25 ev')
|
||||
})
|
||||
|
||||
it('should format exposure correctly for negative numbers', () => {
|
||||
const input = -0.25
|
||||
const result = formatExposure(input)
|
||||
expect(result).toBe('- 0.25 ev')
|
||||
})
|
||||
})
|
||||
|
||||
describe('formatExif', () => {
|
||||
it('should format EXIF data correctly', () => {
|
||||
const input: FastExif = {
|
||||
image: { Model: 'FC7203' },
|
||||
exif: {
|
||||
ISO: 100,
|
||||
FNumber: 2.8,
|
||||
ExposureTime: 1 / 50,
|
||||
FocalLength: 24,
|
||||
ExposureBiasValue: 0,
|
||||
DateTimeOriginal: '2020-12-31T23:59:59.000Z'
|
||||
},
|
||||
gps: {
|
||||
GPSLatitudeRef: 'N',
|
||||
GPSLatitude: [52, 30, 0],
|
||||
GPSLongitudeRef: 'E',
|
||||
GPSLongitude: [13, 23, 0]
|
||||
}
|
||||
}
|
||||
const result = formatExif(input)
|
||||
expect(result).toEqual({
|
||||
date: expect.any(String),
|
||||
iso: 'ISO 100',
|
||||
model: 'DJI Mavic Mini',
|
||||
fstop: 'ƒ/2.8',
|
||||
shutterspeed: '1/50s',
|
||||
focalLength: '24mm',
|
||||
lensModel: undefined,
|
||||
exposure: '+/- 0 ev',
|
||||
gps: {
|
||||
latitude: 52.5,
|
||||
longitude: 13.383333333333333
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
it('returns nothing when no exif received', () => {
|
||||
const input: FastExif = {}
|
||||
const result = formatExif(input)
|
||||
expect(result).toBeUndefined()
|
||||
})
|
||||
})
|
||||
})
|
@ -5,7 +5,7 @@ import getCoordinates from 'dms2dec'
|
||||
import Fraction from 'fraction.js'
|
||||
import type { ExifFormatted, FastExif } from './types.ts'
|
||||
|
||||
function formatGps(gpsData: FastExif['gps']): {
|
||||
export function formatGps(gpsData: FastExif['gps']): {
|
||||
latitude: number
|
||||
longitude: number
|
||||
} {
|
||||
@ -24,18 +24,16 @@ function formatGps(gpsData: FastExif['gps']): {
|
||||
return { latitude, longitude }
|
||||
}
|
||||
|
||||
function formatExposure(exposureMode: number) {
|
||||
if (exposureMode === null || exposureMode === undefined) return
|
||||
export function formatExposure(exposureMode: number) {
|
||||
if (!exposureMode || exposureMode === 0) return `+/- 0 ev`
|
||||
|
||||
const exposureShortened = parseFloat(exposureMode.toFixed(2))
|
||||
let exposure
|
||||
|
||||
if (exposureMode === 0) {
|
||||
exposure = `+/- ${exposureShortened} ev`
|
||||
} else if (exposureMode > 0) {
|
||||
if (exposureMode > 0) {
|
||||
exposure = `+ ${exposureShortened} ev`
|
||||
} else {
|
||||
exposure = `${exposureShortened} ev`
|
||||
exposure = `- ${Math.abs(exposureShortened)} ev`
|
||||
}
|
||||
|
||||
return exposure
|
||||
@ -76,12 +74,12 @@ export function formatExif(exifData: FastExif): ExifFormatted | undefined {
|
||||
const exposure = formatExposure(exposureValue)
|
||||
|
||||
// Model
|
||||
model === 'FC7203' ? 'DJI Mavic Mini' : model
|
||||
const formattedModel = model === 'FC7203' ? 'DJI Mavic Mini' : model
|
||||
|
||||
return {
|
||||
date: date as string,
|
||||
iso,
|
||||
model,
|
||||
model: formattedModel,
|
||||
fstop,
|
||||
shutterspeed,
|
||||
focalLength,
|
||||
|
@ -1,35 +1,2 @@
|
||||
import fs from 'node:fs'
|
||||
import path from 'node:path'
|
||||
import { read } from 'fast-exif'
|
||||
import iptc from 'node-iptc'
|
||||
import type { Exif, ExifFormatted } from './types.ts'
|
||||
import { formatExif } from './format.ts'
|
||||
|
||||
export async function readOutExif(filePath: string): Promise<Exif | undefined> {
|
||||
if (!filePath) return
|
||||
|
||||
const imageId = path.basename(filePath, path.extname(filePath))
|
||||
|
||||
try {
|
||||
// exif
|
||||
const exifData = await read(filePath, true)
|
||||
if (!exifData) return
|
||||
|
||||
// iptc
|
||||
const file = fs.readFileSync(filePath)
|
||||
const iptcData = iptc(file)
|
||||
|
||||
// format before output
|
||||
const exifDataFormatted = formatExif(exifData)
|
||||
|
||||
const exif = {
|
||||
image: imageId,
|
||||
exif: { ...exifDataFormatted } as ExifFormatted,
|
||||
iptc: { ...iptcData }
|
||||
}
|
||||
|
||||
return exif
|
||||
} catch (error: any) {
|
||||
console.error(`${imageId}: ${error.message}`)
|
||||
}
|
||||
}
|
||||
export * from './readOutExif'
|
||||
export * from './types'
|
||||
|
35
src/lib/exif/readOutExif.ts
Normal file
35
src/lib/exif/readOutExif.ts
Normal file
@ -0,0 +1,35 @@
|
||||
import fs from 'node:fs'
|
||||
import path from 'node:path'
|
||||
import { read } from 'fast-exif'
|
||||
import iptc from 'node-iptc'
|
||||
import type { Exif, ExifFormatted } from './types.ts'
|
||||
import { formatExif } from './format.ts'
|
||||
|
||||
export async function readOutExif(filePath: string): Promise<Exif | undefined> {
|
||||
if (!filePath) return
|
||||
|
||||
const imageId = path.basename(filePath, path.extname(filePath))
|
||||
|
||||
try {
|
||||
// exif
|
||||
const exifData = await read(filePath, true)
|
||||
if (!exifData) return
|
||||
|
||||
// iptc
|
||||
const file = fs.readFileSync(filePath)
|
||||
const iptcData = iptc(file)
|
||||
|
||||
// format before output
|
||||
const exifDataFormatted = formatExif(exifData)
|
||||
|
||||
const exif = {
|
||||
image: imageId,
|
||||
exif: { ...exifDataFormatted } as ExifFormatted,
|
||||
iptc: { ...iptcData }
|
||||
}
|
||||
|
||||
return exif
|
||||
} catch (error: any) {
|
||||
console.error(`${imageId}: ${error.message}`)
|
||||
}
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
import { it, describe, expect } from 'vitest'
|
||||
import { getFeedContent } from './feed'
|
||||
import { getFeedContent } from '.'
|
||||
|
||||
describe('getFeedContent', () => {
|
||||
it('should generate post feed content with an image', async () => {
|
@ -1,5 +1,5 @@
|
||||
import type { CollectionEntry } from 'astro:content'
|
||||
import { markdownToHtml } from './markdown'
|
||||
import { markdownToHtml } from '../markdown'
|
||||
|
||||
export async function getFeedContent(
|
||||
post: CollectionEntry<'articles' | 'photos' | 'links'>
|
1
src/lib/feed/index.ts
Normal file
1
src/lib/feed/index.ts
Normal file
@ -0,0 +1 @@
|
||||
export * from './feed'
|
@ -1,5 +1,5 @@
|
||||
import { it, describe, expect, vi } from 'vitest'
|
||||
import { getRepo } from './github'
|
||||
import { getRepo } from '.'
|
||||
|
||||
describe('getRepo Function', () => {
|
||||
const mockResponseData = {
|
1
src/lib/github/index.ts
Normal file
1
src/lib/github/index.ts
Normal file
@ -0,0 +1 @@
|
||||
export * from './github'
|
1
src/lib/remark-lead-paragraph/index.ts
Normal file
1
src/lib/remark-lead-paragraph/index.ts
Normal file
@ -0,0 +1 @@
|
||||
export * from './remark-lead-paragraph'
|
@ -4,7 +4,7 @@ import remarkRehype from 'remark-rehype'
|
||||
import rehypeStringify from 'rehype-stringify'
|
||||
import { VFile } from 'vfile'
|
||||
import { test, expect, beforeAll } from 'vitest'
|
||||
import remarkLeadParagraph, { type MyFile } from './remark-lead-paragraph'
|
||||
import { remarkLeadParagraph, type MyFile } from '.'
|
||||
|
||||
let processor: ReturnType<typeof unified>
|
||||
|
@ -17,7 +17,7 @@ export interface MyFile extends VFile {
|
||||
}
|
||||
}
|
||||
|
||||
export default function remarkLeadParagraph(): Transformer {
|
||||
export function remarkLeadParagraph(): Transformer {
|
||||
return (tree, file) => {
|
||||
// Check if the file is the type we want to process
|
||||
if (!file.history[0]?.includes('articles')) return
|
1
src/lib/remark-toc/index.ts
Normal file
1
src/lib/remark-toc/index.ts
Normal file
@ -0,0 +1 @@
|
||||
export * from './remark-toc'
|
@ -4,7 +4,7 @@ import remarkRehype from 'remark-rehype'
|
||||
import rehypeStringify from 'rehype-stringify'
|
||||
import { VFile } from 'vfile'
|
||||
import { test, expect } from 'vitest'
|
||||
import remarkToc, { type MyFile } from './remark-toc' // Replace with the actual path
|
||||
import { remarkToc, type MyFile } from '.'
|
||||
|
||||
const expectedToc: string = `<ul>
|
||||
<li>
|
@ -19,7 +19,7 @@ export interface MyFile extends VFile {
|
||||
}
|
||||
}
|
||||
|
||||
export default function remarkToc(): Transformer {
|
||||
export function remarkToc(): Transformer {
|
||||
return (tree, file) => {
|
||||
// Check if the file is the type we want to process
|
||||
if (!file.history[0]?.includes('articles')) return
|
1
src/lib/slugify/index.ts
Normal file
1
src/lib/slugify/index.ts
Normal file
@ -0,0 +1 @@
|
||||
export * from './slugify'
|
@ -1,5 +1,5 @@
|
||||
import { test, expect } from 'vitest'
|
||||
import slugify, { slugifyAll } from './slugify'
|
||||
import { slugify, slugifyAll } from '.'
|
||||
|
||||
test('slugify should convert text to slug', () => {
|
||||
const text = 'Hello World!'
|
@ -1,8 +1,6 @@
|
||||
import slugifyLib from 'slugify'
|
||||
|
||||
const slugify = (text: string) =>
|
||||
export const slugify = (text: string) =>
|
||||
slugifyLib(text, { lower: true, remove: /[*+~.()'"!:@]/g })
|
||||
|
||||
export const slugifyAll = (arr: string[]) => arr.map((str) => slugify(str))
|
||||
|
||||
export default slugify
|
1
src/lib/umami/index.ts
Normal file
1
src/lib/umami/index.ts
Normal file
@ -0,0 +1 @@
|
||||
export * from './umami'
|
@ -1,5 +1,5 @@
|
||||
import { test, expect } from 'vitest'
|
||||
import { getUmamiConfig } from './umami'
|
||||
import { getUmamiConfig } from '.'
|
||||
|
||||
test('should throw an error if Umami environment variables are missing in production', () => {
|
||||
const mockEnv = {
|
Loading…
Reference in New Issue
Block a user