165 lines
5.3 KiB
Python
Executable file
165 lines
5.3 KiB
Python
Executable file
#!/usr/bin/env python3
|
|
# A simple class to get geographical data from fas and FedoraAsk
|
|
# Alberto Rodriguez Sanchez bt0dotninja@fedoraproject.org
|
|
# Renato Silva resilva87@fedoraproject.org
|
|
|
|
|
|
from fedora.client.fas2 import AccountSystem
|
|
from fedora.client import AuthError
|
|
from collections import Counter
|
|
from datetime import datetime
|
|
|
|
import sys
|
|
import numpy as np
|
|
import pandas as pd
|
|
import json
|
|
import requests
|
|
import configparser
|
|
|
|
|
|
class geofp(object):
|
|
'''
|
|
An object for querying the Fedora Account System and get Geographical data from groups and the whole project
|
|
'''
|
|
def __init__(self,ConfigFile):
|
|
'''A Simple constructor for geofp object'''
|
|
Config = configparser.ConfigParser()
|
|
Config.read(ConfigFile)
|
|
options = Config.options('FAS')
|
|
userdata={}
|
|
for opt in options:
|
|
userdata[opt] = Config.get('FAS', opt)
|
|
|
|
user=userdata['user']
|
|
password=userdata['pass']
|
|
self.members=None
|
|
self.fas = AccountSystem(username=user, password=password)
|
|
|
|
def by_group(self, group, active_date=None):
|
|
'''get information by group'''
|
|
groupMembers=self.fas.group_members(group)
|
|
GeoData={}
|
|
for member in groupMembers:
|
|
gd=self.fas.people_by_key(key=u'username', search=member['username'])
|
|
GeoData.update(gd)
|
|
|
|
#To pandas DataFrame
|
|
self.members=pd.DataFrame.from_dict(GeoData, orient='index')
|
|
self.members['last_seen']=pd.to_datetime(self.members.last_seen)
|
|
#subsetting by date
|
|
if active_date!=None:
|
|
self.members=self.members[(self.members.last_seen >= active_date) & (self.members.status == 'active')]
|
|
return self.members
|
|
|
|
def all_fedorians(self,active_date=None):
|
|
'''Crazy method to get all fedorians'''
|
|
people=self.fas.people_by_key()
|
|
self.members=pd.DataFrame.from_dict(people, orient='index')
|
|
self.members['last_seen']=pd.to_datetime(self.members.last_seen)
|
|
#subsetting by date
|
|
if active_date!=None:
|
|
self.members=self.members[(self.members.last_seen >= active_date) & (self.members.status == 'active')]
|
|
return self.members
|
|
|
|
def plot_world(self,title='Map', label='# Elements', filename='base_file.svg', save=True):
|
|
'''plot a fancy map with heat information '''
|
|
import pygal
|
|
ct = Counter(self.members.country_code.values.tolist())
|
|
data=dict((k.lower(), v) for k,v in ct.items() if k!=None )
|
|
worldmap = pygal.maps.world.World()
|
|
worldmap.title = title
|
|
worldmap.add(label, data)
|
|
if save:
|
|
worldmap.render_to_file(filename)
|
|
else:
|
|
worldmap.render()
|
|
|
|
def plot_world2(self,title='Map', label='# Elements', filename='base_file', notebook=False):
|
|
'''plot a fancy map with heat information '''
|
|
import plotly.graph_objs as gobj
|
|
import pandas as pd
|
|
from iso3166 import countries
|
|
from plotly.offline import download_plotlyjs,init_notebook_mode,plot,iplot
|
|
init_notebook_mode(connected=notebook)
|
|
|
|
ct = Counter(self.members.country_code.values.tolist())
|
|
del ct[None]
|
|
|
|
locations=[]
|
|
z=[]
|
|
names=[]
|
|
for k in ct.keys():
|
|
try:
|
|
country=countries.get(k)
|
|
locations.append(country[2])
|
|
z.append(ct[k])
|
|
names.append(country[0])
|
|
except:
|
|
continue
|
|
|
|
data = [ dict(
|
|
type = 'choropleth',
|
|
locations = pd.Series(locations) ,
|
|
z = pd.Series(z),
|
|
text = pd.Series(names),
|
|
autocolorscale = True,
|
|
reversescale = False,
|
|
marker = dict(
|
|
line = dict (
|
|
color = 'rgb(180,180,180)',
|
|
width = 0.5
|
|
) ),
|
|
colorbar = dict(
|
|
title = label),
|
|
) ]
|
|
|
|
layout = dict(
|
|
title = title,
|
|
geo = dict(
|
|
showframe = False,
|
|
showcountries = True,
|
|
showcoastlines = False,
|
|
projection = dict(
|
|
type = 'natural earth'
|
|
)
|
|
)
|
|
)
|
|
|
|
fig = gobj.Figure(data = data,layout = layout)
|
|
|
|
if notebook:
|
|
return iplot(fig,filename=filename )
|
|
else:
|
|
return plot(fig,filename=filename )
|
|
|
|
|
|
|
|
def plot_heat(self, title='test', filename='base_file', label='label', notebook=False):
|
|
'''plots heatmap with location/number of asked questions '''
|
|
import plotly.plotly as py
|
|
import plotly.graph_objs as go
|
|
from iso3166 import countries
|
|
|
|
ct = Counter(self.members.country_code.values.tolist())
|
|
del ct[None]
|
|
|
|
locations=[]
|
|
z=[]
|
|
names=[]
|
|
for k in ct.keys():
|
|
try:
|
|
country=countries.get(k)
|
|
locations.append(country[2])
|
|
z.append(ct[k])
|
|
names.append(country[0])
|
|
except:
|
|
continue
|
|
|
|
z = pd.Series(z)
|
|
trace = go.Heatmap(z = [z], x = names)
|
|
data = [trace]
|
|
|
|
if notebook:
|
|
return py.iplot(data,filename=filename )
|
|
else:
|
|
return py.plot(data,filename=filename )
|