Compare commits

12 Commits

Author SHA1 Message Date
5569c4444b Make thing beeing able to be modified 2017-09-23 17:10:50 +02:00
d901943758 Corrects some path 2017-09-23 16:48:56 +02:00
91765d2c84 Makes request rate limited per second, not microseconds 2017-09-23 16:48:56 +02:00
b0eefe8de3 Makes all tests pass green again
* Removed a concurrent write condition that was happening while fetching
  BD
* Updated the local test database to match bedetheque.com state
* Note field being highly dynamic removed test from it.
2017-09-23 16:48:56 +02:00
2f526632fe Uses default gulp build task 2017-09-23 16:47:35 +02:00
ea64b0a6c5 Adds cleaning task and default task 2017-09-23 16:47:35 +02:00
78acb0a1c7 Removes some of the debug output 2017-09-23 16:47:35 +02:00
17c2f18193 Cleans the javascript 2017-09-23 16:47:35 +02:00
e6e1f6d6b3 Adds jshint reporting 2017-09-23 16:46:03 +02:00
c86e06fe23 adds a production, minified version 2017-09-23 16:46:03 +02:00
e98765fbdb Allows for minified and unminifed bower versions 2017-09-23 16:46:03 +02:00
924ea137b9 Makes the dev file built more gulp-ish way 2017-09-23 16:46:03 +02:00
21 changed files with 309 additions and 122 deletions

1
.gitignore vendored
View File

@@ -32,3 +32,4 @@ tmp/
bower_components
node_modules
/webapp/index.html
dist/

3
.jshintrc Normal file
View File

@@ -0,0 +1,3 @@
{
"varstmt" : false
}

View File

@@ -25,7 +25,7 @@ COPY . /satbd
RUN go get $(go list -e -f "{{.Imports}} {{.TestImports}}" . | tr "[" " " | tr "]" " " | xargs go list -e -f "{{if not .Standard}}{{.ImportPath}}{{end}}")
RUN go build
RUN go test
RUN gulp build
RUN gulp
EXPOSE 33276

View File

@@ -5,6 +5,7 @@ import (
"regexp"
"strconv"
"strings"
"sync"
"time"
)
@@ -65,6 +66,7 @@ type Album struct {
Designers []string `json:"dessins"`
Colorists []string `json:"couleurs"`
mx sync.Mutex
Links map[string]string
FetchDate time.Time
@@ -114,3 +116,14 @@ func AlbumCoverExt(URL string) string {
}
return strings.ToLower(ext)
}
func (a *Album) addLink(title string, value string) {
a.mx.Lock()
defer a.mx.Unlock()
if a.Links == nil {
a.Links = make(map[string]string)
}
a.Links[title] = value
}

View File

@@ -1,6 +1,7 @@
package main
import (
"fmt"
"log"
"path/filepath"
"time"
@@ -43,14 +44,19 @@ func (s *AlbumDatabaseSuite) TestCanGet(c *C) {
func (s *AlbumDatabaseSuite) TestCanSort(c *C) {
start := time.Now()
data := []AlbumID{160366, 58595, 15875, 9935, 84448, 46005, 19762, 164, 52100, 8179, 44989, 32043, 22737, 754}
sorted, err := s.db.ByPurchaseDate()
log.Printf("sorting took %s", time.Since(start))
c.Assert(err, IsNil)
c.Assert(len(sorted), Equals, len(data))
for i, a := range sorted {
c.Check(a, Equals, data[i], Commentf("expected %d", a))
c.Assert(len(sorted) > 0, Equals, true)
last := time.Now()
for _, a := range sorted {
al, err := s.db.get(fmt.Sprintf("%d", a))
if c.Check(err, IsNil) == false {
continue
}
c.Check(last.After(al.PurchaseDate), Equals, true)
}
}

View File

@@ -2,6 +2,7 @@ package main
import (
"fmt"
"log"
"path"
"regexp"
"strconv"
@@ -29,11 +30,13 @@ func linkFromSelection(s *goquery.Selection) Link {
// Get fetches data from www.bedetheque.com and parses it to a
func (g *AlbumDescriptionGetter) Get(a *Album) error {
URL := path.Join("www.bedetheque.com", fmt.Sprintf("BD--%d.html", a.ID))
resp, err := g.getter.Get("http://" + URL)
resp, err := g.getter.Get("https://" + URL)
if err != nil {
return err
}
defer closeOrPanic(resp.Body, "GET:http://"+URL)
defer closeOrPanic(resp.Body, "GET:https://"+URL)
log.Printf("Fetched %s", URL)
doc, err := goquery.NewDocumentFromReader(resp.Body)
if err != nil {
@@ -100,7 +103,6 @@ func (g *AlbumDescriptionGetter) Get(a *Album) error {
details := map[string][]*goquery.Selection{}
previous := ""
a.Links = map[string]string{}
doc.Find("div.detail-album ul.infos-albums li").Each(func(i int, s *goquery.Selection) {
labelSelection := s.Find("label")
if labelSelection.Size() != 1 {
@@ -124,7 +126,7 @@ func (g *AlbumDescriptionGetter) Get(a *Album) error {
l := linkFromSelection(s.Find("a"))
if len(l.Title) > 0 {
a.Scenarists = append(a.Scenarists, l.Title)
a.Links[l.Title] = l.Target
a.addLink(l.Title, l.Target)
}
}
errors <- nil
@@ -141,7 +143,7 @@ func (g *AlbumDescriptionGetter) Get(a *Album) error {
l := linkFromSelection(s.Find("a"))
if len(l.Title) > 0 {
a.Designers = append(a.Designers, l.Title)
a.Links[l.Title] = l.Target
a.addLink(l.Title, l.Target)
}
}
errors <- nil
@@ -158,7 +160,7 @@ func (g *AlbumDescriptionGetter) Get(a *Album) error {
l := linkFromSelection(s.Find("a"))
if len(l.Title) > 0 {
a.Colorists = append(a.Colorists, l.Title)
a.Links[l.Title] = l.Target
a.addLink(l.Title, l.Target)
}
}
errors <- nil
@@ -173,9 +175,11 @@ func (g *AlbumDescriptionGetter) Get(a *Album) error {
}
if len(errorList) != 0 {
return fmt.Errorf("Could not parse description from http://%s:%s",
return fmt.Errorf("Could not parse description from https://%s:%s\n%s",
URL,
strings.Join(append([]string{""}, errorList...), "\n * "))
strings.Join(append([]string{""}, errorList...), "\n * "),
resp.Body)
}
a.FetchDate = time.Now()

View File

@@ -28,6 +28,8 @@ func (s *AlbumDescriptionGetterSuite) TestGet(c *C) {
if c.Check(s.g.Get(&aStripped), IsNil) == true {
//we skip the fetch date, for sure it will always expire
aStripped.FetchDate = a.FetchDate
//we skip the note as it is a dynamic value, and may change over time
aStripped.Note = a.Note
c.Check(aStripped, DeepEquals, a)
}
}

View File

@@ -1,6 +1,137 @@
var gulp = require('gulp');
var plugins = require('gulp-load-plugins')({});
var karma = require('karma');
var es = require('event-stream');
var mainBowerFiles = require('main-bower-files');
var exists = require('path-exists').sync
var Q = require('q');
var del = require('del');
var pipes = {};
var paths = {
appFiles: 'webapp/js/**/*.js',
cssFiles: 'webapp/css/**/*.css',
partials: 'webapp/js/**/*.html',
pages : ['webapp/html/**/*.html', '!webapp/html/index.html'],
index : 'webapp/html/index.html',
distDev : 'dist/dev',
distProd: 'dist/prod'
}
pipes.bowerFiles = function() {
return gulp.src(mainBowerFiles({
overrides : {
jquery : {
main: []
},
bootstrap : {
main: [
"dist/**/*.min.css",
'./dist/fonts/*.*'
]
}
}
}),{base: 'webapp/bower_components'});
}
pipes.bowerFilesMinified = function() {
return pipes.bowerFiles()
.pipe(plugins.rename(function (path) {
testpath = 'webapp/bower_components/' + path.dirname + '/' + path.basename + '.min' + path.extname;
if (exists(testpath)) {
path.extname = '.min' + path.extname;
}
}));
}
pipes.validatedAppScripts = function() {
return gulp.src(paths.appFiles)
.pipe(plugins.jshint())
.pipe(plugins.jshint.reporter('jshint-stylish'));
}
pipes.validatedIndex = function() {
return gulp.src(paths.index)
.pipe(plugins.htmlhint())
.pipe(plugins.htmlhint.reporter());
}
pipes.validatedPartials = function() {
return gulp.src(paths.partials)
.pipe(plugins.htmlhint({'doctype-first': false}))
.pipe(plugins.htmlhint.reporter());
}
pipes.validatedPages = function() {
return gulp.src(paths.pages)
.pipe(plugins.htmlhint({'doctype-first': false}))
.pipe(plugins.htmlhint.reporter());
}
pipes.builtIndexDev = function() {
var vendorFiles = pipes.bowerFilesMinified()
.pipe(gulp.dest(paths.distDev + '/vendor'));
var appScript = pipes.validatedAppScripts()
.pipe(plugins.angularFilesort())
.pipe(gulp.dest(paths.distDev + '/js'))
var appStyle = gulp.src(paths.cssFiles)
.pipe(gulp.dest(paths.distDev + '/css'))
var partials = pipes.validatedPartials()
.pipe(gulp.dest(paths.distDev + '/js'))
var pages = pipes.validatedPages()
.pipe(gulp.dest(paths.distDev + '/html'))
return pipes.validatedIndex()
.pipe(plugins.inject(vendorFiles, {ignorePath: '/'+ paths.distDev, name:'bower'}))
.pipe(plugins.inject(es.merge(appStyle,partials,pages), {ignorePath: '/'+ paths.distDev}))
.pipe(plugins.inject(appScript, {ignorePath: '/'+ paths.distDev}))
.pipe(gulp.dest(paths.distDev));
}
pipes.builtIndexProd = function() {
var filterJS = plugins.filter('**/*.js',{restore: true});
var vendorFiles = pipes.bowerFiles()
.pipe(filterJS)
.pipe(plugins.concat('vendor.min.js'))
.pipe(plugins.uglify())
.pipe(filterJS.restore)
.pipe(gulp.dest(paths.distProd + '/vendor'));
var appScript = pipes.validatedAppScripts()
.pipe(plugins.angularFilesort())
.pipe(plugins.ngAnnotate())
.pipe(plugins.concat('app.min.js'))
.pipe(plugins.uglify())
.pipe(gulp.dest(paths.distProd + '/js'));
var appStyle = gulp.src(paths.cssFiles)
.pipe(plugins.minifyCss())
.pipe(plugins.rename(function (path) {
path.extname = '.min'+ path.extname;
}))
.pipe(gulp.dest(paths.distProd + '/css'))
var partials = pipes.validatedPartials()
.pipe(gulp.dest(paths.distProd + '/js'))
var pages = pipes.validatedPages()
.pipe(gulp.dest(paths.distProd + '/html'))
return pipes.validatedIndex()
.pipe(plugins.inject(vendorFiles, {ignorePath: '/' + paths.distProd, name : 'bower'}))
.pipe(plugins.inject(es.merge(appStyle,partials,pages), {ignorePath: '/' + paths.distProd}))
.pipe(plugins.inject(appScript, {ignorePath: '/' + paths.distProd}))
.pipe(gulp.dest(paths.distProd));
}
gulp.task('test', function(done) {
server = new karma.Server({
@@ -15,19 +146,24 @@ gulp.task('test', function(done) {
});
gulp.task('build-dev', pipes.builtIndexDev);
gulp.task('build-prod', pipes.builtIndexProd);
gulp.task('build', function() {
return gulp.src('./webapp/html/index.html')
.pipe(plugins.inject(
gulp.src(['./webapp/js/**/*.js']).pipe(plugins.angularFilesort()),
{
ignorePath: '/webapp'
}
))
.pipe(gulp.dest('./webapp'));
pipes.cleanDir = function(dir) {
}
gulp.task('clean-dev', function() {
return del([paths.distDev]);
});
gulp.task('autobuild', function() {
return gulp.watch(['webapp/js/**/*.js','webapp/html/index.html'], ['build']);
gulp.task('clean-prod', function() {
return del([paths.distProd]);
});
gulp.task('clean-build-dev', ['clean-dev'], pipes.builtIndexDev);
gulp.task('clean-build-prod', ['clean-prod'] , pipes.builtIndexProd);
gulp.task('default',['clean-build-prod'])

View File

@@ -27,6 +27,7 @@ type Options struct {
RequestWindow time.Duration `long:"request-window" description:"Window over which no more --max-request are done"`
CacheTTL time.Duration `long:"chache-ttl" description:"TTL of the cached data" `
BatchSize int `long:"batch-size" description:"Sizes of the batch for indexing" default:"1000"`
BasePath string `long:"basepath" short:"b" description:"basepath of the webapp" default:"dist/prod"`
}
type appData struct {
@@ -77,7 +78,7 @@ func newAppData(opts Options) (*appData, error) {
res.db = OpenAlbumDatabase(filepath.Join(basepath, "db"))
res.getter = &AlbumDescriptionGetter{
getter: NewRateLimitedGetter(10, 10),
getter: NewRateLimitedGetter(opts.MaxRequests, opts.RequestWindow),
}
res.cover = NewAlbumCoverCache(filepath.Join(basepath, "covers"), opts.MaxRequests, opts.RequestWindow)
@@ -378,7 +379,7 @@ func Execute() error {
log.Printf("Listening on %s", opts.Listen)
a.start(srv.StopChan())
srv.Server.Handler = a.buildRouter()
srv.Server.Handler = a.buildRouter(opts.BasePath)
if err := srv.ListenAndServe(); err != nil {
if opErr, ok := err.(*net.OpError); !ok || (ok && opErr.Op != "accept") {
return err

View File

@@ -4,20 +4,35 @@
"description": "Small website for exploring privately satellite.bar bedetheque",
"devDependencies": {
"bower": "^1.7.7",
"del": "^2.2.0",
"gulp": "^3.9.1",
"gulp-angular-filesort": "^1.1.1",
"gulp-concat": "^2.6.0",
"gulp-debug": "^2.1.2",
"gulp-filter": "^3.0.1",
"gulp-htmlhint": "^0.3.1",
"gulp-htmlmin": "^1.3.0",
"gulp-inject": "^3.0.0",
"gulp-jasmine": "^2.2.1",
"gulp-jshint": "^2.0.0",
"gulp-karma": "0.0.5",
"gulp-load-plugins": "^1.2.0",
"gulp-minify-css": "^1.2.3",
"gulp-ng-annotate": "^1.1.0",
"gulp-rename": "^1.2.2",
"gulp-uglify": "^1.5.3",
"gulp-util": "^3.0.7",
"jasmine-core": "^2.4.1",
"jshint": "^2.9.1",
"jshint-stylish": "^2.1.0",
"karma": "^0.13.19",
"karma-chrome-launcher": "^0.2.2",
"karma-firefox-launcher": "^0.1.7",
"karma-jasmine": "^0.3.7",
"karma-junit-reporter": "^0.3.8",
"karma-safari-launcher": "^0.1.1",
"main-bower-files": "^2.11.1",
"path-exists": "^2.1.0",
"protractor": "^3.1.1"
},
"scripts": {

View File

@@ -19,7 +19,7 @@ import (
"golang.org/x/net/context"
)
func (a *appData) buildRouter() http.Handler {
func (a *appData) buildRouter(basepath string) http.Handler {
router := httprouter.New()
logger := narco.NewLogger()
@@ -126,19 +126,19 @@ func (a *appData) buildRouter() http.Handler {
})))
dirs := []string{"css", "js", "img", "bower_components", "html"}
dirs := []string{"css", "js", "vendor", "html"}
for _, d := range dirs {
router.ServeFiles(path.Join("/", d, "/*filepath"), http.Dir(filepath.Join("webapp", d)))
router.ServeFiles(path.Join("/", d, "/*filepath"), http.Dir(filepath.Join(basepath, d)))
}
router.GET("/", narco.EndChain(ch, narco.HandlerFunc(
func(ctx context.Context, w http.ResponseWriter, req *http.Request, _ httprouter.Params) {
f, err := os.Open(filepath.Join("webapp", "index.html"))
f, err := os.Open(filepath.Join(basepath, "index.html"))
if err != nil {
narco.Error(ctx, w, err, http.StatusInternalServerError)
return
}
defer closeOrPanic(f, filepath.Join("webapp", "index.html"))
defer closeOrPanic(f, filepath.Join(basepath, "index.html"))
_, err = io.Copy(w, f)
if err != nil {

View File

@@ -1,5 +1,5 @@
[
{
{
"ID": 8179,
"ISBN": "2-8001-1161-5",
"série": "Mortes saisons",
@@ -12,8 +12,8 @@
"ref": "BERT-9",
"LegalDeposit": "1985-10-01T00:00:00Z",
"PrintDate": "0001-01-01T00:00:00Z",
"PurchaseDate": "2013-09-04T00:00:00Z",
"CoverURL": "http://www.bedetheque.com/media/Couvertures/Couv_8179.jpg",
"PurchaseDate": "2013-09-02T00:00:00Z",
"CoverURL": "https://www.bedetheque.com/media/Couvertures/Couv_8179.jpg",
"description": "",
"Note": 3.4,
"scenario": [
@@ -26,9 +26,9 @@
"Berthet, Philippe"
],
"Links": {
"Andreas":"http://www.bedetheque.com/auteur-267-BD-Andreas.html",
"Berthet, Philippe": "http://www.bedetheque.com/auteur-13-BD-Berthet-Philippe.html"
},
"Andreas":"https://www.bedetheque.com/auteur-267-BD-Andreas.html",
"Berthet, Philippe": "https://www.bedetheque.com/auteur-13-BD-Berthet-Philippe.html"
},
"FetchDate": "0001-01-01T00:00:00Z"
},
{
@@ -45,8 +45,8 @@
"ref": "ZCO-35",
"LegalDeposit": "1979-01-01T00:00:00Z",
"PrintDate": "0001-01-01T00:00:00Z",
"PurchaseDate": "2013-09-04T00:00:00Z",
"CoverURL": "http://www.bedetheque.com/media/Couvertures/abeldopeulapeul02.JPG",
"PurchaseDate": "2013-09-01T00:00:00Z",
"CoverURL": "https://www.bedetheque.com/media/Couvertures/Couv_44989.jpg",
"description": "",
"Note": 4,
"scenario": [
@@ -55,8 +55,12 @@
"dessins": [
"Loro"
],
"couleurs": [
"<Quadrichromie>"
],
"Links": {
"Loro": "http://www.bedetheque.com/auteur-839-BD-Loro.html"
"Loro": "https://www.bedetheque.com/auteur-839-BD-Loro.html",
"<Quadrichromie>" : "https://www.bedetheque.com/auteur-7691-BD-Quadrichromie.html"
},
"FetchDate": "0001-01-01T00:00:00Z"
},
@@ -75,7 +79,7 @@
"LegalDeposit": "0001-01-01T00:00:00Z",
"PrintDate": "0001-01-01T00:00:00Z",
"PurchaseDate": "2013-12-07T00:00:00Z",
"CoverURL": "http://www.bedetheque.com/media/Couvertures/plantufourmicouverture.JPG",
"CoverURL": "https://www.bedetheque.com/media/Couvertures/plantufourmicouverture.JPG",
"description": "",
"Note": 3,
"scenario": [
@@ -88,8 +92,8 @@
"\u003cN\u0026B\u003e"
],
"Links" : {
"Plantu": "http://www.bedetheque.com/auteur-5996-BD-Plantu.html",
"\u003cN\u0026B\u003e": "http://www.bedetheque.com/auteur-477-BD-NB.html"
"Plantu": "https://www.bedetheque.com/auteur-5996-BD-Plantu.html",
"\u003cN\u0026B\u003e": "https://www.bedetheque.com/auteur-477-BD-NB.html"
},
"FetchDate": "0001-01-01T00:00:00Z"
},
@@ -107,8 +111,8 @@
"ref": "DARK-2",
"LegalDeposit": "2002-09-01T00:00:00Z",
"PrintDate": "2002-09-01T00:00:00Z",
"PurchaseDate": "2013-09-06T00:00:00Z",
"CoverURL": "http://www.bedetheque.com/media/Couvertures/Darken02_22102002.jpg",
"PurchaseDate": "2013-08-31T00:00:00Z",
"CoverURL": "https://www.bedetheque.com/media/Couvertures/Darken02_22102002.jpg",
"description": "Kelmar le Darken a retrouvé Lorik, son frère, engagé dans la résistance au Nouvel Ordre Humain. Celui-ci aurait découvert l'endroit où leur mère est tenue prisonnière : le Mangeforêt, un monstre mécanique qui défriche la forêt héossienne et sert de bagne aux autochtones récalcitrants. Mais pour les chefs de la résistance, ce n'est pas un objectif prioritaire. Alors Kelmar part à l'assaut de la machine avec Langue Agile la voleuse feling, Doonda la Woon, et une poignée d'enfants-soldats. Et s'il avait été prévu dès le début... Lire la suite",
"Note": 5,
"scenario": [
@@ -116,16 +120,16 @@
"Rastoin, Bernard"
],
"dessins": [
"Swal, Christophe"
"Swal, Christophe"
],
"couleurs": [
"Robert, Jacky"
],
"Links": {
"Polouchine, Igor": "http://www.bedetheque.com/auteur-2556-BD-Polouchine-Igor.html",
"Rastoin, Bernard": "http://www.bedetheque.com/auteur-31834-BD-Rastoin-Bernard.html",
"Swal, Christophe": "http://www.bedetheque.com/auteur-2557-BD-Swal-Christophe.html",
"Robert, Jacky": "http://www.bedetheque.com/auteur-820-BD-Robert-Jacky.html"
"Polouchine, Igor": "https://www.bedetheque.com/auteur-2556-BD-Polouchine-Igor.html",
"Rastoin, Bernard": "https://www.bedetheque.com/auteur-31834-BD-Rastoin-Bernard.html",
"Swal, Christophe": "https://www.bedetheque.com/auteur-2557-BD-Swal-Christophe.html",
"Robert, Jacky": "https://www.bedetheque.com/auteur-820-BD-Robert-Jacky.html"
},
"FetchDate": "0001-01-01T00:00:00Z"
},
@@ -144,7 +148,7 @@
"LegalDeposit": "1992-10-01T00:00:00Z",
"PrintDate": "0001-01-01T00:00:00Z",
"PurchaseDate": "2013-10-31T00:00:00Z",
"CoverURL": "http://www.bedetheque.com/media/Couvertures/bizu05.jpg",
"CoverURL": "https://www.bedetheque.com/media/Couvertures/bizu05.jpg",
"description": "",
"Note": 3,
"scenario": [
@@ -157,8 +161,8 @@
"D'Authenay, Anne-Marie"
],
"Links": {
"Fournier, Jean-Claude": "http://www.bedetheque.com/auteur-755-BD-Fournier-Jean-Claude.html",
"D'Authenay, Anne-Marie":"http://www.bedetheque.com/auteur-550-BD-D-Authenay-Anne-Marie.html"
"Fournier, Jean-Claude": "https://www.bedetheque.com/auteur-755-BD-Fournier-Jean-Claude.html",
"D'Authenay, Anne-Marie":"https://www.bedetheque.com/auteur-550-BD-D-Authenay-Anne-Marie.html"
},
"FetchDate": "0001-01-01T00:00:00Z"
},
@@ -176,8 +180,8 @@
"ref": "EAU-5",
"LegalDeposit": "1992-02-01T00:00:00Z",
"PrintDate": "0001-01-01T00:00:00Z",
"PurchaseDate": "2013-09-06T00:00:00Z",
"CoverURL": "http://www.bedetheque.com/media/Couvertures/Couv_164.jpg",
"PurchaseDate": "2013-08-30T00:00:00Z",
"CoverURL": "https://www.bedetheque.com/media/Couvertures/Couv_164.jpg",
"description": "",
"Note": 3.9,
"scenario": [
@@ -190,8 +194,8 @@
"Adamov, Philippe"
],
"Links": {
"Cothias, Patrick": "http://www.bedetheque.com/auteur-36-BD-Cothias-Patrick.html",
"Adamov, Philippe": "http://www.bedetheque.com/auteur-471-BD-Adamov-Philippe.html"
"Cothias, Patrick": "https://www.bedetheque.com/auteur-36-BD-Cothias-Patrick.html",
"Adamov, Philippe": "https://www.bedetheque.com/auteur-471-BD-Adamov-Philippe.html"
},
"FetchDate": "0001-01-01T00:00:00Z"
},
@@ -209,8 +213,8 @@
"ref": "KEN-2",
"LegalDeposit": "2003-01-01T00:00:00Z",
"PrintDate": "0001-01-01T00:00:00Z",
"PurchaseDate": "2013-09-03T00:00:00Z",
"CoverURL": "http://www.bedetheque.com/media/Couvertures/kenyaco02.jpg",
"PurchaseDate": "2013-08-29T00:00:00Z",
"CoverURL": "https://www.bedetheque.com/media/Couvertures/kenyaco02.jpg",
"description": "",
"Note": 4,
"scenario": [
@@ -224,9 +228,9 @@
"Scarlett"
],
"Links": {
"Leo": "http://www.bedetheque.com/auteur-97-BD-Leo.html",
"Rodolphe": "http://www.bedetheque.com/auteur-128-BD-Rodolphe.html",
"Scarlett": "http://www.bedetheque.com/auteur-1296-BD-Scarlett.html"
"Leo": "https://www.bedetheque.com/auteur-97-BD-Leo.html",
"Rodolphe": "https://www.bedetheque.com/auteur-128-BD-Rodolphe.html",
"Scarlett": "https://www.bedetheque.com/auteur-1296-BD-Scarlett.html"
},
"FetchDate": "0001-01-01T00:00:00Z"
},
@@ -244,8 +248,8 @@
"ref": "ACC-2",
"LegalDeposit": "2003-12-01T00:00:00Z",
"PrintDate": "0001-01-01T00:00:00Z",
"PurchaseDate": "2013-09-04T00:00:00Z",
"CoverURL": "http://www.bedetheque.com/media/Couvertures/accrocderap.jpg",
"PurchaseDate": "2013-08-28T00:00:00Z",
"CoverURL": "https://www.bedetheque.com/media/Couvertures/accrocderap.jpg",
"description": "",
"Note": -1,
"scenario": [
@@ -258,9 +262,9 @@
"Ptiluc"
],
"Links": {
"Harty": "http://www.bedetheque.com/auteur-6505-BD-Harty.html",
"Joan": "http://www.bedetheque.com/auteur-4285-BD-Joan.html",
"Ptiluc": "http://www.bedetheque.com/auteur-125-BD-Ptiluc.html"
"Harty": "https://www.bedetheque.com/auteur-6505-BD-Harty.html",
"Joan": "https://www.bedetheque.com/auteur-4285-BD-Joan.html",
"Ptiluc": "https://www.bedetheque.com/auteur-125-BD-Ptiluc.html"
},
"FetchDate": "0001-01-01T00:00:00Z"
},
@@ -278,8 +282,8 @@
"ref": "CHI-23",
"LegalDeposit": "1978-03-01T00:00:00Z",
"PrintDate": "0001-01-01T00:00:00Z",
"PurchaseDate": "2013-09-06T00:00:00Z",
"CoverURL": "http://www.bedetheque.com/media/Couvertures/Couv_46005.jpg",
"PurchaseDate": "2013-08-27T00:00:00Z",
"CoverURL": "https://www.bedetheque.com/media/Couvertures/Couv_46005.jpg",
"description": "",
"Note": 3,
"scenario": [
@@ -292,7 +296,7 @@
"Tibet"
],
"Links": {
"Tibet": "http://www.bedetheque.com/auteur-1791-BD-Tibet.html"
"Tibet": "https://www.bedetheque.com/auteur-1791-BD-Tibet.html"
},
"FetchDate": "0001-01-01T00:00:00Z"
},
@@ -311,7 +315,7 @@
"LegalDeposit": "1990-10-01T00:00:00Z",
"PrintDate": "0001-01-01T00:00:00Z",
"PurchaseDate": "2013-12-02T00:00:00Z",
"CoverURL": "http://www.bedetheque.com/media/Couvertures/Couv_15875.jpg",
"CoverURL": "https://www.bedetheque.com/media/Couvertures/Couv_15875.jpg",
"description": "",
"Note": 4,
"scenario": [
@@ -324,8 +328,8 @@
"\u003cBichromie\u003e"
],
"Links": {
"Veyron, Martin": "http://www.bedetheque.com/auteur-1491-BD-Veyron-Martin.html",
"\u003cBichromie\u003e": "http://www.bedetheque.com/auteur-6563-BD-Bichromie.html"
"Veyron, Martin": "https://www.bedetheque.com/auteur-1491-BD-Veyron-Martin.html",
"\u003cBichromie\u003e": "https://www.bedetheque.com/auteur-6563-BD-Bichromie.html"
},
"FetchDate": "0001-01-01T00:00:00Z"
},
@@ -344,7 +348,7 @@
"LegalDeposit": "2009-02-01T00:00:00Z",
"PrintDate": "2009-03-01T00:00:00Z",
"PurchaseDate": "2013-10-14T00:00:00Z",
"CoverURL": "http://www.bedetheque.com/media/Couvertures/84448_c.jpg",
"CoverURL": "https://www.bedetheque.com/media/Couvertures/84448_c.jpg",
"description": "À travers lhistoire dune frégate, devenez le témoin de lindépendance du peuple américain au siècle des lumières. En 1778, dans l'arsenal de Rochefort la frégate LHermione est mise en chantier daprès les plans de lingénieur Chevillard Aîné. Pendant près dun an, charpentiers, perceurs, calfats, forgerons et bagnards se relaient pour construire ce navire de près de 45 mètres, doté dune voilure de 1500 m2, de 26 canons pouvant tirer des boulets de 12 livres. En 1779, Gilbert Motier, marquis de La Fayette, cherche... Lire la suite",
"Note": 3.7,
"scenario": [
@@ -357,7 +361,7 @@
"Delitte, Jean-Yves"
],
"Links": {
"Delitte, Jean-Yves":"http://www.bedetheque.com/auteur-808-BD-Delitte-Jean-Yves.html"
"Delitte, Jean-Yves":"https://www.bedetheque.com/auteur-808-BD-Delitte-Jean-Yves.html"
},
"FetchDate": "0001-01-01T00:00:00Z"
},
@@ -376,7 +380,7 @@
"LegalDeposit": "2012-04-01T00:00:00Z",
"PrintDate": "0001-01-01T00:00:00Z",
"PurchaseDate": "2014-03-31T00:00:00Z",
"CoverURL": "http://www.bedetheque.com/media/Couvertures/Couv_160366.jpg",
"CoverURL": "https://www.bedetheque.com/media/Couvertures/Couv_160366.jpg",
"description": "Ralph, toujours accompagné par les magiciens Yassou et maître Migachi, a décidé de voler la couronne de Tanghor, dont le pouvoir pourrait rendre la mémoire à sa soeur. Il s'associe à trois voleurs rencontrés sur le bord de la route et se rend à Onophalae, où la couronne magique est conservée en haut d'un pic particulièrement bien protégé. Du moins pour le commun des mortels, car rien ne résiste aux méthodes non- conventionnelles de Ralph. De son côté, le père de Ralph, qui a survécu à l'effondrement du barrage, s'installe à... Lire la suite",
"Note": 4.1,
"scenario": [
@@ -389,8 +393,8 @@
"Findakly, Brigitte"
],
"Links": {
"Trondheim, Lewis": "http://www.bedetheque.com/auteur-145-BD-Trondheim-Lewis.html",
"Findakly, Brigitte": "http://www.bedetheque.com/auteur-1382-BD-Findakly-Brigitte.html"
"Trondheim, Lewis": "https://www.bedetheque.com/auteur-145-BD-Trondheim-Lewis.html",
"Findakly, Brigitte": "https://www.bedetheque.com/auteur-1382-BD-Findakly-Brigitte.html"
},
"FetchDate": "0001-01-01T00:00:00Z"
},
@@ -408,8 +412,8 @@
"ref": "MAX-2",
"LegalDeposit": "1993-05-01T00:00:00Z",
"PrintDate": "0001-01-01T00:00:00Z",
"PurchaseDate": "2013-09-03T00:00:00Z",
"CoverURL": "http://www.bedetheque.com/media/Couvertures/Couv_754.jpg",
"PurchaseDate": "2013-08-26T00:00:00Z",
"CoverURL": "https://www.bedetheque.com/media/Couvertures/Couv_754.jpg",
"description": "",
"Note": -1,
"scenario": [
@@ -419,7 +423,7 @@
"Bruyninx, Marc"
],
"Links": {
"Bruyninx, Marc": "http://www.bedetheque.com/auteur-17-BD-Bruyninx-Marc.html"
"Bruyninx, Marc": "https://www.bedetheque.com/auteur-17-BD-Bruyninx-Marc.html"
},
"FetchDate": "0001-01-01T00:00:00Z"
},
@@ -437,8 +441,8 @@
"ref": "YIU-5",
"LegalDeposit": "2005-11-01T00:00:00Z",
"PrintDate": "0001-01-01T00:00:00Z",
"PurchaseDate": "2013-09-04T00:00:00Z",
"CoverURL": "http://www.bedetheque.com/media/Couvertures/Couv_52100.jpg",
"PurchaseDate": "2013-08-25T00:00:00Z",
"CoverURL": "https://www.bedetheque.com/media/Couvertures/Couv_52100.jpg",
"description": "",
"Note": 4.4,
"scenario": [
@@ -452,9 +456,9 @@
"Guénet, Nicolas"
],
"Links" : {
"Téhy": "http://www.bedetheque.com/auteur-205-BD-Tehy.html",
"Vee, J.M.": "http://www.bedetheque.com/auteur-8231-BD-Vee-JM.html",
"Guénet, Nicolas": "http://www.bedetheque.com/auteur-2601-BD-Guenet-Nicolas.html"
"Téhy": "https://www.bedetheque.com/auteur-205-BD-Tehy.html",
"Vee, J.M.": "https://www.bedetheque.com/auteur-8231-BD-Vee-JM.html",
"Guénet, Nicolas": "https://www.bedetheque.com/auteur-2601-BD-Guenet-Nicolas.html"
},
"FetchDate": "0001-01-01T00:00:00Z"
}

View File

@@ -4,10 +4,12 @@
<meta charset="utf-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<link href="/bower_components/bootstrap/dist/css/bootstrap.min.css" rel="stylesheet" />
<link rel="icon" href="https://satellite.bar/images/sat.ico" />
<link href="/css/satbd.sateliite.bar.css" rel="stylesheet" />
<title>satbd: explorez la betheque de sat</title>
<!-- bower:css -->
<!-- endinject -->
<!-- inject:css -->
<!-- endinject -->
</head>
<body ng-app="satbd.satellite.bar">
<nav class="navbar navbar-inverse navbar-fixed-top">
@@ -46,12 +48,8 @@
<div class="container-fluid" ng-view>
</div>
<script src="/bower_components/angular/angular.min.js"></script>
<script src="/bower_components/angular-animate/angular-animate.min.js"></script>
<script src="/bower_components/angular-route/angular-route.min.js"></script>
<script src="/bower_components/angular-sanitize/angular-sanitize.min.js"></script>
<script src="/bower_components/angular-bootstrap/ui-bootstrap-tpls.min.js"></script>
<script src="/bower_components/angular-inview/angular-inview.js"></script>
<!-- bower:js -->
<!-- endinject -->
<!-- inject:js -->
<!-- endinject -->
</body>

View File

@@ -38,7 +38,7 @@ album.component('album', {
id: '<albumId',
ratio: '<'
}
})
});
album.controller('AlbumModalInstanceCtrl', function($scope,$uibModalInstance,album) {
$scope.album = album;
@@ -47,5 +47,5 @@ album.controller('AlbumModalInstanceCtrl', function($scope,$uibModalInstance,alb
};
$scope.getLink = function(n) {
return $scope.album[n];
}
};
});

View File

@@ -1,11 +1,11 @@
'use strict';
var controllers = angular.module('satbd.satellite.bar.controllers',[
'ui.bootstrap',
'ngAnimate'
]);
controllers.controller('NavBarCtrl',function($scope,$location,$uibModal) {
"use strict";
$scope.isCollapsed = true;
$scope.isActive = function(loc) {
return loc === $location.path();
@@ -15,7 +15,7 @@ controllers.controller('NavBarCtrl',function($scope,$location,$uibModal) {
if (searchTerms) {
$location.url('/search?q='+ encodeURIComponent(searchTerms));
}
}
};
$scope.openHelpModal = function () {
var modalInstance = $uibModal.open({

View File

@@ -1,5 +1,3 @@
'use strict';
angular.module('satbd.satellite.bar',[
'ngRoute',
'satbd.satellite.bar.controllers',
@@ -9,5 +7,7 @@ angular.module('satbd.satellite.bar',[
'satbd.satellite.bar.views.authors',
'satbd.satellite.bar.views.search'
]).config(function($routeProvider) {
'use strict';
$routeProvider.otherwise({redirectTo: '/recents'});
});

View File

@@ -1,4 +1,4 @@
var services = angular.module('satbd.satellite.bar.services',[])
var services = angular.module('satbd.satellite.bar.services',[]);
services.factory('albumService',['$http','$log','$q', function($http,$log,$q) {
var determinantRegexp = /^(.*) \(([Ll][eas']+)\)$/;
@@ -6,8 +6,8 @@ services.factory('albumService',['$http','$log','$q', function($http,$log,$q) {
var removeSerie = /^\(.*\) .*$/;
function cleanupName(name) {
matches = name.match(determinantRegexp);
if (matches == null) {
var matches = name.match(determinantRegexp);
if (matches === null) {
return name;
}
return matches[2] + ' ' + matches[1];
@@ -18,7 +18,7 @@ services.factory('albumService',['$http','$log','$q', function($http,$log,$q) {
album.série = undefined;
album.editeur = album.éditeur;
album.éditeur = undefined;
if (removeSerie.test(album.serie) == true) {
if (removeSerie.test(album.serie) === true) {
album.serieDisplay = '';
} else {
album.serieDisplay = cleanupName(album.serie);
@@ -64,7 +64,7 @@ services.factory('albumService',['$http','$log','$q', function($http,$log,$q) {
"query": terms
}
}).then(function(response) {
if ( fuzzify == true && response.data.total_hits == 0) {
if ( fuzzify === true && response.data.total_hits === 0) {
return search(fuzzifyTerms(terms),from,false,response.data.took);
}
return processResult(response.data,previousTime);

View File

@@ -1,9 +1,10 @@
'use strict';
angular.module('satbd.satellite.bar.views.authors',[
'ngRoute'
]).config(function($routeProvider) {
'use strict';
$routeProvider.when('/authors', {
templateUrl: 'js/views/authors/authors.html',
});
})
});

View File

@@ -1,15 +1,17 @@
'use strict';
angular.module('satbd.satellite.bar.views.recents',[
'ngRoute',
'satbd.satellite.bar.components.album',
'angular-inview'
]).config(function($routeProvider) {
'use strict';
$routeProvider.when('/recents', {
templateUrl: 'js/views/recents/recents.html',
controller: 'RecentsCtrl'
});
}).controller('RecentsCtrl', function( $scope, $http, $log) {
'use strict';
$scope.albumIDs = [];
$scope.allAlbums = [];
$scope.scrollMore = false;
@@ -29,13 +31,12 @@ angular.module('satbd.satellite.bar.views.recents',[
$log.info('Loading more components');
if (!$scope.scrollMore || $scope.albumIDs.length >= $scope.allAlbums.length) {
$scope.scrollMore = false;
$log.info('reached the end of albums')
$log.info('reached the end of albums');
return;
}
var newSize = Math.min($scope.albumIDs.length + batchSize, $scope.allAlbums.length);
for( var i = $scope.albumIDs.length; i < newSize; i++) {
$scope.albumIDs.push($scope.allAlbums[i]);
}
}
};
});

View File

@@ -1,5 +1,3 @@
'use strict';
angular.module('satbd.satellite.bar.views.search',[
'ngRoute',
'ngSanitize',
@@ -7,11 +5,15 @@ angular.module('satbd.satellite.bar.views.search',[
'satbd.satellite.bar.components.album',
'angular-inview'
]).config(function($routeProvider) {
'use strict';
$routeProvider.when('/search', {
templateUrl: 'js/views/search/search.html',
controller: 'SearchCtrl'
});
}).controller('SearchCtrl', function($scope,$routeParams,$log,$sce,albumService) {
'use strict';
$scope.terms=$routeParams.q;
$scope.scrollMore = false;
$scope.allHits = [];
@@ -43,14 +45,14 @@ angular.module('satbd.satellite.bar.views.search',[
};
$scope.inSecond= function(bleveValue) {
return bleveValue / 1e9;
}
return bleveValue / 1e6;
};
$scope.trustedFragment = function(f) {
return $sce.trustAsHtml(f);
}
};
$scope.round4Dec = function(value) {
return Math.round(value * 10000) / 10000;
}
};
});

View File

@@ -1,9 +1,9 @@
'use strict';
angular.module('satbd.satellite.bar.views.series',[
'ngRoute',
'satbd.satellite.bar.directives.responsive-ratio'
]).config(function($routeProvider) {
'use strict';
$routeProvider.when('/series', {
templateUrl: 'js/views/series/series.html'
});