Added warning_paste module and created related webpages.

Fixed a Faup bug in credential (multiple instanciation) and added correc populate_set_out in concerned modules (creditcard, credential, ...).
Linked browse_warning_paste module and Flask function with redis (created new sets).
This commit is contained in:
Mokaddem 2016-08-08 09:17:44 +02:00
parent 3523d79a05
commit 78c611fead
17 changed files with 280 additions and 135 deletions

57
bin/Browse_warning_paste.py Executable file
View file

@ -0,0 +1,57 @@
#!/usr/bin/env python2
# -*-coding:UTF-8 -*
"""
The Browse_warning_paste module
====================
This module saved signaled paste (logged as 'warning') in redis for further usage
like browsing by category
Its input comes from other modules, namely:
Credential, CreditCard, SQLinjection, CVE, Keys, Mail and Phone
"""
import redis
import time
from datetime import datetime, timedelta
from packages import Paste
from pubsublogger import publisher
from Helper import Process
if __name__ == "__main__":
publisher.port = 6380
publisher.channel = "Script"
config_section = 'Browse_warning_paste'
p = Process(config_section)
server = redis.StrictRedis(
host=p.config.get("Redis_Level_DB", "host"),
port=p.config.get("Redis_Level_DB", "port"),
db=p.config.get("Redis_Level_DB", "db"))
# FUNCTIONS #
publisher.info("Script duplicate started")
while True:
message = p.get_from_set()
if message is not None:
module_name, p_path = message.split(';')
#PST = Paste.Paste(p_path)
else:
publisher.debug("Script Attribute is idling 10s")
time.sleep(10)
continue
# Add in redis
# Format in set: WARNING_moduleName -> p_path
key = "WARNING_" + module_name
print key + ' -> ' + p_path
server.sadd(key, p_path)
publisher.info('Saved in warning paste {}'.format(p_path))
#print 'Saved in warning paste {}'.format(p_path)

View file

@ -15,6 +15,8 @@ if __name__ == "__main__":
p = Process(config_section) p = Process(config_section)
publisher.info("Find credentials") publisher.info("Find credentials")
faup = Faup()
critical = 8 critical = 8
regex_web = "((?:https?:\/\/)[-_0-9a-zA-Z]+\.[0-9a-zA-Z]+)" regex_web = "((?:https?:\/\/)[-_0-9a-zA-Z]+\.[0-9a-zA-Z]+)"
@ -55,10 +57,11 @@ if __name__ == "__main__":
publisher.warning(to_print) publisher.warning(to_print)
#Send to duplicate #Send to duplicate
p.populate_set_out(filepath, 'Duplicate') p.populate_set_out(filepath, 'Duplicate')
#send to Browse_warning_paste
p.populate_set_out('credential;{}'.format(filepath), 'BrowseWarningPaste')
#Put in form, count occurences, then send to moduleStats #Put in form, count occurences, then send to moduleStats
creds_sites = {} creds_sites = {}
faup = Faup()
for url in sites: for url in sites:
faup.decode(url) faup.decode(url)
domain = faup.get()['domain'] domain = faup.get()['domain']

View file

@ -67,6 +67,8 @@ if __name__ == "__main__":
to_print, len(creditcard_set))) to_print, len(creditcard_set)))
#Send to duplicate #Send to duplicate
p.populate_set_out(filepath, 'Redis_Duplicate') p.populate_set_out(filepath, 'Redis_Duplicate')
#send to Browse_warning_paste
p.populate_set_out('creditCard;{}'.format(filename), 'BrowseWarningPaste')
else: else:
publisher.info('{}CreditCard related'.format(to_print)) publisher.info('{}CreditCard related'.format(to_print))
else: else:

View file

@ -53,5 +53,8 @@ if __name__ == '__main__':
# Do something with the message from the queue # Do something with the message from the queue
search_cve(message) search_cve(message)
# (Optional) Send that thing to the next queue #send to Browse_warning_paste
#p.populate_set_out(something_has_been_done) filepath, count = message.split()
p.populate_set_out('cve;{}'.format(filepath), 'BrowseWarningPaste')
#Send to duplicate
p.populate_set_out(filepath, 'Duplicate')

View file

@ -7,7 +7,7 @@ The Duplicate module
This huge module is, in short term, checking duplicates. This huge module is, in short term, checking duplicates.
Its input comes from other modules, namely: Its input comes from other modules, namely:
Credential, CreditCard, Keys, Mails and Phone Credential, CreditCard, Keys, Mails, SQLinjectionDetection, CVE and Phone
This one differ from v1 by only using redis and not json file stored on disk This one differ from v1 by only using redis and not json file stored on disk

View file

@ -17,7 +17,9 @@ def search_gpg(message):
if '-----BEGIN PGP MESSAGE-----' in content: if '-----BEGIN PGP MESSAGE-----' in content:
publisher.warning('{} has a PGP enc message'.format(paste.p_name)) publisher.warning('{} has a PGP enc message'.format(paste.p_name))
#Send to duplicate #Send to duplicate
p.populate_set_out(message) p.populate_set_out(message, 'Duplicate')
#send to Browse_warning_paste
p.populate_set_out('keys;{}'.format(message), 'BrowseWarningPaste')
if __name__ == '__main__': if __name__ == '__main__':
@ -49,4 +51,3 @@ if __name__ == '__main__':
search_gpg(message) search_gpg(message)
# (Optional) Send that thing to the next queue # (Optional) Send that thing to the next queue
#p.populate_set_out(something_has_been_done)

View file

@ -144,6 +144,8 @@ function launching_scripts {
screen -S "Script" -X screen -t "ModuleStats" bash -c './ModuleStats.py; read x' screen -S "Script" -X screen -t "ModuleStats" bash -c './ModuleStats.py; read x'
sleep 0.1 sleep 0.1
screen -S "Script" -X screen -t "SQLInjectionDetection" bash -c './SQLInjectionDetection.py; read x' screen -S "Script" -X screen -t "SQLInjectionDetection" bash -c './SQLInjectionDetection.py; read x'
sleep 0.1
screen -S "Script" -X screen -t "Browse_warning_paste" bash -c './Browse_warning_paste.py; read x'
} }
#If no params, display the help #If no params, display the help

View file

@ -69,6 +69,7 @@ if __name__ == "__main__":
for mail in MX_values[1]: for mail in MX_values[1]:
print 'mail;{};{};{}'.format(1, mail, PST.p_date) print 'mail;{};{};{}'.format(1, mail, PST.p_date)
p.populate_set_out('mail;{};{};{}'.format(1, mail, PST.p_date), 'ModuleStats') p.populate_set_out('mail;{};{};{}'.format(1, mail, PST.p_date), 'ModuleStats')
p.populate_set_out('mail;{}'.format(filename), 'BrowseWarningPaste')
prec_filename = filename prec_filename = filename

View file

@ -23,8 +23,10 @@ def search_phone(message):
if len(results) > 4: if len(results) > 4:
print results print results
publisher.warning('{} contains PID (phone numbers)'.format(paste.p_name)) publisher.warning('{} contains PID (phone numbers)'.format(paste.p_name))
#send to Browse_warning_paste
p.populate_set_out('phone;{}'.format(message), 'BrowseWarningPaste')
#Send to duplicate #Send to duplicate
p.populate_set_out(message) p.populate_set_out(message, 'Duplicate')
if __name__ == '__main__': if __name__ == '__main__':
# If you wish to use an other port of channel, do not forget to run a subscriber accordingly (see launch_logs.sh) # If you wish to use an other port of channel, do not forget to run a subscriber accordingly (see launch_logs.sh)

View file

@ -74,6 +74,10 @@ def analyse(url, path):
print urllib2.unquote(url) print urllib2.unquote(url)
to_print = 'SQLInjection;{};{};{};{}'.format(paste.p_source, paste.p_date, paste.p_name, "Detected SQL in URL") to_print = 'SQLInjection;{};{};{};{}'.format(paste.p_source, paste.p_date, paste.p_name, "Detected SQL in URL")
publisher.warning(to_print) publisher.warning(to_print)
#Send to duplicate
p.populate_set_out(path, 'Duplicate')
#send to Browse_warning_paste
p.populate_set_out('sqlInjectionDetection;{}'.format(path), 'BrowseWarningPaste')
else: else:
print "Potential SQL injection:" print "Potential SQL injection:"
print urllib2.unquote(url) print urllib2.unquote(url)

View file

@ -103,10 +103,11 @@ if __name__ == "__main__":
print hostl, asn, cc, \ print hostl, asn, cc, \
pycountry.countries.get(alpha2=cc).name pycountry.countries.get(alpha2=cc).name
if cc == cc_critical: if cc == cc_critical:
publisher.warning( to_print = 'Url;{};{};{};Detected {} {}'.format(
'Url;{};{};{};Detected {} {}'.format(
PST.p_source, PST.p_date, PST.p_name, PST.p_source, PST.p_date, PST.p_name,
hostl, cc)) hostl, cc)
#publisher.warning(to_print)
print to_print
else: else:
print hostl, asn, cc print hostl, asn, cc

View file

@ -31,11 +31,11 @@ publish = Redis_CreditCards,Redis_Mail,Redis_Onion,Redis_Web,Redis_Credential,Re
[CreditCards] [CreditCards]
subscribe = Redis_CreditCard subscribe = Redis_CreditCard
publish = Redis_Duplicate,Redis_ModuleStats publish = Redis_Duplicate,Redis_ModuleStats,Redis_BrowseWarningPaste
[Mail] [Mail]
subscribe = Redis_Mail subscribe = Redis_Mail
publish = Redis_Duplicate,Redis_ModuleStats publish = Redis_Duplicate,Redis_ModuleStats,Redis_BrowseWarningPaste
[Onion] [Onion]
subscribe = Redis_Onion subscribe = Redis_Onion
@ -54,27 +54,36 @@ subscribe = Redis_Url
[SQLInjectionDetection] [SQLInjectionDetection]
subscribe = Redis_Url subscribe = Redis_Url
publish = Redis_BrowseWarningPaste,Redis_Duplicate
[ModuleStats] [ModuleStats]
subscribe = Redis_ModuleStats subscribe = Redis_ModuleStats
[Browse_warning_paste]
subscribe = Redis_BrowseWarningPaste
#[send_to_queue]
#subscribe = Redis_Cve
#publish = Redis_BrowseWarningPaste
[Release] [Release]
subscribe = Redis_Global subscribe = Redis_Global
[Credential] [Credential]
subscribe = Redis_Credential subscribe = Redis_Credential
publish = Redis_Duplicate,Redis_ModuleStats publish = Redis_Duplicate,Redis_ModuleStats,Redis_BrowseWarningPaste
[Cve] [Cve]
subscribe = Redis_Cve subscribe = Redis_Cve
publish = Redis_Browse_warning_paste,Redis_Duplicate
[Phone] [Phone]
subscribe = Redis_Global subscribe = Redis_Global
publish = Redis_Duplicate publish = Redis_Duplicate,Redis_BrowseWarningPaste
[SourceCode] [SourceCode]
subscribe = Redis_SourceCode subscribe = Redis_SourceCode
[Keys] [Keys]
subscribe = Redis_Global subscribe = Redis_Global
publish = Redis_Duplicate publish = Redis_Duplicate,Redis_BrowseWarningPaste

View file

@ -44,6 +44,10 @@ r_serv_charts = redis.StrictRedis(
port=cfg.getint("Redis_Level_DB_Trending", "port"), port=cfg.getint("Redis_Level_DB_Trending", "port"),
db=cfg.getint("Redis_Level_DB_Trending", "db")) db=cfg.getint("Redis_Level_DB_Trending", "db"))
r_serv_db = redis.StrictRedis(
host=cfg.get("Redis_Level_DB", "host"),
port=cfg.getint("Redis_Level_DB", "port"),
db=cfg.getint("Redis_Level_DB", "db"))
app = Flask(__name__, static_url_path='/static/') app = Flask(__name__, static_url_path='/static/')
@ -157,9 +161,11 @@ def showpaste(content_range):
return render_template("show_saved_paste.html", date=p_date, source=p_source, encoding=p_encoding, language=p_language, size=p_size, mime=p_mime, lineinfo=p_lineinfo, content=p_content, initsize=len(p_content), duplicate_list = p_duplicate_list, simil_list = p_simil_list, hashtype_list = p_hashtype_list) return render_template("show_saved_paste.html", date=p_date, source=p_source, encoding=p_encoding, language=p_language, size=p_size, mime=p_mime, lineinfo=p_lineinfo, content=p_content, initsize=len(p_content), duplicate_list = p_duplicate_list, simil_list = p_simil_list, hashtype_list = p_hashtype_list)
def getPastebyType(module_name): def getPastebyType(server, module_name):
all_path = [] all_path = []
all_path.append("/home/mokaddem/AIL-framework/PASTES/archive/paste.debian.net/2016/06/30/771058.gz") for path in server.smembers('WARNING_'+module_name):
#all_path.append("/home/mokaddem/AIL-framework/PASTES/archive/paste.debian.net/2016/06/30/771058.gz")
all_path.append(path)
return all_path return all_path
@ -377,13 +383,19 @@ def trending():
@app.route("/browseImportantPaste/", methods=['GET']) @app.route("/browseImportantPaste/", methods=['GET'])
def browseImportantPaste(): def browseImportantPaste():
module_name = request.args.get('moduleName') module_name = request.args.get('moduleName')
return render_template("browse_important_paste.html")
@app.route("/importantPasteByModule/", methods=['GET'])
def importantPasteByModule():
module_name = request.args.get('moduleName')
all_content = [] all_content = []
paste_date = [] paste_date = []
paste_linenum = [] paste_linenum = []
all_path = [] all_path = []
for path in getPastebyType(module_name): for path in getPastebyType(r_serv_db, module_name):
all_path.append(path) all_path.append(path)
paste = Paste.Paste(path) paste = Paste.Paste(path)
content = paste.get_p_content().decode('utf8', 'ignore') content = paste.get_p_content().decode('utf8', 'ignore')
@ -394,9 +406,7 @@ def browseImportantPaste():
paste_date.append(curr_date) paste_date.append(curr_date)
paste_linenum.append(paste.get_lines_info()[0]) paste_linenum.append(paste.get_lines_info()[0])
return render_template("browse_important_paste.html", all_path=all_path, content=all_content, paste_date=paste_date, paste_linenum=paste_linenum, char_to_display=max_preview_modal) return render_template("important_paste_by_module.html", all_path=all_path, content=all_content, paste_date=paste_date, paste_linenum=paste_linenum, char_to_display=max_preview_modal)
@app.route("/moduletrending/") @app.route("/moduletrending/")
def moduletrending(): def moduletrending():

View file

@ -29,6 +29,7 @@
<li><a href="{{ url_for('index') }}"><i class="fa fa-dashboard fa-fw"></i> Dashboard</a></li> <li><a href="{{ url_for('index') }}"><i class="fa fa-dashboard fa-fw"></i> Dashboard</a></li>
<li><a href="{{ url_for('trending') }}"><i class="glyphicon glyphicon-stats"></i> Trending charts</a></li> <li><a href="{{ url_for('trending') }}"><i class="glyphicon glyphicon-stats"></i> Trending charts</a></li>
<li class="active"><a href="{{ url_for('moduletrending') }}"><i class="glyphicon glyphicon-stats"></i> Modules statistics</a></li> <li class="active"><a href="{{ url_for('moduletrending') }}"><i class="glyphicon glyphicon-stats"></i> Modules statistics</a></li>
<li><a href="{{ url_for('browseImportantPaste') }}"><i class="fa fa-search-plus "></i> Browse important pastes</a></li>
</ul> </ul>
</div> </div>
<!-- /.navbar-top-links --> <!-- /.navbar-top-links -->

View file

@ -33,6 +33,7 @@
<li><a href="{{ url_for('index') }}"><i class="fa fa-dashboard fa-fw"></i> Dashboard</a></li> <li><a href="{{ url_for('index') }}"><i class="fa fa-dashboard fa-fw"></i> Dashboard</a></li>
<li class="active"><a href="{{ url_for('trending') }}"><i class="glyphicon glyphicon-stats"></i> Trending charts</a></li> <li class="active"><a href="{{ url_for('trending') }}"><i class="glyphicon glyphicon-stats"></i> Trending charts</a></li>
<li><a href="{{ url_for('moduletrending') }}"><i class="glyphicon glyphicon-stats"></i> Modules statistics</a></li> <li><a href="{{ url_for('moduletrending') }}"><i class="glyphicon glyphicon-stats"></i> Modules statistics</a></li>
<li><a href="{{ url_for('browseImportantPaste') }}"><i class="fa fa-search-plus "></i> Browse important pastes</a></li>
</ul> </ul>
</div> </div>
<!-- /.navbar-top-links --> <!-- /.navbar-top-links -->

View file

@ -95,49 +95,38 @@
<!-- /.nav-tabs --> <!-- /.nav-tabs -->
<ul class="nav nav-tabs"> <ul class="nav nav-tabs">
<li class="active"><a data-toggle="tab" href="#cred-tab" data-attribute-name="credential" data-panel="credential-panel">Credentials</a></li> <li name='nav-pan' class="active"><a data-toggle="tab" href="#credential-tab" data-attribute-name="credential" data-panel="credential-panel">Credentials</a></li>
<li><a data-toggle="tab" href="#creditcard-tab" data-attribute-name="creditcard" data-panel="creditcard-panel">Credit cards</a></li> <li name='nav-pan'><a data-toggle="tab" href="#creditcard-tab" data-attribute-name="creditcard" data-panel="creditcard-panel">Credit cards</a></li>
<li><a data-toggle="tab" href="#sqlinjection-tab" data-attribute-name="sqlinjection" data-panel="sqlinjection-panel">SQL injections</a></li> <li name='nav-pan'><a data-toggle="tab" href="#sqlinjection-tab" data-attribute-name="sqlinjection" data-panel="sqlinjection-panel">SQL injections</a></li>
<li><a data-toggle="tab" href="#CVE-tab" data-pannel="CVE">CVE</a></li> <li name='nav-pan'><a data-toggle="tab" href="#cve-tab" data-attribute-name="cve" data-panel="cve-panel">CVEs</a></li>
<li name='nav-pan'><a data-toggle="tab" href="#key-tab" data-attribute-name="key" data-panel="key-panel">Keys</a></li>
<li name='nav-pan'><a data-toggle="tab" href="#mail-tab" data-attribute-name="mail" data-panel="mail-panel">Mails</a></li>
<li name='nav-pan'><a data-toggle="tab" href="#phone-tab" data-attribute-name="phone" data-panel="phone-panel">Phones</a></li>
</ul> </ul>
</br> </br>
<div class="tab-content"> <div class="tab-content">
<div class="col-lg-12 tab-pane fade in active" id="cred-tab" > <div class="col-lg-12 tab-pane fade in active" id="credential-tab" >
<table class="table table-striped table-bordered table-hover" id="myTable"> <img id="loading-gif-modal" src="{{url_for('static', filename='image/loading.gif') }}" style="margin: 4px;">
<thead>
<tr>
<th>#</th>
<th style="max-width: 800px;">Path</th>
<th>Date</th>
<th># of lines</th>
<th>Action</th>
</tr>
</thead>
<tbody>
{% set i = 0 %}
{% for path in all_path %}
<tr>
<td> {{ i + 1 }}</td>
<td><a target="_blank" href="{{ url_for('showsavedpaste') }}?paste={{path}}&num={{i+1}}">{{ path }}</a></td>
<td>{{ paste_date[i] }}</td>
<td>{{ paste_linenum[i] }}</td>
<td><p><span class="glyphicon glyphicon-info-sign" data-toggle="tooltip" data-placement="left" title="{{ content[i] }} "></span> <button type="button" class="btn-link" data-num="{{ i + 1 }}" data-toggle="modal" data-target="#mymodal" data-url="{{ url_for('showsavedpaste') }}?paste={{ path }}&num={{ i+1 }}" data-path="{{ path }}"><span class="fa fa-search-plus"></span></button></p></td>
</tr>
{% set i = i + 1 %}
{% endfor %}
</tbody>
</table>
</div> </div>
<div class="col-lg-12 tab-pane fade" id="creditcard-tab"> <div class="col-lg-12 tab-pane fade" id="creditcard-tab">
coucou2 <img id="loading-gif-modal" src="{{url_for('static', filename='image/loading.gif') }}" style="margin: 4px;">
</div> </div>
<div class="col-lg-12 tab-pane fade" id="sqlinjection-tab"> <div class="col-lg-12 tab-pane fade" id="sqlinjection-tab">
coucou3 <img id="loading-gif-modal" src="{{url_for('static', filename='image/loading.gif') }}" style="margin: 4px;">
</div> </div>
<div class="col-lg-12 tab-pane fade" id="CVE-tab"> <div class="col-lg-12 tab-pane fade" id="cve-tab">
coucou4 <img id="loading-gif-modal" src="{{url_for('static', filename='image/loading.gif') }}" style="margin: 4px;">
</div>
<div class="col-lg-12 tab-pane fade" id="key-tab">
<img id="loading-gif-modal" src="{{url_for('static', filename='image/loading.gif') }}" style="margin: 4px;">
</div>
<div class="col-lg-12 tab-pane fade" id="mail-tab">
<img id="loading-gif-modal" src="{{url_for('static', filename='image/loading.gif') }}" style="margin: 4px;">
</div>
<div class="col-lg-12 tab-pane fade" id="phone-tab">
<img id="loading-gif-modal" src="{{url_for('static', filename='image/loading.gif') }}" style="margin: 4px;">
</div> </div>
</div> <!-- tab-content --> </div> <!-- tab-content -->
<!-- /.row --> <!-- /.row -->
@ -147,86 +136,33 @@
<!-- import graph function --> <!-- import graph function -->
<script> <script>
$(document).ready(function(){ $(document).ready(function(){
$('[data-toggle="tooltip"]').tooltip(); var dataPath = 'credential';
$('#myTable').dataTable(); $.get("{{ url_for('importantPasteByModule') }}"+"?moduleName="+dataPath, function(data, status){
$('#'+dataPath+'-tab').html(data);
});
}); });
</script> </script>
<!-- Dynamically update the modal -->
<script type="text/javascript">
// static data
var alert_message = '<div class="alert alert-info alert-dismissable"><button type="button" class="close" data-dismiss="alert" aria-hidden="true">×</button><strong>No more data.</strong> Full paste displayed.</div>';
var complete_paste = null;
var char_to_display = {{ char_to_display }};
var start_index = 0;
// On click, get html content from url and update the corresponding modal <script>
$("[data-toggle='modal']").on("click", function (event) { // When a pannel is shown, create the data-table.
event.preventDefault(); var previous_tab = $('[data-attribute-name="credential');
var modal=$(this); var loading_gif = "<img id='loading-gif-modal' class='img-center' src=\"{{url_for('static', filename='image/loading.gif') }}\" height='26' width='26' style='margin: 4px;'>";
var url = " {{ url_for('showpreviewpaste') }}?paste=" + $(this).attr('data-path') + "&num=" + $(this).attr('data-num');
$.get(url, function (data) {
$("#mymodalbody").html(data);
var button = $('<button type="button" id="load-more-button" class="btn btn-info btn-xs center-block" data-url="' + $(modal).attr('data-path') +'" data-toggle="tooltip" data-placement="bottom" title="Load more content"><span class="glyphicon glyphicon-download"></span></button>');
button.tooltip();
$("#mymodalbody").children(".panel-default").append(button);
$("#button_show_path").attr('href', $(modal).attr('data-url')); $('.nav-tabs a').on('shown.bs.tab', function(event){
$("#button_show_path").show('fast'); console.log(event.target);
$("#loading-gif-modal").css("visibility", "hidden"); // Hide the loading GIF var dataPath = $(event.target).attr('data-attribute-name');
if ($("[data-initsize]").attr('data-initsize') < char_to_display) { // All the content is displayed $.get("{{ url_for('importantPasteByModule') }}"+"?moduleName="+dataPath, function(data, status){
nothing_to_display(); var currentTab = $('[name].active').children();
} $('#'+previous_tab.attr('data-attribute-name')+'-tab').html("");
// On click, donwload all paste's content currentTab.removeClass( "active" );
$("#load-more-button").on("click", function (event) {
if (complete_paste == null) { //Donwload only once
$.get("{{ url_for('getmoredata') }}"+"?paste="+$(modal).attr('data-path'), function(data, status){
complete_paste = data;
update_preview();
});
} else {
update_preview();
}
});
});
});
// When the modal goes out, refresh it to normal content $('#'+dataPath+'-tab').html(data);
$("#mymodal").on('hidden.bs.modal', function () {
$("#mymodalbody").html("<p>Loading paste information...</p>"); $(event.target).parent().addClass( "active" );
var loading_gif = "<img id='loading-gif-modal' class='img-center' src=\"{{url_for('static', filename='image/loading.gif') }}\" height='26' width='26' style='margin: 4px;'>"; previous_tab = currentTab;
$("#mymodalbody").append(loading_gif); // Show the loading GIF
$("#button_show_path").attr('href', '');
$("#button_show_path").hide();
complete_paste = null;
start_index = 0;
}); });
});
// Update the paste preview in the modal
function update_preview() {
if (start_index + char_to_display > complete_paste.length-1){ // end of paste reached
var final_index = complete_paste.length-1;
var flag_stop = true;
} else {
var final_index = start_index + char_to_display;
}
if (final_index != start_index){ // still have data to display
$("#mymodalbody").find("#paste-holder").text($("#mymodalbody").find("#paste-holder").text()+complete_paste.substring(start_index+1, final_index+1)); // Append the new content
start_index = final_index;
if (flag_stop)
nothing_to_display();
} else {
nothing_to_display();
}
}
// Update the modal when there is no more data
function nothing_to_display() {
var new_content = $(alert_message).hide();
$("#mymodalbody").find("#panel-body").append(new_content);
new_content.show('fast');
$("#load-more-button").hide();
}
</script> </script>

View file

@ -0,0 +1,112 @@
<table class="table table-striped table-bordered table-hover" id="myTable">
<thead>
<tr>
<th>#</th>
<th style="max-width: 800px;">Path</th>
<th>Date</th>
<th># of lines</th>
<th>Action</th>
</tr>
</thead>
<tbody>
{% set i = 0 %}
{% for path in all_path %}
<tr>
<td> {{ i + 1 }}</td>
<td><a target="_blank" href="{{ url_for('showsavedpaste') }}?paste={{path}}&num={{i+1}}">{{ path }}</a></td>
<td>{{ paste_date[i] }}</td>
<td>{{ paste_linenum[i] }}</td>
<td><p><span class="glyphicon glyphicon-info-sign" data-toggle="tooltip" data-placement="left" title="{{ content[i] }} "></span> <button type="button" class="btn-link" data-num="{{ i + 1 }}" data-toggle="modal" data-target="#mymodal" data-url="{{ url_for('showsavedpaste') }}?paste={{ path }}&num={{ i+1 }}" data-path="{{ path }}"><span class="fa fa-search-plus"></span></button></p></td>
</tr>
{% set i = i + 1 %}
{% endfor %}
</tbody>
</table>
</br>
</br>
<script>
$(document).ready(function(){
$('[data-toggle="tooltip"]').tooltip();
$('#myTable').dataTable();
});
</script>
<!-- Dynamically update the modal -->
<script type="text/javascript">
// static data
var alert_message = '<div class="alert alert-info alert-dismissable"><button type="button" class="close" data-dismiss="alert" aria-hidden="true">×</button><strong>No more data.</strong> Full paste displayed.</div>';
var complete_paste = null;
var char_to_display = {{ char_to_display }};
var start_index = 0;
// On click, get html content from url and update the corresponding modal
$("[data-toggle='modal']").on("click", function (event) {
console.log('hi');
event.preventDefault();
var modal=$(this);
var url = " {{ url_for('showpreviewpaste') }}?paste=" + $(this).attr('data-path') + "&num=" + $(this).attr('data-num');
$.get(url, function (data) {
$("#mymodalbody").html(data);
var button = $('<button type="button" id="load-more-button" class="btn btn-info btn-xs center-block" data-url="' + $(modal).attr('data-path') +'" data-toggle="tooltip" data-placement="bottom" title="Load more content"><span class="glyphicon glyphicon-download"></span></button>');
button.tooltip();
$("#mymodalbody").children(".panel-default").append(button);
$("#button_show_path").attr('href', $(modal).attr('data-url'));
$("#button_show_path").show('fast');
$("#loading-gif-modal").css("visibility", "hidden"); // Hide the loading GIF
if ($("[data-initsize]").attr('data-initsize') < char_to_display) { // All the content is displayed
nothing_to_display();
}
// On click, donwload all paste's content
$("#load-more-button").on("click", function (event) {
if (complete_paste == null) { //Donwload only once
$.get("{{ url_for('getmoredata') }}"+"?paste="+$(modal).attr('data-path'), function(data, status){
complete_paste = data;
update_preview();
});
} else {
update_preview();
}
});
});
});
// When the modal goes out, refresh it to normal content
$("#mymodal").on('hidden.bs.modal', function () {
$("#mymodalbody").html("<p>Loading paste information...</p>");
var loading_gif = "<img id='loading-gif-modal' class='img-center' src=\"{{url_for('static', filename='image/loading.gif') }}\" height='26' width='26' style='margin: 4px;'>";
$("#mymodalbody").append(loading_gif); // Show the loading GIF
$("#button_show_path").attr('href', '');
$("#button_show_path").hide();
complete_paste = null;
start_index = 0;
});
// Update the paste preview in the modal
function update_preview() {
if (start_index + char_to_display > complete_paste.length-1){ // end of paste reached
var final_index = complete_paste.length-1;
var flag_stop = true;
} else {
var final_index = start_index + char_to_display;
}
if (final_index != start_index){ // still have data to display
$("#mymodalbody").find("#paste-holder").text($("#mymodalbody").find("#paste-holder").text()+complete_paste.substring(start_index+1, final_index+1)); // Append the new content
start_index = final_index;
if (flag_stop)
nothing_to_display();
} else {
nothing_to_display();
}
}
// Update the modal when there is no more data
function nothing_to_display() {
var new_content = $(alert_message).hide();
$("#mymodalbody").find("#panel-body").append(new_content);
new_content.show('fast');
$("#load-more-button").hide();
}
</script>