multistockphoto 0.8.0 → 0.8.1

Sign up to get free protection for your applications and to get access to all the features.
data/History.txt CHANGED
@@ -1,3 +1,10 @@
1
+ == 0.8.1 2008-12-30
2
+ * 1 enhancement
3
+ * doppelte Tags in Datei nicht mehrfach zaehlen
4
+ * photocase: bessere Fehleranalyse, falls Upload-Fehler
5
+ * 1 bugfix
6
+ * Anpassung an neue Syntax beim mechanize gem in site_* Dateien
7
+
1
8
  == 0.8.0 2008-06-28
2
9
  * 1 major enhancement
3
10
  * neue Site Bigstockphoto erstellt
@@ -9,9 +16,11 @@
9
16
  * Optimierungen in bin/multistockphoto
10
17
  * 1 bug fix
11
18
  * --stats Fehler bei deaktivierten Sites behoben
19
+
12
20
  == 0.7.1 2008-06-16
13
21
  * 1 bug fix
14
22
  * entfernen von ueberfluessiger aldi-site fuehrte anderweitig zu Fehler
23
+
15
24
  == 0.7.0 2008-06-16
16
25
  * 1 major enhancement
17
26
  * neue Site Dreamstime erstellt
data/Manifest.txt CHANGED
@@ -22,6 +22,7 @@ lib/multistockphoto/mock_zoonar.rb
22
22
  lib/multistockphoto/site_photocase.rb
23
23
  lib/multistockphoto/site_dreamstime.rb
24
24
  lib/multistockphoto/site_bigstockphoto.rb
25
+ lib/multistockphoto/site_panthermedia.rb
25
26
  lib/multistockphoto/photo.rb
26
27
  lib/multistockphoto/upload_exception.rb
27
28
  script/console
data/bin/multistockphoto CHANGED
@@ -12,13 +12,16 @@ include Grep
12
12
  SENDELISTE = 'sendeliste.dat'
13
13
  ROT_PREFIX = 'rot_'
14
14
  MAX_ERRORS = 3
15
- PICTURE_FILES = /(.PNG|.JPG|.GIF|.JPEG|.EPS|.AI|.PSD|.PDF|.TIF|.TIFF)$/
15
+ PICTURE_FILES = /(.PNG|.JPG|.JPEG|.GIF|.EPS|.AI|.PSD|.PDF|.TIF|.TIFF)$/
16
16
 
17
17
  require 'fcntl'
18
18
 
19
19
  #STDOUT.sync = true
20
20
  #STDOUT.fcntl(Fcntl::F_SETFL, Fcntl::O_NONBLOCK)
21
21
 
22
+ require 'logger'
23
+ $log = Logger.new('multistockphoto.log', 'daily', 30)
24
+
22
25
  # alle Sites komplett bearbeitet?
23
26
  def all_sites_done(sites,n)
24
27
  #p sites
@@ -165,6 +168,15 @@ Choice.options do
165
168
  end
166
169
  end
167
170
 
171
+ option :silent do
172
+ short '-c'
173
+ long '--silent'
174
+ desc 'No output at list-done and purge-done'
175
+ action do
176
+ $silent = true
177
+ end
178
+ end
179
+
168
180
  option :ordered do
169
181
  short '-o' #TODO: geht das?
170
182
  long '--ordered'
@@ -186,9 +198,9 @@ Choice.options do
186
198
  end
187
199
 
188
200
  option :count do
189
- short '-3'
201
+ short '-b'
190
202
  long '--count'
191
- desc 'count'
203
+ desc 'Count - only photo with at least N tags'
192
204
  cast Integer
193
205
  default 0
194
206
  action do
@@ -197,14 +209,32 @@ Choice.options do
197
209
  end
198
210
 
199
211
  option :plist do
200
- short '-2'
212
+ short '-d'
201
213
  long '--plist'
202
- desc 'Show details sending status for each picture'
214
+ desc 'Show detailed sending state for each picture'
203
215
  action do
204
216
  $plist = true
205
217
  end
206
218
  end
207
219
 
220
+ option :check_translation do
221
+ short '-e'
222
+ long '--check-translation'
223
+ desc 'Checks if translation can be done for all tags'
224
+ action do
225
+ $check_translation = true
226
+ end
227
+ end
228
+
229
+ option :shuffle do
230
+ short '-f'
231
+ long '--shuffle'
232
+ desc 'Shuffle order of files (sending)'
233
+ action do
234
+ $shuffle = true
235
+ end
236
+ end
237
+
208
238
  option :dont_send do
209
239
  long '--dont-send'
210
240
  action do
@@ -243,7 +273,7 @@ def not_enough_tags?(photo)
243
273
  else
244
274
  if $count_flag
245
275
  photo.set_keywords
246
- if photo.tags.size < $count
276
+ if photo.tags.uniq.size < $count
247
277
  return true
248
278
  end
249
279
  end
@@ -284,6 +314,9 @@ def send_all
284
314
  if $ordered
285
315
  allfiles.sort!
286
316
  end
317
+ if $shuffle
318
+ allfiles = allfiles.sort_by { rand }
319
+ end
287
320
  allfiles.each {|filename|
288
321
  next if File.basename(filename)[0,4] == ROT_PREFIX
289
322
  #puts "rot_ uebersprungen"
@@ -291,69 +324,96 @@ def send_all
291
324
  total_per_site_flag = $total_per_site
292
325
  photo = Photo.new(filename)
293
326
  next if not_enough_tags? photo
327
+ # threads = []
294
328
  $active_sites.each {|site_name|
295
- begin
296
- Timeout::timeout(10.0*60.0) do
297
- t1 = Time.now
298
- site = eval(site_name.to_s.capitalize+".new(#{site_name.to_s.capitalize})")
299
- # if ! site.accept?(File.extname(filename))
300
- # warn "Warning: Site (#{site_name}) does not support this file extension (#{File.extname(filename)}). Skipped"
301
- # next
302
- # end
303
- # site.rotate_photos = rotate_photos[site_name]
304
- done[site_name] = true if remaining[site_name] <= 0
305
- next if done[site_name]
329
+ # TODO:
330
+ # Bevor man Threads nutzt, muß man sicherstellen, dass das Rotieren
331
+ # von Bildern abeschlossen ist, bevor ein anderer Thread auf das
332
+ # rotierte Bilde zugreift
333
+ #threads << Thread.new(site_name) { |site_name|
334
+ #print "Thread #{site_name} gestartet\n"
335
+ #Thread.current["threadname"] = site_name.to_s
336
+ begin
337
+ Timeout::timeout(10.0*60.0) do
338
+ t1 = Time.now
339
+ site = eval(site_name.to_s.capitalize+".new(#{site_name.to_s.capitalize})")
340
+ done[site_name] = true if remaining[site_name] <= 0
341
+ next if done[site_name]
306
342
 
307
- if ! site.accept?(File.extname(filename))
308
- warn "Warning: Site (#{site_name}) does not support this file extension (#{File.extname(filename)}). Skipped"
309
- next
310
- end
311
- #end
312
- if $send_all or
313
- (total_per_site_flag and
314
- total[site_name] < Choice.choices[:total_per_site])
315
- if !site.already_sent?(photo)
316
- begin
317
- result = site.transfer(photo,$dont_send,$dont_log)
318
- if result != :duplicate
319
- total_transfers += 1
320
- total[site_name] += 1
321
- remaining[site_name] -= 1
322
- done[site_name] = true if remaining[site_name] <= 0
323
- errors[site_name] = 0
324
- t2 = Time.now
325
- if $verbose
326
- if $dont_send and $dont_log
327
- puts "1:23"
328
- else
329
- puts formatted_minutes(t2-t1)
343
+ if ! site.accept?(File.extname(filename))
344
+ warn "Warning: Site (#{site_name}) does not support this file extension (#{File.extname(filename)}). Skipped"
345
+ next
346
+ end
347
+ if ! site.photosize_valid?(photo)
348
+ warn "Warning: filesize for #{photo.filename} not valid for site #{site_name}"
349
+ next
350
+ end
351
+ #end
352
+ if $send_all or
353
+ (total_per_site_flag and
354
+ total[site_name] < Choice.choices[:total_per_site])
355
+ if !site.already_sent?(photo)
356
+ begin
357
+ result = site.transfer(photo,$dont_send,$dont_log)
358
+ if result != :duplicate
359
+ total_transfers += 1
360
+ total[site_name] += 1
361
+ remaining[site_name] -= 1
362
+ done[site_name] = true if remaining[site_name] <= 0
363
+ errors[site_name] = 0
364
+ t2 = Time.now
365
+ if $verbose
366
+ if $dont_send and $dont_log
367
+ puts "1:23"
368
+ else
369
+ puts formatted_minutes(t2-t1)
370
+ end
371
+ p total # Summenzeile ausgeben
330
372
  end
331
- p total # Summenzeile ausgeben
332
373
  end
333
- end
334
- rescue UploadException
335
- errors[site_name] += 1
336
- if errors[site_name] >= MAX_ERRORS
337
- done[site_name] = true
338
- puts "too many errors. giving up."
339
- end
340
- puts "Upload error at sending to #{site_name} occurred. Check configuration or try again later!"
341
- rescue Timeout::Error
342
- puts "timeout error"
343
- #timeout error
344
- errors[site_name] += 1
345
- if errors[site_name] >= MAX_ERRORS
346
- done[site_name] = true
347
- puts "too many errors. giving up."
374
+ # TODO: SocketError nur experimentell
375
+ rescue SocketError
376
+ print "SocketError - ignore and sleep 30 seconds"
377
+ sleep 30
378
+ errors[site_name] += 1
379
+ if errors[site_name] >= MAX_ERRORS
380
+ done[site_name] = true
381
+ puts "too many errors. giving up."
382
+ end
383
+ puts "Upload error at sending to #{site_name} occurred. Check configuration or try again later!"
384
+ rescue UploadException
385
+ errors[site_name] += 1
386
+ if errors[site_name] >= MAX_ERRORS
387
+ done[site_name] = true
388
+ puts "too many errors. giving up."
389
+ end
390
+ puts "Upload error at sending to #{site_name} occurred. Check configuration or try again later!"
391
+ rescue Timeout::Error
392
+ puts "timeout error"
393
+ #timeout error
394
+ errors[site_name] += 1
395
+ if errors[site_name] >= MAX_ERRORS
396
+ done[site_name] = true
397
+ puts "too many errors. giving up."
398
+ end
348
399
  end
349
400
  end
401
+ break if result != :duplicate && total_transfers >= Choice.choices[:total_transfers]
402
+ break if all_sites_done(total,Choice.choices[:total_per_site])
350
403
  end
351
- break if result != :duplicate && total_transfers >= Choice.choices[:total_transfers]
352
- break if all_sites_done(total,Choice.choices[:total_per_site])
353
- end
354
- end # Timeout
355
- end # timeout
356
- }
404
+ end # Timeout
405
+ end # timeout
406
+ #} # Thread
407
+
408
+ } # alle Sites
409
+ #print "warte auf Beendigung aller Threads ...\n"
410
+ #
411
+ #threads.each {|thr|
412
+ # print "warte auf Thread "+thr.to_s+" "+thr["threadname"]+"\n"
413
+ # $stdout.flush
414
+ # thr.join
415
+ #}
416
+
357
417
  end
358
418
  }
359
419
  puts "#{total_transfers} photos sent."
@@ -429,7 +489,7 @@ def stats
429
489
  end
430
490
  }
431
491
  }
432
- print " "*11+"| "
492
+ print " "*14+"| "
433
493
  $active_sites.each {|site|
434
494
  print "#{site.to_s}"
435
495
  print " | "
@@ -440,7 +500,11 @@ def stats
440
500
  10.times do |i|
441
501
  chosen_date = today - i
442
502
  total = 0
443
- print chosen_date.to_s+" | "
503
+ # print chosen_date.to_s+" | "
504
+ print sprintf("%2s %04d-%02d-%02d",%w{ So Mo Di Mi Do Fr Sa}[chosen_date.wday],
505
+ chosen_date.year,
506
+ chosen_date.month,
507
+ chosen_date.day)+" | "
444
508
  $active_sites.each {|site|
445
509
  key = [site.to_s, chosen_date]
446
510
  fmt = "%#{site.to_s.length}d | "
@@ -463,7 +527,7 @@ def stats
463
527
  end
464
528
  all += v
465
529
  }
466
- print "total | "
530
+ print "total | "
467
531
  $active_sites.each {|site|
468
532
  fmt = "%#{site.to_s.length}d | "
469
533
  printf(fmt, (totals[site] || 0))
@@ -510,7 +574,7 @@ def list_done
510
574
  }
511
575
  end
512
576
  unless photo_sent.has_value?(false)
513
- puts "#{filename} sent to all sites"
577
+ puts "#{filename} sent to all sites"+" "*20 unless $silent
514
578
  end
515
579
  }
516
580
  end
@@ -532,7 +596,7 @@ end
532
596
  # dort koennen sie entweder geloescht oder archiviert werden
533
597
  # Es schadet aber auch nicht, wenn dieser Schritt nie ausgefuehrt wird.
534
598
  def purge_done
535
- puts 'purge_done'
599
+ puts 'purge_done' unless $silent
536
600
  Dir.glob(File.join($upload_dir,'*')).each {|filename|
537
601
  photo_sent = {}
538
602
  $active_sites.each {|site|
@@ -549,15 +613,16 @@ def purge_done
549
613
  }
550
614
  end
551
615
  unless photo_sent.has_value?(false)
552
- puts "#{filename} sent to all sites"
616
+ puts "#{filename} sent to all sites" unless $silent
553
617
  if !File.exist? $done_dir
554
618
  FileUtils.mkdir $done_dir
555
619
  end
556
- puts "mv #{filename} done/#{File.basename filename}"
557
- FileUtils.mv filename, $done_dir+"/"
620
+ puts "mv #{filename} done/#{File.basename filename}" unless $silent
621
+ FileUtils.mv(filename, File.join($done_dir,File.basename(filename)))
558
622
  if tagsfile?(filename)
559
- puts "mv #{tagsfilename(filename)} done/#{File.basename(tagsfilename(filename))}"
560
- FileUtils.mv(tagsfilename(filename), $done_dir+"/")
623
+ puts "mv #{tagsfilename(filename)} done/#{File.basename(tagsfilename(filename))}" unless $silent
624
+ FileUtils.mv(tagsfilename(filename),
625
+ File.join($done_dir,File.basename(tagsfilename(filename))))
561
626
  end
562
627
  end
563
628
  }
@@ -582,8 +647,8 @@ def no_tags
582
647
  if $count_flag
583
648
  photo = Photo.new(fn)
584
649
  photo.set_keywords_without_write
585
- if photo.tags.size < $count
586
- puts fn + " only #{photo.tags.size} keywords"
650
+ if photo.tags.uniq.size < $count
651
+ puts fn + " only #{photo.tags.uniq.size} keywords"
587
652
  end
588
653
  end
589
654
  end
@@ -609,7 +674,7 @@ def plist
609
674
  photo.set_keywords_without_write
610
675
  printf("%-30s ",filename)
611
676
  if tagsfile?(filename)
612
- printf "(t %2d) ", photo.tags.size
677
+ printf "(t %2d) ", photo.tags.uniq.size
613
678
  else
614
679
  print ' '
615
680
  end
@@ -626,6 +691,24 @@ def plist
626
691
  }
627
692
  end
628
693
 
694
+ # Testet, ob für jedes Tag in jeder tags-Datei eine Übersetzung existiert.
695
+ def check_translation
696
+ allfiles = Dir.glob(File.join($upload_dir,'*'))
697
+ if $ordered
698
+ allfiles.sort!
699
+ end
700
+ allfiles.each {|fn|
701
+ next if File.basename(fn)[0,4] == ROT_PREFIX
702
+ if fn.upcase =~ PICTURE_FILES
703
+ if tagsfile?(fn)
704
+ photo = Photo.new(fn)
705
+ photo.set_keywords_without_write(:de,:en) #TODO: später noch flexibler machen!
706
+ end
707
+
708
+ end
709
+ }
710
+ end
711
+
629
712
  if $send_all or $total_per_site
630
713
  send_all
631
714
  end
@@ -662,3 +745,7 @@ end
662
745
  if $plist
663
746
  plist
664
747
  end
748
+
749
+ if $check_translation
750
+ check_translation
751
+ end
@@ -5,6 +5,9 @@ begin
5
5
  require 'rubygems'
6
6
  rescue LoadError
7
7
  end
8
+ #gem 'wxruby', "1.9.7"
9
+ #require 'wx'
10
+ gem 'wxruby', "!=1.9.8"
8
11
  require 'wx'
9
12
 
10
13
  # This sample shows a fairly minimal Wx::App using a Frame, with a
@@ -19,6 +22,7 @@ class MinimalFrame < Wx::Frame
19
22
  Id_purge_done = 2003
20
23
  Id_no_tags = 2004
21
24
  Id_not_sent = 2005
25
+ Id_random = 2006
22
26
 
23
27
  def initialize(title)
24
28
  # The main application frame has no parent (nil)
@@ -43,6 +47,7 @@ class MinimalFrame < Wx::Frame
43
47
  menu_actions.append(Id_send_all,"Send all photos")
44
48
  menu_actions.append(Id_list_done,"List all done photos")
45
49
  menu_actions.append(Id_purge_done,"Purge all done photos")
50
+ menu_actions.append(Id_random,"Random")
46
51
  menu_bar.append(menu_actions, "Actions")
47
52
 
48
53
  #multistockphoto - admin
@@ -70,6 +75,7 @@ class MinimalFrame < Wx::Frame
70
75
  evt_menu Id_list_done, :on_list_done
71
76
  evt_menu Id_no_tags, :on_no_tags
72
77
  evt_menu Id_not_sent, :on_not_sent
78
+ evt_menu Id_random, :on_random
73
79
  end
74
80
 
75
81
  # End the application; it should finish automatically when the last
@@ -96,6 +102,35 @@ class MinimalFrame < Wx::Frame
96
102
  self.status_text = "done uploading all photos"
97
103
  end
98
104
 
105
+ def on_random
106
+ puts 'random'
107
+ self.status_text = "select a random picture"
108
+ all = Dir.glob("upload/*.JPG")
109
+ while true
110
+ r = all[rand(all.size)]
111
+ b = File.basename(r,".JPG")
112
+ p b
113
+ t = File.join("upload", b)+".tags"
114
+ p t
115
+ if b[0...4] == 'rot_'
116
+ puts "nur rotierte Datei"
117
+ elsif File.exist? t
118
+ puts "tags-File existiert schon"
119
+ else
120
+ Thread.start do
121
+ `eog #{r}`
122
+ end
123
+ Thread.start do
124
+ `gedit #{t}`
125
+ end
126
+ break # wir haben eine gefunden
127
+ end
128
+ end
129
+
130
+ # puts `ruby random.rb`
131
+ self.status_text = "done random"
132
+ end
133
+
99
134
  def on_list_done
100
135
  self.status_text = "list-done"
101
136
  result = `multistockphoto --list-done`
@@ -149,4 +184,4 @@ Wx::App.run do
149
184
  self.app_name = 'Minimal'
150
185
  frame = MinimalFrame.new("multistockphoto")
151
186
  frame.show
152
- end
187
+ end
data/config.yaml CHANGED
@@ -5,6 +5,7 @@
5
5
  - :photocase
6
6
  - :dreamstime
7
7
  - :bigstockphoto
8
+ - :panthermedia
8
9
  :zoonar:
9
10
  :user: 'hugo'
10
11
  :password: 'lalala'
@@ -31,3 +32,9 @@
31
32
  :ftp_user: 'dennis12345'
32
33
  :ftp_password: 'ftpgeheimdennis'
33
34
  :total_per_day: 1
35
+ :panthermedia:
36
+ :user: 'iris'
37
+ :password: 'irisgeheim'
38
+ :ftp_user: 'irisftp'
39
+ :ftp_password: 'irisftpgeheim'
40
+ :total_per_day: 1de
@@ -8,6 +8,10 @@ class GenericSite
8
8
  def initialize(name)
9
9
  @name = name
10
10
  @max_errors = MAX_ERRORS
11
+ unless File.exist?(SENDLIST)
12
+ warn "File #{SENDLIST} does not exist - creating empty file"
13
+ File.open(SENDLIST,"w"){|file|}
14
+ end
11
15
  end
12
16
 
13
17
  def photos_fuer_heute_uebrig?
@@ -30,6 +34,11 @@ class GenericSite
30
34
  return g.size > 0
31
35
  end
32
36
 
37
+ # Groesse der Datei gueltig fuer die Site, auch in Verbindung mit File-Typ
38
+ def photosize_valid?(photo)
39
+ true
40
+ end
41
+
33
42
  protected
34
43
 
35
44
  def sent_today_site(p_site)
@@ -37,8 +46,11 @@ class GenericSite
37
46
  count = {}
38
47
  File.open(SENDLIST) {|f|
39
48
  f.each_line {|line|
49
+ #TODO: leere Zeilen ignorieren
40
50
  site, photo_file, time = line.chomp.split("\t")
41
- date = Date.parse(time)
51
+
52
+ date = Date.parse(time)
53
+
42
54
  key = [site, date]
43
55
  if count[key]==nil
44
56
  count[key] = 1