twitter2vk_reposter 0.2.6 → 0.3

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.
Files changed (4) hide show
  1. data/ChangeLog +6 -0
  2. data/README.markdown +19 -7
  3. data/bin/twitter2vk_reposter +58 -36
  4. metadata +22 -2
data/ChangeLog CHANGED
@@ -1,3 +1,9 @@
1
+ == 0.3 (Суп)
2
+ * Repost retweets.
3
+ * Add last format, which will be add to status after trimmed text.
4
+ * Add Twitter OAuth authentication.
5
+ * Use rvk gem to post status to VK.
6
+
1
7
  == 0.2.6 (Йорурт)
2
8
  * Fix for Ruby Enterprise Edition.
3
9
 
data/README.markdown CHANGED
@@ -33,17 +33,23 @@ You can follow author @andrey_sitnik to receive last updates info.
33
33
  Config is a YAML files with options:
34
34
 
35
35
  * `vk_session` – session ID to access to VK.
36
- * `twitter` your Twitter login.
36
+ * `twitter_token`, `twitter_secret` data to access to Twitter by OAuth.
37
37
  * `exclude` – list of text or regexp patterns to exclude statuses from your VK.
38
- Code `:reply` will exclude your replies to another Twitter users.
38
+ Code `:reply` will exclude your replies to another users, `:retweet` will
39
+ exclude retweets by you.
39
40
  * `include` – list of text or regexp patterns to repost excluded statuses.
40
41
  * `format` – format reposted status. `%status%` will be replaced by status text,
41
42
  `%url%` by status link on Twitter.
43
+ * `last` — text after `format`. If status will be longer that VK allow,
44
+ `format` will be trim first. So `last` it useful, to set link to Twitter
45
+ status.
46
+ * `retweet` — format of retweet. `%status%` will be replaced by text,
47
+ `%author%` will be replace by tweet author.
42
48
  * `replace` – list of array with 2 elements to replace text in status. Code
43
49
  `:user_to_url` will replace user name to his Twitter link.
44
50
  * `last_message` – file to contain ID of last reposted message.
45
51
 
46
- ## Russian
52
+ ## По-русски
47
53
 
48
54
  Автоматический скрипт для публикации статусов Twitter’а во В Контакте. Так же
49
55
  в отдельном пакете есть консольная утилита для создания настроек и добавления
@@ -79,13 +85,19 @@ Config is a YAML files with options:
79
85
  Настройки хранятся в YAML файле с полями:
80
86
 
81
87
  * `vk_session` – ID сессии для доступка к В Контакте.
82
- * `twitter` — логин от вашего Twitter’а.
88
+ * `twitter_token`, `twitter_secret`данные для доступа к Twitter’у через
89
+ OAuth.
83
90
  * `exclude` — список слов или regexp’ов статусов, которые не нужно публиковать
84
- во В Контакте. Код `:reply` исключ ваши ответы другим пользователя
85
- Twitter.
91
+ во В Контакте. Код `:reply` исключит ваши ответы другим пользователя,
92
+ `:retweet` — ретвиты от вас.
86
93
  * `include` — список слов или regexp’ов для отмены exclude.
87
- * `format` — вид статуса во В Контакте. `%status%` будет заменен на текст
94
+ * `format` — вид статуса во В Контакте. `%status%` будет заменён на текст
88
95
  статуса, `%url%` — на ссылку на статус в Twitter’е.
96
+ * `last` — текст после `format`. Если статус больше допустимого во В Контакте,
97
+ то первым делом обрезается `format`, поэтому `last` удобен для указания ссылки
98
+ на твит.
99
+ * `retweet` — вид ретвита. `%status%` будет заменён на текст, `%author%` — на
100
+ автора твита.
89
101
  * `replace` — список массивов из двух элементов для замены текста в статусе. Код
90
102
  `:user_to_url` заменит имена пользователей на ссылку на их Twitter.
91
103
  * `last_message` — файл, чтобы хранить ID последнего полученного сообщения.
@@ -6,6 +6,8 @@ $KCODE = 'u'
6
6
  require 'rubygems'
7
7
  require 'json'
8
8
  require 'active_support'
9
+ require 'rvk'
10
+ require 'twitter_oauth'
9
11
 
10
12
  require 'yaml'
11
13
  require 'open-uri'
@@ -18,21 +20,22 @@ if ARGV.empty? or '--help' == ARGV.first or '-h' == ARGV.first
18
20
  exit
19
21
  end
20
22
 
21
- def check(text, pattern)
22
- pattern = /^@\w/ if :reply == pattern
23
+ def check(status, pattern)
24
+ return status.has_key?('retweeted_status') if :retweet == pattern
23
25
 
26
+ pattern = /^@\w/ if :reply == pattern
24
27
  if pattern.is_a? String
25
- text.index(pattern)
28
+ status['text'].index(pattern)
26
29
  elsif pattern.is_a? Regexp
27
- text =~ pattern
30
+ status['text'] =~ pattern
28
31
  end
29
32
  end
30
33
 
31
- def repost?(text, config)
34
+ def repost?(status, config)
32
35
  Array(config['exclude']).each do |pattern|
33
- if check(text, pattern)
36
+ if check(status, pattern)
34
37
  Array(config['include']).each do |pattern|
35
- return true if check(text, pattern)
38
+ return true if check(status, pattern)
36
39
  end
37
40
  return false
38
41
  end
@@ -40,56 +43,75 @@ def repost?(text, config)
40
43
  true
41
44
  end
42
45
 
43
- def load_vk_activityhash(session)
44
- request = open('http://vk.com/profile.php', 'Cookie' => "remixsid=#{session}")
45
- profile = request.read.to_s
46
- profile.match(/<input type='hidden' id='activityhash' value='([^']+)'>/)[1]
46
+ def link(status)
47
+ "http://twitter.com/#{status['user']['screen_name']}/status/#{status['id']}"
48
+ end
49
+
50
+ def format_text(status, format)
51
+ format.gsub('%status%', status['text']).
52
+ gsub('%url%', link(status)).
53
+ gsub('%author%', '@' + status['user']['screen_name']).mb_chars
54
+ end
55
+
56
+ def trim_text(text, length)
57
+ if text.length > length
58
+ text[0...(length - 1)] + '…'
59
+ else
60
+ text
61
+ end
47
62
  end
48
63
 
49
64
  def format_status(status, config)
50
- format = config['format'] || '%status%'
51
- text = format.gsub('%status%', status['text']).gsub('%url%',
52
- "twitter.com/#{status['user']['screen_name']}/#{status['id']}")
65
+ last = trim_text(format_text(status, config['last']), 159)
53
66
 
67
+ if status.has_key?('retweeted_status')
68
+ text = format_text(status['retweeted_status'], config['retweet'])
69
+ else
70
+ text = format_text(status, config['format'])
71
+ end
54
72
  Array(config['replace']).each do |replace|
55
- replace = [/@([a-zA-Z0-9_]+)/, 'twitter.com/\\1'] if :user_to_url == replace
73
+ if :user_to_url == replace
74
+ replace = [/@([a-zA-Z0-9_]+)/, 'http//twitter.com/\\1']
75
+ end
56
76
  text.gsub!(replace[0], replace[1])
57
77
  end
58
78
 
59
- text = text.mb_chars
60
- text = text[0...159] + '…' if text.length > 160
61
- text.to_s
79
+ trim_text(text, 160 - last.length).to_s + last.to_s
62
80
  end
63
81
 
64
- def set_status_to_vk(text, session, activityhash)
65
- url = URI.parse('http://vk.com/profile.php')
66
- request = Net::HTTP::Post.new(url.path)
67
- request.set_form_data({'setactivity' => text, 'activityhash' => activityhash})
68
- request['cookie'] = "remixsid=#{session}"
69
-
70
- Net::HTTP.new(url.host, url.port).start { |http| http.request(request) }
71
- end
72
-
73
- config = YAML.load_file(ARGV.first)
82
+ default = {
83
+ 'format' => '%status%',
84
+ 'last' => '',
85
+ 'retweet' => 'RT %author%: %status%'
86
+ }
87
+ config = default.merge(YAML.load_file(ARGV.first))
74
88
 
75
89
  last_message = if File.exists? config['last_message']
76
90
  File.read(config['last_message']).strip
77
91
  end
78
92
 
79
- query = last_message ? "since_id=#{last_message}" : 'count=1'
80
- request = open('http://twitter.com/statuses/user_timeline/' +
81
- "#{config['twitter']}.json?#{query}")
82
- statuses = JSON.parse(request.read.to_s)
93
+ twitter = TwitterOAuth::Client.new(:consumer_key => 'lGdk5MXwNqFyQ6glsog0g',
94
+ :consumer_secret => 'jHfpLGY11clNSh9M0Fqnjl7fzqeHwrKSWTBo4i8TUcE',
95
+ :token => config['twitter_token'], :secret => config['twitter_secret'])
96
+ if last_message
97
+ query = { :since_id => last_message }
98
+ else
99
+ query = { :count => 1 }
100
+ end
101
+ statuses = twitter.user_timeline(query) + twitter.retweeted_by_me(query)
102
+ statuses.sort! { |a, b| a['id'] <=> b['id'] }
103
+
104
+ statuses = [statuses.last] unless last_message
83
105
 
84
106
  unless statuses.empty?
85
- activityhash = load_vk_activityhash(config['vk_session'])
107
+ vk = Vkontakte::User.new(config['vk_session'])
86
108
 
87
109
  last_message_id = nil
88
- statuses.reverse.each do |status|
110
+ statuses.each do |status|
111
+ next unless repost? status, config
89
112
  text = format_status(status, config)
90
113
  last_message_id = status['id']
91
- next unless repost? text, config
92
- set_status_to_vk(text, config['vk_session'], activityhash)
114
+ vk.set_status(text)
93
115
  break
94
116
  end
95
117
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: twitter2vk_reposter
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.6
4
+ version: "0.3"
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andrey "A.I." Sitnik
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2010-03-03 00:00:00 +03:00
12
+ date: 2010-03-22 00:00:00 +03:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
@@ -32,6 +32,26 @@ dependencies:
32
32
  - !ruby/object:Gem::Version
33
33
  version: "0"
34
34
  version:
35
+ - !ruby/object:Gem::Dependency
36
+ name: rvk
37
+ type: :runtime
38
+ version_requirement:
39
+ version_requirements: !ruby/object:Gem::Requirement
40
+ requirements:
41
+ - - ">="
42
+ - !ruby/object:Gem::Version
43
+ version: "0"
44
+ version:
45
+ - !ruby/object:Gem::Dependency
46
+ name: twitter_oauth
47
+ type: :runtime
48
+ version_requirement:
49
+ version_requirements: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - ">="
52
+ - !ruby/object:Gem::Version
53
+ version: "0"
54
+ version:
35
55
  description: " Server script to repost Twitter statuses to VK (\xD0\x92 \xD0\x9A\xD0\xBE\xD0\xBD\xD1\x82\xD0\xB0\xD0\xBA\xD1\x82\xD0\xB5).\n Install twitter2vk to create config and cron task for it.\n"
36
56
  email: andrey@sitnik.ru
37
57
  executables: