I'm making an uploader for my project, and I try to avoid any flash-based solutions (I dont like flash much and target for mobile platforms support).
The whole process seems rather simple: I have a form, nice jQuery progress bar, I can make ajax requests with timeout from a script to update progressbar status...
If I do it according to Webpy cookbook, the only thing I don't get is how to recieve any info from server: how many bytes/chunks/whatever were already written?
You can create ajax uploader using FormData for the modern browsers.
$.fn.uploader = function( options ) {
var defaults = {},
opts = $.extend( defaults, options ),
that = $( this ),
url = that.data( "upload_url" ),
is_uploading = false;
function upload( files ) {
$.get( "/file/blank.html" );
if ( FormData === undefined ) {
alert( "Your browser does not support standard HTML5 Drag and Drop" );
return;
}
var xhr = new XMLHttpRequest(),
new_element = $( "<li><p>Loading</p><span></span></li>" )
.appendTo( that ),
xhr_upload = xhr.upload,
form = new FormData();
xhr_upload.addEventListener( "progress", function( e ) {
if( e.lengthComputable ) {
var p = Math.round( e.loaded * 100 / e.total );
new_element.children( "span" ).text( e.loaded == e.total ? "Processing..." : p + "%" );
}
}, false);
xhr_upload.addEventListener( "load", function( e ){}, false);
xhr_upload.addEventListener( "error", function( error ) { alert( "error: " + error ); }, false);
xhr.open( "POST", url, true );
xhr.setRequestHeader( "X-Requested-With", "XMLHttpRequest" );
xhr.onreadystatechange = function ( e ) {
if ( xhr.readyState == 4 ) {
is_uploading = false;
if( xhr.status == 200 ) {
var data = $.parseJSON( e.target.responseText );
if ( data.status == 0 ) {
new_element
.fadeOut(function (){ $( this ).remove(); })
.children( "span" ).text( "Upload error!" );
} else {
that.html( data.html );
}
} else {
new_element
.fadeOut(function (){ $( this ).remove(); })
.children( "span" ).text( "Upload error!" );
}
}
};
$.each( files, function() {
form.append( "files", this );
});
is_uploading = true;
xhr.send( form );
}
that.bind({
"dragover": function( e ) {
var dt = e.originalEvent.dataTransfer;
if( !dt || is_uploading ) { return; };
if( $.browser.webkit ) { dt.dropEffect = "copy"; };
$( this ).addClass( "active" );
return false;
},
"dragleave": function( e ) {
$( this ).removeClass( "active" );
},
"dragenter": function( e ){ return false; },
"drop": function( e ){
var dt = e.originalEvent.dataTransfer;
$( this ).removeClass( "active" );
if( !dt || !dt.files || is_uploading ) { return; };
upload( dt.files );
return false;
}
});
$( document ).bind({
'dragenter': function( e ) { return false; },
'dragleave': function( e ) { return false; },
'dragover': function( e ) {
var dt = e.originalEvent.dataTransfer;
if ( !dt ) { return; }
dt.dropEffect = "none";
return false;
}
});
};
On the server side I process it like this:
def POST(self):
i = web.webapi.rawinput()
try:
files = i.files
if not isinstance(files, list):
files = [files]
for f in files:
if f.filename:
filetype, encoding = mimetypes.guess_type(f.filename)
# do smth with f.file
except KeyError:
pass
if web.ctx.env.get('HTTP_X_REQUESTED_WITH') == 'XMLHttpRequest':
web.header("Content-Type", "application/json")
return json.dumps(dict(status=1, html=unicode(render_partial.files(uploaded_files))))
else:
raise web.seeother(web.ctx.env.get("HTTP_REFERER", "/"))
Otherwise you may look into nginx upload progress module or apache2 upload progress module, uWSGI has got this feature too.
Related
I am trying to get the dates when available on this datepicker
When availables , the dates are saved in the variable available_dates inside a js script which fills the html input.
HTML of the input :
<input type="text" readonly="" class="form-control-input app_date validate" style="width: 260px;" id="app_date" name="app_date" placeholder="YYYY-MM-DD" onchange="this.form.submit();showLoader();" value="" autocomplete="off">
How can i retrieve the values from available_dates when the dates are availables, get them to my python script to select one of them.
The following python script didn't work :
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
from selenium.common.exceptions import TimeoutException
driver.find_element(By.XPATH, "//*[#id='app_date']").click()
time.sleep(3)
try:
print([date.get_attribute("innerHTML") for date in WebDriverWait(driver, 20).until(EC.visibility_of_all_elements_located((By.XPATH, "//div[#class='datepicker-days']/table[#class=' table-condensed']//tr//td[#class='day activeClass' and #title='Book']")))])
except TimeoutException:
print("No booking dates available for the current month")
driver.refresh()
JS script :
<script type="text/javascript" xpath="1">
var today = new Date();
var dd = today.getDate()+1;
var mm = today.getMonth()+1; //January is 0!
var yyyy = today.getFullYear();
if(dd<10){
dd='0'+dd
}
if(mm<10){
mm='0'+mm
}
var today = yyyy+'-'+mm+'-'+dd;
function formatDate(rawDate) {
var day = ("0" + rawDate.getDate()).slice(-2);
var month = ("0" + (rawDate.getMonth() + 1)).slice(-2);
return (day)+ "-" + (month)+ "-" +rawDate.getFullYear() ;
}
$(document).ready(function() {
var dt1 = '2023-02-14';
var checkService = 'Normal';
$('.date_of_birth').datepicker({
format: "yyyy-mm-dd",
endDate: new Date(dt1),
startDate: '-100y',
autoclose: true,
startView: 2
});
$('.pptIssueDate').datepicker({
format: "yyyy-mm-dd",
endDate: new Date(dt1),
startDate: '-100y',
autoclose: true,
startView: 2
});
$('.passport_validate_till').datepicker({
format: "yyyy-mm-dd",
startDate: new Date(dt1),
autoclose: true,
startView: 2
});
var dt4 = '2023-02-15';
var blocked_dates = ["01-01-2023","02-01-2023","06-01-2023","13-01-2023","20-01-2023","27-01-2023","03-02-2023","10-02-2023","17-02-2023","24-02-2023","01-01-2023","02-01-2023","06-01-2023","13-01-2023","20-01-2023","27-01-2023","03-02-2023","10-02-2023","17-02-2023","24-02-2023"];
var available_dates = [];
var fullCapicity_dates = ["15-02-2023","16-02-2023","20-02-2023","21-02-2023","22-02-2023","23-02-2023","27-02-2023","28-02-2023"];
var offDates_dates = ["17-02-2023","18-02-2023","19-02-2023","24-02-2023","25-02-2023","26-02-2023"];
var allowArray = [1,2];
if(checkService == 'Normal')
{
/*if((jQuery.inArray(2, allowArray)!='-1') || (jQuery.inArray(3, allowArray)!='-1') || (jQuery.inArray(4, allowArray)!='-1'))
{
var classFull = 'fullcapspecial';
var tooltipTitle = ' ';
var backDatetitle = 'Not Allowed';
}else{
var classFull = 'fullcap';
var tooltipTitle = 'Slots Full';
var backDatetitle = 'Not Allowed';
}*/
var classFull = 'fullcap';
var tooltipTitle = 'Slots Full';
var backDatetitle = 'Not Allowed';
}else{
var classFull = 'fullcap';
var tooltipTitle = 'Slots Full';
var backDatetitle = 'Not Allowed';
}
$('.app_date').datepicker({
language: "en",
Default: true,
format: "yyyy-mm-dd",
startDate: new Date(dt4),
endDate: '2023-02-28',
autoclose: true,
forceParse:true,
startView: 0,
beforeShowDay: function(date){
var formattedDate = formatDate(date);
if ($.inArray(formattedDate.toString(), blocked_dates) != -1){
return {
enabled : false,
classes: 'inactiveClass',
tooltip: 'Holiday'
};
}
if ($.inArray(formattedDate.toString(), available_dates) != -1){
return {
enabled : true,
classes: 'activeClass',
tooltip: 'Book'
};
}
if ($.inArray(formattedDate.toString(), fullCapicity_dates) != -1){
return {
enabled : false,
classes: classFull,
tooltip: tooltipTitle
};
}
if ($.inArray(formattedDate.toString(), offDates_dates) != -1){
return {
enabled : false,
classes: 'offday',
tooltip: 'Off Day'
};
}
return {
enabled : false,
tooltip: backDatetitle
};
return;
}
});
/*====== CALL POP FOR PL/PT IN NORMAL CASE=======*/
if(checkService == 'Normal')
{
if((jQuery.inArray(2, allowArray)!='-1') || (jQuery.inArray(3, allowArray)!='-1') || (jQuery.inArray(4, allowArray)!='-1'))
{
/*$(document).on('click', '.fullcap,.fullcapspecial', function () {
$(".datepicker").hide();
$('.popupBG').show();
$('#IDBodyPanel').show();
});
$(".popupCloseIcon").click(function() {
$(".popupBG").hide();
$("#IDBodyPanel").hide();
});*/
/*$('input[type=radio][name=serviceChange]').change(function() {
if (this.value == 'Premium') {
$("#premiumService").prop('value', 'GO FOR PREMIUM');
}
else if (this.value == 'Prime') {
$("#premiumService").prop('value', 'GO FOR PRIME TIME');
}
});*/
}
}
/*====== CALL POP FOR PL/PT IN NORMAL CASE=======*/
var eventhandler = function(e) {
e.preventDefault();
}
if (checkService == 'Premium' || checkService == 'Prime' || checkService == 'Premium-Saturday') {
$('input[name="vasId[]"]:checked').each(function() {
$("#vasId"+this.value).bind('click', eventhandler);
});
}
if (checkService != 'Premium')
{
$(document).on('click', '.chkbox', function () {
if($(this).val() == 1)
{
if($(this).is(":checked")){
//$("#vasId6").prop('checked', true);
//$("#vasId6").bind('click', eventhandler);
}else{
//$("#vasId6").prop('checked', false);
//$("#vasId6").unbind('click', eventhandler);
}
}
});
}
});
</script>
Solved
ive been trying to login with the following code in a chinese monitoring system that uses js forms.
i assume i cannot log in because the payload is encrypted with a public key and posted to a randomly generated URL.
import sys, re, requests
class GMU:
def __init__(self):
payload = {'inputAccount': 'admin','inputPassword': 'admin'}
s = requests.Session()
p = s.post('http://10.40.100.146/',data=payload)
self.p = p
r = s.get('http://10.40.100.146/ActiveSignal/ActiveSignalPartial?equipmentId=300001003')
data = str(r.content)
self.data = data
def ask():
return GMU()
n = ask()
print(n.p)
print(n.data)
Here is a post header
Payload
Initiator
looking in the initatior section "send" i found loginname.js with the following code:
var publicKey = "-----BEGIN PUBLIC KEY-----MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC6MqYui/VMzy0qQE2c6S24fNbph7Hr/Nh29aJJ0kWjINV3zPgJXZrmJp43PaQBxHkq3cESuSf9zUCBS0wZtvFL8LTU1Iehnh/rPVKfGHQaHoD928n7CXuGwnEsyl63p6wwgIjiENVTMaReCJz79N2fhXFK99cA1/B7JXRtCPr/pwIDAQAB-----END PUBLIC KEY-----";
var clientMenuTemplateType = 4;
function logout() {
BootstrapDialog.show({
title: lang["Exit the confirmation"],
message: lang["Quit or not?"],
cssClass: 'user-dialog',
buttons: [{
label: lang["Confirm"],
cssClass: 'btn blue btn-outline dropdown-toggle',
action: function () {
//执行操作
location.href = '.././Account/Logout';
}
}, {
label: lang["Cancel"],
action: function (dialog) {
dialog.close();
}
}]
});
}
$("#loginBtn").click(function () {
Login();
});
$('#inputPassword').bind('keyup', function (event) {
if (event.keyCode == "13") {
//回车执行
Login();
}
});
$('#inputAccount').bind('keyup', function (event) {
if (event.keyCode == "13") {
//回车执行
Login();
}
});
$('#loginBtn').bind('keyup', function (event) {
if (event.keyCode == "13") {
//回车执行
Login();
}
});
var flag = 0;
$("#pswdVisual").click(function () {
var input = document.getElementById('inputPassword');
if (flag == 0) {
input.type = 'text';
$("#pswdVisual").addClass("glyphicon-eye-open");
$("#pswdVisual").removeClass("glyphicon-eye-close");
flag = 1;
} else {
input.type = 'password';
$("#pswdVisual").addClass("glyphicon-eye-close");
$("#pswdVisual").removeClass("glyphicon-eye-open");
flag = 0;
}
});
function Login() {
var options = {
positionClass: 'toast-bottom-right'
}
var account = $('#inputAccount').val();
var password = $('#inputPassword').val();
if (!account || account == null || account === "") {
toastr.error(lang["Username cannot be empty!"], lang["login failure"], options);
} else if (!password || password == null || password === "") {
toastr.error(lang["Password cannot be empty!"], lang["login failure"], options);
} else {
var data = account + "&" + password;
//RSA Encrypt
var jsEncrypt = new JSEncrypt();
jsEncrypt.setPublicKey(publicKey);
var key = jsEncrypt.encrypt(data);
$.ajax({
type: "post",
url: currentUrl + "Account/LoginAction/?t=" + Math.random(),
data: {
encryptContext: key
},
dataType: "json",
success: function (response) {
if (response != null) {
if (response.url !== "") {
cookieObject.setCookie("userName", account);
if (response.url.indexOf("Default/Default?ZT=") !== -1) {
location.href = currentUrl + "Default/Default#ZT=" + response.url.replace("Default/Default?ZT=", "");
} else {
location.href = currentUrl + "Default/Default#Page=" + response.url;
}
}
else if (response.error !== "")
console.log(response.error);
else if (response.show !== "") {
if (response.show == lang["The user name does not exist"]) {
toastr.error("", lang["login failure"], options);
} else {
toastr.error(response.show, lang["login failure"], options);
}
}
}
},
error: function () {
}
});
}
};
i dont know if should be passing the rsa encrypted payload or there is some way to just provide the user and password and let the js thing generate itself.
I am calling ajax request from frontend to export data in excel sheet.
js
function exportData(){
create_spinner("Please wait while we export data.");
var agent = $("#agent").val()
var dateRange = $("#dateRangeValue").val()
var queue = $("#queue").val()
var direction = $("#direction").val()
var department = $("#department").val()
var serviceLevel = $("#sl").val()
$.ajax({
type: 'POST',
url: "/call-record-api/export-data/",
data: {
"agent": agent,
"dateRange": dateRange,
"queue": queue,
"direction": direction,
"department": department,
"serviceLevel": serviceLevel,
},
success: function(resultData) {
console.log("success");
hide_spinner();
},
error: function (err) {
console.log("AJAX error in request: " + JSON.stringify(err, null, 2));
create_spinner("Couldn't export data. Please try again");
setTimeout(function(){ hide_spinner()}, 1000);
}
});
}
I have gone through documentation and implemented the same.
urls.py
url(r'^call-record-api/export-data/$', ExportCallRecordView.as_view({"post":"list"})),
views.py
class ExportCallRecordView(XLSXFileMixin, ReadOnlyModelViewSet):
def get_queryset(self):
calls = export_customized_calls(self.request)
print(calls.count())
return calls
serializer_class = CallRecordSerializer
renderer_classes = [XLSXRenderer]
filename = 'call_record_export.xlsx'
But i cannot see the file getting downloaded. However i can see success in browser console and 235 as call count in server console.
You can't download files directly with ajax. You have to use tricks like this (taken from a github repo):
// jQuery ajax
$.ajax({
type: "POST",
url: url,
data: params,
success: function(response, status, xhr) {
// check for a filename
var filename = "";
var disposition = xhr.getResponseHeader('Content-Disposition');
if (disposition && disposition.indexOf('attachment') !== -1) {
var filenameRegex = /filename[^;=\n]*=((['"]).*?\2|[^;\n]*)/;
var matches = filenameRegex.exec(disposition);
if (matches != null && matches[1]) filename = matches[1].replace(/['"]/g, '');
}
var type = xhr.getResponseHeader('Content-Type');
var blob = new Blob([response], { type: type });
if (typeof window.navigator.msSaveBlob !== 'undefined') {
// IE workaround for "HTML7007: One or more blob URLs were revoked by closing the blob for which they were created. These URLs will no longer resolve as the data backing the URL has been freed."
window.navigator.msSaveBlob(blob, filename);
} else {
var URL = window.URL || window.webkitURL;
var downloadUrl = URL.createObjectURL(blob);
if (filename) {
// use HTML5 a[download] attribute to specify filename
var a = document.createElement("a");
// safari doesn't support this yet
if (typeof a.download === 'undefined') {
window.location = downloadUrl;
} else {
a.href = downloadUrl;
a.download = filename;
document.body.appendChild(a);
a.click();
}
} else {
window.location = downloadUrl;
}
setTimeout(function () { URL.revokeObjectURL(downloadUrl); }, 100); // cleanup
}
}
});
Or if you don't mind converting your POST request in to GET request:
window.location = `/<download_url>/?param1=${encodeURIComponent(param1)}`
I want to redirect and pass some data to other page.But not using query string and not pass data in URL
(function() {
var app = angular.module('PlateformApp', [])
app.controller('PlateformController', function ($scope,$window) {
//This will hide the DIV by default.
$scope.IsVisible = false;
$scope.ShowHide = function (platform) {
//If DIV is visible it will be hidden and vice versa.
$scope.IsVisible = $scope.IsVisible ? true : true;
//alert(platform);
document.getElementById("platform").value = platform;
var myEl = angular.element( document.querySelector( '#plat_val' ) );
myEl.text(platform);
}
$scope.storeAppWindow = function()
{
//store_url = $scope.storeUrl;
test_bc_url = ""
text_sh_url = ""
platform_val = document.getElementById("platform").value;
$http.get("/user/installedapp")
.then(function(response) {
$scope.myWelcome = response.data;
});
if (platform_val == "BC")
$window.open(test_bc_url, "popup", "width=500,height=400,left=10,top=50");
else if (platform_val == "Sh")
$window.open(text_sh_url, "popup", "width=500,height=400,left=10,top=50");
}
});
})();
Here It will open new window but i want to pass platform_val text_sh_url url in another page.And i am using flask in python.
You can pass the data by various methods, using $stateParams,using Storages, using factories or services. You can find the example using storage in my answer in this thread: sharing data using storages
(function() {
var app = angular.module('PlateformApp', [])
app.factory('newService', function() {
function set(data) {
datatosend = data;
}
function get() {
return datatosend;
}
return {
set: set,
get: get
}
});
app.controller('PlateformController', function($scope, $window, newService) {
//This will hide the DIV by default.
$scope.IsVisible = false;
$scope.ShowHide = function(platform) {
//If DIV is visible it will be hidden and vice versa.
$scope.IsVisible = $scope.IsVisible ? true : true;
//alert(platform);
document.getElementById("platform").value = platform;
var myEl = angular.element(document.querySelector('#plat_val'));
myEl.text(platform);
}
$scope.storeAppWindow = function()
{
//store_url = $scope.storeUrl;
test_bc_url = ""
text_sh_url = ""
platform_val = document.getElementById("platform").value;
$http.get("/user/installedapp")
.then(function(response) {
$scope.myWelcome = response.data;
});
if (platform_val == "BC") {
$window.open(test_bc_url, "popup", "width=500,height=400,left=10,top=50");
}
else if (platform_val == "Sh") {
var data = {
'platform_val': platform_val,
'text_sh_url ': text_sh_url
};
newService.set(data);
$window.open(text_sh_url, "popup", "width=500,height=400,left=10,top=50");
}
}
});
})();
And,in the page where you want to get the data. Just inject newService in the controller of that page and use newService.get(data)
app.controller('pageController',function($scope,newService){
var datafromanothercontroller = newService.get(data);
console.log(datafromanothercontroller );
})
Im not very good with python, but for this project I need to use a python GUI to test my program. Its compiling without any errors, but its giving errors when I go to test it in the GUI. The objective of the program is to create a English to French dictionary from a .txt file that has all the translations/definitions. My code is as follows. If anyone could help, that would be great.
These are the errors I am getting:
Exception in Tkinter callback
Traceback (most recent call last):
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/lib-tk/Tkinter.py", line 1470, in __call__
return self.func(*args)
File "Dictionary.py", line 33, in <lambda>
lambda e, s=self: s.translate(english, french))
File "Dictionary.py", line 69, in translate
clearall(english, french)
NameError: global name 'clearall' is not defined
For further information, I'm supposed to check these conditions:
1)no command line arguments and 2) unsuccessful file openings.
Dictionary.cpp:
#include "HashTable.h"
#include "DictionaryEntry.h"
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
int main( int argc, char** argv )
{
HashTable <DictionaryEntry> table;
DictionaryEntry dictEntry;
string temp;
string entry;
string translation;
vector <string> engWords;
string uentry;
int randNum;
ifstream inputStream;
//If command line is empty, error
if( argc <= 1)
{
cout << "Invalid entry." << endl;
return 0;
}
inputStream.open(argv[1]);
//If no file is opened, error
/*if( !inputStream )
{
cout << "Invalid file." << endl;
return 0;
}*/
while( !inputStream.eof( ) )
{
getline( inputStream, temp );
unsigned location = temp.find_first_of( '\t' );
entry = temp.substr( 0, location );
int end = temp.length( );
translation = temp.substr( location + 1, end );
dictEntry.set( entry, translation );
table.insert( dictEntry );
engWords.push_back( entry );
}
while( 1 )
{
cout << "Insert english word: ";
cin >> uentry;
DictionaryEntry search;
search.set( uentry, "");
if( uentry == "random" )
{
randNum = rand( ) % engWords.size( );
temp = engWords.at( randNum );
search.set( temp, "" );
dictEntry = table.retrieve( search );
cout << dictEntry.getEntry( ) << endl;
cout << dictEntry.getTranslation( ) << endl;
}
else
{
dictEntry = table.retrieve( search );
if( dictEntry.getEntry( ) != "" )
{
cout << dictEntry.getEntry( ) << endl;
cout << dictEntry.getTranslation( ) << endl;
}
else
{
cout << "\n";
cout << "\n";
}
}
}
}
List.h:
#ifndef LIST_H
#define LIST_H
using namespace std;
template <typename Object>
class List
{
private:
struct Node
{
Object data;
Node *prev;
Node *next;
Node(const Object & d = Object{ }, Node * p = nullptr, Node * n = nullptr )
: data{ d }, prev{ p }, next{ n } { }
Node( Object && d, Node * p = nullptr, Node * n = nullptr )
: data{ std::move( d ) }, prev{ p }, next{ n } { }
};
public:
class const_iterator
{
public:
const_iterator( ) : current{ nullptr }
{ }
const Object & operator* ( ) const
{ return retrieve( ); }
const_iterator & operator++ ( )
{
current = current->next;
return *this;
}
const_iterator operator++ (int)
{
const_iterator old = *this;
++( *this );
return old;
}
bool operator== (const const_iterator & rhs ) const
{ return current == rhs.current; }
bool operator!= ( const const_iterator & rhs ) const
{ return !( *this == rhs ); }
protected:
Node *current;
Object & retrieve( ) const
{return current->data;}
const_iterator(Node *p ) : current{ p }
{ }
friend class List<Object>;
};
class iterator : public const_iterator
{
public:
iterator( )
{ }
Object & operator* ( )
{ return const_iterator::retrieve( ); }
const Object & operator* ( ) const
{ return const_iterator::operator*( ); }
iterator & operator++ ( )
{
this->current = this->current->next;
return *this;
}
iterator operator++ ( int )
{
iterator old = *this;
++( *this );
return old;
}
iterator operator--()
{
const_iterator::current = const_iterator::current->prev;
return *this;
}
iterator operator--(int)
{
iterator old = *this;
--(*this);
return old;
}
protected:
iterator( Node *p ) : const_iterator{ p }
{ }
friend class List<Object>;
};
public:
List( )
{ init( ); }
~List( )
{
clear( );
delete head;
delete tail;
}
List( const List & rhs )
{
init( );
for( auto & x : rhs )
push_back( x );
}
List & operator= ( const List & rhs )
{
List copy = rhs;
std::swap( *this, copy );
return *this;
}
List ( List && rhs )
: theSize{ rhs.theSize }, head{rhs.head }, tail{rhs.tail }
{
rhs.theSize = 0;
rhs.head = nullptr;
rhs.tail = nullptr;
}
List & operator= ( List && rhs )
{
std::swap( theSize, rhs.theSize );
std::swap( head, rhs.head );
std::swap( tail, rhs.tail );
return *this;
}
iterator begin( )
{ return { head->next }; }
const_iterator begin( ) const
{ return { head->next }; }
iterator end( )
{ return { tail }; }
const_iterator end( ) const
{ return { tail }; }
int size( ) const
{ return theSize; }
bool empty( ) const
{ return size( ) == 0; }
void clear( )
{
while( !empty( ) )
pop_front( );
}
Object & front( )
{ return *begin( ); }
const Object & front( ) const
{ return *begin( ); }
Object & back( )
{ return *--end( ); }
const Object & back( ) const
{ return *--end( ); }
void push_front( const Object & x )
{ insert( begin( ), x ); }
void push_front( Object && x )
{ insert( begin( ), std::move( x ) ); }
void push_back( const Object & x )
{ insert( end( ), x ); }
void push_back( Object && x )
{ insert( end( ), std::move( x ) ); }
void pop_front( )
{ erase( begin( ) ); }
void pop_back( )
{ erase( --end( ) ); }
//Insert x before itr
iterator insert( iterator itr, const Object & x )
{
Node *p = itr.current;
theSize++;
return { p->prev = p->prev->next = new Node{ x, p->prev, p } };
}
//Insert x before itr
iterator insert( iterator itr, Object && x )
{
Node *p = itr.current;
theSize++;
return { p->prev = p->prev->next = new Node{ std::move( x ), p->prev, p } };
}
//Erase item at itr
iterator erase( iterator itr )
{
Node *p = itr.current;
iterator retVal{ p->next };
p->prev->next = p->next;
p->next->prev = p->prev;
delete p;
theSize--;
return retVal;
}
iterator erase( iterator from, iterator to )
{
for( iterator itr = from; itr != to; )
itr.erase( itr );
return to;
}
iterator find( const Object & x )
{
iterator start= begin();
while(start!=end()){
if(x==*start)
return start;
start++;
}
return start;
}
/*
iterator find( string & x )
{
iterator start = begin();
while( start != end( ) ) {
if( strcasecmp( x.c_str( ),( *start ).getWord( ).c_str( ) )==0 )
return start;
else
start++;
}
return start;
}
*/
const_iterator find(const Object & x) const
{
const_iterator start=begin();
while(start!=end()){
if(x==*start)
return start;
start++;
}
return start;
}
/*
const_iterator find(const string & x){
const_iterator start = const_iterator(head);
while( start != end()){
if(strcasecmp(x.c_str(),(*start).getWord().c_str())==0)
return start;
else
start++;
}
return start;
}
*/
private:
int theSize;
Node *head;
Node *tail;
void init( )
{
theSize = 0;
head = new Node;
tail = new Node;
head->next = tail;
tail->prev = head;
}
};
#endif
HashTable.h:
#ifndef HASHTABLE_H
#define HASHTABLE_H
#include <vector>
#include <string>
#include "List.h"
#include "DictionaryEntry.h"
using namespace std;
//checks if a value is prime
bool isPrime(int n){
if( n==2 || n==3)
return true;
if( n==1 || n%2 == 0)
return false;
for(int i=3; i*i<n; i+=2)
if(n%i == 0)
return false;
return true;
}
//finds the next prime number
int nextPrime (int n) {
if( n%2==0)
n++;
while( !isPrime(n))
n+=2;
return n;
}
template <typename HashedObj>
class HashTable
{
public:
//constructor (explicit so no implicit conversion)
explicit HashTable( int size = 3500) : tableSize(size), currentSize(size), theLists(size) { }
//empty the Hashtable
void makeEmpty( )
{
currentSize=0;
//clear each linked list from hastable
for(int i=0; i<tableSize; i++)
theLists[i].clear( );
}
//search for x in Hashtable
bool contains( const HashedObj & x ) const{
//assign reference variable to rename the complicated object
const List<HashedObj> & whichList = theLists[ myhash( x ) ];
//return whether x already exists in the list
return whichList.find( x ) != whichList.end( );
}
//insert x into Hashtable (true if successful, false if already exists)
bool insert( const HashedObj & x ) {
//assign reference variable to rename the complicated object
List<HashedObj> & whichList = theLists[ myhash( x ) ];
//if x already exists in the list, return false
if( whichList.find( x ) != whichList.end() )
return false;
//otherwise push to list
whichList.push_front( x );
//rehash if new size is greater than hashtable size
if( ++currentSize >tableSize ) {
rehash( );
}
return true;
}
//remove x from Hashtable (true if successful, false if not found)
bool remove( const HashedObj & x ) {
//assign reference variable to rename the complicated object
List<HashedObj> & whichList = theLists[ myhash( x ) ];
//iterator is at end of list (i.e., not found)
if( whichList.find(x) == whichList.end() )
return false;
//erase x
whichList.erase( whichList.find (x) );
--currentSize;
return true;
}
HashedObj & retrieve( HashedObj & obj)
{
return *(theLists[myhash(obj)].find(obj));
}
private:
//The vector of linked-lists hashtable
vector<List<HashedObj> > theLists;
int currentSize;
int tableSize;
//Because coming with new stuff is hard <--Haha
void rehash( ){
vector<List<HashedObj> > oldLists=theLists;
int oldtableSize = tableSize;
tableSize = nextPrime( 2* oldtableSize );
//Create new double-sized, empty table
theLists.resize( tableSize );
for( int i=0; i<tableSize; i++ )
theLists[i].clear();
//copy table over
currentSize = 0;
for( int i=0; i<oldtableSize; i++ ){
while( !oldLists[i].empty() ){
insert( oldLists[i].front() );
oldLists[i].pop_front();
}
}
}
//call hash function and makes sure values fit in table
int myhash( const HashedObj & x ) const
{
int hashVal = hash2(x); //call hash function
//make sure the hash values fit into HashTable
hashVal %= tableSize;
if( hashVal < 0 )
{
hashVal += tableSize;
}
return hashVal;
}
/*
int myhash( const string & x ) const
{
int hashVal = hash( x );
hashVal %= tableSize;
if( hashVal < 0 )
{
hashVal += tableSize;
}
return hashVal;
}
*/
};
int hash2( const string & key )
{
int hashVal = 0;
for( int i = 0; i < key.length( ); i++ )
{
hashVal = 37 * hashVal + key[i];
}
return hashVal;
}
int hash2( const DictionaryEntry word )
{
return hash2(word.getEntry());
}
int hash2(int key)
{
return key;
}
#endif
DictionaryEntry.h:
#ifndef DICTIONARYENTRY_H
#define DICTIONARYENTRY_H
#include <string>
#include <iostream>
#include "HashTable.h"
using namespace std;
class DictionaryEntry
{
public:
DictionaryEntry( )
{
entry = "";
translation = "";
}
DictionaryEntry( const DictionaryEntry & rhs )
{
entry = rhs.entry;
translation = rhs.translation;
}
void set( string ent, string trans )
{
entry = ent;
translation = trans;
}
const string & getTranslation( ) const
{
return translation;
}
const string & getEntry( ) const
{
return entry;
}
bool operator== ( const DictionaryEntry & rhs ) const
{
return getEntry( ) == rhs.getEntry( );
}
bool operator!= ( const DictionaryEntry & rhs ) const
{
return (getEntry() != rhs.getEntry() );
}
private:
string entry;
string translation;
};
#endif
and Dictionary.py:
#!/usr/bin/python
from Tkinter import *
import subprocess
# general function for frame generation
def frame(root, side):
w = Frame(root)
w.pack(side=side, expand=YES, fill=BOTH)
return w
# general function for button generation
def button(root, side, text, command=None):
w = Button(root, text=text, command=command)
w.pack(side=side, expand=YES, fill=BOTH)
return w
# main class for GUI
class Translator(Frame):
def __init__(self):
Frame.__init__(self)
self.pack(expand=YES, fill=BOTH)
self.master.title("English-French Translator")
self.master.iconname("English-French Translator")
Label(self, text='English').pack(side=TOP, expand=YES, fill=BOTH)
english = StringVar()
Entry(self, relief=SUNKEN, textvariable=english).pack(side=TOP, expand=YES, fill=BOTH)
buttonsF = frame(self, TOP)
btn = button(buttonsF, LEFT, 'Translate')
btn.bind('<ButtonRelease-1>',
lambda e, s=self: s.translate(english, french))
clearF = frame(self, TOP)
btn = button(buttonsF, LEFT, 'Clear')
btn.bind('<ButtonRelease-1>',
lambda e, s=self: s.clearall(english, french))
randF = frame(self, TOP)
btn = button(buttonsF, LEFT, 'Flash Me (TM)')
btn.bind('<ButtonRelease-1>',
lambda e, s=self: s.random(english, french))
Label(self, text='French').pack(side=TOP, expand=YES, fill=BOTH)
french = StringVar()
Message(self, relief=SUNKEN, textvariable=french, width=200).pack(side=TOP, expand=YES, fill=BOTH)
# clear all text boxes
def clearall(self, english, french):
english.set('')
french.set('')
# translate english to french
def translate(self, english, french):
if (len(english.get()) > 0):
try:
# send english word to subprocess
process.stdin.write('%s\n'%english.get())
# read line of output from subprocess (original text)
original=process.stdout.readline()
# read line of output from subprocess (translated text)
translation=process.stdout.readline()
# set english textbox
english.set(original.rstrip())
# set french textbox
french.set(translation.rstrip())
except:
clearall(english, french)
def random(self, english, french):
try:
process.stdin.write('random\n')
original=process.stdout.readline()
translation=process.stdout.readline()
english.set(original.rstrip())
french.set(translation.rstrip())
except:
clearall(english, french)
if __name__ == '__main__':
args='French.txt'
process=subprocess.Popen('Dictionary %s'%args, shell=True,
stdin=subprocess.PIPE,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
Translator().mainloop()
The error message is telling you exactly what's wrong: "global name 'clearall' is not defined". You have to ask yourself, 'why does python think it's not defined?" In this case, the clue is that it thinks clearall is a global function. Why? Because that's how you are using it.
In looking at your code, it appears you have a "clearall" method as part of an object, so likely all you need to do is change clearall(...) to self.clearall(...) everywhere you call clearall.