Compare commits
5 commits
Author | SHA1 | Date | |
---|---|---|---|
920c8932a0 | |||
dee2522676 | |||
b5adf7dbd0 | |||
8dc8688d2e | |||
e490eda3d3 |
11 changed files with 101 additions and 39 deletions
0
_already_sent/.gitkeep
Normal file
0
_already_sent/.gitkeep
Normal file
|
@ -1 +0,0 @@
|
||||||
https://www.openculture.com/2025/05/how-frank-lloyd-wrights-architecture-evolved-over-70-years-and-changed-america.html
|
|
|
@ -1 +0,0 @@
|
||||||
https://en.wikipedia.org/wiki/Rainhill_trials
|
|
|
@ -1 +0,0 @@
|
||||||
https://fossforce.com/2025/04/is-free-or-open-source-software-sustainable/
|
|
|
@ -1 +0,0 @@
|
||||||
https://manualdousuario.net/en/writing-chatgpt-ai/
|
|
|
@ -1 +0,0 @@
|
||||||
https://goblackcat.com/feeling-exhausted/
|
|
|
@ -1 +0,0 @@
|
||||||
https://fenati.org.br/brasil-prepara-marco-regulatorio-para-data-centers-com-beneficios-fiscais-e-regras-sustentaveis/#datacenter
|
|
0
_credentials/.gitkeep
Normal file
0
_credentials/.gitkeep
Normal file
|
@ -1,27 +1,83 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
|
||||||
// === Example use ===
|
// === Example use ===
|
||||||
#addVideoToFediList('https://www.youtube.com/watch?v=dQw4w9WgXcQ');
|
#addVideoToFediList('https://www.youtube.com/watch?v=dQw4w9WgXcQ');
|
||||||
|
|
||||||
|
require_once('utils.php');
|
||||||
|
|
||||||
function isYouTubeLink($url) {
|
function isYouTubeLink($url) {
|
||||||
return preg_match('#^(https?://)?(www\.)?(youtube\.com/watch\?v=|youtu\.be/)[a-zA-Z0-9_-]{11}#', $url);
|
return preg_match('#^(https?://)?(www\.)?(youtube\.com/watch\?v=|youtu\.be/)[a-zA-Z0-9_-]{11}#', $url);
|
||||||
}
|
}
|
||||||
|
|
||||||
function addVideoToFediList($videoUrl) {
|
function addVideoToFediList($videoUrl) {
|
||||||
|
|
||||||
$playlistId = @file_get_contents(__DIR__ .'/_credentials/fedilist_id.txt');
|
$credentialsDir = __DIR__ . '/_credentials';
|
||||||
|
$tokenPath = "$credentialsDir/token.json";
|
||||||
|
$playlistId = @file_get_contents("$credentialsDir/fedilist_id.txt");
|
||||||
|
|
||||||
if (!$playlistId) {
|
if (!$playlistId) {
|
||||||
echo "‼️ Error: FediList ID not found. Make sure fedilist_id.txt exists.\n";
|
echo "‼️ Error: FediList ID not found. Make sure fedilist_id.txt exists.\n";
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
$token = @json_decode(file_get_contents(__DIR__ .'/_credentials/token.json'), true);
|
// === Load client credentials ===
|
||||||
|
$secrets = json_decode(file_get_contents("$credentialsDir/client_secret.json"), true);
|
||||||
|
$client = $secrets['installed'] ?? $secrets['web'] ?? null;
|
||||||
|
|
||||||
|
if (!$client || !isset($client['client_id'], $client['client_secret'])) {
|
||||||
|
die("Error: Invalid client_secret.json format.\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
$clientId = $client['client_id'];
|
||||||
|
$clientSecret = $client['client_secret'];
|
||||||
|
|
||||||
|
// === Load token ===
|
||||||
|
$token = @json_decode(file_get_contents($tokenPath), true);
|
||||||
if (!$token || !isset($token['access_token'])) {
|
if (!$token || !isset($token['access_token'])) {
|
||||||
echo "‼️ Error: token.json missing or invalid. Authenticate first.\n";
|
echo "‼️ Error: token.json missing or invalid. Authenticate first.\n";
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Extract video ID from URL
|
//print_r($token);
|
||||||
|
|
||||||
|
// === Refresh token if expired ===
|
||||||
|
|
||||||
|
// Don't let it expire, refresh if we have less than 15 minutes left
|
||||||
|
// Google Tokens usually last 60 min, so more ore less around 45min we get a new one
|
||||||
|
$refreshSecondMargin = 15*60;
|
||||||
|
|
||||||
|
if (isset($token['expires_at'])) {
|
||||||
|
$secondsLeft = $token['expires_at'] - time();
|
||||||
|
if ($secondsLeft > $refreshSecondMargin) {
|
||||||
|
$minutes = floor($secondsLeft / 60);
|
||||||
|
$seconds = $secondsLeft % 60;
|
||||||
|
echo "⏳ Token expires in $minutes minutes and $seconds seconds.\n";
|
||||||
|
} else {
|
||||||
|
echo "🔄 Access token expired or will expire in less than $refreshSecondMargin seconds. (Seconds Left: $secondsLeft). Refreshing...\n";
|
||||||
|
|
||||||
|
$refreshResponse = curlPost('https://oauth2.googleapis.com/token', [
|
||||||
|
'client_id' => $clientId,
|
||||||
|
'client_secret' => $clientSecret,
|
||||||
|
'refresh_token' => $token['refresh_token'],
|
||||||
|
'grant_type' => 'refresh_token'
|
||||||
|
]);
|
||||||
|
|
||||||
|
if (isset($refreshResponse['access_token'])) {
|
||||||
|
$token['access_token'] = $refreshResponse['access_token'];
|
||||||
|
$token['expires_in'] = $refreshResponse['expires_in'];
|
||||||
|
$token['expires_at'] = time() + $refreshResponse['expires_in'];
|
||||||
|
file_put_contents($tokenPath, json_encode($token));
|
||||||
|
echo "✅ Token refreshed.\n";
|
||||||
|
} else {
|
||||||
|
echo "‼️ Failed to refresh token: " . ($refreshResponse['error'] ?? 'unknown') . "\n";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// === Extract video ID ===
|
||||||
if (!preg_match('/(?:v=|\/)([a-zA-Z0-9_-]{11})/', $videoUrl, $matches)) {
|
if (!preg_match('/(?:v=|\/)([a-zA-Z0-9_-]{11})/', $videoUrl, $matches)) {
|
||||||
echo "⁉️ Invalid YouTube URL: $videoUrl\n";
|
echo "⁉️ Invalid YouTube URL: $videoUrl\n";
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
#!/usr/bin/php
|
#!/usr/bin/php
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
require_once('utils.php');
|
||||||
|
|
||||||
// === Load client credentials ===
|
// === Load client credentials ===
|
||||||
$secrets = json_decode(file_get_contents(__DIR__ . '/_credentials/client_secret.json'), true);
|
$secrets = json_decode(file_get_contents(__DIR__ . '/_credentials/client_secret.json'), true);
|
||||||
$client = $secrets['installed'] ?? $secrets['web'] ?? null;
|
$client = $secrets['installed'] ?? $secrets['web'] ?? null;
|
||||||
|
@ -12,31 +14,13 @@ if (!$client || !isset($client['client_id'], $client['client_secret'])) {
|
||||||
$clientId = $client['client_id'];
|
$clientId = $client['client_id'];
|
||||||
$clientSecret = $client['client_secret'];
|
$clientSecret = $client['client_secret'];
|
||||||
|
|
||||||
// === cURL helper function ===
|
|
||||||
function curlPost($url, $data, $headers = []) {
|
|
||||||
$ch = curl_init($url);
|
|
||||||
curl_setopt($ch, CURLOPT_POST, true);
|
|
||||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
|
||||||
curl_setopt($ch, CURLOPT_HTTPHEADER, array_merge([
|
|
||||||
'Content-Type: application/x-www-form-urlencoded',
|
|
||||||
'User-Agent: curl/7.64.1'
|
|
||||||
], $headers));
|
|
||||||
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($data));
|
|
||||||
$response = curl_exec($ch);
|
|
||||||
if (curl_errno($ch)) {
|
|
||||||
die("cURL error: " . curl_error($ch) . "\n");
|
|
||||||
}
|
|
||||||
curl_close($ch);
|
|
||||||
return json_decode($response, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
// === Create playlist helper ===
|
// === Create playlist helper ===
|
||||||
function createPlaylist($accessToken) {
|
function createPlaylist($accessToken) {
|
||||||
|
|
||||||
$path = __DIR__ . '/_credentials/fedilist_id.txt';
|
$path = __DIR__ . '/_credentials/fedilist_id.txt';
|
||||||
|
|
||||||
if (file_exists($path)) {
|
if (file_exists($path)) {
|
||||||
echo "FediList Playlist ID already exists at :$path\n";
|
echo "✅ FediList Playlist ID already exists at :$path\n";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -88,11 +72,15 @@ if (!isset($deviceData['user_code'])) {
|
||||||
die("Failed to get device code.\n");
|
die("Failed to get device code.\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
echo "\n";
|
||||||
|
echo "==============================\n";
|
||||||
echo "==== DEVICE AUTHORIZATION ====\n";
|
echo "==== DEVICE AUTHORIZATION ====\n";
|
||||||
|
echo "==============================\n";
|
||||||
echo "Visit: " . $deviceData['verification_url'] . "\n";
|
echo "Visit: " . $deviceData['verification_url'] . "\n";
|
||||||
echo "Enter code: " . $deviceData['user_code'] . "\n\n";
|
echo "\n";
|
||||||
|
echo "Enter code: " . $deviceData['user_code'] . "\n\nFinish login process and come back here.";
|
||||||
|
|
||||||
echo "Waiting...\n";
|
echo "\n\nWaiting...";
|
||||||
|
|
||||||
|
|
||||||
// === Step 2: Poll for token ===
|
// === Step 2: Poll for token ===
|
||||||
|
@ -100,6 +88,7 @@ $token = null;
|
||||||
$startTime = time();
|
$startTime = time();
|
||||||
while (true) {
|
while (true) {
|
||||||
sleep($deviceData['interval']);
|
sleep($deviceData['interval']);
|
||||||
|
echo ".";
|
||||||
|
|
||||||
$tokenResponse = curlPost('https://oauth2.googleapis.com/token', [
|
$tokenResponse = curlPost('https://oauth2.googleapis.com/token', [
|
||||||
'client_id' => $clientId,
|
'client_id' => $clientId,
|
||||||
|
@ -109,22 +98,24 @@ while (true) {
|
||||||
]);
|
]);
|
||||||
|
|
||||||
if (isset($tokenResponse['access_token'])) {
|
if (isset($tokenResponse['access_token'])) {
|
||||||
$token = $tokenResponse;
|
$tokenResponse['expires_at'] = time() + $tokenResponse['expires_in'];
|
||||||
echo "Saving token.json\n";
|
$path = __DIR__ . '/_credentials/token.json';
|
||||||
file_put_contents(__DIR__ . '/_credentials/token.json', json_encode($token));
|
file_put_contents($path, json_encode($tokenResponse));
|
||||||
break;
|
echo "\n✅ Token saved as $path.\n";
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (isset($tokenResponse['error']) && $tokenResponse['error'] !== 'authorization_pending') {
|
if (isset($tokenResponse['error']) && $tokenResponse['error'] !== 'authorization_pending') {
|
||||||
die("Auth error: " . $tokenResponse['error'] . "\n");
|
die("\nAuth error: " . $tokenResponse['error'] . "\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (time() - $startTime > $deviceData['expires_in']) {
|
if (time() - $startTime > $deviceData['expires_in']) {
|
||||||
die("Authorization timed out.\n");
|
die("\nAuthorization timed out.\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// === Step 3: Create FediList Playlist ===
|
// === Step 3: Create FediList Playlist ===
|
||||||
createPlaylist($token['access_token']);
|
createPlaylist($tokenResponse['access_token']);
|
||||||
|
|
||||||
?>
|
?>
|
||||||
|
|
21
utils.php
Normal file
21
utils.php
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
// === cURL helper function ===
|
||||||
|
function curlPost($url, $data, $headers = []) {
|
||||||
|
$ch = curl_init($url);
|
||||||
|
curl_setopt($ch, CURLOPT_POST, true);
|
||||||
|
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
||||||
|
curl_setopt($ch, CURLOPT_HTTPHEADER, array_merge([
|
||||||
|
'Content-Type: application/x-www-form-urlencoded',
|
||||||
|
'User-Agent: curl/7.64.1'
|
||||||
|
], $headers));
|
||||||
|
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($data));
|
||||||
|
$response = curl_exec($ch);
|
||||||
|
if (curl_errno($ch)) {
|
||||||
|
die("cURL error: " . curl_error($ch) . "\n");
|
||||||
|
}
|
||||||
|
curl_close($ch);
|
||||||
|
return json_decode($response, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
?>
|
Loading…
Add table
Add a link
Reference in a new issue