Rename communities to channels

This commit is contained in:
myrmidex 2025-07-05 02:29:50 +02:00
parent 214b240423
commit d4e9e27c41
8 changed files with 57 additions and 53 deletions

View file

@ -2,22 +2,22 @@
namespace App\Http\Controllers; namespace App\Http\Controllers;
use App\Models\Community; use App\Models\PlatformChannel;
use App\Models\PlatformInstance; use App\Models\PlatformInstance;
use Illuminate\Http\Request; use Illuminate\Http\Request;
use Illuminate\Contracts\View\View; use Illuminate\Contracts\View\View;
use Illuminate\Http\RedirectResponse; use Illuminate\Http\RedirectResponse;
class CommunitiesController extends Controller class PlatformChannelsController extends Controller
{ {
public function index(): View public function index(): View
{ {
$communities = Community::with('platformInstance') $channels = PlatformChannel::with('platformInstance')
->orderBy('platform_instance_id') ->orderBy('platform_instance_id')
->orderBy('name') ->orderBy('name')
->get(); ->get();
return view('pages.communities.index', compact('communities')); return view('pages.channels.index', compact('channels'));
} }
public function create(): View public function create(): View
@ -26,7 +26,7 @@ public function create(): View
->orderBy('name') ->orderBy('name')
->get(); ->get();
return view('pages.communities.create', compact('instances')); return view('pages.channels.create', compact('instances'));
} }
public function store(Request $request): RedirectResponse public function store(Request $request): RedirectResponse
@ -35,46 +35,46 @@ public function store(Request $request): RedirectResponse
'platform_instance_id' => 'required|exists:platform_instances,id', 'platform_instance_id' => 'required|exists:platform_instances,id',
'name' => 'required|string|max:255', 'name' => 'required|string|max:255',
'display_name' => 'required|string|max:255', 'display_name' => 'required|string|max:255',
'community_id' => 'required|string|max:255', 'channel_id' => 'required|string|max:255',
'description' => 'nullable|string', 'description' => 'nullable|string',
]); ]);
Community::create($validated); PlatformChannel::create($validated);
return redirect()->route('communities.index') return redirect()->route('channels.index')
->with('success', 'Community created successfully!'); ->with('success', 'Channel created successfully!');
} }
public function edit(Community $community): View public function edit(PlatformChannel $channel): View
{ {
$instances = PlatformInstance::where('is_active', true) $instances = PlatformInstance::where('is_active', true)
->orderBy('name') ->orderBy('name')
->get(); ->get();
return view('pages.communities.edit', compact('community', 'instances')); return view('pages.channels.edit', compact('channel', 'instances'));
} }
public function update(Request $request, Community $community): RedirectResponse public function update(Request $request, PlatformChannel $channel): RedirectResponse
{ {
$validated = $request->validate([ $validated = $request->validate([
'platform_instance_id' => 'required|exists:platform_instances,id', 'platform_instance_id' => 'required|exists:platform_instances,id',
'name' => 'required|string|max:255', 'name' => 'required|string|max:255',
'display_name' => 'required|string|max:255', 'display_name' => 'required|string|max:255',
'community_id' => 'required|string|max:255', 'channel_id' => 'required|string|max:255',
'description' => 'nullable|string', 'description' => 'nullable|string',
]); ]);
$community->update($validated); $channel->update($validated);
return redirect()->route('communities.index') return redirect()->route('channels.index')
->with('success', 'Community updated successfully!'); ->with('success', 'Channel updated successfully!');
} }
public function destroy(Community $community): RedirectResponse public function destroy(PlatformChannel $channel): RedirectResponse
{ {
$community->delete(); $channel->delete();
return redirect()->route('communities.index') return redirect()->route('channels.index')
->with('success', 'Community deleted successfully!'); ->with('success', 'Channel deleted successfully!');
} }
} }

View file

@ -22,7 +22,7 @@
* @property string $status * @property string $status
* @property Carbon $created_at * @property Carbon $created_at
* @property Carbon $updated_at * @property Carbon $updated_at
* @property Collection $activeCommunities * @property Collection $activeChannels
* @method static where(string $string, PlatformEnum $platform) * @method static where(string $string, PlatformEnum $platform)
* @method static orderBy(string $string) * @method static orderBy(string $string)
* @method static create(array $validated) * @method static create(array $validated)
@ -86,16 +86,16 @@ public function setAsActive(): void
$this->update(['is_active' => true]); $this->update(['is_active' => true]);
} }
public function communities(): BelongsToMany public function channels(): BelongsToMany
{ {
return $this->belongsToMany(Community::class, 'account_communities') return $this->belongsToMany(PlatformChannel::class, 'platform_account_channels')
->withPivot(['is_active', 'priority']) ->withPivot(['is_active', 'priority'])
->withTimestamps(); ->withTimestamps();
} }
public function activeCommunities(): BelongsToMany public function activeChannels(): BelongsToMany
{ {
return $this->communities() return $this->channels()
->wherePivot('is_active', true) ->wherePivot('is_active', true)
->orderByPivot('priority', 'desc'); ->orderByPivot('priority', 'desc');
} }

View file

@ -10,13 +10,15 @@
* @method static create(array $validated) * @method static create(array $validated)
* @property PlatformInstance $platformInstance * @property PlatformInstance $platformInstance
*/ */
class Community extends Model class PlatformChannel extends Model
{ {
protected $table = 'platform_channels';
protected $fillable = [ protected $fillable = [
'platform_instance_id', 'platform_instance_id',
'name', 'name',
'display_name', 'display_name',
'community_id', 'channel_id',
'description', 'description',
'is_active' 'is_active'
]; ];
@ -32,13 +34,15 @@ public function platformInstance(): BelongsTo
public function platformAccounts(): BelongsToMany public function platformAccounts(): BelongsToMany
{ {
return $this->belongsToMany(PlatformAccount::class, 'account_communities') return $this->belongsToMany(PlatformAccount::class, 'platform_account_channels')
->withPivot(['is_active', 'priority']) ->withPivot(['is_active', 'priority'])
->withTimestamps(); ->withTimestamps();
} }
public function getFullNameAttribute(): string public function getFullNameAttribute(): string
{ {
return $this->platformInstance->url . '/c/' . $this->name; // For Lemmy, use /c/ prefix. Other platforms may use different formats
$prefix = $this->platformInstance->platform === 'lemmy' ? '/c/' : '/';
return $this->platformInstance->url . $prefix . $this->name;
} }
} }

View file

@ -42,27 +42,27 @@ public static function fromActiveAccount(): self
public function publish(Article $article, array $extractedData): Collection public function publish(Article $article, array $extractedData): Collection
{ {
$publications = collect(); $publications = collect();
$activeCommunities = $this->account->activeCommunities; $activeChannels = $this->account->activeChannels;
if ($activeCommunities->isEmpty()) { if ($activeChannels->isEmpty()) {
throw new PublishException($article, PlatformEnum::LEMMY, new RuntimeException('No active communities configured for account: ' . $this->account->username)); throw new PublishException($article, PlatformEnum::LEMMY, new RuntimeException('No active channels configured for account: ' . $this->account->username));
} }
$activeCommunities->each(function ($community) use ($article, $extractedData, $publications) { $activeChannels->each(function ($channel) use ($article, $extractedData, $publications) {
try { try {
$publication = $this->publishToCommunity($article, $extractedData, $community); $publication = $this->publishToChannel($article, $extractedData, $channel);
$publications->push($publication); $publications->push($publication);
} catch (Exception $e) { } catch (Exception $e) {
logger()->warning('Failed to publish to community', [ logger()->warning('Failed to publish to channel', [
'article_id' => $article->id, 'article_id' => $article->id,
'community' => $community->name, 'channel' => $channel->name,
'error' => $e->getMessage() 'error' => $e->getMessage()
]); ]);
} }
}); });
if ($publications->isEmpty()) { if ($publications->isEmpty()) {
throw new PublishException($article, PlatformEnum::LEMMY, new RuntimeException('Failed to publish to any community')); throw new PublishException($article, PlatformEnum::LEMMY, new RuntimeException('Failed to publish to any channel'));
} }
return $publications; return $publications;
@ -72,7 +72,7 @@ public function publish(Article $article, array $extractedData): Collection
* @throws PlatformAuthException * @throws PlatformAuthException
* @throws Exception * @throws Exception
*/ */
private function publishToCommunity(Article $article, array $extractedData, $community): ArticlePublication private function publishToChannel(Article $article, array $extractedData, $channel): ArticlePublication
{ {
$token = LemmyAuthService::getToken($this->account); $token = LemmyAuthService::getToken($this->account);
$languageId = $this->getLanguageIdForSource($article->url); $languageId = $this->getLanguageIdForSource($article->url);
@ -81,21 +81,21 @@ private function publishToCommunity(Article $article, array $extractedData, $com
$token, $token,
$extractedData['title'] ?? 'Untitled', $extractedData['title'] ?? 'Untitled',
$extractedData['description'] ?? '', $extractedData['description'] ?? '',
(int) $community->community_id, (int) $channel->channel_id,
$article->url, $article->url,
$extractedData['thumbnail'] ?? null, $extractedData['thumbnail'] ?? null,
$languageId $languageId
); );
return $this->createPublicationRecord($article, $postData, (int) $community->community_id); return $this->createPublicationRecord($article, $postData, (int) $channel->channel_id);
} }
private function createPublicationRecord(Article $article, array $postData, int $communityId): ArticlePublication private function createPublicationRecord(Article $article, array $postData, int $channelId): ArticlePublication
{ {
return ArticlePublication::create([ return ArticlePublication::create([
'article_id' => $article->id, 'article_id' => $article->id,
'post_id' => $postData['post_view']['post']['id'], 'post_id' => $postData['post_view']['post']['id'],
'community_id' => $communityId, 'community_id' => $channelId,
'published_by' => $this->account->username, 'published_by' => $this->account->username,
'published_at' => now(), 'published_at' => now(),
'platform' => 'lemmy', 'platform' => 'lemmy',

View file

@ -8,12 +8,12 @@
{ {
public function up(): void public function up(): void
{ {
Schema::create('communities', function (Blueprint $table) { Schema::create('platform_channels', function (Blueprint $table) {
$table->id(); $table->id();
$table->foreignId('platform_instance_id')->constrained()->onDelete('cascade'); $table->foreignId('platform_instance_id')->constrained()->onDelete('cascade');
$table->string('name'); // "technology" $table->string('name'); // "technology"
$table->string('display_name'); // "Technology" $table->string('display_name'); // "Technology"
$table->string('community_id'); // API ID from platform $table->string('channel_id'); // API ID from platform
$table->text('description')->nullable(); $table->text('description')->nullable();
$table->boolean('is_active')->default(true); $table->boolean('is_active')->default(true);
$table->timestamps(); $table->timestamps();
@ -24,6 +24,6 @@ public function up(): void
public function down(): void public function down(): void
{ {
Schema::dropIfExists('communities'); Schema::dropIfExists('platform_channels');
} }
}; };

View file

@ -8,19 +8,19 @@
{ {
public function up(): void public function up(): void
{ {
Schema::create('account_communities', function (Blueprint $table) { Schema::create('platform_account_channels', function (Blueprint $table) {
$table->foreignId('platform_account_id')->constrained()->onDelete('cascade'); $table->foreignId('platform_account_id')->constrained()->onDelete('cascade');
$table->foreignId('community_id')->constrained()->onDelete('cascade'); $table->foreignId('platform_channel_id')->constrained()->onDelete('cascade');
$table->boolean('is_active')->default(false); $table->boolean('is_active')->default(false);
$table->integer('priority')->default(0); // for ordering $table->integer('priority')->default(0); // for ordering
$table->timestamps(); $table->timestamps();
$table->primary(['platform_account_id', 'community_id']); $table->primary(['platform_account_id', 'platform_channel_id']);
}); });
} }
public function down(): void public function down(): void
{ {
Schema::dropIfExists('account_communities'); Schema::dropIfExists('platform_account_channels');
} }
}; };

View file

@ -13,9 +13,9 @@
<i class="fas fa-share-alt mr-3"></i> <i class="fas fa-share-alt mr-3"></i>
Platforms Platforms
</a> </a>
<a href="/communities" class="flex items-center px-4 py-3 text-gray-300 hover:bg-gray-700 hover:text-white transition-colors {{ request()->is('communities*') ? 'bg-gray-700 text-white' : '' }}"> <a href="/channels" class="flex items-center px-4 py-3 text-gray-300 hover:bg-gray-700 hover:text-white transition-colors {{ request()->is('channels*') ? 'bg-gray-700 text-white' : '' }}">
<i class="fas fa-users mr-3"></i> <i class="fas fa-hashtag mr-3"></i>
Communities Channels
</a> </a>
<a href="/logs" class="flex items-center px-4 py-3 text-gray-300 hover:bg-gray-700 hover:text-white transition-colors {{ request()->is('logs') ? 'bg-gray-700 text-white' : '' }}"> <a href="/logs" class="flex items-center px-4 py-3 text-gray-300 hover:bg-gray-700 hover:text-white transition-colors {{ request()->is('logs') ? 'bg-gray-700 text-white' : '' }}">
<i class="fas fa-list mr-3"></i> <i class="fas fa-list mr-3"></i>

View file

@ -24,4 +24,4 @@
Route::resource('platforms', App\Http\Controllers\PlatformAccountsController::class)->names('platforms'); Route::resource('platforms', App\Http\Controllers\PlatformAccountsController::class)->names('platforms');
Route::post('/platforms/{platformAccount}/set-active', [App\Http\Controllers\PlatformAccountsController::class, 'setActive'])->name('platforms.set-active'); Route::post('/platforms/{platformAccount}/set-active', [App\Http\Controllers\PlatformAccountsController::class, 'setActive'])->name('platforms.set-active');
Route::resource('communities', App\Http\Controllers\CommunitiesController::class)->names('communities'); Route::resource('channels', App\Http\Controllers\PlatformChannelsController::class)->names('channels');