multistockphoto 0.8.0 → 0.8.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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