Ugurrrrr commited on
Commit
91cb15f
·
verified ·
1 Parent(s): e39125f

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +110 -0
app.py ADDED
@@ -0,0 +1,110 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # app.py
2
+ import gradio as gr
3
+ import yake
4
+ from transformers import AutoTokenizer, AutoModelForSeq2SeqLM
5
+ import math
6
+
7
+ # --- Models / tools (küçük ve CPU-dostu)
8
+ MODEL_NAME = "google/flan-t5-small"
9
+ tokenizer = AutoTokenizer.from_pretrained(MODEL_NAME)
10
+ model = AutoModelForSeq2SeqLM.from_pretrained(MODEL_NAME)
11
+
12
+ # YAKE keyword extractor (çok hafif)
13
+ def extract_keywords(text, lang="en", max_kw=8):
14
+ kw_extractor = yake.KeywordExtractor(lan=lang, n=1, top=max_kw)
15
+ kws = kw_extractor.extract_keywords(text)
16
+ # returns list of keywords (sorted)
17
+ return [kw for kw, score in kws]
18
+
19
+ # Basit SEO puanı hesaplama
20
+ def seo_score(title, description, keywords, tags):
21
+ score = 0
22
+ # title presence & length
23
+ if title and title.strip():
24
+ score += 15
25
+ L = len(title)
26
+ if 40 <= L <= 70:
27
+ score += 20
28
+ elif 30 <= L < 40 or 71 <= L <= 90:
29
+ score += 10
30
+ # keywords in title/description
31
+ kw_in_title = sum(1 for k in keywords if k.lower() in (title or "").lower())
32
+ kw_in_desc = sum(1 for k in keywords if k.lower() in (description or "").lower())
33
+ score += min(20, kw_in_title * 10)
34
+ score += min(15, kw_in_desc * 5)
35
+ # description length
36
+ dlen = len(description or "")
37
+ if dlen >= 300:
38
+ score += 20
39
+ elif dlen >= 150:
40
+ score += 10
41
+ # tags
42
+ if tags:
43
+ if 3 <= len(tags) <= 15:
44
+ score += 10
45
+ elif len(tags) > 15:
46
+ score += 5
47
+ # normalize
48
+ return min(100, score)
49
+
50
+ # Title & description generator (Flan-T5)
51
+ def gen_suggestions(main_text, keywords, max_titles=3):
52
+ prompt = (
53
+ "You are an assistant that generates catchy YouTube video titles and an SEO-optimized description.\n"
54
+ f"Main content: {main_text}\n"
55
+ f"Keywords: {', '.join(keywords)}\n"
56
+ "Produce 3 short catchy titles (each <70 chars) and one SEO-friendly description (2 paragraphs). "
57
+ "Return clearly, titles separated by '||' then '---' then the description."
58
+ )
59
+ inputs = tokenizer(prompt, return_tensors="pt")
60
+ out = model.generate(**inputs, max_new_tokens=300)
61
+ text = tokenizer.decode(out[0], skip_special_tokens=True)
62
+ # Try to split results
63
+ if "||" in text:
64
+ parts = text.split("---")
65
+ titles = parts[0].split("||")
66
+ desc = parts[1].strip() if len(parts) > 1 else ""
67
+ else:
68
+ # fallback: guess
69
+ lines = [l.strip() for l in text.split("\n") if l.strip()]
70
+ titles = lines[:max_titles]
71
+ desc = "\n".join(lines[max_titles:])
72
+ titles = [t.strip() for t in titles if t.strip()]
73
+ return titles[:max_titles], desc
74
+
75
+ # Gradio function
76
+ def analyze(title, description, lang_choice):
77
+ text = (title or "") + "\n" + (description or "")
78
+ lang = "tr" if lang_choice == "Türkçe" else "en"
79
+ # extract keywords
80
+ keywords = extract_keywords(text, lang=lang, max_kw=8)
81
+ # generate suggestions
82
+ gen_titles, gen_desc = gen_suggestions(text if text.strip() else "Short video about ...", keywords)
83
+ # tags: use keywords as tags (shorten)
84
+ tags = [k.replace(" ", "_") for k in keywords][:12]
85
+ # score
86
+ score = seo_score(title, description, keywords, tags)
87
+ return {
88
+ "SEO Skoru (0-100)": score,
89
+ "Çıkarılan Anahtar Kelimeler": ", ".join(keywords),
90
+ "Önerilen Başlıklar": "\n".join([f"- {t}" for t in gen_titles]),
91
+ "Önerilen Açıklama": gen_desc,
92
+ "Önerilen Etiketler (tags)": ", ".join(tags)
93
+ }
94
+
95
+ # Gradio UI
96
+ with gr.Blocks() as demo:
97
+ gr.Markdown("## YouTube SEO Asistanı — Basit & Ücretsiz (örnek)")
98
+ with gr.Row():
99
+ with gr.Column(scale=2):
100
+ title_in = gr.Textbox(label="Mevcut başlık (isteğe bağlı)", lines=1, placeholder="Var olan videonuzun başlığını yazın")
101
+ desc_in = gr.Textbox(label="Açıklama / Transcript / İçerik", lines=8, placeholder="Video açıklaması veya transkriptinizi buraya yapıştırın")
102
+ lang = gr.Radio(choices=["Türkçe", "English"], value="Türkçe", label="Dil")
103
+ btn = gr.Button("Analiz Et")
104
+ with gr.Column(scale=1):
105
+ score_out = gr.Label(num_top_classes=1, label="Sonuç")
106
+ result_box = gr.JSON(label="Detaylı Öneriler")
107
+ btn.click(fn=analyze, inputs=[title_in, desc_in, lang], outputs=[score_out, result_box])
108
+
109
+ if __name__ == "__main__":
110
+ demo.launch()