Merge pull request #2 from bellingcat/feat/add-existing-sheet

This commit is contained in:
Miguel Sozinho Ramalho
2023-11-27 15:25:29 +00:00
committed by GitHub
9 changed files with 195 additions and 33 deletions

11
package-lock.json generated
View File

@@ -8,6 +8,7 @@
"name": "firebase-archiver-2",
"version": "0.1.0",
"dependencies": {
"@mdi/font": "^7.2.96",
"core-js": "^3.8.3",
"firebase": "^9.22.0",
"firebaseui": "^6.0.2",
@@ -2783,6 +2784,11 @@
"dev": true,
"license": "MIT"
},
"node_modules/@mdi/font": {
"version": "7.3.67",
"resolved": "https://registry.npmjs.org/@mdi/font/-/font-7.3.67.tgz",
"integrity": "sha512-SWxvzRbUQRfewlIV+OF4/YF4DkeTjMWoT8Hh9yeU/5UBVdJZj9Uf4a9+cXjknSIhIaMxZ/4N1O/s7ojApOOGjg=="
},
"node_modules/@nicolo-ribaudo/eslint-scope-5-internals": {
"version": "5.1.1-v1",
"resolved": "https://registry.npmjs.org/@nicolo-ribaudo/eslint-scope-5-internals/-/eslint-scope-5-internals-5.1.1-v1.tgz",
@@ -14324,6 +14330,11 @@
"integrity": "sha512-Hcv+nVC0kZnQ3tD9GVu5xSMR4VVYOteQIr/hwFPVEvPdlXqgGEuRjiheChHgdM+JyqdgNcmzZOX/tnl0JOiI7A==",
"dev": true
},
"@mdi/font": {
"version": "7.3.67",
"resolved": "https://registry.npmjs.org/@mdi/font/-/font-7.3.67.tgz",
"integrity": "sha512-SWxvzRbUQRfewlIV+OF4/YF4DkeTjMWoT8Hh9yeU/5UBVdJZj9Uf4a9+cXjknSIhIaMxZ/4N1O/s7ojApOOGjg=="
},
"@nicolo-ribaudo/eslint-scope-5-internals": {
"version": "5.1.1-v1",
"resolved": "https://registry.npmjs.org/@nicolo-ribaudo/eslint-scope-5-internals/-/eslint-scope-5-internals-5.1.1-v1.tgz",

View File

@@ -3,7 +3,7 @@
"version": "0.1.0",
"private": true,
"scripts": {
"serve": "vue-cli-service serve",
"serve": "vue-cli-service serve --port 8081",
"build": "vue-cli-service build",
"lint": "vue-cli-service lint"
},

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.2 KiB

After

Width:  |  Height:  |  Size: 614 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.7 KiB

After

Width:  |  Height:  |  Size: 5.8 KiB

View File

@@ -1,7 +1,7 @@
<template>
<div>
<div style="margin-bottom: 1em">
<div class="text-h5 mt-5 mb-3" v-if="docs.length > 0">
Your auto-archiver documents
Your auto-archiver sheets
</div>
<v-row v-for="doc in docs" :key="doc.sheetId">
<v-col>

View File

@@ -3,12 +3,12 @@ import { getAuth } from "firebase/auth";
import { getFirestore } from "firebase/firestore";
const firebaseConfig = {
apiKey: "AIzaSyBN5oJ8c_VGhcfesAxXPVmuVnJ_V5MM8JM",
authDomain: "osm-search-364115.firebaseapp.com",
projectId: "osm-search-364115",
storageBucket: "osm-search-364115.appspot.com",
messagingSenderId: "919009657823",
appId: "1:919009657823:web:f3be7f8470a6c36665ba6a"
apiKey: "AIzaSyBEawXAq9pajlVKQtLopWyd_ELDwoUlbDo",
authDomain: "bellingcat-auto-archiver-b85db.firebaseapp.com",
projectId: "bellingcat-auto-archiver-b85db",
storageBucket: "bellingcat-auto-archiver-b85db.appspot.com",
messagingSenderId: "406209235111",
appId: "1:406209235111:web:f27327bed2db7295a43382",
};
const firebaseApp = initializeApp(firebaseConfig);

View File

@@ -14,6 +14,7 @@ import {
addDoc,
query,
where,
limit,
getDocs,
doc,
deleteDoc,
@@ -29,6 +30,7 @@ export default new Vuex.Store({
access_token: null,
docs: [],
loading: false,
errorMessage: "",
},
mutations: {
setUser(state, user) {
@@ -43,6 +45,9 @@ export default new Vuex.Store({
setAccessToken(state, access_token) {
state.access_token = access_token;
},
setErrorMessage(state, errorMessage) {
state.errorMessage = errorMessage;
},
},
actions: {
async signin({ commit, dispatch }) {
@@ -282,7 +287,7 @@ export default new Vuex.Store({
endColumnIndex: 11,
},
description:
"Protecting header row (needed for auto-archiver)",
"Protecting header row (needed for auto-archiver), do not modify archiving column names, you can add and move columns around when no 'Archive in Progress' is present in the 'Archive status' column.",
warningOnly: true,
},
},
@@ -317,5 +322,45 @@ export default new Vuex.Store({
console.error("add (firebase.js): ", error);
}
},
async enable({ state, dispatch, commit }, { spreadsheetId }) {
commit("setLoading", true);
commit("setErrorMessage", "");
try {
// fetch existing sheet
const sheetToEnable = await gapi.client.sheets.spreadsheets.get({
spreadsheetId: spreadsheetId,
});
const q = query(
collection(firebaseFirestore, "sheets"),
where("uid", "==", state.user.uid),
where("sheetId", "==", spreadsheetId),
limit(1)
);
const response = await getDocs(q);
if(response.docs.length > 0) {
throw "Sheet already enabled";
}
const col = await collection(firebaseFirestore, "sheets");
await addDoc(col, {
sheetId: spreadsheetId,
url: sheetToEnable.result.spreadsheetUrl,
timestamp: Date.now(),
uid: state.user.uid,
lastArchived: null,
name: sheetToEnable.result.properties.title,
});
dispatch("getDocs");
} catch (error) {
commit("setErrorMessage", `Unable to add sheet: ${JSON.stringify(error)}`);
commit("setLoading", false);
console.error("add (firebase.js): ", error);
}
},
},
});

View File

@@ -25,27 +25,38 @@
>associated article</a
>.
</p>
<h4>How archiving a Google Spreadsheet works</h4>
<ul>
<li>Add links to the <code>Link</code> column</li>
<li>
Links be archived
<b>every 15 minutes</b>, or you can trigger a manual archive
below
</li>
<li>
You can modify and share the Google Sheet subsequently, but do
not edit the auto archiver column names in the header row or
remove the service account from the shared users
</li>
</ul>
</v-card-text>
</v-card>
<DocList v-if="user" />
<div class="text-h5 mt-5 mb-3">Manage new auto-archiver sheets</div>
<v-card style="margin-bottom: 1em">
<v-card-title>Create a new auto-archiver sheet</v-card-title>
<v-card-text>
<ol style="margin-bottom: 1em">
<li>Press "create" to create a new archiving Google Sheet</li>
<li>
Add links to the "Link" column. They will be archived every 15
minutes, or you can trigger a manual archive below
</li>
<li>
This sheet will be shared with the service account necessary for
Bellingcat's archiving server
</li>
<li>
You can modify and share the Google Sheet subsequently, but do
not edit the column names in the header row or remove the
service account from the shared users
</li>
<li>The sheet will appear in your list</li>
</ol>
</v-card-text>
</v-card>
<v-card>
<v-card-title>Create a new auto archiver sheet</v-card-title>
<v-card-text>
<v-text-field
label="Document name"
v-model="docName"
@@ -58,7 +69,93 @@
>Create</v-btn
>
<v-alert v-if="!user" color="#f2d97c" light icon="mdi-alert"
><a href="#" @click="$store.dispatch('signin')"
><a href="#!" @click="$store.dispatch('signin')"
>Sign in with a Google account</a
>
to continue</v-alert
>
</v-card-text>
</v-card>
<v-card>
<v-card-title
>Enable the auto-archiver in an existing sheet</v-card-title
>
<v-card-text>
<ol style="margin-bottom: 1em">
<li>
Invite
<code
>bellingcat-auto-archiver-api@bellingcat-auto-archiver-b85db.iam.gserviceaccount.com</code
>
into your spreadsheet
</li>
<!-- Link Archive status Destination folder Archive location Archive date Thumbnail Upload timestamp Upload title Textual content Screenshot Hash -->
<li>
Make sure you have the following <b>mandatory</b> column names:
<ul>
<li><code>Link</code> where you will put the URLs.</li>
<li>
<code>Archive Status</code> to monitor progress and success
of archiver
</li>
<li>
<code>Archive location</code> where the link to the archived
content is added
</li>
</ul>
</li>
<li>
Add any of the following <b>optional</b> column names:
<ul>
<li>
<code>Archive date</code> info on when archiving occurred
</li>
<li>
<code>Thumbnail</code> an image preview from archived media
</li>
<li>
<code>Upload timestamp</code> online content creation date
</li>
<li><code>Upload title</code> title</li>
<li><code>Textual content</code> text content</li>
<li><code>Screenshot</code> link to page screenshot</li>
<li>
<code>Hash</code> content hash (for integrity purposes)
</li>
</ul>
</li>
<li>Paste the Google Sheet URL</li>
<li>Press "enable" to add the Google Sheet to your list</li>
<li>
Manually check archiving is working and re-check the steps above
if it is not
</li>
</ol>
<v-alert
v-if="$store.state.errorMessage"
title="Error"
text
type="error"
variant="outlined"
closable
>{{ $store.state.errorMessage }}</v-alert
>
<v-text-field
label="Google Sheet URL"
v-model="spreadsheetUrl"
:hint="spreadsheetId ? 'Detected id: ' + spreadsheetId : ''"
persistent-hint
v-if="user"
></v-text-field>
<v-btn
@click="$store.dispatch('enable', { spreadsheetId })"
:loading="$store.state.loading"
v-if="user"
>Enable</v-btn
>
<v-alert v-if="!user" color="#f2d97c" light icon="mdi-alert"
><a href="#!" @click="$store.dispatch('signin')"
>Sign in with a Google account</a
>
to continue</v-alert
@@ -67,8 +164,6 @@
</v-card>
</v-col>
</v-row>
<DocList v-if="user" />
</v-container>
</template>
@@ -83,12 +178,23 @@ export default {
data() {
return {
docName: "Auto archiver sheet",
spreadsheetUrl: "",
};
},
computed: {
user() {
return this.$store.state.user;
},
spreadsheetId() {
if (
this.spreadsheetUrl.startsWith("http") &&
this.spreadsheetUrl.split("/").length >= 6
) {
return this.spreadsheetUrl.split("/")[5];
}
return this.spreadsheetUrl;
},
},
methods: {},
};
</script>

View File

@@ -1473,9 +1473,9 @@
integrity sha512-Hcv+nVC0kZnQ3tD9GVu5xSMR4VVYOteQIr/hwFPVEvPdlXqgGEuRjiheChHgdM+JyqdgNcmzZOX/tnl0JOiI7A==
"@mdi/font@^7.2.96":
version "7.2.96"
resolved "https://registry.yarnpkg.com/@mdi/font/-/font-7.2.96.tgz#af800d9fe3b424f85ad45e9baa755bd003ab4986"
integrity sha512-e//lmkmpFUMZKhmCY9zdjRe4zNXfbOIJnn6xveHbaV2kSw5aJ5dLXUxcRt1Gxfi7ZYpFLUWlkG2MGSFAiqAu7w==
version "7.3.67"
resolved "https://registry.npmjs.org/@mdi/font/-/font-7.3.67.tgz"
integrity sha512-SWxvzRbUQRfewlIV+OF4/YF4DkeTjMWoT8Hh9yeU/5UBVdJZj9Uf4a9+cXjknSIhIaMxZ/4N1O/s7ojApOOGjg==
"@nicolo-ribaudo/eslint-scope-5-internals@5.1.1-v1":
version "5.1.1-v1"
@@ -3801,9 +3801,9 @@ fs.realpath@^1.0.0:
integrity sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==
fsevents@~2.3.2:
version "2.3.2"
resolved "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz"
integrity sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==
version "2.3.3"
resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.3.tgz#cac6407785d03675a2a5e1a5305c697b347d90d6"
integrity sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==
function-bind@^1.1.1:
version "1.1.1"