commit 8d76ed1f82d9fb2a763318574132a01556b48b62 Author: Hautvast Date: Wed Feb 3 00:17:39 2016 +0100 initial commit diff --git a/src/fileserver/data/frans.json b/src/fileserver/data/frans.json new file mode 100644 index 0000000..221be3f --- /dev/null +++ b/src/fileserver/data/frans.json @@ -0,0 +1,139 @@ +{"borgne": "verdacht", +"antre, le": "hol", +"impétueusement": "woest, onstuimig", +"vénal": "(om)koopbaar", +"relier à": "verbinden met", +"bauge, la": "vuil bed/nest", +"n'en déplaise à": "in weerwil van", +"affadie": "verslapt", +"ouïe, la": "het horen", +"lambiner": "treuzelen", +"brochet, le": "snoek", +"écorce, la": "schors, schil, korst, bast", +"estaminet, le": "kroeg", +"joue, la": "wang", +"nuque, la": "nek", +"cuisse, la": "dij", +"pudeur, la": "schroom", +"chevaucher": "paardijden", +"trébucher": "struikelen", +"pavé, le": "straatsteen", +"lame, la": "lemmet", +"fillette, la": "klein meisje", +"apeurer": "bang maken", +"faïence, la": "aardewerk", +"pieux": "vroom", +"oreiller, le": "hoofdkussen", +"plume, la": "dons", +"drap, le": "laken", +"broc, le": "waterkan", +"rodomontade": "kletser, zwetser", +"sein, le": "borst", +"trouer": "doorboren", +"jetée, la": "havenhoofd, pier", +"chahut, le": "lawaai", +"chahuter": "lawaai maken", +"bénir": "zegenen", +"éclos, le": "het uit het ei komen", +"incongru": "onbetamelijk", +"gifler": "slaan", +"silex": "vuursteen", +"brisure": "breuk, barst", +"saoul, soûl": "zat, dronken", +"breuvage, le": "drank", +"brandir": "zwaaien", +"mamelon, le": "borst", +"transi": "verkleumd", +"parapet, le": "leuning", +"tanguer": "tango dansen", +"éructation, la": "oprisping", +"querelle, la": "twist", +"délaisser": "achterlaten", +"tiède": "lauw", +"lisse": "glad", +"retable, le": "altaarblad", +"incommensurable": "onmeetbaar", +"basque, la": "pand van een jas", +"bataclan, le": "santekraam", +"lâche": "laf, laag", +"fange, la": "modder, slijk", +"épuiser": "leegscheppen", +"hâve": "mager, bleek", +"gerçure": "kloof in de huid", +"j'en ai marre": "ik heb er genoeg van", +"laine, la": "wol", +"hébétude, la": "afstomping (van de zintuigen)", +"tripaille, la": "(dierlijke) ingewanden", +"crever": "barsten", +"désarroi, le": "wanorde", +"bégayer": "stotteren", +"secouer": "afschudden", +"fumier, le": "mest, mesthoop", +"réconforter": "versterken, troosten", +"suppurer": "etteren", +"creux, le": "holte", +"implorer": "smeken, aanroepen", +"ombre, le": "schaduw, schim", +"terreux": "aardachtig", +"ronger": "knagen", +"crénelé": "gekarteld", +"terrasser": "op de grond werpen", +"triturer": "fijnwrijven", +"soulagement, le": "verzachting", +"vase, la": "modder (rivierbodem)", +"poumon, le": "long", +"deviner": "raden, voorspellen", +"fébrile": "koortsachtig", +"meurtrir": "kwetsen, kneuzen", +"pantin, le": "pop", +"giguer": "dansen (als een pop?)", +"veuf, le": "weduwnaar", +"plaindre": "beklagen", +"boue, la": "modder", +"immonde": "vuil", +"crasse, la": "vuil(nis)", +"serpe, la": "snoeimes", +"couler": "vloeien", +"goulot, le": "flessehals", +"atteindre": "raken", +"renouer": "opnieuw knopen", +"grelotter": "huiveren", +"étoffe, la": "stof", +"exiger": "eisen", +"esquisser": "schetsen", +"croupe, la": "achterop een paard", +"accrocher": "vastmaken", +"empreinte": "indruk", +"gueuler": "schreeuwen", +"piètre": "armzalig", +"branler": "waggelen", +"mollet, le": "kuit", +"lasser": "vermoeien, vervelen", +"taie, la": "sloop, oogwit", +"acajou, le": "mahoniehout", +"moit": "klam", +"moiteur": "klamheid", +"hanche, la": "heup", +"gant, le": "handschoen", +"septentrion, le": "het noorden", +"ardoise, la": "leisteen", +"aboucher": "verbinden", +"troquet, le": "drinker", +"tituber": "wankelen", +"rance": "ranzig", +"cicatrice, la": "litteken", +"étreindre": "omarmen", +"songer": "mijmeren", +"marne, la": "mergel", +"entrelacs, le": "vlechtwerk", +"étouffer": "verstikken, uitdoven", +"extirper": "uitroeien, verdelgen", +"défaire": "losmaken, vernietigen", +"flairer": "ruiken, snuffelen", +"éplucher": "schoonmaken (groente)", +"frein, le": "gebit", +"fesse,la": "bil", +"flaque, la": "plas", +"paume, la": "handpalm", +"écorché": "ontveld", +"bagarre, la": "rumoer"} diff --git a/src/fileserver/data/wehkamp.json b/src/fileserver/data/wehkamp.json new file mode 100644 index 0000000..df9aa58 --- /dev/null +++ b/src/fileserver/data/wehkamp.json @@ -0,0 +1,110 @@ +{"aanmaakdatum": "creation date", +"additionele kosten": "additional costs (ie. shipping costs)", +"adres": "address", +"afgerond": "finished, rounded", +"afkeuren": "to denounce", +"afronden": "to finish, to round (numbers)", +"afspraak": "appointment", +"anders": "different", +"annuleren": "to cancel", +"artikel": "article", +"bedrag": "amount (of money)", +"behandelen": "to process, to handle", +"beoordelen": "to evaluate, to judge", +"bepalen": "to determine", +"berekening": "calculation", +"bericht": "message", +"bestelling": "order", +"betaalkeuze": "payment method", +"betalen": "to pay", +"bezorgen": "to deliver", +"bijpinnen": "getting extra money at an ATM", +"brief": "letter (written document)", +"BTW (belasting toegevoegde waarde)": "VAT (value added tax)", +"dag": "day", +"dienst": "(financial) service", +"domein": "domain", +"donderdag": "thursday", +"fabriek": "factory", +"financieel": "financial", +"fraude": "fraud", +"geannuleerd": "cancelled", +"gegevens": "data (IT)", +"gekozen": "chosen", +"geld": "money", +"gemeente": "city, municipality", +"gesloten": "closed", +"haal": "get (context getters and setters in java)", +"huisnummer": "number (in address)", +"iDeal": "payment provider (brandname)", +"invoer": "import, input", +"kiezen": "to choose", +"klant":" customer", +"kopen": "to buy", +"kredietwaardig": "creditworthy", +"letter": "letter (character)", +"leverancier": "supplier", +"leveren": "to deliver", +"levering": "delivery", +"lezen": "to read (IT and non-IT)", +"maandag": "monday", +"magazijn": "warehouse", +"money at home": "brand name of wehkamp loan scheme", +"nieuw": "new", +"nu": "now", +"oln": "optimistic locking number", +"opdracht": "assignment", +"openstaand": "outstanding, having status 'open'", +"opslaan": "to save (IT context)", +"optie": "combination of article number and size", +"order": "order", +"orderregel onderdeel": "part of an orderline item", +"orderregel": "orderline", +"overig": "other not mentioned", +"postbus": "mailbox", +"postcode": "zipcode", +"presentatie": "presentation", +"prijs": "price / prize", +"rekenen": "to calculate", +"rekening": "invoice", +"resultaat": "result", +"selectvracht": "brandname for the main carrier for small items", +"servicepunt": "(fysical) shop where goods can be delivered for the customer to pick up", +"sluiten": "to close", +"straat": "street", +"stuksregel": "orderline", +"tijd-voorraad": "(lit: time-stock) data served by LVT (stock information)", +"tuesday": "dinsdag", +"uitval": "dropped messages, lost data", +"uitvoeren": "to export, to execute", +"uitzondering": "exception", +"vastleggen": "to save (IT)", +"vaststellen": "to determine", +"verboden": "prohibited", +"verkopen": "to sell", +"verplicht": "mandatory", +"verrijken": "to enrich", +"versturen": "to send", +"vervangen": "to replace", +"verwachten": "to expect", +"verwerken": "to process", +"verzenden": "to send", +"verzendkosten": "shipping costs", +"vinden": "to find", +"voegsel": "address number pre/postfix", +"volgnummer": "sequence number", +"voorbereiden": "to prepare", +"vooruitbetaling": "prepayment", +"vraag": "question, query", +"vrijdag": "friday", +"VUB = vooruitbetaling": "prepayment", +"wachten": "to wait", +"werken": "to work", +"wijzigingsdatum": "date of mutation", +"woensdag": "wednesday", +"zaterdag": "saturday", +"zenden": "to send", +"zet": "set (context getters and setters in java)", +"zoeken": "to search", +"zondag": "sunday", +"nadenken":"to think"} \ No newline at end of file diff --git a/src/fileserver/fileserver.exe b/src/fileserver/fileserver.exe new file mode 100644 index 0000000..918794e Binary files /dev/null and b/src/fileserver/fileserver.exe differ diff --git a/src/fileserver/main.go b/src/fileserver/main.go new file mode 100644 index 0000000..dd18a13 --- /dev/null +++ b/src/fileserver/main.go @@ -0,0 +1,67 @@ +package main + +import ( + "github.com/julienschmidt/httprouter" + "io/ioutil" + "log" + "net/http" + "strings" +) + +func main() { + router := httprouter.New() + router.GET("/dictionary/:dictionaryName", GetDictionary) + router.GET("/dictionaries", GetDictionaries) + router.GET("/newDictionary/:dictionaryName", NewDictionary) + router.GET("/add/:dictionaryName/:key/:value", AddTranslation) + router.NotFound = http.FileServer(http.Dir("public")) + + log.Fatal(http.ListenAndServe(":8080", router)) +} + +func GetDictionaries(res http.ResponseWriter, req *http.Request, _ httprouter.Params) { + result := "[" + dirEntries, err := ioutil.ReadDir("data") + check(err) + for _, file := range dirEntries { + if strings.ContainsAny(file.Name(), ".json") { + filename := file.Name() + filename = filename[0 : len(filename)-5] //chop off .json + result += "\"" + filename + "\"," + } + } + result = result[0:len(result)-1] + "]" + + res.Header().Set("Content-Type", "application/json") + res.Write([]byte(result)) +} + +func GetDictionary(res http.ResponseWriter, req *http.Request, ps httprouter.Params) { + dictionary := ps.ByName("dictionaryName") + dat, err := ioutil.ReadFile("data/" + dictionary + ".json") + check(err) + res.Header().Set("Content-Type", "application/json") + res.Write(dat) +} + +func AddTranslation(res http.ResponseWriter, req *http.Request, ps httprouter.Params) { + dictionary := ps.ByName("dictionaryName") + data, err := ioutil.ReadFile("data/" + dictionary + ".json") + check(err) + jsonText := string(data) + addition := ",\n\"" + ps.ByName("key") + "\":\"" + ps.ByName("value") + "\"}" + jsonText = strings.Replace(jsonText, "}", addition, 1) + ioutil.WriteFile("data/"+dictionary+".json", []byte(jsonText), 0644) +} + +func NewDictionary(res http.ResponseWriter, req *http.Request, ps httprouter.Params) { + dictionary := ps.ByName("dictionaryName") + jsonText := "{\"\":\"\"\n}" + ioutil.WriteFile("data/"+dictionary+".json", []byte(jsonText), 0644) +} + +func check(e error) { + if e != nil { + panic(e) + } +} diff --git a/src/fileserver/npm-debug.log b/src/fileserver/npm-debug.log new file mode 100644 index 0000000..83f47bf --- /dev/null +++ b/src/fileserver/npm-debug.log @@ -0,0 +1,21 @@ +0 info it worked if it ends with ok +1 verbose cli [ 'D:\\dev\\nodejs\\node.exe', +1 verbose cli 'D:\\dev\\nodejs\\node_modules\\npm\\bin\\npm-cli.js', +1 verbose cli 'start' ] +2 info using npm@3.3.12 +3 info using node@v5.2.0 +4 verbose stack Error: ENOENT: no such file or directory, open 'D:\workspaces\go\src\fileserver\package.json' +4 verbose stack at Error (native) +5 verbose cwd D:\workspaces\go\src\fileserver +6 error Windows_NT 6.1.7601 +7 error argv "D:\\dev\\nodejs\\node.exe" "D:\\dev\\nodejs\\node_modules\\npm\\bin\\npm-cli.js" "start" +8 error node v5.2.0 +9 error npm v3.3.12 +10 error path D:\workspaces\go\src\fileserver\package.json +11 error code ENOENT +12 error errno -4058 +13 error syscall open +14 error enoent ENOENT: no such file or directory, open 'D:\workspaces\go\src\fileserver\package.json' +14 error enoent This is most likely not a problem with npm itself +14 error enoent and is related to npm not being able to find a file. +15 verbose exit [ -4058, true ] diff --git a/src/fileserver/public/css/Gloss.css b/src/fileserver/public/css/Gloss.css new file mode 100644 index 0000000..3da1eb0 --- /dev/null +++ b/src/fileserver/public/css/Gloss.css @@ -0,0 +1,12 @@ +.left{ + background-color: rgba(0,0,0,.1); + color: #b0b0b0; + height: 100%; + position: absolute; +} + +.bottom{ + position: absolute; + bottom: 0px; + float: left; +} \ No newline at end of file diff --git a/src/fileserver/public/css/cover.css b/src/fileserver/public/css/cover.css new file mode 100644 index 0000000..00e5ffd --- /dev/null +++ b/src/fileserver/public/css/cover.css @@ -0,0 +1,165 @@ +/* + * Globals + */ + +/* Links */ +a, +a:focus, +a:hover { + color: #fff; +} + +/* Custom default button */ +.btn-default, +.btn-default:hover, +.btn-default:focus { + color: #333; + text-shadow: none; /* Prevent inheritence from `body` */ + background-color: #fff; + border: 1px solid #fff; +} + + +/* + * Base structure + */ + +html, +body { + height: 100%; + background-color: #333; +} +body { + color: #fff; + text-shadow: 0 1px 3px rgba(0,0,0,.5); +} + +/* Extra markup and styles for table-esque vertical and horizontal centering */ +.site-wrapper { + display: table; + width: 100%; + height: 100%; /* For at least Firefox */ + min-height: 100%; + -webkit-box-shadow: inset 0 0 100px rgba(0,0,0,.5); + box-shadow: inset 0 0 100px rgba(0,0,0,.5); +} +.site-wrapper-inner { + display: table-cell; + vertical-align: top; +} +.cover-container { + margin-right: auto; + margin-left: auto; +} + +/* Padding for spacing */ +.inner { + padding: 30px; +} + + +.cover-heading{ + text-align: center; +} +/* + * Header + */ +.masthead-brand { + margin-top: 10px; + margin-bottom: 10px; +} + +.masthead-nav > li { + display: inline-block; +} +.masthead-nav > li + li { + margin-left: 20px; +} +.masthead-nav > li > a { + padding-right: 0; + padding-left: 0; + font-size: 16px; + font-weight: bold; + color: #fff; /* IE8 proofing */ + color: rgba(255,255,255,.75); + border-bottom: 2px solid transparent; +} +.masthead-nav > li > a:hover, +.masthead-nav > li > a:focus { + background-color: transparent; + border-bottom-color: #a9a9a9; + border-bottom-color: rgba(255,255,255,.25); +} +.masthead-nav > .active > a, +.masthead-nav > .active > a:hover, +.masthead-nav > .active > a:focus { + color: #fff; + border-bottom-color: #fff; +} + +@media (min-width: 768px) { + .masthead-brand { + float: left; + } + .masthead-nav { + float: right; + } +} + + +/* + * Cover + */ + +.cover { + padding: 0 20px; +} +.cover .btn-lg { + padding: 10px 20px; + font-weight: bold; +} + + +/* + * Footer + */ + +.mastfoot { + color: #999; /* IE8 proofing */ + color: rgba(255,255,255,.5); +} + + +/* + * Affix and center + */ + +@media (min-width: 768px) { + /* Pull out the header and footer */ + .masthead { + position: fixed; + top: 0; + } + .mastfoot { + position: fixed; + bottom: 0; + } + /* Start the vertical centering */ + .site-wrapper-inner { + vertical-align: middle; + } + /* Handle the widths */ + .masthead, + .mastfoot, + .cover-container { + width: 100%; /* Must be percentage or pixels for horizontal alignment */ + } +} + +@media (min-width: 992px) { + .masthead, + .mastfoot, + .cover-container { + width: 700px; + } +} \ No newline at end of file diff --git a/src/fileserver/public/img/dictionary-icon.png b/src/fileserver/public/img/dictionary-icon.png new file mode 100644 index 0000000..f14785f Binary files /dev/null and b/src/fileserver/public/img/dictionary-icon.png differ diff --git a/src/fileserver/public/index.html b/src/fileserver/public/index.html new file mode 100644 index 0000000..17853ff --- /dev/null +++ b/src/fileserver/public/index.html @@ -0,0 +1,69 @@ + + + + + + + + + + + Gloss Dictionary + + + + + + + + + +
+ +
+
+

Translate

+ +

+

+ Add +

+
+

Add new translation

+
+ word + meaning +

+ +
+
+
+ + + +
+
+

Built with go and angular.

+
+
+ + + + + + + + diff --git a/src/fileserver/public/js/main.js b/src/fileserver/public/js/main.js new file mode 100644 index 0000000..bacd915 --- /dev/null +++ b/src/fileserver/public/js/main.js @@ -0,0 +1,101 @@ +angular.module("Gloss", []) + +.controller('TranslateCtrl', function($scope, $http) { + reloadDictionaries(); + focus("#searchInput"); + + //select text in input elements when focus gained + $(function () { + var focusedElement; + $(document).on('focus', 'input', function () { + if (focusedElement == $(this)) return; //already focused, return so user can now place cursor at specific point in input. + focusedElement = $(this); + setTimeout(function () { focusedElement.select(); }, 50); //select all text in any field on focus for easy re-entry. Delay sightly to allow focus to "stick" before selecting. + }); + }); + + //focusses the element after a short interval + function focus(element){ + setTimeout(function(){ $(element).focus(); }, 200); + } + + //simple DIY routing + setInterval(function(){ + var savedHash; + if (document.location.hash != savedHash){ + if(document.location.hash != '#adding'){ + $scope.adding = false; + $scope.$digest(); + focus('#newKeyInput'); + } else { + $scope.adding = true; + $scope.$digest(); + focus("#searchInput"); + } + savedHash = document.location.hash; + } + },100); + + //find all matches for a given search key (all keys beginning with the text typed) + $scope.translate = function(){ + output=[]; + if ($scope.input && $scope.input != ''){ + for (var i=0; i<$scope.keys.length; i++){ + if (stringStartsWith($scope.keys[i], $scope.input)) { + output.push({dutch: $scope.keys[i], english: $scope.dictionary[$scope.keys[i]]}); + } + } + $scope.translation = output; + } else { + $scope.translation = null; + } + } + + $scope.chooseDictionary = function(element){ + $scope.currentDictionary = element.dictionary; + reloadDictionary(); + $scope.translation=[]; + focus("#searchInput"); + } + + //uploads a new translation to the server + $scope.addTranslation = function(){ + if ($scope.newDutchWord){ + $http.get('/add/' + $scope.currentDictionary + '/' + $scope.newDutchWord + '/' + $scope.newEnglishWord); + } + $scope.adding = false; + document.location.hash = ''; + setTimeout(reloadDictionary, 200); //as it turns out doing this immediately returns the old version + } + + /* startsWith function, ignores case*/ + function stringStartsWith(string, prefix) { + return string.slice(0, prefix.length).toLowerCase() == prefix.toLowerCase(); + } + + //retrieves the dictionary from the server + function reloadDictionaries(){ + $http.get('dictionaries').success(function(data) { + $scope.dictionaries=data; + if (!$scope.currentDictionary) { + $scope.currentDictionary = data[0]; + } + reloadDictionary(); + }); + } + + function reloadDictionary(){ + $http.get('dictionary/'+$scope.currentDictionary).success(function(data) { + $scope.dictionary = data; + $scope.keys=Object.keys(data); + }); + } + + $scope.newDictionary=function(){ + $http.get('newDictionary/' + $scope.dictionaryName); + $scope.currentDictionary=$scope.dictionaryName; + reloadDictionaries(); + + $scope.dictionaryName=''; + } +}); \ No newline at end of file diff --git a/src/fileserver/public/package.json b/src/fileserver/public/package.json new file mode 100644 index 0000000..a863078 --- /dev/null +++ b/src/fileserver/public/package.json @@ -0,0 +1,19 @@ +{ + "name": "hatchviewer", + "version": "1.0.0", + "description": "", + "scripts": { + "start": "go run main.go" + }, + "keywords": [], + "author": "", + "license": "ISC", + "dependencies": { + "angular": "^1.4.9", + "systemjs": "0.19.4" + }, + "devDependencies": { + "bootstrap": "^3.3.6", + "jquery": "^2.1.4" + } +} diff --git a/src/github.com/codegangsta/negroni b/src/github.com/codegangsta/negroni new file mode 160000 index 0000000..c7477ad --- /dev/null +++ b/src/github.com/codegangsta/negroni @@ -0,0 +1 @@ +Subproject commit c7477ad8e330bef55bf1ebe300cf8aa67c492d1b diff --git a/src/github.com/julienschmidt/httprouter b/src/github.com/julienschmidt/httprouter new file mode 160000 index 0000000..abb0dc9 --- /dev/null +++ b/src/github.com/julienschmidt/httprouter @@ -0,0 +1 @@ +Subproject commit abb0dc9f755ff0a9d818db28d9d8b9810066e2b5 diff --git a/src/github.com/russross/blackfriday b/src/github.com/russross/blackfriday new file mode 160000 index 0000000..006144a --- /dev/null +++ b/src/github.com/russross/blackfriday @@ -0,0 +1 @@ +Subproject commit 006144af03eeeff1037240a71865a9fd61f1c25f diff --git a/src/github.com/shurcooL/sanitized_anchor_name b/src/github.com/shurcooL/sanitized_anchor_name new file mode 160000 index 0000000..10ef21a --- /dev/null +++ b/src/github.com/shurcooL/sanitized_anchor_name @@ -0,0 +1 @@ +Subproject commit 10ef21a441db47d8b13ebcc5fd2310f636973c77 diff --git a/src/gopkg.in/unrolled/render.v1 b/src/gopkg.in/unrolled/render.v1 new file mode 160000 index 0000000..40a2dfa --- /dev/null +++ b/src/gopkg.in/unrolled/render.v1 @@ -0,0 +1 @@ +Subproject commit 40a2dfa24398d37b4a14938442a0f4fe4307b929
{{word.dutch}}{{word.english}}