modified create dialog to display torrent infos detected from files
This commit is contained in:
		
							
								
								
									
										22
									
								
								indexer.py
									
									
									
									
									
								
							
							
						
						
									
										22
									
								
								indexer.py
									
									
									
									
									
								
							@@ -43,8 +43,7 @@ def init():
 | 
				
			|||||||
def initDb():
 | 
					def initDb():
 | 
				
			||||||
	connection = sqlite3.connect("torrentdb.sqlite")
 | 
						connection = sqlite3.connect("torrentdb.sqlite")
 | 
				
			||||||
	c = connection.cursor()
 | 
						c = connection.cursor()
 | 
				
			||||||
	c.execute('CREATE TABLE IF NOT EXISTS torrents (fileid TEXT PRIMARY KEY NOT NULL, name TEXT NOT NULL, category TEXT NOT NULL, subcategory TEXT NOT NULL, description TEXT NOT NULL);')
 | 
						c.execute('CREATE TABLE IF NOT EXISTS torrents (fileid TEXT PRIMARY KEY NOT NULL, name TEXT NOT NULL, category TEXT NOT NULL, subcategory TEXT NOT NULL, description TEXT NOT NULL, audioquality_description TEXT NOT NULL, videoquality_description TEXT NOT NULL);')
 | 
				
			||||||
	c.execute('CREATE TABLE IF NOT EXISTS language_mapping (fileid TEXT NOT NULL, language TEXT NOT NULL);')
 | 
					 | 
				
			||||||
	connection.commit()
 | 
						connection.commit()
 | 
				
			||||||
	connection.close()
 | 
						connection.close()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -78,8 +77,9 @@ def createNewTorrent(reuqest):
 | 
				
			|||||||
	category = request.form["category"]
 | 
						category = request.form["category"]
 | 
				
			||||||
	subcategory = request.form["subcategory"]
 | 
						subcategory = request.form["subcategory"]
 | 
				
			||||||
	description = request.form["description"]
 | 
						description = request.form["description"]
 | 
				
			||||||
	languages = []
 | 
						audioquality_description = request.form["audioquality_description"]
 | 
				
			||||||
	newTFile = TorrentFile(safeFilename, name, category, subcategory, description, languages)
 | 
						videoquality_description = request.form["videoquality_description"]
 | 
				
			||||||
 | 
						newTFile = TorrentFile(safeFilename, name, category, subcategory, description, audioquality_description, videoquality_description)
 | 
				
			||||||
	connection = sqlite3.connect("torrentdb.sqlite")
 | 
						connection = sqlite3.connect("torrentdb.sqlite")
 | 
				
			||||||
	newTFile.writeToDb(connection.cursor())
 | 
						newTFile.writeToDb(connection.cursor())
 | 
				
			||||||
	connection.commit()
 | 
						connection.commit()
 | 
				
			||||||
@@ -92,21 +92,23 @@ class TorrentFile():
 | 
				
			|||||||
	category = None
 | 
						category = None
 | 
				
			||||||
	subcategory = None
 | 
						subcategory = None
 | 
				
			||||||
	description = None
 | 
						description = None
 | 
				
			||||||
	languages = []
 | 
						audioquality_description = None
 | 
				
			||||||
	def __init__(self, fileid=fileid, name=name, category=category, subcategory=subcategory, description=description, languages=languages):
 | 
						videoquality_description = None
 | 
				
			||||||
 | 
						def __init__(self, fileid=fileid, name=name, category=category, subcategory=subcategory, description=description, audioquality_description=audioquality_description, videoquality_description=videoquality_description):
 | 
				
			||||||
		self.fileid = fileid
 | 
							self.fileid = fileid
 | 
				
			||||||
		self.name = name
 | 
							self.name = name
 | 
				
			||||||
		self.category = category
 | 
							self.category = category
 | 
				
			||||||
		self.subcategory = subcategory
 | 
							self.subcategory = subcategory
 | 
				
			||||||
		self.description = description
 | 
							self.description = description
 | 
				
			||||||
		self.languages = languages
 | 
							self.audioquality_description = audioquality_description
 | 
				
			||||||
 | 
							self.videoquality_description = videoquality_description
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	def writeToDb(self, cursor):
 | 
						def writeToDb(self, cursor):
 | 
				
			||||||
		c = cursor
 | 
							c = cursor
 | 
				
			||||||
		b64description = base64.b64encode(self.description.encode())
 | 
							b64description = base64.b64encode(self.description.encode())
 | 
				
			||||||
		c.execute("INSERT INTO torrents(fileid, name, category, subcategory, description) VALUES(:fileid, :name, :category, :subcategory, :description)", { 'fileid' : self.fileid, 'name' : self.name, 'category' : self.category, 'subcategory' : self.subcategory, 'description' : b64description })
 | 
							b64audioquality_description = base64.b64encode(self.audioquality_description.encode())
 | 
				
			||||||
		for language in self.languages:
 | 
							b64videoquality_description = base64.b64encode(self.videoquality_description.encode())
 | 
				
			||||||
			c.execute("INSERT INTO language_mapping(fileid, language)", { "fileid" : self.fileid, "language" : language })
 | 
							c.execute("INSERT INTO torrents(fileid, name, category, subcategory, description, audioquality_description, videoquality_description) VALUES(:fileid, :name, :category, :subcategory, :description, :audioquality_description, :videoquality_description)", { 'fileid' : self.fileid, 'name' : self.name, 'category' : self.category, 'subcategory' : self.subcategory, 'description' : b64description , 'audioquality_description' : b64audioquality_description, 'videoquality_description' : b64videoquality_description})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
if __name__ == "__main__":
 | 
					if __name__ == "__main__":
 | 
				
			||||||
	init()
 | 
						init()
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -108,6 +108,15 @@ body {
 | 
				
			|||||||
	content: ":";
 | 
						content: ":";
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.detectedFiles {
 | 
				
			||||||
 | 
						max-height: 100px;
 | 
				
			||||||
 | 
						overflow: auto;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.detectedInfos h5,p {
 | 
				
			||||||
 | 
						display: inline;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.row {
 | 
					.row {
 | 
				
			||||||
	margin-bottom: 10px;
 | 
						margin-bottom: 10px;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -2,34 +2,13 @@ window.onload = function () {
 | 
				
			|||||||
	$('.dropdown li > a').click(function(e){
 | 
						$('.dropdown li > a').click(function(e){
 | 
				
			||||||
		setDropdownButtonText(this.innerHTML, this.parentElement.parentElement.parentElement) //set the display-text to the selected value
 | 
							setDropdownButtonText(this.innerHTML, this.parentElement.parentElement.parentElement) //set the display-text to the selected value
 | 
				
			||||||
		fillDropdownByValue(this.innerHTML, $(".dropdown")["1"])
 | 
							fillDropdownByValue(this.innerHTML, $(".dropdown")["1"])
 | 
				
			||||||
 | 
							this.parentElement.parentElement.parentElement.classList.remove("open");
 | 
				
			||||||
 | 
							return false;
 | 
				
			||||||
	});
 | 
						});
 | 
				
			||||||
	
 | 
						
 | 
				
			||||||
	customizeUploadButton()
 | 
						customizeUploadButton()
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
//function fillDropdownByValue(value, dropdownToFill) {
 | 
					 | 
				
			||||||
//	dropdownToFill.getElementsByClassName("text")[0].innerHTML = "Subcategory"
 | 
					 | 
				
			||||||
//	var dropdownToFillUl = dropdownToFill.getElementsByClassName("dropdown-menu")[0]
 | 
					 | 
				
			||||||
//	dropdownToFillUl.innerHTML = ""
 | 
					 | 
				
			||||||
//
 | 
					 | 
				
			||||||
//	subCategory = getDescriptorByLocalString("english", value)
 | 
					 | 
				
			||||||
//	catList = document.getElementById("subcategory_list")
 | 
					 | 
				
			||||||
//	catList.innerHTML = ""
 | 
					 | 
				
			||||||
//	categories = global_categories[subCategory].sort()
 | 
					 | 
				
			||||||
//	for(var key in categories) {
 | 
					 | 
				
			||||||
//		var newEntry = document.createElement("li")
 | 
					 | 
				
			||||||
//		var newEntryLink = document.createElement("a")
 | 
					 | 
				
			||||||
//		newEntry.setAttribute("role", "presentation")
 | 
					 | 
				
			||||||
//		newEntryLink.setAttribute("role", "menuitem")
 | 
					 | 
				
			||||||
//		newEntryLink.tabIndex = -1
 | 
					 | 
				
			||||||
//		newEntryLink.href = "#"
 | 
					 | 
				
			||||||
//		newEntryLink.innerHTML = getLocalString("english", categories[key])
 | 
					 | 
				
			||||||
//		newEntryLink.onclick = function(){ setDropdownButtonText(this.innerHTML, this.parentElement.parentElement.parentElement) }
 | 
					 | 
				
			||||||
//		newEntry.appendChild(newEntryLink)
 | 
					 | 
				
			||||||
//		dropdownToFillUl.appendChild(newEntry)
 | 
					 | 
				
			||||||
//	}
 | 
					 | 
				
			||||||
//}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
function setDropdownButtonText(text, dropdownButton) {
 | 
					function setDropdownButtonText(text, dropdownButton) {
 | 
				
			||||||
	var dropdownTextSpan = dropdownButton.getElementsByClassName("text")[0]
 | 
						var dropdownTextSpan = dropdownButton.getElementsByClassName("text")[0]
 | 
				
			||||||
	dropdownTextSpan.innerHTML = text
 | 
						dropdownTextSpan.innerHTML = text
 | 
				
			||||||
@@ -44,6 +23,40 @@ function sortCategories(categories) {
 | 
				
			|||||||
	return sortedCategories
 | 
						return sortedCategories
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function fillDetectedFilelist(file) {
 | 
				
			||||||
 | 
						var reader = new FileReader();
 | 
				
			||||||
 | 
						fileList = document.querySelectorAll(".detectedFiles ul")[0]
 | 
				
			||||||
 | 
						fileList.innerHTML = ""
 | 
				
			||||||
 | 
						reader.onload = function() {
 | 
				
			||||||
 | 
							b = new bencode()
 | 
				
			||||||
 | 
							torrentObject = b.decode(reader.result)
 | 
				
			||||||
 | 
							for(var fileIndex = 0; fileIndex < torrentObject.info.files.length; fileIndex++){
 | 
				
			||||||
 | 
								newListElement = document.createElement("li")
 | 
				
			||||||
 | 
								newListElement.innerHTML = torrentObject.info.files[fileIndex].path[0]
 | 
				
			||||||
 | 
								fileList.appendChild(newListElement)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							document.querySelectorAll("input.name")[0].value = torrentObject.info.name
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							sizeGroup = document.querySelectorAll(".sizeGroup")[0]
 | 
				
			||||||
 | 
							if(torrentObject.info.pieces.length && torrentObject.info["piece length"]){
 | 
				
			||||||
 | 
								sizeGroup.style.display = ""
 | 
				
			||||||
 | 
								document.querySelectorAll(".detectedSize")[0].innerHTML = ((Math.round((torrentObject.info.pieces.length / 20) * torrentObject.info["piece length"]) / 1024 / 1024 * 100) / 100) + " MB"
 | 
				
			||||||
 | 
							} else {
 | 
				
			||||||
 | 
								sizeGroup.style.display = "none"
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							trackerGroup = document.querySelectorAll(".trackerGroup")[0]
 | 
				
			||||||
 | 
							if(torrentObject.announce){
 | 
				
			||||||
 | 
								trackerGroup.style.display = ""
 | 
				
			||||||
 | 
								document.querySelectorAll(".detectedTracker")[0].innerHTML = torrentObject.announce
 | 
				
			||||||
 | 
							} else {
 | 
				
			||||||
 | 
								trackerGroup.style.display = "none"
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						reader.readAsArrayBuffer(file)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Fill a defined dropdown with values.
 | 
					// Fill a defined dropdown with values.
 | 
				
			||||||
// These values will be generated out of the categories.json
 | 
					// These values will be generated out of the categories.json
 | 
				
			||||||
function fillDropdownByValue(value, dropdownToFill) {
 | 
					function fillDropdownByValue(value, dropdownToFill) {
 | 
				
			||||||
@@ -63,7 +76,11 @@ function fillDropdownByValue(value, dropdownToFill) {
 | 
				
			|||||||
		newEntryLink.tabIndex = -1
 | 
							newEntryLink.tabIndex = -1
 | 
				
			||||||
		newEntryLink.href = "#"
 | 
							newEntryLink.href = "#"
 | 
				
			||||||
		newEntryLink.innerHTML = subcategoryLocalString
 | 
							newEntryLink.innerHTML = subcategoryLocalString
 | 
				
			||||||
		newEntryLink.onclick = function(){ setDropdownButtonText(this.innerHTML, this.parentElement.parentElement.parentElement) }
 | 
							newEntryLink.onclick = function(e){
 | 
				
			||||||
 | 
								setDropdownButtonText(this.innerHTML, this.parentElement.parentElement.parentElement)
 | 
				
			||||||
 | 
								this.parentElement.parentElement.parentElement.classList.remove("open");
 | 
				
			||||||
 | 
								return false;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
		newEntry.appendChild(newEntryLink)
 | 
							newEntry.appendChild(newEntryLink)
 | 
				
			||||||
		dropdownToFillUl.appendChild(newEntry)
 | 
							dropdownToFillUl.appendChild(newEntry)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -85,6 +102,7 @@ function setButtonToFilename(event) {
 | 
				
			|||||||
		targetInput = event["target"]
 | 
							targetInput = event["target"]
 | 
				
			||||||
		button = targetInput.previousSibling.getElementsByClassName("text")[0]
 | 
							button = targetInput.previousSibling.getElementsByClassName("text")[0]
 | 
				
			||||||
		button.innerHTML = chunk(fileName, 40)
 | 
							button.innerHTML = chunk(fileName, 40)
 | 
				
			||||||
 | 
							fillDetectedFilelist(this.files[0])
 | 
				
			||||||
	});
 | 
						});
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -162,3 +180,171 @@ function chunk(string, n) {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
	return ret
 | 
						return ret
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Bencode Library 
 | 
				
			||||||
 | 
					// Copyright 2014 Steven Goodwin
 | 
				
			||||||
 | 
					// Released under the GPL, version 2
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// For format details, please see:
 | 
				
			||||||
 | 
					// http://en.wikipedia.org/wiki/Bencode
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bencode = function() {
 | 
				
			||||||
 | 
						this.STATE_NULL = 0;
 | 
				
			||||||
 | 
						this.STATE_INTEGER = 1;				// i-?[0-9]e
 | 
				
			||||||
 | 
						this.STATE_STRING_LENGTH = 2;		// [0-9]+:\a+
 | 
				
			||||||
 | 
						this.STATE_STRING_CONTENT = 3;		// [0-9]+:\a+
 | 
				
			||||||
 | 
						this.STATE_LIST = 4;				// l<contents>e
 | 
				
			||||||
 | 
						this.STATE_DICTIONARY = 5;			// d<contents>e
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Parse accepts an array of characters to process, and the index of the
 | 
				
			||||||
 | 
					// first character to parse.
 | 
				
			||||||
 | 
					// It returns an object containing the parsed result (in result.o), and the index
 | 
				
			||||||
 | 
					// of the next character to parse in result.idx
 | 
				
			||||||
 | 
					bencode.prototype.parse = function(dataArray, fromIndex) {
 | 
				
			||||||
 | 
						var length = dataArray.byteLength;
 | 
				
			||||||
 | 
						var idx = fromIndex;
 | 
				
			||||||
 | 
						var state = this.STATE_NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// State data
 | 
				
			||||||
 | 
						var current = "";
 | 
				
			||||||
 | 
						var currentObject = null;;
 | 
				
			||||||
 | 
						// String-specific state data
 | 
				
			||||||
 | 
						var stringLength;
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
						while(idx < length) {
 | 
				
			||||||
 | 
							var c = String.fromCharCode(dataArray[idx]) ;
 | 
				
			||||||
 | 
							
 | 
				
			||||||
 | 
							switch(state) {
 | 
				
			||||||
 | 
								case this.STATE_NULL:
 | 
				
			||||||
 | 
										switch(c) {
 | 
				
			||||||
 | 
											case 'i':
 | 
				
			||||||
 | 
													state = this.STATE_INTEGER;
 | 
				
			||||||
 | 
													current = "";
 | 
				
			||||||
 | 
													break;
 | 
				
			||||||
 | 
											case '0':
 | 
				
			||||||
 | 
											case '1':
 | 
				
			||||||
 | 
											case '2':
 | 
				
			||||||
 | 
											case '3':
 | 
				
			||||||
 | 
											case '4':
 | 
				
			||||||
 | 
											case '5':
 | 
				
			||||||
 | 
											case '6':
 | 
				
			||||||
 | 
											case '7':
 | 
				
			||||||
 | 
											case '8':
 | 
				
			||||||
 | 
											case '9':
 | 
				
			||||||
 | 
													state = this.STATE_STRING_LENGTH;
 | 
				
			||||||
 | 
													current = c;
 | 
				
			||||||
 | 
													break;
 | 
				
			||||||
 | 
											case 'l':
 | 
				
			||||||
 | 
													currentObject = new Array();
 | 
				
			||||||
 | 
													state = this.STATE_LIST;
 | 
				
			||||||
 | 
													break;
 | 
				
			||||||
 | 
													
 | 
				
			||||||
 | 
											case 'd':
 | 
				
			||||||
 | 
													currentObject = new Object();
 | 
				
			||||||
 | 
													state = this.STATE_DICTIONARY;
 | 
				
			||||||
 | 
													break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
											default:
 | 
				
			||||||
 | 
													return null;
 | 
				
			||||||
 | 
											}
 | 
				
			||||||
 | 
										//
 | 
				
			||||||
 | 
										++idx;
 | 
				
			||||||
 | 
										break;
 | 
				
			||||||
 | 
										
 | 
				
			||||||
 | 
								case this.STATE_INTEGER:	
 | 
				
			||||||
 | 
										switch(c) {
 | 
				
			||||||
 | 
											case '-':	// we assume that negative numbers start with -
 | 
				
			||||||
 | 
													current = "-";
 | 
				
			||||||
 | 
													break;
 | 
				
			||||||
 | 
											case 'e':
 | 
				
			||||||
 | 
													return { o : current, idx : idx+1 };
 | 
				
			||||||
 | 
											case '0':
 | 
				
			||||||
 | 
											case '1':
 | 
				
			||||||
 | 
											case '2':
 | 
				
			||||||
 | 
											case '3':
 | 
				
			||||||
 | 
											case '4':
 | 
				
			||||||
 | 
											case '5':
 | 
				
			||||||
 | 
											case '6':
 | 
				
			||||||
 | 
											case '7':
 | 
				
			||||||
 | 
											case '8':
 | 
				
			||||||
 | 
											case '9':
 | 
				
			||||||
 | 
													current += c;
 | 
				
			||||||
 | 
													break;
 | 
				
			||||||
 | 
										}
 | 
				
			||||||
 | 
										++idx;
 | 
				
			||||||
 | 
										break;
 | 
				
			||||||
 | 
										
 | 
				
			||||||
 | 
								case this.STATE_STRING_LENGTH:	
 | 
				
			||||||
 | 
										switch(c) {
 | 
				
			||||||
 | 
											case ':':	// the separator between length and content
 | 
				
			||||||
 | 
													stringLength = parseInt(current, 10);
 | 
				
			||||||
 | 
													state = this.STATE_STRING_CONTENT;
 | 
				
			||||||
 | 
													current = "";		// We now parse the string content
 | 
				
			||||||
 | 
													break;
 | 
				
			||||||
 | 
											case '0':
 | 
				
			||||||
 | 
											case '1':
 | 
				
			||||||
 | 
											case '2':
 | 
				
			||||||
 | 
											case '3':
 | 
				
			||||||
 | 
											case '4':
 | 
				
			||||||
 | 
											case '5':
 | 
				
			||||||
 | 
											case '6':
 | 
				
			||||||
 | 
											case '7':
 | 
				
			||||||
 | 
											case '8':
 | 
				
			||||||
 | 
											case '9':
 | 
				
			||||||
 | 
													current += c;
 | 
				
			||||||
 | 
													break;
 | 
				
			||||||
 | 
											default:
 | 
				
			||||||
 | 
													return null;
 | 
				
			||||||
 | 
											
 | 
				
			||||||
 | 
										}
 | 
				
			||||||
 | 
										++idx;
 | 
				
			||||||
 | 
										break;
 | 
				
			||||||
 | 
										
 | 
				
			||||||
 | 
									case this.STATE_STRING_CONTENT:
 | 
				
			||||||
 | 
										current += c;
 | 
				
			||||||
 | 
										if (--stringLength == 0) {
 | 
				
			||||||
 | 
											return { o : current, idx : idx+1 };
 | 
				
			||||||
 | 
										}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
										++idx;
 | 
				
			||||||
 | 
										break;
 | 
				
			||||||
 | 
																
 | 
				
			||||||
 | 
									case this.STATE_DICTIONARY:
 | 
				
			||||||
 | 
										
 | 
				
			||||||
 | 
										if (c == 'e') {
 | 
				
			||||||
 | 
											return { o : currentObject, idx : idx+1 };
 | 
				
			||||||
 | 
										} else {
 | 
				
			||||||
 | 
											var objKey = this.parse(dataArray, idx);
 | 
				
			||||||
 | 
											var objValue = this.parse(dataArray, objKey.idx);
 | 
				
			||||||
 | 
											
 | 
				
			||||||
 | 
											currentObject[objKey.o] = objValue.o;
 | 
				
			||||||
 | 
											idx = objValue.idx;
 | 
				
			||||||
 | 
										}
 | 
				
			||||||
 | 
										break;
 | 
				
			||||||
 | 
										
 | 
				
			||||||
 | 
									case this.STATE_LIST:
 | 
				
			||||||
 | 
										
 | 
				
			||||||
 | 
										if (c == 'e') {
 | 
				
			||||||
 | 
											return { o : currentObject, idx : idx+1 };
 | 
				
			||||||
 | 
										} else {
 | 
				
			||||||
 | 
											var obj = this.parse(dataArray, idx);
 | 
				
			||||||
 | 
											
 | 
				
			||||||
 | 
											currentObject.push(obj.o);
 | 
				
			||||||
 | 
											idx = obj.idx;
 | 
				
			||||||
 | 
										}
 | 
				
			||||||
 | 
										break;
 | 
				
			||||||
 | 
									
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
						return null;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bencode.prototype.decode = function(byteArray) {
 | 
				
			||||||
 | 
						var dataArray = new Uint8Array(byteArray);
 | 
				
			||||||
 | 
						var result = this.parse(dataArray, 0);
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
						return result.o;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -35,7 +35,9 @@
 | 
				
			|||||||
		"create" : "Create",
 | 
							"create" : "Create",
 | 
				
			||||||
		"torrent_file" : "Torrent file",
 | 
							"torrent_file" : "Torrent file",
 | 
				
			||||||
		"name" : "Name",
 | 
							"name" : "Name",
 | 
				
			||||||
		"create_new_torrent" : "Create new torrent",
 | 
							"create_new_torrent" : "Create a new torrent",
 | 
				
			||||||
		"description" : "Description"
 | 
							"description" : "Description",
 | 
				
			||||||
 | 
							"audio_quality" : "Audio quality",
 | 
				
			||||||
 | 
							"video_quality" : "Video quality"
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -24,6 +24,26 @@ vim: ts=2 noexpandtab
 | 
				
			|||||||
					<input name="torrentFile" class="file" type="file" size="50" maxlength="100000" accept="text/*" onchange="setButtonToFilename(event)">
 | 
										<input name="torrentFile" class="file" type="file" size="50" maxlength="100000" accept="text/*" onchange="setButtonToFilename(event)">
 | 
				
			||||||
				</div>
 | 
									</div>
 | 
				
			||||||
			</div>
 | 
								</div>
 | 
				
			||||||
 | 
								<div class="form-group">
 | 
				
			||||||
 | 
									<label for="inputTorrentFile" class="col-sm-3 control-label">File info</label>
 | 
				
			||||||
 | 
									<div class="col-sm-9 detectedInfos">
 | 
				
			||||||
 | 
										<div class="detectedGroup sizeGroup">
 | 
				
			||||||
 | 
											<h5>Size:</h5>
 | 
				
			||||||
 | 
											<p class="detectedSize">123MB</p>
 | 
				
			||||||
 | 
										</div>
 | 
				
			||||||
 | 
										<div class="detectedGroup trackerGroup">
 | 
				
			||||||
 | 
											<h5>Tracker:</h5>
 | 
				
			||||||
 | 
											<p class="detectedTracker">http://foo.bar/tracker</p>
 | 
				
			||||||
 | 
										</div>
 | 
				
			||||||
 | 
										<div class="detectedGroup filesGroup">
 | 
				
			||||||
 | 
											<h5>Detected files:</h5>
 | 
				
			||||||
 | 
											<div class="detectedFiles">
 | 
				
			||||||
 | 
												<ul>
 | 
				
			||||||
 | 
												</ul>
 | 
				
			||||||
 | 
											</div>
 | 
				
			||||||
 | 
										</div>
 | 
				
			||||||
 | 
									</div>
 | 
				
			||||||
 | 
								</div>
 | 
				
			||||||
			<div class="form-group">
 | 
								<div class="form-group">
 | 
				
			||||||
				<label for="inputCategory" class="col-sm-3 control-label">{{ getLocalString(language, "category") }}</label>
 | 
									<label for="inputCategory" class="col-sm-3 control-label">{{ getLocalString(language, "category") }}</label>
 | 
				
			||||||
				<div class="col-sm-9">
 | 
									<div class="col-sm-9">
 | 
				
			||||||
@@ -62,6 +82,19 @@ vim: ts=2 noexpandtab
 | 
				
			|||||||
					<input type="text" name="name" class="form-control name" placeholder="e.g. Attack of the Killer Tomatoes" aria-describedby="basic-addon1">
 | 
										<input type="text" name="name" class="form-control name" placeholder="e.g. Attack of the Killer Tomatoes" aria-describedby="basic-addon1">
 | 
				
			||||||
				</div>
 | 
									</div>
 | 
				
			||||||
			</div>
 | 
								</div>
 | 
				
			||||||
 | 
								<div class="form-group">
 | 
				
			||||||
 | 
									<label for="inputName" class="col-sm-3 control-label">{{ getLocalString(language, "audio_quality") }}</label>
 | 
				
			||||||
 | 
									<div class="col-sm-9">
 | 
				
			||||||
 | 
										<input type="text" name="audioquality_description" class="form-control name" placeholder="e.g. English, AC-3 at 384kbps" aria-describedby="basic-addon1">
 | 
				
			||||||
 | 
									</div>
 | 
				
			||||||
 | 
								</div>
 | 
				
			||||||
 | 
								<div class="form-group">
 | 
				
			||||||
 | 
									<label for="inputName" class="col-sm-3 control-label">{{ getLocalString(language, "video_quality") }}</label>
 | 
				
			||||||
 | 
									<div class="col-sm-9">
 | 
				
			||||||
 | 
										<input type="text" name="videoquality_description" class="form-control name" placeholder="e.g. XviD, 720×400 at 1809 kbps" aria-describedby="basic-addon1">
 | 
				
			||||||
 | 
									</div>
 | 
				
			||||||
 | 
								</div>
 | 
				
			||||||
 | 
					<!--
 | 
				
			||||||
			<div class="form-group">
 | 
								<div class="form-group">
 | 
				
			||||||
				<label for="inputName" class="col-sm-3 control-label">Audio-Quality</label>
 | 
									<label for="inputName" class="col-sm-3 control-label">Audio-Quality</label>
 | 
				
			||||||
				<div class="col-sm-9">
 | 
									<div class="col-sm-9">
 | 
				
			||||||
@@ -84,10 +117,11 @@ vim: ts=2 noexpandtab
 | 
				
			|||||||
					</div>
 | 
										</div>
 | 
				
			||||||
				</div>
 | 
									</div>
 | 
				
			||||||
			</div>
 | 
								</div>
 | 
				
			||||||
 | 
					-->
 | 
				
			||||||
			<div class="form-group">
 | 
								<div class="form-group">
 | 
				
			||||||
				<label for="inputName" class="col-sm-3 control-label">{{ getLocalString(language, "description") }}</label>
 | 
									<label for="inputName" class="col-sm-3 control-label">{{ getLocalString(language, "description") }}</label>
 | 
				
			||||||
				<div class="col-sm-9">
 | 
									<div class="col-sm-9">
 | 
				
			||||||
					<textarea name="description" class="form-control description" rows="10"></textarea>
 | 
										<textarea name="description" class="form-control description" rows="10" placeholder="Hint: Markdown is supported in this field"></textarea>
 | 
				
			||||||
				</div>
 | 
									</div>
 | 
				
			||||||
			</div>
 | 
								</div>
 | 
				
			||||||
			<div class="form-group">
 | 
								<div class="form-group">
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user