OSSEval/OSProject/ohloh.py to OSSEval/OpenSourceProject/views.py
--- a/OSSEval/OSProject/ohloh.py +++ b/OSSEval/OpenSourceProject/views.py @@ -1,153 +1,122 @@ -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. -# -# Copyright 2014 Bitergium SLL +from pprint import pformat -import urllib2 -from xml.dom import minidom -from utils import Configuration, xmlElements, Forges -from OSSEval.utils import TrivialJSONEncoder +from django.conf import settings +from django.contrib import messages +from django.core.urlresolvers import reverse +from django.http import HttpResponseRedirect, HttpResponse +from django.shortcuts import render, get_object_or_404 -class OhlohProxy(): +from analysis.models import Analysis, Instance +from forms import SearchForm +from flossmole import FSF, FC, GC, GH +from OpenSourceProject.models import OSProjectForge, OSProject, Forge +from ohloh import OhlohProxy +from utils import Forges +import OpenSourceProject + +def test(request): + return HttpResponse(OpenSourceProject.flossmole_locale) + +def instance_list_html(request, analysis_id): + ''' + Part of the required interface + ''' + analysis = Analysis.objects.get(pk=analysis_id) + context = {'analysis': analysis} + return render(request, 'OSProject/detail.html', context) + +def search_html_form(request, analysis_id): + ''' + Part of the required interface + ''' + form = SearchForm(initial={'analysis_id': analysis_id}) # An unbound form + return render(request, 'OSProject/search.html', {'form': form}) + +def search_html(request): + ''' + Part of the required interface + ''' + form = SearchForm(request.POST) + if form.is_valid(): # All validation rules pass + target = int(str(form.cleaned_data['target'])) + name = str(form.cleaned_data['name']) + analysis_id = str(form.cleaned_data['analysis_id']) + projects = [] + if target == Forges.FC or target == Forges.ALL: + projects += FC.search(name) + if target == Forges.FSF or target == Forges.ALL: + projects += FSF.search(name) + if target == Forges.GC or target == Forges.ALL: + projects += GC.search(name) + if target == Forges.GH or target == Forges.ALL: + projects += GH.search(name) + if target == Forges.OHLOH or target == Forges.ALL: + projects += OhlohProxy.search(name) + + return render(request, 'OSProject/search_results.html', {'projects': projects, 'analysis_id': analysis_id}) + +def OSProjectForge_delete(request, osprojectforge_id, analysis_id): + pf = get_object_or_404(OSProjectForge, pk=osprojectforge_id) + osp = pf.os_project + i = osp.instance + pf.delete() + if len(osp.osprojectforge_set.all()) == 0: + osp.delete() + i.delete() - def search_json(self, name): - a = TrivialJSONEncoder().encode(OhlohProxy.search(name)) - return a + return HttpResponseRedirect(reverse('analysis_detail', args=(analysis_id,))) - @staticmethod - def search(name): - page = 1 - print "Ohloh search - " + name + " - page " + str(page) - url_ohloh = "https://www.ohloh.net/p.xml?api_key=" + Configuration.api_key + "&query=" + name + "&page=" - response = urllib2.urlopen(url_ohloh + str(page)) - xml = response.read() - xmldoc = minidom.parseString(xml) - - items_available = xmlElements(xmldoc.getElementsByTagName('items_available')).firstValue() - status = xmlElements(xmldoc.getElementsByTagName('status')).firstValue() - project_list = [] - while (status == 'success' and len(project_list) < min(Configuration.max_number_of_records, items_available)): - page = page + 1 - print "Ohloh search - " + name + " - page " + str(page) - item_list = xmldoc.getElementsByTagName('project') - for s in item_list : - try: - op = OhlohProject() - op.id = xmlElements(s.getElementsByTagName('url_name')).firstValue() - op.name = xmlElements(s.getElementsByTagName('name')).firstValue() - op.description = xmlElements(s.getElementsByTagName('description')).firstValue() - op.small_logo_url = xmlElements(s.getElementsByTagName('small_logo_url')).firstValue() - op.homepage_url = xmlElements(s.getElementsByTagName('homepage_url')).firstValue() - op.id_forge = Forges.OHLOH - op.datasource_id = 0 - project_list.append(op) - # s.getElementsByTagName('id')[0].localName - # id - except Exception as ex: - print str(ex) - response = urllib2.urlopen(url_ohloh + str(page)) - xml = response.read() - xmldoc = minidom.parseString(xml) - status = xmldoc.getElementsByTagName('status')[0].firstChild.nodeValue - - return project_list - - @staticmethod - def getProjectInfo(project_identifier): - url_ohloh = "http://www.ohloh.net/projects/" + project_identifier + ".xml?api_key=" + Configuration.api_key - response = urllib2.urlopen(url_ohloh) - xml = response.read() - xmldoc = minidom.parseString(xml) - info = {} - - status = xmlElements(xmldoc.getElementsByTagName('status')).firstValue() - if status == 'success': - info['id'] = project_identifier - info['project_identifier'] = project_identifier - info['widget_languages'] = '<script type="text/javascript" src="http://www.ohloh.net/p/' + project_identifier + '/widgets/project_languages.js"></script>' - info['ohloh_url'] = "http://www.ohloh.net/p/" + project_identifier - info['commits_spark'] = "http://www.ohloh.net/p/" + project_identifier + "/analyses/latest/commits_spark.png"; - info['created_at'] = xmlElements(xmldoc.getElementsByTagName('created_at')).firstValue() - info['updated_at'] = xmlElements(xmldoc.getElementsByTagName('updated_at')).firstValue() - info['description'] = xmlElements(xmldoc.getElementsByTagName('description')).firstValue() - info['homepage_url'] = xmlElements(xmldoc.getElementsByTagName('homepage_url')).firstValue() - info['download_url'] = xmlElements(xmldoc.getElementsByTagName('download_url')).firstValue() - info['medium_logo_url'] = xmlElements(xmldoc.getElementsByTagName('medium_logo_url')).firstValue() - info['small_logo_url'] = xmlElements(xmldoc.getElementsByTagName('small_logo_url')).firstValue() - info['user_count'] = xmlElements(xmldoc.getElementsByTagName('user_count')).firstValue() - info['average_rating'] = xmlElements(xmldoc.getElementsByTagName('average_rating')).firstValue() - info['rating_count'] = xmlElements(xmldoc.getElementsByTagName('rating_count')).firstValue() - info['review_count'] = xmlElements(xmldoc.getElementsByTagName('review_count')).firstValue() - info['twelve_month_contributor_count'] = xmlElements(xmldoc.getElementsByTagName('twelve_month_contributor_count')).firstValue() - info['total_code_lines'] = xmlElements(xmldoc.getElementsByTagName('total_code_lines')).firstValue() - info['main_language_name'] = xmlElements(xmldoc.getElementsByTagName('main_language_name')).firstValue() - info['licenses'] = [] - license_list = xmldoc.getElementsByTagName('license') - for s in license_list : - info['licenses'].append(xmlElements(s.getElementsByTagName('nice_name')).firstValue()) - info['languages'] = [] - language_list = xmldoc.getElementsByTagName('language') - for l in language_list : - language = {} - language['project_identifier'] = l.firstChild.nodeValue - language['percentage'] = l.attributes['percentage'].value - language['color'] = l.attributes['color'].value - language['id'] = l.attributes['id'].value - info['languages'].append(language) - - url_ohloh = "http://www.ohloh.net/projects/" + project_identifier + "/factoids.xml?api_key=" + Configuration.api_key - response = urllib2.urlopen(url_ohloh) - xml = response.read() - xmldoc = minidom.parseString(xml) - - status = xmlElements(xmldoc.getElementsByTagName('status')).firstValue() - info['factoids'] = [] - if status == 'success': - factoid_list = xmldoc.getElementsByTagName('factoid') - for f in factoid_list : - factoid = {} - factoid['type'] = xmlElements(f.getElementsByTagName('type')).firstValue() - factoid['description'] = xmlElements(f.getElementsByTagName('description')).firstValue() - factoid['severity'] = xmlElements(f.getElementsByTagName('severity')).firstValue() - info['factoids'].append(factoid) +def OSProjectForge_add(request): + #TODO: check there's just one per forge + analysis_id = int(request.POST.get("analysis_id", "")) + id_forge = int(request.POST.get("id_forge", "")) + datasource_id = request.POST.get("datasource_id", "") + project_name = request.POST.get("project_name", "") + identifier_in_forge = request.POST.get("identifier_in_forge", "") + id_selected_instance = int(request.POST.get("id_selected_instance", "")) + #id_selected_instance is -1 if I have to create a new instance; otherwise it tells to which instance I should add it + if id_selected_instance > 0: + instance = Instance.objects.get(pk=id_selected_instance) + osp=OSProject.objects.get(instance = instance) + for ospf in osp.osprojectforge_set.all(): + if ospf.forge.id == id_forge: + messages.add_message(request, messages.INFO, 'Hello world.') + print ('Hello world.') + return HttpResponseRedirect(reverse('analysis_detail', args=(analysis_id,))) + else: + analysis = get_object_or_404(Analysis, pk=analysis_id) + instance=Instance.objects.create(name=project_name, name_for_search="", analysis=analysis) + osp=OSProject.objects.create(name=project_name, instance=instance) + forge=Forge.objects.get(pk=id_forge) + pf=OSProjectForge(name=project_name, os_project=osp, forge=forge, identifier_in_forge=identifier_in_forge, datasource_id=datasource_id) + pf.save() + return HttpResponseRedirect(reverse('analysis_detail', args=(analysis_id,))) - url_ohloh = "http://www.ohloh.net/projects/" + project_identifier + "/analyses/latest/size_facts.xml?api_key=" + Configuration.api_key - response = urllib2.urlopen(url_ohloh) - xml = response.read() - xmldoc = minidom.parseString(xml) - - info['size_fact'] = None - status = xmlElements(xmldoc.getElementsByTagName('status')).firstValue() - if status == 'success': - size_fact_list = xmldoc.getElementsByTagName('size_fact') - if len(size_fact_list) > 0: - sf = size_fact_list[len(size_fact_list) - 1] - size_fact = {} - size_fact['month'] = xmlElements(sf.getElementsByTagName('month')).firstValue() - size_fact['code'] = xmlElements(sf.getElementsByTagName('code')).firstValue() - size_fact['comments'] = xmlElements(sf.getElementsByTagName('comments')).firstValue() - size_fact['blanks'] = xmlElements(sf.getElementsByTagName('comment_ratio')).firstValue() - size_fact['commits'] = xmlElements(sf.getElementsByTagName('commits')).firstValue() - size_fact['comment_ratio'] = xmlElements(sf.getElementsByTagName('comment_ratio')).firstValue() - size_fact['man_months'] = xmlElements(sf.getElementsByTagName('man_months')).firstValue() - # I just need the last as it is the most recent - info['size_fact'] = size_fact +def OSProjectForgeFromResultList_detail(request): + identifier_in_forge = request.POST.get("identifier_in_forge", "") + id_forge = int(request.POST.get("id_forge", "")) + pf = OSProjectForge(identifier_in_forge=identifier_in_forge, forge_id=id_forge) + osprojectforge_info = pf.getProjectInfo() + osprojectforge_info_nice_print = pformat(osprojectforge_info) + return render(request, 'OSProject/osprojectforge_detail.html', {'osprojectforge_info': osprojectforge_info, 'osprojectforge_info_nice_print': osprojectforge_info_nice_print}) - return info +def OSProjectForge_detail(request, osprojectforge_id): + pf = get_object_or_404(OSProjectForge, pk=osprojectforge_id) + osprojectforge_info = pf.getProjectInfo() + osprojectforge_info_nice_print = pformat(osprojectforge_info) + return render(request, 'OSProject/osprojectforge_detail.html', {'osprojectforge_info': osprojectforge_info, 'osprojectforge_info_nice_print': osprojectforge_info_nice_print}) - -class OhlohProject(): - id = 0 - name = "" - description = "" - small_logo_url = "" - homepage_url = "" - id_forge = 0 - datasource_id = 0 - def load_information(self): - self.info = OhlohProxy.getProjectInfo(self.name) +# def actual_entity_detail(request, osproject_id): +# ''' +# Part of the required interface +# ''' +# osp = get_object_or_404(OSProject, pk=osproject_id) +# osproject_info = osp.getProjectInfo() +# return osproject_info - - +def OSProject_detail(request, osproject_id): + osp = get_object_or_404(OSProject, pk=osproject_id) + osproject_info = osp.getInstanceInfo() + osproject_info_nice_print = pformat(osproject_info) + return render(request, 'OSProject/osproject_detail.html', {'osprojectforge_info': osproject_info, 'osprojectforge_info_nice_print': osproject_info_nice_print})
OSSEval/OSProject/tests.py to OSSEval/OpenSourceProject/tests.py
File was renamed.
OSSEval/OSProject/urls.py to OSSEval/OpenSourceProject/urls.py
--- a/OSSEval/OSProject/urls.py +++ b/OSSEval/OpenSourceProject/urls.py @@ -1,15 +1,16 @@ from django.conf.urls import patterns, url -from OSProject import views +from OpenSourceProject import views urlpatterns = patterns('', url(r'^instance_list_html/(?P<analysis_id>\d+)/$', views.instance_list_html, name='instance_list_html'), url(r'^search_html/$', views.search_html, name='search_html'), url(r'^search_html_form/$', views.search_html_form, name='search_html_form'), - url(r'^OSProjectForge_delete/(?P<osprojectforge_id>\d+)/(?P<analysis_id>\d+)/$', views.OSProjectForge_delete, name='OSProjectForge_delete'), + url(r'^OpenSProjectForge_delete/(?P<osprojectforge_id>\d+)/(?P<analysis_id>\d+)/$', views.OSProjectForge_delete, name='OSProjectForge_delete'), url(r'^OSProjectForge_add$', views.OSProjectForge_add, name='OSProjectForge_add'), url(r'^OSProjectForge_detail/(?P<osprojectforge_id>\d+)/$', views.OSProjectForge_detail, name='OSProjectForge_detail'), url(r'^OSProjectForgeFromResultList_detail/$', views.OSProjectForgeFromResultList_detail, name='OSProjectForgeFromResultList_detail'), url(r'^OSProject_detail/(?P<osproject_id>\d+)/$', views.OSProject_detail, name='OSProject_detail'), + url(r'^test$', views.test), )
OSSEval/OSProject/utils.py to OSSEval/analysis/templatetags/custom_tags.py
--- a/OSSEval/OSProject/utils.py +++ b/OSSEval/analysis/templatetags/custom_tags.py @@ -1,34 +1,29 @@ -from xml.dom import minidom +from django import template +from analysis.models import Instance, Question, Answer, Page -class Configuration(): - api_key = "qdD49UAt6Heu1pV9vkC0A" - max_number_of_records = 10 +register = template.Library() + +@register.simple_tag +def instance_score_question(instance_id, question_id, *args, **kwargs): + instance = Instance.objects.get(pk=instance_id) + question = Question.objects.get(pk=question_id) + try: + answer = Answer.objects.get(question=question, instance=instance) + choice = question.choice_set.get(order=answer.value_integer) + return "(" + str(answer.score) + ") " + choice.text + except: + return "<font color=red>not answered</font>" -class Forges(object): - ALL = 0 - #SF = Sourceforge - SF = 1 - #FC = Freecode was FM = Freshmeat - FC = 2 - #FSF = Free Software Foundation - FSF = 5 - #GH = Github - GH = 11 - #GC = Google code - GC = 12 - OHLOH = 100 - CODEPLEX = 1000 - APACHE = 1200 - ECLIPSE = 1300 - -class xmlElements(): - def __init__(self, xml): - self.xml = xml - - def firstValue(self): +@register.simple_tag +def instance_score_page(instance_id, page_id, *args, **kwargs): + instance = Instance.objects.get(pk=instance_id) + page = Page.objects.get(pk=page_id) + score = 0 + for question in page.question_set.all(): try: - return self.xml[0].firstChild.nodeValue + answer = Answer.objects.get(question=question, instance=instance) + score += answer.score except: - return "" - + pass + return "(" + str(score) + ") <strong>" + instance.name + "</strong>"
OSSEval/analysis/templates/analysis/delme_page1_tabs.html to OSSEval/OpenSourceProject/utils.py
--- a/OSSEval/analysis/templates/analysis/delme_page1_tabs.html +++ b/OSSEval/OpenSourceProject/utils.py @@ -1,28 +1,55 @@ -{% load staticfiles %} -<ul> -{% for p in methodology_version.page_set.all %} - <li><a href="#page1.{{ p.id }}">{{ p.name }}</a></li> -{% endfor %} -</ul> -{% for p in methodology_version.page_set.all %} - <div id="page1.{{ p.id }}"> - <ul> - {% for p1 in p.page_set.all %} - <li><a href="#page2.{{ p1.id }}">{{ p1.name }}</a></li> - {% endfor %} - </ul> - {% for p1 in p.page_set.all %} - <div id="pagina'+p.id+'"><form> - {% for q in p1.question_set.all %} - <label>{{ q.text }}:</label> <span id="msgq{{ q.id }}"></span><br> - {% for c in q.choice_set.all %} - <label><input type="radio" id="question{{ q.id }}{{ q.order }}" value="{{ q.order }}" /> {{ c.text }}</label><br> - {% endfor %} - <label>Comments on "{{ q.text }}": </label><input type="text" size="70" id="questioncomments{{ q.id }}" value="" /><br> - <div class="infoDaMetadati" id="infoDaMetadati{{ q.id }}"><img id="metadataajaxwait" src="{% static "images/wait1.gif" %}"/></div><br> - {% endfor %} - </form></div> - {% endfor %} +from xml.dom import minidom +import urllib2 +import OpenSourceProject + +class Configuration(): + api_key = OpenSourceProject.ohloh_api_key + max_number_of_records = OpenSourceProject.local_record_limit + flossmole_locale = OpenSourceProject.flossmole_locale + +class Forges(object): + ALL = 0 + #SF = Sourceforge + SF = 1 + #FC = Freecode was FM = Freshmeat + FC = 2 + #FSF = Free Software Foundation + FSF = 5 + #GH = Github + GH = 11 + #GC = Google code + GC = 12 + OHLOH = 100 + CODEPLEX = 1000 + APACHE = 1200 + ECLIPSE = 1300 + +class xmlElements(): + def __init__(self, xml): + self.xml = xml - </div> -{% endfor %} + def firstValue(self): + try: + return self.xml[0].firstChild.nodeValue + except: + return "" + +class UrllibHelper(): + @staticmethod + def urlopen(url_string, max_attempts = 3): + ''' + Sometimes the download just fails for no apparent reason; retrying right after the + failure solves the issue; so this method retries max_attempts times with a default of 3 + ''' + success = False + n_attempts = 1 + ret = "" + while not (success or n_attempts>max_attempts): + try: + response = urllib2.urlopen(url_string) + ret = response.read() + success = True + except Exception as ex: + print('Error downloading ' + url_string + " - Attempt n.:" + str(n_attempts) + " - " + str(ex)) + n_attempts = n_attempts + 1 + return ret
OSSEval/analysis/templatetags/form_tags.py to OSSEval/analysis/fixtures/initial_data.yaml
--- a/OSSEval/analysis/templatetags/form_tags.py +++ b/OSSEval/analysis/fixtures/initial_data.yaml @@ -1,13 +1,13 @@ -from django import template - -register = template.Library() - -def do_page_form(parser, token): - try: - # split_contents() knows not to split quoted strings. - tag_name, format_string = token.split_contents() - except ValueError: - raise template.TemplateSyntaxError("%r tag requires a single argument" % token.contents.split()[0]) - if not (format_string[0] == format_string[-1] and format_string[0] in ('"', "'")): - raise template.TemplateSyntaxError("%r tag's argument should be in quotes" % tag_name) - return format_string[1:-1]+- model: analysis.QuestionType + pk: 1 + fields: + name: "Single choice" +- model: analysis.QuestionType + pk: 2 + fields: + name: "Multiple choice" +- model: analysis.QuestionType + pk: 3 + fields: + name: "Free text" +