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

adding support for web.archive.org #20

Merged
merged 4 commits into from
Jan 8, 2024
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
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ Install on [brave/chrome](https://chrome.google.com/webstore/detail/uniform-time
| Discord | ✅* | |
| Instagram | ✅ | |
| Bluesky | ✅* | works only for english translation of the platform, hard to expand |
| Wayback Machine | ✅ | |
| Linkedin | TODO | come help! [Linkedin-post-timestamp-extractor](https://ollie-boyd.github.io/Linkedin-post-timestamp-extractor/) |
| Youtube | TODO | come help! it requires the official API (see [amnesty youtube dataviewer](https://citizenevidence.amnestyusa.org/)) / and possibly file metadata |
| Facebook | TODO | come help! |
Expand Down
1 change: 1 addition & 0 deletions source/css/hover-popup.css
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@
margin-left: auto;
/* margin-right: auto; */
display: inline-block;
color: initial;
}

.timezone-fixer-popup a {
Expand Down
2 changes: 1 addition & 1 deletion source/js/fixer.js
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ class Fixer {
for (const node of this.getNodes(target)) {
try {
// eslint-disable-next-line no-new
new HoverPopup(target.attachTo(node), target.timestamp(node), target.url(node));
new HoverPopup(target.attachTo(node), target.timestamp(node), target.label ?? 'post', target.url(node));
} catch (error) {
console.error('failed to process node:', error, node);
} finally {
Expand Down
16 changes: 9 additions & 7 deletions source/js/hover-popup.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,19 +11,21 @@ class HoverPopup {
* @param {DateTime} timeData Date/string instance with timezone information
* @param {int} hoverDelay defaults to 200
* @param {int} hoverAfter defaults to 500
* @param {string} postUrl defaults to empty string - if included adds a link to the popup
* @param {string} resourceLabel defaults to empty string - if included used as a label for the resourceUrl
* @param {string} resourceUrl defaults to empty string - if included adds a link to the popup
*/
constructor(attachTo, timeData, postUrl = '', hoverDelay = 200, hoverAfter = 500) {
constructor(attachTo, timeData, resourceLabel = '', resourceUrl = '', hoverDelay = 200, hoverAfter = 500) {
console.log(`received timeData=${timeData} for ${attachTo}`);
this.moment = moment(timeData);
chrome.runtime.sendMessage({action: 'store-data', data: {url: postUrl, time: this.moment.tz('UTC').format()}});
chrome.runtime.sendMessage({action: 'store-data', data: {url: resourceUrl, time: this.moment.tz('UTC').format()}});
this.element = attachTo;
this.version = chrome.runtime.getManifest().version;

// Optional parameters
this.hoverDelay = hoverDelay;
this.hoverAfter = hoverAfter;
this.postUrl = postUrl;
this.resourceUrl = resourceUrl;
this.resourceLabel = resourceLabel;

this.hoverTimeout = null;
this.isHovered = false;
Expand Down Expand Up @@ -119,20 +121,20 @@ class HoverPopup {
</thead>
<tbody>

${moments.map(m => `<tr class="time-item"><td title="${m.description}">${m.timezone}</td><td><a href="#!" class="copy-time-value" copy-value="${m.timeStr}" title="click to copy to clipboard">${m.timeStr}</a></td></tr>`).join('')}
${moments.map(m => `<tr class="time-item"><td title="${m.description}">${m.timezone}</td><td><a class="copy-time-value" copy-value="${m.timeStr}" title="click to copy to clipboard">${m.timeStr}</a></td></tr>`).join('')}

<tr id="custom-${this.randomId}">
<td>
<select id="select-${this.randomId}">
${moment.tz.names().map(tz => `<option value="${tz}">${tz}</option>`).join('')}
</select>
</td>
<td class="time-item"><a href="#!" class="copy-time-value" copy-value="DYNAMIC" title="click to copy to clipboard"></a></td>
<td class="time-item"><a class="copy-time-value" copy-value="DYNAMIC" title="click to copy to clipboard"></a></td>
</tr>
</tbody>
</table>

${this.postUrl ? `<small>post: <a href="${this.postUrl}" title="link to post">${this.postUrl}</a> - <a href="#!" class="copy-time-value" copy-value="${this.postUrl}" title="click to copy to clipboard">copy</a><small/>` : ''}
${this.resourceUrl ? `<small>${this.resourceLabel}: <a href="${this.resourceUrl}" title="link to resource">${this.resourceUrl}</a> - <a class="copy-time-value" copy-value="${this.resourceUrl}" title="click to copy to clipboard">copy</a><small/>` : ''}

<hr/>

Expand Down
47 changes: 47 additions & 0 deletions source/js/timezone-fixers/web-archive.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import moment from 'moment-timezone';
import Fixer from '../fixer.js';

/**
* This script enables uniform timestamps for web.archive.org.
* Timestamps handled by this script:
* - start and end date of snapshots in WayBack Machine's calendar view
* - saved n times between <start date> and <end date>
* - div.captures-range-info a[href^="/web/"]
* - time of capture shown at the top of the calendar view
* - a.capture-link[href^="/web/"]
* - time of crawl in WayBack Machine's calendar view
* - a.snapshot-link[href^="/web/"]
*/
const fixer = new Fixer('WayBackMachine', [
{
name: 'Time of Crawl',
selector: 'div.captures-range-info a[href^="/web/"], a.capture-link[href^="/web/"], a.snapshot-link[href^="/web/"]',
attachTo: node => node,
timestamp(node) {
// Href = "/web/20230304105925/example.com"
const timestamp = node.getAttribute('href').match(/\/web\/(\d+)\//);
if (timestamp && timestamp[1]) {
return parseWayBackMachineDateString(timestamp[1]);
}

return null;
},
url(node) {
// `https://web.archive.org/web/20230304105925/example.com`
return `https://web.archive.org${node.getAttribute('href')}`;
},
label: 'snapshot',
},
]);

fixer.start();

const parseWayBackMachineDateString = dateString => {
// DateString = "20230304105925"
if (typeof dateString !== 'string' || !/^\d{14}$/.test(dateString)) {
return null;
}

return moment(dateString, 'YYYYMMDDHHmmss').utc();
};

7 changes: 6 additions & 1 deletion source/manifest.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "Uniform Timezone Extension",
"version": "0.0.10",
"version": "0.0.11",
"description": "Brings standardization to social media posts' dates and times.",
"homepage_url": "https://github.com/bellingcat/uniform-timezone",
"manifest_version": 3,
Expand Down Expand Up @@ -43,6 +43,11 @@
"js": ["js/timezone-fixers/bluesky.js"],
"css": ["css/hover-popup.css"],
"run_at": "document_end"
}, {
"matches": ["https://web.archive.org/web/*/*"],
"js": ["js/timezone-fixers/web-archive.js"],
"css": ["css/hover-popup.css"],
"run_at": "document_end"
}],
"action": {
"default_popup": "html/popup.html"
Expand Down