fuck_facebook 0.3.0 → 0.5.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 9f15615d0c24e530547c2a40e4509d434bc25578dde17737a5b8d8ef5fe2e68f
4
- data.tar.gz: e3c8a9d379b9df92d0d986bfb1dba35846779d32d4cf1bbf16ae39d1f778fae4
3
+ metadata.gz: 26fe62245cbbcf826c49ee9f89fa3d889ebbb27a662c6076777a17ab181b8715
4
+ data.tar.gz: 59ddf6a1f3450188862019d37e7e75cab558c4948b3be3a1e08997318a108505
5
5
  SHA512:
6
- metadata.gz: cffa79b7c7b58717a8507ba129668db846b40e6682621527b7799665d4fa74a5032a27ef471da20659ee01cd57662e82d85f76aff5b01e43a547d638e0c70374
7
- data.tar.gz: 4acc110f1bb5e7115b28a429594a5fc8459f402fcffe88391a7189687791d677e857117049227d656d977c00b5daac88b4bded2780b1044b81fdce8cc603f0e6
6
+ metadata.gz: b51a6b441c836d9073bbb7312238beee8f902e48b16a87d4e84723db31f661e31a2adb180792e8c0c51020373b43ed67b6afbc4736bd522391a5cbe1cf8890f3
7
+ data.tar.gz: 7d11525734de217266e14b3b49adb8b177adfe8b9d50a20bcb19aea3929029c701fc9bac9188a1a5b223f828fb4a4a57e642b45de074b10abd5b5c01ddb9ea85
data/.gitignore CHANGED
@@ -11,3 +11,5 @@
11
11
  .rspec_status
12
12
 
13
13
  *.gem
14
+
15
+ fuck_facebook_error*.png
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- fuck_facebook (0.2.1)
4
+ fuck_facebook (0.5.1)
5
5
  activesupport (~> 6.1)
6
6
  highline (~> 2.0)
7
7
  mail (~> 2.7)
data/README.md CHANGED
@@ -26,6 +26,9 @@ This way if you have emails going out for new messages, you won't get notified f
26
26
  Here's a complete config file along with an explanation of each option:
27
27
 
28
28
  ```yaml
29
+ errors:
30
+ min_minutes_between_reports: 0 # Only report error if one has not occured in the past X minutes
31
+ include_screenshot: false # Generates a screenshot with the error report
29
32
  smtp:
30
33
  from_email: sender@example.com
31
34
  to_email: receiver@example.com
@@ -36,6 +39,8 @@ smtp:
36
39
  authentication: plain
37
40
  ```
38
41
 
42
+ Place this file in `~/.local/share/fuck-facebook/config.yaml`
43
+
39
44
  These options can be passed as environment variables, by:
40
45
  * Joining the keys with `_`
41
46
  * Capitalizing the entire string
data/bin/fuck-facebook CHANGED
@@ -7,59 +7,23 @@ require_relative '../src/facebook_connection'
7
7
  require_relative '../src/config'
8
8
  require_relative '../src/initializers/mail_initializer'
9
9
  require_relative '../src/senders'
10
-
11
- options = {
12
- headless: true,
13
- clear_cookies: false,
14
- unread_messages: false,
15
- messages: false,
16
- sender: 'stdout'
17
- }
18
-
19
- OptionParser.new do |opts|
20
- opts.banner = 'Usage: fuck-facebook.rb [options]'
21
-
22
- opts.on('-h', '--[no-]headless', 'Run in a headless browser') do |v|
23
- options[:headless] = v
24
- end
25
-
26
- opts.on('--clear-cookies') do |v|
27
- options[:clear_cookies] = v
28
- end
29
-
30
- opts.on('--unread-messages') do |v|
31
- options[:unread_messages] = v
32
- end
33
-
34
- opts.on('--messages') do |v|
35
- options[:messages] = v
36
- end
37
-
38
- opts.on('--login') do |v|
39
- options[:login] = v
40
- end
41
-
42
- opts.on('--sender=SENDER') do |sender|
43
- options[:sender] = sender
44
- end
45
- end.parse!
46
-
47
- facebook_connection = FacebookConnection.new(headless: options[:headless])
48
-
49
- facebook_connection.cookie_handler.clear! if options[:clear_cookies]
50
-
51
- facebook_connection.login if options[:login]
52
-
53
- messages =
54
- if options[:unread_messages]
55
- facebook_connection.message_handler.unread
56
- elsif options[:messages]
57
- facebook_connection.message_handler.messages
58
- else
59
- []
60
- end
61
-
62
- sender = Senders.by_name(options[:sender])
63
- sender.send_messages(messages)
64
-
65
- facebook_connection.close
10
+ require_relative '../src/args_parser'
11
+ require_relative '../src/message_sender'
12
+ require_relative '../src/error_reporter'
13
+
14
+ options = ArgsParser.parse_args
15
+ facebook_connection = nil
16
+
17
+ begin
18
+ facebook_connection = FacebookConnection.new(headless: options[:headless])
19
+ raise 'Error triggered by --simulate-error flag' if options[:simulate_error]
20
+
21
+ facebook_connection.cookie_handler.clear! if options[:clear_cookies]
22
+ facebook_connection.login if options[:login]
23
+ message_sender = MessageSender.new(options[:sender], facebook_connection)
24
+ message_sender.send_unread_messages if options[:unread_messages]
25
+ message_sender.send_messages if options[:messages]
26
+ facebook_connection.close
27
+ rescue StandardError => e
28
+ ErrorReporter.report_error(options[:sender], e, facebook_connection: facebook_connection)
29
+ end
@@ -1,3 +1,3 @@
1
1
  module FuckFacebook
2
- VERSION = '0.3.0'.freeze
2
+ VERSION = '0.5.1'.freeze
3
3
  end
@@ -0,0 +1,82 @@
1
+ class ArgsParser
2
+ DEFAULT_OPTIONS = {
3
+ headless: true,
4
+ clear_cookies: false,
5
+ unread_messages: false,
6
+ messages: false,
7
+ sender: 'stdout',
8
+ simulate_error: false
9
+ }.freeze
10
+
11
+ AVAILABLE_OPTIONS = [
12
+ {
13
+ short: '-h',
14
+ long: '--[no-]headless',
15
+ message: 'Run in a headless browser',
16
+ option: :headless
17
+ },
18
+ {
19
+ short: nil,
20
+ long: '--clear-cookies',
21
+ message: 'Clears all cookies',
22
+ option: :clear_cookies
23
+ },
24
+ {
25
+ short: nil,
26
+ long: '--unread-messages',
27
+ message: 'Outputs all unread messages sent since the last check',
28
+ option: :unread_messages
29
+ },
30
+ {
31
+ short: nil,
32
+ long: '--messages',
33
+ message: 'Outputs all messages sent since the last check',
34
+ option: :messages
35
+ },
36
+ {
37
+ short: nil,
38
+ long: '--login',
39
+ message: 'Prompts for details to login to Facebook account',
40
+ option: :login
41
+ },
42
+ {
43
+ short: nil,
44
+ long: '--sender=SENDER',
45
+ message: 'Send results to either stdout or email',
46
+ option: :sender
47
+ },
48
+ {
49
+ short: nil,
50
+ long: '--simulate-error',
51
+ message: 'Simulates an error so you can see how it will be outputted',
52
+ option: :simulate_error
53
+ }
54
+ ].freeze
55
+
56
+ def self.parse_args
57
+ passed_options = DEFAULT_OPTIONS.dup
58
+
59
+ OptionParser.new do |opts|
60
+ generate_banner(opts)
61
+
62
+ AVAILABLE_OPTIONS.each do |available_option|
63
+ parser_for_available_option(opts, available_option, passed_options)
64
+ end
65
+ end.parse!
66
+
67
+ passed_options
68
+ end
69
+
70
+ private_class_method def self.generate_banner(opts)
71
+ opts.banner = 'Usage: fuck-facebook.rb [options]'
72
+ end
73
+
74
+ private_class_method def self.parser_for_available_option(opts, available_option, passed_options)
75
+ args = [available_option[:long], available_option[:message]]
76
+ args = [available_option[:short]] + args if available_option[:short]
77
+
78
+ opts.on(*args) do |v|
79
+ passed_options[available_option[:option]] = v
80
+ end
81
+ end
82
+ end
data/src/config.rb CHANGED
@@ -3,15 +3,16 @@ require 'yaml'
3
3
  class Config
4
4
  CONFIG_FILE_PATH = "#{ENV['HOME']}/.local/share/fuck-facebook/config.yaml".freeze
5
5
 
6
- def self.option(*path)
6
+ def self.option(*path, default: nil, type: nil)
7
7
  env_var = "FF_#{path.join('_').upcase}"
8
- return ENV[env_var] if ENV[env_var]
9
-
10
8
  path_strings = path.map(&:to_s)
11
- config.dig(*path_strings)
12
- end
13
9
 
14
- private
10
+ value = config.dig(*path_strings)
11
+ value = ENV[env_var] if ENV[env_var]
12
+ value = default if value.nil?
13
+
14
+ cast_value_to_type(value, type)
15
+ end
15
16
 
16
17
  def self.config
17
18
  create_config_file_if_not_exists!
@@ -19,9 +20,26 @@ class Config
19
20
  YAML.load_file(CONFIG_FILE_PATH)
20
21
  end
21
22
 
22
- def self.create_config_file_if_not_exists!
23
+ private_class_method def self.create_config_file_if_not_exists!
23
24
  dirname = File.dirname(CONFIG_FILE_PATH)
24
25
  FileUtils.mkdir_p(dirname) unless File.directory?(dirname)
25
26
  File.write(CONFIG_FILE_PATH, '{}') unless File.exist?(CONFIG_FILE_PATH)
26
27
  end
28
+
29
+ private_class_method def self.cast_value_to_type(value, type)
30
+ case type
31
+ when :boolean
32
+ cast_value_to_boolean(value)
33
+ when :float
34
+ value.to_f
35
+ end
36
+ end
37
+
38
+ private_class_method def self.cast_value_to_boolean(value)
39
+ if [true, false].include?(value)
40
+ value
41
+ elsif value.is_a?(String)
42
+ value == 'true'
43
+ end
44
+ end
27
45
  end
@@ -0,0 +1,44 @@
1
+ class ErrorReporter
2
+ def self.report_error(sender_name, error, facebook_connection: nil)
3
+ raise error unless report_error?
4
+
5
+ Storage.set(:last_error_reported_time, Time.now)
6
+
7
+ screenshot = include_screenshot?(facebook_connection) ? create_screenshot(facebook_connection) : nil
8
+
9
+ Senders.by_name(sender_name).send_error(error, screenshot: screenshot)
10
+ raise error
11
+ end
12
+
13
+ private_class_method def self.include_screenshot?(facebook_connection)
14
+ include_screenshot_config = Config.option(
15
+ :errors,
16
+ :include_screenshot,
17
+ default: false,
18
+ type: :boolean
19
+ )
20
+
21
+ include_screenshot_config && facebook_connection.present?
22
+ end
23
+
24
+ private_class_method def self.create_screenshot(facebook_connection)
25
+ facebook_connection.driver.screenshot_as(:png)
26
+ rescue StandardError
27
+ nil
28
+ end
29
+
30
+ private_class_method def self.report_error?
31
+ min_minutes_between_reports = Config.option(
32
+ :errors,
33
+ :min_minutes_between_reports,
34
+ default: 0,
35
+ type: :float
36
+ )
37
+
38
+ last_error_reported_time = Storage.get(:last_error_reported_time, default: Time.new(2000))
39
+
40
+ next_report_time = last_error_reported_time + min_minutes_between_reports.minutes
41
+
42
+ Time.now > next_report_time
43
+ end
44
+ end
@@ -53,13 +53,12 @@ class MessageHandler
53
53
  end
54
54
 
55
55
  def messages_after_last_message_time(messages)
56
- last_message_time = Storage.get(:last_message_time, default: Time.new(2004, 2, 4))
56
+ last_message_check_time = Storage.get(:last_message_check_time, default: Time.new(2004, 2, 4))
57
+ last_check_time_with_buffer = last_message_check_time - 5.minutes
57
58
 
58
- messages_to_return = messages.select { _1.timestamp > last_message_time }
59
+ messages_to_return = messages.select { _1.timestamp > last_check_time_with_buffer }
59
60
 
60
- last_message_time = messages.map(&:timestamp).max
61
-
62
- Storage.set(:last_message_time, last_message_time)
61
+ Storage.set(:last_message_check_time, Time.now)
63
62
 
64
63
  messages_to_return
65
64
  end
@@ -0,0 +1,25 @@
1
+ class MessageSender
2
+ attr_accessor :sender_name, :facebook_connection
3
+
4
+ def initialize(sender_name, facebook_connection)
5
+ @sender_name = sender_name
6
+ @facebook_connection = facebook_connection
7
+ end
8
+
9
+ def send_unread_messages
10
+ messages = facebook_connection.message_handler.unread
11
+ send_array_of_messages(messages)
12
+ end
13
+
14
+ def send_messages
15
+ messages = facebook_connection.message_handler.messages
16
+ send_array_of_messages(messages)
17
+ end
18
+
19
+ private
20
+
21
+ def send_array_of_messages(messages)
22
+ sender = Senders.by_name(sender_name)
23
+ sender.send_messages(messages)
24
+ end
25
+ end
data/src/senders/email.rb CHANGED
@@ -10,5 +10,15 @@ module Senders
10
10
  end
11
11
  end
12
12
  end
13
+
14
+ def self.send_error(error, screenshot: nil)
15
+ Mail.deliver do
16
+ from Config.option(:smtp, :from_email)
17
+ to Config.option(:smtp, :to_email)
18
+ subject 'Error occurred during Fuck Facebook command'
19
+ body error.full_message(highlight: false)
20
+ add_file filename: 'error_screenshot.png', content: screenshot if screenshot
21
+ end
22
+ end
13
23
  end
14
24
  end
@@ -5,5 +5,14 @@ module Senders
5
5
  puts message
6
6
  end
7
7
  end
8
+
9
+ def self.send_error(error, screenshot: nil)
10
+ puts error
11
+ return if screenshot.nil?
12
+
13
+ filename = "fuck_facebook_error_#{Time.now.iso8601}.png"
14
+ File.write(filename, screenshot)
15
+ puts "Screenshot of error page saved as #{filename}"
16
+ end
8
17
  end
9
18
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fuck_facebook
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 0.5.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Keeyan Nejad
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-12-23 00:00:00.000000000 Z
11
+ date: 2021-12-25 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -94,13 +94,16 @@ files:
94
94
  - fuck_facebook.gemspec
95
95
  - lib/fuck_facebook.rb
96
96
  - lib/fuck_facebook/version.rb
97
+ - src/args_parser.rb
97
98
  - src/authenticator.rb
98
99
  - src/config.rb
99
100
  - src/cookie_handler.rb
101
+ - src/error_reporter.rb
100
102
  - src/facebook_connection.rb
101
103
  - src/fb_duration.rb
102
104
  - src/initializers/mail_initializer.rb
103
105
  - src/message_handler.rb
106
+ - src/message_sender.rb
104
107
  - src/models/message.rb
105
108
  - src/models/message_thread.rb
106
109
  - src/models/user.rb