Browse Source

Convert Mastodon usernames to Twitter ones

aeris 1 year ago
parent
commit
aaf143e5b5
5 changed files with 103 additions and 36 deletions
  1. 2
    0
      Gemfile
  2. 1
    0
      cross-post.gemspec
  3. 74
    35
      lib/cross-post/config.rb
  4. 7
    1
      lib/cross-post/twitter.rb
  5. 19
    0
      spec/config_spec.rb

+ 2
- 0
Gemfile View File

@@ -2,5 +2,7 @@ source 'https://rubygems.org'
2 2
 
3 3
 gem 'mastodon-api', '~> 1.1.0', require: 'mastodon', git: 'https://github.com/tootsuite/mastodon-api.git'
4 4
 gem 'awesome_print'
5
+gem 'dotenv'
6
+gem 'pry'
5 7
 
6 8
 gemspec

+ 1
- 0
cross-post.gemspec View File

@@ -17,6 +17,7 @@ Gem::Specification.new do |spec|
17 17
 	spec.test_files = spec.files.grep %r{^(test|spec|features)/}
18 18
 
19 19
 	spec.add_development_dependency 'bundler', '~> 1.15', '>= 1.15.4'
20
+	spec.add_development_dependency 'rspec', '~> 3.6.0', '>= 3.6.0'
20 21
 
21 22
 	spec.add_dependency 'twitter', '~> 6.1', '>= 6.1.0'
22 23
 	spec.add_dependency 'mastodon-api', '~> 1.1', '>= 1.1.0'

+ 74
- 35
lib/cross-post/config.rb View File

@@ -1,4 +1,5 @@
1 1
 require 'yaml'
2
+require 'fileutils'
2 3
 
3 4
 class CrossPost
4 5
 	class Config
@@ -6,22 +7,26 @@ class CrossPost
6 7
 		DEFAULT_CONFIG_FILE   = 'config.yml'
7 8
 
8 9
 		class SubConfig
9
-			def initialize(file)
10
-				@file = file
11
-				@config = if File.readable? @file
12
-							  File.open(@file) { |f| YAML.safe_load f }
13
-						  else
14
-							  {}
15
-						  end
10
+			def initialize(config = {})
11
+				@config = config
12
+			end
13
+
14
+			def each(&block)
15
+				@config.each &block
16 16
 			end
17 17
 
18 18
 			def [](key)
19
-				current = @config
20
-				key.split(/\./).each do |k|
21
-					current = current[k]
22
-					return nil if current.nil?
19
+				case key
20
+				when String
21
+					current = @config
22
+					key.split(/\./).each do |k|
23
+						current = current[k]
24
+						return nil if current.nil?
25
+					end
26
+					current
27
+				else
28
+					@config[key]
23 29
 				end
24
-				current
25 30
 			end
26 31
 
27 32
 			def fetch(key, default = nil)
@@ -29,20 +34,51 @@ class CrossPost
29 34
 			end
30 35
 
31 36
 			def []=(key, value)
32
-				*key, last = key.split(/\./)
33
-				current    = @config
34
-				key.each do |k|
35
-					next_ = current[k]
36
-					case next_
37
-					when nil
38
-						next_ = current[k] = {}
39
-					when Hash
40
-					else
41
-						raise "Invalid entry, Hash expected, had #{next_.class} (#{next_})"
37
+				case key
38
+				when String
39
+					*key, last = key.to_s.split(/\./)
40
+					current    = @config
41
+					key.each do |k|
42
+						next_ = current[k]
43
+						case next_
44
+						when nil
45
+							next_ = current[k] = {}
46
+						when Hash
47
+						else
48
+							raise "Invalid entry, Hash expected, had #{next_.class} (#{next_})"
49
+						end
50
+						current = next_
42 51
 					end
43
-					current = next_
52
+					current[last] = value
53
+				else
54
+					@config[key] = value
44 55
 				end
45
-				current[last] = value
56
+			end
57
+		end
58
+
59
+		class FifoSubConfig < SubConfig
60
+			def initialize(size = 100)
61
+				@size = size
62
+				@keys = []
63
+				super({})
64
+			end
65
+
66
+			def []=(key, value)
67
+				@keys.delete key
68
+				value = super key, value
69
+				@keys << key
70
+				while @keys.size > @size
71
+					key = @keys.delete_at 0
72
+					@config.delete key
73
+				end
74
+				value
75
+			end
76
+		end
77
+
78
+		class FileSubConfig < SubConfig
79
+			def initialize(file)
80
+				@file = file
81
+				super YAML.load_file @file
46 82
 			end
47 83
 
48 84
 			def put(key, value, save: false)
@@ -51,31 +87,34 @@ class CrossPost
51 87
 			end
52 88
 
53 89
 			def save
54
-					LOGGER.debug "Saving #{@file}"
55
-					yaml = YAML.dump @config
56
-					File.write @file, yaml
90
+				LOGGER.debug "Saving #{@file}"
91
+				yaml = YAML.dump @config
92
+				File.write @file, yaml
57 93
 			end
58 94
 		end
59 95
 
60 96
 		def initialize
61
-			@config = {}
62
-			@dir    = ENV.fetch 'CONFIG_FOLDER', DEFAULT_CONFIG_FOLDER
63
-			file    = ENV.fetch 'CONFIG_FILE', DEFAULT_CONFIG_FILE
97
+			@configs = {}
98
+			@dir     = ENV.fetch 'CONFIG_FOLDER', DEFAULT_CONFIG_FOLDER
99
+			file     = ENV.fetch 'CONFIG_FILE', DEFAULT_CONFIG_FILE
64 100
 			self.load :settings, file
65
-			self.load :posts
66 101
 			self.load :users
102
+			self[:posts] = FifoSubConfig.new
67 103
 		end
68 104
 
69 105
 		def [](name)
70
-			settings = @config[name]
71
-			return settings if settings
72
-			self.load name
106
+			@configs[name]
107
+		end
108
+
109
+		def []=(name, value)
110
+			@configs[name] = value
73 111
 		end
74 112
 
75 113
 		def load(name, file = nil)
76 114
 			file ||= "#{name}.yml"
77 115
 			file = File.join @dir, file
78
-			@config[name] = SubConfig.new file
116
+			FileUtils.touch file unless File.exist? file
117
+			self[name] = FileSubConfig.new file
79 118
 		end
80 119
 	end
81 120
 end

+ 7
- 1
lib/cross-post/twitter.rb View File

@@ -11,6 +11,7 @@ class CrossPost
11 11
 		def initialize(config)
12 12
 			settings = config[:settings]
13 13
 			@posts   = config[:posts]
14
+			@users   = config[:users]
14 15
 
15 16
 			config  = {
16 17
 					consumer_key:        settings['twitter.consumer.key'],
@@ -34,7 +35,7 @@ class CrossPost
34 35
 			parts.each { |p| reply_to = @client.update p, in_reply_to_status: reply_to }
35 36
 
36 37
 			reply_to = reply_to.id if reply_to.respond_to? :id
37
-			@posts.put id, reply_to, save: true
38
+			@posts[id] = reply_to
38 39
 		end
39 40
 
40 41
 		WHITESPACE_TAGS = {
@@ -47,6 +48,11 @@ class CrossPost
47 48
 			content = status.content
48 49
 			content = Sanitize.clean(content, whitespace_elements: WHITESPACE_TAGS).strip
49 50
 			content = CGI.unescape_html content
51
+
52
+			@users.each do |mastodon, twitter|
53
+				content = content.gsub /@\b#{mastodon}\b/, "@#{twitter}"
54
+			end
55
+
50 56
 			media   = status.media_attachments.collect { |f| open f.url }
51 57
 
52 58
 			LOGGER.info { 'Sending to twitter' }

+ 19
- 0
spec/config_spec.rb View File

@@ -0,0 +1,19 @@
1
+require 'cross-post'
2
+
3
+RSpec.describe CrossPost::Config::FifoSubConfig do
4
+	it 'must remove first value in case of overflow' do
5
+		config = CrossPost::Config::FifoSubConfig.new 2
6
+		config[:foo] = :foo
7
+		config[:bar] = :bar
8
+
9
+		expect(config[:foo]).to be :foo
10
+		expect(config[:bar]).to be :bar
11
+		expect(config[:baz]).to be_nil
12
+
13
+		config[:baz] = :baz
14
+
15
+		expect(config[:foo]).to be_nil
16
+		expect(config[:bar]).to be :bar
17
+		expect(config[:baz]).to be :baz
18
+	end
19
+end

Loading…
Cancel
Save