Families.AutoWriter 1.0.0.0
Families 콘텐츠를 반복 작업 없이 작성·등록하도록 돕는 자동화 작성 도구입니다.
로딩중...
검색중...
일치하는것 없음
FamiliesAutoWriter.Services.PostWriterService 클래스 참조sealed

더 자세히 ...

Public 멤버 함수

IReadOnlyList< AlbumInfoGetAlbums (string slug)
IReadOnlyList< string > GetSlugs ()
async Task< bool > SavePostAsync (string slug, PostEntry post, IEnumerable< string > localPhotoPaths)
IReadOnlyList< string > GetExistingTitles (string slug)
DateTime? int LastNumber GetCookingTimelineState (string slug)

Public 속성

DateTime? LastPostedAt

속성

string AppDataRoot = "" [get, set]

정적 Private 멤버 함수

static bool IsCookingPost (string title)
static int ExtractCookingNumber (string title)
static bool TryGetPropertyIgnoreCase (JsonElement element, string name, out JsonElement value)
static string Sanitize (string id)

정적 Private 속성

static readonly JsonSerializerOptions _opts

상세한 설명

Post Writer Service 기능과 관련 상태를 캡슐화합니다.

PostWriterService.cs 파일의 17 번째 라인에서 정의되었습니다.

멤버 함수 문서화

◆ ExtractCookingNumber()

int FamiliesAutoWriter.Services.PostWriterService.ExtractCookingNumber ( string title)
inlinestaticprivate

Extract Cooking Number 작업을 수행합니다.

매개변수
titletitle에 사용할 string 값입니다.
반환값
Extract Cooking Number 작업에서 생성한 int 결과입니다.

PostWriterService.cs 파일의 368 번째 라인에서 정의되었습니다.

369 {
370 var match = Regex.Match(title, @"#(?<n>\d+)");
371 return match.Success && int.TryParse(match.Groups["n"].Value, out var n) ? n : 0;
372 }

다음에 의해서 참조됨 : GetCookingTimelineState().

이 함수를 호출하는 함수들에 대한 그래프입니다.:

◆ GetAlbums()

IReadOnlyList< AlbumInfo > FamiliesAutoWriter.Services.PostWriterService.GetAlbums ( string slug)
inline

Albums 값을 가져옵니다.

매개변수
slugslug에 사용할 string 값입니다.
반환값
Get Albums 작업에서 생성한 IReadOnlyList<AlbumInfo> 결과입니다.

PostWriterService.cs 파일의 69 번째 라인에서 정의되었습니다.

70 {
71 var dir = Path.Combine(AppDataRoot, "Family", slug, "albums");
72 if (!Directory.Exists(dir)) return [];
73 var list = new List<AlbumInfo>();
74 foreach (var f in Directory.GetFiles(dir, "*.json"))
75 {
76 try
77 {
78 var json = File.ReadAllText(f);
79 var a = JsonSerializer.Deserialize<AlbumInfo>(json, _opts);
80 if (a != null) list.Add(a);
81 }
82 catch { }
83 }
84 return list.OrderBy(a => a.SortOrder).ThenBy(a => a.Name).ToList();
85 }

다음을 참조함 : _opts, AppDataRoot.

◆ GetCookingTimelineState()

DateTime? int LastNumber FamiliesAutoWriter.Services.PostWriterService.GetCookingTimelineState ( string slug)
inline

PostWriterService.cs 파일의 290 번째 라인에서 정의되었습니다.

291 {
292 var dir = Path.Combine(AppDataRoot, "Family", slug, "posts");
293 if (!Directory.Exists(dir)) return (null, 0);
294
295 DateTime? lastPostedAt = null;
296 var lastNumber = 0;
297
298 foreach (var f in Directory.GetFiles(dir, "*.json"))
299 {
300 try
301 {
302 var post = JsonSerializer.Deserialize<PostEntry>(File.ReadAllText(f), _opts);
303 if (post is null || !IsCookingPost(post.Title)) continue;
304
305 if (lastPostedAt is null || post.PostedAt > lastPostedAt.Value)
306 lastPostedAt = post.PostedAt;
307
308 lastNumber = Math.Max(lastNumber, ExtractCookingNumber(post.Title));
309 }
310 catch { }
311 }
312
313 return (lastPostedAt, lastNumber);
314 }

다음을 참조함 : _opts, AppDataRoot, ExtractCookingNumber(), IsCookingPost(), LastPostedAt.

이 함수 내부에서 호출하는 함수들에 대한 그래프입니다.:

◆ GetExistingTitles()

IReadOnlyList< string > FamiliesAutoWriter.Services.PostWriterService.GetExistingTitles ( string slug)
inline

Existing Titles 값을 가져옵니다.

매개변수
slugslug에 사용할 string 값입니다.
반환값
Get Existing Titles 작업에서 생성한 IReadOnlyList<string> 결과입니다.

PostWriterService.cs 파일의 245 번째 라인에서 정의되었습니다.

246 {
247 var dir = Path.Combine(AppDataRoot, "Family", slug, "posts");
248 if (!Directory.Exists(dir)) return [];
249 var titles = new List<string>();
250 foreach (var f in Directory.GetFiles(dir, "*.json"))
251 {
252 try
253 {
254 using var doc = JsonDocument.Parse(File.ReadAllText(f));
255 if (TryGetPropertyIgnoreCase(doc.RootElement, "title", out var t))
256 {
257 var v = t.GetString();
258 if (!string.IsNullOrWhiteSpace(v)) titles.Add(v);
259 }
260 }
261 catch { }
262 }
263 return titles;
264 }

다음을 참조함 : AppDataRoot, TryGetPropertyIgnoreCase().

이 함수 내부에서 호출하는 함수들에 대한 그래프입니다.:

◆ GetSlugs()

IReadOnlyList< string > FamiliesAutoWriter.Services.PostWriterService.GetSlugs ( )
inline

Slugs 값을 가져옵니다.

반환값
Get Slugs 작업에서 생성한 IReadOnlyList<string> 결과입니다.

PostWriterService.cs 파일의 103 번째 라인에서 정의되었습니다.

104 {
105 var root = Path.Combine(AppDataRoot, "Family");
106 if (!Directory.Exists(root)) return [];
107 return Directory.GetDirectories(root)
108 .Select(Path.GetFileName)
109 .Where(s => s != null)
110 .Cast<string>()
111 .ToList();
112 }

다음을 참조함 : AppDataRoot.

◆ IsCookingPost()

bool FamiliesAutoWriter.Services.PostWriterService.IsCookingPost ( string title)
inlinestaticprivate

Is Cooking Post 조건을 확인합니다.

매개변수
titletitle에 사용할 string 값입니다.
반환값
Is Cooking Post 조건이 충족되면 true이고, 그렇지 않으면 false입니다.

PostWriterService.cs 파일의 340 번째 라인에서 정의되었습니다.

340 =>
341 title.Contains("1983", StringComparison.OrdinalIgnoreCase) &&
342 title.Contains("집밥육아", StringComparison.OrdinalIgnoreCase);

다음에 의해서 참조됨 : GetCookingTimelineState().

이 함수를 호출하는 함수들에 대한 그래프입니다.:

◆ Sanitize()

string FamiliesAutoWriter.Services.PostWriterService.Sanitize ( string id)
inlinestaticprivate

Sanitize 작업을 수행합니다.

매개변수
idid에 사용할 string 값입니다.
반환값
Sanitize 작업에서 생성한 string 결과입니다.

PostWriterService.cs 파일의 453 번째 라인에서 정의되었습니다.

453 =>
454 string.Concat(id.Split(Path.GetInvalidFileNameChars()));

◆ SavePostAsync()

async Task< bool > FamiliesAutoWriter.Services.PostWriterService.SavePostAsync ( string slug,
PostEntry post,
IEnumerable< string > localPhotoPaths )
inline

Post Async 데이터를 저장합니다.

매개변수
slugslug에 사용할 string 값입니다.
postpost에 사용할 PostEntry 값입니다.
localPhotoPathslocal Photo Paths에 사용할 IEnumerable<string> 값입니다.
반환값
Save Post Async 작업에서 생성한 Task<bool> 결과입니다.
예외
InvalidOperationException현재 객체 상태에서 Save Post Async 작업을 수행할 수 없는 경우 발생합니다.
IOExceptionSave Post Async 작업을 완료할 수 없는 경우 IOException이 발생합니다.

PostWriterService.cs 파일의 170 번째 라인에서 정의되었습니다.

171 {
172 if (string.IsNullOrWhiteSpace(AppDataRoot))
173 throw new InvalidOperationException("App_Data 경로가 비어 있습니다.");
174 if (string.IsNullOrWhiteSpace(slug))
175 throw new InvalidOperationException("가족 슬러그가 비어 있습니다.");
176 if (string.IsNullOrWhiteSpace(post.Id))
177 post.Id = Guid.NewGuid().ToString("N");
178
179 var tenantDir = Path.Combine(AppDataRoot, "Family", slug);
180 var postsDir = Path.Combine(tenantDir, "posts");
181 var mediaDir = Path.Combine(tenantDir, "media", post.Id);
182
183 Directory.CreateDirectory(postsDir);
184 Directory.CreateDirectory(mediaDir);
185
186 // 로컬 사진 복사
187 foreach (var src in localPhotoPaths)
188 {
189 if (!File.Exists(src)) continue;
190 var fn = Path.GetFileName(src);
191 var dst = Path.Combine(mediaDir, fn);
192 File.Copy(src, dst, overwrite: true);
193 if (!post.PhotoFileNames.Contains(fn))
194 post.PhotoFileNames.Add(fn);
195 }
196
197 var path = Path.Combine(postsDir, $"{Sanitize(post.Id)}.json");
198 var tmp = Path.Combine(postsDir, $"{Sanitize(post.Id)}.{Guid.NewGuid():N}.tmp");
199 try
200 {
201 await using (var fs = File.Create(tmp))
202 await JsonSerializer.SerializeAsync(fs, post, _opts);
203 File.Move(tmp, path, overwrite: true);
204 }
205 catch (Exception ex)
206 {
207 throw new IOException($"JSON 저장 실패: {path} ({ex.Message})", ex);
208 }
209 finally
210 {
211 try
212 {
213 if (File.Exists(tmp)) File.Delete(tmp);
214 }
215 catch { }
216 }
217 return true;
218 }

다음을 참조함 : _opts, AppDataRoot, FamiliesAutoWriter.Models.PostEntry.Id.

◆ TryGetPropertyIgnoreCase()

bool FamiliesAutoWriter.Services.PostWriterService.TryGetPropertyIgnoreCase ( JsonElement element,
string name,
out JsonElement value )
inlinestaticprivate

Get Property Ignore Case 작업을 시도하고 성공 여부를 반환합니다.

매개변수
elementelement에 사용할 JsonElement 값입니다.
namename에 사용할 string 값입니다.
value적용할 값입니다.
반환값
Try Get Property Ignore Case 조건이 충족되면 true이고, 그렇지 않으면 false입니다.

PostWriterService.cs 파일의 414 번째 라인에서 정의되었습니다.

415 {
416 foreach (var prop in element.EnumerateObject())
417 {
418 if (string.Equals(prop.Name, name, StringComparison.OrdinalIgnoreCase))
419 {
420 value = prop.Value;
421 return true;
422 }
423 }
424
425 value = default;
426 return false;
427 }

다음에 의해서 참조됨 : GetExistingTitles().

이 함수를 호출하는 함수들에 대한 그래프입니다.:

멤버 데이터 문서화

◆ _opts

readonly JsonSerializerOptions FamiliesAutoWriter.Services.PostWriterService._opts
staticprivate
초기값:
= new()
{
WriteIndented = true,
PropertyNameCaseInsensitive = true,
}

opts 값을 보관합니다.

PostWriterService.cs 파일의 29 번째 라인에서 정의되었습니다.

30 {
31 WriteIndented = true,
32 PropertyNameCaseInsensitive = true,
33 };

다음에 의해서 참조됨 : GetAlbums(), GetCookingTimelineState(), SavePostAsync().

◆ LastPostedAt

DateTime? FamiliesAutoWriter.Services.PostWriterService.LastPostedAt

Cooking Timeline State 값을 가져옵니다.

매개변수
slugslug에 사용할 string 값입니다.
반환값
Get Cooking Timeline State 작업에서 생성한 (DateTime? LastPostedAt, int LastNumber) 결과입니다.

PostWriterService.cs 파일의 290 번째 라인에서 정의되었습니다.

다음에 의해서 참조됨 : GetCookingTimelineState().

속성 문서화

◆ AppDataRoot

string FamiliesAutoWriter.Services.PostWriterService.AppDataRoot = ""
getset

App Data Root 값을 가져오거나 설정합니다.

PostWriterService.cs 파일의 43 번째 라인에서 정의되었습니다.

43{ get; set; } = "";

다음에 의해서 참조됨 : GetAlbums(), GetCookingTimelineState(), GetExistingTitles(), GetSlugs(), SavePostAsync().


이 클래스에 대한 문서화 페이지는 다음의 파일로부터 생성되었습니다.: