Example #1
0
func StripDatabase(dbpath, flagStrip string) (err error) {
	err = util.CopyFile(dbpath, flagStrip)
	if err != nil {
		return
	}

	db, err := trans.NewDatabase(flagStrip)
	if err != nil {
		return
	}

	err = db.Strip()

	db.Close()

	return
}
Example #2
0
func CommitInstalled(pso2path string, patchlist *download.PatchList) error {
	scratch := PathScratch(pso2path)

	pathPatchlistInstalled := path.Join(scratch, PathPatchlistInstalled)
	f, err := os.Create(pathPatchlistInstalled)
	if err != nil {
		return err
	}
	err = patchlist.Write(f)
	f.Close()
	if err != nil {
		return err
	}

	pathVersionInstalled := path.Join(scratch, PathVersionInstalled)
	err = util.CopyFile(path.Join(scratch, PathVersion), pathVersionInstalled)

	return err
}
Example #3
0
func PatchFiles(db *trans.Database, pso2dir, translationName, backupPath, outputPath string, parallel int) (errs []error) {
	translation, err := db.QueryTranslation(translationName)
	if err == nil && translation == nil {
		err = errors.New("translation not found")
	}
	if err != nil {
		return []error{err}
	}

	archives, err := db.QueryArchivesTranslation(translation)
	if err != nil {
		return []error{err}
	}

	pbar := pb.New(len(archives))
	pbar.SetRefreshRate(time.Second / 10)
	pbar.Start()

	queue := make(chan *trans.Archive)
	done := make(chan bool)

	errlock := sync.Mutex{}

	complain := func(err error) bool {
		if err != nil {
			errlock.Lock()
			errs = append(errs, err)
			errlock.Unlock()
			return true
		}

		return false
	}

	for i := 0; i < parallel; i++ {
		go func() {
			for {
				a, ok := <-queue
				if !ok {
					break
				}

				aname := path.Join(pso2dir, a.Name.String())
				af, err := os.OpenFile(aname, os.O_RDONLY, 0)
				if complain(err) {
					continue
				}

				archive, err := ice.NewArchive(util.BufReader(af))
				if complain(err) {
					continue
				}

				files, err := db.QueryFiles(a)
				if complain(err) {
					continue
				}

				fileDirty := false

				var textfiles []*os.File
				for _, f := range files {
					tstrings, err := db.QueryTranslationStringsFile(translation, &f)
					if complain(err) || len(tstrings) == 0 {
						continue
					}

					strings := make([]*trans.String, len(tstrings))
					for i, ts := range tstrings {
						strings[i], err = db.QueryStringTranslation(&ts)
						complain(err)
					}

					file := archive.FindFile(-1, f.Name)
					if file == nil {
						if complain(errors.New(f.Name + ": file not found")) {
							continue
						}
					}
					textfile, err := text.NewTextFile(file.Data)

					collisions := make(map[string]int)

					for _, p := range textfile.Pairs {
						collision := collisions[p.Identifier]
						collisions[p.Identifier] = collision + 1

						var ts *trans.TranslationString
						for i, s := range strings {
							if s.Identifier == p.Identifier && s.Collision == collision {
								ts = &tstrings[i]
								break
							}
						}
						if ts == nil {
							continue
						}

						if p.String != ts.Translation {
							entry := textfile.PairString(&p)
							entry.Text = ts.Translation
							fileDirty = true
						}
					}

					tf, err := ioutil.TempFile("", "")
					if complain(err) {
						continue
					}

					writer := bufio.NewWriter(tf)
					err = textfile.Write(writer)
					writer.Flush()
					if complain(err) {
						tf.Close()
						os.Remove(tf.Name())
						continue
					}
					pos, _ := tf.Seek(0, 1)
					tf.Seek(0, 0)

					archive.ReplaceFile(file, tf, uint32(pos))
					textfiles = append(textfiles, tf)
				}

				if fileDirty {
					ofile, err := ioutil.TempFile("", "")

					aname := path.Join(outputPath, a.Name.String())

					if !complain(err) {
						backupPath := backupPath
						if archive.IsModified() {
							backupPath = ""
						}

						writer := bufio.NewWriter(ofile)
						err = archive.Write(writer)
						writer.Flush()
						ofile.Close()

						if backupPath != "" {
							opath := path.Join(backupPath, path.Base(aname))
							err = os.Rename(aname, opath)
							if err != nil {
								err = util.CopyFile(aname, opath)
							}
						}

						if complain(err) {
							os.Remove(ofile.Name())
						} else {
							err = os.Rename(ofile.Name(), aname)
							if err != nil {
								err = util.CopyFile(ofile.Name(), aname)
								os.Remove(ofile.Name())
							}
							complain(err)
						}
					}
				}

				for _, tf := range textfiles {
					tf.Close()
					os.Remove(tf.Name())
				}

				af.Close()

				pbar.Increment()
			}

			done <- true
		}()
	}

	for i := range archives {
		queue <- &archives[i]
	}
	close(queue)

	for i := 0; i < parallel; i++ {
		<-done
	}

	pbar.Finish()

	return
}