Skip to content

Instantly share code, notes, and snippets.

@jirutka
Created February 7, 2017 20:49
Show Gist options
  • Save jirutka/5391d609bf129ffac742012e6305b6a4 to your computer and use it in GitHub Desktop.
Save jirutka/5391d609bf129ffac742012e6305b6a4 to your computer and use it in GitHub Desktop.
Twitter statistics for #FOSDEM and #FOSDEM2017 (2017)

Twitter statistics for #FOSDEM and #FOSDEM2017 (2017)

Includes tweets created between 2017-02-03 and 2017-02-06

  • Number of tweets (excluding RTs): 5597

  • Number of likes: 19306

  • Number of retweets: 8697

  • Number of tweeting users: 1720

Archive of all tweets is available here.

TOP tweeting users

List of most active users sorted by number of their tweets with hashtag #FOSDEM or #FOSDEM2017.

Rank User(s) Tweets

1.

@dchetwynd

81

2.

@A_S_G

79

3.

@NicolasLoubet

48

4.

@bernardtyers

47

5.

@lefred, @lhirlimann

45

6.

@miss_jwo

39

7.

@NURPA

34

8.

@JimStLeger

32

9.

@opensrcdesign

31

10.

@saghul

30

TOP liked tweets

Rank Tweet(s) Favourites

1.

@RouvenWessling: The @videolan team is easily the most recognizable here at #fosdem https://t.co/EXcoCEIcll

559

2.

@pythondj: #Fosdem is it just me or does everyone in the #devroom for #microservices & #containers apparently to be praying fo… https://t.co/qqgHOINQF0

514

3.

@francesc: I had so much fun talking about #golang 1.8 at #FOSDEM! The slides are here https://t.co/ZjgrUhEfWw https://t.co/qgAr3NkdWT

246

4.

@nskuelptor: #fosdem #ulb https://t.co/wCorWaju9q

166

5.

@francesc: I wrote a little #golang program that does hot code swapping with plugins! #fosdem #hackroom #go18 https://t.co/df0wJuCVpL

131

6.

@reactos: #Fosdem visitors were “shocked” when watching Office running natively in #ReactOS in a laptop. https://t.co/zOqyFIIBoh

102

7.

@jonatoni: Don’t forget to pass by @fedora booth at #FOSDEM and say Hi 😊. #FedoraAtFOSDEM https://t.co/Kv8KquEBNJ

96

8.

@ppolo99: This tram is sponsored by @videolan #FOSDEM https://t.co/yNDsQGUxI2

93

9.

@d4v3nu11: Mandatory #XKCD reference https://t.co/bMEnzIduXd #FOSDEM https://t.co/GBYMaeTLKL

77

10.

@fedora: We’re at #FOSDEM2017 in Building K, Level 1! You can find us with many goodies! Don’t forget the #FOSDEM badge!… https://t.co/wYItxq2cVT

@akrabat: Curl’s roadmap is very honest!

Enjoyable talk by @bagder - recommended. #FOSDEM https://t.co/BI8SsR4Ulm

70

TOP retweeted tweets

Rank Tweet(s) Retweets

1.

@pythondj: #Fosdem is it just me or does everyone in the #devroom for #microservices & #containers apparently to be praying fo… https://t.co/qqgHOINQF0

328

2.

@RouvenWessling: The @videolan team is easily the most recognizable here at #fosdem https://t.co/EXcoCEIcll

265

3.

@nskuelptor: #fosdem #ulb https://t.co/wCorWaju9q

126

4.

@francesc: I had so much fun talking about #golang 1.8 at #FOSDEM! The slides are here https://t.co/ZjgrUhEfWw https://t.co/qgAr3NkdWT

98

5.

@d4v3nu11: Mandatory #XKCD reference https://t.co/bMEnzIduXd #FOSDEM https://t.co/GBYMaeTLKL

74

6.

@ppolo99: This tram is sponsored by @videolan #FOSDEM https://t.co/yNDsQGUxI2

65

7.

@reactos: #Fosdem visitors were “shocked” when watching Office running natively in #ReactOS in a laptop. https://t.co/zOqyFIIBoh

54

8.

@akrabat: Curl’s roadmap is very honest!

Enjoyable talk by @bagder - recommended. #FOSDEM https://t.co/BI8SsR4Ulm

48

9.

@DVRansbeeck: What motivates contributors to give their time & skills to #opensource projects? https://t.co/4YyJI39gOk by… https://t.co/BpFwfvrIjU

45

10.

@francesc: I wrote a little #golang program that does hot code swapping with plugins! #fosdem #hackroom #go18 https://t.co/df0wJuCVpL

@electrofelix: So very true #fosdem2017 https://t.co/2WCDcQdWah

39


Generated on 2017-02-07 21:32:24 +0100.

#!/usr/bin/env ruby
#
# Quick & dirty script to generate some Twitter statistics for events.
#
# Usage:
# 1. gem install twitter
# 2. Register your “app” on https://apps.twitter.com/apps and set OAuth
# credentials here.
# 3. Profit!
#
# License:
# Creative Commons CC-Zero This file is made available under the Creative
# Commons CC0 1.0 Universal Public Domain Dedication.
# https://creativecommons.org/publicdomain/zero/1.0/deed.en
#
# Author: Jakub Jirutka
# Version: 2017-02-07
require 'ostruct'
require 'twitter'
require 'yaml'
######## Configuration ########
HASHTAGS = ['#FOSDEM', '#FOSDEM2017']
DATE_FROM = '2017-02-03'
DATE_TO = '2017-02-06'
USERS_LIST_LIMIT = 10
FAVORITES_LIST_LIMIT = 10
RETWEETS_LIST_LIMIT = 10
CACHE_FILE = 'data.yml'
client = Twitter::REST::Client.new do |config|
config.consumer_key = 'YOUR_CONSUMER_KEY'
config.consumer_secret = 'YOUR_CONSUMER_SECRET'
config.access_token = 'YOUR_ACCESS_TOKEN'
config.access_token_secret = 'YOUR_ACCESS_SECRET'
end
year = DATE_FROM.split('-').first
######## Functions ########
def top_tweets_by(field, tweets)
tweets.lazy
.group_by { |tw| tw.public_send(field) }
.sort.reverse
.map { |count, tweets| [count, tweets.sort_by(&:created_at)] }
end
def top_users_by_tweets_count(tweets)
tweets.lazy
.group_by(&:user)
.map { |user, tweets| [user, tweets.count] }
.group_by(&:last) # group by number of tweets
.sort.reverse
.map { |count, tuples| [count, tuples.map(&:first)] } # extract users as value of the entry
.map { |count, users| [count, users.sort_by(&:screen_name)] }
end
def title(level, text)
puts "\n\n#{'=' * level} #{text}\n\n"
end
def table(headers, data, &block)
lines = ['|===', '| ' + headers.join(' | '), '']
data.each_with_index do |item, idx|
(yield item, idx + 1).each do |col|
lines << "| #{col}"
end
lines << ''
end
lines << '|===' << ''
puts lines.join("\n")
end
def format_tweet_text(text)
text.gsub(/@(\w+)/, 'https://twitter.com/\1[@\1]')
.gsub(/(#\w+)/, '_\1_')
.gsub(/^\./, '')
end
def format_date(date)
date.strftime('%a %k:%M').squeeze(' ')
end
format_user = ->(user) { "#{user.uri}[@#{user.screen_name}]" }
format_tweet = ->(tweet) { "@#{tweet.user.screen_name}: #{tweet.uri}[#{tweet.text}]" }
######## Main ########
tweets =
if File.exist? CACHE_FILE
YAML.load(File.read(CACHE_FILE))
else
client.search("#{HASHTAGS.join(' OR ')} since:#{DATE_FROM} until:#{DATE_TO}", result_type: :all)
.reject(&:retweet?)
.tap { |tweets| File.write(CACHE_FILE, YAML.dump(tweets)) }
end
users = tweets.map(&:user).uniq
favourites_count = tweets.map(&:favorite_count).reduce(:+)
retweets_count = tweets.map(&:retweet_count).reduce(:+)
top_users = top_users_by_tweets_count(tweets).take(USERS_LIST_LIMIT)
top_favorites = top_tweets_by(:favorite_count, tweets).take(FAVORITES_LIST_LIMIT)
top_retweets = top_tweets_by(:retweet_count, tweets).take(RETWEETS_LIST_LIMIT)
# Print report in AsciiDoc
title 1, "Twitter statistics for #{HASHTAGS.join(' and ')} (#{year})"
puts "_Includes tweets created between #{DATE_FROM} and #{DATE_TO}_\n\n"
puts "* Number of tweets (excluding RTs): #{tweets.count}"
puts "* Number of likes: #{favourites_count}"
puts "* Number of retweets: #{retweets_count}"
puts "* Number of tweeting users: #{users.count}"
title 2, 'TOP tweeting users'
puts "List of most active users sorted by number of their tweets with hashtag #{HASHTAGS.join(' or ')}.\n\n"
table ['Rank', 'User(s)', 'Tweets'], top_users do |(count, users), idx|
["#{idx}.", users.map(&format_user).join(', '), count]
end
title 2, 'TOP liked tweets'
table ['Rank', 'Tweet(s)', 'Favourites'], top_favorites do |(count, tweets), idx|
["#{idx}.", tweets.map(&format_tweet).join("\n\n"), count]
end
title 2, 'TOP retweeted tweets'
table ['Rank', 'Tweet(s)', 'Retweets'], top_retweets do |(count, tweets), idx|
["#{idx}.", tweets.map(&format_tweet).join("\n\n"), count]
end
puts "\n\n''''"
puts "_Generated on #{Time.now}._"
title 1, "Archive of tweets with #{HASHTAGS.join(' and ')} (#{year})"
puts "_Includes tweets created between #{DATE_FROM} and #{DATE_TO}_\n\n"
tweets.sort_by { |tw| [tw.user.screen_name, tw.created_at] }.group_by(&:user).each do |user, tweets|
title 2, "@#{user.screen_name}"
tweets.each do |tweet|
puts "* #{tweet.uri}[#{format_date(tweet.created_at)}]: #{format_tweet_text(tweet.text)}"
end
end
puts "\n\n''''"
puts "_Generated on #{Time.now}._"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment