diff --git a/src/joann-pupper-bot.cr b/src/joann-pupper-bot.cr index 27f54c8..253fe0f 100644 --- a/src/joann-pupper-bot.cr +++ b/src/joann-pupper-bot.cr @@ -1,120 +1,18 @@ require "./joann-pupper-bot/*" -require "log" -require "telepathy" -require "time" -require "sqlite3" -require "cron_scheduler" +require "option_parser" +config_file = "./config.yaml" -# Chat IDs -CHATID_JOANN = 215301902_i64 -CHATID_DANIEL = 220888832_i64 -DATABASE_URL = "sqlite3://./data.sqlite" -BOT_TOKEN = "599474797:AAEmjQNO32uqurI16blS9FT4OoO7GdUZ6h0" -EXTENSIONS = ["png", "jpeg", "jpg"] -LOGGER = Log.for("joann-pupper-bot") - -class BotConfiguration - include JSON::Serializable - - @[JSON::Field(key: "subreddits")] - property subreddits : Array(String) - - @[JSON::Field(key: "send_cron")] - property send_cron : String - - @[JSON::Field(key: "refresh_cron")] - property refresh_cron : String - - @[JSON::Field(key: "recepients")] - property recepients : Array(Int64) - - def initialize - @subreddits = [ "rarepuppers" ] - @send_cron = "*/30 8-21 * * *" - @refresh_cron = "*/15 * * * *" - @recepients = [ CHATID_DANIEL ] +OptionParser.parse do |parser| + parser.banner = "Usage: joann-pupper-bot [arguments]" + parser.on("-c", "--config=CONFIG", "Select config file") do |c| + config_file = c + end + parser.on("-h", "--help", "Show this message") do + puts parser + exit end end -class PupperBot - @db : DB::Database - - def initialize(@configuration : BotConfiguration) - @telegram_bot = Telepathy::Bot.new BOT_TOKEN - @db = DB.open DATABASE_URL - initialize_db - update_database - initialize_timers - initialize_telegram - send_broadcast - end - - def initialize - initialize BotConfiguration.new - end - - private def initialize_db - @db.exec "create table if not exists posts(id integer primary key, title text, url text unique)" - @db.exec "create table if not exists recepient_posts(recepient integer, post integer, foreign key(post) references posts(id))" - end - - private def initialize_timers - CronScheduler.define do - at(@configuration.send_cron) { send_broadcast } - at(@configuration.refresh_cron) { update_database } - end - end - - private def initialize_telegram - @telegram_bot.command "ping" do |update, args| - @telegram_bot.send_message(update.message.as(Telepathy::Message).chat.id, "pong") - end - - @telegram_bot.command "pupper" do |update, args| - command_chatid = update.message.as(Telepathy::Message).chat.id - send_single command_chatid - end - - @telegram_bot.poll - end - - def send_single(chatid) - unsent_query = "select id, title, url from posts where not exists (select * from recepient_posts where recepient=? and post=id) limit 1" - - unless to_send = @db.query_one? unsent_query, chatid, as: { Int64, String, String } - LOGGER.info { "Unable to find a post to send to #{chatid}." } - return - end - - id, title, url = to_send - LOGGER.info { "Using URL #{url} for request from #{chatid}" } - @db.exec "insert into recepient_posts(recepient, post) values(?, ?)", chatid, id - @telegram_bot.send_photo(chatid, url, title) - end - - def send_broadcast - @configuration.recepients.each do |recepient| - send_single recepient - end - end - - def update_database - unless response = RedditResponse.from_subreddits(@configuration.subreddits) - LOGGER.info { "Unable to find more posts for the database" } - return - end - - posts = response.data.posts_matching { |post| EXTENSIONS.any? { |it| post.url.ends_with? it } } - posts.each do |post| - LOGGER.info { "Trying to save post #{post.title} #{post.url}" } - begin - @db.exec "insert into posts(title, url) values(?, ?)", post.title, post.url - rescue - end - end - end -end - -botc = PupperBot.new +botc = PupperBot.new(BotConfiguration.from_yaml(File.open(config_file))) sleep diff --git a/src/joann-pupper-bot/bot.cr b/src/joann-pupper-bot/bot.cr new file mode 100644 index 0000000..34ffe13 --- /dev/null +++ b/src/joann-pupper-bot/bot.cr @@ -0,0 +1,83 @@ +require "log" +require "telepathy" +require "time" +require "sqlite3" +require "cron_scheduler" + +EXTENSIONS = ["png", "jpeg", "jpg"] +LOGGER = Log.for("joann-pupper-bot") + +class PupperBot + @db : DB::Database + + def initialize(@configuration : BotConfiguration) + @telegram_bot = Telepathy::Bot.new @configuration.token + @db = DB.open "sqlite3://#{@configuration.database}" + initialize_db + update_database + initialize_timers + initialize_telegram + send_broadcast + end + + private def initialize_db + @db.exec "create table if not exists posts(id integer primary key, title text, url text unique)" + @db.exec "create table if not exists recepient_posts(recepient integer, post integer, foreign key(post) references posts(id))" + end + + private def initialize_timers + CronScheduler.define do + at(@configuration.send_cron) { send_broadcast } + at(@configuration.refresh_cron) { update_database } + end + end + + private def initialize_telegram + @telegram_bot.command "ping" do |update, args| + @telegram_bot.send_message(update.message.as(Telepathy::Message).chat.id, "pong") + end + + @telegram_bot.command "pupper" do |update, args| + command_chatid = update.message.as(Telepathy::Message).chat.id + send_single command_chatid + end + + @telegram_bot.poll + end + + def send_single(chatid) + unsent_query = "select id, title, url from posts where not exists (select * from recepient_posts where recepient=? and post=id) limit 1" + + unless to_send = @db.query_one? unsent_query, chatid, as: { Int64, String, String } + LOGGER.info { "Unable to find a post to send to #{chatid}." } + return + end + + id, title, url = to_send + LOGGER.info { "Using URL #{url} for request from #{chatid}" } + @db.exec "insert into recepient_posts(recepient, post) values(?, ?)", chatid, id + @telegram_bot.send_photo(chatid, url, title) + end + + def send_broadcast + @configuration.recipients.each do |recepient| + send_single recepient + end + end + + def update_database + unless response = RedditResponse.from_subreddits(@configuration.subreddits) + LOGGER.info { "Unable to find more posts for the database" } + return + end + + posts = response.data.posts_matching { |post| EXTENSIONS.any? { |it| post.url.ends_with? it } } + posts.each do |post| + LOGGER.info { "Trying to save post #{post.title} #{post.url}" } + begin + @db.exec "insert into posts(title, url) values(?, ?)", post.title, post.url + rescue + end + end + end +end diff --git a/src/joann-pupper-bot/config.cr b/src/joann-pupper-bot/config.cr new file mode 100644 index 0000000..ead556c --- /dev/null +++ b/src/joann-pupper-bot/config.cr @@ -0,0 +1,23 @@ +require "yaml" + +class BotConfiguration + include YAML::Serializable + + @[YAML::Field(key: "token")] + property token : String + + @[YAML::Field(key: "database")] + property database : String = "./data.sqlite" + + @[YAML::Field(key: "subreddits")] + property subreddits : Array(String) = ["rarepuppers"] + + @[YAML::Field(key: "send_cron")] + property send_cron : String = "*/30 8-21 * * *" + + @[YAML::Field(key: "refresh_cron")] + property refresh_cron : String = "*/15 * * * *" + + @[YAML::Field(key: "recipients")] + property recipients : Array(Int64) +end