diff --git a/.ci/build.sh b/.ci/build.sh
index 1f01164d..56c2be06 100755
--- a/.ci/build.sh
+++ b/.ci/build.sh
@@ -27,6 +27,7 @@ python manage.py fetch_deployed_data _site $ISSUES_JSON \
python manage.py migrate
python manage.py import_contributors_data
+python manage.py create_org_cluster_map_and_activity_graph org_map
python manage.py import_issues_data
python manage.py import_merge_requests_data
python manage.py create_config_data
diff --git a/.coafile b/.coafile
index 8dc3cf12..3b4c1c5b 100644
--- a/.coafile
+++ b/.coafile
@@ -1,6 +1,6 @@
[all]
files = **.py, **.js, **.sh
-ignore = .git/**, **/__pycache__/**, gci/client.py, */migrations/**, private/*, openhub/**
+ignore = .git/**, **/__pycache__/**, gci/client.py, */migrations/**, private/*, openhub/**, **/leaflet_dist/**
max_line_length = 80
use_spaces = True
preferred_quotation = '
@@ -42,6 +42,7 @@ files = static/**/*.js
bears = JSHintBear
allow_unused_variables = True
javascript_strictness = False
+environment_jquery = True
[all.yml]
bears = YAMLLintBear
diff --git a/.moban.yaml b/.moban.yaml
index 574c2d69..f8b46e9c 100644
--- a/.moban.yaml
+++ b/.moban.yaml
@@ -16,6 +16,7 @@ packages:
- unassigned_issues
dependencies:
+ - getorg~=0.3.1
- git+https://gitlab.com/coala/coala-utils.git
- git-url-parse
- django>2.1,<2.2
diff --git a/activity/scraper.py b/activity/scraper.py
index 069bc668..9d8fc794 100644
--- a/activity/scraper.py
+++ b/activity/scraper.py
@@ -136,7 +136,7 @@ def get_data(self):
return self.data
-def activity_json(request):
+def activity_json(filename):
org_name = get_org_name()
@@ -152,4 +152,5 @@ def activity_json(request):
real_data = Scraper(parsed_json['issues'], datetime.datetime.today())
real_data = real_data.get_data()
- return HttpResponse(json.dumps(real_data))
+ with open(filename, 'w+') as f:
+ json.dump(real_data, f, indent=4)
diff --git a/community/urls.py b/community/urls.py
index ed936b9d..c03de2e2 100644
--- a/community/urls.py
+++ b/community/urls.py
@@ -5,12 +5,10 @@
from django_distill import distill_url
from django.conf.urls.static import static
from django.conf import settings
-from django.views.generic import TemplateView
from community.views import HomePageView, info
from gci.views import index as gci_index
from gci.feeds import LatestTasksFeed as gci_tasks_rss
-from activity.scraper import activity_json
from twitter.view_twitter import index as twitter_index
from log.view_log import index as log_index
from data.views import index as contributors_index
@@ -87,18 +85,6 @@ def get_organization():
distill_func=get_index,
distill_file='info.txt',
),
- distill_url(
- r'static/activity-data.json', activity_json,
- name='activity_json',
- distill_func=get_index,
- distill_file='static/activity-data.json',
- ),
- distill_url(
- r'activity/', TemplateView.as_view(template_name='activity.html'),
- name='activity',
- distill_func=get_index,
- distill_file='activity/index.html',
- ),
distill_url(
r'gci/tasks/rss.xml', gci_tasks_rss(),
name='gci-tasks-rss',
diff --git a/community/views.py b/community/views.py
index 595c02ed..d09ba0cf 100644
--- a/community/views.py
+++ b/community/views.py
@@ -8,21 +8,106 @@
get_org_name,
get_owner,
get_upstream_deploy_url,
+ get_remote_url
)
+from data.models import Team, Contributor
+
+
+def initialize_org_context_details():
+ org_name = get_org_name()
+ org_details = {
+ 'name': org_name,
+ 'blog_url': 'https://blog.{}.io/'.format(org_name),
+ 'twitter_url': 'https://twitter.com/{}_io/'.format(org_name),
+ 'facebook_url': 'https://www.facebook.com/{}Analyzer'.format(
+ org_name),
+ 'repo_url': get_remote_url().href,
+ 'docs': 'http://{}.io/docs'.format(org_name),
+ 'newcomer_docs': 'http://{}.io/newcomer'.format(org_name),
+ 'coc': 'http://{}.io/coc'.format(org_name),
+ 'logo_url': ('https://api.{}.io/en/latest/_static/images/'
+ '{}_logo.svg'.format(org_name, org_name)),
+ 'gitter_chat': 'https://gitter.im/{}/{}/'.format(org_name,
+ org_name),
+ 'github_core_repo': 'https://github.com/{}/{}/'.format(org_name,
+ org_name),
+ 'licence_type': 'GNU AGPL v3.0'
+ }
+ return org_details
+
+
+def get_header_and_footer(context):
+ context['isTravis'] = Travis.TRAVIS
+ context['travisLink'] = Travis.TRAVIS_BUILD_WEB_URL
+ context['org'] = initialize_org_context_details()
+ print('Running on Travis: {}, build link: {}'.format(context['isTravis'],
+ context['travisLink']
+ ))
+ return context
class HomePageView(TemplateView):
template_name = 'index.html'
- def get_context_data(self, **kwargs):
- context = super().get_context_data(**kwargs)
- context['isTravis'] = Travis.TRAVIS
- context['travisLink'] = Travis.TRAVIS_BUILD_WEB_URL
+ def get_team_details(self):
+ org_name = get_org_name()
+ teams = [
+ '{} newcomers'.format(org_name),
+ '{} developers'.format(org_name),
+ '{} admins'.format(org_name)
+ ]
+ team_details = {}
+ for team in teams:
+ team_objs = [Team.objects.get(name=team), ]
+ contributors = Contributor.objects.filter(teams__in=team_objs)
+ team_details[team] = contributors.count()
+ return team_details
+
+ def get_quote_of_the_day(self):
+ import requests
+ qod = requests.get('http://quotes.rest/qod?category=inspire')
+ qod_data = qod.json()
+ if qod.status_code == 429:
+ return None
+ return {
+ 'quote': qod_data['contents']['quotes'][0]['quote'],
+ 'author': qod_data['contents']['quotes'][0]['author'],
+ }
+
+ def get_top_meta_review_users(self, count):
+ from meta_review.models import Participant
+ participants = Participant.objects.all()[:count]
+ for contrib in participants:
+ contrib.score = int(contrib.score)
+ return participants
- print('Running on Travis: {}, build link: {}'.format(
- context['isTravis'],
- context['travisLink']))
+ def get_top_gamification_users(self, count):
+ from gamification.models import Participant
+ return enumerate(Participant.objects.all()[:count])
+ def get_context_data(self, **kwargs):
+ context = super().get_context_data(**kwargs)
+ context = get_header_and_footer(context)
+ context['org']['team_details'] = dict(self.get_team_details())
+ org_name = context['org']['name']
+ about_org = ('{org_name} (always spelled with a lowercase c!) is one'
+ ' of the welcoming open-source organizations for'
+ ' newcomers. {org_name} stands for “COde AnaLysis'
+ ' Application” as it works well with animals and thus is'
+ ' well visualizable which makes it easy to memorize.'
+ ' {org_name} provides a unified interface for linting'
+ ' and fixing the code with a single configuration file,'
+ ' regardless of the programming languages used. You can'
+ ' use {org_name} from within your favorite editor,'
+ ' integrate it with your CI and, get the results as JSON'
+ ', or customize it to your needs with its flexible'
+ ' configuration syntax.'.format(org_name=org_name))
+ context['org']['about'] = about_org
+ context['quote_details'] = self.get_quote_of_the_day()
+ context['top_meta_review_users'] = self.get_top_meta_review_users(
+ count=5)
+ context['top_gamification_users'] = self.get_top_gamification_users(
+ count=5)
return context
diff --git a/data/management/commands/create_org_cluster_map_and_activity_graph.py b/data/management/commands/create_org_cluster_map_and_activity_graph.py
new file mode 100644
index 00000000..f49162ae
--- /dev/null
+++ b/data/management/commands/create_org_cluster_map_and_activity_graph.py
@@ -0,0 +1,119 @@
+import logging
+import json
+import getorg
+import os
+
+from django.core.management.base import BaseCommand
+
+from data.models import Contributor
+from activity.scraper import activity_json
+
+
+class Command(BaseCommand):
+ help = 'Create a cluster map using contributors geolocation'
+
+ def add_arguments(self, parser):
+ parser.add_argument('output_dir', nargs='?', type=str)
+
+ def handle(self, *args, **options):
+ logger = logging.getLogger(__name__)
+ output_dir = options.get('output_dir')
+
+ if not output_dir:
+ logger.debug('output_dir arg not provided! Setting output_dir'
+ ' to cluster_map/')
+ output_dir = 'cluster_map'
+
+ class Location:
+
+ def __init__(self, longitude, latitude):
+ self.longitude = longitude
+ self.latitude = latitude
+
+ org_location_dict = {}
+
+ for contrib in Contributor.objects.all():
+ if not contrib.login.startswith('testuser') and contrib.location:
+ user_location = json.loads(contrib.location)
+ location = Location(user_location['longitude'],
+ user_location['latitude'])
+ org_location_dict[contrib.login] = location
+ logger.debug('{} location {} added on map'.format(
+ contrib.login, user_location))
+ getorg.orgmap.output_html_cluster_map(org_location_dict,
+ folder_name=output_dir)
+
+ self.move_and_make_changes_in_files(output_dir)
+
+ # Fetch data for activity graph to be displayed on home-page
+ activity_json('static/activity-data.js')
+
+ def move_and_make_changes_in_files(self, output_dir):
+ # Move leaflet_dist folder to static folder
+ leaflet_source_path = '{}/{}/leaflet_dist/'.format(os.getcwd(),
+ output_dir)
+ leaflet_destination_path = '{}/{}/leaflet_dist/'.format(os.getcwd(),
+ 'static')
+ os.renames(leaflet_source_path, leaflet_destination_path)
+ # Move org_locations.js to static folder
+ locations_source_path = '{}/{}/org-locations.js'.format(os.getcwd(),
+ output_dir)
+ locations_destination_path = '{}/{}/org-locations.js'.format(
+ os.getcwd(), 'static')
+ os.rename(locations_source_path, locations_destination_path)
+ # Change map.html to support django
+ with open('{}/map.html'.format(output_dir)) as f:
+ django_supported_htmls = []
+ lines = f.readlines()
+ for index in range(len(lines)):
+ line = lines[index].strip()
+ if line.__contains__(''):
+ django_supported_htmls.append('{% load staticfiles %}\n')
+ django_supported_htmls.append(line+'\n')
+ elif line.__contains__(''):
+ adjust_prop = '''
+ \n
+ '''
+ meta_charset = ''
+ adjust_prop = adjust_prop.strip().replace(' ', '')
+ django_supported_htmls.insert(6, meta_charset+'\n')
+ django_supported_htmls.append(adjust_prop+'\n')
+ django_supported_htmls.append(line+'\n')
+ elif line.__contains__('https://'):
+ line = line.replace('https:', '').replace(' />', '>')
+ django_supported_htmls.append(line.strip()+'\n')
+ elif line.__contains__('', '>')
+ django_supported_htmls.append(line+'\n')
+ elif line.__contains__('
-
-
-
-