Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(imgur): timestamps are now saved into the decription of each Imgur image in a readable format #216

Merged
merged 1 commit into from
Dec 22, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions documentation.md
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,7 @@ const biketagPortland = await client.getGame('portland')
| `getPlayerFromText` | parses text for a player name based on existing BikeTag posts. (uses `getPlayerFromTextRegex`) |
| `getFoundLocationFromText` | parses text for a found location based on existing BikeTag posts. (uses `getFoundLocationFromTextRegex`) |
| `getHintFromText` | parses text for a hint based on existing BikeTag posts. (uses `getHintFromTextRegex`) |
| `geTimeFromText` | parses text for a timestamp based on existing BikeTag posts. (uses `getTimeFromTextRegex`) |
| `getGPSLocationFromText` | parses text for GPS coordinates. (uses `getGPSLocationFromTextRegex`) |
| `getImageURLsFromText` | parses text for URLs of known BikeTag image providers. (uses `getImageURLsFromTextRegex`) |
| `getDiscussionUrlFromText` | parses a url, or string, for a Reddit post link. (uses `getDiscussionUrlFromTextRegex`) |
Expand All @@ -224,6 +225,7 @@ const biketagPortland = await client.getGame('portland')
| `getPlayerFromTextRegex` | Searches a string for player names associated with BikeTag posts. |
| `getFoundLocationFromTextRegex` | Searches a string for "found at ()" and parses out the innards of that substring. |
| `getHintFromTextRegex` | Searches a string for "(hint: )" and parses out the innards of that substring. |
| `getTimeFromTextRegex` | Searches a string for "on [ x/x/x @ y:y:y ]" and parses out the innards of that substring to a usable timestamp. |
| `getGPSLocationFromTextRegex` | Searches a string for GPS coordinates in the format (lat,long,alt) |
| `getImageURLsFromTextRegex` | Searches a string for an Imgur.com image url |
| `getDiscussionUrlFromTextRegex` | Searches a string for a URL within `{}` brackets |
Expand Down
4 changes: 2 additions & 2 deletions examples/node/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -170,8 +170,8 @@ const runTests = async (out = false) => {
await getTodaysTagsAsync("Imgur", bikeTagImgurInstance, out)
// await queueTagAsync("Imgur", bikeTagImgurInstance, out)
// await getQueueAsync("Imgur", bikeTagImgurInstance, out)
// await getCurrentTagAsync("Imgur", bikeTagImgurInstance, out)
// await get10TagsAsync("Imgur", bikeTagImgurInstance, out)
await getCurrentTagAsync("Imgur", bikeTagImgurInstance, out)
await get10TagsAsync("Imgur", bikeTagImgurInstance, out)
// await get10PlayersAsync("Imgur", bikeTagImgurInstance, out)
}

Expand Down
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "biketag",
"version": "3.1.11",
"version": "3.2.0",
"description": "The Javascript client API for BikeTag Games",
"main": "./biketag.node.js",
"browser": "./biketag.js",
Expand Down
1 change: 1 addition & 0 deletions src/common/data.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ export const cacheKeys = {
bikeTagImage: `biketag::`,
bikeTagsByUser: `userTags::`,
hintText: `hint::`,
timeText: `time::`,
playerText: `player::`,
playerData: `playerData::`,
playerIdText: `playerId::`,
Expand Down
7 changes: 5 additions & 2 deletions src/common/expressions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ export const getTagNumbersFromTextRegex = new RegExp(
/((?:(?:bike\s*)?(?:\s*tag)?)(#|num|number)(\d+)(?:(?:\s*tag)?|(?:\s*proof)?))|((?:bike\s*)?(?:tag\s*)(#|num|number)?\s*(\d+))|((?:(?:found\s*#?)|(?:here'?i?s?\s*))\[?(\d+)\]?)/gi
)

/// Too many ORs here, TEST: tag 1 found at (hint: ) by byers
/// Too many ORs here, TEST: tag 1 found at (hint: ) by byers on [12/12/23@14:23:00]
export const getPlayerFromTextRegex = new RegExp(
/((?:proof\s*(?:found\s*at\s*)?(?:\(.*\))?\s*by\s*)(.*?(?=]|$)))|((?:tag\s*(?:(?:\(\s*hint:\s*)?.*\))?\s*by\s*)(.+?(?=]|\r|\n|$))?)|((?:tag\s*(?:(?:\(\s*hint:\s*)?.*\))?\s*by\s*)(.+?(?=]|\r|\n))?)|((?:credit goes to:\s*)(.*)(?:\sfor finding))|(?:tag\s*)(?:number\s*)?(\d*)?(?:\s*by\s*)(.+?(?=$|\n))/i
/((?:proof\s*(?:found\s*at\s*)?(?:\(.*\))?\s*by\s*)(.*?(?= on \[|$)))|((?:tag\s*(?:(?:\(\s*hint:\s*)?.*\))?\s*by\s*)(.+?(?= on \[|\r|\n|$))?)|((?:tag\s*(?:(?:\(\s*hint:\s*)?.*\))?\s*by\s*)(.+?(?= on \[|\r|\n))?)|((?:credit goes to:\s*)(.*)(?:\sfor finding))|(?:tag\s*)(?:number\s*)?(\d*)?(?:\s*by\s*)(.+?(?= on \[|$|\n))/i
)

export const getFoundLocationFromTextRegex = new RegExp(
Expand All @@ -26,6 +26,9 @@ export const getGameFromInfoFromTextRegex = new RegExp(
export const getGameSlugFromTextRegex = new RegExp(/((\w*)\s*bike\s*tag!?)/i)

export const getHintFromTextRegex = new RegExp(/(?:hint:\s*)(.*)\)/i)
export const getTimeFromTextRegex = new RegExp(
/(?:on\s+\[(\d+\/\d+\/\d\d)@(\d+:\d+:\d+)\])/i
)

export const getGPSLocationFromTextRegex = new RegExp(
/(([0-9]{1,2})[:|°]([0-9]{1,2})[:|'|′]?([0-9]{1,2}(?:\.[0-9]+){0,1})?["|″]([N|S]),?\s*([0-9]{1,3})[:|°]([0-9]{1,2})[:|'|′]?([0-9]{1,2}(?:\.[0-9]+){0,1})?["|″]([E|W]))|((-?\d+(\.\d+)?),\s*(-?\d+(\.\d+)?))/
Expand Down
24 changes: 22 additions & 2 deletions src/common/getters.ts
Original file line number Diff line number Diff line change
Expand Up @@ -454,13 +454,31 @@ export const getImgurFoundImageHashFromBikeTagData = (
return getImageHashFromText(tag.foundImageUrl, cache)
}

export const getDateStringForImgurDescription = (isodate: number): string => {
if (!isodate) return ''

const date = new Date(isodate * 1000)
const dateString = `${date.getMonth() + 1}/${date.getDate()}/${date
.getFullYear()
.toString()
.substring(2)}`
const timeString = `${date.getHours().toString().padStart(2, '0')}:${date
.getMinutes()
.toString()
.padStart(2, '0')}:${date.getSeconds().toString().padStart(2, '0')}`

return ` on [${dateString}@${timeString}]`
}

export const getImgurFoundDescriptionFromBikeTagData = (
tag: Tag,
includeCredit = true
): string =>
`#${tag.tagnumber} proof${
tag.foundLocation ? ` found at (${tag.foundLocation})` : ''
}${includeCredit ? ` by ${tag.foundPlayer}` : ''}`
}${
includeCredit ? ` by ${tag.foundPlayer}` : ''
}${getDateStringForImgurDescription(tag.foundTime)}`

export const getImgurFoundTitleFromBikeTagData = (tag: Tag): string =>
`${
Expand Down Expand Up @@ -493,7 +511,9 @@ export const getImgurMysteryDescriptionFromBikeTagData = (
): string =>
`#${tag.tagnumber} tag ${
includeHint && tag.hint ? `(hint: ${tag.hint})` : ''
}${includeCredit ? ` by ${tag.mysteryPlayer}` : ''}`
}${
includeCredit ? ` by ${tag.mysteryPlayer}` : ''
}${getDateStringForImgurDescription(tag.mysteryTime)}`

export const getOnlyMysteryTagFromTagData = (tagData: Tag): Tag => {
const onlyMysteryTagFields = {
Expand Down
32 changes: 30 additions & 2 deletions src/imgur/helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -321,6 +321,31 @@ export function getConfirmedBoundaryFromText(
return confirmedBoundary
}

export function getTimeFromText(
inputText: string,
fallback?: number,
cache?: typeof TinyCache
): number {
const cacheKey = `${cacheKeys.timeText}${inputText}`
const existingParsed = getCacheIfExists(cacheKey)
if (existingParsed) return existingParsed

const timeMatch = expressions.getTimeFromTextRegex.exec(inputText)

if (!timeMatch || timeMatch?.length < 2) {
fallback = fallback ?? null
/// DO NOT PUT INTO CACHE, NO TIME WAS FOUND
// putCacheIfExists(cacheKey, fallback, cache)
return fallback
}

/// Imgur timestamps are in seconds, not milliseconds, so we should match suit
const time = new Date(`${timeMatch[1]} ${timeMatch[2]}`).getTime() / 1000
putCacheIfExists(cacheKey, time, cache)

return time
}

export function getHintFromText(
inputText: string,
fallback?: string | null,
Expand Down Expand Up @@ -444,7 +469,7 @@ export function getBikeTagFromImgurImageSet(
foundImageLink = foundImage?.link
foundImageDescription = foundImage?.description
foundImageTitle = foundImage?.title
foundTime = foundImage?.datetime
foundTime = getTimeFromText(foundImageDescription, foundImage?.datetime)
foundPlayer = getPlayerFromText(foundImageDescription)
foundLocation = getFoundLocationFromText(foundImageDescription)
confirmedBoundary = getConfirmedBoundaryFromText(foundImageTitle)
Expand All @@ -454,7 +479,10 @@ export function getBikeTagFromImgurImageSet(
mysteryImageLink = mysteryImage?.link
mysteryImageDescription = mysteryImage?.description
mysteryImageTitle = mysteryImage?.title
mysteryTime = mysteryImage?.datetime
mysteryTime = getTimeFromText(
mysteryImageDescription,
mysteryImage?.datetime
)
hint = getHintFromText(mysteryImageDescription)
discussionUrl = getDiscussionUrlFromText(mysteryImageTitle)
mysteryPlayer = getPlayerFromText(mysteryImageDescription)
Expand Down