2021-07-16 22:56:41 +00:00
|
|
|
<template>
|
2022-01-12 12:13:04 +00:00
|
|
|
<div class="text-center">
|
|
|
|
<form>
|
|
|
|
<div>
|
2021-10-08 18:52:51 +00:00
|
|
|
<input ref="fileSelector" type="file" @change="fileChange" />
|
2021-07-16 22:56:41 +00:00
|
|
|
</div>
|
2022-01-12 12:13:04 +00:00
|
|
|
<div>
|
2021-12-27 16:29:25 +00:00
|
|
|
<strong v-text="`Selected Subscriptions: ${selectedSubscriptions}`" />
|
2021-07-16 22:56:41 +00:00
|
|
|
</div>
|
2022-01-12 12:13:04 +00:00
|
|
|
<div>
|
2022-01-12 11:27:08 +00:00
|
|
|
<strong>Override: <input v-model="override" class="checkbox" type="checkbox" /></strong>
|
2021-08-28 07:57:16 +00:00
|
|
|
</div>
|
2022-01-12 12:13:04 +00:00
|
|
|
<div>
|
|
|
|
<a class="btn w-auto" @click="handleImport">Import</a>
|
2021-07-16 22:56:41 +00:00
|
|
|
</div>
|
|
|
|
</form>
|
|
|
|
<br />
|
2021-12-27 14:43:37 +00:00
|
|
|
<strong>Importing Subscriptions from YouTube</strong>
|
2021-07-16 22:56:41 +00:00
|
|
|
<br />
|
|
|
|
<div>
|
|
|
|
Open
|
|
|
|
<a href="https://takeout.google.com/takeout/custom/youtube">takeout.google.com/takeout/custom/youtube</a>
|
|
|
|
<br />
|
|
|
|
In "Select data to include", click on "All YouTube data included" and select only "subscriptions".
|
|
|
|
<br />
|
|
|
|
Create the export and download the zip file.
|
|
|
|
<br />
|
2022-05-16 09:42:08 +00:00
|
|
|
Extract subscriptions.csv from the zip file.
|
2021-07-16 22:56:41 +00:00
|
|
|
<br />
|
|
|
|
Select and import the file above.
|
|
|
|
</div>
|
|
|
|
<br />
|
2021-12-27 14:43:37 +00:00
|
|
|
<strong>Importing Subscriptions from Invidious</strong>
|
2021-07-16 22:56:41 +00:00
|
|
|
<br />
|
|
|
|
<div>
|
|
|
|
Open
|
|
|
|
<a href="https://invidio.us/data_control">invidiou.us/data_control</a>
|
|
|
|
<br />
|
|
|
|
Click on any of the export options.
|
|
|
|
<br />
|
|
|
|
Select and import the file above.
|
|
|
|
</div>
|
|
|
|
<br />
|
2021-12-27 14:43:37 +00:00
|
|
|
<strong>Importing Subscriptions from NewPipe</strong>
|
2021-07-16 22:56:41 +00:00
|
|
|
<br />
|
|
|
|
<div>
|
|
|
|
Go to the Feed tab.
|
|
|
|
<br />
|
|
|
|
Click on the arrow on where it says "Subscriptions".
|
|
|
|
<br />
|
|
|
|
Save the file somewhere.
|
|
|
|
<br />
|
|
|
|
Select and import the file above.
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</template>
|
|
|
|
|
|
|
|
<script>
|
|
|
|
export default {
|
|
|
|
data() {
|
|
|
|
return {
|
|
|
|
subscriptions: [],
|
2021-08-28 07:57:16 +00:00
|
|
|
override: false,
|
2021-07-16 22:56:41 +00:00
|
|
|
};
|
|
|
|
},
|
|
|
|
computed: {
|
|
|
|
selectedSubscriptions() {
|
|
|
|
return this.subscriptions.length;
|
|
|
|
},
|
|
|
|
},
|
|
|
|
activated() {
|
2021-07-21 10:59:53 +00:00
|
|
|
document.title = "Import - Piped";
|
2021-07-16 22:56:41 +00:00
|
|
|
},
|
|
|
|
methods: {
|
|
|
|
fileChange() {
|
2021-10-08 18:52:51 +00:00
|
|
|
const file = this.$refs.fileSelector.files[0];
|
2021-09-05 22:36:42 +00:00
|
|
|
file.text().then(text => {
|
2021-07-16 22:56:41 +00:00
|
|
|
this.subscriptions = [];
|
|
|
|
|
|
|
|
// Invidious
|
|
|
|
if (text.indexOf("opml") != -1) {
|
|
|
|
const parser = new DOMParser();
|
|
|
|
const xmlDoc = parser.parseFromString(text, "text/xml");
|
|
|
|
xmlDoc.querySelectorAll("outline[xmlUrl]").forEach(item => {
|
|
|
|
const url = item.getAttribute("xmlUrl");
|
2022-02-13 19:36:32 +00:00
|
|
|
const id = url.slice(-24);
|
2021-07-16 22:56:41 +00:00
|
|
|
this.subscriptions.push(id);
|
|
|
|
});
|
|
|
|
}
|
|
|
|
// NewPipe
|
2021-09-05 22:36:42 +00:00
|
|
|
else if (text.indexOf("app_version") != -1) {
|
2021-07-16 22:56:41 +00:00
|
|
|
const json = JSON.parse(text);
|
|
|
|
json.subscriptions
|
|
|
|
.filter(item => item.service_id == 0)
|
|
|
|
.forEach(item => {
|
|
|
|
const url = item.url;
|
2022-02-13 19:36:32 +00:00
|
|
|
const id = url.slice(-24);
|
2021-07-16 22:56:41 +00:00
|
|
|
this.subscriptions.push(id);
|
|
|
|
});
|
|
|
|
}
|
|
|
|
// Invidious JSON
|
2021-09-05 22:36:42 +00:00
|
|
|
else if (text.indexOf("thin_mode") != -1) {
|
2021-07-16 22:56:41 +00:00
|
|
|
const json = JSON.parse(text);
|
|
|
|
this.subscriptions = json.subscriptions;
|
|
|
|
}
|
2022-02-13 19:11:44 +00:00
|
|
|
// FreeTube DB
|
|
|
|
else if (text.indexOf("allChannels") != -1) {
|
2023-08-04 15:35:02 +00:00
|
|
|
const lines = text.split("\n");
|
|
|
|
for (let line of lines) {
|
|
|
|
if (line === "") continue;
|
|
|
|
const json = JSON.parse(line);
|
|
|
|
json.subscriptions.forEach(item => {
|
|
|
|
this.subscriptions.push(item.id);
|
|
|
|
});
|
|
|
|
}
|
2022-02-13 19:11:44 +00:00
|
|
|
}
|
2021-07-27 17:44:31 +00:00
|
|
|
// Google Takeout JSON
|
2021-09-05 22:36:42 +00:00
|
|
|
else if (text.indexOf("contentDetails") != -1) {
|
2021-07-16 22:56:41 +00:00
|
|
|
const json = JSON.parse(text);
|
|
|
|
json.forEach(item => {
|
|
|
|
const id = item.snippet.resourceId.channelId;
|
|
|
|
this.subscriptions.push(id);
|
|
|
|
});
|
|
|
|
}
|
2021-07-27 17:44:31 +00:00
|
|
|
|
|
|
|
// Google Takeout CSV
|
2021-09-05 22:36:42 +00:00
|
|
|
else if (file.name.length >= 5 && file.name.slice(-4).toLowerCase() == ".csv") {
|
2021-07-27 17:44:31 +00:00
|
|
|
const lines = text.split("\n");
|
|
|
|
for (let i = 1; i < lines.length; i++) {
|
|
|
|
const line = lines[i];
|
2022-02-13 19:36:32 +00:00
|
|
|
const id = line.slice(0, line.indexOf(","));
|
2021-07-27 17:44:31 +00:00
|
|
|
if (id.length === 24) this.subscriptions.push(id);
|
|
|
|
}
|
|
|
|
}
|
2021-07-16 22:56:41 +00:00
|
|
|
});
|
|
|
|
},
|
|
|
|
handleImport() {
|
2022-08-01 14:16:06 +00:00
|
|
|
if (this.authenticated) {
|
|
|
|
this.fetchJson(
|
|
|
|
this.authApiUrl() + "/import",
|
|
|
|
{
|
|
|
|
override: this.override,
|
2021-08-28 07:57:16 +00:00
|
|
|
},
|
2022-08-01 14:16:06 +00:00
|
|
|
{
|
|
|
|
method: "POST",
|
|
|
|
headers: {
|
|
|
|
Authorization: this.getAuthToken(),
|
|
|
|
},
|
|
|
|
body: JSON.stringify(this.subscriptions),
|
|
|
|
},
|
|
|
|
).then(json => {
|
|
|
|
if (json.message === "ok") window.location = "/feed";
|
|
|
|
});
|
|
|
|
} else {
|
|
|
|
this.importSubscriptionsLocally(this.subscriptions);
|
|
|
|
window.location = "/feed";
|
|
|
|
}
|
|
|
|
},
|
|
|
|
importSubscriptionsLocally(newChannels) {
|
|
|
|
const subscriptions = this.override
|
|
|
|
? [...new Set(newChannels)]
|
2022-08-05 16:55:51 +00:00
|
|
|
: [...new Set((this.getLocalSubscriptions() ?? []).concat(newChannels))];
|
2022-08-01 14:16:06 +00:00
|
|
|
// Sort for better cache hits
|
|
|
|
subscriptions.sort();
|
2022-11-07 10:20:13 +00:00
|
|
|
try {
|
|
|
|
localStorage.setItem("localSubscriptions", JSON.stringify(subscriptions));
|
|
|
|
} catch (e) {
|
|
|
|
alert(this.$t("info.local_storage"));
|
|
|
|
}
|
2021-07-16 22:56:41 +00:00
|
|
|
},
|
|
|
|
},
|
|
|
|
};
|
|
|
|
</script>
|