diff options
-rw-r--r-- | R_on_Cloud/default_config.py | 7 | ||||
-rw-r--r-- | website/query.py | 76 | ||||
-rw-r--r-- | website/static/website/js/cloud.js | 72 | ||||
-rw-r--r-- | website/static/website/templates/index.html | 25 | ||||
-rw-r--r-- | website/static/website/templates/search_code.html | 28 | ||||
-rw-r--r-- | website/urls.py | 11 | ||||
-rw-r--r-- | website/views.py | 143 |
7 files changed, 309 insertions, 53 deletions
diff --git a/R_on_Cloud/default_config.py b/R_on_Cloud/default_config.py index 842baec..a0a1737 100644 --- a/R_on_Cloud/default_config.py +++ b/R_on_Cloud/default_config.py @@ -46,3 +46,10 @@ TORNADO_PORT = '8000' # class ExecutionHandler. DEFAULT_TORNADO_WORKERS = 1 DEFAULT_REQUEST_COUNT = 1 + +# Solr search engine config + +HOST = "localhost" +PORT = "8983" +COLLECTION = "r_code_search_collection" +URL = 'http://' + HOST + ':' + PORT + '/solr/' + COLLECTION diff --git a/website/query.py b/website/query.py index 8ccd7a2..863c497 100644 --- a/website/query.py +++ b/website/query.py @@ -2,11 +2,14 @@ GET_ALLMAINCATEGORY_SQL = """ SELECT category_id, maincategory FROM list_of_category ORDER BY maincategory ASC """ + + GET_ALLSUBCATEGORY_SQL = """ SELECT id, subcategory_id, subcategory, maincategory_id FROM list_of_subcategory ORDER BY subcategory ASC """ + GET_SUBCATEGORY_SQL = """ SELECT id, subcategory_id, subcategory, maincategory_id FROM list_of_subcategory WHERE maincategory_id =%s @@ -14,8 +17,6 @@ GET_SUBCATEGORY_SQL = """ """ - - GET_TBC_PREFERENCE_SQL = """ SELECT DISTINCT (loc.category_id), pe.id, tcbm.sub_category, loc.maincategory, pe.book as book, @@ -61,6 +62,7 @@ GET_TBC_EXAMPLE_FILE_SQL = """ WHERE tcef.filetype = 'S' AND tcef.example_id = %s """ + GET_TBC_CONTRIBUTOR_DETAILS_SQL = """ SELECT preference.id, proposal.full_name as proposal_full_name, @@ -73,20 +75,24 @@ GET_TBC_CONTRIBUTOR_DETAILS_SQL = """ WHERE preference.id = %s """ + GET_TBC_CHAPTER_ID_SQL = """ SELECT chapter_id FROM textbook_companion_example WHERE id = %s """ + INSERT_TBC_EXAMPLE_VIEW_SQL = """ INSERT INTO textbook_companion_example_views (example_id,chapter_id) VALUES(%s, %s) """ + UPDATE_TBC_EXAMPLE_VIEW_SQL = """ UPDATE textbook_companion_example_views SET views_count = views_count + 1 WHERE example_id = %s """ + GET_TBC_EXAMPLE_VIEW_SQL = """ SELECT views_count FROM textbook_companion_example_views WHERE example_id = %s @@ -96,6 +102,7 @@ GET_TBC_EXAMPLE_R_CLOUD_COMMENT_SQL = """ SELECT COUNT(id) FROM r_cloud_comment WHERE example= %s """ + GET_TBC_EXAMPLE_CHAPTER_ID_SQL = """ SELECT DISTINCT(chapter_id) FROM textbook_companion_example @@ -112,6 +119,7 @@ GET_TBC_CHAPTER_PREFERENCE_ID_SQL = """ FROM textbook_companion_chapter WHERE id = %s) """ + GET_TBC_PREFERENCE_DETAIL_CATEGORY_SQL = """ SELECT DISTINCT (loc.category_id), tcbm.sub_category,loc.maincategory, pe.book as book, @@ -129,6 +137,7 @@ GET_TBC_PREFERENCE_DETAIL_CATEGORY_SQL = """ AND pe.id= %s """ + GET_TBC_PREFERENCE_FROM_CATEGORY_ID_SQL = """ SELECT DISTINCT (loc.category_id),pe.id, tcbm.sub_category,loc.maincategory, pe.book as @@ -146,6 +155,7 @@ GET_TBC_PREFERENCE_FROM_CATEGORY_ID_SQL = """ AND tcbm.sub_category = %s """ + GET_TBC_CHAPTER_DETAIL_SQL = """ SELECT id, name, number, preference_id FROM textbook_companion_chapter @@ -154,3 +164,65 @@ GET_TBC_CHAPTER_DETAIL_SQL = """ FROM textbook_companion_chapter WHERE id = %s) ORDER BY number ASC """ + + +GET_SEARCH_BOOK_SQL = """ + SELECT pe.id, pe.book as book, pe.author as author, + pe.publisher as publisher,pe.year as year, + pe.id as pe_id, po.approval_date as approval_date + FROM textbook_companion_preference pe + LEFT JOIN textbook_companion_proposal po ON + pe.proposal_id = po.id WHERE + (pe.book like %s OR pe.author like %s) + AND po.proposal_status = 3 + AND pe.approval_status = 1 + ORDER BY (pe.book = %s OR pe.author = %s) DESC, + length(pe.book) + """ + + +GET_SEARCH_POPULAR_BOOK_SQL = """ + SELECT pe.id, pe.book as book, pe.author as author, + pe.publisher as publisher,pe.year as year, + pe.id as pe_id, po.approval_date as approval_date, + tcph.hitcount FROM textbook_companion_preference pe + left join textbook_companion_preference_hits tcph on + tcph.pref_id = pe.id + LEFT JOIN textbook_companion_proposal po ON + pe.proposal_id = po.id WHERE po.proposal_status = 3 + AND pe.approval_status = 1 + ORDER BY tcph.hitcount DESC LIMIT 10 + """ + + +GET_SEARCH_RECENT_BOOK_SQL = """ + SELECT pe.id, pe.book as book, pe.author as author, + pe.publisher as publisher,pe.year as year, + pe.id as pe_id, po.approval_date as approval_date, + tcph.hitcount, tcph.last_search + FROM textbook_companion_preference pe + left join textbook_companion_preference_hits tcph + on tcph.pref_id = pe.id + LEFT JOIN textbook_companion_proposal po ON + pe.proposal_id = po.id WHERE po.proposal_status = 3 + AND pe.approval_status = 1 + ORDER BY tcph.last_search DESC LIMIT 10 + """ + + +GET_BOOK_CATEGORY_FROM_ID = """ + SELECT DISTINCT (loc.category_id),pe.id, + tcbm.sub_category,loc.maincategory, pe.book as + book,pe.author as author, pe.publisher as publisher, + pe.year as year, pe.id as pe_id, pe.edition, + po.approval_date as approval_date + FROM textbook_companion_preference pe LEFT JOIN + textbook_companion_proposal po ON pe.proposal_id = po.id + LEFT JOIN textbook_companion_book_main_subcategories + tcbm ON pe.id = tcbm.pref_id LEFT JOIN list_of_category + loc ON tcbm.main_category = loc.category_id WHERE + po.proposal_status = 3 AND pe.approval_status = 1 + AND pe.id = tcbm.pref_id AND + pe.cloud_pref_err_status = 0 AND + pe.id=%s + """ diff --git a/website/static/website/js/cloud.js b/website/static/website/js/cloud.js index 43f035f..9a632e7 100644 --- a/website/static/website/js/cloud.js +++ b/website/static/website/js/cloud.js @@ -905,10 +905,27 @@ $(document.body).ready(function() { }); }); /********************************************/ + /********************************************/ + /********************************************/ + /********* search feature *******************/ + /********************************************/ + $(document).on("change", "input[type=radio][name=optradio]", function() { + if (this.value == 'bybook') { + $("#searched_code").hide(); + $("#searched_book").show(); + } + else if (this.value == 'bycode') { + $("#searched_code").show(); + $("#searched_book").hide(); + } + }); + /********************************************/ $(document).on("click", "#search", function() { ajax_loader(this); - $("#relevant").html(''); var search_string = jQuery.trim($("#search-input").val()); + if(search_string != ''){ + if($("input[name='optradio']:checked").val() == 'bybook'){ + $("#relevant").html(''); if (search_string == '') { search_string = 'Null'; } @@ -920,13 +937,17 @@ $(document.body).ready(function() { search_string: search_string, }, success: function(data) { + if(data.length > 0 ){ $("#relevant").html('<h2>Relevant</h2><hr>'); for (var i = 0; i < data.length; i++) { $("#relevant").append( - '<a href="?book_id=' + data[i].ids + '" class="">' + data[i].book + + '<a href="?book_id=' + data[i].id + '" class="">' + data[i].book + ' (Author: ' + data[i].author + ')</a><hr>'); } + }else{ + $("#relevant").append('Oops! This book is not availabe!'); + } ajax_loader("clear"); } }), @@ -946,7 +967,6 @@ $(document.body).ready(function() { } ajax_loader("clear"); } - }), $.ajax({ url: 'search_book/recent/', @@ -962,9 +982,33 @@ $(document.body).ready(function() { '<a href="?book_id=' + data[i].ids + '" class="">' + data[i].book + ' (Author: ' + data[i].author + ')</a><hr>'); } - ajax_loader("clear"); } }); + } else{ + ajax_loader(this); + $.ajax({ + url: 'search_in_code/', + dataType: 'JSON', + type: 'GET', + data: { + search_string: search_string, + }, + success: function(data) { + if(data.error != 'True'){ + console.log(data.data); + $("#searched_code_data").html(""); + $("#searched_code").html(data.data); + }else{ + alert("Oops! Search engine is away, please try after some time!") + } + } + }); + ajax_loader("clear"); + } + }else{ + alert("Please enter the search string!"); + } + ajax_loader("clear"); }); $(document).on("click", "#search_book", function(e) { @@ -986,7 +1030,7 @@ $(document.body).ready(function() { $("#popular").html('<h2>Popular</h2><hr>'); for (var i = 0; i < data.length; i++) { $("#popular").append( - '<a href="?book_id=' + data[i].ids + '" class="">' + data[i].book + + '<a href="?book_id=' + data[i].id + '" class="">' + data[i].book + ' (Author: ' + data[i].author + ')</a><hr>'); } ajax_loader("clear"); @@ -1003,7 +1047,7 @@ $(document.body).ready(function() { $("#recent").html('<h2>Recent</h2><hr>'); for (var i = 0; i < data.length; i++) { $("#recent").append( - '<a href="?book_id=' + data[i].ids + '" class="">' + data[i].book + + '<a href="?book_id=' + data[i].id + '" class="">' + data[i].book + ' (Author: ' + data[i].author + ')</a><hr>'); } ajax_loader("clear"); @@ -1068,14 +1112,14 @@ function doSubmit(){ } function checkserver(){ - - $.ajax({url: api_url, - dataType: "jsonp", - statusCode: { - 404: function (response) { - alert("Oops! R cloud server is not available, please try after some time"); - } - } + $.ajax({url: 'check_server/', + dataType: "json", + success : function (data) { + if((data.status == 200) || (data.error != 'True')){ + }else{ + alert("R cloud server is not available, please try after some time"); + } + } }); } diff --git a/website/static/website/templates/index.html b/website/static/website/templates/index.html index 18dd01b..6d68515 100644 --- a/website/static/website/templates/index.html +++ b/website/static/website/templates/index.html @@ -45,9 +45,9 @@ <div class="collapse navbar-collapse" id="collapsibleNavbar"> <ul class="navbar-nav ml-auto"> {% if user and not user.is_anonymous %} {% if not user.is_staff %} - <!--> <li class="nav-item"> - <a class="nav-link" href="" id="search_book" data-toggle="modal" data-target="#search_wrapper">Search Book</a> - </li> --> + <li class="nav-item"> + <a class="nav-link" href="" id="search_book" data-toggle="modal" data-target="#search_wrapper"><i class="fa fa-search" aria-hidden="true"></i>Search Book</a> + </li> <li class="nav-item"> <a class="nav-link" href="" id="about-us" data-toggle="modal" data-target="#about_wrapper">About</a> </li> @@ -69,9 +69,9 @@ <a style="color:red">Hello, {{ user.get_full_name }}!</a> </li> {% else %} - <!-- > <li class="nav-item"> - <a class="nav-link" href="" id="search_book" data-toggle="modal" data-target="#search_wrapper">Search Book</a> - </li> --> + <li class="nav-item"> + <a class="nav-link" href="" id="search_book" data-toggle="modal" data-target="#search_wrapper"><i class="fa fa-search text-primary" aria-hidden="true"></i>Search</a> + </li> <li class="nav-item"> <a class="nav-link" href="" id="about-us" data-toggle="modal" data-target="#about_wrapper">About</a> </li> @@ -500,21 +500,26 @@ <!-- Modal Header --> <div class="modal-header"> - <h4 class="modal-title">Search book</h4> + <h4 class="modal-title">Search</h4> <button type="button" class="close" data-dismiss="modal">×</button> </div> <!-- Modal body --> <div class="modal-body"> <div class="input-group"> - <input id="search-input" type="text" class="form-control" placeholder="Enter book or author name"> + <input id="search-input" type="text" class="form-control" placeholder="Enter book/author name or code string"> <span class="input-group-btn"> <button id="search" class="btn btn-info" type="button">Search</button> </span> </div> + + <div class="custom-control custom-radio"> + <label class="radio-inline"><input id="bybook" type="radio" value="bybook" name="optradio" checked="checked"> <i class="fa fa-search" aria-hidden="true"></i>Search by book/author name <i class="fa fa-book" aria-hidden="true"></i></label> + <label class="radio-inline"><input id="bycode" type="radio" value="bycode" name="optradio"> <i class="fa fa-search" aria-hidden="true"></i>Search by code</label> + </div> </div> <div class="container"> - <div class="row"> + <div id="searched_book" class="row"> <div id="relevant" class="col-4 small"> </div> <div id="popular" class="col-4 small bg-light text-primary" style="word-wrap: break-word;overflow:auto;"> @@ -522,6 +527,8 @@ <div id="recent" class="col-4 small bg-light text-primary" style="word-wrap: break-word;overflow:auto;"> </div> </div> + <div id="searched_code" class="row"> + </div> </div> <!-- Modal footer --> <div class="modal-footer"> diff --git a/website/static/website/templates/search_code.html b/website/static/website/templates/search_code.html new file mode 100644 index 0000000..f5d082f --- /dev/null +++ b/website/static/website/templates/search_code.html @@ -0,0 +1,28 @@ +<span class="badge badge-info">Search results count {{ data|length }}</span> +<div id="searched_code_data" class="col-12 bg-light text-success" style="word-wrap: break-word;overflow:auto;"> + +{% for result in data %} +<div><span class="badge badge-info">{{ forloop.counter }}</span> + <i class="fa fa-book" aria-hidden="true"></i> + Book: <span class="text-info">{{ result.book }}</span></div> +<div><i class="fa fa-file" aria-hidden="true"></i> + Chapter: <span class="text-info">{{result.chapter.0 }}</span></div> +<div><i class="fa fa-bars" aria-hidden="true"></i> + Example: <span class="text-info">{{ result.example.0 }}</span></div> +<div><i class="fa fa-external-link" aria-hidden="true"></i> + Links: <span class="text-success"> + <a href="https://r.fossee.in/textbook-companion/download/book/{{ result.book_id.0 }}" target="_blank">Download book + <i class="fa fa-download" aria-hidden="true"></i> + </a> + </span> <i class="fa fa-expand" aria-hidden="true"></i> + + <span class="text-success"> + <a href="http://rcloud.fossee.in/index?eid={{ result.example_id }}" target="_blank"> View this example + <i class="fa fa-cloud" aria-hidden="true"></i> + </a> + </span> +</div> +<hr> +{% endfor %} + +</div> diff --git a/website/urls.py b/website/urls.py index 127cf09..5a13bb4 100644 --- a/website/urls.py +++ b/website/urls.py @@ -7,7 +7,7 @@ urlpatterns = [ path('', views.index, name='index'), path('index', views.index, name='index'), path('get_subcategories/', ajax.subcategories, - name='subcategories'), + name='subcategories'), path('get_books/', ajax.books, name='books'), path('get_chapters/', ajax.chapters, name='chapters'), path('get_examples/', ajax.examples, name='examples'), @@ -15,7 +15,12 @@ urlpatterns = [ path('get_code/', ajax.code, name='code'), path('get_diff/', ajax.diff, name='diff'), path('update_view_count/', views.update_view_count, - name='update_view_count'), + name='update_view_count'), path('get_contributor/', ajax.contributor, name='contributor'), path('reset/', views.reset, name='reset'), - ] + path('search_book/', views.search_book, name='search_book'), + path('search_book/popular/', views.popular, name='popular'), + path('search_book/recent/', views.recent, name='recent'), + path('search_in_code/', views.solr_search_string, name='solr_search_string'), + path('check_server/', views.checkserver, name='checkserver'), +] diff --git a/website/views.py b/website/views.py index e554ef4..b449b27 100644 --- a/website/views.py +++ b/website/views.py @@ -1,10 +1,10 @@ from django.shortcuts import render, redirect -from django.http import HttpResponse -from django.template import loader +from django.http import HttpResponse, JsonResponse +from django.template import loader, Context, Template import requests import uuid from R_on_Cloud.config import (API_URL_UPLOAD, API_URL_RESET, AUTH_KEY, - API_URL_SERVER) + API_URL_SERVER, URL) from website.models import * from django.db.models import Q import json as simplejson @@ -12,6 +12,8 @@ from . import utils from django.db import connections from collections import defaultdict from .query import * +import pysolr +import json def dictfetchall(cursor): @@ -147,23 +149,10 @@ def index(request): template = loader.get_template('index.html') return HttpResponse(template.render(context, request)) elif book_id: - books = TextbookCompanionPreference.objects\ - .db_manager('r').raw(""" - SELECT DISTINCT (loc.category_id),pe.id, - tcbm.sub_category,loc.maincategory, pe.book as - book,loc.category_id,tcbm.sub_category, - pe.author as author, pe.publisher as publisher, - pe.year as year, pe.id as pe_id, pe.edition, - po.approval_date as approval_date - FROM textbook_companion_preference pe LEFT JOIN - textbook_companion_proposal po ON pe.proposal_id = po.id - LEFT JOIN textbook_companion_book_main_subcategories - tcbm ON pe.id = tcbm.pref_id LEFT JOIN list_of_category - loc ON tcbm.main_category = loc.category_id WHERE - po.proposal_status = 3 AND pe.approval_status = 1 - AND pe.id = tcbm.pref_id AND - pe.cloud_pref_err_status = 0 AND - pe.id=%s""", [book_id]) + with connections['r'].cursor() as cursor: + cursor.execute(GET_BOOK_CATEGORY_FROM_ID, + params=[book_id]) + books = cursor.fetchone() books = list(books) if len(books) == 0: @@ -179,9 +168,9 @@ def index(request): template = loader.get_template('index.html') return HttpResponse(template.render(context, request)) - books = get_books(books[0].sub_category) - maincat_id = books[0].category_id - subcat_id = books[0].sub_category + req_books = get_books(books[2]) + maincat_id = books[0] + subcat_id = books[2] request.session['maincat_id'] = maincat_id request.session['subcategory_id'] = subcat_id request.session['book_id'] = book_id @@ -196,8 +185,8 @@ def index(request): 'subcatg': subcateg_all, 'maincat_id': maincat_id, 'chapters': chapters, - 'subcategory_id': books[0].sub_category, - 'books': books, + 'subcategory_id': books[2], + 'books': req_books, 'book_id': int(book_id), } @@ -375,3 +364,107 @@ def reset(request): response = {"data": "ok"} return HttpResponse(simplejson.dumps(response), content_type='application/json') + + +def search_book(request): + result = {} + response_dict = [] + if request.is_ajax(): + exact_search_string = request.GET.get('search_string') + search_string = "%" + exact_search_string + "%" + with connections['r'].cursor() as cursor: + cursor.execute(GET_SEARCH_BOOK_SQL, [search_string, search_string, + str(exact_search_string), + str(exact_search_string)]) + result = dictfetchall(cursor) + return HttpResponse(simplejson.dumps(result), + content_type='application/json') + + +def popular(request): + result = {} + response_dict = [] + if request.is_ajax(): + search_string = request.GET.get('search_string') + search_string = "%" + search_string + "%" + with connections['r'].cursor() as cursor: + cursor.execute(GET_SEARCH_POPULAR_BOOK_SQL) + result = dictfetchall(cursor) + return HttpResponse(simplejson.dumps(result), + content_type='application/json') + + +def recent(request): + result = {} + response_dict = [] + if request.is_ajax(): + exact_search_string = request.GET.get('search_string') + search_string = "%" + exact_search_string + "%" + with connections['r'].cursor() as cursor: + cursor.execute(GET_SEARCH_RECENT_BOOK_SQL) + result = dictfetchall(cursor) + return HttpResponse(simplejson.dumps(result), + content_type='application/json') + + +def update_pref_hits(pref_id): + updatecount = TextbookCompanionPreferenceHits.objects.using('r')\ + .filter(pref_id=pref_id)\ + .update(hitcount=F('hitcount') + 1) + if not updatecount: + insertcount = TextbookCompanionPreferenceHits.objects.using('r')\ + .get_or_create(pref_id=pref_id, hitcount=1) + return + + +def solr_search_string(request): + + try: + requests.get(URL) + results = {} + context = [] + response_dict = [] + search_string = request.GET.get('search_string') + q = "content:'{0}'".format(search_string) + fl = "*" + qt = "select" + fq = "*" + rows = "100" + wt = 'json' + solr = pysolr.Solr(URL, search_handler="/"+qt, timeout=5) + results = solr.search(q, **{ + 'rows': rows, + 'group': 'true', + 'group.field': 'example', + 'group.limit': '1', + 'group.main': 'true', + }) + for obj in results: + response = { + 'example_id': obj['id'], + 'book_id': obj['book_id'], + 'book': obj['title'], + 'author': obj['author'], + 'chapter': obj['chapter'], + 'example': obj['example'], + } + response_dict.append(response) + + print("Saw {0} result(s).".format(len(results))) + template = loader.get_template('search_code.html') + context = {'data': response_dict} + data = template.render(context) + return JsonResponse({'data': data}) + except Exception: + context = {'data': ''} + template = loader.get_template('search_code.html') + data = template.render(context) + return JsonResponse({'data': '', 'error': 'True'}) + + +def checkserver(request): + try: + req_status = requests.get(API_URL_SERVER) + return JsonResponse({'status': req_status.status_code}) + except Exception: + return JsonResponse({'error': 'True'}) |