Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Created the license v exception #496

Merged
merged 2 commits into from
Aug 24, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions src/app/formatxml.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,11 @@
'name',
'listVersionAdded',
],
'exception': [
'licenseId',
'name',
'listVersionAdded',
],
'alt': [
'name',
'match',
Expand Down
45 changes: 39 additions & 6 deletions src/app/forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,32 @@
("Unknown", "Don't know")
)

YES_NO_CHOICES = (
(True, 'Yes'),
(False, 'No'),
)

class TooltipTextInput(forms.TextInput):
def __init__(self, tooltip='', attrs=None):
super().__init__(attrs)
self.tooltip = tooltip

def get_context(self, name, value, attrs):
context = super().get_context(name, value, attrs)
context['widget']['attrs']['data-toggle'] = 'tooltip'
context['widget']['attrs']['title'] = self.tooltip
return context

class CustomSelectWidget(forms.Select):
def __init__(self, *args, **kwargs):
self.tooltip = kwargs.pop('tooltip', '') # Get the tooltip text from widget attributes
super().__init__(*args, **kwargs)

def get_context(self, name, value, attrs):
context = super().get_context(name, value, attrs)
context['widget'].update({'attrs': {'title': self.tooltip}}) # Add the title attribute to the widget
return context

class UserRegisterForm(forms.ModelForm):

password = forms.CharField(widget=forms.PasswordInput())
Expand Down Expand Up @@ -75,12 +101,19 @@ def __init__(self, *args, **kwargs):
super(LicenseRequestForm, self).__init__(*args,**kwargs)
self.fields["userEmail"] = forms.EmailField(label='Email', initial=self.email, max_length=35, required=False)

licenseAuthorName = forms.CharField(label="License Author name", max_length=100, required=False)
fullname = forms.CharField(label="Fullname", max_length=70)
shortIdentifier = forms.CharField(label='Short identifier', max_length=25)
sourceUrl = forms.CharField(label='Source / URL', required=False)
osiApproved = forms.CharField(label="OSI Status", widget=forms.Select(choices=OSI_CHOICES))
exampleUrl = forms.CharField(label='Example Projects / URL', required=True)
licenseAuthorName = forms.CharField(label="License Author name", max_length=100, required=False, widget=TooltipTextInput(tooltip='License Author name goes here'))
fullname = forms.CharField(label="Fullname", max_length=70, widget=TooltipTextInput(tooltip='Full Identifier of the license text goes here'))
shortIdentifier = forms.CharField(label='Short identifier', max_length=25, widget=TooltipTextInput(tooltip='A short identifier of the license'))
sourceUrl = forms.CharField(label='Source / URL', required=False, widget=TooltipTextInput(tooltip='Source URL for the license text'))
osiApproved = forms.ChoiceField(
choices=OSI_CHOICES,
widget=CustomSelectWidget(tooltip='OSI status')
)
isException = forms.ChoiceField(
choices=YES_NO_CHOICES,
widget=CustomSelectWidget(tooltip='Whether or not the license is an exception')
)
exampleUrl = forms.CharField(label='Example Projects / URL', required=True, widget=TooltipTextInput(tooltip='Example project URL where the license is being used'))
comments = forms.CharField(label='Comments', required=True, widget=forms.Textarea(attrs={'rows': 4, 'cols': 40}))
licenseHeader = forms.CharField(label='Standard License Header', widget=forms.Textarea(attrs={'rows': 3, 'cols': 40}), required=False)
text = forms.CharField(label='Text', widget=forms.Textarea(attrs={'rows': 4, 'cols': 40}))
Expand Down
7 changes: 5 additions & 2 deletions src/app/generateXml.py
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ def getTextElement(points):
return elements[0]


def generateLicenseXml(licenseOsi, licenseIdentifier, licenseName, listVersionAdded, licenseSourceUrls, licenseHeader, licenseNotes, licenseText):
def generateLicenseXml(licenseOsi, licenseIdentifier, licenseName, listVersionAdded, licenseSourceUrls, licenseHeader, licenseNotes, licenseText, isException=False):
""" Generate a spdx license xml
returns the license xml as a string
"""
Expand All @@ -140,7 +140,10 @@ def generateLicenseXml(licenseOsi, licenseIdentifier, licenseName, listVersionAd
licenseOsi = "true"
else:
licenseOsi = "false"
license = ET.SubElement(root, "license", isOsiApproved=licenseOsi, licenseId=licenseIdentifier, listVersionAdded=listVersionAdded, name=licenseName)
if isException:
license = ET.SubElement(root, "exception", isOsiApproved=licenseOsi, licenseId=licenseIdentifier, listVersionAdded=listVersionAdded, name=licenseName)
else:
license = ET.SubElement(root, "license", isOsiApproved=licenseOsi, licenseId=licenseIdentifier, listVersionAdded=listVersionAdded, name=licenseName)
crossRefs = ET.SubElement(license, "crossRefs")
for sourceUrl in licenseSourceUrls:
ET.SubElement(crossRefs, "crossRef").text = sourceUrl
Expand Down
23 changes: 23 additions & 0 deletions src/app/migrations/0003_auto_20230727_1802.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# Generated by Django 3.2.18 on 2023-07-27 18:02

from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
('app', '0002_auto_20230704_1902'),
]

operations = [
migrations.AddField(
model_name='licensenamespace',
name='isException',
field=models.BooleanField(default=True),
),
migrations.AddField(
model_name='licenserequest',
name='isException',
field=models.BooleanField(default=True),
),
]
1 change: 1 addition & 0 deletions src/app/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ class License(models.Model):
notes = models.CharField(max_length=255, default="")
xml = models.TextField()
text = models.TextField(default="")
isException = models.BooleanField(default=True)
archive = models.BooleanField(default=False)

class Meta:
Expand Down
21 changes: 17 additions & 4 deletions src/app/templates/app/submit_new_license.html
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,15 @@
</div>
</div>

<div class = "form-group">
<div class="col-sm-12">
<label class="control-label col-sm-3" >Is Exception</label>
<div class="col-sm-4">
{{ form.isException }}
</div>
</div>
</div>

<div class = "form-group">
<div class="col-sm-12">
<label class="control-label col-sm-3" for="{{form.text.id_for_label}}">Text of license
Expand Down Expand Up @@ -166,6 +175,10 @@
{% block script_block %}
<script src="{% static 'js/utils.js' %}"></script>
<script type="text/javascript">
$(function () {
$('[data-toggle="tooltip"]').tooltip();
});

$(document).ready(function () {
var is_touch_device = "ontouchstart" in document.documentElement;

Expand Down Expand Up @@ -359,10 +372,10 @@
if(githubCode == '201'){
var successMessage = "The license request has been successfully submitted.";
$("#messages").html('<div class="alert alert-success alert-dismissable fade in"><a href="#" class="close" data-dismiss="alert" aria-label="close">&times;</a><strong>Success! </strong>'+ successMessage +'</div>');
setTimeout(function() {
$("#messages").html("");
}, 7000);
window.open(githubUrl + githubIssueId, "_blank");
setTimeout(function() {
$("#messages").html("");
}, 7000);
window.open(githubUrl + githubIssueId, "_blank");
}
else if(githubCode == '409'){
var matchType = data.matchType;
Expand Down
39 changes: 33 additions & 6 deletions src/app/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ def utilForPullRequestFileCheckIfExists(file_url, headers, body, username, commi
}
return response

def makePullRequest(username, token, branchName, updateUpstream, fileName, commitMessage, prTitle, prBody, xmlText, plainText, is_ns):
def makePullRequest(username, token, branchName, updateUpstream, fileName, commitMessage, prTitle, prBody, xmlText, plainText, isException, is_ns):

if not xmlText:
logger.error("Error occurred while getting xml text. The xml text is empty")
Expand Down Expand Up @@ -188,9 +188,16 @@ def makePullRequest(username, token, branchName, updateUpstream, fileName, commi
""" Creating Commit """
if fileName[-4:] == ".xml":
fileName = fileName[:-4]
textFileName = fileName + ".txt"
fileName += ".xml"
commit_url = "{0}repos/{1}/{2}/contents/src/{3}".format(url, username, settings.NAMESPACE_REPO_NAME if is_ns else settings.LICENSE_REPO_NAME, fileName)
if isException:
textFileName = fileName + "-exception.txt"
fileName += "-exception.xml"
else:
textFileName = fileName + ".txt"
fileName += ".xml"
if isException:
commit_url = "{0}repos/{1}/{2}/contents/src/exceptions/{3}".format(url, username, settings.NAMESPACE_REPO_NAME if is_ns else settings.LICENSE_REPO_NAME, fileName)
else:
commit_url = "{0}repos/{1}/{2}/contents/src/{3}".format(url, username, settings.NAMESPACE_REPO_NAME if is_ns else settings.LICENSE_REPO_NAME, fileName)
text_commit_url = "{0}repos/{1}/{2}/contents/test/simpleTestForGenerator/{3}".format(url, username, settings.NAMESPACE_REPO_NAME if is_ns else settings.LICENSE_REPO_NAME, textFileName)
xmlText = xmlText.encode('utf-8') if isinstance(xmlText, str) else xmlText
fileContent = base64.b64encode(xmlText).decode()
Expand All @@ -209,7 +216,10 @@ def makePullRequest(username, token, branchName, updateUpstream, fileName, commi
"branch":branchName,
}
""" Check if file already exists """
file_url = "{0}/contents/src/{1}".format(TYPE_TO_URL_NAMESPACE[NORMAL] if is_ns else TYPE_TO_URL_LICENSE[NORMAL], fileName)
if isException:
file_url = "{0}/contents/src/exceptions/{1}".format(TYPE_TO_URL_NAMESPACE[NORMAL] if is_ns else TYPE_TO_URL_LICENSE[NORMAL], fileName)
else:
file_url = "{0}/contents/src/{1}".format(TYPE_TO_URL_NAMESPACE[NORMAL] if is_ns else TYPE_TO_URL_LICENSE[NORMAL], fileName)
response = utilForPullRequestFileCheckIfExists(file_url, headers, body, username, commit_url)
text_file_url = "{0}/contents/test/simpleTestForGenerator/{1}".format(TYPE_TO_URL_NAMESPACE[NORMAL] if is_ns else TYPE_TO_URL_LICENSE[NORMAL], textFileName)
text_response = utilForPullRequestFileCheckIfExists(text_file_url, headers, text_file_body, username, text_commit_url)
Expand Down Expand Up @@ -369,7 +379,24 @@ def createIssue(licenseAuthorName, licenseName, licenseIdentifier, licenseCommen
headers = {'Authorization': 'token ' + token}
url = "{0}/issues".format(TYPE_TO_URL_LICENSE[urlType])
r = requests.post(url, data=json.dumps(payload), headers=headers)
return r.status_code
status_code = r.status_code
response_json = {}
issue_id = ""

if status_code in [200, 201]:
try:
response_json = r.json()
except ValueError:
# Handle JSON parsing error
return None, None


if status_code in [200, 201] and "number" in response_json:
issue_id = response_json["number"]
else:
issue_id = None

return status_code, issue_id


def postToGithub(message, encodedContent, filename):
Expand Down
58 changes: 39 additions & 19 deletions src/app/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ def submitNewLicense(request):
"""
context_dict = {}
ajaxdict = {}
githubIssueId = ""
if request.method=="POST":
if not request.user.is_authenticated:
if (request.is_ajax()):
Expand All @@ -108,6 +109,11 @@ def submitNewLicense(request):
licenseName = form.cleaned_data['fullname']
licenseIdentifier = form.cleaned_data['shortIdentifier']
licenseOsi = form.cleaned_data['osiApproved']
isException = form.cleaned_data['isException']
if isException == "False":
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What if the value given is false? Use it like
isException.lower() == "true" then true else false instead

isException = False
else:
isException = True
licenseSourceUrls = request.POST.getlist('sourceUrl')
licenseExamples = request.POST.getlist('exampleUrl')
licenseHeader = form.cleaned_data['licenseHeader']
Expand Down Expand Up @@ -154,15 +160,19 @@ def submitNewLicense(request):
# Check if the license text doesn't matches with the rejected as well as not yet approved licenses
if not matches:
xml = generateLicenseXml(licenseOsi, licenseIdentifier, licenseName,
listVersionAdded, licenseSourceUrls, licenseHeader, licenseNotes, licenseText)
listVersionAdded, licenseSourceUrls, licenseHeader, licenseNotes, licenseText, isException)
now = datetime.datetime.now()
licenseRequest = LicenseRequest(licenseAuthorName=licenseAuthorName, fullname=licenseName, shortIdentifier=licenseIdentifier,
submissionDatetime=now, notes=licenseNotes, xml=xml, text=licenseText)
submissionDatetime=now, notes=licenseNotes, xml=xml, text=licenseText, isException=isException)
licenseRequest.save()
licenseId = licenseRequest.id
serverUrl = request.build_absolute_uri('/')
licenseRequestUrl = os.path.join(serverUrl, reverse('license-requests')[1:], str(licenseId))
statusCode = utils.createIssue(licenseAuthorName, licenseName, licenseIdentifier, licenseComments, licenseSourceUrls, licenseHeader, licenseOsi, licenseExamples, licenseRequestUrl, token, urlType)
statusCode, githubIssueId = utils.createIssue(
licenseAuthorName, licenseName, licenseIdentifier,
licenseComments, licenseSourceUrls, licenseHeader,
licenseOsi, licenseExamples, licenseRequestUrl,
token, urlType)

# If the license text matches with either rejected or yet not approved license then return 409 Conflict
else:
Expand All @@ -172,6 +182,7 @@ def submitNewLicense(request):
data['issueUrl'] = issueUrl

data['statusCode'] = str(statusCode)
data['issueId'] = str(githubIssueId)
return JsonResponse(data)
except UserSocialAuth.DoesNotExist:
""" User not authenticated with GitHub """
Expand Down Expand Up @@ -986,7 +997,10 @@ def promoteNamespaceRequests(request, license_id=None):
if 'urlType' in request.POST:
# This is present only when executing submit license via tests
urlType = request.POST["urlType"]
statusCode = utils.createIssue(licenseAuthorName, licenseName, licenseIdentifier, licenseComments, licenseSourceUrls, licenseHeader, licenseOsi, licenseExamples, licenseRequestUrl, token, urlType)
statusCode, githubIssueId = utils.createIssue(
licenseAuthorName, licenseName, licenseIdentifier,
licenseComments, licenseSourceUrls, licenseHeader, licenseOsi,
licenseExamples, licenseRequestUrl, token, urlType)
return_tuple = (statusCode, licenseRequest)
statusCode = return_tuple[0]
if statusCode == 201:
Expand Down Expand Up @@ -1156,12 +1170,16 @@ def issue(request):
listVersionAdded, licenseSourceUrls, licenseHeader, licenseNotes, licenseText)
now = datetime.datetime.now()
licenseRequest = LicenseRequest(licenseAuthorName=licenseAuthorName, fullname=licenseName, shortIdentifier=licenseIdentifier,
submissionDatetime=now, notes=licenseNotes, xml=xml, text=licenseText)
submissionDatetime=now, notes=licenseNotes, xml=xml)
licenseRequest.save()
licenseRequestId = licenseRequest.id
serverUrl = request.build_absolute_uri('/')
licenseRequestUrl = os.path.join(serverUrl, reverse('license-requests')[1:], str(licenseRequestId))
statusCode = utils.createIssue(licenseAuthorName, licenseName, licenseIdentifier, licenseComments, licenseSourceUrls, licenseHeader, licenseOsi, licenseExamples, licenseRequestUrl, token, urlType, matchId, diffUrl, msg)
statusCode, githubIssueId = utils.createIssue(
licenseAuthorName, licenseName, licenseIdentifier,
licenseComments, licenseSourceUrls, licenseHeader,
licenseOsi, licenseExamples, licenseRequestUrl, token,
urlType, matchId, diffUrl, msg)
data['statusCode'] = str(statusCode)
return JsonResponse(data)
except UserSocialAuth.DoesNotExist:
Expand Down Expand Up @@ -1200,20 +1218,22 @@ def handle_pull_request(request, is_ns):
github_login = user.social_auth.get(provider="github")
token = github_login.extra_data["access_token"]
username = github_login.extra_data["login"]
hidden_license_id = request.POST.get('hidden_license_id')
license_obj = LicenseRequest.objects.get(id=hidden_license_id)
license_id = request.POST.get('hidden_license_id')
print(request)
license_obj = LicenseRequest.objects.get(id=license_id)
response = utils.makePullRequest(
username=username,
token=token,
branchName=request.POST["branchName"],
updateUpstream=request.POST["updateUpstream"],
fileName=request.POST["fileName"],
commitMessage=request.POST["commitMessage"],
prTitle=request.POST["prTitle"],
prBody=request.POST["prBody"],
xmlText=request.POST["xmlText"],
plainText=license_obj.text,
is_ns=is_ns
username,
token,
request.POST["branchName"],
request.POST["updateUpstream"],
request.POST["fileName"],
request.POST["commitMessage"],
request.POST["prTitle"],
request.POST["prBody"],
request.POST["xmlText"],
license_obj.text,
license_obj.isException,
is_ns,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's continue to pass arguments by name so that order doesn't get messed up when adding more args. It's always better and clearer to pass args by name.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's pick all these nits later. @BassCoder2808 , merging it

)
if response["type"] == "success":
"""PR made successfully"""
Expand Down