diff --git a/kadai3-1/InoAyaka/README.md b/kadai3-1/InoAyaka/README.md new file mode 100644 index 0000000..5f5a170 --- /dev/null +++ b/kadai3-1/InoAyaka/README.md @@ -0,0 +1,55 @@ +# <課題3-1>【TRY】タイピングゲームを作ろう +## 概要 + +- 標準出力に英単語を出す(出すものは自由) +- 標準入力から1行受け取る +- 制限時間内に何問解けたか表示する + + +## 使い方 +``` +$ go build -o typing +$ +$ ./typing -h +Usage of ./typing: + -t int + time limit(unit:seconds) (default 30) +$ +$ +``` + +実行例 +``` +$ ./typing -t 15 +society +society +ability +ablity +bless +bless +anybody +anybody +title +title +understand +understand +commercial +commercial +表示 入力 (一致) +--------------------------------------------------------------------------- +society society (◯) +ability ablity (×) +bless bless (◯) +anybody anybody (◯) +title title (◯) +understand understand (◯) +commercial commercial (◯) +--------------------------------------------------------------------------- +7問中 6問 (85.71 %) +--------------------------------------------------------------------------- +``` + +### 感想 + +- 前回の課題にあったテストのしやすさを考慮したコードをいかに書くかに悩みました +- 課題3-2に比べると、難しい課題ではないように感じたが、いざ書いてみると読みやすく書くにはどうしたら良いか悩んだ部分も多かった diff --git a/kadai3-1/InoAyaka/go.mod b/kadai3-1/InoAyaka/go.mod new file mode 100644 index 0000000..3e58c44 --- /dev/null +++ b/kadai3-1/InoAyaka/go.mod @@ -0,0 +1,3 @@ +module github.com/gopherdojo/dojo8/kadai3-1/InoAyaka + +go 1.14 diff --git a/kadai3-1/InoAyaka/typing.go b/kadai3-1/InoAyaka/typing.go new file mode 100644 index 0000000..0672a69 --- /dev/null +++ b/kadai3-1/InoAyaka/typing.go @@ -0,0 +1,174 @@ +package main + +import ( + "bufio" + "flag" + "fmt" + "io" + "math/rand" + "os" + "strings" + "time" +) + +type word string +type words []word + +var errOut io.Writer = os.Stderr +var out io.Writer = os.Stdout + +//オプション指定 +var t = flag.Int("t", 30, "time limit(unit:seconds)") + +type result struct { + word word + input string + match bool +} + +func main() { + flag.Parse() + + //出力する英単語リストの取得 + words, err := getWords() + if err != nil { + fmt.Fprintf(errOut, err.Error()) + os.Exit(1) + } + + //結果を記録するための構造体 + rs := make([]result, 0, 100) + //結果をやり取りするためのチャネル + ch := make(chan result) + //時間の設定 + tm := time.After(time.Duration(*t) * time.Second) + + //MEMO:引数のresultは、スライスのためアドレスを渡すことはしない + go do(&words, ch) + +LOOP: + for { + select { + case r := <-ch: + rs = append(rs, r) + case <-tm: + //結果を表示 + printResult(rs) + //close(abort) + break LOOP + } + } + +} + +//getWords 英単語のリストを取得します +func getWords() (words, error) { + wordsFile := "./words.txt" + + words := make(words, 0, 2000) + + f, err := os.Open(wordsFile) + if err != nil { + return nil, err + } + + defer f.Close() + + scanner := bufio.NewScanner(f) + for scanner.Scan() { + line := scanner.Text() + words = append(words, word(line)) + } + + if scanner.Err() != nil { + return nil, err + } + + return words, nil +} + +//do 英単語の表示、入力結果の送信を行います +func do(words *words, ch chan<- result) { + for { + //標準出力にランダムで1単語出力する + word := printWord(words) + + input, err := getInput() + if err != nil { + fmt.Fprintf(errOut, err.Error()) + os.Exit(1) + } + + ch <- result{ + word: word, + input: input, + match: string(word) == input, + } + } + +} + +//printWord ランダムで英単語を出力します +func printWord(words *words) word { + //ランダムで出力するために、乱数を作成 + t := time.Now().UnixNano() + rand.Seed(t) + + //indexを指定して取得するため、len(words)までを上限とする + s := rand.Intn(len(*words)) + + fmt.Fprintln(out, (*words)[s]) + return (*words)[s] +} + +//getInput 標準入力から1行読み込みます +func getInput() (string, error) { + scanner := bufio.NewScanner(os.Stdin) + + //読み込み失敗を5回繰り返したら、エラーを返す + var input string + + for errCnt := 0; errCnt < 5; { + scanner.Scan() + input = scanner.Text() + + if err := scanner.Err(); err != nil { + errCnt++ + fmt.Fprintf(errOut, "読み込みに失敗しました(%d回目): %v", errCnt+1, err) + } else { + //問題なく読み込めた場合、読み込み結果を返す + return input, nil + } + } + return input, fmt.Errorf("読み込みに5回連続で失敗しました") +} + +//printResult 結果の表示を行います +func printResult(rs []result) { + var matchCnt int + + //入力途中でタイムアウトした場合を考慮し、改行を追加しておく + fmt.Fprintln(out) + fmt.Fprintf(out, "%-20s %-20s (%s)\n", "表示", "入力", "一致") + fmt.Fprintln(out, strings.Repeat("-", 75)) + + for _, r := range rs { + var m string + + switch { + case r.match: + m = "◯" + matchCnt++ + case !r.match: + m = "×" + } + + fmt.Fprintf(out, "%-20s %-20s (%s)\n", r.word, r.input, m) + } + + matchRate := float64(matchCnt) / float64(len(rs)) * 100 + + fmt.Fprintln(out, strings.Repeat("-", 75)) + fmt.Fprintf(out, "%d問中 %d問 (%.2f %%)\n", len(rs), matchCnt, matchRate) + fmt.Fprintln(out, strings.Repeat("-", 75)) +} diff --git a/kadai3-1/InoAyaka/words.txt b/kadai3-1/InoAyaka/words.txt new file mode 100644 index 0000000..fe113e2 --- /dev/null +++ b/kadai3-1/InoAyaka/words.txt @@ -0,0 +1,2000 @@ +a +ability +able +about +above +abroad +absence +absent +absolute +accept +accident +accord +account +accuse +accustom +across +act +action +active +actor +actual +add +address +admire +admission +admit +adopt +advance +advantage +adventure +advertise +advice +advise +affair +afford +afraid +after +afternoon +again +against +age +agency +agent +ago +agree +agriculture +ahead +aim +air +airplane +alike +alive +all +allow +allowance +almost +alone +along +already +also +although +altogether +always +ambition +ambitious +among +amount +amuse +ancient +and +anger +angle +angry +animal +annoy +another +answer +anxiety +anxious +any +anybody +anyhow +anyone +anything +anyway +anywhere +apart +appear +appearance +application +apply +appoint +approve +arch +argue +arise +arm +army +around +arrange +arrest +arrive +arrow +art +article +artificial +as +ash +ashamed +aside +ask +asleep +association +astonish +at +attack +attempt +attend +attention +attract +attraction +attractive +audience +aunt +autumn +avenue +average +avoid +awake +away +awkward +axe +baby +back +backward +bad +bag +bake +balance +ball +band +bank +bar +bare +bargain +barrel +base +basic +basis +basket +bath +bathe +battle +bay +be +beam +bear +beard +beat +beauty +because +become +bed +bedroom +before +beg +begin +behave +behavior +behind +being +belief +believe +bell +belong +below +belt +bend +beneath +beside +besides +best +better +between +beyond +big +bill +bind +bird +birth +bit +bite +bitter +black +blade +blame +bleed +bless +blind +block +blood +blow +blue +board +boast +boat +body +boil +bold +bone +book +border +borrow +both +bottle +bottom +bound +boundary +bow +bowl +box +boy +brain +branch +brass +brave +bread +break +breakfast +breath +breathe +brick +bridge +bright +bring +broad +broadcast +brother +brown +brush +build +bunch +bundle +burn +burst +bury +bus +bush +business +businessman +busy +but +butter +button +buy +by +cake +calculate +calculation +call +calm +camera +camp +can +cap +cape +capital +captain +car +card +care +carriage +carry +case +cat +catch +cattle +cause +caution +cautious +cave +cent +center +century +ceremony +certain +certainty +chain +chair +chairman +chance +change +character +charge +charm +cheap +check +cheer +chest +chicken +chief +child +childhood +choice +choose +Christmas +church +circle +circular +citizen +city +civilize +claim +class +classification +classify +clay +clean +clear +clerk +clever +climb +clock +close +cloth +clothe +cloud +club +coal +coast +coat +coffee +coin +cold +collar +collect +collection +collector +college +colony +color +combine +come +comfort +command +commerce +commercial +committee +common +companion +company +compare +comparison +compete +competition +complain +complaint +complete +completion +complicate +compose +composition +concern +condition +confess +confession +confidence +confident +confuse +confusion +connect +connection +conscience +conscious +consider +contain +content +continue +control +convenience +convenient +conversation +cook +cool +copy +corn +corner +correct +cost +cottage +cotton +could +council +count +country +courage +course +court +cousin +cover +cow +crack +crash +cream +creature +creep +crime +criminal +critic +crop +cross +crowd +crown +cruel +crush +cry +cultivate +cup +cure +curious +curl +current +curse +curtain +curve +custom +customary +customer +cut +daily +damage +damp +dance +danger +dare +dark +date +daughter +day +daylight +dead +deal +dear +death +debt +decay +decide +decision +decisive +declare +decrease +deed +deep +defeat +defend +defendant +defense +degree +delay +delicate +delight +deliver +delivery +demand +department +depend +dependence +dependent +depth +descend +describe +description +desert +deserve +desire +desk +despair +destroy +destruction +destructive +detail +determine +develop +devil +dictionary +die +difference +different +difficult +difficulty +dig +dine +dinner +dip +direct +direction +director +dirt +disagree +disappear +disappoint +disapprove +discipline +discover +discovery +discuss +discussion +disease +dish +dismiss +distance +distant +distinguish +district +disturb +dive +divide +division +do +doctor +dog +dollar +door +dot +double +doubt +down +dozen +drag +draw +dream +dress +drink +drive +drop +drum +dry +duck +due +dull +during +dust +duty +each +eager +ear +early +earn +earnest +earth +ease +east +eastern +easy +eat +edge +educate +education +educator +effect +effective +efficiency +efficient +effort +egg +either +elder +elect +election +electric +elephant +else +elsewhere +empire +employ +employee +empty +encourage +end +enemy +engine +engineer +English +enjoy +enough +enter +entertain +entire +entrance +envelope +envy +equal +escape +especially +essence +essential +even +evening +event +ever +every +everybody +everyone +everything +everywhere +evil +exact +examine +example +excellent +except +exception +excess +excessive +exchange +excite +excuse +exercise +exist +existence +expect +expense +expensive +experience +experiment +explain +explode +explore +explosion +explosive +express +expression +extend +extension +extensive +extent +extra +extraordinary +extreme +eye +face +fact +factory +fade +fail +failure +faint +fair +faith +fall +false +fame +familiar +family +fan +fancy +far +farm +fashion +fast +fasten +fat +fate +father +fault +favor +favorite +fear +feather +feed +feel +fellow +fellowship +female +fence +fever +few +field +fight +figure +fill +film +find +fine +finger +finish +fire +firm +first +fish +fit +fix +flag +flame +flash +flat +flavor +flesh +float +flood +floor +flow +flower +fly +fold +follow +fond +food +fool +foot +for +forbid +force +foreign +forest +forget +forgive +fork +form +formal +former +forth +fortunate +fortune +forward +frame +free +freedom +freeze +frequency +frequent +fresh +friend +friendly +friendship +frighten +from +front +fruit +full +fun +funeral +funny +fur +furnish +furniture +further +future +gain +game +gap +garage +garden +gas +gate +gather +gay +general +generous +gentle +gentleman +get +gift +girl +give +glad +glass +glory +go +god +gold +golden +good +govern +governor +grace +gradual +grain +grand +grass +grateful +grave +gray +grease +great +green +greet +grind +ground +group +grow +growth +guard +guess +guest +guide +guilt +gun +habit +hair +half +hall +hand +handle +hang +happen +happy +harbor +hard +hardly +harm +harvest +haste +hat +hate +hatred +have +hay +he +head +heal +health +heap +hear +heart +heat +heaven +heavy +height +help +here +hesitate +hide +high +highway +hill +hire +history +hit +hold +hole +holiday +holy +home +honest +honor +hope +horizon +horse +hospital +host +hot +hotel +hour +house +how +however +human +humble +hunger +hunt +hurry +hurt +husband +hut +I +ice +idea +ideal +idle +if +ill +imaginary +imagine +imitation +immediate +immense +importance +important +impossible +improve +in +inch +include +increase +indeed +industry +influence +inform +inquire +inquiry +insect +inside +instant +instead +instrument +insult +insurance +insure +intend +intention +interest +interfere +interference +international +interrupt +into +introduce +introduction +invent +invention +invite +iron +island +it +jaw +join +joint +joke +journey +joy +judge +juice +jump +just +justice +keep +key +kick +kill +kind +king +kingdom +kiss +kitchen +knee +kneel +knife +knock +know +knowledge +lack +ladder +lady +lake +lamp +land +language +large +last +late +latter +laugh +laughter +law +lawyer +lay +lead +leadership +leaf +lean +learn +least +leather +leave +left +leg +lend +length +less +lessen +lesson +let +letter +level +liberty +library +lid +lie +life +lift +light +like +likely +limit +line +lip +liquid +list +listen +literary +literature +little +live +load +loan +local +lock +lodge +log +lonely +long +look +loose +lord +lose +loss +lot +loud +love +lovely +low +loyal +loyalty +luck +lump +lunch +lung +machine +machinery +mad +mail +main +make +male +man +manage +mankind +manner +manufacture +many +map +march +mark +market +marriage +marry +mass +master +match +material +matter +may +maybe +meal +mean +meanwhile +measure +meat +mechanic +mechanism +medical +medicine +meet +melt +member +membership +memory +mention +merchant +mercy +mere +message +metal +middle +might +mild +mile +milk +mill +mind +mine +mineral +minister +minute +miserable +misery +miss +mistake +mix +mixture +model +moderate +modern +modest +moment +money +month +moon +moral +more +moreover +morning +most +mother +motion +motor +mountain +mouse +mouth +move +much +mud +multiply +murder +music +musician +must +mystery +nail +name +narrow +nation +native +nature +near +neat +necessary +necessity +neck +need +needle +neglect +neighbor +neighborhood +neither +nest +net +network +never +new +news +newspaper +next +nice +night +no +noble +nobody +noise +none +noon +nor +north +northern +nose +not +note +nothing +notice +now +nowhere +number +numerous +nurse +nut +obey +object +objection +observe +occasion +ocean +of +off +offer +office +officer +official +often +oil +old +omit +on +once +one +only +onto +open +operate +operation +operator +opinion +opportunity +oppose +opposite +opposition +or +orange +order +ordinary +organ +organize +origin +other +otherwise +ought +out +outline +outside +over +overcome +owe +own +ownership +pack +package +pad +page +pain +paint +pair +pale +pan +paper +parent +park +part +particle +particular +partner +party +pass +passage +passenger +past +paste +path +patience +patient +pattern +pause +pay +peace +peculiar +pen +pencil +people +per +perfect +perform +performance +perhaps +permanent +permission +permit +person +persuade +pet +photograph +pick +picture +piece +pile +pin +pink +pipe +pity +place +plain +plan +plant +plaster +plate +play +pleasant +please +pleasure +plenty +plow +pocket +poem +poet +point +poison +police +polish +polite +political +politician +politics +pool +poor +popular +population +position +possess +possession +possible +post +postpone +pot +pound +pour +poverty +powder +power +practical +practice +praise +pray +preach +precious +prefer +preference +prejudice +prepare +presence +present +preserve +president +press +pressure +pretend +pretty +prevent +prevention +price +pride +priest +print +prison +private +prize +probable +problem +produce +product +production +profession +profit +program +progress +promise +prompt +pronounce +proof +proper +property +proposal +propose +protect +protection +proud +prove +provide +public +pull +pump +punish +pupil +pure +purpose +push +put +puzzle +qualification +qualify +quality +quantity +quarrel +quarter +queen +question +quick +quiet +quite +rabbit +race +radio +rail +railroad +rain +raise +rank +rapid +rare +rate +rather +raw +reach +read +ready +real +realize +reason +reasonable +receive +recent +recognition +recognize +recommend +record +red +reduce +reduction +refer +reference +reflect +reflection +refresh +refuse +regard +regret +regular +relate +relation +relative +relief +relieve +religion +remain +remark +remedy +remember +remind +rent +repair +repeat +repetition +replace +reply +report +represent +representative +reproduce +republic +reputation +request +rescue +reserve +resign +resist +resistance +respect +responsible +rest +restaurant +result +retire +return +review +reward +ribbon +rice +rich +rid +ride +right +ring +rise +risk +rival +river +road +roar +roast +rob +rock +roll +roof +room +root +rope +rough +round +row +royal +rub +rubber +rug +ruin +rule +run +rush +rust +sacred +sacrifice +sad +saddle +safe +safety +sail +sake +salary +sale +salesman +salt +same +sample +sand +satisfaction +satisfactory +satisfy +sauce +save +saw +say +scale +scarce +scatter +scene +scenery +school +science +scientific +scientist +scrape +scratch +screen +screw +sea +search +season +seat +second +secret +secretary +see +seed +seem +seize +seldom +self +sell +send +sense +sensitive +sentence +separate +separation +serious +servant +serve +service +set +settle +several +severe +sew +shade +shadow +shake +shall +shallow +shame +shape +share +sharp +shave +she +sheep +sheet +shelf +shell +shelter +shield +shine +ship +shirt +shock +shoe +shoot +shop +shore +short +should +shoulder +shout +show +shower +shut +sick +side +sight +sign +signal +silence +silent +silver +simple +simplicity +since +sincere +sing +single +sink +sir +sister +sit +situation +size +skill +skin +skirt +sky +slave +slavery +sleep +slide +slight +slip +slope +slow +small +smell +smile +smoke +smooth +snake +snow +so +soap +social +society +soft +soften +soil +soldier +solemn +solid +solution +solve +some +somebody +somehow +someone +something +sometimes +somewhere +son +song +soon +sorry +sort +soul +sound +soup +south +space +spare +speak +special +speech +speed +spell +spend +spin +spirit +spit +spite +splendid +split +sport +spot +spread +spring +square +staff +stage +stain +stair +stamp +stand +standard +star +start +state +station +stay +steady +steam +steel +steep +steer +stem +step +stick +stiff +still +stir +stock +stomach +stone +stop +store +storm +story +stove +straight +straighten +strange +straw +stream +street +strength +strengthen +stretch +strict +strike +string +strip +stroke +strong +struggle +student +study +stuff +stupid +subject +substance +succeed +success +such +suck +sudden +suffer +sugar +suggest +suggestion +suit +summer +sun +supper +supply +support +suppose +sure +surface +surprise +surround +suspect +suspicion +suspicious +swallow +swear +sweat +sweep +sweet +swell +swim +swing +sympathetic +sympathy +system +table +tail +take +talk +tall +tap +taste +tax +taxi +tea +teach +tear +telegraph +telephone +tell +temperature +temple +tempt +tend +tender +tent +term +terrible +test +than +thank +that +the +theater +theatrical +then +there +therefore +these +they +thick +thief +thin +thing +think +this +thorough +those +though +thread +threat +threaten +throat +through +throw +thumb +thunder +thus +ticket +tide +tie +tight +till +time +tip +tire +title +to +tobacco +today +toe +together +tomorrow +ton +tongue +tonight +too +tool +tooth +top +total +touch +tough +tour +toward +towel +tower +town +toy +track +trade +train +translate +translation +trap +travel +tray +treasure +treasury +treat +tree +tremble +trial +tribe +trick +trip +trouble +true +trust +truth +try +tube +tune +turn +twist +type +ugly +uncle +under +understand +union +unit +unite +unity +universal +universe +university +unless +until +up +upon +upper +upset +urge +urgent +use +usual +valley +valuable +value +variety +various +veil +verb +verse +very +vessel +victory +view +village +violence +violent +virtue +visit +visitor +voice +vote +voyage +wage +wait +waiter +wake +walk +wall +wander +want +war +warm +warmth +warn +wash +waste +watch +water +wave +wax +way +we +weak +weaken +wealth +weapon +wear +weather +weave +week +weekend +weigh +weight +welcome +well +west +western +wet +what +whatever +wheel +when +whenever +where +wherever +whether +which +while +whip +whisper +whistle +white +who +whole +why +wide +widow +width +wife +wild +will +win +wind +window +wine +wing +winter +wipe +wire +wisdom +wise +wish +with +within +without +witness +woman +wonder +wood +wooden +word +work +world +worry +worse +worship +worth +would +wound +wrap +wreck +wrist +write +wrong +yard +year +yellow +yes +yesterday +yet +yield +you +young +youth +zero \ No newline at end of file diff --git a/kadai3-2/InoAyaka/README.md b/kadai3-2/InoAyaka/README.md new file mode 100644 index 0000000..4bad9ee --- /dev/null +++ b/kadai3-2/InoAyaka/README.md @@ -0,0 +1,49 @@ +# <課題3-2>【TRY】分割ダウンローダを作ろう +## 概要 + +- Rangeアクセスを用いる +- いくつかのゴルーチンでダウンロードしてマージする +- エラー処理を工夫する +-- golang.org/x/sync/errgourpパッケージなどを使ってみる +- キャンセルが発生した場合の実装を行う + + + +## 使い方 +``` +$ go build -o downloader +$ +$ ./downloader -h +Usage of ./downloader: + -URL string + URL to download + -dir string + Download directory (default "./") + -div uint + Specifying the number of divisions (default 5) +$ +$ +``` + +実行例 +``` +$ ./downloader -dir testdata -URL https://golang.org/doc/gopher/bumper640x360.png +checkDir(testdata): OK +checkURL(https://golang.org/doc/gopher/bumper640x360.png): OK +-------------------------------------------------- +finished download [05] : bytes 33608 - 42013 +finished download [02] : bytes 8402 - 16803 +finished download [04] : bytes 25206 - 33607 +finished download [01] : bytes 0 - 8401 +finished download [03] : bytes 16804 - 25205 +-------------------------------------------------- +download complete + +``` + +### 感想 + +- 個人的には今までの課題の中で難易度は高いように感じた +- 分割ダウンローダーというものをどういう構成でプログラムすれば実現できるのか、という点から非常に時間がかかってしまった +- [Code-Hex/pget](https://github.com/Code-Hex/pget) を参考に作成した +- 参考にするために"Code-Hex/pget"のコードを読み、読む力についても、力をつける必要があると感じた diff --git a/kadai3-2/InoAyaka/downloader.go b/kadai3-2/InoAyaka/downloader.go new file mode 100644 index 0000000..6e19a51 --- /dev/null +++ b/kadai3-2/InoAyaka/downloader.go @@ -0,0 +1,206 @@ +package main + +import ( + "context" + "flag" + "fmt" + "io" + "net/http" + "net/url" + "os" + "path/filepath" + "strings" + + "golang.org/x/sync/errgroup" +) + +type downloader struct { + targetURL string + dir string + div uint + fileName string + fileSize uint + split uint +} + +type Range struct { + start uint + end uint + worker uint +} + +var div = flag.Uint("div", 5, "Specifying the number of divisions") +var dir = flag.String("dir", "./", "Download directory") +var targetURL = flag.String("URL", "", "URL to download") + +func main() { + + flag.Parse() + + //URLのチェック + d := &downloader{ + div: *div, + dir: *dir, + targetURL: *targetURL, + } + + if ok := d.ready(); !ok { + os.Exit(1) + } + + fmt.Println(strings.Repeat("-", 50)) + + if err := d.download(); err != nil { + fmt.Fprintln(os.Stderr, err) + os.Exit(1) + } + + if err := d.unionFiles(); err != nil { + fmt.Fprintln(os.Stderr, err) + os.Exit(1) + } + + if err := d.deleteTmpFiles(); err != nil { + fmt.Fprintln(os.Stderr, err) + os.Exit(1) + } + + fmt.Println(strings.Repeat("-", 50)) + fmt.Println("download complete") + +} + +//download 分割ダウンロードを実行します +func (d *downloader) download() error { + + _, err := url.Parse(d.targetURL) + if err != nil { + return err + } + + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + grp, gctx := errgroup.WithContext(ctx) + + for i := 0; i < int(d.div); i++ { + part := i + 1 + grp.Go(func() error { + return d.partDownload(gctx, part) + }) + } + + if err := grp.Wait(); err != nil { + return err + } + + return nil +} + +func (d *downloader) partDownload(gctx context.Context, part int) error { + + r := d.makeRange(part) + + req, err := http.NewRequest("GET", d.targetURL, nil) + if err != nil { + return err + } + + //ヘッダーのセット + req.Header.Set("Range", fmt.Sprintf("bytes=%d-%d", r.start, r.end)) + + //HTTP要求を送信 + resp, err := http.DefaultClient.Do(req) + if err != nil { + return fmt.Errorf("failed to split get requests: %d", part) + } + defer resp.Body.Close() + + //分割ファイル名の設定 + tmpFilePath := fmt.Sprintf("%s/%s.%d.%d", d.dir, d.fileName, d.div, part) + + f, err := os.OpenFile(tmpFilePath, os.O_WRONLY|os.O_CREATE|os.O_APPEND, 0666) + if err != nil { + return fmt.Errorf("failed to create %s ", tmpFilePath) + } + defer f.Close() + + if _, err := io.Copy(f, resp.Body); err != nil { + return err + } + + //他のタスクからのキャンセルを受信した場合を考慮 + select { + case <-gctx.Done(): + fmt.Printf("cancelled [%02d]\n", part) + return gctx.Err() + default: + fmt.Printf("finished download [%02d] : bytes %5d - %5d\n", part, r.start, r.end) + return nil + } +} + +//makeRange 範囲の指定を行うRangeを作成します +func (d *downloader) makeRange(part int) Range { + start := d.split * uint(part-1) + end := start + d.split - 1 + + //最後のパートのみendの指定をファイルサイズに設定する + if uint(part) == d.div { + end = d.fileSize + } + + return Range{ + start: start, + end: end, + worker: uint(part), + } +} + +//unionFiles ファイルの結合を行います +func (d *downloader) unionFiles() error { + + outFilePath := filepath.Join(d.dir, d.fileName) + + outFile, err := os.Create(outFilePath) + if err != nil { + return err + } + + for i := 0; i < int(d.div); i++ { + part := i + 1 + tmpFilePath := fmt.Sprintf("%s/%s.%d.%d", d.dir, d.fileName, d.div, part) + + tmpFile, err := os.Open(tmpFilePath) + if err != nil { + return fmt.Errorf("failed to open %s", tmpFilePath) + } + + if _, err := io.Copy(outFile, tmpFile); err != nil { + return fmt.Errorf("failed to copy %s", tmpFilePath) + } + + if err := tmpFile.Close(); err != nil { + return fmt.Errorf("failed to close %s", tmpFilePath) + } + + } + + if err := outFile.Close(); err != nil { + return err + } + + return nil +} + +//deleteTmpFiles 不要になった一時ファイルを削除します +func (d *downloader) deleteTmpFiles() error { + for i := 0; i < int(d.div); i++ { + part := i + 1 + tmpFilePath := fmt.Sprintf("%s/%s.%d.%d", d.dir, d.fileName, d.div, part) + + if err := os.Remove(tmpFilePath); err != nil { + return fmt.Errorf("failed to remove %s", tmpFilePath) + } + } + return nil +} diff --git a/kadai3-2/InoAyaka/go.mod b/kadai3-2/InoAyaka/go.mod new file mode 100644 index 0000000..e86ca40 --- /dev/null +++ b/kadai3-2/InoAyaka/go.mod @@ -0,0 +1,8 @@ +module github.com/gopherdojo/dojo8/kadai3-2/InoAyaka + +go 1.14 + +require ( + github.com/pkg/errors v0.9.1 + golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208 +) diff --git a/kadai3-2/InoAyaka/go.sum b/kadai3-2/InoAyaka/go.sum new file mode 100644 index 0000000..e8a22ca --- /dev/null +++ b/kadai3-2/InoAyaka/go.sum @@ -0,0 +1,4 @@ +github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= +github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208 h1:qwRHBd0NqMbJxfbotnDhm2ByMI1Shq4Y6oRJo21SGJA= +golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= diff --git a/kadai3-2/InoAyaka/ready.go b/kadai3-2/InoAyaka/ready.go new file mode 100644 index 0000000..5667f25 --- /dev/null +++ b/kadai3-2/InoAyaka/ready.go @@ -0,0 +1,97 @@ +package main + +import ( + "fmt" + "net/http" + "net/url" + "os" + "strings" +) + +func (d *downloader) ready() bool { + + errFlg := true + + if err := d.checkDir(); err != nil { + errFlg = false + fmt.Fprintf(os.Stderr, "checkDir(%s): NG \n", d.dir) + fmt.Fprintln(os.Stderr, err) + } else { + fmt.Fprintf(os.Stdout, "checkDir(%s): OK\n", d.dir) + } + + if err := d.checkURL(); err != nil { + errFlg = false + fmt.Fprintf(os.Stderr, "checkURL(%s): NG \n", d.targetURL) + fmt.Fprintln(os.Stderr, err) + } else { + fmt.Fprintf(os.Stdout, "checkURL(%s): OK\n", d.targetURL) + } + + d.setFileName() + + if err := d.setFileSize(); err != nil { + errFlg = false + fmt.Fprintf(os.Stderr, "getFileSize(%s): NG \n", d.targetURL) + fmt.Fprintln(os.Stderr, err) + } + + return errFlg +} + +//checkURL 指定されたダウンロードURLのチェックを行います +func (d *downloader) checkURL() error { + _, err := url.ParseRequestURI(d.targetURL) + if err != nil { + return fmt.Errorf("URL error , %w", err) + } + + u, err := url.Parse(d.targetURL) + if err != nil || u.Scheme == "" || u.Hostname() == "" { + return fmt.Errorf("URL error , %w", err) + } + + return nil +} + +//checkDir 指定されたディレクトリのチェックを行います +//チェック内容:ディレクトリの存在、ディレクトリを表しているか +func (d *downloader) checkDir() error { + + //ディレクトリの存在チェック & ディレクトリを表しているかどうか + if m, err := os.Stat(d.dir); os.IsNotExist(err) { + return err + } else if !m.IsDir() { + return fmt.Errorf("%s : not a directory", d.dir) + } + + return nil + +} + +//setFileName urlからファイル名を切り出します、ファイル名を設定します +func (d *downloader) setFileName() { + token := strings.Split(d.targetURL, "/") + + var fileName string + for i := 1; fileName == ""; i++ { + fileName = token[len(token)-i] + } + + d.fileName = fileName +} + +//setFileSize HTTPのヘッダーからファイルサイズを取得し、分割サイズを設定します +func (d *downloader) setFileSize() error { + resp, err := http.Head(d.targetURL) + + if err != nil { + return err + } + + d.fileSize = uint(resp.ContentLength) + d.split = d.fileSize / d.div + + return nil + +}