import 'dart:convert'; import 'dart:io'; import 'dart:math'; import 'package:dio/dio.dart' as dio_lib; var dio = dio_lib.Dio(); // Load mastodon instance url from env final instanceUrl = Platform.environment['INSTANCE_URL']; // Load mastodon auth token from env final authToken = Platform.environment['MASTODON_TOKEN']; Future _postOnMastodon(String postText, bool isHorny) async { await dio.post('$instanceUrl/api/v1/statuses', data: { 'status': postText, if (isHorny) 'sensitive': true, if (isHorny) 'spoiler_text': 'NSFW' }, options: dio_lib.Options(headers: {'Authorization': 'Bearer $authToken'})); } /// Reads a file [fileUri] and adds posts to posts.json /// /// If [fileUri] does not exist, do nothing. /// [fileUri] is a plain text file where the posts are separated by empty lines. /// posts.json is an array of posts Future _importPosts(String fileUri, String outputFile) async { if (!File(fileUri).existsSync()) { return; } final file = File(fileUri); final lines = await file.readAsLines(); final List posts = []; String post = ''; for (final line in lines) { if (line.isEmpty && post != '') { posts.add(post); print('Added post: $post'); post = ''; } else { post += '$line\n'; } } if (post != '') { posts.add(post); print('Added post: $post'); } // Read posts.json and add posts to it final postsJson = json.decode(await File('/data/$outputFile').readAsString()); postsJson.addAll(posts); // Write posts.json await File('/data/$outputFile').writeAsString(json.encode(postsJson)); // Delete file await file.delete(); return; } /// Posts a random string from posts.json to mastodon /// /// If posts.json does not exist, do nothing. /// posts.json is an array of posts /// If an array is empty, do nothing. /// Delete posted post from posts.json Future _postRandomPost() async { if (!File('/data/posts.json').existsSync()) { return; } if (!File('/data/horny.json').existsSync()) { return; } bool isHorny = false; final postsJson = json.decode(await File('/data/posts.json').readAsString()); final hornyPostsJson = json.decode(await File('/data/horny.json').readAsString()); if (postsJson.isEmpty && hornyPostsJson.isEmpty) { return; } if (postsJson.isEmpty) { isHorny = true; } else if (hornyPostsJson.isEmpty) { isHorny = false; } else { // 30% chance of being horny isHorny = Random().nextInt(3) == 0; } final post = isHorny ? hornyPostsJson.removeAt(Random().nextInt(hornyPostsJson.length)) : postsJson.removeAt(Random().nextInt(postsJson.length)); if (isHorny) { await File('/data/horny.json').writeAsString(json.encode(hornyPostsJson)); } else { await File('/data/posts.json').writeAsString(json.encode(postsJson)); } await _postOnMastodon(post, isHorny); return; } void main(List args) async { // If posts.json does not exist, create it and write an empty array if (!File('/data/posts.json').existsSync()) { await File('/data/posts.json').writeAsString(json.encode([])); } if (!File('/data/horny.json').existsSync()) { await File('/data/horny.json').writeAsString(json.encode([])); } // Import posts from files await _importPosts('/data/posts.txt', 'posts.json'); await _importPosts('/data/horny.txt', 'horny.json'); // Post a random post await _postRandomPost(); // Post a random post at random time // Random time is between 1 and 8 hours // Random time is choosen after every post while (true) { await Future.delayed(Duration(minutes: Random().nextInt(60 * 5) + 10)); await _importPosts('/data/posts.txt', 'posts.json'); await _importPosts('/data/horny.txt', 'horny.json'); await _postRandomPost(); } }